mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
Start to make pymlac parts classes
This commit is contained in:
parent
5e9aa7aa02
commit
bd37a8aa4c
@ -9,6 +9,7 @@ import sys
|
||||
|
||||
from Globals import *
|
||||
import DisplayCPU
|
||||
#import Display
|
||||
import Memory
|
||||
import Ptr
|
||||
import Ptp
|
||||
@ -39,12 +40,17 @@ micro_opcodes = None
|
||||
micro_singles = None
|
||||
|
||||
# module-level state variables
|
||||
running = False
|
||||
running = False # True if CPU running
|
||||
|
||||
Display = None # reference to the Display object
|
||||
|
||||
|
||||
def init():
|
||||
def init(display):
|
||||
global running, main_decode, page_00_decode, page02_decode, micro_opcodes
|
||||
global micro_singles
|
||||
global Display
|
||||
|
||||
Display = display
|
||||
|
||||
# main dispatch dictionary for decoding opcodes in bits 1-4
|
||||
main_decode = {000: page_00, # secondary decode
|
||||
|
||||
134
pymlac/xyzzy
134
pymlac/xyzzy
@ -50,23 +50,29 @@ except ImportError:
|
||||
|
||||
|
||||
######
|
||||
# Various demo constants
|
||||
# Default things
|
||||
######
|
||||
|
||||
WindowTitleHeight = 22
|
||||
DefaultAppSize = (600, 600+WindowTitleHeight)
|
||||
|
||||
|
||||
|
||||
# map ROM name to type
|
||||
RomTypeMap = {'ptr': ROM_PTR,
|
||||
'tty': ROM_TTY,
|
||||
'none': ROM_NONE}
|
||||
|
||||
count = 1
|
||||
DefaultBootROM = 'ptr'
|
||||
DefaultCoreFile = 'pymlac.core'
|
||||
|
||||
######
|
||||
# Various demo constants
|
||||
######
|
||||
|
||||
WindowTitleHeight = 22 # FIXME probably depends on OS/GUI framework
|
||||
DefaultAppSize = (600, 600+WindowTitleHeight)
|
||||
|
||||
count = 1 # debug
|
||||
|
||||
|
||||
def abort(msg):
|
||||
"""Handle a terminal problem."""
|
||||
"""Handle a fatal problem."""
|
||||
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
@ -99,11 +105,12 @@ def get_next(options, index, msg):
|
||||
|
||||
return next_arg
|
||||
|
||||
def handle_options():
|
||||
def get_options():
|
||||
"""Routine to analyse command line options.
|
||||
|
||||
Returns a list of operation objects which are tuples:
|
||||
(OPERATION, ARGS)
|
||||
ARGS may be None or possibly another tuple.
|
||||
"""
|
||||
|
||||
options = sys.argv[1:]
|
||||
@ -240,7 +247,7 @@ def main():
|
||||
"""Start of the emulator."""
|
||||
|
||||
# get operations list
|
||||
ops = handle_options()
|
||||
ops = get_options()
|
||||
|
||||
# Initialize the emulator.
|
||||
boot_rom = 'ptr' # default ROM loader
|
||||
@ -688,7 +695,6 @@ class InterpreterThread(Thread):
|
||||
class DisplayFrame(wx.Frame):
|
||||
def __init__(self):
|
||||
wx.Frame.__init__(self, parent=None, size=DefaultAppSize)
|
||||
# title=('pymlac v%s' % Display.__version__))
|
||||
self.SetMinSize(DefaultAppSize)
|
||||
self.panel = wx.Panel(self, wx.ID_ANY)
|
||||
self.panel.ClearBackground()
|
||||
@ -719,8 +725,9 @@ class DisplayFrame(wx.Frame):
|
||||
def OnInterpreterStop(self, event):
|
||||
"""A STOP event from the interpreter."""
|
||||
|
||||
print('OnInterpreterStop: event=%s' % str(dir(event)))
|
||||
# print('OnInterpreterStop: event=%s' % str(dir(event)))
|
||||
self.running = False
|
||||
Trace.comment('Imlac halted')
|
||||
|
||||
def OnSize(self, event):
|
||||
"""Maintain square window."""
|
||||
@ -737,13 +744,17 @@ class DisplayFrame(wx.Frame):
|
||||
def run_machine(self):
|
||||
"""Run the interpreter."""
|
||||
|
||||
# get operations list
|
||||
ops = handle_options()
|
||||
|
||||
# Initialize the emulator.
|
||||
boot_rom = 'ptr' # default ROM loader
|
||||
Imlac.init(0, TRACE_FILENAME, None, None, boot_rom, CORE_FILENAME)
|
||||
# FIXME create all devices, build the Imlac machine
|
||||
self.memory = Memory.Memory(boot_rom=DefaultBootROM, corefile=DefaultCoreFile)
|
||||
self.ptr = Ptr.Ptr()
|
||||
self.ptp = Ptp.Ptp()
|
||||
self.display = Display.Display(self.memory)
|
||||
self.dcpu = DisplayCPU.DisplayCPU(self.display, self.memory)
|
||||
self.cpu = MainCPU.MainCPU(self.ptr, self.ptp,
|
||||
self.display, self.dcpu, self.memory)
|
||||
|
||||
# get and execute the operations list
|
||||
ops = get_options()
|
||||
for (operation, args) in ops:
|
||||
while self.running:
|
||||
time.sleep(1)
|
||||
@ -751,23 +762,18 @@ class DisplayFrame(wx.Frame):
|
||||
if operation == 'boot':
|
||||
Memory.set_ROM(args)
|
||||
Trace.comment('Bootstrap ROM set to %s' % args.upper())
|
||||
#self.on_paint()
|
||||
elif operation == 'clear':
|
||||
Memory.clear_core()
|
||||
Trace.comment('Core cleared')
|
||||
#self.on_paint()
|
||||
elif operation == 'load_ptp':
|
||||
Ptp.mount(args)
|
||||
Trace.comment("File '%s' mounted on PTP" % args)
|
||||
#self.on_paint()
|
||||
elif operation == 'load_ptr':
|
||||
Ptr.mount(args)
|
||||
Trace.comment("File '%s' mounted on PTR" % args)
|
||||
#self.on_paint()
|
||||
elif operation == 'data':
|
||||
MainCPU.DS = args
|
||||
Trace.comment('Dataswitch value set to %06o' % args)
|
||||
#self.on_paint()
|
||||
elif operation == 'run':
|
||||
MainCPU.PC = args
|
||||
Trace.comment('Running from address %06o' % args)
|
||||
@ -775,16 +781,10 @@ class DisplayFrame(wx.Frame):
|
||||
Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
|
||||
Trace.comment('------ ------------- ------ -------------- '
|
||||
'-----------------------')
|
||||
#self.on_paint()
|
||||
self.interpreter = InterpreterThread(self)
|
||||
self.running = True
|
||||
# Imlac.run()
|
||||
#self.on_paint()
|
||||
# Trace.comment('Imlac halted')
|
||||
#self.on_paint()
|
||||
elif operation == 'set':
|
||||
Trace.comment("Setting memory from file '%s'" % args)
|
||||
#self.on_paint()
|
||||
elif operation == 'trace':
|
||||
if args == 'off':
|
||||
Imlac.tracestart = None
|
||||
@ -800,18 +800,14 @@ class DisplayFrame(wx.Frame):
|
||||
if tend is not None:
|
||||
tend = '%06o' % tend
|
||||
Trace.comment('Trace set to (%s, %s)' % (tstart, tend))
|
||||
#self.on_paint()
|
||||
elif operation == 'ttyin':
|
||||
TtyIn.mount(args)
|
||||
Trace.comment("File '%s' mounted on TTYIN" % args)
|
||||
#self.on_paint()
|
||||
elif operation == 'ttyout':
|
||||
TtyOut.mount(args)
|
||||
Trace.comment("File '%s' mounted on TTYOUT" % args)
|
||||
#self.on_paint()
|
||||
elif operation == 'view':
|
||||
Trace.comment("Viewing memory from file '%s'" % args)
|
||||
#self.on_paint()
|
||||
elif operation == 'write':
|
||||
if args == 'on':
|
||||
Memory.using_rom = True
|
||||
@ -820,20 +816,20 @@ class DisplayFrame(wx.Frame):
|
||||
else:
|
||||
abort("Invalid view arg: %s" % args)
|
||||
Trace.comment('ROM write protect set %s' % args.upper())
|
||||
#self.on_paint()
|
||||
else:
|
||||
abort('Invalid internal operation: %s' % operation)
|
||||
|
||||
Imlac.close(CORE_FILENAME)
|
||||
|
||||
|
||||
# our own handler for uncaught exceptions
|
||||
def excepthook(type, value, tb):
|
||||
"""Handler for uncaught exceptions."""
|
||||
|
||||
msg = '\n' + '=' * 80
|
||||
msg += '\nUncaught exception:\n'
|
||||
msg += ''.join(traceback.format_exception(type, value, tb))
|
||||
msg += '=' * 80 + '\n'
|
||||
print(msg)
|
||||
log.critical(msg)
|
||||
sys.exit(1)
|
||||
|
||||
# plug our handler into the python system
|
||||
@ -843,69 +839,3 @@ sys.excepthook = excepthook
|
||||
app = wx.App()
|
||||
DisplayFrame().Show()
|
||||
app.MainLoop()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# GUI Frame class that spins off the worker thread
|
||||
class MainFrame(wx.Frame):
|
||||
"""Class MainFrame."""
|
||||
def __init__(self, parent, id):
|
||||
"""Create the MainFrame."""
|
||||
wx.Frame.__init__(self, parent, id, 'Thread Test')
|
||||
|
||||
# Dumb sample frame with two buttons
|
||||
wx.Button(self, ID_START, 'Start', pos=(0,0))
|
||||
wx.Button(self, ID_STOP, 'Stop', pos=(0,50))
|
||||
self.status = wx.StaticText(self, -1, '', pos=(0,100))
|
||||
|
||||
self.Bind(wx.EVT_BUTTON, self.OnStart, id=ID_START)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnStop, id=ID_STOP)
|
||||
|
||||
# Set up event handler for any worker thread results
|
||||
EVT_INTERPRETER(self,self.OnResult)
|
||||
|
||||
# And indicate we don't have a worker thread yet
|
||||
self.interpreter = None
|
||||
|
||||
def OnStart(self, event):
|
||||
"""Start Computation."""
|
||||
# Trigger the worker thread unless it's already busy
|
||||
if not self.interpreter:
|
||||
self.status.SetLabel('Starting computation')
|
||||
self.interpreter = InterpreterThread(self)
|
||||
|
||||
def OnStop(self, event):
|
||||
"""Stop Computation."""
|
||||
# Flag the worker thread to stop if running
|
||||
if self.interpreter:
|
||||
self.status.SetLabel('Trying to abort computation')
|
||||
self.interpreter.abort()
|
||||
|
||||
def OnResult(self, event):
|
||||
"""Show Result status."""
|
||||
if event.data is None:
|
||||
# Thread aborted (using our convention of None return)
|
||||
self.status.SetLabel('Computation aborted')
|
||||
else:
|
||||
# Process results here
|
||||
self.status.SetLabel('Computation Result: %s' % event.data)
|
||||
# In either event, the worker is done
|
||||
self.interpreter = None
|
||||
|
||||
class MainApp(wx.App):
|
||||
"""Class Main App."""
|
||||
def OnInit(self):
|
||||
"""Init Main App."""
|
||||
self.frame = MainFrame(None, -1)
|
||||
self.frame.Show(True)
|
||||
self.SetTopWindow(self.frame)
|
||||
return True
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = MainApp(0)
|
||||
app.MainLoop()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user