diff --git a/pymlac/Display.py b/pymlac/Display.py index 638e739..fcaa6b6 100644 --- a/pymlac/Display.py +++ b/pymlac/Display.py @@ -76,13 +76,13 @@ class Display(object): filename = 'pymlac_%06d.ppm' % self.next_file_num with open(filename, 'wb') as handle: # output header data - handle.write('P1\n') - handle.write('# created by pymlac %s\n' % __version__) - handle.write('%d %d\n' % (self.ScaleMaxX, self.ScaleMaxY)) + handle.write(bytes('P1\n', 'utf-8')) + handle.write(bytes('# created by pymlac %s\n' % __version__, 'utf-8')) + handle.write(bytes('%d %d\n' % (self.ScaleMaxX, self.ScaleMaxY), 'utf-8')) # output graphics data for v in self.array: - handle.write('%d\n' % v) + handle.write(bytes('%d\n' % v, 'utf-8')) self.dirty = False diff --git a/pymlac/DisplayCPU.py b/pymlac/DisplayCPU.py index 554815b..fc9d068 100644 --- a/pymlac/DisplayCPU.py +++ b/pymlac/DisplayCPU.py @@ -28,17 +28,17 @@ log = log.Log('test.log', log.Log.DEBUG) MSBBITS = 6 LSBBITS = 5 -MSBMASK = 03740 -LSBMASK = 037 +MSBMASK = 0o3740 +LSBMASK = 0o37 class DisplayCPU(object): # mask for display address - DMASK = 03777 # full 11 bits of display addressing - BITS10 = 01777 # AC bits that set DX or DY - DMSB = 03740 - DLSB = 037 + DMASK = 0o3777 # full 11 bits of display addressing + BITS10 = 0o1777 # AC bits that set DX or DY + DMSB = 0o3740 + DLSB = 0o37 # display CPU constants - modes MODE_NORMAL = 0 @@ -82,11 +82,11 @@ class DisplayCPU(object): 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 + if byte == 0o111: result += 'N' + elif byte == 0o151: result += 'R' + elif byte == 0o171: result += 'F' + elif byte == 0o200: result += 'P' + else: result += 'A%3.3o' % byte return result def doDEIMByte(self, byte, last=False): @@ -168,16 +168,16 @@ class DisplayCPU(object): return (1, tracestr) opcode = instruction >> 12 - address = instruction & 007777 + address = instruction & 0o07777 - 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) + if opcode == 0o00: return self.page00(instruction) + elif opcode == 0o01: return self.i_DLXA(address) + elif opcode == 0o02: return self.i_DLYA(address) + elif opcode == 0o03: return self.i_DEIM(address) + elif opcode == 0o04: return self.i_DLVH(address) + elif opcode == 0o05: return self.i_DJMS(address) + elif opcode == 0o06: return self.i_DJMP(address) + elif opcode == 0o07: self.illegal(instruction) else: self.illegal(instruction) def illegal(self, instruction=None): @@ -193,18 +193,18 @@ class DisplayCPU(object): return self.Running def i_DDXM(self): - self.DX -= 040 + self.DX -= 0o40 tracestr = trace.dtrace(self.dot, 'DDXM', None) return (1, tracestr) def i_DDYM(self): - self.DY -= 040 + self.DY -= 0o40 tracestr = trace.dtrace(self.dot, 'DDYM', None) return (1, tracestr) def i_DEIM(self, address): self.Mode = self.MODE_DEIM - tracestr = 'DEIM\t' + self.doDEIMByte(address & 0377, last=True) + tracestr = 'DEIM\t' + self.doDEIMByte(address & 0o377, last=True) return (1, tracestr) def i_DHLT(self): @@ -215,11 +215,11 @@ class DisplayCPU(object): return (1, trace.dtrace(self.dot, 'DHVC', None)) def i_DIXM(self): - self.DX += 04000 + self.DX += 0o4000 return (1, trace.dtrace(self.dot, 'DIXM', None)) def i_DIYM(self): - self.DY += 04000 + self.DY += 0o4000 return (1, trace.dtrace(self.dot, 'DIYM', None)) def i_DJMP(self, address): @@ -250,14 +250,14 @@ class DisplayCPU(object): word3 = self.memory.get(self.DPC, 0) self.DPC = MASK_MEM(self.DPC + 1) - dotted = word2 & 040000 - beamon = word2 & 020000 - negx = word3 & 040000 - negy = word3 & 020000 - ygtx = word3 & 010000 + dotted = word2 & 0o40000 + beamon = word2 & 0o20000 + negx = word3 & 0o40000 + negy = word3 & 0o20000 + ygtx = word3 & 0o10000 - M = word2 & 007777 - N = word3 & 007777 + M = word2 & 0o07777 + N = word3 & 0o07777 prevDX = self.DX prevDY = self.DY @@ -312,34 +312,34 @@ class DisplayCPU(object): return (1, trace.dtrace('DSTS\t%d' % scale, None)) # FIXME check # cycles used def page00(self, instruction): - if instruction == 000000: # DHLT + if instruction == 0o00000: # DHLT (cycles, tracestr) = self.i_DHLT() - elif instruction == 004000: # DNOP + elif instruction == 0o04000: # DNOP cycles = 1 tracestr = trace.dtrace('DNOP') - elif instruction == 004004: # DSTS 0 + elif instruction == 0o04004: # DSTS 0 (cycles, tracestr) = self.i_DSTS(0) - elif instruction == 004005: # DSTS 1 + elif instruction == 0o04005: # DSTS 1 (cycles, tracestr) = self.i_DSTS(1) - elif instruction == 004006: # DSTS 2 + elif instruction == 0o04006: # DSTS 2 (cycles, tracestr) = self.i_DSTS(2) - elif instruction == 004007: # DSTS 3 + elif instruction == 0o04007: # DSTS 3 (cycles, tracestr) = self.i_DSTS(3) - elif instruction == 004010: # DSTB 0 + elif instruction == 0o04010: # DSTB 0 (cycles, tracestr) = self.i_DSTB(0) - elif instruction == 004011: # DSTB 1 + elif instruction == 0o04011: # DSTB 1 (cycles, tracestr) = self.i_DSTB(1) - elif instruction == 004040: # DRJM + elif instruction == 0o04040: # DRJM (cycles, tracestr) = self.i_DRJM() - elif instruction == 004100: # DDYM + elif instruction == 0o04100: # DDYM (cycles, tracestr) = self.i_DDYM() - elif instruction == 004200: # DDXM + elif instruction == 0o04200: # DDXM (cycles, tracestr) = self.i_DDXM() - elif instruction == 004400: # DIYM + elif instruction == 0o04400: # DIYM (cycles, tracestr) = self.i_DIYM() - elif instruction == 005000: # DIXM + elif instruction == 0o05000: # DIXM (cycles, tracestr) = self.i_DIXM() - elif instruction == 006000: # DHVC + elif instruction == 0o06000: # DHVC (cycles, tracestr) = self.i_DHVC() else: self.illegal(instruction) diff --git a/pymlac/Globals.py b/pymlac/Globals.py index d6673f4..9340c8c 100644 --- a/pymlac/Globals.py +++ b/pymlac/Globals.py @@ -23,7 +23,7 @@ CANVAS_HEIGHT = 1024 # 'core' size (words) and save filename CORE_FILENAME = 'pymlac.core' #MEMORY_SIZE = 040000 # 16K words memory size -MEMORY_SIZE = 04000 # 2K words memory size - while debugging +MEMORY_SIZE = 0o4000 # 2K words memory size - while debugging # removes some block address bugs PCMASK = MEMORY_SIZE - 1 @@ -46,7 +46,7 @@ OVERFLOWMASK = 0xffff0000 WORDMASK = 0xffff HIGHBITMASK = 0x8000 #ADDRMASK = 0x7fff -ADDRMASK = 037777 +ADDRMASK = 0o37777 # global instruction cycle counter #instruction_cycles = 0 @@ -67,6 +67,6 @@ def MASK_MEM(address): # A function to decide if an address is an auto-increment address def ISAUTOINC(address): - maskaddr = address & 03777 - return (maskaddr >= 010) and (maskaddr <= 017) + maskaddr = address & 0o3777 + return (maskaddr >= 0o10) and (maskaddr <= 0o17) diff --git a/pymlac/MainCPU.py b/pymlac/MainCPU.py index b647b06..e8de1bf 100644 --- a/pymlac/MainCPU.py +++ b/pymlac/MainCPU.py @@ -58,110 +58,110 @@ class MainCPU(object): self.ptrptp = ptrptp # main dispatch dictionary for decoding opcodes in bits 1-4 - self.main_decode = {000: self.page_00, # secondary decode - 001: self.i_LAW_LWC, - 002: self.i_JMP, - # 003: self.illegal, - 004: self.i_DAC, - 005: self.i_XAM, - 006: self.i_ISZ, - 007: self.i_JMS, - # 010: self.illegal - 011: self.i_AND, - 012: self.i_IOR, - 013: self.i_XOR, - 014: self.i_LAC, - 015: self.i_ADD, - 016: self.i_SUB, - 017: self.i_SAM} + self.main_decode = {0o00: self.page_00, # secondary decode + 0o01: self.i_LAW_LWC, + 0o02: self.i_JMP, + # 0o03: self.illegal, + 0o04: self.i_DAC, + 0o05: self.i_XAM, + 0o06: self.i_ISZ, + 0o07: self.i_JMS, + # 0o10: self.illegal + 0o11: self.i_AND, + 0o12: self.i_IOR, + 0o13: self.i_XOR, + 0o14: self.i_LAC, + 0o15: self.i_ADD, + 0o16: self.i_SUB, + 0o17: self.i_SAM} # page_00 dispatch dictionary for decoding opcodes # HLT may be handled specially - self.page_00_decode = {001003: self.i_DLA, - 001011: self.i_CTB, - 001012: self.i_DOF, - 001021: self.i_KRB, - 001022: self.i_KCF, - 001023: self.i_KRC, - 001031: self.i_RRB, - 001032: self.i_RCF, - 001033: self.i_RRC, - 001041: self.i_TPR, - 001042: self.i_TCF, - 001043: self.i_TPC, - 001051: self.i_HRB, - 001052: self.i_HOF, - 001061: self.i_HON, - 001062: self.i_STB, - 001071: self.i_SCF, - 001072: self.i_IOS, - 001101: self.i_IOT101, - 001111: self.i_IOT111, - 001131: self.i_IOT131, - 001132: self.i_IOT132, - 001134: self.i_IOT134, - 001141: self.i_IOT141, - 001161: self.i_IOF, - 001162: self.i_ION, - 001271: self.i_PPC, - 001274: self.i_PSF, - # 003000: self.illegal RAL0 - 003001: self.i_RAL1, - 003002: self.i_RAL2, - 003003: self.i_RAL3, - # 003020: self.illegal RAR0, - 003021: self.i_RAR1, - 003022: self.i_RAR2, - 003023: self.i_RAR3, - # 003040: self.illegal SAL0, - 003041: self.i_SAL1, - 003042: self.i_SAL2, - 003043: self.i_SAL3, - # 003060: self.illegal SAR0, - 003061: self.i_SAR1, - 003062: self.i_SAR2, - 003063: self.i_SAR3, - 003100: self.i_DON} + self.page_00_decode = {0o01003: self.i_DLA, + 0o01011: self.i_CTB, + 0o01012: self.i_DOF, + 0o01021: self.i_KRB, + 0o01022: self.i_KCF, + 0o01023: self.i_KRC, + 0o01031: self.i_RRB, + 0o01032: self.i_RCF, + 0o01033: self.i_RRC, + 0o01041: self.i_TPR, + 0o01042: self.i_TCF, + 0o01043: self.i_TPC, + 0o01051: self.i_HRB, + 0o01052: self.i_HOF, + 0o01061: self.i_HON, + 0o01062: self.i_STB, + 0o01071: self.i_SCF, + 0o01072: self.i_IOS, + 0o01101: self.i_IOT101, + 0o01111: self.i_IOT111, + 0o01131: self.i_IOT131, + 0o01132: self.i_IOT132, + 0o01134: self.i_IOT134, + 0o01141: self.i_IOT141, + 0o01161: self.i_IOF, + 0o01162: self.i_ION, + 0o01271: self.i_PPC, + 0o01274: self.i_PSF, + # 0o03000: self.illegal RAL0 + 0o03001: self.i_RAL1, + 0o03002: self.i_RAL2, + 0o03003: self.i_RAL3, + # 0o03020: self.illegal RAR0, + 0o03021: self.i_RAR1, + 0o03022: self.i_RAR2, + 0o03023: self.i_RAR3, + # 0o03040: self.illegal SAL0, + 0o03041: self.i_SAL1, + 0o03042: self.i_SAL2, + 0o03043: self.i_SAL3, + # 0o03060: self.illegal SAR0, + 0o03061: self.i_SAR1, + 0o03062: self.i_SAR2, + 0o03063: self.i_SAR3, + 0o03100: self.i_DON} - self.page02_decode = {0002001: self.i_ASZ, - 0102001: self.i_ASN, - 0002002: self.i_ASP, - 0102002: self.i_ASM, - 0002004: self.i_LSZ, - 0102004: self.i_LSN, - 0002010: self.i_DSF, - 0102010: self.i_DSN, - 0002020: self.i_KSF, - 0102020: self.i_KSN, - 0002040: self.i_RSF, - 0102040: self.i_RSN, - 0002100: self.i_TSF, - 0102100: self.i_TSN, - 0002200: self.i_SSF, - 0102200: self.i_SSN, - 0002400: self.i_HSF, - 0102400: self.i_HSN} + self.page02_decode = {0o002001: self.i_ASZ, + 0o102001: self.i_ASN, + 0o002002: self.i_ASP, + 0o102002: self.i_ASM, + 0o002004: self.i_LSZ, + 0o102004: self.i_LSN, + 0o002010: self.i_DSF, + 0o102010: self.i_DSN, + 0o002020: self.i_KSF, + 0o102020: self.i_KSN, + 0o002040: self.i_RSF, + 0o102040: self.i_RSN, + 0o002100: self.i_TSF, + 0o102100: self.i_TSN, + 0o002200: self.i_SSF, + 0o102200: self.i_SSN, + 0o002400: self.i_HSF, + 0o102400: self.i_HSN} - self.micro_opcodes = {0100000: 'NOP', - 0100001: 'CLA', - 0100002: 'CMA', - 0100003: 'STA', - 0100004: 'IAC', - 0100005: 'COA', - 0100006: 'CIA', - 0100010: 'CLL', - 0100011: 'CAL', - 0100020: 'CML', - 0100030: 'STL', - 0100040: 'ODA', - 0100041: 'LDA'} + self.micro_opcodes = {0o100000: 'NOP', + 0o100001: 'CLA', + 0o100002: 'CMA', + 0o100003: 'STA', + 0o100004: 'IAC', + 0o100005: 'COA', + 0o100006: 'CIA', + 0o100010: 'CLL', + 0o100011: 'CAL', + 0o100020: 'CML', + 0o100030: 'STL', + 0o100040: 'ODA', + 0o100041: 'LDA'} - self.micro_singles = {0100001: 'CLA', - 0100002: 'CMA', - 0100004: 'IAC', - 0100010: 'CLL', - 0100020: 'CML', - 0100040: 'ODA'} + self.micro_singles = {0o100001: 'CLA', + 0o100002: 'CMA', + 0o100004: 'IAC', + 0o100010: 'CLL', + 0o100020: 'CML', + 0o100040: 'ODA'} self.running = False @@ -189,9 +189,9 @@ class MainCPU(object): self.PC = MASK_MEM(self.PC + 1) # get instruction opcode, indirect bit and address - opcode = (instruction >> 11) & 017 - indirect = bool(instruction & 0100000) - address = (instruction & 03777) + opcode = (instruction >> 11) & 0o17 + indirect = bool(instruction & 0o100000) + address = (instruction & 0o3777) return self.main_decode.get(opcode, self.illegal)(indirect, address, @@ -208,9 +208,9 @@ class MainCPU(object): raise RuntimeError(msg) def page_00(self, indirect, address, instruction): - if (instruction & 0077700) == 000000: + if (instruction & 0o077700) == 0o00000: return self.microcode(instruction) - elif (instruction & 0077000) == 002000: + elif (instruction & 0o077000) == 0o02000: return self.page02_decode.get(instruction, self.illegal)() return self.page_00_decode.get(instruction, self.illegal)(indirect, @@ -310,24 +310,24 @@ class MainCPU(object): def microcode(self, instruction): # T1 - if instruction & 001: + if instruction & 0o01: self.AC = 0 - if instruction & 010: + if instruction & 0o10: self.L = 0 # T2 - if instruction & 002: + if instruction & 0o02: self.AC = (~self.AC) & WORDMASK - if instruction & 020: + if instruction & 0o20: self.L = 0 if self.L else 1 # T3 - if instruction & 004: + if instruction & 0o04: self.AC += 1 if self.AC & OVERFLOWMASK: self.L = 0 if self.L else 1 self.AC &= WORDMASK - if instruction & 040: + if instruction & 0o40: self.AC |= self.DS # do some sort of trace @@ -338,7 +338,7 @@ class MainCPU(object): if not combine: # nothing so far, we have HLT or unknown microcode - if not instruction & 0100000: + if not instruction & 0o100000: # bit 0 is clear, it's HLT self.running = False combine.append('HLT') @@ -558,21 +558,21 @@ class MainCPU(object): def i_SAL1(self, indirect, address, instruction): high_bit = self.AC & HIGHBITMASK - value = self.AC & 037777 + value = self.AC & 0o37777 self.AC = (value << 1) | high_bit 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 & 017777 + value = self.AC & 0o17777 self.AC = (value << 2) | high_bit 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 & 007777 + value = self.AC & 0o07777 self.AC = (value << 3) | high_bit tracestr = trace.itrace(self.dot, 'SAL', False, 3) return (1, tracestr) diff --git a/pymlac/Memory.py b/pymlac/Memory.py index 35fba3c..b53a002 100644 --- a/pymlac/Memory.py +++ b/pymlac/Memory.py @@ -17,101 +17,102 @@ log = log.Log('test.log', log.Log.DEBUG) class Memory(object): - ROM_START = 040 - ROM_SIZE = 040 + ROM_START = 0o40 + ROM_SIZE = 0o40 ROM_END = ROM_START + ROM_SIZE - 1 # this PTR bootstrap from "Loading The PDS-1" (loading.pdf) - PTR_ROM_IMAGE = [ # org 040 - 0060077, # start lac base ;40 get load address - 0020010, # dac 010 ;41 put into auto-inc reg - 0104076, # lwc 076 ;42 -0100+1 into AC - 0020020, # dac 020 ;43 put into memory - 0001061, # hon ;44 start PTR - 0100011, # wait cal ;45 clear AC+LINK - 0002400, # hsf ;46 skip if PTR has data - 0010046, # jmp .-1 ;47 wait until is data - 0001051, # hrb ;50 read PTR -> AC - 0074075, # sam what ;51 skip if AC == 2 - 0010045, # jmp wait ;52 wait until PTR return 0 - 0002400, # loop hsf ;53 skip if PTR has data - 0010053, # jmp .-1 ;54 wait until is data - 0001051, # hrb ;55 read PTR -> AC - 0003003, # ral 3 ;56 move byte into high AC - 0003003, # ral 3 ;57 - 0003002, # ral 2 ;60 - 0102400, # hsn ;61 wait until PTR moves - 0010061, # jmp .-1 ;62 - 0002400, # hsf ;63 skip if PTR has data - 0010063, # jmp .-1 ;64 wait until is data - 0001051, # hrb ;65 read PTR -> AC - 0120010, # dac *010 ;66 store word, inc pointer - 0102400, # hsn ;67 wait until PTR moves - 0010067, # jmp .-1 ;70 - 0100011, # cal ;71 clear AC & LINK - 0030020, # isz 020 ;72 inc mem and skip zero - 0010053, # jmp loop ;73 if not finished, jump - 0110076, # jmp *go ;74 execute loader - 0000002, # what data 2 ;75 - 0003700, # go data 03700 ;76 - 0003677, # base data 03677 ;77 + PTR_ROM_IMAGE = [ # org 040 + 0o060077, # start lac base ;40 get load address + 0o020010, # dac 010 ;41 put into auto-inc reg + 0o104076, # lwc 076 ;42 -0100+1 into AC + 0o020020, # dac 020 ;43 put into memory + 0o001061, # hon ;44 start PTR + 0o100011, # wait cal ;45 clear AC+LINK + 0o002400, # hsf ;46 skip if PTR has data + 0o010046, # jmp .-1 ;47 wait until is data + 0o001051, # hrb ;50 read PTR -> AC + 0o074075, # sam what ;51 skip if AC == 2 + 0o010045, # jmp wait ;52 wait until PTR return 0 + 0o002400, # loop hsf ;53 skip if PTR has data + 0o010053, # jmp .-1 ;54 wait until is data + 0o001051, # hrb ;55 read PTR -> AC + 0o003003, # ral 3 ;56 move byte into high AC + 0o003003, # ral 3 ;57 + 0o003002, # ral 2 ;60 + 0o102400, # hsn ;61 wait until PTR moves + 0o010061, # jmp .-1 ;62 + 0o002400, # hsf ;63 skip if PTR has data + 0o010063, # jmp .-1 ;64 wait until is data + 0o001051, # hrb ;65 read PTR -> AC + 0o120010, # dac *010 ;66 store word, inc pointer + 0o102400, # hsn ;67 wait until PTR moves + 0o010067, # jmp .-1 ;70 + 0o100011, # cal ;71 clear AC & LINK + 0o030020, # isz 020 ;72 inc mem and skip zero + 0o010053, # jmp loop ;73 if not finished, jump + 0o110076, # jmp *go ;74 execute loader + 0o000002, # what data 2 ;75 + 0o003700, # go data 03700 ;76 + 0o003677, # base data 03677 ;77 ] TTY_ROM_IMAGE_TEST = [ #00040 0001: org 040 -0100001, #00040 0002: loop cla ; clear AC -0001031, #00041 0003: rrb ; IOR tty input -> AC -0010040, #00042 0004: jmp loop ; keep going - # 0005: end +0o100001, #00040 0002: loop cla ; clear AC +0o001031, #00041 0003: rrb ; IOR tty input -> AC +0o010040, #00042 0004: jmp loop ; keep going + # 0005: end ] + # TTY ROM image from "Loading The PDS-1" (loading.pdf) TTY_ROM_IMAGE = [ - # 0001: ;------------------------ - # 0002: ; TTY bootstrap code from images/imlacdocs/loading.pdf - # 0003: ;------------------------ - # 0004: ; - #37700 0005: bladdr equ 037700 ; address of top mem minus 0100 - #00100 0006: blsize equ 0100 ; size of blockloader code - # 0007: ; - #00040 0008: ORG 040 ; - # 0009: ; -0060077, #00040 0010: LAC staddr ; -0020010, #00041 0011: DAC 010 ; 010 points to loading word -0104076, #00042 0012: LWC blsize-2; -0020020, #00043 0013: DAC 020 ; 020 is ISZ counter of loader size - # 0014: ; skip all bytes until the expected byte -0001032, #00044 0015: skpzer RCF ; -0100011, #00045 0016: CAL ; -0002040, #00046 0017: RSF ; wait for next byte -0010046, #00047 0018: JMP .-1 ; -0001031, #00050 0019: RRB ; get next TTY byte -0074075, #00051 0020: SAM fbyte ; wait until it's the expected byte -0010044, #00052 0021: JMP skpzer ; -0002040, #00053 0022: nxtwrd RSF ; wait until TTY byte ready -0010053, #00054 0023: JMP .-1 ; -0001033, #00055 0024: RRC ; get high byte and clear flag -0003003, #00056 0025: RAL 3 ; shift into AC high byte -0003003, #00057 0026: RAL 3 ; -0003002, #00060 0027: RAL 2 ; -0002040, #00061 0028: RSF ; wait until next TTY byte -0010061, #00062 0029: JMP .-1 ; -0001033, #00063 0030: RRC ; get low byte and clear flag -0120010, #00064 0031: DAC *010 ; store word -0100011, #00065 0032: CAL ; clear AC ready for next word -0030020, #00066 0033: ISZ 020 ; finished? -0010053, #00067 0034: JMP nxtwrd ; jump if not -0110076, #00070 0035: JMP *blstrt ; else execute the blockloader - # 0036: ; -0000000, #00071 0037: DATA 000000 ; empty space? -0000000, #00072 0038: DATA 000000 ; -0000000, #00073 0039: DATA 000000 ; -0000000, #00074 0040: DATA 000000 ; - # 0041: ; -0000002, #00075 0042: fbyte DATA 000002 ; expected first byte of block loader -0037700, #00076 0043: blstrt data bladdr ; start of blockloader code -0037677, #00077 0044: staddr data bladdr-1; ISZ counter for blockloader size - # 0045: ; - # 0046: END ; + # 0001: ;------------------------ + # 0002: ; TTY bootstrap code from images/imlacdocs/loading.pdf + # 0003: ;------------------------ + # 0004: ; + #37700 0005: bladdr equ 037700 ; address of top mem minus 0100 + #00100 0006: blsize equ 0100 ; size of blockloader code + # 0007: ; + #00040 0008: ORG 040 ; + # 0009: ; +0o060077, #00040 0010: LAC staddr ; +0o020010, #00041 0011: DAC 010 ; 010 points to loading word +0o104076, #00042 0012: LWC blsize-2 ; +0o020020, #00043 0013: DAC 020 ; 020 is ISZ counter of loader size + # 0014: ; skip all bytes until the expected byte +0o001032, #00044 0015: skpzer RCF ; +0o100011, #00045 0016: CAL ; +0o002040, #00046 0017: RSF ; wait for next byte +0o010046, #00047 0018: JMP .-1 ; +0o001031, #00050 0019: RRB ; get next TTY byte +0o074075, #00051 0020: SAM fbyte ; wait until it's the expected byte +0o010044, #00052 0021: JMP skpzer ; +0o002040, #00053 0022: nxtwrd RSF ; wait until TTY byte ready +0o010053, #00054 0023: JMP .-1 ; +0o001033, #00055 0024: RRC ; get high byte and clear flag +0o003003, #00056 0025: RAL 3 ; shift into AC high byte +0o003003, #00057 0026: RAL 3 ; +0o003002, #00060 0027: RAL 2 ; +0o002040, #00061 0028: RSF ; wait until next TTY byte +0o010061, #00062 0029: JMP .-1 ; +0o001033, #00063 0030: RRC ; get low byte and clear flag +0o120010, #00064 0031: DAC *010 ; store word +0o100011, #00065 0032: CAL ; clear AC ready for next word +0o030020, #00066 0033: ISZ 020 ; finished? +0o010053, #00067 0034: JMP nxtwrd ; jump if not +0o110076, #00070 0035: JMP *blstrt ; else execute the blockloader + # 0036: ; +0o000000, #00071 0037: DATA 000000 ; empty space? +0o000000, #00072 0038: DATA 000000 ; +0o000000, #00073 0039: DATA 000000 ; +0o000000, #00074 0040: DATA 000000 ; + # 0041: ; +0o000002, #00075 0042: fbyte DATA 000002 ; expected first byte of block loader +0o037700, #00076 0043: blstrt data bladdr ; start of blockloader code +0o037677, #00077 0044: staddr data bladdr-1 ; ISZ counter for blockloader size + # 0045: ; + # 0046: END ; ] # class instance variables @@ -243,7 +244,7 @@ class Memory(object): if ISAUTOINC(address): self.memory[address] += 1 address = self.memory[MASK_MEM(address)] - indirect = bool(address & 0100000) + indirect = bool(address & 0o100000) return self.memory[MASK_MEM(address)] @@ -265,7 +266,7 @@ class Memory(object): # assume we are addressing out of memory limits msg = 'Bad memory address: %06o' % address raise IndexError(msg) - indirect = bool(address & 0100000) + indirect = bool(address & 0o100000) return address diff --git a/pymlac/PtrPtp.py b/pymlac/PtrPtp.py index 28513be..9255ae7 100644 --- a/pymlac/PtrPtp.py +++ b/pymlac/PtrPtp.py @@ -27,7 +27,7 @@ class PtrPtp(object): PtpNotReadyCycles = int(CYCLES_PER_SECOND / PtpCharsPerSecond) # no tape in reader, return 0377 (all holes see light) - PtrEOF = 0377 + PtrEOF = 0xff # module-level state variables device_use = None diff --git a/pymlac/Trace.py b/pymlac/Trace.py index 5a37621..4a9a21c 100644 --- a/pymlac/Trace.py +++ b/pymlac/Trace.py @@ -40,7 +40,8 @@ class Trace(object): except: pass self.tracefile = open(filename, 'wb') - self.tracefile.write('%s trace\n%s\n' % (PYMLAC_VERSION, '-'*60)) + s = bytes('%s trace\n%s\n' % (PYMLAC_VERSION, '-'*60), 'utf-8') + self.tracefile.write(s) self.cpu = maincpu self.dcpu = displaycpu diff --git a/pymlac/pymlac b/pymlac/pymlac index 32a26b9..b5d7f4a 100755 --- a/pymlac/pymlac +++ b/pymlac/pymlac @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- """