diff --git a/idasm/binimport.py b/idasm/binimport.py index 90f426d..0e65f98 100755 --- a/idasm/binimport.py +++ b/idasm/binimport.py @@ -67,38 +67,56 @@ def dobody(f, mymem): f input file handle mymem the mem.Mem() dict to store data in - Returns an updated mem.Mem() object containing the input code. + 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. """ - numwords = skipzeros(f) + start_address = None + while True: # negative load address is end-of-file ldaddr = readword(f) + print('read: ldaddr=%06o' % ldaddr) if ldaddr & 0x8000: + print('End load: ldaddr=%06o' % ldaddr) break # read data block, calculating checksum - csum = 0 - #csum = ldaddr - while numwords > 0: + csum = ldaddr # start checksum with base address + print('BLOCK: ldaddr=%06o, csum=%06o' % (ldaddr, csum)) + neg_count = readword(f) + csum = (csum + neg_count) & 0xffff # add neg word count + print(' neg_count=%06o (%d), csum=%06o' % (neg_count, -neg_count, csum)) + csum_word = readword(f) + csum = (csum + csum_word) & 0xffff # add checksum word + print(' csum_word=%06o, csum=%06o' % (csum_word, csum)) + while neg_count < 0: word = readword(f) - csum += word - csum &= 0xffff + csum = (csum + word) & 0xffff + print(' word=%06o, csum=%06o' % (word, csum)) mymem.add(ldaddr, word) (op, fld) = disasmdata.disasmdata(word) mymem.putOp(ldaddr, op) mymem.putFld(ldaddr, fld) ldaddr += 1 - numwords -= 1 + numwords += 1 csum &= 0xffff - checksum = readword(f) - if csum != checksum: + if csum != 0: #wx.MessageBox('Checksum error', 'Error', wx.OK | wx.ICON_ERROR) - wx.MessageBox('Checksum error', 'Warning', wx.OK | wx.ICON_WARNING) -# return None - numwords = skipzeros(f) + print('Checksum error, csum=%06o, expected 0' % csum) + wx.MessageBox('Checksum error, got %06o, expected 0' % csum, 'Warning', wx.OK | wx.ICON_WARNING) - return mymem + # 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 @@ -120,9 +138,11 @@ def ptpimport(file): doblockloader(f, word, mymem) # now read all the data blocks - mymem = dobody(f, mymem) + result = dobody(f, mymem) + if result is None: + return (mymem, None, None) - return mymem + return result def readbyte(f): global Dot @@ -142,8 +162,17 @@ def readbyte(f): else: return 0 -def readword(f): - return (readbyte(f) << 8) + readbyte(f) +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 + """ + + if first_byte is None: + return (readbyte(f) << 8) + readbyte(f) + + return (first_byte << 8) + readbyte(f) def skipzeros(f): while True: @@ -153,11 +182,17 @@ def skipzeros(f): if __name__ == "__main__": - themem = ptpimport('40tp_simpleDisplay.ptp') - if themem is None: + 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() diff --git a/idasm/idasm b/idasm/idasm index 243c7cd..d018f1d 100755 --- a/idasm/idasm +++ b/idasm/idasm @@ -487,8 +487,9 @@ class MyFrame(wx.Frame): if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetPaths()[0] self.grid.ClearGrid() - mem = binimport.ptpimport(filename) - if mem is not None: + result = binimport.ptpimport(filename) + if result is not None: + (mem, start, ac) = result fillGrid(grid, mem) projectName = os.path.basename(filename) if projectName.endswith(DEFPTPSUFFIX): @@ -496,6 +497,9 @@ class MyFrame(wx.Frame): self.enableSaveWrite(True) mem.clearUndo() self.enableUndo(False) + if start is not None: + # mark start address as MAIN instructions + self.do_main_start(start) dlg.Destroy() @@ -541,12 +545,16 @@ class MyFrame(wx.Frame): mem.undoX() fillGrid(grid, mem) + def do_main_start(self, start): + """Mark start address as MAIN opcodes.""" + + print('do_main_start: start=%06o' % start) class MyApp(wx.App): def OnInit(self): global frame - wx.InitAllImageHandlers() + #wx.InitAllImageHandlers() frame = MyFrame(None, -1, "") self.SetTopWindow(frame) frame.Show() diff --git a/pyasm/pyasm b/pyasm/pyasm index 24b47a51..5c271f9 100755 --- a/pyasm/pyasm +++ b/pyasm/pyasm @@ -75,6 +75,9 @@ BlockBufferBase = None # base address of the block # mask for 16bit values WordMask = 0xFFFF +# high bit in 16-bit word +HighBit = 0x8000 + # the output PTP filename extension PTPExtension = '.ptp' @@ -237,7 +240,7 @@ BlockLoader = [ # ; integers, incrementing the sum whenever the 16bit value overflows. # ; # ; The end of the load is signalled by a block with a - # ; starting address 0177777. + # ; starting address WordMask. # ; # ; Disassembled from the 40tp_simpleDisplay.ptp image file. # ; @@ -267,7 +270,7 @@ BlockLoader = [ 0102001, # 003725 asn ; 0013746, # 003726 jmp newblk ;if same, get next block 0000000, # 003727 hlt ;if not same, ERROR - 0177777, # 003730 neg1 data 0177777 ; + WordMask, # 003730 neg1 data WordMask ; # ;------------------------ # ;Compute checksum. Word to sum in AC. # ;------------------------ @@ -367,17 +370,18 @@ def write_word(word): write_byte(word >> 8) write_byte(word) -def write_endload(): - """Write the special 'end of load' block.""" +def write_start(address, ac=None): + """Write the start block. - write_byte(1) - write_word(0xffff) + Add the AC contents word if passed. + """ -def write_start(address): - """Write the start block.""" + if ac is None: + ac = 0 - start_block(address) - write_block() + write_word(address + HighBit) + if address != 0 and ac is not None: + write_word(ac & WordMask) def write_leader(size=ZeroLeaderSize): """Write the papertape leader.""" @@ -393,8 +397,6 @@ def write_block_loader(): for word in BlockLoader: write_word(word) - write_leader() - def start_block(addr): """Prepare next block to start at 'addr'""" @@ -426,15 +428,17 @@ def write_block(): # block buffer is empty, do nothing return - # emit the block size and load address - write_byte(code_block_size) + # emit the block size and data word count (negated) write_word(BlockBufferBase) - for word in BlockBuffer: - write_word(word) + write_word((~code_block_size+1) & WordMask) # calculate and write the checksum - checksum = sum(BlockBuffer) & WordMask - write_word(checksum) + checksum = (BlockBufferBase + ((~code_block_size+1) & WordMask) + sum(BlockBuffer)) + write_word((~checksum+1) & WordMask) + + # finally, write out data words + for word in BlockBuffer: + write_word(word) # reset the code buffer start_block(None) @@ -774,9 +778,8 @@ def pass_2(lines): # write the final block of code and optional start address write_block() -# if StartAddress is not None: -# write_start(StartAddress) - write_endload() + if StartAddress is not None: + write_start(StartAddress, ac=0177777) write_leader() # check nothing after END diff --git a/pyasm/test.asm b/pyasm/test.asm index 5f86ddc..2ac2037 100644 --- a/pyasm/test.asm +++ b/pyasm/test.asm @@ -3,4 +3,4 @@ start hlt - end + end start