diff --git a/idasm/loadptp.py b/idasm/loadptp.py index ee455b8..6e95bd8 100755 --- a/idasm/loadptp.py +++ b/idasm/loadptp.py @@ -24,6 +24,15 @@ MemSize = 04000 # size of block loader LoaderSize = 0100 +# True if debug code is active +Debug = False + + +def debug(msg): + """Debug message, but only if global Debug is True.""" + + if Debug: + print(msg) def pyword(word): """Convert a 16bit value to a real python integer. @@ -148,10 +157,10 @@ def c8lds_handler(ptp_data, memory): The example on the last page of the doc has a example tape containing: 004 000770 001061 100011 023775 037765 165054 - 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, modulo 177777. + The 'checksum' is not well defined in the documentation which says: the + checksum is the sum of all the contents modulo 077777. Yet the example tape + has a checksum of 0165054. It is assumed the doc is in error and the + checksum 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. @@ -159,7 +168,7 @@ def c8lds_handler(ptp_data, memory): Note that we DO need an 'end of load' block of three bytes at the end of the tape: - 001 # 1 data word (any non-zero value will do) + 377 # number of data words (any non-zero value will do) 0177777 # a block load address of 0177777 """ @@ -169,24 +178,22 @@ def c8lds_handler(ptp_data, memory): index = skipzeros(ptp_data, index) if index is None: # empty tape + debug('c8lds: No leader?') return None index = read_blockloader(ptp_data, index, memory) if index is None: # short block loader? + debug('c8lds: Short leader?') return None # now read data blocks while True: - # skip any leading zeros -# index = skipzeros(ptp_data, index) -# if index is None: -# return (None, None) # end of tape - # get data word count result = get_byte(ptp_data, index) if result is None: # premature end of tape? + debug('c8lds: EOT at start of block?') return None (count, index) = result @@ -194,6 +201,7 @@ def c8lds_handler(ptp_data, memory): result = get_word(ptp_data, index) if result is None: # premature end of tape? + debug('c8lds: EOT getting load address?') return None (address, index) = result if address == 0177777: @@ -206,28 +214,35 @@ def c8lds_handler(ptp_data, memory): result = get_word(ptp_data, index) if result is None: # premature end of tape? + debug('c8lds: EOT getting data word?') return None (data, index) = result memory[address] = data address += 1 checksum += data - if checksum != (checksum & 0177777): - checksum = (checksum & 0177777) + 1 + checksum = checksum & 0177777 # check block checksum result = get_word(ptp_data, index) if result is None: # premature end of tape? + debug('c8lds: EOT getting checksum?') return None (ptp_checksum, index) = result if ptp_checksum != checksum: # bad checksum + debug('c8lds: Bad checksum? Read %06o, expected %06o.' % (ptp_checksum, checksum)) return None # no auto-start mechanism, so return (None, None) +def lc16sd_add_csum(csum, word): + """Add 'csum' and 'word', return new checksum.""" + + result = (csum + word) & 0xffff + return result def lc16sd_handler(ptp_data, memory): """Load blocks according to the ... @@ -244,6 +259,10 @@ def lc16sd_handler(ptp_data, memory): a checksum word (16bits) one or more data words (16bits) + The checksum is computed such that the sum of the load address, complemented + word count, the checksum itself and all data words will be zero, modulo + 0177777. + If the load address word is negative the load is finished. The load address with the high bit removed is the actual start address. The following word is the value put into the AC just before start. @@ -260,23 +279,21 @@ def lc16sd_handler(ptp_data, memory): index = skipzeros(ptp_data, index) if index is None: # empty tape + debug('lc16sd: No leader?') return None index = read_blockloader(ptp_data, index, memory) if index is None: # short block loader? + debug('lc16sd: Short blockloader?') return None # now read data blocks while True: -# # skip leading zeros, if any -# index = skipzeros(ptp_data, index) -# if index is None: -# break - # get this block load address result = get_word(ptp_data, index) if result is None: + debug('lc16sd: EOT getting load address?') return None # premature end of tape? (address, index) = result # if block load address has high bit set, we are finished @@ -286,6 +303,7 @@ def lc16sd_handler(ptp_data, memory): # we have an autostart result = get_word(ptp_data, index) if result is None: + debug('lc16sd: EOT getting AC value for autostart?') return None # premature end of tape? (start_ac, index) = result return (address & 0x7ffff, start_ac) @@ -294,32 +312,40 @@ def lc16sd_handler(ptp_data, memory): # read data block, calculating checksum csum = address # start checksum with base address + debug('lc16sd: address=%06o' % address) result = get_word(ptp_data, index) if result is None: + debug('lc16sd: EOT getting word count?') return None # premature end of tape? (count, index) = result - count = pyword(count) neg_count = pyword(count) - csum = (csum + count) & 0xffff # add neg word count + debug('lc16sd: count=%06o, neg_count=%d' % (count, neg_count)) + csum = lc16sd_add_csum(csum, neg_count) result = get_word(ptp_data, index) if result is None: + debug('lc16sd: EOT getting checksum?') return None # premature end of tape? (csum_word, index) = result - csum = (csum + csum_word) & 0xffff # add checksum word + debug('lc16sd: csum_word=%06o' % csum_word) + old_csum = csum + csum = lc16sd_add_csum(csum, csum_word) while neg_count < 0: result = get_word(ptp_data, index) if result is None: + debug('lc16sd: EOT getting data word?') return None # premature end of tape? (word, index) = result - csum = (csum + word) & 0xffff + debug('lc16sd: data word=%06o' % word) + old_csum = csum + csum = lc16sd_add_csum(csum, word) memory[address] = word address += 1 neg_count += 1 - csum &= 0xffff if csum != 0: - return None # bad block checlsum + debug('lc16sd: Bad checksum, sum is %06o, expected 0?' % csum) + return None # bad block checksum # if we return here there is no autostart return (None, None) diff --git a/pyasm/Makefile b/pyasm/Makefile index 41d558a..2b8a2b4 100644 --- a/pyasm/Makefile +++ b/pyasm/Makefile @@ -7,9 +7,13 @@ test: python test_pyasm.py debug: - pyasm -o default_TEST.ptp test2.asm - pyasm -b c8lds -o c8lds_TEST.ptp test2.asm - pyasm -b lc16sd -o lc16sd_TEST.ptp test2.asm + rm -Rf default_TEST.lst c8lds_TEST.lst lc16sd_TEST.lst default_TEST.ptp c8lds_TEST.ptp lc16sd_TEST.ptp + pyasm -l default_TEST.lst -o default_TEST.ptp test2.asm + pyasm -b c8lds -l c8lds_TEST.lst -o c8lds_TEST.ptp test2.asm + pyasm -b lc16sd -l lc16sd_TEST.lst -o lc16sd_TEST.ptp test2.asm + @../idasm/loadptp.py default_TEST.ptp + @../idasm/loadptp.py c8lds_TEST.ptp + @../idasm/loadptp.py lc16sd_TEST.ptp run: python pyasm test.asm diff --git a/pyasm/pyasm b/pyasm/pyasm index 69ee17d..93655fb 100755 --- a/pyasm/pyasm +++ b/pyasm/pyasm @@ -414,7 +414,6 @@ BlockLoader_LC16SD = [ 0017702, # 03775 himem DATA 0017702 ; 0010000, # 03776 DATA 0010000 ; 0177777, # 03777 DATA 0177777 ; - 0000000, # 04000 DATA 0000000 ; # # END ; ] @@ -551,8 +550,6 @@ def write_block_c8lds(): is the sum of all the data words, modulo 177777. """ - global BlockBuffer, BlockBufferBase - code_block_size = len(BlockBuffer) if code_block_size == 0: # block buffer is empty, do nothing @@ -576,8 +573,6 @@ def write_block_c8lds(): def write_block_lc16sd(): """Write the current code block and reset the buffer.""" - global BlockBuffer, BlockBufferBase - code_block_size = len(BlockBuffer) if code_block_size == 0: # block buffer is empty, do nothing @@ -589,8 +584,9 @@ def write_block_lc16sd(): write_word(neg_size) # calculate and write the checksum - checksum = BlockBufferBase + neg_size + sum(BlockBuffer) - write_word((~checksum+1) & WordMask) + checksum = (BlockBufferBase + neg_size + sum(BlockBuffer)) & WordMask + tape_checksum = (~checksum+1) & WordMask + write_word(tape_checksum) # finally, write out data words for word in BlockBuffer: @@ -643,7 +639,8 @@ def eval_expr(expr): Undefined = e.message if 'is not defined' in e.message: Undefined = e.message[len("name '"):-len("' is not defined")] - error("ORG pseudo-opcode expression has '%s' undefined" % Undefined) + msg = "ORG pseudo-opcode expression has '%s' undefined" % Undefined + raise NameError(msg) error("ORG pseudo-opcode expression has an error") return result @@ -653,7 +650,7 @@ def num_gen_words(opcode, addr): if opcode: # we assume opcode will return 1 - # TODO has to changed when macros are implemented + # TODO has to change when macros are implemented return 1 return 0