mirror of
https://github.com/rzzzwilson/pymlac.git
synced 2025-06-10 09:32:41 +00:00
Debugging recognition of different blockloaders
This commit is contained in:
@@ -27,21 +27,28 @@ MemSize = 04000
|
||||
LoaderSize = 0100
|
||||
|
||||
|
||||
def doblockloader(f, word, mymem):
|
||||
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)
|
||||
#JUST SKIP OVER, DON'T PUT INTO MEMORY
|
||||
# mymem.add(ldaddr, word)
|
||||
print('doblockloader: word=%06o' % word)
|
||||
if save:
|
||||
mymem.add(ldaddr, word)
|
||||
ldaddr += 1
|
||||
numwords = numwords - 1
|
||||
|
||||
@@ -74,20 +81,23 @@ def pyword(word):
|
||||
return struct.unpack(">h", bstr)[0]
|
||||
|
||||
|
||||
def dobody(f, mymem):
|
||||
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)
|
||||
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:
|
||||
@@ -124,11 +134,21 @@ def dobody(f, mymem):
|
||||
|
||||
return (mymem, None, None)
|
||||
|
||||
def ptpimport(file):
|
||||
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(file, "rb")
|
||||
f = open(filename, "rb")
|
||||
except IOError as e:
|
||||
print e
|
||||
return 3
|
||||
@@ -141,10 +161,10 @@ def ptpimport(file):
|
||||
# find and read the block loader
|
||||
byte = skipzeros(f)
|
||||
word = (byte << 8) + readbyte(f)
|
||||
doblockloader(f, word, mymem)
|
||||
doblockloader(f, word, mymem, save=blockloader)
|
||||
|
||||
# now read all the data blocks
|
||||
result = dobody(f, mymem)
|
||||
result = dobody(f, mymem, save=code)
|
||||
if result is None:
|
||||
return (mymem, None, None)
|
||||
|
||||
|
||||
75
idasm/idasm
75
idasm/idasm
@@ -338,9 +338,14 @@ class MyFrame(wx.Frame):
|
||||
self.saveAsMenuitem = fileMenu.Append(102, "Save Project As ...", \
|
||||
"Save disassembly project to new file")
|
||||
fileMenu.AppendSeparator()
|
||||
fileMenu.Append(103, "Import Binary File", \
|
||||
"Import an Imlac binary file")
|
||||
self.writeASMMenuitem = fileMenu.Append(104, "Write Assembler", \
|
||||
fileMenu.Append(103, "Import PTP File",
|
||||
"Import all of an Imlac PTP file")
|
||||
fileMenu.Append(104, "Import only code of PTP File",
|
||||
"Import only code of an Imlac PTP file")
|
||||
fileMenu.Append(105, "Import only blockloader of PTP File",
|
||||
"Import only blockloader of an Imlac binary file")
|
||||
fileMenu.AppendSeparator()
|
||||
self.writeASMMenuitem = fileMenu.Append(109, "Write Assembler",
|
||||
"Write an assembler source file")
|
||||
fileMenu.AppendSeparator()
|
||||
fileMenu.Append(199, "Exit", "Exit the program")
|
||||
@@ -364,6 +369,8 @@ class MyFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.Menu102, id=102)
|
||||
self.Bind(wx.EVT_MENU, self.Menu103, id=103)
|
||||
self.Bind(wx.EVT_MENU, self.Menu104, id=104)
|
||||
self.Bind(wx.EVT_MENU, self.Menu105, id=105)
|
||||
self.Bind(wx.EVT_MENU, self.Menu109, id=109)
|
||||
self.Bind(wx.EVT_MENU, self.Menu199, id=199)
|
||||
|
||||
self.Bind(wx.EVT_MENU, self.Menu202, id=202)
|
||||
@@ -479,6 +486,8 @@ class MyFrame(wx.Frame):
|
||||
dlg.Destroy()
|
||||
|
||||
def Menu103(self, event):
|
||||
"""Choose PTP file to load blockloader and code from."""
|
||||
|
||||
global grid, mem, projectName
|
||||
|
||||
filename = None
|
||||
@@ -489,7 +498,7 @@ class MyFrame(wx.Frame):
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
filename = dlg.GetPath()
|
||||
self.grid.ClearGrid()
|
||||
result = binimport.ptpimport(filename)
|
||||
result = binimport.ptpimport(filename, blockloader=True, code=True)
|
||||
if result is not None:
|
||||
(mem, start, ac) = result
|
||||
fillGrid(grid, mem)
|
||||
@@ -506,6 +515,64 @@ class MyFrame(wx.Frame):
|
||||
|
||||
|
||||
def Menu104(self, event):
|
||||
"""Choose PTP file to load code from."""
|
||||
|
||||
global grid, mem, projectName
|
||||
|
||||
filename = None
|
||||
dlg = wx.FileDialog(self, message="Choose an IMLAC object file to load",
|
||||
defaultDir=os.getcwd(), defaultFile="",
|
||||
wildcard=objwildcard,
|
||||
style=wx.OPEN | wx.CHANGE_DIR)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
filename = dlg.GetPath()
|
||||
self.grid.ClearGrid()
|
||||
result = binimport.ptpimport(filename, blockloader=False, code=True)
|
||||
if result is not None:
|
||||
(mem, start, ac) = result
|
||||
fillGrid(grid, mem)
|
||||
projectName = os.path.basename(filename)
|
||||
if projectName.endswith(DEFPTPSUFFIX):
|
||||
projectName = projectName[:-len(DEFPTPSUFFIX)]
|
||||
self.enableSaveWrite(True)
|
||||
mem.clearUndo()
|
||||
self.enableUndo(False)
|
||||
if start:
|
||||
# mark start address as MAIN instructions
|
||||
self.do_main_start(start & 077777)
|
||||
dlg.Destroy()
|
||||
|
||||
|
||||
def Menu105(self, event):
|
||||
"""Choose PTP file to load blockloader from."""
|
||||
|
||||
global grid, mem, projectName
|
||||
|
||||
filename = None
|
||||
dlg = wx.FileDialog(self, message="Choose an IMLAC object file to load",
|
||||
defaultDir=os.getcwd(), defaultFile="",
|
||||
wildcard=objwildcard,
|
||||
style=wx.OPEN | wx.CHANGE_DIR)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
filename = dlg.GetPath()
|
||||
self.grid.ClearGrid()
|
||||
result = binimport.ptpimport(filename, blockloader=True, code=False)
|
||||
if result is not None:
|
||||
(mem, start, ac) = result
|
||||
fillGrid(grid, mem)
|
||||
projectName = os.path.basename(filename)
|
||||
if projectName.endswith(DEFPTPSUFFIX):
|
||||
projectName = projectName[:-len(DEFPTPSUFFIX)]
|
||||
self.enableSaveWrite(True)
|
||||
mem.clearUndo()
|
||||
self.enableUndo(False)
|
||||
if start:
|
||||
# mark start address as MAIN instructions
|
||||
self.do_main_start(start & 077777)
|
||||
dlg.Destroy()
|
||||
|
||||
|
||||
def Menu109(self, event):
|
||||
global mem, grid, projectName
|
||||
filename = None
|
||||
dlg = wx.FileDialog(self,
|
||||
|
||||
@@ -51,8 +51,6 @@ def get_byte(ptp_data, index):
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
# print('get_byte: %03o' % result)
|
||||
|
||||
return (result, index+1)
|
||||
|
||||
def get_word(ptp_data, index):
|
||||
@@ -80,7 +78,6 @@ def get_word(ptp_data, index):
|
||||
|
||||
|
||||
word = (first_byte << 8) + second_byte
|
||||
# print('get_word: %06o' % word)
|
||||
return (word, index)
|
||||
|
||||
def skipzeros(ptp_data, index):
|
||||
@@ -141,6 +138,7 @@ def c8lds_handler(ptp_data, memory):
|
||||
...
|
||||
data word 'count' (16 bits)
|
||||
checksum (16 bits)
|
||||
Note that a data block may be preceded by a zero leader.
|
||||
|
||||
The example on the last page of the doc has a example tape containing:
|
||||
004 000770 001061 100011 023775 037765 165054
|
||||
@@ -148,8 +146,9 @@ def c8lds_handler(ptp_data, memory):
|
||||
The 'checksum' is not well defined in the documentation: the checksum is
|
||||
the sum of all the contents modulo 077777. Yet the example tape has a
|
||||
checksum of 165054. It is assumed the doc is in error and the checksum
|
||||
is the sum of all the data words, module 177777.
|
||||
is the sum of all the data words, modulo 177777.
|
||||
|
||||
A load address of 0177777 indicates the end of the load.
|
||||
As there is no autostart mechanism, returns (None, None) on successful load.
|
||||
Returns None if there was nothing to load.
|
||||
"""
|
||||
@@ -160,11 +159,13 @@ def c8lds_handler(ptp_data, memory):
|
||||
index = skipzeros(ptp_data, index)
|
||||
if index is None:
|
||||
# empty tape
|
||||
print('empty tape')
|
||||
return None
|
||||
|
||||
index = read_blockloader(ptp_data, index, memory)
|
||||
if index is None:
|
||||
# short block loader?
|
||||
print('short blockloader?')
|
||||
return None
|
||||
|
||||
# now read data blocks
|
||||
@@ -173,23 +174,24 @@ def c8lds_handler(ptp_data, memory):
|
||||
index = skipzeros(ptp_data, index)
|
||||
if index is None:
|
||||
break
|
||||
print('start of data block at %05o' % index)
|
||||
|
||||
# get data word count
|
||||
result = get_byte(ptp_data, index)
|
||||
if result is None:
|
||||
# premature end of tape?
|
||||
print('EOT in block getting count?')
|
||||
return None
|
||||
(count, index) = result
|
||||
print('word count=%d (%03o)' % (count, count))
|
||||
|
||||
# get block load address
|
||||
result = get_word(ptp_data, index)
|
||||
if result is None:
|
||||
# premature end of tape?
|
||||
print('EOT in block getting load address?')
|
||||
return None
|
||||
(address, index) = result
|
||||
print('block load address=%05o' % address)
|
||||
if address == 0177777:
|
||||
break
|
||||
|
||||
# read data words, store in memory and calculate checksum
|
||||
checksum = 0
|
||||
@@ -197,26 +199,27 @@ def c8lds_handler(ptp_data, memory):
|
||||
result = get_word(ptp_data, index)
|
||||
if result is None:
|
||||
# premature end of tape?
|
||||
print('EOT in block getting data word?')
|
||||
return None
|
||||
(data, index) = result
|
||||
print('data word: %06o at address %05o' % (data, address))
|
||||
|
||||
memory[address] = data
|
||||
address += 1
|
||||
checksum = (checksum + data) & 0177777
|
||||
checksum += data
|
||||
if checksum != (checksum & 0177777):
|
||||
checksum = (checksum & 0177777) + 1
|
||||
|
||||
# check block checksum
|
||||
# checksum = checksum & 0177777
|
||||
result = get_word(ptp_data, index)
|
||||
if result is None:
|
||||
# premature end of tape?
|
||||
print('EOT')
|
||||
print('EOT in block getting checksum?')
|
||||
return None
|
||||
(ptp_checksum, index) = result
|
||||
print('ptp_checksum=%06o, checksum=%06o' % (ptp_checksum, checksum))
|
||||
if ptp_checksum != checksum:
|
||||
# bad checksum
|
||||
print('bad checksum')
|
||||
print('bad checksum, PTP checksum is %06o, expected %06o'
|
||||
% (ptp_checksum, checksum))
|
||||
return None
|
||||
|
||||
# no auto-start mechanism, so
|
||||
@@ -246,8 +249,6 @@ def lc16sd_handler(ptp_data, memory):
|
||||
Returns None if there was nothing to load.
|
||||
"""
|
||||
|
||||
# print('lc16sd_handler:')
|
||||
|
||||
index = 0
|
||||
|
||||
# skip initial zero leader
|
||||
@@ -269,7 +270,6 @@ def lc16sd_handler(ptp_data, memory):
|
||||
# break
|
||||
|
||||
# get this block load address
|
||||
# print('block load address')
|
||||
result = get_word(ptp_data, index)
|
||||
if result is None:
|
||||
return None # premature end of tape?
|
||||
@@ -283,12 +283,11 @@ def lc16sd_handler(ptp_data, memory):
|
||||
if result is None:
|
||||
return None # premature end of tape?
|
||||
(start_ac, index) = result
|
||||
return (address & 0x7ffff, ac)
|
||||
return (address & 0x7ffff, start_ac)
|
||||
else:
|
||||
return (None, None)
|
||||
|
||||
# read data block, calculating checksum
|
||||
# print('block word count')
|
||||
csum = address # start checksum with base address
|
||||
result = get_word(ptp_data, index)
|
||||
if result is None:
|
||||
@@ -298,7 +297,6 @@ def lc16sd_handler(ptp_data, memory):
|
||||
neg_count = pyword(count)
|
||||
csum = (csum + count) & 0xffff # add neg word count
|
||||
|
||||
# print('block checksum')
|
||||
result = get_word(ptp_data, index)
|
||||
if result is None:
|
||||
return None # premature end of tape?
|
||||
@@ -306,7 +304,6 @@ def lc16sd_handler(ptp_data, memory):
|
||||
csum = (csum + csum_word) & 0xffff # add checksum word
|
||||
|
||||
while neg_count < 0:
|
||||
# print('data word')
|
||||
result = get_word(ptp_data, index)
|
||||
if result is None:
|
||||
return None # premature end of tape?
|
||||
@@ -370,6 +367,8 @@ def load(filename, memory=None):
|
||||
print('%s: %s successful!' % (filename, name))
|
||||
return result
|
||||
|
||||
print('%s: not recognized!' % filename)
|
||||
|
||||
# if we get here, no loader was successful
|
||||
return None
|
||||
|
||||
@@ -386,7 +385,7 @@ if __name__ == '__main__':
|
||||
print('Usage: loadptp <filename>')
|
||||
sys.exit(10)
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
if len(sys.argv) < 2:
|
||||
usage()
|
||||
filename = sys.argv[1]
|
||||
load(filename)
|
||||
for filename in sys.argv[1:]:
|
||||
load(filename)
|
||||
|
||||
Reference in New Issue
Block a user