1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00
rzzzwilson.pymlac/idasm/binimport.py
2016-02-23 14:12:12 +07:00

230 lines
5.4 KiB
Python
Executable File

#!/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'
# {<base_address>: [word1, word2, ...], ...}
Memory = {}
# size of memory configured
MemSize = 04000
# size of block loader
LoaderSize = 0100
def doblockloader(f, word, mymem, save):
"""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
save True if blockloader is to be stored in 'mymem'
'mymem' is updated.
"""
ldaddr = MemSize - LoaderSize
print('doblockloader: word=%06o' % word)
mymem.add(ldaddr, word)
ldaddr += 1
numwords = LoaderSize - 1 # have already read one word in
mymem.add(ldaddr, word)
while numwords > 0:
word = readword(f)
print('doblockloader: word=%06o' % word)
if save:
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, save):
"""Read all of file after block loader.
f input file handle
mymem the mem.Mem() dict to store data in
save True if body code is to be saved in 'mymem'
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.
"""
if not save:
return (mymem, None, 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(filename, blockloader, code):
"""Import data from PTP file into memory.
filename the PTP file to read
blockloader True if blockloader is returned
code True if body code is returned
Returns a memory object containing blockloader data or body code
data, or both.
"""
global Dot
try:
f = open(filename, "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, save=blockloader)
# now read all the data blocks
result = dobody(f, mymem, save=code)
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)