mirror of
https://github.com/open-simh/simh.git
synced 2026-01-26 20:23:09 +00:00
CMake: Make generate.py reusable
Make generate.py resuable outside of open-simh, as suggested and
motivated by Richard Cornwell's simulator repository.
- Make the "experimental" rule optional. Do not generate a Python
"KeyError" if the rule is missing.
- Add documentation on how to use the CMake infrastructure outside
of open-simh: Customize the packaging.py script, season to taste.
- Update the KA10 simulator customization, moving it to its own
Python script, simgen/pdp10_simulator.py. Preparatory move that
anticipates additional frontpanel and display options.
- generate.py option "--skip-orphans": Skip the orphaned simulator
check (i.e., don't cross-reference the simulators in packaging.py
with what was scraped from the makefile.)
- Add "TEST_ARGS" argument to CMake's add_simulator function so that the
IBM 1130 simulator can pass to "-g" on the command line to disable the
GUI when running RegisterSanityCheck, i.e.:
ibm1130 RegisterSanityCheck -g
This fixes an edge case Heisenbug encountered during Github CI/CD
tests where ibm1130 appears to hang indefinitely on the Windows
runners.
The cause is the GUI's Pump() thread function being prematurely
terminated before all GUI resources are acquired. The net result is an
infinite loop in the MS C runtime trying to exit the process with
unstable internal state. (Separate patch: synchronization across main
and Pump() threads to ensure resource acquisition completes.)
This issue never shows up on non-Windows platforms or the SIMH makefile.
- cmake/generator.py, cmake/simgen: Add a "test_args" keyword argument
to the BasicSimulator constructor that holds the tests argument
parameter emitted as the "TEST_ARGS" argument to a simulator's
add_simulator(). Ensure that the IBM 1130 emits 'TEST_ARG "-g"' in its
add_simulator().
- scp.c: reset_all_p() adds 'P' to the existing switches, versus saving
sim_switches and ONLY setting the 'P' power-up reset switch. Net effect
is that the IBM 1130 simulator actually sees the 'G' flag that inhibits
the GUI during the console device reset.
This commit is contained in:
committed by
Paul Koning
parent
24f145ad16
commit
191b2131e9
@@ -7,8 +7,9 @@ import simgen.packaging as SPKG
|
||||
class SIMHBasicSimulator:
|
||||
"""
|
||||
"""
|
||||
def __init__(self, sim_name, dir_macro, test_name, buildrom):
|
||||
def __init__(self, sim_name, dir_macro, test_name, buildrom, test_args=None):
|
||||
self.sim_name = sim_name
|
||||
## self.dir_macro -> Directory macro (e.g., "${PDP11D}" for source
|
||||
self.dir_macro = dir_macro
|
||||
self.test_name = test_name
|
||||
self.int64 = False
|
||||
@@ -22,6 +23,11 @@ class SIMHBasicSimulator:
|
||||
self.besm6_sdl_hack = False
|
||||
## self.uses_aio -> True if the simulator uses AIO
|
||||
self.uses_aio = False
|
||||
## self.test_args -> Simulator flags to pass to the test phase. Used by ibm1130 to
|
||||
## pass "-g" to disable to the GUI. This argument can be a single
|
||||
## string or a list.
|
||||
self.test_args = test_args
|
||||
|
||||
self.sources = []
|
||||
self.defines = []
|
||||
self.includes = []
|
||||
@@ -128,6 +134,13 @@ class SIMHBasicSimulator:
|
||||
stream.write('\n' + indent4 + "BESM6_SDL_HACK")
|
||||
if self.uses_aio:
|
||||
stream.write('\n' + indent4 + "USES_AIO")
|
||||
if self.test_args:
|
||||
out_args = self.test_args
|
||||
if isinstance(self.test_args, str):
|
||||
out_args = self.test_args.split()
|
||||
|
||||
out_args = ' '.join('"{0}"'.format(w) for w in out_args)
|
||||
stream.write('\n' + indent4 + 'TEST_ARGS {}'.format(out_args))
|
||||
if self.buildrom:
|
||||
stream.write('\n' + indent4 + "BUILDROMS")
|
||||
stream.write('\n' + indent4 + "LABEL " + test_label)
|
||||
@@ -250,22 +263,6 @@ class BESM6Simulator(SIMHBasicSimulator):
|
||||
'unset(cand_fonts)',
|
||||
'unset(cand_fontdirs)\n']))
|
||||
|
||||
class KA10Simulator(SIMHBasicSimulator):
|
||||
def __init__(self, sim_name, dir_macro, test_name, buildrom):
|
||||
super().__init__(sim_name, dir_macro, test_name, buildrom)
|
||||
|
||||
def write_simulator(self, stream, indent, test_label='ka10'):
|
||||
super().write_simulator(stream, indent, test_label)
|
||||
stream.write('\n')
|
||||
stream.write('\n'.join([
|
||||
'if (PANDA_LIGHTS)',
|
||||
' target_sources({0} PUBLIC {1}/ka10_lights.c)'.format(self.sim_name, self.dir_macro),
|
||||
' target_compile_definitions({0} PUBLIC PANDA_LIGHTS)'.format(self.sim_name),
|
||||
' target_link_libraries({0} PUBLIC usb-1.0)'.format(self.sim_name),
|
||||
'endif (PANDA_LIGHTS)'
|
||||
]))
|
||||
stream.write('\n')
|
||||
|
||||
class IBM650Simulator(SIMHBasicSimulator):
|
||||
'''The IBM650 simulator creates relatively deep stacks, which will fail on Windows.
|
||||
Adjust target simulator link flags to provide a 8M stack, similar to Linux.
|
||||
@@ -293,25 +290,6 @@ class IBM650Simulator(SIMHBasicSimulator):
|
||||
'endif()'
|
||||
]))
|
||||
|
||||
class IBM1130Simulator(SIMHBasicSimulator):
|
||||
'''The IBM650 simulator creates relatively deep stacks, which will fail on Windows.
|
||||
Adjust target simulator link flags to provide a 8M stack, similar to Linux.
|
||||
'''
|
||||
def __init__(self, sim_name, dir_macro, test_name, buildrom):
|
||||
super().__init__(sim_name, dir_macro, test_name, buildrom)
|
||||
|
||||
def write_simulator(self, stream, indent, test_label='ibm650'):
|
||||
super().write_simulator(stream, indent, test_label)
|
||||
stream.write('\n'.join([
|
||||
'',
|
||||
'if (WIN32)',
|
||||
' target_compile_definitions(ibm1130 PRIVATE GUI_SUPPORT)',
|
||||
' ## missing source in IBM1130?'
|
||||
' ## target_sources(ibm1130 PRIVATE ibm1130.c)',
|
||||
'endif()'
|
||||
]))
|
||||
|
||||
|
||||
if '_dispatch' in pprint.PrettyPrinter.__dict__:
|
||||
def sim_pprinter(pprinter, sim, stream, indent, allowance, context, level):
|
||||
cls = sim.__class__
|
||||
|
||||
30
cmake/simgen/ibm1130_simulator.py
Normal file
30
cmake/simgen/ibm1130_simulator.py
Normal file
@@ -0,0 +1,30 @@
|
||||
## IBM 1130 simulator customizations:
|
||||
##
|
||||
## - Add the Win32 resource file for Windows builds
|
||||
## - Add the "-g" test flag to bypass/disable the simulator GUI when
|
||||
## running RegisterSanityCheck test.
|
||||
import simgen.basic_simulator as SBS
|
||||
|
||||
class IBM1130Simulator(SBS.SIMHBasicSimulator):
|
||||
'''The IBM650 simulator creates relatively deep stacks, which will fail on Windows.
|
||||
Adjust target simulator link flags to provide a 8M stack, similar to Linux.
|
||||
'''
|
||||
def __init__(self, sim_name, dir_macro, test_name, buildrom):
|
||||
super().__init__(sim_name, dir_macro, test_name, buildrom, test_args="-g")
|
||||
|
||||
def write_simulator(self, stream, indent, test_label='ibm650'):
|
||||
super().write_simulator(stream, indent, test_label)
|
||||
stream.write('\n'.join([
|
||||
'',
|
||||
'if (WIN32)',
|
||||
' ## Add GUI support, compile in resources:',
|
||||
' target_compile_definitions(ibm1130 PRIVATE GUI_SUPPORT)',
|
||||
' target_sources(ibm1130 PRIVATE ibm1130.rc)',
|
||||
'endif()',
|
||||
'',
|
||||
'# IBM 1130 utilities:',
|
||||
'# add_subdirectory(utils)',
|
||||
''
|
||||
]))
|
||||
|
||||
|
||||
@@ -30,16 +30,18 @@ class PkgFamily:
|
||||
pkg_description += '.'
|
||||
sims = []
|
||||
for sim, pkg in package_info.items():
|
||||
if pkg.family is self:
|
||||
if pkg.family is self and pkg.was_processed():
|
||||
sims.append(sim)
|
||||
sims.sort()
|
||||
pkg_description += " Simulators: " + ', '.join(sims)
|
||||
indent0 = ' ' * indent
|
||||
indent4 = ' ' * (indent + 4)
|
||||
stream.write(indent0 + "cpack_add_component(" + self.component_name + "\n")
|
||||
stream.write(indent4 + "DISPLAY_NAME \"" + self.display_name + "\"\n")
|
||||
stream.write(indent4 + "DESCRIPTION \"" + pkg_description + "\"\n")
|
||||
stream.write(indent0 + ")\n")
|
||||
|
||||
if len(sims) > 0:
|
||||
sims.sort()
|
||||
pkg_description += " Simulators: " + ', '.join(sims)
|
||||
indent0 = ' ' * indent
|
||||
indent4 = ' ' * (indent + 4)
|
||||
stream.write(indent0 + "cpack_add_component(" + self.component_name + "\n")
|
||||
stream.write(indent4 + "DISPLAY_NAME \"" + self.display_name + "\"\n")
|
||||
stream.write(indent4 + "DESCRIPTION \"" + pkg_description + "\"\n")
|
||||
stream.write(indent0 + ")\n")
|
||||
|
||||
def __lt__(self, obj):
|
||||
return self.component_name < obj.component_name
|
||||
|
||||
@@ -13,9 +13,10 @@ _variable_rx = re.compile(r"\s*([A-Za-z][\w_-]+)\s*=\s*(.*)")
|
||||
_rule_rx = re.compile(r"(((\$[({])*\w[\w_-]+[)}]*)+)\s*:\s*(.*)")
|
||||
|
||||
# Regex that recognizes variables. Group 1 is the variable's name.
|
||||
_var_rx = re.compile(r"^\$[{(]([A-Za-z][\w_-]*)[)}]$")
|
||||
_var_rx2 = re.compile(r"\$[{(]([A-Za-z][\w_-]*)[)}]")
|
||||
_norm_var_rx = re.compile(r"\$\(([A-Za-z][\w_-]*)\)")
|
||||
_var_pattern = r"[A-Za-z][\w_-]*"
|
||||
_var_rx = re.compile(r"^\$[{(](" + _var_pattern + r")[)}]$")
|
||||
_var_rx2 = re.compile(r"\$[{(](" + _var_pattern + r")[)}]")
|
||||
_norm_var_rx = re.compile(r"\$[(](" + _var_pattern + r")[)]")
|
||||
|
||||
def parse_makefile(fn, g_vars=None, g_rules=None, g_actions=None):
|
||||
"""Parse a Makefile-style file.
|
||||
@@ -56,8 +57,15 @@ def parse_makefile(fn, g_vars=None, g_rules=None, g_actions=None):
|
||||
|
||||
line = fp.readline()
|
||||
elif rmatch:
|
||||
## make allows "$(VAR)" and "${VAR}" to be used interchangably, so there's a
|
||||
## possibility that the sim developer used both forms in the target, e.g.:
|
||||
##
|
||||
## foosim: $(BIN)foosim$(EXE)
|
||||
##
|
||||
## ${BIN}foosim${EXE}: stuff that foosim depends on...
|
||||
|
||||
n, v = rmatch.group(1, 4)
|
||||
rules[n] = v
|
||||
rules[normalize_variables(n)] = normalize_variables(v)
|
||||
|
||||
## Collect the actions:
|
||||
collected = []
|
||||
|
||||
45
cmake/simgen/pdp10_simulator.py
Normal file
45
cmake/simgen/pdp10_simulator.py
Normal file
@@ -0,0 +1,45 @@
|
||||
## KA10 simulator: Add the PANDA_LIGHTS and the PIDP10 options for frontpanel
|
||||
## code.
|
||||
|
||||
import simgen.basic_simulator as SBS
|
||||
|
||||
class KA10Simulator(SBS.SIMHBasicSimulator):
|
||||
def __init__(self, sim_name, dir_macro, test_name, buildrom):
|
||||
super().__init__(sim_name, dir_macro, test_name, buildrom)
|
||||
|
||||
def write_simulator(self, stream, indent, test_label='ka10'):
|
||||
## Keep the CMake options separate, just in case they are needed for more
|
||||
## than just the KA10 (and add a class variable so they are only written
|
||||
## once.)
|
||||
stream.write('''
|
||||
option(PANDA_LIGHTS
|
||||
"Enable (=1)/disable (=0) KA-10/KI-11 simulator\'s Panda display. (def: disabled)"
|
||||
FALSE)
|
||||
option(PIDP10
|
||||
"Enable (=1)/disable (=0) PIDP10 display options (def: disabled)"
|
||||
FALSE)
|
||||
|
||||
### Ensure that the options are mutually exclusive:
|
||||
if (PANDA_LIGHTS AND PIDP10)
|
||||
message(FATAL_ERROR "PANDA_LIGHTS and PIDP10 options are mutually exclusive. Choose one.")
|
||||
endif ()
|
||||
|
||||
|
||||
''')
|
||||
## Emit the simulator:
|
||||
super().write_simulator(stream, indent, test_label)
|
||||
## Update the display sources for PANDA_LIGHTS or PIDP10:
|
||||
stream.write('\n'.join([
|
||||
'',
|
||||
'if (PANDA_LIGHTS)',
|
||||
' target_sources({0} PUBLIC {1}/kx10_lights.c)'.format(self.sim_name, self.dir_macro),
|
||||
' target_compile_definitions({0} PUBLIC PANDA_LIGHTS)'.format(self.sim_name),
|
||||
' target_link_libraries({0} PUBLIC usb-1.0)'.format(self.sim_name),
|
||||
'endif ()',
|
||||
'if (PIDP10)',
|
||||
' target_sources({0} PUBLIC {1}/ka10_pipanel.c)'.format(self.sim_name, self.dir_macro),
|
||||
' target_compile_definitions({0} PUBLIC PIDP10=1)'.format(self.sim_name),
|
||||
'endif ()'
|
||||
]))
|
||||
stream.write('\n')
|
||||
|
||||
@@ -2,6 +2,8 @@ import pprint
|
||||
|
||||
import simgen.parse_makefile as SPM
|
||||
import simgen.basic_simulator as SBS
|
||||
import simgen.ibm1130_simulator as IBM1130
|
||||
import simgen.pdp10_simulator as PDP10
|
||||
import simgen.vax_simulators as VAXen
|
||||
import simgen.utils as SU
|
||||
|
||||
@@ -16,8 +18,8 @@ _special_vars = frozenset(['DISPLAYL',
|
||||
_special_simulators = {
|
||||
"besm6": SBS.BESM6Simulator,
|
||||
"i650": SBS.IBM650Simulator,
|
||||
"ibm1130": SBS.IBM1130Simulator,
|
||||
"pdp10-ka": SBS.KA10Simulator,
|
||||
"ibm1130": IBM1130.IBM1130Simulator,
|
||||
"pdp10-ka": PDP10.KA10Simulator,
|
||||
"vax": VAXen.VAXSimulator,
|
||||
"vax730": VAXen.BasicVAXSimulator
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
"3b2"
|
||||
"3b2-700"
|
||||
"altair"
|
||||
"altairz80"
|
||||
"b5500"
|
||||
"besm6"
|
||||
"cdc1700"
|
||||
"eclipse"
|
||||
"gri"
|
||||
"h316"
|
||||
"hp2100"
|
||||
"hp3000"
|
||||
"i1401"
|
||||
"i1620"
|
||||
"i650"
|
||||
"i701"
|
||||
"i7010"
|
||||
"i704"
|
||||
"i7070"
|
||||
"i7080"
|
||||
"i7090"
|
||||
"i7094"
|
||||
"ibm1130"
|
||||
"id16"
|
||||
"id32"
|
||||
"imlac"
|
||||
"infoserver100"
|
||||
"infoserver1000"
|
||||
"infoserver150vxt"
|
||||
"intel-mds"
|
||||
"lgp"
|
||||
"microvax1"
|
||||
"microvax2"
|
||||
"microvax2000"
|
||||
"microvax3100"
|
||||
"microvax3100e"
|
||||
"microvax3100m80"
|
||||
"microvax3900"
|
||||
"nova"
|
||||
"pdp1"
|
||||
"pdp10"
|
||||
"pdp10-ka"
|
||||
"pdp10-ki"
|
||||
"pdp10-kl"
|
||||
"pdp10-ks"
|
||||
"pdp11"
|
||||
"pdp15"
|
||||
"pdp4"
|
||||
"pdp6"
|
||||
"pdp7"
|
||||
"pdp8"
|
||||
"pdp9"
|
||||
"rtvax1000"
|
||||
"s3"
|
||||
"scelbi"
|
||||
"sds"
|
||||
"sel32"
|
||||
"sigma"
|
||||
"ssem"
|
||||
"swtp6800mp-a"
|
||||
"swtp6800mp-a2"
|
||||
"tt2500"
|
||||
"tx-0"
|
||||
"uc15"
|
||||
"vax"
|
||||
"vax730"
|
||||
"vax750"
|
||||
"vax780"
|
||||
"vax8200"
|
||||
"vax8600"
|
||||
"vaxstation3100m30"
|
||||
"vaxstation3100m38"
|
||||
"vaxstation3100m76"
|
||||
"vaxstation4000m60"
|
||||
"vaxstation4000vlc"
|
||||
@@ -1,3 +1,5 @@
|
||||
## VAX simulators require extra magic -- notably, 'microvax3900${EXE}' needs
|
||||
## to be symlinked, hardlinked or copied (in that order) to 'vax${EXE}'.
|
||||
|
||||
import simgen.basic_simulator as SBS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user