1
0
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:
Ross Wilson
2016-02-23 14:12:12 +07:00
parent fbb67b7c74
commit 4b5708678c
3 changed files with 123 additions and 37 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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)