SIMH: Fix spelling errors in comments and strings
This commit is contained in:
parent
e7b2431f11
commit
0f6bcb9682
34 changed files with 1893 additions and 1893 deletions
|
@ -3,36 +3,36 @@ SIM_ASYNCH_IO
|
||||||
Theory of operation.
|
Theory of operation.
|
||||||
|
|
||||||
Features.
|
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.
|
simulators will still build and perform correctly when run.
|
||||||
Additionmally, a simulator built with SIM_ASYNCH_IO defined can
|
Additionally, a simulator built with SIM_ASYNCH_IO defined can
|
||||||
dynamically disable and reenable asynchronous operation with
|
dynamically disable and reenable asynchronous operation with
|
||||||
the scp commands SET NOASYNCH and SET ASYNCH respectively.
|
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 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.
|
support.
|
||||||
- Optimal behavior/performance with simulator running with or
|
- Optimal behavior/performance with simulator running with or
|
||||||
without CPU idling enabled.
|
without CPU idling enabled.
|
||||||
- Consistent minimum instruction scheduling delays when operating
|
- Consistent minimum instruction scheduling delays when operating
|
||||||
with or without SIM_ASYNCH_IO. When SIM_ASYNCH_IO is emabled,
|
with or without SIM_ASYNCH_IO. When SIM_ASYNCH_IO is enabled,
|
||||||
any operation which would have been scheduled to occurr in 'n'
|
any operation which would have been scheduled to occur in 'n'
|
||||||
instructions will still occur (from the simulated computer's
|
instructions will still occur (from the simulated computer's
|
||||||
point of view) at least 'n' instructions after it was initiated.
|
point of view) at least 'n' instructions after it was initiated.
|
||||||
|
|
||||||
Benefits.
|
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.
|
with I/O operations which may take numerous milliseconds to perform.
|
||||||
- Allows a simulated device to potentially avoid polling for the
|
- Allows a simulated device to potentially avoid polling for the
|
||||||
arrival of data. Polling consumes host processor CPU cycles which
|
arrival of data. Polling consumes host processor CPU cycles which
|
||||||
may better be spent executing simulated instructions or letting
|
may better be spent executing simulated instructions or letting
|
||||||
other host processes run. Measurements made of available
|
other host processes run. Measurements made of available
|
||||||
instruction execution easily demonstrate the benefits of parallel
|
instruction execution easily demonstrate the benefits of parallel
|
||||||
instruction and I/O activities. A VAX simulator with a process
|
instruction and I/O activities. A VAX simulator with a process
|
||||||
running a disk intensive application in one process was able to
|
running a disk intensive application in one process was able to
|
||||||
run (in another process) 11 times the number of Dhrystone operations
|
run (in another process) 11 times the number of Dhrystone operations
|
||||||
with Asynch I/O enabled vs not enabled.
|
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.
|
possible under varying I/O load and activities.
|
||||||
|
|
||||||
SimH Libraries which provide Asynch I/O support:
|
SimH Libraries which provide Asynch I/O support:
|
||||||
|
@ -44,7 +44,7 @@ SimH Libraries which provide Asynch I/O support:
|
||||||
|
|
||||||
Requirements to use:
|
Requirements to use:
|
||||||
The Simulator's instruction loop needs to be modified to include a single
|
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 >>>:
|
module added the following line indicated by >>>:
|
||||||
|
|
||||||
/* Main instruction loop */
|
/* Main instruction loop */
|
||||||
|
@ -60,20 +60,20 @@ module added the following line indicated by >>>:
|
||||||
SET_IRQL; /* update interrupts */
|
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
|
dispatch latency". This variable is the number of nanoseconds between checks
|
||||||
for completed asynchronous I/O. The default value is 4000 (4 usec) which
|
for completed asynchronous I/O. The default value is 4000 (4 usec) which
|
||||||
corresponds reasonably with simulated hardware. This variable controls
|
corresponds reasonably with simulated hardware. This variable controls
|
||||||
the computation of sim_asynch_inst_latency which is the number of simulated
|
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
|
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
|
actual checking every instruction can slow down execution. Periodic checks
|
||||||
provide a balance which allows response similar to real hardware while also
|
provide a balance which allows response similar to real hardware while also
|
||||||
providing minimal impact on actual instruction execution. Meanwhile, if
|
providing minimal impact on actual instruction execution. Meanwhile, if
|
||||||
maximal response is desired, then the value of sim_asynch_latency can be
|
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.
|
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
|
The sim_asynch_inst_latency is dynamically updated once per second in the
|
||||||
sim_rtcn_calb routine where clock to instruction execution is dynamically
|
sim_rtcn_calb routine where clock to instruction execution is dynamically
|
||||||
determined. A simulator would usually add register definitions
|
determined. A simulator would usually add register definitions
|
||||||
to enable viewing and setting of these variables via scp:
|
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
|
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
|
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
|
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:
|
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 (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);
|
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
|
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:
|
Considerations:
|
||||||
Avoiding multiple concurrent users of the unit structure. While asynch
|
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
|
queue. The I/O completion will cause the Unit to be scheduled to run
|
||||||
immediately to actually dispatch control flow to the callback routine.
|
immediately to actually dispatch control flow to the callback routine.
|
||||||
The callback routine is always called in the same thread which is
|
The callback routine is always called in the same thread which is
|
||||||
executing instructions. Since all simulator device data structures are
|
executing instructions. Since all simulator device data structures are
|
||||||
only referenced from this thread there are no host multi-processor cache
|
only referenced from this thread there are no host multi-processor cache
|
||||||
coherency issues to be concerned about.
|
coherency issues to be concerned about.
|
||||||
|
|
||||||
Arguments to the callback routine:
|
Arguments to the callback routine:
|
||||||
UNIT *, and IO Status
|
UNIT *, and IO Status
|
||||||
Requirements of the Callback routine.
|
Requirements of the Callback routine.
|
||||||
The callback routine must save the I/O completion status in a place
|
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
|
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 (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
|
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
|
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
|
will have been scheduled with a delay time of 0. If a different event
|
||||||
firing time is desired, then the callback completion routine should
|
firing time is desired, then the callback completion routine should
|
||||||
call sim_activate_abs to schedule the event at the appropriate time.
|
call sim_activate_abs to schedule the event at the appropriate time.
|
||||||
|
|
||||||
Required change in device coding.
|
Required change in device coding.
|
||||||
Devices which wish to leverage the benefits of asynch I/O must rearrange
|
Devices which wish to leverage the benefits of asynch I/O must rearrange
|
||||||
the code which implements the unit service routine. This rearrangement
|
the code which implements the unit service routine. This rearrangement
|
||||||
usually entails breaking the activities into two phases. The first phase
|
usually entails breaking the activities into two phases. The first phase
|
||||||
(I'll call the top half) involves performing whatever is needed to
|
(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.
|
initiate a call to perform an I/O operation with a callback argument.
|
||||||
Control is then immediately returned to the scp event dispatcher.
|
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.
|
status and some indicator that an I/O has completed.
|
||||||
The top/bottom half separation of the unit service routine would be
|
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
|
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
|
code upon completion. The bottom half code should clear the I/O
|
||||||
completion indicator and then perform any activities which normally
|
completion indicator and then perform any activities which normally
|
||||||
need to occur after the I/O completes. Care should be taken while
|
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
|
performing these top/bottom half activities to return to the scp event
|
||||||
dispatcher with either SCPE_OK or an appropriate error code when needed.
|
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 need to return error indications to the scp event dispatcher is why
|
||||||
the bottom half activities can't simply be performed in the
|
the bottom half activities can't simply be performed in the
|
||||||
callback routine (the callback routine does not return a status).
|
callback routine (the callback routine does not return a status).
|
||||||
Care should also be taken to realize that local variables in the
|
Care should also be taken to realize that local variables in the
|
||||||
unit service routine will not directly survive between the separate
|
unit service routine will not directly survive between the separate
|
||||||
top and bottom half calls to the unit service routine. If any such
|
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
|
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
|
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
|
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
|
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:
|
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
|
1) there are many different operations which can be requested of tape
|
||||||
devices and 2) some of the tmscp operations required many separate
|
devices and 2) some of the tmscp operations required many separate
|
||||||
operations on the physical device layer to perform a single tmscp request.
|
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.
|
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.
|
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.
|
minimize 'unproductive' polling.
|
||||||
|
|
||||||
There are two goals for asynchronous Multiplexer I/O: 1) Minimize 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,
|
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.
|
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
|
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
|
multiplexer device emulation. If a device emulation takes the normal
|
||||||
model of polling for arriving data on every simulated clock tick, then if
|
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
|
Asynch I/O is enabled, the device will operate asynchronously and behave
|
||||||
well. There is one restriction in this model. Specifically, the device
|
well. There is one restriction in this model. Specifically, the device
|
||||||
emulation logic can't expect that there will be a particular number (clock
|
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
|
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?).
|
in any interval of time (this is what we're trying to change, right?).
|
||||||
Therefore presumptions about measuring time by counting polls is not
|
Therefore presumptions about measuring time by counting polls is not
|
||||||
valid. If a device needs to manage time related activities, then the
|
valid. If a device needs to manage time related activities, then the
|
||||||
device should create a separate unit which is dedicated to the timing
|
device should create a separate unit which is dedicated to the timing
|
||||||
activities and which explicitly schedules a different unit service routine
|
activities and which explicitly schedules a different unit service routine
|
||||||
for those activities as needed. Such scheduled polling should only be
|
for those activities as needed. Such scheduled polling should only be
|
||||||
enabled when actual timing is required.
|
enabled when actual timing is required.
|
||||||
|
|
||||||
A device which is unprepared to operate asynchronously can specifically
|
A device which is unprepared to operate asynchronously can specifically
|
||||||
disable multiplexer Asynch I/O for that device by explicitly defining
|
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
|
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
|
particular device emulation which isn't capable of asynch operation, or
|
||||||
it can be defined globally on the compile command line for the simulator.
|
it can be defined globally on the compile command line for the simulator.
|
||||||
Alternatively, if a specific Multiplexer device doesn't function correctly
|
Alternatively, if a specific Multiplexer device doesn't function correctly
|
||||||
under the multiplexer asynchronous environment and it will never be
|
under the multiplexer asynchronous environment and it will never be
|
||||||
revised to operate correctly, it may statically set the TMUF_NOASYNCH bit
|
revised to operate correctly, it may statically set the TMUF_NOASYNCH bit
|
||||||
in its unit flags field.
|
in its unit flags field.
|
||||||
|
|
||||||
Some devices will need a small amount of extra coding to leverage the
|
Some devices will need a small amount of extra coding to leverage the
|
||||||
Multiplexer Asynch I/O capabilties. Devices which require extra coding
|
Multiplexer Asynch I/O capabilities. Devices which require extra coding
|
||||||
have one or more of the following characteristics:
|
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.
|
which was provided when tmxr_attach was called.
|
||||||
- they poll for connections on a different unit than the unit which was
|
- they poll for connections on a different unit than the unit which was
|
||||||
provided when tmxr_attach was called.
|
provided when tmxr_attach was called.
|
||||||
|
|
||||||
The extra coding required for proper operation is to call
|
The extra coding required for proper operation is to call
|
||||||
tmxr_set_line_unit() to associate the appropriate input polling unit to
|
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
|
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()
|
polling is done on a different unit, then tmxr_set_line_output_unit()
|
||||||
should be called to describe that fact.
|
should be called to describe that fact.
|
||||||
|
|
||||||
Console I/O can operate asynchronously if the simulator notifies the
|
Console I/O can operate asynchronously if the simulator notifies the
|
||||||
tmxr/console subsystem which device unit is used by the simulator to poll
|
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
|
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
|
in the source module which contains the console input device definition
|
||||||
and calling tmxr_set_console_units(). tmxr_set_console_units would usually
|
and calling tmxr_set_console_units(). tmxr_set_console_units would usually
|
||||||
be called in a device reset routine.
|
be called in a device reset routine.
|
||||||
|
|
||||||
sim_tmxr consumers:
|
sim_tmxr consumers:
|
||||||
|
@ -241,68 +241,68 @@ sim_tmxr consumers:
|
||||||
- PDP-18b TT1 devices = 2, units = 1/16, lines = 16, flagbits = 0, Untested Asynch
|
- 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
|
- SDS MUX devices = 2, units = 1/32, lines = 32, flagbits = 0, Untested Asynch
|
||||||
- sim_console Good 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
|
Program Clock Devices to leverage Asynch I/O
|
||||||
instructions which the simulator can execute in a given amount of wall
|
|
||||||
clock time. Once this is determined, the appropriate value is continually
|
simh's concept of time is calibrated by counting the number of
|
||||||
recalibrated and used throughout a simulator to schedule device time
|
instructions which the simulator can execute in a given amount of wall
|
||||||
related delays as needed. Historically, this was fine until modern
|
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.
|
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
|
drastically. This dynamic adjustment of the host system's execution rate
|
||||||
may cause dramatic drifting of the simulated operating system's concept
|
may cause dramatic drifting of the simulated operating system's concept
|
||||||
of time. Once all devices are disconnected from the calibrated clock's
|
of time. Once all devices are disconnected from the calibrated clock's
|
||||||
instruction count, the only concern for time in the simulated system is
|
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
|
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
|
in the past, however each simulator was burdened with providing code
|
||||||
which facilitated managing the concept of the relationship between the
|
which facilitated managing the concept of the relationship between the
|
||||||
number of instructions executed and the passage of wall clock time.
|
number of instructions executed and the passage of wall clock time.
|
||||||
To accomodate the needs of activities or events which should be measured
|
To accomodate the needs of activities or events which should be measured
|
||||||
against wall clock time (vs specific number of instructions executed),
|
against wall clock time (vs specific number of instructions executed),
|
||||||
the simulator framework has been extended to specifically provide event
|
the simulator framework has been extended to specifically provide event
|
||||||
scheduling based on elapsed wall time. A new API can be used by devices
|
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
|
to schedule unit event delivery after the passage of a specific amount
|
||||||
of wall clock time. The api sim_activate_after() provides this
|
of wall clock time. The api sim_activate_after() provides this
|
||||||
capability. This capability is not limited to being available ONLY when
|
capability. This capability is not limited to being available ONLY when
|
||||||
compiling with SIM_SYNCH_IO defined. When SIM_ASYNCH_IO is defined, this
|
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
|
facility is implemented by a thread which drives the delivery of these
|
||||||
events from the host system's clock ticks (interpolated as needed to
|
events from the host system's clock ticks (interpolated as needed to
|
||||||
accomodate hosts with relatively large clock ticks). When SIM_ASYNCH_IO
|
accomodate hosts with relatively large clock ticks). When SIM_ASYNCH_IO
|
||||||
is not defined, this facility is implemented using the traditional simh
|
is not defined, this facility is implemented using the traditional simh
|
||||||
calibrated clock approach. This new approach has been measured to provide
|
calibrated clock approach. This new approach has been measured to provide
|
||||||
clocks which drift far less than the drift realized in prior simh versions.
|
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
|
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
|
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
|
disk also running with idling enabled booted for 4 hours had less that 5
|
||||||
seconds of clock drift (approximately 0.03%).
|
seconds of clock drift (approximately 0.03%).
|
||||||
|
|
||||||
Co-Scheduling Clock and Multiplexer (or other devices)
|
Co-Scheduling Clock and Multiplexer (or other devices)
|
||||||
|
|
||||||
Many simulator devices have needs to periodically executed with timing on the
|
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
|
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.
|
about exactly when they execute as long as they execute frequently enough.
|
||||||
Frequently executing events has the potential to interfere with a simulator's
|
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.
|
attempts to idle when the simulated system isn't actually doing useful work.
|
||||||
|
|
||||||
Interactions with attempts to 'co-schedule' multiplexer polling with clock
|
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:
|
happen under a combination of conditions:
|
||||||
1) a multiplexer device is defined in the simulator configuration,
|
1) a multiplexer device is defined in the simulator configuration,
|
||||||
2) the multiplexor device is NOT attached, and thus is not being managed by
|
2) the multiplexor device is NOT attached, and thus is not being managed by
|
||||||
the asynchronous multiplexer support
|
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
|
attached (such polling will never produce any input, so this is probably
|
||||||
a bug).
|
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:
|
separately by each simulator, and usually was expressed by code of the form:
|
||||||
sim_activate (uptr, clk_cosched (tmxr_poll));
|
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
|
extended to generically provide clock co-scheduling support. The use of this
|
||||||
new capability requires an initial call (usually in the clock device reset
|
new capability requires an initial call (usually in the clock device reset
|
||||||
routing) of the form:
|
routing) of the form:
|
||||||
sim_register_clock_unit (&clk_unit);
|
sim_register_clock_unit (&clk_unit);
|
||||||
Once the clock unit has been registered, co-scheduling is achieved by replacing
|
Once the clock unit has been registered, co-scheduling is achieved by replacing
|
||||||
the earlier sim_activate with the following:
|
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.
|
Run time requirements to use SIM_ASYNCH_IO.
|
||||||
The Posix threads API (pthreads) is required for asynchronous execution.
|
The Posix threads API (pthreads) is required for asynchronous execution.
|
||||||
Most *nix platforms have these APIs available and on these platforms
|
Most *nix platforms have these APIs available and on these platforms
|
||||||
simh is typically built with these available since on these platforms,
|
simh is typically built with these available since on these platforms,
|
||||||
pthreads is required for simh networking support. Windows can also
|
pthreads is required for simh networking support. Windows can also
|
||||||
utilize the pthreads APIs if the compile and run time support for the
|
utilize the pthreads APIs if the compile and run time support for the
|
||||||
win32Pthreads package has been installed on the build system.
|
win32Pthreads package has been installed on the build system.
|
||||||
|
|
||||||
|
|
|
@ -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
|
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.
|
for the SIMH emulator.
|
||||||
|
|
||||||
The XU emulator is a host-independent software emulation of Digital's DEUNA
|
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.
|
are on a direct or hub(repeater) segment.
|
||||||
|
|
||||||
On Windows using the WinPcap interface, the simulated computer can "talk" to
|
On Windows using the WinPcap interface, the simulated computer can "talk" to
|
||||||
the host computer on the same interface. On other platforms with libpcap
|
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
|
(*nix), the simulated computer can not "talk" to the host computer via the
|
||||||
selected interface, since simulator transmitted packets are not received
|
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
|
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
|
in the host and connect them both into the same network; then the host and
|
||||||
the simulator can communicate over the physical LAN.
|
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
|
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
|
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
|
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
|
real network interface. Note that the TAP device and any bridging or routing
|
||||||
must be established before running the simulator; SIMH does not create,
|
must be established before running the simulator; SIMH does not create,
|
||||||
bridge, or route TAP devices for you.
|
bridge, or route TAP devices for you.
|
||||||
|
|
||||||
Integrated Universal TUN/TAP support can be used for host<->simulator network
|
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:
|
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
|
"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
|
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
|
platforms has some way to create a tap pseudo device (and possibly then to
|
||||||
bridge it with a physical network interface).
|
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:
|
sharing a physical NIC and allowing Host<->SIMH vax communications:
|
||||||
|
|
||||||
Linux (Ubuntu 10.04):
|
Linux (Ubuntu 10.04):
|
||||||
|
@ -79,7 +79,7 @@ Linux (Ubuntu 10.04):
|
||||||
/sbin/ifconfig tap0 0.0.0.0
|
/sbin/ifconfig tap0 0.0.0.0
|
||||||
|
|
||||||
# Run simulator and "attach xq tap:tap0"
|
# Run simulator and "attach xq tap:tap0"
|
||||||
|
|
||||||
|
|
||||||
Linux (Fedora Core 18, 20, CentOS, RedHat, etc.):
|
Linux (Fedora Core 18, 20, CentOS, RedHat, etc.):
|
||||||
yum install gcc
|
yum install gcc
|
||||||
|
@ -90,7 +90,7 @@ Linux (Centos 6.x):
|
||||||
yum install gcc
|
yum install gcc
|
||||||
yum install libpcap-devel
|
yum install libpcap-devel
|
||||||
yum install uml_utilities
|
yum install uml_utilities
|
||||||
|
|
||||||
OpenBSD (OpenBSD 4.6)
|
OpenBSD (OpenBSD 4.6)
|
||||||
|
|
||||||
/sbin/ifconfig tun0 create
|
/sbin/ifconfig tun0 create
|
||||||
|
@ -103,10 +103,10 @@ OpenBSD (OpenBSD 4.6)
|
||||||
/sbin/brconfig bridge0 up
|
/sbin/brconfig bridge0 up
|
||||||
|
|
||||||
# Run simulator and "attach xq tap:tun0"
|
# Run simulator and "attach xq tap:tun0"
|
||||||
|
|
||||||
FreeBSD (FreeBSD 11.3)
|
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 create
|
||||||
/sbin/ifconfig tap0 up
|
/sbin/ifconfig tap0 up
|
||||||
|
|
||||||
|
@ -131,38 +131,38 @@ NetBSD (NetBSD 5.0.2)
|
||||||
OSX (Snow Leopard)
|
OSX (Snow Leopard)
|
||||||
OSX Does NOT have native support for tun/tap interfaces. It also does not have native
|
OSX Does NOT have native support for tun/tap interfaces. It also does not have native
|
||||||
support for bridging.
|
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
|
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.
|
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
|
http://sourceforge.net/projects/tuntaposx/files/tuntap/20111101/tuntap_20111101.tar.gz
|
||||||
|
|
||||||
Expand the tarball to a directory.
|
Expand the tarball to a directory.
|
||||||
Invoke the package installer tuntap_20111101.pkg
|
Invoke the package installer tuntap_20111101.pkg
|
||||||
Click through the various prompts accepting things and eventually installing the package.
|
Click through the various prompts accepting things and eventually installing the package.
|
||||||
|
|
||||||
# Build and Run simulator and:
|
# Build and Run simulator and:
|
||||||
sim> attach xq tap:tap0
|
sim> attach xq tap:tap0
|
||||||
sim> ! ifconfig tap0 192.168.6.1 netmask 255.255.255.0
|
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.
|
and things work.
|
||||||
You must run as root for this to 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).
|
VDE (Virtual Distributed Ethernet).
|
||||||
|
|
||||||
Note 1: Using vde based networking is likely more flexible, but it isn't
|
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
|
nearly as efficient. Host OS overhead will always be higher when
|
||||||
vde networking is used as compared to native pcap and/or tun/tap
|
vde networking is used as compared to native pcap and/or tun/tap
|
||||||
networking.
|
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.
|
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.
|
privilege.
|
||||||
|
|
||||||
Linux (Ubuntu 11.10):
|
Linux (Ubuntu 11.10):
|
||||||
|
@ -172,44 +172,44 @@ Linux (Ubuntu 11.10):
|
||||||
|
|
||||||
vde_switch -s /tmp/switch1 -tap tap0 -m 666
|
vde_switch -s /tmp/switch1 -tap tap0 -m 666
|
||||||
ifconfig tap0 192.168.6.1 netmask 255.255.255.0 up
|
ifconfig tap0 192.168.6.1 netmask 255.255.255.0 up
|
||||||
|
|
||||||
# Build and Run simulator and:
|
# Build and Run simulator and:
|
||||||
sim> attach xq vde:/tmp/switch1 #simulator uses IP address 192.168.6.2
|
sim> attach xq vde:/tmp/switch1 #simulator uses IP address 192.168.6.2
|
||||||
|
|
||||||
OSX:
|
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.
|
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
|
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
|
so DECnet, LAT and Clusting can't work on a NAT connected interface, but this may
|
||||||
be the easiest solution for many folks.
|
be the easiest solution for many folks.
|
||||||
|
|
||||||
sim> attach xq nat:
|
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.
|
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
|
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
|
NAT based parameters can be configured on the attach command. HELP XQ ATTACH
|
||||||
will provide useful information. Host to simulator connectivitiy can be
|
will provide useful information. Host to simulator connectivity can be
|
||||||
achieved for a simulator which gets its IP address via DHCP with the following
|
achieved for a simulator which gets its IP address via DHCP with the following
|
||||||
command:
|
command:
|
||||||
|
|
||||||
sim> attach xq nat:tcp=2323:10.0.2.15:23,tcp=2121:10.0.2.15:21
|
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.
|
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
|
networking to a) reach the simulated system and b) allow the simulated system
|
||||||
to reach out to the Internet.
|
to reach out to the Internet.
|
||||||
|
|
||||||
Note: As mentioned above, NAT networking is specifically capable of providing
|
Note: As mentioned above, NAT networking is specifically capable of providing
|
||||||
TCP/IP connectivity. Only expect TCP and UDP traffic to pass through
|
TCP/IP connectivity. Only expect TCP and UDP traffic to pass through
|
||||||
the interface. Do not expect ICMP traffic (ping mostly) to traverse
|
the interface. Do not expect ICMP traffic (ping mostly) to traverse
|
||||||
the NAT boundary. This restriction is a conseqence of host platform
|
the NAT boundary. This restriction is a consequence of host platform
|
||||||
and network limitations regarding direct user mode code generating ICMP
|
and network limitations regarding direct user mode code generating ICMP
|
||||||
packets.
|
packets.
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,34 +217,34 @@ Note: As mentioned above, NAT networking is specifically capable of providing
|
||||||
|
|
||||||
Windows notes:
|
Windows notes:
|
||||||
1. The Npcap package available from https://nmap.org/npcap is the preferred
|
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
|
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
|
developed or supported. These packages for windows simulate the libpcap
|
||||||
package that is freely available for un*x systems.
|
package that is freely available for un*x systems.
|
||||||
|
|
||||||
2. You must *install* the npcap or WinPCAP runtime package.
|
2. You must *install* the npcap or WinPCAP runtime package.
|
||||||
|
|
||||||
3. The first time the npcap/WinPCAP driver is used, it will be dynamically
|
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.
|
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
|
If you need to run as an unprivileged user, you must set the "npf" driver
|
||||||
to autostart.
|
to autostart.
|
||||||
Current Npcap and WinPcap installers provide an option to configure this
|
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
|
at installation time, so if that choice is made, then there is no need for
|
||||||
administrator privileged to run simulators with network support.
|
administrator privileged to run simulators with network support.
|
||||||
|
|
||||||
|
|
||||||
Building on Windows:
|
Building on Windows:
|
||||||
You should be able to build with any of the free compiler environments
|
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++
|
available on the Windows platform. If you want to use the Visual C++
|
||||||
Express 2008 or 2010 interactive development environments, read the file
|
Express 2008 or 2010 interactive development environments, read the file
|
||||||
".\Visual Studio Projects\0ReadMe_Projects.txt" for details about the
|
".\Visual Studio Projects\0ReadMe_Projects.txt" for details about the
|
||||||
required dependencies. Alternatively, you can build simh with networking
|
required dependencies. Alternatively, you can build simh with networking
|
||||||
support using the MinGW GCC compiler environment (32 bit) or the cygwin
|
support using the MinGW GCC compiler environment (32 bit) or the cygwin
|
||||||
environment. Each of these Visual C++, MinGW and cygwin build environments
|
environment. Each of these Visual C++, MinGW and cygwin build environments
|
||||||
require Npcap or WinPcap and Posix threading packages being available.
|
require Npcap or WinPcap and Posix threading packages being available.
|
||||||
These should be located in a directory structure parallel to the current
|
These should be located in a directory structure parallel to the current
|
||||||
simulator source directory.
|
simulator source directory.
|
||||||
|
|
||||||
For Example, the directory structure should look like:
|
For Example, the directory structure should look like:
|
||||||
|
|
||||||
.../simh/simh-master/VAX/vax_cpu.c
|
.../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
|
There are Windows batch files provided to initiate compiles using the MinGW
|
||||||
compiler tool chain. These batch files are located in the same directory
|
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
|
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
|
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
|
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)
|
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.
|
file is invoked with.
|
||||||
|
|
||||||
The current windows network built binaries will run on any system without
|
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
|
regard to whether or not Npcap or WinPcap is installed, and will provide
|
||||||
Network functionality when Npcap or WinPcap is available.
|
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
|
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
|
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
|
distributions provide a libpcap-dev package which has the needed version
|
||||||
of libpcap and the required components to build applications using it.
|
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
|
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
|
library from www.tcpdump.org - see the comments at the top of Sim_ether.c
|
||||||
for details.
|
for details.
|
||||||
|
|
||||||
----- WARNING ----- WARNING ----- WARNING ----- WARNING ----- WARNING -----
|
----- WARNING ----- WARNING ----- WARNING ----- WARNING ----- WARNING -----
|
||||||
|
|
||||||
1. For all platforms, you must run SIMH(scp) with sufficient privilege to
|
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
|
allow the Ethernet card can be set into promiscuous mode and to write
|
||||||
packets through the driver.
|
packets through the driver.
|
||||||
a) For Windows systems this means having administrator privileges to
|
a) For Windows systems this means having administrator privileges to
|
||||||
start the "npf" driver. The current WinPcap installer offers an
|
start the "npf" driver. The current WinPcap installer offers an
|
||||||
option to autostart the "npf" driver when the system boots.
|
option to autostart the "npf" driver when the system boots.
|
||||||
Starting the "npf" driver at boot time means that simulators do
|
Starting the "npf" driver at boot time means that simulators do
|
||||||
not need to run with administrator privileges.
|
not need to run with administrator privileges.
|
||||||
b) For more recent Linux systems, The concepts leveraging "Filesystem
|
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/
|
http://packetlife.net/blog/2010/mar/19/sniffing-wireshark-non-root-user/
|
||||||
describes how to do this for wireshark. The exact same capabilities
|
describes how to do this for wireshark. The exact same capabilities
|
||||||
are needed by SIMH for network support. Use that article as a guide.
|
are needed by SIMH for network support. Use that article as a guide.
|
||||||
c) For Unix/Unix-like systems which use bpf devices (NetBSD,
|
c) For Unix/Unix-like systems which use bpf devices (NetBSD,
|
||||||
OpenBSD, FreeBSD and OS/X) it is possible to set permissions on
|
OpenBSD, FreeBSD and OS/X) it is possible to set permissions on
|
||||||
the bpf devices to allow read and write access to users other
|
the bpf devices to allow read and write access to users other
|
||||||
than root (For example: chmod 666 /dev/bpf*). Doing this, has
|
than root (For example: chmod 666 /dev/bpf*). Doing this, has
|
||||||
its own security issues.
|
its own security issues.
|
||||||
d) For other platforms this will likely mean running as root.
|
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.
|
will be welcomed.
|
||||||
|
|
||||||
2. If you want to use TAP devices, and any surrounding system network/bridge
|
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
|
(possibly at system boot time), using the TAP devices can be done without
|
||||||
root privileges.
|
root privileges.
|
||||||
|
|
||||||
Building on Linux, {Free|Net|Open}BSD, OS/X, Solaris, other *nix:
|
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:
|
operating system. Sources:
|
||||||
All : http://www.tcpdump.org/
|
All : http://www.tcpdump.org/
|
||||||
Older versions of libpcap can be found, for various systems, at:
|
Older versions of libpcap can be found, for various systems, at:
|
||||||
Linux :
|
Linux :
|
||||||
Debian Based distributions:
|
Debian Based distributions:
|
||||||
# apt-get install libpcap-dev
|
# apt-get install libpcap-dev
|
||||||
RedHat/Fedora Based distributions:
|
RedHat/Fedora Based distributions:
|
||||||
# yum install libpcap-devel
|
# yum install libpcap-devel
|
||||||
|
|
||||||
OS/X : The libpcap components are installed as part of the Xcode
|
OS/X : The libpcap components are installed as part of the Xcode
|
||||||
developer package. Instructions to install Xcode on various
|
developer package. Instructions to install Xcode on various
|
||||||
OSX versions are available at:
|
OSX versions are available at:
|
||||||
https://guide.macports.org/chunked/installing.xcode.html
|
https://guide.macports.org/chunked/installing.xcode.html
|
||||||
Be sure to install the command line tools which are installed
|
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.
|
versions of the Apple developer support.
|
||||||
|
|
||||||
HP-UX : ftp://hpux.connect.org.uk/hpux/Networking/Admin/
|
HP-UX : ftp://hpux.connect.org.uk/hpux/Networking/Admin/
|
||||||
|
|
||||||
NOTE: The repositories for older versions of these platforms
|
NOTE: The repositories for older versions of these platforms
|
||||||
don't contain a version of libpcap greater than 0.8.1.
|
don't contain a version of libpcap greater than 0.8.1.
|
||||||
However, most(all) recent releases of *nix environments
|
However, most(all) recent releases of *nix environments
|
||||||
ship with sufficiently recent versions of libpcap either
|
ship with sufficiently recent versions of libpcap either
|
||||||
automatically installed or available for installation as
|
automatically installed or available for installation as
|
||||||
part of the distribution.
|
part of the distribution.
|
||||||
The OS provided libpcap-dev components will be prefereable
|
The OS provided libpcap-dev components will be preferable
|
||||||
to a package built from www.tcpdump.org sources. This is
|
to a package built from www.tcpdump.org sources. This is
|
||||||
due to the fact that various OS supplied packages will
|
due to the fact that various OS supplied packages will
|
||||||
depend on the OS supplied libpcap. The improper build or
|
depend on the OS supplied libpcap. The improper build or
|
||||||
install of the www.tcpdump.org source package can conflict
|
install of the www.tcpdump.org source package can conflict
|
||||||
with the OS provided one and break the OS provided
|
with the OS provided one and break the OS provided
|
||||||
applications (i.e. tcpdump and/or wireshark) as well as
|
applications (i.e. tcpdump and/or wireshark) as well as
|
||||||
not working correctly for use by simh.
|
not working correctly for use by simh.
|
||||||
|
|
||||||
2. If you install the vendor supplied libpcap-dev package then the simh
|
2. If you install the vendor supplied libpcap-dev package then the simh
|
||||||
makefile will automatically use the vendor supplied library without any
|
makefile will automatically use the vendor supplied library without any
|
||||||
additional arguments. If you have downloaded and built libpcap from
|
additional arguments. If you have downloaded and built libpcap from
|
||||||
www.tcpdump.org, then the existing makefile will detect that this is
|
www.tcpdump.org, then the existing makefile will detect that this is
|
||||||
the case and try to use that.
|
the case and try to use that.
|
||||||
|
|
||||||
3. The makefile defaults to building simulators with network support which
|
3. The makefile defaults to building simulators with network support which
|
||||||
dynamically load the libpcap library. This means that the same simulator
|
dynamically load the libpcap library. This means that the same simulator
|
||||||
binaries will run on any system whether or not libpcap is installed. If
|
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
|
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
|
typing 'make USE_NETWORK=1'. You must build with gcc to do this. There
|
||||||
is no observable benefit to statically linking against libpcap. Support
|
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.
|
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
|
components available and installed with the operating system. The packages
|
||||||
which are available for this platform install include and library files in
|
which are available for this platform install include and library files in
|
||||||
user specified locations. When building on these platforms the library
|
user specified locations. When building on these platforms the library
|
||||||
path must be specified on the make command line. This can be done with:
|
path must be specified on the make command line. This can be done with:
|
||||||
'make LPATH=/usr/lib:/usr/local/lib'
|
'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
|
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
|
when required VCI promiscuous mode support was added. Hobbyists can
|
||||||
get the required version of VMS from the OpenVMS Alpha Hobbyist Kit 3.0.
|
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.
|
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.
|
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
|
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
|
VAX780, and PDP11. The descrip.mms driven builds will also build the
|
||||||
pcap library and build and install the VCI execlet.
|
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
|
http://simh.trailing-edge.com/sources/vms-pcap.zip
|
||||||
2. Unzip it into the base of the SIMH distribution directory.
|
2. Unzip it into the base of the SIMH distribution directory.
|
||||||
3. Build the simulator(s) with MMS or MMK:
|
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
|
systems also work. RSTS/E v10.1 has preliminary support - RSTS/E boots and
|
||||||
enables the XH (XQ) device - DECNET and LAT software have not been tested.
|
enables the XH (XQ) device - DECNET and LAT software have not been tested.
|
||||||
|
|
||||||
The XU module has been tested by a third party for basic packet functionality
|
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
|
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
|
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.
|
RSX11M+ system image that also contains DECNET, LAT, and/or TCP/IP software.
|
||||||
|
@ -486,9 +486,9 @@ Dave
|
||||||
===============================================================================
|
===============================================================================
|
||||||
Change Log
|
Change Log
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
||||||
01-Mar-12 AGN Added support for building using Cygwin on Windows
|
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
|
and mad it work when compiling under Cygwin
|
||||||
29-Feb-12 MP Fixed MAC Address Conflict detection support
|
29-Feb-12 MP Fixed MAC Address Conflict detection support
|
||||||
28-Feb-12 MP Fixed overrun bug in eth_devices which caused SEGFAULTs
|
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
|
17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms
|
||||||
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
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
|
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
|
vector assignments
|
||||||
12-Aug-11 MP Cleaned up payload length determination
|
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
|
reading and writing is enabled
|
||||||
07-Jul-11 MB VMS Pcap (from Mike Burke)
|
07-Jul-11 MB VMS Pcap (from Mike Burke)
|
||||||
- Fixed Alpha issues
|
- Fixed Alpha issues
|
||||||
- Added OpenVMS Integrety support
|
- Added OpenVMS Integrity support
|
||||||
20-Apr-11 MP Fixed save/restore behavior
|
20-Apr-11 MP Fixed save/restore behavior
|
||||||
12-Jan-11 DTH Added SHOW XU FILTERS modifier
|
12-Jan-11 DTH Added SHOW XU FILTERS modifier
|
||||||
11-Jan-11 DTH Corrected DEUNA/DELUA SELFTEST command, enabling use by
|
11-Jan-11 DTH Corrected DEUNA/DELUA SELFTEST command, enabling use by
|
||||||
VMS 3.7, VMS 4.7, and Ultrix 1.1
|
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)
|
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
|
USE_READER_THREAD does I/O in separate threads. This helps
|
||||||
throughput since it allows these I/O bound threads to preempt
|
throughput since it allows these I/O bound threads to preempt
|
||||||
the main thread (which is executing simulated instructions).
|
the main thread (which is executing simulated instructions).
|
||||||
09-Dec-10 MP allowed more flexible parsing of MAC address strings
|
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
|
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
|
07-Dec-10 MP Reworked DECnet self detection to the more general approach
|
||||||
of loopback self when any Physical Address is being set.
|
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 Added loopback processing support to pdp11_xu.c
|
||||||
06-Dec-10 MP Fixed loopback processing to correctly handle forward packets.
|
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.
|
USE_READER_THREAD is defined.
|
||||||
30-Nov-10 MP Fixed the fact that no broadcast packets were received by the DEUNA
|
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.
|
(in and out) to sometimes not interrupt the CPU after processing.
|
||||||
17-Jun-10 MP Fixed bug in the AUTODIN II hash filtering.
|
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.
|
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.
|
platforms.
|
||||||
31-May-10 MP Added support for more TOE (TCP Offload Engine) features for IPv4
|
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
|
network traffic from the host and/or from hosts on the LAN. These
|
||||||
new TOE features are: LSO (Large Send Offload) and Jumbo packet
|
new TOE features are: LSO (Large Send Offload) and Jumbo packet
|
||||||
fragmentation support. These features allow a simulated network
|
fragmentation support. These features allow a simulated network
|
||||||
device to support traffic when a host leverages a NIC's Large
|
device to support traffic when a host leverages a NIC's Large
|
||||||
Send Offload capabilities to fragment and/or segment outgoing
|
Send Offload capabilities to fragment and/or segment outgoing
|
||||||
network traffic. Additionally a simulated network device can
|
network traffic. Additionally a simulated network device can
|
||||||
reasonably exist on a LAN which is configured to use Jumbo frames.
|
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)
|
packets from a host with a NIC which has TOE (TCP Offload Engine)
|
||||||
enabled which is expected to implement the checksum computations
|
enabled which is expected to implement the checksum computations
|
||||||
in hardware. Since we catch packets before they arrive at the
|
in hardware. Since we catch packets before they arrive at the
|
||||||
NIC the expected checksum insertions haven't been performed yet.
|
NIC the expected checksum insertions haven't been performed yet.
|
||||||
This processing is only done for packets sent from the host to
|
This processing is only done for packets sent from the host to
|
||||||
the guest we're supporting. In general this will be a relatively
|
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
|
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
|
determination of packets specifically arriving from the host we
|
||||||
need to know the hardware MAC address of the host NIC. Currently
|
need to know the hardware MAC address of the host NIC. Currently
|
||||||
determining a NIC's MAC address is relatively easy on Windows.
|
determining a NIC's MAC address is relatively easy on Windows.
|
||||||
The non-windows code works on linux and may work on other *nix
|
The non-windows code works on linux and may work on other *nix
|
||||||
platforms either as is or with slight modifications. The code,
|
platforms either as is or with slight modifications. The code,
|
||||||
as implemented, only messes with this activity if the host
|
as implemented, only messes with this activity if the host
|
||||||
interface MAC address can be determined.
|
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
|
than ETH_MIN_PACKET in length. These come from packets
|
||||||
looped back by some bridging mechanism and need to be padded
|
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
|
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.
|
devices, AND it belongs here to get CRC processing right.
|
||||||
15-Aug-08 MP Fixed transmitted packets to have the correct source MAC address.
|
15-Aug-08 MP Fixed transmitted packets to have the correct source MAC address.
|
||||||
Fixed incorrect address filter setting calling eth_filter().
|
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=.
|
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.
|
will succeed.
|
||||||
03-Mar-08 MP Added DELQA-T (aka DELQA Plus) device emulation support.
|
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
|
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
|
received packets due to the receiver being disabled, or due to the
|
||||||
XQ device's packet receive queue being full.
|
XQ device's packet receive queue being full.
|
||||||
Fixed bug in receive processing when we're not polling. This could
|
Fixed bug in receive processing when we're not polling. This could
|
||||||
cause receive processing to never be activated again if we don't
|
cause receive processing to never be activated again if we don't
|
||||||
read all available packets via eth_read each time we get the
|
read all available packets via eth_read each time we get the
|
||||||
opportunity.
|
opportunity.
|
||||||
31-Jan-08 MP Added the ability to Coalesce received packet interrupts. This
|
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
|
microseconds to delay the triggering of an interrupt when a packet
|
||||||
is received.
|
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.
|
polling for packet read completion.
|
||||||
29-Jan-08 MP Changed the sanity and id timer mechanisms to use a separate timer
|
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
|
unit so that transmit and receive activities can be dealt with
|
||||||
by the normal xq_svc routine.
|
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.
|
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
|
25-Jan-08 MP Enabled the SET XQ POLL to be meaningful if the simulator currently
|
||||||
doesn't support idling.
|
doesn't support idling.
|
||||||
|
@ -594,7 +594,7 @@ Dave
|
||||||
all debug output goes to the same place.
|
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
|
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
|
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.
|
while other things were being tested.
|
||||||
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
23-Jan-08 MP Added debugging support to display packet headers and packet data
|
||||||
18-Jun-07 RMS Added UNIT_IDLE flag
|
18-Jun-07 RMS Added UNIT_IDLE flag
|
||||||
|
@ -608,21 +608,21 @@ Dave
|
||||||
LANCE style AUTODIN II based hashed filtering.
|
LANCE style AUTODIN II based hashed filtering.
|
||||||
07-Feb-08 MP Added eth_show_dev to display Ethernet state
|
07-Feb-08 MP Added eth_show_dev to display Ethernet state
|
||||||
Changed the return value from eth_read to return whether
|
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
|
checked constant return value that previously was being
|
||||||
supplied.
|
supplied.
|
||||||
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
|
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
|
||||||
USE_READER_THREAD is enabled) to allow packet reception
|
USE_READER_THREAD is enabled) to allow packet reception
|
||||||
to dynamically update the simulator event queue and
|
to dynamically update the simulator event queue and
|
||||||
potentially avoid polling for I/O. This provides a minimal
|
potentially avoid polling for I/O. This provides a minimal
|
||||||
overhead (no polling) maximal responsiveness for network
|
overhead (no polling) maximal responsiveness for network
|
||||||
activities.
|
activities.
|
||||||
29-Jan-08 MP Properly sequenced activities in eth_close to avoid a race
|
29-Jan-08 MP Properly sequenced activities in eth_close to avoid a race
|
||||||
condition when USE_READER_THREAD is enabled.
|
condition when USE_READER_THREAD is enabled.
|
||||||
25-Jan-08 MP Changed the following 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.
|
in packet data which is read.
|
||||||
- Added call to pcap_setmintocopy to minimize packet
|
- Added call to pcap_setmintocopy to minimize packet
|
||||||
delivery latencies.
|
delivery latencies.
|
||||||
- Added ethq_destroy and used it to avoid a memory leak in
|
- Added ethq_destroy and used it to avoid a memory leak in
|
||||||
eth_close.
|
eth_close.
|
||||||
|
@ -632,8 +632,8 @@ Dave
|
||||||
Fixed the bpf filter used when no traffic is to be matched.
|
Fixed the bpf filter used when no traffic is to be matched.
|
||||||
Reworked eth_add_packet_crc32 implementation to avoid an
|
Reworked eth_add_packet_crc32 implementation to avoid an
|
||||||
extra buffer copy while reading packets.
|
extra buffer copy while reading packets.
|
||||||
Fixed up #ifdef's relating to USE_SHARED so that setting
|
Fixed up #ifdef's relating to USE_SHARED so that setting
|
||||||
USE_SHARED or USE_NETWORK will build a working network
|
USE_SHARED or USE_NETWORK will build a working network
|
||||||
environment.
|
environment.
|
||||||
23-Jan-08 MP Reworked eth_packet_trace and eth_packet_trace_ex to allow
|
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
|
only output Ethernet header+crc and provide a mechanism for
|
||||||
|
@ -719,7 +719,7 @@ Dave
|
||||||
1. Added VMScluster support (thanks to Mark Pizzolato)
|
1. Added VMScluster support (thanks to Mark Pizzolato)
|
||||||
2. Verified VAX remote boot functionality (>>>B XQA0)
|
2. Verified VAX remote boot functionality (>>>B XQA0)
|
||||||
3. Added major performance enhancements (thanks to Mark Pizzolato again)
|
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
|
5. Added local packet processing
|
||||||
6. Added system id broadcast
|
6. Added system id broadcast
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# SIMH_SYSTEM_ID: Roughly analogous to the autoconf system triple. Used (almost exclusively)
|
# 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})
|
set(SIMH_SYSTEM_ID ${CMAKE_SYSTEM_NAME})
|
||||||
string(REPLACE "." ";" version_list ${CMAKE_SYSTEM_VERSION})
|
string(REPLACE "." ";" version_list ${CMAKE_SYSTEM_VERSION})
|
||||||
list(GET version_list 0 version_major)
|
list(GET version_list 0 version_major)
|
||||||
|
@ -163,9 +163,9 @@ if (NOT DEFINED MAC_UNIVERSAL)
|
||||||
else ()
|
else ()
|
||||||
set(MAC_UNIVERSAL_OPTVAL ${MAC_UNIVERSAL})
|
set(MAC_UNIVERSAL_OPTVAL ${MAC_UNIVERSAL})
|
||||||
if (MAC_UNIVERSAL_OPTVAL)
|
if (MAC_UNIVERSAL_OPTVAL)
|
||||||
message(STATUS "macOS unversal binaries WILL BE BUILT.")
|
message(STATUS "macOS universal binaries WILL BE BUILT.")
|
||||||
else ()
|
else ()
|
||||||
message(STATUS "macOS unversal binaries NOT WILL BE BUILT.")
|
message(STATUS "macOS universal binaries NOT WILL BE BUILT.")
|
||||||
endif ()
|
endif ()
|
||||||
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})
|
if (NOT (USING_VCPKG OR NO_DEP_BUILD) AND NOT EXISTS ${SIMH_DEP_TOPDIR})
|
||||||
message(STATUS "Creating dependency library directory hierarchy")
|
message(STATUS "Creating dependency library directory hierarchy")
|
||||||
execute_process(
|
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
|
${SIMH_DEP_TOPDIR}/bin
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
|
@ -297,7 +297,7 @@ include(platform-quirks)
|
||||||
|
|
||||||
# Find packages, arrange for dependency download/compile/install:
|
# 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.
|
# SIMH_DEP_TARGETS is the list of dependency targets' names that we'll actually build.
|
||||||
|
|
||||||
set(SIMH_BUILD_DEPS)
|
set(SIMH_BUILD_DEPS)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
- [Why CMake?](#why-cmake)
|
- [Why CMake?](#why-cmake)
|
||||||
- [Before You Begin Building...](#before-you-begin-building)
|
- [Before You Begin Building...](#before-you-begin-building)
|
||||||
- [Toolchains and Tools](#toolchains-and-tools)
|
- [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)
|
- [Windows XP-compatible/Server 2003 binaries](#windows-xp-compatibleserver-2003-binaries)
|
||||||
- [Feature Libraries](#feature-libraries)
|
- [Feature Libraries](#feature-libraries)
|
||||||
- [Linux, macOS and MinGW-w64](#linux-macos-and-mingw-w64)
|
- [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
|
- Unix Makefiles
|
||||||
- [MinGW Makefiles][mingw64]
|
- [MinGW Makefiles][mingw64]
|
||||||
- [Ninja][ninja]
|
- [Ninja][ninja]
|
||||||
- macOS XCode
|
- macOS Xcode
|
||||||
- MS Visual Studio solutions (2015, 2017, 2019, 2022)
|
- MS Visual Studio solutions (2015, 2017, 2019, 2022)
|
||||||
- IDE build wrappers ([Sublime Text][sublime] and [CodeBlocks][codeblocks])
|
- 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
|
_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.
|
modifying an existing installation.
|
||||||
|
|
||||||
- New install
|
- 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.
|
_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.
|
modifying an existing installation.
|
||||||
|
|
||||||
- New installation: Follow the VS 2022 "New install" instructions. The steps are
|
- 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:\...\vcpkg> cd ..\open-simh
|
||||||
PS C:\...\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
|
[^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
|
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.)
|
`x64-Release` configuration. And wait for reconfiguration to finish (again.)
|
||||||
|
|
||||||
5. Select `Build All` from the `Build` menu, or equivalently chord `Ctrl-Shift-B`
|
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
|
- When all dependency feature libraries have been built, the build process
|
||||||
__will__ unexpectedly terminate with a _"failed recompaction: Permission
|
__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
|
Choose `Delete Cache and Reconfigure` from the `Project` menu. This will
|
||||||
cause CMake to reconfigure the project and detect the dependency feature
|
cause CMake to reconfigure the project and detect the dependency feature
|
||||||
|
@ -1141,7 +1141,7 @@ add_simulator(3b2
|
||||||
TEST 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
|
- The first argument is the simulator's executable name: `3b2`. This generates
|
||||||
an executable named `3b2` on Unix platforms or `3b2.exe` on Windows.
|
an executable named `3b2` on Unix platforms or `3b2.exe` on Windows.
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
|
|
||||||
#### CDC 1700 simulator from John Forecast
|
#### 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
|
#### 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
|
#### 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:
|
In addition, there is explicit support for per device help:
|
||||||
|
|
||||||
HELP dev
|
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
|
$ unzip -a simh-vms-pcap.zip
|
||||||
$ rename [.simh-vms-pcap]pcap-vms.dir []
|
$ 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
|
located in a directory at the same level as the directory containing the
|
||||||
simh source files. For example, if these exist here:
|
simh source files. For example, if these exist here:
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
:: If this procedure is not invoked from a Developer command prompt
|
:: If this procedure is not invoked from a Developer command prompt
|
||||||
:: then the VS2008 tools are preferred if VS2008 is installed,
|
:: then the VS2008 tools are preferred if VS2008 is installed,
|
||||||
:: otherwise the installed Visual Studio tools will be used
|
:: 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
|
:: If this procedure is invoked from a Developer command prompt
|
||||||
:: then the tool chain provided with the command prompt is used
|
:: then the tool chain provided with the command prompt is used
|
||||||
|
|
64
descrip.mms
64
descrip.mms
|
@ -10,7 +10,7 @@
|
||||||
# HP C V7.3-009-48GBT (AXP), HP C V7.2-001 (IA64) and v6.4-005(VAX).
|
# 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
|
# 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.
|
# simulators.
|
||||||
#
|
#
|
||||||
# This build script will accept the following build options.
|
# This build script will accept the following build options.
|
||||||
|
@ -25,9 +25,9 @@
|
||||||
# ECLIPSE Just Build The Data General Eclipse.
|
# ECLIPSE Just Build The Data General Eclipse.
|
||||||
# GRI Just Build The GRI Corporation GRI-909.
|
# GRI Just Build The GRI Corporation GRI-909.
|
||||||
# LGP Just Build The Royal-McBee LGP-30.
|
# LGP Just Build The Royal-McBee LGP-30.
|
||||||
# H316 Just Build The Honewell 316/516.
|
# H316 Just Build The Honeywell 316/516.
|
||||||
# HP2100 Just Build The Hewlett-Packard HP-2100.
|
# HP2100 Just Build The Hewlett-Packard HP-2100.
|
||||||
# HP3000 Just Build The Hewlett-Packard HP-3000.
|
# HP3000 Just Build The Hewlett-Packard HP-3000.
|
||||||
# I1401 Just Build The IBM 1401.
|
# I1401 Just Build The IBM 1401.
|
||||||
# I1620 Just Build The IBM 1620.
|
# I1620 Just Build The IBM 1620.
|
||||||
# I7094 Just Build The IBM 7094.
|
# I7094 Just Build The IBM 7094.
|
||||||
|
@ -75,22 +75,22 @@
|
||||||
# VAX8600 Just Build The DEC VAX8600.
|
# VAX8600 Just Build The DEC VAX8600.
|
||||||
# CLEAN Will Clean Files Back To Base Kit.
|
# 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..
|
# information) use..
|
||||||
#
|
#
|
||||||
# MMK/MACRO=(DEBUG=1)
|
# MMK/MACRO=(DEBUG=1)
|
||||||
#
|
#
|
||||||
# This will produce an executable named {Simulator}-{I64|VAX|AXP}-DBG.EXE
|
# 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..
|
# use..
|
||||||
#
|
#
|
||||||
# MMK/MACRO=(NOASYNCH=1)
|
# 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.
|
# 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
|
# DEC/Compaq/HP Compiler version V6.5-001 or later. To build using an
|
||||||
# older compiler, networking support must be disabled. Use...
|
# 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_DIR = SYS$DISK:[.SDS]
|
||||||
SDS_LIB = $(LIB_DIR)SDS-$(ARCH).OLB
|
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_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_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
|
$(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
|
$! No further actions necessary
|
||||||
.ENDIF
|
.ENDIF
|
||||||
|
|
||||||
CLEAN :
|
CLEAN :
|
||||||
$!
|
$!
|
||||||
$! Clean out all targets and building Remnants
|
$! 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.
|
# 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
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
.ENDIF
|
.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.
|
# 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
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
|
|
||||||
$(PDP6_LIB) :
|
$(PDP6_LIB) :
|
||||||
$! Due To The Use Of INT64 We Can't Build The
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
|
|
||||||
$(KA10_LIB) :
|
$(KA10_LIB) :
|
||||||
$! Due To The Use Of INT64 We Can't Build The
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
|
|
||||||
$(KI10_LIB) :
|
$(KI10_LIB) :
|
||||||
$! Due To The Use Of INT64 We Can't Build The
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
.ENDIF
|
.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.
|
# 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
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
.ENDIF
|
.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.
|
# 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
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
.ENDIF
|
.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.
|
# 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
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
.ENDIF
|
.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.
|
# 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
|
$! Due To The Use Of INT64 We Can't Build The
|
||||||
$! $(MMS$TARGET) Library On VAX.
|
$! $(MMS$TARGET) Library On VAX.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
ATT3B2 :
|
ATT3B2 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)ATT3B2-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)ATT3B2-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
ALTAIRZ80 :
|
ALTAIRZ80 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)ALTAIRZ80-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)ALTAIRZ80-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
ECLIPSE :
|
ECLIPSE :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)ECLIPSE-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)ECLIPSE-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
PDP10 :
|
PDP10 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)PDP10-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)PDP10-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
|
|
||||||
PDP6 :
|
PDP6 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)PDP6-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)PDP6-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
|
|
||||||
PDP10-KA :
|
PDP10-KA :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)PDP10-KA-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)PDP10-KA-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
|
|
||||||
PDP10-KI :
|
PDP10-KI :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)PDP10-KI-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)PDP10-KI-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
BESM6 :
|
BESM6 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)BESM6-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)BESM6-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
B5500 :
|
B5500 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)B5500-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)B5500-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
CDC1700 :
|
CDC1700 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)CDC1700-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)CDC1700-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.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
|
# Else We Are On VAX And Tell The User We Can't Build On VAX
|
||||||
# Due To The Use Of INT64.
|
# Due To The Use Of INT64.
|
||||||
#
|
#
|
||||||
I7094 :
|
I7094 :
|
||||||
$! Sorry, Can't Build $(BIN_DIR)I7094-$(ARCH).EXE Simulator
|
$! Sorry, Can't Build $(BIN_DIR)I7094-$(ARCH).EXE Simulator
|
||||||
$! Because It Requires The Use Of INT64.
|
$! Because It Requires The Use Of INT64.
|
||||||
.ENDIF
|
.ENDIF
|
||||||
|
@ -3375,9 +3375,9 @@ $(PCAP_VCI) : $(PCAP_VCMDIR)PCAPVCM.EXE
|
||||||
$!
|
$!
|
||||||
$! Installing the PCAP VCI Execlet in SYS$LOADABLE_IMAGES
|
$! 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
|
$! Building The PCAP VCI Execlet
|
||||||
$!
|
$!
|
||||||
|
|
6
helpx
6
helpx
|
@ -226,7 +226,7 @@ while( <STDIN> ) {
|
||||||
next;
|
next;
|
||||||
} elsif ($tok eq 'word' && $val =~ /^fprint_(set|show|reg)_help(?:_ex)?$/) {
|
} elsif ($tok eq 'word' && $val =~ /^fprint_(set|show|reg)_help(?:_ex)?$/) {
|
||||||
my %alt = ( set => "\$Set commands",
|
my %alt = ( set => "\$Set commands",
|
||||||
show => "\$Show commmands",
|
show => "\$Show commands",
|
||||||
reg => "\$Registers" );
|
reg => "\$Registers" );
|
||||||
$b .= "/* Use \"$alt{$1}\" topic instead:\n";
|
$b .= "/* Use \"$alt{$1}\" topic instead:\n";
|
||||||
do {
|
do {
|
||||||
|
@ -272,7 +272,7 @@ while( <STDIN> ) {
|
||||||
" The SET commands for the device will automagically display above\n"
|
" The SET commands for the device will automagically display above\n"
|
||||||
" this line. Add any special notes.\n"
|
" this line. Add any special notes.\n"
|
||||||
"2 OSNAME1\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"
|
" If the device needs special configuration for a particular OS, a subtopic\n"
|
||||||
" for each such OS goes here.\n"
|
" for each such OS goes here.\n"
|
||||||
"2 Files\n"
|
"2 Files\n"
|
||||||
|
@ -299,7 +299,7 @@ while( <STDIN> ) {
|
||||||
"1 Related Devices\n"
|
"1 Related Devices\n"
|
||||||
" If devices are configured or used together, list the other devices here.\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"
|
" 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 **** */
|
/* **** Your converted help text starts hare **** */
|
||||||
|
|
||||||
|
|
142
makefile
142
makefile
|
@ -19,21 +19,21 @@
|
||||||
# In general, the logic below will detect and build with the available
|
# In general, the logic below will detect and build with the available
|
||||||
# features which the host build environment provides.
|
# 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 available at build time. Support to statically linking against libpcap
|
||||||
# is deprecated and may be removed in the future. Static linking against
|
# 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
|
# libpcap can be enabled if GNU make is invoked with USE_NETWORK=1 on the
|
||||||
# command line.
|
# 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
|
# one such example. The packages which are available for this platform
|
||||||
# install include files and libraries in user specified directories. In
|
# install include files and libraries in user specified directories. In
|
||||||
# order for this makefile to locate where these components may have been
|
# order for this makefile to locate where these components may have been
|
||||||
# installed, gmake should be invoked with LPATH=/usr/lib:/usr/local/lib
|
# installed, gmake should be invoked with LPATH=/usr/lib:/usr/local/lib
|
||||||
# defined (adjusted as needed depending on where they may be installed).
|
# defined (adjusted as needed depending on where they may be installed).
|
||||||
#
|
#
|
||||||
# In the unlikely event that someone wants to build network capable
|
# In the unlikely event that someone wants to build network capable
|
||||||
# simulators without networking support, invoking GNU make with
|
# simulators without networking support, invoking GNU make with
|
||||||
# NONETWORK=1 on the command line will do the trick.
|
# NONETWORK=1 on the command line will do the trick.
|
||||||
#
|
#
|
||||||
# By default, video support is enabled if the SDL2 development
|
# 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
|
# If debugging is desired, then GNU make can be invoked with
|
||||||
# DEBUG=1 on the command line.
|
# DEBUG=1 on the command line.
|
||||||
#
|
#
|
||||||
# When building compiler optimized binaries with the gcc or clang
|
# When building compiler optimized binaries with the gcc or clang
|
||||||
# compilers, invoking GNU make with LTO=1 on the command line will
|
# compilers, invoking GNU make with LTO=1 on the command line will
|
||||||
# cause the build to use Link Time Optimization to maximally optimize
|
# cause the build to use Link Time Optimization to maximally optimize
|
||||||
# the results. Link Time Optimization can report errors which aren't
|
# the results. Link Time Optimization can report errors which aren't
|
||||||
# otherwise detected and will also take significantly longer to
|
# otherwise detected and will also take significantly longer to
|
||||||
# complete. Additionally, non debug builds default to build with an
|
# complete. Additionally, non debug builds default to build with an
|
||||||
# optimization level of -O2. This optimization level can be changed
|
# optimization level of -O2. This optimization level can be changed
|
||||||
# by invoking GNU OPTIMIZE=-O3 (or whatever optimize value you want)
|
# by invoking GNU OPTIMIZE=-O3 (or whatever optimize value you want)
|
||||||
# on the command line if desired.
|
# on the command line if desired.
|
||||||
#
|
#
|
||||||
# The default setup will fail simulator build(s) if the compile
|
# The default setup will fail simulator build(s) if the compile
|
||||||
# produces any warnings. These should be cleaned up before new
|
# produces any warnings. These should be cleaned up before new
|
||||||
# or changd code is accepted into the code base. This option
|
# or changed code is accepted into the code base. This option
|
||||||
# can be overridden if GNU make is invoked with WARNINGS=ALLOWED
|
# can be overridden if GNU make is invoked with WARNINGS=ALLOWED
|
||||||
# on the command line.
|
# on the command line.
|
||||||
#
|
#
|
||||||
# The default build will run per simulator tests if they are
|
# The default build will run per simulator tests if they are
|
||||||
# available. If building without running tests is desired,
|
# available. If building without running tests is desired,
|
||||||
# then GNU make should be invoked with TESTS=0 on the command
|
# then GNU make should be invoked with TESTS=0 on the command
|
||||||
# line.
|
# line.
|
||||||
#
|
#
|
||||||
# Default test execution will produce summary output. Detailed
|
# 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.
|
# TEST_ARG=-v on the command line.
|
||||||
#
|
#
|
||||||
# simh project support is provided for simulators that are built with
|
# simh project support is provided for simulators that are built with
|
||||||
# dependent packages provided with the or by the operating system
|
# dependent packages provided with the or by the operating system
|
||||||
# distribution OR for platforms where that isn't directly available
|
# distribution OR for platforms where that isn't directly available
|
||||||
# (OS X/macOS) by packages from specific package management systems (MacPorts
|
# (OS X/macOS) by packages from specific package management systems (MacPorts
|
||||||
# or Homebrew). Users wanting to build simulators with locally built
|
# or Homebrew). Users wanting to build simulators with locally built
|
||||||
# dependent packages or packages provided by an unsupported package
|
# dependent packages or packages provided by an unsupported package
|
||||||
# management system may be able to override where this procedure looks
|
# management system may be able to override where this procedure looks
|
||||||
# for include files and/or libraries. Overrides can be specified by define
|
# for include files and/or libraries. Overrides can be specified by define
|
||||||
# exported environment variables or GNU make command line arguments which
|
# exported environment variables or GNU make command line arguments which
|
||||||
# specify INCLUDES and/or LIBRARIES.
|
# specify INCLUDES and/or LIBRARIES.
|
||||||
# Each of these, if specified, must be the complete list include directories
|
# 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/:...)
|
# 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.
|
# ToolChain, you're free to solve this problem on your own. Good Luck.
|
||||||
#
|
#
|
||||||
# Some environments may have the LLVM (clang) compiler installed as
|
# 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.
|
# invoke make with GCC=clang.
|
||||||
#
|
#
|
||||||
# Internal ROM support can be disabled if GNU make is invoked with
|
# 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)
|
$(shell git log -1 --pretty="SIM_GIT_COMMIT_ID %H$(GIT_EXTRA_FILES)%nSIM_GIT_COMMIT_TIME $(isodate)" >.git-commit-id)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
LTO_EXCLUDE_VERSIONS =
|
LTO_EXCLUDE_VERSIONS =
|
||||||
PCAPLIB = pcap
|
PCAPLIB = pcap
|
||||||
ifeq (agcc,$(findstring agcc,${GCC})) # Android target build?
|
ifeq (agcc,$(findstring agcc,${GCC})) # Android target build?
|
||||||
OS_CCDEFS += -D_GNU_SOURCE
|
OS_CCDEFS += -D_GNU_SOURCE
|
||||||
|
@ -585,16 +585,16 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
|
||||||
LIBEXTSAVE := ${LIBEXT}
|
LIBEXTSAVE := ${LIBEXT}
|
||||||
LIBEXT = a
|
LIBEXT = a
|
||||||
ifneq (,$(call find_lib,pthread))
|
ifneq (,$(call find_lib,pthread))
|
||||||
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
|
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
|
||||||
OS_LDFLAGS += -lpthread
|
OS_LDFLAGS += -lpthread
|
||||||
$(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread))
|
$(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread))
|
||||||
else
|
else
|
||||||
ifneq (,$(findstring Haiku,$(OSTYPE)))
|
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))
|
$(info using libpthread: $(call find_include,pthread))
|
||||||
else
|
else
|
||||||
ifeq (Darwin,$(OSTYPE))
|
ifeq (Darwin,$(OSTYPE))
|
||||||
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
|
AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO
|
||||||
OS_LDFLAGS += -lpthread
|
OS_LDFLAGS += -lpthread
|
||||||
$(info using macOS libpthread: $(call find_include,pthread))
|
$(info using macOS libpthread: $(call find_include,pthread))
|
||||||
endif
|
endif
|
||||||
|
@ -688,7 +688,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
|
||||||
OS_CCDEFS += -DHAVE_GLOB
|
OS_CCDEFS += -DHAVE_GLOB
|
||||||
else
|
else
|
||||||
ifneq (,$(call find_include,fnmatch))
|
ifneq (,$(call find_include,fnmatch))
|
||||||
OS_CCDEFS += -DHAVE_FNMATCH
|
OS_CCDEFS += -DHAVE_FNMATCH
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifneq (,$(call find_include,sys/mman))
|
ifneq (,$(call find_include,sys/mman))
|
||||||
|
@ -1285,8 +1285,8 @@ else
|
||||||
$(info ***********************************************************************)
|
$(info ***********************************************************************)
|
||||||
$(error .)
|
$(error .)
|
||||||
else
|
else
|
||||||
$(info ** date. For the most functional and stable features you shoud **)
|
$(info ** date. For the most functional and stable features you should **)
|
||||||
$(info ** Download the file: **)
|
$(info ** download the file: **)
|
||||||
$(info ** https://github.com/simh/windows-build/archive/windows-build.zip **)
|
$(info ** https://github.com/simh/windows-build/archive/windows-build.zip **)
|
||||||
$(info ** Extract the windows-build-windows-build folder it contains to **)
|
$(info ** Extract the windows-build-windows-build folder it contains to **)
|
||||||
$(info ** $(abspath ..\) **)
|
$(info ** $(abspath ..\) **)
|
||||||
|
@ -1332,7 +1332,7 @@ else
|
||||||
else
|
else
|
||||||
CFLAGS_O := $(OPTIMIZE)
|
CFLAGS_O := $(OPTIMIZE)
|
||||||
endif
|
endif
|
||||||
LDFLAGS_O =
|
LDFLAGS_O =
|
||||||
GCC_MAJOR_VERSION = $(firstword $(subst ., ,$(GCC_VERSION)))
|
GCC_MAJOR_VERSION = $(firstword $(subst ., ,$(GCC_VERSION)))
|
||||||
ifneq (3,$(GCC_MAJOR_VERSION))
|
ifneq (3,$(GCC_MAJOR_VERSION))
|
||||||
ifeq (,$(GCC_OPTIMIZERS_CMD))
|
ifeq (,$(GCC_OPTIMIZERS_CMD))
|
||||||
|
@ -1743,7 +1743,7 @@ H316D = ${SIMHD}/H316
|
||||||
H316 = ${H316D}/h316_stddev.c ${H316D}/h316_lp.c ${H316D}/h316_cpu.c \
|
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_sys.c ${H316D}/h316_mt.c ${H316D}/h316_fhd.c \
|
||||||
${H316D}/h316_dp.c ${H316D}/h316_rtc.c ${H316D}/h316_imp.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
|
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}/i7090_cdr.c ${I7000D}/i7090_cdp.c ${I7000D}/i7090_lpr.c \
|
||||||
${I7000D}/i7000_chan.c ${I7000D}/i7000_mt.c ${I7000D}/i7090_drum.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}/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
|
I7090_OPT = -I $(I7000D) -DUSE_INT64 -DI7090 -DUSE_SIM_CARD
|
||||||
|
|
||||||
I7080D = ${SIMHD}/I7000
|
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}/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_con.c ${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c \
|
||||||
${I7000D}/i7000_mt.c ${I7000D}/i7000_chron.c ${I7000D}/i7000_dsk.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
|
I7080_OPT = -I $(I7000D) -DI7080 -DUSE_SIM_CARD
|
||||||
|
|
||||||
I7070D = ${SIMHD}/I7000
|
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_cdp.c ${I7000D}/i7000_cdr.c ${I7000D}/i7000_con.c \
|
||||||
${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c ${I7000D}/i7000_mt.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_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
|
I7070_OPT = -I $(I7000D) -DUSE_INT64 -DI7070 -DUSE_SIM_CARD
|
||||||
|
|
||||||
I7010D = ${SIMHD}/I7000
|
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_cdp.c ${I7000D}/i7000_cdr.c ${I7000D}/i7000_con.c \
|
||||||
${I7000D}/i7000_chan.c ${I7000D}/i7000_lpr.c ${I7000D}/i7000_mt.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_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
|
I7010_OPT = -I $(I7010D) -DI7010 -DUSE_SIM_CARD
|
||||||
|
|
||||||
I704D = ${SIMHD}/I7000
|
I704D = ${SIMHD}/I7000
|
||||||
I704 = ${I7000D}/i7090_cpu.c ${I7000D}/i7090_sys.c ${I7000D}/i7090_chan.c \
|
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}/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
|
I704_OPT = -I $(I7000D) -DUSE_INT64 -DI704 -DUSE_SIM_CARD
|
||||||
|
|
||||||
|
|
||||||
I701D = ${SIMHD}/I7000
|
I701D = ${SIMHD}/I7000
|
||||||
I701 = ${I7000D}/i701_cpu.c ${I7000D}/i701_sys.c ${I7000D}/i701_chan.c \
|
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}/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
|
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
|
${IBM1130D}/ibm1130_t2741.c
|
||||||
IBM1130_OPT = -I ${IBM1130D}
|
IBM1130_OPT = -I ${IBM1130D}
|
||||||
ifneq (${WIN32},)
|
ifneq (${WIN32},)
|
||||||
IBM1130_OPT += -DGUI_SUPPORT -lgdi32 ${BIN}ibm1130.o
|
IBM1130_OPT += -DGUI_SUPPORT -lgdi32 ${BIN}ibm1130.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ID16D = ${SIMHD}/Interdata
|
ID16D = ${SIMHD}/Interdata
|
||||||
|
@ -1983,7 +1983,7 @@ INTEL_PARTS = \
|
||||||
${INTELSYSC}/multibus.c \
|
${INTELSYSC}/multibus.c \
|
||||||
${INTELSYSC}/mem.c \
|
${INTELSYSC}/mem.c \
|
||||||
${INTELSYSC}/sys.c \
|
${INTELSYSC}/sys.c \
|
||||||
${INTELSYSC}/zx200a.c
|
${INTELSYSC}/zx200a.c
|
||||||
|
|
||||||
|
|
||||||
INTEL_MDSD = ${INTELSYSD}/Intel-MDS
|
INTEL_MDSD = ${INTELSYSD}/Intel-MDS
|
||||||
|
@ -2008,7 +2008,7 @@ IBMPCXT = ${IBMPCXTC}/i8088.c ${IBMPCXTD}/ibmpcxt_sys.c \
|
||||||
${IBMPCXTC}/i8253.c ${IBMPCXTC}/i8259.c \
|
${IBMPCXTC}/i8253.c ${IBMPCXTC}/i8259.c \
|
||||||
${IBMPCXTC}/i8255.c ${IBMPCXTD}/ibmpcxt.c \
|
${IBMPCXTC}/i8255.c ${IBMPCXTD}/ibmpcxt.c \
|
||||||
${IBMPCXTC}/pceprom.c ${IBMPCXTC}/pcram8.c \
|
${IBMPCXTC}/pceprom.c ${IBMPCXTC}/pcram8.c \
|
||||||
${IBMPCXTC}/pcbus.c ${IBMPCXTC}/i8237.c
|
${IBMPCXTC}/pcbus.c ${IBMPCXTC}/i8237.c
|
||||||
IBMPCXT_OPT = -I ${IBMPCXTD}
|
IBMPCXT_OPT = -I ${IBMPCXTD}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2044,7 +2044,7 @@ BESM6_OPT = -I ${BESM6D} -DUSE_INT64 $(BESM6_PANEL_OPT)
|
||||||
|
|
||||||
PDP6D = ${SIMHD}/PDP10
|
PDP6D = ${SIMHD}/PDP10
|
||||||
ifneq (,${DISPLAY_OPT})
|
ifneq (,${DISPLAY_OPT})
|
||||||
PDP6_DISPLAY_OPT =
|
PDP6_DISPLAY_OPT =
|
||||||
endif
|
endif
|
||||||
PDP6 = ${PDP6D}/kx10_cpu.c ${PDP6D}/kx10_sys.c ${PDP6D}/kx10_cty.c \
|
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 \
|
${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
|
KA10D = ${SIMHD}/PDP10
|
||||||
ifneq (,${DISPLAY_OPT})
|
ifneq (,${DISPLAY_OPT})
|
||||||
KA10_DISPLAY_OPT =
|
KA10_DISPLAY_OPT =
|
||||||
endif
|
endif
|
||||||
KA10 = ${KA10D}/kx10_cpu.c ${KA10D}/kx10_sys.c ${KA10D}/kx10_df.c \
|
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 \
|
${KA10D}/kx10_dp.c ${KA10D}/kx10_mt.c ${KA10D}/kx10_cty.c \
|
||||||
|
@ -2084,7 +2084,7 @@ endif
|
||||||
|
|
||||||
KI10D = ${SIMHD}/PDP10
|
KI10D = ${SIMHD}/PDP10
|
||||||
ifneq (,${DISPLAY_OPT})
|
ifneq (,${DISPLAY_OPT})
|
||||||
KI10_DISPLAY_OPT =
|
KI10_DISPLAY_OPT =
|
||||||
endif
|
endif
|
||||||
KI10 = ${KI10D}/kx10_cpu.c ${KI10D}/kx10_sys.c ${KI10D}/kx10_df.c \
|
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 \
|
${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}/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_cpu.c ${SAGED}/m68k_mem.c ${SAGED}/m68k_scp.c \
|
||||||
${SAGED}/m68k_parse.tab.c ${SAGED}/m68k_sys.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
|
SAGE_OPT = -I ${SAGED} -DHAVE_INT64
|
||||||
|
|
||||||
PDQ3D = ${SIMHD}/PDQ-3
|
PDQ3D = ${SIMHD}/PDQ-3
|
||||||
PDQ3 = ${PDQ3D}/pdq3_cpu.c ${PDQ3D}/pdq3_sys.c ${PDQ3D}/pdq3_stddev.c \
|
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}
|
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 \
|
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 intel-mds \
|
||||||
scelbi 3b2 3b2-700 i701 i704 i7010 i7070 i7080 i7090 \
|
scelbi 3b2 3b2-700 i701 i704 i7010 i7070 i7080 i7090 \
|
||||||
sigma uc15 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp6 i650 \
|
sigma uc15 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp6 i650 \
|
||||||
imlac tt2500 sel32
|
imlac tt2500 sel32
|
||||||
|
|
||||||
all : ${ALL}
|
all : ${ALL}
|
||||||
|
|
||||||
|
@ -2228,7 +2228,7 @@ else
|
||||||
if exist BIN rmdir /s /q BIN
|
if exist BIN rmdir /s /q BIN
|
||||||
endif
|
endif
|
||||||
|
|
||||||
${BUILD_ROMS} :
|
${BUILD_ROMS} :
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
ifeq (${WIN32},)
|
ifeq (${WIN32},)
|
||||||
@if ${TEST} \( ! -e $@ \) -o \( sim_BuildROMs.c -nt $@ \) ; then ${CC} sim_BuildROMs.c ${CC_OUTSPEC}; fi
|
@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}
|
b5500 : ${BIN}b5500${EXE}
|
||||||
|
|
||||||
${BIN}b5500${EXE} : ${B5500} ${SIM}
|
${BIN}b5500${EXE} : ${B5500} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${B5500} ${SIM} ${B5500_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${B5500} ${SIM} ${B5500_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${B5500D},b5500))
|
ifneq (,$(call find_test,${B5500D},b5500))
|
||||||
|
@ -2874,7 +2874,7 @@ endif
|
||||||
3b2-400 : 3b2
|
3b2-400 : 3b2
|
||||||
|
|
||||||
3b2 : ${BIN}3b2${EXE}
|
3b2 : ${BIN}3b2${EXE}
|
||||||
|
|
||||||
${BIN}3b2${EXE} : ${ATT3B2M400} ${SIM}
|
${BIN}3b2${EXE} : ${ATT3B2M400} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${ATT3B2M400} ${SIM} ${ATT3B2M400_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${ATT3B2M400} ${SIM} ${ATT3B2M400_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
|
@ -2898,7 +2898,7 @@ endif
|
||||||
|
|
||||||
i7090 : ${BIN}i7090${EXE}
|
i7090 : ${BIN}i7090${EXE}
|
||||||
|
|
||||||
${BIN}i7090${EXE} : ${I7090} ${SIM}
|
${BIN}i7090${EXE} : ${I7090} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${I7090} ${SIM} ${I7090_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${I7090} ${SIM} ${I7090_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${I7000D},i7090))
|
ifneq (,$(call find_test,${I7000D},i7090))
|
||||||
|
@ -2907,7 +2907,7 @@ endif
|
||||||
|
|
||||||
i7080 : ${BIN}i7080${EXE}
|
i7080 : ${BIN}i7080${EXE}
|
||||||
|
|
||||||
${BIN}i7080${EXE} : ${I7080} ${SIM}
|
${BIN}i7080${EXE} : ${I7080} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${I7080} ${SIM} ${I7080_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${I7080} ${SIM} ${I7080_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${I7080D},i7080))
|
ifneq (,$(call find_test,${I7080D},i7080))
|
||||||
|
@ -2916,7 +2916,7 @@ endif
|
||||||
|
|
||||||
i7070 : ${BIN}i7070${EXE}
|
i7070 : ${BIN}i7070${EXE}
|
||||||
|
|
||||||
${BIN}i7070${EXE} : ${I7070} ${SIM}
|
${BIN}i7070${EXE} : ${I7070} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${I7070} ${SIM} ${I7070_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${I7070} ${SIM} ${I7070_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${I7070D},i7070))
|
ifneq (,$(call find_test,${I7070D},i7070))
|
||||||
|
@ -2925,7 +2925,7 @@ endif
|
||||||
|
|
||||||
i7010 : ${BIN}i7010${EXE}
|
i7010 : ${BIN}i7010${EXE}
|
||||||
|
|
||||||
${BIN}i7010${EXE} : ${I7010} ${SIM}
|
${BIN}i7010${EXE} : ${I7010} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${I7010} ${SIM} ${I7010_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${I7010} ${SIM} ${I7010_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${I7010D},i7010))
|
ifneq (,$(call find_test,${I7010D},i7010))
|
||||||
|
@ -2934,7 +2934,7 @@ endif
|
||||||
|
|
||||||
i704 : ${BIN}i704${EXE}
|
i704 : ${BIN}i704${EXE}
|
||||||
|
|
||||||
${BIN}i704${EXE} : ${I704} ${SIM}
|
${BIN}i704${EXE} : ${I704} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${I704} ${SIM} ${I704_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${I704} ${SIM} ${I704_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${I704D},i704))
|
ifneq (,$(call find_test,${I704D},i704))
|
||||||
|
@ -2943,7 +2943,7 @@ endif
|
||||||
|
|
||||||
i701 : ${BIN}i701${EXE}
|
i701 : ${BIN}i701${EXE}
|
||||||
|
|
||||||
${BIN}i701${EXE} : ${I701} ${SIM}
|
${BIN}i701${EXE} : ${I701} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${I701} ${SIM} ${I701_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${I701} ${SIM} ${I701_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${I701D},i701))
|
ifneq (,$(call find_test,${I701D},i701))
|
||||||
|
@ -2952,7 +2952,7 @@ endif
|
||||||
|
|
||||||
i650 : ${BIN}i650${EXE}
|
i650 : ${BIN}i650${EXE}
|
||||||
|
|
||||||
${BIN}i650${EXE} : ${I650} ${SIM}
|
${BIN}i650${EXE} : ${I650} ${SIM}
|
||||||
${MKDIRBIN}
|
${MKDIRBIN}
|
||||||
${CC} ${I650} ${SIM} ${I650_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
${CC} ${I650} ${SIM} ${I650_OPT} ${CC_OUTSPEC} ${LDFLAGS}
|
||||||
ifneq (,$(call find_test,${I650D},i650))
|
ifneq (,$(call find_test,${I650D},i650))
|
||||||
|
|
10
scp.h
10
scp.h
|
@ -23,7 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
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
|
09-Aug-06 JDB Added assign_device and deassign_device
|
||||||
14-Jul-06 RMS Added sim_activate_abs
|
14-Jul-06 RMS Added sim_activate_abs
|
||||||
06-Jan-06 RMS Added fprint_stopped_gen
|
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_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);
|
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_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);
|
BITFIELD* bitdefs, uint32 before, uint32 after, int terminate);
|
||||||
void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
|
void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
|
||||||
uint32 before, uint32 after, int terminate);
|
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);
|
int32 sw);
|
||||||
|
|
||||||
/* The per-simulator init routine is a weak global that defaults to NULL
|
/* 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);
|
extern void (*sim_vm_init) (void);
|
||||||
|
|
||||||
This routine is no longer invoked this way since it doesn't work reliably
|
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
|
on all simh supported compile environments. A simulator that needs these
|
||||||
initializations can perform them in the CPU device reset routine which will
|
initializations can perform them in the CPU device reset routine which will
|
||||||
always be called before anything else can be processed.
|
always be called before anything else can be processed.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
20
scp_help.h
20
scp_help.h
|
@ -84,7 +84,7 @@
|
||||||
* For these cases, ?#, where # is a 1-based parameter number, can be used
|
* For these cases, ?#, where # is a 1-based parameter number, can be used
|
||||||
* to selectively include a topic. If the specified parameter is TRUE
|
* 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.
|
* (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.
|
* the topic will not be visible.
|
||||||
*
|
*
|
||||||
* If it can be determined at compile time whether the topic in question
|
* If it can be determined at compile time whether the topic in question
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
* Guidelines:
|
* Guidelines:
|
||||||
* Help should be concise and easy to understand.
|
* 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.
|
* subtopic list.
|
||||||
*
|
*
|
||||||
* Keep line lengths to 76 columns or less.
|
* Keep line lengths to 76 columns or less.
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
* Hardware Description - The details of the hardware. Feeds & speeds are OK here.
|
* 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.
|
* Models - If the device was offered in distinct models, a subtopic for each.
|
||||||
* Registers - Register descriptions
|
* Registers - Register descriptions
|
||||||
*
|
*
|
||||||
* Configuration - How to configure the device under SimH. SET commands.
|
* Configuration - How to configure the device under SimH. SET commands.
|
||||||
* Operating System - If the device needs special configuration for a particular
|
* Operating System - If the device needs special configuration for a particular
|
||||||
* OS, a subtopic for each such OS goes here.
|
* 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.
|
* 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;
|
* 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
|
* 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,
|
* 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, ...)
|
* UNIT *uptr, int flag, const char *help, char *cptr, ...)
|
||||||
*
|
*
|
||||||
* If you need to pass the variable argument list from another routine, use:
|
* If you need to pass the variable argument list from another routine, use:
|
||||||
*
|
*
|
||||||
* t_stat scp_vhelp (FILE *st, DEVICE *dptr,
|
* t_stat scp_vhelp (FILE *st, DEVICE *dptr,
|
||||||
* UNIT *uptr, int flag, const char *help, char *cptr, va_list ap)
|
* UNIT *uptr, int flag, const char *help, char *cptr, va_list ap)
|
||||||
*
|
*
|
||||||
|
@ -175,12 +175,12 @@
|
||||||
* to a string.)
|
* to a string.)
|
||||||
*
|
*
|
||||||
* Lines beginning with ';' will be ignored.
|
* Lines beginning with ';' will be ignored.
|
||||||
*
|
*
|
||||||
* Here is a worked-out example:
|
* Here is a worked-out example:
|
||||||
*
|
*
|
||||||
;****************************************************************************
|
;****************************************************************************
|
||||||
The Whizbang 100 is a DMA line printer controller used on the Whizbang 1000
|
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
|
1 Hardware Description
|
||||||
The Whizbang 100 is specified to operate "any printer you and a friend can
|
The Whizbang 100 is specified to operate "any printer you and a friend can
|
||||||
lift", and speeds up to 0.5 C.
|
lift", and speeds up to 0.5 C.
|
||||||
|
@ -205,7 +205,7 @@
|
||||||
Bit 2 ejects the operator
|
Bit 2 ejects the operator
|
||||||
Bit 3 enables interrupts
|
Bit 3 enables interrupts
|
||||||
3 Print data register
|
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
|
elephantcode, the precursor to Unicode. Paper advance is accomplished
|
||||||
with the Rocket Return and Page Trampoline characters.
|
with the Rocket Return and Page Trampoline characters.
|
||||||
1 Configuration
|
1 Configuration
|
||||||
|
@ -217,7 +217,7 @@
|
||||||
+ SET WHIZBANG CODESET ASCII
|
+ SET WHIZBANG CODESET ASCII
|
||||||
+ SET WHIZBANG CODESET ELEPHANTCODE
|
+ SET WHIZBANG CODESET ELEPHANTCODE
|
||||||
|
|
||||||
The VFU (carriage control tape) is specifed with
|
The VFU (carriage control tape) is specified with
|
||||||
+ SET WHIZBANG TAPE vfufile
|
+ SET WHIZBANG TAPE vfufile
|
||||||
2 WOS
|
2 WOS
|
||||||
Under WOS, the device will only work at LooneyBus slot 9
|
Under WOS, the device will only work at LooneyBus slot 9
|
||||||
|
@ -231,7 +231,7 @@
|
||||||
2 Examples
|
2 Examples
|
||||||
TBS
|
TBS
|
||||||
1 Operation
|
1 Operation
|
||||||
Specify the host file to receive output using the
|
Specify the host file to receive output using the
|
||||||
+ATTACH WHIZBANG filespec
|
+ATTACH WHIZBANG filespec
|
||||||
command.
|
command.
|
||||||
1 Monitoring
|
1 Monitoring
|
||||||
|
|
22
sim_card.c
22
sim_card.c
|
@ -22,7 +22,7 @@
|
||||||
This is the standard card reader.
|
This is the standard card reader.
|
||||||
This is the standard card punch.
|
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.
|
Standard ASCII: one record per line.
|
||||||
returns are ignored.
|
returns are ignored.
|
||||||
tabs are expanded to modules 8 characters.
|
tabs are expanded to modules 8 characters.
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
Bits 5-0 are character.
|
Bits 5-0 are character.
|
||||||
|
|
||||||
CBN Format:
|
CBN Format:
|
||||||
Each record 160 charaters.
|
Each record 160 characters.
|
||||||
First char has bit 7 set. Rest set to 0.
|
First char has bit 7 set. Rest set to 0.
|
||||||
Bit 6 is odd parity.
|
Bit 6 is odd parity.
|
||||||
Bit 5-0 of first character are top 6 bits
|
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
|
is not enough octal numbers to span a full card the remainder of the
|
||||||
card will not be punched.
|
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.
|
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.
|
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
|
#if SIMH_EVER_USES_THIS
|
||||||
/* This is a static const that isn't referenced in this code.
|
/* 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] = {
|
static const uint16 ascii_to_hol_ebcdic[128] = {
|
||||||
/* Control */
|
/* Control */
|
||||||
|
@ -434,7 +434,7 @@ static struct card_formats fmts[] = {
|
||||||
|
|
||||||
/* Conversion routines */
|
/* Conversion routines */
|
||||||
|
|
||||||
/* Convert BCD character into hollerith code */
|
/* Convert BCD character into Hollerith code */
|
||||||
uint16
|
uint16
|
||||||
sim_bcd_to_hol(uint8 bcd) {
|
sim_bcd_to_hol(uint8 bcd) {
|
||||||
uint16 hol;
|
uint16 hol;
|
||||||
|
@ -479,7 +479,7 @@ sim_bcd_to_hol(uint8 bcd) {
|
||||||
return hol;
|
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
|
uint8
|
||||||
sim_hol_to_bcd(uint16 hol) {
|
sim_hol_to_bcd(uint16 hol) {
|
||||||
uint8 bcd;
|
uint8 bcd;
|
||||||
|
@ -529,7 +529,7 @@ sim_hol_to_bcd(uint16 hol) {
|
||||||
return bcd;
|
return bcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert EBCDIC character into hollerith code */
|
/* Convert EBCDIC character into Hollerith code */
|
||||||
uint16
|
uint16
|
||||||
sim_ebcdic_to_hol(uint8 ebcdic) {
|
sim_ebcdic_to_hol(uint8 ebcdic) {
|
||||||
return ebcdic_to_hol[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
|
uint16
|
||||||
sim_hol_to_ebcdic(uint16 hol) {
|
sim_hol_to_ebcdic(uint16 hol) {
|
||||||
return hol_to_ebcdic[hol];
|
return hol_to_ebcdic[hol];
|
||||||
|
@ -987,7 +987,7 @@ _sim_read_deck(UNIT * uptr, int eof)
|
||||||
|
|
||||||
buf.len = 0;
|
buf.len = 0;
|
||||||
buf.size = 0;
|
buf.size = 0;
|
||||||
buf.buffer[0] = 0; /* Initialize bufer to empty */
|
buf.buffer[0] = 0; /* Initialize buffer to empty */
|
||||||
|
|
||||||
/* Slurp up current file */
|
/* Slurp up current file */
|
||||||
do {
|
do {
|
||||||
|
@ -1014,7 +1014,7 @@ _sim_read_deck(UNIT * uptr, int eof)
|
||||||
sim_uname(uptr), uptr->filename, sim_error_text(r), cards);
|
sim_uname(uptr), uptr->filename, sim_error_text(r), cards);
|
||||||
}
|
}
|
||||||
data->hopper_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 */
|
/* Data is moved down to simplify the decoding of one card */
|
||||||
l = buf.len - buf.size;
|
l = buf.len - buf.size;
|
||||||
j = buf.size;
|
j = buf.size;
|
||||||
|
@ -1059,7 +1059,7 @@ sim_punch_card(UNIT * uptr, uint16 image[80])
|
||||||
/* Convert word record into column image */
|
/* Convert word record into column image */
|
||||||
/* Check output type, if auto or text, try and convert record to bcd first */
|
/* 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 */
|
/* 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 */
|
/* Try to convert to text */
|
||||||
uint8 out[512];
|
uint8 out[512];
|
||||||
|
|
12
sim_card.h
12
sim_card.h
|
@ -22,7 +22,7 @@
|
||||||
This is the standard card reader.
|
This is the standard card reader.
|
||||||
This is the standard card punch.
|
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.
|
Standard ASCII: one record per line.
|
||||||
returns are ignored.
|
returns are ignored.
|
||||||
tabs are expanded to modules 8 characters.
|
tabs are expanded to modules 8 characters.
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
Bits 5-0 are character.
|
Bits 5-0 are character.
|
||||||
|
|
||||||
CBN Format:
|
CBN Format:
|
||||||
Each record 160 charaters.
|
Each record 160 characters.
|
||||||
First char has bit 7 set. Rest set to 0.
|
First char has bit 7 set. Rest set to 0.
|
||||||
Bit 6 is odd parity.
|
Bit 6 is odd parity.
|
||||||
Bit 5-0 of first character are top 6 bits
|
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
|
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
|
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
|
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.
|
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.
|
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.
|
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_OK 0 /* Good */
|
||||||
#define CDSE_EOF 1 /* End of File */
|
#define CDSE_EOF 1 /* End of File */
|
||||||
#define CDSE_EMPTY 2 /* Input Hopper Empty */
|
#define CDSE_EMPTY 2 /* Input Hopper Empty */
|
||||||
#define CDSE_ERROR 3 /* Error Card Read */
|
#define CDSE_ERROR 3 /* Error Card Read */
|
||||||
|
|
||||||
/* Generic routines. */
|
/* Generic routines. */
|
||||||
|
|
||||||
|
|
120
sim_console.c
120
sim_console.c
|
@ -34,33 +34,33 @@
|
||||||
10-Nov-14 JDB Added -N option to SET CONSOLE LOG and SET CONSOLE DEBUG
|
10-Nov-14 JDB Added -N option to SET CONSOLE LOG and SET CONSOLE DEBUG
|
||||||
02-Jan-14 RMS Added tab stop routines
|
02-Jan-14 RMS Added tab stop routines
|
||||||
18-Mar-12 RMS Removed unused reference to sim_switches (Dave Bryan)
|
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
|
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
|
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.
|
process.
|
||||||
17-Apr-11 MP Cleaned up to support running in a background/detached
|
17-Apr-11 MP Cleaned up to support running in a background/detached
|
||||||
process
|
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.
|
for/ignore other keyboard Meta characters.
|
||||||
18-Jan-11 MP Added log file reference count support
|
18-Jan-11 MP Added log file reference count support
|
||||||
17-Jan-11 MP Added support for a "Buffered" behaviors which include:
|
17-Jan-11 MP Added support for a "Buffered" behaviors which include:
|
||||||
- If Buffering is enabled and Telnet is enabled, a
|
- 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).
|
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
|
written to the buffer at all times (deleting the
|
||||||
oldest buffer contents on overflow).
|
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
|
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
|
will then proceed as if the connection had always
|
||||||
been there.
|
been there.
|
||||||
This concept allows a simulator to run in the background
|
This concept allows a simulator to run in the background
|
||||||
and when needed a console session to be established.
|
and when needed a console session to be established.
|
||||||
The "when needed" case usually will be interested in
|
The "when needed" case usually will be interested in
|
||||||
what already happened before looking to address what
|
what already happened before looking to address what
|
||||||
to do, hence the buffer contents being presented.
|
to do, hence the buffer contents being presented.
|
||||||
28-Dec-10 MP Added support for BREAK key on Windows
|
28-Dec-10 MP Added support for BREAK key on Windows
|
||||||
30-Sep-06 RMS Fixed non-printable characters in KSR mode
|
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
|
25-Jan-97 RMS Added POSIX terminal I/O support
|
||||||
02-Jan-97 RMS Fixed bug in sim_poll_kbd
|
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:
|
Remote Console I/O:
|
||||||
|
|
||||||
sim_poll_kbd poll for keyboard input
|
sim_poll_kbd poll for keyboard input
|
||||||
|
@ -158,7 +158,7 @@
|
||||||
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
|
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Forward Declaraations of Platform specific routines */
|
/* Forward declarations of platform specific routines */
|
||||||
|
|
||||||
static t_stat sim_os_poll_kbd (void);
|
static t_stat sim_os_poll_kbd (void);
|
||||||
static t_bool sim_os_poll_kbd_ready (int ms_timeout);
|
static t_bool sim_os_poll_kbd_ready (int ms_timeout);
|
||||||
|
@ -257,9 +257,9 @@ return "Console telnet support";
|
||||||
}
|
}
|
||||||
|
|
||||||
DEVICE sim_con_telnet = {
|
DEVICE sim_con_telnet = {
|
||||||
"CON-TELNET", sim_con_units, sim_con_reg, sim_con_mod,
|
"CON-TELNET", sim_con_units, sim_con_reg, sim_con_mod,
|
||||||
2, 0, 0, 0, 0, 0,
|
2, 0, 0, 0, 0, 0,
|
||||||
NULL, NULL, sim_con_reset, NULL, sim_con_attach, sim_con_detach,
|
NULL, NULL, sim_con_reset, NULL, sim_con_attach, sim_con_detach,
|
||||||
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_con_debug,
|
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_con_debug,
|
||||||
NULL, NULL, NULL, NULL, NULL, sim_con_telnet_description};
|
NULL, NULL, NULL, NULL, NULL, sim_con_telnet_description};
|
||||||
TMLN sim_con_ldsc = { 0 }; /* console line descr */
|
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);
|
return sim_set_notelnet (0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forward declaratations */
|
/* Forward declarations */
|
||||||
|
|
||||||
static t_stat sim_os_fd_isatty (int fd);
|
static t_stat sim_os_fd_isatty (int fd);
|
||||||
|
|
||||||
|
@ -505,9 +505,9 @@ return "Remote Console Facility";
|
||||||
}
|
}
|
||||||
|
|
||||||
DEVICE sim_remote_console = {
|
DEVICE sim_remote_console = {
|
||||||
"REM-CON", NULL, NULL, sim_rem_con_mod,
|
"REM-CON", NULL, NULL, sim_rem_con_mod,
|
||||||
0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0,
|
||||||
NULL, NULL, sim_rem_con_reset, NULL, NULL, NULL,
|
NULL, NULL, sim_rem_con_reset, NULL, NULL, NULL,
|
||||||
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_rem_con_debug,
|
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_rem_con_debug,
|
||||||
NULL, NULL, NULL, NULL, NULL, sim_rem_con_description};
|
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"
|
tmxr_linemsgf (lp, "%s Remote Console\r\n"
|
||||||
"Enter single commands or to enter multiple command mode enter the %s character\r"
|
"Enter single commands or to enter multiple command mode enter the %s character\r"
|
||||||
"%s",
|
"%s",
|
||||||
sim_name, wru_name,
|
sim_name, wru_name,
|
||||||
((sim_rem_master_mode && (c == 0)) ? "" : "\nSimulator Running..."));
|
((sim_rem_master_mode && (c == 0)) ? "" : "\nSimulator Running..."));
|
||||||
if (sim_rem_master_mode && (c == 0)) /* Master Mode session? */
|
if (sim_rem_master_mode && (c == 0)) /* Master Mode session? */
|
||||||
rem->single_mode = FALSE; /* start in multi-command mode */
|
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)
|
static t_stat _sim_rem_message (const char *cmd, t_stat stat)
|
||||||
{
|
{
|
||||||
CTAB *cmdp = NULL;
|
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);
|
cmdp = find_cmd (cmd);
|
||||||
stat = SCPE_BARE_STATUS(stat); /* remove possible flag */
|
stat = SCPE_BARE_STATUS(stat); /* remove possible flag */
|
||||||
|
@ -906,7 +906,7 @@ if ((!sim_oline) && (sim_log)) {
|
||||||
tmxr_linemsgf (lp, "%s", cbuf);
|
tmxr_linemsgf (lp, "%s", cbuf);
|
||||||
}
|
}
|
||||||
sim_oline = NULL;
|
sim_oline = NULL;
|
||||||
if ((rem->act == NULL) &&
|
if ((rem->act == NULL) &&
|
||||||
(!tmxr_input_pending_ln (lp))) {
|
(!tmxr_input_pending_ln (lp))) {
|
||||||
size_t unwritten;
|
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 */
|
if (ep [0] == '\\' && ep [1] == quote) /* if an escaped quote sequence follows */
|
||||||
ep = ep + 2; /* then skip over the pair */
|
ep = ep + 2; /* then skip over the pair */
|
||||||
else /* otherwise */
|
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 */
|
ep = strchr (ep, ';'); /* the next semicolon is outside the quotes if it exists */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,7 +1019,7 @@ else {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse and setup Remote Console REPEAT command:
|
Parse and setup Remote Console REPEAT command:
|
||||||
REPEAT EVERY nnn USECS Command {; command...}
|
REPEAT EVERY nnn USECS Command {; command...}
|
||||||
*/
|
*/
|
||||||
|
@ -1100,7 +1100,7 @@ return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse and setup Remote Console REPEAT command:
|
Parse and setup Remote Console REPEAT command:
|
||||||
COLLECT nnn SAMPLES EVERY nnn CYCLES reg{,reg...}
|
COLLECT nnn SAMPLES EVERY nnn CYCLES reg{,reg...}
|
||||||
*/
|
*/
|
||||||
|
@ -1396,8 +1396,8 @@ CTAB *basecmdp = NULL;
|
||||||
uint32 read_start_time = 0;
|
uint32 read_start_time = 0;
|
||||||
|
|
||||||
tmxr_poll_rx (&sim_rem_con_tmxr); /* poll input */
|
tmxr_poll_rx (&sim_rem_con_tmxr); /* poll input */
|
||||||
for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
|
for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
|
||||||
(i < sim_rem_con_tmxr.lines) && (!active_command);
|
(i < sim_rem_con_tmxr.lines) && (!active_command);
|
||||||
i++) {
|
i++) {
|
||||||
REMOTE *rem = &sim_rem_consoles[i];
|
REMOTE *rem = &sim_rem_consoles[i];
|
||||||
t_bool master_session = (sim_rem_master_mode && (i == 0));
|
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);
|
c = tmxr_getc_ln (lp);
|
||||||
if (!(TMXR_VALID & c)) {
|
if (!(TMXR_VALID & c)) {
|
||||||
tmxr_send_buffered_data (lp); /* flush any buffered data */
|
tmxr_send_buffered_data (lp); /* flush any buffered data */
|
||||||
if (!master_session &&
|
if (!master_session &&
|
||||||
rem->read_timeout &&
|
rem->read_timeout &&
|
||||||
((sim_os_msec() - read_start_time)/1000 >= rem->read_timeout)) {
|
((sim_os_msec() - read_start_time)/1000 >= rem->read_timeout)) {
|
||||||
while (rem->buf_ptr > 0) { /* Erase current input line */
|
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 */
|
return SCPE_REMOTE; /* force sim_instr() to exit to process command */
|
||||||
}
|
}
|
||||||
else
|
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? */
|
if (sim_rem_master_was_enabled && !sim_rem_master_mode) { /* Transitioning out of master mode? */
|
||||||
lp = &sim_rem_con_tmxr.ldsc[0];
|
lp = &sim_rem_con_tmxr.ldsc[0];
|
||||||
tmxr_linemsgf (lp, "Non Master Mode Session..."); /* report transition */
|
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
|
/* In master mode, commands are subsequently processed from the
|
||||||
primary/initial (master mode) remote console session. Commands
|
primary/initial (master mode) remote console session. Commands
|
||||||
are processed from that source until that source disables master
|
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)
|
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);
|
sim_activate (rem_con_data_unit, -1);
|
||||||
stat = run_cmd (RU_GO, "");
|
stat = run_cmd (RU_GO, "");
|
||||||
if (stat != SCPE_TTMO) {
|
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);
|
stat = _sim_rem_message ("RUN", stat);
|
||||||
}
|
}
|
||||||
brk_action = sim_brk_replace_act (NULL);
|
brk_action = sim_brk_replace_act (NULL);
|
||||||
|
@ -2203,7 +2203,7 @@ if (sim_devices[0]->dradix == 16)
|
||||||
else
|
else
|
||||||
fprintf (st, "pchar mask = %o", sim_tt_pchar);
|
fprintf (st, "pchar mask = %o", sim_tt_pchar);
|
||||||
if (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)",
|
"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)",
|
"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"};
|
"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? */
|
if (*cptr != 0) /* now eol? */
|
||||||
return SCPE_2MARG;
|
return SCPE_2MARG;
|
||||||
sim_set_logoff (0, NULL); /* close cur log */
|
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 */
|
&sim_log, &sim_log_ref); /* open log */
|
||||||
if (r != SCPE_OK) /* error? */
|
if (r != SCPE_OK) /* error? */
|
||||||
return r;
|
return r;
|
||||||
if ((!sim_quiet) && (!(sim_switches & SWMASK ('Q'))))
|
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));
|
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 */
|
sim_logfile_name (sim_log, sim_log_ref)); /* start of log */
|
||||||
time(&now);
|
time(&now);
|
||||||
if ((!sim_quiet) && (!(sim_switches & SWMASK ('Q'))))
|
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))
|
if (cptr && (*cptr != 0))
|
||||||
return SCPE_2MARG;
|
return SCPE_2MARG;
|
||||||
if (sim_log)
|
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));
|
sim_logfile_name (sim_log, sim_log_ref));
|
||||||
else
|
else
|
||||||
fprintf (st, "Logging disabled\n");
|
fprintf (st, "Logging disabled\n");
|
||||||
|
@ -2309,9 +2309,9 @@ int32 sim_set_deb_switches (int32 switches)
|
||||||
{
|
{
|
||||||
int32 old_deb_switches = sim_deb_switches;
|
int32 old_deb_switches = sim_deb_switches;
|
||||||
|
|
||||||
sim_deb_switches = switches &
|
sim_deb_switches = switches &
|
||||||
(SWMASK ('R') | SWMASK ('P') |
|
(SWMASK ('R') | SWMASK ('P') |
|
||||||
SWMASK ('T') | SWMASK ('A') |
|
SWMASK ('T') | SWMASK ('A') |
|
||||||
SWMASK ('F') | SWMASK ('N') |
|
SWMASK ('F') | SWMASK ('N') |
|
||||||
SWMASK ('B') | SWMASK ('E') |
|
SWMASK ('B') | SWMASK ('E') |
|
||||||
SWMASK ('D') ); /* save debug switches */
|
SWMASK ('D') ); /* save debug switches */
|
||||||
|
@ -2370,7 +2370,7 @@ if (sim_deb_switches & SWMASK ('F'))
|
||||||
if (sim_deb_switches & SWMASK ('E'))
|
if (sim_deb_switches & SWMASK ('E'))
|
||||||
sim_messagef (SCPE_OK, " Debug messages containing blob data in EBCDIC will display in readable form\n");
|
sim_messagef (SCPE_OK, " Debug messages containing blob data in EBCDIC will display in readable form\n");
|
||||||
if (sim_deb_switches & SWMASK ('B'))
|
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);
|
(unsigned int)buffer_size);
|
||||||
time(&now);
|
time(&now);
|
||||||
if (!sim_quiet) {
|
if (!sim_quiet) {
|
||||||
|
@ -2432,7 +2432,7 @@ int32 i;
|
||||||
if (cptr && (*cptr != 0))
|
if (cptr && (*cptr != 0))
|
||||||
return SCPE_2MARG;
|
return SCPE_2MARG;
|
||||||
if (sim_deb) {
|
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));
|
sim_logfile_name (sim_deb, sim_deb_ref));
|
||||||
if (sim_deb_switches & SWMASK ('P'))
|
if (sim_deb_switches & SWMASK ('P'))
|
||||||
fprintf (st, " Debug messages contain current PC value\n");
|
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))
|
if (cptr && (*cptr != 0))
|
||||||
return SCPE_2MARG;
|
return SCPE_2MARG;
|
||||||
if ((sim_con_tmxr.master == 0) &&
|
if ((sim_con_tmxr.master == 0) &&
|
||||||
(sim_con_ldsc.serport == 0))
|
(sim_con_ldsc.serport == 0))
|
||||||
fprintf (st, "Connected to console window\n");
|
fprintf (st, "Connected to console window\n");
|
||||||
else {
|
else {
|
||||||
|
@ -2544,7 +2544,7 @@ else {
|
||||||
fprintf (st, "Connected to ");
|
fprintf (st, "Connected to ");
|
||||||
tmxr_fconns (st, &sim_con_ldsc, -1);
|
tmxr_fconns (st, &sim_con_ldsc, -1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (sim_con_ldsc.sock == 0)
|
if (sim_con_ldsc.sock == 0)
|
||||||
fprintf (st, "Listening on port %s\n", sim_con_tmxr.port);
|
fprintf (st, "Listening on port %s\n", sim_con_tmxr.port);
|
||||||
else {
|
else {
|
||||||
|
@ -2790,7 +2790,7 @@ if (!ref)
|
||||||
return ref->name;
|
return ref->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check connection before executing
|
/* Check connection before executing
|
||||||
(including a remote console which may be required in master mode) */
|
(including a remote console which may be required in master mode) */
|
||||||
|
|
||||||
t_stat sim_check_console (int32 sec)
|
t_stat sim_check_console (int32 sec)
|
||||||
|
@ -2827,7 +2827,7 @@ if (trys == sec) {
|
||||||
return SCPE_TTMO; /* timed out */
|
return SCPE_TTMO; /* timed out */
|
||||||
}
|
}
|
||||||
if (sim_con_ldsc.serport)
|
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 */
|
sim_con_ldsc.rcve = 1; /* rcv enabled */
|
||||||
if ((sim_con_tmxr.master == 0) || /* serial console or not Telnet? done */
|
if ((sim_con_tmxr.master == 0) || /* serial console or not Telnet? done */
|
||||||
(sim_con_ldsc.serport))
|
(sim_con_ldsc.serport))
|
||||||
|
@ -2931,7 +2931,7 @@ if (!sim_rem_master_mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmxr_poll_rx (&sim_con_tmxr); /* poll for input */
|
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);
|
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;
|
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)");
|
fprintf (st, "KSR (UC, MARK parity)");
|
||||||
else
|
else
|
||||||
fprintf (st, "%s", modes[md]);
|
fprintf (st, "%s", modes[md]);
|
||||||
if ((md != TTUF_MODE_8B) &&
|
if ((md != TTUF_MODE_8B) &&
|
||||||
((md != TTUF_MODE_UC) || (par_mode != TTUF_PAR_MARK))) {
|
((md != TTUF_MODE_UC) || (par_mode != TTUF_PAR_MARK))) {
|
||||||
if (par_mode != 0)
|
if (par_mode != 0)
|
||||||
fprintf (st, ", %s parity", parity[par_mode]);
|
fprintf (st, ", %s parity", parity[par_mode]);
|
||||||
|
@ -3153,8 +3153,8 @@ _console_poll(void *arg)
|
||||||
int wait_count = 0;
|
int wait_count = 0;
|
||||||
DEVICE *d;
|
DEVICE *d;
|
||||||
|
|
||||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||||
thread which, in general, won't be readily yielding the processor when
|
thread which, in general, won't be readily yielding the processor when
|
||||||
this thread needs to run */
|
this thread needs to run */
|
||||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||||
|
|
||||||
|
@ -3496,11 +3496,11 @@ static DWORD saved_error_mode;
|
||||||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Note: This routine catches all the potential events which some aspect
|
/* Note: This routine catches all the potential events which some aspect
|
||||||
of the windows system can generate. The CTRL_C_EVENT won't be
|
of the windows system can generate. The CTRL_C_EVENT won't be
|
||||||
generated by a user typing in a console session since that
|
generated by a user typing in a console session since that
|
||||||
session is in RAW mode. In general, Ctrl-C on a simulator's
|
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. */
|
simulator. This code does nothing to disable or affect that. */
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -3513,7 +3513,7 @@ ControlHandler(DWORD dwCtrlType)
|
||||||
|
|
||||||
switch (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
|
case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
|
||||||
int_handler(SIGINT);
|
int_handler(SIGINT);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -3927,11 +3927,11 @@ static t_stat sim_os_ttinit (void)
|
||||||
sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_ttinit()\n");
|
sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_ttinit()\n");
|
||||||
|
|
||||||
cmdfl = fcntl (fileno (stdin), F_GETFL, 0); /* get old flags and status */
|
cmdfl = fcntl (fileno (stdin), F_GETFL, 0); /* get old flags and status */
|
||||||
/*
|
/*
|
||||||
* make sure systems with broken termios (that don't honor
|
* make sure systems with broken termios (that don't honor
|
||||||
* VMIN=0 and VTIME=0) actually implement non blocking reads.
|
* VMIN=0 and VTIME=0) actually implement non blocking reads.
|
||||||
* This will have no negative effect on other systems since
|
* This will have no negative effect on other systems since
|
||||||
* this is turned on and off depending on whether simulation
|
* this is turned on and off depending on whether simulation
|
||||||
* is running or not.
|
* is running or not.
|
||||||
*/
|
*/
|
||||||
runfl = cmdfl | O_NONBLOCK;
|
runfl = cmdfl | O_NONBLOCK;
|
||||||
|
@ -4130,7 +4130,7 @@ else {
|
||||||
|
|
||||||
mbuf2 = (char *)malloc (3 + strlen(cptr));
|
mbuf2 = (char *)malloc (3 + strlen(cptr));
|
||||||
sprintf (mbuf2, "%s%s%s", (sim_switches & SWMASK ('A')) ? "\n" : "",
|
sprintf (mbuf2, "%s%s%s", (sim_switches & SWMASK ('A')) ? "\n" : "",
|
||||||
mbuf,
|
mbuf,
|
||||||
(sim_switches & SWMASK ('I')) ? "" : "\n");
|
(sim_switches & SWMASK ('I')) ? "" : "\n");
|
||||||
free (mbuf);
|
free (mbuf);
|
||||||
mbuf = sim_encode_quoted_string ((uint8 *)mbuf2, strlen (mbuf2));
|
mbuf = sim_encode_quoted_string ((uint8 *)mbuf2, strlen (mbuf2));
|
||||||
|
|
|
@ -212,7 +212,7 @@ extern "C" {
|
||||||
|
|
||||||
/* Length specific integer declarations */
|
/* 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)
|
#if defined (VMS)
|
||||||
#include <ints.h>
|
#include <ints.h>
|
||||||
#elif defined(_MSC_VER) && (_MSC_VER < 1600)
|
#elif defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||||
|
@ -224,7 +224,7 @@ typedef unsigned __int16 uint16;
|
||||||
typedef unsigned __int32 uint32;
|
typedef unsigned __int32 uint32;
|
||||||
#else
|
#else
|
||||||
/* All modern/standard compiler environments */
|
/* All modern/standard compiler environments */
|
||||||
/* any other environment needa a special case above */
|
/* any other environment needs a special case above */
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef int8_t int8;
|
typedef int8_t int8;
|
||||||
typedef int16_t int16;
|
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_MAX_ERR (SCPE_BASE + 51) /* Maximum SCPE Error Value */
|
||||||
#define SCPE_KFLAG 0x10000000 /* tti data flag */
|
#define SCPE_KFLAG 0x10000000 /* tti data flag */
|
||||||
#define SCPE_BREAK 0x20000000 /* tti break 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))
|
#define SCPE_BARE_STATUS(stat) ((stat) & ~(SCPE_NOMESSAGE|SCPE_KFLAG|SCPE_BREAK))
|
||||||
|
|
||||||
/* Print value format codes */
|
/* Print value format codes */
|
||||||
|
|
166
sim_disk.c
166
sim_disk.c
|
@ -28,7 +28,7 @@
|
||||||
This is the place which hides processing of various disk formats,
|
This is the place which hides processing of various disk formats,
|
||||||
as well as OS-specific direct hardware access.
|
as well as OS-specific direct hardware access.
|
||||||
|
|
||||||
25-Jan-11 MP Initial Implemementation
|
25-Jan-11 MP Initial Implementation
|
||||||
|
|
||||||
Public routines:
|
Public routines:
|
||||||
|
|
||||||
|
@ -276,8 +276,8 @@ return NULL;
|
||||||
processing events for any unit. It is only called when an asynchronous
|
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
|
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
|
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
|
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
|
particular disk device (due to using stdio for the SimH Disk format
|
||||||
and stdio doesn't have an atomic seek+(read|write) operation),
|
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_switches = 0;
|
||||||
sim_quiet = 1;
|
sim_quiet = 1;
|
||||||
strcpy (path, uptr->filename);
|
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);
|
FALSE, ctx->dbit, NULL, 0, 0);
|
||||||
sim_quiet = saved_quiet;
|
sim_quiet = saved_quiet;
|
||||||
sim_switches = saved_switches;
|
sim_switches = saved_switches;
|
||||||
|
@ -524,7 +524,7 @@ DEVICE *dptr;
|
||||||
uint32 dev, unit, count = 0;
|
uint32 dev, unit, count = 0;
|
||||||
|
|
||||||
if (flag == sim_disk_no_autosize)
|
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");
|
sim_disk_no_autosize ? "dis" : "en");
|
||||||
for (dev = 0; (dptr = sim_devices[dev]) != NULL; dev++) {
|
for (dev = 0; (dptr = sim_devices[dev]) != NULL; dev++) {
|
||||||
if ((DEV_TYPE (dptr) != DEV_DISK) ||
|
if ((DEV_TYPE (dptr) != DEV_DISK) ||
|
||||||
|
@ -665,7 +665,7 @@ while (tbc) {
|
||||||
if (i < tbc) /* fill */
|
if (i < tbc) /* fill */
|
||||||
memset (&buf[i], 0, tbc-i);
|
memset (&buf[i], 0, tbc-i);
|
||||||
if ((i == 0) && /* Reading at or past EOF? */
|
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 */
|
i = tbc; /* return 0's which have already been filled in buffer */
|
||||||
sectbytes = (i / ctx->sector_size) * ctx->sector_size;
|
sectbytes = (i / ctx->sector_size) * ctx->sector_size;
|
||||||
if (i > sectbytes)
|
if (i > sectbytes)
|
||||||
|
@ -871,7 +871,7 @@ if (f == DKUF_F_RAW) {
|
||||||
if (tbuf == NULL)
|
if (tbuf == NULL)
|
||||||
return SCPE_MEM;
|
return SCPE_MEM;
|
||||||
/* Partial Sector writes require a read-modify-write sequence for the partial sectors */
|
/* 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, ssaddr, tbuf, NULL, ctx->storage_sector_size);
|
||||||
sim_os_disk_read (uptr, sladdr, tbuf + (size_t)(sladdr - ssaddr), 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,
|
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;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
t_lba sectno = lba, psa;
|
t_lba sectno = lba, psa;
|
||||||
t_stat status;
|
t_stat status;
|
||||||
|
|
||||||
if (sectsread)
|
if (sectsread)
|
||||||
*sectsread = 0;
|
*sectsread = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
uint16 i, track, sector;
|
uint16 i, track, sector;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map an LBA address into a physical sector address
|
* Map an LBA address into a physical sector address
|
||||||
*/
|
*/
|
||||||
|
@ -1141,7 +1141,7 @@ typedef struct _ODS2_FileHeader
|
||||||
|
|
||||||
typedef union _ODS2_Retreval
|
typedef union _ODS2_Retreval
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned fm2___fill : 14; /* type specific data */
|
unsigned fm2___fill : 14; /* type specific data */
|
||||||
unsigned fm2_v_format : 2; /* format type code */
|
unsigned fm2_v_format : 2; /* format type code */
|
||||||
|
@ -1278,31 +1278,31 @@ if ((_DEC_rdsect (uptr, 512 / ctx->sector_size, (uint8 *)&Home, §s_read, siz
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
CheckSum1 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum1)-((char *)&Home.hm2_l_homelbn))/2));
|
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));
|
CheckSum2 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum2)-((char *)&Home.hm2_l_homelbn))/2));
|
||||||
if ((Home.hm2_l_homelbn == 0) ||
|
if ((Home.hm2_l_homelbn == 0) ||
|
||||||
(Home.hm2_l_alhomelbn == 0) ||
|
(Home.hm2_l_alhomelbn == 0) ||
|
||||||
(Home.hm2_l_altidxlbn == 0) ||
|
(Home.hm2_l_altidxlbn == 0) ||
|
||||||
((Home.hm2_b_struclev != 2) && (Home.hm2_b_struclev != 5)) ||
|
((Home.hm2_b_struclev != 2) && (Home.hm2_b_struclev != 5)) ||
|
||||||
(Home.hm2_b_strucver == 0) ||
|
(Home.hm2_b_strucver == 0) ||
|
||||||
(Home.hm2_w_cluster == 0) ||
|
(Home.hm2_w_cluster == 0) ||
|
||||||
(Home.hm2_w_homevbn == 0) ||
|
(Home.hm2_w_homevbn == 0) ||
|
||||||
(Home.hm2_w_alhomevbn == 0) ||
|
(Home.hm2_w_alhomevbn == 0) ||
|
||||||
(Home.hm2_w_ibmapvbn == 0) ||
|
(Home.hm2_w_ibmapvbn == 0) ||
|
||||||
(Home.hm2_l_ibmaplbn == 0) ||
|
(Home.hm2_l_ibmaplbn == 0) ||
|
||||||
(Home.hm2_w_resfiles >= Home.hm2_l_maxfiles) ||
|
(Home.hm2_w_resfiles >= Home.hm2_l_maxfiles) ||
|
||||||
(Home.hm2_w_ibmapsize == 0) ||
|
(Home.hm2_w_ibmapsize == 0) ||
|
||||||
(Home.hm2_w_resfiles < 5) ||
|
(Home.hm2_w_resfiles < 5) ||
|
||||||
(Home.hm2_w_checksum1 != CheckSum1) ||
|
(Home.hm2_w_checksum1 != CheckSum1) ||
|
||||||
(Home.hm2_w_checksum2 != CheckSum2))
|
(Home.hm2_w_checksum2 != CheckSum2))
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
if ((_DEC_rdsect (uptr, (Home.hm2_l_ibmaplbn+Home.hm2_w_ibmapsize+1) * (512 / ctx->sector_size),
|
if ((_DEC_rdsect (uptr, (Home.hm2_l_ibmaplbn+Home.hm2_w_ibmapsize+1) * (512 / ctx->sector_size),
|
||||||
(uint8 *)&Header, §s_read, sizeof (Header) / ctx->sector_size, physsectsz)) ||
|
(uint8 *)&Header, §s_read, sizeof (Header) / ctx->sector_size, physsectsz)) ||
|
||||||
(sects_read != (sizeof (Header) / ctx->sector_size)))
|
(sects_read != (sizeof (Header) / ctx->sector_size)))
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
CheckSum1 = ODSChecksum (&Header, 255);
|
CheckSum1 = ODSChecksum (&Header, 255);
|
||||||
if (CheckSum1 != *(((uint16 *)&Header)+255)) /* Verify Checksum on BITMAP.SYS file header */
|
if (CheckSum1 != *(((uint16 *)&Header)+255)) /* Verify Checksum on BITMAP.SYS file header */
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
Retr = (ODS2_Retreval *)(((uint16*)(&Header))+Header.fh2_b_mpoffset);
|
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)
|
if (Retr->fm2_r_word0_bits.fm2_v_format == 0)
|
||||||
Retr = (ODS2_Retreval *)(((uint16 *)Retr)+1); /* skip placement descriptor */
|
Retr = (ODS2_Retreval *)(((uint16 *)Retr)+1); /* skip placement descriptor */
|
||||||
switch (Retr->fm2_r_word0_bits.fm2_v_format)
|
switch (Retr->fm2_r_word0_bits.fm2_v_format)
|
||||||
|
@ -1324,12 +1324,12 @@ if ((_DEC_rdsect (uptr, ScbLbn * (512 / ctx->sector_size), (uint8 *)&Scb, §s
|
||||||
CheckSum1 = ODSChecksum (&Scb, 255);
|
CheckSum1 = ODSChecksum (&Scb, 255);
|
||||||
if (CheckSum1 != *(((uint16 *)&Scb)+255)) /* Verify Checksum on Storage Control Block */
|
if (CheckSum1 != *(((uint16 *)&Scb)+255)) /* Verify Checksum on Storage Control Block */
|
||||||
goto Return_Cleanup;
|
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_strucver != Home.hm2_b_strucver) ||
|
||||||
(Scb.scb_b_struclev != Home.hm2_b_struclev))
|
(Scb.scb_b_struclev != Home.hm2_b_struclev))
|
||||||
goto Return_Cleanup;
|
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: '%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);
|
sim_uname (uptr), Home.hm2_t_volname, Home.hm2_t_format, Scb.scb_l_volsize);
|
||||||
ret_val = ((t_offset)Scb.scb_l_volsize) * 512;
|
ret_val = ((t_offset)Scb.scb_l_volsize) * 512;
|
||||||
|
|
||||||
|
@ -1365,12 +1365,12 @@ if ((_DEC_rdsect (uptr, 512 / ctx->sector_size, (uint8 *)&Home, §s_read, siz
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
CheckSum1 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm1_w_checksum1)-((char *)&Home.hm1_w_ibmapsize))/2));
|
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));
|
CheckSum2 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm1_w_checksum2)-((char *)&Home.hm1_w_ibmapsize))/2));
|
||||||
if ((Home.hm1_w_ibmapsize == 0) ||
|
if ((Home.hm1_w_ibmapsize == 0) ||
|
||||||
(Home.hm1_l_ibmaplbn == 0) ||
|
(Home.hm1_l_ibmaplbn == 0) ||
|
||||||
(Home.hm1_w_maxfiles == 0) ||
|
(Home.hm1_w_maxfiles == 0) ||
|
||||||
(Home.hm1_w_cluster != 1) ||
|
(Home.hm1_w_cluster != 1) ||
|
||||||
((Home.hm1_w_structlev != HM1_C_LEVEL1) && (Home.hm1_w_structlev != HM1_C_LEVEL2)) ||
|
((Home.hm1_w_structlev != HM1_C_LEVEL1) && (Home.hm1_w_structlev != HM1_C_LEVEL2)) ||
|
||||||
(Home.hm1_l_ibmaplbn == 0) ||
|
(Home.hm1_l_ibmaplbn == 0) ||
|
||||||
(Home.hm1_w_checksum1 != CheckSum1) ||
|
(Home.hm1_w_checksum1 != CheckSum1) ||
|
||||||
(Home.hm1_w_checksum2 != CheckSum2))
|
(Home.hm1_w_checksum2 != CheckSum2))
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
|
@ -1392,7 +1392,7 @@ if (Scb->scb_b_bitmapblks < 127)
|
||||||
else
|
else
|
||||||
ret_val = (((t_offset)Scb->scb_r_blocks[0].scb_w_freeblks << 16) + Scb->scb_r_blocks[0].scb_w_freeptr) * 512;
|
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: '%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));
|
sim_uname (uptr), Home.hm1_t_volname, Home.hm1_t_format, (uint32)(ret_val / 512));
|
||||||
Return_Cleanup:
|
Return_Cleanup:
|
||||||
uptr->capac = saved_capac;
|
uptr->capac = saved_capac;
|
||||||
|
@ -1434,7 +1434,7 @@ if ((_DEC_rdsect (uptr, 31 * (512 / ctx->sector_size), sector_buf, §s_read,
|
||||||
(sects_read != (512 / ctx->sector_size)))
|
(sects_read != (512 / ctx->sector_size)))
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
|
|
||||||
if ((Label->pt_magic != PT_MAGIC) ||
|
if ((Label->pt_magic != PT_MAGIC) ||
|
||||||
(Label->pt_valid != PT_VALID))
|
(Label->pt_valid != PT_VALID))
|
||||||
goto Return_Cleanup;
|
goto Return_Cleanup;
|
||||||
|
|
||||||
|
@ -1524,7 +1524,7 @@ saved_capac = uptr->capac;
|
||||||
uptr->capac = temp_capac;
|
uptr->capac = temp_capac;
|
||||||
|
|
||||||
while (sim_disk_rdsect(uptr, (t_lba)(sectfactor * cur_pos / sizeof (*Desc)), (uint8 *)Desc, §sread, sectfactor) == DKSE_OK) {
|
while (sim_disk_rdsect(uptr, (t_lba)(sectfactor * cur_pos / sizeof (*Desc)), (uint8 *)Desc, §sread, sectfactor) == DKSE_OK) {
|
||||||
if ((sectsread != sectfactor) ||
|
if ((sectsread != sectfactor) ||
|
||||||
(Desc->Version != 1) ||
|
(Desc->Version != 1) ||
|
||||||
(0 != memcmp (Desc->Identifier, "CD001", sizeof (Desc->Identifier))))
|
(0 != memcmp (Desc->Identifier, "CD001", sizeof (Desc->Identifier))))
|
||||||
break;
|
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: '%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_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));
|
sim_messagef(SCPE_OK, "%s: Last Unallocated Sector In File System: %u\n", sim_uname (uptr), (uint32)((ret_val / 512) - 1));
|
||||||
goto cleanup_done;
|
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)
|
if (strncmp((char *)&home->hb_b_sysid, HB_C_VMSSYSID, strlen(HB_C_VMSSYSID)) == 0)
|
||||||
return RT11_SINGLEPART;
|
return RT11_SINGLEPART;
|
||||||
|
|
||||||
return RT11_NOPART;
|
return RT11_NOPART;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2156,7 +2156,7 @@ for (part = 0; part < RT11_MAXPARTITIONS; part++) {
|
||||||
*/
|
*/
|
||||||
if ((part != 0) && (physsectsz != 0))
|
if ((part != 0) && (physsectsz != 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
base = part << 16;
|
base = part << 16;
|
||||||
|
|
||||||
if (_DEC_rdsect(uptr, (base + RT11_HOME) * (512 / ctx->sector_size), (uint8 *)&Home, §s_read, 512 / ctx->sector_size, physsectsz) ||
|
if (_DEC_rdsect(uptr, (base + RT11_HOME) * (512 / ctx->sector_size), (uint8 *)&Home, §s_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) {
|
if ((ret_val = checks[i] (uptr, 0, readonly)) != (t_offset)-1) {
|
||||||
/* ISO files that haven't already been determined to be ISO 9660
|
/* ISO files that haven't already been determined to be ISO 9660
|
||||||
* which contain a known file system are also marked read-only
|
* 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.
|
* before ISO 9660 was standardized and operating support was added.
|
||||||
*/
|
*/
|
||||||
if ((readonly != NULL) &&
|
if ((readonly != NULL) &&
|
||||||
(*readonly == FALSE) &&
|
(*readonly == FALSE) &&
|
||||||
(NULL != match_ext (uptr->filename, "ISO")))
|
(NULL != match_ext (uptr->filename, "ISO")))
|
||||||
*readonly = TRUE;
|
*readonly = TRUE;
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* The only known interleaved disk devices have either 256 byte
|
* The only known interleaved disk devices have either 256 byte
|
||||||
* or 128 byte sector sizes. If additional interleaved file
|
* or 128 byte sector sizes. If additional interleaved file
|
||||||
* system scenarios with different sector sizes come up they
|
* system scenarios with different sector sizes come up they
|
||||||
* should be added here.
|
* should be added here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; checks[i] != NULL; i++) {
|
for (i = 0; checks[i] != NULL; i++) {
|
||||||
ctx->sector_size = 256;
|
ctx->sector_size = 256;
|
||||||
if ((ret_val = checks[i] (uptr, ctx->sector_size, readonly)) != (t_offset)-1)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if ((ret_val != (t_offset)-1) && (ctx->sector_size != saved_sector_size ))
|
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);
|
sim_uname (uptr), ctx->sector_size, saved_sector_size);
|
||||||
ctx->sector_size = saved_sector_size;
|
ctx->sector_size = saved_sector_size;
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
@ -2395,7 +2395,7 @@ if (f) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* We've got a valid footer, but it may need to be corrected */
|
/* 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))) {
|
(0 == memcmp (f->DriveType, "RZ", 2))) {
|
||||||
f->TransferElementSize = NtoHl (2);
|
f->TransferElementSize = NtoHl (2);
|
||||||
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
|
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
|
||||||
|
@ -2415,12 +2415,12 @@ if (f) {
|
||||||
" AccessFormat: %u\n"
|
" AccessFormat: %u\n"
|
||||||
" CreationTime: %s",
|
" CreationTime: %s",
|
||||||
sim_uname (uptr), uptr->filename,
|
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);
|
NtoHl (f->TransferElementSize), f->FooterVersion, f->AccessFormat, f->CreationTime);
|
||||||
if (f->DeviceName[0] != '\0')
|
if (f->DeviceName[0] != '\0')
|
||||||
sim_debug_unit (ctx->dbit, uptr,
|
sim_debug_unit (ctx->dbit, uptr,
|
||||||
" DeviceName: %s\n", (char *)f->DeviceName);
|
" 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));
|
" 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);
|
sim_messagef (SCPE_OK, "Copying %u sectors each %u bytes in size\n", (uint32)total_sectors, (uint32)sector_size);
|
||||||
if (source_capac > target_capac) {
|
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))));
|
(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");
|
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->fileref = save_unit_fileref;
|
||||||
uptr->flags = saved_unit_flags;
|
uptr->flags = saved_unit_flags;
|
||||||
if (r == SCPE_OK) {
|
if (r == SCPE_OK) {
|
||||||
if ((sects_read != verify_read) ||
|
if ((sects_read != verify_read) ||
|
||||||
(0 != memcmp (copy_buf, verify_buf, verify_read*sector_size)))
|
(0 != memcmp (copy_buf, verify_buf, verify_read*sector_size)))
|
||||||
r = SCPE_IOERR;
|
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))
|
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);
|
r = sim_messagef (SCPE_OPENERR, "%s: Incompatible Container Sector Size %d\n", sim_uname (uptr), container_sector_size);
|
||||||
else {
|
else {
|
||||||
if (dontchangecapac &&
|
if (dontchangecapac &&
|
||||||
((((t_lba)(ctx->container_size/sector_size) > current_unit_sectors)) ||
|
((((t_lba)(ctx->container_size/sector_size) > current_unit_sectors)) ||
|
||||||
((container_sectors != 0) && (container_sectors != 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);
|
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 lba;
|
||||||
t_lba total_lbas = (t_lba)((((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1))/ctx->sector_size);
|
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;
|
t_seccnt sectors = ((lba + 128) <= total_lbas) ? 128 : total_lbas - lba;
|
||||||
|
|
||||||
r = sim_disk_wrsect (uptr, lba, secbuf, NULL, sectors);
|
r = sim_disk_wrsect (uptr, lba, secbuf, NULL, sectors);
|
||||||
|
@ -3077,7 +3077,7 @@ if ((created) && (!copied)) {
|
||||||
free (init_buf);
|
free (init_buf);
|
||||||
sim_disk_detach (uptr); /* report error now */
|
sim_disk_detach (uptr); /* report error now */
|
||||||
(void)remove (cptr); /* remove the created file */
|
(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");
|
(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));
|
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, §s_verify, sects);
|
r = sim_disk_rdsect (uptr, lba, verify_buf, §s_verify, sects);
|
||||||
if (r == SCPE_OK) {
|
if (r == SCPE_OK) {
|
||||||
if (sects != sects_verify)
|
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);
|
sim_uname (uptr), (int)lba, (int)lba, (int)total_sectors, (int)total_sectors, sects, sects_verify);
|
||||||
for (sect = 0; sect < sects_verify; sect++) {
|
for (sect = 0; sect < sects_verify; sect++) {
|
||||||
t_lba offset;
|
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)));
|
uptr->capac = (t_addr)(filesystem_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
|
||||||
capac1 = strdup (sprint_capac (dptr, uptr));
|
capac1 = strdup (sprint_capac (dptr, uptr));
|
||||||
uptr->capac = saved_capac;
|
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));
|
sim_uname (uptr), cptr, capac1, sprint_capac (dptr, uptr));
|
||||||
free (capac1);
|
free (capac1);
|
||||||
sim_disk_detach (uptr);
|
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)));
|
uptr->capac = (t_addr)(container_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
|
||||||
capac1 = strdup (sprint_capac (dptr, uptr));
|
capac1 = strdup (sprint_capac (dptr, uptr));
|
||||||
uptr->capac = saved_capac;
|
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));
|
sim_uname (uptr), cptr, capac1, sprint_capac (dptr, uptr));
|
||||||
free (capac1);
|
free (capac1);
|
||||||
sim_disk_detach (uptr);
|
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)));
|
uptr->capac = (t_addr)(filesystem_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
|
||||||
capac1 = strdup (sprint_capac (dptr, uptr));
|
capac1 = strdup (sprint_capac (dptr, uptr));
|
||||||
uptr->capac = saved_capac;
|
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));
|
sim_uname (uptr), cptr, capac1, sprint_capac (dptr, uptr));
|
||||||
free (capac1);
|
free (capac1);
|
||||||
sim_disk_detach (uptr);
|
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)));
|
uptr->capac = (t_addr)(container_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)));
|
||||||
capac1 = strdup (sprint_capac (dptr, uptr));
|
capac1 = strdup (sprint_capac (dptr, uptr));
|
||||||
uptr->capac = saved_capac;
|
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));
|
sim_uname (uptr), container_dtype, (*container_dtype != '\0') ? " " : "", cptr, capac1, sprint_capac (dptr, uptr));
|
||||||
free (capac1);
|
free (capac1);
|
||||||
sim_disk_detach (uptr);
|
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 : "";
|
container_dtype = ctx->footer ? (const char *)ctx->footer->DriveType : "";
|
||||||
sim_switches = saved_switches;
|
sim_switches = saved_switches;
|
||||||
if (r == SCPE_OK)
|
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",
|
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,
|
sim_uname (uptr), container_dtype, (*container_dtype != '\0') ? " " : "", cptr,
|
||||||
capac1, sprint_capac (dptr, uptr));
|
capac1, sprint_capac (dptr, uptr));
|
||||||
free (capac1);
|
free (capac1);
|
||||||
return r;
|
return r;
|
||||||
|
@ -3317,9 +3317,9 @@ if (uptr->flags & UNIT_BUFABLE) { /* buffer in memory? */
|
||||||
t_stat r = SCPE_OK;
|
t_stat r = SCPE_OK;
|
||||||
|
|
||||||
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
|
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 */
|
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 */
|
ctx->xfer_element_size); /* allocate copy */
|
||||||
if ((uptr->filebuf == NULL) || /* either failed? */
|
if ((uptr->filebuf == NULL) || /* either failed? */
|
||||||
(uptr->filebuf2 == NULL)) {
|
(uptr->filebuf2 == NULL)) {
|
||||||
|
@ -3379,7 +3379,7 @@ if (NULL == find_dev_from_unit (uptr))
|
||||||
if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
||||||
uint32 cap = (uptr->hwmark + uptr->dptr->aincr - 1) / uptr->dptr->aincr;
|
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)) {
|
(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_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);
|
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
|
/* Factory bad block table creation routine
|
||||||
|
|
||||||
This routine writes a DEC standard 144 compliant bad block table on the
|
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
|
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:
|
formatted as follows:
|
||||||
|
|
||||||
words 0-1 pack id number
|
words 0-1 pack id number
|
||||||
|
@ -3948,9 +3948,9 @@ if (strchr (openmode, 'r'))
|
||||||
DesiredAccess |= GENERIC_READ;
|
DesiredAccess |= GENERIC_READ;
|
||||||
if (strchr (openmode, 'w') || strchr (openmode, '+'))
|
if (strchr (openmode, 'w') || strchr (openmode, '+'))
|
||||||
DesiredAccess |= GENERIC_WRITE;
|
DesiredAccess |= GENERIC_WRITE;
|
||||||
/* SCP Command Line parsing replaces \\ with \ presuming this is an
|
/* SCP Command Line parsing replaces \\ with \ presuming this is an
|
||||||
escape sequence. This only affecdts RAW device names and UNC paths.
|
escape sequence. This only affects RAW device names and UNC paths.
|
||||||
We handle the RAW device name case here by prepending paths beginning
|
We handle the RAW device name case here by prepending paths beginning
|
||||||
with \.\ with an extra \. */
|
with \.\ with an extra \. */
|
||||||
if ((!memcmp ("\\.\\", rawdevicename, 3)) ||
|
if ((!memcmp ("\\.\\", rawdevicename, 3)) ||
|
||||||
(!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);
|
Handle = CreateFileA (tmpname, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH, NULL);
|
||||||
free (tmpname);
|
free (tmpname);
|
||||||
if (Handle != INVALID_HANDLE_VALUE) {
|
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)) {
|
((DesiredAccess & GENERIC_WRITE) && is_cdrom)) {
|
||||||
CloseHandle (Handle);
|
CloseHandle (Handle);
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
|
@ -5411,7 +5411,7 @@ static FILE *sim_vhd_disk_open (const char *szVHDPath, const char *DesiredAccess
|
||||||
0);
|
0);
|
||||||
if (Status)
|
if (Status)
|
||||||
goto Cleanup_Return;
|
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)) {
|
(ParentModifiedTimeStamp != hVHD->Dynamic.ParentTimeStamp)) {
|
||||||
if (sim_switches & SWMASK ('O')) { /* OVERRIDE consistency checks? */
|
if (sim_switches & SWMASK ('O')) { /* OVERRIDE consistency checks? */
|
||||||
if ((sim_switches & SWMASK ('U')) && /* FIX (UPDATE) consistency checks AND */
|
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 */
|
/* We are now dealing with a Dynamically expanding or differencing disk */
|
||||||
DynamicBlockSize = NtoHl (hVHD->Dynamic.BlockSize);
|
DynamicBlockSize = NtoHl (hVHD->Dynamic.BlockSize);
|
||||||
if ((DynamicBlockSize == 0) ||
|
if ((DynamicBlockSize == 0) ||
|
||||||
((DynamicBlockSize & (DynamicBlockSize - 1)) != 0)) {
|
((DynamicBlockSize & (DynamicBlockSize - 1)) != 0)) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return SCPE_IOERR;
|
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 */
|
/* We are now dealing with a Dynamically expanding or differencing disk */
|
||||||
DynamicBlockSize = NtoHl (hVHD->Dynamic.BlockSize);
|
DynamicBlockSize = NtoHl (hVHD->Dynamic.BlockSize);
|
||||||
if ((DynamicBlockSize == 0) ||
|
if ((DynamicBlockSize == 0) ||
|
||||||
((DynamicBlockSize & (DynamicBlockSize - 1)) != 0)) {
|
((DynamicBlockSize & (DynamicBlockSize - 1)) != 0)) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return SCPE_IOERR;
|
return SCPE_IOERR;
|
||||||
|
@ -6381,9 +6381,9 @@ while (BytesToWrite && (r == SCPE_OK)) {
|
||||||
goto Fatal_IO_Error;
|
goto Fatal_IO_Error;
|
||||||
/* Since a large VHD can have a pretty large BAT, and we've only changed one longword bat entry
|
/* 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 */
|
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));
|
(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
|
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 */
|
BAT table. If so, only write the BAT data needed */
|
||||||
if (BATUpdateBufferAddress < (uint8 *)hVHD->BAT) {
|
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 */
|
return TRUE; /* can't stat assume attached */
|
||||||
}
|
}
|
||||||
free (fullpath);
|
free (fullpath);
|
||||||
if ((statb.st_dev != filestat.st_dev) ||
|
if ((statb.st_dev != filestat.st_dev) ||
|
||||||
(statb.st_ino != filestat.st_ino) ||
|
(statb.st_ino != filestat.st_ino) ||
|
||||||
(statb.st_mode != filestat.st_mode) ||
|
(statb.st_mode != filestat.st_mode) ||
|
||||||
(statb.st_nlink != filestat.st_nlink) ||
|
(statb.st_nlink != filestat.st_nlink) ||
|
||||||
|
@ -6556,7 +6556,7 @@ free (fullname);
|
||||||
return FALSE; /* Not attached */
|
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,
|
const char *filename,
|
||||||
t_offset FileSize,
|
t_offset FileSize,
|
||||||
const struct stat *filestat,
|
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)) &&
|
if ((container_size != (t_offset)-1) && (container_size > (t_offset)sizeof (*f)) &&
|
||||||
(sim_fseeko (container, container_size - sizeof (*f), SEEK_SET) == 0) &&
|
(sim_fseeko (container, container_size - sizeof (*f), SEEK_SET) == 0) &&
|
||||||
(sizeof (*f) == sim_fread (f, 1, sizeof (*f), container))) {
|
(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))))) {
|
(f->Checksum == NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum))))) {
|
||||||
uint8 *sector_data;
|
uint8 *sector_data;
|
||||||
uint8 *zero_sector;
|
uint8 *zero_sector;
|
||||||
size_t sector_size = NtoHl (f->SectorSize);
|
size_t sector_size = NtoHl (f->SectorSize);
|
||||||
t_offset highwater = (((t_offset)NtoHl (f->Highwater[0])) << 32) | ((t_offset)NtoHl (f->Highwater[1]));
|
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;
|
sector_size = 16384;
|
||||||
/* determine whole sectors in original container size */
|
/* determine whole sectors in original container size */
|
||||||
/* By default we chop off the disk footer and trailing */
|
/* By default we chop off the disk footer and trailing */
|
||||||
|
@ -6686,7 +6686,7 @@ if (info->flag == 0) {
|
||||||
" AccessFormat: %s\n"
|
" AccessFormat: %s\n"
|
||||||
" CreationTime: %s",
|
" CreationTime: %s",
|
||||||
uptr->filename,
|
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);
|
NtoHl (f->TransferElementSize), fmts[f->AccessFormat].name, f->CreationTime);
|
||||||
if (f->DeviceName[0] != '\0')
|
if (f->DeviceName[0] != '\0')
|
||||||
sim_printf (" DeviceName: %s\n", (char *)f->DeviceName);
|
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++)
|
for (i = 0; i < uint32s_per_sector; i++)
|
||||||
if (c->data[i + sector_to_check * uint32s_per_sector] != (lba + sector_to_check)) {
|
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]);
|
lba + sector_to_check, lba + sector_to_check, i, c->data[i + sector_to_check * uint32s_per_sector]);
|
||||||
unexpected_data = TRUE;
|
unexpected_data = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
24
sim_disk.h
24
sim_disk.h
|
@ -19,12 +19,12 @@
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
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.
|
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
|
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.
|
authorization from Robert M Supnik and Mark Pizzolato.
|
||||||
|
|
||||||
25-Jan-11 MP Initial Implemementation
|
25-Jan-11 MP Initial Implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SIM_DISK_H_
|
#ifndef SIM_DISK_H_
|
||||||
|
@ -70,19 +70,19 @@ typedef void (*DISK_PCALLBACK)(UNIT *unit, t_stat status);
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
|
|
||||||
t_stat sim_disk_init (void);
|
t_stat sim_disk_init (void);
|
||||||
t_stat sim_disk_attach (UNIT *uptr,
|
t_stat sim_disk_attach (UNIT *uptr,
|
||||||
const char *cptr,
|
const char *cptr,
|
||||||
size_t memory_sector_size, /* memory footprint of sector data */
|
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 */
|
t_bool dontchangecapac, /* if false just change uptr->capac as needed */
|
||||||
uint32 debugbit, /* debug bit */
|
uint32 debugbit, /* debug bit */
|
||||||
const char *drivetype, /* drive type */
|
const char *drivetype, /* drive type */
|
||||||
uint32 pdp11_tracksize, /* BAD144 track */
|
uint32 pdp11_tracksize, /* BAD144 track */
|
||||||
int completion_delay); /* Minimum Delay for asynch I/O completion */
|
int completion_delay); /* Minimum Delay for asynch I/O completion */
|
||||||
t_stat sim_disk_attach_ex (UNIT *uptr,
|
t_stat sim_disk_attach_ex (UNIT *uptr,
|
||||||
const char *cptr,
|
const char *cptr,
|
||||||
size_t memory_sector_size, /* memory footprint of sector data */
|
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 */
|
t_bool dontchangecapac, /* if false just change uptr->capac as needed */
|
||||||
uint32 dbit, /* debug bit */
|
uint32 dbit, /* debug bit */
|
||||||
const char *dtype, /* drive type */
|
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 */
|
int completion_delay, /* Minimum Delay for asynch I/O completion */
|
||||||
const char **drivetypes); /* list of drive types (from smallest to largest) */
|
const char **drivetypes); /* list of drive types (from smallest to largest) */
|
||||||
/* to try and fit the container/file system into */
|
/* to try and fit the container/file system into */
|
||||||
t_stat sim_disk_attach_ex2 (UNIT *uptr,
|
t_stat sim_disk_attach_ex2 (UNIT *uptr,
|
||||||
const char *cptr,
|
const char *cptr,
|
||||||
size_t memory_sector_size, /* memory footprint of sector data */
|
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 */
|
t_bool dontchangecapac, /* if false just change uptr->capac as needed */
|
||||||
uint32 dbit, /* debug bit */
|
uint32 dbit, /* debug bit */
|
||||||
const char *dtype, /* drive type */
|
const char *dtype, /* drive type */
|
||||||
|
|
468
sim_ether.c
468
sim_ether.c
|
@ -66,27 +66,27 @@
|
||||||
HP/UX ??
|
HP/UX ??
|
||||||
Compaq Tru64 Unix ??
|
Compaq Tru64 Unix ??
|
||||||
VMS Alpha/Itanium VMS only, needs VMS libpcap
|
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/
|
http://winpcap.polito.it/
|
||||||
Npcap is a complete replacement for systems running Windows7 and later
|
Npcap is a complete replacement for systems running Windows7 and later
|
||||||
and is available from:
|
and is available from:
|
||||||
https://nmap.org/npcap
|
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
|
http://simh.trailing-edge.com/sources/vms-pcap.zip
|
||||||
libpcap for other Unix platforms is available at:
|
libpcap for other Unix platforms is available at:
|
||||||
NOTE: As of the release of this version of sim_ether.c ALL current
|
NOTE: As of the release of this version of sim_ether.c ALL current
|
||||||
*nix platforms ship with a sufficiently new version of
|
*nix platforms ship with a sufficiently new version of
|
||||||
libpcap, and ALL provide a libpcap-dev package for developing
|
libpcap, and ALL provide a libpcap-dev package for developing
|
||||||
libpcap based applications. The OS vendor supplied version
|
libpcap based applications. The OS vendor supplied version
|
||||||
of libpcap AND the libpcap-dev components are preferred for
|
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.
|
host system which use libpcap.
|
||||||
Current Version: http://www.tcpdump.org/daily/libpcap-current.tar.gz
|
Current Version: http://www.tcpdump.org/daily/libpcap-current.tar.gz
|
||||||
Released Version: http://www.tcpdump.org/release/
|
Released Version: http://www.tcpdump.org/release/
|
||||||
|
|
||||||
When absolutely necessary (see NOTE above about vendor supplied
|
When absolutely necessary (see NOTE above about vendor supplied
|
||||||
libpcap), we've gotten the tarball, unpacked, built and installed
|
libpcap), we've gotten the tarball, unpacked, built and installed
|
||||||
it with:
|
it with:
|
||||||
gzip -dc libpcap-current.tar.gz | tar xvf -
|
gzip -dc libpcap-current.tar.gz | tar xvf -
|
||||||
cd libpcap-directory-name
|
cd libpcap-directory-name
|
||||||
|
@ -95,74 +95,74 @@
|
||||||
make install
|
make install
|
||||||
Note: The "make install" step generally will have to be done as root.
|
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
|
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.
|
reference the OS provided libpcap or the one just installed.
|
||||||
|
|
||||||
|
|
||||||
Note: Building for the platforms indicated above, with the indicated libpcap,
|
Note: Building for the platforms indicated above, with the indicated libpcap,
|
||||||
should automatically leverage the appropriate mechanisms contained here.
|
should automatically leverage the appropriate mechanisms contained here.
|
||||||
Things are structured so that it is likely to work for any other as yet
|
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
|
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
|
can update the table above. If it doesn't work, then the following #define
|
||||||
variables can influence the operation on an untested platform.
|
variables can influence the operation on an untested platform.
|
||||||
|
|
||||||
USE_BPF - Determines if this code leverages a libpcap/WinPcap
|
USE_BPF - Determines if this code leverages a libpcap/WinPcap
|
||||||
provided bpf packet filtering facility. All tested
|
provided bpf packet filtering facility. All tested
|
||||||
environments have bpf facilities that work the way we
|
environments have bpf facilities that work the way we
|
||||||
need them to. However a new one might not. undefine
|
need them to. However a new one might not. undefine
|
||||||
this variable to let this code do its own filtering.
|
this variable to let this code do its own filtering.
|
||||||
USE_SETNONBLOCK - Specifies whether the libpcap environment's non-blocking
|
USE_SETNONBLOCK - Specifies whether the libpcap environment's non-blocking
|
||||||
semantics are to be leveraged. This helps to manage the
|
semantics are to be leveraged. This helps to manage the
|
||||||
varying behaviours of the kernel packet facilities
|
varying behaviours of the kernel packet facilities
|
||||||
leveraged by libpcap.
|
leveraged by libpcap.
|
||||||
USE_READER_THREAD - Specifies that packet reading should be done in the
|
USE_READER_THREAD - Specifies that packet reading should be done in the
|
||||||
context of a separate thread. The Posix threading
|
context of a separate thread. The Posix threading
|
||||||
APIs are used. This option is less efficient than the
|
APIs are used. This option is less efficient than the
|
||||||
default non-threaded approach, but it exists since some
|
default non-threaded approach, but it exists since some
|
||||||
platforms don't want to work with nonblocking libpcap
|
platforms don't want to work with nonblocking libpcap
|
||||||
semantics. OpenBSD and NetBSD either don't have pthread
|
semantics. OpenBSD and NetBSD either don't have pthread
|
||||||
APIs available, or they are too buggy to be useful.
|
APIs available, or they are too buggy to be useful.
|
||||||
Using the threaded approach may require special compile
|
Using the threaded approach may require special compile
|
||||||
and/or link time switches (i.e. -lpthread or -pthread,
|
and/or link time switches (i.e. -lpthread or -pthread,
|
||||||
etc.) Consult the documentation for your platform as
|
etc.) Consult the documentation for your platform as
|
||||||
needed. Although this may be 'less efficient' than the
|
needed. Although this may be 'less efficient' than the
|
||||||
non-threaded approach, the efficiency is an overall system
|
non-threaded approach, the efficiency is an overall system
|
||||||
efficiency not necessarily a simulator efficiency. This
|
efficiency not necessarily a simulator efficiency. This
|
||||||
means that work is removed from the thread executing
|
means that work is removed from the thread executing
|
||||||
simulated instructions so the simulated system will most
|
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).
|
multi-core and have someplace to do this work in parallel).
|
||||||
MUST_DO_SELECT - Specifies that, when USE_READER_THREAD is active,
|
MUST_DO_SELECT - Specifies that, when USE_READER_THREAD is active,
|
||||||
select() should be used to determine when available
|
select() should be used to determine when available
|
||||||
packets are ready for reading. Otherwise, we depend
|
packets are ready for reading. Otherwise, we depend
|
||||||
on the libpcap/kernel packet timeout specified on
|
on the libpcap/kernel packet timeout specified on
|
||||||
pcap_open_live. If USE_READER_THREAD is not set, then
|
pcap_open_live. If USE_READER_THREAD is not set, then
|
||||||
MUST_DO_SELECT is irrelevant
|
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
|
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
|
allows device names of the form tap:tap0 to be specified
|
||||||
at open time. This functionality is only useful/needed
|
at open time. This functionality is only useful/needed
|
||||||
on *nix platforms since native sharing of Windows NIC
|
on *nix platforms since native sharing of Windows NIC
|
||||||
devices works with no external magic.
|
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
|
included. This can be leveraged, along with OS bridging
|
||||||
capabilities to share a single LAN interface. It also
|
capabilities to share a single LAN interface. It also
|
||||||
can allow a simulator to have useful networking
|
can allow a simulator to have useful networking
|
||||||
functionality when running without root access. This
|
functionality when running without root access. This
|
||||||
allows device names of the form vde:/tmp/switch to be
|
allows device names of the form vde:/tmp/switch to be
|
||||||
specified at open time. This functionality is only
|
specified at open time. This functionality is only
|
||||||
available on *nix platforms since the vde api isn't
|
available on *nix platforms since the vde api isn't
|
||||||
available on Windows.
|
available on Windows.
|
||||||
HAVE_SLIRP_NETWORK- Specifies that support for SLiRP networking should be
|
HAVE_SLIRP_NETWORK- Specifies that support for SLiRP networking should be
|
||||||
included. This can be leveraged to provide User Mode
|
included. This can be leveraged to provide User Mode
|
||||||
IP NAT connectivity for simulators.
|
IP NAT connectivity for simulators.
|
||||||
|
|
||||||
NEED_PCAP_SENDPACKET
|
NEED_PCAP_SENDPACKET
|
||||||
- Specifies that you are using an older version of libpcap
|
- Specifies that you are using an older version of libpcap
|
||||||
which doesn't provide a pcap_sendpacket API.
|
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
|
compiler command line which builds all of the modules included in a
|
||||||
simulator.
|
simulator.
|
||||||
|
|
||||||
|
@ -171,9 +171,9 @@
|
||||||
Modification history:
|
Modification history:
|
||||||
|
|
||||||
30-Mar-12 MP Added host NIC address determination on supported VMS platforms
|
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.
|
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
|
under Cygwin
|
||||||
01-Mar-12 AGN Add conditionals for Cygwin dynamic loading of wpcap.dll
|
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.
|
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
|
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
|
29-Oct-11 MP Added support for integrated Tap networking interfaces on OSX
|
||||||
12-Aug-11 MP Cleaned up payload length determination
|
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
|
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
|
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)
|
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
|
USE_READER_THREAD does I/O in separate threads. This helps
|
||||||
throughput since it allows these I/O bound threads to preempt
|
throughput since it allows these I/O bound threads to preempt
|
||||||
the main thread (which is executing simulated instructions).
|
the main thread (which is executing simulated instructions).
|
||||||
09-Dec-10 MP allowed more flexible parsing of MAC address strings
|
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
|
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
|
07-Dec-10 MP Reworked DECnet self detection to the more general approach
|
||||||
of loopback self when a Physical Address is being set.
|
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.
|
USE_READER_THREAD is defined.
|
||||||
20-Aug-10 TVO Fix for Mac OSX 10.6
|
20-Aug-10 TVO Fix for Mac OSX 10.6
|
||||||
17-Jun-10 MP Fixed bug in the AUTODIN II hash filtering.
|
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.
|
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.
|
platforms.
|
||||||
31-May-10 MP Added support for more TOE (TCP Offload Engine) features for IPv4
|
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
|
network traffic from the host and/or from hosts on the LAN. These
|
||||||
new TOE features are: LSO (Large Send Offload) and Jumbo packet
|
new TOE features are: LSO (Large Send Offload) and Jumbo packet
|
||||||
fragmentation support. These features allow a simulated network
|
fragmentation support. These features allow a simulated network
|
||||||
device to support traffic when a host leverages a NIC's Large
|
device to support traffic when a host leverages a NIC's Large
|
||||||
Send Offload capabilities to fregment and/or segment outgoing
|
Send Offload capabilities to fragment and/or segment outgoing
|
||||||
network traffic. Additionally a simulated network device can
|
network traffic. Additionally a simulated network device can
|
||||||
reasonably exist on a LAN which is configured to use Jumbo frames.
|
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)
|
packets from a host with a NIC which has TOE (TCP Offload Engine)
|
||||||
enabled which is expected to implement the checksum computations
|
enabled which is expected to implement the checksum computations
|
||||||
in hardware. Since we catch packets before they arrive at the
|
in hardware. Since we catch packets before they arrive at the
|
||||||
NIC the expected checksum insertions haven't been performed yet.
|
NIC the expected checksum insertions haven't been performed yet.
|
||||||
This processing is only done for packets sent from the hoat to
|
This processing is only done for packets sent from the host to
|
||||||
the guest we're supporting. In general this will be a relatively
|
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
|
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
|
determination of packets specifically arriving from the host we
|
||||||
need to know the hardware MAC address of the host NIC. Currently
|
need to know the hardware MAC address of the host NIC. Currently
|
||||||
determining a NIC's MAC address is relatively easy on Windows.
|
determining a NIC's MAC address is relatively easy on Windows.
|
||||||
The non-windows code works on linux and may work on other *nix
|
The non-windows code works on linux and may work on other *nix
|
||||||
platforms either as is or with slight modifications. The code,
|
platforms either as is or with slight modifications. The code,
|
||||||
as implemented, only messes with this activity if the host
|
as implemented, only messes with this activity if the host
|
||||||
interface MAC address can be determined.
|
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
|
than ETH_MIN_PACKET in length. These come from packets
|
||||||
looped back by some bridging mechanism and need to be padded
|
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
|
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.
|
devices, AND it belongs here to get CRC processing right.
|
||||||
05-Mar-08 MP Added optional multicast filtering support for doing
|
05-Mar-08 MP Added optional multicast filtering support for doing
|
||||||
LANCE style AUTODIN II based hashed filtering.
|
LANCE style AUTODIN II based hashed filtering.
|
||||||
07-Feb-08 MP Added eth_show_dev to display ethernet state
|
07-Feb-08 MP Added eth_show_dev to display ethernet state
|
||||||
Changed the return value from eth_read to return whether
|
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
|
checked constant return value that previously was being
|
||||||
supplied.
|
supplied.
|
||||||
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
|
29-Jan-08 MP Added eth_set_async to provide a mechanism (when
|
||||||
USE_READER_THREAD is enabled) to allow packet reception
|
USE_READER_THREAD is enabled) to allow packet reception
|
||||||
to dynamically update the simulator event queue and
|
to dynamically update the simulator event queue and
|
||||||
potentially avoid polling for I/O. This provides a minimal
|
potentially avoid polling for I/O. This provides a minimal
|
||||||
overhead (no polling) maximal responsiveness for network
|
overhead (no polling) maximal responsiveness for network
|
||||||
activities.
|
activities.
|
||||||
29-Jan-08 MP Properly sequenced activities in eth_close to avoid a race
|
29-Jan-08 MP Properly sequenced activities in eth_close to avoid a race
|
||||||
condition when USE_READER_THREAD is enabled.
|
condition when USE_READER_THREAD is enabled.
|
||||||
25-Jan-08 MP Changed the following 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.
|
in packet data which is read.
|
||||||
- Added call to pcap_setmintocopy to minimize packet
|
- Added call to pcap_setmintocopy to minimize packet
|
||||||
delivery latencies.
|
delivery latencies.
|
||||||
- Added ethq_destroy and used it to avoid a memory leak in
|
- Added ethq_destroy and used it to avoid a memory leak in
|
||||||
eth_close.
|
eth_close.
|
||||||
|
@ -262,8 +262,8 @@
|
||||||
Fixed the bpf filter used when no traffic is to be matched.
|
Fixed the bpf filter used when no traffic is to be matched.
|
||||||
Reworked eth_add_packet_crc32 implementation to avoid an
|
Reworked eth_add_packet_crc32 implementation to avoid an
|
||||||
extra buffer copy while reading packets.
|
extra buffer copy while reading packets.
|
||||||
Fixedup #ifdef's relating to USE_SHARED so that setting
|
Fixedup #ifdef's relating to USE_SHARED so that setting
|
||||||
USE_SHARED or USE_NETWORK will build a working network
|
USE_SHARED or USE_NETWORK will build a working network
|
||||||
environment.
|
environment.
|
||||||
23-Jan-08 MP Reworked eth_packet_trace and eth_packet_trace_ex to allow
|
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
|
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
|
25-Mar-04 MP Revised comments and minor #defines to deal with updated
|
||||||
libpcap which now provides pcap_sendpacket on all platforms.
|
libpcap which now provides pcap_sendpacket on all platforms.
|
||||||
04-Feb-04 MP Returned success/fail status from eth_write to support
|
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.
|
write packets.
|
||||||
Added threaded approach to reading packets since
|
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.
|
inconsistently implemented non-blocking read approach.
|
||||||
04-Feb-04 DTH Converted ETH_DEBUG to sim_debug
|
04-Feb-04 DTH Converted ETH_DEBUG to sim_debug
|
||||||
13-Jan-04 MP tested and fixed on OpenBSD, NetBS and FreeBSD.
|
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.
|
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
|
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
|
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
|
char data instead of unsigned char data. Suggested by the
|
||||||
DECC compiler.
|
DECC compiler.
|
||||||
15-Jan-03 DTH Corrected PacketGetAdapterNames parameter2 datatype
|
15-Jan-03 DTH Corrected PacketGetAdapterNames parameter2 datatype
|
||||||
|
@ -364,7 +364,7 @@
|
||||||
24-Sep-02 DTH Finished eth_devices, eth_getname
|
24-Sep-02 DTH Finished eth_devices, eth_getname
|
||||||
18-Sep-02 DTH Callbacks implemented
|
18-Sep-02 DTH Callbacks implemented
|
||||||
13-Sep-02 DTH Basic packet read/write written
|
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 };
|
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)
|
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]);
|
return sim_messagef (SCPE_ARG, "Invalid MAC address byte value: %02X\n", a[i]);
|
||||||
else {
|
else {
|
||||||
uint32 mask, shift;
|
uint32 mask, shift;
|
||||||
|
|
||||||
state.base_mac[i] = a[i];
|
state.base_mac[i] = a[i];
|
||||||
if (((i + 1) << 3) < state.bits)
|
if (((i + 1) << 3) < state.bits)
|
||||||
shift = 0;
|
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");
|
fprintf (st, "This simulator was not built with ethernet device support\n");
|
||||||
return SCPE_OK;
|
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)
|
ETH_MAC* const mac)
|
||||||
{return SCPE_NOFNC;}
|
{return SCPE_NOFNC;}
|
||||||
t_stat eth_set_throttle (ETH_DEV* dev, uint32 time, uint32 burst, uint32 delay)
|
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)
|
ETH_BOOL all_multicast, ETH_BOOL promiscuous, ETH_MULTIHASH* const hash)
|
||||||
{return SCPE_NOFNC;}
|
{return SCPE_NOFNC;}
|
||||||
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
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)
|
ETH_BOOL match_broadcast, ETH_MULTIHASH* const hash)
|
||||||
{return SCPE_NOFNC;}
|
{return SCPE_NOFNC;}
|
||||||
const char *eth_version (void)
|
const char *eth_version (void)
|
||||||
|
@ -1033,8 +1033,8 @@ typedef void * pcap_t; /* Pseudo Type to avoid compiler errors */
|
||||||
#endif /* HAVE_PCAP_NETWORK */
|
#endif /* HAVE_PCAP_NETWORK */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The libpcap provided API pcap_findalldevs() on most platforms, will
|
The libpcap provided API pcap_findalldevs() on most platforms, will
|
||||||
leverage the getifaddrs() API if it is available in preference to
|
leverage the getifaddrs() API if it is available in preference to
|
||||||
alternate platform specific methods of determining the interface list.
|
alternate platform specific methods of determining the interface list.
|
||||||
|
|
||||||
A limitation of getifaddrs() is that it returns only interfaces which
|
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 that we are interested in since a host may have dedicated
|
||||||
interfaces for a simulator, which is otherwise unused by the host.
|
interfaces for a simulator, which is otherwise unused by the host.
|
||||||
|
|
||||||
One could hand craft the the build of libpcap to specifically use
|
One could hand craft the the build of libpcap to specifically use
|
||||||
alternate methods to implement pcap_findalldevs(). However, this can
|
alternate methods to implement pcap_findalldevs(). However, this can
|
||||||
get tricky, and would then result in a sort of deviant libpcap.
|
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
|
extend the set of available interfaces to include any that are not
|
||||||
returned by pcap_findalldevs.
|
returned by pcap_findalldevs.
|
||||||
|
|
||||||
|
@ -1098,7 +1098,7 @@ for (i=0; i<used; i++) {
|
||||||
continue;
|
continue;
|
||||||
reglen = sizeof(regval);
|
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 */
|
/* same comment about Windows XP x64 (above) using RegQueryValueEx */
|
||||||
if ((status = RegQueryValueExA (reghnd, "Name", NULL, ®type, regval, ®len)) != ERROR_SUCCESS) {
|
if ((status = RegQueryValueExA (reghnd, "Name", NULL, ®type, regval, ®len)) != ERROR_SUCCESS) {
|
||||||
RegCloseKey (reghnd);
|
RegCloseKey (reghnd);
|
||||||
|
@ -1210,9 +1210,9 @@ return used;
|
||||||
|
|
||||||
#ifdef HAVE_TAP_NETWORK
|
#ifdef HAVE_TAP_NETWORK
|
||||||
#if defined(__linux) || defined(__linux__)
|
#if defined(__linux) || defined(__linux__)
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <linux/if_tun.h>
|
#include <linux/if_tun.h>
|
||||||
#elif defined(HAVE_BSDTUNTAP)
|
#elif defined(HAVE_BSDTUNTAP)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <net/if_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
|
uint32 Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
|
||||||
///< for a complete list of valid codes.
|
///< for a complete list of valid codes.
|
||||||
uint32 Length; ///< Length of the data field
|
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.
|
///< from the adapter.
|
||||||
};
|
};
|
||||||
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
|
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
|
||||||
typedef void **LPADAPTER;
|
typedef void **LPADAPTER;
|
||||||
#define OID_802_3_CURRENT_ADDRESS 0x01010102 /* Extracted from ntddndis.h */
|
#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_PacketCloseAdapter = (void (*)(LPADAPTER lpAdapter))dlsym(hDll, "PacketCloseAdapter");
|
||||||
p_PacketRequest = (int (*)(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData))dlsym(hDll, "PacketRequest");
|
p_PacketRequest = (int (*)(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData))dlsym(hDll, "PacketRequest");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Open the selected adapter */
|
/* Open the selected adapter */
|
||||||
|
|
||||||
lpAdapter = p_PacketOpenAdapter(AdapterName);
|
lpAdapter = p_PacketOpenAdapter(AdapterName);
|
||||||
|
@ -1625,7 +1625,7 @@ static int pcap_mac_if_win32(const char *AdapterName, unsigned char MACAddress[6
|
||||||
return -1;
|
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));
|
OidData = (PACKET_OID_DATA *)malloc(6 + sizeof(PACKET_OID_DATA));
|
||||||
if (OidData == NULL) {
|
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);
|
Device.dsc$w_length = strlen(VMS_Device);
|
||||||
if (!$VMS_STATUS_SUCCESS( sys$assign (&Device, &chan, 0, 0, 0) ))
|
if (!$VMS_STATUS_SUCCESS( sys$assign (&Device, &chan, 0, 0, 0) ))
|
||||||
return -1;
|
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);
|
0, &setupdesc, 0, 0, 0, 0);
|
||||||
if ((!$VMS_STATUS_SUCCESS(status)) || (!$VMS_STATUS_SUCCESS(iosb[0]))) {
|
if ((!$VMS_STATUS_SUCCESS(status)) || (!$VMS_STATUS_SUCCESS(iosb[0]))) {
|
||||||
sys$dassgn(chan);
|
sys$dassgn(chan);
|
||||||
return -1;
|
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);
|
0, &chardesc, 0, 0, 0, 0);
|
||||||
sys$dassgn(chan);
|
sys$dassgn(chan);
|
||||||
if ((!$VMS_STATUS_SUCCESS(status)) || (!$VMS_STATUS_SUCCESS(iosb[0])))
|
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];
|
char tool[CBUFSIZE];
|
||||||
const char *turnon[] = {
|
const char *turnon[] = {
|
||||||
"ip link set dev %.*s up 2>/dev/null",
|
"ip link set dev %.*s up 2>/dev/null",
|
||||||
"ifconfig %.*s up 2>/dev/null",
|
"ifconfig %.*s up 2>/dev/null",
|
||||||
NULL};
|
NULL};
|
||||||
const char *patterns[] = {
|
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]",
|
"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");
|
sim_debug(dev->dbit, dev->dptr, "Reader Thread Starting\n");
|
||||||
|
|
||||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||||
thread which, in general, won't be readily yielding the processor
|
thread which, in general, won't be readily yielding the processor
|
||||||
when this thread needs to run */
|
when this thread needs to run */
|
||||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||||
|
|
||||||
|
@ -1991,7 +1991,7 @@ while (dev->handle) {
|
||||||
{
|
{
|
||||||
fd_set setl;
|
fd_set setl;
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
|
|
||||||
FD_ZERO(&setl);
|
FD_ZERO(&setl);
|
||||||
FD_SET(select_fd, &setl);
|
FD_SET(select_fd, &setl);
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = 0;
|
||||||
|
@ -2001,7 +2001,7 @@ while (dev->handle) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sel_ret = 1;
|
sel_ret = 1;
|
||||||
if (sel_ret < 0 && errno != EINTR)
|
if (sel_ret < 0 && errno != EINTR)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sel_ret > 0) {
|
if (sel_ret > 0) {
|
||||||
|
@ -2128,8 +2128,8 @@ _eth_writer(void *arg)
|
||||||
ETH_DEV* volatile dev = (ETH_DEV*)arg;
|
ETH_DEV* volatile dev = (ETH_DEV*)arg;
|
||||||
ETH_WRITE_REQUEST *request = NULL;
|
ETH_WRITE_REQUEST *request = NULL;
|
||||||
|
|
||||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||||
thread which in general won't be readily yielding the processor when
|
thread which in general won't be readily yielding the processor when
|
||||||
this thread needs to run */
|
this thread needs to run */
|
||||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||||
|
|
||||||
|
@ -2177,9 +2177,9 @@ return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
t_stat eth_set_async (ETH_DEV *dev, int latency)
|
||||||
{
|
{
|
||||||
|
@ -2203,9 +2203,9 @@ if (wakeup_needed) {
|
||||||
return SCPE_OK;
|
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)
|
t_stat eth_clr_async (ETH_DEV *dev)
|
||||||
{
|
{
|
||||||
|
@ -2345,7 +2345,7 @@ else { /* !tap: */
|
||||||
#if defined(HAVE_VDE_NETWORK)
|
#if defined(HAVE_VDE_NETWORK)
|
||||||
char vdeswitch_s[CBUFSIZE]; /* VDE switch name */
|
char vdeswitch_s[CBUFSIZE]; /* VDE switch name */
|
||||||
char vdeport_s[CBUFSIZE]; /* VDE switch port (optional), numeric */
|
char vdeport_s[CBUFSIZE]; /* VDE switch port (optional), numeric */
|
||||||
|
|
||||||
struct vde_open_args voa;
|
struct vde_open_args voa;
|
||||||
const char *devname = savname + 4;
|
const char *devname = savname + 4;
|
||||||
|
|
||||||
|
@ -2616,7 +2616,7 @@ if (1) {
|
||||||
}
|
}
|
||||||
#endif /* defined (USE_READER_THREAD */
|
#endif /* defined (USE_READER_THREAD */
|
||||||
_eth_add_to_open_list (dev);
|
_eth_add_to_open_list (dev);
|
||||||
/*
|
/*
|
||||||
* install a total filter on a newly opened interface and let the device
|
* install a total filter on a newly opened interface and let the device
|
||||||
* simulator install an appropriate filter that reflects the device's
|
* simulator install an appropriate filter that reflects the device's
|
||||||
* configuration.
|
* configuration.
|
||||||
|
@ -2761,7 +2761,7 @@ if (!rand_initialized)
|
||||||
return (rand() & 0xFF);
|
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,
|
ETH_MAC* const mac,
|
||||||
int *reflections,
|
int *reflections,
|
||||||
t_bool silent)
|
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);
|
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 */
|
/* 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)[3] == 0) && ((*mac)[4] == 0) && ((*mac)[5] == 0)) ||
|
||||||
((*mac)[0] & 1)) {
|
((*mac)[0] & 1)) {
|
||||||
return sim_messagef (SCPE_ARG, "%s: Invalid NIC MAC Address: %s\n", sim_dname(dev->dptr), mac_string);
|
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:
|
/* The process of checking address conflicts is used in two ways:
|
||||||
1) to determine the behavior of the currently running packet
|
1) to determine the behavior of the currently running packet
|
||||||
delivery facility regarding whether it may receive copies
|
delivery facility regarding whether it may receive copies
|
||||||
of every packet sent (and how many).
|
of every packet sent (and how many).
|
||||||
2) to verify if a MAC address which this facility is planning
|
2) to verify if a MAC address which this facility is planning
|
||||||
to use as the source address of packets is already in use
|
to use as the source address of packets is already in use
|
||||||
by some other node on the local network
|
by some other node on the local network
|
||||||
Case #1, doesn't require (and explicitly doesn't want) any
|
Case #1, doesn't require (and explicitly doesn't want) any
|
||||||
interaction or response from other systems on the LAN so
|
interaction or response from other systems on the LAN so
|
||||||
therefore no considerations regarding switch packet forwarding
|
therefore no considerations regarding switch packet forwarding
|
||||||
are important. Meanwhile, Case #2 does require responses from
|
are important. Meanwhile, Case #2 does require responses from
|
||||||
other components on the LAN to provide useful functionality.
|
other components on the LAN to provide useful functionality.
|
||||||
The original designers of this mechanism did this when essentially
|
The original designers of this mechanism did this when essentially
|
||||||
all LANs were single collision domains (i.e. ALL nodes which might
|
all LANs were single collision domains (i.e. ALL nodes which might
|
||||||
be affected by an address conflict were physically present on a single
|
be affected by an address conflict were physically present on a single
|
||||||
Ethernet cable which might have been extended by a couple of repeaters).
|
Ethernet cable which might have been extended by a couple of repeaters).
|
||||||
Since that time, essentially no networks are single collision domains.
|
Since that time, essentially no networks are single collision domains.
|
||||||
Thick and thinwire Ethernet cables don't exist and very few networks
|
Thick and thinwire Ethernet cables don't exist and very few networks
|
||||||
even have hubs. Today, essentially all LANs are deployed using one
|
even have hubs. Today, essentially all LANs are deployed using one
|
||||||
or more layers of network switches. In a switched LAN environment, the
|
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
|
switches on the LAN "learn" which ports on the LAN source traffic from
|
||||||
which MAC addresses and then forward traffic destined for particular
|
which MAC addresses and then forward traffic destined for particular
|
||||||
MAC address to the appropriate ports. If a particular MAC address is
|
MAC address to the appropriate ports. If a particular MAC address is
|
||||||
already in use somewhere on the LAN, then the switches "know" where
|
already in use somewhere on the LAN, then the switches "know" where
|
||||||
it is. The host based test using the loopback protocol is poorly
|
it is. The host based test using the loopback protocol is poorly
|
||||||
designed to detect this condition. This test is performed by the host
|
designed to detect this condition. This test is performed by the host
|
||||||
first changing the device's Physical MAC address to the address which
|
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
|
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
|
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
|
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
|
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 tables know where to deliver packets destined to this MAC
|
||||||
address, however the response it generates won't be delivered to the
|
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
|
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
|
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. A better test design to detect these conflicts would be for
|
||||||
the testing system to send a loopback packet FROM the current physical
|
the testing system to send a loopback packet FROM the current physical
|
||||||
MAC address (BEFORE changing it) TO the MAC address being tested with
|
MAC address (BEFORE changing it) TO the MAC address being tested with
|
||||||
the loopback response coming to the current physical MAC address of
|
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 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
|
can't change the software running in these simulators to implement this
|
||||||
better conflict detection approach, we can still "do the right thing"
|
better conflict detection approach, we can still "do the right thing"
|
||||||
in the sim_ether layer. We're already handling the loopback test
|
in the sim_ether layer. We're already handling the loopback test
|
||||||
packets specially since we always had to avoid receiving the packets
|
packets specially since we always had to avoid receiving the packets
|
||||||
which were being sent, but needed to allow for the incoming loopback
|
which were being sent, but needed to allow for the incoming loopback
|
||||||
packets to be properly dealt with. We can extend this current special
|
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
|
AND loopback destination addresses in the packets to be the host NIC's
|
||||||
physical address. The switch network will already know the correct
|
physical address. The switch network will already know the correct
|
||||||
MAC/port relationship for the host NIC's physical address, so loopback
|
MAC/port relationship for the host NIC's physical address, so loopback
|
||||||
response packets will be delivered as needed.
|
response packets will be delivered as needed.
|
||||||
|
|
||||||
Code in _eth_write and _eth_callback provide the special handling to
|
Code in _eth_write and _eth_callback provide the special handling to
|
||||||
perform the described loopback packet adjustments, and code in
|
perform the described loopback packet adjustments, and code in
|
||||||
eth_filter_hash makes sure that the loopback response packets are received.
|
eth_filter_hash makes sure that the loopback response packets are received.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -2905,7 +2905,7 @@ if (reflections)
|
||||||
return SCPE_OK;
|
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)
|
ETH_MAC* const mac)
|
||||||
{
|
{
|
||||||
char mac_string[32];
|
char mac_string[32];
|
||||||
|
@ -2983,13 +2983,13 @@ dev->error_needs_reset = (((dev->transmit_packet_errors + dev->receive_packet_er
|
||||||
#endif
|
#endif
|
||||||
/* Limit errors to 1 per second (per invoking thread (reader and writer)) */
|
/* Limit errors to 1 per second (per invoking thread (reader and writer)) */
|
||||||
sim_os_sleep (1);
|
sim_os_sleep (1);
|
||||||
/*
|
/*
|
||||||
When all of the threads which can reference this ETH_DEV object are
|
When all of the threads which can reference this ETH_DEV object are
|
||||||
simultaneously waiting in this routine, we have the potential to close
|
simultaneously waiting in this routine, we have the potential to close
|
||||||
and reopen the network connection.
|
and reopen the network connection.
|
||||||
We do this after ETH_ERROR_REOPEN_THRESHOLD total errors have occurred.
|
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
|
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, but normally would be about once every 1.5*ETH_ERROR_REOPEN_THRESHOLD
|
||||||
seconds (ONLY when the error condition exists).
|
seconds (ONLY when the error condition exists).
|
||||||
*/
|
*/
|
||||||
#ifdef USE_READER_THREAD
|
#ifdef USE_READER_THREAD
|
||||||
|
@ -3128,7 +3128,7 @@ int write_queue_size = 1;
|
||||||
/* make sure device exists */
|
/* make sure device exists */
|
||||||
if ((!dev) || (dev->eth_api == ETH_API_NONE)) return SCPE_UNATT;
|
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! */
|
return SCPE_IERR; /* that's no good! */
|
||||||
|
|
||||||
/* Get a buffer */
|
/* Get a buffer */
|
||||||
|
@ -3199,26 +3199,26 @@ for (i=0; i<count; ++i) {
|
||||||
int key = 0x3f & (eth_crc32(0, MultiCastList[i], 6) >> 26);
|
int key = 0x3f & (eth_crc32(0, MultiCastList[i], 6) >> 26);
|
||||||
|
|
||||||
key ^= 0x3F;
|
key ^= 0x3F;
|
||||||
printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X Key: %X, Byte: %X, Val: %X\n",
|
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],
|
MultiCastList[i][0], MultiCastList[i][1], MultiCastList[i][2], MultiCastList[i][3], MultiCastList[i][4], MultiCastList[i][5],
|
||||||
key, key>>3, (1 << (key&0x7)));
|
key, key>>3, (1 << (key&0x7)));
|
||||||
lhash[key>>3] |= (1 << (key&0x7));
|
lhash[key>>3] |= (1 << (key&0x7));
|
||||||
}
|
}
|
||||||
if (memcmp(hash, lhash, sizeof(lhash))) {
|
if (memcmp(hash, lhash, sizeof(lhash))) {
|
||||||
printf("Inconsistent Computed Hash:\n");
|
printf("Inconsistent Computed Hash:\n");
|
||||||
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||||
hash[0], hash[1], hash[2], hash[3],
|
hash[0], hash[1], hash[2], hash[3],
|
||||||
hash[4], hash[5], hash[6], hash[7]);
|
hash[4], hash[5], hash[6], hash[7]);
|
||||||
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||||
lhash[0], lhash[1], lhash[2], lhash[3],
|
lhash[0], lhash[1], lhash[2], lhash[3],
|
||||||
lhash[4], lhash[5], lhash[6], lhash[7]);
|
lhash[4], lhash[5], lhash[6], lhash[7]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
printf("Should be: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||||
hash[0], hash[1], hash[2], hash[3],
|
hash[0], hash[1], hash[2], hash[3],
|
||||||
hash[4], hash[5], hash[6], hash[7]);
|
hash[4], hash[5], hash[6], hash[7]);
|
||||||
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
printf("Was: %02X %02X %02X %02X %02X %02X %02X %02X\n",
|
||||||
lhash[0], lhash[1], lhash[2], lhash[3],
|
lhash[0], lhash[1], lhash[2], lhash[3],
|
||||||
lhash[4], lhash[5], lhash[6], lhash[7]);
|
lhash[4], lhash[5], lhash[6], lhash[7]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3310,11 +3310,11 @@ struct TCPHeader {
|
||||||
#define IPPROTO_ICMP 1 /* control message protocol */
|
#define IPPROTO_ICMP 1 /* control message protocol */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint16
|
static uint16
|
||||||
ip_checksum(uint16 *buffer, int size)
|
ip_checksum(uint16 *buffer, int size)
|
||||||
{
|
{
|
||||||
unsigned long cksum = 0;
|
unsigned long cksum = 0;
|
||||||
|
|
||||||
/* Sum all the words together, adding the final byte if size is odd */
|
/* Sum all the words together, adding the final byte if size is odd */
|
||||||
while (size > 1) {
|
while (size > 1) {
|
||||||
cksum += *buffer++;
|
cksum += *buffer++;
|
||||||
|
@ -3332,16 +3332,16 @@ if (size) {
|
||||||
/* Do a little shuffling */
|
/* Do a little shuffling */
|
||||||
cksum = (cksum >> 16) + (cksum & 0xffff);
|
cksum = (cksum >> 16) + (cksum & 0xffff);
|
||||||
cksum += (cksum >> 16);
|
cksum += (cksum >> 16);
|
||||||
|
|
||||||
/* Return the bitwise complement of the resulting mishmash */
|
/* Return the bitwise complement of the resulting mishmash */
|
||||||
return (uint16)(~cksum);
|
return (uint16)(~cksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* src_addr and dest_addr are presented in network byte order
|
* 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)
|
pseudo_checksum(uint16 len, uint16 proto, void *nsrc_addr, void *ndest_addr, uint8 *buff)
|
||||||
{
|
{
|
||||||
uint32 sum;
|
uint32 sum;
|
||||||
|
@ -3351,7 +3351,7 @@ uint16 *dest_addr = (uint16 *)ndest_addr;
|
||||||
/* Sum the data first */
|
/* Sum the data first */
|
||||||
sum = 0xffff&(~ip_checksum((uint16 *)buff, len));
|
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 */
|
destination addresses already in network byte order */
|
||||||
sum += src_addr[0];
|
sum += src_addr[0];
|
||||||
sum += src_addr[1];
|
sum += src_addr[1];
|
||||||
|
@ -3363,7 +3363,7 @@ sum = sum + htons(proto) + htons(len);
|
||||||
/* Do a little shuffling */
|
/* Do a little shuffling */
|
||||||
sum = (sum >> 16) + (sum & 0xffff);
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
sum += (sum >> 16);
|
sum += (sum >> 16);
|
||||||
|
|
||||||
/* Return the bitwise complement of the resulting mishmash */
|
/* Return the bitwise complement of the resulting mishmash */
|
||||||
return (uint16)(~sum);
|
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 */
|
/* We don't do anything with the TCP checksum since we're going to resegment the TCP data below */
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
return;
|
||||||
}
|
}
|
||||||
/* Reasonable Checksums are now in the jumbo packet, but we've got to actually */
|
/* 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_UDP:
|
||||||
case IPPROTO_ICMP:
|
case IPPROTO_ICMP:
|
||||||
++dev->jumbo_fragmented;
|
++dev->jumbo_fragmented;
|
||||||
/* When we're performing LSO (Large Send Offload), we're given a
|
/* When we're performing LSO (Large Send Offload), we're given a
|
||||||
'template' header which may not include a value being populated
|
'template' header which may not include a value being populated
|
||||||
in the IP header length (which is only 16 bits).
|
in the IP header length (which is only 16 bits).
|
||||||
We process as payload everything which isn't known header data. */
|
We process as payload everything which isn't known header data. */
|
||||||
payload_len = (uint16)(len - (14 + IP_HLEN(IP)));
|
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)
|
(i.e. we can use Wireshark to verify packet contents)
|
||||||
we don't want to do this all the time for 2 reasons:
|
we don't want to do this all the time for 2 reasons:
|
||||||
1) sending through pcap involves kernel transitions and
|
1) sending through pcap involves kernel transitions and
|
||||||
2) if the current system reflects sent packets, the
|
2) if the current system reflects sent packets, the
|
||||||
recieving side will receive and process 2 copies of
|
receiving side will receive and process 2 copies of
|
||||||
any packets sent this way. */
|
any packets sent this way. */
|
||||||
ETH_PACK pkt;
|
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);
|
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));
|
TCP = (struct TCPHeader *)(((char *)IP)+IP_HLEN(IP));
|
||||||
orig_tcp_flags = ntohs(TCP->data_offset_and_flags);
|
orig_tcp_flags = ntohs(TCP->data_offset_and_flags);
|
||||||
/* When we're performing LSO (Large Send Offload), we're given a
|
/* When we're performing LSO (Large Send Offload), we're given a
|
||||||
'template' header which may not include a value being populated
|
'template' header which may not include a value being populated
|
||||||
in the IP header length (which is only 16 bits).
|
in the IP header length (which is only 16 bits).
|
||||||
We process as payload everything which isn't known header data. */
|
We process as payload everything which isn't known header data. */
|
||||||
payload_len = (uint16)(len - (14 + IP_HLEN(IP) + TCP_DATA_OFFSET(TCP)));
|
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)
|
(i.e. we can use Wireshark to verify packet contents)
|
||||||
we don't want to do this all the time for 2 reasons:
|
we don't want to do this all the time for 2 reasons:
|
||||||
1) sending through pcap involves kernel transitions and
|
1) sending through pcap involves kernel transitions and
|
||||||
2) if the current system reflects sent packets, the
|
2) if the current system reflects sent packets, the
|
||||||
recieving side will receive and process 2 copies of
|
receiving side will receive and process 2 copies of
|
||||||
any packets sent this way. */
|
any packets sent this way. */
|
||||||
ETH_PACK pkt;
|
ETH_PACK pkt;
|
||||||
|
|
||||||
|
@ -3638,16 +3638,16 @@ function = data[offset] | (data[offset+1] << 8);
|
||||||
if (function != 2) /*forward*/
|
if (function != 2) /*forward*/
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* The only packets we should be responding to are ones which
|
/* The only packets we should be responding to are ones which
|
||||||
we received due to them being directed to our physical MAC address,
|
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
|
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
|
(we may receive others if we're in promiscuous mode, but shouldn't
|
||||||
respond to them) */
|
respond to them) */
|
||||||
if ((0 == (data[0]&1)) && /* Multicast or Broadcast */
|
if ((0 == (data[0]&1)) && /* Multicast or Broadcast */
|
||||||
(0 != memcmp(dev->filter_address[0], data, sizeof(ETH_MAC))))
|
(0 != memcmp(dev->filter_address[0], data, sizeof(ETH_MAC))))
|
||||||
return 0;
|
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 */
|
ignored by consuming the packet and doing nothing else */
|
||||||
if (data[offset+2]&1)
|
if (data[offset+2]&1)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3771,7 +3771,7 @@ if (bpf_used ? to_me : (to_me && !from_me)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_eth_process_loopback(dev, data, header->len))
|
if (_eth_process_loopback(dev, data, header->len))
|
||||||
return;
|
return;
|
||||||
#if defined (USE_READER_THREAD)
|
#if defined (USE_READER_THREAD)
|
||||||
if (1) {
|
if (1) {
|
||||||
int crc_len = 0;
|
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 */
|
/* but were presumed to be traversing a NIC which was going to handle that task */
|
||||||
/* This must be done before any needed CRC calculation */
|
/* This must be done before any needed CRC calculation */
|
||||||
_eth_fix_ip_xsum_offload(dev, (const u_char*)data, len);
|
_eth_fix_ip_xsum_offload(dev, (const u_char*)data, len);
|
||||||
|
|
||||||
if (dev->need_crc)
|
if (dev->need_crc)
|
||||||
crc_len = eth_get_packet_crc32_data(data, len, crc_data);
|
crc_len = eth_get_packet_crc32_data(data, len, crc_data);
|
||||||
|
|
||||||
|
@ -3948,7 +3948,7 @@ if (status < 0) {
|
||||||
status = 1;
|
status = 1;
|
||||||
ethq_remove(&dev->read_queue);
|
ethq_remove(&dev->read_queue);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&dev->lock);
|
pthread_mutex_unlock (&dev->lock);
|
||||||
if ((status) && (routine))
|
if ((status) && (routine))
|
||||||
routine(0);
|
routine(0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -3957,7 +3957,7 @@ return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat eth_bpf_filter (ETH_DEV* dev, int addr_count, ETH_MAC* const filter_address,
|
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,
|
int reflections,
|
||||||
ETH_MAC* physical_addr,
|
ETH_MAC* physical_addr,
|
||||||
ETH_MAC* host_nic_phy_hw_addr,
|
ETH_MAC* host_nic_phy_hw_addr,
|
||||||
|
@ -3986,9 +3986,9 @@ if (!promiscuous) {
|
||||||
sprintf(&buf[strlen(buf)], ")");
|
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
|
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. */
|
simulated NIC will not send out packets with multicast source fields. */
|
||||||
if ((addr_count > 0) && (reflections > 0)) {
|
if ((addr_count > 0) && (reflections > 0)) {
|
||||||
if (strlen(buf) > 0)
|
if (strlen(buf) > 0)
|
||||||
|
@ -4013,22 +4013,22 @@ if ((addr_count > 0) && (reflections > 0)) {
|
||||||
}
|
}
|
||||||
if (strlen(buf) > 0)
|
if (strlen(buf) > 0)
|
||||||
sprintf(&buf[strlen(buf)], ")");
|
sprintf(&buf[strlen(buf)], ")");
|
||||||
/* When changing the Physical Address on a LAN interface, VMS sends out a
|
/* 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
|
loopback packet with the source and destination addresses set to the same
|
||||||
value as the Physical Address which is being setup. This packet is
|
value as the Physical Address which is being setup. This packet is
|
||||||
designed to find and help diagnose MAC address conflicts (which also
|
designed to find and help diagnose MAC address conflicts (which also
|
||||||
include DECnet address conflicts). Normally, this packet would not be
|
include DECnet address conflicts). Normally, this packet would not be
|
||||||
seen by the sender, only by the other machine that has the same Physical
|
seen by the sender, only by the other machine that has the same Physical
|
||||||
Address (or possibly DECnet address). If the ethernet subsystem is
|
Address (or possibly DECnet address). If the ethernet subsystem is
|
||||||
reflecting packets, the network startup will fail to start if it sees the
|
reflecting packets, the network startup will fail to start if it sees the
|
||||||
reflected packet, since it thinks another system is using this Physical
|
reflected packet, since it thinks another system is using this Physical
|
||||||
Address (or DECnet address). We have to let these packets through, so
|
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 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
|
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, and _eth_callback() check the value - if the
|
||||||
dev->loopback_self_sent count is zero, then the packet has come from
|
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
|
another machine with the same address, and needs to be passed on to the
|
||||||
simulated machine. */
|
simulated machine. */
|
||||||
/* check for physical address in filters */
|
/* check for physical address in filters */
|
||||||
if ((!promiscuous) && (addr_count) && (reflections > 0)) {
|
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,
|
t_stat eth_filter(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
||||||
ETH_BOOL all_multicast, ETH_BOOL promiscuous)
|
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,
|
all_multicast, promiscuous, FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat eth_filter_hash(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
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)
|
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,
|
all_multicast, promiscuous, TRUE,
|
||||||
hash);
|
hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
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)
|
ETH_BOOL match_broadcast, ETH_MULTIHASH* const hash)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -4084,7 +4084,7 @@ if (!dev) return SCPE_UNATT;
|
||||||
if ((addr_count < 0) || ((addr_count + (match_broadcast ? 1 : 0)) > ETH_FILTER_MAX))
|
if ((addr_count < 0) || ((addr_count + (match_broadcast ? 1 : 0)) > ETH_FILTER_MAX))
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
else
|
else
|
||||||
if (!addresses && (addr_count != 0))
|
if (!addresses && (addr_count != 0))
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
|
|
||||||
/* test reflections. This is done early in this routine since eth_reflect */
|
/* test reflections. This is done early in this routine since eth_reflect */
|
||||||
|
@ -4111,7 +4111,7 @@ dev->hash_filter = (hash != NULL);
|
||||||
if (hash) {
|
if (hash) {
|
||||||
memcpy(dev->hash, hash, sizeof(*hash));
|
memcpy(dev->hash, hash, sizeof(*hash));
|
||||||
sim_debug(dev->dbit, dev->dptr, "Multicast Hash: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
|
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]);
|
dev->hash[4], dev->hash[5], dev->hash[6], dev->hash[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4151,14 +4151,14 @@ for (i = 0; i < addr_count; i++) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* setup BPF filters and other fields to minimize packet delivery */
|
/* setup BPF filters and other fields to minimize packet delivery */
|
||||||
eth_bpf_filter (dev, dev->addr_count, dev->filter_address,
|
eth_bpf_filter (dev, dev->addr_count, dev->filter_address,
|
||||||
dev->all_multicast, dev->promiscuous,
|
dev->all_multicast, dev->promiscuous,
|
||||||
dev->reflections, &dev->physical_addr,
|
dev->reflections, &dev->physical_addr,
|
||||||
dev->have_host_nic_phy_addr ? &dev->host_nic_phy_hw_addr: NULL,
|
dev->have_host_nic_phy_addr ? &dev->host_nic_phy_hw_addr: NULL,
|
||||||
(dev->hash_filter ? &dev->hash : NULL), buf);
|
(dev->hash_filter ? &dev->hash : NULL), buf);
|
||||||
|
|
||||||
/* get netmask, which is a required argument for compiling. The value,
|
/* get netmask, which is a required argument for compiling. The value,
|
||||||
in our case isn't actually interesting since the filters we generate
|
in our case isn't actually interesting since the filters we generate
|
||||||
aren't referencing IP fields, networks or values */
|
aren't referencing IP fields, networks or values */
|
||||||
|
|
||||||
#ifdef USE_BPF
|
#ifdef USE_BPF
|
||||||
|
@ -4188,7 +4188,7 @@ if (dev->eth_api == ETH_API_PCAP) {
|
||||||
sim_printf ("Eth: Promiscuous\n");
|
sim_printf ("Eth: Promiscuous\n");
|
||||||
if (dev->hash_filter)
|
if (dev->hash_filter)
|
||||||
sim_printf ("Eth: Multicast Hash: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
|
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]);
|
dev->hash[4], dev->hash[5], dev->hash[6], dev->hash[7]);
|
||||||
if (dev->have_host_nic_phy_addr) {
|
if (dev->have_host_nic_phy_addr) {
|
||||||
eth_mac_fmt(&dev->host_nic_phy_hw_addr, mac);
|
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];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
|
||||||
++bpf_count;
|
++bpf_count;
|
||||||
r = eth_bpf_filter (&dev, addr_count, &filter_address[0],
|
r = eth_bpf_filter (&dev, addr_count, &filter_address[0],
|
||||||
all_multicast, promiscuous, reflections,
|
all_multicast, promiscuous, reflections,
|
||||||
&filter_address[0],
|
&filter_address[0],
|
||||||
host_phy_addr_list[host_phy_addr_listindex],
|
host_phy_addr_list[host_phy_addr_listindex],
|
||||||
hash_list[hash_listindex],
|
hash_list[hash_listindex],
|
||||||
buf);
|
buf);
|
||||||
|
|
20
sim_ether.h
20
sim_ether.h
|
@ -31,12 +31,12 @@
|
||||||
01-Mar-12 AGN Cygwin doesn't have non-blocking pcap I/O pcap (it uses WinPcap)
|
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
|
17-Nov-11 MP Added dynamic loading of libpcap on *nix platforms
|
||||||
30-Oct-11 MP Added support for vde (Virtual Distributed Ethernet) networking
|
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
|
multithreaded environments
|
||||||
09-Dec-10 MP Added support to determine if network address conflicts exist
|
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
|
07-Dec-10 MP Reworked DECnet self detection to the more general approach
|
||||||
of loopback self when any Physical Address is being set.
|
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.
|
USE_READER_THREAD is defined.
|
||||||
07-Feb-08 MP Added eth_show_dev to display ethernet state
|
07-Feb-08 MP Added eth_show_dev to display ethernet state
|
||||||
28-Jan-08 MP Added eth_set_async
|
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
|
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.
|
07-Jun-03 MP Added WIN32 support for DECNET duplicate address detection.
|
||||||
05-Jun-03 DTH Added used to struct eth_packet
|
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
|
22-Oct-02 DTH Added all_multicast and promiscuous support
|
||||||
21-Oct-02 DTH Corrected copyright again
|
21-Oct-02 DTH Corrected copyright again
|
||||||
16-Oct-02 DTH Fixed copyright
|
16-Oct-02 DTH Fixed copyright
|
||||||
|
@ -82,7 +82,7 @@ extern "C" {
|
||||||
#define USE_SETNONBLOCK 1
|
#define USE_SETNONBLOCK 1
|
||||||
#endif
|
#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
|
#if defined(__CYGWIN__) || defined(__ZAURUS__) // psco added check for Zaurus platform
|
||||||
#define DONT_USE_READER_THREAD
|
#define DONT_USE_READER_THREAD
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,9 +135,9 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
USE_BPF is defined to let this code leverage the libpcap/OS kernel provided
|
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
|
BPF packet filtering. This generally will enhance performance. It may not
|
||||||
be available in some environments and/or it may not work correctly, so
|
be available in some environments and/or it may not work correctly, so
|
||||||
undefining this will still provide working code here.
|
undefining this will still provide working code here.
|
||||||
*/
|
*/
|
||||||
#if defined(HAVE_PCAP_NETWORK)
|
#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);
|
DEVICE* dptr, uint32 dbit);
|
||||||
t_stat eth_close (ETH_DEV* dev); /* close ethernet interface */
|
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_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 */
|
ETH_PCALLBACK routine); /* callback when done */
|
||||||
int eth_read (ETH_DEV* dev, ETH_PACK* packet, /* read single packet; */
|
int eth_read (ETH_DEV* dev, ETH_PACK* packet, /* read single packet; */
|
||||||
ETH_PCALLBACK routine); /* callback when done*/
|
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 promiscuous,
|
||||||
ETH_BOOL match_broadcast,
|
ETH_BOOL match_broadcast,
|
||||||
ETH_MULTIHASH* const hash); /* AUTODIN II based 8 byte imperfect hash */
|
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);
|
ETH_MAC* const address);
|
||||||
const char *eth_version (void); /* Version of dynamically loaded library (pcap) */
|
const char *eth_version (void); /* Version of dynamically loaded library (pcap) */
|
||||||
void eth_setcrc (ETH_DEV* dev, int need_crc); /* enable/disable CRC mode */
|
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 */
|
void ethq_insert (ETH_QUE* que, int32 type, /* insert item into FIFO queue */
|
||||||
ETH_PACK* packet, int32 status);
|
ETH_PACK* packet, int32 status);
|
||||||
void ethq_insert_data(ETH_QUE* que, int32 type, /* insert item into FIFO queue */
|
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);
|
size_t crc_len, const uint8 *crc_data, int32 status);
|
||||||
t_stat ethq_destroy(ETH_QUE* que); /* release FIFO queue */
|
t_stat ethq_destroy(ETH_QUE* que); /* release FIFO queue */
|
||||||
const char *eth_capabilities(void);
|
const char *eth_capabilities(void);
|
||||||
|
|
22
sim_fio.c
22
sim_fio.c
|
@ -136,7 +136,7 @@ unsigned char by, *sptr, *dptr;
|
||||||
if (sim_end || (count == 0) || (size == sizeof (char)))
|
if (sim_end || (count == 0) || (size == sizeof (char)))
|
||||||
return;
|
return;
|
||||||
for (j = 0, dptr = sptr = (unsigned char *) bptr; /* loop on items */
|
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--) {
|
for (k = (int32)(size - 1); k >= (((int32) size + 1) / 2); k--) {
|
||||||
by = *sptr; /* swap end-for-end */
|
by = *sptr; /* swap end-for-end */
|
||||||
*sptr++ = *(dptr + k);
|
*sptr++ = *(dptr + k);
|
||||||
|
@ -359,7 +359,7 @@ if (NULL == _sim_expand_homedir (path, pathbuf, sizeof (pathbuf)))
|
||||||
return rmdir (pathbuf);
|
return rmdir (pathbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _sim_filelist_entry (const char *directory,
|
static void _sim_filelist_entry (const char *directory,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
t_offset FileSize,
|
t_offset FileSize,
|
||||||
const struct stat *filestat,
|
const struct stat *filestat,
|
||||||
|
@ -503,9 +503,9 @@ return (t_offset)(ftello64 (st));
|
||||||
|
|
||||||
/* Apple OS/X */
|
/* 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
|
#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);
|
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;
|
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 *= 24; /* Hours */
|
||||||
time64 *= 3600; /* Seconds */
|
time64 *= 3600; /* Seconds */
|
||||||
time64 += (t_uint64)ttime; /* include time_t seconds */
|
time64 += (t_uint64)ttime; /* include time_t seconds */
|
||||||
|
@ -674,7 +674,7 @@ if (AlreadyExists) {
|
||||||
else
|
else
|
||||||
*((DWORD *)((*shmem)->shm_base)) = (DWORD)size; /* Save Size in first page */
|
*((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;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,8 +936,8 @@ return FALSE;
|
||||||
#endif /* defined (_WIN32) */
|
#endif /* defined (_WIN32) */
|
||||||
|
|
||||||
#if defined(__VAX)
|
#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
|
* the actual use cases don't on other platforms and none of the callers
|
||||||
* care about the function return value.
|
* 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
|
* %~pnI% - expands filepath value to a path and name only
|
||||||
* %~nxI% - expands filepath value to a file name and extension 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
|
* environment variables or numeric parameters to a DO command
|
||||||
* invocation.
|
* invocation.
|
||||||
*/
|
*/
|
||||||
|
@ -1001,7 +1001,7 @@ filepath = namebuf;
|
||||||
|
|
||||||
/* Check for full or current directory relative path */
|
/* Check for full or current directory relative path */
|
||||||
if ((filepath[1] == ':') ||
|
if ((filepath[1] == ':') ||
|
||||||
(filepath[0] == '/') ||
|
(filepath[0] == '/') ||
|
||||||
(filepath[0] == '\\')){
|
(filepath[0] == '\\')){
|
||||||
tot_len = 1 + strlen (filepath);
|
tot_len = 1 + strlen (filepath);
|
||||||
fullpath = (char *)malloc (tot_len);
|
fullpath = (char *)malloc (tot_len);
|
||||||
|
@ -1155,7 +1155,7 @@ if ((hFind = FindFirstFileA (cptr, &File)) != INVALID_HANDLE_VALUE) {
|
||||||
c = strrchr (DirName, '\\');
|
c = strrchr (DirName, '\\');
|
||||||
*c = '\0'; /* Truncate to just directory path */
|
*c = '\0'; /* Truncate to just directory path */
|
||||||
if (!pathsep || /* Separator wasn't mentioned? */
|
if (!pathsep || /* Separator wasn't mentioned? */
|
||||||
(slash && (0 == strcmp (slash, "/*"))))
|
(slash && (0 == strcmp (slash, "/*"))))
|
||||||
pathsep = "\\"; /* Default to Windows backslash */
|
pathsep = "\\"; /* Default to Windows backslash */
|
||||||
if (*pathsep == '/') { /* If slash separator? */
|
if (*pathsep == '/') { /* If slash separator? */
|
||||||
while ((c = strchr (DirName, '\\')))
|
while ((c = strchr (DirName, '\\')))
|
||||||
|
|
108
sim_frontpanel.c
108
sim_frontpanel.c
|
@ -28,15 +28,15 @@
|
||||||
03-Apr-15 MP Added logic to pass simulator startup messages in
|
03-Apr-15 MP Added logic to pass simulator startup messages in
|
||||||
panel error text if the connection to the simulator
|
panel error text if the connection to the simulator
|
||||||
shuts down while it is starting.
|
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
|
disconnect removable media
|
||||||
|
|
||||||
This module provides interface between a front panel application and a simh
|
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.
|
observe and control the state of a simulator.
|
||||||
|
|
||||||
The details of the 'wire protocol' are internal to the API interfaces
|
The details of the 'wire protocol' are internal to the API interfaces
|
||||||
provided here and described in sim_frontpanel.h. These details are subject
|
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
|
to change from one sim_frontpanel version to the next, while all efforts
|
||||||
will be made to retain any prior sim_frontpanel API interfaces.
|
will be made to retain any prior sim_frontpanel API interfaces.
|
||||||
|
|
||||||
|
@ -189,19 +189,19 @@ struct PANEL {
|
||||||
*
|
*
|
||||||
* Mutex: Role:
|
* Mutex: Role:
|
||||||
* io_lock Serialize access to panel state variables
|
* 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_register_query_string,
|
||||||
* _panel_establish_register_bits_collection,
|
* _panel_establish_register_bits_collection,
|
||||||
* _panel_sendf
|
* _panel_sendf
|
||||||
* acquired and released in internal threads:
|
* acquired and released in internal threads:
|
||||||
* _panel_callback
|
* _panel_callback
|
||||||
* _panel_reader
|
* _panel_reader
|
||||||
* io_send_lock Serializes writes to a panel's sockets so that complete
|
* io_send_lock Serializes writes to a panel's sockets so that complete
|
||||||
* command/request data can be delivered before another
|
* command/request data can be delivered before another
|
||||||
* thread attempts to write to the socket.
|
* thread attempts to write to the socket.
|
||||||
* acquired and released in: _panel_send
|
* acquired and released in: _panel_send
|
||||||
* io_command_lock To serialize frontpanel application command requests
|
* 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
|
* _panel_sendf_completion
|
||||||
*
|
*
|
||||||
* Condition Var: Sync Mutex: Purpose & Duration:
|
* Condition Var: Sync Mutex: Purpose & Duration:
|
||||||
|
@ -291,8 +291,8 @@ while (p && p->Debug && (dbits & p->debug)) {
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &time_now);
|
clock_gettime(CLOCK_REALTIME, &time_now);
|
||||||
sprintf (timestamp, "%lld.%03d ", (long long)(time_now.tv_sec), (int)(time_now.tv_nsec/1000000));
|
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';
|
obuf[obufsize - 1] = '\0';
|
||||||
len = vsnprintf (obuf, obufsize - 1, fmt, arglist);
|
len = vsnprintf (obuf, obufsize - 1, fmt, arglist);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
|
@ -620,7 +620,7 @@ for (i=0; i<panel->reg_count; i++) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
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_mid1, panel->sample_frequency,
|
||||||
register_collect_mid2, panel->sample_dither_pct,
|
register_collect_mid2, panel->sample_dither_pct,
|
||||||
register_collect_mid3, buf)) {
|
register_collect_mid3, buf)) {
|
||||||
|
@ -669,7 +669,7 @@ int i;
|
||||||
for (i=0; i<panel_count; i++) {
|
for (i=0; i<panel_count; i++) {
|
||||||
if (panels[i] == p) {
|
if (panels[i] == p) {
|
||||||
int j;
|
int j;
|
||||||
for (j=i+1; j<panel_count; j++)
|
for (j=i+1; j<panel_count; j++)
|
||||||
panels[j-1] = panels[j];
|
panels[j-1] = panels[j];
|
||||||
--panel_count;
|
--panel_count;
|
||||||
if (panel_count == 0) {
|
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 */
|
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 (dup (dup (open ("/dev/null", O_RDWR)))) {}; /* open standard handles to /dev/null */
|
||||||
if (execlp (sim_path, sim_path, p->temp_config, NULL, NULL)) {
|
if (execlp (sim_path, sim_path, p->temp_config, NULL, NULL)) {
|
||||||
perror ("execl");
|
perror ("execlp");
|
||||||
exit(errno);
|
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");
|
sim_panel_set_error (NULL, "sim_panel_set_sampling_parameters() must be called first");
|
||||||
return -1;
|
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)
|
if (regs == NULL)
|
||||||
return sim_panel_set_error (panel, "_panel_add_register(): Out of Memory\n");
|
return sim_panel_set_error (panel, "_panel_add_register(): Out of Memory\n");
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
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 (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);
|
sprintf (t2, "%s %s", reg->device_name ? reg->device_name : "", reg->name);
|
||||||
if ((!strcmp (t1, t2)) &&
|
if ((!strcmp (t1, t2)) &&
|
||||||
(reg->indirect == regs[i].indirect) &&
|
(reg->indirect == regs[i].indirect) &&
|
||||||
((reg->bits == NULL) == (regs[i].bits == NULL))) {
|
((reg->bits == NULL) == (regs[i].bits == NULL))) {
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
pthread_mutex_unlock (&panel->io_lock);
|
||||||
sim_panel_set_error (NULL, "Duplicate Register Declaration");
|
sim_panel_set_error (NULL, "Duplicate Register Declaration");
|
||||||
|
@ -1379,9 +1379,9 @@ return _panel_get_registers (panel, (panel->State == Halt), simulation_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_set_display_callback_interval (PANEL *panel,
|
sim_panel_set_display_callback_interval (PANEL *panel,
|
||||||
PANEL_DISPLAY_PCALLBACK callback,
|
PANEL_DISPLAY_PCALLBACK callback,
|
||||||
void *context,
|
void *context,
|
||||||
int usecs_between_callbacks)
|
int usecs_between_callbacks)
|
||||||
{
|
{
|
||||||
if (!panel) {
|
if (!panel) {
|
||||||
|
@ -1707,7 +1707,7 @@ return 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_gen_examine (PANEL *panel,
|
sim_panel_gen_examine (PANEL *panel,
|
||||||
const char *name_or_addr,
|
const char *name_or_addr,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *value)
|
void *value)
|
||||||
|
@ -1755,7 +1755,7 @@ return 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_get_history (PANEL *panel,
|
sim_panel_get_history (PANEL *panel,
|
||||||
int count,
|
int count,
|
||||||
size_t size,
|
size_t size,
|
||||||
char *buffer)
|
char *buffer)
|
||||||
|
@ -1781,7 +1781,7 @@ return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_device_debug_mode (PANEL *panel,
|
sim_panel_device_debug_mode (PANEL *panel,
|
||||||
const char *device,
|
const char *device,
|
||||||
int set_unset,
|
int set_unset,
|
||||||
const char *mode_bits)
|
const char *mode_bits)
|
||||||
|
@ -1796,17 +1796,17 @@ if (!panel || (panel->State == Error)) {
|
||||||
if ((device != NULL) &&
|
if ((device != NULL) &&
|
||||||
((_panel_sendf (panel, &cmd_stat, &response, "SHOW %s", device) ||
|
((_panel_sendf (panel, &cmd_stat, &response, "SHOW %s", device) ||
|
||||||
(cmd_stat)))) {
|
(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);
|
set_unset ? "Enable" : "Disable", mode_bits ? mode_bits : "", device, response);
|
||||||
free (response);
|
free (response);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
free (response);
|
free (response);
|
||||||
response = NULL;
|
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 : "") ||
|
set_unset ? "" : "NO", device ? device : "", mode_bits ? mode_bits : "") ||
|
||||||
(cmd_stat)) {
|
(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);
|
set_unset ? "Enable" : "Disable", mode_bits ? mode_bits : "", device, response);
|
||||||
free (response);
|
free (response);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1822,12 +1822,12 @@ return 0;
|
||||||
name_or_addr the name the simulator knows this register by
|
name_or_addr the name the simulator knows this register by
|
||||||
size the size (in local storage) of the buffer which
|
size the size (in local storage) of the buffer which
|
||||||
contains the data to be deposited into the simulator
|
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
|
be deposited into the simulator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_gen_deposit (PANEL *panel,
|
sim_panel_gen_deposit (PANEL *panel,
|
||||||
const char *name_or_addr,
|
const char *name_or_addr,
|
||||||
size_t size,
|
size_t size,
|
||||||
const void *value)
|
const void *value)
|
||||||
|
@ -1856,7 +1856,7 @@ return 0;
|
||||||
|
|
||||||
sim_panel_mem_examine
|
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
|
contains the memory address of the data to be examined
|
||||||
in the simulator
|
in the simulator
|
||||||
addr a pointer to the buffer containing the memory address
|
addr a pointer to the buffer containing the memory address
|
||||||
|
@ -1868,7 +1868,7 @@ return 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_mem_examine (PANEL *panel,
|
sim_panel_mem_examine (PANEL *panel,
|
||||||
size_t addr_size,
|
size_t addr_size,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
size_t value_size,
|
size_t value_size,
|
||||||
|
@ -1913,7 +1913,7 @@ return 0;
|
||||||
|
|
||||||
sim_panel_mem_deposit
|
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
|
contains the memory address of the data to be deposited
|
||||||
into the simulator
|
into the simulator
|
||||||
addr a pointer to the buffer containing the memory address
|
addr a pointer to the buffer containing the memory address
|
||||||
|
@ -1925,7 +1925,7 @@ return 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_mem_deposit (PANEL *panel,
|
sim_panel_mem_deposit (PANEL *panel,
|
||||||
size_t addr_size,
|
size_t addr_size,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
size_t value_size,
|
size_t value_size,
|
||||||
|
@ -1959,17 +1959,17 @@ return 0;
|
||||||
|
|
||||||
sim_panel_mem_deposit_instruction
|
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
|
contains the memory address of the data to be deposited
|
||||||
into the simulator
|
into the simulator
|
||||||
addr a pointer to the buffer containing the memory address
|
addr a pointer to the buffer containing the memory address
|
||||||
of the data to be deposited into the simulator
|
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
|
instruction to be deposited at the indicated address
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_mem_deposit_instruction (PANEL *panel,
|
sim_panel_mem_deposit_instruction (PANEL *panel,
|
||||||
size_t addr_size,
|
size_t addr_size,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
const char *instruction)
|
const char *instruction)
|
||||||
|
@ -1999,8 +1999,8 @@ return 0;
|
||||||
|
|
||||||
name the name of a simulator register or a memory address
|
name the name of a simulator register or a memory address
|
||||||
which is to receive a new value
|
which is to receive a new value
|
||||||
value the new value in character string form. The string
|
value the new value in character string form. The string
|
||||||
must be in the native/natural radix that the simulator
|
must be in the native/natural radix that the simulator
|
||||||
uses when referencing that register
|
uses when referencing that register
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -2118,8 +2118,8 @@ int buf_data = 0;
|
||||||
int processing_register_output = 0;
|
int processing_register_output = 0;
|
||||||
int io_wait_done = 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.
|
arriving data.
|
||||||
*/
|
*/
|
||||||
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
|
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
|
||||||
|
@ -2201,13 +2201,13 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
++s;
|
++s;
|
||||||
continue; /* process next line */
|
continue; /* process next line */
|
||||||
}
|
}
|
||||||
if ((*s == '}') &&
|
if ((*s == '}') &&
|
||||||
(3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */
|
(3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */
|
||||||
r = NULL;
|
r = NULL;
|
||||||
for (i=0; i<p->reg_count; i++) {
|
for (i=0; i<p->reg_count; i++) {
|
||||||
if (p->regs[i].bits == NULL)
|
if (p->regs[i].bits == NULL)
|
||||||
continue;
|
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)))) {
|
((!p->device_name) || (!strcmp (smp_dev, p->device_name)))) {
|
||||||
r = &p->regs[i];
|
r = &p->regs[i];
|
||||||
break;
|
break;
|
||||||
|
@ -2283,7 +2283,7 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
|
|
||||||
if (end)
|
if (end)
|
||||||
end_index = (size_t)atoi (end + 1);
|
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);
|
p->array_element_data = strtoull (e, NULL, 16);
|
||||||
while (array_index <= end_index) {
|
while (array_index <= end_index) {
|
||||||
if (little_endian)
|
if (little_endian)
|
||||||
|
@ -2319,14 +2319,14 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
p->io_response[p->io_response_data] = '\0';
|
p->io_response[p->io_response_data] = '\0';
|
||||||
goto Start_Next_Line;
|
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_repeat_start)) ||
|
||||||
(!strcmp (s + strlen (sim_prompt), register_get_start)))) {
|
(!strcmp (s + strlen (sim_prompt), register_get_start)))) {
|
||||||
_panel_debug (p, DBG_RCV, "*Repeat/Register Block Starting", NULL, 0);
|
_panel_debug (p, DBG_RCV, "*Repeat/Register Block Starting", NULL, 0);
|
||||||
processing_register_output = 1;
|
processing_register_output = 1;
|
||||||
goto Start_Next_Line;
|
goto Start_Next_Line;
|
||||||
}
|
}
|
||||||
if ((strlen (s) > strlen (sim_prompt)) &&
|
if ((strlen (s) > strlen (sim_prompt)) &&
|
||||||
(!strcmp (s + strlen (sim_prompt), register_get_end))) {
|
(!strcmp (s + strlen (sim_prompt), register_get_end))) {
|
||||||
_panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0);
|
_panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0);
|
||||||
p->io_waiting = 0;
|
p->io_waiting = 0;
|
||||||
|
@ -2359,8 +2359,8 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
p->io_response_data += strlen(s);
|
p->io_response_data += strlen(s);
|
||||||
strcpy (p->io_response + p->io_response_data, "\r\n");
|
strcpy (p->io_response + p->io_response_data, "\r\n");
|
||||||
p->io_response_data += 2;
|
p->io_response_data += 2;
|
||||||
if ((!p->parent) &&
|
if ((!p->parent) &&
|
||||||
(p->completion_string) &&
|
(p->completion_string) &&
|
||||||
(!memcmp (s, p->completion_string, strlen (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);
|
_panel_debug (p, DBG_RCV, "Match with potentially coalesced additional data: '%s'", NULL, 0, p->completion_string);
|
||||||
if (eol < &buf[buf_data])
|
if (eol < &buf[buf_data])
|
||||||
|
@ -2376,8 +2376,8 @@ Start_Next_Line:
|
||||||
buf_data = strlen (buf);
|
buf_data = strlen (buf);
|
||||||
if (buf_data)
|
if (buf_data)
|
||||||
_panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf);
|
_panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf);
|
||||||
if ((!p->parent) &&
|
if ((!p->parent) &&
|
||||||
(p->completion_string) &&
|
(p->completion_string) &&
|
||||||
(!memcmp (buf, p->completion_string, strlen (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);
|
_panel_debug (p, DBG_RCV, "*Received Command Complete - Match: '%s'", NULL, 0, p->completion_string);
|
||||||
io_wait_done = 1;
|
io_wait_done = 1;
|
||||||
|
@ -2448,8 +2448,8 @@ size_t buf_data = 0;
|
||||||
unsigned int callback_count = 0;
|
unsigned int callback_count = 0;
|
||||||
int cmd_stat;
|
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.
|
with compute bound activities.
|
||||||
*/
|
*/
|
||||||
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
|
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 */
|
pthread_cond_signal (&p->startup_done); /* Signal we're ready to go */
|
||||||
msleep (100);
|
msleep (100);
|
||||||
pthread_mutex_lock (&p->io_lock);
|
pthread_mutex_lock (&p->io_lock);
|
||||||
while ((p->sock != INVALID_SOCKET) &&
|
while ((p->sock != INVALID_SOCKET) &&
|
||||||
(p->usecs_between_callbacks) &&
|
(p->usecs_between_callbacks) &&
|
||||||
(p->State != Error)) {
|
(p->State != Error)) {
|
||||||
int interval = p->usecs_between_callbacks;
|
int interval = p->usecs_between_callbacks;
|
||||||
|
@ -2501,9 +2501,9 @@ while ((p->sock != INVALID_SOCKET) &&
|
||||||
buf_data -= (c - buf) + strlen (register_get_start);
|
buf_data -= (c - buf) + strlen (register_get_start);
|
||||||
c += strlen (register_get_start);
|
c += strlen (register_get_start);
|
||||||
}
|
}
|
||||||
sprintf (repeat, "%s%d%s%s%*.*s", register_repeat_prefix,
|
sprintf (repeat, "%s%d%s%s%*.*s", register_repeat_prefix,
|
||||||
p->usecs_between_callbacks,
|
p->usecs_between_callbacks,
|
||||||
register_repeat_units,
|
register_repeat_units,
|
||||||
register_repeat_start,
|
register_repeat_start,
|
||||||
(int)buf_data, (int)buf_data, c);
|
(int)buf_data, (int)buf_data, c);
|
||||||
pthread_mutex_unlock (&p->io_lock);
|
pthread_mutex_unlock (&p->io_lock);
|
||||||
|
|
172
sim_frontpanel.h
172
sim_frontpanel.h
|
@ -28,18 +28,18 @@
|
||||||
03-Apr-15 MP Added logic to pass simulator startup messages in
|
03-Apr-15 MP Added logic to pass simulator startup messages in
|
||||||
panel error text if the connection to the simulator
|
panel error text if the connection to the simulator
|
||||||
shuts down while it is starting.
|
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
|
disconnect removable media
|
||||||
|
|
||||||
This module defines interface between a front panel application and a simh
|
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.
|
observe and control the state of a simulator.
|
||||||
|
|
||||||
Any application which wants to use this API needs to:
|
Any application which wants to use this API needs to:
|
||||||
1) include this file in the application code
|
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.
|
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.
|
into the application.
|
||||||
4) Use a simh simulator built from the same version of simh that the
|
4) Use a simh simulator built from the same version of simh that the
|
||||||
sim_frontpanel and sim_sock modules came from.
|
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
|
configuration
|
||||||
|
|
||||||
sim_path the path to the simulator binary
|
sim_path the path to the simulator binary
|
||||||
sim_config the configuration to run the simulator with
|
sim_config the configuration to run the simulator with
|
||||||
device_panel_count the number of sub panels for connected devices
|
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
|
it could be merely the simulator name if the simulator binary
|
||||||
is located in the current PATH.
|
is located in the current PATH.
|
||||||
- The simulator binary must be built from the same version
|
- The simulator binary must be built from the same version
|
||||||
simh source code that the frontpanel API was acquired fron
|
simh source code that the frontpanel API was acquired from
|
||||||
(the API and the simh framework must speak the same language)
|
(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).
|
statements (enable, disable, CPU types and attach commands).
|
||||||
It should not start a simulator running.
|
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
|
with a specific simulator panel
|
||||||
|
|
||||||
simulator_panel the simulator panel to connect to
|
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.
|
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
|
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.
|
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
|
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.
|
simulator.
|
||||||
|
|
||||||
The registers that a particular frontpanel application mught need
|
The registers that a particular frontpanel application might need
|
||||||
access to are specified by the application when it calls:
|
access to are specified by the application when it calls:
|
||||||
|
|
||||||
sim_panel_add_register
|
sim_panel_add_register
|
||||||
sim_panel_add_register_bits
|
sim_panel_add_register_bits
|
||||||
sim_panel_add_register_array
|
sim_panel_add_register_array
|
||||||
and
|
and
|
||||||
sim_panel_add_register_indirect
|
sim_panel_add_register_indirect
|
||||||
|
@ -142,13 +142,13 @@ and
|
||||||
element_count number of elements in the register array
|
element_count number of elements in the register array
|
||||||
size the size (in local storage) of the buffer which will
|
size the size (in local storage) of the buffer which will
|
||||||
receive the data in the simulator's register
|
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
|
be loaded with the data in the simulator's register
|
||||||
bit_width the number of values to populate in the bits array
|
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.
|
will receive each bit's current accumulated value.
|
||||||
The accumulated value will range from 0 thru the
|
The accumulated value will range from 0 thru the
|
||||||
the sample_depth specified when calling
|
the sample_depth specified when calling
|
||||||
sim_panel_set_sampling_parameters().
|
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 values contained in the set of registers it has declared interest in via
|
||||||
the sim_panel_add_register APIs.
|
the sim_panel_add_register APIs.
|
||||||
|
|
||||||
1) The values can be polled (whenever it is desired) by calling
|
1) The values can be polled (whenever it is desired) by calling
|
||||||
sim_panel_get_registers().
|
sim_panel_get_registers().
|
||||||
2) The panel can call sim_panel_set_display_callback_interval() to
|
2) The panel can call sim_panel_set_display_callback_interval() to
|
||||||
specify a callback routine and a periodic rate that the callback
|
specify a callback routine and a periodic rate that the callback
|
||||||
routine should be called. The panel API will make a best effort
|
routine should be called. The panel API will make a best effort
|
||||||
to deliver the current register state at the desired rate.
|
to deliver the current register state at the desired rate.
|
||||||
|
|
||||||
|
|
||||||
Note 1: The buffers described in a panel's register set will be
|
Note 1: The buffers described in a panel's register set will be
|
||||||
dynamically revised as soon as data is available from the
|
dynamically revised as soon as data is available from the
|
||||||
simulator. The callback routine merely serves as a notification
|
simulator. The callback routine merely serves as a notification
|
||||||
that a complete register set has arrived.
|
that a complete register set has arrived.
|
||||||
Note 2: The callback routine should, in general, not run for a long time
|
Note 2: The callback routine should, in general, not run for a long time
|
||||||
or frontpanel interactions with the simulator may be disrupted.
|
or frontpanel interactions with the simulator may be disrupted.
|
||||||
Setting a flag, signaling an event or posting a message are
|
Setting a flag, signaling an event or posting a message are
|
||||||
reasonable activities to perform in a callback routine.
|
reasonable activities to perform in a callback routine.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_get_registers (PANEL *panel, unsigned long long *simulation_time);
|
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,
|
unsigned long long simulation_time,
|
||||||
void *context);
|
void *context);
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_set_display_callback_interval (PANEL *panel,
|
sim_panel_set_display_callback_interval (PANEL *panel,
|
||||||
PANEL_DISPLAY_PCALLBACK callback,
|
PANEL_DISPLAY_PCALLBACK callback,
|
||||||
void *context,
|
void *context,
|
||||||
int usecs_between_callbacks);
|
int usecs_between_callbacks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
When a front panel application wants to get averaged bit sample
|
When a front panel application wants to get averaged bit sample
|
||||||
values, it must first declare the sampling parameters that will
|
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
|
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.
|
to the specified value.
|
||||||
|
|
||||||
sim_panel_set_sampling_parameters
|
sim_panel_set_sampling_parameters
|
||||||
sim_panel_set_sampling_parameters_ex
|
sim_panel_set_sampling_parameters_ex
|
||||||
|
|
||||||
sample_frequency cycles/instructions between sample captures
|
sample_frequency cycles/instructions between sample captures
|
||||||
sample_dither_pct percentage of sample_frequency to vary randomly
|
sample_dither_pct percentage of sample_frequency to vary randomly
|
||||||
sample_depth how many samples to accumulate in the rolling
|
sample_depth how many samples to accumulate in the rolling
|
||||||
average for each bit sample. Returned bit
|
average for each bit sample. Returned bit
|
||||||
sample values will range from 0 thru this
|
sample values will range from 0 thru this
|
||||||
value.
|
value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -258,13 +258,13 @@ sim_panel_set_sampling_parameters (PANEL *panel,
|
||||||
/**
|
/**
|
||||||
|
|
||||||
When a front panel application needs to change the running
|
When a front panel application needs to change the running
|
||||||
state of a simulator one of the following routines should
|
state of a simulator one of the following routines should
|
||||||
be called:
|
be called:
|
||||||
|
|
||||||
sim_panel_exec_halt - Stop instruction execution
|
sim_panel_exec_halt - Stop instruction execution
|
||||||
sim_panel_exec_boot - Boot a simulator from a specific device
|
sim_panel_exec_boot - Boot a simulator from a specific device
|
||||||
sim_panel_exec_run - Start/Resume a simulator running instructions
|
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
|
after resetting all devices
|
||||||
sim_panel_exec_step - Have a simulator execute a single step
|
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
|
A simulator often displays some useful information as it stops
|
||||||
executing instructions.
|
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.
|
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
|
should stop instruction execution an execution or an output
|
||||||
breakpoint should be used. To established or clear a breakpoint,
|
breakpoint should be used. To established or clear a breakpoint,
|
||||||
one of the following routines should be called:
|
one of the following routines should be called:
|
||||||
|
|
||||||
sim_panel_break_set - Establish a simulation breakpoint
|
sim_panel_break_set - Establish a simulation breakpoint
|
||||||
sim_panel_break_clear - Cancel/Delete a previously defined
|
sim_panel_break_clear - Cancel/Delete a previously defined
|
||||||
breakpoint
|
breakpoint
|
||||||
sim_panel_break_output_set - Establish a simulator output
|
sim_panel_break_output_set - Establish a simulator output
|
||||||
breakpoint
|
breakpoint
|
||||||
sim_panel_break_output_clear - Cancel/Delete a previously defined
|
sim_panel_break_output_clear - Cancel/Delete a previously defined
|
||||||
output breakpoint
|
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
|
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
|
When a front panel application needs to change or access
|
||||||
memory or a register one of the following routines should
|
memory or a register one of the following routines should
|
||||||
be called:
|
be called:
|
||||||
|
|
||||||
sim_panel_gen_examine - Examine register or memory
|
sim_panel_gen_examine - Examine register or memory
|
||||||
sim_panel_gen_deposit - Deposit to register or memory
|
sim_panel_gen_deposit - Deposit to register or memory
|
||||||
sim_panel_mem_examine - Examine memory location
|
sim_panel_mem_examine - Examine memory location
|
||||||
sim_panel_mem_deposit - Deposit to 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
|
location
|
||||||
sim_panel_set_register_value - Deposit to a register or memory
|
sim_panel_set_register_value - Deposit to a register or memory
|
||||||
location
|
location
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -358,7 +358,7 @@ sim_panel_break_output_clear (PANEL *panel, const char *condition);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_gen_examine (PANEL *panel,
|
sim_panel_gen_examine (PANEL *panel,
|
||||||
const char *name_or_addr,
|
const char *name_or_addr,
|
||||||
size_t size,
|
size_t size,
|
||||||
void *value);
|
void *value);
|
||||||
|
@ -370,12 +370,12 @@ sim_panel_gen_examine (PANEL *panel,
|
||||||
name_or_addr the name the simulator knows this register by
|
name_or_addr the name the simulator knows this register by
|
||||||
size the size (in local storage) of the buffer which
|
size the size (in local storage) of the buffer which
|
||||||
contains the data to be deposited into the simulator
|
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
|
be deposited into the simulator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_gen_deposit (PANEL *panel,
|
sim_panel_gen_deposit (PANEL *panel,
|
||||||
const char *name_or_addr,
|
const char *name_or_addr,
|
||||||
size_t size,
|
size_t size,
|
||||||
const void *value);
|
const void *value);
|
||||||
|
@ -384,7 +384,7 @@ sim_panel_gen_deposit (PANEL *panel,
|
||||||
|
|
||||||
sim_panel_mem_examine
|
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
|
contains the memory address of the data to be examined
|
||||||
in the simulator
|
in the simulator
|
||||||
addr a pointer to the buffer containing the memory address
|
addr a pointer to the buffer containing the memory address
|
||||||
|
@ -396,7 +396,7 @@ sim_panel_gen_deposit (PANEL *panel,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_mem_examine (PANEL *panel,
|
sim_panel_mem_examine (PANEL *panel,
|
||||||
size_t addr_size,
|
size_t addr_size,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
size_t value_size,
|
size_t value_size,
|
||||||
|
@ -406,7 +406,7 @@ sim_panel_mem_examine (PANEL *panel,
|
||||||
|
|
||||||
sim_panel_mem_deposit
|
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
|
contains the memory address of the data to be deposited
|
||||||
into the simulator
|
into the simulator
|
||||||
addr a pointer to the buffer containing the memory address
|
addr a pointer to the buffer containing the memory address
|
||||||
|
@ -418,7 +418,7 @@ sim_panel_mem_examine (PANEL *panel,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_mem_deposit (PANEL *panel,
|
sim_panel_mem_deposit (PANEL *panel,
|
||||||
size_t addr_size,
|
size_t addr_size,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
size_t value_size,
|
size_t value_size,
|
||||||
|
@ -428,17 +428,17 @@ sim_panel_mem_deposit (PANEL *panel,
|
||||||
|
|
||||||
sim_panel_mem_deposit_instruction
|
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
|
contains the memory address of the data to be deposited
|
||||||
into the simulator
|
into the simulator
|
||||||
addr a pointer to the buffer containing the memory address
|
addr a pointer to the buffer containing the memory address
|
||||||
of the data to be deposited into the simulator
|
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
|
instruction to be deposited at the indicated address
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_mem_deposit_instruction (PANEL *panel,
|
sim_panel_mem_deposit_instruction (PANEL *panel,
|
||||||
size_t addr_size,
|
size_t addr_size,
|
||||||
const void *addr,
|
const void *addr,
|
||||||
const char *instruction);
|
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
|
name the name of a simulator register or a memory address
|
||||||
which is to receive a new value
|
which is to receive a new value
|
||||||
value the new value in character string form. The string
|
value the new value in character string form. The string
|
||||||
must be in the native/natural radix that the simulator
|
must be in the native/natural radix that the simulator
|
||||||
uses when referencing that register
|
uses when referencing that register
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
@ -461,9 +461,9 @@ sim_panel_set_register_value (PANEL *panel,
|
||||||
/**
|
/**
|
||||||
|
|
||||||
A front panel application might want to have access to the
|
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
|
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.
|
in the sim_config file that the simulator is started with.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ sim_panel_set_register_value (PANEL *panel,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_get_history (PANEL *panel,
|
sim_panel_get_history (PANEL *panel,
|
||||||
int count,
|
int count,
|
||||||
size_t size,
|
size_t size,
|
||||||
char *buffer);
|
char *buffer);
|
||||||
|
@ -488,7 +488,7 @@ sim_panel_get_history (PANEL *panel,
|
||||||
/**
|
/**
|
||||||
|
|
||||||
A front panel application might want some details of simulator
|
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)
|
via debug information. Debugging for particular device(s)
|
||||||
and/or simulator debug settings can be controlled via the
|
and/or simulator debug settings can be controlled via the
|
||||||
sim_panel_device_debug_mode API.
|
sim_panel_device_debug_mode API.
|
||||||
|
@ -499,15 +499,15 @@ sim_panel_get_history (PANEL *panel,
|
||||||
sim_panel_device_debug_mode
|
sim_panel_device_debug_mode
|
||||||
|
|
||||||
device the device whose debug mode is to change
|
device the device whose debug mode is to change
|
||||||
set_untset 1 to set debug flags, 0 to clear debug flags
|
set_unset 1 to set debug flags, 0 to clear debug flags
|
||||||
mode_bits character string with different debug mode bits
|
mode_bits character string with different debug mode bits
|
||||||
to enable or disable. An empty string will
|
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
|
device
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sim_panel_device_debug_mode (PANEL *panel,
|
sim_panel_device_debug_mode (PANEL *panel,
|
||||||
const char *device,
|
const char *device,
|
||||||
int set_unset,
|
int set_unset,
|
||||||
const char *mode_bits);
|
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
|
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:
|
routines should be called:
|
||||||
|
|
||||||
sim_panel_mount - mounts the indicated media file on a device
|
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
|
from a device
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -564,13 +564,13 @@ sim_panel_get_state (PANEL *panel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
All API routines which return an int return 0 for
|
All API routines which return an int return 0 for
|
||||||
success and -1 for an error.
|
success and -1 for an error.
|
||||||
|
|
||||||
An API which returns an error (-1), will not change the panel state
|
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
|
except to possibly set the panel state to Error if the panel
|
||||||
condition is no longer useful.
|
condition is no longer useful.
|
||||||
|
|
||||||
sim_panel_get_error - the details of the most recent error
|
sim_panel_get_error - the details of the most recent error
|
||||||
sim_panel_clear_error - clears the error buffer
|
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_set_debug_mode - Specifies the debug detail to be recorded
|
||||||
sim_panel_flush_debug - Flushes debug output to disk
|
sim_panel_flush_debug - Flushes debug output to disk
|
||||||
sim_panel_debug - Write message to the debug file
|
sim_panel_debug - Write message to the debug 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));
|
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);
|
hdrBytes = sim_fread(&imd, 1, 5, myDisk->file);
|
||||||
|
|
||||||
if ((hdrBytes == 0) && feof(myDisk->file))
|
if ((hdrBytes == 0) && feof(myDisk->file))
|
||||||
break; /* detected end of IMD 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.)
|
* 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.
|
* 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,
|
* 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.
|
* and proceed sequentially through all tracks/heads on the disk.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* sim_printf_fmts.h
|
* sim_printf_fmts.h
|
||||||
*
|
*
|
||||||
* Cross-platform printf() formats for simh data types. Refactored out to
|
* 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
|
* Author: B. Scott Michel
|
||||||
*
|
*
|
||||||
|
|
106
sim_rev.h
106
sim_rev.h
|
@ -45,8 +45,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SIM__GIT_COMMMIT_ID is undefined when working with an
|
SIM__GIT_COMMMIT_ID is undefined when working with an
|
||||||
archive (zip file or tar ball). Use Git keyword subsitution
|
archive (zip file or tar ball). Use Git keyword substitution
|
||||||
to record the archive's commit id via the .gitattributes
|
to record the archive's commit id via the .gitattributes
|
||||||
"export-subst".
|
"export-subst".
|
||||||
*/
|
*/
|
||||||
|
@ -55,9 +55,9 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The comment section below reflects the manual editing process which was in place
|
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.
|
history.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -86,7 +86,7 @@ patch date module(s) and fix(es)
|
||||||
connected LANs
|
connected LANs
|
||||||
|
|
||||||
sim_tmxr.c:
|
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)
|
works with PuTTY as console (Mark Pizzolato)
|
||||||
|
|
||||||
h316_cpu.c:
|
h316_cpu.c:
|
||||||
|
@ -147,7 +147,7 @@ patch date module(s) and fix(es)
|
||||||
|
|
||||||
hp2100_dp.c (Dave Bryan):
|
hp2100_dp.c (Dave Bryan):
|
||||||
- Added CNTLR_TYPE cast to dp_settype
|
- Added CNTLR_TYPE cast to dp_settype
|
||||||
|
|
||||||
hp2100_ds.c (Dave Bryan):
|
hp2100_ds.c (Dave Bryan):
|
||||||
- Rewritten to use the MAC/ICD disc controller library
|
- Rewritten to use the MAC/ICD disc controller library
|
||||||
- ioIOO now notifies controller service of parameter output
|
- ioIOO now notifies controller service of parameter output
|
||||||
|
@ -178,21 +178,21 @@ patch date module(s) and fix(es)
|
||||||
|
|
||||||
hp2100_ms.c (Dave Bryan):
|
hp2100_ms.c (Dave Bryan):
|
||||||
- Added CNTLR_TYPE cast to ms_settype
|
- Added CNTLR_TYPE cast to ms_settype
|
||||||
|
|
||||||
hp2100_mt.c (Dave Bryan):
|
hp2100_mt.c (Dave Bryan):
|
||||||
- Removed redundant MTAB_VUN from "format" MTAB entry
|
- Removed redundant MTAB_VUN from "format" MTAB entry
|
||||||
- Fixed command scanning error in mtcio ioIOO handler
|
- Fixed command scanning error in mtcio ioIOO handler
|
||||||
|
|
||||||
hp2100_stddev.c (Dave Bryan):
|
hp2100_stddev.c (Dave Bryan):
|
||||||
- Add TBG as a logical name for the CLK device
|
- Add TBG as a logical name for the CLK device
|
||||||
|
|
||||||
hp2100_sys.c (Dave Bryan):
|
hp2100_sys.c (Dave Bryan):
|
||||||
- Deprecated DEVNO in favor of SC
|
- Deprecated DEVNO in favor of SC
|
||||||
- Added hp_setsc, hp_showsc functions to support SC modifier
|
- Added hp_setsc, hp_showsc functions to support SC modifier
|
||||||
- Added DA and dummy DC devices
|
- Added DA and dummy DC devices
|
||||||
- DMA channels renamed from 0,1 to 1,2 to match documentation
|
- DMA channels renamed from 0,1 to 1,2 to match documentation
|
||||||
- Changed DIB access for revised signal model
|
- Changed DIB access for revised signal model
|
||||||
|
|
||||||
hp_disclib.c, hp_disclib.h (Dave Bryan)
|
hp_disclib.c, hp_disclib.h (Dave Bryan)
|
||||||
- Created MAC/ICD disc controller library
|
- 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)
|
- fixed misuse of & instead of && in Ea_ch (Michael Bloom)
|
||||||
|
|
||||||
pdp1_stddev.c:
|
pdp1_stddev.c:
|
||||||
- fixed unitialized variable in tty output service (Michael Bloom)
|
- fixed uninitialized variable in tty output service (Michael Bloom)
|
||||||
|
|
||||||
pdp10_fe.c:
|
pdp10_fe.c:
|
||||||
- revised to use clock coscheduling
|
- 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 Qbus interrupts to treat all IO devices (except clock) as BR4
|
||||||
- fixed order of int_internal (Jordi Guillaumes i Pons)
|
- fixed order of int_internal (Jordi Guillaumes i Pons)
|
||||||
|
|
||||||
ppd11_rf.c
|
pdp11_rf.c
|
||||||
- fixed bug in updating mem addr extension (Peter Schorn)
|
- fixed bug in updating mem addr extension (Peter Schorn)
|
||||||
|
|
||||||
pdp11_rk.c:
|
pdp11_rk.c:
|
||||||
|
@ -254,7 +254,7 @@ patch date module(s) and fix(es)
|
||||||
- added RD32 support
|
- added RD32 support
|
||||||
|
|
||||||
pdp11_tq.c: (Mark Pizzolato)
|
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
|
during forward motion read operations
|
||||||
- fixed logic which clears UNIT_SXC to check command modifier
|
- fixed logic which clears UNIT_SXC to check command modifier
|
||||||
- added CMF_WR flag to tq_cmf entry for OP_WTM
|
- 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 more debug output after positioning operations
|
||||||
- added textual display of the command being performed
|
- added textual display of the command being performed
|
||||||
- fixed comments about register addresses
|
- fixed comments about register addresses
|
||||||
|
|
||||||
pdp11_ts.c:
|
pdp11_ts.c:
|
||||||
- fixed t_addr printouts for 64b big-endian systems (Mark Pizzolato)
|
- 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)
|
pdp11_xq.c: (Mark Pizzolato)
|
||||||
- Fixed missing information from save/restore which
|
- 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.
|
a restore until the OS reset the controller.
|
||||||
- Added address conflict check during attach.
|
- Added address conflict check during attach.
|
||||||
- Fixed loopback processing to correctly handle forward packets.
|
- 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.
|
(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=.
|
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.
|
will succeed.
|
||||||
- Added DELQA-T (aka DELQA Plus) device emulation support.
|
- Added DELQA-T (aka DELQA Plus) device emulation support.
|
||||||
- Added dropped frame statistics to record when the receiver discards
|
- Added dropped frame statistics to record when the receiver discards
|
||||||
received packets due to the receiver being disabled, or due to the
|
received packets due to the receiver being disabled, or due to the
|
||||||
XQ device's packet receive queue being full.
|
XQ device's packet receive queue being full.
|
||||||
- Fixed bug in receive processing when we're not polling. This could
|
- Fixed bug in receive processing when we're not polling. This could
|
||||||
cause receive processing to never be activated again if we don't
|
cause receive processing to never be activated again if we don't
|
||||||
read all available packets via eth_read each time we get the
|
read all available packets via eth_read each time we get the
|
||||||
opportunity.
|
opportunity.
|
||||||
- Added the ability to Coalesce received packet interrupts. This
|
- 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
|
microseconds to delay the triggering of an interrupt when a packet
|
||||||
is received.
|
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.
|
polling for packet read completion.
|
||||||
- Changed the sanity and id timer mechanisms to use a separate timer
|
- 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.
|
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.
|
calibrated tmr_poll and clk_tps values of the simulator.
|
||||||
- Enabled the SET XQ POLL to be meaningful if the simulator currently
|
- Enabled the SET XQ POLL to be meaningful if the simulator currently
|
||||||
doesn't support idling.
|
doesn't support idling.
|
||||||
|
@ -313,7 +313,7 @@ patch date module(s) and fix(es)
|
||||||
all debug output goes to the same place.
|
all debug output goes to the same place.
|
||||||
- Restored the call to xq_svc after all successful calls to eth_write
|
- Restored the call to xq_svc after all successful calls to eth_write
|
||||||
to allow receive processing to happen before the next event
|
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.
|
while other things were being tested.
|
||||||
|
|
||||||
pdp11_xu.c: (Mark Pizzolato)
|
pdp11_xu.c: (Mark Pizzolato)
|
||||||
|
@ -328,7 +328,7 @@ patch date module(s) and fix(es)
|
||||||
pdp18b_stddev.c:
|
pdp18b_stddev.c:
|
||||||
- added clock coscheduling
|
- added clock coscheduling
|
||||||
- revised TTI to use clock coscheduling and to fix perpetual CAF bug
|
- revised TTI to use clock coscheduling and to fix perpetual CAF bug
|
||||||
|
|
||||||
pdp18b_ttx.c:
|
pdp18b_ttx.c:
|
||||||
- revised to use clock coscheduling
|
- 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
|
- revised to use clock coscheduling and to fix perpetual CAF bug
|
||||||
|
|
||||||
pdp8_ttx.c:
|
pdp8_ttx.c:
|
||||||
- revised to use clock cosheduling
|
- revised to use clock coscheduling
|
||||||
|
|
||||||
pdp8_sys.c:
|
pdp8_sys.c:
|
||||||
- added link to FPP
|
- added link to FPP
|
||||||
|
@ -401,7 +401,7 @@ patch date module(s) and fix(es)
|
||||||
- decommitted MTAB_VAL
|
- decommitted MTAB_VAL
|
||||||
- fixed implementation of MTAB_NC
|
- fixed implementation of MTAB_NC
|
||||||
- fixed warnings in help printouts
|
- 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:
|
sim_tape.c:
|
||||||
- fixed signed/unsigned warning in sim_tape_set_fmt (Dave Bryan)
|
- 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
|
- Moved non-existent memory checks to WritePW
|
||||||
- Fixed mp_dms_jmp to accept lower bound, check write protection
|
- Fixed mp_dms_jmp to accept lower bound, check write protection
|
||||||
- Corrected DMS violation register set conditions
|
- 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
|
- Combined dms and dms_io routines
|
||||||
- JSB to 0/1 with W5 out and fence = 0 erroneously causes MP abort
|
- 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
|
- 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
|
- Updated mp_dms_jmp calling sequence
|
||||||
- Fixed DJP, SJP, and UJP jump target validation
|
- Fixed DJP, SJP, and UJP jump target validation
|
||||||
- RVA/B conditionally updates dms_vr before returning value
|
- RVA/B conditionally updates dms_vr before returning value
|
||||||
|
|
||||||
hp2100_cpu3.c (Dave Bryan):
|
hp2100_cpu3.c (Dave Bryan):
|
||||||
- Moved microcode function prototypes to hp2100_cpu1.h
|
- Moved microcode function prototypes to hp2100_cpu1.h
|
||||||
- Removed option-present tests (now in UIG dispatchers)
|
- Removed option-present tests (now in UIG dispatchers)
|
||||||
|
@ -506,7 +506,7 @@ patch date module(s) and fix(es)
|
||||||
hp2100_mt.c (Dave Bryan):
|
hp2100_mt.c (Dave Bryan):
|
||||||
- Fixed missing flag after CLR command
|
- Fixed missing flag after CLR command
|
||||||
- Moved write enable and format commands from MTD to MTC
|
- Moved write enable and format commands from MTD to MTC
|
||||||
|
|
||||||
hp2100_mux.c (Dave Bryan):
|
hp2100_mux.c (Dave Bryan):
|
||||||
- SHOW MUX CONN/STAT with SET MUX DIAG is no longer disallowed
|
- SHOW MUX CONN/STAT with SET MUX DIAG is no longer disallowed
|
||||||
- Changed Telnet poll to connect immediately after reset or attach
|
- 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)
|
- fixed declarations (Mark Pizzolato)
|
||||||
|
|
||||||
|
|
||||||
V3.7 revision history
|
V3.7 revision history
|
||||||
|
|
||||||
3 02-Sep-07 scp.c:
|
3 02-Sep-07 scp.c:
|
||||||
- fixed bug in SET THROTTLE command
|
- fixed bug in SET THROTTLE command
|
||||||
|
@ -771,7 +771,7 @@ patch date module(s) and fix(es)
|
||||||
|
|
||||||
sim_timer.c:
|
sim_timer.c:
|
||||||
- fixed idle timer event selection algorithm
|
- fixed idle timer event selection algorithm
|
||||||
|
|
||||||
h316_lp.c:
|
h316_lp.c:
|
||||||
- fixed loss of last print line (Theo Engel)
|
- 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 to set "mux_rchp" when a line break is received
|
||||||
- fixed incorrect "odd_par" table values
|
- fixed incorrect "odd_par" table values
|
||||||
- reversed test in "RCV_PAR" to return "LIL_PAR" on odd parity
|
- 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
|
- fixed to use PUT_DCH instead of PUT_CCH for data channel status
|
||||||
- added DIAG/TERM modifiers to implement diagnostic mode
|
- 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)
|
- 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:
|
1 25-Jul-06 sim_console.c:
|
||||||
- implemented SET/SHOW PCHAR
|
- 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 not exit prematurely if arg = 0
|
||||||
- fixed POLYD, POLYG to do full 64b multiply
|
- fixed POLYD, POLYG to do full 64b multiply
|
||||||
- fixed POLYF, POLYD, POLYG to remove truncation on add
|
- 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
|
- fixed fp add routine to test for zero via fraction
|
||||||
to support "denormal" argument from POLYF, POLYD, POLYG
|
to support "denormal" argument from POLYF, POLYD, POLYG
|
||||||
- fixed bug in 32b floating multiply routine
|
- 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 ACBH to set cc's on result
|
||||||
- fixed POLYH to set R3 correctly
|
- fixed POLYH to set R3 correctly
|
||||||
- fixed POLYH to not exit prematurely if arg = 0
|
- 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
|
- fixed fp add routine to test for zero via fraction
|
||||||
to support "denormal" argument from POLYH
|
to support "denormal" argument from POLYH
|
||||||
- fixed EMODH to concatenate 15b of 16b extension
|
- fixed EMODH to concatenate 15b of 16b extension
|
||||||
- fixed bug in reported VA on faulting cross-page write
|
- 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)
|
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
|
vax_io.c: revised autoconfiguration algorithm and interface
|
||||||
|
|
||||||
V3.4 revision history
|
V3.4 revision history
|
||||||
|
|
||||||
0 01-May-04 scp.c:
|
0 01-May-04 scp.c:
|
||||||
- fixed ASSERT code
|
- fixed ASSERT code
|
||||||
|
@ -1364,7 +1364,7 @@ patch date module(s) and fix(es)
|
||||||
|
|
||||||
pdp11_tu.c: fixed error reporting
|
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)
|
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
|
- TMK is cleared by new motion command, not DCLR
|
||||||
- DONE is set on data transfers, ATA on non data transfers
|
- DONE is set on data transfers, ATA on non data transfers
|
||||||
|
|
||||||
pdp11_defs.h:
|
pdp11_defs.h:
|
||||||
- revised Unibus/Qbus DMA API's
|
- revised Unibus/Qbus DMA API's
|
||||||
- added CPU type and options flags
|
- added CPU type and options flags
|
||||||
|
|
||||||
|
@ -1582,7 +1582,7 @@ patch date module(s) and fix(es)
|
||||||
vax_defs.h:
|
vax_defs.h:
|
||||||
- added octaword, compatibility mode support
|
- added octaword, compatibility mode support
|
||||||
|
|
||||||
vax_moddefs.h:
|
vax_moddefs.h:
|
||||||
- revised Unibus/Qbus DMA API's
|
- revised Unibus/Qbus DMA API's
|
||||||
|
|
||||||
vax_cpu.c:
|
vax_cpu.c:
|
||||||
|
@ -1616,7 +1616,7 @@ patch date module(s) and fix(es)
|
||||||
- split from vax_sys.c
|
- split from vax_sys.c
|
||||||
- removed PTR, PTP
|
- removed PTR, PTP
|
||||||
|
|
||||||
V3.2 revision history
|
V3.2 revision history
|
||||||
|
|
||||||
3 03-Sep-04 scp.c:
|
3 03-Sep-04 scp.c:
|
||||||
- added ECHO command (Dave Bryan)
|
- added ECHO command (Dave Bryan)
|
||||||
|
@ -1701,7 +1701,7 @@ patch date module(s) and fix(es)
|
||||||
- revised SR values to preserve SR<5:3>
|
- revised SR values to preserve SR<5:3>
|
||||||
|
|
||||||
hp2100_lps.c, hp2100_lpt.c: fixed timing
|
hp2100_lps.c, hp2100_lpt.c: fixed timing
|
||||||
|
|
||||||
hp2100_dp.c: fixed interpretation of SR<0>
|
hp2100_dp.c: fixed interpretation of SR<0>
|
||||||
|
|
||||||
hp2100_dr.c: revised boot code to use IBL algorithm
|
hp2100_dr.c: revised boot code to use IBL algorithm
|
||||||
|
@ -1868,7 +1868,7 @@ patch date module(s) and fix(es)
|
||||||
|
|
||||||
pdp1_drm.c:
|
pdp1_drm.c:
|
||||||
- added parallel drum support
|
- 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
|
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):
|
pdp11_xq.c (Dave Hittner, Mark Pizzolato):
|
||||||
- fixed second controller interrupts
|
- fixed second controller interrupts
|
||||||
- fixed bugs in multicast and promiscuous setup
|
- fixed bugs in multicast and promiscuous setup
|
||||||
|
|
||||||
pdp18b_cpu.c:
|
pdp18b_cpu.c:
|
||||||
- added instruction history
|
- added instruction history
|
||||||
- fixed PDP-4,-7,-9 autoincrement bug
|
- fixed PDP-4,-7,-9 autoincrement bug
|
||||||
|
@ -1928,7 +1928,7 @@ patch date module(s) and fix(es)
|
||||||
- revised instruction decoding
|
- revised instruction decoding
|
||||||
- added instruction history
|
- added instruction history
|
||||||
|
|
||||||
V3.0 revision history
|
V3.0 revision history
|
||||||
|
|
||||||
2 15-Sep-03 scp.c:
|
2 15-Sep-03 scp.c:
|
||||||
- fixed end-of-file problem in dep, idep
|
- 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
|
- added address switch functionality to PTR BOOT
|
||||||
|
|
||||||
pdp1_sys.c: added multibank capability to LOAD
|
pdp1_sys.c: added multibank capability to LOAD
|
||||||
|
|
||||||
pdp18b_cpu.c:
|
pdp18b_cpu.c:
|
||||||
- fixed priorities in PDP-15 API (PI between 3 and 4)
|
- fixed priorities in PDP-15 API (PI between 3 and 4)
|
||||||
- fixed sign handling in PDP-15 unsigned mul/div
|
- 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)
|
pdp11_cpu.c: fixed bugs (John Dundas)
|
||||||
- added special case for PS<15:12> = 1111 to MFPI
|
- added special case for PS<15:12> = 1111 to MFPI
|
||||||
- removed special case from MTPI
|
- removed special case from MTPI
|
||||||
- added masking of relocation adds
|
- added masking of relocation adds
|
||||||
|
|
||||||
i1401_cpu.c:
|
i1401_cpu.c:
|
||||||
- added multiply/divide
|
- added multiply/divide
|
||||||
|
@ -2446,7 +2446,7 @@ patch date module(s) and fix(es)
|
||||||
- changed LOG/NOLOG to SET LOG/NOLOG
|
- changed LOG/NOLOG to SET LOG/NOLOG
|
||||||
- added SHOW LOG
|
- added SHOW LOG
|
||||||
- added SET VT/NOVT and SHOW VT for VT emulation
|
- added SET VT/NOVT and SHOW VT for VT emulation
|
||||||
|
|
||||||
sim_sock.h: changed VMS stropt.h include to ioctl.h
|
sim_sock.h: changed VMS stropt.h include to ioctl.h
|
||||||
|
|
||||||
vax_cpu.c
|
vax_cpu.c
|
||||||
|
@ -2455,12 +2455,12 @@ patch date module(s) and fix(es)
|
||||||
- fixed register logging in autoincrement indexed
|
- fixed register logging in autoincrement indexed
|
||||||
|
|
||||||
vax_stddev.c: added TODR powerup routine
|
vax_stddev.c: added TODR powerup routine
|
||||||
|
|
||||||
vax_cpu1.c: fixed exception flows to clear trap request
|
vax_cpu1.c: fixed exception flows to clear trap request
|
||||||
|
|
||||||
7 30-Apr-02 scp.c: fixed bug in clock calibration when (real) clock
|
7 30-Apr-02 scp.c: fixed bug in clock calibration when (real) clock
|
||||||
jumps forward due too far (Jonathan Engdahl)
|
jumps forward due too far (Jonathan Engdahl)
|
||||||
|
|
||||||
pdp11_cpu.c: fixed bugs, added features (John Dundas
|
pdp11_cpu.c: fixed bugs, added features (John Dundas
|
||||||
and Wolfgang Helbig)
|
and Wolfgang Helbig)
|
||||||
- added HTRAP and BPOK to maintenance register
|
- 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 RTS SP, don't increment restored SP
|
||||||
- fixed TSTSET, write dst | 1 rather than prev R0 | 1
|
- 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 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-
|
- fixed ASH, ASHC, count = -32 used implementation-
|
||||||
dependent 32 bit right shift
|
dependent 32 bit right shift
|
||||||
- fixed illegal instruction test to detect 000010
|
- 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
|
- cleaned up volatile state for GNU C longjmp
|
||||||
|
|
||||||
pdp11_cpu.c: cleaned up declarations
|
pdp11_cpu.c: cleaned up declarations
|
||||||
|
|
||||||
pdp11_rq.c: added RA-class disks
|
pdp11_rq.c: added RA-class disks
|
||||||
|
|
||||||
4 17-Dec-01 pdp11_rq.c: added delayed processing of packets
|
4 17-Dec-01 pdp11_rq.c: added delayed processing of packets
|
||||||
|
|
14
sim_scsi.c
14
sim_scsi.c
|
@ -71,7 +71,7 @@
|
||||||
#define KEY_ILLREQ 5 /* illegal request */
|
#define KEY_ILLREQ 5 /* illegal request */
|
||||||
#define KEY_PROT 7 /* data protect */
|
#define KEY_PROT 7 /* data protect */
|
||||||
#define KEY_BLANK 8 /* blank check */
|
#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 */
|
/* Additional sense codes */
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ scsi_debug_cmd (bus, "Test Unit Ready\n");
|
||||||
|
|
||||||
if (uptr->flags & UNIT_ATT) /* attached? */
|
if (uptr->flags & UNIT_ATT) /* attached? */
|
||||||
scsi_status (bus, STS_OK, KEY_OK, ASC_OK); /* unit is ready */
|
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 */
|
scsi_status (bus, STS_CHK, KEY_NOTRDY, ASC_NOMEDIA); /* no media present */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,11 +428,11 @@ else {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (dev->removeable)
|
if (dev->removeable)
|
||||||
bus->buf[bus->buf_b++] = 0x80; /* removeable */
|
bus->buf[bus->buf_b++] = 0x80; /* removable */
|
||||||
else
|
else
|
||||||
bus->buf[bus->buf_b++] = 0; /* fixed */
|
bus->buf[bus->buf_b++] = 0; /* fixed */
|
||||||
bus->buf[bus->buf_b++] = dev->scsiver; /* versions */
|
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++] = 31; /* additional length */
|
||||||
bus->buf[bus->buf_b++] = 0; /* reserved */
|
bus->buf[bus->buf_b++] = 0; /* reserved */
|
||||||
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++] = 0x4; /* landing zone cyl (15:8) */
|
||||||
bus->buf[bus->buf_b++] = 0; /* landing zone cyl (7:0) */
|
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; /* 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++] = 0; /* reserved */
|
||||||
bus->buf[bus->buf_b++] = 0x1C; /* medium rotation rate (15:8) */
|
bus->buf[bus->buf_b++] = 0x1C; /* medium rotation rate (15:8) */
|
||||||
bus->buf[bus->buf_b++] = 0x20; /* medium rotation rate (7:0) */
|
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);
|
r = sim_tape_wrtmk (uptr);
|
||||||
if (r != MTSE_OK) break;
|
if (r != MTSE_OK) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_tape_status (bus, r);
|
scsi_tape_status (bus, r);
|
||||||
bus->buf[bus->buf_b++] = bus->status; /* status code */
|
bus->buf[bus->buf_b++] = bus->status; /* status code */
|
||||||
scsi_set_phase (bus, SCSI_STS); /* status phase next */
|
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);
|
return scsi_attach_ex (uptr, cptr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dettach device */
|
/* Detach device */
|
||||||
|
|
||||||
t_stat scsi_detach (UNIT *uptr)
|
t_stat scsi_detach (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
|
56
sim_serial.c
56
sim_serial.c
|
@ -74,12 +74,12 @@
|
||||||
sim_control_serial (SERHANDLE port, int32 bits_to_set, int32 bits_to_clear, int32 *incoming_bits)
|
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 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
|
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,
|
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
|
||||||
DSR and CTS are returned.
|
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;
|
specified, then the return status is SCPE_ARG;
|
||||||
If an error occurs, SCPE_IOERR is returned.
|
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);
|
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
|
/* 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
|
so we add the open ports to the list removing duplicates before sorting
|
||||||
the resulting list */
|
the resulting list */
|
||||||
|
|
||||||
for (i=0; i<serial_open_device_count; ++i) {
|
for (i=0; i<serial_open_device_count; ++i) {
|
||||||
|
@ -500,9 +500,9 @@ return r;
|
||||||
|
|
||||||
/* Enumerate the available serial ports.
|
/* 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
|
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.
|
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
|
else
|
||||||
break;
|
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].name, 0, sizeof(list[ports].name));
|
||||||
memset(list[ports].desc, 0, sizeof(list[ports].desc));
|
memset(list[ports].desc, 0, sizeof(list[ports].desc));
|
||||||
dwValueNameSize = sizeof(list[ports].desc);
|
dwValueNameSize = sizeof(list[ports].desc);
|
||||||
|
@ -775,12 +775,12 @@ return SCPE_OK; /* return success status
|
||||||
|
|
||||||
/* Control a serial port.
|
/* Control a serial port.
|
||||||
|
|
||||||
The DTR and RTS line of the serial port is set or cleared as indicated in
|
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
|
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,
|
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
|
||||||
DSR and CTS are returned.
|
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;
|
specified, then the return status is SCPE_ARG;
|
||||||
If an error occurs, SCPE_IOERR is returned.
|
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
|
The serial port names generated by attempting to open /dev/ttyS0 thru
|
||||||
/dev/ttyS63 and /dev/ttyUSB0 thru /dev/ttyUSB63 and /dev/tty.serial0
|
/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
|
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 isatty()) are added to the list. The list is sorted alphabetically
|
||||||
by device name.
|
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};
|
static char *serial_unix_serial_names[] = { "S", "U", "USB", ".serial", ".usbserial", NULL};
|
||||||
char **sp;
|
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) {
|
for (i=0; (ports < max) && (i <= 64); ++i) {
|
||||||
if (i < 64)
|
if (i < 64)
|
||||||
snprintf (list[ports].name, sizeof (list[ports].name), "/dev/tty%s%d", *sp, i);
|
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.
|
/* Control a serial port.
|
||||||
|
|
||||||
The DTR and RTS line of the serial port is set or cleared as indicated in
|
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
|
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,
|
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
|
||||||
DSR and CTS are returned.
|
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;
|
specified, then the return status is SCPE_ARG;
|
||||||
If an error occurs, SCPE_IOERR is returned.
|
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
|
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
|
/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.
|
is sorted alphabetically by device name.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -1539,10 +1539,10 @@ SERHANDLE port;
|
||||||
|
|
||||||
devnam.dsc$w_length = strlen (devnam.dsc$a_pointer);
|
devnam.dsc$w_length = strlen (devnam.dsc$a_pointer);
|
||||||
status = sys$assign (&devnam, &chan, 0, 0);
|
status = sys$assign (&devnam, &chan, 0, 0);
|
||||||
if (status != SS$_NORMAL)
|
if (status != SS$_NORMAL)
|
||||||
return INVALID_HANDLE;
|
return INVALID_HANDLE;
|
||||||
status = sys$getdviw (0, chan, NULL, items, &iosb, NULL, 0, NULL);
|
status = sys$getdviw (0, chan, NULL, items, &iosb, NULL, 0, NULL);
|
||||||
if ((status != SS$_NORMAL) ||
|
if ((status != SS$_NORMAL) ||
|
||||||
(iosb.status != SS$_NORMAL) ||
|
(iosb.status != SS$_NORMAL) ||
|
||||||
(devclass != DC$_TERM)) {
|
(devclass != DC$_TERM)) {
|
||||||
sys$dassgn (chan);
|
sys$dassgn (chan);
|
||||||
|
@ -1671,12 +1671,12 @@ return SCPE_OK; /* configuration set suc
|
||||||
|
|
||||||
/* Control a serial port.
|
/* Control a serial port.
|
||||||
|
|
||||||
The DTR and RTS line of the serial port is set or cleared as indicated in
|
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
|
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,
|
incoming_bits parameter is not NULL, then the modem status bits DCD, RNG,
|
||||||
DSR and CTS are returned.
|
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;
|
specified, then the return status is SCPE_ARG;
|
||||||
If an error occurs, SCPE_IOERR is returned.
|
If an error occurs, SCPE_IOERR is returned.
|
||||||
*/
|
*/
|
||||||
|
@ -1770,7 +1770,7 @@ if (status != SS$_NORMAL) {
|
||||||
}
|
}
|
||||||
if (sense.sense_count == 0) /* no characters available? */
|
if (sense.sense_count == 0) /* no characters available? */
|
||||||
return 0; /* return 0 to indicate */
|
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);
|
&iosb, 0, 0, buffer, (count < sense.sense_count) ? count : sense.sense_count, 0, term, 0, 0);
|
||||||
if (status == SS$_NORMAL)
|
if (status == SS$_NORMAL)
|
||||||
status = iosb.status;
|
status = iosb.status;
|
||||||
|
|
12
sim_sock.h
12
sim_sock.h
|
@ -23,10 +23,10 @@
|
||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
15-Oct-12 MP Added definitions needed to detect possible tcp
|
15-Oct-12 MP Added definitions needed to detect possible tcp
|
||||||
connect failures
|
connect failures
|
||||||
25-Sep-12 MP Reworked for RFC3493 interfaces supporting IPv6 and IPv4
|
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)
|
14-Apr-05 RMS Added WSAEINPROGRESS (from Tim Riker)
|
||||||
20-Aug-04 HV Added missing definition for OS/2 (from Holger Veit)
|
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
|
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 WSAGetLastError() errno /* Windows macros */
|
||||||
#define WSASetLastError(err) errno = err
|
#define WSASetLastError(err) errno = err
|
||||||
#define closesocket close
|
#define closesocket close
|
||||||
#define SOCKET int
|
#define SOCKET int
|
||||||
#if defined(__hpux)
|
#if defined(__hpux)
|
||||||
#define WSAEWOULDBLOCK EAGAIN
|
#define WSAEWOULDBLOCK EAGAIN
|
||||||
|
@ -111,10 +111,10 @@ extern "C" {
|
||||||
#define sim_printf printf
|
#define sim_printf printf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sim_parse_addr (const char *cptr, char *host, size_t hostlen, const char *default_host,
|
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,
|
char *port, size_t port_len, const char *default_port,
|
||||||
const char *validate_addr);
|
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);
|
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);
|
int sim_addr_acl_check (const char *validate_addr, const char *acl);
|
||||||
#define SIM_SOCK_OPT_REUSEADDR 0x0001
|
#define SIM_SOCK_OPT_REUSEADDR 0x0001
|
||||||
|
|
160
sim_tape.c
160
sim_tape.c
|
@ -35,8 +35,8 @@
|
||||||
sim_tape_sprecsr - skip records rev
|
sim_tape_sprecsr - skip records rev
|
||||||
sim_tape_spfiler - skip files rev
|
sim_tape_spfiler - skip files rev
|
||||||
sim_tape_position - general purpose position
|
sim_tape_position - general purpose position
|
||||||
These routines correspond to natural tape operations
|
These routines correspond to natural tape operations
|
||||||
and will align better when physical tape support is
|
and will align better when physical tape support is
|
||||||
included here.
|
included here.
|
||||||
08-Jun-08 JDB Fixed signed/unsigned warning in sim_tape_set_fmt
|
08-Jun-08 JDB Fixed signed/unsigned warning in sim_tape_set_fmt
|
||||||
23-Jan-07 JDB Fixed backspace over gap at BOT
|
23-Jan-07 JDB Fixed backspace over gap at BOT
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
sim_tape_errecf erase record forward
|
sim_tape_errecf erase record forward
|
||||||
sim_tape_errecr erase record reverse
|
sim_tape_errecr erase record reverse
|
||||||
sim_tape_sprecsf space records forward
|
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_sprecsr space records reverse
|
||||||
sim_tape_spfiler space files reverse
|
sim_tape_spfiler space files reverse
|
||||||
sim_tape_position generalized position
|
sim_tape_position generalized position
|
||||||
|
@ -229,8 +229,8 @@ _tape_io(void *arg)
|
||||||
UNIT* volatile uptr = (UNIT*)arg;
|
UNIT* volatile uptr = (UNIT*)arg;
|
||||||
struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
|
struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
|
||||||
|
|
||||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||||
thread which in general won't be readily yielding the processor when
|
thread which in general won't be readily yielding the processor when
|
||||||
this thread needs to run */
|
this thread needs to run */
|
||||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||||
|
|
||||||
|
@ -308,14 +308,14 @@ struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This routine is called in the context of the main simulator thread before
|
/* 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
|
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
|
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
|
routine is to put the unit in proper condition to digest what may have
|
||||||
occurred in the asynchronous thread.
|
occurred in the asynchronous thread.
|
||||||
|
|
||||||
Since tape processing only handles a single I/O at a time to a
|
Since tape processing only handles a single I/O at a time to a
|
||||||
particular tape device, we have the opportunity to possibly detect
|
particular tape device, we have the opportunity to possibly detect
|
||||||
improper attempts to issue multiple concurrent I/O requests. */
|
improper attempts to issue multiple concurrent I/O requests. */
|
||||||
static void _tape_completion_dispatch (UNIT *uptr)
|
static void _tape_completion_dispatch (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
@ -453,30 +453,30 @@ typedef struct MEMORY_TAPE {
|
||||||
VOL1 vol1;
|
VOL1 vol1;
|
||||||
} MEMORY_TAPE;
|
} MEMORY_TAPE;
|
||||||
|
|
||||||
const char HDR3_RMS_STREAM[] = "HDR3020002040000"
|
const char HDR3_RMS_STREAM[] = "HDR3020002040000"
|
||||||
"0000000100000000"
|
"0000000100000000"
|
||||||
"0000000002000000"
|
"0000000002000000"
|
||||||
"0000000000000000"
|
"0000000000000000"
|
||||||
"0000 ";
|
"0000 ";
|
||||||
const char HDR3_RMS_STMLF[] = "HDR3020002050000"
|
const char HDR3_RMS_STMLF[] = "HDR3020002050000"
|
||||||
"0000000100000000"
|
"0000000100000000"
|
||||||
"0000000002000000"
|
"0000000002000000"
|
||||||
"0000000000000000"
|
"0000000000000000"
|
||||||
"0000 ";
|
"0000 ";
|
||||||
const char HDR3_RMS_FIXED[] = "HDR3020000010000"
|
const char HDR3_RMS_FIXED[] = "HDR3020000010000"
|
||||||
"0000000100000000"
|
"0000000100000000"
|
||||||
"0000000002000000"
|
"0000000002000000"
|
||||||
"0000000000000000"
|
"0000000000000000"
|
||||||
"0000 ";
|
"0000 ";
|
||||||
const char HDR3_RMS_VARRSX[] = "HDR300000A020000"
|
const char HDR3_RMS_VARRSX[] = "HDR300000A020000"
|
||||||
"0000000100000000"
|
"0000000100000000"
|
||||||
"0000000000000000"
|
"0000000000000000"
|
||||||
"0000000000000000"
|
"0000000000000000"
|
||||||
"0000 ";
|
"0000 ";
|
||||||
const char HDR3_RMS_FIXRSX[] = "HDR3020008010000"
|
const char HDR3_RMS_FIXRSX[] = "HDR3020008010000"
|
||||||
"0000000100000000"
|
"0000000100000000"
|
||||||
"0000000000000000"
|
"0000000000000000"
|
||||||
"0000000000000000"
|
"0000000000000000"
|
||||||
"0000 ";
|
"0000 ";
|
||||||
|
|
||||||
static struct ansi_tape_parameters {
|
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 *ansi_create_tape (const char *label, size_t block_size, uint32 ansi_type);
|
||||||
static MEMORY_TAPE *memory_create_tape (void);
|
static MEMORY_TAPE *memory_create_tape (void);
|
||||||
static void memory_free_tape (void *vtape);
|
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,
|
const char *filename,
|
||||||
t_offset FileSize,
|
t_offset FileSize,
|
||||||
const struct stat *filestat,
|
const struct stat *filestat,
|
||||||
|
@ -596,7 +596,7 @@ return SCPE_OK;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This routine is called when the simulator stops and any time
|
This routine is called when the simulator stops and any time
|
||||||
the asynch mode is changed (enabled or disabled)
|
the asynch mode is changed (enabled or disabled)
|
||||||
*/
|
*/
|
||||||
|
@ -781,7 +781,7 @@ switch (MT_GET_FMT (uptr)) {
|
||||||
if (uptr->recsize == 0)
|
if (uptr->recsize == 0)
|
||||||
uptr->recsize = 512;
|
uptr->recsize = 512;
|
||||||
if ((statb.st_size % uptr->recsize) != 0) {
|
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);
|
fclose (f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -810,11 +810,11 @@ switch (MT_GET_FMT (uptr)) {
|
||||||
tape->block_size = uptr->recsize;
|
tape->block_size = uptr->recsize;
|
||||||
block = (uint8 *)calloc (1, tape->block_size + 3);
|
block = (uint8 *)calloc (1, tape->block_size + 3);
|
||||||
while (!feof (f) && !error) {
|
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)) {
|
if (fgets ((char *)block, (int) (tape->block_size + 3), f)) {
|
||||||
size_t len = strlen ((char *)block);
|
size_t len = strlen ((char *)block);
|
||||||
|
|
||||||
while ((len > 0) &&
|
while ((len > 0) &&
|
||||||
((block[len - 1] == '\r') || (block[len - 1] == '\n')))
|
((block[len - 1] == '\r') || (block[len - 1] == '\n')))
|
||||||
--len;
|
--len;
|
||||||
memset (block + len, ' ', tape->block_size - len);
|
memset (block + len, ' ', tape->block_size - len);
|
||||||
|
@ -891,7 +891,7 @@ switch (MT_GET_FMT (uptr)) {
|
||||||
if (uptr->recsize == 0)
|
if (uptr->recsize == 0)
|
||||||
uptr->recsize = TAR_DFLT_RECSIZE; /* Apply default block size */
|
uptr->recsize = TAR_DFLT_RECSIZE; /* Apply default block size */
|
||||||
if ((uptr->recsize % 512) != 0)
|
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 */
|
sim_switches |= SWMASK ('E'); /* The TAR file must exist */
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
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 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, " fixed sized records/blocks with ascii text data optionally converted\n");
|
||||||
fprintf (st, " to EBCDIC.\n\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, " 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, " 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");
|
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 */
|
if ((uptr->flags & UNIT_ATT) == 0) /* if the unit is not attached */
|
||||||
return MTSE_UNATT; /* then quit with an error */
|
return MTSE_UNATT; /* then quit with an error */
|
||||||
|
|
||||||
if ((uptr->tape_eom > 0) &&
|
if ((uptr->tape_eom > 0) &&
|
||||||
(uptr->pos >= uptr->tape_eom)) {
|
(uptr->pos >= uptr->tape_eom)) {
|
||||||
MT_SET_PNU (uptr); /* then set position not updated */
|
MT_SET_PNU (uptr); /* then set position not updated */
|
||||||
return MTSE_EOM; /* and quit with I/O error status */
|
return MTSE_EOM; /* and quit with I/O error status */
|
||||||
|
@ -1402,7 +1402,7 @@ switch (f) { /* otherwise the read method
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((feof (uptr->fileref)) || /* eof? */
|
if ((feof (uptr->fileref)) || /* eof? */
|
||||||
((tpcbc == TPC_EOM) &&
|
((tpcbc == TPC_EOM) &&
|
||||||
(sim_fsize (uptr->fileref) == (uint32)sim_ftell (uptr->fileref)))) {
|
(sim_fsize (uptr->fileref) == (uint32)sim_ftell (uptr->fileref)))) {
|
||||||
MT_SET_PNU (uptr); /* pos not upd */
|
MT_SET_PNU (uptr); /* pos not upd */
|
||||||
status = MTSE_EOM;
|
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 */
|
saved_pos = (t_addr)sim_ftell (uptr->fileref);/* save record data address */
|
||||||
(void)sim_tape_seek (uptr, uptr->pos); /* for read */
|
(void)sim_tape_seek (uptr, uptr->pos); /* for read */
|
||||||
rdcnt = sim_fread (&awshdr, sizeof (t_awslnt), 3, uptr->fileref);
|
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)))) {
|
((awshdr.prelen != *bc) || ((awshdr.rectyp != AWS_REC) && (awshdr.rectyp != AWS_TMK)))) {
|
||||||
status = MTSE_INVRL;
|
status = MTSE_INVRL;
|
||||||
uptr->tape_eom = uptr->pos;
|
uptr->tape_eom = uptr->pos;
|
||||||
|
@ -1499,7 +1499,7 @@ switch (f) { /* otherwise the read method
|
||||||
*bc = (t_mtrlnt)uptr->recsize; /* TAR record size */
|
*bc = (t_mtrlnt)uptr->recsize; /* TAR record size */
|
||||||
else
|
else
|
||||||
*bc = (t_mtrlnt)(uptr->hwmark - uptr->pos); /* TAR remnant last record */
|
*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;
|
uptr->pos += *bc;
|
||||||
MT_CLR_INMRK (uptr);
|
MT_CLR_INMRK (uptr);
|
||||||
}
|
}
|
||||||
|
@ -1798,8 +1798,8 @@ switch (f) { /* otherwise the read me
|
||||||
status = MTSE_EOM;
|
status = MTSE_EOM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((rdcnt != 3) ||
|
if ((rdcnt != 3) ||
|
||||||
((awshdr.rectyp != AWS_REC) &&
|
((awshdr.rectyp != AWS_REC) &&
|
||||||
(awshdr.rectyp != AWS_TMK))) {
|
(awshdr.rectyp != AWS_TMK))) {
|
||||||
status = MTSE_INVRL;
|
status = MTSE_INVRL;
|
||||||
}
|
}
|
||||||
|
@ -1810,8 +1810,8 @@ switch (f) { /* otherwise the read me
|
||||||
if (awshdr.prelen == 0)
|
if (awshdr.prelen == 0)
|
||||||
status = MTSE_TMK;
|
status = MTSE_TMK;
|
||||||
else {
|
else {
|
||||||
if ((uptr->tape_eom > 0) &&
|
if ((uptr->tape_eom > 0) &&
|
||||||
(uptr->pos >= uptr->tape_eom) &&
|
(uptr->pos >= uptr->tape_eom) &&
|
||||||
(awshdr.rectyp == AWS_TMK)) {
|
(awshdr.rectyp == AWS_TMK)) {
|
||||||
status = MTSE_TMK;
|
status = MTSE_TMK;
|
||||||
*bc = 0; /* save rec lnt */
|
*bc = 0; /* save rec lnt */
|
||||||
|
@ -1847,7 +1847,7 @@ switch (f) { /* otherwise the read me
|
||||||
*bc = (t_mtrlnt)uptr->recsize;
|
*bc = (t_mtrlnt)uptr->recsize;
|
||||||
if (*bc) {
|
if (*bc) {
|
||||||
uptr->pos -= *bc;
|
uptr->pos -= *bc;
|
||||||
(void)sim_tape_seek (uptr, uptr->pos);
|
(void)sim_tape_seek (uptr, uptr->pos);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2139,7 +2139,7 @@ if (ferror (uptr->fileref)) { /* error? */
|
||||||
MT_SET_PNU (uptr); /* pos not upd */
|
MT_SET_PNU (uptr); /* pos not upd */
|
||||||
return sim_tape_ioerr (uptr);
|
return sim_tape_ioerr (uptr);
|
||||||
}
|
}
|
||||||
if ((!sim_tape_bot (uptr)) &&
|
if ((!sim_tape_bot (uptr)) &&
|
||||||
(((feof (uptr->fileref)) && (rdcnt < 3)) || /* eof? */
|
(((feof (uptr->fileref)) && (rdcnt < 3)) || /* eof? */
|
||||||
((awshdr.rectyp != AWS_REC) && (awshdr.rectyp != AWS_TMK)))) {
|
((awshdr.rectyp != AWS_REC) && (awshdr.rectyp != AWS_TMK)))) {
|
||||||
MT_SET_PNU (uptr); /* pos not upd */
|
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 */
|
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);
|
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 */
|
st = sim_tape_sprecf (uptr, &tbc); /* spc rec */
|
||||||
if (st != MTSE_OK)
|
if (st != MTSE_OK)
|
||||||
return st;
|
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 */
|
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);
|
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 */
|
st = sim_tape_sprecr (uptr, &tbc); /* spc rec rev */
|
||||||
if (st != MTSE_OK)
|
if (st != MTSE_OK)
|
||||||
return st;
|
return st;
|
||||||
|
@ -3028,7 +3028,7 @@ if (check_leot) {
|
||||||
}
|
}
|
||||||
*skipped = 0;
|
*skipped = 0;
|
||||||
*recsskipped = 0;
|
*recsskipped = 0;
|
||||||
while (*skipped < count) { /* loopo */
|
while (*skipped < count) { /* loop */
|
||||||
while (1) {
|
while (1) {
|
||||||
st = sim_tape_sprecsf (uptr, 0x1ffffff, &filerecsskipped);/* spc recs */
|
st = sim_tape_sprecsf (uptr, 0x1ffffff, &filerecsskipped);/* spc recs */
|
||||||
*recsskipped += filerecsskipped;
|
*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 */
|
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);
|
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) {
|
while (1) {
|
||||||
st = sim_tape_sprecsr (uptr, 0x1ffffff, &filerecsskipped);/* spc recs rev */
|
st = sim_tape_sprecsr (uptr, 0x1ffffff, &filerecsskipped);/* spc recs rev */
|
||||||
*recsskipped += filerecsskipped;
|
*recsskipped += filerecsskipped;
|
||||||
|
@ -3250,7 +3250,7 @@ if (flags & MTPOS_M_OBJ) {
|
||||||
uint32 skipped;
|
uint32 skipped;
|
||||||
uint32 objsremaining = objs;
|
uint32 objsremaining = objs;
|
||||||
|
|
||||||
while (*objectsskipped < objs) { /* loopo */
|
while (*objectsskipped < objs) { /* loop */
|
||||||
if (flags & MTPOS_M_REV) /* reverse? */
|
if (flags & MTPOS_M_REV) /* reverse? */
|
||||||
r = sim_tape_sprecsr (uptr, objsremaining, &skipped);
|
r = sim_tape_sprecsr (uptr, objsremaining, &skipped);
|
||||||
else
|
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" : "");
|
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) &&
|
(tpos > tape_size) &&
|
||||||
(!had_double_tape_mark)) ||
|
(!had_double_tape_mark)) ||
|
||||||
(!had_double_tape_mark) ||
|
(!had_double_tape_mark) ||
|
||||||
((objc == countmap[0]) &&
|
((objc == countmap[0]) &&
|
||||||
(countmap[0] != 2))) { /* Unreasonable format? */
|
(countmap[0] != 2))) { /* Unreasonable format? */
|
||||||
if (last_bc != TPC_EOM)
|
if (last_bc != TPC_EOM)
|
||||||
sim_debug_unit (MTSE_DBG_STR, uptr, "tpc_map: ERROR unexpected EOT byte count: %d\n", last_bc);
|
sim_debug_unit (MTSE_DBG_STR, uptr, "tpc_map: ERROR unexpected EOT byte count: %d\n", last_bc);
|
||||||
if (tpos > tape_size)
|
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);
|
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])
|
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 (countmap);
|
||||||
free (recbuf);
|
free (recbuf);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3582,7 +3582,7 @@ while (r == SCPE_OK) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (0 != memcmp (buf_f, buf_r, bc_f)) {
|
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;
|
r = MTSE_RECE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3817,11 +3817,11 @@ return SCPE_OK;
|
||||||
|
|
||||||
/* list supported densities
|
/* 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)"
|
"(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.
|
SET <unit> DENSITY= command.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -4076,7 +4076,7 @@ tpclnt = 0xffff;
|
||||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fE11);
|
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fE11);
|
||||||
(void)sim_fwrite (&tpclnt, sizeof (tpclnt), 1, fTPC);
|
(void)sim_fwrite (&tpclnt, sizeof (tpclnt), 1, fTPC);
|
||||||
(void)sim_fwrite (buf, 1, 1, fP7B);
|
(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 */
|
the end of the SIMH, E11 and AWS files */
|
||||||
mtrlnt = 25;
|
mtrlnt = 25;
|
||||||
(void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, fSIMH);
|
(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, "")))
|
(strcmp (buf, "")))
|
||||||
return stat;
|
return stat;
|
||||||
valid_bits = MT_556_VALID;
|
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")))
|
(strcmp (buf, "556")))
|
||||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
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;
|
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}")))
|
(strcmp (buf, "{800|1600}")))
|
||||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
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;
|
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}")))
|
(strcmp (buf, "{800|1600|6250}")))
|
||||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
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;
|
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}")))
|
(strcmp (buf, "{200|800|1600|6250}")))
|
||||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
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;
|
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}")))
|
(strcmp (buf, "{0|800|1600|6250}")))
|
||||||
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||||
return SCPE_OK;
|
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);
|
tape_classify_file_contents (f, &mrs, &lf_lines, &crlf_lines);
|
||||||
fclose (f);
|
fclose (f);
|
||||||
if ((mrs != t->expected_mrs) || (lf_lines != t->expected_lf_lines) || (crlf_lines != t->expected_crlf_lines))
|
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");
|
t->testname, (int)mrs, lf_lines ? "true" : "false", crlf_lines ? "true" : "false");
|
||||||
if (t->success_attach_args) {
|
if (t->success_attach_args) {
|
||||||
char args[CBUFSIZE*2];
|
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);
|
lt = localtime (&datetime);
|
||||||
if (y2k_date_bug)
|
if (y2k_date_bug)
|
||||||
sprintf (buf, " %c%c%03d", '0' + (lt->tm_year / 10),
|
sprintf (buf, " %c%c%03d", '0' + (lt->tm_year / 10),
|
||||||
'0' + (lt->tm_year % 10),
|
'0' + (lt->tm_year % 10),
|
||||||
lt->tm_yday + 1);
|
lt->tm_yday + 1);
|
||||||
else
|
else
|
||||||
sprintf (buf, "%c%02d%03d", (lt->tm_year < 100) ? ' ' : '0' + (lt->tm_year/100 - 1),
|
sprintf (buf, "%c%02d%03d", (lt->tm_year < 100) ? ' ' : '0' + (lt->tm_year/100 - 1),
|
||||||
lt->tm_year % 100,
|
lt->tm_year % 100,
|
||||||
lt->tm_yday + 1);
|
lt->tm_yday + 1);
|
||||||
memcpy (date, buf, 6);
|
memcpy (date, buf, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This isn't quite ANSI 'a' since several ANSI allowed characters
|
* This isn't quite ANSI 'a' since several ANSI allowed characters
|
||||||
* are either illegal file names on many DEC systems or are confusing
|
* are either illegal file names on many DEC systems or are confusing
|
||||||
* to OS file name parsers.
|
* 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;
|
fn = fn_cpy;
|
||||||
ext = strrchr (fn_cpy, '.');
|
ext = strrchr (fn_cpy, '.');
|
||||||
if (ext) {
|
if (ext) {
|
||||||
while (((c = strchr (fn_cpy, '.')) != NULL) &&
|
while (((c = strchr (fn_cpy, '.')) != NULL) &&
|
||||||
(c != ext))
|
(c != ext))
|
||||||
*c = '_'; /* translate extra .'s to _ */
|
*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;
|
move_size = rec_size;
|
||||||
else
|
else
|
||||||
move_size = buf_size - offset;
|
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);
|
memcpy (buf + offset, tmp, move_size);
|
||||||
offset += move_size;
|
offset += move_size;
|
||||||
if (offset == buf_size) {
|
if (offset == buf_size) {
|
||||||
|
@ -4798,7 +4798,7 @@ else {
|
||||||
if (data_read > 0)
|
if (data_read > 0)
|
||||||
error = memory_tape_add_block (tape, block, data_read);
|
error = memory_tape_add_block (tape, block, data_read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose (f);
|
fclose (f);
|
||||||
free (block);
|
free (block);
|
||||||
|
@ -4953,7 +4953,7 @@ else { /* Text file */
|
||||||
1 - ansi->skip_lf_line_endings);
|
1 - ansi->skip_lf_line_endings);
|
||||||
/* max_record_size must fit in the 4-character ANSI RCW */
|
/* max_record_size must fit in the 4-character ANSI RCW */
|
||||||
if (max_record_size > 9999) {
|
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 :
|
(crlf_line_endings ? 2 - ansi->skip_crlf_line_endings :
|
||||||
1 - ansi->skip_lf_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",
|
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;
|
size_t data_read = tape->block_size;
|
||||||
|
|
||||||
if (lf_line_endings || crlf_line_endings) /* Text file? */
|
if (lf_line_endings || crlf_line_endings) /* Text file? */
|
||||||
ansi_fill_text_buffer (f, (char *)block, tape->block_size,
|
ansi_fill_text_buffer (f, (char *)block, tape->block_size,
|
||||||
crlf_line_endings ? ansi->skip_crlf_line_endings : ansi->skip_lf_line_endings,
|
crlf_line_endings ? ansi->skip_crlf_line_endings : ansi->skip_lf_line_endings,
|
||||||
ansi->fixed_text);
|
ansi->fixed_text);
|
||||||
|
|
||||||
else { /* Binary file */
|
else { /* Binary file */
|
||||||
size_t runt = 0;
|
size_t runt = 0;
|
||||||
|
|
||||||
data_read = fread (block, 1, tape->block_size, f);
|
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 */
|
runt = data_read % max_record_size; /* data_read (=0) % anypositivenumber == 0 */
|
||||||
/* Pad short records with zeros */
|
/* Pad short records with zeros */
|
||||||
if (runt > 0) {
|
if (runt > 0) {
|
||||||
|
@ -5049,7 +5049,7 @@ if (sim_switches & SWMASK ('V'))
|
||||||
return error;
|
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,
|
const char *filename,
|
||||||
t_offset FileSize,
|
t_offset FileSize,
|
||||||
const struct stat *filestat,
|
const struct stat *filestat,
|
||||||
|
|
272
sim_timer.c
272
sim_timer.c
|
@ -32,23 +32,23 @@
|
||||||
- Sleep for the observed clock tick size while throttling
|
- Sleep for the observed clock tick size while throttling
|
||||||
- Recompute the throttling wait once every 10 seconds
|
- Recompute the throttling wait once every 10 seconds
|
||||||
to account for varying instruction mixes during
|
to account for varying instruction mixes during
|
||||||
different phases of a simulator execution or to
|
different phases of a simulator execution or to
|
||||||
accommodate the presence of other load on the host
|
accommodate the presence of other load on the host
|
||||||
system.
|
system.
|
||||||
- Each of the pre-existing throttling modes (Kcps,
|
- Each of the pre-existing throttling modes (Kcps,
|
||||||
Mcps, and %) all compute the appropriate throttling
|
Mcps, and %) all compute the appropriate throttling
|
||||||
interval dynamically. These dynamic computations
|
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.
|
the current simulator during this computation.
|
||||||
This assumption may not always be true and under
|
This assumption may not always be true and under
|
||||||
certain conditions may never provide a way to
|
certain conditions may never provide a way to
|
||||||
correctly determine the appropriate throttling
|
correctly determine the appropriate throttling
|
||||||
wait. An additional throttling mode has been added
|
wait. An additional throttling mode has been added
|
||||||
which allows the simulator operator to explicitly
|
which allows the simulator operator to explicitly
|
||||||
state the desired throttling wait parameters.
|
state the desired throttling wait parameters.
|
||||||
These are specified by:
|
These are specified by:
|
||||||
SET THROT insts/delay
|
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.
|
execute before sleeping for 'delay' milliseconds.
|
||||||
22-Apr-11 MP Fixed Asynch I/O support to reasonably account cycles
|
22-Apr-11 MP Fixed Asynch I/O support to reasonably account cycles
|
||||||
when an idle wait is terminated by an external event
|
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)
|
#if defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1)
|
||||||
|
|
||||||
#define sim_idle_ms_sleep real_sim_idle_ms_sleep
|
#define sim_idle_ms_sleep real_sim_idle_ms_sleep
|
||||||
#define sim_os_msec real_sim_os_msec
|
#define sim_os_msec real_sim_os_msec
|
||||||
#define sim_os_ms_sleep real_sim_os_ms_sleep
|
#define sim_os_ms_sleep real_sim_os_ms_sleep
|
||||||
|
|
||||||
#endif /* defined(MS_MIN_GRANULARITY) && (MS_MIN_GRANULARITY != 1) */
|
#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)
|
int32 sim_rtcn_init_unit_ticks (UNIT *uptr, int32 time, int32 tmr, int32 ticksper)
|
||||||
{
|
{
|
||||||
RTC *rtc;
|
RTC *rtc;
|
||||||
|
|
||||||
if (time == 0)
|
if (time == 0)
|
||||||
time = 1;
|
time = 1;
|
||||||
if (tmr == SIM_INTERNAL_CLK)
|
if (tmr == SIM_INTERNAL_CLK)
|
||||||
|
@ -864,8 +864,8 @@ if (rtc->hz != ticksper) { /* changing tick rate? */
|
||||||
|
|
||||||
if (rtc->hz == 0)
|
if (rtc->hz == 0)
|
||||||
rtc->clock_tick_start_time = sim_timenow_double ();
|
rtc->clock_tick_start_time = sim_timenow_double ();
|
||||||
if ((rtc->last_hz != 0) &&
|
if ((rtc->last_hz != 0) &&
|
||||||
(rtc->last_hz != ticksper) &&
|
(rtc->last_hz != ticksper) &&
|
||||||
(ticksper != 0))
|
(ticksper != 0))
|
||||||
rtc->currd = (int32)(sim_timer_inst_per_sec () / ticksper);
|
rtc->currd = (int32)(sim_timer_inst_per_sec () / ticksper);
|
||||||
rtc->last_hz = rtc->hz;
|
rtc->last_hz = rtc->hz;
|
||||||
|
@ -912,9 +912,9 @@ if (sim_calb_tmr != tmr) {
|
||||||
return rtc->currd;
|
return rtc->currd;
|
||||||
}
|
}
|
||||||
new_rtime = sim_os_msec (); /* wall time */
|
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)) {
|
((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 ();
|
(void)sim_poll_kbd ();
|
||||||
}
|
}
|
||||||
++rtc->calibrations; /* count calibrations */
|
++rtc->calibrations; /* count calibrations */
|
||||||
|
@ -989,7 +989,7 @@ if (sim_asynch_timer || (catchup_ticks_curr > 0)) {
|
||||||
}
|
}
|
||||||
rtc->based = rtc->currd = new_currd;
|
rtc->based = rtc->currd = new_currd;
|
||||||
rtc->gtime = new_gtime; /* save instruction time */
|
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);
|
sim_asynch_timer ? "asynch" : "catchup", tmr, ticksper, catchup_ticks_curr, last_idle_pct, rtc->currd);
|
||||||
return rtc->currd; /* calibrated result */
|
return rtc->currd; /* calibrated result */
|
||||||
}
|
}
|
||||||
|
@ -1016,7 +1016,7 @@ if (rtc->based <= 0) /* never negative or zero! *
|
||||||
rtc->based = 1;
|
rtc->based = 1;
|
||||||
if (rtc->currd <= 0) /* never negative or zero! */
|
if (rtc->currd <= 0) /* never negative or zero! */
|
||||||
rtc->currd = 1;
|
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);
|
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 */
|
/* Adjust calibration for other timers which depend on this timer's calibration */
|
||||||
for (itmr=0; itmr<=SIM_NTIMERS; itmr++) {
|
for (itmr=0; itmr<=SIM_NTIMERS; itmr++) {
|
||||||
|
@ -1025,7 +1025,7 @@ for (itmr=0; itmr<=SIM_NTIMERS; itmr++) {
|
||||||
if ((itmr != tmr) && (irtc->hz != 0))
|
if ((itmr != tmr) && (irtc->hz != 0))
|
||||||
irtc->currd = (rtc->currd * ticksper) / irtc->hz;
|
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;
|
return rtc->currd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1077,7 @@ sim_stop_time = clock_last = clock_start = sim_os_msec ();
|
||||||
sim_os_clock_resoluton_ms = 1000;
|
sim_os_clock_resoluton_ms = 1000;
|
||||||
do {
|
do {
|
||||||
uint32 clock_diff;
|
uint32 clock_diff;
|
||||||
|
|
||||||
clock_now = sim_os_msec ();
|
clock_now = sim_os_msec ();
|
||||||
clock_diff = clock_now - clock_last;
|
clock_diff = clock_now - clock_last;
|
||||||
if ((clock_diff > 0) && (clock_diff < sim_os_clock_resoluton_ms))
|
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) {
|
if (sim_throt_type != SIM_THROT_NONE) {
|
||||||
sim_show_throt (st, NULL, uptr, val, desc);
|
sim_show_throt (st, NULL, uptr, val, desc);
|
||||||
}
|
}
|
||||||
fprintf (st, "Calibrated Timer: %s\n", (calb_tmr == -1) ? "Undetermined" :
|
fprintf (st, "Calibrated Timer: %s\n", (calb_tmr == -1) ? "Undetermined" :
|
||||||
((calb_tmr == SIM_NTIMERS) ? "Internal Timer" :
|
((calb_tmr == SIM_NTIMERS) ? "Internal Timer" :
|
||||||
(rtcs[calb_tmr].clock_unit ? sim_uname(rtcs[calb_tmr].clock_unit) : "")));
|
(rtcs[calb_tmr].clock_unit ? sim_uname(rtcs[calb_tmr].clock_unit) : "")));
|
||||||
if (calb_tmr == SIM_NTIMERS)
|
if (calb_tmr == SIM_NTIMERS)
|
||||||
fprintf (st, "Catchup Ticks: %s\n", sim_catchup_ticks ? "Enabled" : "Disabled");
|
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)
|
if (0 == rtc->initd)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (rtc->clock_unit) {
|
if (rtc->clock_unit) {
|
||||||
++clocks;
|
++clocks;
|
||||||
fprintf (st, "%s clock device is %s%s%s\n", sim_name,
|
fprintf (st, "%s clock device is %s%s%s\n", sim_name,
|
||||||
(tmr == SIM_NTIMERS) ? "Internal Calibrated Timer(" : "",
|
(tmr == SIM_NTIMERS) ? "Internal Calibrated Timer(" : "",
|
||||||
sim_uname(rtc->clock_unit),
|
sim_uname(rtc->clock_unit),
|
||||||
(tmr == SIM_NTIMERS) ? ")" : "");
|
(tmr == SIM_NTIMERS) ? ")" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1478,30 +1478,30 @@ return "Throttle facility";
|
||||||
|
|
||||||
|
|
||||||
DEVICE sim_timer_dev = {
|
DEVICE sim_timer_dev = {
|
||||||
"INT-CLOCK", sim_timer_units, sim_timer_reg, sim_timer_mod,
|
"INT-CLOCK", sim_timer_units, sim_timer_reg, sim_timer_mod,
|
||||||
SIM_NTIMERS+1, 0, 0, 0, 0, 0,
|
SIM_NTIMERS+1, 0, 0, 0, 0, 0,
|
||||||
NULL, NULL, &sim_timer_clock_reset, NULL, NULL, NULL,
|
NULL, NULL, &sim_timer_clock_reset, NULL, NULL, NULL,
|
||||||
NULL, DEV_DEBUG | DEV_NOSAVE, 0,
|
NULL, DEV_DEBUG | DEV_NOSAVE, 0,
|
||||||
sim_timer_debug};
|
sim_timer_debug};
|
||||||
|
|
||||||
DEVICE sim_int_timer_dev = {
|
DEVICE sim_int_timer_dev = {
|
||||||
"INT-TIMER", &sim_internal_timer_unit, NULL, NULL,
|
"INT-TIMER", &sim_internal_timer_unit, NULL, NULL,
|
||||||
1, 0, 0, 0, 0, 0,
|
1, 0, 0, 0, 0, 0,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
NULL, DEV_NOSAVE};
|
NULL, DEV_NOSAVE};
|
||||||
|
|
||||||
DEVICE sim_stop_dev = {
|
DEVICE sim_stop_dev = {
|
||||||
"INT-STOP", &sim_stop_unit, NULL, NULL,
|
"INT-STOP", &sim_stop_unit, NULL, NULL,
|
||||||
1, 0, 0, 0, 0, 0,
|
1, 0, 0, 0, 0, 0,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
NULL, DEV_NOSAVE, 0,
|
NULL, DEV_NOSAVE, 0,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
sim_int_stop_description};
|
sim_int_stop_description};
|
||||||
|
|
||||||
DEVICE sim_throttle_dev = {
|
DEVICE sim_throttle_dev = {
|
||||||
"INT-THROTTLE", &sim_throttle_unit, sim_throttle_reg, NULL,
|
"INT-THROTTLE", &sim_throttle_unit, sim_throttle_reg, NULL,
|
||||||
1, 0, 0, 0, 0, 0,
|
1, 0, 0, 0, 0, 0,
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
NULL, DEV_NOSAVE};
|
NULL, DEV_NOSAVE};
|
||||||
|
|
||||||
/* SET CLOCK command */
|
/* 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 != QUEUE_LIST_END) && /* or clock queue not empty */
|
||||||
((sim_clock_queue->flags & UNIT_IDLE) == 0))|| /* and event not idle-able? */
|
((sim_clock_queue->flags & UNIT_IDLE) == 0))|| /* and event not idle-able? */
|
||||||
(rtc->elapsed < sim_idle_stable)) { /* or calibrated timer not stable? */
|
(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" :
|
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" :
|
((rtc->elapsed < sim_idle_stable) ? "not stable" :
|
||||||
((sim_clock_queue != QUEUE_LIST_END) ? sim_uname (sim_clock_queue) :
|
((sim_clock_queue != QUEUE_LIST_END) ? sim_uname (sim_clock_queue) :
|
||||||
"")), rtc->elapsed, rtc->ticks, rtc->hz);
|
"")), rtc->elapsed, rtc->ticks, rtc->hz);
|
||||||
sim_interval -= sin_cyc;
|
sim_interval -= sin_cyc;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
When a simulator is in an instruction path (or under other conditions
|
When a simulator is in an instruction path (or under other conditions
|
||||||
which would indicate idling), the countdown of sim_interval may not
|
which would indicate idling), the countdown of sim_interval may not
|
||||||
be happening at a pace which is consistent with the rate it happens
|
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
|
when not in the 'idle capable' state. The consequence of this is that
|
||||||
the clock calibration may produce calibrated results which vary much
|
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
|
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
|
the calibrated tick size to approximate an adjustment to sim_interval
|
||||||
to reflect the number of instructions which would have executed during
|
to reflect the number of instructions which would have executed during
|
||||||
the actual idle time, so consistent calibrated numbers produce better
|
the actual idle time, so consistent calibrated numbers produce better
|
||||||
adjustments.
|
adjustments.
|
||||||
|
|
||||||
To negate this effect, we accumulate the time actually idled here.
|
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
|
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.
|
didn't idle too much.
|
||||||
|
|
||||||
we also check check sim_idle_enab above so that all simulators can avoid
|
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
|
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
|
the bookkeeping on sim_idle_idled is done here in sim_timer where it
|
||||||
means something, while not idling when it isn't enabled.
|
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);
|
sim_debug (DBG_TRC, &sim_timer_dev, "sim_idle(tmr=%d, sin_cyc=%d)\n", tmr, sin_cyc);
|
||||||
if (sim_idle_cyc_ms == 0) {
|
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)
|
if (cyc_since_idle > sim_idle_cyc_sleep)
|
||||||
act_cyc -= sim_idle_cyc_sleep / 2; /* account for half an interval's worth of cycles */
|
act_cyc -= sim_idle_cyc_sleep / 2; /* account for half an interval's worth of cycles */
|
||||||
else
|
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_interval = sim_interval - act_cyc; /* count down sim_interval to reflect idle period */
|
||||||
sim_idle_end_time = sim_gtime(); /* save idle completed time */
|
sim_idle_end_time = sim_gtime(); /* save idle completed time */
|
||||||
if (sim_clock_queue == QUEUE_LIST_END)
|
if (sim_clock_queue == QUEUE_LIST_END)
|
||||||
|
@ -1723,7 +1723,7 @@ else {
|
||||||
if ((*tptr != '\0') || (val == 0))
|
if ((*tptr != '\0') || (val == 0))
|
||||||
return sim_messagef (SCPE_ARG, "Invalid throttle delay specifier: %s\n", cptr);
|
return sim_messagef (SCPE_ARG, "Invalid throttle delay specifier: %s\n", cptr);
|
||||||
}
|
}
|
||||||
if (c == 'M')
|
if (c == 'M')
|
||||||
sim_throt_type = SIM_THROT_MCYC;
|
sim_throt_type = SIM_THROT_MCYC;
|
||||||
else if (c == 'K')
|
else if (c == 'K')
|
||||||
sim_throt_type = SIM_THROT_KCYC;
|
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_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;
|
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;
|
sim_throt_peak_cps = (double)rtc->hz * rtc->currd;
|
||||||
return sim_throt_svc (uptr);
|
return sim_throt_svc (uptr);
|
||||||
}
|
}
|
||||||
|
@ -1902,11 +1902,11 @@ switch (sim_throt_state) {
|
||||||
sim_set_throt (0, NULL); /* disable throttling */
|
sim_set_throt (0, NULL); /* disable throttling */
|
||||||
return SCPE_OK;
|
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);
|
(int)delta_ms, delta_inst, sim_vm_interval_units);
|
||||||
sim_throt_wait = (int32)(delta_inst * SIM_THROT_WMUL);
|
sim_throt_wait = (int32)(delta_inst * SIM_THROT_WMUL);
|
||||||
sim_throt_inst_start = sim_gtime();
|
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 ();
|
sim_throt_ms_start = sim_os_msec ();
|
||||||
}
|
}
|
||||||
else { /* long enough */
|
else { /* long enough */
|
||||||
|
@ -1920,11 +1920,11 @@ switch (sim_throt_state) {
|
||||||
d_cps = (sim_throt_peak_cps * sim_throt_val) / 100.0;
|
d_cps = (sim_throt_peak_cps * sim_throt_val) / 100.0;
|
||||||
if (d_cps >= a_cps) {
|
if (d_cps >= a_cps) {
|
||||||
/* the initial throttling calibration measures a slower cps rate than the desired cps rate, */
|
/* 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);
|
a_cps, d_cps);
|
||||||
/* if the measured rate is well below the measured peak rate? */
|
/* if the measured rate is well below the measured peak rate? */
|
||||||
if (sim_throt_peak_cps >= (2.0 * d_cps)) {
|
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. */
|
cps rate. */
|
||||||
sim_printf ("*********** WARNING ***********\n");
|
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);
|
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? */
|
if (sim_throt_wait >= SIM_THROT_WMIN) /* long enough? */
|
||||||
break;
|
break;
|
||||||
sim_throt_sleep_time += sim_os_sleep_inc_ms;
|
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_sleep_time, a_cps, d_cps, sim_throt_wait);
|
||||||
}
|
}
|
||||||
sim_throt_ms_start = sim_throt_ms_stop;
|
sim_throt_ms_start = sim_throt_ms_stop;
|
||||||
sim_throt_inst_start = sim_gtime();
|
sim_throt_inst_start = sim_gtime();
|
||||||
sim_throt_state = SIM_THROT_STATE_THROTTLE;
|
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);
|
a_cps, d_cps, sim_throt_wait, sim_throt_sleep_time);
|
||||||
sim_throt_cps = d_cps; /* save the desired rate */
|
sim_throt_cps = d_cps; /* save the desired rate */
|
||||||
_sim_timer_adjust_cal(); /* adjust timer calibrations */
|
_sim_timer_adjust_cal(); /* adjust timer calibrations */
|
||||||
|
@ -1982,11 +1982,11 @@ switch (sim_throt_state) {
|
||||||
else
|
else
|
||||||
d_cps = (sim_throt_peak_cps * sim_throt_val) / 100.0;
|
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) {
|
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));
|
a_cps, d_cps, fabs(100.0 * (d_cps - a_cps) / d_cps));
|
||||||
if ((a_cps > d_cps) && /* too fast? */
|
if ((a_cps > d_cps) && /* too fast? */
|
||||||
((100.0 * (a_cps - d_cps) / d_cps) > (100 - sim_throt_drift_pct))) {
|
((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));
|
a_cps, d_cps, fabs(100.0 * (d_cps - a_cps) / d_cps));
|
||||||
while (1) {
|
while (1) {
|
||||||
sim_throt_wait = (int32) /* cycles between sleeps */
|
sim_throt_wait = (int32) /* cycles between sleeps */
|
||||||
|
@ -1995,16 +1995,16 @@ switch (sim_throt_state) {
|
||||||
if (sim_throt_wait >= SIM_THROT_WMIN)/* long enough? */
|
if (sim_throt_wait >= SIM_THROT_WMIN)/* long enough? */
|
||||||
break;
|
break;
|
||||||
sim_throt_sleep_time += sim_os_sleep_inc_ms;
|
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);
|
sim_throt_sleep_time, sim_throt_peak_cps, d_cps, sim_throt_wait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* slow or within reasonable range */
|
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));
|
(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_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);
|
a_cps, d_cps, sim_throt_wait, sim_throt_sleep_time);
|
||||||
sim_throt_cps = d_cps; /* save the desired rate */
|
sim_throt_cps = d_cps; /* save the desired rate */
|
||||||
sim_throt_ms_start = sim_os_msec ();
|
sim_throt_ms_start = sim_os_msec ();
|
||||||
|
@ -2013,7 +2013,7 @@ switch (sim_throt_state) {
|
||||||
}
|
}
|
||||||
else { /* record instruction rate */
|
else { /* record instruction rate */
|
||||||
sim_throt_cps = (int32)a_cps;
|
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_wait, sim_throt_sleep_time, sim_throt_cps);
|
||||||
sim_throt_inst_start = sim_gtime();
|
sim_throt_inst_start = sim_gtime();
|
||||||
sim_throt_ms_start = sim_os_msec ();
|
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)
|
t_stat sim_timer_tick_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 tmr = (int32)(uptr-sim_timer_units);
|
int32 tmr = (int32)(uptr-sim_timer_units);
|
||||||
|
@ -2060,11 +2060,11 @@ RTC *rtc = &rtcs[tmr];
|
||||||
rtc->clock_ticks += 1;
|
rtc->clock_ticks += 1;
|
||||||
rtc->calib_tick_time += rtc->clock_tick_size;
|
rtc->calib_tick_time += rtc->clock_tick_size;
|
||||||
/*
|
/*
|
||||||
* Some devices may depend on executing during the same instruction or
|
* Some devices may depend on executing during the same instruction or
|
||||||
* immediately after the clock tick event. To satisfy this, we directly
|
* immediately after the clock tick event. To satisfy this, we directly
|
||||||
* run the clock event here and if it completes successfully, schedule any
|
* run the clock event here and if it completes successfully, schedule any
|
||||||
* currently coschedule units to run now. Ticks should never return a
|
* currently coschedule units to run now. Ticks should never return a
|
||||||
* non-success status, while co-schedule activities might, so they are
|
* non-success status, while co-schedule activities might, so they are
|
||||||
* queued to run from sim_process_event
|
* 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);
|
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 */
|
--rtc->cosched_interval; /* Countdown ticks */
|
||||||
if (rtc->clock_cosched_queue != QUEUE_LIST_END)
|
if (rtc->clock_cosched_queue != QUEUE_LIST_END)
|
||||||
rtc->clock_cosched_queue->time = rtc->cosched_interval;
|
rtc->clock_cosched_queue->time = rtc->cosched_interval;
|
||||||
if ((stat == SCPE_OK) &&
|
if ((stat == SCPE_OK) &&
|
||||||
(rtc->cosched_interval <= 0) &&
|
(rtc->cosched_interval <= 0) &&
|
||||||
(rtc->clock_cosched_queue != QUEUE_LIST_END)) {
|
(rtc->clock_cosched_queue != QUEUE_LIST_END)) {
|
||||||
UNIT *sptr = rtc->clock_cosched_queue;
|
UNIT *sptr = rtc->clock_cosched_queue;
|
||||||
|
@ -2150,7 +2150,7 @@ if (now)
|
||||||
return ts_now.tv_sec;
|
return ts_now.tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the host system has a relatively large clock tick (as compared to
|
* If the host system has a relatively large clock tick (as compared to
|
||||||
* the desired simulated hz) ticks will naturally be scheduled late and
|
* the desired simulated hz) ticks will naturally be scheduled late and
|
||||||
* these delays will accumulate. The net result will be unreasonably
|
* 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
|
* We accomodate these problems and make up for lost ticks by injecting
|
||||||
* catch-up ticks to the simulator.
|
* 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:
|
* of two conditions:
|
||||||
* 1) after indicated number of instructions in a call by the simulator
|
* 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
|
* to sim_rtcn_tick_ack. sim_rtcn_tick_ack exists to provide a
|
||||||
* mechanism to inform the simh timer facilities when the simulated
|
* mechanism to inform the simh timer facilities when the simulated
|
||||||
* system has accepted the most recent clock tick interrupt.
|
* system has accepted the most recent clock tick interrupt.
|
||||||
* 2) immediately when the simulator calls sim_idle
|
* 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.
|
* conditions after at least one tick has been acknowledged.
|
||||||
*
|
*
|
||||||
* The clock tick UNIT that will be scheduled to run for catchup ticks
|
* 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));
|
sim_debug (DBG_QUE, &sim_timer_dev, "_rtcn_tick_catchup_check() - Enabling catchup ticks for %s\n", sim_uname (rtc->clock_unit));
|
||||||
bReturn = TRUE;
|
bReturn = TRUE;
|
||||||
}
|
}
|
||||||
if ((rtc->hz > 0) &&
|
if ((rtc->hz > 0) &&
|
||||||
rtc->clock_catchup_eligible)
|
rtc->clock_catchup_eligible)
|
||||||
{
|
{
|
||||||
double tnow = sim_timenow_double();
|
double tnow = sim_timenow_double();
|
||||||
|
@ -2295,8 +2295,8 @@ _timer_thread(void *arg)
|
||||||
int sched_policy;
|
int sched_policy;
|
||||||
struct sched_param sched_priority;
|
struct sched_param sched_priority;
|
||||||
|
|
||||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||||
thread which, in general, won't be readily yielding the processor when
|
thread which, in general, won't be readily yielding the processor when
|
||||||
this thread needs to run */
|
this thread needs to run */
|
||||||
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
|
pthread_getschedparam (pthread_self(), &sched_policy, &sched_priority);
|
||||||
++sched_priority.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? */
|
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));
|
sim_uname(sim_wallclock_entry), sim_fmt_secs (sim_wallclock_entry->a_usec_delay/1000000.0));
|
||||||
|
|
||||||
uptr = sim_wallclock_entry;
|
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");
|
sim_debug (DBG_TIM, &sim_timer_dev, "_timer_thread() - waiting forever\n");
|
||||||
else
|
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));
|
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))) {
|
(0 != pthread_cond_timedwait (&sim_timer_wake, &sim_timer_lock, &due_time))) {
|
||||||
|
|
||||||
if (sim_wallclock_queue == QUEUE_LIST_END) /* queue empty? */
|
if (sim_wallclock_queue == QUEUE_LIST_END) /* queue empty? */
|
||||||
|
@ -2372,7 +2372,7 @@ while (sim_asynch_timer && sim_is_running) {
|
||||||
inst_delay = 0;
|
inst_delay = 0;
|
||||||
else
|
else
|
||||||
inst_delay = (int32)(inst_per_sec*(_timespec_to_double(&due_time)-_timespec_to_double(&stop_time)));
|
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);
|
1000.0*(_timespec_to_double (&stop_time)-_timespec_to_double (&start_time)), sim_uname(uptr), inst_delay);
|
||||||
sim_activate (uptr, inst_delay);
|
sim_activate (uptr, inst_delay);
|
||||||
}
|
}
|
||||||
|
@ -2390,17 +2390,17 @@ return NULL;
|
||||||
#endif /* defined(SIM_ASYNCH_CLOCKS) */
|
#endif /* defined(SIM_ASYNCH_CLOCKS) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In the event that there are no active calibrated clock devices,
|
In the event that there are no active calibrated clock devices,
|
||||||
no instruction rate calibration will be performed. This is more
|
no instruction rate calibration will be performed. This is more
|
||||||
likely on simpler simulators which don't have a full spectrum of
|
likely on simpler simulators which don't have a full spectrum of
|
||||||
standard devices or possibly when a clock device exists but its
|
standard devices or possibly when a clock device exists but its
|
||||||
use is optional.
|
use is optional.
|
||||||
|
|
||||||
Additonally, when a host system has a natural clock tick (
|
Additionally, when a host system has a natural clock tick (
|
||||||
or minimal sleep time) which is greater than the tick size that
|
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
|
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.
|
rate implied by the host system's minimal sleep time or 50Hz.
|
||||||
|
|
||||||
To solve this we merely run an internal clock at 100Hz.
|
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;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This routine exists to assure that there is a single reliably calibrated
|
This routine exists to assure that there is a single reliably calibrated
|
||||||
clock properly counting instruction execution relative to time. The best
|
clock properly counting instruction execution relative to time. The best
|
||||||
way to assure reliable calibration is to use a clock which ticks no
|
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
|
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
|
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
|
clock with an appropriate tick rate, an internal clock is run that meets
|
||||||
this requirement, OR when asynch clocks are enabled, the internal clock
|
this requirement, OR when asynch clocks are enabled, the internal clock
|
||||||
is always run.
|
is always run.
|
||||||
|
|
||||||
Some simulators have clocks that have dynamically programmable tick
|
Some simulators have clocks that have dynamically programmable tick
|
||||||
rates. Such a clock is only a reliable candidate to be the calibrated
|
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
|
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
|
on the fly. Generally most systems like this, under normal conditions
|
||||||
don't change their tick rates unless they're running something that is
|
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
|
these conditions this clock is removed from the potential selection as
|
||||||
"the" calibrated clock all others are relative to and if necessary, an
|
"the" calibrated clock all others are relative to and if necessary, an
|
||||||
internal calibrated clock is selected.
|
internal calibrated clock is selected.
|
||||||
|
@ -2486,7 +2486,7 @@ if (tmr == SIM_NTIMERS) { /* None found? */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((tmr == newtmr) &&
|
if ((tmr == newtmr) &&
|
||||||
(sim_calb_tmr == newtmr)) /* already set? */
|
(sim_calb_tmr == newtmr)) /* already set? */
|
||||||
return;
|
return;
|
||||||
if (sim_calb_tmr == SIM_NTIMERS) { /* was old the internal timer? */
|
if (sim_calb_tmr == SIM_NTIMERS) { /* was old the internal timer? */
|
||||||
|
@ -2567,7 +2567,7 @@ if (sim_calb_tmr == -1) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (sim_calb_tmr == SIM_NTIMERS) {
|
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_internal_timer_time, sim_vm_interval_units);
|
||||||
sim_activate (&SIM_INTERNAL_UNIT, sim_internal_timer_time);
|
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? */
|
if (sim_is_active (uptr)) /* already active? */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
if (usec_delay < 0.0) {
|
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);
|
sim_uname(uptr), usec_delay);
|
||||||
}
|
}
|
||||||
if ((sim_is_running) || (tmr <= SIM_NTIMERS))
|
if ((sim_is_running) || (tmr <= SIM_NTIMERS))
|
||||||
|
@ -2739,7 +2739,7 @@ else { /* defer non timer wallclock activat
|
||||||
uptr->usecs_remaining = usec_delay;
|
uptr->usecs_remaining = usec_delay;
|
||||||
usec_delay = 0;
|
usec_delay = 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Handle long delays by aligning with the calibrated timer's calibration
|
* Handle long delays by aligning with the calibrated timer's calibration
|
||||||
* activities. Delays which would expire prior to the next calibration
|
* activities. Delays which would expire prior to the next calibration
|
||||||
* are specifically scheduled directly based on the the current instruction
|
* 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? */
|
if (inst_delay_d > (double)inst_til_calib) { /* long wait? */
|
||||||
stat = sim_clock_coschedule_tmr (uptr, sim_calb_tmr, ticks_til_calib - 1);
|
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;
|
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_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));
|
sim_uname(uptr), usec_delay, sim_timer_activate_time_usecs (ouptr), sim_timer_activate_time_usecs (uptr));
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
@ -2781,16 +2781,16 @@ if (sim_calb_tmr != -1) {
|
||||||
|
|
||||||
stat = sim_clock_coschedule_tmr (uptr, sim_calb_tmr, 0);
|
stat = sim_clock_coschedule_tmr (uptr, sim_calb_tmr, 0);
|
||||||
uptr->usecs_remaining = (stat == SCPE_OK) ? usec_delay - usecs_til_tick : 0.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_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));
|
sim_uname(uptr), usec_delay, sim_timer_activate_time_usecs (ouptr), sim_timer_activate_time_usecs (uptr));
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* We're here to schedule if:
|
* We're here to schedule if:
|
||||||
* No Calibrated Timer, OR
|
* No Calibrated Timer, OR
|
||||||
* Scheduling the Calibrated Timer OR
|
* Scheduling the Calibrated Timer OR
|
||||||
|
@ -2798,8 +2798,8 @@ if (sim_calb_tmr != -1) {
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Bound delay to avoid overflow.
|
* Bound delay to avoid overflow.
|
||||||
* Long delays are usually canceled before they expire, however bounding the
|
* Long delays are usually canceled before they expire, however bounding the
|
||||||
* delay will cause sim_activate_time to return inconsistent results when
|
* delay will cause sim_activate_time to return inconsistent results when
|
||||||
* truncation has happened.
|
* truncation has happened.
|
||||||
*/
|
*/
|
||||||
if (inst_delay_d > (double)0x7fffffff)
|
if (inst_delay_d > (double)0x7fffffff)
|
||||||
|
@ -2823,7 +2823,7 @@ if ((sim_asynch_timer) &&
|
||||||
rtc->clock_unit->a_is_active = &_sim_wallclock_is_active;
|
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);
|
sim_uname(uptr), usec_delay, uptr->a_due_time);
|
||||||
|
|
||||||
pthread_mutex_lock (&sim_timer_lock);
|
pthread_mutex_lock (&sim_timer_lock);
|
||||||
|
@ -2836,7 +2836,7 @@ if ((sim_asynch_timer) &&
|
||||||
uptr->a_next = QUEUE_LIST_END; /* Temporarily mark as active */
|
uptr->a_next = QUEUE_LIST_END; /* Temporarily mark as active */
|
||||||
if (sim_timer_thread_running) {
|
if (sim_timer_thread_running) {
|
||||||
while (sim_wallclock_entry) { /* wait for any prior entry has been digested */
|
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));
|
sim_uname(uptr), usec_delay, sim_uname(sim_wallclock_entry));
|
||||||
pthread_mutex_unlock (&sim_timer_lock);
|
pthread_mutex_unlock (&sim_timer_lock);
|
||||||
sim_os_ms_sleep (1);
|
sim_os_ms_sleep (1);
|
||||||
|
@ -2857,9 +2857,9 @@ if ((sim_asynch_timer) &&
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
stat = _sim_activate (uptr, inst_delay); /* queue it now */
|
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_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));
|
sim_uname(uptr), usec_delay, sim_timer_activate_time_usecs (ouptr), sim_timer_activate_time_usecs (uptr));
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
@ -2900,7 +2900,7 @@ if (rtc->clock_unit == NULL)
|
||||||
rtc->clock_cosched_queue = QUEUE_LIST_END;
|
rtc->clock_cosched_queue = QUEUE_LIST_END;
|
||||||
rtc->clock_unit = uptr;
|
rtc->clock_unit = uptr;
|
||||||
uptr->dynflags |= UNIT_TMR_UNIT;
|
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);
|
(rtc->clock_unit ? UNIT_IDLE : 0);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -3213,7 +3213,7 @@ for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
|
||||||
return _sim_activate_time (&sim_timer_units[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)
|
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 ();
|
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);
|
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
|
/* read only memory delayed support
|
||||||
|
@ -3314,10 +3314,10 @@ return result; /* Not found. */
|
||||||
time to meet timing assumptions in the code being executed.
|
time to meet timing assumptions in the code being executed.
|
||||||
|
|
||||||
The default calibration determines a way to limit activities
|
The default calibration determines a way to limit activities
|
||||||
to 1Mhz for each call to sim_rom_read_with_delay(). If a
|
to 1Mhz for each call to sim_rom_read_with_delay(). If a
|
||||||
simulator needs a different delay factor, the 1 Mhz initial
|
simulator needs a different delay factor, the 1 MHz initial
|
||||||
value can be queried with sim_get_rom_delay_factor() and the
|
value can be queried with sim_get_rom_delay_factor() and the
|
||||||
result can be adjusted as nessary and the operating delay
|
result can be adjusted as necessary and the operating delay
|
||||||
can be set with sim_set_rom_delay_factor().
|
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)
|
SIM_NOINLINE uint32 sim_get_rom_delay_factor (void)
|
||||||
{
|
{
|
||||||
/* Calibrate the loop delay factor at startup.
|
/* 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
|
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
|
a 6 byte delay loop running from ROM address space to execute
|
||||||
1 instruction per usec */
|
1 instruction per usec */
|
||||||
|
@ -3361,7 +3361,7 @@ if (sim_rom_delay == 0) {
|
||||||
|
|
||||||
for (i = 0; i < c; i++)
|
for (i = 0; i < c; i++)
|
||||||
rom_loopval |= (rom_loopval + ts) ^ _rom_swapb (_rom_swapb (rom_loopval + ts));
|
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? */
|
if ((te - ts) < 50) /* sample big enough? */
|
||||||
continue;
|
continue;
|
||||||
if (sim_rom_delay < (rom_loopval + (c / (te - ts) / 1000) + 1))
|
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
|
* 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.
|
* 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
|
* 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.
|
* seconds that normal clock calibration takes.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -3434,7 +3434,7 @@ sim_inst_per_sec_last = sim_precalibrate_ips;
|
||||||
sim_idle_stable = 0;
|
sim_idle_stable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
sim_host_speed_factor (void)
|
sim_host_speed_factor (void)
|
||||||
{
|
{
|
||||||
if (sim_precalibrate_ips > sim_vm_initial_ips)
|
if (sim_precalibrate_ips > sim_vm_initial_ips)
|
||||||
|
|
504
sim_tmxr.c
504
sim_tmxr.c
File diff suppressed because it is too large
Load diff
|
@ -26,7 +26,7 @@
|
||||||
Based on the original DZ11 simulator by Thord Nilson, as updated by
|
Based on the original DZ11 simulator by Thord Nilson, as updated by
|
||||||
Arthur Krewat.
|
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
|
listener and outgoing connections
|
||||||
17-Jan-11 MP Added buffered line capabilities
|
17-Jan-11 MP Added buffered line capabilities
|
||||||
20-Nov-08 RMS Added three new standardized SHOW routines
|
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 */
|
#define TMUF_NOASYNCH (1u << TMUF_V_NOASYNCH) /* This flag can be defined */
|
||||||
/* statically in a unit's flag field */
|
/* statically in a unit's flag field */
|
||||||
/* This will disable the unit from */
|
/* This will disable the unit from */
|
||||||
/* supporting asynchronmous mux behaviors */
|
/* supporting asynchronous mux behaviors */
|
||||||
/* Receive line speed limits */
|
/* Receive line speed limits */
|
||||||
|
|
||||||
#define TMLN_SPD_50_BPS 200000 /* usec per character */
|
#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 */
|
#define TMLN_SPD_115200_BPS 86 /* usec per character */
|
||||||
|
|
||||||
/* Internal struct */
|
/* Internal struct */
|
||||||
struct framer_data;
|
struct framer_data;
|
||||||
|
|
||||||
typedef struct tmln TMLN;
|
typedef struct tmln TMLN;
|
||||||
typedef struct tmxr TMXR;
|
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_abs tmxr_activate_abs
|
||||||
#define sim_activate_after tmxr_activate_after
|
#define sim_activate_after tmxr_activate_after
|
||||||
#define sim_activate_after_abs tmxr_activate_after_abs
|
#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_abs tmxr_clock_coschedule_abs
|
||||||
#define sim_clock_coschedule_tmr tmxr_clock_coschedule_tmr
|
#define sim_clock_coschedule_tmr tmxr_clock_coschedule_tmr
|
||||||
#define sim_clock_coschedule_tmr_abs tmxr_clock_coschedule_tmr_abs
|
#define sim_clock_coschedule_tmr_abs tmxr_clock_coschedule_tmr_abs
|
||||||
|
|
94
sim_video.c
94
sim_video.c
|
@ -104,20 +104,20 @@ char vid_release_key[64] = "Ctrl-Right-Shift";
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_thread.h>
|
#include <SDL_thread.h>
|
||||||
|
|
||||||
static const char *key_names[] =
|
static const char *key_names[] =
|
||||||
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
|
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
|
||||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
|
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
|
||||||
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
|
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
|
||||||
"U", "V", "W", "X", "Y", "Z",
|
"U", "V", "W", "X", "Y", "Z",
|
||||||
"BACKQUOTE", "MINUS", "EQUALS", "LEFT_BRACKET", "RIGHT_BRACKET",
|
"BACKQUOTE", "MINUS", "EQUALS", "LEFT_BRACKET", "RIGHT_BRACKET",
|
||||||
"SEMICOLON", "SINGLE_QUOTE", "BACKSLASH", "LEFT_BACKSLASH", "COMMA",
|
"SEMICOLON", "SINGLE_QUOTE", "BACKSLASH", "LEFT_BACKSLASH", "COMMA",
|
||||||
"PERIOD", "SLASH", "PRINT", "SCRL_LOCK", "PAUSE", "ESC", "BACKSPACE",
|
"PERIOD", "SLASH", "PRINT", "SCRL_LOCK", "PAUSE", "ESC", "BACKSPACE",
|
||||||
"TAB", "ENTER", "SPACE", "INSERT", "DELETE", "HOME", "END", "PAGE_UP",
|
"TAB", "ENTER", "SPACE", "INSERT", "DELETE", "HOME", "END", "PAGE_UP",
|
||||||
"PAGE_DOWN", "UP", "DOWN", "LEFT", "RIGHT", "CAPS_LOCK", "NUM_LOCK",
|
"PAGE_DOWN", "UP", "DOWN", "LEFT", "RIGHT", "CAPS_LOCK", "NUM_LOCK",
|
||||||
"ALT_L", "ALT_R", "CTRL_L", "CTRL_R", "SHIFT_L", "SHIFT_R",
|
"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",
|
"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_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"
|
"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
|
#define amask 0xFF000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* libpng callbacks */
|
/* libpng callbacks */
|
||||||
static void png_error_SDL(png_structp ctx, png_const_charp str)
|
static void png_error_SDL(png_structp ctx, png_const_charp str)
|
||||||
{
|
{
|
||||||
SDL_SetError("libpng: %s\n", 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);
|
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_Surface *surf;
|
||||||
SDL_Rect rect = { 0 };
|
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) {
|
if (src->format->BitsPerPixel <= 24 || src->format->Amask) {
|
||||||
src->refcount++;
|
src->refcount++;
|
||||||
return src;
|
return src;
|
||||||
|
@ -202,7 +202,7 @@ static SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src)
|
||||||
return surf;
|
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_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
|
@ -225,7 +225,7 @@ static int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||||
return (ERROR);
|
return (ERROR);
|
||||||
}
|
}
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_SDL, NULL); /* err_ptr, err_fn, warn_fn */
|
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);
|
SDL_SetError("Unable to png_create_write_struct on %s\n", PNG_LIBPNG_VER_STRING);
|
||||||
if (freedst) SDL_RWclose(dst);
|
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) */
|
#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.
|
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:
|
which does:
|
||||||
|
|
||||||
#defines main SDL_main
|
#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
|
application's SDL_main in a separate thread, and while that thread
|
||||||
is running, the main thread performs event handling and dispatch.
|
is running, the main thread performs event handling and dispatch.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define EVENT_REDRAW 1 /* redraw event for SDL */
|
#define EVENT_REDRAW 1 /* redraw event for SDL */
|
||||||
|
@ -641,7 +641,7 @@ int i, n;
|
||||||
if (vid_gamepad_inited++)
|
if (vid_gamepad_inited++)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Chech that the SDL_GameControllerFromInstanceID function is
|
/* Check that the SDL_GameControllerFromInstanceID function is
|
||||||
available at run time. */
|
available at run time. */
|
||||||
SDL_GetVersion(&ver);
|
SDL_GetVersion(&ver);
|
||||||
vid_gamepad_ok = (ver.major > 2 ||
|
vid_gamepad_ok = (ver.major > 2 ||
|
||||||
|
@ -999,7 +999,7 @@ if (vptr->vid_flags & SIM_VID_INPUTCAPTURED)
|
||||||
|
|
||||||
if ((x_delta) || (y_delta)) {
|
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);
|
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. */
|
positions adjusted since they were queued based on different info. */
|
||||||
if (SDL_SemWait (vid_mouse_events.sem) == 0) {
|
if (SDL_SemWait (vid_mouse_events.sem) == 0) {
|
||||||
int32 i;
|
int32 i;
|
||||||
|
@ -1452,9 +1452,9 @@ if (vptr->vid_mouse_captured) {
|
||||||
|
|
||||||
if (!KeyStates)
|
if (!KeyStates)
|
||||||
KeyStates = SDL_GetKeyboardState(&numkeys);
|
KeyStates = SDL_GetKeyboardState(&numkeys);
|
||||||
if ((vptr->vid_flags & SIM_VID_INPUTCAPTURED) &&
|
if ((vptr->vid_flags & SIM_VID_INPUTCAPTURED) &&
|
||||||
(event->state == SDL_PRESSED) &&
|
(event->state == SDL_PRESSED) &&
|
||||||
KeyStates[SDL_SCANCODE_RSHIFT] &&
|
KeyStates[SDL_SCANCODE_RSHIFT] &&
|
||||||
(KeyStates[SDL_SCANCODE_LCTRL] || KeyStates[SDL_SCANCODE_RCTRL])) {
|
(KeyStates[SDL_SCANCODE_LCTRL] || KeyStates[SDL_SCANCODE_RCTRL])) {
|
||||||
sim_debug (SIM_VID_DBG_KEY, vptr->vid_dev, "vid_key() - Cursor Release\n");
|
sim_debug (SIM_VID_DBG_KEY, vptr->vid_dev, "vid_key() - Cursor Release\n");
|
||||||
if (SDL_SetRelativeMouseMode(SDL_FALSE) < 0) /* release cursor, show cursor */
|
if (SDL_SetRelativeMouseMode(SDL_FALSE) < 0) /* release cursor, show cursor */
|
||||||
|
@ -1512,7 +1512,7 @@ if (!sim_is_running)
|
||||||
return;
|
return;
|
||||||
if (!vptr->vid_cursor_visible)
|
if (!vptr->vid_cursor_visible)
|
||||||
return;
|
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);
|
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)) {
|
while (SDL_PeepEvents (&dummy_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION)) {
|
||||||
/* Coalesce motion activity to avoid thrashing */
|
/* 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->x = dev->x;
|
||||||
event->y = dev->y;
|
event->y = dev->y;
|
||||||
event->state = dev->state;
|
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);
|
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) {
|
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_b1 = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE;
|
||||||
vid_mouse_b2 = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 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;
|
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);
|
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) {
|
if (vid_mouse_events.count < MAX_EVENTS) {
|
||||||
SIM_MOUSE_EVENT *tail = &vid_mouse_events.events[(vid_mouse_events.tail+MAX_EVENTS-1)%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;
|
ev.y_pos = event->y;
|
||||||
if ((vid_mouse_events.count > 0) && /* Is there a tail event? */
|
if ((vid_mouse_events.count > 0) && /* Is there a tail event? */
|
||||||
(ev.b1_state == tail->b1_state) && /* With the same button state? */
|
(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 */
|
(ev.b3_state == tail->b3_state)) { /* Merge the motion */
|
||||||
tail->x_rel += ev.x_rel;
|
tail->x_rel += ev.x_rel;
|
||||||
tail->y_rel += ev.y_rel;
|
tail->y_rel += ev.y_rel;
|
||||||
tail->x_pos = ev.x_pos;
|
tail->x_pos = ev.x_pos;
|
||||||
tail->y_pos = ev.y_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);
|
tail->x_rel, tail->y_rel);
|
||||||
}
|
}
|
||||||
else { /* Add a new event */
|
else { /* Add a new event */
|
||||||
|
@ -1757,7 +1757,7 @@ void vid_update_cursor (VID_DISPLAY *vptr, SDL_Cursor *cursor, t_bool visible)
|
||||||
{
|
{
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
return;
|
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_ShowCursor(-1) ? "visible" : "invisible", visible ? "visible" : "invisible", cursor, vptr->vid_cursor);
|
||||||
SDL_SetCursor (cursor);
|
SDL_SetCursor (cursor);
|
||||||
if ((vptr->vid_window == SDL_GetMouseFocus ()) && visible)
|
if ((vptr->vid_window == SDL_GetMouseFocus ()) && visible)
|
||||||
|
@ -1794,7 +1794,7 @@ SDL_UnlockMutex (vptr->vid_draw_mutex);
|
||||||
|
|
||||||
if (vptr->vid_blending) {
|
if (vptr->vid_blending) {
|
||||||
SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf));
|
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
|
else
|
||||||
if (SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf)))
|
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) &&
|
if ((compiled.major == running.major) &&
|
||||||
(compiled.minor == running.minor) &&
|
(compiled.minor == running.minor) &&
|
||||||
(compiled.patch == running.patch))
|
(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);
|
compiled.major, compiled.minor, compiled.patch);
|
||||||
else
|
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,
|
compiled.major, compiled.minor, compiled.patch,
|
||||||
running.major, running.minor, running.patch);
|
running.major, running.minor, running.patch);
|
||||||
#if defined (HAVE_LIBPNG)
|
#if defined (HAVE_LIBPNG)
|
||||||
|
@ -2293,19 +2293,19 @@ if (1) {
|
||||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
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)))
|
if (strcmp (PNG_LIBPNG_VER_STRING, png_get_libpng_ver (png)))
|
||||||
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
|
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
|
||||||
", PNG Version (Compiled: %s, Runtime: %s)",
|
", PNG Version (Compiled: %s, Runtime: %s)",
|
||||||
PNG_LIBPNG_VER_STRING, png_get_libpng_ver (png));
|
PNG_LIBPNG_VER_STRING, png_get_libpng_ver (png));
|
||||||
else
|
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 Version %s", PNG_LIBPNG_VER_STRING);
|
||||||
png_destroy_read_struct(&png, NULL, NULL);
|
png_destroy_read_struct(&png, NULL, NULL);
|
||||||
#if defined (ZLIB_VERSION)
|
#if defined (ZLIB_VERSION)
|
||||||
if (strcmp (ZLIB_VERSION, zlibVersion ()))
|
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 ());
|
", zlib: (Compiled: %s, Runtime: %s)", ZLIB_VERSION, zlibVersion ());
|
||||||
else
|
else
|
||||||
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
|
snprintf(&SDLVersion[strlen (SDLVersion)], sizeof (SDLVersion) - (strlen (SDLVersion) + 1),
|
||||||
", zlib: %s", ZLIB_VERSION);
|
", zlib: %s", ZLIB_VERSION);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2654,7 +2654,7 @@ char *extension = strrchr ((char *)_screenshot_filename, '.');
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
_screenshot_stat = SCPE_NXM;
|
_screenshot_stat = SCPE_NXM;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (extension)
|
if (extension)
|
||||||
n = extension - _screenshot_filename;
|
n = extension - _screenshot_filename;
|
||||||
else {
|
else {
|
||||||
|
@ -2778,7 +2778,7 @@ while (SDL_PushEvent (&user_event) < 0)
|
||||||
#else
|
#else
|
||||||
vid_beep_event ();
|
vid_beep_event ();
|
||||||
#endif
|
#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)) */
|
#else /* !(defined(USE_SIM_VIDEO) && defined(HAVE_LIBSDL)) */
|
||||||
|
|
Loading…
Add table
Reference in a new issue