1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00

Fixing errors creating/checking checksum

This commit is contained in:
Ross Wilson
2016-03-01 15:06:28 +07:00
parent 85745ca220
commit 0fb8980c48
3 changed files with 62 additions and 35 deletions

View File

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

View File

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

View File

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