diff --git a/pymlac/DisplayCPU.py b/pymlac/DisplayCPU.py index 3ce2bc6..b6cba9d 100644 --- a/pymlac/DisplayCPU.py +++ b/pymlac/DisplayCPU.py @@ -14,10 +14,6 @@ import sys from Globals import * import Trace - - -trace = Trace.Trace(TRACE_FILENAME) - import log log = log.Log('test.log', log.Log.DEBUG) @@ -122,7 +118,7 @@ class DisplayCPU(object): if byte & 0x20: # DRJM if self.DRSindex <= 0: - trace.comment('\nDRS stack underflow at display address %6.6o' + Trace.comment('\nDRS stack underflow at display address %6.6o' % (self.DPC - 1)) self.illegal() self.DRSindex -= 1 @@ -180,10 +176,10 @@ class DisplayCPU(object): def illegal(self, instruction=None): if instruction: - trace.comment('Illegal display instruction (%6.6o) at address %6.6o' + Trace.comment('Illegal display instruction (%6.6o) at address %6.6o' % (instruction, (self.DPC - 1))) else: - trace.comment('Illegal display instruction at address %6.6o' + Trace.comment('Illegal display instruction at address %6.6o' % (self.DPC - 1)) sys.exit(0) @@ -192,12 +188,12 @@ class DisplayCPU(object): def i_DDXM(self): self.DX -= 0o40 - tracestr = trace.dtrace(self.dot, 'DDXM', None) + tracestr = Trace.dtrace(self.dot, 'DDXM', None) return (1, tracestr) def i_DDYM(self): self.DY -= 0o40 - tracestr = trace.dtrace(self.dot, 'DDYM', None) + tracestr = Trace.dtrace(self.dot, 'DDYM', None) return (1, tracestr) def i_DEIM(self, address): @@ -207,22 +203,22 @@ class DisplayCPU(object): def i_DHLT(self): self.Running = False - return (1, trace.dtrace(self.dot, 'DHLT', None)) + return (1, Trace.dtrace(self.dot, 'DHLT', None)) def i_DHVC(self): - return (1, trace.dtrace(self.dot, 'DHVC', None)) + return (1, Trace.dtrace(self.dot, 'DHVC', None)) def i_DIXM(self): self.DX += 0o4000 - return (1, trace.dtrace(self.dot, 'DIXM', None)) + return (1, Trace.dtrace(self.dot, 'DIXM', None)) def i_DIYM(self): self.DY += 0o4000 - return (1, trace.dtrace(self.dot, 'DIYM', None)) + return (1, Trace.dtrace(self.dot, 'DIYM', None)) def i_DJMP(self, address): self.DPC = MASK_MEM(address + (self.DIB << 12)) - return (1, trace.dtrace(self.dot, 'DJMP', address)) + return (1, Trace.dtrace(self.dot, 'DJMP', address)) def i_DJMS(self, address): if self.DRSindex >= 8: @@ -232,15 +228,15 @@ class DisplayCPU(object): self.DRS[self.DRSindex] = self.DPC self.DRSindex += 1 self.DPC = MASK_MEM(address + (self.DIB << 12)) - return (1, trace.dtrace(self.dot, 'DJMS', address)) + return (1, Trace.dtrace(self.dot, 'DJMS', address)) def i_DLXA(self, address): self.DX = (address & self.BITS10) << 1 - return (1, trace.dtrace(self.dot, 'DLXA', address)) + return (1, Trace.dtrace(self.dot, 'DLXA', address)) def i_DLYA(self, address): self.DY = (address & self.BITS10) << 1 - return (1, trace.dtrace(self.dot, 'DLXA', address)) + return (1, Trace.dtrace(self.dot, 'DLXA', address)) def i_DLVH(self, word1): word2 = self.memory.get(self, DPC, 0) @@ -280,7 +276,7 @@ class DisplayCPU(object): self.DY += N self.display.draw(prevDX, prevDY, self.DX, self.DY, dotted) - return (3, trace.dtrace(self.dot, 'DLVH', None)) + return (3, Trace.dtrace(self.dot, 'DLVH', None)) def i_DRJM(self): if self.DRSindex <= 0: @@ -289,12 +285,12 @@ class DisplayCPU(object): self.illegal() self.DRSindex -= 1 self.DPC = self.DRS[self.DRSindex] - return (1, trace.dtrace(self.dot, 'DRJM', None)) # FIXME check # cycles used + return (1, Trace.dtrace(self.dot, 'DRJM', None)) # FIXME check # cycles used def i_DSTB(self, block): self.DIB = block - trace.dtrace('DSTB\t%d' % block) - return (1, trace.dtrace('DSTB\t%d' % block, None)) + Trace.dtrace('DSTB\t%d' % block) + return (1, Trace.dtrace('DSTB\t%d' % block, None)) def i_DSTS(self, scale): if scale == 0: @@ -307,14 +303,14 @@ class DisplayCPU(object): self.Scale = 3.0 else: self.illegal() - return (1, trace.dtrace('DSTS\t%d' % scale, None)) # FIXME check # cycles used + return (1, Trace.dtrace('DSTS\t%d' % scale, None)) # FIXME check # cycles used def page00(self, instruction): if instruction == 0o00000: # DHLT (cycles, tracestr) = self.i_DHLT() elif instruction == 0o04000: # DNOP cycles = 1 - tracestr = trace.dtrace('DNOP') + tracestr = Trace.dtrace('DNOP') elif instruction == 0o04004: # DSTS 0 (cycles, tracestr) = self.i_DSTS(0) elif instruction == 0o04005: # DSTS 1 diff --git a/pymlac/MainCPU.py b/pymlac/MainCPU.py index d26c641..70a8fe3 100644 --- a/pymlac/MainCPU.py +++ b/pymlac/MainCPU.py @@ -5,14 +5,11 @@ The Imlac main CPU. import sys -from Globals import * import Trace - +from Globals import * import log log = log.Log('test.log', log.Log.DEBUG) -trace = Trace.Trace(TRACE_FILENAME) - class MainCPU(object): @@ -219,22 +216,22 @@ class MainCPU(object): tracestr = None if indirect: self.AC = (~address+1) & WORDMASK - tracestr = trace.itrace(self.dot, 'LWC', False, address) + tracestr = Trace.itrace(self.dot, 'LWC', False, address) else: self.AC = address - tracestr = trace.itrace(self.dot, 'LAW', False, address) + tracestr = Trace.itrace(self.dot, 'LAW', False, address) return (1, tracestr) def i_JMP(self, indirect, address, instruction): eff_address = self.memory.eff_address(address, indirect) self.PC = eff_address & PCMASK - tracestr = trace.itrace(self.dot, 'JMP', indirect, address) + tracestr = Trace.itrace(self.dot, 'JMP', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_DAC(self, indirect, address, instruction): eff_address = self.memory.eff_address(address, indirect) self.memory.put(self.AC, eff_address, False) - tracestr = trace.itrace(self.dot, 'DAC', indirect, address) + tracestr = Trace.itrace(self.dot, 'DAC', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_XAM(self, indirect, address, instruction): @@ -242,7 +239,7 @@ class MainCPU(object): tmp = self.memory.fetch(eff_address, False) self.memory.put(self.AC, eff_address, False) self.AC = tmp - tracestr = trace.itrace(self.dot, 'XAM', indirect, address) + tracestr = Trace.itrace(self.dot, 'XAM', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_ISZ(self, indirect, address, instruction): @@ -251,34 +248,34 @@ class MainCPU(object): self.memory.put(value, eff_address, False) if value == 0: self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'ISZ', indirect, address) + tracestr = Trace.itrace(self.dot, 'ISZ', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_JMS(self, indirect, address, instruction): eff_address = self.memory.eff_address(address, indirect) self.memory.put(self.PC, eff_address, False) self.PC = (eff_address + 1) & PCMASK - tracestr = trace.itrace(self.dot, 'JMS', indirect, address) + tracestr = Trace.itrace(self.dot, 'JMS', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_AND(self, indirect, address, instruction): self.AC &= self.memory.fetch(address, indirect) - tracestr = trace.itrace(self.dot, 'AND', indirect, address) + tracestr = Trace.itrace(self.dot, 'AND', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_IOR(self, indirect, address, instruction): self.AC |= self.memory.fetch(address, indirect) - tracestr = trace.itrace(self.dot, 'IOR', indirect, address) + tracestr = Trace.itrace(self.dot, 'IOR', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_XOR(self, indirect, address, instruction): self.AC ^= self.memory.fetch(address, indirect) - tracestr = trace.itrace(self.dot, 'XOR', indirect, address) + tracestr = Trace.itrace(self.dot, 'XOR', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_LAC(self, indirect, address, instruction): self.AC = self.memory.fetch(address, indirect) - tracestr = trace.itrace(self.dot, 'LAC', indirect, address) + tracestr = Trace.itrace(self.dot, 'LAC', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_ADD(self, indirect, address, instruction): @@ -286,7 +283,7 @@ class MainCPU(object): if self.AC & OVERFLOWMASK: self.L = 0 if self.L else 1 self.AC &= WORDMASK - tracestr = trace.itrace(self.dot, 'ADD', indirect, address) + tracestr = Trace.itrace(self.dot, 'ADD', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_SUB(self, indirect, address, instruction): @@ -296,14 +293,14 @@ class MainCPU(object): if self.AC & OVERFLOWMASK: self.L = 0 if self.L else 1 self.AC &= WORDMASK - tracestr = trace.itrace(self.dot, 'SUB', indirect, address) + tracestr = Trace.itrace(self.dot, 'SUB', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def i_SAM(self, indirect, address, instruction): samaddr = self.BLOCKADDR(address) if self.AC == self.memory.fetch(samaddr, indirect): self.PC = (self.PC + 1) & PCMASK - tracestr = trace.itrace(self.dot, 'SAM', indirect, address) + tracestr = Trace.itrace(self.dot, 'SAM', indirect, address) return (3, tracestr) if indirect else (2, tracestr) def microcode(self, instruction): @@ -345,141 +342,141 @@ class MainCPU(object): if instruction & k: combine.append(op) - tracestr = trace.itrace(self.dot, '+'.join(combine), False) + tracestr = Trace.itrace(self.dot, '+'.join(combine), False) return (1, tracestr) def i_DLA(self, indirect, address, instruction): self.displaycpu.DPC = self.AC - tracestr = trace.itrace(self.dot, 'DLA') + tracestr = Trace.itrace(self.dot, 'DLA') return (1, tracestr) def i_CTB(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'CTB') + tracestr = Trace.itrace(self.dot, 'CTB') return (1, tracestr) def i_DOF(self, indirect, address, instruction): log('self.displaycpu=%s' % str(self.displaycpu)) self.displaycpu.stop() - tracestr = trace.itrace(self.dot, 'DOF') + tracestr = Trace.itrace(self.dot, 'DOF') return (1, tracestr) def i_KRB(self, indirect, address, instruction): self.AC |= self.kbd.read() - tracestr = trace.itrace(self.dot, 'KRB') + tracestr = Trace.itrace(self.dot, 'KRB') return (1, tracestr) def i_KCF(self, indirect, address, instruction): self.kbd.clear() - tracestr = trace.itrace(self.dot, 'KCF') + tracestr = Trace.itrace(self.dot, 'KCF') return (1, tracestr) def i_KRC(self, indirect, address, instruction): self.AC |= self.kbd.read() self.kbd.clear() - tracestr = trace.itrace(self.dot, 'KRC') + tracestr = Trace.itrace(self.dot, 'KRC') return (1, tracestr) def i_RRB(self, indirect, address, instruction): self.AC |= self.ttyin.read() - tracestr = trace.itrace(self.dot, 'RRB') + tracestr = Trace.itrace(self.dot, 'RRB') return (1, tracestr) def i_RCF(self, indirect, address, instruction): self.ttyin.clear() - tracestr = trace.itrace(self.dot, 'RCF') + tracestr = Trace.itrace(self.dot, 'RCF') return (1, tracestr) def i_RRC(self, indirect, address, instruction): self.AC |= self.ttyin.read() self.ttyin.clear() - tracestr = trace.itrace(self.dot, 'RRC') + tracestr = Trace.itrace(self.dot, 'RRC') return (1, tracestr) def i_TPR(self, indirect, address, instruction): self.ttyout.write(self.AC & 0xff) - tracestr = trace.itrace(self.dot, 'TPR') + tracestr = Trace.itrace(self.dot, 'TPR') return (1, tracestr) def i_TCF(self, indirect, address, instruction): self.ttyout.clear() - tracestr = trace.itrace(self.dot, 'TCF') + tracestr = Trace.itrace(self.dot, 'TCF') return (1, tracestr) def i_TPC(self, indirect, address, instruction): self.ttyout.write(self.AC & 0xff) self.ttyout.clear() - tracestr = trace.itrace(self.dot, 'TPC') + tracestr = Trace.itrace(self.dot, 'TPC') return (1, tracestr) def i_HRB(self, indirect, address, instruction): self.AC |= self.ptrptp.read() - tracestr = trace.itrace(self.dot, 'HRB') + tracestr = Trace.itrace(self.dot, 'HRB') return (1, tracestr) def i_HOF(self, indirect, address, instruction): self.ptrptp.stop() - tracestr = trace.itrace(self.dot, 'HOF') + tracestr = Trace.itrace(self.dot, 'HOF') return (1, tracestr) def i_HON(self, indirect, address, instruction): self.ptrptp.start() - tracestr = trace.itrace(self.dot, 'HON') + tracestr = Trace.itrace(self.dot, 'HON') return (1, tracestr) def i_STB(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'STB') + tracestr = Trace.itrace(self.dot, 'STB') return (1, tracestr) def i_SCF(self, indirect, address, instruction): self.Sync40Hz = 0 - tracestr = trace.itrace(self.dot, 'SCF') + tracestr = Trace.itrace(self.dot, 'SCF') return (1, tracestr) def i_IOS(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOS') + tracestr = Trace.itrace(self.dot, 'IOS') return (1, tracestr) def i_IOT101(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOT101') + tracestr = Trace.itrace(self.dot, 'IOT101') return (1, tracestr) def i_IOT111(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOT111') + tracestr = Trace.itrace(self.dot, 'IOT111') return (1, tracestr) def i_IOT131(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOT131') + tracestr = Trace.itrace(self.dot, 'IOT131') return (1, tracestr) def i_IOT132(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOT132') + tracestr = Trace.itrace(self.dot, 'IOT132') return (1, tracestr) def i_IOT134(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOT134') + tracestr = Trace.itrace(self.dot, 'IOT134') return (1, tracestr) def i_IOT141(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOT141') + tracestr = Trace.itrace(self.dot, 'IOT141') return (1, tracestr) def i_IOF(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'IOF') + tracestr = Trace.itrace(self.dot, 'IOF') return (1, tracestr) def i_ION(self, indirect, address, instruction): - tracestr = trace.itrace(self.dot, 'ION') + tracestr = Trace.itrace(self.dot, 'ION') return (1, tracestr) def i_PPC(self, indirect, address, instruction): self.ptrptp.punch(self.AC & 0xff) - tracestr = trace.itrace(self.dot, 'PPC') + tracestr = Trace.itrace(self.dot, 'PPC') return (1, tracestr) def i_PSF(self, indirect, address, instruction): if self.ptrptp.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'PSF') + tracestr = Trace.itrace(self.dot, 'PSF') return (1, tracestr) def i_RAL1(self, indirect, address, instruction): @@ -487,7 +484,7 @@ class MainCPU(object): newac = (self.AC << 1) | self.L self.L = newl self.AC = newac & WORDMASK - tracestr = trace.itrace(self.dot, 'RAL', False, 1) + tracestr = Trace.itrace(self.dot, 'RAL', False, 1) return (1, tracestr) def i_RAL2(self, indirect, address, instruction): @@ -499,7 +496,7 @@ class MainCPU(object): newac = (self.AC << 1) | self.L self.L = newl self.AC = newac & WORDMASK - tracestr = trace.itrace(self.dot, 'RAL', False, 2) + tracestr = Trace.itrace(self.dot, 'RAL', False, 2) return (1, tracestr) def i_RAL3(self, indirect, address, instruction): @@ -515,7 +512,7 @@ class MainCPU(object): newac = (self.AC << 1) | self.L self.L = newl self.AC = newac & WORDMASK - tracestr = trace.itrace(self.dot, 'RAL', False, 3) + tracestr = Trace.itrace(self.dot, 'RAL', False, 3) return (1, tracestr) def i_RAR1(self, indirect, address, instruction): @@ -523,7 +520,7 @@ class MainCPU(object): newac = (self.AC >> 1) | (self.L << 15) self.L = newl self.AC = newac & WORDMASK - tracestr = trace.itrace(self.dot, 'RAR', False, 1) + tracestr = Trace.itrace(self.dot, 'RAR', False, 1) return (1, tracestr) def i_RAR2(self, indirect, address, instruction): @@ -535,7 +532,7 @@ class MainCPU(object): newac = (self.AC >> 1) | (self.L << 15) self.L = newl self.AC = newac & WORDMASK - tracestr = trace.itrace(self.dot, 'RAR', False, 2) + tracestr = Trace.itrace(self.dot, 'RAR', False, 2) return (1, tracestr) def i_RAR3(self, indirect, address, instruction): @@ -551,41 +548,41 @@ class MainCPU(object): newac = (self.AC >> 1) | (self.L << 15) self.L = newl self.AC = newac & WORDMASK - tracestr = trace.itrace(self.dot, 'RAR', False, 3) + tracestr = Trace.itrace(self.dot, 'RAR', False, 3) return (1, tracestr) def i_SAL1(self, indirect, address, instruction): high_bit = self.AC & HIGHBITMASK value = self.AC & 0o37777 self.AC = (value << 1) | high_bit - tracestr = trace.itrace(self.dot, 'SAL', False, 1) + tracestr = Trace.itrace(self.dot, 'SAL', False, 1) return (1, tracestr) def i_SAL2(self, indirect, address, instruction): high_bit = self.AC & HIGHBITMASK value = self.AC & 0o17777 self.AC = (value << 2) | high_bit - tracestr = trace.itrace(self.dot, 'SAL', False, 2) + tracestr = Trace.itrace(self.dot, 'SAL', False, 2) return (1, tracestr) def i_SAL3(self, indirect, address, instruction): high_bit = self.AC & HIGHBITMASK value = self.AC & 0o07777 self.AC = (value << 3) | high_bit - tracestr = trace.itrace(self.dot, 'SAL', False, 3) + tracestr = Trace.itrace(self.dot, 'SAL', False, 3) return (1, tracestr) def i_SAR1(self, indirect, address, instruction): high_bit = self.AC & HIGHBITMASK self.AC = (self.AC >> 1) | high_bit - tracestr = trace.itrace(self.dot, 'SAR', False, 1) + tracestr = Trace.itrace(self.dot, 'SAR', False, 1) return (1, tracestr) def i_SAR2(self, indirect, address, instruction): high_bit = self.AC & HIGHBITMASK self.AC = (self.AC >> 1) | high_bit self.AC = (self.AC >> 1) | high_bit - tracestr = trace.itrace(self.dot, 'SAR', False, 2) + tracestr = Trace.itrace(self.dot, 'SAR', False, 2) return (1, tracestr) def i_SAR3(self, indirect, address, instruction): @@ -593,121 +590,121 @@ class MainCPU(object): self.AC = (self.AC >> 1) | high_bit self.AC = (self.AC >> 1) | high_bit self.AC = (self.AC >> 1) | high_bit - tracestr = trace.itrace(self.dot, 'SAR', False, 3) + tracestr = Trace.itrace(self.dot, 'SAR', False, 3) return (1, tracestr) def i_DON(self, indirect, address, instruction): self.display.clear() self.displaycpu.DRSindex = 0 self.displaycpu.start() - tracestr = trace.itrace(self.dot, 'DON') + tracestr = Trace.itrace(self.dot, 'DON') return (1, tracestr) def i_ASZ(self): if self.AC == 0: self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'ASZ') + tracestr = Trace.itrace(self.dot, 'ASZ') return (1, tracestr) def i_ASN(self): if self.AC != 0: self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'ASN') + tracestr = Trace.itrace(self.dot, 'ASN') return (1, tracestr) def i_ASP(self): if not (self.AC & HIGHBITMASK): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'ASP') + tracestr = Trace.itrace(self.dot, 'ASP') return (1, tracestr) def i_ASM(self): if (self.AC & HIGHBITMASK): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'ASM') + tracestr = Trace.itrace(self.dot, 'ASM') return (1, tracestr) def i_LSZ(self): if self.L == 0: self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'LSZ') + tracestr = Trace.itrace(self.dot, 'LSZ') return (1, tracestr) def i_LSN(self): if self.L != 0: self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'LSN') + tracestr = Trace.itrace(self.dot, 'LSN') return (1, tracestr) def i_DSF(self): if self.displaycpu.ison(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'DSF') + tracestr = Trace.itrace(self.dot, 'DSF') return (1, tracestr) def i_DSN(self): if not self.displaycpu.ison(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'DSN') + tracestr = Trace.itrace(self.dot, 'DSN') return (1, tracestr) def i_KSF(self): if self.kbd.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'KSF') + tracestr = Trace.itrace(self.dot, 'KSF') return (1, tracestr) def i_KSN(self): if not self.kbd.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'KSN') + tracestr = Trace.itrace(self.dot, 'KSN') return (1, tracestr) def i_RSF(self): if self.ttyin.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'RSF') + tracestr = Trace.itrace(self.dot, 'RSF') return (1, tracestr) def i_RSN(self): if not self.ttyin.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'RSN') + tracestr = Trace.itrace(self.dot, 'RSN') return (1, tracestr) def i_TSF(self): if self.ttyout.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'TSF') + tracestr = Trace.itrace(self.dot, 'TSF') return (1, tracestr) def i_TSN(self): if not self.ttyout.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'TSN') + tracestr = Trace.itrace(self.dot, 'TSN') return (1, tracestr) def i_SSF(self): if self.display.ready(): # skip if 40Hz sync on self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'SSF') + tracestr = Trace.itrace(self.dot, 'SSF') return (1, tracestr) def i_SSN(self): if not self.display.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'SSN') + tracestr = Trace.itrace(self.dot, 'SSN') return (1, tracestr) def i_HSF(self): if self.ptrptp.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'HSF') + tracestr = Trace.itrace(self.dot, 'HSF') return (1, tracestr) def i_HSN(self): if not self.ptrptp.ready(): self.PC = (self.PC + 1) & WORDMASK - tracestr = trace.itrace(self.dot, 'HSN') + tracestr = Trace.itrace(self.dot, 'HSN') return (1, tracestr) diff --git a/pymlac/Trace.py b/pymlac/Trace.py index d8fb319..3754cab 100644 --- a/pymlac/Trace.py +++ b/pymlac/Trace.py @@ -3,10 +3,18 @@ The Imlac trace stuff. Simple usage: import Trace - trace = Trace.Trace('my_log.log', maincpu, dispcpu) - trace.itrace(msg) + Trace.init('my_log.log', maincpu, dispcpu) + Trace.set_trace_map(map) + while running: + Trace.start() + Trace.itrace(inst_str) + Trace.dtrace(inst_str) + Trace.end() -Based on the 'borg' recipe from [http://code.activestate.com/recipes/66531/]. +The idea is that trace system will handle formatting and writing trace data to +the trace file and the "main" code will perform the above steps. The +.endtrace() method will grab the register values after the instructions and +format the trace data and write it to the file. """ import os @@ -18,150 +26,189 @@ import log log = log.Log('test.log', log.Log.DEBUG) -class Trace(object): +Tracing = False +TrafeFilename = None +TraceFile = None +CPU = None +DCPU = None +TraceMap = None +CPUInst = None +DCPUInst = None +CPU_PC = None +DCPU_PC = None - __shared_state = {} # this __dict__ shared by ALL instances - def __init__(self, filename, maincpu=None, displaycpu=None): - """Initialize the trace: +def init(filename, maincpu=None, displaycpu=None): + """Initialize the trace: - filename name of the trace file - maincpu the main CPU object (may be added later) - displaycpu the display CPU object (may be added later) - """ + filename name of the trace file + maincpu the main CPU object (may be added later) + displaycpu the display CPU object (may be added later) + """ - # ensure same state as all other instances - self.__dict__ = Trace.__shared_state + global CPU, DCPU, TraceMap, CPUInst, DCPUInst + global TraceFile, TraceFilename - # set internal state - self.tracing = True - self.tracefile = filename - try: - os.remove(filename) - except: - pass - self.tracefile = open(filename, 'wb') - s = bytes('%s trace\n%s\n' % (PYMLAC_VERSION, '-'*60), 'utf-8') - self.tracefile.write(s) + # set internal state + Tracing = True + TraceFilename = filename + try: + os.remove(filename) + except: + pass + TraceFile = open(filename, 'w') + TraceFile.write(f"{PYMLAC_VERSION} trace\n{'-'*60}\n") - self.cpu = maincpu - self.dcpu = displaycpu + CPU = maincpu + DCPU = displaycpu - self.trace_map = collections.defaultdict(bool) - log(f'Trace.__init__: self.tracing={self.tracing}, self.tracefile={self.tracefile}') + TraceMap = collections.defaultdict(bool) + log(f'Trace.init: Tracing={Tracing}, TraceFilename={TraceFilename}') - def set_trace_map(self, trace_map): - """Set the trace address dict mapping.""" + CPUInst = None + DCPUInst = None - self.trace_map = trace_map - log(f'Trace.set_trace_map: self.trace_map={trace_map}') +def start(): + """Prepare trace system for new execution.""" - def add_maincpu(self, maincpu): - """Add the main CPU object.""" + global CPU_PC, DCPU_PC, CPUInst, DCPUInst - self.cpu = maincpu - log(f'Trace.add_maincpu: self.cpu={maincpu}') + CPUInst = None + DCPUInst = None + CPU_PC = CPU.PC + DCPU_PC = DCPU.DPC - def add_displaycpu(self, dispcpu): - """Add the display CPU object.""" +def set_TraceMap(trace_map): + """Set the trace address dict mapping.""" - self.dcpu = dispcpu - log(f'Trace.add_displaycpu: self.dcpu={dispcpu}') + global TraceMap - def close(self): - """Close trace.""" + TraceMap = trace_map + log(f'Trace.set_TraceMap: TraceMap={TraceMap}') - self.tracefile.close() - self.tracing = False - self.tracefile = None - self.dcpu = dispcpu - log(f'Trace.close: self.tracing={self.tracing}') +def add_CPU(maincpu): + """Add the main CPU object.""" - def deimtrace(self, opcode, code): - """Trace the DEIM instruction. + global CPU - opcode DEIM opcode - code the operation - """ + CPU = maincpu - log(f"deimtrace: self.tracing={self.tracing}, writing '{opcode} {code}'") - if self.tracing: - self.tracefile.write('%s\t%s\t' % (opcode, code)) - self.tracefile.flush() +def add_DCPU(dispcpu): + """Add the display CPU object.""" - def dtrace(self, ddot, opcode, address=None): - """Trace the display CPU. + global DCPU + DCPU = dispcpu - ddot address of instruction being traced - opcode display opcode - address address for the opcode +def close(): + """Close trace.""" - Returns the trace string or None if not tracing. - """ + global TraceFile, Tracing - log(f'Trace.dtrace: self.tracing={self.tracing}') - result = None +# TraceFile.close() + TraceFile = None + Tracing = False - if self.tracing: - if address is None: - result = '%s: %s\t' % (ddot, opcode) - else: - result = '%04o: %s\t%5.5o' % (ddot, opcode, address) +def deimtrace(opcode, code): + """Trace the DEIM instruction. - log(f"dtrace: result='{result}'") - return result + opcode DEIM opcode + code the operation + """ - def itrace(self, dot, opcode, indirect=False, address=None): - """Main CPU trace. + log(f"deimtrace: Tracing={Tracing}, writing '{opcode} {code}'") + if Tracing: + TraceFile.write('%s\t%s\t' % (opcode, code)) + TraceFile.flush() - dot address of instruction being traced - opcode the main CPU opcode - indirect True if instruction was indirect - address address for the instruction (if any) +def dtrace(ddot, opcode, address=None): + """Trace the display CPU. - Returns the trace string or None if not tracing. - """ + ddot address of instruction being traced + opcode display opcode + address address for the opcode -# log(f'Trace.itrace: self.tracing={self.tracing}, self.trace_map={self.trace_map}') - result = None + Returns the trace string or None if not tracing. + """ - if self.tracing and self.trace_map[dot]: - char = '*' if indirect else '' - if address is None: - result = '%04o\t%s\t%s' % (dot, opcode, char) - else: - result = '%04o\t%s\t%s%5.5o' % (dot, opcode, char, address) + log(f'Trace.dtrace: Tracing={Tracing}') + result = None - return result + if Tracing: + if address is None: + result = '%s: %s\t' % (ddot, opcode) + else: + result = '%04o: %s\t%5.5o' % (ddot, opcode, address) - def itraceend(self, dispon): - """Trace at the end of one execution cycle. + log(f"dtrace: result='{result}'") + DCPUInst = result + return result - dispon True if the display was on +def itrace(dot, opcode, indirect=False, address=None): + """Main CPU trace. - Returns the trace string. - """ + dot address of instruction being traced + opcode the main CPU opcode + indirect True if instruction was indirect + address address for the instruction (if any) - result = ('L=%1.1o AC=%6.6o PC=%6.6o' - % (self.cpu.L, self.cpu.AC, self.cpu.PC)) + Returns the trace string or None if not tracing. + """ - if dispon: - result += ' DX=%5.5o DY=%5.5o' % (self.dcpu.DX, self.dcpu.DY) + result = None - return result + if Tracing and TraceMap[dot]: + char = '*' if indirect else '' + if address is None: + result = '%04o\t%s\t%s' % (dot, opcode, char) + else: + result = '%04o\t%s\t%s%5.5o' % (dot, opcode, char, address) - def flush(self): - self.tracefile.flush() + log(f"itrace: result='{result}'") + CPUInst = result + return result - def comment(self, msg): - """Write a line to the trace file.""" +def itraceend(dispon): + """Trace at the end of one execution cycle. - msg = bytes(msg+'\n', 'utf-8') - self.tracefile.write(msg) - self.tracefile.flush() + dispon True if the display was on - def settrace(self, new_tracing): - """Set the trace ON or OFF.""" + Returns the trace string. + """ - self.tracing = new_tracing - log(f'Trace.settrace: self.tracing={new_tracing}') + result = ('L=%1.1o AC=%6.6o PC=%6.6o' % (CPU.L, CPU.AC, CPU.PC)) + + if dispon: + result += ' DX=%5.5o DY=%5.5o' % (DCPU.DX, DCPU.DY) + + return result + +def end_line(): + """Write the line for this set of I/D instructions.""" + + registers = ('L=%1.1o AC=%6.6o PC=%6.6o' % (CPU.L, CPU.AC, CPU.PC)) + + if DCPU.Running: + registers += ' DX=%5.5o DY=%5.5o' % (DCPU.DX, DCPU.DY) + + CPUInst = None + DCPUInst = None + + #TraceFile.write(f'{CPUInst:-50s}{DCPUInst:-40s} {registers}\n') + TraceFile.write('%-50s %-40s %s\n' % (CPUInst, DCPUInst, registers)) + +#def flush(self): +# TraceFile.flush() + +def comment(msg): + """Write a line to the trace file.""" + + TraceFile.write(msg + '\n') + TraceFile.flush() + +def settrace(new_tracing): + """Set the trace ON or OFF.""" + + global Tracing + + Tracing = new_tracing + log(f'Trace.settrace: Tracing={Tracing}') diff --git a/pymlac/pymlac b/pymlac/pymlac index e441aa4..d8a02f3 100755 --- a/pymlac/pymlac +++ b/pymlac/pymlac @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ -A simulator for an Imlac PDS-1 or PDS-4. +A simulator for an Imlac PDS-1. Usage: pymlac [