#!/usr/bin/env python # -*- coding: utf-8 -*- """ Import an imlac binary file. """ import sys import getopt import struct import wx import mem import disasmdata # address where next word will be loaded into memory Dot = 0 # dictionary of memory 'chunks' # {: [word1, word2, ...], ...} Memory = {} # size of memory configured MemSize = 04000 # size of block loader LoaderSize = 0100 def doblockloader(f, word, mymem): """Read block loader into high memory. f file handle to read from word the word we have already read mymem Mem() object to store loader in """ ldaddr = MemSize - LoaderSize numwords = LoaderSize - 1 # have already read one word in mymem.add(ldaddr, word) while numwords > 0: word = readword(f) #JUST SKIP OVER, DON'T PUT INTO MEMORY # mymem.add(ldaddr, word) ldaddr += 1 numwords = numwords - 1 def calc_checksum(csum, word): """Calculate new checksum from word value. csum old checksum value word new word to include in checksum Returns the new checksum value. """ csum += word # if csum & 0xffff: # # add got overflow # csum = (csum & 0xffff) + 1 return csum & 0xffff def pyword(word): """Convert a 16bit value to a real python integer. That is, convert 0xFFFF to -1. """ byte = (word >> 8) & 0xff byte2 = word & 0xff bstr = chr(byte) + chr(byte2) return struct.unpack(">h", bstr)[0] def dobody(f, mymem): """Read all of file after block loader. f input file handle mymem the mem.Mem() dict to store data in Returns an updated mem.Mem() object containing the input code and a start address: (mem, start, ac) If a start address is not specified, 'start' and 'ac' are both None. If there was a checksum error, just return None. """ start_address = None while True: # negative load address is end-of-file ldaddr = readword(f) if ldaddr & 0x8000: break # read data block, calculating checksum csum = ldaddr # start checksum with base address count = pyword(readword(f)) neg_count = pyword(count) csum = (csum + count) & 0xffff # add neg word count csum_word = readword(f) csum = (csum + csum_word) & 0xffff # add checksum word while neg_count < 0: word = readword(f) csum = (csum + word) & 0xffff mymem.add(ldaddr, word) (op, fld) = disasmdata.disasmdata(word) mymem.putOp(ldaddr, op) mymem.putFld(ldaddr, fld) ldaddr += 1 neg_count += 1 csum &= 0xffff if csum != 0: wx.MessageBox('Checksum error, got %06o, expected 0' % csum, 'Warning', wx.OK | wx.ICON_WARNING) # check for real start address if ldaddr != 0177777: # actual start address ac = readword(f) return (mymem, ldaddr & 0x7ffff, ac) return (mymem, None, None) def ptpimport(file): global Dot try: f = open(file, "rb") except IOError as e: print e return 3 # create Mem() object to store data mymem = mem.Mem() Dot = 0 # find and read the block loader byte = skipzeros(f) word = (byte << 8) + readbyte(f) doblockloader(f, word, mymem) # now read all the data blocks result = dobody(f, mymem) if result is None: return (mymem, None, None) return result def readbyte(f): global Dot try: byte = f.read(1) except IOError as e: print e sys.exit(10) except EOFError as e: print e sys.exit(11) Dot += 1 if len(byte) > 0: val = struct.unpack("B", byte) return val[0] else: return 0 def readword(f, first_byte=None): """Return the next word from the input file. f handle of the input file first_byte value of first byte of word Convert 16bit values to python integers """ if first_byte is None: first_byte = readbyte(f) return (first_byte << 8) + readbyte(f) def skipzeros(f): while True: val = readbyte(f) if val > 0: return val if __name__ == "__main__": result = ptpimport('40tp_simpleDisplay.ptp') if result is None: print('Error reading input file.') sys.exit(10) (themem, start, ac) = result print('str(dir(themem))=%s' % str(dir(themem))) if start is not None: print('start=%06o, ac=%06o' % (start, ac)) else: print('start=None, ac=None') addrlist = themem.keys() addrlist.sort() for addr in addrlist: (word, cycle, type, lab, ref) = mymem[addr] print "%s %s: %05o" % (addr, type, word)