Notes For V3.0-0
Because some key files have changed, V3.0 should be unzipped to a clean directory. 1. New Features in 3.0-0 1.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 1.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. 1.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). 2. Bugs Fixed in 3.01-0 2.1 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). 2.2 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. 2.3 Nova - Fixed DSK variable size interaction with restore. 2.4 PDP-1 - Fixed DT variable size interaction with restore. 2.5 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. 2.6 PDP-18B - Fixed DT, RF variable size interaction with restore. - Fixed MT bug in MTTR. 2.7 PDP-8 - Fixed DT, DF, RF, RX variable size interaction with restore. - Fixed MT bug in SKTR. 2.8 HP2100 - Fixed bug in DP (13210A controller only), DQ read status. - Fixed bug in DP, DQ seek complete. 2.9 GRI - Fixed bug in SC queue pointer management. 3. New Features in 3.0 vs prior releases N/A 4. Bugs Fixed in 3.0 vs prior releases N/A 5. General Notes WARNING: The RESTORE command has changed. RESTORE will now detach an attached file on a unit, if that unit did not have an attached file in the saved configuration. This is required to assure that the unit flags and the file state are consistent. WARNING: The compilation scheme for the PDP-10, PDP-11, and VAX has changed. Use one of the supplied build files, or read the documentation carefully, before compiling any of these simulators.
This commit is contained in:
parent
43385c9616
commit
4ffd3be790
215 changed files with 12913 additions and 8563 deletions
305
0readme_210.txt
305
0readme_210.txt
|
@ -1,305 +0,0 @@
|
|||
Notes For V2.10-4
|
||||
|
||||
1. New Features in 2.10-4
|
||||
|
||||
1.1 SCP and Libraries
|
||||
|
||||
- Added .ini startup file capability (suggested by Hans Pufal).
|
||||
- Added multiple switch evaluation points (suggested by Hans Pufal).
|
||||
- Added multiple command per action.
|
||||
- Added new library, sim_tape.c, for magtape emulation.
|
||||
|
||||
1.2 PDP-11
|
||||
|
||||
- Added user-defined disk capacity to RQ.
|
||||
- Addec choice of controllers to TQ.
|
||||
- Added user-defined tape capacity to TQ.
|
||||
|
||||
1.3 Interdata
|
||||
|
||||
- Added SHOW SELCH n command to display selector channel state.
|
||||
|
||||
1.4 Line Frequency Clocks (H316, Interdata, Nova, PDP-8, PDP-11,
|
||||
PDP-18B, SDS)
|
||||
|
||||
- Added SET <device> {50HZ/60HZ}, to set the line frequency.
|
||||
|
||||
1.5 DEC Console Input (PDP-8, PDP-11, PDP-18B, VAX)
|
||||
|
||||
- Added SET TTI CTRL-C, to generate ^C from SIMH prompt (^C
|
||||
crashes simulators compiled with Windows Visual C++).
|
||||
|
||||
1.6 Magtapes
|
||||
|
||||
- Revised to use magtape library for consistency.
|
||||
|
||||
2. Bugs Fixed in 2.10-4
|
||||
|
||||
- SCP: fixed bug in multiword deposits to files
|
||||
- Interdata disks: fixed bug in cylinder overflow on writes
|
||||
- Interdata tape: fixed bug, read error did not stop selector
|
||||
channel
|
||||
- Interdata precision clock: improved autocalibrate algorithm
|
||||
for UNIX V7.
|
||||
- Nova fixed head disk: fixed autosize algorithm.
|
||||
- PDP-11 RQ and TQ: fixed bugs in queue process and in vector
|
||||
calculation for VAXen.
|
||||
- PDP-11 TQ: fixed overly strict implementation of illegal
|
||||
modifiers check.
|
||||
- PDP-11 RY: fixed autosize algorithm.
|
||||
- PDP-18B CPU: fixed three EAE bugs (found by Hans Pufal).
|
||||
- PDP-18B MT: fixed bugs in interrupt handling, BOT error handling.
|
||||
- PDP-18B RF: removed extra bit from disk address, fixed autosize
|
||||
algorithm.
|
||||
- PDP-18B SYS: fixed bug in FMTASC usage (found by Hans Pufal).
|
||||
- PDP-8 MT: fixed bug in BOT error handling.
|
||||
- PDP-8 DF, RF, RX: fixed autosize algorithm.
|
||||
|
||||
3. New Features in 2.10 vs prior releases
|
||||
|
||||
3.1 SCP and Libraries
|
||||
|
||||
- The VT emulation package has been replaced by the capability
|
||||
to remote the console to a Telnet session. Telnet clients
|
||||
typically have more complete and robust VT100 emulation.
|
||||
- Simulated devices may now have statically allocated buffers,
|
||||
in addition to dynamically allocated buffers or disk-based
|
||||
data stores.
|
||||
- The DO command now takes substitutable arguments (max 9).
|
||||
In command files, %n represents substitutable argument n.
|
||||
- The initial command line is now interpreted as the command
|
||||
name and substitutable arguments for a DO command. This is
|
||||
backward compatible to prior versions.
|
||||
- The initial command line parses switches. -Q is interpreted
|
||||
as quiet mode; informational messages are suppressed.
|
||||
- The HELP command now takes an optional argument. HELP <cmd>
|
||||
types help on the specified command.
|
||||
- Hooks have been added for implementing GUI-based consoles,
|
||||
as well as simulator-specific command extensions. A few
|
||||
internal data structures and definitions have changed.
|
||||
- Two new routines (tmxr_open_master, tmxr_close_master) have
|
||||
been added to sim_tmxr.c. The calling sequence for
|
||||
sim_accept_conn has been changed in sim_sock.c.
|
||||
- The calling sequence for the VM boot routine has been modified
|
||||
to add an additional parameter.
|
||||
- SAVE now saves, and GET now restores, controller and unit flags.
|
||||
- Library sim_ether.c has been added for Ethernet support.
|
||||
- The EVAL command will evaluate a symbolic type-in and display
|
||||
it in numeric form.
|
||||
- The ! command (with no arguments) will launch the host operating
|
||||
system command shell. The ! command (with an argument) executes
|
||||
the argument as a host operating system command. (Code from
|
||||
Mark Pizzolato)
|
||||
- Telnet sessions now recognize BREAK. How a BREAK is transmitted
|
||||
dependent on the particular Telnet client. (Code from Mark
|
||||
Pizzolato)
|
||||
- The sockets library includes code for active connections as
|
||||
well as listening connections.
|
||||
- The RESTORE command will restore saved memory size, if the
|
||||
simulator supports dynamic memory resizing.
|
||||
- Added dynamic extension of the breakpoint table.
|
||||
- Added breakpoint actions.
|
||||
- Added VMS support for ! (from Mark Pizzolato).
|
||||
|
||||
3.2 VAX
|
||||
|
||||
- Non-volatile RAM (NVR) can behave either like a memory or like
|
||||
a disk-based peripheral. If unattached, it behaves like memory
|
||||
and is saved and restored by SAVE and RESTORE, respectively.
|
||||
If attached, its contents are loaded from disk by ATTACH and
|
||||
written back to disk at DETACH and EXIT.
|
||||
- SHOW <device> VECTOR displays the device's interrupt vector.
|
||||
A few devices allow the vector to be changed with SET
|
||||
<device> VECTOR=nnn.
|
||||
- SHOW CPU IOSPACE displays the I/O space address map.
|
||||
- The TK50 (TMSCP tape) has been added.
|
||||
- The DEQNA/DELQA (Qbus Ethernet controllers) have been added.
|
||||
- Autoconfiguration support has been added.
|
||||
- The paper tape reader has been removed from vax_stddev.c and
|
||||
now references a common implementation file, dec_pt.h.
|
||||
- Examine and deposit switches now work on all devices, not just
|
||||
the CPU.
|
||||
- Device address conflicts are not detected until simulation starts.
|
||||
- If the VAX console is attached to a Telnet session, BREAK is
|
||||
interpreted as console halt.
|
||||
- The SET/SHOW HISTORY commands enable and display a history of
|
||||
the most recently executed instructions. (Code from Mark
|
||||
Pizzolato)
|
||||
|
||||
3.3 PDP-11
|
||||
|
||||
- SHOW <device> VECTOR displays the device's interrupt vector.
|
||||
Most devices allow the vector to be changed with SET
|
||||
<device> VECTOR=nnn.
|
||||
- SHOW CPU IOSPACE displays the I/O space address map.
|
||||
- The TK50 (TMSCP tape), RK611/RK06/RK07 (cartridge disk),
|
||||
RX211 (double density floppy), and KW11P programmable clock
|
||||
have been added.
|
||||
- The DEQNA/DELQA (Qbus Ethernet controllers) have been added.
|
||||
- Autoconfiguration support has been added.
|
||||
- The paper tape reader has been removed from pdp11_stddev.c and
|
||||
now references a common implementation file, dec_pt.h.
|
||||
- Device bootstraps now use the actual CSR specified by the
|
||||
SET ADDRESS command, rather than just the default CSR. Note
|
||||
that PDP-11 operating systems may NOT support booting with
|
||||
non-standard addresses.
|
||||
- Specifying more than 256KB of memory, or changing the bus
|
||||
configuration, causes all peripherals that are not compatible
|
||||
with the current bus configuration to be disabled.
|
||||
- Device address conflicts are not detected until simulation starts.
|
||||
- The PDP-11 implements a stub DEUNA/DELUA (XU). The real XU
|
||||
module will be included in a later release.
|
||||
|
||||
3.4 PDP-10
|
||||
|
||||
- SHOW <device> VECTOR displays the device's interrupt vector.
|
||||
A few devices allow the vector to be changed with SET
|
||||
<device> VECTOR=nnn.
|
||||
- SHOW CPU IOSPACE displays the I/O space address map.
|
||||
- The RX211 (double density floppy) has been added; it is off
|
||||
by default.
|
||||
- The paper tape now references a common implementation file,
|
||||
dec_pt.h.
|
||||
- Device address conflicts are not detected until simulation starts.
|
||||
- The PDP-10 implements a stub DEUNA/DELUA (XU). The real XU
|
||||
module will be included in a later release.
|
||||
|
||||
3.5 PDP-1
|
||||
|
||||
- DECtape (then known as MicroTape) support has been added.
|
||||
- The line printer and DECtape can be disabled and enabled.
|
||||
- The PDP-1 supports the Type 24 serial drum (based on recently
|
||||
discovered documents).
|
||||
|
||||
3.6 18b PDP's
|
||||
|
||||
- The PDP-4 supports the Type 24 serial drum (based on recently
|
||||
discovered documents).
|
||||
- Added RB09 fixed head disk for the PDP-9.
|
||||
- Added LP09 line printer for the PDP-9 and PDP-15.
|
||||
- Added variable size support and autosizing to the RF15/RF09.
|
||||
|
||||
3.7 PDP-8
|
||||
|
||||
- The RX28 (double density floppy) has been added as an option to
|
||||
the existing RX8E controller.
|
||||
- SHOW <device> DEVNO displays the device's device number. Most
|
||||
devices allow the device number to be changed with SET <device>
|
||||
DEVNO=nnn.
|
||||
- Device number conflicts are not detected until simulation starts.
|
||||
- Added variable size support and autosizing to the DF32 and RF08.
|
||||
|
||||
3.8 Nova
|
||||
|
||||
- Added variable size support and autosizing to the Novadisk.
|
||||
|
||||
3.9 AltairZ80
|
||||
|
||||
- A hard drive has been added for increased storage.
|
||||
- Several bugs have been fixed.
|
||||
|
||||
3.10 HP 2100
|
||||
|
||||
- The 12845A has been added and made the default line printer (LPT).
|
||||
The 12653A has been renamed LPS and is off by default. It also
|
||||
supports the diagnostic functions needed to run the DCPC and DMS
|
||||
diagnostics.
|
||||
- The 12557A/13210A disk defaults to the 13210A (7900/7901).
|
||||
- The 12559A magtape is off by default.
|
||||
- New CPU options (EAU/NOEAU) enable/disable the extended arithmetic
|
||||
instructions for the 2116. These instructions are standard on
|
||||
the 2100 and 21MX.
|
||||
- New CPU options (MPR/NOMPR) enable/disable memory protect for the
|
||||
2100 and 21MX.
|
||||
- New CPU options (DMS/NODMS) enable/disable the dynamic mapping
|
||||
instructions for the 21MX.
|
||||
- The 12539 timebase generator autocalibrates.
|
||||
- The IOP microinstruction set is supported for the 21MX as well
|
||||
as the 2100.
|
||||
- The HP2100 supports the Access Interprocessor Link (IPL).
|
||||
|
||||
3.11 Simulated Magtapes
|
||||
|
||||
- Simulated magtapes recognize end of file and the marker
|
||||
0xFFFFFFFF as end of medium. Only the TMSCP tape simulator
|
||||
can generate an end of medium marker.
|
||||
- The error handling in simulated magtapes was overhauled to be
|
||||
consistent through all simulators.
|
||||
|
||||
3.12 Simulated DECtapes
|
||||
|
||||
- Added support for RT11 image file format (256 x 16b) to DECtapes.
|
||||
|
||||
3.13 Terminals Multiplexors
|
||||
|
||||
- BREAK detection was added to the HP, DEC, and Interdata terminal
|
||||
multiplexors.
|
||||
|
||||
4. Bugs Fixed in 2.10 vs prior releases
|
||||
|
||||
- TS11/TSV05 was not simulating the XS0_MOT bit, causing failures
|
||||
under VMS. In addition, two of the CTL options were coded
|
||||
interchanged.
|
||||
- IBM 1401 tape was not setting a word mark under group mark for
|
||||
load mode reads. This caused the diagnostics to crash.
|
||||
- SCP bugs in ssh_break and set_logon were fixed (found by Dave
|
||||
Hittner).
|
||||
- Numerous bugs in the HP 2100 extended arithmetic, floating point,
|
||||
21MX, DMS, and IOP instructions were fixed. Bugs were also fixed
|
||||
in the memory protect and DMS functions. The moving head disks
|
||||
(DP, DQ) were revised to simulate the hardware more accurately.
|
||||
Missing functions in DQ (address skip, read address) were added.
|
||||
- PDP-10 tape wouldn't boot, and then wouldn't read (reported by
|
||||
Michael Thompson and Harris Newman, respectively)
|
||||
- PDP-1 typewriter is half duplex, with only one shift state for
|
||||
both input and output (found by Derek Peschel)
|
||||
- PDP-11 console must default to 7b for early UNIX compatibility.
|
||||
- PDP-11/VAX TMSCP emulator was using the wrong packet length for
|
||||
read/write end packets.
|
||||
- Telnet IAC+IAC processing was fixed, both for input and output
|
||||
(found by Mark Pizzolato).
|
||||
- PDP-11/VAX Ethernet setting flag bits wrong for chained
|
||||
descriptors (found by Mark Pizzolato).
|
||||
- 18b PDP RF15/RF09: fixed IOT decoding and address wraparound
|
||||
logic (found by Hans Pufal).
|
||||
- 18b PDP RP15: fixed IOT decoding and command initiation.
|
||||
- HP2100 IPL: changed to full duplex (found by Mike Gemeny).
|
||||
- HP2100 CPU: fixed last cycle bug in DMA outpout (found by Mike
|
||||
Gemeny).
|
||||
- Interdata 16b CPU: fixed bug in SETM, SETMR (found by Mark
|
||||
Pizzolato).
|
||||
|
||||
|
||||
5. General Notes
|
||||
|
||||
WARNING: The build procedures have changed. There is only one UNIX
|
||||
makefile. To compile without Ethernet support, simply type
|
||||
|
||||
gmake {target|all}
|
||||
|
||||
To compile with Ethernet support, type
|
||||
|
||||
gmake USE_NETWORK=1 {target|all}
|
||||
|
||||
The Mingw batch files require Mingw release 2 and invoke the Unix
|
||||
makefile. There are still separate batch files for compilation
|
||||
with or without Ethernet support.
|
||||
|
||||
WARNING: V2.10 has reorganized and renamed some of the definition
|
||||
files for the PDP-10, PDP-11, and VAX. Be sure to delete all
|
||||
previous source files before you unpack the Zip archive, or
|
||||
unpack it into a new directory structure.
|
||||
|
||||
WARNING: V2.10 has a new, more comprehensive save file format.
|
||||
Restoring save files from previous releases will cause 'invalid
|
||||
register' errors and loss of CPU option flags, device enable/
|
||||
disable flags, unit online/offline flags, and unit writelock
|
||||
flags.
|
||||
|
||||
WARNING: If you are using Visual Studio .NET through the IDE,
|
||||
be sure to turn off the /Wp64 flag in the project settings, or
|
||||
dozens of spurious errors will be generated.
|
||||
|
||||
WARNING: Compiling Ethernet support under Windows requires
|
||||
extra steps; see the Ethernet readme file. Ethernet support is
|
||||
currently available only for Windows, Linux, NetBSD, and OpenBSD.
|
110
0readme_30.txt
Normal file
110
0readme_30.txt
Normal file
|
@ -0,0 +1,110 @@
|
|||
Notes For V3.0-0
|
||||
|
||||
Because some key files have changed, V3.0 should be unzipped to a
|
||||
clean directory.
|
||||
|
||||
1. New Features in 3.0-0
|
||||
|
||||
1.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
|
||||
|
||||
1.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.
|
||||
|
||||
1.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).
|
||||
|
||||
2. Bugs Fixed in 3.01-0
|
||||
|
||||
2.1 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).
|
||||
|
||||
2.2 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.
|
||||
|
||||
2.3 Nova
|
||||
|
||||
- Fixed DSK variable size interaction with restore.
|
||||
|
||||
2.4 PDP-1
|
||||
|
||||
- Fixed DT variable size interaction with restore.
|
||||
|
||||
2.5 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.
|
||||
|
||||
2.6 PDP-18B
|
||||
|
||||
- Fixed DT, RF variable size interaction with restore.
|
||||
- Fixed MT bug in MTTR.
|
||||
|
||||
2.7 PDP-8
|
||||
|
||||
- Fixed DT, DF, RF, RX variable size interaction with restore.
|
||||
- Fixed MT bug in SKTR.
|
||||
|
||||
2.8 HP2100
|
||||
|
||||
- Fixed bug in DP (13210A controller only), DQ read status.
|
||||
- Fixed bug in DP, DQ seek complete.
|
||||
|
||||
2.9 GRI
|
||||
|
||||
- Fixed bug in SC queue pointer management.
|
||||
|
||||
3. New Features in 3.0 vs prior releases
|
||||
|
||||
N/A
|
||||
|
||||
4. Bugs Fixed in 3.0 vs prior releases
|
||||
|
||||
N/A
|
||||
|
||||
5. General Notes
|
||||
|
||||
WARNING: The RESTORE command has changed. RESTORE will now
|
||||
detach an attached file on a unit, if that unit did not have
|
||||
an attached file in the saved configuration. This is required
|
||||
to assure that the unit flags and the file state are consistent.
|
||||
|
||||
WARNING: The compilation scheme for the PDP-10, PDP-11, and VAX
|
||||
has changed. Use one of the supplied build files, or read the
|
||||
documentation carefully, before compiling any of these simulators.
|
|
@ -2,6 +2,147 @@ This file contains information about the XQ/SIM_ETHER 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, and OpenBSD.
|
||||
|
||||
Currently, 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).
|
||||
|
||||
If your ethernet card is plugged into a switch, the promiscuous mode setting
|
||||
should not cause much of a problem, since the switch will still filter out
|
||||
most of the undesirable traffic. You will only see "excessive" traffic if you
|
||||
are on a direct or hub(repeater) segment.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Windows notes:
|
||||
1. The Windows-specific code uses the WinPCAP 3.0 package from
|
||||
http://winpcap.polito.it. This package for windows simulates the libpcap
|
||||
package that is freely available for unix systems.
|
||||
2. You must *install* the WinPCAP runtime package.
|
||||
3. The first time the WinPCAP driver is used, it will be dynamically loaded,
|
||||
and the user must be an Administrator on the machine to do so. If you need
|
||||
to run as an unprivileged user, you must set the service to autostart. See
|
||||
the WinPCAP documentation for details on the static load workaround.
|
||||
4. WinPCAP loops packet writes back into the read queue. This causes problems
|
||||
since the XQ controller is not expecting to read it's own packet. A fix
|
||||
to the packet read filter was added to reject packets from the current MAC,
|
||||
but this defeats DECNET's duplicate node number detection scheme. A more
|
||||
correct fix for WinPCAP will be explored as time allows.
|
||||
|
||||
Building on Windows:
|
||||
1. Install WinPCAP 3.0.
|
||||
2. Put the required .h files (bittypes,devioctl,ip6_misc,packet32,pcap,
|
||||
pcap-stdinc).h from the WinPCAP 3.0 developer's kit in the compiler's path
|
||||
3. Put the required .lib files (packet,wpcap).lib from the WinPCAP 3.0
|
||||
developer's kit in the linker's path
|
||||
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.
|
||||
6. Build it!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Linux, NetBSD, and OpenBSD 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.
|
||||
|
||||
Building on Linux, NetBSD, and OpenBSD:
|
||||
1. Get/install the libpcap package for your unix version. http://rpmfind.net
|
||||
might be a useful site for finding the linux variants.
|
||||
2. Use Make USE_NETWORK=1 if you want the network functionality.
|
||||
3. Build it!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
VAX simulator support:
|
||||
|
||||
An OpenVMS VAX v7.2 system with DECNET Phase IV, MultiNet 4.4a, and LAT 5.3 has
|
||||
been successfully run. Other testers have reported success booting NetBSD also.
|
||||
|
||||
|
||||
PDP11 simulator support:
|
||||
|
||||
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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Things planned for future releases:
|
||||
1. PDP-11 bootstrap/bootrom
|
||||
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
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Things which I need help with:
|
||||
1. Porting Sim_Ether packet driver to other host platforms, especially VMS.
|
||||
2. Information about Remote MOP processing
|
||||
3. VAX/PDP-11 hardware diagnotics image files and docs, to test XQ thoroughly.
|
||||
4. Feedback on operation with other VAX/PDP-11 OS's.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Please send all patches, questions, feedback, clarifications, and help to:
|
||||
dhittner AT northropgrumman DOT com
|
||||
|
||||
Thanks, and Enjoy!!
|
||||
Dave
|
||||
|
||||
|
||||
===============================================================================
|
||||
Change Log
|
||||
===============================================================================
|
||||
|
||||
05-Jun-03 Release:
|
||||
1. Added SET/SHOW XQ STATS
|
||||
2. Added SHOW XQ FILTERS
|
||||
3. Added ability to split received packet into multiple buffers
|
||||
4. Added explicit runt & giant packet processing
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
30-May-03 Release:
|
||||
1. Corrected bug in xq_setmac introduced in v3.0 (multiple people)
|
||||
2. Made XQ receive buffer allocation dynamic to reduce scp executable size
|
||||
3. Optimized some structs, removed legacy variables (Mark Pizzolato)
|
||||
4. Changed #ifdef WIN32 to _WIN32 for consistancy
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
06-May-03 Release:
|
||||
1. Added second XQ controller
|
||||
2. Added SIMH v3.0 compatibility
|
||||
3. Removed SET ADDRESS functionality
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
10-Apr-03 Release:
|
||||
1. Added preliminary support for RSTS/E
|
||||
2. Added PDP-11 bootrom load via CSR flags
|
||||
3. Support for SPARC linux (thanks to Mark Pizzolato)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
11-Mar-03 Release:
|
||||
1. Added support for RT-11 TCP/IP
|
||||
2. Corrected interrupts (thanks to Tom Evans and Bob Supnik)
|
||||
3. Moved change log to the bottom of the readme file, cleaned up document
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
16-Jan-03 Release:
|
||||
1. Added VMScluster support (thanks to Mark Pizzolato)
|
||||
2. Verified VAX remote boot functionality (>>>B XQA0)
|
||||
|
@ -12,176 +153,10 @@ This file contains information about the XQ/SIM_ETHER package.
|
|||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
GOLD Changes: (08-Nov-02)
|
||||
08-Nov-02 Release:
|
||||
1. Added USE_NETWORK conditional to Sim_Ether
|
||||
2. Fixed behaviour of SHOW XQ ETH if no devices exist
|
||||
3. Added OpenBSD support to Sim_Ether (courtesy of Federico Schwindt)
|
||||
4. Added ethX detection simplification (from Megan Gentry)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
BETA 5 Changes: (23-Oct-02)
|
||||
1. Added all_multicast and promiscuous mode support
|
||||
2. Finished DEQNA emulation
|
||||
3. Verified LAT functionality
|
||||
4. Added NXM (Non-eXistant Memory) protection (suggested by Robert Supnik)
|
||||
5. Added NetBSD support to Sim_Ether (courtesy of Jason Thorpe)
|
||||
6. Fixed write buffer overflow bug (discovered by Jason Thorpe)
|
||||
7. Fixed unattached device behavior (discovered by Patrick Caulfield)
|
||||
8. Extensive rewrite of this README
|
||||
9. Debugged sanity timer
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
BETA 4 Changes: (16-Oct-02)
|
||||
1. Added stub support for all_multicast and promiscuous modes
|
||||
2. Integrated with SIMH v2.10-0b1
|
||||
3. Added VAX network bootstrap support
|
||||
4. Added SET/SHOW XQ TYPE and SANITY commands
|
||||
5. Added stub support for DEQNA mode
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
BETA 3 Changes: (10-Oct-02)
|
||||
1. Fixed off-by-one bug in setup address processing
|
||||
2. Added rejection of multicast addresses to SET XQ MAC
|
||||
3. Added linux support to Sim_Ether (courtesy of Patrick Caulfield)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
BETA 2 Changes: (08-Oct-02)
|
||||
1. Integrated with SIMH v2.10-0p4
|
||||
2. Added floating vectors; this also fixes pdp11 emulation problem
|
||||
3. Cleaned up codebase; 100% of packet driver code moved to Sim_Ether
|
||||
4. Verified TCP/IP functionality
|
||||
5. Added Copyrights
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
BETA 1 Changes: (03-Oct-02)
|
||||
1. Moved most of packet driver functionality from XQ to Sim_Ether
|
||||
2. Verified DECNET functionality
|
||||
3. Added SET/SHOW MAC command
|
||||
4. Added SHOW ETH command
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
||||
See the last section of this document for XQ usage instructions.
|
||||
|
||||
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, and NetBSD.
|
||||
|
||||
Currently, 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).
|
||||
|
||||
If your ethernet card is plugged into a switch, the promiscuous mode setting
|
||||
should not cause much of a problem, since the switch will still filter out
|
||||
most of the undesirable traffic. You will only see "excessive" traffic if you
|
||||
are on a direct or hub(repeater) segment.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Windows notes:
|
||||
1. The Windows-specific code uses the WinPCAP 3.0 (or 2.3) package from
|
||||
http://winpcap.polito.it. This package for windows simulates the libpcap
|
||||
package that is freely available for unix systems.
|
||||
2. You must *install* WinPCAP.
|
||||
3. Note that WinPCAP DOES NOT support dual CPU environments.
|
||||
4. WinPCAP loops packet writes back into the read queue. This causes problems
|
||||
since the XQ controller is not expecting to read it's own packet. A fix
|
||||
to the packet read filter was added to reject packets from the current MAC,
|
||||
but this defeats DECNET's duplicate node number detection scheme. A more
|
||||
correct fix for WinPCAP will be explored as time allows.
|
||||
5. The first time the WinPCAP driver is used, it will be dynamically loaded,
|
||||
and the user must be an Administrator on the machine to do so. If you need
|
||||
to run as an unprivileged user, you must set the service to autostart. See
|
||||
the WinPCAP documentation for details on the static load workaround.
|
||||
|
||||
Building on Windows:
|
||||
1. Install WinPCAP 3.0.
|
||||
2. Get the required .h files (bittypes.h, devioctl.h, ip6_misc.h, packet32.h,
|
||||
pcap.h, pcap-stdinc.h) from the WinPCAP 3.0 developer's kit
|
||||
3. Get the required .lib files (packet.lib, wpcap.lib) from the WinPCAP 3.0
|
||||
developer's kit. If you're using Borland C++, use COFF2OMF to convert
|
||||
the .lib files into a format that can be used by the compiler.
|
||||
4. Define USE_NETWORK if you want the network functionality.
|
||||
5. Build it!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Linux, NetBSD, and OpenBSD notes:
|
||||
|
||||
1. You must run SIMH(scp) as root so that the ethernet card can be set into
|
||||
promiscuous mode by the driver. Alternative suggestions will be welcomed.
|
||||
|
||||
Building on Linux, NetBSD, and OpenBSD:
|
||||
1. Define USE_NETWORK if you want the network functionality.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
THE XQ/SIM_ETHER modules have been successfully tested on a Windows 2000 host,
|
||||
emulating an OpenVMS 7.2 VAX system with DECNET Phase IV, MultiNet 4.4a, and
|
||||
LAT 5.3.
|
||||
|
||||
Regression test criteria:
|
||||
1. VAX shows device correctly (passed)
|
||||
2. VMS boots successfully with new device emulation (passed)
|
||||
3. VMS initializes device correctly (passed)
|
||||
4. DECNET loads successfully (passed)
|
||||
5. DECNET line stays up (passed)
|
||||
6. SET HOST x.y:: works from SIMH to real DECNET machine (passed)
|
||||
7. SET HOST x.y:: works from real DECNET machine to SIMH (passed)
|
||||
8. DECNET copy works from SIMH to real DECNET machine (passed)
|
||||
9. DECNET copy works from real DECNET machine to SIMH (passed)
|
||||
10. MultiNet TCP/IP loads successfully (passed)
|
||||
11. Multinet TCP/IP initializes device successfully (passed)
|
||||
12. SET HOST/TELNET x.y.z.w works from SIMH to real VAX IP machine (passed)
|
||||
13. SET HOST/TELNET x.y.z.w works from real VAX IP machine to SIMH (passed)
|
||||
14. FTP GET from a real VAX IP machine (passed)
|
||||
15. LAT loads sucessfully (passed)
|
||||
16. SET HOST/LAT <nodename> works from SIMH to real VAX LAT machine (passed)
|
||||
17. SET HOST/LAT <nodename> works from real VAX LAT machine to SIMH (passed)
|
||||
18. SIMH node joins VMSCluster (passed)
|
||||
19. SIMH node mounts other VMSCluster disks (passed)
|
||||
20. SIMH node MSCP serves disks to other nodes (passed)
|
||||
21. SIMH node remote boots into VMScluster (>>>B XQAO) (passed)
|
||||
|
||||
The following are known to NOT work:
|
||||
1. PDP-11 using RSTS/E v10.1 (fails to enable device - needs bootrom support)
|
||||
|
||||
I have reports that the following work:
|
||||
1. PDP-11 using RSX
|
||||
2. VAX remote booting of NetBSD (via >>> B XQA0)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Things planned for future releases:
|
||||
1. Full MOP implementation
|
||||
2. PDP-11 bootstrap/bootrom
|
||||
3. DESQA support (if someone can get me the user manuals)
|
||||
4. DETQA support [DELQA-Turbo] (I have the manual)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Things which I need help with:
|
||||
1. Porting Sim_Ether packet driver to other platforms, especially VMS.
|
||||
2. Information about Remote MOP processing
|
||||
3. PDP-11 bootstrap code.
|
||||
4. VAX hardware diagnotics image file and docs, to test XQ thoroughly.
|
||||
5. Feedback on operation with other VAX OS's.
|
||||
6. Feedback on operation with PDP-11 OS's.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Please send all patches, questions, feedback, clarifications, and help to:
|
||||
dhittner AT northropgrumman DOT com
|
||||
|
||||
Thanks, and Enjoy!!
|
||||
Dave
|
||||
===============================================================================
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altair_cpu.c: MITS Altair Intel 8080 CPU simulator
|
||||
|
||||
Copyright (c) 1997, Charles E. Owen
|
||||
Copyright (c) 1997-2003, Charles E. Owen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -58,7 +58,7 @@
|
|||
|
||||
HALT instruction
|
||||
I/O error in I/O simulator
|
||||
Invalid OP code (If ITRAP is set on CPU)
|
||||
Invalid OP code (if ITRAP is set on CPU)
|
||||
|
||||
2. Interrupts.
|
||||
There are 8 possible levels of interrupt, and in effect they
|
||||
|
@ -1168,7 +1168,7 @@ t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0))
|
||||
return SCPE_ARG;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altair_defs.h: MITS Altair simulator definitions
|
||||
|
||||
Copyright (c) 1997, Charles E. Owen
|
||||
Copyright (c) 1997-2003, Charles E. Owen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -31,7 +31,7 @@
|
|||
#define MAXMEMSIZE 65536 /* max memory size */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define ADDRMASK (MAXMEMSIZE - 1) /* address mask */
|
||||
#define MEM_ADDR_OK(x) (x < MEMSIZE)
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
|
||||
/* Simulator stop codes */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altair_dsk.c: MITS Altair 88-DISK Simulator
|
||||
|
||||
Copyright (c) 1997, Charles E. Owen
|
||||
Copyright (c) 1997-2003, Charles E. Owen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -124,8 +124,6 @@ t_stat dsk_svc (UNIT *uptr);
|
|||
t_stat dsk_reset (DEVICE *dptr);
|
||||
void writebuf();
|
||||
|
||||
extern int32 sim_activate (UNIT *uptr, int32 interval);
|
||||
extern int32 sim_cancel (UNIT *uptr);
|
||||
extern int32 PCX;
|
||||
|
||||
/* Global data on status */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altair_sio: MITS Altair serial I/O card
|
||||
|
||||
Copyright (c) 1997, Charles E. Owen
|
||||
Copyright (c) 1997-2003, Charles E. Owen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -63,11 +63,6 @@ t_stat ptp_reset (DEVICE *dptr);
|
|||
|
||||
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
|
||||
|
||||
extern t_stat sim_activate (UNIT *uptr, int32 interval);
|
||||
extern t_stat sim_cancel (UNIT *uptr);
|
||||
extern t_stat sim_poll_kbd (void);
|
||||
extern t_stat sim_putchar (int32 out);
|
||||
|
||||
/* 2SIO Standard I/O Data Structures */
|
||||
|
||||
UNIT sio_unit = { UDATA (&sio_svc, 0, 0),
|
||||
|
@ -95,7 +90,7 @@ UNIT ptr_unit = { UDATA (&ptr_svc, UNIT_SEQ + UNIT_ATTABLE, 0),
|
|||
REG ptr_reg[] = {
|
||||
{ ORDATA (DATA, ptr_unit.buf, 8) },
|
||||
{ ORDATA (STAT, ptr_unit.u3, 8) },
|
||||
{ ORDATA (POS, ptr_unit.pos, 32) },
|
||||
{ ORDATA (POS, ptr_unit.pos, T_ADDR_W) },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE ptr_dev = {
|
||||
|
@ -110,7 +105,7 @@ UNIT ptp_unit = { UDATA (&ptp_svc, UNIT_SEQ + UNIT_ATTABLE, 0),
|
|||
REG ptp_reg[] = {
|
||||
{ ORDATA (DATA, ptp_unit.buf, 8) },
|
||||
{ ORDATA (STAT, ptp_unit.u3, 8) },
|
||||
{ ORDATA (POS, ptp_unit.pos, 32) },
|
||||
{ ORDATA (POS, ptp_unit.pos, T_ADDR_W) },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE ptp_dev = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altair_sys.c: MITS Altair system interface
|
||||
|
||||
Copyright (c) 1997, Charles E. Owen
|
||||
Copyright (c) 1997-2003, Charles E. Owen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -37,9 +37,6 @@ extern DEVICE ptp_dev;
|
|||
extern DEVICE lpt_dev;
|
||||
extern unsigned char M[];
|
||||
extern int32 saved_PC;
|
||||
extern char *get_glyph (char *cptr, char *gbuf, char term);
|
||||
extern unsigned int32 get_uint (char *cptr, int32 radix, unsigned int32 max,
|
||||
int32 *status);
|
||||
|
||||
/* SCP data structures
|
||||
|
||||
|
|
|
@ -3,31 +3,34 @@ Altair 8800 Simulator with Z80 support
|
|||
|
||||
0. Revision History
|
||||
|
||||
Original version of this document written by Charles E Owen
|
||||
- 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)
|
||||
- 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
|
||||
|
||||
|
||||
1. 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.
|
||||
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
|
||||
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.
|
||||
|
@ -35,8 +38,8 @@ adopted as an industry standard, and eventually became the IEE-696 Bus.
|
|||
|
||||
2. Hardware
|
||||
|
||||
We are simulating a fairly "loaded" Altair 8800 from about 1977,
|
||||
with the following configuration:
|
||||
We are simulating a fairly "loaded" Altair 8800 from about 1977, with the
|
||||
following configuration:
|
||||
|
||||
device simulates
|
||||
name(s)
|
||||
|
@ -52,13 +55,13 @@ with the following configuration:
|
|||
DSK MITS 88-DISK Floppy Disk controller with up
|
||||
to eight drives.
|
||||
|
||||
|
||||
2.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.
|
||||
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
|
||||
|
@ -76,10 +79,8 @@ a minimum of 24K.
|
|||
SET CPU 8K
|
||||
SET CPU 12K
|
||||
SET CPU 16K
|
||||
......
|
||||
...... (in 4K steps)
|
||||
SET CPU 64K All these set various CPU memory configurations.
|
||||
The 2K EPROM at the high end of memory is always
|
||||
present and will always boot.
|
||||
|
||||
SET CPU BANKED Enables the banked memory support. The simulated memory
|
||||
has eight banks with address range 0..'common' (see registers below)
|
||||
|
@ -110,15 +111,16 @@ a minimum of 24K.
|
|||
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 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.
|
||||
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:
|
||||
|
||||
|
@ -135,20 +137,20 @@ CPU Registers include the following:
|
|||
- = 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 (only on Z80)
|
||||
BC1 16 The alternate BC register (only on Z80)
|
||||
DE1 16 The alternate DE register (only on Z80)
|
||||
HL1 16 The alternate HL register (only on Z80)
|
||||
IX 16 The IX index register (only on Z80)
|
||||
IY 16 The IY index register (only on Z80)
|
||||
IFF 8 Interrupt flag (only on Z80, no effect)
|
||||
INT 8 Interrupt register (only on Z80, no effect)
|
||||
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
|
||||
|
@ -163,19 +165,24 @@ CPU Registers include the following:
|
|||
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.
|
||||
|
||||
|
||||
2.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.
|
||||
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.
|
||||
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:
|
||||
|
||||
|
@ -199,11 +206,13 @@ simple stream of 8-bit bytes.
|
|||
ATTACH SIO 23 Console IO goes via a Telnet connection on port 23
|
||||
DETACH SIO Console IO goes via the regular SIMH console
|
||||
|
||||
|
||||
2.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 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
|
||||
|
||||
|
@ -220,23 +229,23 @@ registers (see source code) which are primarily useful for debugging purposes.
|
|||
TIMH This is the address of the interrupt handler to call for a
|
||||
timer interrupt.
|
||||
|
||||
|
||||
2.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 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 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)
|
||||
|
@ -287,43 +296,46 @@ command "D HDTRACE 1". The default for "HDTRACE" is 0 (no trace).
|
|||
|
||||
3. 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
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
3.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.
|
||||
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
|
||||
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".
|
||||
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>.
|
||||
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
|
||||
|
@ -341,6 +353,8 @@ 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
|
||||
|
@ -349,13 +363,12 @@ 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 ; Elisa game in Basic
|
||||
EX8080 .COM 10K ; exercise 8080 instruction set
|
||||
EX8080 .MAC 48K ; source for EX8080.COM
|
||||
EX8080 .SUB 2K ; benchmark execution of EX8080.COM
|
||||
EXZ80 .COM 10K ; exercise Z80 instruction set
|
||||
EXZ80 .MAC 48K ; source for EXZ80.COM
|
||||
EXZ80 .SUB 2K ; benchmark execution of EXZ80.COM
|
||||
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
|
||||
|
@ -375,11 +388,14 @@ 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
|
||||
|
@ -397,15 +413,17 @@ 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
|
||||
|
||||
|
||||
3.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.
|
||||
|
||||
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
|
||||
|
@ -414,9 +432,9 @@ place the CP/M loader (LDR.COM) on the boot tracks of a disk.
|
|||
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.
|
||||
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
|
||||
|
@ -508,10 +526,9 @@ version supports four terminals available via Telnet. To boot:
|
|||
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).
|
||||
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
|
||||
|
@ -595,10 +612,10 @@ XREF .COM 16K ; cross reference utility
|
|||
XSUB .COM 2K ; for CP/M DO
|
||||
|
||||
|
||||
3.5 CP/M application software
|
||||
3.4 CP/M application software
|
||||
|
||||
There is also a small collection of sample application software containing
|
||||
the following items:
|
||||
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
|
||||
|
@ -616,16 +633,16 @@ 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
|
||||
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
|
||||
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
|
||||
|
@ -652,18 +669,21 @@ 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 ; compiles the sources (you can ignore any compiler
|
||||
errors)
|
||||
QUEEN .PRO 2K ; Prolog demo program n-queens problem
|
||||
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
|
||||
|
@ -674,7 +694,7 @@ XFORMAT .COM 2K
|
|||
XFORMAT .SPL 6K ; SPL source for XFORMAT.COM
|
||||
|
||||
|
||||
3.6 MITS Disk Extended BASIC Version 4.1
|
||||
3.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
|
||||
|
@ -702,11 +722,11 @@ ran under. To boot:
|
|||
[FILES]
|
||||
|
||||
|
||||
3.7 Altair DOS Version 1.0
|
||||
3.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:
|
||||
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
|
||||
|
@ -728,9 +748,10 @@ to CP/M. To boot:
|
|||
.[DIR 0]
|
||||
|
||||
|
||||
3.8 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).
|
||||
3.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
|
||||
|
@ -750,7 +771,7 @@ is to get the Switch Register right).
|
|||
OK
|
||||
|
||||
|
||||
3.9 Altair 8k Basic
|
||||
3.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
|
||||
|
@ -774,7 +795,8 @@ is to get the Switch Register right).
|
|||
OK
|
||||
|
||||
|
||||
3.10 Altair Basic 4.0
|
||||
3.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
|
||||
|
@ -794,7 +816,8 @@ is to get the Switch Register right).
|
|||
OK
|
||||
|
||||
|
||||
3.11 Altair Disk Extended Basic Version 300-5-C
|
||||
3.10 Altair Disk Extended Basic Version 300-5-C
|
||||
|
||||
This version of Basic was provided by Scott LaBombard. To execute use the
|
||||
following commands:
|
||||
|
||||
|
@ -818,6 +841,7 @@ is to get the Switch Register right).
|
|||
|
||||
|
||||
4. Special simulator features
|
||||
|
||||
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
|
||||
|
@ -827,8 +851,8 @@ 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.
|
||||
(this is the job of regular breakpoints). This feature has been implemented
|
||||
by using the typing facility of the SIMH breakpoints.
|
||||
|
||||
|
||||
5. Brief summary of all major changes to the original Altair simulator
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
/* altairZ80_defs.h: MITS Altair simulator definitions
|
||||
/* altairz80_defs.h: MITS Altair simulator definitions
|
||||
|
||||
Copyright (c) 2002, Peter Schorn
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
|||
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
|
||||
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.
|
||||
|
||||
|
@ -28,8 +28,7 @@
|
|||
|
||||
#include "sim_defs.h" /* simulator definitions */
|
||||
|
||||
/* Memory */
|
||||
#define MAXMEMSIZE 65536 /* max memory size */
|
||||
#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 */
|
||||
|
@ -45,19 +44,19 @@
|
|||
#define unitNoOffset1 0x37 /* LD A,<unitno> */
|
||||
#define unitNoOffset2 0xb4 /* LD a,80h | <unitno> */
|
||||
|
||||
#define UNIT_V_OPSTOP (UNIT_V_UF+0) /* Stop on Invalid OP? */
|
||||
#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 */
|
||||
#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_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_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_V_WARNROM (UNIT_V_UF+6) /* warn if ROM is written to */
|
||||
#define UNIT_WARNROM (1 << UNIT_V_WARNROM)
|
||||
|
||||
#define AddressFormat "[%04xh]"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairZ80_dsk.c: MITS Altair 88-DISK Simulator
|
||||
/* altairz80_dsk.c: MITS Altair 88-DISK Simulator
|
||||
|
||||
Copyright (c) 2002, Peter Schorn
|
||||
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"),
|
||||
|
@ -15,7 +15,7 @@
|
|||
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
|
||||
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.
|
||||
|
||||
|
@ -108,7 +108,6 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "altairz80_defs.h"
|
||||
|
||||
#define UNIT_V_DSKWLK (UNIT_V_UF + 0) /* write locked */
|
||||
|
@ -127,18 +126,18 @@
|
|||
#define TRACE_TRACK_STUCK 8
|
||||
#define NUM_OF_DSK_MASK (NUM_OF_DSK - 1)
|
||||
|
||||
int32 dsk10(int32 port, int32 io, int32 data);
|
||||
int32 dsk11(int32 port, int32 io, int32 data);
|
||||
int32 dsk12(int32 port, int32 io, int32 data);
|
||||
int32 dskseek(UNIT *xptr);
|
||||
t_stat dsk_boot(int32 unitno, DEVICE *dptr);
|
||||
t_stat dsk_reset(DEVICE *dptr);
|
||||
t_stat dsk_svc(UNIT *uptr);
|
||||
void writebuf(void);
|
||||
t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
void resetDSKWarningFlags(void);
|
||||
int32 hasVerbose(void);
|
||||
char* selectInOut(int32 io);
|
||||
int32 dsk10(const int32 port, const int32 io, const int32 data);
|
||||
int32 dsk11(const int32 port, const int32 io, const int32 data);
|
||||
int32 dsk12(const int32 port, const int32 io, const int32 data);
|
||||
static int32 dskseek(const UNIT *xptr);
|
||||
static t_stat dsk_boot(int32 unitno, DEVICE *dptr);
|
||||
static t_stat dsk_reset(DEVICE *dptr);
|
||||
static t_stat dsk_svc(UNIT *uptr);
|
||||
static void writebuf(void);
|
||||
static t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static void resetDSKWarningFlags(void);
|
||||
static int32 hasVerbose(void);
|
||||
static char* selectInOut(const int32 io);
|
||||
|
||||
extern int32 PCX;
|
||||
extern int32 saved_PC;
|
||||
|
@ -149,27 +148,27 @@ extern char messageBuffer[];
|
|||
extern int32 install_bootrom(void);
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
/* Global data on status */
|
||||
/* global data on status */
|
||||
|
||||
int32 cur_disk = NUM_OF_DSK; /* Currently selected drive (values are 0 .. NUM_OF_DSK)
|
||||
cur_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */
|
||||
int32 cur_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 cur_sect [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 cur_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 cur_flags [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8 tracks [NUM_OF_DSK] = { MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, MAX_TRACKS,
|
||||
static int32 current_disk = NUM_OF_DSK; /* currently selected drive (values are 0 .. NUM_OF_DSK)
|
||||
current_disk < NUM_OF_DSK implies that the corresponding disk is attached to a file */
|
||||
static int32 current_track [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 current_sector [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 current_byte [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 current_flag [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static uint8 tracks [NUM_OF_DSK] = { MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, MAX_TRACKS,
|
||||
MAX_TRACKS, MAX_TRACKS, MAX_TRACKS, MAX_TRACKS };
|
||||
int32 trace_flag = 0;
|
||||
int32 in9_count = 0;
|
||||
int32 in9_message = FALSE;
|
||||
int32 dirty = FALSE; /* TRUE when buffer has unwritten data in it */
|
||||
int32 warnLevelDSK = 3;
|
||||
int32 warnLock [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 warnAttached[NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int32 warnDSK10 = 0;
|
||||
int32 warnDSK11 = 0;
|
||||
int32 warnDSK12 = 0;
|
||||
int8 dskbuf[DSK_SECTSIZE]; /* Data Buffer */
|
||||
static int32 trace_flag = 0;
|
||||
static int32 in9_count = 0;
|
||||
static int32 in9_message = FALSE;
|
||||
static int32 dirty = FALSE; /* TRUE when buffer has unwritten data in it */
|
||||
static int32 warnLevelDSK = 3;
|
||||
static int32 warnLock [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 warnAttached [NUM_OF_DSK] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static int32 warnDSK10 = 0;
|
||||
static int32 warnDSK11 = 0;
|
||||
static int32 warnDSK12 = 0;
|
||||
static int8 dskbuf[DSK_SECTSIZE]; /* data Buffer */
|
||||
|
||||
/* Altair MITS modified BOOT EPROM, fits in upper 256 byte of memory */
|
||||
int32 bootrom[bootrom_size] = {
|
||||
|
@ -209,7 +208,7 @@ int32 bootrom[bootrom_size] = {
|
|||
|
||||
/* 88DSK Standard I/O Data Structures */
|
||||
|
||||
UNIT dsk_unit[] = {
|
||||
static UNIT dsk_unit[] = {
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) },
|
||||
|
@ -219,15 +218,27 @@ UNIT dsk_unit[] = {
|
|||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) },
|
||||
{ UDATA (&dsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, MAX_DSK_SIZE) } };
|
||||
|
||||
REG dsk_reg[] = {
|
||||
{ DRDATA (DISK, cur_disk, 4) },
|
||||
{ DRDATA (DSKWL, warnLevelDSK, 32) },
|
||||
{ ORDATA (TRACE, trace_flag, 8) },
|
||||
static REG dsk_reg[] = {
|
||||
{ DRDATA (DISK, current_disk, 4) },
|
||||
{ BRDATA (CURTRACK, current_track, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO },
|
||||
{ BRDATA (CURSECTOR, current_sector, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO },
|
||||
{ BRDATA (CURBYTE, current_byte, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO },
|
||||
{ BRDATA (CURFLAG, current_flag, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO },
|
||||
{ BRDATA (TRACKS, tracks, 10, 8, NUM_OF_DSK), REG_CIRC },
|
||||
{ DRDATA (IN9, in9_count, 4), REG_RO },
|
||||
{ ORDATA (TRACE, trace_flag, 8) },
|
||||
{ DRDATA (IN9COUNT, in9_count, 4), REG_RO },
|
||||
{ DRDATA (IN9MESSAGE, in9_message, 4), REG_RO },
|
||||
{ DRDATA (DIRTY, dirty, 4), REG_RO },
|
||||
{ DRDATA (DSKWL, warnLevelDSK, 32) },
|
||||
{ BRDATA (WARNLOCK, warnLock, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO },
|
||||
{ BRDATA (WARNATTACHED, warnAttached, 10, 32, NUM_OF_DSK), REG_CIRC + REG_RO },
|
||||
{ DRDATA (WARNDSK10, warnDSK10, 4), REG_RO },
|
||||
{ DRDATA (WARNDSK11, warnDSK11, 4), REG_RO },
|
||||
{ DRDATA (WARNDSK12, warnDSK12, 4), REG_RO },
|
||||
{ BRDATA (DISKBUFFER, dskbuf, 10, 8, DSK_SECTSIZE), REG_CIRC + REG_RO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB dsk_mod[] = {
|
||||
static MTAB dsk_mod[] = {
|
||||
{ UNIT_DSKWLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_DSKWLK, UNIT_DSKWLK, "write locked", "LOCKED", NULL },
|
||||
/* quiet, no warning messages */
|
||||
|
@ -240,9 +251,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 };
|
||||
&dsk_boot, NULL, NULL, NULL, 0, NULL, NULL };
|
||||
|
||||
void resetDSKWarningFlags(void) {
|
||||
static void resetDSKWarningFlags(void) {
|
||||
int32 i;
|
||||
for (i = 0; i < NUM_OF_DSK; i++) {
|
||||
warnLock[i] = 0;
|
||||
|
@ -253,13 +264,13 @@ void resetDSKWarningFlags(void) {
|
|||
warnDSK12 = 0;
|
||||
}
|
||||
|
||||
t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
static t_stat dsk_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
resetDSKWarningFlags();
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* returns TRUE iff there exists a disk with VERBOSE */
|
||||
int32 hasVerbose(void) {
|
||||
static int32 hasVerbose(void) {
|
||||
int32 i;
|
||||
for (i = 0; i < NUM_OF_DSK; i++) {
|
||||
if (((dsk_dev.units + i) -> flags) & UNIT_DSK_VERBOSE) {
|
||||
|
@ -269,23 +280,23 @@ int32 hasVerbose(void) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
char* selectInOut(int32 io) {
|
||||
static char* selectInOut(const int32 io) {
|
||||
return io == 0 ? "IN" : "OUT";
|
||||
}
|
||||
|
||||
/* Service routines to handle simulator functions */
|
||||
/* service routines to handle simulator functions */
|
||||
|
||||
/* service routine - actually gets char & places in buffer */
|
||||
|
||||
t_stat dsk_svc(UNIT *uptr) {
|
||||
static t_stat dsk_svc(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
/* reset routine */
|
||||
|
||||
t_stat dsk_reset(DEVICE *dptr) {
|
||||
static t_stat dsk_reset(DEVICE *dptr) {
|
||||
resetDSKWarningFlags();
|
||||
cur_disk = NUM_OF_DSK;
|
||||
current_disk = NUM_OF_DSK;
|
||||
trace_flag = 0;
|
||||
in9_count = 0;
|
||||
in9_message = FALSE;
|
||||
|
@ -295,7 +306,7 @@ t_stat dsk_reset(DEVICE *dptr) {
|
|||
/* The boot routine modifies the boot ROM in such a way that subsequently
|
||||
the specified disk is used for boot purposes.
|
||||
*/
|
||||
t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
|
||||
static t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
|
||||
if (cpu_unit.flags & (UNIT_ALTAIRROM | UNIT_BANKED)) {
|
||||
if (install_bootrom()) {
|
||||
printf("ALTAIR boot ROM installed.\n");
|
||||
|
@ -333,50 +344,50 @@ t_stat dsk_boot(int32 unitno, DEVICE *dptr) {
|
|||
simulation requirement that they are reversed in hardware.
|
||||
*/
|
||||
|
||||
int32 dsk10(int32 port, int32 io, int32 data) {
|
||||
int32 cur_flag;
|
||||
int32 dsk10(const int32 port, const int32 io, const int32 data) {
|
||||
int32 current_disk_flags;
|
||||
in9_count = 0;
|
||||
if (io == 0) { /* IN: return flags */
|
||||
if (cur_disk >= NUM_OF_DSK) {
|
||||
if (current_disk >= NUM_OF_DSK) {
|
||||
if (hasVerbose() && (warnDSK10 < warnLevelDSK)) {
|
||||
warnDSK10++;
|
||||
/*01*/ message1("Attempt of IN 0x08 on unattached disk - ignored.\n");
|
||||
}
|
||||
return 0xff; /* no drive selected - can do nothing */
|
||||
}
|
||||
return (~cur_flags[cur_disk]) & 0xff; /* Return the COMPLEMENT! */
|
||||
return (~current_flag[current_disk]) & 0xff; /* return the COMPLEMENT! */
|
||||
}
|
||||
|
||||
/* OUT: Controller set/reset/enable/disable */
|
||||
if (dirty) {/* implies that cur_disk < NUM_OF_DSK */
|
||||
if (dirty) { /* implies that current_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
if (trace_flag & TRACE_IN_OUT) {
|
||||
message2("OUT 0x08: %x\n", data);
|
||||
}
|
||||
cur_disk = data & NUM_OF_DSK_MASK; /* 0 <= cur_disk < NUM_OF_DSK */
|
||||
cur_flag = (dsk_dev.units + cur_disk) -> flags;
|
||||
if ((cur_flag & UNIT_ATT) == 0) { /* nothing attached? */
|
||||
if ( (cur_flag & UNIT_DSK_VERBOSE) && (warnAttached[cur_disk] < warnLevelDSK) ) {
|
||||
warnAttached[cur_disk]++;
|
||||
/*02*/message2("Attempt to select unattached DSK%d - ignored.\n", cur_disk);
|
||||
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);
|
||||
}
|
||||
cur_disk = NUM_OF_DSK;
|
||||
current_disk = NUM_OF_DSK;
|
||||
}
|
||||
else {
|
||||
cur_sect[cur_disk] = 0xff; /* reset internal counters */
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
cur_flags[cur_disk] = data & 0x80 ? 0 /* Disable drive */ :
|
||||
(cur_track[cur_disk] == 0 ? 0x5a /* Enable: head move true, track 0 if there */ :
|
||||
0x1a); /* Enable: head move true */
|
||||
current_sector[current_disk] = 0xff; /* reset internal counters */
|
||||
current_byte[current_disk] = 0xff;
|
||||
current_flag[current_disk] = data & 0x80 ? 0 /* disable drive */ :
|
||||
(current_track[current_disk] == 0 ? 0x5a /* enable: head move true, track 0 if there */ :
|
||||
0x1a);/* enable: head move true */
|
||||
}
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
|
||||
/* Disk Drive Status/Functions */
|
||||
|
||||
int32 dsk11(int32 port, int32 io, int32 data) {
|
||||
if (cur_disk >= NUM_OF_DSK) {
|
||||
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));
|
||||
|
@ -384,26 +395,26 @@ int32 dsk11(int32 port, int32 io, int32 data) {
|
|||
return 0; /* no drive selected - can do nothing */
|
||||
}
|
||||
|
||||
/* now cur_disk < NUM_OF_DSK */
|
||||
if (io == 0) { /* Read sector position */
|
||||
/* now current_disk < NUM_OF_DSK */
|
||||
if (io == 0) { /* read sector position */
|
||||
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", cur_disk);
|
||||
message2("Looping on sector find %d.\n", current_disk);
|
||||
}
|
||||
if (trace_flag & TRACE_IN_OUT) {
|
||||
message1("IN 0x09\n");
|
||||
}
|
||||
if (dirty) {/* implies that cur_disk < NUM_OF_DSK */
|
||||
if (dirty) {/* implies that current_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
if (cur_flags[cur_disk] & 0x04) { /* head loaded? */
|
||||
cur_sect[cur_disk]++;
|
||||
if (cur_sect[cur_disk] >= DSK_SECT) {
|
||||
cur_sect[cur_disk] = 0;
|
||||
if (current_flag[current_disk] & 0x04) { /* head loaded? */
|
||||
current_sector[current_disk]++;
|
||||
if (current_sector[current_disk] >= DSK_SECT) {
|
||||
current_sector[current_disk] = 0;
|
||||
}
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
return (((cur_sect[cur_disk] << 1) & 0x3e) /* return 'sector true' bit = 0 (true) */
|
||||
current_byte[current_disk] = 0xff;
|
||||
return (((current_sector[current_disk] << 1) & 0x3e) /* return 'sector true' bit = 0 (true) */
|
||||
| 0xc0); /* set on 'unused' bits */
|
||||
} else {
|
||||
return 0; /* head not loaded - return 0 */
|
||||
|
@ -411,83 +422,83 @@ int32 dsk11(int32 port, int32 io, int32 data) {
|
|||
}
|
||||
|
||||
in9_count = 0;
|
||||
/* Drive functions */
|
||||
/* drive functions */
|
||||
|
||||
if (trace_flag & TRACE_IN_OUT) {
|
||||
message2("OUT 0x09: %x\n", data);
|
||||
}
|
||||
if (data & 0x01) { /* Step head in */
|
||||
if (data & 0x01) { /* step head in */
|
||||
if (trace_flag & TRACE_TRACK_STUCK) {
|
||||
if (cur_track[cur_disk] == (tracks[cur_disk] - 1)) {
|
||||
message2("Unnecessary step in for disk %d\n", cur_disk);
|
||||
if (current_track[current_disk] == (tracks[current_disk] - 1)) {
|
||||
message2("Unnecessary step in for disk %d\n", current_disk);
|
||||
}
|
||||
}
|
||||
cur_track[cur_disk]++;
|
||||
if (cur_track[cur_disk] > (tracks[cur_disk] - 1)) {
|
||||
cur_track[cur_disk] = (tracks[cur_disk] - 1);
|
||||
current_track[current_disk]++;
|
||||
if (current_track[current_disk] > (tracks[current_disk] - 1)) {
|
||||
current_track[current_disk] = (tracks[current_disk] - 1);
|
||||
}
|
||||
if (dirty) { /* implies that cur_disk < NUM_OF_DSK */
|
||||
if (dirty) { /* implies that current_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
cur_sect[cur_disk] = 0xff;
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
current_sector[current_disk] = 0xff;
|
||||
current_byte[current_disk] = 0xff;
|
||||
}
|
||||
|
||||
if (data & 0x02) { /* Step head out */
|
||||
if (data & 0x02) { /* step head out */
|
||||
if (trace_flag & TRACE_TRACK_STUCK) {
|
||||
if (cur_track[cur_disk] == 0) {
|
||||
message2("Unnecessary step out for disk %d\n", cur_disk);
|
||||
if (current_track[current_disk] == 0) {
|
||||
message2("Unnecessary step out for disk %d\n", current_disk);
|
||||
}
|
||||
}
|
||||
cur_track[cur_disk]--;
|
||||
if (cur_track[cur_disk] < 0) {
|
||||
cur_track[cur_disk] = 0;
|
||||
cur_flags[cur_disk] |= 0x40; /* track 0 if there */
|
||||
current_track[current_disk]--;
|
||||
if (current_track[current_disk] < 0) {
|
||||
current_track[current_disk] = 0;
|
||||
current_flag[current_disk] |= 0x40; /* track 0 if there */
|
||||
}
|
||||
if (dirty) { /* implies that cur_disk < NUM_OF_DSK */
|
||||
if (dirty) { /* implies that current_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
cur_sect[cur_disk] = 0xff;
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
current_sector[current_disk] = 0xff;
|
||||
current_byte[current_disk] = 0xff;
|
||||
}
|
||||
|
||||
if (dirty) { /* implies that cur_disk < NUM_OF_DSK */
|
||||
if (dirty) { /* implies that current_disk < NUM_OF_DSK */
|
||||
writebuf();
|
||||
}
|
||||
|
||||
if (data & 0x04) { /* Head load */
|
||||
cur_flags[cur_disk] |= 0x04; /* turn on head loaded bit */
|
||||
cur_flags[cur_disk] |= 0x80; /* turn on 'read data available' */
|
||||
if (data & 0x04) { /* head load */
|
||||
current_flag[current_disk] |= 0x04; /* turn on head loaded bit */
|
||||
current_flag[current_disk] |= 0x80; /* turn on 'read data available' */
|
||||
}
|
||||
|
||||
if (data & 0x08) { /* Head Unload */
|
||||
cur_flags[cur_disk] &= 0xfb; /* turn off 'head loaded' bit */
|
||||
cur_flags[cur_disk] &= 0x7f; /* turn off 'read data available' */
|
||||
cur_sect[cur_disk] = 0xff;
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
if (data & 0x08) { /* head unload */
|
||||
current_flag[current_disk] &= 0xfb; /* turn off 'head loaded' bit */
|
||||
current_flag[current_disk] &= 0x7f; /* turn off 'read data available' */
|
||||
current_sector[current_disk] = 0xff;
|
||||
current_byte[current_disk] = 0xff;
|
||||
}
|
||||
|
||||
/* Interrupts & head current are ignored */
|
||||
/* interrupts & head current are ignored */
|
||||
|
||||
if (data & 0x80) { /* write sequence start */
|
||||
cur_byte[cur_disk] = 0;
|
||||
cur_flags[cur_disk] |= 0x01; /* enter new write data on */
|
||||
current_byte[current_disk] = 0;
|
||||
current_flag[current_disk] |= 0x01; /* enter new write data on */
|
||||
}
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
|
||||
/* Disk Data In/Out */
|
||||
|
||||
INLINE int32 dskseek(UNIT *xptr) {
|
||||
return fseek(xptr -> fileref, DSK_TRACSIZE * cur_track[cur_disk] +
|
||||
DSK_SECTSIZE * cur_sect[cur_disk], SEEK_SET);
|
||||
static INLINE int32 dskseek(const UNIT *xptr) {
|
||||
return fseek(xptr -> fileref, DSK_TRACSIZE * current_track[current_disk] +
|
||||
DSK_SECTSIZE * current_sector[current_disk], SEEK_SET);
|
||||
}
|
||||
|
||||
int32 dsk12(int32 port, int32 io, int32 data) {
|
||||
static int32 i;
|
||||
int32 dsk12(const int32 port, const int32 io, const int32 data) {
|
||||
int32 i;
|
||||
UNIT *uptr;
|
||||
|
||||
if (cur_disk >= NUM_OF_DSK) {
|
||||
if (current_disk >= NUM_OF_DSK) {
|
||||
if (hasVerbose() && (warnDSK12 < warnLevelDSK)) {
|
||||
warnDSK12++;
|
||||
/*04*/message2("Attempt of %s 0x0a on unattached disk - ignored.\n", selectInOut(io));
|
||||
|
@ -495,64 +506,64 @@ int32 dsk12(int32 port, int32 io, int32 data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* now cur_disk < NUM_OF_DSK */
|
||||
/* now current_disk < NUM_OF_DSK */
|
||||
in9_count = 0;
|
||||
uptr = dsk_dev.units + cur_disk;
|
||||
uptr = dsk_dev.units + current_disk;
|
||||
if (io == 0) {
|
||||
if (cur_byte[cur_disk] >= DSK_SECTSIZE) {
|
||||
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", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
message4("IN 0x0a (READ) D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||
}
|
||||
for (i = 0; i < DSK_SECTSIZE; i++) {
|
||||
dskbuf[i] = 0;
|
||||
}
|
||||
dskseek(uptr);
|
||||
fread(dskbuf, DSK_SECTSIZE, 1, uptr -> fileref);
|
||||
cur_byte[cur_disk] = 0;
|
||||
current_byte[current_disk] = 0;
|
||||
}
|
||||
return dskbuf[cur_byte[cur_disk]++] & 0xff;
|
||||
return dskbuf[current_byte[current_disk]++] & 0xff;
|
||||
}
|
||||
else {
|
||||
if (cur_byte[cur_disk] >= DSK_SECTSIZE) {
|
||||
writebuf(); /* from above we have that cur_disk < NUM_OF_DSK */
|
||||
if (current_byte[current_disk] >= DSK_SECTSIZE) {
|
||||
writebuf(); /* from above we have that current_disk < NUM_OF_DSK */
|
||||
}
|
||||
else {
|
||||
dirty = TRUE; /* this guarantees for the next call to writebuf that cur_disk < NUM_OF_DSK */
|
||||
dskbuf[cur_byte[cur_disk]++] = data & 0xff;
|
||||
dirty = TRUE; /* this guarantees for the next call to writebuf that current_disk < NUM_OF_DSK */
|
||||
dskbuf[current_byte[current_disk]++] = data & 0xff;
|
||||
}
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
}
|
||||
|
||||
/* Precondition: cur_disk < NUM_OF_DSK */
|
||||
void writebuf(void) {
|
||||
/* precondition: current_disk < NUM_OF_DSK */
|
||||
static void writebuf(void) {
|
||||
int32 i, rtn;
|
||||
UNIT *uptr;
|
||||
i = cur_byte[cur_disk]; /* null-fill rest of sector if any */
|
||||
i = current_byte[current_disk]; /* null-fill rest of sector if any */
|
||||
while (i < DSK_SECTSIZE) {
|
||||
dskbuf[i++] = 0;
|
||||
}
|
||||
uptr = dsk_dev.units + cur_disk;
|
||||
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", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
message4("OUT 0x0a (WRITE) D%d T%d S%d\n", current_disk, current_track[current_disk], current_sector[current_disk]);
|
||||
}
|
||||
if (dskseek(uptr)) {
|
||||
message4("fseek failed D%d T%d S%d\n", cur_disk, cur_track[cur_disk], cur_sect[cur_disk]);
|
||||
message4("fseek failed D%d T%d S%d\n", 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", cur_track[cur_disk], cur_sect[cur_disk], rtn);
|
||||
message4("fwrite failed T%d S%d Return=%d\n", current_track[current_disk], current_sector[current_disk], rtn);
|
||||
}
|
||||
}
|
||||
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[cur_disk] < warnLevelDSK) ) {
|
||||
else if ( ((uptr -> flags) & UNIT_DSK_VERBOSE) && (warnLock[current_disk] < warnLevelDSK) ) {
|
||||
/* write locked - print warning message if required */
|
||||
warnLock[cur_disk]++;
|
||||
warnLock[current_disk]++;
|
||||
/*05*/
|
||||
message2("Attempt to write to locked DSK%d - ignored.\n", cur_disk);
|
||||
message2("Attempt to write to locked DSK%d - ignored.\n", current_disk);
|
||||
}
|
||||
cur_flags[cur_disk] &= 0xfe; /* ENWD off */
|
||||
cur_byte[cur_disk] = 0xff;
|
||||
current_flag[current_disk] &= 0xfe; /* ENWD off */
|
||||
current_byte[current_disk] = 0xff;
|
||||
dirty = FALSE;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairZ80_sio: MITS Altair serial I/O card
|
||||
/* altairz80_sio: MITS Altair serial I/O card
|
||||
|
||||
Copyright (c) 2002, Peter Schorn
|
||||
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"),
|
||||
|
@ -15,7 +15,7 @@
|
|||
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
|
||||
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.
|
||||
|
||||
|
@ -49,7 +49,6 @@
|
|||
to the data port writes the character to the device.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "altairz80_defs.h"
|
||||
|
@ -77,35 +76,36 @@
|
|||
#define DELETE_CHAR 0x7f /* delete character */
|
||||
#define CONTROLZ_CHAR 0x1a /* control Z character */
|
||||
|
||||
void resetSIOWarningFlags(void);
|
||||
t_stat sio_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
t_stat sio_svc(UNIT *uptr);
|
||||
t_stat sio_reset(DEVICE *dptr);
|
||||
t_stat sio_attach(UNIT *uptr, char *cptr);
|
||||
t_stat sio_detach(UNIT *uptr);
|
||||
t_stat ptr_reset(DEVICE *dptr);
|
||||
t_stat ptp_reset(DEVICE *dptr);
|
||||
int32 nulldev (int32 port, int32 io, int32 data);
|
||||
int32 sr_dev (int32 port, int32 io, int32 data);
|
||||
int32 simh_dev(int32 port, int32 io, int32 data);
|
||||
int32 sio0d (int32 port, int32 io, int32 data);
|
||||
int32 sio0s (int32 port, int32 io, int32 data);
|
||||
int32 sio1d (int32 port, int32 io, int32 data);
|
||||
int32 sio1s (int32 port, int32 io, int32 data);
|
||||
void reset_sio_terminals(int32 useDefault);
|
||||
t_stat simh_dev_reset(DEVICE *dptr);
|
||||
t_stat simh_svc(UNIT *uptr);
|
||||
t_stat simh_dev_set_timeron(UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat simh_dev_set_timeroff(UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
int32 simh_in(void);
|
||||
int32 simh_out(int32 data);
|
||||
void attachCPM(UNIT *uptr);
|
||||
void setClockZSDOS(void);
|
||||
void setClockCPM3(void);
|
||||
time_t mkCPM3Origin(void);
|
||||
int32 toBCD(int32 x);
|
||||
int32 fromBCD(int32 x);
|
||||
static void resetSIOWarningFlags(void);
|
||||
static t_stat sio_set_verbose (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat simh_dev_set_timeron (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat simh_dev_set_timeroff (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
static t_stat sio_svc(UNIT *uptr);
|
||||
static t_stat sio_reset(DEVICE *dptr);
|
||||
static t_stat sio_attach(UNIT *uptr, char *cptr);
|
||||
static t_stat sio_detach(UNIT *uptr);
|
||||
static t_stat ptr_reset(DEVICE *dptr);
|
||||
static t_stat ptp_reset(DEVICE *dptr);
|
||||
int32 nulldev (const int32 port, const int32 io, const int32 data);
|
||||
int32 sr_dev (const int32 port, const int32 io, const int32 data);
|
||||
int32 simh_dev(const int32 port, const int32 io, const int32 data);
|
||||
int32 sio0d (const int32 port, const int32 io, const int32 data);
|
||||
int32 sio0s (const int32 port, const int32 io, const int32 data);
|
||||
int32 sio1d (const int32 port, const int32 io, const int32 data);
|
||||
int32 sio1s (const int32 port, const int32 io, const int32 data);
|
||||
static void reset_sio_terminals(const int32 useDefault);
|
||||
static t_stat simh_dev_reset(DEVICE *dptr);
|
||||
static t_stat simh_svc(UNIT *uptr);
|
||||
static int32 simh_in(const int32 port);
|
||||
static int32 simh_out(const int32 port, const int32 data);
|
||||
static void attachCPM(UNIT *uptr);
|
||||
static void setClockZSDOS(void);
|
||||
static void setClockCPM3(void);
|
||||
static time_t mkCPM3Origin(void);
|
||||
static int32 toBCD(const int32 x);
|
||||
static int32 fromBCD(const int32 x);
|
||||
void printMessage(void);
|
||||
static void warnNoRealTimeClock(void);
|
||||
|
||||
extern t_stat sim_activate(UNIT *uptr, int32 interval);
|
||||
extern t_stat sim_cancel(UNIT *uptr);
|
||||
|
@ -124,54 +124,50 @@ extern int32 common;
|
|||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
||||
extern UNIT cpu_unit;
|
||||
|
||||
/* the following variables define state for the SIMH pseudo device */
|
||||
/* SIMH pseudo device status registers */
|
||||
/* ZSDOS clock definitions */
|
||||
int32 ClockZSDOSDelta = 0; /* delta between real clock and Altair clock */
|
||||
int32 setClockZSDOSPos = 0; /* determines state for receiving address of parameter block */
|
||||
int32 setClockZSDOSAdr = 0; /* address in M of 6 byte parameter block for setting time */
|
||||
int32 getClockZSDOSPos = 0; /* determines state for sending clock information */
|
||||
static int32 ClockZSDOSDelta = 0; /* delta between real clock and Altair clock */
|
||||
static int32 setClockZSDOSPos = 0; /* determines state for receiving address of parameter block */
|
||||
static int32 setClockZSDOSAdr = 0; /* address in M of 6 byte parameter block for setting time */
|
||||
static int32 getClockZSDOSPos = 0; /* determines state for sending clock information */
|
||||
|
||||
/* CPM3 clock definitions */
|
||||
int32 ClockCPM3Delta = 0; /* delta between real clock and Altair clock */
|
||||
int32 setClockCPM3Pos = 0; /* determines state for receiving address of parameter block */
|
||||
int32 setClockCPM3Adr = 0; /* address in M of 5 byte parameter block for setting time */
|
||||
int32 getClockCPM3Pos = 0; /* determines state for sending clock information */
|
||||
int32 daysCPM3SinceOrg = 0; /* days since 1 Jan 1978 */
|
||||
static int32 ClockCPM3Delta = 0; /* delta between real clock and Altair clock */
|
||||
static int32 setClockCPM3Pos = 0; /* determines state for receiving address of parameter block */
|
||||
static int32 setClockCPM3Adr = 0; /* address in M of 5 byte parameter block for setting time */
|
||||
static int32 getClockCPM3Pos = 0; /* determines state for sending clock information */
|
||||
static int32 daysCPM3SinceOrg = 0; /* days since 1 Jan 1978 */
|
||||
|
||||
int32 timerDelta = 100; /* interrupt every 100 ms */
|
||||
int32 tmpTimerDelta;
|
||||
uint32 timeOfNextInterrupt;
|
||||
/* interrupt related */
|
||||
static uint32 timeOfNextInterrupt; /* time when next interrupt is scheduled */
|
||||
int32 timerInterrupt = FALSE; /* timer interrupt pending */
|
||||
int32 timerInterruptHandler = 0x0fc00;/* default address of interrupt handling routine */
|
||||
int32 tmpTimerInterruptHandler;
|
||||
int32 setTimerDeltaPos = 0; /* determines state for receiving timerDelta */
|
||||
int32 setTimerInterruptAdrPos = 0; /* determines state for receiving timerInterruptHandler */
|
||||
int32 markTimeSP = 0; /* stack pointer for timer stack */
|
||||
int32 versionPos = 0; /* determines state for sending device identifier */
|
||||
int32 lastCPMStatus = 0; /* result of last attachCPM command */
|
||||
int32 lastCommand = 0; /* most recent command processed on port 0xfeh */
|
||||
int32 getCommonPos = 0; /* determines state for sending the 'common' register */
|
||||
int32 warnLevelSIO = 3; /* display at most 'warnLevelSIO' times the same warning */
|
||||
int32 warnUnattachedPTP = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
static int32 setTimerInterruptAdrPos= 0; /* determines state for receiving timerInterruptHandler */
|
||||
static int32 timerDelta = 100; /* interrupt every 100 ms */
|
||||
static int32 setTimerDeltaPos = 0; /* determines state for receiving timerDelta */
|
||||
|
||||
/* stop watch and timer related */
|
||||
static uint32 stopWatchDelta = 0; /* stores elapsed time of stop watch */
|
||||
static int32 getStopWatchDeltaPos = 0; /* determines the state for receiving stopWatchDelta */
|
||||
static uint32 stopWatchNow = 0; /* stores starting time of stop watch */
|
||||
static int32 markTimeSP = 0; /* stack pointer for timer stack */
|
||||
|
||||
/* miscellaneous */
|
||||
static int32 versionPos = 0; /* determines state for sending device identifier */
|
||||
static int32 lastCPMStatus = 0; /* result of last attachCPM command */
|
||||
static int32 lastCommand = 0; /* most recent command processed on port 0xfeh */
|
||||
static int32 getCommonPos = 0; /* determines state for sending the 'common' register */
|
||||
|
||||
/* SIO status registers */
|
||||
static int32 warnLevelSIO = 3; /* display at most 'warnLevelSIO' times the same warning */
|
||||
static int32 warnUnattachedPTP = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
VERBOSE and output to PTP without an attached file */
|
||||
int32 warnUnattachedPTR = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
static int32 warnUnattachedPTR = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
VERBOSE and attempt to read from PTR without an attached file */
|
||||
int32 warnPTREOF = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
static int32 warnPTREOF = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
VERBOSE and attempt to read from PTR past EOF */
|
||||
int32 warnUnassignedPort = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
static int32 warnUnassignedPort = 0; /* display a warning message if < warnLevel and SIO set to
|
||||
VERBOSE andattempt to perform IN or OUT on an unassigned PORT */
|
||||
char messageBuffer[256];
|
||||
|
||||
void printMessage(void) {
|
||||
printf(messageBuffer);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, messageBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 2SIO Standard I/O Data Structures */
|
||||
struct sio_terminal {
|
||||
int32 data; /* data for this terminal */
|
||||
int32 status; /* status information for this terminal */
|
||||
|
@ -182,16 +178,17 @@ struct sio_terminal {
|
|||
|
||||
typedef struct sio_terminal SIO_TERMINAL;
|
||||
|
||||
SIO_TERMINAL sio_terminals[Terminals] = { {0, 0, 0x10, 0x11, 0x02},
|
||||
static SIO_TERMINAL sio_terminals[Terminals] =
|
||||
{ {0, 0, 0x10, 0x11, 0x02},
|
||||
{0, 0, 0x14, 0x15, 0x00},
|
||||
{0, 0, 0x16, 0x17, 0x00},
|
||||
{0, 0, 0x18, 0x19, 0x00} };
|
||||
TMLN TerminalLines[Terminals] = { {0} }; /* four terminals */
|
||||
TMXR altairTMXR = {Terminals, 0, 0 }; /* mux descriptor */
|
||||
static TMLN TerminalLines[Terminals] = { {0} }; /* four terminals */
|
||||
static TMXR altairTMXR = {Terminals, 0, 0 }; /* mux descriptor */
|
||||
|
||||
UNIT sio_unit = { UDATA (&sio_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
||||
static UNIT sio_unit = { UDATA (&sio_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG sio_reg[] = {
|
||||
static REG sio_reg[] = {
|
||||
{ HRDATA (DATA0, sio_terminals[0].data, 8) },
|
||||
{ HRDATA (STAT0, sio_terminals[0].status, 8) },
|
||||
{ HRDATA (DATA1, sio_terminals[1].data, 8) },
|
||||
|
@ -207,7 +204,7 @@ REG sio_reg[] = {
|
|||
{ DRDATA (WUPORT, warnUnassignedPort, 32) },
|
||||
{ NULL } };
|
||||
|
||||
MTAB sio_mod[] = {
|
||||
static MTAB sio_mod[] = {
|
||||
{ UNIT_ANSI, 0, "TTY", "TTY", NULL }, /* keep bit 8 as is for output */
|
||||
{ UNIT_ANSI, UNIT_ANSI, "ANSI", "ANSI", NULL }, /* set bit 8 to 0 before output */
|
||||
{ UNIT_UPPER, 0, "ALL", "ALL", NULL }, /* do not change case of input characters */
|
||||
|
@ -223,68 +220,80 @@ 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, &sio_attach, &sio_detach, NULL, 0, NULL, NULL };
|
||||
|
||||
UNIT ptr_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE + UNIT_ROABLE, 0),
|
||||
static UNIT ptr_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE + UNIT_ROABLE, 0),
|
||||
KBD_POLL_WAIT };
|
||||
|
||||
REG ptr_reg[] = {
|
||||
static REG ptr_reg[] = {
|
||||
{ HRDATA (DATA, ptr_unit.buf, 8) },
|
||||
{ HRDATA (STAT, ptr_unit.u3, 8) },
|
||||
{ DRDATA (POS, ptr_unit.pos, 31) },
|
||||
{ DRDATA (POS, ptr_unit.pos, 32) },
|
||||
{ NULL } };
|
||||
|
||||
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, 0, NULL, NULL };
|
||||
|
||||
UNIT ptp_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE, 0),
|
||||
static UNIT ptp_unit = { UDATA (NULL, UNIT_SEQ + UNIT_ATTABLE, 0),
|
||||
KBD_POLL_WAIT };
|
||||
|
||||
REG ptp_reg[] = {
|
||||
static REG ptp_reg[] = {
|
||||
{ HRDATA (DATA, ptp_unit.buf, 8) },
|
||||
{ HRDATA (STAT, ptp_unit.u3, 8) },
|
||||
{ DRDATA (POS, ptp_unit.pos, 31) },
|
||||
{ DRDATA (POS, ptp_unit.pos, 32) },
|
||||
{ NULL } };
|
||||
|
||||
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, 0, NULL, NULL };
|
||||
|
||||
/* Synthetic device SIMH for communication
|
||||
between Altair and SIMH environment using port 0xfe */
|
||||
UNIT simh_unit = { UDATA (&simh_svc, 0, 0), KBD_POLL_WAIT };
|
||||
static UNIT simh_unit = { UDATA (&simh_svc, 0, 0), KBD_POLL_WAIT };
|
||||
|
||||
REG simh_reg[] = {
|
||||
{ DRDATA (CZD, ClockZSDOSDelta, 31) },
|
||||
static REG simh_reg[] = {
|
||||
{ DRDATA (CZD, ClockZSDOSDelta, 32) },
|
||||
{ DRDATA (SCZP, setClockZSDOSPos, 8), REG_RO },
|
||||
{ HRDATA (SCZA, setClockZSDOSAdr, 16), REG_RO },
|
||||
{ DRDATA (GCZP, getClockZSDOSPos, 8), REG_RO },
|
||||
{ HRDATA (SCZA, setClockZSDOSAdr, 17), REG_RO },
|
||||
{ DRDATA (CC3D, ClockCPM3Delta, 31) },
|
||||
{ DRDATA (TIMD, timerDelta, 31) },
|
||||
|
||||
{ DRDATA (CC3D, ClockCPM3Delta, 32) },
|
||||
{ DRDATA (SC3DP, setClockCPM3Pos, 8), REG_RO },
|
||||
{ HRDATA (SC3DA, setClockCPM3Adr, 16), REG_RO },
|
||||
{ DRDATA (GC3DP, getClockCPM3Pos, 8), REG_RO },
|
||||
{ DRDATA (D3DO, daysCPM3SinceOrg, 32), REG_RO },
|
||||
|
||||
{ DRDATA (TOFNI, timeOfNextInterrupt, 32), REG_RO },
|
||||
{ DRDATA (TIMI, timerInterrupt, 3) },
|
||||
{ HRDATA (TIMH, timerInterruptHandler, 17) },
|
||||
{ DRDATA (SCC3P, setClockCPM3Pos, 8), REG_RO },
|
||||
{ DRDATA (GCC3P, getClockCPM3Pos, 8), REG_RO },
|
||||
{ HRDATA (SCC3A, setClockCPM3Adr, 17), REG_RO },
|
||||
{ HRDATA (TIMH, timerInterruptHandler, 16) },
|
||||
{ DRDATA (STIAP, setTimerInterruptAdrPos,8), REG_RO },
|
||||
{ DRDATA (TIMD, timerDelta, 32) },
|
||||
{ DRDATA (STDP, setTimerDeltaPos, 8), REG_RO },
|
||||
|
||||
{ DRDATA (STPDT, stopWatchDelta, 32), REG_RO },
|
||||
{ DRDATA (STPOS, getStopWatchDeltaPos, 8), REG_RO },
|
||||
{ DRDATA (STPNW, stopWatchNow, 32), REG_RO },
|
||||
{ DRDATA (MTSP, markTimeSP, 8), REG_RO },
|
||||
{ DRDATA (VP, versionPos, 8), REG_RO },
|
||||
{ DRDATA (CP, getCommonPos, 8), REG_RO },
|
||||
{ DRDATA (LC, lastCommand, 8), REG_RO },
|
||||
|
||||
{ DRDATA (VPOS, versionPos, 8), REG_RO },
|
||||
{ DRDATA (LCPMS, lastCPMStatus, 8), REG_RO },
|
||||
{ DRDATA (LCMD, lastCommand, 8), REG_RO },
|
||||
{ DRDATA (CPOS, getCommonPos, 8), REG_RO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB simh_mod[] = {
|
||||
static MTAB simh_mod[] = {
|
||||
/* quiet, no warning messages */
|
||||
{ UNIT_SIMH_VERBOSE, 0, "QUIET", "QUIET", NULL },
|
||||
/* verbose, display warning messages */
|
||||
{ UNIT_SIMH_VERBOSE, UNIT_SIMH_VERBOSE, "VERBOSE", "VERBOSE", NULL },
|
||||
/* quiet, no warning messages */
|
||||
/* timer generated interrupts are off */
|
||||
{ UNIT_SIMH_TIMERON, 0, "TIMEROFF", "TIMEROFF", &simh_dev_set_timeroff },
|
||||
/* verbose, display warning messages */
|
||||
/* timer generated interrupts are on */
|
||||
{ UNIT_SIMH_TIMERON, UNIT_SIMH_TIMERON, "TIMERON", "TIMERON", &simh_dev_set_timeron },
|
||||
{ 0 } };
|
||||
|
||||
|
@ -292,22 +301,30 @@ 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, 0, NULL, NULL };
|
||||
|
||||
char messageBuffer[256];
|
||||
|
||||
void resetSIOWarningFlags(void) {
|
||||
void printMessage(void) {
|
||||
printf(messageBuffer);
|
||||
if (sim_log) {
|
||||
fprintf(sim_log, messageBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void resetSIOWarningFlags(void) {
|
||||
warnUnattachedPTP = 0;
|
||||
warnUnattachedPTR = 0;
|
||||
warnPTREOF = 0;
|
||||
warnUnassignedPort = 0;
|
||||
}
|
||||
|
||||
t_stat sio_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
static t_stat sio_set_verbose(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
resetSIOWarningFlags();
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat sio_attach(UNIT *uptr, char *cptr) {
|
||||
static t_stat sio_attach(UNIT *uptr, char *cptr) {
|
||||
int32 i;
|
||||
for (i = 0; i < Terminals; i++) {
|
||||
altairTMXR.ldsc[i] = &TerminalLines[i];
|
||||
|
@ -316,25 +333,25 @@ t_stat sio_attach(UNIT *uptr, char *cptr) {
|
|||
return tmxr_attach(&altairTMXR, uptr, cptr); /* attach mux */
|
||||
}
|
||||
|
||||
void reset_sio_terminals(int32 useDefault) {
|
||||
static void reset_sio_terminals(const int32 useDefault) {
|
||||
int32 i;
|
||||
for (i = 0; i < Terminals; i++) {
|
||||
sio_terminals[i].status = useDefault ? sio_terminals[i].defaultStatus : 0; /* Status */
|
||||
sio_terminals[i].data = 0x00; /* Data */
|
||||
sio_terminals[i].status = useDefault ? sio_terminals[i].defaultStatus : 0; /* status */
|
||||
sio_terminals[i].data = 0x00; /* data */
|
||||
}
|
||||
}
|
||||
|
||||
/* Detach */
|
||||
t_stat sio_detach(UNIT *uptr) {
|
||||
/* detach */
|
||||
static t_stat sio_detach(UNIT *uptr) {
|
||||
reset_sio_terminals(TRUE);
|
||||
return tmxr_detach(&altairTMXR, uptr);
|
||||
}
|
||||
|
||||
/* Service routines to handle simulator functions */
|
||||
/* service routines to handle simulator functions */
|
||||
|
||||
/* service routine - actually gets char & places in buffer */
|
||||
|
||||
t_stat sio_svc(UNIT *uptr) {
|
||||
static t_stat sio_svc(UNIT *uptr) {
|
||||
int32 temp;
|
||||
|
||||
sim_activate(&sio_unit, sio_unit.wait); /* continue poll */
|
||||
|
@ -354,16 +371,16 @@ t_stat sio_svc(UNIT *uptr) {
|
|||
if ((temp = sim_poll_kbd()) < SCPE_KFLAG) {
|
||||
return temp; /* no char or error? */
|
||||
}
|
||||
sio_terminals[0].data = temp & 0xff; /* Save char */
|
||||
sio_terminals[0].status |= 0x01; /* Set status */
|
||||
sio_terminals[0].data = temp & 0xff; /* save character */
|
||||
sio_terminals[0].status |= 0x01; /* set status */
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Reset routines */
|
||||
/* reset routines */
|
||||
|
||||
t_stat sio_reset(DEVICE *dptr) {
|
||||
static t_stat sio_reset(DEVICE *dptr) {
|
||||
int32 i;
|
||||
resetSIOWarningFlags();
|
||||
if (sio_unit.flags & UNIT_ATT) {
|
||||
|
@ -381,7 +398,7 @@ t_stat sio_reset(DEVICE *dptr) {
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat ptr_reset(DEVICE *dptr) {
|
||||
static t_stat ptr_reset(DEVICE *dptr) {
|
||||
resetSIOWarningFlags();
|
||||
ptr_unit.buf = 0;
|
||||
ptr_unit.u3 = 0;
|
||||
|
@ -393,7 +410,7 @@ t_stat ptr_reset(DEVICE *dptr) {
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat ptp_reset(DEVICE *dptr) {
|
||||
static t_stat ptp_reset(DEVICE *dptr) {
|
||||
resetSIOWarningFlags();
|
||||
ptp_unit.buf = 0;
|
||||
ptp_unit.u3 = 0x02;
|
||||
|
@ -415,7 +432,7 @@ t_stat ptp_reset(DEVICE *dptr) {
|
|||
2) SIO not attached to a port (i.e. "regular" console I/O)
|
||||
*/
|
||||
|
||||
int32 sio0s(int32 port, int32 io, int32 data) {
|
||||
int32 sio0s(const int32 port, const int32 io, const int32 data) {
|
||||
int32 ti;
|
||||
for (ti = 0; ti < Terminals; ti++) {
|
||||
if (sio_terminals[ti].statusPort == port) {
|
||||
|
@ -449,7 +466,7 @@ int32 sio0s(int32 port, int32 io, int32 data) {
|
|||
}
|
||||
}
|
||||
|
||||
int32 sio0d(int32 port, int32 io, int32 data) {
|
||||
int32 sio0d(const int32 port, const int32 io, const int32 data) {
|
||||
int32 ti;
|
||||
for (ti = 0; ti < Terminals; ti++) {
|
||||
if (sio_terminals[ti].dataPort == port) {
|
||||
|
@ -474,22 +491,20 @@ int32 sio0d(int32 port, int32 io, int32 data) {
|
|||
return (sio_unit.flags & UNIT_UPPER) ? toupper(sio_terminals[ti].data) : sio_terminals[ti].data;
|
||||
}
|
||||
else { /* OUT */
|
||||
if (sio_unit.flags & UNIT_ANSI) {
|
||||
data &= 0x7f;
|
||||
}
|
||||
int32 d = sio_unit.flags & UNIT_ANSI ? data & 0x7f : data;
|
||||
if (sio_unit.flags & UNIT_ATT) {
|
||||
tmxr_putc_ln(altairTMXR.ldsc[ti], data);
|
||||
tmxr_putc_ln(altairTMXR.ldsc[ti], d);
|
||||
}
|
||||
else {
|
||||
sim_putchar(data);
|
||||
sim_putchar(d);
|
||||
}
|
||||
return 0; /* ignored since OUT */
|
||||
}
|
||||
}
|
||||
|
||||
/* Port 2 controls the PTR/PTP devices */
|
||||
/* port 2 controls the PTR/PTP devices */
|
||||
|
||||
int32 sio1s(int32 port, int32 io, int32 data) {
|
||||
int32 sio1s(const int32 port, const int32 io, const int32 data) {
|
||||
if (io == 0) {
|
||||
/* reset I bit iff PTR unit not attached or no more data available. */
|
||||
/* O bit is always set since write always possible. */
|
||||
|
@ -500,7 +515,7 @@ int32 sio1s(int32 port, int32 io, int32 data) {
|
|||
}
|
||||
return 0x02;
|
||||
}
|
||||
return (ptr_unit.u3 != 0) ? 0x02 : 0x03;
|
||||
return ptr_unit.u3 ? 0x02 : 0x03;
|
||||
}
|
||||
else { /* OUT */
|
||||
if (data == 0x03) {
|
||||
|
@ -515,7 +530,7 @@ int32 sio1s(int32 port, int32 io, int32 data) {
|
|||
}
|
||||
}
|
||||
|
||||
int32 sio1d(int32 port, int32 io, int32 data) {
|
||||
int32 sio1d(const int32 port, const int32 io, const int32 data) {
|
||||
int32 temp;
|
||||
if (io == 0) { /* IN */
|
||||
if (ptr_unit.u3) { /* no more data available */
|
||||
|
@ -552,7 +567,7 @@ int32 sio1d(int32 port, int32 io, int32 data) {
|
|||
}
|
||||
}
|
||||
|
||||
int32 nulldev(int32 port, int32 io, int32 data) {
|
||||
int32 nulldev(const int32 port, const int32 io, const int32 data) {
|
||||
if ((sio_unit.flags & UNIT_SIO_VERBOSE) && (warnUnassignedPort < warnLevelSIO)) {
|
||||
warnUnassignedPort++;
|
||||
if (io == 0) {
|
||||
|
@ -565,20 +580,20 @@ int32 nulldev(int32 port, int32 io, int32 data) {
|
|||
return io == 0 ? 0xff : 0;
|
||||
}
|
||||
|
||||
int32 sr_dev(int32 port, int32 io, int32 data) {
|
||||
int32 sr_dev(const int32 port, const int32 io, const int32 data) {
|
||||
return io == 0 ? SR : 0;
|
||||
}
|
||||
|
||||
int32 toBCD(int32 x) {
|
||||
static int32 toBCD(const int32 x) {
|
||||
return (x / 10) * 16 + (x % 10);
|
||||
}
|
||||
|
||||
int32 fromBCD(int32 x) {
|
||||
static int32 fromBCD(const int32 x) {
|
||||
return 10 * ((0xf0 & x) >> 4) + (0x0f & x);
|
||||
}
|
||||
|
||||
/* Z80 or 8080 programs communicate with the SIMH pseudo device via port 0xfe.
|
||||
The principles are as follows:
|
||||
The following principles apply:
|
||||
|
||||
1) For commands that do not require parameters and do not return results
|
||||
ld a,<cmd>
|
||||
|
@ -610,38 +625,43 @@ int32 fromBCD(int32 x) {
|
|||
|
||||
*/
|
||||
|
||||
#define splimit 10
|
||||
#define printTimeCmd 0 /* print the current time in milliseconds */
|
||||
#define startTimerCmd 1 /* start a new timer on the top of the timer stack */
|
||||
#define stopTimerCmd 2 /* stop timer on top of timer stack and show time difference */
|
||||
#define resetPTRCmd 3 /* reset the PTR device */
|
||||
#define attachPTRCmd 4 /* attach the PTR device */
|
||||
#define detachPTRCmd 5 /* detach the PTR device */
|
||||
#define getSIMHVersionCMD 6 /* get the current version of the SIMH pseudo device */
|
||||
#define getClockZSDOSCmd 7 /* get the current time in ZSDOS format */
|
||||
#define setClockZSDOSCmd 8 /* set the current time in ZSDOS format */
|
||||
#define getClockCPM3Cmd 9 /* get the current time in CP/M 3 format */
|
||||
#define setClockCPM3Cmd 10 /* set the current time in CP/M 3 format */
|
||||
#define getBankSelectCmd 11 /* get the selected bank */
|
||||
#define setBankSelectCmd 12 /* set the selected bank */
|
||||
#define getCommonCmd 13 /* get the base address of the common memory segment */
|
||||
#define resetSIMHInterfaceCmd 14 /* reset the SIMH pseudo device */
|
||||
#define showTimerCmd 15 /* show time difference to timer on top of stack */
|
||||
#define attachPTPCmd 16 /* attach PTP to the file with name at beginning of CP/M command line */
|
||||
#define detachPTPCmd 17 /* detach PTP */
|
||||
#define hasBankedMemoryCmd 18 /* determines whether machine has banked memory */
|
||||
#define setZ80CPUCmd 19 /* set the CPU to a Z80 */
|
||||
#define set8080CPUCmd 20 /* set the CPU to an 8080 */
|
||||
#define startTimerInterruptsCmd 21 /* statr timer interrupts */
|
||||
#define stopTimerInterruptsCmd 22 /* stop timer interrupts */
|
||||
#define setTimerDeltaCmd 23 /* set the timer interval in which interrupts occur */
|
||||
#define setTimerInterruptAdrCmd 24 /* set the address to call by timer interrupts */
|
||||
#define cpmCommandLineLength 128
|
||||
struct tm *currentTime = NULL;
|
||||
uint32 markTime[splimit];
|
||||
char version[] = "SIMH002";
|
||||
enum simhPseudoDeviceCommands { /* do not change order or remove commands, add only at the end */
|
||||
printTimeCmd, /* 0 print the current time in milliseconds */
|
||||
startTimerCmd, /* 1 start a new timer on the top of the timer stack */
|
||||
stopTimerCmd, /* 2 stop timer on top of timer stack and show time difference */
|
||||
resetPTRCmd, /* 3 reset the PTR device */
|
||||
attachPTRCmd, /* 4 attach the PTR device */
|
||||
detachPTRCmd, /* 5 detach the PTR device */
|
||||
getSIMHVersionCmd, /* 6 get the current version of the SIMH pseudo device */
|
||||
getClockZSDOSCmd, /* 7 get the current time in ZSDOS format */
|
||||
setClockZSDOSCmd, /* 8 set the current time in ZSDOS format */
|
||||
getClockCPM3Cmd, /* 9 get the current time in CP/M 3 format */
|
||||
setClockCPM3Cmd, /* 10 set the current time in CP/M 3 format */
|
||||
getBankSelectCmd, /* 11 get the selected bank */
|
||||
setBankSelectCmd, /* 12 set the selected bank */
|
||||
getCommonCmd, /* 13 get the base address of the common memory segment */
|
||||
resetSIMHInterfaceCmd, /* 14 reset the SIMH pseudo device */
|
||||
showTimerCmd, /* 15 show time difference to timer on top of stack */
|
||||
attachPTPCmd, /* 16 attach PTP to the file with name at beginning of CP/M command line*/
|
||||
detachPTPCmd, /* 17 detach PTP */
|
||||
hasBankedMemoryCmd, /* 18 determines whether machine has banked memory */
|
||||
setZ80CPUCmd, /* 19 set the CPU to a Z80 */
|
||||
set8080CPUCmd, /* 20 set the CPU to an 8080 */
|
||||
startTimerInterruptsCmd,/* 21 start timer interrupts */
|
||||
stopTimerInterruptsCmd, /* 22 stop timer interrupts */
|
||||
setTimerDeltaCmd, /* 23 set the timer interval in which interrupts occur */
|
||||
setTimerInterruptAdrCmd,/* 24 set the address to call by timer interrupts */
|
||||
resetStopWatchCmd, /* 25 reset the millisecond stop watch */
|
||||
readStopWatchCmd /* 26 read the millisecond stop watch */
|
||||
};
|
||||
|
||||
t_stat simh_dev_reset(DEVICE *dptr) {
|
||||
#define cpmCommandLineLength 128
|
||||
#define splimit 10 /* stack depth of timer stack */
|
||||
static uint32 markTime[splimit]; /* timer stack */
|
||||
static struct tm *currentTime = NULL;
|
||||
static char version[] = "SIMH002";
|
||||
|
||||
static t_stat simh_dev_reset(DEVICE *dptr) {
|
||||
currentTime = NULL;
|
||||
ClockZSDOSDelta = 0;
|
||||
setClockZSDOSPos = 0;
|
||||
|
@ -649,6 +669,7 @@ t_stat simh_dev_reset(DEVICE *dptr) {
|
|||
ClockCPM3Delta = 0;
|
||||
setClockCPM3Pos = 0;
|
||||
getClockCPM3Pos = 0;
|
||||
getStopWatchDeltaPos = 0;
|
||||
getCommonPos = 0;
|
||||
setTimerDeltaPos = 0;
|
||||
setTimerInterruptAdrPos = 0;
|
||||
|
@ -663,24 +684,30 @@ t_stat simh_dev_reset(DEVICE *dptr) {
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat simh_dev_set_timeron(UNIT *uptr, int32 val, char *cptr, void *desc) {
|
||||
static void warnNoRealTimeClock(void) {
|
||||
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
||||
printf("Sorry - no real time clock available.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static t_stat simh_dev_set_timeron(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
if (rtc_avail) {
|
||||
timeOfNextInterrupt = sim_os_msec() + timerDelta;
|
||||
return sim_activate(&simh_unit, simh_unit.wait); /* activate unit */
|
||||
}
|
||||
else {
|
||||
printf("Sorry - no real time clock available.\n");
|
||||
warnNoRealTimeClock();
|
||||
return SCPE_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
t_stat simh_dev_set_timeroff(UNIT *uptr, int32 val, char *cptr, void *desc) {
|
||||
static t_stat simh_dev_set_timeroff(UNIT *uptr, int32 value, char *cptr, void *desc) {
|
||||
timerInterrupt = FALSE;
|
||||
sim_cancel(&simh_unit);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat simh_svc(UNIT *uptr) {
|
||||
static t_stat simh_svc(UNIT *uptr) {
|
||||
uint32 n = sim_os_msec();
|
||||
if (n >= timeOfNextInterrupt) {
|
||||
timerInterrupt = TRUE;
|
||||
|
@ -695,8 +722,8 @@ t_stat simh_svc(UNIT *uptr) {
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* The CP/M commandline is used as the name of a file and UNIT* uptr is attached to it */
|
||||
void attachCPM(UNIT *uptr) {
|
||||
/* The CP/M commandline is used as the name of a file and UNIT* uptr is attached to it. */
|
||||
static void attachCPM(UNIT *uptr) {
|
||||
char cpmCommandLine[cpmCommandLineLength];
|
||||
uint32 i, len = (GetBYTEWrapper(0x80) & 0x7f) - 1; /* 0x80 contains length of commandline, discard first char */
|
||||
for (i = 0; i < len; i++) {
|
||||
|
@ -716,7 +743,7 @@ void attachCPM(UNIT *uptr) {
|
|||
}
|
||||
|
||||
/* setClockZSDOSAdr points to 6 byte block in M: YY MM DD HH MM SS in BCD notation */
|
||||
void setClockZSDOS(void) {
|
||||
static void setClockZSDOS(void) {
|
||||
struct tm newTime;
|
||||
int32 year = fromBCD(GetBYTEWrapper(setClockZSDOSAdr));
|
||||
newTime.tm_year = year < 50 ? year + 100 : year;
|
||||
|
@ -731,7 +758,7 @@ void setClockZSDOS(void) {
|
|||
#define secondsPerMinute 60
|
||||
#define secondsPerHour (60 * secondsPerMinute)
|
||||
#define secondsPerDay (24 * secondsPerHour)
|
||||
time_t mkCPM3Origin(void) {
|
||||
static time_t mkCPM3Origin(void) {
|
||||
struct tm date;
|
||||
date.tm_year = 77;
|
||||
date.tm_mon = 11;
|
||||
|
@ -747,7 +774,7 @@ time_t mkCPM3Origin(void) {
|
|||
2 BCD byte: HH
|
||||
3 BCD byte: MM
|
||||
4 BCD byte: SS */
|
||||
void setClockCPM3(void) {
|
||||
static void setClockCPM3(void) {
|
||||
ClockCPM3Delta = mkCPM3Origin() +
|
||||
(GetBYTEWrapper(setClockCPM3Adr) + GetBYTEWrapper(setClockCPM3Adr + 1) * 256) * secondsPerDay +
|
||||
fromBCD(GetBYTEWrapper(setClockCPM3Adr + 2)) * secondsPerHour +
|
||||
|
@ -755,12 +782,13 @@ void setClockCPM3(void) {
|
|||
fromBCD(GetBYTEWrapper(setClockCPM3Adr + 4)) - time(NULL);
|
||||
}
|
||||
|
||||
int32 simh_in(void) {
|
||||
static int32 simh_in(const int32 port) {
|
||||
int32 result;
|
||||
switch(lastCommand) {
|
||||
case attachPTRCmd:
|
||||
case attachPTPCmd:
|
||||
result = lastCPMStatus;
|
||||
lastCommand = 0;
|
||||
break;
|
||||
case getClockZSDOSCmd:
|
||||
if (currentTime) {
|
||||
|
@ -768,40 +796,67 @@ int32 simh_in(void) {
|
|||
case 0:
|
||||
result = toBCD(currentTime -> tm_year > 99 ?
|
||||
currentTime -> tm_year - 100 : currentTime -> tm_year);
|
||||
getClockZSDOSPos = 1;
|
||||
break;
|
||||
case 1:
|
||||
result = toBCD(currentTime -> tm_mon + 1);
|
||||
getClockZSDOSPos = 2;
|
||||
break;
|
||||
case 2:
|
||||
result = toBCD(currentTime -> tm_mday);
|
||||
getClockZSDOSPos = 3;
|
||||
break;
|
||||
case 3:
|
||||
result = toBCD(currentTime -> tm_hour);
|
||||
getClockZSDOSPos = 4;
|
||||
break;
|
||||
case 4:
|
||||
result = toBCD(currentTime -> tm_min);
|
||||
getClockZSDOSPos = 5;
|
||||
break;
|
||||
case 5:
|
||||
result = toBCD(currentTime -> tm_sec);
|
||||
getClockZSDOSPos = lastCommand = 0;
|
||||
break;
|
||||
case 1: result = toBCD(currentTime -> tm_mon + 1); break;
|
||||
case 2: result = toBCD(currentTime -> tm_mday); break;
|
||||
case 3: result = toBCD(currentTime -> tm_hour); break;
|
||||
case 4: result = toBCD(currentTime -> tm_min); break;
|
||||
case 5: result = toBCD(currentTime -> tm_sec); break;
|
||||
default: result = 0;
|
||||
}
|
||||
getClockZSDOSPos++;
|
||||
}
|
||||
else {
|
||||
result = 0;
|
||||
result = getClockZSDOSPos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
case getClockCPM3Cmd:
|
||||
if (currentTime) {
|
||||
switch(getClockCPM3Pos) {
|
||||
case 0: result = daysCPM3SinceOrg & 0xff; break;
|
||||
case 1: result = (daysCPM3SinceOrg >> 8) & 0xff; break;
|
||||
case 2: result = toBCD(currentTime -> tm_hour); break;
|
||||
case 3: result = toBCD(currentTime -> tm_min); break;
|
||||
case 4: result = toBCD(currentTime -> tm_sec); break;
|
||||
default: result = 0;
|
||||
case 0:
|
||||
result = daysCPM3SinceOrg & 0xff;
|
||||
getClockCPM3Pos = 1;
|
||||
break;
|
||||
case 1:
|
||||
result = (daysCPM3SinceOrg >> 8) & 0xff;
|
||||
getClockCPM3Pos = 2;
|
||||
break;
|
||||
case 2:
|
||||
result = toBCD(currentTime -> tm_hour);
|
||||
getClockCPM3Pos = 3;
|
||||
break;
|
||||
case 3:
|
||||
result = toBCD(currentTime -> tm_min);
|
||||
getClockCPM3Pos = 4;
|
||||
break;
|
||||
case 4:
|
||||
result = toBCD(currentTime -> tm_sec);
|
||||
getClockCPM3Pos = lastCommand = 0;
|
||||
break;
|
||||
}
|
||||
getClockCPM3Pos++;
|
||||
}
|
||||
else {
|
||||
result = 0;
|
||||
result = getClockCPM3Pos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
case getSIMHVersionCMD:
|
||||
case getSIMHVersionCmd:
|
||||
result = version[versionPos++];
|
||||
if (result == 0) {
|
||||
versionPos = 0;
|
||||
versionPos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
case getBankSelectCmd:
|
||||
|
@ -814,6 +869,7 @@ int32 simh_in(void) {
|
|||
message1("Get selected bank ignored for non-banked memory.");
|
||||
}
|
||||
}
|
||||
lastCommand = 0;
|
||||
break;
|
||||
case getCommonCmd:
|
||||
if (getCommonPos == 0) {
|
||||
|
@ -822,48 +878,56 @@ int32 simh_in(void) {
|
|||
}
|
||||
else {
|
||||
result = (common >> 8) & 0xff;
|
||||
getCommonPos = 0;
|
||||
getCommonPos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
case hasBankedMemoryCmd:
|
||||
result = cpu_unit.flags & UNIT_BANKED ? MAXBANKS : 0;
|
||||
lastCommand = 0;
|
||||
break;
|
||||
case readStopWatchCmd:
|
||||
if (getStopWatchDeltaPos == 0) {
|
||||
result = stopWatchDelta & 0xff;
|
||||
getStopWatchDeltaPos = 1;
|
||||
}
|
||||
else {
|
||||
result = (stopWatchDelta >> 8) & 0xff;
|
||||
getStopWatchDeltaPos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
||||
message2("Unnecessary IN from SIMH pseudo device on port %03xh ignored.\n",
|
||||
port);
|
||||
}
|
||||
result = lastCommand = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int32 simh_out(int32 data) {
|
||||
uint32 delta;
|
||||
static int32 simh_out(const int32 port, const int32 data) {
|
||||
time_t now;
|
||||
switch(lastCommand) {
|
||||
case setClockZSDOSCmd:
|
||||
switch(setClockZSDOSPos) {
|
||||
case 0:
|
||||
if (setClockZSDOSPos == 0) {
|
||||
setClockZSDOSAdr = data;
|
||||
setClockZSDOSPos++;
|
||||
break;
|
||||
case 1:
|
||||
setClockZSDOSAdr += (data << 8);
|
||||
setClockZSDOSPos = 1;
|
||||
}
|
||||
else {
|
||||
setClockZSDOSAdr |= (data << 8);
|
||||
setClockZSDOS();
|
||||
lastCommand = 0;
|
||||
break;
|
||||
default:;
|
||||
setClockZSDOSPos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
case setClockCPM3Cmd:
|
||||
switch(setClockCPM3Pos) {
|
||||
case 0:
|
||||
if (setClockCPM3Pos == 0) {
|
||||
setClockCPM3Adr = data;
|
||||
setClockCPM3Pos++;
|
||||
break;
|
||||
case 1:
|
||||
setClockCPM3Adr += (data << 8);
|
||||
setClockCPM3Pos = 1;
|
||||
}
|
||||
else {
|
||||
setClockCPM3Adr |= (data << 8);
|
||||
setClockCPM3();
|
||||
lastCommand = 0;
|
||||
break;
|
||||
default:;
|
||||
setClockCPM3Pos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
case setBankSelectCmd:
|
||||
|
@ -876,29 +940,23 @@ int32 simh_out(int32 data) {
|
|||
lastCommand = 0;
|
||||
break;
|
||||
case setTimerDeltaCmd:
|
||||
switch(setTimerDeltaPos) {
|
||||
case 0:
|
||||
tmpTimerDelta = data;
|
||||
setTimerDeltaPos++;
|
||||
break;
|
||||
case 1:
|
||||
timerDelta = tmpTimerDelta + (data << 8);
|
||||
lastCommand = 0;
|
||||
break;
|
||||
default:;
|
||||
if (setTimerDeltaPos == 0) {
|
||||
timerDelta = data;
|
||||
setTimerDeltaPos = 1;
|
||||
}
|
||||
else {
|
||||
timerDelta |= (data << 8);
|
||||
setTimerDeltaPos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
case setTimerInterruptAdrCmd:
|
||||
switch(setTimerInterruptAdrPos) {
|
||||
case 0:
|
||||
tmpTimerInterruptHandler = data;
|
||||
setTimerInterruptAdrPos++;
|
||||
break;
|
||||
case 1:
|
||||
timerInterruptHandler = tmpTimerInterruptHandler + (data << 8);
|
||||
lastCommand = 0;
|
||||
break;
|
||||
default:;
|
||||
if (setTimerInterruptAdrPos == 0) {
|
||||
timerInterruptHandler = data;
|
||||
setTimerInterruptAdrPos = 1;
|
||||
}
|
||||
else {
|
||||
timerInterruptHandler |= (data << 8);
|
||||
setTimerInterruptAdrPos = lastCommand = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -908,6 +966,9 @@ int32 simh_out(int32 data) {
|
|||
if (rtc_avail) {
|
||||
message2("Current time in milliseconds = %d.\n", sim_os_msec());
|
||||
}
|
||||
else {
|
||||
warnNoRealTimeClock();
|
||||
}
|
||||
break;
|
||||
case startTimerCmd: /* create a new timer on top of stack */
|
||||
if (rtc_avail) {
|
||||
|
@ -918,17 +979,23 @@ int32 simh_out(int32 data) {
|
|||
message1("Timer stack overflow.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
warnNoRealTimeClock();
|
||||
}
|
||||
break;
|
||||
case stopTimerCmd: /* stop timer on top of stack and show time difference */
|
||||
if (rtc_avail) {
|
||||
if (markTimeSP > 0) {
|
||||
delta = sim_os_msec() - markTime[--markTimeSP];
|
||||
uint32 delta = sim_os_msec() - markTime[--markTimeSP];
|
||||
message2("Timer stopped. Elapsed time in milliseconds = %d.\n", delta);
|
||||
}
|
||||
else {
|
||||
message1("No timer active.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
warnNoRealTimeClock();
|
||||
}
|
||||
break;
|
||||
case resetPTRCmd: /* reset ptr device */
|
||||
ptr_reset(NULL);
|
||||
|
@ -939,7 +1006,7 @@ int32 simh_out(int32 data) {
|
|||
case detachPTRCmd: /* detach ptr */
|
||||
detach_unit(&ptr_unit);
|
||||
break;
|
||||
case getSIMHVersionCMD:
|
||||
case getSIMHVersionCmd:
|
||||
versionPos = 0;
|
||||
break;
|
||||
case getClockZSDOSCmd:
|
||||
|
@ -962,10 +1029,9 @@ int32 simh_out(int32 data) {
|
|||
setClockCPM3Pos = 0;
|
||||
break;
|
||||
case getBankSelectCmd:
|
||||
break;
|
||||
case setBankSelectCmd:
|
||||
break;
|
||||
case getCommonCmd:
|
||||
case hasBankedMemoryCmd:
|
||||
break;
|
||||
case resetSIMHInterfaceCmd:
|
||||
markTimeSP = 0;
|
||||
|
@ -974,13 +1040,16 @@ int32 simh_out(int32 data) {
|
|||
case showTimerCmd: /* show time difference to timer on top of stack */
|
||||
if (rtc_avail) {
|
||||
if (markTimeSP > 0) {
|
||||
delta = sim_os_msec() - markTime[markTimeSP - 1];
|
||||
uint32 delta = sim_os_msec() - markTime[markTimeSP - 1];
|
||||
message2("Timer running. Elapsed in milliseconds = %d.\n", delta);
|
||||
}
|
||||
else {
|
||||
message1("No timer active.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
warnNoRealTimeClock();
|
||||
}
|
||||
break;
|
||||
case attachPTPCmd: /* attach ptp to the file with name at beginning of CP/M command line */
|
||||
attachCPM(&ptp_unit);
|
||||
|
@ -988,8 +1057,6 @@ int32 simh_out(int32 data) {
|
|||
case detachPTPCmd: /* detach ptp */
|
||||
detach_unit(&ptp_unit);
|
||||
break;
|
||||
case hasBankedMemoryCmd:
|
||||
break;
|
||||
case setZ80CPUCmd:
|
||||
cpu_unit.flags |= UNIT_CHIP;
|
||||
break;
|
||||
|
@ -1012,9 +1079,17 @@ int32 simh_out(int32 data) {
|
|||
case setTimerInterruptAdrCmd:
|
||||
setTimerInterruptAdrPos = 0;
|
||||
break;
|
||||
case resetStopWatchCmd:
|
||||
stopWatchNow = rtc_avail ? sim_os_msec() : 0;
|
||||
break;
|
||||
case readStopWatchCmd:
|
||||
getStopWatchDeltaPos = 0;
|
||||
stopWatchDelta = rtc_avail ? sim_os_msec() - stopWatchNow : 0;
|
||||
break;
|
||||
default:
|
||||
if (simh_unit.flags & UNIT_SIMH_VERBOSE) {
|
||||
message2("Unknown command (%i) to SIMH pseudo device ignored.\n", data);
|
||||
message3("Unknown command (%i) to SIMH pseudo device on port %03xh ignored.\n",
|
||||
data, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1022,6 +1097,6 @@ int32 simh_out(int32 data) {
|
|||
}
|
||||
|
||||
/* port 0xfe is a device for communication SIMH <--> Altair machine */
|
||||
int32 simh_dev(int32 port, int32 io, int32 data) {
|
||||
return io == 0 ? simh_in() : simh_out(data);
|
||||
int32 simh_dev(const int32 port, const int32 io, const int32 data) {
|
||||
return io == 0 ? simh_in(port) : simh_out(port, data);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairz80_sys.c: MITS Altair system interface
|
||||
|
||||
Copyright (c) 2002, Peter Schorn
|
||||
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"),
|
||||
|
@ -15,7 +15,7 @@
|
|||
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
|
||||
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.
|
||||
|
||||
|
@ -40,27 +40,24 @@ extern DEVICE simh_device;
|
|||
extern DEVICE ptr_dev;
|
||||
extern DEVICE ptp_dev;
|
||||
extern int32 saved_PC;
|
||||
extern char *get_range(char *cptr, t_addr *lo, t_addr *hi, int rdx,
|
||||
t_addr max, char term);
|
||||
extern t_value get_uint(char *cptr, int radix, t_value max, t_stat *status);
|
||||
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
|
||||
extern void PutBYTEForced(register uint32 Addr, register uint32 Value);
|
||||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
||||
extern int32 addressIsInROM(uint32 Addr);
|
||||
extern int32 addressExists(uint32 Addr);
|
||||
extern uint32 ROMLow;
|
||||
extern uint32 ROMHigh;
|
||||
extern int32 addressIsInROM(const uint32 Addr);
|
||||
extern int32 addressExists(const uint32 Addr);
|
||||
extern void printROMMessage(const uint32 cntROM);
|
||||
|
||||
int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag);
|
||||
int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw);
|
||||
int32 checkbase(char ch, char *numString);
|
||||
int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 requireSign, int32 *result);
|
||||
int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star, int32 *at,
|
||||
static int32 checkbase(char ch, const char *numString);
|
||||
static int32 numok(char ch, const char **numString, const int32 minvalue,
|
||||
const int32 maxvalue, const int32 requireSign, int32 *result);
|
||||
static int32 match(const char *pattern, const char *input, char *xyFirst, char *xy, int32 *number, int32 *star, int32 *at,
|
||||
int32 *hat, int32 *dollar);
|
||||
int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]);
|
||||
static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, char *const Mnemonics[]);
|
||||
int32 parse_sym(char *cptr, int32 addr, UNIT *uptr, uint32 *val, int32 sw);
|
||||
int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr);
|
||||
int32 checkXY(char xy);
|
||||
static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const int32 addr);
|
||||
static int32 checkXY(const char xy);
|
||||
|
||||
/* SCP data structures
|
||||
sim_name simulator name string
|
||||
|
@ -78,14 +75,12 @@ DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &simh_device, &ptr_dev, &ptp_dev,
|
|||
|
||||
char memoryAccessMessage[80];
|
||||
const char *sim_stop_messages[] = {
|
||||
"Unknown error",
|
||||
"Unknown I/O Instruction",
|
||||
"HALT instruction",
|
||||
"Breakpoint",
|
||||
memoryAccessMessage,
|
||||
"Invalid Opcode" };
|
||||
|
||||
static char *Mnemonics8080[] = {
|
||||
static char *const Mnemonics8080[] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"NOP", "LXI B,#h", "STAX B", "INX B", "INR B", "DCR B", "MVI B,*h", "RLC", /* 00-07 */
|
||||
"DB 09h", "DAD B", "LDAX B", "DCX B", "INR C", "DCR C", "MVI C,*h", "RRC", /* 08-0f */
|
||||
|
@ -121,7 +116,7 @@ static char *Mnemonics8080[] = {
|
|||
"RM", "SPHL", "JM #h", "EI", "CM #h", "DB FDh", "CPI *h", "RST 7" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsZ80[256] = {
|
||||
static char *const MnemonicsZ80[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */
|
||||
"EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */
|
||||
|
@ -157,7 +152,7 @@ static char *MnemonicsZ80[256] = {
|
|||
"RET M", "LD SP,HL", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsCB[256] = {
|
||||
static char *const MnemonicsCB[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A", /* 00-07 */
|
||||
"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A", /* 08-0f */
|
||||
|
@ -193,7 +188,7 @@ static char *MnemonicsCB[256] = {
|
|||
"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(HL)", "SET 7,A" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsED[256] = {
|
||||
static char *const MnemonicsED[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"DB EDh,00h", "DB EDh,01h", "DB EDh,02h", "DB EDh,03h", "DB EDh,04h", "DB EDh,05h", "DB EDh,06h", "DB EDh,07h", /* 00-07 */
|
||||
"DB EDh,08h", "DB EDh,09h", "DB EDh,0Ah", "DB EDh,0Bh", "DB EDh,0Ch", "DB EDh,0Dh", "DB EDh,0Eh", "DB EDh,0Fh", /* 08-0f */
|
||||
|
@ -229,32 +224,32 @@ static char *MnemonicsED[256] = {
|
|||
"DB EDh,F8h", "DB EDh,F9h", "DB EDh,FAh", "DB EDh,FBh", "DB EDh,FCh", "DB EDh,FDh", "DB EDh,FEh", "DB EDh,FFh" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsXX[256] = {
|
||||
static char *const MnemonicsXX[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA", /* 00-07 */
|
||||
"EX AF,AF'", "ADD I%,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA", /* 08-0f */
|
||||
"DJNZ $h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA", /* 10-17 */
|
||||
"JR $h", "ADD I%,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA", /* 18-1f */
|
||||
"JR NZ,$h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%h", "DEC I%h", "LD I%h,*h", "DAA", /* 20-27 */
|
||||
"JR Z,$h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%l", "DEC I%l", "LD I%l,*h", "CPL", /* 28-2f */
|
||||
"JR NZ,$h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%H", "DEC I%H", "LD I%H,*h", "DAA", /* 20-27 */
|
||||
"JR Z,$h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%L", "DEC I%L", "LD I%L,*h", "CPL", /* 28-2f */
|
||||
"JR NC,$h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (I%+^h)", "DEC (I%+^h)", "LD (I%+^h),*h", "SCF", /* 30-37 */
|
||||
"JR C,$h", "ADD I%,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF", /* 38-3f */
|
||||
"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%h", "LD B,I%l", "LD B,(I%+^h)", "LD B,A", /* 40-47 */
|
||||
"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%h", "LD C,I%l", "LD C,(I%+^h)", "LD C,A", /* 48-4f */
|
||||
"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%h", "LD D,I%l", "LD D,(I%+^h)", "LD D,A", /* 50-57 */
|
||||
"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%h", "LD E,I%l", "LD E,(I%+^h)", "LD E,A", /* 58-5f */
|
||||
"LD I%h,B", "LD I%h,C", "LD I%h,D", "LD I%h,E", "LD I%h,I%h", "LD I%h,I%l", "LD H,(I%+^h)", "LD I%h,A", /* 60-67 */
|
||||
"LD I%l,B", "LD I%l,C", "LD I%l,D", "LD I%l,E", "LD I%l,I%h", "LD I%l,I%l", "LD L,(I%+^h)", "LD I%l,A", /* 68-6f */
|
||||
"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%H", "LD B,I%L", "LD B,(I%+^h)", "LD B,A", /* 40-47 */
|
||||
"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%H", "LD C,I%L", "LD C,(I%+^h)", "LD C,A", /* 48-4f */
|
||||
"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%H", "LD D,I%L", "LD D,(I%+^h)", "LD D,A", /* 50-57 */
|
||||
"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%H", "LD E,I%L", "LD E,(I%+^h)", "LD E,A", /* 58-5f */
|
||||
"LD I%H,B", "LD I%H,C", "LD I%H,D", "LD I%H,E", "LD I%H,I%H", "LD I%H,I%L", "LD H,(I%+^h)", "LD I%H,A", /* 60-67 */
|
||||
"LD I%L,B", "LD I%L,C", "LD I%L,D", "LD I%L,E", "LD I%L,I%H", "LD I%L,I%L", "LD L,(I%+^h)", "LD I%L,A", /* 68-6f */
|
||||
"LD (I%+^h),B", "LD (I%+^h),C", "LD (I%+^h),D", "LD (I%+^h),E", "LD (I%+^h),H", "LD (I%+^h),L", "HALT", "LD (I%+^h),A", /* 70-77 */
|
||||
"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%h", "LD A,I%l", "LD A,(I%+^h)", "LD A,A", /* 78-7f */
|
||||
"ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,I%h", "ADD A,I%l", "ADD A,(I%+^h)", "ADD A,A", /* 80-87 */
|
||||
"ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,I%h", "ADC A,I%l", "ADC A,(I%+^h)", "ADC A,A", /* 88-8f */
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB I%h", "SUB I%l", "SUB (I%+^h)", "SUB A", /* 90-97 */
|
||||
"SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,I%h", "SBC A,I%l", "SBC A,(I%+^h)", "SBC A,A", /* 98-9f */
|
||||
"AND B", "AND C", "AND D", "AND E", "AND I%h", "AND I%l", "AND (I%+^h)", "AND A", /* a0-a7 */
|
||||
"XOR B", "XOR C", "XOR D", "XOR E", "XOR I%h", "XOR I%l", "XOR (I%+^h)", "XOR A", /* a8-af */
|
||||
"OR B", "OR C", "OR D", "OR E", "OR I%h", "OR I%l", "OR (I%+^h)", "OR A", /* b0-b7 */
|
||||
"CP B", "CP C", "CP D", "CP E", "CP I%h", "CP I%l", "CP (I%+^h)", "CP A", /* b8-bf */
|
||||
"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%H", "LD A,I%L", "LD A,(I%+^h)", "LD A,A", /* 78-7f */
|
||||
"ADD A,B", "ADD A,C", "ADD A,D", "ADD A,E", "ADD A,I%H", "ADD A,I%L", "ADD A,(I%+^h)", "ADD A,A", /* 80-87 */
|
||||
"ADC A,B", "ADC A,C", "ADC A,D", "ADC A,E", "ADC A,I%H", "ADC A,I%L", "ADC A,(I%+^h)", "ADC A,A", /* 88-8f */
|
||||
"SUB B", "SUB C", "SUB D", "SUB E", "SUB I%H", "SUB I%L", "SUB (I%+^h)", "SUB A", /* 90-97 */
|
||||
"SBC A,B", "SBC A,C", "SBC A,D", "SBC A,E", "SBC A,I%H", "SBC A,I%L", "SBC A,(I%+^h)", "SBC A,A", /* 98-9f */
|
||||
"AND B", "AND C", "AND D", "AND E", "AND I%H", "AND I%L", "AND (I%+^h)", "AND A", /* a0-a7 */
|
||||
"XOR B", "XOR C", "XOR D", "XOR E", "XOR I%H", "XOR I%L", "XOR (I%+^h)", "XOR A", /* a8-af */
|
||||
"OR B", "OR C", "OR D", "OR E", "OR I%H", "OR I%L", "OR (I%+^h)", "OR A", /* b0-b7 */
|
||||
"CP B", "CP C", "CP D", "CP E", "CP I%H", "CP I%L", "CP (I%+^h)", "CP A", /* b8-bf */
|
||||
"RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD A,*h", "RST 00h", /* c8-cf */
|
||||
"RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC A,*h", "RST 08h", /* c8-cf */
|
||||
"RET NC", "POP DE", "JP NC,#h", "OUT (*h),A", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h", /* d0-d7 */
|
||||
|
@ -265,7 +260,7 @@ static char *MnemonicsXX[256] = {
|
|||
"RET M", "LD SP,I%", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h" /* f8-ff */
|
||||
};
|
||||
|
||||
static char *MnemonicsXCB[256] = {
|
||||
static char *const MnemonicsXCB[256] = {
|
||||
/*0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F */
|
||||
"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (I%@h)", "RLC A", /* 00-07 */
|
||||
"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (I%@h)", "RRC A", /* 08-0f */
|
||||
|
@ -301,7 +296,7 @@ static char *MnemonicsXCB[256] = {
|
|||
"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(I%@h)", "SET 7,A" /* f8-ff */
|
||||
};
|
||||
|
||||
/* Symbolic disassembler
|
||||
/* symbolic disassembler
|
||||
|
||||
Inputs:
|
||||
*val = instructions to disassemble
|
||||
|
@ -316,9 +311,9 @@ static char *MnemonicsXCB[256] = {
|
|||
|
||||
*/
|
||||
|
||||
int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr) {
|
||||
static int32 DAsm(char *S, const uint32 *val, const int32 useZ80Mnemonics, const int32 addr) {
|
||||
char R[128], H[10], C = '\0', *T, *P;
|
||||
uint8 J = 0, Offset;
|
||||
uint8 J = 0, Offset = 0;
|
||||
uint16 B = 0;
|
||||
|
||||
if (useZ80Mnemonics) {
|
||||
|
@ -333,8 +328,7 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr) {
|
|||
break;
|
||||
case 0xdd:
|
||||
case 0xfd:
|
||||
C = (val[B] == 0xdd) ? 'X' : 'Y';
|
||||
B++;
|
||||
C = (val[B++] == 0xdd) ? 'X' : 'Y';
|
||||
if (val[B] == 0xcb) {
|
||||
B++;
|
||||
Offset = val[B++];
|
||||
|
@ -411,7 +405,7 @@ int32 DAsm(char *S, uint32 *val, int32 useZ80Mnemonics, int32 addr) {
|
|||
return(B);
|
||||
}
|
||||
|
||||
/* Symbolic output
|
||||
/* symbolic output
|
||||
|
||||
Inputs:
|
||||
*of = output stream
|
||||
|
@ -440,7 +434,7 @@ int32 fprint_sym(FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw) {
|
|||
|
||||
/* numString checks determines the base of the number (ch, *numString)
|
||||
and returns FALSE if the number is bad */
|
||||
int32 checkbase(char ch, char *numString) {
|
||||
static int32 checkbase(char ch, const char *numString) {
|
||||
int32 decimal = (ch <= '9');
|
||||
if (toupper(ch) == 'H') {
|
||||
return FALSE;
|
||||
|
@ -453,7 +447,8 @@ int32 checkbase(char ch, char *numString) {
|
|||
return toupper(ch) == 'H' ? 16 : (decimal ? 10 : FALSE);
|
||||
}
|
||||
|
||||
int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 requireSign, int32 *result) {
|
||||
static int32 numok(char ch, const char **numString, const int32 minvalue,
|
||||
const int32 maxvalue, const int32 requireSign, int32 *result) {
|
||||
int32 sign = 1, value = 0, base;
|
||||
if (requireSign) {
|
||||
if (ch == '+') {
|
||||
|
@ -481,17 +476,19 @@ int32 numok(char ch, char **numString, int32 minvalue, int32 maxvalue, int32 req
|
|||
return (minvalue <= value) && (value <= maxvalue);
|
||||
}
|
||||
|
||||
int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star,
|
||||
static int32 match(const char *pattern, const char *input, char *xyFirst, char *xy, int32 *number, int32 *star,
|
||||
int32 *at, int32 *hat, int32 *dollar) {
|
||||
char pat = *pattern++;
|
||||
char inp = *input++;
|
||||
while ((pat) && (inp)) {
|
||||
switch(pat) {
|
||||
case '_': /* patterns containting '_' should never match */
|
||||
return FALSE;
|
||||
case ',':
|
||||
if (inp == ' ') {
|
||||
inp = *input++;
|
||||
continue;
|
||||
}
|
||||
} /* otherwise fall through */
|
||||
case ' ':
|
||||
if (inp != pat) {
|
||||
return FALSE;
|
||||
|
@ -502,15 +499,25 @@ int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star,
|
|||
inp = *input++;
|
||||
}
|
||||
continue;
|
||||
break;
|
||||
case '%':
|
||||
inp = toupper(inp);
|
||||
if ((inp == 'X') || (inp == 'Y')) {
|
||||
if (*xyFirst) { /* make sure that second '%' corresponds to first */
|
||||
if (*xyFirst == inp) {
|
||||
*xy = inp;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else { /* take note of first '%' for later */
|
||||
*xyFirst = inp;
|
||||
*xy = inp;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
case '#':
|
||||
if (numok(inp, &input, 0, 65535, FALSE, number)) {
|
||||
|
@ -566,25 +573,16 @@ int32 match(char *pattern, char *input, char *xy, int32 *number, int32 *star,
|
|||
return (pat == 0) && (inp == 0);
|
||||
}
|
||||
|
||||
INLINE int32 checkXY(char xy) {
|
||||
if (xy == 'X') {
|
||||
return 0xdd;
|
||||
}
|
||||
else if (xy == 'Y') {
|
||||
return 0xfd;
|
||||
}
|
||||
else {
|
||||
printf("X or Y expected.\n");
|
||||
return FALSE;
|
||||
}
|
||||
static INLINE int32 checkXY(const char xy) {
|
||||
return xy == 'X' ? 0xdd : 0xfd; /* else is 'Y' */
|
||||
}
|
||||
|
||||
int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
||||
char xy;
|
||||
static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, char *const Mnemonics[]) {
|
||||
char xyFirst = 0, xy;
|
||||
int32 op, number, star, at, hat, dollar;
|
||||
for (op = 0; op < 256; op++) {
|
||||
number = star = at = dollar = -129;
|
||||
if (match(Mnemonics[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
if (match(Mnemonics[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
val[0] = op;
|
||||
if (number >= 0) {
|
||||
val[1] = (0xff) & number;
|
||||
|
@ -598,7 +596,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
|||
else if (at > -129) {
|
||||
if ((-128 <= at) && (at <= 127)) {
|
||||
val[1] = (int8)(at);
|
||||
return -1;
|
||||
return -1; /* one additional byte returned */
|
||||
}
|
||||
else {
|
||||
return SCPE_ARG;
|
||||
|
@ -624,7 +622,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
|||
}
|
||||
|
||||
for (op = 0; op < 256; op++) {
|
||||
if (match(MnemonicsCB[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
if (match(MnemonicsCB[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
val[0] = 0xcb;
|
||||
val[1] = op;
|
||||
return -1; /* one additional byte returned */
|
||||
|
@ -633,7 +631,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
|||
|
||||
for (op = 0; op < 256; op++) {
|
||||
number = -1;
|
||||
if (match(MnemonicsED[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
if (match(MnemonicsED[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
val[0] = 0xed;
|
||||
val[1] = op;
|
||||
if (number >= 0) {
|
||||
|
@ -649,8 +647,9 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
|||
|
||||
for (op = 0; op < 256; op++) {
|
||||
number = star = hat = -1;
|
||||
xy = ' ';
|
||||
if (match(MnemonicsXX[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
xy = 0;
|
||||
if (match(MnemonicsXX[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
/* all matches must have contained a '%' character */
|
||||
if (!(val[0] = checkXY(xy))) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
|
@ -681,8 +680,9 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
|||
|
||||
for (op = 0; op < 256; op++) {
|
||||
at = -129;
|
||||
xy = ' ';
|
||||
if (match(MnemonicsXCB[op], cptr, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
xy = 0;
|
||||
if (match(MnemonicsXCB[op], cptr, &xyFirst, &xy, &number, &star, &at, &hat, &dollar)) {
|
||||
/* all matches must have contained a '%' character */
|
||||
if (!(val[0] = checkXY(xy))) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
|
@ -702,7 +702,7 @@ int32 parse_X80(char *cptr, int32 addr, uint32 *val, char *Mnemonics[]) {
|
|||
}
|
||||
|
||||
|
||||
/* Symbolic input
|
||||
/* symbolic input
|
||||
|
||||
Inputs:
|
||||
*cptr = pointer to input string
|
||||
|
@ -773,9 +773,7 @@ int32 sim_load(FILE *fileref, char *cptr, char *fnam, int32 flag) {
|
|||
} /* end while */
|
||||
printf("%d bytes [%d page%s] loaded at %x.\n", cnt, (cnt + 255) >> 8,
|
||||
((cnt + 255) >> 8) == 1 ? "" : "s", org);
|
||||
if (cntROM) {
|
||||
printf("Warning: %d bytes written to ROM [%04X - %04X].\n", cntROM, ROMLow, ROMHigh);
|
||||
}
|
||||
printROMMessage(cntROM);
|
||||
if (cntNonExist) {
|
||||
printf("Warning: %d bytes written to non-existing memory (for this configuration).\n", cntNonExist);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* altairZ80_hdsk.c: simulated hard disk device to increase capacity
|
||||
/* altairz80_hdsk.c: simulated hard disk device to increase capacity
|
||||
|
||||
Copyright (c) 2002, Peter Schorn
|
||||
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"),
|
||||
|
@ -15,7 +15,7 @@
|
|||
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
|
||||
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.
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
|||
in this Software without prior written authorization from Peter Schorn.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "altairz80_defs.h"
|
||||
|
||||
#define UNIT_V_HDSKWLK (UNIT_V_UF + 0) /* write locked */
|
||||
|
@ -54,32 +53,32 @@ extern int32 saved_PC;
|
|||
|
||||
extern int32 install_bootrom(void);
|
||||
extern void printMessage(void);
|
||||
extern void PutBYTEBasic(const uint32 Addr, const uint32 Bank, const uint32 Value);
|
||||
extern void PutBYTEWrapper(register uint32 Addr, register uint32 Value);
|
||||
extern void protect(int32 l, int32 h);
|
||||
extern void protect(const int32 l, const int32 h);
|
||||
extern uint8 GetBYTEWrapper(register uint32 Addr);
|
||||
extern int32 bootrom[bootrom_size];
|
||||
|
||||
t_stat hdsk_svc(UNIT *uptr);
|
||||
t_stat hdsk_boot(int32 unitno, DEVICE *dptr);
|
||||
int32 hdsk_hasVerbose(void);
|
||||
int32 hdsk_io(int32 port, int32 io, int32 data);
|
||||
int32 hdsk_in(void);
|
||||
int32 hdsk_out(int32 data);
|
||||
int32 checkParameters(void);
|
||||
int32 doSeek(void);
|
||||
int32 doRead(void);
|
||||
int32 doWrite(void);
|
||||
static t_stat hdsk_svc(UNIT *uptr);
|
||||
static t_stat hdsk_boot(int32 unitno, DEVICE *dptr);
|
||||
static int32 hdsk_hasVerbose(void);
|
||||
int32 hdsk_io(const int32 port, const int32 io, const int32 data);
|
||||
static int32 hdsk_in(const int32 port);
|
||||
static int32 hdsk_out(const int32 data);
|
||||
static int32 checkParameters(void);
|
||||
static int32 doSeek(void);
|
||||
static int32 doRead(void);
|
||||
static int32 doWrite(void);
|
||||
|
||||
uint8 hdskbuf[HDSK_SECTOR_SIZE]; /* Data Buffer */
|
||||
int32 hdskLastCommand = hdsk_none;
|
||||
int32 hdskCommandPosition = 0;
|
||||
int32 selectedDisk;
|
||||
int32 selectedSector;
|
||||
int32 selectedTrack;
|
||||
int32 selectedDMA;
|
||||
int32 hdskTrace;
|
||||
static int32 hdskLastCommand = hdsk_none;
|
||||
static int32 hdskCommandPosition = 0;
|
||||
static int32 selectedDisk;
|
||||
static int32 selectedSector;
|
||||
static int32 selectedTrack;
|
||||
static int32 selectedDMA;
|
||||
static int32 hdskTrace;
|
||||
|
||||
UNIT hdsk_unit[] = {
|
||||
static UNIT hdsk_unit[] = {
|
||||
{ UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) },
|
||||
{ UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) },
|
||||
{ UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) },
|
||||
|
@ -89,7 +88,7 @@ UNIT hdsk_unit[] = {
|
|||
{ UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) },
|
||||
{ UDATA (&hdsk_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, HDSK_CAPACITY) } };
|
||||
|
||||
REG hdsk_reg[] = {
|
||||
static REG hdsk_reg[] = {
|
||||
{ DRDATA (HDCMD, hdskLastCommand, 32), REG_RO },
|
||||
{ DRDATA (HDPOS, hdskCommandPosition, 32), REG_RO },
|
||||
{ DRDATA (HDDSK, selectedDisk, 32), REG_RO },
|
||||
|
@ -99,7 +98,7 @@ REG hdsk_reg[] = {
|
|||
{ DRDATA (HDTRACE, hdskTrace, 8), },
|
||||
{ NULL } };
|
||||
|
||||
MTAB hdsk_mod[] = {
|
||||
static MTAB hdsk_mod[] = {
|
||||
{ UNIT_HDSKWLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_HDSKWLK, UNIT_HDSKWLK, "write locked", "LOCKED", NULL },
|
||||
/* quiet, no warning messages */
|
||||
|
@ -112,13 +111,13 @@ 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 };
|
||||
&hdsk_boot, NULL, NULL, NULL, 0, NULL, NULL };
|
||||
|
||||
t_stat hdsk_svc(UNIT *uptr) {
|
||||
static t_stat hdsk_svc(UNIT *uptr) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
int32 hdskBoot[bootrom_size] = {
|
||||
static const int32 hdskBoot[bootrom_size] = {
|
||||
0xf3, 0x06, 0x80, 0x3e, 0x0e, 0xd3, 0xfe, 0x05, /* 5c00-5c07 */
|
||||
0xc2, 0x05, 0x5c, 0x3e, 0x16, 0xd3, 0xfe, 0x3e, /* 5c08-5c0f */
|
||||
0x12, 0xd3, 0xfe, 0xdb, 0xfe, 0xb7, 0xca, 0x20, /* 5c10-5c17 */
|
||||
|
@ -153,7 +152,7 @@ int32 hdskBoot[bootrom_size] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5cf8-5cff */
|
||||
};
|
||||
|
||||
t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
|
||||
static t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
|
||||
int32 i;
|
||||
if (MEMSIZE < 24*KB) {
|
||||
printf("Need at least 24KB RAM to boot from hard disk.\n");
|
||||
|
@ -173,7 +172,7 @@ t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
|
|||
}
|
||||
}
|
||||
for (i = 0; i < bootrom_size; i++) {
|
||||
M[i + hdsk_boot_address][0] = hdskBoot[i] & 0xff;
|
||||
PutBYTEBasic(i + hdsk_boot_address, 0, hdskBoot[i] & 0xff);
|
||||
}
|
||||
saved_PC = hdsk_boot_address;
|
||||
protect(hdsk_boot_address, hdsk_boot_address + bootrom_size - 1);
|
||||
|
@ -181,7 +180,7 @@ t_stat hdsk_boot(int32 unitno, DEVICE *dptr) {
|
|||
}
|
||||
|
||||
/* returns TRUE iff there exists a disk with VERBOSE */
|
||||
int32 hdsk_hasVerbose(void) {
|
||||
static int32 hdsk_hasVerbose(void) {
|
||||
int32 i;
|
||||
for (i = 0; i < HDSK_NUMBER; i++) {
|
||||
if (((hdsk_dev.units + i) -> flags) & UNIT_HDSK_VERBOSE) {
|
||||
|
@ -221,7 +220,7 @@ l ld a,(hl) ; get byte of parameter block
|
|||
*/
|
||||
|
||||
/* check the parameters and return TRUE iff parameters are correct or have been repaired */
|
||||
int32 checkParameters(void) {
|
||||
static int32 checkParameters(void) {
|
||||
int32 currentFlag;
|
||||
if ((selectedDisk < 0) || (selectedDisk >= HDSK_NUMBER)) {
|
||||
if (hdsk_hasVerbose()) {
|
||||
|
@ -259,7 +258,7 @@ int32 checkParameters(void) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
int32 doSeek(void) {
|
||||
static int32 doSeek(void) {
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
if (fseek(uptr -> fileref,
|
||||
HDSK_TRACK_SIZE * selectedTrack + HDSK_SECTOR_SIZE * selectedSector, SEEK_SET)) {
|
||||
|
@ -274,8 +273,9 @@ int32 doSeek(void) {
|
|||
}
|
||||
}
|
||||
|
||||
int32 doRead(void) {
|
||||
static int32 doRead(void) {
|
||||
int32 i;
|
||||
uint8 hdskbuf[HDSK_SECTOR_SIZE]; /* data buffer */
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
if (doSeek()) {
|
||||
return CPM_ERROR;
|
||||
|
@ -296,8 +296,9 @@ int32 doRead(void) {
|
|||
return CPM_OK;
|
||||
}
|
||||
|
||||
int32 doWrite(void) {
|
||||
static int32 doWrite(void) {
|
||||
int32 i;
|
||||
uint8 hdskbuf[HDSK_SECTOR_SIZE]; /* data buffer */
|
||||
UNIT *uptr = hdsk_dev.units + selectedDisk;
|
||||
if (((uptr -> flags) & UNIT_HDSKWLK) == 0) { /* write enabled */
|
||||
if (doSeek()) {
|
||||
|
@ -324,7 +325,7 @@ int32 doWrite(void) {
|
|||
return CPM_OK;
|
||||
}
|
||||
|
||||
int32 hdsk_in(void) {
|
||||
static int32 hdsk_in(const int32 port) {
|
||||
int32 result;
|
||||
if ((hdskCommandPosition == 6) && ((hdskLastCommand == hdsk_read) || (hdskLastCommand == hdsk_write))) {
|
||||
result = checkParameters() ? ((hdskLastCommand == hdsk_read) ? doRead() : doWrite()) : CPM_ERROR;
|
||||
|
@ -333,12 +334,13 @@ int32 hdsk_in(void) {
|
|||
return result;
|
||||
}
|
||||
else if (hdsk_hasVerbose()) {
|
||||
message3("Illegal IN command detected (cmd=%d, pos=%d).\n", hdskLastCommand, hdskCommandPosition);
|
||||
message4("Illegal IN command detected (port=%03xh, cmd=%d, pos=%d).\n",
|
||||
port, hdskLastCommand, hdskCommandPosition);
|
||||
}
|
||||
return CPM_OK;
|
||||
}
|
||||
|
||||
int32 hdsk_out(int32 data) {
|
||||
static int32 hdsk_out(const int32 data) {
|
||||
switch(hdskLastCommand) {
|
||||
case hdsk_read:
|
||||
case hdsk_write:
|
||||
|
@ -379,6 +381,6 @@ int32 hdsk_out(int32 data) {
|
|||
return 0; /* ignored, since OUT */
|
||||
}
|
||||
|
||||
int32 hdsk_io(int32 port, int32 io, int32 data) {
|
||||
return io == 0 ? hdsk_in() : hdsk_out(data);
|
||||
int32 hdsk_io(const int32 port, const int32 io, const int32 data) {
|
||||
return io == 0 ? hdsk_in(port) : hdsk_out(data);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* gri_cpu.c: GRI-909 CPU simulator
|
||||
|
||||
Copyright (c) 2001-2002, Robert M. Supnik
|
||||
Copyright (c) 2001-2003, 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,10 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
cpu GRI-909 CPU
|
||||
|
||||
14-Mar-03 RMS Fixed bug in SC queue tracking
|
||||
|
||||
The system state for the GRI-909 is:
|
||||
|
||||
AX<0:15> arithmetic input
|
||||
|
@ -167,6 +171,7 @@ uint32 stop_opr = 1; /* stop ill operator */
|
|||
int16 scq[SCQ_SIZE] = { 0 }; /* PC queue */
|
||||
int32 scq_p = 0; /* PC queue ptr */
|
||||
REG *scq_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 */
|
||||
|
@ -475,7 +480,7 @@ else if ((src != U_MEM) && (dst != U_MEM)) { /* reg-reg? */
|
|||
/* Memory reference. The second SC increment occurs after the first
|
||||
execution cycle. For direct, defer, and immediate defer, this is
|
||||
after the first memory read and before the bus transfer; but for
|
||||
immediate, it is before the bus transfer.
|
||||
immediate, it is after the bus transfer.
|
||||
*/
|
||||
|
||||
else { SC = (SC + 1) & AMASK; /* incr SC */
|
||||
|
@ -512,6 +517,7 @@ else { SC = (SC + 1) & AMASK; /* incr SC */
|
|||
/* Simulation halted */
|
||||
|
||||
AO = ao_update (); /* update AO */
|
||||
scq_r->qptr = scq_p; /* update sc q ptr */
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
@ -871,7 +877,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0))
|
||||
return SCPE_ARG;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* gri_defs.h: GRI-909 simulator definitions
|
||||
|
||||
Copyright (c) 2001-2002, Robert M. Supnik
|
||||
Copyright (c) 2001-2003, 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.
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
19-Sep-02 RMS Fixed declarations in gdev structure
|
||||
|
||||
There are several discrepancies between the original GRI-909 Reference
|
||||
|
@ -65,7 +66,7 @@
|
|||
#define MAXMEMSIZE 32768 /* max memory size */
|
||||
#define AMASK 077777 /* logical addr mask */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE)
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
|
||||
/* Architectural constants */
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: GRI-909 Simulator Usage
|
||||
Date: 15-Nov-2002
|
||||
Date: 20-Apr-2003
|
||||
|
||||
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-2002, Robert M Supnik
|
||||
Original code published in 1993-2003, written by Robert M Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -103,7 +103,7 @@ control registers for the interrupt system.
|
|||
|
||||
name size comments
|
||||
|
||||
SC 14 sequence counter
|
||||
SC 15 sequence counter
|
||||
AX 16 arithmetic operator input register 1
|
||||
AY 16 arithmetic operator input register 2
|
||||
AO 16 arithmetic operator output register
|
||||
|
@ -126,7 +126,7 @@ control registers for the interrupt system.
|
|||
ION 1 interrupts enabled
|
||||
INODEF 1 interrupts not deferred
|
||||
BKP 1 breakpoint request
|
||||
SCQ[0:63] 16 SC prior to last jump or interrupt;
|
||||
SCQ[0:63] 15 SC prior to last jump or interrupt;
|
||||
most recent SC change first
|
||||
STOP_OPR 1 stop on undefined operator
|
||||
WRU 8 interrupt character
|
||||
|
@ -136,8 +136,8 @@ control registers for the interrupt system.
|
|||
2.2.1 S42-004 High Speed Reader (HSR)
|
||||
|
||||
The paper tape reader (HSR) reads data from or a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
by changing POS, the user can backspace or advance the reader.
|
||||
register specifies the number of the next data item to be read.
|
||||
Thus, by changing POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* gri_stddev.c: GRI-909 standard devices
|
||||
|
||||
Copyright (c) 2001-2002, Robert M Supnik
|
||||
Copyright (c) 2001-2003, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -29,6 +29,7 @@
|
|||
hsp S42-006 high speed punch
|
||||
rtc real time clock
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
22-Dec-02 RMS Added break support
|
||||
01-Nov-02 RMS Added 7b/8B support to terminal
|
||||
*/
|
||||
|
@ -73,7 +74,7 @@ REG tti_reg[] = {
|
|||
{ ORDATA (BUF, tti_unit.buf, 8) },
|
||||
{ FLDATA (IRDY, dev_done, INT_V_TTI) },
|
||||
{ FLDATA (IENB, ISR, INT_V_TTI) },
|
||||
{ DRDATA (POS, tti_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (UC, tti_unit.flags, UNIT_V_KSR), REG_HRO },
|
||||
{ NULL } };
|
||||
|
@ -103,7 +104,7 @@ REG tto_reg[] = {
|
|||
{ ORDATA (BUF, tto_unit.buf, 8) },
|
||||
{ FLDATA (ORDY, dev_done, INT_V_TTO) },
|
||||
{ FLDATA (IENB, ISR, INT_V_TTO) },
|
||||
{ DRDATA (POS, tto_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
|
@ -134,7 +135,7 @@ REG hsr_reg[] = {
|
|||
{ ORDATA (BUF, hsr_unit.buf, 8) },
|
||||
{ FLDATA (IRDY, dev_done, INT_V_HSR) },
|
||||
{ FLDATA (IENB, ISR, INT_V_HSR) },
|
||||
{ DRDATA (POS, hsr_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, hsr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, hsr_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, hsr_stopioe, 0) },
|
||||
{ NULL } };
|
||||
|
@ -159,7 +160,7 @@ REG hsp_reg[] = {
|
|||
{ ORDATA (BUF, hsp_unit.buf, 8) },
|
||||
{ FLDATA (ORDY, dev_done, INT_V_HSP) },
|
||||
{ FLDATA (IENB, ISR, INT_V_HSP) },
|
||||
{ DRDATA (POS, hsp_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, hsp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, hsp_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, hsp_stopioe, 0) },
|
||||
{ NULL } };
|
||||
|
@ -223,7 +224,7 @@ return 0;
|
|||
|
||||
/* Service routines */
|
||||
|
||||
t_stat tti_svc (UNIT *uhsr)
|
||||
t_stat tti_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c;
|
||||
|
||||
|
@ -240,7 +241,7 @@ tti_unit.pos = tti_unit.pos + 1;
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat tto_svc (UNIT *uhsr)
|
||||
t_stat tto_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c;
|
||||
t_stat r;
|
||||
|
@ -257,7 +258,7 @@ return SCPE_OK;
|
|||
|
||||
/* Reset routines */
|
||||
|
||||
t_stat tti_reset (DEVICE *dhsr)
|
||||
t_stat tti_reset (DEVICE *dptr)
|
||||
{
|
||||
tti_unit.buf = 0; /* clear buffer */
|
||||
dev_done = dev_done & ~INT_TTI; /* clear ready */
|
||||
|
@ -265,7 +266,7 @@ sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat tto_reset (DEVICE *dhsr)
|
||||
t_stat tto_reset (DEVICE *dptr)
|
||||
{
|
||||
tto_unit.buf = 0; /* clear buffer */
|
||||
dev_done = dev_done | INT_TTO; /* set ready */
|
||||
|
@ -310,7 +311,7 @@ if (((op & PT_IRDY) && (dev_done & INT_HSR)) ||
|
|||
return 0;
|
||||
}
|
||||
|
||||
t_stat hsr_svc (UNIT *uhsr)
|
||||
t_stat hsr_svc (UNIT *uptr)
|
||||
{
|
||||
int32 temp;
|
||||
|
||||
|
@ -329,7 +330,7 @@ hsr_unit.pos = hsr_unit.pos + 1;
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat hsp_svc (UNIT *uhsr)
|
||||
t_stat hsp_svc (UNIT *uptr)
|
||||
{
|
||||
dev_done = dev_done | INT_HSP; /* set ready */
|
||||
if ((hsp_unit.flags & UNIT_ATT) == 0) /* attached? */
|
||||
|
@ -344,7 +345,7 @@ return SCPE_OK;
|
|||
|
||||
/* Reset routines */
|
||||
|
||||
t_stat hsr_reset (DEVICE *dhsr)
|
||||
t_stat hsr_reset (DEVICE *dptr)
|
||||
{
|
||||
hsr_unit.buf = 0; /* clear buffer */
|
||||
dev_done = dev_done & ~INT_HSR; /* clear ready */
|
||||
|
@ -352,7 +353,7 @@ sim_cancel (&hsr_unit); /* deactivate unit */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat hsp_reset (DEVICE *dhsr)
|
||||
t_stat hsp_reset (DEVICE *dptr)
|
||||
{
|
||||
hsp_unit.buf = 0; /* clear buffer */
|
||||
dev_done = dev_done | INT_HSP; /* set ready */
|
||||
|
@ -377,7 +378,7 @@ if ((op & RTC_OV) && (dev_done & INT_RTC)) return 1;
|
|||
return 0;
|
||||
}
|
||||
|
||||
t_stat rtc_svc (UNIT *uhsr)
|
||||
t_stat rtc_svc (UNIT *uptr)
|
||||
{
|
||||
M[RTC_CTR] = (M[RTC_CTR] + 1) & DMASK; /* incr counter */
|
||||
if (M[RTC_CTR] == 0) dev_done = dev_done | INT_RTC; /* ovflo? set ready */
|
||||
|
@ -385,7 +386,7 @@ sim_activate (&rtc_unit, sim_rtc_calb (rtc_tps)); /* reactivate */
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat rtc_reset (DEVICE *dhsr)
|
||||
t_stat rtc_reset (DEVICE *dptr)
|
||||
{
|
||||
dev_done = dev_done & ~INT_RTC; /* clear ready */
|
||||
sim_cancel (&rtc_unit); /* stop clock */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* gri_sys.c: GRI-909 simulator interface
|
||||
|
||||
Copyright (c) 2001-2002, Robert M Supnik
|
||||
Copyright (c) 2001-2003, 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"),
|
||||
|
@ -80,7 +80,8 @@ const char *sim_stop_messages[] = {
|
|||
|
||||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||||
{
|
||||
int32 c, org;
|
||||
int32 c;
|
||||
uint32 org;
|
||||
t_stat r;
|
||||
char gbuf[CBUFSIZE];
|
||||
|
||||
|
@ -114,7 +115,7 @@ return SCPE_OK;
|
|||
|
||||
/* Symbol tables */
|
||||
|
||||
#define F_V_FL 16
|
||||
#define F_V_FL 16 /* class flag */
|
||||
#define F_M_FL 017
|
||||
#define F_V_FO 000 /* function out */
|
||||
#define F_V_FOI 001 /* FO, impl reg */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_cpu.c: Honeywell 316/516 CPU simulator
|
||||
|
||||
Copyright (c) 1999-2002, Robert M. Supnik
|
||||
Copyright (c) 1999-2003, 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"),
|
||||
|
@ -195,7 +195,7 @@
|
|||
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC
|
||||
#define PCQ_TOP pcq[pcq_p]
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF) /* dummy mask */
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#define UNIT_MSIZE (1u << UNIT_V_MSIZE)
|
||||
#define m7 0001000 /* for generics */
|
||||
#define m8 0000400
|
||||
#define m9 0000200
|
||||
|
@ -229,17 +229,20 @@ int32 pcq_p = 0; /* PC queue ptr */
|
|||
REG *pcq_r = NULL; /* PC queue reg ptr */
|
||||
int32 dlog = 0; /* debug log */
|
||||
int32 turnoff = 0;
|
||||
|
||||
extern int32 sim_int_char;
|
||||
extern int32 sim_interval;
|
||||
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern FILE *sim_log;
|
||||
|
||||
extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw);
|
||||
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_noext (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
|
||||
extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw);
|
||||
|
||||
/* CPU data structures
|
||||
|
||||
|
@ -323,10 +326,9 @@ int32 (*iotab[64])() = {
|
|||
|
||||
t_stat sim_instr (void)
|
||||
{
|
||||
extern int32 sim_interval;
|
||||
extern UNIT clk_unit;
|
||||
int32 AR, BR, MB, Y, t1, t2, t3, skip;
|
||||
unsigned int32 ut;
|
||||
uint32 ut;
|
||||
t_stat reason;
|
||||
t_stat Ea (int32 inst, int32 *addr);
|
||||
void Write (int32 val, int32 addr);
|
||||
|
@ -377,6 +379,7 @@ else { if (sim_brk_summ &&
|
|||
MB = Read (Y); /* fetch instr */
|
||||
PC = NEWA (Y, Y + 1); /* incr PC */
|
||||
dev_ready = dev_ready | INT_NODEF; }
|
||||
|
||||
sim_interval = sim_interval - 1;
|
||||
if (dlog && sim_log && !turnoff) { /* cycle log? */
|
||||
int32 op = I_GETOP (MB) & 017; /* core opcode */
|
||||
|
@ -389,6 +392,7 @@ if (dlog && sim_log && !turnoff) { /* cycle log? */
|
|||
/* Memory reference instructions */
|
||||
|
||||
switch (I_GETOP (MB)) { /* case on <1:6> */
|
||||
|
||||
case 001: case 021: case 041: case 061: /* JMP */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
PCQ_ENTRY; /* save PC */
|
||||
|
@ -401,6 +405,7 @@ case 001: case 021: case 041: case 061: /* JMP */
|
|||
else turnoff = 0; } /* no, log */
|
||||
if (extoff_pending) ext = extoff_pending = 0; /* cond ext off */
|
||||
break;
|
||||
|
||||
case 002: case 022: case 042: case 062: /* LDA */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
if (dp) { /* double prec? */
|
||||
|
@ -409,10 +414,12 @@ case 002: case 022: case 042: case 062: /* LDA */
|
|||
sc = 0; }
|
||||
else AR = Read (Y); /* no, get word */
|
||||
break;
|
||||
|
||||
case 003: case 023: case 043: case 063: /* ANA */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
AR = AR & Read (Y);
|
||||
break;
|
||||
|
||||
case 004: case 024: case 044: case 064: /* STA */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
if (dp) { /* double prec? */
|
||||
|
@ -421,10 +428,12 @@ case 004: case 024: case 044: case 064: /* STA */
|
|||
sc = 0; }
|
||||
else Write (AR, Y); /* no, store word */
|
||||
break;
|
||||
|
||||
case 005: case 025: case 045: case 065: /* ERA */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
AR = AR ^ Read (Y);
|
||||
break;
|
||||
|
||||
case 006: case 026: case 046: case 066: /* ADD */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
if (dp) { /* double prec? */
|
||||
|
@ -435,6 +444,7 @@ case 006: case 026: case 046: case 066: /* ADD */
|
|||
sc = 0; }
|
||||
else AR = Add16 (AR, Read (Y)); /* no, 16b add */
|
||||
break;
|
||||
|
||||
case 007: case 027: case 047: case 067: /* SUB */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
if (dp) { /* double prec? */
|
||||
|
@ -455,32 +465,38 @@ case 010: case 030: case 050: case 070: /* JST */
|
|||
PCQ_ENTRY;
|
||||
PC = NEWA (PC, Y + 1); /* set new PC */
|
||||
break;
|
||||
|
||||
case 011: case 031: case 051: case 071: /* CAS */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
MB = Read (Y);
|
||||
if (AR == MB) PC = NEWA (PC, PC + 1);
|
||||
else if (SEXT (AR) < SEXT (MB)) PC = NEWA (PC, PC + 2);
|
||||
break;
|
||||
|
||||
case 012: case 032: case 052: case 072: /* IRS */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
MB = (Read (Y) + 1) & DMASK; /* incr, rewrite */
|
||||
Write (MB, Y);
|
||||
if (MB == 0) PC = NEWA (PC, PC + 1); /* skip if zero */
|
||||
break;
|
||||
|
||||
case 013: case 033: case 053: case 073: /* IMA */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
MB = Read (Y);
|
||||
Write (AR, Y); /* A to mem */
|
||||
AR = MB; /* mem to A */
|
||||
break;
|
||||
|
||||
case 015: case 055: /* STX */
|
||||
if (reason = Ea (MB & ~IDX, &Y)) break; /* eff addr */
|
||||
Write (XR, Y); /* store XR */
|
||||
break;
|
||||
|
||||
case 035: case 075: /* LDX */
|
||||
if (reason = Ea (MB & ~IDX, &Y)) break; /* eff addr */
|
||||
XR = Read (Y); /* load XR */
|
||||
break;
|
||||
|
||||
case 016: case 036: case 056: case 076: /* MPY */
|
||||
if (cpu_unit.flags & UNIT_HSA) { /* installed? */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
|
@ -489,6 +505,7 @@ case 016: case 036: case 056: case 076: /* MPY */
|
|||
sc = 0; }
|
||||
else reason = stop_inst;
|
||||
break;
|
||||
|
||||
case 017: case 037: case 057: case 077: /* DIV */
|
||||
if (cpu_unit.flags & UNIT_HSA) { /* installed? */
|
||||
if (reason = Ea (MB, &Y)) break; /* eff addr */
|
||||
|
@ -512,6 +529,7 @@ case 014: /* OCP */
|
|||
reason = t2 >> IOT_V_REASON;
|
||||
turnoff = 0;
|
||||
break;
|
||||
|
||||
case 034: /* SKS */
|
||||
t2 = iotab[MB & DEVMASK] (ioSKS, I_GETFNC (MB), AR);
|
||||
reason = t2 >> IOT_V_REASON;
|
||||
|
@ -519,6 +537,7 @@ case 034: /* SKS */
|
|||
PC = NEWA (PC, PC + 1);
|
||||
turnoff = 0; }
|
||||
break;
|
||||
|
||||
case 054: /* INA */
|
||||
if (MB & INCLRA) AR = 0;
|
||||
t2 = iotab[MB & DEVMASK] (ioINA, I_GETFNC (MB), AR);
|
||||
|
@ -528,6 +547,7 @@ case 054: /* INA */
|
|||
turnoff = 0; }
|
||||
AR = t2 & DMASK; /* data */
|
||||
break;
|
||||
|
||||
case 074: /* OTA */
|
||||
t2 = iotab[MB & DEVMASK] (ioOTA, I_GETFNC (MB), AR);
|
||||
reason = t2 >> IOT_V_REASON;
|
||||
|
@ -606,6 +626,7 @@ case 020:
|
|||
sc = 0; /* clear sc */
|
||||
if ((t1 = (-MB) & SHFMASK) == 0) break; /* shift count */
|
||||
switch (I_GETFNC (MB)) { /* case shift fnc */
|
||||
|
||||
case 000: /* LRL */
|
||||
if (t1 > 32) ut = 0; /* >32? all 0 */
|
||||
else {
|
||||
|
@ -614,6 +635,7 @@ case 020:
|
|||
ut = ut >> t1; } /* log right */
|
||||
PUTDBL_U (ut); /* store A,B */
|
||||
break;
|
||||
|
||||
case 001: /* LRS */
|
||||
if (t1 > 31) t1 = 31; /* limit to 31 */
|
||||
t2 = GETDBL_S (SEXT (AR), BR); /* get A'B signed */
|
||||
|
@ -621,6 +643,7 @@ case 020:
|
|||
t2 = t2 >> t1; /* arith right */
|
||||
PUTDBL_S (t2); /* store A,B */
|
||||
break;
|
||||
|
||||
case 002: /* LRR */
|
||||
t2 = t1 % 32; /* mod 32 */
|
||||
ut = GETDBL_U (AR, BR); /* get A'B */
|
||||
|
@ -628,6 +651,7 @@ case 020:
|
|||
C = (ut >> 31) & 1; /* C = A<1> */
|
||||
PUTDBL_U (ut); /* store A,B */
|
||||
break;
|
||||
|
||||
case 003: /* "long right arot" */
|
||||
if (reason = stop_inst) break; /* stop on undef? */
|
||||
for (t2 = 0; t2 < t1; t2++) { /* bit by bit */
|
||||
|
@ -636,22 +660,26 @@ case 020:
|
|||
((BR & MMASK) >> 1);
|
||||
AR = ((AR & SIGN) | (C << 15)) | (AR >> 1); }
|
||||
break;
|
||||
|
||||
case 004: /* LGR */
|
||||
if (t1 > 16) AR = 0; /* > 16? all 0 */
|
||||
else {
|
||||
C = (AR >> (t1 - 1)) & 1; /* C = last out */
|
||||
AR = (AR >> t1) & DMASK; } /* log right */
|
||||
break;
|
||||
|
||||
case 005: /* ARS */
|
||||
if (t1 > 16) t1 = 16; /* limit to 16 */
|
||||
C = ((SEXT (AR)) >> (t1 - 1)) & 1; /* C = last out */
|
||||
AR = ((SEXT (AR)) >> t1) & DMASK; /* arith right */
|
||||
break;
|
||||
|
||||
case 006: /* ARR */
|
||||
t2 = t1 % 16; /* mod 16 */
|
||||
AR = ((AR >> t2) | (AR << (16 - t2))) & DMASK;
|
||||
C = (AR >> 15) & 1; /* C = A<1> */
|
||||
break;
|
||||
|
||||
case 007: /* "short right arot" */
|
||||
if (reason = stop_inst) break; /* stop on undef? */
|
||||
for (t2 = 0; t2 < t1; t2++) { /* bit by bit */
|
||||
|
@ -669,6 +697,7 @@ case 020:
|
|||
ut = ut << t1; } /* log left */
|
||||
PUTDBL_U (ut); /* store A,B */
|
||||
break;
|
||||
|
||||
case 011: /* LLS */
|
||||
if (t1 > 31) t1 = 31; /* limit to 31 */
|
||||
t2 = GETDBL_S (SEXT (AR), BR); /* get A'B */
|
||||
|
@ -677,6 +706,7 @@ case 020:
|
|||
if ((t2 >> (31 - t1)) != /* shf out = sgn? */
|
||||
((AR & SIGN)? -1: 0)) C = 1;
|
||||
break;
|
||||
|
||||
case 012: /* LLR */
|
||||
t2 = t1 % 32; /* mod 32 */
|
||||
ut = GETDBL_U (AR, BR); /* get A'B */
|
||||
|
@ -684,6 +714,7 @@ case 020:
|
|||
C = ut & 1; /* C = B<16> */
|
||||
PUTDBL_U (ut); /* store A,B */
|
||||
break;
|
||||
|
||||
case 013: /* "long left arot" */
|
||||
if (reason = stop_inst) break; /* stop on undef? */
|
||||
for (t2 = 0; t2 < t1; t2++) { /* bit by bit */
|
||||
|
@ -693,12 +724,14 @@ case 020:
|
|||
if ((AR & SIGN) != ((AR >> 1) & SIGN)) C = 1;
|
||||
AR = AR & DMASK; }
|
||||
break;
|
||||
|
||||
case 014: /* LGL */
|
||||
if (t1 > 16) AR = 0; /* > 16? all 0 */
|
||||
else {
|
||||
C = (AR >> (16 - t1)) & 1; /* C = last out */
|
||||
AR = (AR << t1) & DMASK; } /* log left */
|
||||
break;
|
||||
|
||||
case 015: /* ALS */
|
||||
if (t1 > 16) t1 = 16; /* limit to 16 */
|
||||
t2 = SEXT (AR); /* save AR */
|
||||
|
@ -706,11 +739,13 @@ case 020:
|
|||
if ((t2 >> (16 - t1)) != /* shf out + sgn */
|
||||
((AR & SIGN)? -1: 0)) C = 1;
|
||||
break;
|
||||
|
||||
case 016: /* ALR */
|
||||
t2 = t1 % 16; /* mod 16 */
|
||||
AR = ((AR << t2) | (AR >> (16 - t2))) & DMASK;
|
||||
C = AR & 1; /* C = A<16> */
|
||||
break;
|
||||
|
||||
case 017: /* "short left arot" */
|
||||
if (reason = stop_inst) break; /* stop on undef? */
|
||||
for (t2 = 0; t2 < t1; t2++) { /* bit by bit */
|
||||
|
@ -826,6 +861,7 @@ return;
|
|||
int32 Add16 (int32 v1, int32 v2)
|
||||
{
|
||||
int32 r = v1 + v2;
|
||||
|
||||
C = 0;
|
||||
if (((v1 ^ ~v2) & (v1 ^ r)) & SIGN) C = 1;
|
||||
return (r & DMASK);
|
||||
|
@ -834,6 +870,7 @@ return (r & DMASK);
|
|||
int32 Add31 (int32 v1, int32 v2)
|
||||
{
|
||||
int32 r = v1 + v2;
|
||||
|
||||
C = 0;
|
||||
if (((v1 ^ ~v2) & (v1 ^ r)) & (1u << 30)) C = 1;
|
||||
return r;
|
||||
|
@ -1037,7 +1074,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0) ||
|
||||
(((cpu_unit.flags & UNIT_EXT) == 0) && (val > (NX_AMASK + 1))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_defs.h: Honeywell 316/516 simulator definitions
|
||||
|
||||
Copyright (c) 1999-2002, Robert M. Supnik
|
||||
Copyright (c) 1999-2003, 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"),
|
||||
|
@ -22,6 +22,8 @@
|
|||
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.
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
*/
|
||||
|
||||
#include "sim_defs.h" /* simulator defns */
|
||||
|
@ -40,7 +42,7 @@
|
|||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define X_AMASK (MAXMEMSIZE - 1) /* ext address mask */
|
||||
#define NX_AMASK ((MAXMEMSIZE / 2) - 1) /* nx address mask */
|
||||
#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE)
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
|
||||
/* Architectural constants */
|
||||
|
||||
|
@ -56,8 +58,8 @@
|
|||
|
||||
#define UNIT_V_EXT (UNIT_V_UF + 1) /* extended mem */
|
||||
#define UNIT_V_HSA (UNIT_V_UF + 2) /* high speed arith */
|
||||
#define UNIT_EXT (1 << UNIT_V_EXT)
|
||||
#define UNIT_HSA (1 << UNIT_V_HSA)
|
||||
#define UNIT_EXT (1u << UNIT_V_EXT)
|
||||
#define UNIT_HSA (1u << UNIT_V_HSA)
|
||||
|
||||
/* Instruction format */
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: H316 Simulator Usage
|
||||
Date: 15-Mar-2003
|
||||
Date: 20-Apr-2003
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_lp.c: Honeywell 316/516 line printer
|
||||
|
||||
Copyright (c) 1999-2002, Robert M. Supnik
|
||||
Copyright (c) 1999-2003, 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,34 +25,10 @@
|
|||
|
||||
lpt line printer
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
*/
|
||||
|
||||
#include "h316_defs.h"
|
||||
#define LPT_WIDTH 120 /* width */
|
||||
#define LPT_SCAN (LPT_WIDTH / 2) /* words/scan */
|
||||
#define LPT_DRUM 64 /* drum rows */
|
||||
#define LPT_SVCSH 01 /* shuttle */
|
||||
#define LPT_SVCPA 02 /* paper advance */
|
||||
|
||||
extern int32 dev_ready, dev_enable;
|
||||
extern int32 stop_inst;
|
||||
int32 lpt_wdpos = 0; /* word position */
|
||||
int32 lpt_drpos = 0; /* drum position */
|
||||
int32 lpt_crpos = 0; /* carriage position */
|
||||
int32 lpt_svcst = 0; /* service state */
|
||||
int32 lpt_svcch = 0; /* service channel */
|
||||
int32 lpt_xfer = 0; /* transfer flag */
|
||||
int32 lpt_prdn = 1; /* printing done */
|
||||
char lpt_buf[LPT_WIDTH + 1] = { 0 }; /* line buffer */
|
||||
int32 lpt_xtime = 5; /* transfer time */
|
||||
int32 lpt_etime = 50; /* end of scan time */
|
||||
int32 lpt_ptime = 5000; /* paper adv time */
|
||||
int32 lpt_stopioe = 0; /* stop on error */
|
||||
t_stat lpt_svc (UNIT *uptr);
|
||||
t_stat lpt_reset (DEVICE *dptr);
|
||||
|
||||
/* The Series 16 line printer is an unbuffered Analex shuttle printer.
|
||||
The Series 16 line printer is an unbuffered Analex shuttle printer.
|
||||
Because it was unbuffered, the CPU had to scan out an entire line's
|
||||
worth of characters (60 words) for every character on the print drum
|
||||
(64 characters). Because it was a shuttle printer, the entire
|
||||
|
@ -81,8 +57,36 @@ t_stat lpt_reset (DEVICE *dptr);
|
|||
lpt_svcch channel for paper advance (0 = no adv)
|
||||
lpt_xfer transfer ready flag
|
||||
lpt_prdn printing done flag
|
||||
*/
|
||||
|
||||
LPT data structures
|
||||
#include "h316_defs.h"
|
||||
|
||||
#define LPT_WIDTH 120 /* width */
|
||||
#define LPT_SCAN (LPT_WIDTH / 2) /* words/scan */
|
||||
#define LPT_DRUM 64 /* drum rows */
|
||||
#define LPT_SVCSH 01 /* shuttle */
|
||||
#define LPT_SVCPA 02 /* paper advance */
|
||||
|
||||
extern int32 dev_ready, dev_enable;
|
||||
extern int32 stop_inst;
|
||||
|
||||
int32 lpt_wdpos = 0; /* word position */
|
||||
int32 lpt_drpos = 0; /* drum position */
|
||||
int32 lpt_crpos = 0; /* carriage position */
|
||||
int32 lpt_svcst = 0; /* service state */
|
||||
int32 lpt_svcch = 0; /* service channel */
|
||||
int32 lpt_xfer = 0; /* transfer flag */
|
||||
int32 lpt_prdn = 1; /* printing done */
|
||||
char lpt_buf[LPT_WIDTH + 1] = { 0 }; /* line buffer */
|
||||
int32 lpt_xtime = 5; /* transfer time */
|
||||
int32 lpt_etime = 50; /* end of scan time */
|
||||
int32 lpt_ptime = 5000; /* paper adv time */
|
||||
int32 lpt_stopioe = 0; /* stop on error */
|
||||
|
||||
t_stat lpt_svc (UNIT *uptr);
|
||||
t_stat lpt_reset (DEVICE *dptr);
|
||||
|
||||
/* LPT data structures
|
||||
|
||||
lpt_dev LPT device descriptor
|
||||
lpt_unit LPT unit descriptor
|
||||
|
@ -103,7 +107,7 @@ REG lpt_reg[] = {
|
|||
{ ORDATA (SVCST, lpt_svcst, 2) },
|
||||
{ ORDATA (SVCCH, lpt_svcch, 2) },
|
||||
{ BRDATA (BUF, lpt_buf, 8, 8, 120) },
|
||||
{ DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (XTIME, lpt_xtime, 24), PV_LEFT },
|
||||
{ DRDATA (ETIME, lpt_etime, 24), PV_LEFT },
|
||||
{ DRDATA (PTIME, lpt_ptime, 24), PV_LEFT },
|
||||
|
@ -115,7 +119,6 @@ DEVICE lpt_dev = {
|
|||
1, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &lpt_reset,
|
||||
NULL, NULL, NULL };
|
||||
|
||||
|
||||
/* IO routine */
|
||||
|
||||
|
@ -141,6 +144,7 @@ case ioOCP: /* OCP */
|
|||
default:
|
||||
return IOBADFNC (dat); }
|
||||
break;
|
||||
|
||||
case ioSKS: /* SKS */
|
||||
switch (fnc) { /* case on fnc */
|
||||
case 000: /* if xfer rdy */
|
||||
|
@ -180,6 +184,7 @@ case ioSKS: /* SKS */
|
|||
default:
|
||||
return IOBADFNC (dat); }
|
||||
break;
|
||||
|
||||
case ioOTA: /* OTA */
|
||||
if (fnc) return IOBADFNC (dat); /* only fnc 0 */
|
||||
if (lpt_xfer) { /* xfer ready? */
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
tty 316/516-33 teleprinter
|
||||
clk/options 316/516-12 real time clocks/internal options
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
01-Mar-03 RMS Added SET/SHOW CLK FREQ support
|
||||
22-Dec-02 RMS Added break support
|
||||
01-Nov-02 RMS Added 7b/8b support to terminal
|
||||
|
@ -87,7 +88,7 @@ REG ptr_reg[] = {
|
|||
{ ORDATA (BUF, ptr_unit.buf, 8) },
|
||||
{ FLDATA (READY, dev_ready, INT_V_PTR) },
|
||||
{ FLDATA (ENABLE, dev_enable, INT_V_PTR) },
|
||||
{ DRDATA (POS, ptr_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
|
||||
{ NULL } };
|
||||
|
@ -114,7 +115,7 @@ REG ptp_reg[] = {
|
|||
{ FLDATA (READY, dev_ready, INT_V_PTP) },
|
||||
{ FLDATA (ENABLE, dev_enable, INT_V_PTP) },
|
||||
{ FLDATA (POWER, ptp_power, 0) },
|
||||
{ DRDATA (POS, ptp_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
||||
{ DRDATA (PWRTIME, ptp_ptime, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
||||
|
@ -147,9 +148,9 @@ REG tty_reg[] = {
|
|||
{ FLDATA (MODE, tty_mode, 0) },
|
||||
{ FLDATA (READY, dev_ready, INT_V_TTY) },
|
||||
{ FLDATA (ENABLE, dev_enable, INT_V_TTY) },
|
||||
{ DRDATA (KPOS, tty_unit[TTI].pos, 32), PV_LEFT },
|
||||
{ DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TPOS, tty_unit[TTO].pos, 32), PV_LEFT },
|
||||
{ DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TTIME, tty_unit[TTO].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
|
@ -164,7 +165,7 @@ DEVICE tty_dev = {
|
|||
2, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tty_reset,
|
||||
NULL, NULL, NULL };
|
||||
|
||||
|
||||
/* CLK data structures
|
||||
|
||||
clk_dev CLK device descriptor
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* h316_sys.c: Honeywell 316/516 simulator interface
|
||||
|
||||
Copyright (c) 1999-2002, Robert M Supnik
|
||||
Copyright (c) 1999-2003, 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.
|
||||
|
||||
12-Mar-03 RMS Added logical name support
|
||||
02-Feb-03 RMS Fixed last cycle bug in DMA output (found by Mike Gemeny)
|
||||
22-Nov-02 RMS Added 21MX IOP support
|
||||
24-Oct-02 RMS Fixed bugs in IOP and extended instructions
|
||||
|
@ -2493,7 +2494,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > PASIZE) || ((val & 07777) != 0) ||
|
||||
(!(uptr->flags & UNIT_21MX) && (val > 32768)))
|
||||
|
@ -2567,9 +2568,11 @@ for (i = 0; cdptr = sim_devices[i]; i++) {
|
|||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp && !(dptr->flags & DEV_DIS) &&
|
||||
(chkp != dibp) && (dno == dibp->devno)) {
|
||||
printf ("%s device number conflict, devno = %d\n", dptr->name, dno);
|
||||
printf ("%s device number conflict, devno = %d\n",
|
||||
sim_dname (dptr), dno);
|
||||
if (sim_log) fprintf (sim_log,
|
||||
"%s device number conflict, devno = %d\n", dptr->name, dno);
|
||||
"%s device number conflict, devno = %d\n",
|
||||
sim_dname (dptr), dno);
|
||||
return TRUE; } } } }
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_defs.h: HP 2100 simulator definitions
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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.
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
24-Oct-02 RMS Added indirect address interrupt
|
||||
08-Feb-02 RMS Added DMS definitions
|
||||
01-Feb-02 RMS Added terminal multiplexor support
|
||||
|
@ -52,7 +53,7 @@
|
|||
/* Memory */
|
||||
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE)
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
#define VA_N_SIZE 15 /* virtual addr size */
|
||||
#define VASIZE (1 << VA_N_SIZE)
|
||||
#define VAMASK (VASIZE - 1) /* virt addr mask */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_dp.c: HP 2100 12557A/13210A disk simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,8 @@
|
|||
dp 12557A 2871 disk subsystem
|
||||
13210A 7900 disk subsystem
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
Fixed bug(s) in boot (found by Terry Newton)
|
||||
10-Nov-02 RMS Added BOOT command, fixed numerous bugs
|
||||
15-Jan-02 RMS Fixed INIT handling (found by Bill McDermith)
|
||||
10-Jan-02 RMS Fixed f(x)write call (found by Bill McDermith)
|
||||
|
@ -239,7 +241,7 @@ REG dpc_reg[] = {
|
|||
DP_NUMDRV, PV_LEFT | REG_HRO) },
|
||||
{ URDATA (UFNC, dpc_unit[0].FNC, 8, 8, 0,
|
||||
DP_NUMDRV, REG_HRO) },
|
||||
{ URDATA (CAPAC, dpc_unit[0].capac, 10, 31, 0,
|
||||
{ URDATA (CAPAC, dpc_unit[0].capac, 10, T_ADDR_W, 0,
|
||||
DP_NUMDRV, PV_LEFT | REG_HRO) },
|
||||
{ ORDATA (DEVNO, dpc_dib.devno, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
|
@ -311,6 +313,7 @@ return dat;
|
|||
int32 dpcio (int32 inst, int32 IR, int32 dat)
|
||||
{
|
||||
int32 i, devc, fnc, drv;
|
||||
int32 devd = dpd_dib.devno;
|
||||
|
||||
devc = IR & I_DEVMASK; /* get device no */
|
||||
switch (inst) { /* case on opcode */
|
||||
|
@ -340,21 +343,24 @@ case ioCTL: /* control clear/set */
|
|||
sim_cancel (&dpd_unit); /* cancel dch */
|
||||
dpd_xfer = 0; /* clr dch xfer */
|
||||
dpc_busy = 0; } /* clr cch busy */
|
||||
else if (!CTL (devc)) { /* set and was clr? */
|
||||
else { /* STC */
|
||||
setCTL (devc); /* set ctl */
|
||||
if (!CMD (devc)) { /* is cmd clr? */
|
||||
setCMD (devc); /* set cmd */
|
||||
drv = CW_GETDRV (dpc_obuf); /* get fnc, drv */
|
||||
fnc = CW_GETFNC (dpc_obuf); /* from cmd word */
|
||||
switch (fnc) { /* case on fnc */
|
||||
case FNC_STA: /* rd sta */
|
||||
if (dp_ctype) { clrFLG (devd); } /* 13210? clr dch flag */
|
||||
case FNC_SEEK: case FNC_CHK: /* seek, check */
|
||||
case FNC_STA: case FNC_AR: /* rd sta, addr rec */
|
||||
case FNC_AR: /* addr rec */
|
||||
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
|
||||
break;
|
||||
case FNC_RD: case FNC_WD: /* read, write */
|
||||
case FNC_REF: case FNC_INIT: /* refine, init */
|
||||
dp_goc (fnc, drv, dpc_ctime); /* sched drive */
|
||||
break;
|
||||
} /* end case */
|
||||
break; } /* end case */
|
||||
}
|
||||
} /* end else */
|
||||
break;
|
||||
default:
|
||||
|
@ -469,7 +475,7 @@ case FNC_AR1: /* arec, need hd/sec */
|
|||
break;
|
||||
|
||||
case FNC_STA: /* read status */
|
||||
if (CMD (devd)) { /* dch active? */
|
||||
if (CMD (devd) || dp_ctype) { /* dch act or 13210? */
|
||||
if (dpc_unit[drv].flags & UNIT_ATT) { /* attached? */
|
||||
dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */
|
||||
if (dp_ctype) dpd_ibuf = /* 13210? */
|
||||
|
@ -480,6 +486,7 @@ case FNC_STA: /* read status */
|
|||
dpd_ibuf = dpd_ibuf | STA_ERR;
|
||||
setFLG (devd); /* set dch flg */
|
||||
clrCMD (devd); /* clr dch cmd */
|
||||
clrCMD (devc); /* clr cch cmd */
|
||||
dpc_sta[drv] = dpc_sta[drv] & /* clr sta flags */
|
||||
~(STA_ATN | STA_1ST | STA_OVR |
|
||||
STA_RWU | STA_ACU | STA_EOC |
|
||||
|
@ -545,7 +552,9 @@ case FNC_SEEK3: /* waiting for flag */
|
|||
if (dpc_busy || FLG (devc)) { /* ctrl busy? wait */
|
||||
uptr->FNC = FNC_SEEK3; /* next state */
|
||||
sim_activate (uptr, dpc_xtime); }
|
||||
else setFLG (devc); /* set cch flg */
|
||||
else {
|
||||
setFLG (devc); /* set cch flg */
|
||||
clrCMD (devc); } /* clear cmd */
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_REF: /* refine sector */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_dq.c: HP 2100 12565A disk simulator
|
||||
|
||||
Copyright (c) 1993-2002, Bill McDermith
|
||||
Copyright (c) 1993-2003, Bill McDermith
|
||||
|
||||
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 @@
|
|||
|
||||
dq 12565A 2883 disk system
|
||||
|
||||
25-Apr-03 RMS Fixed bug in status check
|
||||
10-Nov-02 RMS Added boot command, rebuilt like 12559/13210
|
||||
09-Jan-02 WOM Copied dp driver and mods for 2883
|
||||
|
||||
|
@ -303,9 +304,10 @@ case ioCTL: /* control clear/set */
|
|||
sim_cancel (&dqd_unit); /* cancel dch */
|
||||
dqd_xfer = 0; /* clr dch xfer */
|
||||
dqc_busy = 0; } /* clr busy */
|
||||
else if (!CTL (devc)) { /* set and was clr? */
|
||||
else { /* STC */
|
||||
setCTL (devc); /* set ctl */
|
||||
if (!CMD (devc)) { /* cmd clr? */
|
||||
setCMD (devc); /* set cmd, ctl */
|
||||
setCTL (devc);
|
||||
drv = CW_GETDRV (dqc_obuf); /* get fnc, drv */
|
||||
fnc = CW_GETFNC (dqc_obuf); /* from cmd word */
|
||||
switch (fnc) { /* case on fnc */
|
||||
|
@ -319,8 +321,8 @@ case ioCTL: /* control clear/set */
|
|||
case FNC_RA: case FNC_WA: /* rd addr, wr addr */
|
||||
case FNC_AS: /* address skip */
|
||||
dq_goc (fnc, drv, dqc_ctime); /* sched drive */
|
||||
break;
|
||||
} /* end case */
|
||||
break; } /* end case */
|
||||
} /* end if !CMD */
|
||||
} /* end else */
|
||||
break;
|
||||
default:
|
||||
|
@ -451,6 +453,7 @@ case FNC_STA: /* read status */
|
|||
if (drv) dqd_ibuf = dqd_ibuf | STA_DID;
|
||||
setFLG (devd); /* set dch flg */
|
||||
clrCMD (devd); /* clr dch cmd */
|
||||
clrCMD (devc); /* clr cch cmd */
|
||||
dqc_sta[drv] = dqc_sta[drv] & /* clr sta flags */
|
||||
~(STA_DTE | STA_FLG | STA_AER | STA_EOC | STA_ERR);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_dr.c: HP 2100 12606B/12610B fixed head disk/drum simulator
|
||||
|
||||
Copyright (c) 1993-2000, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -284,7 +284,7 @@ da = ((trk * DR_NUMSC) + sec) * DR_NUMWD;
|
|||
if (drc_cw & CW_WR) { /* write? */
|
||||
if ((da < uptr->capac) && (sec < DR_NUMSC)) {
|
||||
*(((uint16 *) uptr->filebuf) + da + drd_ptr) = drd_obuf;
|
||||
if (((t_addr) (da + drd_ptr)) >= uptr->hwmark)
|
||||
if (((uint32) (da + drd_ptr)) >= uptr->hwmark)
|
||||
uptr->hwmark = da + drd_ptr + 1; }
|
||||
drd_ptr = dr_incda (trk, sec, drd_ptr); /* inc disk addr */
|
||||
if (CMD (devd)) { /* dch active? */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_fp.c: HP 2100 floating point instructions
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2003, 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 @@
|
|||
|
||||
ipli, iplo 12556B interprocessor link pair
|
||||
|
||||
09-May-03 RMS Added network device flag
|
||||
31-Jan-03 RMS Links are full duplex (found by Mike Gemeny)
|
||||
*/
|
||||
|
||||
|
@ -113,7 +114,7 @@ DEVICE ipli_dev = {
|
|||
1, 10, 31, 1, 16, 16,
|
||||
&tmxr_ex, &tmxr_dep, &ipl_reset,
|
||||
&ipl_boot, &ipl_attach, &ipl_detach,
|
||||
&ipli_dib, DEV_DISABLE | DEV_DIS };
|
||||
&ipli_dib, DEV_NET | DEV_DISABLE | DEV_DIS };
|
||||
|
||||
/* IPLO data structures
|
||||
|
||||
|
@ -139,7 +140,7 @@ DEVICE iplo_dev = {
|
|||
1, 10, 31, 1, 16, 16,
|
||||
&tmxr_ex, &tmxr_dep, &ipl_reset,
|
||||
&ipl_boot, &ipl_attach, &ipl_detach,
|
||||
&iplo_dib, DEV_DISABLE | DEV_DIS };
|
||||
&iplo_dib, DEV_NET | DEV_DISABLE | DEV_DIS };
|
||||
|
||||
/* Interprocessor link I/O routines */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_lps.c: HP 2100 12653A line printer simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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 @@
|
|||
lps 12653A 2767 line printer
|
||||
(based on 12556B microcircuit interface)
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
24-Oct-02 RMS Added microcircuit test features
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
03-Dec-01 RMS Changed DEVNO to use extended SET/SHOW
|
||||
|
@ -72,7 +73,7 @@ REG lps_reg[] = {
|
|||
{ FLDATA (CTL, lps_dib.ctl, 0) },
|
||||
{ FLDATA (FLG, lps_dib.flg, 0) },
|
||||
{ FLDATA (FBF, lps_dib.fbf, 0) },
|
||||
{ DRDATA (POS, lps_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lps_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (CTIME, lps_ctime, 31), PV_LEFT },
|
||||
{ DRDATA (PTIME, lps_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, lps_stopioe, 0) },
|
||||
|
@ -159,7 +160,7 @@ if (fputc (c, lps_unit.fileref) == EOF) {
|
|||
perror ("LPS I/O error");
|
||||
clearerr (lps_unit.fileref);
|
||||
return SCPE_IOERR; }
|
||||
lps_unit.pos = ftell (lps_unit.fileref); /* update pos */
|
||||
lps_unit.pos = lps_unit.pos + 1; /* update pos */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_lpt.c: HP 2100 12845A line printer simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt 12845A line printer
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
24-Oct-02 RMS Cloned from 12653A
|
||||
*/
|
||||
|
||||
|
@ -74,7 +75,7 @@ REG lpt_reg[] = {
|
|||
{ FLDATA (FLG, lpt_dib.flg, 0) },
|
||||
{ FLDATA (FBF, lpt_dib.fbf, 0) },
|
||||
{ DRDATA (LCNT, lpt_lcnt, 7) },
|
||||
{ DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (CTIME, lpt_ctime, 31), PV_LEFT },
|
||||
{ DRDATA (PTIME, lpt_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_ms.c: HP 2100 13181A/13183A magnetic tape simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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,9 @@
|
|||
ms 13181A 7970B 800bpi nine track magnetic tape
|
||||
13183A 7970E 1600bpi nine track magnetic tape
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
28-Feb-03 RMS Revised for magtape library
|
||||
18-Oct-02 RMS Added BOOT command, added 13183A support
|
||||
30-Sep-02 RMS Revamped error handling
|
||||
29-Aug-02 RMS Added end of medium support
|
||||
|
@ -200,7 +203,7 @@ REG msc_reg[] = {
|
|||
{ FLDATA (CTL, msc_dib.ctl, 0) },
|
||||
{ FLDATA (FLG, msc_dib.flg, 0) },
|
||||
{ FLDATA (FBF, msc_dib.fbf, 0) },
|
||||
{ URDATA (POS, msc_unit[0].pos, 10, 32, 0, MS_NUMDR, PV_LEFT) },
|
||||
{ URDATA (POS, msc_unit[0].pos, 10, T_ADDR_W, 0, MS_NUMDR, PV_LEFT) },
|
||||
{ URDATA (FNC, msc_unit[0].FNC, 8, 8, 0, MS_NUMDR, REG_HRO) },
|
||||
{ URDATA (UST, msc_unit[0].UST, 8, 12, 0, MS_NUMDR, REG_HRO) },
|
||||
{ DRDATA (CTIME, msc_ctime, 24), REG_NZ + PV_LEFT },
|
||||
|
@ -215,6 +218,8 @@ REG msc_reg[] = {
|
|||
MTAB msc_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV, 0, NULL, "13181A",
|
||||
&ms_settype, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV, 1, NULL, "13183A",
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
mt 12559A 3030 nine track magnetic tape
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
28-Feb-03 RMS Revised for magtape library
|
||||
30-Sep-02 RMS Revamped error handling
|
||||
28-Aug-02 RMS Added end of medium support
|
||||
|
@ -138,6 +140,8 @@ REG mtd_reg[] = {
|
|||
MTAB mtd_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
|
||||
&hp_setdev, &hp_showdev, &mtd_dev },
|
||||
{ 0 } };
|
||||
|
@ -169,7 +173,7 @@ REG mtc_reg[] = {
|
|||
{ FLDATA (FBF, mtc_dib.fbf, 0) },
|
||||
{ FLDATA (DTF, mtc_dtf, 0) },
|
||||
{ FLDATA (FSVC, mtc_1st, 0) },
|
||||
{ DRDATA (POS, mtc_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, mtc_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (CTIME, mtc_ctime, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (GTIME, mtc_gtime, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (XTIME, mtc_xtime, 24), REG_NZ + PV_LEFT },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_mux.c: HP 2100 12920A terminal multiplexor simulator
|
||||
|
||||
Copyright (c) 2002, Robert M Supnik
|
||||
Copyright (c) 2002-2003, 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
|
||||
|
||||
09-May-03 RMS Added network device flag
|
||||
01-Nov-02 RMS Added 7B/8B support
|
||||
22-Aug-02 RMS Updated for changes to sim_tmxr
|
||||
|
||||
|
@ -231,7 +232,7 @@ DEVICE muxu_dev = {
|
|||
1, 10, 31, 1, 8, 8,
|
||||
&tmxr_ex, &tmxr_dep, &mux_reset,
|
||||
NULL, &mux_attach, &mux_detach,
|
||||
&muxu_dib, DEV_DISABLE };
|
||||
&muxu_dib, DEV_NET | DEV_DISABLE };
|
||||
|
||||
/* MUXL data structures
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_stddev.c: HP2100 standard devices simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -28,6 +28,7 @@
|
|||
tty 12531C buffered teleprinter interface
|
||||
clk 12539C time base generator
|
||||
|
||||
25-Apr-03 RMS Added extended file support
|
||||
22-Dec-02 RMS Added break support
|
||||
01-Nov-02 RMS Revised BOOT command for IBL ROMs
|
||||
Fixed bug in TTY reset, TTY starts in input mode
|
||||
|
@ -133,7 +134,7 @@ REG ptr_reg[] = {
|
|||
{ FLDATA (CTL, ptr_dib.ctl, 0) },
|
||||
{ FLDATA (FLG, ptr_dib.flg, 0) },
|
||||
{ FLDATA (FBF, ptr_dib.fbf, 0) },
|
||||
{ DRDATA (POS, ptr_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
|
||||
{ ORDATA (DEVNO, ptr_dib.devno, 6), REG_HRO },
|
||||
|
@ -170,7 +171,7 @@ REG ptp_reg[] = {
|
|||
{ FLDATA (CTL, ptp_dib.ctl, 0) },
|
||||
{ FLDATA (FLG, ptp_dib.flg, 0) },
|
||||
{ FLDATA (FBF, ptp_dib.fbf, 0) },
|
||||
{ DRDATA (POS, ptp_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
||||
{ ORDATA (DEVNO, ptp_dib.devno, 6), REG_HRO },
|
||||
|
@ -214,11 +215,11 @@ REG tty_reg[] = {
|
|||
{ FLDATA (CTL, tty_dib.ctl, 0) },
|
||||
{ FLDATA (FLG, tty_dib.flg, 0) },
|
||||
{ FLDATA (FBF, tty_dib.fbf, 0) },
|
||||
{ DRDATA (KPOS, tty_unit[TTI].pos, 32), PV_LEFT },
|
||||
{ DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TPOS, tty_unit[TTO].pos, 32), PV_LEFT },
|
||||
{ DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TTIME, tty_unit[TTO].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (PPOS, tty_unit[TTP].pos, 32), PV_LEFT },
|
||||
{ DRDATA (PPOS, tty_unit[TTP].pos, T_ADDR_W), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ttp_stopioe, 0) },
|
||||
{ ORDATA (DEVNO, tty_dib.devno, 6), REG_HRO },
|
||||
{ NULL } };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hp2100_sys.c: HP 2100 simulator interface
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_cd.c: IBM 1402 card reader/punch
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -35,6 +35,7 @@
|
|||
Cards are represented as ASCII text streams terminated by newlines.
|
||||
This allows cards to be created and edited as normal files.
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
30-Jan-02 RMS New zero footprint card bootstrap from Van Snyder
|
||||
29-Nov-01 RMS Added read only unit support
|
||||
|
@ -70,7 +71,7 @@ REG cdr_reg[] = {
|
|||
{ FLDATA (ERR, ind[IN_READ], 0) },
|
||||
{ FLDATA (S1, s1sel, 0) },
|
||||
{ FLDATA (S2, s2sel, 0) },
|
||||
{ DRDATA (POS, cdr_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, cdr_unit.wait, 24), PV_LEFT },
|
||||
{ BRDATA (BUF, rbuf, 8, 8, CDR_WIDTH) },
|
||||
{ NULL } };
|
||||
|
@ -95,7 +96,7 @@ REG cdp_reg[] = {
|
|||
{ FLDATA (ERR, ind[IN_PNCH], 0) },
|
||||
{ FLDATA (S4, s4sel, 0) },
|
||||
{ FLDATA (S8, s8sel, 0) },
|
||||
{ DRDATA (POS, cdp_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE cdp_dev = {
|
||||
|
@ -119,10 +120,10 @@ UNIT stack_unit[] = {
|
|||
{ UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) } };
|
||||
|
||||
REG stack_reg[] = {
|
||||
{ DRDATA (POS0, stack_unit[0].pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS1, stack_unit[1].pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS28, stack_unit[2].pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS4, stack_unit[4].pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS0, stack_unit[0].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (POS1, stack_unit[1].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (POS28, stack_unit[2].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (POS4, stack_unit[4].pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE stack_dev = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_cpu.c: IBM 1401 CPU simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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,12 @@
|
|||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
16-Mar-03 RMS 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
|
||||
03-Jun-03 RMS Added 1311 support
|
||||
22-May-02 RMS Added multiply and divide
|
||||
30-Dec-01 RMS Added old PC queue
|
||||
|
@ -142,7 +148,9 @@ uint8 M[MAXMEMSIZE] = { 0 }; /* main memory */
|
|||
int32 saved_IS = 0; /* saved IS */
|
||||
int32 AS = 0; /* AS */
|
||||
int32 BS = 0; /* BS */
|
||||
int32 D = 0; /* modifier */
|
||||
int32 as_err = 0, bs_err = 0; /* error flags */
|
||||
int32 hb_pend = 0; /* halt br pending */
|
||||
uint16 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
|
||||
int32 pcq_p = 0; /* PC queue ptr */
|
||||
REG *pcq_r = NULL; /* PC queue reg ptr */
|
||||
|
@ -194,6 +202,7 @@ REG cpu_reg[] = {
|
|||
{ DRDATA (BS, BS, 14), PV_LEFT },
|
||||
{ FLDATA (ASERR, as_err, 0) },
|
||||
{ FLDATA (BSERR, bs_err, 0) },
|
||||
{ ORDATA (D, D, 7) },
|
||||
{ FLDATA (SSA, ssa, 0) },
|
||||
{ FLDATA (SSB, ind[IN_SSB], 0) },
|
||||
{ FLDATA (SSC, ind[IN_SSC], 0) },
|
||||
|
@ -208,8 +217,9 @@ REG cpu_reg[] = {
|
|||
{ FLDATA (OVF, ind[IN_OVF], 0) },
|
||||
{ FLDATA (IOCHK, iochk, 0) },
|
||||
{ FLDATA (PRCHK, prchk, 0) },
|
||||
{ FLDATA (HBPEND, hb_pend, 0) },
|
||||
{ BRDATA (ISQ, pcq, 10, 14, PCQ_SIZE), REG_RO+REG_CIRC },
|
||||
{ ORDATA (ISQP, pcq_p, 6), REG_HRO },
|
||||
{ DRDATA (ISQP, pcq_p, 6), REG_HRO },
|
||||
{ ORDATA (WRU, sim_int_char, 8) },
|
||||
{ NULL } };
|
||||
|
||||
|
@ -271,7 +281,7 @@ const int32 op_table[64] = {
|
|||
L1 | L8 | BREQ | BBE, /* branch if bit eq */
|
||||
0, /* illegal */
|
||||
L1 | L4 | L7 | AREQ | BREQ, /* 30: move zones */
|
||||
L7 | AREQ | BREQ, /* move supress zero */
|
||||
L1 | L4 | L7 | AREQ | BREQ, /* move supress zero */
|
||||
0, /* illegal */
|
||||
L1 | L4 | L7 | AREQ | BREQ | NOWM, /* set word mark */
|
||||
L7 | AREQ | BREQ | MDV, /* divide */
|
||||
|
@ -305,7 +315,7 @@ const int32 op_table[64] = {
|
|||
L1 | L4 | L7 | AREQ | MLS, /* 70: store B addr */
|
||||
0, /* illegal */
|
||||
L1 | L4 | L7 | AREQ | BREQ, /* zero and add */
|
||||
HNOP | L1 | L4, /* halt */
|
||||
HNOP | L1 | L4 | L7, /* halt */
|
||||
L1 | L4 | L7 | AREQ | BREQ, /* clear word mark */
|
||||
0, /* illegal */
|
||||
0, /* illegal */
|
||||
|
@ -456,8 +466,8 @@ static const int32 mtf_mod[] = { BCD_B, BCD_E, BCD_M, BCD_R, BCD_U, -1 };
|
|||
t_stat sim_instr (void)
|
||||
{
|
||||
extern int32 sim_interval;
|
||||
int32 IS, D, ilnt, flags;
|
||||
int32 op, xa, t, wm, dev, unit;
|
||||
int32 IS, ilnt, flags;
|
||||
int32 op, xa, t, wm, ioind, dev, unit;
|
||||
int32 a, b, i, asave, bsave;
|
||||
int32 carry, lowprd, sign, ps;
|
||||
int32 quo, ahigh, qs;
|
||||
|
@ -466,16 +476,21 @@ t_stat reason, r1, r2;
|
|||
|
||||
/* Restore saved state */
|
||||
|
||||
|
||||
IS = saved_IS;
|
||||
if (as_err) AS = AS | BA; /* flag bad addresses */
|
||||
if (bs_err) BS = BS | BA;
|
||||
as_err = bs_err = 0; /* reset error flags */
|
||||
D = 0;
|
||||
reason = 0;
|
||||
|
||||
/* Main instruction fetch/decode loop */
|
||||
|
||||
while (reason == 0) { /* loop until halted */
|
||||
|
||||
if (hb_pend) { /* halt br pending? */
|
||||
hb_pend = 0; /* clear flag */
|
||||
BRANCH; } /* execute branch */
|
||||
|
||||
saved_IS = IS; /* commit prev instr */
|
||||
if (sim_interval <= 0) { /* check clock queue */
|
||||
if (reason = sim_process_event ()) break; }
|
||||
|
@ -500,7 +515,7 @@ if (op == OP_SAR) BS = AS; /* SAR? save ASTAR */
|
|||
PP (IS);
|
||||
|
||||
if ((t = M[IS]) & WM) goto CHECK_LENGTH; /* WM? 1 char inst */
|
||||
D = t; /* could be D char */
|
||||
D = ioind = t; /* could be D char, % */
|
||||
AS = hun_table[t]; /* could be A addr */
|
||||
PP (IS); /* if %xy, BA is set */
|
||||
|
||||
|
@ -519,7 +534,7 @@ if ((t = M[IS]) & WM) { /* WM? 3 char inst */
|
|||
AS = AS + one_table[t]; /* finish A addr */
|
||||
unit = (t == BCD_ZERO)? 0: t; /* save char as unit */
|
||||
xa = (AS >> V_INDEX) & M_INDEX; /* get index reg */
|
||||
if (xa && (D != BCD_PERCNT) && (cpu_unit.flags & XSA)) { /* indexed? */
|
||||
if (xa && (ioind != BCD_PERCNT) && (cpu_unit.flags & XSA)) { /* indexed? */
|
||||
AS = AS + hun_table[M[xa] & CHAR] + ten_table[M[xa + 1] & CHAR] +
|
||||
one_table[M[xa + 2] & CHAR];
|
||||
AS = (AS & INDEXMASK) % MAXMEMSIZE; }
|
||||
|
@ -570,7 +585,7 @@ switch (op) { /* case on opcode */
|
|||
until A WM
|
||||
MCM: copy A to B, preserving B WM, fetch fetch
|
||||
until record or group mark
|
||||
MSZ: copy A to B, clearing B WM, until A WM; fetch fetch
|
||||
MCS: copy A to B, clearing B WM, until A WM; fetch fetch
|
||||
reverse scan and suppress leading zeroes
|
||||
MN: copy A char digit to B char digit, fetch fetch
|
||||
preserving B zone and WM
|
||||
|
@ -580,21 +595,23 @@ switch (op) { /* case on opcode */
|
|||
|
||||
case OP_MCW: /* move char */
|
||||
if (ilnt >= 8) { /* I/O form? */
|
||||
reason = iodisp (dev, unit, MD_NORM, D);
|
||||
if (ioind != BCD_PERCNT) reason = STOP_INVL;
|
||||
else reason = iodisp (dev, unit, MD_NORM, D);
|
||||
break; }
|
||||
if (ADDR_ERR (AS)) { /* check A addr */
|
||||
reason = STOP_INVA;
|
||||
break; }
|
||||
do {
|
||||
M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */
|
||||
wm = M[AS] | M[BS];
|
||||
M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */
|
||||
MM (AS); MM (BS); } /* decr pointers */
|
||||
while ((wm & WM) == 0); /* stop on A,B WM */
|
||||
break;
|
||||
|
||||
case OP_LCA: /* load char */
|
||||
if (ilnt >= 8) { /* I/O form? */
|
||||
reason = iodisp (dev, unit, MD_WM, D);
|
||||
if (ioind != BCD_PERCNT) reason = STOP_INVL;
|
||||
else reason = iodisp (dev, unit, MD_WM, D);
|
||||
break; }
|
||||
if (ADDR_ERR (AS)) { /* check A addr */
|
||||
reason = STOP_INVA;
|
||||
|
@ -607,18 +624,18 @@ case OP_LCA: /* load char */
|
|||
|
||||
case OP_MCM: /* move to rec/group */
|
||||
do {
|
||||
M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */
|
||||
t = M[AS];
|
||||
M[BS] = (M[BS] & WM) | (M[AS] & CHAR); /* move char */
|
||||
PP (AS); PP (BS); } /* incr pointers */
|
||||
while (((t & CHAR) != BCD_RECMRK) && (t != (BCD_GRPMRK + WM)));
|
||||
break;
|
||||
|
||||
case OP_MSZ: /* move suppress zero */
|
||||
case OP_MCS: /* move suppress zero */
|
||||
bsave = BS; /* save B start */
|
||||
qzero = 1; /* set suppress */
|
||||
do {
|
||||
M[BS] = M[AS] & ((BS != bsave)? CHAR: DIGIT); /* copy char */
|
||||
wm = M[AS];
|
||||
M[BS] = M[AS] & ((BS != bsave)? CHAR: DIGIT); /* copy char */
|
||||
MM (AS); MM (BS); } /* decr pointers */
|
||||
while ((wm & WM) == 0); /* stop on A WM */
|
||||
if (reason) break; /* addr err? stop */
|
||||
|
@ -631,7 +648,8 @@ case OP_MSZ: /* move suppress zero */
|
|||
else if (((t == BCD_DECIMAL) && (cpu_unit.flags & EPE)) ||
|
||||
(t <= BCD_NINE)) qzero = 0;
|
||||
else qzero = 1; }
|
||||
while (BS <= bsave);
|
||||
while (BS < bsave);
|
||||
PP (BS); /* BS end is B+1 */
|
||||
break;
|
||||
|
||||
case OP_MN: /* move numeric */
|
||||
|
@ -644,10 +662,7 @@ case OP_MZ: /* move zone */
|
|||
MM (AS); MM (BS); /* decr pointers */
|
||||
break;
|
||||
|
||||
/* Compare
|
||||
|
||||
A and B are checked in fetch
|
||||
*/
|
||||
/* Compare - A and B are checked in fetch */
|
||||
|
||||
case OP_C: /* compare */
|
||||
if (ilnt != 1) { /* if not chained */
|
||||
|
@ -993,7 +1008,9 @@ case OP_MCE: /* edit */
|
|||
while ((b & WM) == 0);
|
||||
|
||||
M[BS] = M[BS] & ~WM; /* clear B WM */
|
||||
if (!qdollar && !(qdecimal && qzero)) break; /* rescan again? */
|
||||
if (!qdollar && !(qdecimal && qzero)) { /* rescan again? */
|
||||
BS++; /* BS = addr WM + 1 */
|
||||
break; }
|
||||
if (qdecimal && qzero) qdollar = 0; /* no digits? clr $ */
|
||||
|
||||
/* Edit pass 3 (extended print only) - from right to left */
|
||||
|
@ -1208,7 +1225,7 @@ case OP_NOP: /* nop */
|
|||
break;
|
||||
|
||||
case OP_H: /* halt */
|
||||
if (ilnt >= 4) { BRANCH; } /* branch if called */
|
||||
if (ilnt == 4) hb_pend = 1; /* set pending branch */
|
||||
reason = STOP_HALT; /* stop simulator */
|
||||
saved_IS = IS; /* commit instruction */
|
||||
break;
|
||||
|
@ -1355,10 +1372,12 @@ t_stat cpu_reset (DEVICE *dptr)
|
|||
{
|
||||
int32 i;
|
||||
|
||||
for (i = 0; i < 64; i++) ind[i] = 0;
|
||||
ind[IN_UNC] = 1;
|
||||
AS = 0; as_err = 1;
|
||||
BS = 0; bs_err = 1;
|
||||
for (i = 0; i < 64; i++) ind[i] = 0; /* clr indicators */
|
||||
ind[IN_UNC] = 1; /* ind[0] always on */
|
||||
AS = 0; as_err = 1; /* clear AS */
|
||||
BS = 0; bs_err = 1; /* clear BS */
|
||||
D = 0; /* clear D */
|
||||
hb_pend = 0; /* no halt br */
|
||||
pcq_r = find_reg ("ISQ", NULL, dptr);
|
||||
if (pcq_r) pcq_r->qptr = 0;
|
||||
else return SCPE_IERR;
|
||||
|
@ -1389,7 +1408,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE) || ((val % 1000) != 0))
|
||||
return SCPE_ARG;
|
||||
|
|
|
@ -1,3 +1,28 @@
|
|||
/* i1401_dat.h: IBM 1401 character conversion tables
|
||||
|
||||
Copyright (c) 1993-2003, 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.
|
||||
*/
|
||||
|
||||
/* ASCII to BCD conversion */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_defs.h: IBM 1401 simulator definitions
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,7 +23,8 @@
|
|||
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.
|
||||
|
||||
03-Jun-03 RMS Added 1311 support
|
||||
16-Mar-03 RMS Fixed mnemonic for MCS
|
||||
03-Jun-02 RMS Added 1311 support
|
||||
14-Apr-99 RMS Converted t_addr to unsigned
|
||||
|
||||
This simulator is based on the 1401 simulator written by Len Fehskens
|
||||
|
@ -79,7 +80,7 @@
|
|||
#define LPT_WIDTH 132 /* line print width */
|
||||
#define CCT_LNT 132 /* car ctrl length */
|
||||
#define INQ_WIDTH 80 /* inq term width */
|
||||
#define ADDR_ERR(x) (((t_addr) (x)) >= MEMSIZE)
|
||||
#define ADDR_ERR(x) (((uint32) (x)) >= MEMSIZE)
|
||||
|
||||
/* Binary address format
|
||||
|
||||
|
@ -205,7 +206,7 @@
|
|||
#define OP_BWZ 025 /* branch wm or zone */
|
||||
#define OP_BBE 026 /* branch bit equal */
|
||||
#define OP_MZ 030 /* move zone */
|
||||
#define OP_MSZ 031 /* move suppr zeroes */
|
||||
#define OP_MCS 031 /* move suppr zeroes */
|
||||
#define OP_SWM 033 /* set word mark */
|
||||
#define OP_DIV 034 /* divide */
|
||||
#define OP_SS 042 /* select stacker */
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: IBM 1401 Simulator Usage
|
||||
Date: 15-Nov-2002
|
||||
Date: 20-Apr-2003
|
||||
|
||||
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-2002, Robert M Supnik
|
||||
Original code published in 1993-2003, written by Robert M Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -161,7 +161,7 @@ interrupt system.
|
|||
OVF 1 overflow indicator
|
||||
IOCHK 1 I/O check switch
|
||||
PRCHK 1 process check switch
|
||||
ISQ 1 IS prior to last branch;
|
||||
ISQ[0:63] 14 IS prior to last branch;
|
||||
most recent IS change first
|
||||
WRU 8 interrupt character
|
||||
|
||||
|
@ -184,11 +184,11 @@ the POS register specifies the number of the next data item to be read or
|
|||
written. Thus, by changing POS, the user can backspace or advance these
|
||||
devices.
|
||||
|
||||
The reader/punch registers are:
|
||||
The card reader registers are:
|
||||
|
||||
device name size comments
|
||||
name size comments
|
||||
|
||||
CDR LAST 1 last card indicator
|
||||
LAST 1 last card indicator
|
||||
ERR 1 error indicator
|
||||
S1 1 stacker 1 select flag
|
||||
S2 1 stacker 2 select flag
|
||||
|
@ -196,11 +196,15 @@ The reader/punch registers are:
|
|||
TIME 24 delay window for stacker select
|
||||
BUF[0:79] 8 reader buffer
|
||||
|
||||
CDP ERR 1 error indicator
|
||||
The card punch registers are:
|
||||
|
||||
ERR 1 error indicator
|
||||
S4 1 stacker 4 select flag
|
||||
S8 1 stacker 8 select flag
|
||||
|
||||
STKR POS0 32 position, normal reader stack
|
||||
The stacker registers are:
|
||||
|
||||
POS0 32 position, normal reader stack
|
||||
POS1 32 position, reader stacker 1
|
||||
POS2 32 position, shared stacker 2/8
|
||||
POS4 32 position, punch stacker 4
|
||||
|
@ -423,7 +427,7 @@ devices can only accept single character input, without word marks.
|
|||
|
||||
2.7 Character Sets
|
||||
|
||||
The IBM 1401 used a 6b character code called BCD (binary coded decimal).
|
||||
The IBM 1401 uses a 6b character code called BCD (binary coded decimal).
|
||||
Some of the characters have no equivalent in ASCII and require different
|
||||
representations:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_dp.c: IBM 1311 disk simulator
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_iq.c: IBM 1407 inquiry terminal
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_lp.c: IBM 1403 line printer simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt 1403 line printer
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
13-Apr-01 RMS Revised for register arrays
|
||||
*/
|
||||
|
@ -87,7 +88,7 @@ UNIT lpt_unit = {
|
|||
|
||||
REG lpt_reg[] = {
|
||||
{ FLDATA (ERR, ind[IN_LPT], 0) },
|
||||
{ DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ BRDATA (CCT, cct, 8, 32, CCT_LNT) },
|
||||
{ DRDATA (LINES, lines, 8), PV_LEFT },
|
||||
{ DRDATA (CCTP, cctptr, 8), PV_LEFT },
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
mt 7-track magtape
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
15-Mar-03 RMS Fixed end-of-record on load read yet again
|
||||
28-Feb-03 RMS Modified for magtape library
|
||||
31-Oct-02 RMS Added error record handling
|
||||
10-Oct-02 RMS Fixed end-of-record on load read writes WM plus GM
|
||||
|
@ -101,17 +104,19 @@ UNIT mt_unit[] = {
|
|||
REG mt_reg[] = {
|
||||
{ FLDATA (END, ind[IN_END], 0) },
|
||||
{ FLDATA (ERR, ind[IN_TAP], 0) },
|
||||
{ DRDATA (POS1, mt_unit[1].pos, 32), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS2, mt_unit[2].pos, 32), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS3, mt_unit[3].pos, 32), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS4, mt_unit[4].pos, 32), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS5, mt_unit[5].pos, 32), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS6, mt_unit[6].pos, 32), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS1, mt_unit[1].pos, T_ADDR_W), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS2, mt_unit[2].pos, T_ADDR_W), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS3, mt_unit[3].pos, T_ADDR_W), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS4, mt_unit[4].pos, T_ADDR_W), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS5, mt_unit[5].pos, T_ADDR_W), PV_LEFT + REG_RO },
|
||||
{ DRDATA (POS6, mt_unit[6].pos, T_ADDR_W), PV_LEFT + REG_RO },
|
||||
{ NULL } };
|
||||
|
||||
MTAB mt_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE mt_dev = {
|
||||
|
@ -173,6 +178,12 @@ return mt_map_status (st);
|
|||
mod = modifier character
|
||||
Outputs:
|
||||
status = status
|
||||
|
||||
Fine point: after a read, the system writes a group mark just
|
||||
beyond the end of the record. However, first it checks for a
|
||||
GM + WM; if present, the GM + WM is not changed. Otherwise,
|
||||
an MCW read sets a GM, preserving the current WM; while an LCA
|
||||
read sets a GM and clears the WM.
|
||||
*/
|
||||
|
||||
t_stat mt_io (int32 unit, int32 flag, int32 mod)
|
||||
|
@ -211,8 +222,9 @@ case BCD_R: /* read */
|
|||
if (ADDR_ERR (BS)) { /* check next BS */
|
||||
BS = BA | (BS % MAXMEMSIZE);
|
||||
return STOP_WRAP; } }
|
||||
if (flag == MD_WM) M[BS] = WM | BCD_GRPMRK; /* load? set WM */
|
||||
else M[BS] = (M[BS] & WM) | BCD_GRPMRK; /* move? save WM */
|
||||
if (M[BS] != (BCD_GRPMRK + WM)) { /* not GM+WM at end? */
|
||||
if (flag == MD_WM) M[BS] = BCD_GRPMRK; /* LCA: clear WM */
|
||||
else M[BS] = (M[BS] & WM) | BCD_GRPMRK; } /* MCW: save WM */
|
||||
BS++; /* adv BS */
|
||||
if (ADDR_ERR (BS)) { /* check final BS */
|
||||
BS = BA | (BS % MAXMEMSIZE);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1401_sys.c: IBM 1401 simulator interface
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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.
|
||||
|
||||
16-Mar-03 RMS Fixed mnemonic for MCS
|
||||
03-Jun-02 RMS Added 1311 support
|
||||
18-May-02 RMS Added -D feature from Van Snyder
|
||||
26-Jan-02 RMS Fixed H, NOP with no trailing wm (found by Van Snyder)
|
||||
|
@ -158,7 +159,7 @@ const char *opcode[64] = {
|
|||
NULL, "R", "W", "WR", "P", "RP", "WP", "WRP",
|
||||
"RF", "WF", NULL, "MA", "MUL", NULL, NULL, NULL,
|
||||
NULL, "CS", "S", NULL, "MTF", "BWZ", "BBE", NULL,
|
||||
"MZ", "MSZ", NULL, "SWM", "DIV", NULL, NULL, NULL,
|
||||
"MZ", "MCS", NULL, "SWM", "DIV", NULL, NULL, NULL,
|
||||
NULL, NULL, "SS", "LCA", "MCW", "NOP", NULL, "MCM",
|
||||
"SAR", NULL, "ZS", NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, "A", "B", "C", "MN", "MCE", "CC", NULL,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_cd.c: IBM 1622 card reader/punch
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,8 @@
|
|||
cdr 1622 card reader
|
||||
cdp 1622 card punch
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
|
||||
Cards are represented as ASCII text streams terminated by newlines.
|
||||
This allows cards to be created and edited as normal files.
|
||||
*/
|
||||
|
@ -62,7 +64,7 @@ UNIT cdr_unit = {
|
|||
|
||||
REG cdr_reg[] = {
|
||||
{ FLDATA (LAST, ind[IN_LAST], 0) },
|
||||
{ DRDATA (POS, cdr_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE cdr_dev = {
|
||||
|
@ -82,7 +84,7 @@ UNIT cdp_unit = {
|
|||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) };
|
||||
|
||||
REG cdp_reg[] = {
|
||||
{ DRDATA (POS, cdp_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE cdp_dev = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_cpu.c: IBM 1620 CPU simulator
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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.
|
||||
|
||||
25-Apr-03 RMS Changed t_addr to uint32 throughout
|
||||
18-Oct-02 RMS Fixed bugs in invalid result testing (found by Hans Pufal)
|
||||
|
||||
The simulated register state for the IBM 1620 is:
|
||||
|
@ -760,7 +761,7 @@ case OP_BCXM:
|
|||
break; }
|
||||
reason = add_field (GET_IDXADDR (idx), QAR, FALSE, TRUE, &sta);
|
||||
if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL;
|
||||
if ((ind[IN_EZ] == 0) && (sta == ADD_NOCRY)) { /* ~z, ~c, ~schg? */
|
||||
if ((ind[IN_EZ] == 0) && (sta == ADD_NOCRY)) { /* ~z, ~c, ~sign chg? */
|
||||
BRANCH (PAR); } /* branch */
|
||||
break;
|
||||
|
||||
|
@ -954,10 +955,10 @@ cnt = 0; /* count depth */
|
|||
do { indir = indir & M[alast]; /* get indirect */
|
||||
if (cvt_addr (alast, lnt, FALSE, &addr)) /* cvt addr to bin */
|
||||
return STOP_INVPDG; /* bad? */
|
||||
idx = get_idx (ADDR_S (alast, 1)); /* get index addr */
|
||||
idx = get_idx (ADDR_S (alast, 1)); /* get index reg num */
|
||||
if (indexok && (idx > 0)) { /* indexable? */
|
||||
idxa = GET_IDXADDR (idx); /* get idx addr */
|
||||
if (cvt_addr (idxa, ADDR_LEN, TRUE, &idxv)) /* cvt idx */
|
||||
idxa = GET_IDXADDR (idx); /* get idx reg addr */
|
||||
if (cvt_addr (idxa, ADDR_LEN, TRUE, &idxv)) /* cvt idx reg */
|
||||
return STOP_INVPDG;
|
||||
addr = addr + idxv; /* add in index */
|
||||
if (addr < 0) addr = addr + 100000; } /* -? 10's comp */
|
||||
|
@ -1009,10 +1010,10 @@ return SCPE_OK;
|
|||
|
||||
t_stat get_idx (uint32 aidx)
|
||||
{
|
||||
int32 i, idx = 0;
|
||||
int32 i, idx;
|
||||
|
||||
if (idxe == 0) return -1; /* indexing off? */
|
||||
for (i = 0; i < 3; i++) { /* 3 flags worth */
|
||||
for (i = idx = 0; i < 3; i++) { /* 3 flags worth */
|
||||
if (M[aidx] & FLAG) idx = idx | (1 << i); /* test flag */
|
||||
MM (aidx); } /* next digit */
|
||||
return idx;
|
||||
|
@ -1040,7 +1041,7 @@ return;
|
|||
|
||||
t_stat xmt_field (uint32 d, uint32 s, uint32 skp)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
uint8 t;
|
||||
|
||||
do { t = M[d] = M[s] & (FLAG | DIGIT); /* copy src to dst */
|
||||
|
@ -1054,7 +1055,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat xmt_record (uint32 d, uint32 s, t_bool cpy)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
|
||||
while ((M[s] & REC_MARK) != REC_MARK) { /* until rec mark */
|
||||
M[d] = M[s] & (FLAG | DIGIT); /* copy src to dst */
|
||||
|
@ -1083,7 +1084,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat xmt_divd (uint32 d, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
|
||||
M[d] = M[s] & DIGIT; /* first w/o flag */
|
||||
do { MM (d); MM (s); /* decr mem addrs */
|
||||
|
@ -1097,7 +1098,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat xmt_tns (uint32 d, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
uint8 t, z;
|
||||
|
||||
t = M[s] & DIGIT; /* get units */
|
||||
|
@ -1120,7 +1121,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat xmt_tnf (uint32 d, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
uint8 t;
|
||||
|
||||
t = M[s]; /* get 1st digit */
|
||||
|
@ -1242,7 +1243,7 @@ t_stat mul_field (uint32 mpc, uint32 mpy)
|
|||
int32 i;
|
||||
uint32 pro; /* prod pointer */
|
||||
uint32 mpyd, mpyf; /* mpy digit, flag */
|
||||
t_addr cnt = 0; /* counter */
|
||||
uint32 cnt = 0; /* counter */
|
||||
uint8 sign; /* final sign */
|
||||
t_stat r;
|
||||
|
||||
|
@ -1299,7 +1300,7 @@ uint32 mpcd, mpcf; /* mpc digit, flag */
|
|||
uint32 prwp; /* prod working ptr */
|
||||
uint32 prod; /* product digit */
|
||||
uint32 cry; /* carry */
|
||||
t_addr mpcc, cryc; /* counters */
|
||||
uint32 mpcc, cryc; /* counters */
|
||||
|
||||
mptb = MUL_TABLE + ((mpyd <= 4)? (mpyd * 2): /* set mpy table 100's, */
|
||||
(((mpyd - 5) * 2) + 100)); /* 1's digits */
|
||||
|
@ -1535,7 +1536,7 @@ t_stat div_one_digit (uint32 dvd, uint32 dvr, uint32 max,
|
|||
uint32 dvrp, dvrd, dvrf; /* dvr ptr, dig, flag */
|
||||
uint32 dvdp, dvdd; /* dvd ptr, dig */
|
||||
uint32 qd, cry; /* quo dig, carry */
|
||||
t_addr cnt;
|
||||
uint32 cnt;
|
||||
|
||||
for (qd = 0; qd < max; qd++) { /* devel quo dig */
|
||||
dvrp = dvr; /* divisor ptr */
|
||||
|
@ -1592,7 +1593,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat or_field (uint32 d, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
int32 t;
|
||||
|
||||
ind[IN_EZ] = 1; /* assume result zero */
|
||||
|
@ -1607,7 +1608,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat and_field (uint32 d, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
int32 t;
|
||||
|
||||
ind[IN_EZ] = 1; /* assume result zero */
|
||||
|
@ -1622,7 +1623,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat xor_field (uint32 d, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
int32 t;
|
||||
|
||||
ind[IN_EZ] = 1; /* assume result zero */
|
||||
|
@ -1637,7 +1638,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat com_field (uint32 d, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0;
|
||||
uint32 cnt = 0;
|
||||
int32 t;
|
||||
|
||||
ind[IN_EZ] = 1; /* assume result zero */
|
||||
|
@ -1667,7 +1668,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat oct_to_dec (uint32 tbl, uint32 s)
|
||||
{
|
||||
t_addr cnt = 0, tblc;
|
||||
uint32 cnt = 0, tblc;
|
||||
uint32 i, sd, sf, tf, sign;
|
||||
t_stat r;
|
||||
|
||||
|
@ -1715,7 +1716,7 @@ t_stat dec_to_oct (uint32 d, uint32 tbl, int32 *ez)
|
|||
{
|
||||
uint32 sign, octd, t;
|
||||
t_bool first = TRUE;
|
||||
t_addr ctr = 0;
|
||||
uint32 ctr = 0;
|
||||
t_stat r;
|
||||
|
||||
sign = M[PROD_AREA + PROD_AREA_LEN - 1] & FLAG; /* input sign */
|
||||
|
@ -1794,7 +1795,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE) || ((val % 1000) != 0))
|
||||
return SCPE_ARG;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_defs.h: IBM 1620 simulator definitions
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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"),
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: IBM 1620 Simulator Usage
|
||||
Date: 15-Nov-2002
|
||||
Date: 15-Apr-2003
|
||||
|
||||
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-2002, Robert M Supnik
|
||||
Original code published in 1993-2003, written by Robert M Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -138,10 +138,10 @@ standard on the Model 2.
|
|||
|
||||
If memory size is being reduced, and the memory being truncated contains
|
||||
non-zero data, the simulator asks for confirmation. Data in the truncated
|
||||
portion of memory is lost. Initially, memory size is 16K, and all special
|
||||
features are enabled.
|
||||
portion of memory is lost. Initially, the CPU is a Model I, memory size is
|
||||
20K, and indirect addressing, editing instructions, and divide are enabled.
|
||||
|
||||
Memory is implemented as 5 bit BCD characters, as follows:
|
||||
Memory is implemented as 5 bit BCD digits, as follows:
|
||||
|
||||
4 3 2 1 0
|
||||
|
||||
|
@ -177,8 +177,8 @@ interrupt system.
|
|||
IND[0:99] 1 indicator array
|
||||
IAE 1 indirect address enable (Model 2 only)
|
||||
IDXE 1 indexing enable (Model 2 only)
|
||||
IDXB 1 indexinb band select (Model 2 only)
|
||||
IR1Q 1 IR1 prior to last branch;
|
||||
IDXB 1 indexing band select (Model 2 only)
|
||||
IR1Q[0:63] 16 IR1 prior to last branch;
|
||||
most recent IR1 change first
|
||||
WRU 8 interrupt character
|
||||
|
||||
|
@ -198,12 +198,12 @@ key is pressed. The typewriter has no errors.
|
|||
|
||||
2.3 1621 Paper Tape Reader (PTR)
|
||||
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||
register specifies the number of the next data item to be read. Thus,
|
||||
by changing POS, the user can backspace or advance the reader.
|
||||
The paper tape reader (PTR) reads data from a disk file. The POS register
|
||||
specifies the number of the next data item to be read. Thus, by changing
|
||||
POS, the user can backspace or advance the reader.
|
||||
|
||||
The paper tape reader supports the BOOT command. BOOT PTR starts the
|
||||
specified instruction sequence at location 0.
|
||||
standard paper tape boot sequence at location 0.
|
||||
|
||||
The paper tape reader implements these registers:
|
||||
|
||||
|
@ -252,8 +252,8 @@ Error handling is as follows:
|
|||
The IBM 1402 card/reader punch is simulated as two independent devices:
|
||||
the card reader (CDR) and the card punch (CDP).
|
||||
|
||||
The card reader supports the BOOT command. BOOT CDR starts the
|
||||
specified instruction sequence at location 0.
|
||||
The card reader supports the BOOT command. BOOT CDR starts the standard
|
||||
card boot sequence at location 0.
|
||||
|
||||
The card reader reads data from a disk file, while the punch writes data
|
||||
to a disk file. Cards are simulated as ASCII text lines with terminating
|
||||
|
@ -436,11 +436,11 @@ marks the end of the immediate Q operand; and the flags over digits
|
|||
The IBM 1620 uses single digits to represent numbers, and pairs of
|
||||
digits to represent characters (alphameric coding). Only a small
|
||||
number of the 256 possible alphameric codings have legitimate values.
|
||||
Further, the translation between alphameric and devices varied
|
||||
from device to device. The simulator implements a code called
|
||||
Further, the translation between alphameric and devices varied from
|
||||
device to device. The simulator implements a code called 1620 ASCII,
|
||||
which allows all 64 possible card codes to be represented by upper
|
||||
case ASCII characters. In addition, lower case alphabetic
|
||||
characters are accepted on input as equivalent to upper case.
|
||||
case ASCII characters. In addition, lower case alphabetic characters
|
||||
are accepted on input as equivalent to upper case.
|
||||
|
||||
Card code PT code RA RN LPT WA ASCII representation
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_dp.c: IBM 1311 disk simulator
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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"),
|
||||
|
@ -83,7 +83,7 @@ extern uint8 ind[NUM_IND];
|
|||
extern UNIT cpu_unit;
|
||||
|
||||
int32 dp_stop = 1; /* disk err stop */
|
||||
t_addr dp_ba = 0; /* buffer addr */
|
||||
uint32 dp_ba = 0; /* buffer addr */
|
||||
|
||||
t_stat dp_reset (DEVICE *dptr);
|
||||
t_stat dp_rdadr (UNIT *uptr, int32 sec, int32 qnr, int32 qwc);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_fp.c: IBM 1620 floating point simulator
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_lp.c: IBM 1443 line printer simulator
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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"),
|
||||
|
@ -24,6 +24,8 @@
|
|||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
lpt 1443 line printer
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
*/
|
||||
|
||||
#include "i1620_defs.h"
|
||||
|
@ -75,7 +77,7 @@ REG lpt_reg[] = {
|
|||
{ FLDATA (PRCH9, ind[IN_PRCH9], 0) },
|
||||
{ FLDATA (PRCH12, ind[IN_PRCH12], 0) },
|
||||
{ FLDATA (PRBSY, ind[IN_PRBSY], 0) },
|
||||
{ DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ BRDATA (CCT, cct, 8, 32, CCT_LNT) },
|
||||
{ DRDATA (CCTP, cct_ptr, 8), PV_LEFT },
|
||||
{ DRDATA (CCTL, cct_lnt, 8), REG_RO + PV_LEFT },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_pt.c: IBM 1621/1624 paper tape reader/punch simulator
|
||||
|
||||
Copyright (c) 2002, Robert M Supnik
|
||||
Copyright (c) 2002-2003, 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 @@
|
|||
|
||||
ptr 1621 paper tape reader
|
||||
ptp 1624 paper tape punch
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
*/
|
||||
|
||||
#include "i1620_defs.h"
|
||||
|
@ -58,7 +60,7 @@ UNIT ptr_unit = {
|
|||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0) };
|
||||
|
||||
REG ptr_reg[] = {
|
||||
{ DRDATA (POS, ptr_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE ptr_dev = {
|
||||
|
@ -78,7 +80,7 @@ UNIT ptp_unit = {
|
|||
UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) };
|
||||
|
||||
REG ptp_reg[] = {
|
||||
{ DRDATA (POS, ptp_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
DEVICE ptp_dev = {
|
||||
|
@ -197,7 +199,7 @@ const int8 alp_to_ptp[256] = {
|
|||
|
||||
t_stat ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1)
|
||||
{
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
int8 mc;
|
||||
uint8 ptc;
|
||||
t_stat r, inv = SCPE_OK;
|
||||
|
@ -243,7 +245,7 @@ return STOP_RWRAP;
|
|||
|
||||
t_stat btr (uint32 op, uint32 pa, uint32 f0, uint32 f1)
|
||||
{
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
uint8 ptc;
|
||||
t_stat r, inv = SCPE_OK;
|
||||
|
||||
|
@ -333,7 +335,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat ptp (uint32 op, uint32 pa, uint32 f0, uint32 f1)
|
||||
{
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
int8 ptc;
|
||||
uint8 z, d;
|
||||
t_stat r;
|
||||
|
@ -366,7 +368,7 @@ return STOP_RWRAP;
|
|||
|
||||
t_stat btp (uint32 op, uint32 pa, uint32 f0, uint32 f1)
|
||||
{
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
uint8 ptc, z, d;
|
||||
t_stat r;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_sys.c: IBM 1620 simulator interface
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* i1620_tty.c: IBM 1620 typewriter
|
||||
|
||||
Copyright (c) 2002, Robert M. Supnik
|
||||
Copyright (c) 2002-2003, 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"),
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
10-May-02 BLK Fixed bug in MDX instruction
|
||||
27-Mar-02 BLK Made BOSC work even in short form
|
||||
16-Aug-02 BLK Fixed bug in multiply instruction; didn't work with negative values
|
||||
18-Mar-03 BLK Fixed bug in divide instruction; didn't work with negative values
|
||||
|
||||
The register state for the IBM 1130 CPU is:
|
||||
|
||||
|
@ -883,7 +884,7 @@ t_stat sim_instr (void)
|
|||
break;
|
||||
|
||||
case 0x11: /* --- AD - Add Double --- */
|
||||
src = ((ACC << 16) + (EXT & 0xFFFF));
|
||||
src = ((ACC << 16) | (EXT & 0xFFFF));
|
||||
src2 = (ReadW(eaddr) << 16) + ReadW(eaddr|1);
|
||||
dst = src + src2;
|
||||
ACC = (dst >> 16) & 0xFFFF;
|
||||
|
@ -905,7 +906,7 @@ t_stat sim_instr (void)
|
|||
break;
|
||||
|
||||
case 0x13: /* --- SD - Subtract Double --- */
|
||||
src = ((ACC << 16) + (EXT & 0xFFFF));
|
||||
src = ((ACC << 16) | (EXT & 0xFFFF));
|
||||
src2 = (ReadW(eaddr) << 16) + ReadW(eaddr|1);
|
||||
dst = src - src2;
|
||||
ACC = (dst >> 16) & 0xFFFF;
|
||||
|
@ -918,9 +919,9 @@ t_stat sim_instr (void)
|
|||
|
||||
case 0x14: /* --- M - Multiply --- */
|
||||
if ((src = ACC & 0xFFFF) & 0x8000) /* sign extend the values */
|
||||
src |= 0xFFFF0000;
|
||||
src |= ~0xFFFF;
|
||||
if ((src2 = ReadW(eaddr)) & 0x8000)
|
||||
src2 |= 0xFFFF0000;
|
||||
src2 |= ~0xFFFF;
|
||||
|
||||
dst = src * src2;
|
||||
ACC = (dst >> 16) & 0xFFFF; /* split the results */
|
||||
|
@ -928,8 +929,10 @@ t_stat sim_instr (void)
|
|||
break;
|
||||
|
||||
case 0x15: /* --- D - Divide --- */
|
||||
src = ((ACC << 16) + EXT);
|
||||
src2 = ReadW(eaddr);
|
||||
src = ((ACC << 16) | (EXT & 0xFFFF));
|
||||
if ((src2 = ReadW(eaddr)) & 0x8000)
|
||||
src2 |= ~0xFFFF; /* oops: sign extend was missing, fixed 18Mar03 */
|
||||
|
||||
if (src2 == 0)
|
||||
V = 1; /* divide by zero just sets overflow, ACC & EXT are undefined */
|
||||
else {
|
||||
|
@ -1251,7 +1254,7 @@ void xio_error (char *msg)
|
|||
* register_cmd - add a command to the extensible command table
|
||||
* ------------------------------------------------------------------------ */
|
||||
|
||||
t_stat register_cmd (char *name, t_stat (*action)(), int arg, char *help)
|
||||
t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
@ -16,7 +16,12 @@
|
|||
NOTE - there is a problem with this code. The Device Status Word (DSW) is
|
||||
computed from current conditions when requested by an XIO load status
|
||||
command; the value of DSW available to the simulator's examine & save
|
||||
commands may NOT be accurate. This should probably be fixed.
|
||||
commands may NOT be accurate. This should probably be fixed. (I think there's
|
||||
a way to have the expression evaluator call a routine? That would be one
|
||||
way to solve the problem, the other is to keep DSW up-to-date all the time).
|
||||
|
||||
* Update 2003-02-08: Fixed error in declaration of array list_save, pointed
|
||||
out by Ray Comas.
|
||||
|
||||
* Update 2002-02-29: Added deck-list option. If you issue an attach
|
||||
command and specify the filename as "@filename", the named file is interpreted
|
||||
|
@ -436,8 +441,9 @@ static char tempfile[128];
|
|||
static int cardnum;
|
||||
static int any_punched = 0;
|
||||
|
||||
#define MAXARG 80 /* saved arguments to attach command */
|
||||
static char list_save[MAXARG][10], *list_arg[MAXARG];
|
||||
#define MAXARGLEN 80 /* max length of a saved attach command argument */
|
||||
#define MAXARGS 10 /* max number of arguments to save */
|
||||
static char list_save[MAXARGS][MAXARGLEN], *list_arg[MAXARGLEN];
|
||||
static int list_nargs = 0;
|
||||
|
||||
static int16 punchstation[80];
|
||||
|
@ -497,12 +503,12 @@ t_stat set_active_cr_code (int match)
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat cr_set_code (UNIT *uptr, int32 match, char *cptr, void *desc)
|
||||
static t_stat cr_set_code (UNIT *uptr, int32 match, char *cptr, void *desc)
|
||||
{
|
||||
return set_active_cr_code(match);
|
||||
}
|
||||
|
||||
t_stat cp_set_code (UNIT *uptr, int32 match, char *cptr, void *desc)
|
||||
static t_stat cp_set_code (UNIT *uptr, int32 match, char *cptr, void *desc)
|
||||
{
|
||||
CPCODE *code;
|
||||
int ncode;
|
||||
|
@ -964,7 +970,6 @@ static t_stat cr_attach (UNIT *uptr, char *cptr)
|
|||
// no - don't cancel pending read?
|
||||
// sim_cancel(uptr); /* cancel pending operations */
|
||||
|
||||
|
||||
CLRBIT(uptr->flags, UNIT_QUIET|UNIT_DEBUG); /* set debug/quiet flags */
|
||||
if (sim_switches & SWMASK('D')) SETBIT(uptr->flags, UNIT_DEBUG);
|
||||
else if (sim_switches & SWMASK('Q')) SETBIT(uptr->flags, UNIT_QUIET);
|
||||
|
@ -972,15 +977,15 @@ static t_stat cr_attach (UNIT *uptr, char *cptr)
|
|||
cr_detach(uptr); /* detach file and possibly deckfile */
|
||||
CLRBIT(uptr->flags, UNIT_SCRATCH);
|
||||
|
||||
c = cptr;
|
||||
for (list_nargs = 0; list_nargs < 10; ) { /* extract arguments */
|
||||
c = cptr; /* extract arguments */
|
||||
for (list_nargs = 0; list_nargs < MAXARGS; list_nargs++) {
|
||||
while (*c && (*c <= ' ')) /* skip blanks */
|
||||
c++;
|
||||
|
||||
if (! *c)
|
||||
break; /* all done */
|
||||
|
||||
arg = c; /* save start */
|
||||
|
||||
while (*c && (*c > ' ')) {
|
||||
if (*c == '\'' || *c == '"') { /* quoted string */
|
||||
for (quote = *c++; *c;)
|
||||
|
@ -989,11 +994,12 @@ static t_stat cr_attach (UNIT *uptr, char *cptr)
|
|||
}
|
||||
else c++;
|
||||
}
|
||||
|
||||
if (*c)
|
||||
*c++ = 0; /* term arg at space */
|
||||
|
||||
list_arg[list_nargs] = list_save[list_nargs]; /* set pointer to permanent storage location */
|
||||
strncpy(list_arg[list_nargs++], arg, MAXARG); /* store copy */
|
||||
strncpy(list_arg[list_nargs], arg, MAXARGLEN); /* store copy */
|
||||
}
|
||||
|
||||
if (list_nargs <= 0) /* need at least 1 */
|
||||
|
|
|
@ -271,7 +271,7 @@ void remark_cmd (char *remark);
|
|||
void stuff_cmd (char *cmd);
|
||||
void update_gui (t_bool force);
|
||||
void sim_init (void);
|
||||
t_stat register_cmd (char *name, t_stat (*action)(), int arg, char *help);
|
||||
t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help);
|
||||
|
||||
/* GUI interface routines */
|
||||
t_bool keyboard_is_locked (void);
|
||||
|
|
|
@ -188,7 +188,7 @@ static void Beep (void) // notify user keyboard was locked or key was bad
|
|||
|
||||
// tti_svc - keyboard polling (never stops)
|
||||
|
||||
t_stat tti_svc (UNIT *uptr)
|
||||
static t_stat tti_svc (UNIT *uptr)
|
||||
{
|
||||
int32 temp;
|
||||
|
||||
|
@ -243,7 +243,7 @@ t_stat tti_svc (UNIT *uptr)
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat tti_reset (DEVICE *dptr)
|
||||
static t_stat tti_reset (DEVICE *dptr)
|
||||
{
|
||||
tti_unit.buf = 0;
|
||||
tti_dsw = 0;
|
||||
|
@ -262,7 +262,7 @@ t_bool keyboard_is_locked (void) /* return TRUE if keyboard is not expecting
|
|||
return (tti_dsw & TT_DSW_KEYBOARD_BUSY) == 0;
|
||||
}
|
||||
|
||||
t_stat tto_svc (UNIT *uptr)
|
||||
static t_stat tto_svc (UNIT *uptr)
|
||||
{
|
||||
int32 temp;
|
||||
int ch;
|
||||
|
@ -300,7 +300,7 @@ t_stat tto_svc (UNIT *uptr)
|
|||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat tto_reset (DEVICE *dptr)
|
||||
static t_stat tto_reset (DEVICE *dptr)
|
||||
{
|
||||
tto_unit.buf = 0;
|
||||
tto_dsw = 0;
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
Version: 18 March 2003
|
||||
|
||||
History (partial):
|
||||
|
||||
2003-03-18 Fixed bug in asm1130 that produced an error message
|
||||
with a (legal) offset of +127 in MDX instructions.
|
||||
|
||||
Fixed sign bug in 1130 emulator divide instruction.
|
||||
|
||||
Interim 1130 distribution:
|
||||
--------------------------------------------
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id16_cpu.c: Interdata 16b CPU simulator
|
||||
|
||||
Copyright (c) 2000-2002, Robert M. Supnik
|
||||
Copyright (c) 2000-2003, 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"),
|
||||
|
@ -1683,7 +1683,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || ((val & 0xFFF) != 0) ||
|
||||
(((uint32) val) > ((uptr->flags & UNIT_816E)? MAXMEMSIZE16E: MAXMEMSIZE16)))
|
||||
|
@ -1700,7 +1700,7 @@ return SCPE_OK;
|
|||
|
||||
t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if (!(val & UNIT_816E) && (MEMSIZE > MAXMEMSIZE16)) {
|
||||
MEMSIZE = MAXMEMSIZE16;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id16_dboot.c: Interdata 16b simulator disk bootstrap
|
||||
|
||||
Copyright (c) 2000-2002, Robert M. Supnik
|
||||
Copyright (c) 2000-2003, 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"),
|
||||
|
|
|
@ -1993,7 +1993,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
uint32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE32) || ((val & 0xFFFF) != 0))
|
||||
return SCPE_ARG;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_defs.h: Interdata 16b/32b simulator definitions
|
||||
|
||||
Copyright (c) 2000-2002, Robert M. Supnik
|
||||
Copyright (c) 2000-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -26,6 +26,8 @@
|
|||
The author gratefully acknowledges the help of Carl Friend and Al Kossow,
|
||||
who provided key documents about the Interdata product line.
|
||||
|
||||
21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Feb-03 RMS Changed magtape device default to 0x85
|
||||
*/
|
||||
|
||||
|
@ -52,7 +54,7 @@
|
|||
#define PAMASK32 (MAXMEMSIZE32 - 1)
|
||||
|
||||
#define MEMSIZE (cpu_unit.capac) /* act memory size */
|
||||
#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE)
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
|
||||
/* Single precision floating point registers */
|
||||
|
||||
|
@ -171,8 +173,8 @@ typedef struct dpr dpr_t;
|
|||
|
||||
struct BlockIO {
|
||||
uint32 dfl; /* devno, flags */
|
||||
t_addr cur; /* current addr */
|
||||
t_addr end; /* end addr */
|
||||
uint32 cur; /* current addr */
|
||||
uint32 end; /* end addr */
|
||||
};
|
||||
|
||||
#define BL_RD 0x8000 /* block read */
|
||||
|
@ -466,7 +468,7 @@ typedef struct interdib DIB;
|
|||
|
||||
/* Function prototypes */
|
||||
|
||||
int32 int_chg (uint32 irq, int32 dat, int32 arm);
|
||||
int32 int_chg (uint32 irq, int32 dat, int32 armdis);
|
||||
int32 io_2b (int32 val, int32 pos, int32 old);
|
||||
uint32 IOReadB (uint32 loc);
|
||||
void IOWriteB (uint32 loc, uint32 val);
|
||||
|
|
|
@ -46,8 +46,8 @@ sim/ sim_defs.h
|
|||
sim_tmxr.c
|
||||
|
||||
sim/interdata/ id_defs.h
|
||||
id16_cpu.c [or id32_cpu.c]
|
||||
id16_dboot.c [or id32_dboot.c]
|
||||
id16_cpu.c [id32_cpu.c]
|
||||
id16_dboot.c [id32_dboot.c]
|
||||
id_dp.c
|
||||
id_fd.c
|
||||
id_fp.c
|
||||
|
@ -60,7 +60,7 @@ sim/interdata/ id_defs.h
|
|||
id_tt.c
|
||||
id_ttp.c
|
||||
id_uvc.c
|
||||
id16_sys.c [or id32_sys.c]
|
||||
id16_sys.c [id32_sys.c]
|
||||
|
||||
2. Interdata Features
|
||||
|
||||
|
@ -235,9 +235,6 @@ control registers for the interrupt system.
|
|||
R0..R15 32 active general register set
|
||||
GREG[32] 32 general register sets, 16 x 2
|
||||
FR0..FR14 32 single precision floating point registers
|
||||
if double precision floating point; for
|
||||
microcoded floating point, floating point
|
||||
registers are kept in memory locations 00 - 1F
|
||||
D0H..D14H 32 double precision floating point registers,
|
||||
high order
|
||||
D0L..D14L 32 double precision floating point registers,
|
||||
|
@ -521,8 +518,8 @@ The programmable interval clock (PIC) implements these registers:
|
|||
IENB 1 clock interrupt enable
|
||||
IARM 1 clock interrupt armed
|
||||
|
||||
If the interval requested is longer than 1 msec, and a multiple of
|
||||
1 msec, the programmable clock auto-calibrates; if not, it simply
|
||||
If the interval requested is an exact multiple of 1 msec, the
|
||||
programmable clock auto-calibrates; if not, it simply counts
|
||||
counts instructions.
|
||||
|
||||
2.4.7 Floppy Disk Controller (FD)
|
||||
|
@ -587,7 +584,7 @@ or 8B. In UC mode, lower case input and output characters are converted
|
|||
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 UC mode
|
||||
control with the command SET PASLn DATASET. The defaults are 7b mode
|
||||
and DATASET disabled.
|
||||
|
||||
Once PAS is attached and the simulator is running, the terminals listen
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
dp M46-421 2.5MB/10MB cartridge disk
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
|
||||
*/
|
||||
|
||||
|
@ -151,7 +152,7 @@ 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 */
|
||||
int32 dp_log = 0; /* debug log */
|
||||
uint32 dp_log = 0; /* debug log */
|
||||
uint8 dp_tplte[(2 * DP_NUMDR) + 2]; /* fix/rmv + ctrl + end */
|
||||
|
||||
DEVICE dp_dev;
|
||||
|
@ -210,7 +211,7 @@ REG dp_reg[] = {
|
|||
DP_NUMDR, REG_RO) },
|
||||
{ URDATA (UST, dp_unit[0].STD, 16, 8, 0,
|
||||
DP_NUMDR, REG_RO) },
|
||||
{ URDATA (CAPAC, dp_unit[0].capac, 10, 31, 0,
|
||||
{ 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 },
|
||||
|
@ -513,9 +514,10 @@ uint32 i, p;
|
|||
t_stat r;
|
||||
|
||||
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||
r = attach_unit (uptr, cptr);
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
uptr->CYL = 0;
|
||||
if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */
|
||||
if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK;
|
||||
if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK;
|
||||
for (i = 0; drv_tab[i].surf != 0; i++) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_fd.c: Interdata floppy disk simulator
|
||||
|
||||
Copyright (c) 2001-2002, Robert M Supnik
|
||||
Copyright (c) 2001-2003, 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"),
|
||||
|
@ -275,8 +275,7 @@ return 0;
|
|||
|
||||
t_stat fd_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 i, u, tk, sc, crc, fnc;
|
||||
t_addr da;
|
||||
uint32 i, u, tk, sc, crc, fnc, da;
|
||||
|
||||
u = uptr - fd_dev.units; /* get unit number */
|
||||
fnc = GET_FNC (uptr->FNC); /* get function */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_fp.c: Interdata floating point instructions
|
||||
|
||||
Copyright (c) 2000-2002, Robert M. Supnik
|
||||
Copyright (c) 2000-2003, 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 @@
|
|||
|
||||
idc MSM/IDC disk controller
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
16-Feb-03 RMS Fixed read to test transfer ok before selch operation
|
||||
|
||||
Note: define flag ID_IDC to enable the extra functions of the intelligent
|
||||
|
@ -273,7 +274,7 @@ REG idc_reg[] = {
|
|||
ID_NUMDR, REG_HRO) },
|
||||
{ URDATA (UST, idc_unit[0].STD, 16, 8, 0,
|
||||
ID_NUMDR, REG_RO) },
|
||||
{ URDATA (CAPAC, idc_unit[0].capac, 10, 31, 0,
|
||||
{ URDATA (CAPAC, idc_unit[0].capac, 10, T_ADDR_W, 0,
|
||||
ID_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ HRDATA (DEVNO, idc_dib.dno, 8), REG_HRO },
|
||||
{ HRDATA (SELCH, idc_dib.sch, 2), REG_HRO },
|
||||
|
@ -668,9 +669,10 @@ uint32 i, p;
|
|||
t_stat r;
|
||||
|
||||
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||
r = attach_unit (uptr, cptr);
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
uptr->CYL = 0;
|
||||
if ((r != SCPE_OK) || ((uptr->flags & UNIT_AUTO) == 0)) return r;
|
||||
if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */
|
||||
if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK;
|
||||
if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK;
|
||||
for (i = 0; drv_tab[i].surf != 0; i++) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_io.c: Interdata CPU-independent I/O routines
|
||||
|
||||
Copyright (c) 2001-2002, Robert M. Supnik
|
||||
Copyright (c) 2001-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -23,6 +23,8 @@
|
|||
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.
|
||||
|
||||
21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict
|
||||
|
||||
Interdata I/O devices are defined by a device information block:
|
||||
|
||||
dno base device number
|
||||
|
@ -391,7 +393,7 @@ return 0;
|
|||
|
||||
/* Update device interrupt status */
|
||||
|
||||
int32 int_chg (uint32 irq, int32 dat, int32 arm)
|
||||
int32 int_chg (uint32 irq, int32 dat, int32 armdis)
|
||||
{
|
||||
int32 t = CMD_GETINT (dat); /* get int ctrl */
|
||||
|
||||
|
@ -405,7 +407,7 @@ if (t == CMD_IDSA) { /* disarm? */
|
|||
CLR_ENB (irq);
|
||||
CLR_INT (irq);
|
||||
return 0; }
|
||||
return arm;
|
||||
return armdis;
|
||||
}
|
||||
|
||||
/* Process a 2b field and return unchanged, set, clear, complement */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_lp.c: Interdata line printer
|
||||
|
||||
Copyright (c) 2001-2002, Robert M. Supnik
|
||||
Copyright (c) 2001-2003, 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"),
|
||||
|
@ -24,6 +24,8 @@
|
|||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
lpt M46-206 line printer
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
*/
|
||||
|
||||
#include "id_defs.h"
|
||||
|
@ -94,7 +96,7 @@ REG lpt_reg[] = {
|
|||
{ FLDATA (IREQ, int_req[l_LPT], i_LPT) },
|
||||
{ FLDATA (IENB, int_enb[l_LPT], i_LPT) },
|
||||
{ FLDATA (IARM, lpt_arm, 0) },
|
||||
{ DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (CTIME, lpt_ctime, 24), PV_LEFT },
|
||||
{ DRDATA (STIME, lpt_stime, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
mt M46-494 dual density 9-track magtape controller
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
28-Feb-03 RMS Revised for magtape library
|
||||
20-Feb-03 RMS Fixed read to stop selch on error
|
||||
|
||||
|
@ -135,7 +137,7 @@ REG mt_reg[] = {
|
|||
{ DRDATA (RTIME, mt_rtime, 24), PV_LEFT + REG_NZ },
|
||||
{ URDATA (UST, mt_unit[0].UST, 16, 8, 0, MT_NUMDR, 0) },
|
||||
{ URDATA (CMD, mt_unit[0].UCMD, 16, 8, 0, MT_NUMDR, 0) },
|
||||
{ URDATA (POS, mt_unit[0].pos, 10, 32, 0,
|
||||
{ URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
MT_NUMDR, PV_LEFT | REG_RO) },
|
||||
{ HRDATA (DEVNO, mt_dib.dno, 8), REG_HRO },
|
||||
{ HRDATA (SELCH, mt_dib.sch, 1), REG_HRO },
|
||||
|
@ -144,6 +146,8 @@ REG mt_reg[] = {
|
|||
MTAB mt_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO",
|
||||
&set_dev, &show_dev, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "SELCH", "SELCH",
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
pas Programmable asynchronous line adapter(s)
|
||||
|
||||
09-May-03 RMS Added network device flag
|
||||
|
||||
This module implements up to 32 individual serial interfaces, representing
|
||||
either individual PASLA modules or combinations of the 2-line and 8-line
|
||||
multiplexors, which are functionally very similar. These interfaces are mapped
|
||||
|
@ -160,7 +162,7 @@ DEVICE pas_dev = {
|
|||
1, 10, 31, 1, 16, 8,
|
||||
&tmxr_ex, &tmxr_dep, &pas_reset,
|
||||
NULL, &pas_attach, &pas_detach,
|
||||
&pas_dib, DEV_DISABLE };
|
||||
&pas_dib, DEV_NET | DEV_DISABLE };
|
||||
|
||||
/* PASL data structures
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_pt.c: Interdata paper tape reader
|
||||
|
||||
Copyright (c) 2000-2001, Robert M. Supnik
|
||||
Copyright (c) 2000-2003, 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"),
|
||||
|
@ -24,6 +24,9 @@
|
|||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
pt paper tape reader and punch
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
10-Apr-03 RMS Fixed type problem in ptr service (from Mark Pizzolato)
|
||||
*/
|
||||
|
||||
#include "id_defs.h"
|
||||
|
@ -76,11 +79,11 @@ UNIT pt_unit[] = {
|
|||
REG pt_reg[] = {
|
||||
{ HRDATA (STA, pt_sta, 8) },
|
||||
{ HRDATA (RBUF, pt_unit[PTR].buf, 8) },
|
||||
{ DRDATA (RPOS, pt_unit[PTR].pos, 32), PV_LEFT },
|
||||
{ DRDATA (RPOS, pt_unit[PTR].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (RTIME, pt_unit[PTR].wait, 24), PV_LEFT },
|
||||
{ FLDATA (RSTOP_IOE, ptr_stopioe, 0) },
|
||||
{ HRDATA (PBUF, pt_unit[PTP].buf, 8) },
|
||||
{ DRDATA (PPOS, pt_unit[PTP].pos, 32), PV_LEFT },
|
||||
{ DRDATA (PPOS, pt_unit[PTP].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (PTIME, pt_unit[PTP].wait, 24), PV_LEFT },
|
||||
{ FLDATA (PSTOP_IOE, ptp_stopioe, 0) },
|
||||
{ FLDATA (IREQ, int_req[l_PT], i_PT) },
|
||||
|
@ -164,7 +167,7 @@ return 0;
|
|||
|
||||
t_stat ptr_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 temp;
|
||||
int32 temp;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||
return IORETURN (ptr_stopioe, SCPE_UNATT);
|
||||
|
@ -324,8 +327,7 @@ static uint8 load_rom[] = {
|
|||
|
||||
t_stat pt_dump (FILE *of, char *cptr, char *fnam)
|
||||
{
|
||||
t_addr i, lo, hi;
|
||||
uint32 cs;
|
||||
uint32 i, lo, hi, cs;
|
||||
char *tptr;
|
||||
extern DEVICE cpu_dev;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
tt console
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
11-Jan-03 RMS Added TTP support
|
||||
22-Dec-02 RMS Added break support
|
||||
*/
|
||||
|
@ -83,10 +84,10 @@ UNIT tt_unit[] = {
|
|||
REG tt_reg[] = {
|
||||
{ HRDATA (STA, tt_sta, 8) },
|
||||
{ HRDATA (KBUF, tt_unit[TTI].buf, 8) },
|
||||
{ DRDATA (KPOS, tt_unit[TTI].pos, 32), PV_LEFT },
|
||||
{ DRDATA (KPOS, tt_unit[TTI].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (KTIME, tt_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ HRDATA (TBUF, tt_unit[TTO].buf, 8) },
|
||||
{ DRDATA (TPOS, tt_unit[TTO].pos, 32), PV_LEFT },
|
||||
{ DRDATA (TPOS, tt_unit[TTO].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TTIME, tt_unit[TTO].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (IREQ, int_req[l_TT], i_TT) },
|
||||
{ FLDATA (IENB, int_enb[l_TT], i_TT) },
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
ttp console (on PAS)
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
*/
|
||||
|
||||
#include "id_defs.h"
|
||||
|
@ -83,14 +85,14 @@ UNIT ttp_unit[] = {
|
|||
REG ttp_reg[] = {
|
||||
{ HRDATA (CMD, ttp_cmd, 16) },
|
||||
{ HRDATA (KBUF, ttp_unit[TTI].buf, 8) },
|
||||
{ DRDATA (KPOS, ttp_unit[TTI].pos, 32), PV_LEFT },
|
||||
{ DRDATA (KPOS, ttp_unit[TTI].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (KTIME, ttp_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (KIREQ, int_req[l_TTP], i_TTP) },
|
||||
{ FLDATA (KIENB, int_enb[l_TTP], i_TTP) },
|
||||
{ FLDATA (KARM, ttp_karm, 0) },
|
||||
{ FLDATA (CHP, ttp_kchp, 0) },
|
||||
{ HRDATA (TBUF, ttp_unit[TTO].buf, 8) },
|
||||
{ DRDATA (TPOS, ttp_unit[TTO].pos, 32), PV_LEFT },
|
||||
{ DRDATA (TPOS, ttp_unit[TTO].pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TTIME, ttp_unit[TTO].wait, 24), REG_NZ + PV_LEFT },
|
||||
{ FLDATA (TIREQ, int_req[l_TTP], i_TTP + 1) },
|
||||
{ FLDATA (TIENB, int_enb[l_TTP], i_TTP + 1) },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* id_uvc.c: Interdata universal clock
|
||||
|
||||
Copyright (c) 2001-2002, Robert M. Supnik
|
||||
Copyright (c) 2001-2003, 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"),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Modified from the original NOVA simulator by Robert Supnik.
|
||||
|
||||
Copyright (c) 1998-2002, Charles E Owen
|
||||
Copyright (c) 1998-2003, Charles E Owen
|
||||
Portions Copyright (c) 1993-2002, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
|
@ -2953,7 +2953,7 @@ int32 pushrtn(int32 pc)
|
|||
int32 GetMap(int32 addr)
|
||||
{
|
||||
int32 page;
|
||||
t_addr paddr;
|
||||
uint32 paddr;
|
||||
|
||||
switch (Usermap) {
|
||||
case 0:
|
||||
|
@ -3015,7 +3015,7 @@ int32 GetMap(int32 addr)
|
|||
int32 PutMap(int32 addr, int32 data)
|
||||
{
|
||||
int32 page;
|
||||
t_addr paddr;
|
||||
uint32 paddr;
|
||||
|
||||
switch (Usermap) {
|
||||
case 0:
|
||||
|
@ -3060,7 +3060,7 @@ int32 PutMap(int32 addr, int32 data)
|
|||
#if 0
|
||||
int16 GetDCHMap(int32 map, int32 addr)
|
||||
{
|
||||
t_addr paddr;
|
||||
uint32 paddr;
|
||||
if (!(MapStat & 02)) return M[addr];
|
||||
paddr = ((Map[map][(addr >> 10) & 037] & PAGEMASK) << 10) | (addr & 001777);
|
||||
if (paddr < MEMSIZE)
|
||||
|
@ -3070,7 +3070,7 @@ int16 GetDCHMap(int32 map, int32 addr)
|
|||
|
||||
int16 PutDCHMap(int32 map, int32 addr, int16 data)
|
||||
{
|
||||
t_addr paddr;
|
||||
uint32 paddr;
|
||||
if (!(MapStat & 02)) {
|
||||
M[addr] = data;
|
||||
return (data);
|
||||
|
@ -3192,7 +3192,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0))
|
||||
return SCPE_ARG;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eclipse_tt.c: Eclipse console terminal simulator
|
||||
|
||||
Copyright (c) 1998-2002, Charles E Owen
|
||||
Copyright (c) 1998-2003, Charles E Owen
|
||||
Portions copyright (c) 1993-2002, Robert M Supnik
|
||||
Written by Charles Owen, used by gracious permission
|
||||
Commercial use prohibited
|
||||
|
@ -8,6 +8,7 @@
|
|||
tti terminal input
|
||||
tto terminal output
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
03-Oct-02 RMS Added DIBs
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
28-Jan-02 RMS Cleaned up compiler warnings
|
||||
|
@ -49,7 +50,7 @@ REG tti_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_TTI) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_TTI) },
|
||||
{ FLDATA (INT, int_req, INT_V_TTI) },
|
||||
{ DRDATA (POS, tti_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
|
@ -82,7 +83,7 @@ REG tto_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_TTO) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_TTO) },
|
||||
{ FLDATA (INT, int_req, INT_V_TTO) },
|
||||
{ DRDATA (POS, tto_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
|
|
|
@ -674,9 +674,9 @@ else { /* IOT */
|
|||
case ioDOC:
|
||||
if ((dstAC == 2) && (cpu_unit.flags & UNIT_MDV)) {
|
||||
uint32 mddata, uAC0, uAC1, uAC2;
|
||||
uAC0 = (unsigned int32) AC[0];
|
||||
uAC1 = (unsigned int32) AC[1];
|
||||
uAC2 = (unsigned int32) AC[2];
|
||||
uAC0 = (uint32) AC[0];
|
||||
uAC1 = (uint32) AC[1];
|
||||
uAC2 = (uint32) AC[2];
|
||||
if (pulse == iopP) { /* mul */
|
||||
mddata = (uAC1 * uAC2) + uAC0;
|
||||
AC[0] = (mddata >> 16) & DMASK;
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define A_V_IND 15 /* ind: indirect */
|
||||
#define A_IND (1 << A_V_IND)
|
||||
#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE)
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
|
||||
/* Architectural constants */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_dkp.c: NOVA moving head disk simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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
|
||||
|
||||
25-Apr-03 RMS Revised autosizing
|
||||
08-Oct-02 RMS Added DIB
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
30-Nov-01 RMS Added read only unit, extended SET/SHOW support
|
||||
|
@ -76,10 +77,10 @@
|
|||
#define USSC_M_UNIT 03
|
||||
#define USSC_UNIT (USSC_M_UNIT << USSC_V_UNIT)
|
||||
#define GET_COUNT(x) (((x) >> USSC_V_COUNT) & USSC_M_COUNT)
|
||||
#define GET_SECT(x,dt) ((drv_tab[dt].new)? \
|
||||
#define GET_SECT(x,dt) ((drv_tab[dt].newf)? \
|
||||
(((x) >> USSC_V_NSECTOR) & USSC_M_NSECTOR): \
|
||||
(((x) >> USSC_V_OSECTOR) & USSC_M_OSECTOR) )
|
||||
#define GET_SURF(x,dt) ((drv_tab[dt].new)? \
|
||||
#define GET_SURF(x,dt) ((drv_tab[dt].newf)? \
|
||||
(((x) >> USSC_V_NSURFACE) & USSC_M_NSURFACE): \
|
||||
(((x) >> USSC_V_OSURFACE) & USSC_M_OSURFACE) )
|
||||
#define GET_UNIT(x) (((x) >> USSC_V_UNIT) & USSC_M_UNIT)
|
||||
|
@ -105,10 +106,10 @@
|
|||
#define FCCY_SEEK 2
|
||||
#define FCCY_RECAL 3
|
||||
#define FCCY_FLAGS 0174000 /* flags */
|
||||
#define GET_CMD(x,dt) ((drv_tab[dt].new)? \
|
||||
#define GET_CMD(x,dt) ((drv_tab[dt].newf)? \
|
||||
(((x) >> FCCY_V_NCMD) & FCCY_M_NCMD): \
|
||||
(((x) >> FCCY_V_OCMD) & FCCY_M_OCMD) )
|
||||
#define GET_CYL(x,dt) ((drv_tab[dt].new)? \
|
||||
#define GET_CYL(x,dt) ((drv_tab[dt].newf)? \
|
||||
(((x) >> FCCY_V_NCYL) & FCCY_M_NCYL): \
|
||||
((((x) >> FCCY_V_OCYL) & FCCY_M_OCYL) | \
|
||||
((dt != TYPE_D44)? 0: \
|
||||
|
@ -254,7 +255,7 @@ struct drvtyp {
|
|||
int32 surf; /* surfaces */
|
||||
int32 cyl; /* cylinders */
|
||||
int32 size; /* #blocks */
|
||||
int32 new; /* new format flag */
|
||||
int32 newf; /* new format flag */
|
||||
};
|
||||
|
||||
struct drvtyp drv_tab[] = {
|
||||
|
@ -323,7 +324,7 @@ REG dkp_reg[] = {
|
|||
{ FLDATA (DISABLE, dev_disable, INT_V_DKP) },
|
||||
{ DRDATA (STIME, dkp_swait, 24), PV_LEFT },
|
||||
{ DRDATA (RTIME, dkp_rwait, 24), PV_LEFT },
|
||||
{ URDATA (CAPAC, dkp_unit[0].capac, 10, 31, 0,
|
||||
{ URDATA (CAPAC, dkp_unit[0].capac, 10, T_ADDR_W, 0,
|
||||
DKP_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ NULL } };
|
||||
|
||||
|
@ -460,7 +461,7 @@ case ioDIB: /* DIB */
|
|||
break;
|
||||
case ioDOB: /* DOB */
|
||||
if ((dev_busy & INT_DKP) == 0) dkp_ma =
|
||||
AC & (drv_tab[dtype].new? DMASK: AMASK);
|
||||
AC & (drv_tab[dtype].newf? DMASK: AMASK);
|
||||
break;
|
||||
case ioDIC: /* DIC */
|
||||
rval = dkp_ussc; /* return unit, sect */
|
||||
|
@ -618,7 +619,7 @@ else { sc = 16 - GET_COUNT (dkp_ussc); /* get sector count */
|
|||
newsect = sa % drv_tab[dtype].sect;
|
||||
newsurf = (sa / drv_tab[dtype].sect) % drv_tab[dtype].surf;
|
||||
dkp_ussc = (dkp_ussc & USSC_UNIT) | ((dkp_ussc + sc) & USSC_M_COUNT) |
|
||||
((drv_tab[dtype].new)?
|
||||
((drv_tab[dtype].newf)?
|
||||
((newsurf << USSC_V_NSURFACE) | (newsect << USSC_V_NSECTOR)):
|
||||
((newsurf << USSC_V_OSURFACE) | (newsect << USSC_V_OSECTOR)) );
|
||||
dkp_sta = dkp_sta | STA_DONE; } /* set status */
|
||||
|
@ -716,7 +717,7 @@ for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
|
|||
unitno = unitno & USSC_M_UNIT;
|
||||
dtype = GET_DTYPE (dkp_unit[unitno].flags);
|
||||
M[BOOT_UNIT] = M[BOOT_UNIT] | (unitno << USSC_V_UNIT);
|
||||
if (drv_tab[dtype].new) M[BOOT_SEEK] = 0176000;
|
||||
if (drv_tab[dtype].newf) M[BOOT_SEEK] = 0176000;
|
||||
saved_PC = BOOT_START;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
dsk fixed head disk
|
||||
|
||||
14-Mar-03 RMS Fixed variable capacity interaction with save/restore
|
||||
03-Mar-03 RMS Fixed variable capacity and autosizing
|
||||
03-Oct-02 RMS Added DIB
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
|
@ -44,6 +45,7 @@
|
|||
#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */
|
||||
#define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */
|
||||
#define UNIT_M_PLAT 07
|
||||
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
|
||||
#define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1)
|
||||
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
||||
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
|
||||
|
@ -184,7 +186,7 @@ if ((pulse == iopP) && ((dsk_wlk >> GET_DISK (dsk_da)) & 1)) { /* wrt lock? */
|
|||
return rval; }
|
||||
|
||||
if (pulse & 1) { /* read or write? */
|
||||
if (((t_addr) (dsk_da * DSK_NUMWD)) >= dsk_unit.capac) { /* inv sev? */
|
||||
if (((uint32) (dsk_da * DSK_NUMWD)) >= dsk_unit.capac) { /* inv sev? */
|
||||
dev_done = dev_done | INT_DSK; /* set done */
|
||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||
dsk_stat = DSKS_ERR + DSKS_NSD; /* set status */
|
||||
|
@ -222,7 +224,7 @@ if (uptr->FUNC == iopP) { /* write? */
|
|||
for (i = 0; i < DSK_NUMWD; i++) { /* copy sector */
|
||||
pa = MapAddr (0, (dsk_ma + i) & AMASK); /* map address */
|
||||
*(((int16 *) uptr->filebuf) + da + i) = M[pa]; }
|
||||
if (((t_addr) (da + i)) >= uptr->hwmark) /* past end? */
|
||||
if (((uint32) (da + i)) >= uptr->hwmark) /* past end? */
|
||||
uptr->hwmark = da + i + 1; /* upd hwmark */
|
||||
dsk_ma = (dsk_ma + DSK_NUMWD + 3) & AMASK; }
|
||||
|
||||
|
@ -271,15 +273,15 @@ return SCPE_OK;
|
|||
|
||||
t_stat dsk_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_addr sz, p;
|
||||
t_addr ds_bytes = DSK_DKSIZE * sizeof (int16);
|
||||
uint32 sz, p;
|
||||
uint32 ds_bytes = DSK_DKSIZE * sizeof (int16);
|
||||
|
||||
if ((uptr->flags & UNIT_AUTO) && (sz = sim_fsize (cptr))) {
|
||||
p = (sz + ds_bytes - 1) / ds_bytes;
|
||||
if (p == 0) p = 1;
|
||||
if (p > DSK_NUMDK) p = DSK_NUMDK; }
|
||||
else p = UNIT_GETP (uptr->flags); /* get # plat */
|
||||
uptr->capac = p * DSK_DKSIZE; /* set capacity */
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_lp.c: NOVA line printer simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt line printer
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
*/
|
||||
|
||||
|
@ -56,7 +57,7 @@ REG lpt_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_LPT) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_LPT) },
|
||||
{ FLDATA (INT, int_req, INT_V_LPT) },
|
||||
{ DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
|
||||
{ NULL } };
|
||||
|
@ -106,7 +107,7 @@ if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) {
|
|||
perror ("LPT I/O error");
|
||||
clearerr (lpt_unit.fileref);
|
||||
return SCPE_IOERR; }
|
||||
lpt_unit.pos = ftell (lpt_unit.fileref);
|
||||
lpt_unit.pos = lpt_unit.pos + 1;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
mta magnetic tape
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
28-Feb-03 RMS Revised for magtape library
|
||||
30-Oct-02 RMS Fixed BOT handling, added error record handling
|
||||
08-Oct-02 RMS Added DIB
|
||||
|
@ -203,13 +205,15 @@ REG mta_reg[] = {
|
|||
{ DRDATA (CTIME, mta_cwait, 24), PV_LEFT },
|
||||
{ DRDATA (RTIME, mta_rwait, 24), PV_LEFT },
|
||||
{ URDATA (UST, mta_unit[0].USTAT, 8, 32, 0, MTA_NUMDR, 0) },
|
||||
{ URDATA (POS, mta_unit[0].pos, 8, 32, 0,
|
||||
{ URDATA (POS, mta_unit[0].pos, 8, T_ADDR_W, 0,
|
||||
MTA_NUMDR, REG_RO | PV_LEFT) },
|
||||
{ NULL } };
|
||||
|
||||
MTAB mta_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", &mta_vlock },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &mta_vlock },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE mta_dev = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_plt.c: NOVA plotter simulator
|
||||
|
||||
Copyright (c) 2000-2002, Robert M. Supnik
|
||||
Copyright (c) 2000-2003, Robert M. Supnik
|
||||
Written by Bruce Ray and used with his gracious permission.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
|
@ -26,6 +26,7 @@
|
|||
|
||||
plt plotter
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
03-Oct-02 RMS Added DIB
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
06-Jan-02 RMS Revised enable/disable support
|
||||
|
@ -61,7 +62,7 @@ REG plt_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_PLT) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_PLT) },
|
||||
{ FLDATA (INT, int_req, INT_V_PLT) },
|
||||
{ DRDATA (POS, plt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, plt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, plt_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, plt_stopioe, 0) },
|
||||
{ NULL } };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_pt.c: NOVA paper tape read/punch simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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 @@
|
|||
ptr paper tape reader
|
||||
ptp paper tape punch
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
03-Oct-02 RMS Added DIBs
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
29-Nov-01 RMS Added read only unit support
|
||||
|
@ -63,7 +64,7 @@ REG ptr_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_PTR) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_PTR) },
|
||||
{ FLDATA (INT, int_req, INT_V_PTR) },
|
||||
{ DRDATA (POS, ptr_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
|
||||
{ NULL } };
|
||||
|
@ -93,7 +94,7 @@ REG ptp_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_PTP) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_PTP) },
|
||||
{ FLDATA (INT, int_req, INT_V_PTP) },
|
||||
{ DRDATA (POS, ptp_unit.pos, 32), PV_LEFT },
|
||||
{ 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 } };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* nova_sys.c: NOVA simulator interface
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -127,7 +127,7 @@ const char *sim_stop_messages[] = {
|
|||
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
|
||||
{
|
||||
int32 data, csum, count, state, i;
|
||||
t_addr origin;
|
||||
uint32 origin;
|
||||
|
||||
if ((*cptr != 0) || (flag != 0)) return SCPE_ARG;
|
||||
state = 0;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
tti terminal input
|
||||
tto terminal output
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
05-Jan-02 RMS Fixed calling sequence for setmod
|
||||
03-Oct-02 RMS Added DIBs
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
|
@ -67,7 +68,7 @@ REG tti_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_TTI) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_TTI) },
|
||||
{ FLDATA (INT, int_req, INT_V_TTI) },
|
||||
{ DRDATA (POS, tti_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
|
@ -100,7 +101,7 @@ REG tto_reg[] = {
|
|||
{ FLDATA (DONE, dev_done, INT_V_TTO) },
|
||||
{ FLDATA (DISABLE, dev_disable, INT_V_TTO) },
|
||||
{ FLDATA (INT, int_req, INT_V_TTO) },
|
||||
{ DRDATA (POS, tto_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||
{ NULL } };
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
tti1 second terminal input
|
||||
tto1 second terminal output
|
||||
|
||||
09-May-03 RMS Added network device flag
|
||||
05-Jan-03 RMS Fixed calling sequence for setmod
|
||||
03-Oct-02 RMS Added DIBs
|
||||
22-Aug-02 RMS Updated for changes in sim_tmxr
|
||||
|
@ -105,7 +106,7 @@ DEVICE tti1_dev = {
|
|||
1, 10, 31, 1, 8, 8,
|
||||
&tmxr_ex, &tmxr_dep, &tti1_reset,
|
||||
NULL, &tti1_attach, &tti1_detach,
|
||||
&tti1_dib, DEV_DISABLE };
|
||||
&tti1_dib, DEV_NET | DEV_DISABLE };
|
||||
|
||||
/* TTO1 data structures
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp1_cpu.c: PDP-1 CPU simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -792,7 +792,7 @@ return SCPE_OK;
|
|||
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 mc = 0;
|
||||
t_addr i;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0))
|
||||
return SCPE_ARG;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp1_defs.h: 18b PDP simulator definitions
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, 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"),
|
||||
|
@ -54,7 +54,7 @@
|
|||
#define MAXMEMSIZE (1u << ASIZE) /* max mem size */
|
||||
#define AMASK (MAXMEMSIZE - 1) /* address mask */
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
#define MEM_ADDR_OK(x) (((t_addr) (x)) < MEMSIZE)
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
|
||||
/* Architectural constants */
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ return IO;
|
|||
t_stat drm_svc (UNIT *uptr)
|
||||
{
|
||||
int32 i;
|
||||
t_addr da;
|
||||
uint32 da;
|
||||
|
||||
if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */
|
||||
drm_err = 1; /* set error */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp1_dt.c: 18b DECtape simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M Supnik
|
||||
Copyright (c) 1993-2003, 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 @@
|
|||
|
||||
dt Type 550/555 DECtape
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
14-Mar-03 RMS Fixed variable size interaction with save/restore
|
||||
17-Oct-02 RMS Fixed bug in end of reel logic
|
||||
06-Oct-02 RMS Added device disable support
|
||||
13-Aug-02 RMS Cloned from pdp18b_dt.c
|
||||
|
@ -309,7 +311,7 @@ REG dt_reg[] = {
|
|||
{ ORDATA (SUBSTATE, dt_substate, 2) },
|
||||
{ ORDATA (LOG, dt_log, 4), REG_HIDDEN },
|
||||
{ DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN },
|
||||
{ URDATA (POS, dt_unit[0].pos, 10, 32, 0,
|
||||
{ URDATA (POS, dt_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
DT_NUMDR, PV_LEFT | REG_RO) },
|
||||
{ URDATA (STATT, dt_unit[0].STATE, 8, 18, 0,
|
||||
DT_NUMDR, REG_RO) },
|
||||
|
@ -622,7 +624,7 @@ int32 fnc = DTS_GETFNC (uptr->STATE);
|
|||
int32 *bptr = uptr->filebuf;
|
||||
int32 unum = uptr - dt_dev.units;
|
||||
int32 blk, wrd, ma, relpos;
|
||||
t_addr ba;
|
||||
uint32 ba;
|
||||
|
||||
/* Motion cases
|
||||
|
||||
|
@ -866,33 +868,35 @@ t_stat dt_attach (UNIT *uptr, char *cptr)
|
|||
{
|
||||
uint16 pdp8b[D8_NBSIZE];
|
||||
uint16 pdp11b[D18_BSIZE];
|
||||
uint32 k, p, *bptr;
|
||||
uint32 ba, sz, k, *bptr;
|
||||
int32 u = uptr - dt_dev.units;
|
||||
t_stat r;
|
||||
t_addr ba;
|
||||
|
||||
r = attach_unit (uptr, cptr); /* attach */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
|
||||
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */
|
||||
if (sim_switches & SWMASK ('R')) /* att 12b? */
|
||||
uptr->flags = uptr->flags | UNIT_8FMT;
|
||||
else if (sim_switches & SWMASK ('S')) /* att 16b? */
|
||||
uptr->flags = uptr->flags | UNIT_11FMT;
|
||||
else if (!(sim_switches & SWMASK ('T')) && /* autosize? */
|
||||
(fseek (uptr->fileref, 0, SEEK_END) == 0) &&
|
||||
((p = ftell (uptr->fileref)) != 0)) {
|
||||
if (p == D8_FILSIZ) uptr->flags = uptr->flags | UNIT_8FMT;
|
||||
if (p == D11_FILSIZ) uptr->flags = uptr->flags | UNIT_11FMT; }
|
||||
(sz = sim_fsize (cptr))) {
|
||||
if (sz == D8_FILSIZ)
|
||||
uptr->flags = uptr->flags | UNIT_8FMT;
|
||||
else if (sz == D11_FILSIZ)
|
||||
uptr->flags = uptr->flags | UNIT_11FMT; } }
|
||||
uptr->capac = DTU_CAPAC (uptr); /* set capacity */
|
||||
uptr->filebuf = calloc (uptr->capac, sizeof (int32));
|
||||
if (uptr->filebuf == NULL) { /* can't alloc? */
|
||||
detach_unit (uptr);
|
||||
return SCPE_MEM; }
|
||||
bptr = uptr->filebuf; /* file buffer */
|
||||
if (uptr->flags & UNIT_8FMT) printf ("DT: 12b format");
|
||||
else if (uptr->flags & UNIT_11FMT) printf ("DT: 16b format");
|
||||
else printf ("DT: 18b/36b format");
|
||||
printf ("%s%d: ", sim_dname (&dt_dev), u);
|
||||
if (uptr->flags & UNIT_8FMT) printf ("12b format");
|
||||
else if (uptr->flags & UNIT_11FMT) printf ("16b format");
|
||||
else printf ("18b/36b format");
|
||||
printf (", buffering file in memory\n");
|
||||
rewind (uptr->fileref); /* start of file */
|
||||
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
||||
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
|
||||
k = fxread (pdp8b, sizeof (int16), D8_NBSIZE, uptr->fileref);
|
||||
|
@ -935,20 +939,19 @@ t_stat dt_detach (UNIT* uptr)
|
|||
{
|
||||
uint16 pdp8b[D8_NBSIZE];
|
||||
uint16 pdp11b[D18_BSIZE];
|
||||
uint32 k, *bptr;
|
||||
int32 unum = uptr - dt_dev.units;
|
||||
t_addr ba;
|
||||
uint32 ba, k, *bptr;
|
||||
int32 u = uptr - dt_dev.units;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK;
|
||||
if (sim_is_active (uptr)) {
|
||||
sim_cancel (uptr);
|
||||
if ((unum == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) {
|
||||
if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) {
|
||||
dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF;
|
||||
DT_UPDINT; }
|
||||
uptr->STATE = uptr->pos = 0; }
|
||||
bptr = uptr->filebuf; /* file buffer */
|
||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
|
||||
printf ("DT: writing buffer to file\n");
|
||||
printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
|
||||
rewind (uptr->fileref); /* start of file */
|
||||
if (uptr->flags & UNIT_8FMT) { /* 12b? */
|
||||
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* pdp1_lp.c: PDP-1 line printer simulator
|
||||
|
||||
Copyright (c) 1993-2002, Robert M. Supnik
|
||||
Copyright (c) 1993-2003, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
lpt Type 62 line printer for the PDP-1
|
||||
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
30-May-02 RMS Widened POS to 32b
|
||||
13-Apr-01 RMS Revised for register arrays
|
||||
*/
|
||||
|
@ -66,7 +67,7 @@ REG lpt_reg[] = {
|
|||
{ FLDATA (RPLS, lpt_rpls, 0) },
|
||||
{ DRDATA (BPTR, bptr, 6) },
|
||||
{ ORDATA (LPT_STATE, lpt_iot, 6), REG_HRO },
|
||||
{ DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
|
||||
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
|
||||
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
|
||||
{ BRDATA (LBUF, lpt_buf, 8, 8, LPT_BSIZE) },
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue