SIMH: Fix spelling errors in comments and strings

This commit is contained in:
Peter Schorn 2024-07-11 12:29:53 +02:00
parent e7b2431f11
commit 0f6bcb9682
34 changed files with 1893 additions and 1893 deletions

View file

@ -3,36 +3,36 @@ SIM_ASYNCH_IO
Theory of operation.
Features.
- Optional Use. Build with or without SIM_ASYNCH_IO defined and
- Optional Use. Build with or without SIM_ASYNCH_IO defined and
simulators will still build and perform correctly when run.
Additionmally, a simulator built with SIM_ASYNCH_IO defined can
dynamically disable and reenable asynchronous operation with
Additionally, a simulator built with SIM_ASYNCH_IO defined can
dynamically disable and reenable asynchronous operation with
the scp commands SET NOASYNCH and SET ASYNCH respectively.
- Consistent Save/Restore state. The state of a simulator saved
- Consistent Save/Restore state. The state of a simulator saved
on a simulator with (or without) Asynch support can be restored
on any simulator of the same version with or without Asynch
on any simulator of the same version with or without Asynch
support.
- Optimal behavior/performance with simulator running with or
- Optimal behavior/performance with simulator running with or
without CPU idling enabled.
- Consistent minimum instruction scheduling delays when operating
with or without SIM_ASYNCH_IO. When SIM_ASYNCH_IO is emabled,
any operation which would have been scheduled to occurr in 'n'
instructions will still occur (from the simulated computer's
- Consistent minimum instruction scheduling delays when operating
with or without SIM_ASYNCH_IO. When SIM_ASYNCH_IO is enabled,
any operation which would have been scheduled to occur in 'n'
instructions will still occur (from the simulated computer's
point of view) at least 'n' instructions after it was initiated.
Benefits.
- Allows a simulator to execute simulated instructions concurrently
- Allows a simulator to execute simulated instructions concurrently
with I/O operations which may take numerous milliseconds to perform.
- Allows a simulated device to potentially avoid polling for the
arrival of data. Polling consumes host processor CPU cycles which
may better be spent executing simulated instructions or letting
other host processes run. Measurements made of available
- Allows a simulated device to potentially avoid polling for the
arrival of data. Polling consumes host processor CPU cycles which
may better be spent executing simulated instructions or letting
other host processes run. Measurements made of available
instruction execution easily demonstrate the benefits of parallel
instruction and I/O activities. A VAX simulator with a process
running a disk intensive application in one process was able to
run (in another process) 11 times the number of Dhrystone operations
instruction and I/O activities. A VAX simulator with a process
running a disk intensive application in one process was able to
run (in another process) 11 times the number of Dhrystone operations
with Asynch I/O enabled vs not enabled.
- Allows simulator clock ticks to track wall clock was precisely as
- Allows simulator clock ticks to track wall clock was precisely as
possible under varying I/O load and activities.
SimH Libraries which provide Asynch I/O support:
@ -44,7 +44,7 @@ SimH Libraries which provide Asynch I/O support:
Requirements to use:
The Simulator's instruction loop needs to be modified to include a single
line which checks for asynchronouzly arrived events. The vax_cpu.c
line which checks for asynchronously arrived events. The vax_cpu.c
module added the following line indicated by >>>:
/* Main instruction loop */
@ -60,20 +60,20 @@ module added the following line indicated by >>>:
SET_IRQL; /* update interrupts */
}
A global variable (sim_asynch_latency) is used to indicate the "interrupt
A global variable (sim_asynch_latency) is used to indicate the "interrupt
dispatch latency". This variable is the number of nanoseconds between checks
for completed asynchronous I/O. The default value is 4000 (4 usec) which
corresponds reasonably with simulated hardware. This variable controls
the computation of sim_asynch_inst_latency which is the number of simulated
instructions in the sim_asynch_latency interval. We are trying to avoid
checking for completed asynchronous I/O after every instruction since the
checking for completed asynchronous I/O after every instruction since the
actual checking every instruction can slow down execution. Periodic checks
provide a balance which allows response similar to real hardware while also
providing minimal impact on actual instruction execution. Meanwhile, if
maximal response is desired, then the value of sim_asynch_latency can be
provide a balance which allows response similar to real hardware while also
providing minimal impact on actual instruction execution. Meanwhile, if
maximal response is desired, then the value of sim_asynch_latency can be
set sufficiently low to assure that sim_asynch_inst_latency computes to 1.
The sim_asynch_inst_latency is dynamically updated once per second in the
sim_rtcn_calb routine where clock to instruction execution is dynamically
The sim_asynch_inst_latency is dynamically updated once per second in the
sim_rtcn_calb routine where clock to instruction execution is dynamically
determined. A simulator would usually add register definitions
to enable viewing and setting of these variables via scp:
@ -91,60 +91,60 @@ Naming conventions:
All of the routines implemented in sim_disk and sim_tape have been kept
in place. All routines which perform I/O have a variant routine available
with a "_a" appended to the the routine name with the addition of a single
parameter which indicates the asynch completion callback routine. For
parameter which indicates the asynch completion callback routine. For
example there now exists the routines:
t_stat sim_tape_rdrecf (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max);
t_stat sim_tape_rdrecf_a (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max, TAPE_PCALLBACK callback);
The Purpose of the callback function is to record the I/O completion status
and then to schedule the activation of the unit.
and then to schedule the activation of the unit.
Considerations:
Avoiding multiple concurrent users of the unit structure. While asynch
I/O is pending on a Unit, the unit should not otherwise be on the event
I/O is pending on a Unit, the unit should not otherwise be on the event
queue. The I/O completion will cause the Unit to be scheduled to run
immediately to actually dispatch control flow to the callback routine.
The callback routine is always called in the same thread which is
executing instructions. Since all simulator device data structures are
only referenced from this thread there are no host multi-processor cache
The callback routine is always called in the same thread which is
executing instructions. Since all simulator device data structures are
only referenced from this thread there are no host multi-processor cache
coherency issues to be concerned about.
Arguments to the callback routine:
UNIT *, and IO Status
Requirements of the Callback routine.
The callback routine must save the I/O completion status in a place
which the next invocation of the unit service routine will reference
which the next invocation of the unit service routine will reference
and act on it. This allows device code to return error conditions
back to scp in a consistent way without regard to how the callback
back to scp in a consistent way without regard to how the callback
routine (and the actual I/O) may have been executed. When the callback
routine is called, it will already be on the simulator event queue with
an event time which was specified when the unit was attached or via a
an event time which was specified when the unit was attached or via a
call to sim_disk_set_async. If no value has been specified then it
will have been scheduled with a delay time of 0. If a different event
firing time is desired, then the callback completion routine should
will have been scheduled with a delay time of 0. If a different event
firing time is desired, then the callback completion routine should
call sim_activate_abs to schedule the event at the appropriate time.
Required change in device coding.
Devices which wish to leverage the benefits of asynch I/O must rearrange
the code which implements the unit service routine. This rearrangement
usually entails breaking the activities into two phases. The first phase
(I'll call the top half) involves performing whatever is needed to
initiate a call to perform an I/O operation with a callback argument.
(I'll call the top half) involves performing whatever is needed to
initiate a call to perform an I/O operation with a callback argument.
Control is then immediately returned to the scp event dispatcher.
The callback routine needs to be coded to stash away the io completion
The callback routine needs to be coded to stash away the io completion
status and some indicator that an I/O has completed.
The top/bottom half separation of the unit service routine would be
coded to examine the I/O completion indicator and invoke the bottom half
code upon completion. The bottom half code should clear the I/O
completion indicator and then perform any activities which normally
code upon completion. The bottom half code should clear the I/O
completion indicator and then perform any activities which normally
need to occur after the I/O completes. Care should be taken while
performing these top/bottom half activities to return to the scp event
dispatcher with either SCPE_OK or an appropriate error code when needed.
The need to return error indications to the scp event dispatcher is why
the bottom half activities can't simply be performed in the
callback routine (the callback routine does not return a status).
Care should also be taken to realize that local variables in the
unit service routine will not directly survive between the separate
dispatcher with either SCPE_OK or an appropriate error code when needed.
The need to return error indications to the scp event dispatcher is why
the bottom half activities can't simply be performed in the
callback routine (the callback routine does not return a status).
Care should also be taken to realize that local variables in the
unit service routine will not directly survive between the separate
top and bottom half calls to the unit service routine. If any such
information must be referenced in both the top and bottom half code paths
then it must either be recomputed prior to the top/bottom half check
@ -162,65 +162,65 @@ more realistic delays to perform I/O operations.
The pdp11_tq.c module has been refactored to leverage the asynch I/O
features of the sim_tape library. The impact to this code to adopt the
asynch I/O paradigm was very significant. This was due to the two facts:
1) there are many different operations which can be requested of tape
devices and 2) some of the tmscp operations required many separate
1) there are many different operations which can be requested of tape
devices and 2) some of the tmscp operations required many separate
operations on the physical device layer to perform a single tmscp request.
This issue was addressed by adding additional routines to the physical
This issue was addressed by adding additional routines to the physical
device layer (in sim_tape.c) which combined these multiple operations.
This approach will dovetail well with a potential future addition of
This approach will dovetail well with a potential future addition of
operations on physical tapes as yet another supported tape format.
Programming Console and Multiplexer devices to leverage Asynch I/O to
Programming Console and Multiplexer devices to leverage Asynch I/O to
minimize 'unproductive' polling.
There are two goals for asynchronous Multiplexer I/O: 1) Minimize polling
to only happen when data is available, not arbitrarily on every clock tick,
and 2) to have polling actually happen as soon as data may be available.
In most cases no effort is required to add Asynch I/O support to a
multiplexer device emulation. If a device emulation takes the normal
to only happen when data is available, not arbitrarily on every clock tick,
and 2) to have polling actually happen as soon as data may be available.
In most cases no effort is required to add Asynch I/O support to a
multiplexer device emulation. If a device emulation takes the normal
model of polling for arriving data on every simulated clock tick, then if
Asynch I/O is enabled, the device will operate asynchronously and behave
well. There is one restriction in this model. Specifically, the device
emulation logic can't expect that there will be a particular number (clock
tick rate maybe) of invocations of a unit service routine to perform polls
in any interval of time (this is what we're trying to change, right?).
Therefore presumptions about measuring time by counting polls is not
valid. If a device needs to manage time related activities, then the
device should create a separate unit which is dedicated to the timing
activities and which explicitly schedules a different unit service routine
for those activities as needed. Such scheduled polling should only be
enabled when actual timing is required.
Asynch I/O is enabled, the device will operate asynchronously and behave
well. There is one restriction in this model. Specifically, the device
emulation logic can't expect that there will be a particular number (clock
tick rate maybe) of invocations of a unit service routine to perform polls
in any interval of time (this is what we're trying to change, right?).
Therefore presumptions about measuring time by counting polls is not
valid. If a device needs to manage time related activities, then the
device should create a separate unit which is dedicated to the timing
activities and which explicitly schedules a different unit service routine
for those activities as needed. Such scheduled polling should only be
enabled when actual timing is required.
A device which is unprepared to operate asynchronously can specifically
disable multiplexer Asynch I/O for that device by explicitly defining
NO_ASYNCH_MUX at compile time. This can be defined at the top of a
particular device emulation which isn't capable of asynch operation, or
disable multiplexer Asynch I/O for that device by explicitly defining
NO_ASYNCH_MUX at compile time. This can be defined at the top of a
particular device emulation which isn't capable of asynch operation, or
it can be defined globally on the compile command line for the simulator.
Alternatively, if a specific Multiplexer device doesn't function correctly
under the multiplexer asynchronous environment and it will never be
revised to operate correctly, it may statically set the TMUF_NOASYNCH bit
Alternatively, if a specific Multiplexer device doesn't function correctly
under the multiplexer asynchronous environment and it will never be
revised to operate correctly, it may statically set the TMUF_NOASYNCH bit
in its unit flags field.
Some devices will need a small amount of extra coding to leverage the
Multiplexer Asynch I/O capabilties. Devices which require extra coding
Some devices will need a small amount of extra coding to leverage the
Multiplexer Asynch I/O capabilities. Devices which require extra coding
have one or more of the following characteristics:
- they poll for input data on a different unit (or units) than the unit
- they poll for input data on a different unit (or units) than the unit
which was provided when tmxr_attach was called.
- they poll for connections on a different unit than the unit which was
provided when tmxr_attach was called.
The extra coding required for proper operation is to call
tmxr_set_line_unit() to associate the appropriate input polling unit to
The extra coding required for proper operation is to call
tmxr_set_line_unit() to associate the appropriate input polling unit to
the respective multiplexer line (ONLY if input polling is done by a unit
different than the unit specified when the MUX was attached). If output
different than the unit specified when the MUX was attached). If output
polling is done on a different unit, then tmxr_set_line_output_unit()
should be called to describe that fact.
Console I/O can operate asynchronously if the simulator notifies the
tmxr/console subsystem which device unit is used by the simulator to poll
for console input and output units. This is done by including sim_tmxr.h
in the source module which contains the console input device definition
and calling tmxr_set_console_units(). tmxr_set_console_units would usually
Console I/O can operate asynchronously if the simulator notifies the
tmxr/console subsystem which device unit is used by the simulator to poll
for console input and output units. This is done by including sim_tmxr.h
in the source module which contains the console input device definition
and calling tmxr_set_console_units(). tmxr_set_console_units would usually
be called in a device reset routine.
sim_tmxr consumers:
@ -241,68 +241,68 @@ sim_tmxr consumers:
- PDP-18b TT1 devices = 2, units = 1/16, lines = 16, flagbits = 0, Untested Asynch
- SDS MUX devices = 2, units = 1/32, lines = 32, flagbits = 0, Untested Asynch
- sim_console Good Asynch
Program Clock Devices to leverage Asynsh I/O
simh's concept of time is calibrated by counting the number of
instructions which the simulator can execute in a given amount of wall
clock time. Once this is determined, the appropriate value is continually
recalibrated and used throughout a simulator to schedule device time
related delays as needed. Historically, this was fine until modern
Program Clock Devices to leverage Asynch I/O
simh's concept of time is calibrated by counting the number of
instructions which the simulator can execute in a given amount of wall
clock time. Once this is determined, the appropriate value is continually
recalibrated and used throughout a simulator to schedule device time
related delays as needed. Historically, this was fine until modern
processors started having dynamically variable processor clock rates.
On such host systems, the simulator's concept of time passing can vary
On such host systems, the simulator's concept of time passing can vary
drastically. This dynamic adjustment of the host system's execution rate
may cause dramatic drifting of the simulated operating system's concept
of time. Once all devices are disconnected from the calibrated clock's
instruction count, the only concern for time in the simulated system is
that it's clock tick be as accurate as possible. This has worked well
in the past, however each simulator was burdened with providing code
which facilitated managing the concept of the relationship between the
number of instructions executed and the passage of wall clock time.
To accomodate the needs of activities or events which should be measured
against wall clock time (vs specific number of instructions executed),
the simulator framework has been extended to specifically provide event
scheduling based on elapsed wall time. A new API can be used by devices
to schedule unit event delivery after the passage of a specific amount
of wall clock time. The api sim_activate_after() provides this
capability. This capability is not limited to being available ONLY when
compiling with SIM_SYNCH_IO defined. When SIM_ASYNCH_IO is defined, this
facility is implemented by a thread which drives the delivery of these
events from the host system's clock ticks (interpolated as needed to
accomodate hosts with relatively large clock ticks). When SIM_ASYNCH_IO
is not defined, this facility is implemented using the traditional simh
may cause dramatic drifting of the simulated operating system's concept
of time. Once all devices are disconnected from the calibrated clock's
instruction count, the only concern for time in the simulated system is
that it's clock tick be as accurate as possible. This has worked well
in the past, however each simulator was burdened with providing code
which facilitated managing the concept of the relationship between the
number of instructions executed and the passage of wall clock time.
To accomodate the needs of activities or events which should be measured
against wall clock time (vs specific number of instructions executed),
the simulator framework has been extended to specifically provide event
scheduling based on elapsed wall time. A new API can be used by devices
to schedule unit event delivery after the passage of a specific amount
of wall clock time. The api sim_activate_after() provides this
capability. This capability is not limited to being available ONLY when
compiling with SIM_SYNCH_IO defined. When SIM_ASYNCH_IO is defined, this
facility is implemented by a thread which drives the delivery of these
events from the host system's clock ticks (interpolated as needed to
accomodate hosts with relatively large clock ticks). When SIM_ASYNCH_IO
is not defined, this facility is implemented using the traditional simh
calibrated clock approach. This new approach has been measured to provide
clocks which drift far less than the drift realized in prior simh versions.
Using the released simh v3.9-0 vax simulator with idling enabled, the clock
drifted some 4 minutes in 35 minutes time (approximately 10%). The same OS
disk also running with idling enabled booted for 4 hours had less that 5
clocks which drift far less than the drift realized in prior simh versions.
Using the released simh v3.9-0 vax simulator with idling enabled, the clock
drifted some 4 minutes in 35 minutes time (approximately 10%). The same OS
disk also running with idling enabled booted for 4 hours had less that 5
seconds of clock drift (approximately 0.03%).
Co-Scheduling Clock and Multiplexer (or other devices)
Many simulator devices have needs to periodically executed with timing on the
order of the simulated system's clock ticks. There are numerous reasons for
this type of execution. Meanwhile, many of these events aren't particular
this type of execution. Meanwhile, many of these events aren't particular
about exactly when they execute as long as they execute frequently enough.
Frequently executing events has the potential to interfere with a simulator's
attempts to idle when the simulated system isn't actually doing useful work.
Interactions with attempts to 'co-schedule' multiplexer polling with clock
ticks can cause strange simulator behaviors. These strange behaviors only
ticks can cause strange simulator behaviors. These strange behaviors only
happen under a combination of conditions:
1) a multiplexer device is defined in the simulator configuration,
2) the multiplexor device is NOT attached, and thus is not being managed by
the asynchronous multiplexer support
3) the multiplexer device schedules polling (co-scheduled) when not
3) the multiplexer device schedules polling (co-scheduled) when not
attached (such polling will never produce any input, so this is probably
a bug).
In prior simh versions support for clock co-scheduling was implmented
In prior simh versions support for clock co-scheduling was implemented
separately by each simulator, and usually was expressed by code of the form:
sim_activate (uptr, clk_cosched (tmxr_poll));
As a part of asynchronous timer support, the simulator framework has been
As a part of asynchronous timer support, the simulator framework has been
extended to generically provide clock co-scheduling support. The use of this
new capability requires an initial call (usually in the clock device reset
routing) of the form:
new capability requires an initial call (usually in the clock device reset
routing) of the form:
sim_register_clock_unit (&clk_unit);
Once the clock unit has been registered, co-scheduling is achieved by replacing
the earlier sim_activate with the following:
@ -311,8 +311,8 @@ the earlier sim_activate with the following:
Run time requirements to use SIM_ASYNCH_IO.
The Posix threads API (pthreads) is required for asynchronous execution.
Most *nix platforms have these APIs available and on these platforms
simh is typically built with these available since on these platforms,
pthreads is required for simh networking support. Windows can also
simh is typically built with these available since on these platforms,
pthreads is required for simh networking support. Windows can also
utilize the pthreads APIs if the compile and run time support for the
win32Pthreads package has been installed on the build system.

View file

@ -3,7 +3,7 @@ This file contains information about the SIMH Ethernet package.
-------------------------------------------------------------------------------
The XQ emulator is a host-independent software emulation of Digital's
DELQA-T (M7516-YM), DELQA (M7516) and DEQNA (M7504) Q-bus Ethernet cards
DELQA-T (M7516-YM), DELQA (M7516) and DEQNA (M7504) Q-bus Ethernet cards
for the SIMH emulator.
The XU emulator is a host-independent software emulation of Digital's DEUNA
@ -25,29 +25,29 @@ most of the undesirable traffic. You will only see "excessive" traffic if you
are on a direct or hub(repeater) segment.
On Windows using the WinPcap interface, the simulated computer can "talk" to
the host computer on the same interface. On other platforms with libpcap
(*nix), the simulated computer can not "talk" to the host computer via the
the host computer on the same interface. On other platforms with libpcap
(*nix), the simulated computer can not "talk" to the host computer via the
selected interface, since simulator transmitted packets are not received
by the host's network stack. The workaround for this is to use a second NIC
in the host and connect them both into the same network; then the host and
by the host's network stack. The workaround for this is to use a second NIC
in the host and connect them both into the same network; then the host and
the simulator can communicate over the physical LAN.
Integrated Universal TUN/TAP support provides another solution for the above
Integrated Universal TUN/TAP support provides another solution for the above
dual-NIC problem for systems that support Universal TUN/TAP. Since the TUN/TAP
interface is a pseudo network interface, the host can create a TAP device for
the simulator and then bridge or route packets between the TAP device and the
real network interface. Note that the TAP device and any bridging or routing
must be established before running the simulator; SIMH does not create,
interface is a pseudo network interface, the host can create a TAP device for
the simulator and then bridge or route packets between the TAP device and the
real network interface. Note that the TAP device and any bridging or routing
must be established before running the simulator; SIMH does not create,
bridge, or route TAP devices for you.
Integrated Universal TUN/TAP support can be used for host<->simulator network
traffic (on the platforms where it is available) by using the SIMH command:
"attach xq tap:tapN" (i.e. attach xq tap:tap0). Platforms that this has been
tested on include: Linux, FreeBSD, OpenBSD, NetBSD and OSX. Each of these
platforms has some way to create a tap pseudo device (and possibly then to
tested on include: Linux, FreeBSD, OpenBSD, NetBSD and OSX. Each of these
platforms has some way to create a tap pseudo device (and possibly then to
bridge it with a physical network interface).
The following steps were performed to get a working SIMH vax simulator
The following steps were performed to get a working SIMH vax simulator
sharing a physical NIC and allowing Host<->SIMH vax communications:
Linux (Ubuntu 10.04):
@ -79,7 +79,7 @@ Linux (Ubuntu 10.04):
/sbin/ifconfig tap0 0.0.0.0
# Run simulator and "attach xq tap:tap0"
Linux (Fedora Core 18, 20, CentOS, RedHat, etc.):
yum install gcc
@ -90,7 +90,7 @@ Linux (Centos 6.x):
yum install gcc
yum install libpcap-devel
yum install uml_utilities
OpenBSD (OpenBSD 4.6)
/sbin/ifconfig tun0 create
@ -103,10 +103,10 @@ OpenBSD (OpenBSD 4.6)
/sbin/brconfig bridge0 up
# Run simulator and "attach xq tap:tun0"
FreeBSD (FreeBSD 11.3)
/sbin/sysctl net.link.tap.up_on_open=1
/sbin/sysctl net.link.tap.up_on_open=1
/sbin/ifconfig tap0 create
/sbin/ifconfig tap0 up
@ -131,38 +131,38 @@ NetBSD (NetBSD 5.0.2)
OSX (Snow Leopard)
OSX Does NOT have native support for tun/tap interfaces. It also does not have native
support for bridging.
Mattias Nissler has created tun/tap functionality available at http://tuntaposx,sourceforge.net/
Mattias Nissler has created tun/tap functionality available at http://tuntaposx.sourceforge.net/
We'll punt on bridging for the sake of this example and move on to use a basic tap
based internal network so a host and guest can communicate directly.
Download the install package from:
Download the install package from:
http://sourceforge.net/projects/tuntaposx/files/tuntap/20111101/tuntap_20111101.tar.gz
Expand the tarball to a directory.
Invoke the package installer tuntap_20111101.pkg
Click through the various prompts accepting things and eventually installing the package.
# Build and Run simulator and:
sim> attach xq tap:tap0
sim> ! ifconfig tap0 192.168.6.1 netmask 255.255.255.0
Simulated system uses IP address 192.168.6.2 and host uses 192.168.6.1
Simulated system uses IP address 192.168.6.2 and host uses 192.168.6.1
and things work.
You must run as root for this to work.
-------------------------------------------------------------------------------
An alternative to direct pcap and tun/tap networking on *nix environments is
An alternative to direct pcap and tun/tap networking on *nix environments is
VDE (Virtual Distributed Ethernet).
Note 1: Using vde based networking is likely more flexible, but it isn't
nearly as efficient. Host OS overhead will always be higher when
vde networking is used as compared to native pcap and/or tun/tap
Note 1: Using vde based networking is likely more flexible, but it isn't
nearly as efficient. Host OS overhead will always be higher when
vde networking is used as compared to native pcap and/or tun/tap
networking.
Note 2: Root access will likely be needed to configure or start the vde
Note 2: Root access will likely be needed to configure or start the vde
environment prior to starting a simulator which may use it.
Note 3: Simulators running using VDE networking can run without root
Note 3: Simulators running using VDE networking can run without root
privilege.
Linux (Ubuntu 11.10):
@ -172,44 +172,44 @@ Linux (Ubuntu 11.10):
vde_switch -s /tmp/switch1 -tap tap0 -m 666
ifconfig tap0 192.168.6.1 netmask 255.255.255.0 up
# Build and Run simulator and:
sim> attach xq vde:/tmp/switch1 #simulator uses IP address 192.168.6.2
OSX:
The macports package manager (http://www.macports.org) can be used to
The macports package manager (http://www.macports.org) can be used to
install the net/vde2 package.
-------------------------------------------------------------------------------
Another alternative to direct pcap and tun/tap networking on all environments is
Another alternative to direct pcap and tun/tap networking on all environments is
NAT (SLiRP) networking. NAT networking is limited to only IP network protocols
so DECnet, LAT and Clusting can't work on a NAT connected interface, but this may
be the easiest solution for many folks.
sim> attach xq nat:
The simulator can use static IP addresses of 10.0.2.4 thru 10.0.2.14 with a
The simulator can use static IP addresses of 10.0.2.4 thru 10.0.2.14 with a
netmask of 255.255.255.0 and a gateway of 10.0.2.2 and a nameserver of 10.0.2.3.
If the simulated machine uses DHCP it will get the address 10.0.2.15. Various
NAT based parameters can be configured on the attach command. HELP XQ ATTACH
will provide useful information. Host to simulator connectivitiy can be
achieved for a simulator which gets its IP address via DHCP with the following
If the simulated machine uses DHCP it will get the address 10.0.2.15. Various
NAT based parameters can be configured on the attach command. HELP XQ ATTACH
will provide useful information. Host to simulator connectivity can be
achieved for a simulator which gets its IP address via DHCP with the following
command:
sim> attach xq nat:tcp=2323:10.0.2.15:23,tcp=2121:10.0.2.15:21
The host computer can telnet to localhost:2323 to reach the simulator via
The host computer can telnet to localhost:2323 to reach the simulator via
telnet, etc.
Additionally NAT based networking is useful to allow host systems with WiFi
Additionally NAT based networking is useful to allow host systems with WiFi
networking to a) reach the simulated system and b) allow the simulated system
to reach out to the Internet.
Note: As mentioned above, NAT networking is specifically capable of providing
TCP/IP connectivity. Only expect TCP and UDP traffic to pass through
the interface. Do not expect ICMP traffic (ping mostly) to traverse
the NAT boundary. This restriction is a conseqence of host platform
and network limitations regarding direct user mode code generating ICMP
Note: As mentioned above, NAT networking is specifically capable of providing
TCP/IP connectivity. Only expect TCP and UDP traffic to pass through
the interface. Do not expect ICMP traffic (ping mostly) to traverse
the NAT boundary. This restriction is a consequence of host platform
and network limitations regarding direct user mode code generating ICMP
packets.
@ -217,34 +217,34 @@ Note: As mentioned above, NAT networking is specifically capable of providing
Windows notes:
1. The Npcap package available from https://nmap.org/npcap is the preferred
interface for Windows 7 onward since the original WinPCAP 4.1.3 package
interface for Windows 7 onward since the original WinPCAP 4.1.3 package
from https://www.winpcap.org/install/bin/WinPcap_4_1_3.exe is no longer
developed or supported. These packages for windows simulate the libpcap
package that is freely available for un*x systems.
developed or supported. These packages for windows simulate the libpcap
package that is freely available for un*x systems.
2. You must *install* the npcap or WinPCAP runtime package.
3. The first time the npcap/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 "npf" driver
to autostart.
Current Npcap and WinPcap installers provide an option to configure this
3. The first time the npcap/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 "npf" driver
to autostart.
Current Npcap and WinPcap installers provide an option to configure this
at installation time, so if that choice is made, then there is no need for
administrator privileged to run simulators with network support.
Building on Windows:
You should be able to build with any of the free compiler environments
available on the Windows platform. If you want to use the Visual C++
Express 2008 or 2010 interactive development environments, read the file
You should be able to build with any of the free compiler environments
available on the Windows platform. If you want to use the Visual C++
Express 2008 or 2010 interactive development environments, read the file
".\Visual Studio Projects\0ReadMe_Projects.txt" for details about the
required dependencies. Alternatively, you can build simh with networking
support using the MinGW GCC compiler environment (32 bit) or the cygwin
environment. Each of these Visual C++, MinGW and cygwin build environments
require Npcap or WinPcap and Posix threading packages being available.
These should be located in a directory structure parallel to the current
support using the MinGW GCC compiler environment (32 bit) or the cygwin
environment. Each of these Visual C++, MinGW and cygwin build environments
require Npcap or WinPcap and Posix threading packages being available.
These should be located in a directory structure parallel to the current
simulator source directory.
For Example, the directory structure should look like:
.../simh/simh-master/VAX/vax_cpu.c
@ -261,16 +261,16 @@ Building on Windows:
There are Windows batch files provided to initiate compiles using the MinGW
compiler tool chain. These batch files are located in the same directory
as this file and are called: build_mingw.bat, build_mingw_ether.bat, and
build_mingw_noasync.bat. These batch files each presume that the MinGW
compiler tool chain. These batch files are located in the same directory
as this file and are called: build_mingw.bat, build_mingw_ether.bat, and
build_mingw_noasync.bat. These batch files each presume that the MinGW
toolchain is either in the current path or, if not that it is located at
C:\MinGW\bin. These batch files merely invoke the MinGW make (GNU make)
passing some specific arguments along with the optional arguments the batch
passing some specific arguments along with the optional arguments the batch
file is invoked with.
The current windows network built binaries will run on any system without
regard to whether or not Npcap or WinPcap is installed, and will provide
The current windows network built binaries will run on any system without
regard to whether or not Npcap or WinPcap is installed, and will provide
Network functionality when Npcap or WinPcap is available.
-------------------------------------------------------------------------------
@ -282,19 +282,19 @@ Linux, {Free|Net|Open}BSD, OS/X, and Un*x notes:
Sim_Ether has been reworked to be more universal; because of this, you will
need to get a version of libpcap that is 0.9 or greater. All current Linux
distributions provide a libpcap-dev package which has the needed version
of libpcap and the required components to build applications using it.
If you are running an older Linux OS, you can download and build the required
library from www.tcpdump.org - see the comments at the top of Sim_ether.c
for details.
of libpcap and the required components to build applications using it.
If you are running an older Linux OS, you can download and build the required
library from www.tcpdump.org - see the comments at the top of Sim_ether.c
for details.
----- WARNING ----- WARNING ----- WARNING ----- WARNING ----- WARNING -----
1. For all platforms, you must run SIMH(scp) with sufficient privilege to
allow the Ethernet card can be set into promiscuous mode and to write
packets through the driver.
a) For Windows systems this means having administrator privileges to
start the "npf" driver. The current WinPcap installer offers an
option to autostart the "npf" driver when the system boots.
packets through the driver.
a) For Windows systems this means having administrator privileges to
start the "npf" driver. The current WinPcap installer offers an
option to autostart the "npf" driver when the system boots.
Starting the "npf" driver at boot time means that simulators do
not need to run with administrator privileges.
b) For more recent Linux systems, The concepts leveraging "Filesystem
@ -303,76 +303,76 @@ for details.
http://packetlife.net/blog/2010/mar/19/sniffing-wireshark-non-root-user/
describes how to do this for wireshark. The exact same capabilities
are needed by SIMH for network support. Use that article as a guide.
c) For Unix/Unix-like systems which use bpf devices (NetBSD,
OpenBSD, FreeBSD and OS/X) it is possible to set permissions on
the bpf devices to allow read and write access to users other
than root (For example: chmod 666 /dev/bpf*). Doing this, has
c) For Unix/Unix-like systems which use bpf devices (NetBSD,
OpenBSD, FreeBSD and OS/X) it is possible to set permissions on
the bpf devices to allow read and write access to users other
than root (For example: chmod 666 /dev/bpf*). Doing this, has
its own security issues.
d) For other platforms this will likely mean running as root.
Additional alternative methods for avoiding the 'run as root' requirement
Additional alternative methods for avoiding the 'run as root' requirement
will be welcomed.
2. If you want to use TAP devices, and any surrounding system network/bridge
setup must be done before running SIMH. However, once that is done
setup must be done before running SIMH. However, once that is done
(possibly at system boot time), using the TAP devices can be done without
root privileges.
Building on Linux, {Free|Net|Open}BSD, OS/X, Solaris, other *nix:
1. Get/make/install the libpcap-dev package (or libpcap-devel) for your
1. Get/make/install the libpcap-dev package (or libpcap-devel) for your
operating system. Sources:
All : http://www.tcpdump.org/
Older versions of libpcap can be found, for various systems, at:
Linux :
Debian Based distributions:
Linux :
Debian Based distributions:
# apt-get install libpcap-dev
RedHat/Fedora Based distributions:
# yum install libpcap-devel
OS/X : The libpcap components are installed as part of the Xcode
developer package. Instructions to install Xcode on various
OSX versions are available at:
OS/X : The libpcap components are installed as part of the Xcode
developer package. Instructions to install Xcode on various
OSX versions are available at:
https://guide.macports.org/chunked/installing.xcode.html
Be sure to install the command line tools which are installed
with the command "xcode-select --install" in more recent
with the command "xcode-select --install" in more recent
versions of the Apple developer support.
HP-UX : ftp://hpux.connect.org.uk/hpux/Networking/Admin/
NOTE: The repositories for older versions of these platforms
don't contain a version of libpcap greater than 0.8.1.
However, most(all) recent releases of *nix environments
ship with sufficiently recent versions of libpcap either
automatically installed or available for installation as
part of the distribution.
The OS provided libpcap-dev components will be prefereable
However, most(all) recent releases of *nix environments
ship with sufficiently recent versions of libpcap either
automatically installed or available for installation as
part of the distribution.
The OS provided libpcap-dev components will be preferable
to a package built from www.tcpdump.org sources. This is
due to the fact that various OS supplied packages will
depend on the OS supplied libpcap. The improper build or
install of the www.tcpdump.org source package can conflict
with the OS provided one and break the OS provided
due to the fact that various OS supplied packages will
depend on the OS supplied libpcap. The improper build or
install of the www.tcpdump.org source package can conflict
with the OS provided one and break the OS provided
applications (i.e. tcpdump and/or wireshark) as well as
not working correctly for use by simh.
2. If you install the vendor supplied libpcap-dev package then the simh
makefile will automatically use the vendor supplied library without any
additional arguments. If you have downloaded and built libpcap from
makefile will automatically use the vendor supplied library without any
additional arguments. If you have downloaded and built libpcap from
www.tcpdump.org, then the existing makefile will detect that this is
the case and try to use that.
3. The makefile defaults to building simulators with network support which
dynamically load the libpcap library. This means that the same simulator
binaries will run on any system whether or not libpcap is installed. If
you want to force direct libpcap linking during a build you do so by
typing 'make USE_NETWORK=1'. You must build with gcc to do this. There
binaries will run on any system whether or not libpcap is installed. If
you want to force direct libpcap linking during a build you do so by
typing 'make USE_NETWORK=1'. You must build with gcc to do this. There
is no observable benefit to statically linking against libpcap. Support
for statically linking libpcap ia deprecated on all platforms except
for statically linking libpcap is deprecated on all platforms except
Linux and OS X where it has already been removed.
4. Some platforms (HP-UX in particular) may not have vendor supplied libpcap
4. Some platforms (HP-UX in particular) may not have vendor supplied libpcap
components available and installed with the operating system. The packages
which are available for this platform install include and library files in
user specified locations. When building on these platforms the library
which are available for this platform install include and library files in
user specified locations. When building on these platforms the library
path must be specified on the make command line. This can be done with:
'make LPATH=/usr/lib:/usr/local/lib'
@ -380,7 +380,7 @@ Building on Linux, {Free|Net|Open}BSD, OS/X, Solaris, other *nix:
-------------------------------------------------------------------------------
OpenVMS Alpha and OpenVMS Integrety (IA64) notes:
OpenVMS Alpha and OpenVMS Integrity (IA64) notes:
1. Ethernet support will only work on Alpha VMS 7.3-1 or later, which is
when required VCI promiscuous mode support was added. Hobbyists can
get the required version of VMS from the OpenVMS Alpha Hobbyist Kit 3.0.
@ -413,13 +413,13 @@ OpenVMS Alpha and OpenVMS Integrety (IA64) notes:
adapter prior trying to connect with SIMH, or the host may crash.
The execlet is not written to create an I/O structure for the device.
Building on OpenVMS Alpha and OpenVMS Integrety (IA64):
Building on OpenVMS Alpha and OpenVMS Integrity (IA64):
The current descrip.mms file will build simulators capable of using
Ethernet support with them automatically. These currently are: VAX,
Ethernet support with them automatically. These currently are: VAX,
VAX780, and PDP11. The descrip.mms driven builds will also build the
pcap library and build and install the VCI execlet.
1. Fetch the VMS-PCAP zip file from:
1. Fetch the VMS-PCAP zip file from:
http://simh.trailing-edge.com/sources/vms-pcap.zip
2. Unzip it into the base of the SIMH distribution directory.
3. Build the simulator(s) with MMS or MMK:
@ -441,7 +441,7 @@ Other testers have reported that RSX with DECNET and the NetBSD operating
systems also work. RSTS/E v10.1 has preliminary support - RSTS/E boots and
enables the XH (XQ) device - DECNET and LAT software have not been tested.
The XU module has been tested by a third party for basic packet functionality
The XU module has been tested by a third party for basic packet functionality
under a modified RSX11M environment. I am unable to test it in-house until
someone can arrange to send me a disk image containing a stock RSTS/E or
RSX11M+ system image that also contains DECNET, LAT, and/or TCP/IP software.
@ -486,9 +486,9 @@ Dave
===============================================================================
Change Log
===============================================================================
01-Mar-12 AGN Added support for building using Cygwin on Windows
01-Mar-12 MP Made host NIC address detection more robust on *nix platforms
01-Mar-12 MP Made host NIC address detection more robust on *nix platforms
and mad it work when compiling under Cygwin
29-Feb-12 MP Fixed MAC Address Conflict detection support
28-Feb-12 MP Fixed overrun bug in eth_devices which caused SEGFAULTs
@ -498,95 +498,95 @@ Dave
17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
29-Oct-11 MP Added support for integrated Tap networking interfaces on OSX
17-Aug-11 RMS Fix from Sergey Oboguev relating to XU and XQ Auto Config and
17-Aug-11 RMS Fix from Sergey Oboguev relating to XU and XQ Auto Config and
vector assignments
12-Aug-11 MP Cleaned up payload length determination
Fixed race condition detecting reflections when threaded
Fixed race condition detecting reflections when threaded
reading and writing is enabled
07-Jul-11 MB VMS Pcap (from Mike Burke)
- Fixed Alpha issues
- Added OpenVMS Integrety support
- Added OpenVMS Integrity support
20-Apr-11 MP Fixed save/restore behavior
12-Jan-11 DTH Added SHOW XU FILTERS modifier
11-Jan-11 DTH Corrected DEUNA/DELUA SELFTEST command, enabling use by
VMS 3.7, VMS 4.7, and Ultrix 1.1
09-Jan-11 MP Fixed missing crc data when USE_READER_THREAD is defined and
09-Jan-11 MP Fixed missing crc data when USE_READER_THREAD is defined and
crc's are needed (only the pdp11_xu)
16-Dec-10 MP added priority boost for read and write threads when
16-Dec-10 MP added priority boost for read and write threads when
USE_READER_THREAD does I/O in separate threads. This helps
throughput since it allows these I/O bound threads to preempt
the main thread (which is executing simulated instructions).
throughput since it allows these I/O bound threads to preempt
the main thread (which is executing simulated instructions).
09-Dec-10 MP allowed more flexible parsing of MAC address strings
09-Dec-10 MP Added support to determine if network address conflicts exist
07-Dec-10 MP Reworked DECnet self detection to the more general approach
of loopback self when any Physical Address is being set.
06-Dec-10 MP Added loopback processing support to pdp11_xu.c
06-Dec-10 MP Fixed loopback processing to correctly handle forward packets.
04-Dec-10 MP Changed eth_write to do nonblocking writes when
04-Dec-10 MP Changed eth_write to do nonblocking writes when
USE_READER_THREAD is defined.
30-Nov-10 MP Fixed the fact that no broadcast packets were received by the DEUNA
29-Nov-10 MP Fixed interrupt dispatch issue which caused delivered packets
29-Nov-10 MP Fixed interrupt dispatch issue which caused delivered packets
(in and out) to sometimes not interrupt the CPU after processing.
17-Jun-10 MP Fixed bug in the AUTODIN II hash filtering.
14-Jun-10 MP Added support for integrated Tap networking interfaces on BSD
14-Jun-10 MP Added support for integrated Tap networking interfaces on BSD
platforms.
13-Jun-10 MP Added support for integrated Tap networking interfaces on Linux
13-Jun-10 MP Added support for integrated Tap networking interfaces on Linux
platforms.
31-May-10 MP Added support for more TOE (TCP Offload Engine) features for IPv4
network traffic from the host and/or from hosts on the LAN. These
new TOE features are: LSO (Large Send Offload) and Jumbo packet
fragmentation support. These features allow a simulated network
device to support traffic when a host leverages a NIC's Large
Send Offload capabilities to fragment and/or segment outgoing
network traffic. Additionally a simulated network device can
device to support traffic when a host leverages a NIC's Large
Send Offload capabilities to fragment and/or segment outgoing
network traffic. Additionally a simulated network device can
reasonably exist on a LAN which is configured to use Jumbo frames.
21-May-10 MP Added functionality to fix up IP header checksums to accommodate
21-May-10 MP Added functionality to fix up IP header checksums to accommodate
packets from a host with a NIC which has TOE (TCP Offload Engine)
enabled which is expected to implement the checksum computations
in hardware. Since we catch packets before they arrive at the
NIC the expected checksum insertions haven't been performed yet.
This processing is only done for packets sent from the host to
the guest we're supporting. In general this will be a relatively
This processing is only done for packets sent from the host to
the guest we're supporting. In general this will be a relatively
small number of packets so it is done for all IP frame packets
coming from the host to the guest. In order to make the
coming from the host to the guest. In order to make the
determination of packets specifically arriving from the host we
need to know the hardware MAC address of the host NIC. Currently
determining a NIC's MAC address is relatively easy on Windows.
The non-windows code works on linux and may work on other *nix
platforms either as is or with slight modifications. The code,
as implemented, only messes with this activity if the host
The non-windows code works on linux and may work on other *nix
platforms either as is or with slight modifications. The code,
as implemented, only messes with this activity if the host
interface MAC address can be determined.
20-May-10 MP Added general support to deal with receiving packets smaller
20-May-10 MP Added general support to deal with receiving packets smaller
than ETH_MIN_PACKET in length. These come from packets
looped back by some bridging mechanism and need to be padded
to the minimum frame size. A real NIC won't pass us any
to the minimum frame size. A real NIC won't pass us any
packets like that. This fix belongs here since this layer
is responsible for interfacing to the physical layer
is responsible for interfacing to the physical layer
devices, AND it belongs here to get CRC processing right.
15-Aug-08 MP Fixed transmitted packets to have the correct source MAC address.
Fixed incorrect address filter setting calling eth_filter().
07-Mar-08 MP Fixed the SCP visible SA registers to always display the
07-Mar-08 MP Fixed the SCP visible SA registers to always display the
ROM MAC address, even after it is changed by SET XQ MAC=.
07-Mar-08 MP Added changes so that the Console DELQA diagnostic (>>>TEST 82)
07-Mar-08 MP Added changes so that the Console DELQA diagnostic (>>>TEST 82)
will succeed.
03-Mar-08 MP Added DELQA-T (aka DELQA Plus) device emulation support.
06-Feb-08 MP Added dropped frame statistics to record when the receiver discards
received packets due to the receiver being disabled, or due to the
XQ device's packet receive queue being full.
Fixed bug in receive processing when we're not polling. This could
cause receive processing to never be activated again if we don't
read all available packets via eth_read each time we get the
cause receive processing to never be activated again if we don't
read all available packets via eth_read each time we get the
opportunity.
31-Jan-08 MP Added the ability to Coalesce received packet interrupts. This
is enabled by SET XQ POLL=DELAY=nnn where nnn is a number of
is enabled by SET XQ POLL=DELAY=nnn where nnn is a number of
microseconds to delay the triggering of an interrupt when a packet
is received.
29-Jan-08 MP Added SET XQ POLL=DISABLE (aka SET XQ POLL=0) to operate without
29-Jan-08 MP Added SET XQ POLL=DISABLE (aka SET XQ POLL=0) to operate without
polling for packet read completion.
29-Jan-08 MP Changed the sanity and id timer mechanisms to use a separate timer
unit so that transmit and receive activities can be dealt with
by the normal xq_svc routine.
Dynamically determine the timer polling rate based on the
Dynamically determine the timer polling rate based on the
calibrated tmr_poll and clk_tps values of the simulator.
25-Jan-08 MP Enabled the SET XQ POLL to be meaningful if the simulator currently
doesn't support idling.
@ -594,7 +594,7 @@ Dave
all debug output goes to the same place.
25-Jan-08 MP Restored the call to xq_svc after all successful calls to eth_write
to allow receive processing to happen before the next event
service time. This must have been inadvertently commented out
service time. This must have been inadvertently commented out
while other things were being tested.
23-Jan-08 MP Added debugging support to display packet headers and packet data
18-Jun-07 RMS Added UNIT_IDLE flag
@ -608,21 +608,21 @@ Dave
LANCE style AUTODIN II based hashed filtering.
07-Feb-08 MP Added eth_show_dev to display Ethernet state
Changed the return value from eth_read to return whether
or not a packet was read. No existing callers used or
or not a packet was read. No existing callers used or
checked constant return value that previously was being
supplied.
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
USE_READER_THREAD is enabled) to allow packet reception
to dynamically update the simulator event queue and
potentially avoid polling for I/O. This provides a minimal
overhead (no polling) maximal responsiveness for network
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
USE_READER_THREAD is enabled) to allow packet reception
to dynamically update the simulator event queue and
potentially avoid polling for I/O. This provides a minimal
overhead (no polling) maximal responsiveness for network
activities.
29-Jan-08 MP Properly sequenced activities in eth_close to avoid a race
condition when USE_READER_THREAD is enabled.
25-Jan-08 MP Changed the following when USE_READER_THREAD is enabled:
- Fixed bug when the simulated device doesn't need crc
- Fixed bug when the simulated device doesn't need crc
in packet data which is read.
- Added call to pcap_setmintocopy to minimize packet
- Added call to pcap_setmintocopy to minimize packet
delivery latencies.
- Added ethq_destroy and used it to avoid a memory leak in
eth_close.
@ -632,8 +632,8 @@ Dave
Fixed the bpf filter used when no traffic is to be matched.
Reworked eth_add_packet_crc32 implementation to avoid an
extra buffer copy while reading packets.
Fixed up #ifdef's relating to USE_SHARED so that setting
USE_SHARED or USE_NETWORK will build a working network
Fixed up #ifdef's relating to USE_SHARED so that setting
USE_SHARED or USE_NETWORK will build a working network
environment.
23-Jan-08 MP Reworked eth_packet_trace and eth_packet_trace_ex to allow
only output Ethernet header+crc and provide a mechanism for
@ -719,7 +719,7 @@ Dave
1. Added VMScluster support (thanks to Mark Pizzolato)
2. Verified VAX remote boot functionality (>>>B XQA0)
3. Added major performance enhancements (thanks to Mark Pizzolato again)
4. Changed _DEBUG tracers to XQ_DEBUG and ETH_DEBUG
4. Changed _DEBUG tracers to XQ_DEBUG and ETH_DEBUG
5. Added local packet processing
6. Added system id broadcast

View file

@ -96,7 +96,7 @@ if (NOT CMAKE_CONFIGURATION_TYPES)
endif ()
# SIMH_SYSTEM_ID: Roughly analogous to the autoconf system triple. Used (almost exclusively)
# as part of the depedencies' top-level directory name.
# as part of the dependencies' top-level directory name.
set(SIMH_SYSTEM_ID ${CMAKE_SYSTEM_NAME})
string(REPLACE "." ";" version_list ${CMAKE_SYSTEM_VERSION})
list(GET version_list 0 version_major)
@ -163,9 +163,9 @@ if (NOT DEFINED MAC_UNIVERSAL)
else ()
set(MAC_UNIVERSAL_OPTVAL ${MAC_UNIVERSAL})
if (MAC_UNIVERSAL_OPTVAL)
message(STATUS "macOS unversal binaries WILL BE BUILT.")
message(STATUS "macOS universal binaries WILL BE BUILT.")
else ()
message(STATUS "macOS unversal binaries NOT WILL BE BUILT.")
message(STATUS "macOS universal binaries NOT WILL BE BUILT.")
endif ()
endif ()
@ -247,7 +247,7 @@ set(DEP_CMAKE_ARGS "-Wno-dev" "--no-warn-unused-cli")
if (NOT (USING_VCPKG OR NO_DEP_BUILD) AND NOT EXISTS ${SIMH_DEP_TOPDIR})
message(STATUS "Creating dependency library directory hierarchy")
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory ${SIMH_DEP_TOPDIR} ${SIMH_DEP_TOPDIR}/include ${SIMH_DEP_TOPDIR}/lib
COMMAND ${CMAKE_COMMAND} -E make_directory ${SIMH_DEP_TOPDIR} ${SIMH_DEP_TOPDIR}/include ${SIMH_DEP_TOPDIR}/lib
${SIMH_DEP_TOPDIR}/bin
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
@ -297,7 +297,7 @@ include(platform-quirks)
# Find packages, arrange for dependency download/compile/install:
#
# SIMH_BUILD_DEPS is the list of the dependecies' names, for pretty-printing.
# SIMH_BUILD_DEPS is the list of the dependencies' names, for pretty-printing.
# SIMH_DEP_TARGETS is the list of dependency targets' names that we'll actually build.
set(SIMH_BUILD_DEPS)

View file

@ -5,7 +5,7 @@
- [Why CMake?](#why-cmake)
- [Before You Begin Building...](#before-you-begin-building)
- [Toolchains and Tools](#toolchains-and-tools)
- [Ninja: "failed recompaction: Permission denied"](#ninja-file-recompation-permission-denied)
- [Ninja: "failed recompaction: Permission denied"](#ninja-file-recompaction-permission-denied)
- [Windows XP-compatible/Server 2003 binaries](#windows-xp-compatibleserver-2003-binaries)
- [Feature Libraries](#feature-libraries)
- [Linux, macOS and MinGW-w64](#linux-macos-and-mingw-w64)
@ -43,7 +43,7 @@ framework. A sample of the supported build environments include:
- Unix Makefiles
- [MinGW Makefiles][mingw64]
- [Ninja][ninja]
- macOS XCode
- macOS Xcode
- MS Visual Studio solutions (2015, 2017, 2019, 2022)
- IDE build wrappers ([Sublime Text][sublime] and [CodeBlocks][codeblocks])
@ -189,7 +189,7 @@ to select a 32-bit target architecture and the `v141_xp` toolkit.
_VS2022_: Install the `v141_xp` tools
Start the Visual Studio Installler, whether this is a new VS2022 install or
Start the Visual Studio Installer, whether this is a new VS2022 install or
modifying an existing installation.
- New install
@ -219,7 +219,7 @@ the [command line](#cmake-command-line) or [via the IDE](#xp-compatible-build-vi
_VS2019_: Install the `v141_xp` tools.
Start the Visual Studio Installler, whether this is a new VS2019 install or
Start the Visual Studio Installer, whether this is a new VS2019 install or
modifying an existing installation.
- New installation: Follow the VS 2022 "New install" instructions. The steps are
@ -373,7 +373,7 @@ Setup and Usage:
PS C:\...\vcpkg> cd ..\open-simh
PS C:\...\open-simh>
```
Then set the `VCPKG_ROOT` environment variable to the `vcpkg` installaton directory.
Then set the `VCPKG_ROOT` environment variable to the `vcpkg` installation directory.
[^1]: `vcpkg` does not support the `v141_xp` toolkit required to compile Windows
XP binaries. Windows XP is a target platform that SIMH can hopefully deprecate
@ -1033,11 +1033,11 @@ within the IDE. The walkthrough provides directions for VS 2022 and VS 2019.
`x64-Release` configuration. And wait for reconfiguration to finish (again.)
5. Select `Build All` from the `Build` menu, or equivalently chord `Ctrl-Shift-B`
on the keyboard, to start the dependecy feature library superbuild.
on the keyboard, to start the dependency feature library superbuild.
- When all dependency feature libraries have been built, the build process
__will__ unexpectedly terminate with a _"failed recompaction: Permission
denied"_ error (see [this `ninja` note](#ninja-file-recompation-permission-denied).)
denied"_ error (see [this `ninja` note](#ninja-file-recompaction-permission-denied).)
Choose `Delete Cache and Reconfigure` from the `Project` menu. This will
cause CMake to reconfigure the project and detect the dependency feature
@ -1141,7 +1141,7 @@ add_simulator(3b2
TEST 3b2)
```
`add_simulator` is relatively self explanitory:
`add_simulator` is relatively self explanatory:
- The first argument is the simulator's executable name: `3b2`. This generates
an executable named `3b2` on Unix platforms or `3b2.exe` on Windows.

View file

@ -99,7 +99,7 @@
#### CDC 1700 simulator from John Forecast
#### Hans-Åke Lund has implemented an SCELBI (SCientic-ELectronics-BIology) simulator.
#### Hans-Åke Lund has implemented an SCELBI (SCientific-ELectronics-BIology) simulator.
#### IBM 650 simulator from Roberto Sancho Villa
@ -351,7 +351,7 @@ The EXPECT command now exists to provide a means of reacting to simulator output
#### Help
The built-in help system provides a heirarchical oriented help command interface.
The built-in help system provides a hierarchical oriented help command interface.
In addition, there is explicit support for per device help:
HELP dev
@ -600,7 +600,7 @@ This link will return a file called simh-vms-pcap.zip which should be unpacked a
$ unzip -a simh-vms-pcap.zip
$ rename [.simh-vms-pcap]pcap-vms.dir []
The PCAP-VMS components are presumed (by the descript.mms file) to be
The PCAP-VMS components are presumed (by the descrip.mms file) to be
located in a directory at the same level as the directory containing the
simh source files. For example, if these exist here:

View file

@ -4,7 +4,7 @@
:: If this procedure is not invoked from a Developer command prompt
:: then the VS2008 tools are preferred if VS2008 is installed,
:: otherwise the installed Visual Studio tools will be used
:: prefering newer Visual Studio versions over older ones.
:: preferring newer Visual Studio versions over older ones.
::
:: If this procedure is invoked from a Developer command prompt
:: then the tool chain provided with the command prompt is used

View file

@ -10,7 +10,7 @@
# HP C V7.3-009-48GBT (AXP), HP C V7.2-001 (IA64) and v6.4-005(VAX).
#
# Notes: On VAX, the PDP-10, Eclipse, IBM 7094 and BESM6 simulators will
# not be built due to the fact that INT64 is required for these
# not be built due to the fact that INT64 is required for these
# simulators.
#
# This build script will accept the following build options.
@ -25,9 +25,9 @@
# ECLIPSE Just Build The Data General Eclipse.
# GRI Just Build The GRI Corporation GRI-909.
# LGP Just Build The Royal-McBee LGP-30.
# H316 Just Build The Honewell 316/516.
# HP2100 Just Build The Hewlett-Packard HP-2100.
# HP3000 Just Build The Hewlett-Packard HP-3000.
# H316 Just Build The Honeywell 316/516.
# HP2100 Just Build The Hewlett-Packard HP-2100.
# HP3000 Just Build The Hewlett-Packard HP-3000.
# I1401 Just Build The IBM 1401.
# I1620 Just Build The IBM 1620.
# I7094 Just Build The IBM 7094.
@ -75,22 +75,22 @@
# VAX8600 Just Build The DEC VAX8600.
# CLEAN Will Clean Files Back To Base Kit.
#
# To build with debugging enabled (which will also enable traceback
# To build with debugging enabled (which will also enable traceback
# information) use..
#
# MMK/MACRO=(DEBUG=1)
#
# This will produce an executable named {Simulator}-{I64|VAX|AXP}-DBG.EXE
#
# To build on older Alpha VMS platforms, SIM_ASYNCH_IO must be disabled.
# To build on older Alpha VMS platforms, SIM_ASYNCH_IO must be disabled.
# use..
#
# MMK/MACRO=(NOASYNCH=1)
#
# On AXP and IA64 the VMS PCAP components are built and used to provide
# On AXP and IA64 the VMS PCAP components are built and used to provide
# network support for the VAX and PDP11 simulators.
#
# The AXP PCAP components can only be built using a version of the
# The AXP PCAP components can only be built using a version of the
# DEC/Compaq/HP Compiler version V6.5-001 or later. To build using an
# older compiler, networking support must be disabled. Use...
#
@ -716,7 +716,7 @@ S3_OPTIONS = /INCL=($(SIMH_DIR),$(S3_DIR))/DEF=($(CC_DEFS))
#
SDS_DIR = SYS$DISK:[.SDS]
SDS_LIB = $(LIB_DIR)SDS-$(ARCH).OLB
SDS_SOURCE = $(SDS_DIR)SDS_CPU.C,$(SDS_DIR)SDS_DRM.C,$(SDS_DIR)SDS_DSK.C,\
SDS_SOURCE = $(SDS_DIR)SDS_CPU.C,$(SDS_DIR)SDS_DRM.C,$(SDS_DIR)SDS_DSK.C,\
$(SDS_DIR)SDS_IO.C,$(SDS_DIR)SDS_LP.C,$(SDS_DIR)SDS_MT.C,\
$(SDS_DIR)SDS_MUX.C,$(SDS_DIR)SDS_RAD.C,$(SDS_DIR)SDS_STDDEV.C,\
$(SDS_DIR)SDS_SYS.C,$(SDS_DIR)SDS_CR.C,$(SDS_DIR)SDS_CP.C
@ -1431,7 +1431,7 @@ ALL : ALTAIR GRI H316 HP2100 I1401 I1620 IBM1130 ID16 ID32 \
$! No further actions necessary
.ENDIF
CLEAN :
CLEAN :
$!
$! Clean out all targets and building Remnants
$!
@ -1578,7 +1578,7 @@ $(ECLIPSE_LIB) : $(ECLIPSE_SOURCE)
#
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
#
$(ECLIPSE_LIB) :
$(ECLIPSE_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
.ENDIF
@ -1832,19 +1832,19 @@ $(KI10_LIB) : $(KI10_SOURCE)
#
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
#
$(PDP10_LIB) :
$(PDP10_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
$(PDP6_LIB) :
$(PDP6_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
$(KA10_LIB) :
$(KA10_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
$(KI10_LIB) :
$(KI10_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
.ENDIF
@ -1955,7 +1955,7 @@ $(BESM6_LIB) : $(BESM6_SOURCE)
#
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
#
$(BESM6_LIB) :
$(BESM6_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
.ENDIF
@ -1978,7 +1978,7 @@ $(B5500_LIB) : $(B5500_SOURCE)
#
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
#
$(B5500_LIB) :
$(B5500_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
.ENDIF
@ -2001,7 +2001,7 @@ $(CDC1700_LIB) : $(CDC1700_SOURCE)
#
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
#
$(CDC1700_LIB) :
$(CDC1700_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
.ENDIF
@ -2499,7 +2499,7 @@ $(I7094_LIB) : $(I7094_SOURCE)
#
# We Are On VAX And Due To The Use of INT64 We Can't Build It.
#
$(I7094_LIB) :
$(I7094_LIB) :
$! Due To The Use Of INT64 We Can't Build The
$! $(MMS$TARGET) Library On VAX.
.ENDIF
@ -2519,7 +2519,7 @@ ATT3B2 : $(BIN_DIR)ATT3B2-$(ARCH).EXE
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
ATT3B2 :
ATT3B2 :
$! Sorry, Can't Build $(BIN_DIR)ATT3B2-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -2557,7 +2557,7 @@ ALTAIRZ80 : $(BIN_DIR)ALTAIRZ80-$(ARCH).EXE
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
ALTAIRZ80 :
ALTAIRZ80 :
$! Sorry, Can't Build $(BIN_DIR)ALTAIRZ80-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -2583,7 +2583,7 @@ ECLIPSE : $(BIN_DIR)ECLIPSE-$(ARCH).EXE
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
ECLIPSE :
ECLIPSE :
$! Sorry, Can't Build $(BIN_DIR)ECLIPSE-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -2847,19 +2847,19 @@ $(BIN_DIR)PDP10-KI-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_NONET_LIB) $(PCAP_LIBD) $(K
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
PDP10 :
PDP10 :
$! Sorry, Can't Build $(BIN_DIR)PDP10-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
PDP6 :
PDP6 :
$! Sorry, Can't Build $(BIN_DIR)PDP6-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
PDP10-KA :
PDP10-KA :
$! Sorry, Can't Build $(BIN_DIR)PDP10-KA-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
PDP10-KI :
PDP10-KI :
$! Sorry, Can't Build $(BIN_DIR)PDP10-KI-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -2968,7 +2968,7 @@ $(BIN_DIR)BESM6-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_NONET_LIB) $(BESM6_LIB)
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
BESM6 :
BESM6 :
$! Sorry, Can't Build $(BIN_DIR)BESM6-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -2994,7 +2994,7 @@ $(BIN_DIR)B5500-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_NONET_LIB) $(B5500_LIB)
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
B5500 :
B5500 :
$! Sorry, Can't Build $(BIN_DIR)B5500-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -3020,7 +3020,7 @@ $(BIN_DIR)CDC1700-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_NONET_LIB) $(CDC1700_LIB)
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
CDC1700 :
CDC1700 :
$! Sorry, Can't Build $(BIN_DIR)CDC1700-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -3363,7 +3363,7 @@ $(BIN_DIR)I7094-$(ARCH).EXE : $(SIMH_MAIN) $(SIMH_NONET_LIB) $(I7094_LIB)
# Else We Are On VAX And Tell The User We Can't Build On VAX
# Due To The Use Of INT64.
#
I7094 :
I7094 :
$! Sorry, Can't Build $(BIN_DIR)I7094-$(ARCH).EXE Simulator
$! Because It Requires The Use Of INT64.
.ENDIF
@ -3375,9 +3375,9 @@ $(PCAP_VCI) : $(PCAP_VCMDIR)PCAPVCM.EXE
$!
$! Installing the PCAP VCI Execlet in SYS$LOADABLE_IMAGES
$!
$ COPY $(PCAP_VCMDIR)PCAPVCM.EXE SYS$COMMON:[SYS$LDR]PCAPVCM.EXE
$ COPY $(PCAP_VCMDIR)PCAPVCM.EXE SYS$COMMON:[SYS$LDR]PCAPVCM.EXE
$(PCAP_VCMDIR)PCAPVCM.EXE : $(PCAP_VCM_SOURCES)
$(PCAP_VCMDIR)PCAPVCM.EXE : $(PCAP_VCM_SOURCES)
$!
$! Building The PCAP VCI Execlet
$!

6
helpx
View file

@ -226,7 +226,7 @@ while( <STDIN> ) {
next;
} elsif ($tok eq 'word' && $val =~ /^fprint_(set|show|reg)_help(?:_ex)?$/) {
my %alt = ( set => "\$Set commands",
show => "\$Show commmands",
show => "\$Show commands",
reg => "\$Registers" );
$b .= "/* Use \"$alt{$1}\" topic instead:\n";
do {
@ -272,7 +272,7 @@ while( <STDIN> ) {
" The SET commands for the device will automagically display above\n"
" this line. Add any special notes.\n"
"2 OSNAME1\n"
" Operating System-specif configuration details\n"
" Operating System-specific configuration details\n"
" If the device needs special configuration for a particular OS, a subtopic\n"
" for each such OS goes here.\n"
"2 Files\n"
@ -299,7 +299,7 @@ while( <STDIN> ) {
"1 Related Devices\n"
" If devices are configured or used together, list the other devices here.\n"
" E.G. The DEC KMC/DUP are two hardware devices that are closely related;\n"
" The KMC controlls the DUP on behalf of the OS.\n"
" The KMC controls the DUP on behalf of the OS.\n"
/* **** Your converted help text starts hare **** */

142
makefile
View file

@ -19,21 +19,21 @@
# In general, the logic below will detect and build with the available
# features which the host build environment provides.
#
# Dynamic loading of libpcap is the preferred default behavior if pcap.h
# Dynamic loading of libpcap is the preferred default behavior if pcap.h
# is available at build time. Support to statically linking against libpcap
# is deprecated and may be removed in the future. Static linking against
# libpcap can be enabled if GNU make is invoked with USE_NETWORK=1 on the
# is deprecated and may be removed in the future. Static linking against
# libpcap can be enabled if GNU make is invoked with USE_NETWORK=1 on the
# command line.
#
# Some platforms may not have vendor supplied libpcap available. HP-UX is
# Some platforms may not have vendor supplied libpcap available. HP-UX is
# one such example. The packages which are available for this platform
# install include files and libraries in user specified directories. In
# order for this makefile to locate where these components may have been
# installed, gmake should be invoked with LPATH=/usr/lib:/usr/local/lib
# install include files and libraries in user specified directories. In
# order for this makefile to locate where these components may have been
# installed, gmake should be invoked with LPATH=/usr/lib:/usr/local/lib
# defined (adjusted as needed depending on where they may be installed).
#
# In the unlikely event that someone wants to build network capable
# simulators without networking support, invoking GNU make with
# In the unlikely event that someone wants to build network capable
# simulators without networking support, invoking GNU make with
# NONETWORK=1 on the command line will do the trick.
#
# By default, video support is enabled if the SDL2 development
@ -44,49 +44,49 @@
# If debugging is desired, then GNU make can be invoked with
# DEBUG=1 on the command line.
#
# When building compiler optimized binaries with the gcc or clang
# compilers, invoking GNU make with LTO=1 on the command line will
# cause the build to use Link Time Optimization to maximally optimize
# the results. Link Time Optimization can report errors which aren't
# otherwise detected and will also take significantly longer to
# When building compiler optimized binaries with the gcc or clang
# compilers, invoking GNU make with LTO=1 on the command line will
# cause the build to use Link Time Optimization to maximally optimize
# the results. Link Time Optimization can report errors which aren't
# otherwise detected and will also take significantly longer to
# complete. Additionally, non debug builds default to build with an
# optimization level of -O2. This optimization level can be changed
# by invoking GNU OPTIMIZE=-O3 (or whatever optimize value you want)
# optimization level of -O2. This optimization level can be changed
# by invoking GNU OPTIMIZE=-O3 (or whatever optimize value you want)
# on the command line if desired.
#
# The default setup will fail simulator build(s) if the compile
# produces any warnings. These should be cleaned up before new
# or changd code is accepted into the code base. This option
# The default setup will fail simulator build(s) if the compile
# produces any warnings. These should be cleaned up before new
# or changed code is accepted into the code base. This option
# can be overridden if GNU make is invoked with WARNINGS=ALLOWED
# on the command line.
#
# The default build will run per simulator tests if they are
# available. If building without running tests is desired,
# then GNU make should be invoked with TESTS=0 on the command
# The default build will run per simulator tests if they are
# available. If building without running tests is desired,
# then GNU make should be invoked with TESTS=0 on the command
# line.
#
# Default test execution will produce summary output. Detailed
# test output can be produced if GNU make is invoked with
# test output can be produced if GNU make is invoked with
# TEST_ARG=-v on the command line.
#
# simh project support is provided for simulators that are built with
# dependent packages provided with the or by the operating system
# distribution OR for platforms where that isn't directly available
# (OS X/macOS) by packages from specific package management systems (MacPorts
# or Homebrew). Users wanting to build simulators with locally built
# dependent packages or packages provided by an unsupported package
# management system may be able to override where this procedure looks
# for include files and/or libraries. Overrides can be specified by define
# exported environment variables or GNU make command line arguments which
# specify INCLUDES and/or LIBRARIES.
# simh project support is provided for simulators that are built with
# dependent packages provided with the or by the operating system
# distribution OR for platforms where that isn't directly available
# (OS X/macOS) by packages from specific package management systems (MacPorts
# or Homebrew). Users wanting to build simulators with locally built
# dependent packages or packages provided by an unsupported package
# management system may be able to override where this procedure looks
# for include files and/or libraries. Overrides can be specified by define
# exported environment variables or GNU make command line arguments which
# specify INCLUDES and/or LIBRARIES.
# Each of these, if specified, must be the complete list include directories
# or library directories that should be used with each element separated by
# or library directories that should be used with each element separated by
# colons. (i.e. INCLUDES=/usr/include/:/usr/local/include/:...)
# If this doesn't work for you and/or you're interested in using a different
# If this doesn't work for you and/or you're interested in using a different
# ToolChain, you're free to solve this problem on your own. Good Luck.
#
# Some environments may have the LLVM (clang) compiler installed as
# an alternate to gcc. If you want to build with the clang compiler,
# an alternate to gcc. If you want to build with the clang compiler,
# invoke make with GCC=clang.
#
# Internal ROM support can be disabled if GNU make is invoked with
@ -362,7 +362,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
$(shell git log -1 --pretty="SIM_GIT_COMMIT_ID %H$(GIT_EXTRA_FILES)%nSIM_GIT_COMMIT_TIME $(isodate)" >.git-commit-id)
endif
endif
LTO_EXCLUDE_VERSIONS =
LTO_EXCLUDE_VERSIONS =
PCAPLIB = pcap
ifeq (agcc,$(findstring agcc,${GCC})) # Android target build?
OS_CCDEFS += -D_GNU_SOURCE
@ -585,16 +585,16 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
LIBEXTSAVE := ${LIBEXT}
LIBEXT = a
ifneq (,$(call find_lib,pthread))
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
OS_LDFLAGS += -lpthread
$(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread))
else
ifneq (,$(findstring Haiku,$(OSTYPE)))
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
$(info using libpthread: $(call find_include,pthread))
else
ifeq (Darwin,$(OSTYPE))
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
OS_LDFLAGS += -lpthread
$(info using macOS libpthread: $(call find_include,pthread))
endif
@ -688,7 +688,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
OS_CCDEFS += -DHAVE_GLOB
else
ifneq (,$(call find_include,fnmatch))
OS_CCDEFS += -DHAVE_FNMATCH
OS_CCDEFS += -DHAVE_FNMATCH
endif
endif
ifneq (,$(call find_include,sys/mman))
@ -1285,8 +1285,8 @@ else
$(info ***********************************************************************)
$(error .)
else
$(info ** date. For the most functional and stable features you shoud **)
$(info ** Download the file: **)
$(info ** date. For the most functional and stable features you should **)
$(info ** download the file: **)
$(info ** https://github.com/simh/windows-build/archive/windows-build.zip **)
$(info ** Extract the windows-build-windows-build folder it contains to **)
$(info ** $(abspath ..\) **)
@ -1332,7 +1332,7 @@ else
else
CFLAGS_O := $(OPTIMIZE)
endif
LDFLAGS_O =
LDFLAGS_O =
GCC_MAJOR_VERSION = $(firstword $(subst ., ,$(GCC_VERSION)))
ifneq (3,$(GCC_MAJOR_VERSION))
ifeq (,$(GCC_OPTIMIZERS_CMD))
@ -1743,7 +1743,7 @@ H316D = ${SIMHD}/H316
H316 = ${H316D}/h316_stddev.c ${H316D}/h316_lp.c ${H316D}/h316_cpu.c \
${H316D}/h316_sys.c ${H316D}/h316_mt.c ${H316D}/h316_fhd.c \
${H316D}/h316_dp.c ${H316D}/h316_rtc.c ${H316D}/h316_imp.c \
${H316D}/h316_hi.c ${H316D}/h316_mi.c ${H316D}/h316_udp.c
${H316D}/h316_hi.c ${H316D}/h316_mi.c ${H316D}/h316_udp.c
H316_OPT = -I ${H316D} -D VM_IMPTIP
@ -1795,7 +1795,7 @@ I7090 = ${I7000D}/i7090_cpu.c ${I7000D}/i7090_sys.c ${I7000D}/i7090_chan.c \
${I7000D}/i7090_cdr.c ${I7000D}/i7090_cdp.c ${I7000D}/i7090_lpr.c \
${I7000D}/i7000_chan.c ${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c \
${I7000D}/i7090_hdrum.c ${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c \
${I7000D}/i7000_com.c ${I7000D}/i7000_ht.c
${I7000D}/i7000_com.c ${I7000D}/i7000_ht.c
I7090_OPT = -I $(I7000D) -DUSE_INT64 -DI7090 -DUSE_SIM_CARD
I7080D = ${SIMHD}/I7000
@ -1803,7 +1803,7 @@ I7080 = ${I7000D}/i7080_cpu.c ${I7000D}/i7080_sys.c ${I7000D}/i7080_chan.c \
${I7000D}/i7080_drum.c ${I7000D}/i7000_cdp.c ${I7000D}/i7000_cdr.c \
${I7000D}/i7000_con.c ${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c \
${I7000D}/i7000_mt.c ${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c \
${I7000D}/i7000_com.c ${I7000D}/i7000_ht.c
${I7000D}/i7000_com.c ${I7000D}/i7000_ht.c
I7080_OPT = -I $(I7000D) -DI7080 -DUSE_SIM_CARD
I7070D = ${SIMHD}/I7000
@ -1811,7 +1811,7 @@ I7070 = ${I7000D}/i7070_cpu.c ${I7000D}/i7070_sys.c ${I7000D}/i7070_chan.c \
${I7000D}/i7000_cdp.c ${I7000D}/i7000_cdr.c ${I7000D}/i7000_con.c \
${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c ${I7000D}/i7000_mt.c \
${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c ${I7000D}/i7000_com.c \
${I7000D}/i7000_ht.c
${I7000D}/i7000_ht.c
I7070_OPT = -I $(I7000D) -DUSE_INT64 -DI7070 -DUSE_SIM_CARD
I7010D = ${SIMHD}/I7000
@ -1819,20 +1819,20 @@ I7010 = ${I7000D}/i7010_cpu.c ${I7000D}/i7010_sys.c ${I7000D}/i7010_chan.c \
${I7000D}/i7000_cdp.c ${I7000D}/i7000_cdr.c ${I7000D}/i7000_con.c \
${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c ${I7000D}/i7000_mt.c \
${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.c ${I7000D}/i7000_com.c \
${I7000D}/i7000_ht.c
${I7000D}/i7000_ht.c
I7010_OPT = -I $(I7010D) -DI7010 -DUSE_SIM_CARD
I704D = ${SIMHD}/I7000
I704 = ${I7000D}/i7090_cpu.c ${I7000D}/i7090_sys.c ${I7000D}/i7090_chan.c \
${I7000D}/i7090_cdr.c ${I7000D}/i7090_cdp.c ${I7000D}/i7090_lpr.c \
${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c ${I7000D}/i7000_chan.c
${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c ${I7000D}/i7000_chan.c
I704_OPT = -I $(I7000D) -DUSE_INT64 -DI704 -DUSE_SIM_CARD
I701D = ${SIMHD}/I7000
I701 = ${I7000D}/i701_cpu.c ${I7000D}/i701_sys.c ${I7000D}/i701_chan.c \
${I7000D}/i7090_cdr.c ${I7000D}/i7090_cdp.c ${I7000D}/i7090_lpr.c \
${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c ${I7000D}/i7000_chan.c
${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.c ${I7000D}/i7000_chan.c
I701_OPT = -I $(I7000D) -DUSE_INT64 -DI701 -DUSE_SIM_CARD
@ -1860,8 +1860,8 @@ IBM1130 = ${IBM1130D}/ibm1130_cpu.c ${IBM1130D}/ibm1130_cr.c \
${IBM1130D}/ibm1130_t2741.c
IBM1130_OPT = -I ${IBM1130D}
ifneq (${WIN32},)
IBM1130_OPT += -DGUI_SUPPORT -lgdi32 ${BIN}ibm1130.o
endif
IBM1130_OPT += -DGUI_SUPPORT -lgdi32 ${BIN}ibm1130.o
endif
ID16D = ${SIMHD}/Interdata
@ -1983,7 +1983,7 @@ INTEL_PARTS = \
${INTELSYSC}/multibus.c \
${INTELSYSC}/mem.c \
${INTELSYSC}/sys.c \
${INTELSYSC}/zx200a.c
${INTELSYSC}/zx200a.c
INTEL_MDSD = ${INTELSYSD}/Intel-MDS
@ -2008,7 +2008,7 @@ IBMPCXT = ${IBMPCXTC}/i8088.c ${IBMPCXTD}/ibmpcxt_sys.c \
${IBMPCXTC}/i8253.c ${IBMPCXTC}/i8259.c \
${IBMPCXTC}/i8255.c ${IBMPCXTD}/ibmpcxt.c \
${IBMPCXTC}/pceprom.c ${IBMPCXTC}/pcram8.c \
${IBMPCXTC}/pcbus.c ${IBMPCXTC}/i8237.c
${IBMPCXTC}/pcbus.c ${IBMPCXTC}/i8237.c
IBMPCXT_OPT = -I ${IBMPCXTD}
@ -2044,7 +2044,7 @@ BESM6_OPT = -I ${BESM6D} -DUSE_INT64 $(BESM6_PANEL_OPT)
PDP6D = ${SIMHD}/PDP10
ifneq (,${DISPLAY_OPT})
PDP6_DISPLAY_OPT =
PDP6_DISPLAY_OPT =
endif
PDP6 = ${PDP6D}/kx10_cpu.c ${PDP6D}/kx10_sys.c ${PDP6D}/kx10_cty.c \
${PDP6D}/kx10_lp.c ${PDP6D}/kx10_pt.c ${PDP6D}/kx10_cr.c \
@ -2057,7 +2057,7 @@ PDP6_OPT = -DPDP6=1 -DUSE_INT64 -I ${PDP6D} -DUSE_SIM_CARD ${DISPLAY_OPT} ${PDP6
KA10D = ${SIMHD}/PDP10
ifneq (,${DISPLAY_OPT})
KA10_DISPLAY_OPT =
KA10_DISPLAY_OPT =
endif
KA10 = ${KA10D}/kx10_cpu.c ${KA10D}/kx10_sys.c ${KA10D}/kx10_df.c \
${KA10D}/kx10_dp.c ${KA10D}/kx10_mt.c ${KA10D}/kx10_cty.c \
@ -2084,7 +2084,7 @@ endif
KI10D = ${SIMHD}/PDP10
ifneq (,${DISPLAY_OPT})
KI10_DISPLAY_OPT =
KI10_DISPLAY_OPT =
endif
KI10 = ${KI10D}/kx10_cpu.c ${KI10D}/kx10_sys.c ${KI10D}/kx10_df.c \
${KI10D}/kx10_dp.c ${KI10D}/kx10_mt.c ${KI10D}/kx10_cty.c \
@ -2191,12 +2191,12 @@ SAGE = ${SAGED}/sage_cpu.c ${SAGED}/sage_sys.c ${SAGED}/sage_stddev.c \
${SAGED}/sage_cons.c ${SAGED}/sage_fd.c ${SAGED}/sage_lp.c \
${SAGED}/m68k_cpu.c ${SAGED}/m68k_mem.c ${SAGED}/m68k_scp.c \
${SAGED}/m68k_parse.tab.c ${SAGED}/m68k_sys.c \
${SAGED}/i8251.c ${SAGED}/i8253.c ${SAGED}/i8255.c ${SAGED}/i8259.c ${SAGED}/i8272.c
${SAGED}/i8251.c ${SAGED}/i8253.c ${SAGED}/i8255.c ${SAGED}/i8259.c ${SAGED}/i8272.c
SAGE_OPT = -I ${SAGED} -DHAVE_INT64
PDQ3D = ${SIMHD}/PDQ-3
PDQ3 = ${PDQ3D}/pdq3_cpu.c ${PDQ3D}/pdq3_sys.c ${PDQ3D}/pdq3_stddev.c \
${PDQ3D}/pdq3_mem.c ${PDQ3D}/pdq3_debug.c ${PDQ3D}/pdq3_fdc.c
${PDQ3D}/pdq3_mem.c ${PDQ3D}/pdq3_debug.c ${PDQ3D}/pdq3_fdc.c
PDQ3_OPT = -I ${PDQ3D}
#
@ -2213,7 +2213,7 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 intel-mds \
scelbi 3b2 3b2-700 i701 i704 i7010 i7070 i7080 i7090 \
sigma uc15 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp6 i650 \
imlac tt2500 sel32
imlac tt2500 sel32
all : ${ALL}
@ -2228,7 +2228,7 @@ else
if exist BIN rmdir /s /q BIN
endif
${BUILD_ROMS} :
${BUILD_ROMS} :
${MKDIRBIN}
ifeq (${WIN32},)
@if ${TEST} \( ! -e $@ \) -o \( sim_BuildROMs.c -nt $@ \) ; then ${CC} sim_BuildROMs.c ${CC_OUTSPEC}; fi
@ -2864,7 +2864,7 @@ endif
b5500 : ${BIN}b5500${EXE}
${BIN}b5500${EXE} : ${B5500} ${SIM}
${BIN}b5500${EXE} : ${B5500} ${SIM}
${MKDIRBIN}
${CC} ${B5500} ${SIM} ${B5500_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${B5500D},b5500))
@ -2874,7 +2874,7 @@ endif
3b2-400 : 3b2
3b2 : ${BIN}3b2${EXE}
${BIN}3b2${EXE} : ${ATT3B2M400} ${SIM}
${MKDIRBIN}
${CC} ${ATT3B2M400} ${SIM} ${ATT3B2M400_OPT} ${CC_OUTSPEC} ${LDFLAGS}
@ -2898,7 +2898,7 @@ endif
i7090 : ${BIN}i7090${EXE}
${BIN}i7090${EXE} : ${I7090} ${SIM}
${BIN}i7090${EXE} : ${I7090} ${SIM}
${MKDIRBIN}
${CC} ${I7090} ${SIM} ${I7090_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${I7000D},i7090))
@ -2907,7 +2907,7 @@ endif
i7080 : ${BIN}i7080${EXE}
${BIN}i7080${EXE} : ${I7080} ${SIM}
${BIN}i7080${EXE} : ${I7080} ${SIM}
${MKDIRBIN}
${CC} ${I7080} ${SIM} ${I7080_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${I7080D},i7080))
@ -2916,7 +2916,7 @@ endif
i7070 : ${BIN}i7070${EXE}
${BIN}i7070${EXE} : ${I7070} ${SIM}
${BIN}i7070${EXE} : ${I7070} ${SIM}
${MKDIRBIN}
${CC} ${I7070} ${SIM} ${I7070_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${I7070D},i7070))
@ -2925,7 +2925,7 @@ endif
i7010 : ${BIN}i7010${EXE}
${BIN}i7010${EXE} : ${I7010} ${SIM}
${BIN}i7010${EXE} : ${I7010} ${SIM}
${MKDIRBIN}
${CC} ${I7010} ${SIM} ${I7010_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${I7010D},i7010))
@ -2934,7 +2934,7 @@ endif
i704 : ${BIN}i704${EXE}
${BIN}i704${EXE} : ${I704} ${SIM}
${BIN}i704${EXE} : ${I704} ${SIM}
${MKDIRBIN}
${CC} ${I704} ${SIM} ${I704_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${I704D},i704))
@ -2943,7 +2943,7 @@ endif
i701 : ${BIN}i701${EXE}
${BIN}i701${EXE} : ${I701} ${SIM}
${BIN}i701${EXE} : ${I701} ${SIM}
${MKDIRBIN}
${CC} ${I701} ${SIM} ${I701_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${I701D},i701))
@ -2952,7 +2952,7 @@ endif
i650 : ${BIN}i650${EXE}
${BIN}i650${EXE} : ${I650} ${SIM}
${BIN}i650${EXE} : ${I650} ${SIM}
${MKDIRBIN}
${CC} ${I650} ${SIM} ${I650_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${I650D},i650))

554
scp.c

File diff suppressed because it is too large Load diff

10
scp.h
View file

@ -23,7 +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.
05-Dec-10 MP Added macro invocation of sim_debug
05-Dec-10 MP Added macro invocation of sim_debug
09-Aug-06 JDB Added assign_device and deassign_device
14-Jul-06 RMS Added sim_activate_abs
06-Jan-06 RMS Added fprint_stopped_gen
@ -253,7 +253,7 @@ void sim_perror (const char *msg);
t_stat sim_call_argv (int (*main_like)(int argc, char *argv[]), const char *cptr);
t_stat sim_messagef (t_stat stat, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void sim_data_trace(DEVICE *dptr, UNIT *uptr, const uint8 *data, const char *position, size_t len, const char *txt, uint32 reason);
void sim_debug_bits_hdr (uint32 dbits, DEVICE* dptr, const char *header,
void sim_debug_bits_hdr (uint32 dbits, DEVICE* dptr, const char *header,
BITFIELD* bitdefs, uint32 before, uint32 after, int terminate);
void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
uint32 before, uint32 after, int terminate);
@ -357,13 +357,13 @@ extern t_stat parse_sym (CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val
int32 sw);
/* The per-simulator init routine is a weak global that defaults to NULL
The other per-simulator pointers can be overrriden by the init routine
The other per-simulator pointers can be overridden by the init routine
extern void (*sim_vm_init) (void);
This routine is no longer invoked this way since it doesn't work reliably
on all simh supported compile environments. A simulator that needs these
initializations can perform them in the CPU device reset routine which will
on all simh supported compile environments. A simulator that needs these
initializations can perform them in the CPU device reset routine which will
always be called before anything else can be processed.
*/

View file

@ -84,7 +84,7 @@
* For these cases, ?#, where # is a 1-based parameter number, can be used
* to selectively include a topic. If the specified parameter is TRUE
* (a string with the value "T", "t" or '1'), the topic will be visible.
* If the parameter is FALSE (NULL, or a string with any other value),
* If the parameter is FALSE (NULL, or a string with any other value),
* the topic will not be visible.
*
* If it can be determined at compile time whether the topic in question
@ -95,7 +95,7 @@
* Guidelines:
* Help should be concise and easy to understand.
*
* The main topic should be short - less than a sceenful when presented with the
* The main topic should be short - less than a screenful when presented with the
* subtopic list.
*
* Keep line lengths to 76 columns or less.
@ -107,7 +107,7 @@
* Hardware Description - The details of the hardware. Feeds & speeds are OK here.
* Models - If the device was offered in distinct models, a subtopic for each.
* Registers - Register descriptions
*
*
* Configuration - How to configure the device under SimH. SET commands.
* Operating System - If the device needs special configuration for a particular
* OS, a subtopic for each such OS goes here.
@ -126,7 +126,7 @@
*
* Related Devices - If devices are configured or used together, list the other devices here.
* E.G. The DEC KMC/DUP are two hardware devices that are closely related;
* The KMC controlls the DUP on behalf of the OS.
* The KMC controls the DUP on behalf of the OS.
*
* This text can be created by any convenient means. It can be mechanically extracted from the device
* source, read from a file, or simply entered as a string in the help routine. To facilitate the latter,
@ -151,7 +151,7 @@
* UNIT *uptr, int flag, const char *help, char *cptr, ...)
*
* If you need to pass the variable argument list from another routine, use:
*
*
* t_stat scp_vhelp (FILE *st, DEVICE *dptr,
* UNIT *uptr, int flag, const char *help, char *cptr, va_list ap)
*
@ -175,12 +175,12 @@
* to a string.)
*
* Lines beginning with ';' will be ignored.
*
*
* Here is a worked-out example:
*
;****************************************************************************
The Whizbang 100 is a DMA line printer controller used on the Whizbang 1000
and Gurgle 1200 processor familes of the Obsolete Hardware Corporation.
and Gurgle 1200 processor families of the Obsolete Hardware Corporation.
1 Hardware Description
The Whizbang 100 is specified to operate "any printer you and a friend can
lift", and speeds up to 0.5 C.
@ -205,7 +205,7 @@
Bit 2 ejects the operator
Bit 3 enables interrupts
3 Print data register
The print data register is thiry-seven bits wide, and accepts data in
The print data register is thirty-seven bits wide, and accepts data in
elephantcode, the precursor to Unicode. Paper advance is accomplished
with the Rocket Return and Page Trampoline characters.
1 Configuration
@ -217,7 +217,7 @@
+ SET WHIZBANG CODESET ASCII
+ SET WHIZBANG CODESET ELEPHANTCODE
The VFU (carriage control tape) is specifed with
The VFU (carriage control tape) is specified with
+ SET WHIZBANG TAPE vfufile
2 WOS
Under WOS, the device will only work at LooneyBus slot 9
@ -231,7 +231,7 @@
2 Examples
TBS
1 Operation
Specify the host file to receive output using the
Specify the host file to receive output using the
+ATTACH WHIZBANG filespec
command.
1 Monitoring

View file

@ -22,7 +22,7 @@
This is the standard card reader.
This is the standard card punch.
Input formats are accepted in a variaty of formats:
Input formats are accepted in a variety of formats:
Standard ASCII: one record per line.
returns are ignored.
tabs are expanded to modules 8 characters.
@ -44,7 +44,7 @@
Bits 5-0 are character.
CBN Format:
Each record 160 charaters.
Each record 160 characters.
First char has bit 7 set. Rest set to 0.
Bit 6 is odd parity.
Bit 5-0 of first character are top 6 bits
@ -60,7 +60,7 @@
is not enough octal numbers to span a full card the remainder of the
card will not be punched.
Also ~eor, will generate a 7/8/9 punch card. An ~eof will gernerate a
Also ~eor, will generate a 7/8/9 punch card. An ~eof will generate a
6/7/9 punch card, and a ~eoi will generate a 6/7/8/9 punch.
A single line of ~ will set the EOF flag when that card is read.
@ -252,7 +252,7 @@ static const uint16 ascii_to_dec_029[128] = {
#if SIMH_EVER_USES_THIS
/* This is a static const that isn't referenced in this code.
* Kept for historical refernce.
* Kept for historical reference.
*/
static const uint16 ascii_to_hol_ebcdic[128] = {
/* Control */
@ -434,7 +434,7 @@ static struct card_formats fmts[] = {
/* Conversion routines */
/* Convert BCD character into hollerith code */
/* Convert BCD character into Hollerith code */
uint16
sim_bcd_to_hol(uint8 bcd) {
uint16 hol;
@ -479,7 +479,7 @@ sim_bcd_to_hol(uint8 bcd) {
return hol;
}
/* Returns the BCD of the hollerith code or 0x7f if error */
/* Returns the BCD of the Hollerith code or 0x7f if error */
uint8
sim_hol_to_bcd(uint16 hol) {
uint8 bcd;
@ -529,7 +529,7 @@ sim_hol_to_bcd(uint16 hol) {
return bcd;
}
/* Convert EBCDIC character into hollerith code */
/* Convert EBCDIC character into Hollerith code */
uint16
sim_ebcdic_to_hol(uint8 ebcdic) {
return ebcdic_to_hol[ebcdic];
@ -537,7 +537,7 @@ sim_ebcdic_to_hol(uint8 ebcdic) {
/* Returns the BCD of the hollerith code or 0x7f if error */
/* Returns the BCD of the Hollerith code or 0x7f if error */
uint16
sim_hol_to_ebcdic(uint16 hol) {
return hol_to_ebcdic[hol];
@ -987,7 +987,7 @@ _sim_read_deck(UNIT * uptr, int eof)
buf.len = 0;
buf.size = 0;
buf.buffer[0] = 0; /* Initialize bufer to empty */
buf.buffer[0] = 0; /* Initialize buffer to empty */
/* Slurp up current file */
do {
@ -1014,7 +1014,7 @@ _sim_read_deck(UNIT * uptr, int eof)
sim_uname(uptr), uptr->filename, sim_error_text(r), cards);
}
data->hopper_cards++;
/* Move data to start at begining of buffer */
/* Move data to start at beginning of buffer */
/* Data is moved down to simplify the decoding of one card */
l = buf.len - buf.size;
j = buf.size;
@ -1059,7 +1059,7 @@ sim_punch_card(UNIT * uptr, uint16 image[80])
/* Convert word record into column image */
/* Check output type, if auto or text, try and convert record to bcd first */
/* If failed and text report error and dump what we have */
/* Else if binary or not convertable, dump as image */
/* Else if binary or not convertible, dump as image */
/* Try to convert to text */
uint8 out[512];

View file

@ -22,7 +22,7 @@
This is the standard card reader.
This is the standard card punch.
Input formats are accepted in a variaty of formats:
Input formats are accepted in a variety of formats:
Standard ASCII: one record per line.
returns are ignored.
tabs are expanded to modules 8 characters.
@ -44,7 +44,7 @@
Bits 5-0 are character.
CBN Format:
Each record 160 charaters.
Each record 160 characters.
First char has bit 7 set. Rest set to 0.
Bit 6 is odd parity.
Bit 5-0 of first character are top 6 bits
@ -60,14 +60,14 @@
ASCII mode recognizes some additional forms of input which allows the
intermixing of binary cards with text cards.
intermixing of binary cards with text cards.
Lines beginning with ~raw are taken as a number of 4 digit octal values
with represent each column of the card from 12 row down to 9 row. If there
is not enough octal numbers to span a full card the remainder of the
is not enough octal numbers to span a full card the remainder of the
card will not be punched.
Also ~eor, will generate a 7/8/9 punch card. An ~eof will gernerate a
Also ~eor, will generate a 7/8/9 punch card. An ~eof will generate a
6/7/9 punch card, and a ~eoi will generate a 6/7/8/9 punch.
A single line of ~ will set the EOF flag when that card is read.
@ -110,7 +110,7 @@ typedef int t_cdstat;
#define CDSE_OK 0 /* Good */
#define CDSE_EOF 1 /* End of File */
#define CDSE_EMPTY 2 /* Input Hopper Empty */
#define CDSE_ERROR 3 /* Error Card Read */
#define CDSE_ERROR 3 /* Error Card Read */
/* Generic routines. */

View file

@ -34,33 +34,33 @@
10-Nov-14 JDB Added -N option to SET CONSOLE LOG and SET CONSOLE DEBUG
02-Jan-14 RMS Added tab stop routines
18-Mar-12 RMS Removed unused reference to sim_switches (Dave Bryan)
07-Dec-11 MP Added sim_ttisatty to support reasonable behaviour (i.e.
07-Dec-11 MP Added sim_ttisatty to support reasonable behaviour (i.e.
avoid in infinite loop) in the main command input
loop when EOF is detected and input is coming from
loop when EOF is detected and input is coming from
a file (or a null device: /dev/null or NUL:) This may
happen when a simulator is running in a background
happen when a simulator is running in a background
process.
17-Apr-11 MP Cleaned up to support running in a background/detached
process
20-Jan-11 MP Fixed support for BREAK key on Windows to account
20-Jan-11 MP Fixed support for BREAK key on Windows to account
for/ignore other keyboard Meta characters.
18-Jan-11 MP Added log file reference count support
17-Jan-11 MP Added support for a "Buffered" behaviors which include:
- If Buffering is enabled and Telnet is enabled, a
telnet connection is not required for simulator
telnet connection is not required for simulator
operation (instruction execution).
- If Buffering is enabled, all console output is
- If Buffering is enabled, all console output is
written to the buffer at all times (deleting the
oldest buffer contents on overflow).
- when a connection is established on the console
- when a connection is established on the console
telnet port, the whole contents of the Buffer is
presented on the telnet session and connection
presented on the telnet session and connection
will then proceed as if the connection had always
been there.
This concept allows a simulator to run in the background
and when needed a console session to be established.
The "when needed" case usually will be interested in
what already happened before looking to address what
and when needed a console session to be established.
The "when needed" case usually will be interested in
what already happened before looking to address what
to do, hence the buffer contents being presented.
28-Dec-10 MP Added support for BREAK key on Windows
30-Sep-06 RMS Fixed non-printable characters in KSR mode
@ -94,7 +94,7 @@
25-Jan-97 RMS Added POSIX terminal I/O support
02-Jan-97 RMS Fixed bug in sim_poll_kbd
This module implements the following routines to support terminal and
This module implements the following routines to support terminal and
Remote Console I/O:
sim_poll_kbd poll for keyboard input
@ -158,7 +158,7 @@
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
#endif
/* Forward Declaraations of Platform specific routines */
/* Forward declarations of platform specific routines */
static t_stat sim_os_poll_kbd (void);
static t_bool sim_os_poll_kbd_ready (int ms_timeout);
@ -257,9 +257,9 @@ return "Console telnet support";
}
DEVICE sim_con_telnet = {
"CON-TELNET", sim_con_units, sim_con_reg, sim_con_mod,
2, 0, 0, 0, 0, 0,
NULL, NULL, sim_con_reset, NULL, sim_con_attach, sim_con_detach,
"CON-TELNET", sim_con_units, sim_con_reg, sim_con_mod,
2, 0, 0, 0, 0, 0,
NULL, NULL, sim_con_reset, NULL, sim_con_attach, sim_con_detach,
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_con_debug,
NULL, NULL, NULL, NULL, NULL, sim_con_telnet_description};
TMLN sim_con_ldsc = { 0 }; /* console line descr */
@ -325,7 +325,7 @@ static t_stat sim_con_detach (UNIT *uptr)
return sim_set_notelnet (0, NULL);
}
/* Forward declaratations */
/* Forward declarations */
static t_stat sim_os_fd_isatty (int fd);
@ -505,9 +505,9 @@ return "Remote Console Facility";
}
DEVICE sim_remote_console = {
"REM-CON", NULL, NULL, sim_rem_con_mod,
0, 0, 0, 0, 0, 0,
NULL, NULL, sim_rem_con_reset, NULL, NULL, NULL,
"REM-CON", NULL, NULL, sim_rem_con_mod,
0, 0, 0, 0, 0, 0,
NULL, NULL, sim_rem_con_reset, NULL, NULL, NULL,
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_rem_con_debug,
NULL, NULL, NULL, NULL, NULL, sim_rem_con_description};
@ -711,7 +711,7 @@ if (c >= 0) { /* poll connect */
tmxr_linemsgf (lp, "%s Remote Console\r\n"
"Enter single commands or to enter multiple command mode enter the %s character\r"
"%s",
sim_name, wru_name,
sim_name, wru_name,
((sim_rem_master_mode && (c == 0)) ? "" : "\nSimulator Running..."));
if (sim_rem_master_mode && (c == 0)) /* Master Mode session? */
rem->single_mode = FALSE; /* start in multi-command mode */
@ -878,7 +878,7 @@ return SCPE_OK;
static t_stat _sim_rem_message (const char *cmd, t_stat stat)
{
CTAB *cmdp = NULL;
t_stat stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */
t_stat stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message suppression flag */
cmdp = find_cmd (cmd);
stat = SCPE_BARE_STATUS(stat); /* remove possible flag */
@ -906,7 +906,7 @@ if ((!sim_oline) && (sim_log)) {
tmxr_linemsgf (lp, "%s", cbuf);
}
sim_oline = NULL;
if ((rem->act == NULL) &&
if ((rem->act == NULL) &&
(!tmxr_input_pending_ln (lp))) {
size_t unwritten;
@ -1001,7 +1001,7 @@ if ((ep != NULL) && (*ep != ';')) { /* if a quoted string is present
if (ep [0] == '\\' && ep [1] == quote) /* if an escaped quote sequence follows */
ep = ep + 2; /* then skip over the pair */
else /* otherwise */
ep = ep + 1; /* skip the non-quote character */
ep = ep + 1; /* skip the non-quote character */
ep = strchr (ep, ';'); /* the next semicolon is outside the quotes if it exists */
}
@ -1019,7 +1019,7 @@ else {
return buf;
}
/*
/*
Parse and setup Remote Console REPEAT command:
REPEAT EVERY nnn USECS Command {; command...}
*/
@ -1100,7 +1100,7 @@ return stat;
}
/*
/*
Parse and setup Remote Console REPEAT command:
COLLECT nnn SAMPLES EVERY nnn CYCLES reg{,reg...}
*/
@ -1396,8 +1396,8 @@ CTAB *basecmdp = NULL;
uint32 read_start_time = 0;
tmxr_poll_rx (&sim_rem_con_tmxr); /* poll input */
for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
(i < sim_rem_con_tmxr.lines) && (!active_command);
for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
(i < sim_rem_con_tmxr.lines) && (!active_command);
i++) {
REMOTE *rem = &sim_rem_consoles[i];
t_bool master_session = (sim_rem_master_mode && (i == 0));
@ -1553,7 +1553,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
c = tmxr_getc_ln (lp);
if (!(TMXR_VALID & c)) {
tmxr_send_buffered_data (lp); /* flush any buffered data */
if (!master_session &&
if (!master_session &&
rem->read_timeout &&
((sim_os_msec() - read_start_time)/1000 >= rem->read_timeout)) {
while (rem->buf_ptr > 0) { /* Erase current input line */
@ -1879,7 +1879,7 @@ if (sim_rem_cmd_active_line != -1) {
return SCPE_REMOTE; /* force sim_instr() to exit to process command */
}
else
sim_activate_after(uptr, 100000); /* check again in 100 milliaeconds */
sim_activate_after(uptr, 100000); /* check again in 100 milliseconds */
if (sim_rem_master_was_enabled && !sim_rem_master_mode) { /* Transitioning out of master mode? */
lp = &sim_rem_con_tmxr.ldsc[0];
tmxr_linemsgf (lp, "Non Master Mode Session..."); /* report transition */
@ -2059,7 +2059,7 @@ return sim_rem_master_mode && /* maste
/* In master mode, commands are subsequently processed from the
primary/initial (master mode) remote console session. Commands
are processed from that source until that source disables master
mode or the simulator exits
mode or the simulator exits
*/
static t_stat sim_set_rem_master (int32 flag, CONST char *cptr)
@ -2092,7 +2092,7 @@ if (sim_rem_master_mode) {
sim_activate (rem_con_data_unit, -1);
stat = run_cmd (RU_GO, "");
if (stat != SCPE_TTMO) {
stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */
stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message suppression flag */
stat = _sim_rem_message ("RUN", stat);
}
brk_action = sim_brk_replace_act (NULL);
@ -2203,7 +2203,7 @@ if (sim_devices[0]->dradix == 16)
else
fprintf (st, "pchar mask = %o", sim_tt_pchar);
if (sim_tt_pchar) {
static const char *pchars[] = {"NUL(^@)", "SOH(^A)", "STX(^B)", "ETX(^C)", "EOT(^D)", "ENQ(^E)", "ACK(^F)", "BEL(^G)",
static const char *pchars[] = {"NUL(^@)", "SOH(^A)", "STX(^B)", "ETX(^C)", "EOT(^D)", "ENQ(^E)", "ACK(^F)", "BEL(^G)",
"BS(^H)" , "HT(^I)", "LF(^J)", "VT(^K)", "FF(^L)", "CR(^M)", "SO(^N)", "SI(^O)",
"DLE(^P)", "DC1(^Q)", "DC2(^R)", "DC3(^S)", "DC4(^T)", "NAK(^U)", "SYN(^V)", "ETB(^W)",
"CAN(^X)", "EM(^Y)", "SUB(^Z)", "ESC", "FS", "GS", "RS", "US"};
@ -2258,14 +2258,14 @@ cptr = get_glyph_nc (cptr, gbuf, 0); /* get file name */
if (*cptr != 0) /* now eol? */
return SCPE_2MARG;
sim_set_logoff (0, NULL); /* close cur log */
r = sim_open_logfile (gbuf, (sim_switches & SWMASK ('B')) == SWMASK ('B'),
r = sim_open_logfile (gbuf, (sim_switches & SWMASK ('B')) == SWMASK ('B'),
&sim_log, &sim_log_ref); /* open log */
if (r != SCPE_OK) /* error? */
return r;
if ((!sim_quiet) && (!(sim_switches & SWMASK ('Q'))))
fprintf (stdout, "Logging to file \"%s\"\n",
fprintf (stdout, "Logging to file \"%s\"\n",
sim_logfile_name (sim_log, sim_log_ref));
fprintf (sim_log, "Logging to file \"%s\"\n",
fprintf (sim_log, "Logging to file \"%s\"\n",
sim_logfile_name (sim_log, sim_log_ref)); /* start of log */
time(&now);
if ((!sim_quiet) && (!(sim_switches & SWMASK ('Q'))))
@ -2296,7 +2296,7 @@ t_stat sim_show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char
if (cptr && (*cptr != 0))
return SCPE_2MARG;
if (sim_log)
fprintf (st, "Logging enabled to \"%s\"\n",
fprintf (st, "Logging enabled to \"%s\"\n",
sim_logfile_name (sim_log, sim_log_ref));
else
fprintf (st, "Logging disabled\n");
@ -2309,9 +2309,9 @@ int32 sim_set_deb_switches (int32 switches)
{
int32 old_deb_switches = sim_deb_switches;
sim_deb_switches = switches &
(SWMASK ('R') | SWMASK ('P') |
SWMASK ('T') | SWMASK ('A') |
sim_deb_switches = switches &
(SWMASK ('R') | SWMASK ('P') |
SWMASK ('T') | SWMASK ('A') |
SWMASK ('F') | SWMASK ('N') |
SWMASK ('B') | SWMASK ('E') |
SWMASK ('D') ); /* save debug switches */
@ -2370,7 +2370,7 @@ if (sim_deb_switches & SWMASK ('F'))
if (sim_deb_switches & SWMASK ('E'))
sim_messagef (SCPE_OK, " Debug messages containing blob data in EBCDIC will display in readable form\n");
if (sim_deb_switches & SWMASK ('B'))
sim_messagef (SCPE_OK, " Debug messages will be written to a %u MB circular memory buffer\n",
sim_messagef (SCPE_OK, " Debug messages will be written to a %u MB circular memory buffer\n",
(unsigned int)buffer_size);
time(&now);
if (!sim_quiet) {
@ -2432,7 +2432,7 @@ int32 i;
if (cptr && (*cptr != 0))
return SCPE_2MARG;
if (sim_deb) {
fprintf (st, "Debug output enabled to \"%s\"\n",
fprintf (st, "Debug output enabled to \"%s\"\n",
sim_logfile_name (sim_deb, sim_deb_ref));
if (sim_deb_switches & SWMASK ('P'))
fprintf (st, " Debug messages contain current PC value\n");
@ -2536,7 +2536,7 @@ t_stat sim_show_telnet (FILE *st, DEVICE *dunused, UNIT *uunused, int32 flag, CO
{
if (cptr && (*cptr != 0))
return SCPE_2MARG;
if ((sim_con_tmxr.master == 0) &&
if ((sim_con_tmxr.master == 0) &&
(sim_con_ldsc.serport == 0))
fprintf (st, "Connected to console window\n");
else {
@ -2544,7 +2544,7 @@ else {
fprintf (st, "Connected to ");
tmxr_fconns (st, &sim_con_ldsc, -1);
}
else
else
if (sim_con_ldsc.sock == 0)
fprintf (st, "Listening on port %s\n", sim_con_tmxr.port);
else {
@ -2790,7 +2790,7 @@ if (!ref)
return ref->name;
}
/* Check connection before executing
/* Check connection before executing
(including a remote console which may be required in master mode) */
t_stat sim_check_console (int32 sec)
@ -2827,7 +2827,7 @@ if (trys == sec) {
return SCPE_TTMO; /* timed out */
}
if (sim_con_ldsc.serport)
if (tmxr_poll_conn (&sim_con_tmxr) >= 0)
if (tmxr_poll_conn (&sim_con_tmxr) >= 0)
sim_con_ldsc.rcve = 1; /* rcv enabled */
if ((sim_con_tmxr.master == 0) || /* serial console or not Telnet? done */
(sim_con_ldsc.serport))
@ -2931,7 +2931,7 @@ if (!sim_rem_master_mode) {
}
}
tmxr_poll_rx (&sim_con_tmxr); /* poll for input */
if ((c = (t_stat)tmxr_getc_ln (&sim_con_ldsc))) { /* any char? */
if ((c = (t_stat)tmxr_getc_ln (&sim_con_ldsc))) { /* any char? */
sim_debug (DBG_RCV, &sim_con_telnet, "sim_poll_kbd() tmxr_getc_ln() returning: '%c' (0x%02X)\n", sim_isprint (c & 0xFF) ? c & 0xFF : '.', c);
return (c & (SCPE_BREAK | 0377)) | SCPE_KFLAG;
}
@ -3128,7 +3128,7 @@ if ((md == TTUF_MODE_UC) && (par_mode == TTUF_PAR_MARK))
fprintf (st, "KSR (UC, MARK parity)");
else
fprintf (st, "%s", modes[md]);
if ((md != TTUF_MODE_8B) &&
if ((md != TTUF_MODE_8B) &&
((md != TTUF_MODE_UC) || (par_mode != TTUF_PAR_MARK))) {
if (par_mode != 0)
fprintf (st, ", %s parity", parity[par_mode]);
@ -3153,8 +3153,8 @@ _console_poll(void *arg)
int wait_count = 0;
DEVICE *d;
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which, in general, won't be readily yielding the processor when
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which, in general, won't be readily yielding the processor when
this thread needs to run */
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
@ -3496,11 +3496,11 @@ static DWORD saved_error_mode;
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
/* Note: This routine catches all the potential events which some aspect
of the windows system can generate. The CTRL_C_EVENT won't be
generated by a user typing in a console session since that
/* Note: This routine catches all the potential events which some aspect
of the windows system can generate. The CTRL_C_EVENT won't be
generated by a user typing in a console session since that
session is in RAW mode. In general, Ctrl-C on a simulator's
console terminal is a useful character to be passed to the
console terminal is a useful character to be passed to the
simulator. This code does nothing to disable or affect that. */
#include <signal.h>
@ -3513,7 +3513,7 @@ ControlHandler(DWORD dwCtrlType)
switch (dwCtrlType)
{
case CTRL_BREAK_EVENT: // Use CTRL-Break or CTRL-C to simulate
case CTRL_BREAK_EVENT: // Use CTRL-Break or CTRL-C to simulate
case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
int_handler(SIGINT);
return TRUE;
@ -3927,11 +3927,11 @@ static t_stat sim_os_ttinit (void)
sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_ttinit()\n");
cmdfl = fcntl (fileno (stdin), F_GETFL, 0); /* get old flags and status */
/*
/*
* make sure systems with broken termios (that don't honor
* VMIN=0 and VTIME=0) actually implement non blocking reads.
* This will have no negative effect on other systems since
* this is turned on and off depending on whether simulation
* VMIN=0 and VTIME=0) actually implement non blocking reads.
* This will have no negative effect on other systems since
* this is turned on and off depending on whether simulation
* is running or not.
*/
runfl = cmdfl | O_NONBLOCK;
@ -4130,7 +4130,7 @@ else {
mbuf2 = (char *)malloc (3 + strlen(cptr));
sprintf (mbuf2, "%s%s%s", (sim_switches & SWMASK ('A')) ? "\n" : "",
mbuf,
mbuf,
(sim_switches & SWMASK ('I')) ? "" : "\n");
free (mbuf);
mbuf = sim_encode_quoted_string ((uint8 *)mbuf2, strlen (mbuf2));

View file

@ -212,7 +212,7 @@ extern "C" {
/* Length specific integer declarations */
/* Handle the special/unusual cases first with everything else leveraging stdints.h */
/* Handle the special/unusual cases first with everything else leveraging stdint.h */
#if defined (VMS)
#include <ints.h>
#elif defined(_MSC_VER) && (_MSC_VER < 1600)
@ -224,7 +224,7 @@ typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
#else
/* All modern/standard compiler environments */
/* any other environment needa a special case above */
/* any other environment needs a special case above */
#include <stdint.h>
typedef int8_t int8;
typedef int16_t int16;
@ -435,7 +435,7 @@ typedef uint32 t_addr;
#define SCPE_MAX_ERR (SCPE_BASE + 51) /* Maximum SCPE Error Value */
#define SCPE_KFLAG 0x10000000 /* tti data flag */
#define SCPE_BREAK 0x20000000 /* tti break flag */
#define SCPE_NOMESSAGE 0x40000000 /* message display supression flag */
#define SCPE_NOMESSAGE 0x40000000 /* message display suppression flag */
#define SCPE_BARE_STATUS(stat) ((stat) & ~(SCPE_NOMESSAGE|SCPE_KFLAG|SCPE_BREAK))
/* Print value format codes */

View file

@ -28,7 +28,7 @@
This is the place which hides processing of various disk formats,
as well as OS-specific direct hardware access.
25-Jan-11 MP Initial Implemementation
25-Jan-11 MP Initial Implementation
Public routines:
@ -276,8 +276,8 @@ return NULL;
processing events for any unit. It is only called when an asynchronous
thread has called sim_activate() to activate a unit. The job of this
routine is to put the unit in proper condition to digest what may have
occurred in the asynchrconous thread.
occurred in the asynchronous thread.
Since disk processing only handles a single I/O at a time to a
particular disk device (due to using stdio for the SimH Disk format
and stdio doesn't have an atomic seek+(read|write) operation),
@ -487,7 +487,7 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
sim_switches = 0;
sim_quiet = 1;
strcpy (path, uptr->filename);
sim_disk_attach (uptr, path, ctx->sector_size, ctx->xfer_element_size,
sim_disk_attach (uptr, path, ctx->sector_size, ctx->xfer_element_size,
FALSE, ctx->dbit, NULL, 0, 0);
sim_quiet = saved_quiet;
sim_switches = saved_switches;
@ -524,7 +524,7 @@ DEVICE *dptr;
uint32 dev, unit, count = 0;
if (flag == sim_disk_no_autosize)
return sim_messagef (SCPE_ARG, "Autosizing is already %sabled!\n",
return sim_messagef (SCPE_ARG, "Autosizing is already %sabled!\n",
sim_disk_no_autosize ? "dis" : "en");
for (dev = 0; (dptr = sim_devices[dev]) != NULL; dev++) {
if ((DEV_TYPE (dptr) != DEV_DISK) ||
@ -665,7 +665,7 @@ while (tbc) {
if (i < tbc) /* fill */
memset (&buf[i], 0, tbc-i);
if ((i == 0) && /* Reading at or past EOF? */
feof (uptr->fileref))
feof (uptr->fileref))
i = tbc; /* return 0's which have already been filled in buffer */
sectbytes = (i / ctx->sector_size) * ctx->sector_size;
if (i > sectbytes)
@ -871,7 +871,7 @@ if (f == DKUF_F_RAW) {
if (tbuf == NULL)
return SCPE_MEM;
/* Partial Sector writes require a read-modify-write sequence for the partial sectors */
if (soffset)
if (soffset)
sim_os_disk_read (uptr, ssaddr, tbuf, NULL, ctx->storage_sector_size);
sim_os_disk_read (uptr, sladdr, tbuf + (size_t)(sladdr - ssaddr), NULL, ctx->storage_sector_size);
sim_buf_copy_swapped (tbuf + soffset,
@ -982,13 +982,13 @@ static t_stat _sim_disk_rdsect_interleave (UNIT *uptr, t_lba lba, uint8 *buf, t_
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
t_lba sectno = lba, psa;
t_stat status;
if (sectsread)
*sectsread = 0;
do {
uint16 i, track, sector;
/*
* Map an LBA address into a physical sector address
*/
@ -1141,7 +1141,7 @@ typedef struct _ODS2_FileHeader
typedef union _ODS2_Retreval
{
struct
struct
{
unsigned fm2___fill : 14; /* type specific data */
unsigned fm2_v_format : 2; /* format type code */
@ -1278,31 +1278,31 @@ if ((_DEC_rdsect (uptr, 512 / ctx->sector_size, (uint8 *)&Home, &sects_read, siz
goto Return_Cleanup;
CheckSum1 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum1)-((char *)&Home.hm2_l_homelbn))/2));
CheckSum2 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum2)-((char *)&Home.hm2_l_homelbn))/2));
if ((Home.hm2_l_homelbn == 0) ||
(Home.hm2_l_alhomelbn == 0) ||
(Home.hm2_l_altidxlbn == 0) ||
((Home.hm2_b_struclev != 2) && (Home.hm2_b_struclev != 5)) ||
(Home.hm2_b_strucver == 0) ||
(Home.hm2_w_cluster == 0) ||
(Home.hm2_w_homevbn == 0) ||
(Home.hm2_w_alhomevbn == 0) ||
(Home.hm2_w_ibmapvbn == 0) ||
(Home.hm2_l_ibmaplbn == 0) ||
(Home.hm2_w_resfiles >= Home.hm2_l_maxfiles) ||
(Home.hm2_w_ibmapsize == 0) ||
(Home.hm2_w_resfiles < 5) ||
if ((Home.hm2_l_homelbn == 0) ||
(Home.hm2_l_alhomelbn == 0) ||
(Home.hm2_l_altidxlbn == 0) ||
((Home.hm2_b_struclev != 2) && (Home.hm2_b_struclev != 5)) ||
(Home.hm2_b_strucver == 0) ||
(Home.hm2_w_cluster == 0) ||
(Home.hm2_w_homevbn == 0) ||
(Home.hm2_w_alhomevbn == 0) ||
(Home.hm2_w_ibmapvbn == 0) ||
(Home.hm2_l_ibmaplbn == 0) ||
(Home.hm2_w_resfiles >= Home.hm2_l_maxfiles) ||
(Home.hm2_w_ibmapsize == 0) ||
(Home.hm2_w_resfiles < 5) ||
(Home.hm2_w_checksum1 != CheckSum1) ||
(Home.hm2_w_checksum2 != CheckSum2))
goto Return_Cleanup;
if ((_DEC_rdsect (uptr, (Home.hm2_l_ibmaplbn+Home.hm2_w_ibmapsize+1) * (512 / ctx->sector_size),
(uint8 *)&Header, &sects_read, sizeof (Header) / ctx->sector_size, physsectsz)) ||
if ((_DEC_rdsect (uptr, (Home.hm2_l_ibmaplbn+Home.hm2_w_ibmapsize+1) * (512 / ctx->sector_size),
(uint8 *)&Header, &sects_read, sizeof (Header) / ctx->sector_size, physsectsz)) ||
(sects_read != (sizeof (Header) / ctx->sector_size)))
goto Return_Cleanup;
CheckSum1 = ODSChecksum (&Header, 255);
if (CheckSum1 != *(((uint16 *)&Header)+255)) /* Verify Checksum on BITMAP.SYS file header */
goto Return_Cleanup;
Retr = (ODS2_Retreval *)(((uint16*)(&Header))+Header.fh2_b_mpoffset);
/* The BitMap File has a single extent, which may be preceeded by a placement descriptor */
/* The BitMap File has a single extent, which may be preceded by a placement descriptor */
if (Retr->fm2_r_word0_bits.fm2_v_format == 0)
Retr = (ODS2_Retreval *)(((uint16 *)Retr)+1); /* skip placement descriptor */
switch (Retr->fm2_r_word0_bits.fm2_v_format)
@ -1324,12 +1324,12 @@ if ((_DEC_rdsect (uptr, ScbLbn * (512 / ctx->sector_size), (uint8 *)&Scb, &sects
CheckSum1 = ODSChecksum (&Scb, 255);
if (CheckSum1 != *(((uint16 *)&Scb)+255)) /* Verify Checksum on Storage Control Block */
goto Return_Cleanup;
if ((Scb.scb_w_cluster != Home.hm2_w_cluster) ||
if ((Scb.scb_w_cluster != Home.hm2_w_cluster) ||
(Scb.scb_b_strucver != Home.hm2_b_strucver) ||
(Scb.scb_b_struclev != Home.hm2_b_struclev))
goto Return_Cleanup;
sim_messagef (SCPE_OK, "%s: '%s' Contains ODS%d File system\n", sim_uname (uptr), uptr->filename, Home.hm2_b_struclev);
sim_messagef (SCPE_OK, "%s: Volume Name: %12.12s Format: %12.12s Sectors In Volume: %u\n",
sim_messagef (SCPE_OK, "%s: Volume Name: %12.12s Format: %12.12s Sectors In Volume: %u\n",
sim_uname (uptr), Home.hm2_t_volname, Home.hm2_t_format, Scb.scb_l_volsize);
ret_val = ((t_offset)Scb.scb_l_volsize) * 512;
@ -1365,12 +1365,12 @@ if ((_DEC_rdsect (uptr, 512 / ctx->sector_size, (uint8 *)&Home, &sects_read, siz
goto Return_Cleanup;
CheckSum1 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm1_w_checksum1)-((char *)&Home.hm1_w_ibmapsize))/2));
CheckSum2 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm1_w_checksum2)-((char *)&Home.hm1_w_ibmapsize))/2));
if ((Home.hm1_w_ibmapsize == 0) ||
(Home.hm1_l_ibmaplbn == 0) ||
(Home.hm1_w_maxfiles == 0) ||
(Home.hm1_w_cluster != 1) ||
((Home.hm1_w_structlev != HM1_C_LEVEL1) && (Home.hm1_w_structlev != HM1_C_LEVEL2)) ||
(Home.hm1_l_ibmaplbn == 0) ||
if ((Home.hm1_w_ibmapsize == 0) ||
(Home.hm1_l_ibmaplbn == 0) ||
(Home.hm1_w_maxfiles == 0) ||
(Home.hm1_w_cluster != 1) ||
((Home.hm1_w_structlev != HM1_C_LEVEL1) && (Home.hm1_w_structlev != HM1_C_LEVEL2)) ||
(Home.hm1_l_ibmaplbn == 0) ||
(Home.hm1_w_checksum1 != CheckSum1) ||
(Home.hm1_w_checksum2 != CheckSum2))
goto Return_Cleanup;
@ -1392,7 +1392,7 @@ if (Scb->scb_b_bitmapblks < 127)
else
ret_val = (((t_offset)Scb->scb_r_blocks[0].scb_w_freeblks << 16) + Scb->scb_r_blocks[0].scb_w_freeptr) * 512;
sim_messagef (SCPE_OK, "%s: '%s' Contains an ODS1 File system\n", sim_uname (uptr), uptr->filename);
sim_messagef (SCPE_OK, "%s: Volume Name: %12.12s Format: %12.12s Sectors In Volume: %u\n",
sim_messagef (SCPE_OK, "%s: Volume Name: %12.12s Format: %12.12s Sectors In Volume: %u\n",
sim_uname (uptr), Home.hm1_t_volname, Home.hm1_t_format, (uint32)(ret_val / 512));
Return_Cleanup:
uptr->capac = saved_capac;
@ -1434,7 +1434,7 @@ if ((_DEC_rdsect (uptr, 31 * (512 / ctx->sector_size), sector_buf, &sects_read,
(sects_read != (512 / ctx->sector_size)))
goto Return_Cleanup;
if ((Label->pt_magic != PT_MAGIC) ||
if ((Label->pt_magic != PT_MAGIC) ||
(Label->pt_valid != PT_VALID))
goto Return_Cleanup;
@ -1524,7 +1524,7 @@ saved_capac = uptr->capac;
uptr->capac = temp_capac;
while (sim_disk_rdsect(uptr, (t_lba)(sectfactor * cur_pos / sizeof (*Desc)), (uint8 *)Desc, &sectsread, sectfactor) == DKSE_OK) {
if ((sectsread != sectfactor) ||
if ((sectsread != sectfactor) ||
(Desc->Version != 1) ||
(0 != memcmp (Desc->Identifier, "CD001", sizeof (Desc->Identifier))))
break;
@ -2027,7 +2027,7 @@ for (context.dcshift = 0; context.dcshift < 8; context.dcshift++) {
}
sim_messagef(SCPE_OK, "%s: '%s' Contains a RSTS File system\n", sim_uname (uptr), uptr->filename);
sim_messagef(SCPE_OK, "%s: Pack ID: %6.6s Revision Level: %3s Pack Clustersize: %d\n",
sim_messagef(SCPE_OK, "%s: Pack ID: %6.6s Revision Level: %3s Pack Clustersize: %d\n",
sim_uname (uptr), context.packid, fmt, context.pcs);
sim_messagef(SCPE_OK, "%s: Last Unallocated Sector In File System: %u\n", sim_uname (uptr), (uint32)((ret_val / 512) - 1));
goto cleanup_done;
@ -2120,7 +2120,7 @@ if (strncmp((char *)&home->hb_b_sysid, HB_C_SYSID, strlen(HB_C_SYSID)) == 0) {
if (strncmp((char *)&home->hb_b_sysid, HB_C_VMSSYSID, strlen(HB_C_VMSSYSID)) == 0)
return RT11_SINGLEPART;
return RT11_NOPART;
}
@ -2156,7 +2156,7 @@ for (part = 0; part < RT11_MAXPARTITIONS; part++) {
*/
if ((part != 0) && (physsectsz != 0))
break;
base = part << 16;
if (_DEC_rdsect(uptr, (base + RT11_HOME) * (512 / ctx->sector_size), (uint8 *)&Home, &sects_read, 512 / ctx->sector_size, physsectsz) ||
@ -2293,22 +2293,22 @@ for (i = 0; checks[i] != NULL; i++)
if ((ret_val = checks[i] (uptr, 0, readonly)) != (t_offset)-1) {
/* ISO files that haven't already been determined to be ISO 9660
* which contain a known file system are also marked read-only
* now. This fits early DEC distribution CDs that were created
* now. This fits early DEC distribution CDs that were created
* before ISO 9660 was standardized and operating support was added.
*/
if ((readonly != NULL) &&
if ((readonly != NULL) &&
(*readonly == FALSE) &&
(NULL != match_ext (uptr->filename, "ISO")))
*readonly = TRUE;
return ret_val;
}
/*
* The only known interleaved disk devices have either 256 byte
* or 128 byte sector sizes. If additional interleaved file
/*
* The only known interleaved disk devices have either 256 byte
* or 128 byte sector sizes. If additional interleaved file
* system scenarios with different sector sizes come up they
* should be added here.
*/
for (i = 0; checks[i] != NULL; i++) {
ctx->sector_size = 256;
if ((ret_val = checks[i] (uptr, ctx->sector_size, readonly)) != (t_offset)-1)
@ -2318,7 +2318,7 @@ for (i = 0; checks[i] != NULL; i++) {
break;
}
if ((ret_val != (t_offset)-1) && (ctx->sector_size != saved_sector_size ))
sim_messagef (SCPE_OK, "%s: with an unexpected sector size of %u bytes instead of %u bytes\n",
sim_messagef (SCPE_OK, "%s: with an unexpected sector size of %u bytes instead of %u bytes\n",
sim_uname (uptr), ctx->sector_size, saved_sector_size);
ctx->sector_size = saved_sector_size;
return ret_val;
@ -2395,7 +2395,7 @@ if (f) {
}
else {
/* We've got a valid footer, but it may need to be corrected */
if ((NtoHl (f->TransferElementSize) == 1) &&
if ((NtoHl (f->TransferElementSize) == 1) &&
(0 == memcmp (f->DriveType, "RZ", 2))) {
f->TransferElementSize = NtoHl (2);
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
@ -2415,12 +2415,12 @@ if (f) {
" AccessFormat: %u\n"
" CreationTime: %s",
sim_uname (uptr), uptr->filename,
f->CreatingSimulator, f->DriveType, NtoHl(f->SectorSize), NtoHl (f->SectorCount),
f->CreatingSimulator, f->DriveType, NtoHl(f->SectorSize), NtoHl (f->SectorCount),
NtoHl (f->TransferElementSize), f->FooterVersion, f->AccessFormat, f->CreationTime);
if (f->DeviceName[0] != '\0')
sim_debug_unit (ctx->dbit, uptr,
sim_debug_unit (ctx->dbit, uptr,
" DeviceName: %s\n", (char *)f->DeviceName);
sim_debug_unit (ctx->dbit, uptr,
sim_debug_unit (ctx->dbit, uptr,
" HighwaterSector: %u\n", (uint32)(ctx->highwater/ctx->sector_size));
}
}
@ -2677,7 +2677,7 @@ if (sim_switches & SWMASK ('C')) { /* create new disk conta
}
sim_messagef (SCPE_OK, "Copying %u sectors each %u bytes in size\n", (uint32)total_sectors, (uint32)sector_size);
if (source_capac > target_capac) {
sim_messagef (SCPE_OK, "The source container is %u sectors larger than the destination disk container\n",
sim_messagef (SCPE_OK, "The source container is %u sectors larger than the destination disk container\n",
(t_lba)(((source_capac - target_capac)*capac_factor)/(sector_size/((dptr->flags & DEV_SECTORS) ? 512 : 1))));
sim_messagef (SCPE_OK, "these additional sectors will be unavailable on the target drive\n");
}
@ -2739,7 +2739,7 @@ if (sim_switches & SWMASK ('C')) { /* create new disk conta
uptr->fileref = save_unit_fileref;
uptr->flags = saved_unit_flags;
if (r == SCPE_OK) {
if ((sects_read != verify_read) ||
if ((sects_read != verify_read) ||
(0 != memcmp (copy_buf, verify_buf, verify_read*sector_size)))
r = SCPE_IOERR;
}
@ -2967,7 +2967,7 @@ if ((DK_GET_FMT (uptr) == DKUF_F_VHD) || (ctx->footer)) {
if ((container_sector_size != 0) && (sector_size != container_sector_size))
r = sim_messagef (SCPE_OPENERR, "%s: Incompatible Container Sector Size %d\n", sim_uname (uptr), container_sector_size);
else {
if (dontchangecapac &&
if (dontchangecapac &&
((((t_lba)(ctx->container_size/sector_size) > current_unit_sectors)) ||
((container_sectors != 0) && (container_sectors != current_unit_sectors)))) {
r = sim_messagef (SCPE_OK, "%s: Container has %u sectors, drive has: %u sectors\n", sim_uname (uptr), container_sectors, current_unit_sectors);
@ -3034,7 +3034,7 @@ if ((created) && (!copied)) {
t_lba lba;
t_lba total_lbas = (t_lba)((((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1))/ctx->sector_size);
for (lba = 0; (r == SCPE_OK) && (lba < total_lbas); lba += 128) {
for (lba = 0; (r == SCPE_OK) && (lba < total_lbas); lba += 128) {
t_seccnt sectors = ((lba + 128) <= total_lbas) ? 128 : total_lbas - lba;
r = sim_disk_wrsect (uptr, lba, secbuf, NULL, sectors);
@ -3077,7 +3077,7 @@ if ((created) && (!copied)) {
free (init_buf);
sim_disk_detach (uptr); /* report error now */
(void)remove (cptr); /* remove the created file */
return sim_messagef (SCPE_OPENERR, "Error initializing each sector with its address: %s\n",
return sim_messagef (SCPE_OPENERR, "Error initializing each sector with its address: %s\n",
(r == SCPE_OK) ? sim_error_text (r) : "sectors written not what was requested");
}
sim_messagef (SCPE_OK, "%s: Initialized To Sector Address %u/%u sectors. %d%% complete.\r", sim_uname (uptr), (uint32)(lba + sects_written), (uint32)total_sectors, (int)((((float)lba)*100)/total_sectors));
@ -3109,7 +3109,7 @@ if (sim_switches & SWMASK ('K')) {
r = sim_disk_rdsect (uptr, lba, verify_buf, &sects_verify, sects);
if (r == SCPE_OK) {
if (sects != sects_verify)
sim_printf ("\n%s: Verification Error when reading lbn %d(0x%X) of %d(0x%X) Requested %u sectors, read %u sectors.\n",
sim_printf ("\n%s: Verification Error when reading lbn %d(0x%X) of %d(0x%X) Requested %u sectors, read %u sectors.\n",
sim_uname (uptr), (int)lba, (int)lba, (int)total_sectors, (int)total_sectors, sects, sects_verify);
for (sect = 0; sect < sects_verify; sect++) {
t_lba offset;
@ -3181,7 +3181,7 @@ if (container_size && (container_size != (t_offset)-1)) {
uptr->capac = (t_addr)(filesystem_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
capac1 = strdup (sprint_capac (dptr, uptr));
uptr->capac = saved_capac;
r = sim_messagef (r, "%s: The file system on the disk %s is larger than simulated device (%s > %s)\n",
r = sim_messagef (r, "%s: The file system on the disk %s is larger than simulated device (%s > %s)\n",
sim_uname (uptr), cptr, capac1, sprint_capac (dptr, uptr));
free (capac1);
sim_disk_detach (uptr);
@ -3200,7 +3200,7 @@ if (container_size && (container_size != (t_offset)-1)) {
uptr->capac = (t_addr)(container_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
capac1 = strdup (sprint_capac (dptr, uptr));
uptr->capac = saved_capac;
r = sim_messagef (r, "%s: The disk container '%s' is larger than simulated device (%s > %s)\n",
r = sim_messagef (r, "%s: The disk container '%s' is larger than simulated device (%s > %s)\n",
sim_uname (uptr), cptr, capac1, sprint_capac (dptr, uptr));
free (capac1);
sim_disk_detach (uptr);
@ -3217,7 +3217,7 @@ if (container_size && (container_size != (t_offset)-1)) {
uptr->capac = (t_addr)(filesystem_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
capac1 = strdup (sprint_capac (dptr, uptr));
uptr->capac = saved_capac;
r = sim_messagef (r, "%s: The file system on the %s disk container is larger than simulated device (%s > %s)\n",
r = sim_messagef (r, "%s: The file system on the %s disk container is larger than simulated device (%s > %s)\n",
sim_uname (uptr), cptr, capac1, sprint_capac (dptr, uptr));
free (capac1);
sim_disk_detach (uptr);
@ -3236,7 +3236,7 @@ if (container_size && (container_size != (t_offset)-1)) {
uptr->capac = (t_addr)(container_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
capac1 = strdup (sprint_capac (dptr, uptr));
uptr->capac = saved_capac;
r = sim_messagef (r, "%s: non expandable %s%sdisk container '%s' is smaller than simulated device (%s < %s)\n",
r = sim_messagef (r, "%s: non expandable %s%sdisk container '%s' is smaller than simulated device (%s < %s)\n",
sim_uname (uptr), container_dtype, (*container_dtype != '\0') ? " " : "", cptr, capac1, sprint_capac (dptr, uptr));
free (capac1);
sim_disk_detach (uptr);
@ -3259,8 +3259,8 @@ if (container_size && (container_size != (t_offset)-1)) {
container_dtype = ctx->footer ? (const char *)ctx->footer->DriveType : "";
sim_switches = saved_switches;
if (r == SCPE_OK)
r = sim_messagef (SCPE_OK, "%s: %s%sdisk container '%s' is larger than simulated device (%s > %s) Read Only Forced\n",
sim_uname (uptr), container_dtype, (*container_dtype != '\0') ? " " : "", cptr,
r = sim_messagef (SCPE_OK, "%s: %s%sdisk container '%s' is larger than simulated device (%s > %s) Read Only Forced\n",
sim_uname (uptr), container_dtype, (*container_dtype != '\0') ? " " : "", cptr,
capac1, sprint_capac (dptr, uptr));
free (capac1);
return r;
@ -3317,9 +3317,9 @@ if (uptr->flags & UNIT_BUFABLE) { /* buffer in memory? */
t_stat r = SCPE_OK;
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
uptr->filebuf = calloc ((size_t)(ctx->container_size / ctx->xfer_element_size),
uptr->filebuf = calloc ((size_t)(ctx->container_size / ctx->xfer_element_size),
ctx->xfer_element_size); /* allocate */
uptr->filebuf2 = calloc ((size_t)(ctx->container_size / ctx->xfer_element_size),
uptr->filebuf2 = calloc ((size_t)(ctx->container_size / ctx->xfer_element_size),
ctx->xfer_element_size); /* allocate copy */
if ((uptr->filebuf == NULL) || /* either failed? */
(uptr->filebuf2 == NULL)) {
@ -3379,7 +3379,7 @@ if (NULL == find_dev_from_unit (uptr))
if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
uint32 cap = (uptr->hwmark + uptr->dptr->aincr - 1) / uptr->dptr->aincr;
if (((uptr->flags & UNIT_RO) == 0) &&
if (((uptr->flags & UNIT_RO) == 0) &&
(memcmp (uptr->filebuf, uptr->filebuf2, (size_t)ctx->container_size) != 0)) {
sim_messagef (SCPE_OK, "%s: writing buffer to file: %s\n", sim_uname (uptr), uptr->filename);
sim_disk_wrsect (uptr, 0, (uint8 *)uptr->filebuf, NULL, (cap + ctx->sector_size - 1) / ctx->sector_size);
@ -3667,9 +3667,9 @@ return SCPE_OK;
/* Factory bad block table creation routine
This routine writes a DEC standard 144 compliant bad block table on the
last track of the specified unit as described in:
last track of the specified unit as described in:
EL-00144_B_DEC_STD_144_Disk_Standard_for_Recording_and_Handling_Bad_Sectors_Nov76.pdf
The bad block table consists of 10 repetitions of the same table,
The bad block table consists of 10 repetitions of the same table,
formatted as follows:
words 0-1 pack id number
@ -3948,9 +3948,9 @@ if (strchr (openmode, 'r'))
DesiredAccess |= GENERIC_READ;
if (strchr (openmode, 'w') || strchr (openmode, '+'))
DesiredAccess |= GENERIC_WRITE;
/* SCP Command Line parsing replaces \\ with \ presuming this is an
escape sequence. This only affecdts RAW device names and UNC paths.
We handle the RAW device name case here by prepending paths beginning
/* SCP Command Line parsing replaces \\ with \ presuming this is an
escape sequence. This only affects RAW device names and UNC paths.
We handle the RAW device name case here by prepending paths beginning
with \.\ with an extra \. */
if ((!memcmp ("\\.\\", rawdevicename, 3)) ||
(!memcmp ("/./", rawdevicename, 3))) {
@ -3962,7 +3962,7 @@ else
Handle = CreateFileA (tmpname, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH, NULL);
free (tmpname);
if (Handle != INVALID_HANDLE_VALUE) {
if ((sim_os_disk_info_raw ((FILE *)Handle, NULL, NULL, &is_cdrom)) ||
if ((sim_os_disk_info_raw ((FILE *)Handle, NULL, NULL, &is_cdrom)) ||
((DesiredAccess & GENERIC_WRITE) && is_cdrom)) {
CloseHandle (Handle);
errno = EACCES;
@ -5411,7 +5411,7 @@ static FILE *sim_vhd_disk_open (const char *szVHDPath, const char *DesiredAccess
0);
if (Status)
goto Cleanup_Return;
if ((0 != memcmp (hVHD->Dynamic.ParentUniqueID, ParentFooter.UniqueID, sizeof (ParentFooter.UniqueID))) ||
if ((0 != memcmp (hVHD->Dynamic.ParentUniqueID, ParentFooter.UniqueID, sizeof (ParentFooter.UniqueID))) ||
(ParentModifiedTimeStamp != hVHD->Dynamic.ParentTimeStamp)) {
if (sim_switches & SWMASK ('O')) { /* OVERRIDE consistency checks? */
if ((sim_switches & SWMASK ('U')) && /* FIX (UPDATE) consistency checks AND */
@ -6161,7 +6161,7 @@ if (NtoHl (hVHD->Footer.DiskType) == VHD_DT_Fixed) {
}
/* We are now dealing with a Dynamically expanding or differencing disk */
DynamicBlockSize = NtoHl (hVHD->Dynamic.BlockSize);
if ((DynamicBlockSize == 0) ||
if ((DynamicBlockSize == 0) ||
((DynamicBlockSize & (DynamicBlockSize - 1)) != 0)) {
errno = ERANGE;
return SCPE_IOERR;
@ -6292,7 +6292,7 @@ if (NtoHl(hVHD->Footer.DiskType) == VHD_DT_Fixed) {
}
/* We are now dealing with a Dynamically expanding or differencing disk */
DynamicBlockSize = NtoHl (hVHD->Dynamic.BlockSize);
if ((DynamicBlockSize == 0) ||
if ((DynamicBlockSize == 0) ||
((DynamicBlockSize & (DynamicBlockSize - 1)) != 0)) {
errno = ERANGE;
return SCPE_IOERR;
@ -6381,9 +6381,9 @@ while (BytesToWrite && (r == SCPE_OK)) {
goto Fatal_IO_Error;
/* Since a large VHD can have a pretty large BAT, and we've only changed one longword bat entry
in the current BAT, we write just the aligned sector which contains the updated BAT entry */
BATUpdateBufferAddress = (uint8 *)hVHD->BAT - (size_t)NtoHll(hVHD->Dynamic.TableOffset) +
BATUpdateBufferAddress = (uint8 *)hVHD->BAT - (size_t)NtoHll(hVHD->Dynamic.TableOffset) +
(size_t)((((size_t)&hVHD->BAT[BlockNumber]) - (size_t)hVHD->BAT + (size_t)NtoHll(hVHD->Dynamic.TableOffset)) & ~(VHD_DATA_BLOCK_ALIGNMENT-1));
/* If the starting of the BAT isn't on a VHD_DATA_BLOCK_ALIGNMENT boundary and we've just updated
/* If the starting of the BAT isn't on a VHD_DATA_BLOCK_ALIGNMENT boundary and we've just updated
a BAT entry early in the array, the buffer computed address might be before the start of the
BAT table. If so, only write the BAT data needed */
if (BATUpdateBufferAddress < (uint8 *)hVHD->BAT) {
@ -6537,7 +6537,7 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
return TRUE; /* can't stat assume attached */
}
free (fullpath);
if ((statb.st_dev != filestat.st_dev) ||
if ((statb.st_dev != filestat.st_dev) ||
(statb.st_ino != filestat.st_ino) ||
(statb.st_mode != filestat.st_mode) ||
(statb.st_nlink != filestat.st_nlink) ||
@ -6556,7 +6556,7 @@ free (fullname);
return FALSE; /* Not attached */
}
static void sim_disk_info_entry (const char *directory,
static void sim_disk_info_entry (const char *directory,
const char *filename,
t_offset FileSize,
const struct stat *filestat,
@ -6597,14 +6597,14 @@ if (info->flag) { /* zap type */
if ((container_size != (t_offset)-1) && (container_size > (t_offset)sizeof (*f)) &&
(sim_fseeko (container, container_size - sizeof (*f), SEEK_SET) == 0) &&
(sizeof (*f) == sim_fread (f, 1, sizeof (*f), container))) {
if ((memcmp (f->Signature, "simh", 4) == 0) &&
if ((memcmp (f->Signature, "simh", 4) == 0) &&
(f->Checksum == NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum))))) {
uint8 *sector_data;
uint8 *zero_sector;
size_t sector_size = NtoHl (f->SectorSize);
t_offset highwater = (((t_offset)NtoHl (f->Highwater[0])) << 32) | ((t_offset)NtoHl (f->Highwater[1]));
if (sector_size > 16384) /* arbitray upper limit */
if (sector_size > 16384) /* arbitrary upper limit */
sector_size = 16384;
/* determine whole sectors in original container size */
/* By default we chop off the disk footer and trailing */
@ -6686,7 +6686,7 @@ if (info->flag == 0) {
" AccessFormat: %s\n"
" CreationTime: %s",
uptr->filename,
f->CreatingSimulator, f->DriveType, NtoHl(f->SectorSize), NtoHl (f->SectorCount),
f->CreatingSimulator, f->DriveType, NtoHl(f->SectorSize), NtoHl (f->SectorCount),
NtoHl (f->TransferElementSize), fmts[f->AccessFormat].name, f->CreationTime);
if (f->DeviceName[0] != '\0')
sim_printf (" DeviceName: %s\n", (char *)f->DeviceName);
@ -6824,7 +6824,7 @@ if (!(uptr->flags & UNIT_RO)) { /* Only test drives open Read/Write - Read Only
for (i = 0; i < uint32s_per_sector; i++)
if (c->data[i + sector_to_check * uint32s_per_sector] != (lba + sector_to_check)) {
sim_printf ("Sector %u(0x%X) has unexpected data at offset 0x%X: 0x%08X\n",
sim_printf ("Sector %u(0x%X) has unexpected data at offset 0x%X: 0x%08X\n",
lba + sector_to_check, lba + sector_to_check, i, c->data[i + sector_to_check * uint32s_per_sector]);
unexpected_data = TRUE;
break;

View file

@ -19,12 +19,12 @@
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 names of Robert M Supnik and
Except as contained in this notice, the names of Robert M Supnik and
Mark Pizzolato shall not be used in advertising or otherwise to promote
the sale, use or other dealings in this Software without prior written
the sale, use or other dealings in this Software without prior written
authorization from Robert M Supnik and Mark Pizzolato.
25-Jan-11 MP Initial Implemementation
25-Jan-11 MP Initial Implementation
*/
#ifndef SIM_DISK_H_
@ -70,19 +70,19 @@ typedef void (*DISK_PCALLBACK)(UNIT *unit, t_stat status);
/* Prototypes */
t_stat sim_disk_init (void);
t_stat sim_disk_attach (UNIT *uptr,
const char *cptr,
t_stat sim_disk_attach (UNIT *uptr,
const char *cptr,
size_t memory_sector_size, /* memory footprint of sector data */
size_t xfer_element_size,
size_t xfer_element_size,
t_bool dontchangecapac, /* if false just change uptr->capac as needed */
uint32 debugbit, /* debug bit */
const char *drivetype, /* drive type */
uint32 pdp11_tracksize, /* BAD144 track */
int completion_delay); /* Minimum Delay for asynch I/O completion */
t_stat sim_disk_attach_ex (UNIT *uptr,
const char *cptr,
t_stat sim_disk_attach_ex (UNIT *uptr,
const char *cptr,
size_t memory_sector_size, /* memory footprint of sector data */
size_t xfer_element_size,
size_t xfer_element_size,
t_bool dontchangecapac, /* if false just change uptr->capac as needed */
uint32 dbit, /* debug bit */
const char *dtype, /* drive type */
@ -90,10 +90,10 @@ t_stat sim_disk_attach_ex (UNIT *uptr,
int completion_delay, /* Minimum Delay for asynch I/O completion */
const char **drivetypes); /* list of drive types (from smallest to largest) */
/* to try and fit the container/file system into */
t_stat sim_disk_attach_ex2 (UNIT *uptr,
const char *cptr,
t_stat sim_disk_attach_ex2 (UNIT *uptr,
const char *cptr,
size_t memory_sector_size, /* memory footprint of sector data */
size_t xfer_element_size,
size_t xfer_element_size,
t_bool dontchangecapac, /* if false just change uptr->capac as needed */
uint32 dbit, /* debug bit */
const char *dtype, /* drive type */

View file

@ -66,27 +66,27 @@
HP/UX ??
Compaq Tru64 Unix ??
VMS Alpha/Itanium VMS only, needs VMS libpcap
WinPcap is no longer developed or supported by was available from:
WinPcap is no longer developed or supported by was available from:
http://winpcap.polito.it/
Npcap is a complete replacement for systems running Windows7 and later
and is available from:
https://nmap.org/npcap
libpcap for VMS is available from:
libpcap for VMS is available from:
http://simh.trailing-edge.com/sources/vms-pcap.zip
libpcap for other Unix platforms is available at:
NOTE: As of the release of this version of sim_ether.c ALL current
*nix platforms ship with a sufficiently new version of
libpcap for other Unix platforms is available at:
NOTE: As of the release of this version of sim_ether.c ALL current
*nix platforms ship with a sufficiently new version of
libpcap, and ALL provide a libpcap-dev package for developing
libpcap based applications. The OS vendor supplied version
of libpcap AND the libpcap-dev components are preferred for
proper operation of both simh AND other applications on the
proper operation of both simh AND other applications on the
host system which use libpcap.
Current Version: http://www.tcpdump.org/daily/libpcap-current.tar.gz
Released Version: http://www.tcpdump.org/release/
When absolutely necessary (see NOTE above about vendor supplied
libpcap), we've gotten the tarball, unpacked, built and installed
When absolutely necessary (see NOTE above about vendor supplied
libpcap), we've gotten the tarball, unpacked, built and installed
it with:
gzip -dc libpcap-current.tar.gz | tar xvf -
cd libpcap-directory-name
@ -95,74 +95,74 @@
make install
Note: The "make install" step generally will have to be done as root.
This will install libpcap in /usr/local/lib and /usr/local/include
The current simh makefile will do the right thing to locate and
The current simh makefile will do the right thing to locate and
reference the OS provided libpcap or the one just installed.
Note: Building for the platforms indicated above, with the indicated libpcap,
should automatically leverage the appropriate mechanisms contained here.
Things are structured so that it is likely to work for any other as yet
untested platform. If it works for you, please let the author know so we
can update the table above. If it doesn't work, then the following #define
Note: Building for the platforms indicated above, with the indicated libpcap,
should automatically leverage the appropriate mechanisms contained here.
Things are structured so that it is likely to work for any other as yet
untested platform. If it works for you, please let the author know so we
can update the table above. If it doesn't work, then the following #define
variables can influence the operation on an untested platform.
USE_BPF - Determines if this code leverages a libpcap/WinPcap
provided bpf packet filtering facility. All tested
environments have bpf facilities that work the way we
need them to. However a new one might not. undefine
USE_BPF - Determines if this code leverages a libpcap/WinPcap
provided bpf packet filtering facility. All tested
environments have bpf facilities that work the way we
need them to. However a new one might not. undefine
this variable to let this code do its own filtering.
USE_SETNONBLOCK - Specifies whether the libpcap environment's non-blocking
semantics are to be leveraged. This helps to manage the
varying behaviours of the kernel packet facilities
USE_SETNONBLOCK - Specifies whether the libpcap environment's non-blocking
semantics are to be leveraged. This helps to manage the
varying behaviours of the kernel packet facilities
leveraged by libpcap.
USE_READER_THREAD - Specifies that packet reading should be done in the
context of a separate thread. The Posix threading
USE_READER_THREAD - Specifies that packet reading should be done in the
context of a separate thread. The Posix threading
APIs are used. This option is less efficient than the
default non-threaded approach, but it exists since some
platforms don't want to work with nonblocking libpcap
semantics. OpenBSD and NetBSD either don't have pthread
APIs available, or they are too buggy to be useful.
Using the threaded approach may require special compile
and/or link time switches (i.e. -lpthread or -pthread,
etc.) Consult the documentation for your platform as
default non-threaded approach, but it exists since some
platforms don't want to work with nonblocking libpcap
semantics. OpenBSD and NetBSD either don't have pthread
APIs available, or they are too buggy to be useful.
Using the threaded approach may require special compile
and/or link time switches (i.e. -lpthread or -pthread,
etc.) Consult the documentation for your platform as
needed. Although this may be 'less efficient' than the
non-threaded approach, the efficiency is an overall system
efficiency not necessarily a simulator efficiency. This
means that work is removed from the thread executing
efficiency not necessarily a simulator efficiency. This
means that work is removed from the thread executing
simulated instructions so the simulated system will most
likely run faster (given that modern host CPUs are
likely run faster (given that modern host CPUs are
multi-core and have someplace to do this work in parallel).
MUST_DO_SELECT - Specifies that, when USE_READER_THREAD is active,
select() should be used to determine when available
packets are ready for reading. Otherwise, we depend
on the libpcap/kernel packet timeout specified on
pcap_open_live. If USE_READER_THREAD is not set, then
MUST_DO_SELECT - Specifies that, when USE_READER_THREAD is active,
select() should be used to determine when available
packets are ready for reading. Otherwise, we depend
on the libpcap/kernel packet timeout specified on
pcap_open_live. If USE_READER_THREAD is not set, then
MUST_DO_SELECT is irrelevant
HAVE_TAP_NETWORK - Specifies that support for tap networking should be
HAVE_TAP_NETWORK - Specifies that support for tap networking should be
included. This can be leveraged, along with OS bridging
capabilities to share a single LAN interface. This
capabilities to share a single LAN interface. This
allows device names of the form tap:tap0 to be specified
at open time. This functionality is only useful/needed
on *nix platforms since native sharing of Windows NIC
at open time. This functionality is only useful/needed
on *nix platforms since native sharing of Windows NIC
devices works with no external magic.
HAVE_VDE_NETWORK - Specifies that support for vde networking should be
HAVE_VDE_NETWORK - Specifies that support for vde networking should be
included. This can be leveraged, along with OS bridging
capabilities to share a single LAN interface. It also
can allow a simulator to have useful networking
functionality when running without root access. This
allows device names of the form vde:/tmp/switch to be
specified at open time. This functionality is only
available on *nix platforms since the vde api isn't
can allow a simulator to have useful networking
functionality when running without root access. This
allows device names of the form vde:/tmp/switch to be
specified at open time. This functionality is only
available on *nix platforms since the vde api isn't
available on Windows.
HAVE_SLIRP_NETWORK- Specifies that support for SLiRP networking should be
included. This can be leveraged to provide User Mode
HAVE_SLIRP_NETWORK- Specifies that support for SLiRP networking should be
included. This can be leveraged to provide User Mode
IP NAT connectivity for simulators.
NEED_PCAP_SENDPACKET
- Specifies that you are using an older version of libpcap
which doesn't provide a pcap_sendpacket API.
NOTE: Changing these defines is done in either sim_ether.h OR on the global
NOTE: Changing these defines is done in either sim_ether.h OR on the global
compiler command line which builds all of the modules included in a
simulator.
@ -171,9 +171,9 @@
Modification history:
30-Mar-12 MP Added host NIC address determination on supported VMS platforms
01-Mar-12 MP Made host NIC address determination on *nix platforms more
01-Mar-12 MP Made host NIC address determination on *nix platforms more
robust.
01-Mar-12 MP Added host NIC address determination work when building
01-Mar-12 MP Added host NIC address determination work when building
under Cygwin
01-Mar-12 AGN Add conditionals for Cygwin dynamic loading of wpcap.dll
01-Mar-12 AGN Specify the full /usr/lib for dlopen under Apple Mac OS X.
@ -181,78 +181,78 @@
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
29-Oct-11 MP Added support for integrated Tap networking interfaces on OSX
12-Aug-11 MP Cleaned up payload length determination
Fixed race condition detecting reflections when threaded
Fixed race condition detecting reflections when threaded
reading and writing is enabled
18-Apr-11 MP Fixed race condition with self loopback packets in
18-Apr-11 MP Fixed race condition with self loopback packets in
multithreaded environments
09-Jan-11 MP Fixed missing crc data when USE_READER_THREAD is defined and
09-Jan-11 MP Fixed missing crc data when USE_READER_THREAD is defined and
crc's are needed (only the pdp11_xu)
16-Dec-10 MP added priority boost for read and write threads when
16-Dec-10 MP added priority boost for read and write threads when
USE_READER_THREAD does I/O in separate threads. This helps
throughput since it allows these I/O bound threads to preempt
the main thread (which is executing simulated instructions).
throughput since it allows these I/O bound threads to preempt
the main thread (which is executing simulated instructions).
09-Dec-10 MP allowed more flexible parsing of MAC address strings
09-Dec-10 MP Added support to determine if network address conflicts exist
07-Dec-10 MP Reworked DECnet self detection to the more general approach
of loopback self when a Physical Address is being set.
04-Dec-10 MP Changed eth_write to do nonblocking writes when
04-Dec-10 MP Changed eth_write to do nonblocking writes when
USE_READER_THREAD is defined.
20-Aug-10 TVO Fix for Mac OSX 10.6
17-Jun-10 MP Fixed bug in the AUTODIN II hash filtering.
14-Jun-10 MP Added support for integrated Tap networking interfaces on BSD
14-Jun-10 MP Added support for integrated Tap networking interfaces on BSD
platforms.
13-Jun-10 MP Added support for integrated Tap networking interfaces on Linux
13-Jun-10 MP Added support for integrated Tap networking interfaces on Linux
platforms.
31-May-10 MP Added support for more TOE (TCP Offload Engine) features for IPv4
network traffic from the host and/or from hosts on the LAN. These
new TOE features are: LSO (Large Send Offload) and Jumbo packet
fragmentation support. These features allow a simulated network
device to support traffic when a host leverages a NIC's Large
Send Offload capabilities to fregment and/or segment outgoing
network traffic. Additionally a simulated network device can
device to support traffic when a host leverages a NIC's Large
Send Offload capabilities to fragment and/or segment outgoing
network traffic. Additionally a simulated network device can
reasonably exist on a LAN which is configured to use Jumbo frames.
21-May-10 MP Added functionality to fixup IP header checksums to accomodate
21-May-10 MP Added functionality to fixup IP header checksums to accomodate
packets from a host with a NIC which has TOE (TCP Offload Engine)
enabled which is expected to implement the checksum computations
in hardware. Since we catch packets before they arrive at the
NIC the expected checksum insertions haven't been performed yet.
This processing is only done for packets sent from the hoat to
the guest we're supporting. In general this will be a relatively
This processing is only done for packets sent from the host to
the guest we're supporting. In general this will be a relatively
small number of packets so it is done for all IP frame packets
coming from the hoat to the guest. In order to make the
coming from the host to the guest. In order to make the
determination of packets specifically arriving from the host we
need to know the hardware MAC address of the host NIC. Currently
determining a NIC's MAC address is relatively easy on Windows.
The non-windows code works on linux and may work on other *nix
platforms either as is or with slight modifications. The code,
as implemented, only messes with this activity if the host
The non-windows code works on linux and may work on other *nix
platforms either as is or with slight modifications. The code,
as implemented, only messes with this activity if the host
interface MAC address can be determined.
20-May-10 MP Added general support to deal with receiving packets smaller
20-May-10 MP Added general support to deal with receiving packets smaller
than ETH_MIN_PACKET in length. These come from packets
looped back by some bridging mechanism and need to be padded
to the minimum frame size. A real NIC won't pass us any
to the minimum frame size. A real NIC won't pass us any
packets like that. This fix belongs here since this layer
is responsible for interfacing to they physical layer
is responsible for interfacing to they physical layer
devices, AND it belongs here to get CRC processing right.
05-Mar-08 MP Added optional multicast filtering support for doing
LANCE style AUTODIN II based hashed filtering.
07-Feb-08 MP Added eth_show_dev to display ethernet state
Changed the return value from eth_read to return whether
or not a packet was read. No existing callers used or
or not a packet was read. No existing callers used or
checked constant return value that previously was being
supplied.
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
USE_READER_THREAD is enabled) to allow packet reception
to dynamically update the simulator event queue and
potentially avoid polling for I/O. This provides a minimal
overhead (no polling) maximal responsiveness for network
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
USE_READER_THREAD is enabled) to allow packet reception
to dynamically update the simulator event queue and
potentially avoid polling for I/O. This provides a minimal
overhead (no polling) maximal responsiveness for network
activities.
29-Jan-08 MP Properly sequenced activities in eth_close to avoid a race
condition when USE_READER_THREAD is enabled.
25-Jan-08 MP Changed the following when USE_READER_THREAD is enabled:
- Fixed bug when the simulated device doesn't need crc
- Fixed bug when the simulated device doesn't need crc
in packet data which is read.
- Added call to pcap_setmintocopy to minimize packet
- Added call to pcap_setmintocopy to minimize packet
delivery latencies.
- Added ethq_destroy and used it to avoid a memory leak in
eth_close.
@ -262,8 +262,8 @@
Fixed the bpf filter used when no traffic is to be matched.
Reworked eth_add_packet_crc32 implementation to avoid an
extra buffer copy while reading packets.
Fixedup #ifdef's relating to USE_SHARED so that setting
USE_SHARED or USE_NETWORK will build a working network
Fixedup #ifdef's relating to USE_SHARED so that setting
USE_SHARED or USE_NETWORK will build a working network
environment.
23-Jan-08 MP Reworked eth_packet_trace and eth_packet_trace_ex to allow
only output ethernet header+crc and provide a mechanism for
@ -286,10 +286,10 @@
25-Mar-04 MP Revised comments and minor #defines to deal with updated
libpcap which now provides pcap_sendpacket on all platforms.
04-Feb-04 MP Returned success/fail status from eth_write to support
determining if the current libpcap connection can successfully
determining if the current libpcap connection can successfully
write packets.
Added threaded approach to reading packets since
this works better on some platforms (solaris intel) than the
this works better on some platforms (solaris intel) than the
inconsistently implemented non-blocking read approach.
04-Feb-04 DTH Converted ETH_DEBUG to sim_debug
13-Jan-04 MP tested and fixed on OpenBSD, NetBS and FreeBSD.
@ -323,7 +323,7 @@
work on Red Hat 6.2-sparc and Debian 3.0r1-sparc.
03-Mar-03 MP Changed logging to be consistent on stdout and sim_log
01-Feb-03 MP Changed type of local variables in eth_packet_trace to
conform to the interface needs of eth_mac_fmt wich produces
conform to the interface needs of eth_mac_fmt which produces
char data instead of unsigned char data. Suggested by the
DECC compiler.
15-Jan-03 DTH Corrected PacketGetAdapterNames parameter2 datatype
@ -364,7 +364,7 @@
24-Sep-02 DTH Finished eth_devices, eth_getname
18-Sep-02 DTH Callbacks implemented
13-Sep-02 DTH Basic packet read/write written
20-Aug-02 DTH Created Sim_Ether for O/S independant ethernet implementation
20-Aug-02 DTH Created Sim_Ether for O/S independent ethernet implementation
------------------------------------------------------------------------------
*/
@ -388,7 +388,7 @@ static void eth_get_nic_hw_addr(ETH_DEV* dev, const char *devname, int set_on);
static const unsigned char framer_oui[3] = { 0xaa, 0x00, 0x03 };
/*============================================================================*/
/* OS-independant ethernet routines */
/* OS-independent ethernet routines */
/*============================================================================*/
t_stat eth_mac_scan (ETH_MAC* mac, const char* strmac)
@ -459,7 +459,7 @@ t_stat eth_mac_scan_ex (ETH_MAC* mac, const char* strmac, UNIT *uptr)
return sim_messagef (SCPE_ARG, "Invalid MAC address byte value: %02X\n", a[i]);
else {
uint32 mask, shift;
state.base_mac[i] = a[i];
if (((i + 1) << 3) < state.bits)
shift = 0;
@ -945,7 +945,7 @@ t_stat eth_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const cha
fprintf (st, "This simulator was not built with ethernet device support\n");
return SCPE_OK;
}
t_stat eth_check_address_conflict (ETH_DEV* dev,
t_stat eth_check_address_conflict (ETH_DEV* dev,
ETH_MAC* const mac)
{return SCPE_NOFNC;}
t_stat eth_set_throttle (ETH_DEV* dev, uint32 time, uint32 burst, uint32 delay)
@ -965,7 +965,7 @@ t_stat eth_filter_hash (ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
ETH_BOOL all_multicast, ETH_BOOL promiscuous, ETH_MULTIHASH* const hash)
{return SCPE_NOFNC;}
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL match_broadcast, ETH_MULTIHASH* const hash)
{return SCPE_NOFNC;}
const char *eth_version (void)
@ -1033,8 +1033,8 @@ typedef void * pcap_t; /* Pseudo Type to avoid compiler errors */
#endif /* HAVE_PCAP_NETWORK */
/*
The libpcap provided API pcap_findalldevs() on most platforms, will
leverage the getifaddrs() API if it is available in preference to
The libpcap provided API pcap_findalldevs() on most platforms, will
leverage the getifaddrs() API if it is available in preference to
alternate platform specific methods of determining the interface list.
A limitation of getifaddrs() is that it returns only interfaces which
@ -1042,11 +1042,11 @@ typedef void * pcap_t; /* Pseudo Type to avoid compiler errors */
interfaces that we are interested in since a host may have dedicated
interfaces for a simulator, which is otherwise unused by the host.
One could hand craft the the build of libpcap to specifically use
alternate methods to implement pcap_findalldevs(). However, this can
One could hand craft the the build of libpcap to specifically use
alternate methods to implement pcap_findalldevs(). However, this can
get tricky, and would then result in a sort of deviant libpcap.
This routine exists to allow platform specific code to validate and/or
This routine exists to allow platform specific code to validate and/or
extend the set of available interfaces to include any that are not
returned by pcap_findalldevs.
@ -1098,7 +1098,7 @@ for (i=0; i<used; i++) {
continue;
reglen = sizeof(regval);
/* look for user-defined adapter name, bail if not found */
/* look for user-defined adapter name, bail if not found */
/* same comment about Windows XP x64 (above) using RegQueryValueEx */
if ((status = RegQueryValueExA (reghnd, "Name", NULL, &regtype, regval, &reglen)) != ERROR_SUCCESS) {
RegCloseKey (reghnd);
@ -1210,9 +1210,9 @@ return used;
#ifdef HAVE_TAP_NETWORK
#if defined(__linux) || defined(__linux__)
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_tun.h>
#elif defined(HAVE_BSDTUNTAP)
#include <sys/types.h>
#include <net/if_types.h>
@ -1577,9 +1577,9 @@ struct _PACKET_OID_DATA {
uint32 Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
///< for a complete list of valid codes.
uint32 Length; ///< Length of the data field
uint8 Data[1]; ///< variable-lenght field that contains the information passed to or received
uint8 Data[1]; ///< variable-length field that contains the information passed to or received
///< from the adapter.
};
};
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
typedef void **LPADAPTER;
#define OID_802_3_CURRENT_ADDRESS 0x01010102 /* Extracted from ntddndis.h */
@ -1611,7 +1611,7 @@ static int pcap_mac_if_win32(const char *AdapterName, unsigned char MACAddress[6
p_PacketCloseAdapter = (void (*)(LPADAPTER lpAdapter))dlsym(hDll, "PacketCloseAdapter");
p_PacketRequest = (int (*)(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData))dlsym(hDll, "PacketRequest");
#endif
/* Open the selected adapter */
lpAdapter = p_PacketOpenAdapter(AdapterName);
@ -1625,7 +1625,7 @@ static int pcap_mac_if_win32(const char *AdapterName, unsigned char MACAddress[6
return -1;
}
/* Allocate a buffer to get the MAC adress */
/* Allocate a buffer to get the MAC address */
OidData = (PACKET_OID_DATA *)malloc(6 + sizeof(PACKET_OID_DATA));
if (OidData == NULL) {
@ -1720,13 +1720,13 @@ static int pcap_mac_if_vms(const char *AdapterName, unsigned char MACAddress[6])
Device.dsc$w_length = strlen(VMS_Device);
if (!$VMS_STATUS_SUCCESS( sys$assign (&Device, &chan, 0, 0, 0) ))
return -1;
status = sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP, &iosb, 0, 0,
status = sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP, &iosb, 0, 0,
0, &setupdesc, 0, 0, 0, 0);
if ((!$VMS_STATUS_SUCCESS(status)) || (!$VMS_STATUS_SUCCESS(iosb[0]))) {
sys$dassgn(chan);
return -1;
}
status = sys$qiow (0, chan, IO$_SENSEMODE|IO$M_CTRL, &iosb, 0, 0,
status = sys$qiow (0, chan, IO$_SENSEMODE|IO$M_CTRL, &iosb, 0, 0,
0, &chardesc, 0, 0, 0, 0);
sys$dassgn(chan);
if ((!$VMS_STATUS_SUCCESS(status)) || (!$VMS_STATUS_SUCCESS(iosb[0])))
@ -1779,7 +1779,7 @@ static void eth_get_nic_hw_addr(ETH_DEV* dev, const char *devname, int set_on)
char tool[CBUFSIZE];
const char *turnon[] = {
"ip link set dev %.*s up 2>/dev/null",
"ifconfig %.*s up 2>/dev/null",
"ifconfig %.*s up 2>/dev/null",
NULL};
const char *patterns[] = {
"ip link show %.*s 2>/dev/null | grep [0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]",
@ -1967,8 +1967,8 @@ switch (dev->eth_api) {
sim_debug(dev->dbit, dev->dptr, "Reader Thread Starting\n");
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which, in general, won't be readily yielding the processor
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which, in general, won't be readily yielding the processor
when this thread needs to run */
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
@ -1991,7 +1991,7 @@ while (dev->handle) {
{
fd_set setl;
struct timeval timeout;
FD_ZERO(&setl);
FD_SET(select_fd, &setl);
timeout.tv_sec = 0;
@ -2001,7 +2001,7 @@ while (dev->handle) {
}
else
sel_ret = 1;
if (sel_ret < 0 && errno != EINTR)
if (sel_ret < 0 && errno != EINTR)
break;
}
if (sel_ret > 0) {
@ -2128,8 +2128,8 @@ _eth_writer(void *arg)
ETH_DEV* volatile dev = (ETH_DEV*)arg;
ETH_WRITE_REQUEST *request = NULL;
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which in general won't be readily yielding the processor when
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which in general won't be readily yielding the processor when
this thread needs to run */
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
@ -2177,9 +2177,9 @@ return NULL;
}
#endif
/* eth_set_async
/* eth_set_async
*
* Turn on reciever processing which can be either asynchronous or polled
* Turn on receiver processing which can be either asynchronous or polled
*/
t_stat eth_set_async (ETH_DEV *dev, int latency)
{
@ -2203,9 +2203,9 @@ if (wakeup_needed) {
return SCPE_OK;
}
/* eth_clr_async
/* eth_clr_async
*
* Turn off reciever processing
* Turn off receiver processing
*/
t_stat eth_clr_async (ETH_DEV *dev)
{
@ -2345,7 +2345,7 @@ else { /* !tap: */
#if defined(HAVE_VDE_NETWORK)
char vdeswitch_s[CBUFSIZE]; /* VDE switch name */
char vdeport_s[CBUFSIZE]; /* VDE switch port (optional), numeric */
struct vde_open_args voa;
const char *devname = savname + 4;
@ -2616,7 +2616,7 @@ if (1) {
}
#endif /* defined (USE_READER_THREAD */
_eth_add_to_open_list (dev);
/*
/*
* install a total filter on a newly opened interface and let the device
* simulator install an appropriate filter that reflects the device's
* configuration.
@ -2761,7 +2761,7 @@ if (!rand_initialized)
return (rand() & 0xFF);
}
t_stat eth_check_address_conflict_ex (ETH_DEV* dev,
t_stat eth_check_address_conflict_ex (ETH_DEV* dev,
ETH_MAC* const mac,
int *reflections,
t_bool silent)
@ -2779,68 +2779,68 @@ eth_mac_fmt(mac, mac_string);
sim_debug(dev->dbit, dev->dptr, "Determining Address Conflict for MAC address: %s\n", mac_string);
/* 00:00:00:00:00:00 or any address with a multi-cast address is invalid */
if ((((*mac)[0] == 0) && ((*mac)[1] == 0) && ((*mac)[2] == 0) &&
if ((((*mac)[0] == 0) && ((*mac)[1] == 0) && ((*mac)[2] == 0) &&
((*mac)[3] == 0) && ((*mac)[4] == 0) && ((*mac)[5] == 0)) ||
((*mac)[0] & 1)) {
return sim_messagef (SCPE_ARG, "%s: Invalid NIC MAC Address: %s\n", sim_dname(dev->dptr), mac_string);
}
/* The process of checking address conflicts is used in two ways:
1) to determine the behavior of the currently running packet
delivery facility regarding whether it may receive copies
of every packet sent (and how many).
2) to verify if a MAC address which this facility is planning
to use as the source address of packets is already in use
by some other node on the local network
Case #1, doesn't require (and explicitly doesn't want) any
interaction or response from other systems on the LAN so
therefore no considerations regarding switch packet forwarding
are important. Meanwhile, Case #2 does require responses from
other components on the LAN to provide useful functionality.
The original designers of this mechanism did this when essentially
all LANs were single collision domains (i.e. ALL nodes which might
1) to determine the behavior of the currently running packet
delivery facility regarding whether it may receive copies
of every packet sent (and how many).
2) to verify if a MAC address which this facility is planning
to use as the source address of packets is already in use
by some other node on the local network
Case #1, doesn't require (and explicitly doesn't want) any
interaction or response from other systems on the LAN so
therefore no considerations regarding switch packet forwarding
are important. Meanwhile, Case #2 does require responses from
other components on the LAN to provide useful functionality.
The original designers of this mechanism did this when essentially
all LANs were single collision domains (i.e. ALL nodes which might
be affected by an address conflict were physically present on a single
Ethernet cable which might have been extended by a couple of repeaters).
Since that time, essentially no networks are single collision domains.
Thick and thinwire Ethernet cables don't exist and very few networks
even have hubs. Today, essentially all LANs are deployed using one
or more layers of network switches. In a switched LAN environment, the
switches on the LAN "learn" which ports on the LAN source traffic from
which MAC addresses and then forward traffic destined for particular
Since that time, essentially no networks are single collision domains.
Thick and thinwire Ethernet cables don't exist and very few networks
even have hubs. Today, essentially all LANs are deployed using one
or more layers of network switches. In a switched LAN environment, the
switches on the LAN "learn" which ports on the LAN source traffic from
which MAC addresses and then forward traffic destined for particular
MAC address to the appropriate ports. If a particular MAC address is
already in use somewhere on the LAN, then the switches "know" where
it is. The host based test using the loopback protocol is poorly
already in use somewhere on the LAN, then the switches "know" where
it is. The host based test using the loopback protocol is poorly
designed to detect this condition. This test is performed by the host
first changing the device's Physical MAC address to the address which
is to be tested, and then sending a loopback packet FROM AND TO this
MAC address with a loopback reply to be sent by a system which may be
currently using the MAC address. If no reply is received, then the
currently using the MAC address. If no reply is received, then the
MAC address is presumed to be unused. The sending of this packet will
result in its delivery to the right system since the switch port/MAC
address tables know where to deliver packets destined to this MAC
address, however the response it generates won't be delivered to the
system performing the test since the switches on the LAN won't know
about the local port being the right target for packets with this MAC
address. A better test design to detect these conflicts would be for
address tables know where to deliver packets destined to this MAC
address, however the response it generates won't be delivered to the
system performing the test since the switches on the LAN won't know
about the local port being the right target for packets with this MAC
address. A better test design to detect these conflicts would be for
the testing system to send a loopback packet FROM the current physical
MAC address (BEFORE changing it) TO the MAC address being tested with
the loopback response coming to the current physical MAC address of
MAC address (BEFORE changing it) TO the MAC address being tested with
the loopback response coming to the current physical MAC address of
the device. If a response is received, then the address is in use and
the attempt to change the device's MAC address should fail. Since we
the attempt to change the device's MAC address should fail. Since we
can't change the software running in these simulators to implement this
better conflict detection approach, we can still "do the right thing"
in the sim_ether layer. We're already handling the loopback test
packets specially since we always had to avoid receiving the packets
which were being sent, but needed to allow for the incoming loopback
better conflict detection approach, we can still "do the right thing"
in the sim_ether layer. We're already handling the loopback test
packets specially since we always had to avoid receiving the packets
which were being sent, but needed to allow for the incoming loopback
packets to be properly dealt with. We can extend this current special
handling to change outgoing "loopback to self" packets to have source
handling to change outgoing "loopback to self" packets to have source
AND loopback destination addresses in the packets to be the host NIC's
physical address. The switch network will already know the correct
MAC/port relationship for the host NIC's physical address, so loopback
physical address. The switch network will already know the correct
MAC/port relationship for the host NIC's physical address, so loopback
response packets will be delivered as needed.
Code in _eth_write and _eth_callback provide the special handling to
perform the described loopback packet adjustments, and code in
Code in _eth_write and _eth_callback provide the special handling to
perform the described loopback packet adjustments, and code in
eth_filter_hash makes sure that the loopback response packets are received.
*/
@ -2905,7 +2905,7 @@ if (reflections)
return SCPE_OK;
}
t_stat eth_check_address_conflict (ETH_DEV* dev,
t_stat eth_check_address_conflict (ETH_DEV* dev,
ETH_MAC* const mac)
{
char mac_string[32];
@ -2983,13 +2983,13 @@ dev->error_needs_reset = (((dev->transmit_packet_errors + dev->receive_packet_er
#endif
/* Limit errors to 1 per second (per invoking thread (reader and writer)) */
sim_os_sleep (1);
/*
/*
When all of the threads which can reference this ETH_DEV object are
simultaneously waiting in this routine, we have the potential to close
and reopen the network connection.
We do this after ETH_ERROR_REOPEN_THRESHOLD total errors have occurred.
In practice could be as frequently as once every ETH_ERROR_REOPEN_THRESHOLD/2
seconds, but normally would be about once every 1.5*ETH_ERROR_REOPEN_THRESHOLD
We do this after ETH_ERROR_REOPEN_THRESHOLD total errors have occurred.
In practice could be as frequently as once every ETH_ERROR_REOPEN_THRESHOLD/2
seconds, but normally would be about once every 1.5*ETH_ERROR_REOPEN_THRESHOLD
seconds (ONLY when the error condition exists).
*/
#ifdef USE_READER_THREAD
@ -3128,7 +3128,7 @@ int write_queue_size = 1;
/* make sure device exists */
if ((!dev) || (dev->eth_api == ETH_API_NONE)) return SCPE_UNATT;
if (packet->len > sizeof (packet->msg)) /* packet ovesized? */
if (packet->len > sizeof (packet->msg)) /* packet oversized? */
return SCPE_IERR; /* that's no good! */
/* Get a buffer */
@ -3199,26 +3199,26 @@ for (i=0; i<count; ++i) {
int key = 0x3f & (eth_crc32(0, MultiCastList[i], 6) >> 26);
key ^= 0x3F;
printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X Key: %X, Byte: %X, Val: %X\n",
MultiCastList[i][0], MultiCastList[i][1], MultiCastList[i][2], MultiCastList[i][3], MultiCastList[i][4], MultiCastList[i][5],
printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X Key: %X, Byte: %X, Val: %X\n",
MultiCastList[i][0], MultiCastList[i][1], MultiCastList[i][2], MultiCastList[i][3], MultiCastList[i][4], MultiCastList[i][5],
key, key>>3, (1 << (key&0x7)));
lhash[key>>3] |= (1 << (key&0x7));
}
if (memcmp(hash, lhash, sizeof(lhash))) {
printf("Inconsistent Computed Hash:\n");
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
hash[0], hash[1], hash[2], hash[3],
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
hash[0], hash[1], hash[2], hash[3],
hash[4], hash[5], hash[6], hash[7]);
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
lhash[0], lhash[1], lhash[2], lhash[3],
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
lhash[0], lhash[1], lhash[2], lhash[3],
lhash[4], lhash[5], lhash[6], lhash[7]);
}
else {
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
hash[0], hash[1], hash[2], hash[3],
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
hash[0], hash[1], hash[2], hash[3],
hash[4], hash[5], hash[6], hash[7]);
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
lhash[0], lhash[1], lhash[2], lhash[3],
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
lhash[0], lhash[1], lhash[2], lhash[3],
lhash[4], lhash[5], lhash[6], lhash[7]);
}
return 0;
@ -3310,11 +3310,11 @@ struct TCPHeader {
#define IPPROTO_ICMP 1 /* control message protocol */
#endif
static uint16
ip_checksum(uint16 *buffer, int size)
static uint16
ip_checksum(uint16 *buffer, int size)
{
unsigned long cksum = 0;
/* Sum all the words together, adding the final byte if size is odd */
while (size > 1) {
cksum += *buffer++;
@ -3332,16 +3332,16 @@ if (size) {
/* Do a little shuffling */
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
/* Return the bitwise complement of the resulting mishmash */
return (uint16)(~cksum);
}
/*
/*
* src_addr and dest_addr are presented in network byte order
*/
static uint16
static uint16
pseudo_checksum(uint16 len, uint16 proto, void *nsrc_addr, void *ndest_addr, uint8 *buff)
{
uint32 sum;
@ -3351,7 +3351,7 @@ uint16 *dest_addr = (uint16 *)ndest_addr;
/* Sum the data first */
sum = 0xffff&(~ip_checksum((uint16 *)buff, len));
/* add the pseudo header which contains the IP source and
/* add the pseudo header which contains the IP source and
destination addresses already in network byte order */
sum += src_addr[0];
sum += src_addr[1];
@ -3363,7 +3363,7 @@ sum = sum + htons(proto) + htons(len);
/* Do a little shuffling */
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
/* Return the bitwise complement of the resulting mishmash */
return (uint16)(~sum);
}
@ -3434,7 +3434,7 @@ switch (IP->proto) {
/* We don't do anything with the TCP checksum since we're going to resegment the TCP data below */
break;
default:
++dev->jumbo_dropped; /* We onlt handle UDP, ICMP and TCP jumbo frames others are dropped */
++dev->jumbo_dropped; /* We only handle UDP, ICMP and TCP jumbo frames others are dropped */
return;
}
/* Reasonable Checksums are now in the jumbo packet, but we've got to actually */
@ -3450,8 +3450,8 @@ switch (IP->proto) {
case IPPROTO_UDP:
case IPPROTO_ICMP:
++dev->jumbo_fragmented;
/* When we're performing LSO (Large Send Offload), we're given a
'template' header which may not include a value being populated
/* When we're performing LSO (Large Send Offload), we're given a
'template' header which may not include a value being populated
in the IP header length (which is only 16 bits).
We process as payload everything which isn't known header data. */
payload_len = (uint16)(len - (14 + IP_HLEN(IP)));
@ -3477,8 +3477,8 @@ switch (IP->proto) {
(i.e. we can use Wireshark to verify packet contents)
we don't want to do this all the time for 2 reasons:
1) sending through pcap involves kernel transitions and
2) if the current system reflects sent packets, the
recieving side will receive and process 2 copies of
2) if the current system reflects sent packets, the
receiving side will receive and process 2 copies of
any packets sent this way. */
ETH_PACK pkt;
@ -3504,8 +3504,8 @@ switch (IP->proto) {
eth_packet_trace_ex (dev, ((u_char *)IP)-14, len, "Fragmenting Jumbo TCP segment", 1, dev->dbit);
TCP = (struct TCPHeader *)(((char *)IP)+IP_HLEN(IP));
orig_tcp_flags = ntohs(TCP->data_offset_and_flags);
/* When we're performing LSO (Large Send Offload), we're given a
'template' header which may not include a value being populated
/* When we're performing LSO (Large Send Offload), we're given a
'template' header which may not include a value being populated
in the IP header length (which is only 16 bits).
We process as payload everything which isn't known header data. */
payload_len = (uint16)(len - (14 + IP_HLEN(IP) + TCP_DATA_OFFSET(TCP)));
@ -3531,8 +3531,8 @@ switch (IP->proto) {
(i.e. we can use Wireshark to verify packet contents)
we don't want to do this all the time for 2 reasons:
1) sending through pcap involves kernel transitions and
2) if the current system reflects sent packets, the
recieving side will receive and process 2 copies of
2) if the current system reflects sent packets, the
receiving side will receive and process 2 copies of
any packets sent this way. */
ETH_PACK pkt;
@ -3638,16 +3638,16 @@ function = data[offset] | (data[offset+1] << 8);
if (function != 2) /*forward*/
return 0;
/* The only packets we should be responding to are ones which
we received due to them being directed to our physical MAC address,
OR the Broadcast address OR to a Multicast address we're listening to
(we may receive others if we're in promiscuous mode, but shouldn't
/* The only packets we should be responding to are ones which
we received due to them being directed to our physical MAC address,
OR the Broadcast address OR to a Multicast address we're listening to
(we may receive others if we're in promiscuous mode, but shouldn't
respond to them) */
if ((0 == (data[0]&1)) && /* Multicast or Broadcast */
(0 != memcmp(dev->filter_address[0], data, sizeof(ETH_MAC))))
return 0;
/* Attempts to forward to multicast or broadcast addresses are explicitly
/* Attempts to forward to multicast or broadcast addresses are explicitly
ignored by consuming the packet and doing nothing else */
if (data[offset+2]&1)
return 1;
@ -3771,7 +3771,7 @@ if (bpf_used ? to_me : (to_me && !from_me)) {
return;
}
if (_eth_process_loopback(dev, data, header->len))
return;
return;
#if defined (USE_READER_THREAD)
if (1) {
int crc_len = 0;
@ -3791,7 +3791,7 @@ if (bpf_used ? to_me : (to_me && !from_me)) {
/* but were presumed to be traversing a NIC which was going to handle that task */
/* This must be done before any needed CRC calculation */
_eth_fix_ip_xsum_offload(dev, (const u_char*)data, len);
if (dev->need_crc)
crc_len = eth_get_packet_crc32_data(data, len, crc_data);
@ -3948,7 +3948,7 @@ if (status < 0) {
status = 1;
ethq_remove(&dev->read_queue);
}
pthread_mutex_unlock (&dev->lock);
pthread_mutex_unlock (&dev->lock);
if ((status) && (routine))
routine(0);
#endif
@ -3957,7 +3957,7 @@ return status;
}
t_stat eth_bpf_filter (ETH_DEV* dev, int addr_count, ETH_MAC* const filter_address,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
int reflections,
ETH_MAC* physical_addr,
ETH_MAC* host_nic_phy_hw_addr,
@ -3986,9 +3986,9 @@ if (!promiscuous) {
sprintf(&buf[strlen(buf)], ")");
}
/* construct source filters - this prevents packets from being reflected back
/* construct source filters - this prevents packets from being reflected back
by systems where WinPcap and libpcap cause packet reflections. Note that
some systems do not reflect packets at all. This *assumes* that the
some systems do not reflect packets at all. This *assumes* that the
simulated NIC will not send out packets with multicast source fields. */
if ((addr_count > 0) && (reflections > 0)) {
if (strlen(buf) > 0)
@ -4013,22 +4013,22 @@ if ((addr_count > 0) && (reflections > 0)) {
}
if (strlen(buf) > 0)
sprintf(&buf[strlen(buf)], ")");
/* When changing the Physical Address on a LAN interface, VMS sends out a
loopback packet with the source and destination addresses set to the same
/* When changing the Physical Address on a LAN interface, VMS sends out a
loopback packet with the source and destination addresses set to the same
value as the Physical Address which is being setup. This packet is
designed to find and help diagnose MAC address conflicts (which also
include DECnet address conflicts). Normally, this packet would not be
seen by the sender, only by the other machine that has the same Physical
Address (or possibly DECnet address). If the ethernet subsystem is
reflecting packets, the network startup will fail to start if it sees the
reflected packet, since it thinks another system is using this Physical
Address (or DECnet address). We have to let these packets through, so
designed to find and help diagnose MAC address conflicts (which also
include DECnet address conflicts). Normally, this packet would not be
seen by the sender, only by the other machine that has the same Physical
Address (or possibly DECnet address). If the ethernet subsystem is
reflecting packets, the network startup will fail to start if it sees the
reflected packet, since it thinks another system is using this Physical
Address (or DECnet address). We have to let these packets through, so
that if another machine has the same Physical Address (or DECnet address)
that we can detect it. Both eth_write() and _eth_callback() help by
that we can detect it. Both eth_write() and _eth_callback() help by
checking the reflection count - eth_write() adds the reflection count to
dev->loopback_self_sent, and _eth_callback() check the value - if the
dev->loopback_self_sent count is zero, then the packet has come from
another machine with the same address, and needs to be passed on to the
dev->loopback_self_sent count is zero, then the packet has come from
another machine with the same address, and needs to be passed on to the
simulated machine. */
/* check for physical address in filters */
if ((!promiscuous) && (addr_count) && (reflections > 0)) {
@ -4051,22 +4051,22 @@ return SCPE_OK;
t_stat eth_filter(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
ETH_BOOL all_multicast, ETH_BOOL promiscuous)
{
return eth_filter_hash_ex(dev, addr_count, addresses,
return eth_filter_hash_ex(dev, addr_count, addresses,
all_multicast, promiscuous, FALSE,
NULL);
}
t_stat eth_filter_hash(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_MULTIHASH* const hash)
{
return eth_filter_hash_ex(dev, addr_count, addresses,
return eth_filter_hash_ex(dev, addr_count, addresses,
all_multicast, promiscuous, TRUE,
hash);
}
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
ETH_BOOL match_broadcast, ETH_MULTIHASH* const hash)
{
int i;
@ -4084,7 +4084,7 @@ if (!dev) return SCPE_UNATT;
if ((addr_count < 0) || ((addr_count + (match_broadcast ? 1 : 0)) > ETH_FILTER_MAX))
return SCPE_ARG;
else
if (!addresses && (addr_count != 0))
if (!addresses && (addr_count != 0))
return SCPE_ARG;
/* test reflections. This is done early in this routine since eth_reflect */
@ -4111,7 +4111,7 @@ dev->hash_filter = (hash != NULL);
if (hash) {
memcpy(dev->hash, hash, sizeof(*hash));
sim_debug(dev->dbit, dev->dptr, "Multicast Hash: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
dev->hash[0], dev->hash[1], dev->hash[2], dev->hash[3],
dev->hash[0], dev->hash[1], dev->hash[2], dev->hash[3],
dev->hash[4], dev->hash[5], dev->hash[6], dev->hash[7]);
}
@ -4151,14 +4151,14 @@ for (i = 0; i < addr_count; i++) {
#endif
/* setup BPF filters and other fields to minimize packet delivery */
eth_bpf_filter (dev, dev->addr_count, dev->filter_address,
dev->all_multicast, dev->promiscuous,
dev->reflections, &dev->physical_addr,
eth_bpf_filter (dev, dev->addr_count, dev->filter_address,
dev->all_multicast, dev->promiscuous,
dev->reflections, &dev->physical_addr,
dev->have_host_nic_phy_addr ? &dev->host_nic_phy_hw_addr: NULL,
(dev->hash_filter ? &dev->hash : NULL), buf);
/* get netmask, which is a required argument for compiling. The value,
in our case isn't actually interesting since the filters we generate
/* get netmask, which is a required argument for compiling. The value,
in our case isn't actually interesting since the filters we generate
aren't referencing IP fields, networks or values */
#ifdef USE_BPF
@ -4188,7 +4188,7 @@ if (dev->eth_api == ETH_API_PCAP) {
sim_printf ("Eth: Promiscuous\n");
if (dev->hash_filter)
sim_printf ("Eth: Multicast Hash: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
dev->hash[0], dev->hash[1], dev->hash[2], dev->hash[3],
dev->hash[0], dev->hash[1], dev->hash[2], dev->hash[3],
dev->hash[4], dev->hash[5], dev->hash[6], dev->hash[7]);
if (dev->have_host_nic_phy_addr) {
eth_mac_fmt(&dev->host_nic_phy_hw_addr, mac);
@ -4433,9 +4433,9 @@ for (eth_num=0; eth_num<eth_device_count; eth_num++) {
char errbuf[PCAP_ERRBUF_SIZE];
++bpf_count;
r = eth_bpf_filter (&dev, addr_count, &filter_address[0],
all_multicast, promiscuous, reflections,
&filter_address[0],
r = eth_bpf_filter (&dev, addr_count, &filter_address[0],
all_multicast, promiscuous, reflections,
&filter_address[0],
host_phy_addr_list[host_phy_addr_listindex],
hash_list[hash_listindex],
buf);

View file

@ -31,12 +31,12 @@
01-Mar-12 AGN Cygwin doesn't have non-blocking pcap I/O pcap (it uses WinPcap)
17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
18-Apr-11 MP Fixed race condition with self loopback packets in
18-Apr-11 MP Fixed race condition with self loopback packets in
multithreaded environments
09-Dec-10 MP Added support to determine if network address conflicts exist
07-Dec-10 MP Reworked DECnet self detection to the more general approach
of loopback self when any Physical Address is being set.
04-Dec-10 MP Changed eth_write to do nonblocking writes when
04-Dec-10 MP Changed eth_write to do nonblocking writes when
USE_READER_THREAD is defined.
07-Feb-08 MP Added eth_show_dev to display ethernet state
28-Jan-08 MP Added eth_set_async
@ -52,7 +52,7 @@
14-Nov-03 DTH Added #ifdef DECNET_FIX for problematic duplicate detection code
07-Jun-03 MP Added WIN32 support for DECNET duplicate address detection.
05-Jun-03 DTH Added used to struct eth_packet
01-Feb-03 MP Changed some uint8 strings to char* to reflect usage
01-Feb-03 MP Changed some uint8 strings to char* to reflect usage
22-Oct-02 DTH Added all_multicast and promiscuous support
21-Oct-02 DTH Corrected copyright again
16-Oct-02 DTH Fixed copyright
@ -82,7 +82,7 @@ extern "C" {
#define USE_SETNONBLOCK 1
#endif
/* cygwin dowsn't have the right features to use the threaded network I/O */
/* cygwin doesn't have the right features to use the threaded network I/O */
#if defined(__CYGWIN__) || defined(__ZAURUS__) // psco added check for Zaurus platform
#define DONT_USE_READER_THREAD
#endif
@ -135,9 +135,9 @@ extern "C" {
#endif
/*
USE_BPF is defined to let this code leverage the libpcap/OS kernel provided
BPF packet filtering. This generally will enhance performance. It may not
be available in some environments and/or it may not work correctly, so
USE_BPF is defined to let this code leverage the libpcap/OS kernel provided
BPF packet filtering. This generally will enhance performance. It may not
be available in some environments and/or it may not work correctly, so
undefining this will still provide working code here.
*/
#if defined(HAVE_PCAP_NETWORK)
@ -335,7 +335,7 @@ t_stat eth_open (ETH_DEV* dev, const char* name, /* open ethernet interfa
DEVICE* dptr, uint32 dbit);
t_stat eth_close (ETH_DEV* dev); /* close ethernet interface */
t_stat eth_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
t_stat eth_write (ETH_DEV* dev, ETH_PACK* packet, /* write sychronous packet; */
t_stat eth_write (ETH_DEV* dev, ETH_PACK* packet, /* write synchronous packet; */
ETH_PCALLBACK routine); /* callback when done */
int eth_read (ETH_DEV* dev, ETH_PACK* packet, /* read single packet; */
ETH_PCALLBACK routine); /* callback when done*/
@ -354,7 +354,7 @@ t_stat eth_filter_hash_ex (ETH_DEV* dev, int addr_count,/* set filter on incomin
ETH_BOOL promiscuous,
ETH_BOOL match_broadcast,
ETH_MULTIHASH* const hash); /* AUTODIN II based 8 byte imperfect hash */
t_stat eth_check_address_conflict (ETH_DEV* dev,
t_stat eth_check_address_conflict (ETH_DEV* dev,
ETH_MAC* const address);
const char *eth_version (void); /* Version of dynamically loaded library (pcap) */
void eth_setcrc (ETH_DEV* dev, int need_crc); /* enable/disable CRC mode */
@ -383,7 +383,7 @@ void ethq_remove (ETH_QUE* que); /* remove item from FIFO
void ethq_insert (ETH_QUE* que, int32 type, /* insert item into FIFO queue */
ETH_PACK* packet, int32 status);
void ethq_insert_data(ETH_QUE* que, int32 type, /* insert item into FIFO queue */
const uint8 *data, int used, size_t len,
const uint8 *data, int used, size_t len,
size_t crc_len, const uint8 *crc_data, int32 status);
t_stat ethq_destroy(ETH_QUE* que); /* release FIFO queue */
const char *eth_capabilities(void);

View file

@ -136,7 +136,7 @@ unsigned char by, *sptr, *dptr;
if (sim_end || (count == 0) || (size == sizeof (char)))
return;
for (j = 0, dptr = sptr = (unsigned char *) bptr; /* loop on items */
j < count; j++) {
j < count; j++) {
for (k = (int32)(size - 1); k >= (((int32) size + 1) / 2); k--) {
by = *sptr; /* swap end-for-end */
*sptr++ = *(dptr + k);
@ -359,7 +359,7 @@ if (NULL == _sim_expand_homedir (path, pathbuf, sizeof (pathbuf)))
return rmdir (pathbuf);
}
static void _sim_filelist_entry (const char *directory,
static void _sim_filelist_entry (const char *directory,
const char *filename,
t_offset FileSize,
const struct stat *filestat,
@ -503,9 +503,9 @@ return (t_offset)(ftello64 (st));
/* Apple OS/X */
#if defined (__APPLE__) || defined (__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__) || defined (__CYGWIN__)
#if defined (__APPLE__) || defined (__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__) || defined (__CYGWIN__)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseeko (FILE *st, t_offset xpos, int origin)
int sim_fseeko (FILE *st, t_offset xpos, int origin)
{
return fseeko (st, (off_t)xpos, origin);
}
@ -576,7 +576,7 @@ static void _time_t_to_filetime (time_t ttime, FILETIME *filetime)
{
t_uint64 time64;
time64 = 134774; /* Days betwen Jan 1, 1601 and Jan 1, 1970 */
time64 = 134774; /* Days between Jan 1, 1601 and Jan 1, 1970 */
time64 *= 24; /* Hours */
time64 *= 3600; /* Seconds */
time64 += (t_uint64)ttime; /* include time_t seconds */
@ -674,7 +674,7 @@ if (AlreadyExists) {
else
*((DWORD *)((*shmem)->shm_base)) = (DWORD)size; /* Save Size in first page */
*addr = ((char *)(*shmem)->shm_base + SysInfo.dwPageSize); /* Point to the second paget for data */
*addr = ((char *)(*shmem)->shm_base + SysInfo.dwPageSize); /* Point to the second page for data */
return SCPE_OK;
}
@ -936,8 +936,8 @@ return FALSE;
#endif /* defined (_WIN32) */
#if defined(__VAX)
/*
* We privide a 'basic' snprintf, which 'might' overrun a buffer, but
/*
* We provide a 'basic' snprintf, which 'might' overrun a buffer, but
* the actual use cases don't on other platforms and none of the callers
* care about the function return value.
*/
@ -977,7 +977,7 @@ return getcwd (buf, buf_size);
* %~pnI% - expands filepath value to a path and name only
* %~nxI% - expands filepath value to a file name and extension only
*
* In the above example above %I% can be replaced by other
* In the above example above %I% can be replaced by other
* environment variables or numeric parameters to a DO command
* invocation.
*/
@ -1001,7 +1001,7 @@ filepath = namebuf;
/* Check for full or current directory relative path */
if ((filepath[1] == ':') ||
(filepath[0] == '/') ||
(filepath[0] == '/') ||
(filepath[0] == '\\')){
tot_len = 1 + strlen (filepath);
fullpath = (char *)malloc (tot_len);
@ -1155,7 +1155,7 @@ if ((hFind = FindFirstFileA (cptr, &File)) != INVALID_HANDLE_VALUE) {
c = strrchr (DirName, '\\');
*c = '\0'; /* Truncate to just directory path */
if (!pathsep || /* Separator wasn't mentioned? */
(slash && (0 == strcmp (slash, "/*"))))
(slash && (0 == strcmp (slash, "/*"))))
pathsep = "\\"; /* Default to Windows backslash */
if (*pathsep == '/') { /* If slash separator? */
while ((c = strchr (DirName, '\\')))

View file

@ -28,15 +28,15 @@
03-Apr-15 MP Added logic to pass simulator startup messages in
panel error text if the connection to the simulator
shuts down while it is starting.
04-Apr-15 MP Added mount and dismount routines to connect and
04-Apr-15 MP Added mount and dismount routines to connect and
disconnect removable media
This module provides interface between a front panel application and a simh
simulator. Facilities provide ways to gather information from and to
simulator. Facilities provide ways to gather information from and to
observe and control the state of a simulator.
The details of the 'wire protocol' are internal to the API interfaces
provided here and described in sim_frontpanel.h. These details are subject
The details of the 'wire protocol' are internal to the API interfaces
provided here and described in sim_frontpanel.h. These details are subject
to change from one sim_frontpanel version to the next, while all efforts
will be made to retain any prior sim_frontpanel API interfaces.
@ -189,19 +189,19 @@ struct PANEL {
*
* Mutex: Role:
* io_lock Serialize access to panel state variables
* acquired and released in application threads:
* acquired and released in application threads:
* _panel_register_query_string,
* _panel_establish_register_bits_collection,
* _panel_sendf
* acquired and released in internal threads:
* acquired and released in internal threads:
* _panel_callback
* _panel_reader
* io_send_lock Serializes writes to a panel's sockets so that complete
* command/request data can be delivered before another
* io_send_lock Serializes writes to a panel's sockets so that complete
* command/request data can be delivered before another
* thread attempts to write to the socket.
* acquired and released in: _panel_send
* io_command_lock To serialize frontpanel application command requests
* acquired and released in: _panel_get_registers,
* acquired and released in: _panel_get_registers,
* _panel_sendf_completion
*
* Condition Var: Sync Mutex: Purpose & Duration:
@ -291,8 +291,8 @@ while (p && p->Debug && (dbits & p->debug)) {
clock_gettime(CLOCK_REALTIME, &time_now);
sprintf (timestamp, "%lld.%03d ", (long long)(time_now.tv_sec), (int)(time_now.tv_nsec/1000000));
sprintf (threadname, "%s:%s ", p->parent ? p->device_name : "CPU", (pthread_getspecific (panel_thread_id)) ? (char *)pthread_getspecific (panel_thread_id) : "");
sprintf (threadname, "%s:%s ", p->parent ? p->device_name : "CPU", (pthread_getspecific (panel_thread_id)) ? (char *)pthread_getspecific (panel_thread_id) : "");
obuf[obufsize - 1] = '\0';
len = vsnprintf (obuf, obufsize - 1, fmt, arglist);
if (len < 0)
@ -620,7 +620,7 @@ for (i=0; i<panel->reg_count; i++) {
}
}
pthread_mutex_unlock (&panel->io_lock);
if (_panel_sendf (panel, &cmd_stat, &response, "%s%u%s%u%s%u%s%s\r", register_collect_prefix, panel->sample_depth,
if (_panel_sendf (panel, &cmd_stat, &response, "%s%u%s%u%s%u%s%s\r", register_collect_prefix, panel->sample_depth,
register_collect_mid1, panel->sample_frequency,
register_collect_mid2, panel->sample_dither_pct,
register_collect_mid3, buf)) {
@ -669,7 +669,7 @@ int i;
for (i=0; i<panel_count; i++) {
if (panels[i] == p) {
int j;
for (j=i+1; j<panel_count; j++)
for (j=i+1; j<panel_count; j++)
panels[j-1] = panels[j];
--panel_count;
if (panel_count == 0) {
@ -869,7 +869,7 @@ if (!simulator_panel) {
close (0); close (1); close (2); /* make sure not to pass the open standard handles */
if (dup (dup (open ("/dev/null", O_RDWR)))) {}; /* open standard handles to /dev/null */
if (execlp (sim_path, sim_path, p->temp_config, NULL, NULL)) {
perror ("execl");
perror ("execlp");
exit(errno);
}
}
@ -1160,7 +1160,7 @@ if ((bit_count != 0) && (panel->sample_depth == 0)) {
sim_panel_set_error (NULL, "sim_panel_set_sampling_parameters() must be called first");
return -1;
}
regs = (REG *)_panel_malloc ((1 + panel->reg_count)*sizeof(*regs));
regs = (REG *)_panel_malloc ((1 + panel->reg_count)*sizeof(*regs));
if (regs == NULL)
return sim_panel_set_error (panel, "_panel_add_register(): Out of Memory\n");
pthread_mutex_lock (&panel->io_lock);
@ -1216,8 +1216,8 @@ for (i=0; i<panel->reg_count; i++) {
}
sprintf (t1, "%s %s", regs[i].device_name ? regs[i].device_name : "", regs[i].name);
sprintf (t2, "%s %s", reg->device_name ? reg->device_name : "", reg->name);
if ((!strcmp (t1, t2)) &&
(reg->indirect == regs[i].indirect) &&
if ((!strcmp (t1, t2)) &&
(reg->indirect == regs[i].indirect) &&
((reg->bits == NULL) == (regs[i].bits == NULL))) {
pthread_mutex_unlock (&panel->io_lock);
sim_panel_set_error (NULL, "Duplicate Register Declaration");
@ -1379,9 +1379,9 @@ return _panel_get_registers (panel, (panel->State == Halt), simulation_time);
}
int
sim_panel_set_display_callback_interval (PANEL *panel,
PANEL_DISPLAY_PCALLBACK callback,
void *context,
sim_panel_set_display_callback_interval (PANEL *panel,
PANEL_DISPLAY_PCALLBACK callback,
void *context,
int usecs_between_callbacks)
{
if (!panel) {
@ -1707,7 +1707,7 @@ return 0;
*/
int
sim_panel_gen_examine (PANEL *panel,
sim_panel_gen_examine (PANEL *panel,
const char *name_or_addr,
size_t size,
void *value)
@ -1755,7 +1755,7 @@ return 0;
*/
int
sim_panel_get_history (PANEL *panel,
sim_panel_get_history (PANEL *panel,
int count,
size_t size,
char *buffer)
@ -1781,7 +1781,7 @@ return 0;
}
int
sim_panel_device_debug_mode (PANEL *panel,
sim_panel_device_debug_mode (PANEL *panel,
const char *device,
int set_unset,
const char *mode_bits)
@ -1796,17 +1796,17 @@ if (!panel || (panel->State == Error)) {
if ((device != NULL) &&
((_panel_sendf (panel, &cmd_stat, &response, "SHOW %s", device) ||
(cmd_stat)))) {
sim_panel_set_error (NULL, "Can't %s Debug Mode: '%s' on Device '%s': %s",
sim_panel_set_error (NULL, "Can't %s Debug Mode: '%s' on Device '%s': %s",
set_unset ? "Enable" : "Disable", mode_bits ? mode_bits : "", device, response);
free (response);
return -1;
}
free (response);
response = NULL;
if (_panel_sendf (panel, &cmd_stat, &response, "%sDEBUG %s %s",
if (_panel_sendf (panel, &cmd_stat, &response, "%sDEBUG %s %s",
set_unset ? "" : "NO", device ? device : "", mode_bits ? mode_bits : "") ||
(cmd_stat)) {
sim_panel_set_error (NULL, "Can't %s Debug Mode: '%s' on Device '%s': %s",
sim_panel_set_error (NULL, "Can't %s Debug Mode: '%s' on Device '%s': %s",
set_unset ? "Enable" : "Disable", mode_bits ? mode_bits : "", device, response);
free (response);
return -1;
@ -1822,12 +1822,12 @@ return 0;
name_or_addr the name the simulator knows this register by
size the size (in local storage) of the buffer which
contains the data to be deposited into the simulator
value a pointer to the buffer which contains the data to
value a pointer to the buffer which contains the data to
be deposited into the simulator
*/
int
sim_panel_gen_deposit (PANEL *panel,
sim_panel_gen_deposit (PANEL *panel,
const char *name_or_addr,
size_t size,
const void *value)
@ -1856,7 +1856,7 @@ return 0;
sim_panel_mem_examine
addr_size the size (in local storage) of the buffer which
addr_size the size (in local storage) of the buffer which
contains the memory address of the data to be examined
in the simulator
addr a pointer to the buffer containing the memory address
@ -1868,7 +1868,7 @@ return 0;
*/
int
sim_panel_mem_examine (PANEL *panel,
sim_panel_mem_examine (PANEL *panel,
size_t addr_size,
const void *addr,
size_t value_size,
@ -1913,7 +1913,7 @@ return 0;
sim_panel_mem_deposit
addr_size the size (in local storage) of the buffer which
addr_size the size (in local storage) of the buffer which
contains the memory address of the data to be deposited
into the simulator
addr a pointer to the buffer containing the memory address
@ -1925,7 +1925,7 @@ return 0;
*/
int
sim_panel_mem_deposit (PANEL *panel,
sim_panel_mem_deposit (PANEL *panel,
size_t addr_size,
const void *addr,
size_t value_size,
@ -1959,17 +1959,17 @@ return 0;
sim_panel_mem_deposit_instruction
addr_size the size (in local storage) of the buffer which
addr_size the size (in local storage) of the buffer which
contains the memory address of the data to be deposited
into the simulator
addr a pointer to the buffer containing the memory address
of the data to be deposited into the simulator
instruction a pointer to the buffer that contains the mnemonic
instruction a pointer to the buffer that contains the mnemonic
instruction to be deposited at the indicated address
*/
int
sim_panel_mem_deposit_instruction (PANEL *panel,
sim_panel_mem_deposit_instruction (PANEL *panel,
size_t addr_size,
const void *addr,
const char *instruction)
@ -1999,8 +1999,8 @@ return 0;
name the name of a simulator register or a memory address
which is to receive a new value
value the new value in character string form. The string
must be in the native/natural radix that the simulator
value the new value in character string form. The string
must be in the native/natural radix that the simulator
uses when referencing that register
*/
@ -2118,8 +2118,8 @@ int buf_data = 0;
int processing_register_output = 0;
int io_wait_done = 0;
/*
Boost Priority for this response processing thread to quickly digest
/*
Boost Priority for this response processing thread to quickly digest
arriving data.
*/
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
@ -2201,13 +2201,13 @@ while ((p->sock != INVALID_SOCKET) &&
++s;
continue; /* process next line */
}
if ((*s == '}') &&
if ((*s == '}') &&
(3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */
r = NULL;
for (i=0; i<p->reg_count; i++) {
if (p->regs[i].bits == NULL)
continue;
if ((!strcmp (smp_reg, p->regs[i].name)) &&
if ((!strcmp (smp_reg, p->regs[i].name)) &&
((!p->device_name) || (!strcmp (smp_dev, p->device_name)))) {
r = &p->regs[i];
break;
@ -2283,7 +2283,7 @@ while ((p->sock != INVALID_SOCKET) &&
if (end)
end_index = (size_t)atoi (end + 1);
if (strcmp (e, " same as above"))
if (strcmp (e, " same as above"))
p->array_element_data = strtoull (e, NULL, 16);
while (array_index <= end_index) {
if (little_endian)
@ -2319,14 +2319,14 @@ while ((p->sock != INVALID_SOCKET) &&
p->io_response[p->io_response_data] = '\0';
goto Start_Next_Line;
}
if ((strlen (s) > strlen (sim_prompt)) &&
if ((strlen (s) > strlen (sim_prompt)) &&
((!strcmp (s + strlen (sim_prompt), register_repeat_start)) ||
(!strcmp (s + strlen (sim_prompt), register_get_start)))) {
_panel_debug (p, DBG_RCV, "*Repeat/Register Block Starting", NULL, 0);
processing_register_output = 1;
goto Start_Next_Line;
}
if ((strlen (s) > strlen (sim_prompt)) &&
if ((strlen (s) > strlen (sim_prompt)) &&
(!strcmp (s + strlen (sim_prompt), register_get_end))) {
_panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0);
p->io_waiting = 0;
@ -2359,8 +2359,8 @@ while ((p->sock != INVALID_SOCKET) &&
p->io_response_data += strlen(s);
strcpy (p->io_response + p->io_response_data, "\r\n");
p->io_response_data += 2;
if ((!p->parent) &&
(p->completion_string) &&
if ((!p->parent) &&
(p->completion_string) &&
(!memcmp (s, p->completion_string, strlen (p->completion_string)))) {
_panel_debug (p, DBG_RCV, "Match with potentially coalesced additional data: '%s'", NULL, 0, p->completion_string);
if (eol < &buf[buf_data])
@ -2376,8 +2376,8 @@ Start_Next_Line:
buf_data = strlen (buf);
if (buf_data)
_panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf);
if ((!p->parent) &&
(p->completion_string) &&
if ((!p->parent) &&
(p->completion_string) &&
(!memcmp (buf, p->completion_string, strlen (p->completion_string)))) {
_panel_debug (p, DBG_RCV, "*Received Command Complete - Match: '%s'", NULL, 0, p->completion_string);
io_wait_done = 1;
@ -2448,8 +2448,8 @@ size_t buf_data = 0;
unsigned int callback_count = 0;
int cmd_stat;
/*
Boost Priority for timer thread so it doesn't compete
/*
Boost Priority for timer thread so it doesn't compete
with compute bound activities.
*/
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
@ -2464,7 +2464,7 @@ pthread_mutex_unlock (&p->io_lock);
pthread_cond_signal (&p->startup_done); /* Signal we're ready to go */
msleep (100);
pthread_mutex_lock (&p->io_lock);
while ((p->sock != INVALID_SOCKET) &&
while ((p->sock != INVALID_SOCKET) &&
(p->usecs_between_callbacks) &&
(p->State != Error)) {
int interval = p->usecs_between_callbacks;
@ -2501,9 +2501,9 @@ while ((p->sock != INVALID_SOCKET) &&
buf_data -= (c - buf) + strlen (register_get_start);
c += strlen (register_get_start);
}
sprintf (repeat, "%s%d%s%s%*.*s", register_repeat_prefix,
p->usecs_between_callbacks,
register_repeat_units,
sprintf (repeat, "%s%d%s%s%*.*s", register_repeat_prefix,
p->usecs_between_callbacks,
register_repeat_units,
register_repeat_start,
(int)buf_data, (int)buf_data, c);
pthread_mutex_unlock (&p->io_lock);

View file

@ -28,18 +28,18 @@
03-Apr-15 MP Added logic to pass simulator startup messages in
panel error text if the connection to the simulator
shuts down while it is starting.
04-Apr-15 MP Added mount and dismount routines to connect and
04-Apr-15 MP Added mount and dismount routines to connect and
disconnect removable media
This module defines interface between a front panel application and a simh
simulator. Facilities provide ways to gather information from and to
simulator. Facilities provide ways to gather information from and to
observe and control the state of a simulator.
Any application which wants to use this API needs to:
1) include this file in the application code
2) compile sim_frontpanel.c and sim_sock.c from the top level directory
2) compile sim_frontpanel.c and sim_sock.c from the top level directory
of the simh source.
3) link the sim_frontpanel and sim_sock object modules and libpthreads
3) link the sim_frontpanel and sim_sock object modules and libpthreads
into the application.
4) Use a simh simulator built from the same version of simh that the
sim_frontpanel and sim_sock modules came from.
@ -60,21 +60,21 @@ extern "C" {
/**
sim_panel_start_simulator A starts a simulator with a particular
sim_panel_start_simulator A starts a simulator with a particular
configuration
sim_path the path to the simulator binary
sim_config the configuration to run the simulator with
device_panel_count the number of sub panels for connected devices
Note 1: - The path specified must be either a fully specified path or
Note 1: - The path specified must be either a fully specified path or
it could be merely the simulator name if the simulator binary
is located in the current PATH.
- The simulator binary must be built from the same version
simh source code that the frontpanel API was acquired fron
(the API and the simh framework must speak the same language)
- The simulator binary must be built from the same version
simh source code that the frontpanel API was acquired from
(the API and the simh framework must speak the same language)
Note 2: - Configuration file specified should contain device setup
Note 2: - Configuration file specified should contain device setup
statements (enable, disable, CPU types and attach commands).
It should not start a simulator running.
*/
@ -94,7 +94,7 @@ sim_panel_start_simulator_debug (const char *sim_path,
/**
sim_panel_add_device_panel - creates a sub panel associated
sim_panel_add_device_panel - creates a sub panel associated
with a specific simulator panel
simulator_panel the simulator panel to connect to
@ -109,7 +109,7 @@ sim_panel_add_device_panel (PANEL *simulator_panel,
sim_panel_destroy to shutdown a panel or sub panel.
Note: destroying a simulator panel will also destroy any
Note: destroying a simulator panel will also destroy any
related sub panels
*/
@ -118,18 +118,18 @@ sim_panel_destroy (PANEL *panel);
/**
The frontpanel API exposes the state of a simulator via access to
The frontpanel API exposes the state of a simulator via access to
simh register variables that the simulator and its devices define.
These registers certainly include any architecturally described
These registers certainly include any architecturally described
registers (PC, PSL, SP, etc.), but also include anything else
the simulator uses as internal state to implement the running
the simulator uses as internal state to implement the running
simulator.
The registers that a particular frontpanel application mught need
access to are specified by the application when it calls:
The registers that a particular frontpanel application might need
access to are specified by the application when it calls:
sim_panel_add_register
sim_panel_add_register_bits
sim_panel_add_register_bits
sim_panel_add_register_array
and
sim_panel_add_register_indirect
@ -142,13 +142,13 @@ and
element_count number of elements in the register array
size the size (in local storage) of the buffer which will
receive the data in the simulator's register
addr a pointer to the location of the buffer which will
addr a pointer to the location of the buffer which will
be loaded with the data in the simulator's register
bit_width the number of values to populate in the bits array
bits an array of integers which is bit_width long that
bits an array of integers which is bit_width long that
will receive each bit's current accumulated value.
The accumulated value will range from 0 thru the
the sample_depth specified when calling
The accumulated value will range from 0 thru the
the sample_depth specified when calling
sim_panel_set_sampling_parameters().
*/
@ -190,58 +190,58 @@ sim_panel_add_register_indirect_bits (PANEL *panel,
/**
A panel application has a choice of two different methods of getting
A panel application has a choice of two different methods of getting
the values contained in the set of registers it has declared interest in via
the sim_panel_add_register APIs.
1) The values can be polled (whenever it is desired) by calling
sim_panel_get_registers().
2) The panel can call sim_panel_set_display_callback_interval() to
specify a callback routine and a periodic rate that the callback
routine should be called. The panel API will make a best effort
2) The panel can call sim_panel_set_display_callback_interval() to
specify a callback routine and a periodic rate that the callback
routine should be called. The panel API will make a best effort
to deliver the current register state at the desired rate.
Note 1: The buffers described in a panel's register set will be
dynamically revised as soon as data is available from the
simulator. The callback routine merely serves as a notification
Note 1: The buffers described in a panel's register set will be
dynamically revised as soon as data is available from the
simulator. The callback routine merely serves as a notification
that a complete register set has arrived.
Note 2: The callback routine should, in general, not run for a long time
or frontpanel interactions with the simulator may be disrupted.
Setting a flag, signaling an event or posting a message are
or frontpanel interactions with the simulator may be disrupted.
Setting a flag, signaling an event or posting a message are
reasonable activities to perform in a callback routine.
*/
int
sim_panel_get_registers (PANEL *panel, unsigned long long *simulation_time);
typedef void (*PANEL_DISPLAY_PCALLBACK)(PANEL *panel,
typedef void (*PANEL_DISPLAY_PCALLBACK)(PANEL *panel,
unsigned long long simulation_time,
void *context);
int
sim_panel_set_display_callback_interval (PANEL *panel,
PANEL_DISPLAY_PCALLBACK callback,
void *context,
sim_panel_set_display_callback_interval (PANEL *panel,
PANEL_DISPLAY_PCALLBACK callback,
void *context,
int usecs_between_callbacks);
/**
When a front panel application wants to get averaged bit sample
values, it must first declare the sampling parameters that will
be used while collecting the bit values. The dithering
be used while collecting the bit values. The dithering
percentage must be 25% or less and when non 0 causes the sample
frequency to vary by plus or minus a random percentage value up
frequency to vary by plus or minus a random percentage value up
to the specified value.
sim_panel_set_sampling_parameters
sim_panel_set_sampling_parameters_ex
sim_panel_set_sampling_parameters
sim_panel_set_sampling_parameters_ex
sample_frequency cycles/instructions between sample captures
sample_dither_pct percentage of sample_frequency to vary randomly
sample_depth how many samples to accumulate in the rolling
average for each bit sample. Returned bit
sample values will range from 0 thru this
sample values will range from 0 thru this
value.
*/
@ -258,13 +258,13 @@ sim_panel_set_sampling_parameters (PANEL *panel,
/**
When a front panel application needs to change the running
state of a simulator one of the following routines should
be called:
state of a simulator one of the following routines should
be called:
sim_panel_exec_halt - Stop instruction execution
sim_panel_exec_boot - Boot a simulator from a specific device
sim_panel_exec_run - Start/Resume a simulator running instructions
sim_panel_exec_start - Start a simulator running instructions
sim_panel_exec_start - Start a simulator running instructions
after resetting all devices
sim_panel_exec_step - Have a simulator execute a single step
*/
@ -290,7 +290,7 @@ sim_panel_exec_step (PANEL *panel);
A simulator often displays some useful information as it stops
executing instructions.
sim_panel_halt_text - Returns the simulator output immediately prior
sim_panel_halt_text - Returns the simulator output immediately prior
to the most recent transition to the Halt state.
*/
@ -299,20 +299,20 @@ sim_panel_halt_text (PANEL *panel);
/**
When a front panel application wants to describe conditions that
When a front panel application wants to describe conditions that
should stop instruction execution an execution or an output
breakpoint should be used. To established or clear a breakpoint,
one of the following routines should be called:
breakpoint should be used. To established or clear a breakpoint,
one of the following routines should be called:
sim_panel_break_set - Establish a simulation breakpoint
sim_panel_break_clear - Cancel/Delete a previously defined
breakpoint
sim_panel_break_output_set - Establish a simulator output
sim_panel_break_output_set - Establish a simulator output
breakpoint
sim_panel_break_output_clear - Cancel/Delete a previously defined
output breakpoint
Note: Any breakpoint switches/flags must be located at the
Note: Any breakpoint switches/flags must be located at the
beginning of the condition string
*/
@ -332,16 +332,16 @@ sim_panel_break_output_clear (PANEL *panel, const char *condition);
/**
When a front panel application needs to change or access
memory or a register one of the following routines should
be called:
memory or a register one of the following routines should
be called:
sim_panel_gen_examine - Examine register or memory
sim_panel_gen_deposit - Deposit to register or memory
sim_panel_mem_examine - Examine memory location
sim_panel_mem_deposit - Deposit to memory location
sim_panel_mem_deposit_instruction - Deposit instruction to memory
sim_panel_mem_deposit_instruction - Deposit instruction to memory
location
sim_panel_set_register_value - Deposit to a register or memory
sim_panel_set_register_value - Deposit to a register or memory
location
*/
@ -358,7 +358,7 @@ sim_panel_break_output_clear (PANEL *panel, const char *condition);
*/
int
sim_panel_gen_examine (PANEL *panel,
sim_panel_gen_examine (PANEL *panel,
const char *name_or_addr,
size_t size,
void *value);
@ -370,12 +370,12 @@ sim_panel_gen_examine (PANEL *panel,
name_or_addr the name the simulator knows this register by
size the size (in local storage) of the buffer which
contains the data to be deposited into the simulator
value a pointer to the buffer which contains the data to
value a pointer to the buffer which contains the data to
be deposited into the simulator
*/
int
sim_panel_gen_deposit (PANEL *panel,
sim_panel_gen_deposit (PANEL *panel,
const char *name_or_addr,
size_t size,
const void *value);
@ -384,7 +384,7 @@ sim_panel_gen_deposit (PANEL *panel,
sim_panel_mem_examine
addr_size the size (in local storage) of the buffer which
addr_size the size (in local storage) of the buffer which
contains the memory address of the data to be examined
in the simulator
addr a pointer to the buffer containing the memory address
@ -396,7 +396,7 @@ sim_panel_gen_deposit (PANEL *panel,
*/
int
sim_panel_mem_examine (PANEL *panel,
sim_panel_mem_examine (PANEL *panel,
size_t addr_size,
const void *addr,
size_t value_size,
@ -406,7 +406,7 @@ sim_panel_mem_examine (PANEL *panel,
sim_panel_mem_deposit
addr_size the size (in local storage) of the buffer which
addr_size the size (in local storage) of the buffer which
contains the memory address of the data to be deposited
into the simulator
addr a pointer to the buffer containing the memory address
@ -418,7 +418,7 @@ sim_panel_mem_examine (PANEL *panel,
*/
int
sim_panel_mem_deposit (PANEL *panel,
sim_panel_mem_deposit (PANEL *panel,
size_t addr_size,
const void *addr,
size_t value_size,
@ -428,17 +428,17 @@ sim_panel_mem_deposit (PANEL *panel,
sim_panel_mem_deposit_instruction
addr_size the size (in local storage) of the buffer which
addr_size the size (in local storage) of the buffer which
contains the memory address of the data to be deposited
into the simulator
addr a pointer to the buffer containing the memory address
of the data to be deposited into the simulator
instruction a pointer to the buffer that contains the mnemonic
instruction a pointer to the buffer that contains the mnemonic
instruction to be deposited at the indicated address
*/
int
sim_panel_mem_deposit_instruction (PANEL *panel,
sim_panel_mem_deposit_instruction (PANEL *panel,
size_t addr_size,
const void *addr,
const char *instruction);
@ -449,8 +449,8 @@ sim_panel_mem_deposit_instruction (PANEL *panel,
name the name of a simulator register or a memory address
which is to receive a new value
value the new value in character string form. The string
must be in the native/natural radix that the simulator
value the new value in character string form. The string
must be in the native/natural radix that the simulator
uses when referencing that register
*/
int
@ -461,9 +461,9 @@ sim_panel_set_register_value (PANEL *panel,
/**
A front panel application might want to have access to the
instruction execution history that a simulator may be capable
instruction execution history that a simulator may be capable
of providing. If this functionality is desired, enabling of
recording instruction history should be explicitly enabled
recording instruction history should be explicitly enabled
in the sim_config file that the simulator is started with.
*/
@ -479,7 +479,7 @@ sim_panel_set_register_value (PANEL *panel,
*/
int
sim_panel_get_history (PANEL *panel,
sim_panel_get_history (PANEL *panel,
int count,
size_t size,
char *buffer);
@ -488,7 +488,7 @@ sim_panel_get_history (PANEL *panel,
/**
A front panel application might want some details of simulator
and/or device behavior that is provided by a particular simulator
and/or device behavior that is provided by a particular simulator
via debug information. Debugging for particular device(s)
and/or simulator debug settings can be controlled via the
sim_panel_device_debug_mode API.
@ -499,15 +499,15 @@ sim_panel_get_history (PANEL *panel,
sim_panel_device_debug_mode
device the device whose debug mode is to change
set_untset 1 to set debug flags, 0 to clear debug flags
mode_bits character string with different debug mode bits
set_unset 1 to set debug flags, 0 to clear debug flags
mode_bits character string with different debug mode bits
to enable or disable. An empty string will
enable or disable all mode bits for the specified
enable or disable all mode bits for the specified
device
*/
int
sim_panel_device_debug_mode (PANEL *panel,
sim_panel_device_debug_mode (PANEL *panel,
const char *device,
int set_unset,
const char *mode_bits);
@ -516,11 +516,11 @@ sim_panel_device_debug_mode (PANEL *panel,
/**
When a front panel application needs to change the media
in a simulated removable media device one of the following
in a simulated removable media device one of the following
routines should be called:
sim_panel_mount - mounts the indicated media file on a device
sim_panel_dismount - dismounts the currently mounted media file
sim_panel_dismount - dismounts the currently mounted media file
from a device
*/
@ -564,13 +564,13 @@ sim_panel_get_state (PANEL *panel);
/**
All API routines which return an int return 0 for
success and -1 for an error.
All API routines which return an int return 0 for
success and -1 for an error.
An API which returns an error (-1), will not change the panel state
except to possibly set the panel state to Error if the panel
condition is no longer useful.
sim_panel_get_error - the details of the most recent error
sim_panel_clear_error - clears the error buffer
*/
@ -580,8 +580,8 @@ void sim_panel_clear_error (void);
/**
The panek<->simulator wire protocol can be traced if protocol problems arise.
The panel<->simulator wire protocol can be traced if protocol problems arise.
sim_panel_set_debug_mode - Specifies the debug detail to be recorded
sim_panel_flush_debug - Flushes debug output to disk
sim_panel_debug - Write message to the debug file

View file

@ -156,7 +156,7 @@ static t_stat diskParse(DISK_INFO *myDisk, uint32 isVerbose)
sim_debug(myDisk->debugmask, myDisk->device, "start of track %d at file offset %ld\n", myDisk->ntracks, ftell(myDisk->file));
hdrBytes = sim_fread(&imd, 1, 5, myDisk->file);
if ((hdrBytes == 0) && feof(myDisk->file))
break; /* detected end of IMD file */
@ -672,7 +672,7 @@ t_stat sectWrite(DISK_INFO *myDisk,
* does not involve changing the disk image size.)
*
* Any existing data on the disk image will be destroyed when Track 0, Head 0 is formatted.
* At that time, the IMD file is truncated. So for the trackWrite to be used to sucessfully
* At that time, the IMD file is truncated. So for the trackWrite to be used to successfully
* format a disk image, then format program must format tracks starting with Cyl 0, Head 0,
* and proceed sequentially through all tracks/heads on the disk.
*

View file

@ -2,7 +2,7 @@
* sim_printf_fmts.h
*
* Cross-platform printf() formats for simh data types. Refactored out to
* this header so that these formats are avaiable to more than SCP.
* this header so that these formats are available to more than SCP.
*
* Author: B. Scott Michel
*

106
sim_rev.h
View file

@ -45,8 +45,8 @@
#endif
/*
SIM__GIT_COMMMIT_ID is undefined when working with an
archive (zip file or tar ball). Use Git keyword subsitution
SIM__GIT_COMMMIT_ID is undefined when working with an
archive (zip file or tar ball). Use Git keyword substitution
to record the archive's commit id via the .gitattributes
"export-subst".
*/
@ -55,9 +55,9 @@
/*
The comment section below reflects the manual editing process which was in place
prior to the use of the git source control system on at https://gihub.com/simh/simh
prior to the use of the git source control system on at https://github.com/simh/simh
Details about all future fixes will be visible in the source control system's
Details about all future fixes will be visible in the source control system's
history.
*/
@ -86,7 +86,7 @@ patch date module(s) and fix(es)
connected LANs
sim_tmxr.c:
- made telnet option negotiation more reliable, VAX simulator now
- made telnet option negotiation more reliable, VAX simulator now
works with PuTTY as console (Mark Pizzolato)
h316_cpu.c:
@ -147,7 +147,7 @@ patch date module(s) and fix(es)
hp2100_dp.c (Dave Bryan):
- Added CNTLR_TYPE cast to dp_settype
hp2100_ds.c (Dave Bryan):
- Rewritten to use the MAC/ICD disc controller library
- ioIOO now notifies controller service of parameter output
@ -178,21 +178,21 @@ patch date module(s) and fix(es)
hp2100_ms.c (Dave Bryan):
- Added CNTLR_TYPE cast to ms_settype
hp2100_mt.c (Dave Bryan):
- Removed redundant MTAB_VUN from "format" MTAB entry
- Fixed command scanning error in mtcio ioIOO handler
hp2100_stddev.c (Dave Bryan):
- Add TBG as a logical name for the CLK device
hp2100_sys.c (Dave Bryan):
- Deprecated DEVNO in favor of SC
- Added hp_setsc, hp_showsc functions to support SC modifier
- Added DA and dummy DC devices
- DMA channels renamed from 0,1 to 1,2 to match documentation
- Changed DIB access for revised signal model
hp_disclib.c, hp_disclib.h (Dave Bryan)
- Created MAC/ICD disc controller library
@ -229,7 +229,7 @@ patch date module(s) and fix(es)
- fixed misuse of & instead of && in Ea_ch (Michael Bloom)
pdp1_stddev.c:
- fixed unitialized variable in tty output service (Michael Bloom)
- fixed uninitialized variable in tty output service (Michael Bloom)
pdp10_fe.c:
- revised to use clock coscheduling
@ -241,7 +241,7 @@ patch date module(s) and fix(es)
- fixed Qbus interrupts to treat all IO devices (except clock) as BR4
- fixed order of int_internal (Jordi Guillaumes i Pons)
ppd11_rf.c
pdp11_rf.c
- fixed bug in updating mem addr extension (Peter Schorn)
pdp11_rk.c:
@ -254,7 +254,7 @@ patch date module(s) and fix(es)
- added RD32 support
pdp11_tq.c: (Mark Pizzolato)
- set UNIT_SXC flag when a tape mark is encountered
- set UNIT_SXC flag when a tape mark is encountered
during forward motion read operations
- fixed logic which clears UNIT_SXC to check command modifier
- added CMF_WR flag to tq_cmf entry for OP_WTM
@ -264,7 +264,7 @@ patch date module(s) and fix(es)
- added more debug output after positioning operations
- added textual display of the command being performed
- fixed comments about register addresses
pdp11_ts.c:
- fixed t_addr printouts for 64b big-endian systems (Mark Pizzolato)
@ -278,34 +278,34 @@ patch date module(s) and fix(es)
pdp11_xq.c: (Mark Pizzolato)
- Fixed missing information from save/restore which
caused operations to not complete correctly after
caused operations to not complete correctly after
a restore until the OS reset the controller.
- Added address conflict check during attach.
- Fixed loopback processing to correctly handle forward packets.
- Fixed interrupt dispatch issue which caused delivered packets
- Fixed interrupt dispatch issue which caused delivered packets
(in and out) to sometimes not interrupt the CPU after processing.
- Fixed the SCP visibile SA registers to always display the
- Fixed the SCP visible SA registers to always display the
ROM mac address, even after it is changed by SET XQ MAC=.
- Added changes so that the Console DELQA diagnostic (>>>TEST 82)
- Added changes so that the Console DELQA diagnostic (>>>TEST 82)
will succeed.
- Added DELQA-T (aka DELQA Plus) device emulation support.
- Added dropped frame statistics to record when the receiver discards
received packets due to the receiver being disabled, or due to the
XQ device's packet receive queue being full.
- Fixed bug in receive processing when we're not polling. This could
cause receive processing to never be activated again if we don't
read all available packets via eth_read each time we get the
cause receive processing to never be activated again if we don't
read all available packets via eth_read each time we get the
opportunity.
- Added the ability to Coalesce received packet interrupts. This
is enabled by SET XQ POLL=DELAY=nnn where nnn is a number of
is enabled by SET XQ POLL=DELAY=nnn where nnn is a number of
microseconds to delay the triggering of an interrupt when a packet
is received.
- Added SET XQ POLL=DISABLE (aka SET XQ POLL=0) to operate without
- Added SET XQ POLL=DISABLE (aka SET XQ POLL=0) to operate without
polling for packet read completion.
- Changed the sanity and id timer mechanisms to use a separate timer
unit so that transmit and recieve activities can be dealt with
unit so that transmit and receive activities can be dealt with
by the normal xq_svc routine.
Dynamically determine the timer polling rate based on the
Dynamically determine the timer polling rate based on the
calibrated tmr_poll and clk_tps values of the simulator.
- Enabled the SET XQ POLL to be meaningful if the simulator currently
doesn't support idling.
@ -313,7 +313,7 @@ patch date module(s) and fix(es)
all debug output goes to the same place.
- Restored the call to xq_svc after all successful calls to eth_write
to allow receive processing to happen before the next event
service time. This must have been inadvertently commented out
service time. This must have been inadvertently commented out
while other things were being tested.
pdp11_xu.c: (Mark Pizzolato)
@ -328,7 +328,7 @@ patch date module(s) and fix(es)
pdp18b_stddev.c:
- added clock coscheduling
- revised TTI to use clock coscheduling and to fix perpetual CAF bug
pdp18b_ttx.c:
- revised to use clock coscheduling
@ -342,7 +342,7 @@ patch date module(s) and fix(es)
- revised to use clock coscheduling and to fix perpetual CAF bug
pdp8_ttx.c:
- revised to use clock cosheduling
- revised to use clock coscheduling
pdp8_sys.c:
- added link to FPP
@ -401,7 +401,7 @@ patch date module(s) and fix(es)
- decommitted MTAB_VAL
- fixed implementation of MTAB_NC
- fixed warnings in help printouts
- fixed "SHOW DEVICE" with only one enabled unit (Dave Bryan)
- fixed "SHOW DEVICE" with only one enabled unit (Dave Bryan)
sim_tape.c:
- fixed signed/unsigned warning in sim_tape_set_fmt (Dave Bryan)
@ -423,7 +423,7 @@ patch date module(s) and fix(es)
- Moved non-existent memory checks to WritePW
- Fixed mp_dms_jmp to accept lower bound, check write protection
- Corrected DMS violation register set conditions
- Refefined ABORT to pass address, moved def to hp2100_cpu.h
- Redefined ABORT to pass address, moved def to hp2100_cpu.h
- Combined dms and dms_io routines
- JSB to 0/1 with W5 out and fence = 0 erroneously causes MP abort
- Unified I/O slot dispatch by adding DIBs for CPU, MP, and DMA
@ -449,7 +449,7 @@ patch date module(s) and fix(es)
- Updated mp_dms_jmp calling sequence
- Fixed DJP, SJP, and UJP jump target validation
- RVA/B conditionally updates dms_vr before returning value
hp2100_cpu3.c (Dave Bryan):
- Moved microcode function prototypes to hp2100_cpu1.h
- Removed option-present tests (now in UIG dispatchers)
@ -506,7 +506,7 @@ patch date module(s) and fix(es)
hp2100_mt.c (Dave Bryan):
- Fixed missing flag after CLR command
- Moved write enable and format commands from MTD to MTC
hp2100_mux.c (Dave Bryan):
- SHOW MUX CONN/STAT with SET MUX DIAG is no longer disallowed
- Changed Telnet poll to connect immediately after reset or attach
@ -744,7 +744,7 @@ patch date module(s) and fix(es)
- fixed declarations (Mark Pizzolato)
V3.7 revision history
V3.7 revision history
3 02-Sep-07 scp.c:
- fixed bug in SET THROTTLE command
@ -771,7 +771,7 @@ patch date module(s) and fix(es)
sim_timer.c:
- fixed idle timer event selection algorithm
h316_lp.c:
- fixed loss of last print line (Theo Engel)
@ -827,7 +827,7 @@ patch date module(s) and fix(es)
- fixed to set "mux_rchp" when a line break is received
- fixed incorrect "odd_par" table values
- reversed test in "RCV_PAR" to return "LIL_PAR" on odd parity
- rixed mux reset (ioCRS) to clear port parameters
- fixed mux reset (ioCRS) to clear port parameters
- fixed to use PUT_DCH instead of PUT_CCH for data channel status
- added DIAG/TERM modifiers to implement diagnostic mode
@ -1016,7 +1016,7 @@ patch date module(s) and fix(es)
- fixed operand order in EIS instructions (W.F.J. Mueller)
V3.6 revision history
V3.6 revision history
1 25-Jul-06 sim_console.c:
- implemented SET/SHOW PCHAR
@ -1167,7 +1167,7 @@ patch date module(s) and fix(es)
- fixed POLYD, POLYG to not exit prematurely if arg = 0
- fixed POLYD, POLYG to do full 64b multiply
- fixed POLYF, POLYD, POLYG to remove truncation on add
- fixed POLYF, POLYD, POLYG to mask mul reslt to 31b/63b/63b
- fixed POLYF, POLYD, POLYG to mask mul result to 31b/63b/63b
- fixed fp add routine to test for zero via fraction
to support "denormal" argument from POLYF, POLYD, POLYG
- fixed bug in 32b floating multiply routine
@ -1183,14 +1183,14 @@ patch date module(s) and fix(es)
- fixed ACBH to set cc's on result
- fixed POLYH to set R3 correctly
- fixed POLYH to not exit prematurely if arg = 0
- fixed POLYH to mask mul reslt to 127b
- fixed POLYH to mask mul result to 127b
- fixed fp add routine to test for zero via fraction
to support "denormal" argument from POLYH
- fixed EMODH to concatenate 15b of 16b extension
- fixed bug in reported VA on faulting cross-page write
V3.5 revision history
V3.5 revision history
patch date module(s) and fix(es)
@ -1326,7 +1326,7 @@ patch date module(s) and fix(es)
vax_io.c: revised autoconfiguration algorithm and interface
V3.4 revision history
V3.4 revision history
0 01-May-04 scp.c:
- fixed ASSERT code
@ -1364,7 +1364,7 @@ patch date module(s) and fix(es)
pdp11_tu.c: fixed error reporting
V3.3 revision history
V3.3 revision history
2 08-Mar-05 scp.c: added ASSERT command (Dave Bryan)
@ -1546,7 +1546,7 @@ patch date module(s) and fix(es)
- TMK is cleared by new motion command, not DCLR
- DONE is set on data transfers, ATA on non data transfers
pdp11_defs.h:
pdp11_defs.h:
- revised Unibus/Qbus DMA API's
- added CPU type and options flags
@ -1582,7 +1582,7 @@ patch date module(s) and fix(es)
vax_defs.h:
- added octaword, compatibility mode support
vax_moddefs.h:
vax_moddefs.h:
- revised Unibus/Qbus DMA API's
vax_cpu.c:
@ -1616,7 +1616,7 @@ patch date module(s) and fix(es)
- split from vax_sys.c
- removed PTR, PTP
V3.2 revision history
V3.2 revision history
3 03-Sep-04 scp.c:
- added ECHO command (Dave Bryan)
@ -1701,7 +1701,7 @@ patch date module(s) and fix(es)
- revised SR values to preserve SR<5:3>
hp2100_lps.c, hp2100_lpt.c: fixed timing
hp2100_dp.c: fixed interpretation of SR<0>
hp2100_dr.c: revised boot code to use IBL algorithm
@ -1868,7 +1868,7 @@ patch date module(s) and fix(es)
pdp1_drm.c:
- added parallel drum support
- fixed bug in serial drum instructin decoding
- fixed bug in serial drum instruction decoding
pdp1_sys.c: added parallel drum support, mnemonics
@ -1893,7 +1893,7 @@ patch date module(s) and fix(es)
pdp11_xq.c (Dave Hittner, Mark Pizzolato):
- fixed second controller interrupts
- fixed bugs in multicast and promiscuous setup
pdp18b_cpu.c:
- added instruction history
- fixed PDP-4,-7,-9 autoincrement bug
@ -1928,7 +1928,7 @@ patch date module(s) and fix(es)
- revised instruction decoding
- added instruction history
V3.0 revision history
V3.0 revision history
2 15-Sep-03 scp.c:
- fixed end-of-file problem in dep, idep
@ -1940,7 +1940,7 @@ patch date module(s) and fix(es)
- added address switch functionality to PTR BOOT
pdp1_sys.c: added multibank capability to LOAD
pdp18b_cpu.c:
- fixed priorities in PDP-15 API (PI between 3 and 4)
- fixed sign handling in PDP-15 unsigned mul/div
@ -2429,7 +2429,7 @@ patch date module(s) and fix(es)
pdp11_cpu.c: fixed bugs (John Dundas)
- added special case for PS<15:12> = 1111 to MFPI
- removed special case from MTPI
- added masking of relocation adds
- added masking of relocation adds
i1401_cpu.c:
- added multiply/divide
@ -2446,7 +2446,7 @@ patch date module(s) and fix(es)
- changed LOG/NOLOG to SET LOG/NOLOG
- added SHOW LOG
- added SET VT/NOVT and SHOW VT for VT emulation
sim_sock.h: changed VMS stropt.h include to ioctl.h
vax_cpu.c
@ -2455,12 +2455,12 @@ patch date module(s) and fix(es)
- fixed register logging in autoincrement indexed
vax_stddev.c: added TODR powerup routine
vax_cpu1.c: fixed exception flows to clear trap request
7 30-Apr-02 scp.c: fixed bug in clock calibration when (real) clock
jumps forward due too far (Jonathan Engdahl)
pdp11_cpu.c: fixed bugs, added features (John Dundas
and Wolfgang Helbig)
- added HTRAP and BPOK to maintenance register
@ -2469,7 +2469,7 @@ patch date module(s) and fix(es)
- fixed RTS SP, don't increment restored SP
- fixed TSTSET, write dst | 1 rather than prev R0 | 1
- fixed DIV, set N=0,Z=1 on div by zero (J11, 11/70)
- fixed DIV, set set N=Z=0 on overfow (J11, 11/70)
- fixed DIV, set set N=Z=0 on overflow (J11, 11/70)
- fixed ASH, ASHC, count = -32 used implementation-
dependent 32 bit right shift
- fixed illegal instruction test to detect 000010
@ -2600,7 +2600,7 @@ patch date module(s) and fix(es)
- cleaned up volatile state for GNU C longjmp
pdp11_cpu.c: cleaned up declarations
pdp11_rq.c: added RA-class disks
4 17-Dec-01 pdp11_rq.c: added delayed processing of packets

View file

@ -71,7 +71,7 @@
#define KEY_ILLREQ 5 /* illegal request */
#define KEY_PROT 7 /* data protect */
#define KEY_BLANK 8 /* blank check */
#define KEY_M_ILI 0x20 /* incorrent length indicator */
#define KEY_M_ILI 0x20 /* incorrect length indicator */
/* Additional sense codes */
@ -380,7 +380,7 @@ scsi_debug_cmd (bus, "Test Unit Ready\n");
if (uptr->flags & UNIT_ATT) /* attached? */
scsi_status (bus, STS_OK, KEY_OK, ASC_OK); /* unit is ready */
else
else
scsi_status (bus, STS_CHK, KEY_NOTRDY, ASC_NOMEDIA); /* no media present */
}
@ -428,11 +428,11 @@ else {
}
#endif
if (dev->removeable)
bus->buf[bus->buf_b++] = 0x80; /* removeable */
bus->buf[bus->buf_b++] = 0x80; /* removable */
else
bus->buf[bus->buf_b++] = 0; /* fixed */
bus->buf[bus->buf_b++] = dev->scsiver; /* versions */
bus->buf[bus->buf_b++] = dev->scsiver; /* respose data format */
bus->buf[bus->buf_b++] = dev->scsiver; /* response data format */
bus->buf[bus->buf_b++] = 31; /* additional length */
bus->buf[bus->buf_b++] = 0; /* reserved */
bus->buf[bus->buf_b++] = 0; /* reserved */
@ -639,7 +639,7 @@ if ((pc == 0x4) || (pc == 0x3F)) {
bus->buf[bus->buf_b++] = 0x4; /* landing zone cyl (15:8) */
bus->buf[bus->buf_b++] = 0; /* landing zone cyl (7:0) */
bus->buf[bus->buf_b++] = 0; /* reserved, RPL */
bus->buf[bus->buf_b++] = 0; /* rotational offet */
bus->buf[bus->buf_b++] = 0; /* rotational offset */
bus->buf[bus->buf_b++] = 0; /* reserved */
bus->buf[bus->buf_b++] = 0x1C; /* medium rotation rate (15:8) */
bus->buf[bus->buf_b++] = 0x20; /* medium rotation rate (7:0) */
@ -1189,7 +1189,7 @@ for (i = 0; i < sects; i++) {
r = sim_tape_wrtmk (uptr);
if (r != MTSE_OK) break;
}
scsi_tape_status (bus, r);
bus->buf[bus->buf_b++] = bus->status; /* status code */
scsi_set_phase (bus, SCSI_STS); /* status phase next */
@ -1782,7 +1782,7 @@ t_stat scsi_attach (UNIT *uptr, CONST char *cptr)
return scsi_attach_ex (uptr, cptr, NULL);
}
/* Dettach device */
/* Detach device */
t_stat scsi_detach (UNIT *uptr)
{

View file

@ -74,12 +74,12 @@
sim_control_serial (SERHANDLE port, int32 bits_to_set, int32 bits_to_clear, int32 *incoming_bits)
-------------------------------------------------------------------------------------------------
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
DSR and CTS are returned.
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
specified, then the return status is SCPE_ARG;
If an error occurs, SCPE_IOERR is returned.
@ -233,8 +233,8 @@ static int sim_serial_devices (int max, SERIAL_LIST *list)
{
int i, j, ports = sim_serial_os_devices(max, list);
/* Open ports may not show up in the list returned by sim_serial_os_devices
so we add the open ports to the list removing duplicates before sorting
/* Open ports may not show up in the list returned by sim_serial_os_devices
so we add the open ports to the list removing duplicates before sorting
the resulting list */
for (i=0; i<serial_open_device_count; ++i) {
@ -500,9 +500,9 @@ return r;
/* Enumerate the available serial ports.
The serial port names are extracted from the appropriate place in the
The serial port names are extracted from the appropriate place in the
windows registry (HKLM\HARDWARE\DEVICEMAP\SERIALCOMM\). The resulting
list is sorted alphabetically by device name (COMn). The device description
list is sorted alphabetically by device name (COMn). The device description
is set to the OS internal name for the COM device.
*/
@ -536,7 +536,7 @@ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_
else
break;
}
/* Besure to clear the working entry before trying again */
/* Be sure to clear the working entry before trying again */
memset(list[ports].name, 0, sizeof(list[ports].name));
memset(list[ports].desc, 0, sizeof(list[ports].desc));
dwValueNameSize = sizeof(list[ports].desc);
@ -775,12 +775,12 @@ return SCPE_OK; /* return success status
/* Control a serial port.
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
DSR and CTS are returned.
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
specified, then the return status is SCPE_ARG;
If an error occurs, SCPE_IOERR is returned.
*/
@ -939,8 +939,8 @@ struct SERPORT {
The serial port names generated by attempting to open /dev/ttyS0 thru
/dev/ttyS63 and /dev/ttyUSB0 thru /dev/ttyUSB63 and /dev/tty.serial0
thru /dev/tty.serial63. Ones we can open and are ttys (as determined
by isatty()) are added to the list. The list is sorted alphabetically
thru /dev/tty.serial63. Ones we can open and are ttys (as determined
by isatty()) are added to the list. The list is sorted alphabetically
by device name.
*/
@ -1002,7 +1002,7 @@ for (i=0; (ports < max) && (i < 64); ++i) {
static char *serial_unix_serial_names[] = { "S", "U", "USB", ".serial", ".usbserial", NULL};
char **sp;
for (sp = serial_unix_serial_names; *sp; sp++) {
for (sp = serial_unix_serial_names; *sp; sp++) {
for (i=0; (ports < max) && (i <= 64); ++i) {
if (i < 64)
snprintf (list[ports].name, sizeof (list[ports].name), "/dev/tty%s%d", *sp, i);
@ -1224,12 +1224,12 @@ return SCPE_OK; /* configuration set suc
/* Control a serial port.
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
DSR and CTS are returned.
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
specified, then the return status is SCPE_ARG;
If an error occurs, SCPE_IOERR is returned.
*/
@ -1432,7 +1432,7 @@ struct SERPORT {
The serial port names generated by attempting to open /dev/ttyS0 thru
/dev/ttyS53 and /dev/ttyUSB0 thru /dev/ttyUSB0. Ones we can open and
are ttys (as determined by isatty()) are added to the list. The list
are ttys (as determined by isatty()) are added to the list. The list
is sorted alphabetically by device name.
*/
@ -1539,10 +1539,10 @@ SERHANDLE port;
devnam.dsc$w_length = strlen (devnam.dsc$a_pointer);
status = sys$assign (&devnam, &chan, 0, 0);
if (status != SS$_NORMAL)
if (status != SS$_NORMAL)
return INVALID_HANDLE;
status = sys$getdviw (0, chan, NULL, items, &iosb, NULL, 0, NULL);
if ((status != SS$_NORMAL) ||
if ((status != SS$_NORMAL) ||
(iosb.status != SS$_NORMAL) ||
(devclass != DC$_TERM)) {
sys$dassgn (chan);
@ -1671,12 +1671,12 @@ return SCPE_OK; /* configuration set suc
/* Control a serial port.
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
The DTR and RTS line of the serial port is set or cleared as indicated in
the respective bits_to_set or bits_to_clear parameters. If the
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
DSR and CTS are returned.
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
If unreasonable or nonsense bits_to_set or bits_to_clear bits are
specified, then the return status is SCPE_ARG;
If an error occurs, SCPE_IOERR is returned.
*/
@ -1770,7 +1770,7 @@ if (status != SS$_NORMAL) {
}
if (sense.sense_count == 0) /* no characters available? */
return 0; /* return 0 to indicate */
status = sys$qiow (0, port->port, IO$_READLBLK | IO$M_NOECHO | IO$M_NOFILTR | IO$M_TIMED | IO$M_TRMNOECHO,
status = sys$qiow (0, port->port, IO$_READLBLK | IO$M_NOECHO | IO$M_NOFILTR | IO$M_TIMED | IO$M_TRMNOECHO,
&iosb, 0, 0, buffer, (count < sense.sense_count) ? count : sense.sense_count, 0, term, 0, 0);
if (status == SS$_NORMAL)
status = iosb.status;

View file

@ -23,10 +23,10 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
15-Oct-12 MP Added definitions needed to detect possible tcp
15-Oct-12 MP Added definitions needed to detect possible tcp
connect failures
25-Sep-12 MP Reworked for RFC3493 interfaces supporting IPv6 and IPv4
04-Jun-08 RMS Addes sim_create_sock, for IBM 1130
04-Jun-08 RMS Added sim_create_sock, for IBM 1130
14-Apr-05 RMS Added WSAEINPROGRESS (from Tim Riker)
20-Aug-04 HV Added missing definition for OS/2 (from Holger Veit)
22-Oct-03 MP Changed WIN32 winsock include to use winsock2.h to
@ -69,7 +69,7 @@ extern "C" {
#define WSAGetLastError() errno /* Windows macros */
#define WSASetLastError(err) errno = err
#define closesocket close
#define closesocket close
#define SOCKET int
#if defined(__hpux)
#define WSAEWOULDBLOCK EAGAIN
@ -111,10 +111,10 @@ extern "C" {
#define sim_printf printf
#endif
int sim_parse_addr (const char *cptr, char *host, size_t hostlen, const char *default_host,
char *port, size_t port_len, const char *default_port,
int sim_parse_addr (const char *cptr, char *host, size_t hostlen, const char *default_host,
char *port, size_t port_len, const char *default_port,
const char *validate_addr);
int sim_parse_addr_ex (const char *cptr, char *host, size_t hostlen, const char *default_host,
int sim_parse_addr_ex (const char *cptr, char *host, size_t hostlen, const char *default_host,
char *port, size_t port_len, char *localport, size_t local_port_len, const char *default_port);
int sim_addr_acl_check (const char *validate_addr, const char *acl);
#define SIM_SOCK_OPT_REUSEADDR 0x0001

View file

@ -35,8 +35,8 @@
sim_tape_sprecsr - skip records rev
sim_tape_spfiler - skip files rev
sim_tape_position - general purpose position
These routines correspond to natural tape operations
and will align better when physical tape support is
These routines correspond to natural tape operations
and will align better when physical tape support is
included here.
08-Jun-08 JDB Fixed signed/unsigned warning in sim_tape_set_fmt
23-Jan-07 JDB Fixed backspace over gap at BOT
@ -71,7 +71,7 @@
sim_tape_errecf erase record forward
sim_tape_errecr erase record reverse
sim_tape_sprecsf space records forward
sim_tape_spfilef space files forward
sim_tape_spfilef space files forward
sim_tape_sprecsr space records reverse
sim_tape_spfiler space files reverse
sim_tape_position generalized position
@ -229,8 +229,8 @@ _tape_io(void *arg)
UNIT* volatile uptr = (UNIT*)arg;
struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which in general won't be readily yielding the processor when
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which in general won't be readily yielding the processor when
this thread needs to run */
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
@ -308,14 +308,14 @@ struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
return NULL;
}
/* This routine is called in the context of the main simulator thread before
processing events for any unit. It is only called when an asynchronous
thread has called sim_activate() to activate a unit. The job of this
/* This routine is called in the context of the main simulator thread before
processing events for any unit. It is only called when an asynchronous
thread has called sim_activate() to activate a unit. The job of this
routine is to put the unit in proper condition to digest what may have
occurred in the asynchronous thread.
Since tape processing only handles a single I/O at a time to a
particular tape device, we have the opportunity to possibly detect
Since tape processing only handles a single I/O at a time to a
particular tape device, we have the opportunity to possibly detect
improper attempts to issue multiple concurrent I/O requests. */
static void _tape_completion_dispatch (UNIT *uptr)
{
@ -453,30 +453,30 @@ typedef struct MEMORY_TAPE {
VOL1 vol1;
} MEMORY_TAPE;
const char HDR3_RMS_STREAM[] = "HDR3020002040000"
"0000000100000000"
"0000000002000000"
"0000000000000000"
const char HDR3_RMS_STREAM[] = "HDR3020002040000"
"0000000100000000"
"0000000002000000"
"0000000000000000"
"0000 ";
const char HDR3_RMS_STMLF[] = "HDR3020002050000"
"0000000100000000"
"0000000002000000"
"0000000000000000"
const char HDR3_RMS_STMLF[] = "HDR3020002050000"
"0000000100000000"
"0000000002000000"
"0000000000000000"
"0000 ";
const char HDR3_RMS_FIXED[] = "HDR3020000010000"
"0000000100000000"
"0000000002000000"
"0000000000000000"
const char HDR3_RMS_FIXED[] = "HDR3020000010000"
"0000000100000000"
"0000000002000000"
"0000000000000000"
"0000 ";
const char HDR3_RMS_VARRSX[] = "HDR300000A020000"
"0000000100000000"
"0000000000000000"
"0000000000000000"
const char HDR3_RMS_VARRSX[] = "HDR300000A020000"
"0000000100000000"
"0000000000000000"
"0000000000000000"
"0000 ";
const char HDR3_RMS_FIXRSX[] = "HDR3020008010000"
"0000000100000000"
"0000000000000000"
"0000000000000000"
const char HDR3_RMS_FIXRSX[] = "HDR3020008010000"
"0000000100000000"
"0000000000000000"
"0000000000000000"
"0000 ";
static struct ansi_tape_parameters {
@ -508,7 +508,7 @@ static struct ansi_tape_parameters {
static MEMORY_TAPE *ansi_create_tape (const char *label, size_t block_size, uint32 ansi_type);
static MEMORY_TAPE *memory_create_tape (void);
static void memory_free_tape (void *vtape);
static void sim_tape_add_ansi_entry (const char *directory,
static void sim_tape_add_ansi_entry (const char *directory,
const char *filename,
t_offset FileSize,
const struct stat *filestat,
@ -596,7 +596,7 @@ return SCPE_OK;
#endif
}
/*
/*
This routine is called when the simulator stops and any time
the asynch mode is changed (enabled or disabled)
*/
@ -781,7 +781,7 @@ switch (MT_GET_FMT (uptr)) {
if (uptr->recsize == 0)
uptr->recsize = 512;
if ((statb.st_size % uptr->recsize) != 0) {
r = sim_messagef (SCPE_ARG, "Binary file data is not a multiple of the specifyed record size (%d)\n", (int)uptr->recsize);
r = sim_messagef (SCPE_ARG, "Binary file data is not a multiple of the specified record size (%d)\n", (int)uptr->recsize);
fclose (f);
break;
}
@ -810,11 +810,11 @@ switch (MT_GET_FMT (uptr)) {
tape->block_size = uptr->recsize;
block = (uint8 *)calloc (1, tape->block_size + 3);
while (!feof (f) && !error) {
/* fgest() read size is int, cast accordingly. */
/* fgets() read size is int, cast accordingly. */
if (fgets ((char *)block, (int) (tape->block_size + 3), f)) {
size_t len = strlen ((char *)block);
while ((len > 0) &&
while ((len > 0) &&
((block[len - 1] == '\r') || (block[len - 1] == '\n')))
--len;
memset (block + len, ' ', tape->block_size - len);
@ -891,7 +891,7 @@ switch (MT_GET_FMT (uptr)) {
if (uptr->recsize == 0)
uptr->recsize = TAR_DFLT_RECSIZE; /* Apply default block size */
if ((uptr->recsize % 512) != 0)
return sim_messagef (SCPE_ARG, "TAR format block size of %" SIZE_T_FMT "u is not a multiple of 512\n", uptr->recsize);
return sim_messagef (SCPE_ARG, "TAR format block size of %" SIZE_T_FMT "u is not a multiple of 512\n", uptr->recsize);
sim_switches |= SWMASK ('E'); /* The TAR file must exist */
/* fall through */
default:
@ -1083,7 +1083,7 @@ fprintf (st, " accessible directly as files on the tape.\n\n");
fprintf (st, " FIXED format will present the contents of a file (text or binary) as\n");
fprintf (st, " fixed sized records/blocks with ascii text data optionally converted\n");
fprintf (st, " to EBCDIC.\n\n");
fprintf (st, " DOS11 format will present the contents of a file preceeded by a DOS11\n");
fprintf (st, " DOS11 format will present the contents of a file preceded by a DOS11\n");
fprintf (st, " 14-byte header. All files will be owned by [1,1], have a default\n");
fprintf (st, " protection of <233> and a date in the range 1972 - 1999 with the\n");
fprintf (st, " month/day layout as the current year. The file name on the tape\n");
@ -1239,7 +1239,7 @@ MT_CLR_PNU (uptr); /* clear the position-no
if ((uptr->flags & UNIT_ATT) == 0) /* if the unit is not attached */
return MTSE_UNATT; /* then quit with an error */
if ((uptr->tape_eom > 0) &&
if ((uptr->tape_eom > 0) &&
(uptr->pos >= uptr->tape_eom)) {
MT_SET_PNU (uptr); /* then set position not updated */
return MTSE_EOM; /* and quit with I/O error status */
@ -1402,7 +1402,7 @@ switch (f) { /* otherwise the read method
}
else {
if ((feof (uptr->fileref)) || /* eof? */
((tpcbc == TPC_EOM) &&
((tpcbc == TPC_EOM) &&
(sim_fsize (uptr->fileref) == (uint32)sim_ftell (uptr->fileref)))) {
MT_SET_PNU (uptr); /* pos not upd */
status = MTSE_EOM;
@ -1483,7 +1483,7 @@ switch (f) { /* otherwise the read method
saved_pos = (t_addr)sim_ftell (uptr->fileref);/* save record data address */
(void)sim_tape_seek (uptr, uptr->pos); /* for read */
rdcnt = sim_fread (&awshdr, sizeof (t_awslnt), 3, uptr->fileref);
if ((rdcnt == 3) &&
if ((rdcnt == 3) &&
((awshdr.prelen != *bc) || ((awshdr.rectyp != AWS_REC) && (awshdr.rectyp != AWS_TMK)))) {
status = MTSE_INVRL;
uptr->tape_eom = uptr->pos;
@ -1499,7 +1499,7 @@ switch (f) { /* otherwise the read method
*bc = (t_mtrlnt)uptr->recsize; /* TAR record size */
else
*bc = (t_mtrlnt)(uptr->hwmark - uptr->pos); /* TAR remnant last record */
(void)sim_tape_seek (uptr, uptr->pos);
(void)sim_tape_seek (uptr, uptr->pos);
uptr->pos += *bc;
MT_CLR_INMRK (uptr);
}
@ -1798,8 +1798,8 @@ switch (f) { /* otherwise the read me
status = MTSE_EOM;
break;
}
if ((rdcnt != 3) ||
((awshdr.rectyp != AWS_REC) &&
if ((rdcnt != 3) ||
((awshdr.rectyp != AWS_REC) &&
(awshdr.rectyp != AWS_TMK))) {
status = MTSE_INVRL;
}
@ -1810,8 +1810,8 @@ switch (f) { /* otherwise the read me
if (awshdr.prelen == 0)
status = MTSE_TMK;
else {
if ((uptr->tape_eom > 0) &&
(uptr->pos >= uptr->tape_eom) &&
if ((uptr->tape_eom > 0) &&
(uptr->pos >= uptr->tape_eom) &&
(awshdr.rectyp == AWS_TMK)) {
status = MTSE_TMK;
*bc = 0; /* save rec lnt */
@ -1847,7 +1847,7 @@ switch (f) { /* otherwise the read me
*bc = (t_mtrlnt)uptr->recsize;
if (*bc) {
uptr->pos -= *bc;
(void)sim_tape_seek (uptr, uptr->pos);
(void)sim_tape_seek (uptr, uptr->pos);
}
break;
@ -2139,7 +2139,7 @@ if (ferror (uptr->fileref)) { /* error? */
MT_SET_PNU (uptr); /* pos not upd */
return sim_tape_ioerr (uptr);
}
if ((!sim_tape_bot (uptr)) &&
if ((!sim_tape_bot (uptr)) &&
(((feof (uptr->fileref)) && (rdcnt < 3)) || /* eof? */
((awshdr.rectyp != AWS_REC) && (awshdr.rectyp != AWS_TMK)))) {
MT_SET_PNU (uptr); /* pos not upd */
@ -2870,7 +2870,7 @@ if (ctx == NULL) /* if not properly attac
return sim_messagef (SCPE_IERR, "Bad Attach\n"); /* that's a problem */
sim_debug_unit (ctx->dbit, uptr, "sim_tape_sprecsf(unit=%d, count=%d)\n", (int)(uptr-ctx->dptr->units), count);
while (*skipped < count) { /* loopo */
while (*skipped < count) { /* loop */
st = sim_tape_sprecf (uptr, &tbc); /* spc rec */
if (st != MTSE_OK)
return st;
@ -2967,7 +2967,7 @@ if (ctx == NULL) /* if not properly attac
return sim_messagef (SCPE_IERR, "Bad Attach\n"); /* that's a problem */
sim_debug_unit (ctx->dbit, uptr, "sim_tape_sprecsr(unit=%d, count=%d)\n", (int)(uptr-ctx->dptr->units), count);
while (*skipped < count) { /* loopo */
while (*skipped < count) { /* loop */
st = sim_tape_sprecr (uptr, &tbc); /* spc rec rev */
if (st != MTSE_OK)
return st;
@ -3028,7 +3028,7 @@ if (check_leot) {
}
*skipped = 0;
*recsskipped = 0;
while (*skipped < count) { /* loopo */
while (*skipped < count) { /* loop */
while (1) {
st = sim_tape_sprecsf (uptr, 0x1ffffff, &filerecsskipped);/* spc recs */
*recsskipped += filerecsskipped;
@ -3134,7 +3134,7 @@ if (ctx == NULL) /* if not properly attac
return sim_messagef (SCPE_IERR, "Bad Attach\n"); /* that's a problem */
sim_debug_unit (ctx->dbit, uptr, "sim_tape_spfilebyrecr(unit=%d, count=%d)\n", (int)(uptr-ctx->dptr->units), count);
while (*skipped < count) { /* loopo */
while (*skipped < count) { /* loop */
while (1) {
st = sim_tape_sprecsr (uptr, 0x1ffffff, &filerecsskipped);/* spc recs rev */
*recsskipped += filerecsskipped;
@ -3250,7 +3250,7 @@ if (flags & MTPOS_M_OBJ) {
uint32 skipped;
uint32 objsremaining = objs;
while (*objectsskipped < objs) { /* loopo */
while (*objectsskipped < objs) { /* loop */
if (flags & MTPOS_M_REV) /* reverse? */
r = sim_tape_sprecsr (uptr, objsremaining, &skipped);
else
@ -3445,18 +3445,18 @@ for (i=0; i<65535; i++) {
sim_debug_unit (MTSE_DBG_STR, uptr, "tpc_map: summary - %u %d byte record%s\n", countmap[i], (int)i, (countmap[i] > 1) ? "s" : "");
}
}
if (((last_bc != TPC_EOM) &&
if (((last_bc != TPC_EOM) &&
(tpos > tape_size) &&
(!had_double_tape_mark)) ||
(!had_double_tape_mark) ||
((objc == countmap[0]) &&
((objc == countmap[0]) &&
(countmap[0] != 2))) { /* Unreasonable format? */
if (last_bc != TPC_EOM)
sim_debug_unit (MTSE_DBG_STR, uptr, "tpc_map: ERROR unexpected EOT byte count: %d\n", last_bc);
if (tpos > tape_size)
sim_debug_unit (MTSE_DBG_STR, uptr, "tpc_map: ERROR next record position %" T_ADDR_FMT "u beyond EOT: %" T_ADDR_FMT "u\n", tpos, tape_size);
if (objc == countmap[0])
sim_debug_unit (MTSE_DBG_STR, uptr, "tpc_map: ERROR tape cnly contains tape marks\n");
sim_debug_unit (MTSE_DBG_STR, uptr, "tpc_map: ERROR tape only contains tape marks\n");
free (countmap);
free (recbuf);
return 0;
@ -3582,7 +3582,7 @@ while (r == SCPE_OK) {
break;
}
if (0 != memcmp (buf_f, buf_r, bc_f)) {
sim_printf ("%d byte record contents differ when read forward amd backwards start from position %" T_ADDR_FMT "u\n", bc_f, pos_f);
sim_printf ("%d byte record contents differ when read forward and backwards start from position %" T_ADDR_FMT "u\n", bc_f, pos_f);
r = MTSE_RECE;
break;
}
@ -3817,11 +3817,11 @@ return SCPE_OK;
/* list supported densities
translates the mask of supported densities to a string list in the form:
translates the mask of supported densities to a string list in the form:
"(800|1600|6250)"
this string may be useful to construct a MTAB help string for a
this string may be useful to construct a MTAB help string for a
SET <unit> DENSITY= command.
*/
@ -4076,7 +4076,7 @@ tpclnt = 0xffff;
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fE11);
(void)sim_fwrite (&tpclnt, sizeof (tpclnt), 1, fTPC);
(void)sim_fwrite (buf, 1, 1, fP7B);
/* Write an unmatched record delimiter (aka garbage) at
/* Write an unmatched record delimiter (aka garbage) at
the end of the SIMH, E11 and AWS files */
mtrlnt = 25;
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fSIMH);
@ -4220,23 +4220,23 @@ if ((SCPE_ARG != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bi
(strcmp (buf, "")))
return stat;
valid_bits = MT_556_VALID;
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
(strcmp (buf, "556")))
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
valid_bits = MT_800_VALID | MT_1600_VALID;
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
(strcmp (buf, "{800|1600}")))
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
valid_bits = MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
(strcmp (buf, "{800|1600|6250}")))
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
valid_bits = MT_200_VALID | MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
(strcmp (buf, "{200|800|1600|6250}")))
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
valid_bits = MT_NONE_VALID | MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
(strcmp (buf, "{0|800|1600|6250}")))
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
return SCPE_OK;
@ -4299,7 +4299,7 @@ for (t = classify_tests; t->testname != NULL; t++) {
tape_classify_file_contents (f, &mrs, &lf_lines, &crlf_lines);
fclose (f);
if ((mrs != t->expected_mrs) || (lf_lines != t->expected_lf_lines) || (crlf_lines != t->expected_crlf_lines))
return sim_messagef (SCPE_ARG, "%s was unexpectedly reported to having MRS=%d, lf_lines=%s, crlf_lines=%s\n",
return sim_messagef (SCPE_ARG, "%s was unexpectedly reported to having MRS=%d, lf_lines=%s, crlf_lines=%s\n",
t->testname, (int)mrs, lf_lines ? "true" : "false", crlf_lines ? "true" : "false");
if (t->success_attach_args) {
char args[CBUFSIZE*2];
@ -4414,17 +4414,17 @@ static void ansi_date (time_t datetime, char date[6], t_bool y2k_date_bug)
lt = localtime (&datetime);
if (y2k_date_bug)
sprintf (buf, " %c%c%03d", '0' + (lt->tm_year / 10),
'0' + (lt->tm_year % 10),
sprintf (buf, " %c%c%03d", '0' + (lt->tm_year / 10),
'0' + (lt->tm_year % 10),
lt->tm_yday + 1);
else
sprintf (buf, "%c%02d%03d", (lt->tm_year < 100) ? ' ' : '0' + (lt->tm_year/100 - 1),
lt->tm_year % 100,
sprintf (buf, "%c%02d%03d", (lt->tm_year < 100) ? ' ' : '0' + (lt->tm_year/100 - 1),
lt->tm_year % 100,
lt->tm_yday + 1);
memcpy (date, buf, 6);
}
/*
/*
* This isn't quite ANSI 'a' since several ANSI allowed characters
* are either illegal file names on many DEC systems or are confusing
* to OS file name parsers.
@ -4479,7 +4479,7 @@ static void ansi_make_HDR1 (HDR1 *hdr1, VOL1 *vol, HDR4 *hdr4, const char *filen
fn = fn_cpy;
ext = strrchr (fn_cpy, '.');
if (ext) {
while (((c = strchr (fn_cpy, '.')) != NULL) &&
while (((c = strchr (fn_cpy, '.')) != NULL) &&
(c != ext))
*c = '_'; /* translate extra .'s to _ */
}
@ -4565,7 +4565,7 @@ static void ansi_fill_text_buffer (FILE *f, char *buf, size_t buf_size, size_t r
move_size = rec_size;
else
move_size = buf_size - offset;
/* We've got a line that stradles a block boundary */
/* We've got a line that straddles a block boundary */
memcpy (buf + offset, tmp, move_size);
offset += move_size;
if (offset == buf_size) {
@ -4798,7 +4798,7 @@ else {
if (data_read > 0)
error = memory_tape_add_block (tape, block, data_read);
}
}
}
fclose (f);
free (block);
@ -4953,7 +4953,7 @@ else { /* Text file */
1 - ansi->skip_lf_line_endings);
/* max_record_size must fit in the 4-character ANSI RCW */
if (max_record_size > 9999) {
size_t max_allowed = 9999 - 4 -
size_t max_allowed = 9999 - 4 -
(crlf_line_endings ? 2 - ansi->skip_crlf_line_endings :
1 - ansi->skip_lf_line_endings);
sim_messagef (SCPE_ARG, "Text file: %s has lines longer (%d) than %s format allows (%d)\n",
@ -5002,15 +5002,15 @@ while (!feof (f) && !error) {
size_t data_read = tape->block_size;
if (lf_line_endings || crlf_line_endings) /* Text file? */
ansi_fill_text_buffer (f, (char *)block, tape->block_size,
crlf_line_endings ? ansi->skip_crlf_line_endings : ansi->skip_lf_line_endings,
ansi_fill_text_buffer (f, (char *)block, tape->block_size,
crlf_line_endings ? ansi->skip_crlf_line_endings : ansi->skip_lf_line_endings,
ansi->fixed_text);
else { /* Binary file */
size_t runt = 0;
data_read = fread (block, 1, tape->block_size, f);
if (max_record_size > 0) /* always will be true but XCode thinks otherwise */
if (max_record_size > 0) /* always will be true but Xcode thinks otherwise */
runt = data_read % max_record_size; /* data_read (=0) % anypositivenumber == 0 */
/* Pad short records with zeros */
if (runt > 0) {
@ -5049,7 +5049,7 @@ if (sim_switches & SWMASK ('V'))
return error;
}
static void sim_tape_add_ansi_entry (const char *directory,
static void sim_tape_add_ansi_entry (const char *directory,
const char *filename,
t_offset FileSize,
const struct stat *filestat,

View file

@ -32,23 +32,23 @@
- Sleep for the observed clock tick size while throttling
- Recompute the throttling wait once every 10 seconds
to account for varying instruction mixes during
different phases of a simulator execution or to
accommodate the presence of other load on the host
different phases of a simulator execution or to
accommodate the presence of other load on the host
system.
- Each of the pre-existing throttling modes (Kcps,
Mcps, and %) all compute the appropriate throttling
- Each of the pre-existing throttling modes (Kcps,
Mcps, and %) all compute the appropriate throttling
interval dynamically. These dynamic computations
assume that 100% of the host CPU is dedicated to
assume that 100% of the host CPU is dedicated to
the current simulator during this computation.
This assumption may not always be true and under
certain conditions may never provide a way to
correctly determine the appropriate throttling
This assumption may not always be true and under
certain conditions may never provide a way to
correctly determine the appropriate throttling
wait. An additional throttling mode has been added
which allows the simulator operator to explicitly
state the desired throttling wait parameters.
These are specified by:
These are specified by:
SET THROT insts/delay
where 'insts' is the number of instructions to
where 'insts' is the number of instructions to
execute before sleeping for 'delay' milliseconds.
22-Apr-11 MP Fixed Asynch I/O support to reasonably account cycles
when an idle wait is terminated by an external event
@ -286,8 +286,8 @@ return sim_os_sleep_min_ms;
#if defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1)
#define sim_idle_ms_sleep real_sim_idle_ms_sleep
#define sim_os_msec real_sim_os_msec
#define sim_idle_ms_sleep real_sim_idle_ms_sleep
#define sim_os_msec real_sim_os_msec
#define sim_os_ms_sleep real_sim_os_ms_sleep
#endif /* defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1) */
@ -783,7 +783,7 @@ return sim_rtcn_init_unit_ticks (uptr, time, tmr, 0);
int32 sim_rtcn_init_unit_ticks (UNIT *uptr, int32 time, int32 tmr, int32 ticksper)
{
RTC *rtc;
if (time == 0)
time = 1;
if (tmr == SIM_INTERNAL_CLK)
@ -864,8 +864,8 @@ if (rtc->hz != ticksper) { /* changing tick rate? */
if (rtc->hz == 0)
rtc->clock_tick_start_time = sim_timenow_double ();
if ((rtc->last_hz != 0) &&
(rtc->last_hz != ticksper) &&
if ((rtc->last_hz != 0) &&
(rtc->last_hz != ticksper) &&
(ticksper != 0))
rtc->currd = (int32)(sim_timer_inst_per_sec () / ticksper);
rtc->last_hz = rtc->hz;
@ -912,9 +912,9 @@ if (sim_calb_tmr != tmr) {
return rtc->currd;
}
new_rtime = sim_os_msec (); /* wall time */
if (!sim_signaled_int_char &&
if (!sim_signaled_int_char &&
((new_rtime - sim_last_poll_kbd_time) > 500)) {
sim_debug (DBG_CAL, &sim_timer_dev, "sim_rtcn_calb(tmr=%d) gratuitious keyboard poll after %d msecs\n", tmr, (int)(new_rtime - sim_last_poll_kbd_time));
sim_debug (DBG_CAL, &sim_timer_dev, "sim_rtcn_calb(tmr=%d) gratuitous keyboard poll after %d msecs\n", tmr, (int)(new_rtime - sim_last_poll_kbd_time));
(void)sim_poll_kbd ();
}
++rtc->calibrations; /* count calibrations */
@ -989,7 +989,7 @@ if (sim_asynch_timer || (catchup_ticks_curr > 0)) {
}
rtc->based = rtc->currd = new_currd;
rtc->gtime = new_gtime; /* save instruction time */
sim_debug (DBG_CAL, &sim_timer_dev, "sim_rtcn_calb(%s tmr=%d, tickper=%d) catchups=%u, idle=%d%% result: %d\n",
sim_debug (DBG_CAL, &sim_timer_dev, "sim_rtcn_calb(%s tmr=%d, tickper=%d) catchups=%u, idle=%d%% result: %d\n",
sim_asynch_timer ? "asynch" : "catchup", tmr, ticksper, catchup_ticks_curr, last_idle_pct, rtc->currd);
return rtc->currd; /* calibrated result */
}
@ -1016,7 +1016,7 @@ if (rtc->based <= 0) /* never negative or zero! *
rtc->based = 1;
if (rtc->currd <= 0) /* never negative or zero! */
rtc->currd = 1;
sim_debug (DBG_CAL, &sim_timer_dev, "sim_rtcn_calb(tmr=%d, tickper=%d) (delta_rtime=%d, delta_vtime=%d, base=%d, nxintv=%u, catchups=%u, idle=%d%%, result: %d)\n",
sim_debug (DBG_CAL, &sim_timer_dev, "sim_rtcn_calb(tmr=%d, tickper=%d) (delta_rtime=%d, delta_vtime=%d, base=%d, nxintv=%u, catchups=%u, idle=%d%%, result: %d)\n",
tmr, ticksper, (int)delta_rtime, (int)delta_vtime, rtc->based, rtc->nxintv, catchup_ticks_curr, last_idle_pct, rtc->currd);
/* Adjust calibration for other timers which depend on this timer's calibration */
for (itmr=0; itmr<=SIM_NTIMERS; itmr++) {
@ -1025,7 +1025,7 @@ for (itmr=0; itmr<=SIM_NTIMERS; itmr++) {
if ((itmr != tmr) && (irtc->hz != 0))
irtc->currd = (rtc->currd * ticksper) / irtc->hz;
}
AIO_SET_INTERRUPT_LATENCY(rtc->currd * ticksper); /* set interrrupt latency */
AIO_SET_INTERRUPT_LATENCY(rtc->currd * ticksper); /* set interrupt latency */
return rtc->currd;
}
@ -1077,7 +1077,7 @@ sim_stop_time = clock_last = clock_start = sim_os_msec ();
sim_os_clock_resoluton_ms = 1000;
do {
uint32 clock_diff;
clock_now = sim_os_msec ();
clock_diff = clock_now - clock_last;
if ((clock_diff > 0) && (clock_diff < sim_os_clock_resoluton_ms))
@ -1127,8 +1127,8 @@ if (sim_idle_enab) {
if (sim_throt_type != SIM_THROT_NONE) {
sim_show_throt (st, NULL, uptr, val, desc);
}
fprintf (st, "Calibrated Timer: %s\n", (calb_tmr == -1) ? "Undetermined" :
((calb_tmr == SIM_NTIMERS) ? "Internal Timer" :
fprintf (st, "Calibrated Timer: %s\n", (calb_tmr == -1) ? "Undetermined" :
((calb_tmr == SIM_NTIMERS) ? "Internal Timer" :
(rtcs[calb_tmr].clock_unit ? sim_uname(rtcs[calb_tmr].clock_unit) : "")));
if (calb_tmr == SIM_NTIMERS)
fprintf (st, "Catchup Ticks: %s\n", sim_catchup_ticks ? "Enabled" : "Disabled");
@ -1153,12 +1153,12 @@ for (tmr=clocks=0; tmr<=SIM_NTIMERS; ++tmr) {
if (0 == rtc->initd)
continue;
if (rtc->clock_unit) {
++clocks;
fprintf (st, "%s clock device is %s%s%s\n", sim_name,
(tmr == SIM_NTIMERS) ? "Internal Calibrated Timer(" : "",
sim_uname(rtc->clock_unit),
fprintf (st, "%s clock device is %s%s%s\n", sim_name,
(tmr == SIM_NTIMERS) ? "Internal Calibrated Timer(" : "",
sim_uname(rtc->clock_unit),
(tmr == SIM_NTIMERS) ? ")" : "");
}
@ -1478,30 +1478,30 @@ return "Throttle facility";
DEVICE sim_timer_dev = {
"INT-CLOCK", sim_timer_units, sim_timer_reg, sim_timer_mod,
SIM_NTIMERS+1, 0, 0, 0, 0, 0,
NULL, NULL, &sim_timer_clock_reset, NULL, NULL, NULL,
NULL, DEV_DEBUG | DEV_NOSAVE, 0,
"INT-CLOCK", sim_timer_units, sim_timer_reg, sim_timer_mod,
SIM_NTIMERS+1, 0, 0, 0, 0, 0,
NULL, NULL, &sim_timer_clock_reset, NULL, NULL, NULL,
NULL, DEV_DEBUG | DEV_NOSAVE, 0,
sim_timer_debug};
DEVICE sim_int_timer_dev = {
"INT-TIMER", &sim_internal_timer_unit, NULL, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
"INT-TIMER", &sim_internal_timer_unit, NULL, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, DEV_NOSAVE};
DEVICE sim_stop_dev = {
"INT-STOP", &sim_stop_unit, NULL, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, DEV_NOSAVE, 0,
"INT-STOP", &sim_stop_unit, NULL, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, DEV_NOSAVE, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
sim_int_stop_description};
DEVICE sim_throttle_dev = {
"INT-THROTTLE", &sim_throttle_unit, sim_throttle_reg, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, DEV_NOSAVE};
/* SET CLOCK command */
@ -1569,35 +1569,35 @@ if ((!sim_idle_enab) || /* idling disabled */
((sim_clock_queue != QUEUE_LIST_END) && /* or clock queue not empty */
((sim_clock_queue->flags & UNIT_IDLE) == 0))|| /* and event not idle-able? */
(rtc->elapsed < sim_idle_stable)) { /* or calibrated timer not stable? */
sim_debug (DBG_IDL, &sim_timer_dev, "Can't idle: %s - elapsed: %d and %d/%d\n", !sim_idle_enab ? "idle disabled" :
((rtc->elapsed < sim_idle_stable) ? "not stable" :
((sim_clock_queue != QUEUE_LIST_END) ? sim_uname (sim_clock_queue) :
sim_debug (DBG_IDL, &sim_timer_dev, "Can't idle: %s - elapsed: %d and %d/%d\n", !sim_idle_enab ? "idle disabled" :
((rtc->elapsed < sim_idle_stable) ? "not stable" :
((sim_clock_queue != QUEUE_LIST_END) ? sim_uname (sim_clock_queue) :
"")), rtc->elapsed, rtc->ticks, rtc->hz);
sim_interval -= sin_cyc;
return FALSE;
}
/*
When a simulator is in an instruction path (or under other conditions
which would indicate idling), the countdown of sim_interval may not
be happening at a pace which is consistent with the rate it happens
when not in the 'idle capable' state. The consequence of this is that
the clock calibration may produce calibrated results which vary much
more than they do when not in the idle able state. Sim_idle also uses
When a simulator is in an instruction path (or under other conditions
which would indicate idling), the countdown of sim_interval may not
be happening at a pace which is consistent with the rate it happens
when not in the 'idle capable' state. The consequence of this is that
the clock calibration may produce calibrated results which vary much
more than they do when not in the idle able state. Sim_idle also uses
the calibrated tick size to approximate an adjustment to sim_interval
to reflect the number of instructions which would have executed during
the actual idle time, so consistent calibrated numbers produce better
adjustments.
to reflect the number of instructions which would have executed during
the actual idle time, so consistent calibrated numbers produce better
adjustments.
To negate this effect, we accumulate the time actually idled here.
sim_rtcn_calb compares the accumulated idle time during the most recent
sim_rtcn_calb compares the accumulated idle time during the most recent
second and if it exceeds the percentage defined by sim_idle_calib_pct
calibration is suppressed. Thus recalibration only happens if things
calibration is suppressed. Thus recalibration only happens if things
didn't idle too much.
we also check check sim_idle_enab above so that all simulators can avoid
directly checking sim_idle_enab before calling sim_idle so that all of
the bookkeeping on sim_idle_idled is done here in sim_timer where it
means something, while not idling when it isn't enabled.
directly checking sim_idle_enab before calling sim_idle so that all of
the bookkeeping on sim_idle_idled is done here in sim_timer where it
means something, while not idling when it isn't enabled.
*/
sim_debug (DBG_TRC, &sim_timer_dev, "sim_idle(tmr=%d, sin_cyc=%d)\n", tmr, sin_cyc);
if (sim_idle_cyc_ms == 0) {
@ -1641,7 +1641,7 @@ act_cyc = act_ms * sim_idle_cyc_ms;
if (cyc_since_idle > sim_idle_cyc_sleep)
act_cyc -= sim_idle_cyc_sleep / 2; /* account for half an interval's worth of cycles */
else
act_cyc -= (int32)cyc_since_idle; /* acount for cycles executed */
act_cyc -= (int32)cyc_since_idle; /* account for cycles executed */
sim_interval = sim_interval - act_cyc; /* count down sim_interval to reflect idle period */
sim_idle_end_time = sim_gtime(); /* save idle completed time */
if (sim_clock_queue == QUEUE_LIST_END)
@ -1723,7 +1723,7 @@ else {
if ((*tptr != '\0') || (val == 0))
return sim_messagef (SCPE_ARG, "Invalid throttle delay specifier: %s\n", cptr);
}
if (c == 'M')
if (c == 'M')
sim_throt_type = SIM_THROT_MCYC;
else if (c == 'K')
sim_throt_type = SIM_THROT_KCYC;
@ -1860,7 +1860,7 @@ switch (sim_throt_state) {
}
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc(INIT) Computing Throttling values based on the last second's execution rate\n");
sim_throt_state = SIM_THROT_STATE_TIME;
if (sim_throt_peak_cps < (double)(rtc->hz * rtc->currd))
if (sim_throt_peak_cps < (double)(rtc->hz * rtc->currd))
sim_throt_peak_cps = (double)rtc->hz * rtc->currd;
return sim_throt_svc (uptr);
}
@ -1902,11 +1902,11 @@ switch (sim_throt_state) {
sim_set_throt (0, NULL); /* disable throttling */
return SCPE_OK;
}
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Not enough time. %d ms executing %.f %s.\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Not enough time. %d ms executing %.f %s.\n",
(int)delta_ms, delta_inst, sim_vm_interval_units);
sim_throt_wait = (int32)(delta_inst * SIM_THROT_WMUL);
sim_throt_inst_start = sim_gtime();
sim_idle_ms_sleep (sim_idle_rate_ms); /* start on a tick boundart to calibrate */
sim_idle_ms_sleep (sim_idle_rate_ms); /* start on a tick boundary to calibrate */
sim_throt_ms_start = sim_os_msec ();
}
else { /* long enough */
@ -1920,11 +1920,11 @@ switch (sim_throt_state) {
d_cps = (sim_throt_peak_cps * sim_throt_val) / 100.0;
if (d_cps >= a_cps) {
/* the initial throttling calibration measures a slower cps rate than the desired cps rate, */
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() CPU too slow. Values a_cps = %f, d_cps = %f\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() CPU too slow. Values a_cps = %f, d_cps = %f\n",
a_cps, d_cps);
/* if the measured rate is well below the measured peak rate? */
if (sim_throt_peak_cps >= (2.0 * d_cps)) {
/* distrust the measured rate and instead use half the peak rate as measured
/* distrust the measured rate and instead use half the peak rate as measured
cps rate. */
sim_printf ("*********** WARNING ***********\n");
sim_printf ("Host CPU could be too slow to simulate %s %s per second\n", sim_fmt_numeric(d_cps), sim_vm_interval_units);
@ -1953,13 +1953,13 @@ switch (sim_throt_state) {
if (sim_throt_wait >= SIM_THROT_WMIN) /* long enough? */
break;
sim_throt_sleep_time += sim_os_sleep_inc_ms;
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Wait too small, increasing sleep time to %d ms. Values a_cps = %f, d_cps = %f, wait = %d\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Wait too small, increasing sleep time to %d ms. Values a_cps = %f, d_cps = %f, wait = %d\n",
sim_throt_sleep_time, a_cps, d_cps, sim_throt_wait);
}
sim_throt_ms_start = sim_throt_ms_stop;
sim_throt_inst_start = sim_gtime();
sim_throt_state = SIM_THROT_STATE_THROTTLE;
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Throttle values a_cps = %f, d_cps = %f, wait = %d, sleep = %d ms\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Throttle values a_cps = %f, d_cps = %f, wait = %d, sleep = %d ms\n",
a_cps, d_cps, sim_throt_wait, sim_throt_sleep_time);
sim_throt_cps = d_cps; /* save the desired rate */
_sim_timer_adjust_cal(); /* adjust timer calibrations */
@ -1982,11 +1982,11 @@ switch (sim_throt_state) {
else
d_cps = (sim_throt_peak_cps * sim_throt_val) / 100.0;
if (fabs(100.0 * (d_cps - a_cps) / d_cps) > (double)sim_throt_drift_pct) {
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Recalibrating throttle based on values a_cps = %f, d_cps = %f deviating by %.2f%% from the desired value\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Recalibrating throttle based on values a_cps = %f, d_cps = %f deviating by %.2f%% from the desired value\n",
a_cps, d_cps, fabs(100.0 * (d_cps - a_cps) / d_cps));
if ((a_cps > d_cps) && /* too fast? */
((100.0 * (a_cps - d_cps) / d_cps) > (100 - sim_throt_drift_pct))) {
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Restarting calibrating throttle going too fast: a_cps = %f, d_cps = %f deviating by %.2f%% from the desired value\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Restarting calibrating throttle going too fast: a_cps = %f, d_cps = %f deviating by %.2f%% from the desired value\n",
a_cps, d_cps, fabs(100.0 * (d_cps - a_cps) / d_cps));
while (1) {
sim_throt_wait = (int32) /* cycles between sleeps */
@ -1995,16 +1995,16 @@ switch (sim_throt_state) {
if (sim_throt_wait >= SIM_THROT_WMIN)/* long enough? */
break;
sim_throt_sleep_time += sim_os_sleep_inc_ms;
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Wait too small, increasing sleep time to %d ms. Values a_cps = %f, d_cps = %f, wait = %d\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Wait too small, increasing sleep time to %d ms. Values a_cps = %f, d_cps = %f, wait = %d\n",
sim_throt_sleep_time, sim_throt_peak_cps, d_cps, sim_throt_wait);
}
}
else { /* slow or within reasonable range */
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Adjusting wait before sleep interval by %d\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Adjusting wait before sleep interval by %d\n",
(int32)(((d_cps - a_cps) * (double)sim_throt_wait) / d_cps));
sim_throt_wait += (int32)(((d_cps - a_cps) * (double)sim_throt_wait) / d_cps);
}
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Throttle values a_cps = %f, d_cps = %f, wait = %d, sleep = %d ms\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Throttle values a_cps = %f, d_cps = %f, wait = %d, sleep = %d ms\n",
a_cps, d_cps, sim_throt_wait, sim_throt_sleep_time);
sim_throt_cps = d_cps; /* save the desired rate */
sim_throt_ms_start = sim_os_msec ();
@ -2013,7 +2013,7 @@ switch (sim_throt_state) {
}
else { /* record instruction rate */
sim_throt_cps = (int32)a_cps;
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Recalibrating Special %d/%u Cycles Per Second of %f\n",
sim_debug (DBG_THR, &sim_timer_dev, "sim_throt_svc() Recalibrating Special %d/%u Cycles Per Second of %f\n",
sim_throt_wait, sim_throt_sleep_time, sim_throt_cps);
sim_throt_inst_start = sim_gtime();
sim_throt_ms_start = sim_os_msec ();
@ -2050,7 +2050,7 @@ static void _sim_timer_adjust_cal(void)
}
}
/* Clock assist activites */
/* Clock assist activities */
t_stat sim_timer_tick_svc (UNIT *uptr)
{
int32 tmr = (int32)(uptr-sim_timer_units);
@ -2060,11 +2060,11 @@ RTC *rtc = &rtcs[tmr];
rtc->clock_ticks += 1;
rtc->calib_tick_time += rtc->clock_tick_size;
/*
* Some devices may depend on executing during the same instruction or
* immediately after the clock tick event. To satisfy this, we directly
* Some devices may depend on executing during the same instruction or
* immediately after the clock tick event. To satisfy this, we directly
* run the clock event here and if it completes successfully, schedule any
* currently coschedule units to run now. Ticks should never return a
* non-success status, while co-schedule activities might, so they are
* currently coschedule units to run now. Ticks should never return a
* non-success status, while co-schedule activities might, so they are
* queued to run from sim_process_event
*/
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_tick_svc(tmr=%d) - scheduling %s - cosched interval: %d\n", tmr, sim_uname (rtc->clock_unit), rtc->cosched_interval);
@ -2074,7 +2074,7 @@ stat = rtc->clock_unit->action (rtc->clock_unit);
--rtc->cosched_interval; /* Countdown ticks */
if (rtc->clock_cosched_queue != QUEUE_LIST_END)
rtc->clock_cosched_queue->time = rtc->cosched_interval;
if ((stat == SCPE_OK) &&
if ((stat == SCPE_OK) &&
(rtc->cosched_interval <= 0) &&
(rtc->clock_cosched_queue != QUEUE_LIST_END)) {
UNIT *sptr = rtc->clock_cosched_queue;
@ -2150,7 +2150,7 @@ if (now)
return ts_now.tv_sec;
}
/*
/*
* If the host system has a relatively large clock tick (as compared to
* the desired simulated hz) ticks will naturally be scheduled late and
* these delays will accumulate. The net result will be unreasonably
@ -2163,15 +2163,15 @@ return ts_now.tv_sec;
* We accomodate these problems and make up for lost ticks by injecting
* catch-up ticks to the simulator.
*
* When necessary, catch-up ticks are scheduled to run under one
* When necessary, catch-up ticks are scheduled to run under one
* of two conditions:
* 1) after indicated number of instructions in a call by the simulator
* to sim_rtcn_tick_ack. sim_rtcn_tick_ack exists to provide a
* mechanism to inform the simh timer facilities when the simulated
* to sim_rtcn_tick_ack. sim_rtcn_tick_ack exists to provide a
* mechanism to inform the simh timer facilities when the simulated
* system has accepted the most recent clock tick interrupt.
* 2) immediately when the simulator calls sim_idle
*
* catchup ticks are only scheduled (eligible to happen) under these
* catchup ticks are only scheduled (eligible to happen) under these
* conditions after at least one tick has been acknowledged.
*
* The clock tick UNIT that will be scheduled to run for catchup ticks
@ -2229,7 +2229,7 @@ if ((!rtc->clock_catchup_eligible) && /* not eligible yet? */
sim_debug (DBG_QUE, &sim_timer_dev, "_rtcn_tick_catchup_check() - Enabling catchup ticks for %s\n", sim_uname (rtc->clock_unit));
bReturn = TRUE;
}
if ((rtc->hz > 0) &&
if ((rtc->hz > 0) &&
rtc->clock_catchup_eligible)
{
double tnow = sim_timenow_double();
@ -2295,8 +2295,8 @@ _timer_thread(void *arg)
int sched_policy;
struct sched_param sched_priority;
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which, in general, won't be readily yielding the processor when
/* Boost Priority for this I/O thread vs the CPU instruction execution
thread which, in general, won't be readily yielding the processor when
this thread needs to run */
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
++sched_priority.sched_priority;
@ -2317,7 +2317,7 @@ while (sim_asynch_timer && sim_is_running) {
if (sim_wallclock_entry) { /* something to insert in queue? */
sim_debug (DBG_TIM, &sim_timer_dev, "_timer_thread() - timing %s for %s\n",
sim_debug (DBG_TIM, &sim_timer_dev, "_timer_thread() - timing %s for %s\n",
sim_uname(sim_wallclock_entry), sim_fmt_secs (sim_wallclock_entry->a_usec_delay/1000000.0));
uptr = sim_wallclock_entry;
@ -2356,7 +2356,7 @@ while (sim_asynch_timer && sim_is_running) {
sim_debug (DBG_TIM, &sim_timer_dev, "_timer_thread() - waiting forever\n");
else
sim_debug (DBG_TIM, &sim_timer_dev, "_timer_thread() - waiting for %.0f usecs until %.6f for %s\n", wait_usec, sim_wallclock_queue->a_due_time, sim_uname(sim_wallclock_queue));
if ((wait_usec <= 0.0) ||
if ((wait_usec <= 0.0) ||
(0 != pthread_cond_timedwait (&sim_timer_wake, &sim_timer_lock, &due_time))) {
if (sim_wallclock_queue == QUEUE_LIST_END) /* queue empty? */
@ -2372,7 +2372,7 @@ while (sim_asynch_timer && sim_is_running) {
inst_delay = 0;
else
inst_delay = (int32)(inst_per_sec*(_timespec_to_double(&due_time)-_timespec_to_double(&stop_time)));
sim_debug (DBG_TIM, &sim_timer_dev, "_timer_thread() - slept %.0fms - activating(%s,%d)\n",
sim_debug (DBG_TIM, &sim_timer_dev, "_timer_thread() - slept %.0fms - activating(%s,%d)\n",
1000.0*(_timespec_to_double (&stop_time)-_timespec_to_double (&start_time)), sim_uname(uptr), inst_delay);
sim_activate (uptr, inst_delay);
}
@ -2390,17 +2390,17 @@ return NULL;
#endif /* defined(SIM_ASYNCH_CLOCKS) */
/*
In the event that there are no active calibrated clock devices,
no instruction rate calibration will be performed. This is more
likely on simpler simulators which don't have a full spectrum of
standard devices or possibly when a clock device exists but its
In the event that there are no active calibrated clock devices,
no instruction rate calibration will be performed. This is more
likely on simpler simulators which don't have a full spectrum of
standard devices or possibly when a clock device exists but its
use is optional.
Additonally, when a host system has a natural clock tick (
or minimal sleep time) which is greater than the tick size that
a simulator wants to run a clock at, we run this clock at the
Additionally, when a host system has a natural clock tick (
or minimal sleep time) which is greater than the tick size that
a simulator wants to run a clock at, we run this clock at the
rate implied by the host system's minimal sleep time or 50Hz.
To solve this we merely run an internal clock at 100Hz.
*/
@ -2412,22 +2412,22 @@ sim_activate_after (uptr, 1000000/sim_int_clk_tps); /* reactivate unit */
return SCPE_OK;
}
/*
This routine exists to assure that there is a single reliably calibrated
clock properly counting instruction execution relative to time. The best
way to assure reliable calibration is to use a clock which ticks no
faster than the host system's clock. This is optimal so that accurate
time measurements are taken. If the simulated system doesn't have a
clock with an appropriate tick rate, an internal clock is run that meets
/*
This routine exists to assure that there is a single reliably calibrated
clock properly counting instruction execution relative to time. The best
way to assure reliable calibration is to use a clock which ticks no
faster than the host system's clock. This is optimal so that accurate
time measurements are taken. If the simulated system doesn't have a
clock with an appropriate tick rate, an internal clock is run that meets
this requirement, OR when asynch clocks are enabled, the internal clock
is always run.
Some simulators have clocks that have dynamically programmable tick
rates. Such a clock is only a reliable candidate to be the calibrated
clock if it uses a single tick rate rather than changing the tick rate
Some simulators have clocks that have dynamically programmable tick
rates. Such a clock is only a reliable candidate to be the calibrated
clock if it uses a single tick rate rather than changing the tick rate
on the fly. Generally most systems like this, under normal conditions
don't change their tick rates unless they're running something that is
examining the behavior of the clock system (like a diagnostic). Under
examining the behavior of the clock system (like a diagnostic). Under
these conditions this clock is removed from the potential selection as
"the" calibrated clock all others are relative to and if necessary, an
internal calibrated clock is selected.
@ -2486,7 +2486,7 @@ if (tmr == SIM_NTIMERS) { /* None found? */
}
return;
}
if ((tmr == newtmr) &&
if ((tmr == newtmr) &&
(sim_calb_tmr == newtmr)) /* already set? */
return;
if (sim_calb_tmr == SIM_NTIMERS) { /* was old the internal timer? */
@ -2567,7 +2567,7 @@ if (sim_calb_tmr == -1) {
}
else {
if (sim_calb_tmr == SIM_NTIMERS) {
sim_debug (DBG_CAL, &sim_timer_dev, "sim_start_timer_services() - restarting internal timer after %d %s\n",
sim_debug (DBG_CAL, &sim_timer_dev, "sim_start_timer_services() - restarting internal timer after %d %s\n",
sim_internal_timer_time, sim_vm_interval_units);
sim_activate (&SIM_INTERNAL_UNIT, sim_internal_timer_time);
}
@ -2730,7 +2730,7 @@ for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
if (sim_is_active (uptr)) /* already active? */
return SCPE_OK;
if (usec_delay < 0.0) {
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - surprising usec value\n",
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - surprising usec value\n",
sim_uname(uptr), usec_delay);
}
if ((sim_is_running) || (tmr <= SIM_NTIMERS))
@ -2739,7 +2739,7 @@ else { /* defer non timer wallclock activat
uptr->usecs_remaining = usec_delay;
usec_delay = 0;
}
/*
/*
* Handle long delays by aligning with the calibrated timer's calibration
* activities. Delays which would expire prior to the next calibration
* are specifically scheduled directly based on the the current instruction
@ -2769,9 +2769,9 @@ if (sim_calb_tmr != -1) {
if (inst_delay_d > (double)inst_til_calib) { /* long wait? */
stat = sim_clock_coschedule_tmr (uptr, sim_calb_tmr, ticks_til_calib - 1);
uptr->usecs_remaining = (stat == SCPE_OK) ? usec_delay - usecs_til_calib : 0.0;
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - coscheduling with with calibrated timer(%d), ticks=%d, usecs_remaining=%.0f usecs, inst_til_tick=%d, ticks_til_calib=%d, usecs_til_calib=%u\n",
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - coscheduling with with calibrated timer(%d), ticks=%d, usecs_remaining=%.0f usecs, inst_til_tick=%d, ticks_til_calib=%d, usecs_til_calib=%u\n",
sim_uname(uptr), usec_delay, sim_calb_tmr, ticks_til_calib, uptr->usecs_remaining, inst_til_tick, ticks_til_calib, usecs_til_calib);
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
sim_uname(uptr), usec_delay, sim_timer_activate_time_usecs (ouptr), sim_timer_activate_time_usecs (uptr));
return stat;
}
@ -2781,16 +2781,16 @@ if (sim_calb_tmr != -1) {
stat = sim_clock_coschedule_tmr (uptr, sim_calb_tmr, 0);
uptr->usecs_remaining = (stat == SCPE_OK) ? usec_delay - usecs_til_tick : 0.0;
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - coscheduling with with calibrated timer(%d), ticks=%d, usecs_remaining=%.0f usecs, inst_til_tick=%d, usecs_til_tick=%.0f\n",
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - coscheduling with with calibrated timer(%d), ticks=%d, usecs_remaining=%.0f usecs, inst_til_tick=%d, usecs_til_tick=%.0f\n",
sim_uname(uptr), usec_delay, sim_calb_tmr, 0, uptr->usecs_remaining, inst_til_tick, usecs_til_tick);
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
sim_uname(uptr), usec_delay, sim_timer_activate_time_usecs (ouptr), sim_timer_activate_time_usecs (uptr));
return stat;
}
}
}
}
/*
/*
* We're here to schedule if:
* No Calibrated Timer, OR
* Scheduling the Calibrated Timer OR
@ -2798,8 +2798,8 @@ if (sim_calb_tmr != -1) {
*/
/*
* Bound delay to avoid overflow.
* Long delays are usually canceled before they expire, however bounding the
* delay will cause sim_activate_time to return inconsistent results when
* Long delays are usually canceled before they expire, however bounding the
* delay will cause sim_activate_time to return inconsistent results when
* truncation has happened.
*/
if (inst_delay_d > (double)0x7fffffff)
@ -2823,7 +2823,7 @@ if ((sim_asynch_timer) &&
rtc->clock_unit->a_is_active = &_sim_wallclock_is_active;
}
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - queueing wallclock addition at %.6f\n",
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - queueing wallclock addition at %.6f\n",
sim_uname(uptr), usec_delay, uptr->a_due_time);
pthread_mutex_lock (&sim_timer_lock);
@ -2836,7 +2836,7 @@ if ((sim_asynch_timer) &&
uptr->a_next = QUEUE_LIST_END; /* Temporarily mark as active */
if (sim_timer_thread_running) {
while (sim_wallclock_entry) { /* wait for any prior entry has been digested */
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - queue insert entry %s busy waiting for 1ms\n",
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - queue insert entry %s busy waiting for 1ms\n",
sim_uname(uptr), usec_delay, sim_uname(sim_wallclock_entry));
pthread_mutex_unlock (&sim_timer_lock);
sim_os_ms_sleep (1);
@ -2857,9 +2857,9 @@ if ((sim_asynch_timer) &&
}
#endif
stat = _sim_activate (uptr, inst_delay); /* queue it now */
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - queue addition at %d - remnant: %.0f\n",
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - queue addition at %d - remnant: %.0f\n",
sim_uname(uptr), usec_delay, inst_delay, uptr->usecs_remaining);
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
sim_uname(uptr), usec_delay, sim_timer_activate_time_usecs (ouptr), sim_timer_activate_time_usecs (uptr));
return stat;
}
@ -2900,7 +2900,7 @@ if (rtc->clock_unit == NULL)
rtc->clock_cosched_queue = QUEUE_LIST_END;
rtc->clock_unit = uptr;
uptr->dynflags |= UNIT_TMR_UNIT;
rtc->timer_unit->flags = ((tmr == SIM_NTIMERS) ? 0 : UNIT_DIS) |
rtc->timer_unit->flags = ((tmr == SIM_NTIMERS) ? 0 : UNIT_DIS) |
(rtc->clock_unit ? UNIT_IDLE : 0);
return SCPE_OK;
}
@ -3213,7 +3213,7 @@ for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
return _sim_activate_time (&sim_timer_units[tmr]);
}
}
return -1; /* Not found. */
return -1; /* Not found. */
}
double sim_timer_activate_time_usecs (UNIT *uptr)
@ -3305,7 +3305,7 @@ for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
}
result = uptr->usecs_remaining + (1000000.0 * (sim_activate_time (uptr) - 1)) / sim_timer_inst_per_sec ();
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) clock - %.0f usecs, inst_per_sec=%.0f, usecs_remaining=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec (), uptr->usecs_remaining);
return result; /* Not found. */
return result; /* Not found. */
}
/* read only memory delayed support
@ -3314,10 +3314,10 @@ return result; /* Not found. */
time to meet timing assumptions in the code being executed.
The default calibration determines a way to limit activities
to 1Mhz for each call to sim_rom_read_with_delay(). If a
simulator needs a different delay factor, the 1 Mhz initial
value can be queried with sim_get_rom_delay_factor() and the
result can be adjusted as nessary and the operating delay
to 1Mhz for each call to sim_rom_read_with_delay(). If a
simulator needs a different delay factor, the 1 MHz initial
value can be queried with sim_get_rom_delay_factor() and the
result can be adjusted as necessary and the operating delay
can be set with sim_set_rom_delay_factor().
*/
@ -3341,7 +3341,7 @@ return val + rom_loopval;
SIM_NOINLINE uint32 sim_get_rom_delay_factor (void)
{
/* Calibrate the loop delay factor at startup.
Do this 4 times and use the largest value computed.
Do this 4 times and use the largest value computed.
The goal here is to come up with a delay factor which will throttle
a 6 byte delay loop running from ROM address space to execute
1 instruction per usec */
@ -3361,7 +3361,7 @@ if (sim_rom_delay == 0) {
for (i = 0; i < c; i++)
rom_loopval |= (rom_loopval + ts) ^ _rom_swapb (_rom_swapb (rom_loopval + ts));
te = sim_os_msec ();
te = sim_os_msec ();
if ((te - ts) < 50) /* sample big enough? */
continue;
if (sim_rom_delay < (rom_loopval + (c / (te - ts) / 1000) + 1))
@ -3385,9 +3385,9 @@ sim_rom_delay = delay;
*
* The point of this routine is to run a bunch of simulator provided
* instructions that don't do anything, but run in an effective loop.
* That loop is run for some 5 million instructions and based on
* That loop is run for some 5 million instructions and based on
* the time those 5 million instructions take to execute the effective
* execution rate. That rate is used to avoid the initial 3 to 5
* execution rate. That rate is used to avoid the initial 3 to 5
* seconds that normal clock calibration takes.
*
*/
@ -3434,7 +3434,7 @@ sim_inst_per_sec_last = sim_precalibrate_ips;
sim_idle_stable = 0;
}
double
double
sim_host_speed_factor (void)
{
if (sim_precalibrate_ips > sim_vm_initial_ips)

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,7 @@
Based on the original DZ11 simulator by Thord Nilson, as updated by
Arthur Krewat.
10-Oct-12 MP Added extended attach support for serial, per line
10-Oct-12 MP Added extended attach support for serial, per line
listener and outgoing connections
17-Jan-11 MP Added buffered line capabilities
20-Nov-08 RMS Added three new standardized SHOW routines
@ -96,7 +96,7 @@ typedef struct SERPORT *SERHANDLE;
#define TMUF_NOASYNCH (1u << TMUF_V_NOASYNCH) /* This flag can be defined */
/* statically in a unit's flag field */
/* This will disable the unit from */
/* supporting asynchronmous mux behaviors */
/* supporting asynchronous mux behaviors */
/* Receive line speed limits */
#define TMLN_SPD_50_BPS 200000 /* usec per character */
@ -125,7 +125,7 @@ typedef struct SERPORT *SERHANDLE;
#define TMLN_SPD_115200_BPS 86 /* usec per character */
/* Internal struct */
struct framer_data;
struct framer_data;
typedef struct tmln TMLN;
typedef struct tmxr TMXR;
@ -356,7 +356,7 @@ t_stat tmxr_add_debug (DEVICE *dptr);
#define sim_activate_abs tmxr_activate_abs
#define sim_activate_after tmxr_activate_after
#define sim_activate_after_abs tmxr_activate_after_abs
#define sim_clock_coschedule tmxr_clock_coschedule
#define sim_clock_coschedule tmxr_clock_coschedule
#define sim_clock_coschedule_abs tmxr_clock_coschedule_abs
#define sim_clock_coschedule_tmr tmxr_clock_coschedule_tmr
#define sim_clock_coschedule_tmr_abs tmxr_clock_coschedule_tmr_abs

View file

@ -104,20 +104,20 @@ char vid_release_key[64] = "Ctrl-Right-Shift";
#include <SDL.h>
#include <SDL_thread.h>
static const char *key_names[] =
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z",
"BACKQUOTE", "MINUS", "EQUALS", "LEFT_BRACKET", "RIGHT_BRACKET",
"SEMICOLON", "SINGLE_QUOTE", "BACKSLASH", "LEFT_BACKSLASH", "COMMA",
"PERIOD", "SLASH", "PRINT", "SCRL_LOCK", "PAUSE", "ESC", "BACKSPACE",
"TAB", "ENTER", "SPACE", "INSERT", "DELETE", "HOME", "END", "PAGE_UP",
"PAGE_DOWN", "UP", "DOWN", "LEFT", "RIGHT", "CAPS_LOCK", "NUM_LOCK",
"ALT_L", "ALT_R", "CTRL_L", "CTRL_R", "SHIFT_L", "SHIFT_R",
"WIN_L", "WIN_R", "MENU", "KP_ADD", "KP_SUBTRACT", "KP_END", "KP_DOWN",
"KP_PAGE_DOWN", "KP_LEFT", "KP_RIGHT", "KP_HOME", "KP_UP", "KP_PAGE_UP",
static const char *key_names[] =
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z",
"BACKQUOTE", "MINUS", "EQUALS", "LEFT_BRACKET", "RIGHT_BRACKET",
"SEMICOLON", "SINGLE_QUOTE", "BACKSLASH", "LEFT_BACKSLASH", "COMMA",
"PERIOD", "SLASH", "PRINT", "SCRL_LOCK", "PAUSE", "ESC", "BACKSPACE",
"TAB", "ENTER", "SPACE", "INSERT", "DELETE", "HOME", "END", "PAGE_UP",
"PAGE_DOWN", "UP", "DOWN", "LEFT", "RIGHT", "CAPS_LOCK", "NUM_LOCK",
"ALT_L", "ALT_R", "CTRL_L", "CTRL_R", "SHIFT_L", "SHIFT_R",
"WIN_L", "WIN_R", "MENU", "KP_ADD", "KP_SUBTRACT", "KP_END", "KP_DOWN",
"KP_PAGE_DOWN", "KP_LEFT", "KP_RIGHT", "KP_HOME", "KP_UP", "KP_PAGE_UP",
"KP_INSERT", "KP_DELETE", "KP_5", "KP_ENTER", "KP_MULTIPLY", "KP_DIVIDE"
};
@ -170,7 +170,7 @@ static char tmp_key_name[40];
#define amask 0xFF000000
#endif
/* libpng callbacks */
/* libpng callbacks */
static void png_error_SDL(png_structp ctx, png_const_charp str)
{
SDL_SetError("libpng: %s\n", str);
@ -181,12 +181,12 @@ static void png_write_SDL(png_structp png_ptr, png_bytep data, png_size_t length
SDL_RWwrite(rw, data, sizeof(png_byte), length);
}
static SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src)
static SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src)
{
SDL_Surface *surf;
SDL_Rect rect = { 0 };
/* NO-OP for images < 32bpp and 32bpp images that already have Alpha channel */
/* NO-OP for images < 32bpp and 32bpp images that already have Alpha channel */
if (src->format->BitsPerPixel <= 24 || src->format->Amask) {
src->refcount++;
return src;
@ -202,7 +202,7 @@ static SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src)
return surf;
}
static int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
static int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
{
png_structp png_ptr;
png_infop info_ptr;
@ -225,7 +225,7 @@ static int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
return (ERROR);
}
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_SDL, NULL); /* err_ptr, err_fn, warn_fn */
if (!png_ptr)
if (!png_ptr)
{
SDL_SetError("Unable to png_create_write_struct on %s\n", PNG_LIBPNG_VER_STRING);
if (freedst) SDL_RWclose(dst);
@ -300,19 +300,19 @@ static int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
}
#endif /* defined(HAVE_LIBPNG) */
/*
Some platforms (OS X), require that ALL input event processing be
/*
Some platforms (OS X), require that ALL input event processing be
performed by the main thread of the process.
To satisfy this requirement, we leverage the SDL_MAIN functionality
To satisfy this requirement, we leverage the SDL_MAIN functionality
which does:
#defines main SDL_main
and we define the main() entry point here. Locally, we run the
and we define the main() entry point here. Locally, we run the
application's SDL_main in a separate thread, and while that thread
is running, the main thread performs event handling and dispatch.
*/
#define EVENT_REDRAW 1 /* redraw event for SDL */
@ -641,7 +641,7 @@ int i, n;
if (vid_gamepad_inited++)
return;
/* Chech that the SDL_GameControllerFromInstanceID function is
/* Check that the SDL_GameControllerFromInstanceID function is
available at run time. */
SDL_GetVersion(&ver);
vid_gamepad_ok = (ver.major > 2 ||
@ -999,7 +999,7 @@ if (vptr->vid_flags & SIM_VID_INPUTCAPTURED)
if ((x_delta) || (y_delta)) {
sim_debug (SIM_VID_DBG_CURSOR, vptr->vid_dev, "vid_set_cursor_position(%d, %d) - Cursor position changed\n", x, y);
/* Any queued mouse motion events need to have their relative
/* Any queued mouse motion events need to have their relative
positions adjusted since they were queued based on different info. */
if (SDL_SemWait (vid_mouse_events.sem) == 0) {
int32 i;
@ -1452,9 +1452,9 @@ if (vptr->vid_mouse_captured) {
if (!KeyStates)
KeyStates = SDL_GetKeyboardState(&numkeys);
if ((vptr->vid_flags & SIM_VID_INPUTCAPTURED) &&
(event->state == SDL_PRESSED) &&
KeyStates[SDL_SCANCODE_RSHIFT] &&
if ((vptr->vid_flags & SIM_VID_INPUTCAPTURED) &&
(event->state == SDL_PRESSED) &&
KeyStates[SDL_SCANCODE_RSHIFT] &&
(KeyStates[SDL_SCANCODE_LCTRL] || KeyStates[SDL_SCANCODE_RCTRL])) {
sim_debug (SIM_VID_DBG_KEY, vptr->vid_dev, "vid_key() - Cursor Release\n");
if (SDL_SetRelativeMouseMode(SDL_FALSE) < 0) /* release cursor, show cursor */
@ -1512,7 +1512,7 @@ if (!sim_is_running)
return;
if (!vptr->vid_cursor_visible)
return;
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d)\n",
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d)\n",
event->x, event->y, event->xrel, event->yrel, (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0);
while (SDL_PeepEvents (&dummy_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION)) {
/* Coalesce motion activity to avoid thrashing */
@ -1521,7 +1521,7 @@ while (SDL_PeepEvents (&dummy_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSE
event->x = dev->x;
event->y = dev->y;
event->state = dev->state;
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: Additional Event Coalesced:pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d)\n",
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: Additional Event Coalesced:pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d)\n",
dev->x, dev->y, dev->xrel, dev->yrel, (dev->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0, (dev->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0, (dev->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0);
};
if (SDL_SemWait (vid_mouse_events.sem) == 0) {
@ -1532,7 +1532,7 @@ if (SDL_SemWait (vid_mouse_events.sem) == 0) {
vid_mouse_b1 = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE;
vid_mouse_b2 = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE;
vid_mouse_b3 = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE;
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d) - Count: %d vid_cursor:(%d,%d)\n",
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: pos:(%d,%d) rel:(%d,%d) buttons:(%d,%d,%d) - Count: %d vid_cursor:(%d,%d)\n",
event->x, event->y, event->xrel, event->yrel, (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0, (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0, vid_mouse_events.count, vid_cursor_x, vid_cursor_y);
if (vid_mouse_events.count < MAX_EVENTS) {
SIM_MOUSE_EVENT *tail = &vid_mouse_events.events[(vid_mouse_events.tail+MAX_EVENTS-1)%MAX_EVENTS];
@ -1547,13 +1547,13 @@ if (SDL_SemWait (vid_mouse_events.sem) == 0) {
ev.y_pos = event->y;
if ((vid_mouse_events.count > 0) && /* Is there a tail event? */
(ev.b1_state == tail->b1_state) && /* With the same button state? */
(ev.b2_state == tail->b2_state) &&
(ev.b2_state == tail->b2_state) &&
(ev.b3_state == tail->b3_state)) { /* Merge the motion */
tail->x_rel += ev.x_rel;
tail->y_rel += ev.y_rel;
tail->x_pos = ev.x_pos;
tail->y_pos = ev.y_pos;
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: Coalesced into pending event: (%d,%d)\n",
sim_debug (SIM_VID_DBG_MOUSE, vptr->vid_dev, "Mouse Move Event: Coalesced into pending event: (%d,%d)\n",
tail->x_rel, tail->y_rel);
}
else { /* Add a new event */
@ -1757,7 +1757,7 @@ void vid_update_cursor (VID_DISPLAY *vptr, SDL_Cursor *cursor, t_bool visible)
{
if (!cursor)
return;
sim_debug (SIM_VID_DBG_VIDEO, vptr->vid_dev, "Cursor Update Event: Previously %s, Now %s, New Cursor object at: %p, Old Cursor object at: %p\n",
sim_debug (SIM_VID_DBG_VIDEO, vptr->vid_dev, "Cursor Update Event: Previously %s, Now %s, New Cursor object at: %p, Old Cursor object at: %p\n",
SDL_ShowCursor(-1) ? "visible" : "invisible", visible ? "visible" : "invisible", cursor, vptr->vid_cursor);
SDL_SetCursor (cursor);
if ((vptr->vid_window == SDL_GetMouseFocus ()) && visible)
@ -1794,7 +1794,7 @@ SDL_UnlockMutex (vptr->vid_draw_mutex);
if (vptr->vid_blending) {
SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf));
SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, vid_dst, vid_dst);
SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, vid_dst, vid_dst);
}
else
if (SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf)))
@ -2282,10 +2282,10 @@ SDLVersion[sizeof (SDLVersion) - 1] = '\0';
if ((compiled.major == running.major) &&
(compiled.minor == running.minor) &&
(compiled.patch == running.patch))
snprintf(SDLVersion, sizeof (SDLVersion) - 1, "SDL Version %d.%d.%d",
snprintf(SDLVersion, sizeof (SDLVersion) - 1, "SDL Version %d.%d.%d",
compiled.major, compiled.minor, compiled.patch);
else
snprintf(SDLVersion, sizeof (SDLVersion) - 1, "SDL Version (Compiled: %d.%d.%d, Runtime: %d.%d.%d)",
snprintf(SDLVersion, sizeof (SDLVersion) - 1, "SDL Version (Compiled: %d.%d.%d, Runtime: %d.%d.%d)",
compiled.major, compiled.minor, compiled.patch,
running.major, running.minor, running.patch);
#if defined (HAVE_LIBPNG)
@ -2293,19 +2293,19 @@ if (1) {
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (strcmp (PNG_LIBPNG_VER_STRING, png_get_libpng_ver (png)))
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
", PNG Version (Compiled: %s, Runtime: %s)",
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
", PNG Version (Compiled: %s, Runtime: %s)",
PNG_LIBPNG_VER_STRING, png_get_libpng_ver (png));
else
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
", PNG Version %s", PNG_LIBPNG_VER_STRING);
png_destroy_read_struct(&png, NULL, NULL);
#if defined (ZLIB_VERSION)
if (strcmp (ZLIB_VERSION, zlibVersion ()))
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
", zlib: (Compiled: %s, Runtime: %s)", ZLIB_VERSION, zlibVersion ());
else
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
", zlib: %s", ZLIB_VERSION);
#endif
}
@ -2654,7 +2654,7 @@ char *extension = strrchr ((char *)_screenshot_filename, '.');
if (name == NULL) {
_screenshot_stat = SCPE_NXM;
return;
}
}
if (extension)
n = extension - _screenshot_filename;
else {
@ -2778,7 +2778,7 @@ while (SDL_PushEvent (&user_event) < 0)
#else
vid_beep_event ();
#endif
SDL_Delay (vid_beep_duration + 100);/* Wait for sound to finnish */
SDL_Delay (vid_beep_duration + 100);/* Wait for sound to finish */
}
#else /* !(defined(USE_SIM_VIDEO) && defined(HAVE_LIBSDL)) */