mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
Still moving toward running
This commit is contained in:
@@ -54,6 +54,9 @@ class _BufferedCanvas(wx.Panel):
|
||||
style wxPython style
|
||||
"""
|
||||
|
||||
print('__init__: self=%s' % str(self))
|
||||
print('__init__: parent=%s' % str(parent))
|
||||
|
||||
wx.Panel.__init__(self, parent, id, pos, size, style)
|
||||
|
||||
# Bind events
|
||||
|
||||
@@ -11,320 +11,289 @@ from Globals import *
|
||||
import Trace
|
||||
|
||||
|
||||
# display CPU constants
|
||||
MODE_NORMAL = 0
|
||||
MODE_DEIM = 1
|
||||
class DisplayCPU(object):
|
||||
|
||||
######
|
||||
# The Display CPU registers
|
||||
######
|
||||
# display CPU constants
|
||||
MODE_NORMAL = 0
|
||||
MODE_DEIM = 1
|
||||
|
||||
DPC = 0 # display CPU program counter
|
||||
DRS = [0, 0, 0, 0, 0, 0, 0, 0] # display CPU ???
|
||||
DRSindex = 0 # display CPU ???
|
||||
DIB = 0 # display CPU ???
|
||||
DX = 0 # display CPU draw X register
|
||||
DY = 0 # display CPU draw Y register
|
||||
######
|
||||
# The Display CPU registers
|
||||
######
|
||||
|
||||
# global state variables
|
||||
Mode = MODE_NORMAL
|
||||
Running = False
|
||||
|
||||
|
||||
def init():
|
||||
global Mode, Running
|
||||
DPC = 0 # display CPU program counter
|
||||
DRS = [0, 0, 0, 0, 0, 0, 0, 0] # display CPU ???
|
||||
DRSindex = 0 # display CPU ???
|
||||
DIB = 0 # display CPU ???
|
||||
DX = 0 # display CPU draw X register
|
||||
DY = 0 # display CPU draw Y register
|
||||
|
||||
# global state variables
|
||||
Mode = MODE_NORMAL
|
||||
Running = False
|
||||
|
||||
def DEIMdecode(byte):
|
||||
"""Decode a DEIM byte"""
|
||||
|
||||
result = ''
|
||||
if byte & 0x80:
|
||||
if byte & 0x40: result += 'B'
|
||||
else: result += 'D'
|
||||
if byte & 0x20: result += '-'
|
||||
result += '%d' % ((byte >> 3) & 0x03)
|
||||
if byte & 0x04: result += '-'
|
||||
result += '%d' % (byte & 0x03)
|
||||
else:
|
||||
if byte == 0111: result += 'N'
|
||||
elif byte == 0151: result += 'R'
|
||||
elif byte == 0171: result += 'F'
|
||||
elif byte == 0200: result += 'P'
|
||||
else: result += 'A%3.3o' % byte
|
||||
return result
|
||||
def __init__(self, display, memory):
|
||||
self.Mode = self.MODE_NORMAL
|
||||
self.Running = False
|
||||
|
||||
def doDEIMByte(byte):
|
||||
global DPC, DX, DY, DRSindex
|
||||
global Mode
|
||||
self.display = display
|
||||
self.memory = memory
|
||||
|
||||
if byte & 0x80: # increment?
|
||||
prevDX = DX
|
||||
prevDY = DY
|
||||
if byte & 0x20:
|
||||
DX -= (byte & 0x18) >> 3
|
||||
def DEIMdecode(self, byte):
|
||||
"""Decode a DEIM byte"""
|
||||
|
||||
result = ''
|
||||
if byte & 0x80:
|
||||
if byte & 0x40: result += 'B'
|
||||
else: result += 'D'
|
||||
if byte & 0x20: result += '-'
|
||||
result += '%d' % ((byte >> 3) & 0x03)
|
||||
if byte & 0x04: result += '-'
|
||||
result += '%d' % (byte & 0x03)
|
||||
else:
|
||||
DX += (byte & 0x18) >> 3
|
||||
if byte & 0x04:
|
||||
DY -= (byte & 0x03)
|
||||
else:
|
||||
DY += (byte & 0x03)
|
||||
if byte == 0111: result += 'N'
|
||||
elif byte == 0151: result += 'R'
|
||||
elif byte == 0171: result += 'F'
|
||||
elif byte == 0200: result += 'P'
|
||||
else: result += 'A%3.3o' % byte
|
||||
return result
|
||||
|
||||
def doDEIMByte(self, byte):
|
||||
if byte & 0x80: # increment?
|
||||
prevDX = self.DX
|
||||
prevDY = self.DY
|
||||
if byte & 0x20:
|
||||
self.DX -= (byte & 0x18) >> 3
|
||||
else:
|
||||
self.DX += (byte & 0x18) >> 3
|
||||
if byte & 0x04:
|
||||
self.DY -= (byte & 0x03)
|
||||
else:
|
||||
self.DY += (byte & 0x03)
|
||||
if byte & 0x40:
|
||||
self.display.draw(prevDX, prevDY, self.DX, self.DY)
|
||||
else: # micro instructions
|
||||
if byte & 0x40:
|
||||
display.draw(prevDX, prevDY, DX, DY)
|
||||
else: # micro instructions
|
||||
if byte & 0x40:
|
||||
Mode = MODE_NORMAL
|
||||
if byte & 0x20: # DRJM
|
||||
if DRSindex <= 0:
|
||||
Trace.comment('\nDRS stack underflow at display address %6.6o'
|
||||
% (DPC - 1))
|
||||
illegal()
|
||||
DRSindex -= 1
|
||||
DPC = DRS[DRSindex]
|
||||
if byte & 0x10:
|
||||
DX += 0x08
|
||||
if byte & 0x08:
|
||||
DX &= 0xfff8
|
||||
if byte & 0x02:
|
||||
DY += 0x10
|
||||
if byte & 0x01:
|
||||
DY &= 0xfff0
|
||||
self.Mode = self.self.MODE_NORMAL
|
||||
if byte & 0x20: # DRJM
|
||||
if self.DRSindex <= 0:
|
||||
Trace.comment('\nDRS stack underflow at display address %6.6o'
|
||||
% (self.DPC - 1))
|
||||
self.illegal()
|
||||
self.DRSindex -= 1
|
||||
self.DPC = DRS[DRSindex]
|
||||
if byte & 0x10:
|
||||
self.DX += 0x08
|
||||
if byte & 0x08:
|
||||
self.DX &= 0xfff8
|
||||
if byte & 0x02:
|
||||
self.DY += 0x10
|
||||
if byte & 0x01:
|
||||
self.DY &= 0xfff0
|
||||
|
||||
def execute_one_instruction():
|
||||
global DPC
|
||||
global Mode
|
||||
def execute_one_instruction(self):
|
||||
if not self.Running:
|
||||
Trace.dtrace('')
|
||||
return 0
|
||||
|
||||
if not Running:
|
||||
Trace.dtrace('')
|
||||
return 0
|
||||
instruction = self.memory.get(self.DPC, 0)
|
||||
self.DPC = MASK_MEM(self.DPC + 1)
|
||||
|
||||
instruction = Memory.get(DPC, 0)
|
||||
DPC = MASK_MEM(DPC + 1)
|
||||
if self.Mode == self.MODE_DEIM:
|
||||
Trace.trace(self.DEIMdecode(instruction >> 8) + '\t')
|
||||
self.doDEIMByte(instruction >> 8)
|
||||
if self.Mode == self.MODE_DEIM:
|
||||
Trace.trace(self.DEIMdecode(instruction & 0xff) + '\t')
|
||||
self.doDEIMByte(instruction & 0xff)
|
||||
else:
|
||||
Trace.trace('\t')
|
||||
return 1
|
||||
|
||||
if Mode == MODE_DEIM:
|
||||
Trace.trace(DEIMdecode(instruction >> 8) + '\t')
|
||||
doDEIMByte(instruction >> 8)
|
||||
if Mode == MODE_DEIM:
|
||||
Trace.trace(DEIMdecode(instruction & 0xff) + '\t')
|
||||
doDEIMByte(instruction & 0xff)
|
||||
opcode = instruction >> 12
|
||||
address = instruction & 007777
|
||||
|
||||
if opcode == 000: return self.page00(instruction)
|
||||
elif opcode == 001: return self.i_DLXA(address)
|
||||
elif opcode == 002: return self.i_DLYA(address)
|
||||
elif opcode == 003: return self.i_DEIM(address)
|
||||
elif opcode == 004: return self.i_DLVH(address)
|
||||
elif opcode == 005: return self.i_DJMS(address)
|
||||
elif opcode == 006: return self.i_DJMP(address)
|
||||
elif opcode == 007: self.illegal(instruction)
|
||||
else: self.illegal(instruction)
|
||||
|
||||
def illegal(self, instruction=None):
|
||||
if instruction:
|
||||
Trace.comment('Illegal display instruction (%6.6o) at address %6.6o'
|
||||
% (instruction, (self.DPC - 1)))
|
||||
else:
|
||||
Trace.trace('\t')
|
||||
Trace.comment('Illegal display instruction at address %6.6o'
|
||||
% (self.DPC - 1))
|
||||
sys.exit(0)
|
||||
|
||||
def ison(self):
|
||||
return self.Running
|
||||
|
||||
def i_DDXM(self):
|
||||
self.DX -= 040
|
||||
Trace.dtrace('DDXM')
|
||||
|
||||
def i_DDYM(self):
|
||||
self.DY -= 040
|
||||
Trace.dtrace('DDYM')
|
||||
|
||||
def i_DEIM(self, address):
|
||||
self.Mode = self.MODE_DEIM
|
||||
Trace.deimtrace('DEIM', self.DEIMdecode(address & 0377))
|
||||
self.doDEIMByte(address & 0377)
|
||||
return 1
|
||||
|
||||
opcode = instruction >> 12
|
||||
address = instruction & 007777
|
||||
def i_DHLT(self):
|
||||
self.Running = False
|
||||
Trace.dtrace('DHLT')
|
||||
|
||||
if opcode == 000: return page00(instruction)
|
||||
elif opcode == 001: return i_DLXA(address)
|
||||
elif opcode == 002: return i_DLYA(address)
|
||||
elif opcode == 003: return i_DEIM(address)
|
||||
elif opcode == 004: return i_DLVH(address)
|
||||
elif opcode == 005: return i_DJMS(address)
|
||||
elif opcode == 006: return i_DJMP(address)
|
||||
elif opcode == 007: illegal(instruction)
|
||||
else: illegal(instruction)
|
||||
def i_DHVC(self):
|
||||
Trace.dtrace('DHVC')
|
||||
|
||||
def illegal(instruction=None):
|
||||
if instruction:
|
||||
Trace.comment('Illegal display instruction (%6.6o) at address %6.6o'
|
||||
% (instruction, (DPC - 1)))
|
||||
else:
|
||||
Trace.comment('Illegal display instruction at address %6.6o'
|
||||
% (DPC - 1))
|
||||
sys.exit(0)
|
||||
def i_DIXM(self):
|
||||
self.DX += 04000
|
||||
Trace.dtrace('DIXM')
|
||||
|
||||
def ison():
|
||||
return Running
|
||||
def i_DIYM(self):
|
||||
self.DY += 04000
|
||||
Trace.dtrace('DIYM')
|
||||
|
||||
def i_DDXM():
|
||||
global DX
|
||||
def i_DJMP(self, address):
|
||||
self.DPC = MASK_MEM(address + (self.DIB << 12))
|
||||
Trace.dtrace('DJMP', address)
|
||||
return 1
|
||||
|
||||
DX -= 040
|
||||
Trace.dtrace('DDXM')
|
||||
def i_DJMS(self, address):
|
||||
if self.DRSindex >= 8:
|
||||
Trace.comment('DRS stack overflow at display address %6.6o'
|
||||
% (self.DPC - 1))
|
||||
self.illegal()
|
||||
self.DRS[self.DRSindex] = self.DPC
|
||||
self.DRSindex += 1
|
||||
self.DPC = MASK_MEM(address + (self.DIB << 12))
|
||||
Trace.dtrace('DJMS', address)
|
||||
return 1
|
||||
|
||||
def i_DDYM():
|
||||
global DY
|
||||
def i_DLXA(self, address):
|
||||
self.DX = address
|
||||
Trace.dtrace('DLXA', address)
|
||||
return 1
|
||||
|
||||
DY -= 040
|
||||
Trace.dtrace('DDYM')
|
||||
def i_DLYA(self, address):
|
||||
self.DY = address
|
||||
Trace.dtrace('DLYA', address)
|
||||
return 1
|
||||
|
||||
def i_DEIM(address):
|
||||
global Mode
|
||||
def i_DLVH(self, word1):
|
||||
word2 = self.memory.get(self, DPC, 0)
|
||||
self.DPC = MASK_MEM(self.DPC + 1)
|
||||
word3 = self.memory.get(self.DPC, 0)
|
||||
self.DPC = MASK_MEM(self.DPC + 1)
|
||||
|
||||
Mode = MODE_DEIM
|
||||
Trace.deimtrace('DEIM', DEIMdecode(address & 0377))
|
||||
doDEIMByte(address & 0377)
|
||||
return 1
|
||||
dotted = word2 & 040000
|
||||
beamon = word2 & 020000
|
||||
negx = word3 & 040000
|
||||
negy = word3 & 020000
|
||||
ygtx = word3 & 010000
|
||||
|
||||
def i_DHLT():
|
||||
Running = False
|
||||
Trace.dtrace('DHLT')
|
||||
M = word2 & 007777
|
||||
N = word3 & 007777
|
||||
|
||||
def i_DHVC():
|
||||
Trace.dtrace('DHVC')
|
||||
prevDX = self.DX
|
||||
prevDY = self.DY
|
||||
|
||||
def i_DIXM():
|
||||
global DX
|
||||
if ygtx: # M is y, N is x
|
||||
if negx:
|
||||
self.DX -= N
|
||||
else:
|
||||
self.DX += N
|
||||
if negy:
|
||||
self.DY -= M
|
||||
else:
|
||||
self.DY += M
|
||||
else: # M is x, N is y
|
||||
if negx:
|
||||
self.DX -= M
|
||||
else:
|
||||
self.DX += M
|
||||
if negy:
|
||||
self.DY -= N
|
||||
else:
|
||||
self.DY += N
|
||||
|
||||
DX += 04000
|
||||
Trace.dtrace('DIXM')
|
||||
self.display.draw(prevDX, prevDY, self.DX, self.DY, dotted)
|
||||
Trace.dtrace('DLVH')
|
||||
return 3
|
||||
|
||||
def i_DIYM():
|
||||
global DY
|
||||
def i_DRJM(self):
|
||||
if self.DRSindex <= 0:
|
||||
Trace.comment('DRS stack underflow at display address %6.6o'
|
||||
% (self.DPC - 1))
|
||||
self.illegal()
|
||||
self.DRSindex -= 1
|
||||
self.DPC = self.DRS[self.DRSindex]
|
||||
Trace.dtrace('DRJM')
|
||||
return 1 # FIXME check # cycles used
|
||||
|
||||
DY += 04000
|
||||
Trace.dtrace('DIYM')
|
||||
def i_DSTB(self, block):
|
||||
self.DIB = block
|
||||
Trace.dtrace('DSTB\t%d' % block)
|
||||
|
||||
def i_DJMP(address):
|
||||
global DPC, DIB
|
||||
|
||||
DPC = MASK_MEM(address + (DIB << 12))
|
||||
Trace.dtrace('DJMP', address)
|
||||
return 1
|
||||
|
||||
def i_DJMS(address):
|
||||
global DPC, DRSindex, DIB
|
||||
|
||||
if DRSindex >= 8:
|
||||
Trace.comment('DRS stack overflow at display address %6.6o'
|
||||
% (DPC - 1))
|
||||
illegal()
|
||||
DRS[DRSindex] = DPC
|
||||
DRSindex += 1
|
||||
DPC = MASK_MEM(address + (DIB << 12))
|
||||
Trace.dtrace('DJMS', address)
|
||||
return 1
|
||||
|
||||
def i_DLXA(address):
|
||||
global DX
|
||||
|
||||
DX = address
|
||||
Trace.dtrace('DLXA', address)
|
||||
return 1
|
||||
|
||||
def i_DLYA(address):
|
||||
global DY
|
||||
|
||||
DY = address
|
||||
Trace.dtrace('DLYA', address)
|
||||
return 1
|
||||
|
||||
def i_DLVH(word1):
|
||||
global DPC, DX, DY
|
||||
|
||||
word2 = Memory.get(DPC, 0)
|
||||
DPC = MASK_MEM(DPC + 1)
|
||||
word3 = Memory.get(DPC, 0)
|
||||
DPC = MASK_MEM(DPC + 1)
|
||||
|
||||
dotted = word2 & 040000
|
||||
beamon = word2 & 020000
|
||||
negx = word3 & 040000
|
||||
negy = word3 & 020000
|
||||
ygtx = word3 & 010000
|
||||
|
||||
M = word2 & 007777
|
||||
N = word3 & 007777
|
||||
|
||||
prevDX = DX
|
||||
prevDY = DY
|
||||
|
||||
if ygtx: # M is y, N is x
|
||||
if negx:
|
||||
DX -= N
|
||||
def i_DSTS(self, scale):
|
||||
if scale == 0:
|
||||
self.Scale = 0.5
|
||||
elif scale == 1:
|
||||
self.Scale = 1.0
|
||||
elif scale == 2:
|
||||
self.Scale = 2.0
|
||||
elif scale == 3:
|
||||
self.Scale = 3.0
|
||||
else:
|
||||
DX += N
|
||||
if negy:
|
||||
DY -= M
|
||||
self.illegal()
|
||||
Trace.dtrace('DSTS', scale)
|
||||
return 1 # FIXME check # cycles used
|
||||
|
||||
def page00(self, instruction):
|
||||
if instruction == 000000: # DHLT
|
||||
self.i_DHLT()
|
||||
elif instruction == 004000: # DNOP
|
||||
Trace.dtrace('DNOP')
|
||||
elif instruction == 004004: # DSTS 0
|
||||
self.i_DSTS(0)
|
||||
elif instruction == 004005: # DSTS 1
|
||||
self.i_DSTS(1)
|
||||
elif instruction == 004006: # DSTS 2
|
||||
self.i_DSTS(2)
|
||||
elif instruction == 004007: # DSTS 3
|
||||
self.i_DSTS(3)
|
||||
elif instruction == 004010: # DSTB 0
|
||||
self.i_DSTB(0)
|
||||
elif instruction == 004011: # DSTB 1
|
||||
self.i_DSTB(1)
|
||||
elif instruction == 004040: # DRJM
|
||||
self.i_DRJM()
|
||||
elif instruction == 004100: # DDYM
|
||||
self.i_DDYM()
|
||||
elif instruction == 004200: # DDXM
|
||||
self.i_DDXM()
|
||||
elif instruction == 004400: # DIYM
|
||||
self.i_DIYM()
|
||||
elif instruction == 005000: # DIXM
|
||||
self.i_DIXM()
|
||||
elif instruction == 006000: # DHVC
|
||||
self.i_DHVC()
|
||||
else:
|
||||
DY += M
|
||||
else: # M is x, N is y
|
||||
if negx:
|
||||
DX -= M
|
||||
else:
|
||||
DX += M
|
||||
if negy:
|
||||
DY -= N
|
||||
else:
|
||||
DY += N
|
||||
self.illegal(instruction)
|
||||
return 1
|
||||
|
||||
display.draw(prevDX, prevDY, DX, DY, dotted)
|
||||
Trace.dtrace('DLVH')
|
||||
return 3
|
||||
def start(self):
|
||||
self.Running = True
|
||||
|
||||
def i_DRJM():
|
||||
global DPC, DRSindex
|
||||
|
||||
if DRSindex <= 0:
|
||||
Trace.comment('DRS stack underflow at display address %6.6o'
|
||||
% (DPC - 1))
|
||||
illegal()
|
||||
DRSindex -= 1
|
||||
DPC = DRS[DRSindex]
|
||||
Trace.dtrace('DRJM')
|
||||
|
||||
def i_DSTB(block):
|
||||
global DIB
|
||||
|
||||
DIB = block
|
||||
Trace.dtrace('DSTB\t%d' % block)
|
||||
|
||||
def i_DSTS(scale):
|
||||
global Scale
|
||||
|
||||
if scale == 0:
|
||||
Scale = 0.5
|
||||
elif scale == 1:
|
||||
Scale = 1.0
|
||||
elif scale == 2:
|
||||
Scale = 2.0
|
||||
elif scale == 3:
|
||||
Scale = 3.0
|
||||
else:
|
||||
illegal()
|
||||
Trace.dtrace('DSTS', scale)
|
||||
|
||||
def page00(instruction):
|
||||
if instruction == 000000: # DHLT
|
||||
i_DHLT()
|
||||
elif instruction == 004000: # DNOP
|
||||
Trace.dtrace('DNOP')
|
||||
elif instruction == 004004: # DSTS 0
|
||||
i_DSTS(0)
|
||||
elif instruction == 004005: # DSTS 1
|
||||
i_DSTS(1)
|
||||
elif instruction == 004006: # DSTS 2
|
||||
i_DSTS(2)
|
||||
elif instruction == 004007: # DSTS 3
|
||||
i_DSTS(3)
|
||||
elif instruction == 004010: # DSTB 0
|
||||
i_DSTB(0)
|
||||
elif instruction == 004011: # DSTB 1
|
||||
i_DSTB(1)
|
||||
elif instruction == 004040: # DRJM
|
||||
i_DRJM()
|
||||
elif instruction == 004100: # DDYM
|
||||
i_DDYM()
|
||||
elif instruction == 004200: # DDXM
|
||||
i_DDXM()
|
||||
elif instruction == 004400: # DIYM
|
||||
i_DIYM()
|
||||
elif instruction == 005000: # DIXM
|
||||
i_DIXM()
|
||||
elif instruction == 006000: # DHVC
|
||||
i_DHVC()
|
||||
else:
|
||||
illegal(instruction)
|
||||
return 1
|
||||
|
||||
def start():
|
||||
global Running
|
||||
|
||||
Running = True
|
||||
|
||||
def stop():
|
||||
global Running
|
||||
|
||||
Running = False
|
||||
def stop(self):
|
||||
self.Running = False
|
||||
|
||||
@@ -101,7 +101,7 @@ class Memory(object):
|
||||
|
||||
if self.corefile:
|
||||
try:
|
||||
loadcore(self.corefile)
|
||||
self.loadcore(self.corefile)
|
||||
except IOError:
|
||||
self.clear_core()
|
||||
else:
|
||||
|
||||
@@ -8,16 +8,16 @@ The Imlac trace stuff.
|
||||
import time
|
||||
|
||||
from Globals import *
|
||||
import MainCPU
|
||||
import DisplayCPU
|
||||
|
||||
# module-level state variables
|
||||
tracing = False
|
||||
tracefile = None
|
||||
cpu = None
|
||||
dcpu = None
|
||||
|
||||
|
||||
def init(filename):
|
||||
global tracing, tracefile
|
||||
def init(filename, maincpu, displaycpu):
|
||||
global tracing, tracefile, cpu, dcpu
|
||||
|
||||
tracing = True
|
||||
tracefile = open(filename, 'w')
|
||||
@@ -25,6 +25,9 @@ def init(filename):
|
||||
tracing = False
|
||||
comment = None
|
||||
|
||||
cpu = maincpu
|
||||
dcpu = displaycpu
|
||||
|
||||
def close():
|
||||
import tracing, tracefile
|
||||
|
||||
@@ -58,9 +61,9 @@ def itrace(opcode, indirect=False, address=None):
|
||||
def itraceend(dispon):
|
||||
if dispon:
|
||||
trace('L=%1.1o AC=%6.6o DX=%5.5o DY=%6.6o\n' %
|
||||
(MainCPU.L, MainCPU.AC, DisplayCPU.DX, DisplayCPU.DY))
|
||||
(cpu.L, cpu.AC, dcpu.DX, dcpu.DY))
|
||||
else:
|
||||
trace('L=%1.1o AC=%6.6o\n' % (MainCPU.L, MainCPU.AC))
|
||||
trace('L=%1.1o AC=%6.6o\n' % (cpu.L, cpu.AC))
|
||||
|
||||
def comment(msg):
|
||||
tracefile.write(msg+'\n')
|
||||
|
||||
@@ -169,7 +169,7 @@ class Log(object):
|
||||
except ValueError:
|
||||
mod_name = __name__
|
||||
for (fpath, lnum, mname, _) in frames:
|
||||
(fname, _) = os.path.basename(fpath).rsplit('.', 1)
|
||||
fname = os.path.basename(fpath).rsplit('.', 1)[0]
|
||||
if fname != mod_name:
|
||||
break
|
||||
|
||||
|
||||
635
pymlac/xyzzy
635
pymlac/xyzzy
@@ -30,8 +30,9 @@ from threading import *
|
||||
import wx
|
||||
|
||||
import Display
|
||||
import DisplayCPU
|
||||
from Globals import *
|
||||
import Imlac
|
||||
#import Imlac
|
||||
|
||||
import Memory
|
||||
import Ptr
|
||||
@@ -251,15 +252,15 @@ def main():
|
||||
|
||||
# Initialize the emulator.
|
||||
boot_rom = 'ptr' # default ROM loader
|
||||
Imlac.init(0, TRACE_FILENAME, None, None, boot_rom, CORE_FILENAME)
|
||||
# Imlac.init(0, TRACE_FILENAME, None, None, boot_rom, CORE_FILENAME)
|
||||
|
||||
# now perform operations
|
||||
for (operation, args) in ops:
|
||||
if operation == 'boot':
|
||||
Memory.set_ROM(args)
|
||||
self.memory.set_ROM(args)
|
||||
Trace.comment('Bootstrap ROM set to %s' % args.upper())
|
||||
elif operation == 'clear':
|
||||
Memory.clear_core()
|
||||
self.memory.clear_core()
|
||||
Trace.comment('Core cleared')
|
||||
elif operation == 'load_ptp':
|
||||
Ptp.mount(args)
|
||||
@@ -273,29 +274,31 @@ def main():
|
||||
elif operation == 'run':
|
||||
MainCPU.PC = args
|
||||
Trace.comment('Running from address %06o' % args)
|
||||
if Imlac.tracestart:
|
||||
Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
|
||||
Trace.comment('------ ------------- ------ -------------- '
|
||||
# if Imlac.tracestart:
|
||||
Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
|
||||
Trace.comment('------ ------------- ------ -------------- '
|
||||
'-----------------------')
|
||||
Imlac.run()
|
||||
self.run()
|
||||
# Imlac.run()
|
||||
Trace.comment('Imlac halted')
|
||||
elif operation == 'set':
|
||||
Trace.comment("Setting memory from file '%s'" % args)
|
||||
elif operation == 'trace':
|
||||
if args == 'off':
|
||||
Imlac.tracestart = None
|
||||
Imlac.traceend = None
|
||||
# Imlac.tracestart = None
|
||||
# Imlac.traceend = None
|
||||
pass
|
||||
else:
|
||||
(start, end) = args
|
||||
Imlac.tracestart = start
|
||||
Imlac.traceend = end
|
||||
tstart = Imlac.tracestart
|
||||
if tstart is not None:
|
||||
tstart = '%06o' % tstart
|
||||
tend = Imlac.traceend
|
||||
if tend is not None:
|
||||
tend = '%06o' % tend
|
||||
Trace.comment('Trace set to (%s, %s)' % (tstart, tend))
|
||||
# Imlac.tracestart = start
|
||||
# Imlac.traceend = end
|
||||
# tstart = Imlac.tracestart
|
||||
# if tstart is not None:
|
||||
# tstart = '%06o' % tstart
|
||||
# tend = Imlac.traceend
|
||||
# if tend is not None:
|
||||
# tend = '%06o' % tend
|
||||
# Trace.comment('Trace set to (%s, %s)' % (tstart, tend))
|
||||
elif operation == 'ttyin':
|
||||
TtyIn.mount(args)
|
||||
Trace.comment("File '%s' mounted on TTYIN" % args)
|
||||
@@ -306,16 +309,16 @@ def main():
|
||||
Trace.comment("Viewing memory from file '%s'" % args)
|
||||
elif operation == 'write':
|
||||
if args == 'on':
|
||||
Memory.using_rom = True
|
||||
self.memory.using_rom = True
|
||||
elif args == 'off':
|
||||
Memory.using_rom = False
|
||||
self.memory.using_rom = False
|
||||
else:
|
||||
abort("Invalid view arg: %s" % args)
|
||||
Trace.comment('ROM write protect set %s' % args.upper())
|
||||
else:
|
||||
abort('Invalid internal operation: %s' % operation)
|
||||
|
||||
Imlac.close(CORE_FILENAME)
|
||||
# Imlac.close(CORE_FILENAME)
|
||||
|
||||
class Led_1(object):
|
||||
def __init__(self, parent, label, x, y, off, on):
|
||||
@@ -364,255 +367,255 @@ class Led_16(object):
|
||||
mask = mask >> 1
|
||||
|
||||
|
||||
class PymlacFrame(wx.Frame):
|
||||
"""a frame with two panels"""
|
||||
|
||||
WIDTH_SCREEN = 1024
|
||||
HEIGHT_SCREEN = 1024
|
||||
WIDTH_CONSOLE = 330 # 400 # 256
|
||||
HEIGHT_CONSOLE = HEIGHT_SCREEN
|
||||
|
||||
SCREEN_COLOUR = (0, 0, 0)
|
||||
CONSOLE_COLOUR = (255, 223, 169)
|
||||
PHOSPHOR_COLOUR = '#F0F000' # yellow
|
||||
#PHOSPHOR_COLOUR = '#40FF40' # green
|
||||
|
||||
V_MARGIN = 20
|
||||
CTL_MARGIN = 15
|
||||
LED_MARGIN = 5
|
||||
|
||||
IMAGE_LED_OFF = 'images/led_off.png'
|
||||
IMAGE_LED_ON = 'images/led_on.png'
|
||||
|
||||
INC = 0.01
|
||||
|
||||
def __init__(self, parent=None, id=-1, title=None):
|
||||
wx.Frame.__init__(self, parent, id, title)
|
||||
|
||||
self.make_gui()
|
||||
self.run()
|
||||
|
||||
def make_gui(self):
|
||||
self.screen = wx.Panel(self,
|
||||
size=(self.WIDTH_SCREEN, self.HEIGHT_SCREEN),
|
||||
pos=(0,0))
|
||||
self.screen.SetBackgroundColour(self.SCREEN_COLOUR)
|
||||
self.console = wx.Panel(self, style=wx.SIMPLE_BORDER,
|
||||
size=(self.WIDTH_CONSOLE, self.HEIGHT_SCREEN),
|
||||
pos=(self.WIDTH_SCREEN,0))
|
||||
self.console.SetBackgroundColour(self.CONSOLE_COLOUR)
|
||||
|
||||
python_png = wx.Image('images/PythonPowered.png',
|
||||
wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
python_height = python_png.GetHeight()
|
||||
python_width = python_png.GetWidth()
|
||||
|
||||
wxpython_png = wx.Image('images/wxPython2.png',
|
||||
wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
wxpython_height = wxpython_png.GetHeight()
|
||||
wxpython_width = wxpython_png.GetWidth()
|
||||
|
||||
h_margin = (self.WIDTH_CONSOLE - wxpython_width - python_width) / 3
|
||||
|
||||
png_height = max(python_height, wxpython_height) + self.V_MARGIN
|
||||
|
||||
v_margin = (png_height - python_height)/2
|
||||
python_ypos = self.HEIGHT_CONSOLE - png_height + v_margin
|
||||
v_margin = (png_height - wxpython_height)/2
|
||||
wxpython_ypos = self.HEIGHT_CONSOLE - png_height + v_margin
|
||||
|
||||
wx.StaticBitmap(self.console, -1, python_png,
|
||||
pos=(h_margin, python_ypos))
|
||||
wx.StaticBitmap(self.console, -1, wxpython_png,
|
||||
pos=(python_width + 2*h_margin, wxpython_ypos))
|
||||
|
||||
self.png_height = png_height
|
||||
|
||||
led_off = wx.Image('images/led_off.png',
|
||||
wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
led_on = wx.Image('images/led_on.png',
|
||||
wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
|
||||
y_pos = 8
|
||||
self.led_l = Led_1(self.console, 'l', self.CTL_MARGIN, y_pos,
|
||||
led_off, led_on)
|
||||
self.led_ac = Led_16(self.console, 'ac', 3*self.CTL_MARGIN, y_pos,
|
||||
led_off, led_on)
|
||||
y_pos += 35
|
||||
self.led_pc = Led_16(self.console, 'pc', 3*self.CTL_MARGIN, y_pos,
|
||||
led_off, led_on)
|
||||
|
||||
|
||||
y_pos = 305
|
||||
wx.StaticText(self.console, -1, 'ptr', pos=(self.CTL_MARGIN, y_pos))
|
||||
y_pos += 15
|
||||
self.txt_ptrFile = wx.TextCtrl(self.console, -1,
|
||||
pos=(self.CTL_MARGIN, y_pos),
|
||||
size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
|
||||
y_pos += 30
|
||||
|
||||
wx.StaticText(self.console, -1, 'ptp', pos=(self.CTL_MARGIN, y_pos))
|
||||
y_pos += 15
|
||||
self.txt_ptpFile = wx.TextCtrl(self.console, -1,
|
||||
pos=(self.CTL_MARGIN, y_pos),
|
||||
size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
|
||||
y_pos += 15
|
||||
|
||||
dc = wx.PaintDC(self.console)
|
||||
dc.SetPen(wx.Pen('black', 1))
|
||||
dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
|
||||
self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)
|
||||
|
||||
for (x, y) in self.led_ac.ticks:
|
||||
dc.DrawLine(x, y, x, y+5)
|
||||
first = self.led_ac.ticks[0]
|
||||
last = self.led_ac.ticks[-1]
|
||||
(x1, y1) = first
|
||||
(x2, y2) = last
|
||||
dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
|
||||
for (x, y) in self.led_pc.ticks:
|
||||
dc.DrawLine(x, y, x, y+5)
|
||||
first = self.led_pc.ticks[0]
|
||||
last = self.led_pc.ticks[-1]
|
||||
(x1, y1) = first
|
||||
(x2, y2) = last
|
||||
dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
|
||||
self.y_offset = 0
|
||||
self.y_sign = +1
|
||||
|
||||
self.Fit()
|
||||
|
||||
def run_machine(self, ops):
|
||||
"""Run the console options."""
|
||||
|
||||
for (operation, args) in ops:
|
||||
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)
|
||||
if Imlac.tracestart:
|
||||
Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
|
||||
Trace.comment('------ ------------- ------ -------------- '
|
||||
'-----------------------')
|
||||
self.on_paint()
|
||||
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
|
||||
Imlac.traceend = None
|
||||
else:
|
||||
(start, end) = args
|
||||
Imlac.tracestart = start
|
||||
Imlac.traceend = end
|
||||
tstart = Imlac.tracestart
|
||||
if tstart is not None:
|
||||
tstart = '%06o' % tstart
|
||||
tend = Imlac.traceend
|
||||
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
|
||||
elif args == 'off':
|
||||
Memory.using_rom = False
|
||||
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)
|
||||
|
||||
|
||||
def on_paint(self, event=None):
|
||||
global count
|
||||
|
||||
# establish the painting surface
|
||||
dc = wx.PaintDC(self.screen)
|
||||
dc.SetBackground(wx.Brush(self.SCREEN_COLOUR, 1))
|
||||
dc.SetPen(wx.Pen(self.PHOSPHOR_COLOUR, 1))
|
||||
dc.Clear()
|
||||
if self.y_sign > 0:
|
||||
self.y_offset = self.y_offset + self.INC
|
||||
if self.y_offset > self.HEIGHT_SCREEN-1:
|
||||
self.y_sign = -1
|
||||
self.y_offset = self.HEIGHT_SCREEN-1
|
||||
else:
|
||||
self.y_offset = self.y_offset - self.INC
|
||||
if self.y_offset < 0:
|
||||
self.y_sign = +1
|
||||
self.y_offset = 0
|
||||
dc.DrawLine(0, int(self.y_offset), self.WIDTH_SCREEN-1, int(self.HEIGHT_SCREEN-self.y_offset-1))
|
||||
dc.DrawLine(0, int(self.HEIGHT_SCREEN-self.y_offset-1), self.WIDTH_SCREEN-1, int(self.y_offset))
|
||||
|
||||
dc = wx.PaintDC(self.console)
|
||||
#dc.SetPen(wx.Pen('black', wx.DOT))
|
||||
dc.SetPen(wx.Pen('black', 1))
|
||||
dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
|
||||
self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)
|
||||
|
||||
for (x, y) in self.led_ac.ticks:
|
||||
dc.DrawLine(x, y, x, y+5)
|
||||
first = self.led_ac.ticks[0]
|
||||
last = self.led_ac.ticks[-1]
|
||||
(x1, y1) = first
|
||||
(x2, y2) = last
|
||||
dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
|
||||
for (x, y) in self.led_pc.ticks:
|
||||
dc.DrawLine(x, y, x, y+5)
|
||||
first = self.led_pc.ticks[0]
|
||||
last = self.led_pc.ticks[-1]
|
||||
(x1, y1) = first
|
||||
(x2, y2) = last
|
||||
dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
|
||||
count += 1
|
||||
self.led_ac.set_value(count)
|
||||
|
||||
|
||||
pass
|
||||
#class PymlacFrame(wx.Frame):
|
||||
# """a frame with two panels"""
|
||||
#
|
||||
# WIDTH_SCREEN = 1024
|
||||
# HEIGHT_SCREEN = 1024
|
||||
# WIDTH_CONSOLE = 330 # 400 # 256
|
||||
# HEIGHT_CONSOLE = HEIGHT_SCREEN
|
||||
#
|
||||
# SCREEN_COLOUR = (0, 0, 0)
|
||||
# CONSOLE_COLOUR = (255, 223, 169)
|
||||
# PHOSPHOR_COLOUR = '#F0F000' # yellow
|
||||
# #PHOSPHOR_COLOUR = '#40FF40' # green
|
||||
#
|
||||
# V_MARGIN = 20
|
||||
# CTL_MARGIN = 15
|
||||
# LED_MARGIN = 5
|
||||
#
|
||||
# IMAGE_LED_OFF = 'images/led_off.png'
|
||||
# IMAGE_LED_ON = 'images/led_on.png'
|
||||
#
|
||||
# INC = 0.01
|
||||
#
|
||||
# def __init__(self, parent=None, id=-1, title=None):
|
||||
# wx.Frame.__init__(self, parent, id, title)
|
||||
#
|
||||
# self.make_gui()
|
||||
# self.run()
|
||||
#
|
||||
# def make_gui(self):
|
||||
# self.screen = wx.Panel(self,
|
||||
# size=(self.WIDTH_SCREEN, self.HEIGHT_SCREEN),
|
||||
# pos=(0,0))
|
||||
# self.screen.SetBackgroundColour(self.SCREEN_COLOUR)
|
||||
# self.console = wx.Panel(self, style=wx.SIMPLE_BORDER,
|
||||
# size=(self.WIDTH_CONSOLE, self.HEIGHT_SCREEN),
|
||||
# pos=(self.WIDTH_SCREEN,0))
|
||||
# self.console.SetBackgroundColour(self.CONSOLE_COLOUR)
|
||||
#
|
||||
# python_png = wx.Image('images/PythonPowered.png',
|
||||
# wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
# python_height = python_png.GetHeight()
|
||||
# python_width = python_png.GetWidth()
|
||||
#
|
||||
# wxpython_png = wx.Image('images/wxPython2.png',
|
||||
# wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
# wxpython_height = wxpython_png.GetHeight()
|
||||
# wxpython_width = wxpython_png.GetWidth()
|
||||
#
|
||||
# h_margin = (self.WIDTH_CONSOLE - wxpython_width - python_width) / 3
|
||||
#
|
||||
# png_height = max(python_height, wxpython_height) + self.V_MARGIN
|
||||
#
|
||||
# v_margin = (png_height - python_height)/2
|
||||
# python_ypos = self.HEIGHT_CONSOLE - png_height + v_margin
|
||||
# v_margin = (png_height - wxpython_height)/2
|
||||
# wxpython_ypos = self.HEIGHT_CONSOLE - png_height + v_margin
|
||||
#
|
||||
# wx.StaticBitmap(self.console, -1, python_png,
|
||||
# pos=(h_margin, python_ypos))
|
||||
# wx.StaticBitmap(self.console, -1, wxpython_png,
|
||||
# pos=(python_width + 2*h_margin, wxpython_ypos))
|
||||
#
|
||||
# self.png_height = png_height
|
||||
#
|
||||
# led_off = wx.Image('images/led_off.png',
|
||||
# wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
# led_on = wx.Image('images/led_on.png',
|
||||
# wx.BITMAP_TYPE_PNG).ConvertToBitmap()
|
||||
#
|
||||
# y_pos = 8
|
||||
# self.led_l = Led_1(self.console, 'l', self.CTL_MARGIN, y_pos,
|
||||
# led_off, led_on)
|
||||
# self.led_ac = Led_16(self.console, 'ac', 3*self.CTL_MARGIN, y_pos,
|
||||
# led_off, led_on)
|
||||
# y_pos += 35
|
||||
# self.led_pc = Led_16(self.console, 'pc', 3*self.CTL_MARGIN, y_pos,
|
||||
# led_off, led_on)
|
||||
#
|
||||
#
|
||||
# y_pos = 305
|
||||
# wx.StaticText(self.console, -1, 'ptr', pos=(self.CTL_MARGIN, y_pos))
|
||||
# y_pos += 15
|
||||
# self.txt_ptrFile = wx.TextCtrl(self.console, -1,
|
||||
# pos=(self.CTL_MARGIN, y_pos),
|
||||
# size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
|
||||
# y_pos += 30
|
||||
#
|
||||
# wx.StaticText(self.console, -1, 'ptp', pos=(self.CTL_MARGIN, y_pos))
|
||||
# y_pos += 15
|
||||
# self.txt_ptpFile = wx.TextCtrl(self.console, -1,
|
||||
# pos=(self.CTL_MARGIN, y_pos),
|
||||
# size=(self.WIDTH_CONSOLE-2*self.CTL_MARGIN, 25))
|
||||
# y_pos += 15
|
||||
#
|
||||
# dc = wx.PaintDC(self.console)
|
||||
# dc.SetPen(wx.Pen('black', 1))
|
||||
# dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
|
||||
# self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)
|
||||
#
|
||||
# for (x, y) in self.led_ac.ticks:
|
||||
# dc.DrawLine(x, y, x, y+5)
|
||||
# first = self.led_ac.ticks[0]
|
||||
# last = self.led_ac.ticks[-1]
|
||||
# (x1, y1) = first
|
||||
# (x2, y2) = last
|
||||
# dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
#
|
||||
# for (x, y) in self.led_pc.ticks:
|
||||
# dc.DrawLine(x, y, x, y+5)
|
||||
# first = self.led_pc.ticks[0]
|
||||
# last = self.led_pc.ticks[-1]
|
||||
# (x1, y1) = first
|
||||
# (x2, y2) = last
|
||||
# dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
#
|
||||
# self.y_offset = 0
|
||||
# self.y_sign = +1
|
||||
#
|
||||
# self.Fit()
|
||||
#
|
||||
# def run_machine(self, ops):
|
||||
# """Run the console options."""
|
||||
#
|
||||
# for (operation, args) in ops:
|
||||
# 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)
|
||||
# if Imlac.tracestart:
|
||||
# Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
|
||||
# Trace.comment('------ ------------- ------ -------------- '
|
||||
# '-----------------------')
|
||||
# self.on_paint()
|
||||
# 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
|
||||
# Imlac.traceend = None
|
||||
# else:
|
||||
# (start, end) = args
|
||||
# Imlac.tracestart = start
|
||||
# Imlac.traceend = end
|
||||
# tstart = Imlac.tracestart
|
||||
# if tstart is not None:
|
||||
# tstart = '%06o' % tstart
|
||||
# tend = Imlac.traceend
|
||||
# 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
|
||||
# elif args == 'off':
|
||||
# Memory.using_rom = False
|
||||
# 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)
|
||||
#
|
||||
#
|
||||
# def on_paint(self, event=None):
|
||||
# global count
|
||||
#
|
||||
# # establish the painting surface
|
||||
# dc = wx.PaintDC(self.screen)
|
||||
# dc.SetBackground(wx.Brush(self.SCREEN_COLOUR, 1))
|
||||
# dc.SetPen(wx.Pen(self.PHOSPHOR_COLOUR, 1))
|
||||
# dc.Clear()
|
||||
# if self.y_sign > 0:
|
||||
# self.y_offset = self.y_offset + self.INC
|
||||
# if self.y_offset > self.HEIGHT_SCREEN-1:
|
||||
# self.y_sign = -1
|
||||
# self.y_offset = self.HEIGHT_SCREEN-1
|
||||
# else:
|
||||
# self.y_offset = self.y_offset - self.INC
|
||||
# if self.y_offset < 0:
|
||||
# self.y_sign = +1
|
||||
# self.y_offset = 0
|
||||
# dc.DrawLine(0, int(self.y_offset), self.WIDTH_SCREEN-1, int(self.HEIGHT_SCREEN-self.y_offset-1))
|
||||
# dc.DrawLine(0, int(self.HEIGHT_SCREEN-self.y_offset-1), self.WIDTH_SCREEN-1, int(self.y_offset))
|
||||
#
|
||||
# dc = wx.PaintDC(self.console)
|
||||
# #dc.SetPen(wx.Pen('black', wx.DOT))
|
||||
# dc.SetPen(wx.Pen('black', 1))
|
||||
# dc.DrawLine(0, self.HEIGHT_CONSOLE - self.png_height,
|
||||
# self.WIDTH_CONSOLE-1, self.HEIGHT_CONSOLE - self.png_height)
|
||||
#
|
||||
# for (x, y) in self.led_ac.ticks:
|
||||
# dc.DrawLine(x, y, x, y+5)
|
||||
# first = self.led_ac.ticks[0]
|
||||
# last = self.led_ac.ticks[-1]
|
||||
# (x1, y1) = first
|
||||
# (x2, y2) = last
|
||||
# dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
#
|
||||
# for (x, y) in self.led_pc.ticks:
|
||||
# dc.DrawLine(x, y, x, y+5)
|
||||
# first = self.led_pc.ticks[0]
|
||||
# last = self.led_pc.ticks[-1]
|
||||
# (x1, y1) = first
|
||||
# (x2, y2) = last
|
||||
# dc.DrawLine(x1, y2+5, x2, y2+5)
|
||||
#
|
||||
# count += 1
|
||||
# self.led_ac.set_value(count)
|
||||
#
|
||||
#
|
||||
# pass
|
||||
|
||||
|
||||
|
||||
@@ -652,11 +655,15 @@ class _InterpreterEvent(wx.PyCommandEvent):
|
||||
class InterpreterThread(Thread):
|
||||
"""Worker Thread Class."""
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self, parent, cpu, dcpu):
|
||||
"""Init Worker Thread Class."""
|
||||
|
||||
Thread.__init__(self)
|
||||
self.parent = parent
|
||||
self._want_abort = 0
|
||||
self.cpu = cpu
|
||||
self.dcpu = dcpu
|
||||
|
||||
# This starts the thread running on creation, but you could
|
||||
# also make the GUI thread responsible for calling this
|
||||
self.start()
|
||||
@@ -679,10 +686,39 @@ class InterpreterThread(Thread):
|
||||
|
||||
def run(self):
|
||||
"""Run the interpreter."""
|
||||
|
||||
self.cpu.running = True
|
||||
while self.execute_once() > 0: pass
|
||||
self.cpu.running = False
|
||||
|
||||
Imlac.run()
|
||||
self.RaiseInterpreterStop()
|
||||
|
||||
def execute_once():
|
||||
if traceend is None:
|
||||
if self.cpu.PC == tracestart:
|
||||
Trace.settrace(True)
|
||||
else:
|
||||
Trace.settrace(self.cpu.PC >= tracestart and self.cpu.PC <= traceend)
|
||||
|
||||
if self.dcpu.ison():
|
||||
Trace.trace('%6.6o' % self.dcpu.DPC)
|
||||
Trace.trace('\t')
|
||||
|
||||
instruction_cycles = self.dcpu.execute_one_instruction()
|
||||
|
||||
Trace.trace('%6.6o\t' % self.cpu.PC)
|
||||
|
||||
instruction_cycles += self.cpu.execute_one_instruction()
|
||||
|
||||
Trace.itraceend(self.dcpu.ison())
|
||||
|
||||
self.__tick_all(instruction_cycles)
|
||||
|
||||
if not self.dcpu.ison() and not self.cpu.running:
|
||||
return 0
|
||||
|
||||
return instruction_cycles
|
||||
|
||||
def abort(self):
|
||||
"""abort worker thread."""
|
||||
# Method for use by main thread to signal an abort
|
||||
@@ -744,14 +780,21 @@ class DisplayFrame(wx.Frame):
|
||||
def run_machine(self):
|
||||
"""Run the interpreter."""
|
||||
|
||||
# FIXME create all devices, build the Imlac machine
|
||||
self.memory = Memory.Memory(boot_rom=DefaultBootROM, corefile=DefaultCoreFile)
|
||||
# create device, construct machine
|
||||
self.kbd = None # Kbd.Kbd()
|
||||
self.ttyin = None # TtyIn.TtyIn()
|
||||
self.ttyout = None # TtyOut.TtyOut()
|
||||
self.memory = Memory.Memory(boot_rom=DefaultBootROM, core=DefaultCoreFile)
|
||||
self.ptr = Ptr.Ptr()
|
||||
self.ptp = Ptp.Ptp()
|
||||
self.display = Display.Display(self.memory)
|
||||
self.display = Display.Display(self)
|
||||
self.dcpu = DisplayCPU.DisplayCPU(self.display, self.memory)
|
||||
self.cpu = MainCPU.MainCPU(self.ptr, self.ptp,
|
||||
self.display, self.dcpu, self.memory)
|
||||
self.cpu = MainCPU.MainCPU(self.memory, self.display, self.dcpu,
|
||||
self.kbd, self.ttyin, self.ttyout,
|
||||
self.ptr, self.ptp)
|
||||
|
||||
Trace.init(TRACE_FILENAME, self.cpu, self.dcpu)
|
||||
tracestart = traceend = None
|
||||
|
||||
# get and execute the operations list
|
||||
ops = get_options()
|
||||
@@ -760,66 +803,66 @@ class DisplayFrame(wx.Frame):
|
||||
time.sleep(1)
|
||||
|
||||
if operation == 'boot':
|
||||
Memory.set_ROM(args)
|
||||
self.memory.set_ROM(args)
|
||||
Trace.comment('Bootstrap ROM set to %s' % args.upper())
|
||||
elif operation == 'clear':
|
||||
Memory.clear_core()
|
||||
self.memory.clear_core()
|
||||
Trace.comment('Core cleared')
|
||||
elif operation == 'load_ptp':
|
||||
Ptp.mount(args)
|
||||
Trace.comment("File '%s' mounted on PTP" % args)
|
||||
elif operation == 'load_ptr':
|
||||
Ptr.mount(args)
|
||||
self.ptr.mount(args)
|
||||
Trace.comment("File '%s' mounted on PTR" % args)
|
||||
elif operation == 'data':
|
||||
MainCPU.DS = args
|
||||
self.cpu.DS = args
|
||||
Trace.comment('Dataswitch value set to %06o' % args)
|
||||
elif operation == 'run':
|
||||
MainCPU.PC = args
|
||||
self.cpu.PC = args
|
||||
Trace.comment('Running from address %06o' % args)
|
||||
if Imlac.tracestart:
|
||||
if tracestart:
|
||||
Trace.comment('DPC\tDisplay\t\tPC\tMain\t\tRegs')
|
||||
Trace.comment('------ ------------- ------ -------------- '
|
||||
'-----------------------')
|
||||
self.interpreter = InterpreterThread(self)
|
||||
self.interpreter = InterpreterThread(self, self.cpu, self.dcpu)
|
||||
self.running = True
|
||||
elif operation == 'set':
|
||||
Trace.comment("Setting memory from file '%s'" % args)
|
||||
elif operation == 'trace':
|
||||
if args == 'off':
|
||||
Imlac.tracestart = None
|
||||
Imlac.traceend = None
|
||||
tracestart = None
|
||||
traceend = None
|
||||
else:
|
||||
(start, end) = args
|
||||
Imlac.tracestart = start
|
||||
Imlac.traceend = end
|
||||
tstart = Imlac.tracestart
|
||||
tracestart = start
|
||||
traceend = end
|
||||
tstart = tracestart
|
||||
if tstart is not None:
|
||||
tstart = '%06o' % tstart
|
||||
tend = Imlac.traceend
|
||||
tend = traceend
|
||||
if tend is not None:
|
||||
tend = '%06o' % tend
|
||||
Trace.comment('Trace set to (%s, %s)' % (tstart, tend))
|
||||
elif operation == 'ttyin':
|
||||
TtyIn.mount(args)
|
||||
self.ttyin.mount(args)
|
||||
Trace.comment("File '%s' mounted on TTYIN" % args)
|
||||
elif operation == 'ttyout':
|
||||
TtyOut.mount(args)
|
||||
self.ttyout.mount(args)
|
||||
Trace.comment("File '%s' mounted on TTYOUT" % args)
|
||||
elif operation == 'view':
|
||||
Trace.comment("Viewing memory from file '%s'" % args)
|
||||
elif operation == 'write':
|
||||
if args == 'on':
|
||||
Memory.using_rom = True
|
||||
self.memory.using_rom = True
|
||||
elif args == 'off':
|
||||
Memory.using_rom = False
|
||||
self.memory.using_rom = False
|
||||
else:
|
||||
abort("Invalid view arg: %s" % args)
|
||||
Trace.comment('ROM write protect set %s' % args.upper())
|
||||
else:
|
||||
abort('Invalid internal operation: %s' % operation)
|
||||
|
||||
Imlac.close(CORE_FILENAME)
|
||||
# Imlac.close(CORE_FILENAME)
|
||||
|
||||
def excepthook(type, value, tb):
|
||||
"""Handler for uncaught exceptions."""
|
||||
|
||||
Reference in New Issue
Block a user