with open(lzss_unpack_fwd_bin, 'rb') as fin:
lzss_unpack_fwd = list(fin.read())
-def lzss_pack(dest, bin):
+def lzss_pack(dest, bin, rev):
+ if rev:
+ bin = bin[::-1] # makes it easier to construct LZSS items
+
heads = {}
links = [-1] * len(bin)
lzss = []
i += 1
# checking
- #bin1 = []
- #lzss1 = lzss[::-1]
- #while len(lzss1):
- # _len, dist = lzss1.pop()
- # if _len == 1:
- # bin1.append(dist)
- # else:
- # for i in range(_len):
- # bin1.append(bin1[-dist])
- #assert bin == bin1
+ bin1 = []
+ lzss1 = lzss[::-1]
+ while len(lzss1):
+ _len, dist = lzss1.pop()
+ if _len == 1:
+ bin1.append(dist)
+ else:
+ for i in range(_len):
+ bin1.append(bin1[-dist])
+ assert bin == bin1
# construct the real output in reverse to how it will be decoded,
# this means we flush the bits at the right time for the decoder,
elif _len < (1 << LEN_BITS1) and dist < (1 << DIST_BITS1):
item = dist | (_len << DIST_BITS1)
#print('c', item)
- lzss1.extend([item >> 8, item & 0xff])
+ # keep the 16-bit words in little-endian order in memory,
+ # means swapping them if the output will be reversed later
+ lzss1.extend(
+ [item & 0xff, item >> 8]
+ if rev else
+ [item >> 8, item & 0xff]
+ )
cf = 1
else:
assert False
lzss1.append(bits & 0xff)
bits = 1
count += 1
- lzss = lzss1[::-1]
+ lzss = lzss1
# checking
- #bin1 = []
- #lzss1 = lzss[::-1]
- #count1 = count
- #bits1 = bits
- #while True:
- # if bits1 == 1:
- # if count1 == 0:
- # break
- # count1 -= 1
- # bits1 = lzss1.pop() | 0x100
- # #print('e', bits1)
- # cf = bits1 & 1
- # bits1 >>= 1
- #
- # if cf:
- # if bits1 == 1:
- # bits1 = lzss1.pop() | 0x100
- # #print('d', bits1)
- # cf = bits1 & 1
- # bits1 >>= 1
- #
- # if cf:
- # item = lzss1[-1] | (lzss1[-2] << 8)
- # del lzss1[-2:]
- # #print('c', item)
- # dist = item & ((1 << DIST_BITS1) - 1)
- # _len = item >> DIST_BITS1
- # else:
- # item = lzss1.pop()
- # #print('b', item)
- # dist = item & ((1 << DIST_BITS0) - 1)
- # _len = item >> DIST_BITS0
- # _len += 2
- # dist += 1
- #
- # for i in range(_len):
- # bin1.append(bin1[-dist])
- # else:
- # #print('a', lzss1[-1])
- # bin1.append(lzss1.pop())
- #assert len(lzss1) == 0
- #assert bin1 == bin
+ bin1 = []
+ lzss1 = list(lzss)
+ count1 = count
+ bits1 = bits
+ while True:
+ if bits1 == 1:
+ if count1 == 0:
+ break
+ count1 -= 1
+ bits1 = lzss1.pop() | 0x100
+ #print('e', bits1)
+ cf = bits1 & 1
+ bits1 >>= 1
+
+ if cf:
+ if bits1 == 1:
+ bits1 = lzss1.pop() | 0x100
+ #print('d', bits1)
+ cf = bits1 & 1
+ bits1 >>= 1
+
+ if cf:
+ # keep the 16-bit words in little-endian order in memory,
+ # means swapping them if the output will be reversed later
+ item = (
+ lzss1[-2] | (lzss1[-1] << 8)
+ if rev else
+ lzss1[-1] | (lzss1[-2] << 8)
+ )
+ del lzss1[-2:]
+ #print('c', item)
+ dist = item & ((1 << DIST_BITS1) - 1)
+ _len = item >> DIST_BITS1
+ else:
+ item = lzss1.pop()
+ #print('b', item)
+ dist = item & ((1 << DIST_BITS0) - 1)
+ _len = item >> DIST_BITS0
+ _len += 2
+ dist += 1
+
+ for i in range(_len):
+ bin1.append(bin1[-dist])
+ else:
+ #print('a', lzss1[-1])
+ bin1.append(lzss1.pop())
+ assert len(lzss1) == 0
+ assert bin1 == bin
# optimization: provided the input is not null, the first byte
# has to be literal, so the loader can fall straight into the
if bits == 1:
assert count
count -= 1
- bits = lzss.pop(0) | 0x100
+ bits = lzss.pop() | 0x100
assert (bits & 1) == 0
bits >>= 1
- # prepend data block
+ # LZSS data has been reversed by stackwise encoding method
+ # change it back if needed and put the data block on correct end
count ^= 0xffff # inc/test is easier than test/dec
- return [dest & 0xff, dest >> 8, count & 0xff, count >> 8, bits] + lzss
+ data_block = [dest & 0xff, dest >> 8, count & 0xff, count >> 8, bits]
+ if rev:
+ # append data block
+ lzss.extend(data_block)
+ else:
+ # prepend data block
+ lzss.extend(data_block[::-1])
+ lzss = lzss[::-1]
+ return lzss
intelhex = IntelHex(in_ihx)
entry_point = intelhex.start_addr['EIP']
else:
addr2 = len(section_payload.data)
section_payload.data.extend(
- lzss_pack(addr0, data)
+ lzss_pack(addr0, data, False)
)
addr3 = len(section_payload.data)
report.append(
with open(lzss_unpack_rev_bin, 'rb') as fin:
lzss_unpack_rev = list(fin.read())
-def lzss_pack(dest, bin):
- bin = bin[::-1] # !!! for rev, makes it easier to construct LZSS items
+def lzss_pack(dest, bin, rev):
+ if rev:
+ bin = bin[::-1] # makes it easier to construct LZSS items
heads = {}
links = [-1] * len(bin)
elif _len < (1 << LEN_BITS1) and dist < (1 << DIST_BITS1):
item = dist | (_len << DIST_BITS1)
#print('c', item)
- lzss1.extend([item & 0xff, item >> 8]) # !!! swapped for rev
+ # keep the 16-bit words in little-endian order in memory,
+ # means swapping them if the output will be reversed later
+ lzss1.extend(
+ [item & 0xff, item >> 8]
+ if rev else
+ [item >> 8, item & 0xff]
+ )
cf = 1
else:
assert False
lzss1.append(bits & 0xff)
bits = 1
count += 1
- lzss = lzss1 # !!! not reversed for rev
+ lzss = lzss1
# checking
bin1 = []
- lzss1 = list(lzss) # !!! not reversed for rev
+ lzss1 = list(lzss)
count1 = count
bits1 = bits
while True:
bits1 >>= 1
if cf:
- item = lzss1[-2] | (lzss1[-1] << 8) # !!! swapped for rev
+ # keep the 16-bit words in little-endian order in memory,
+ # means swapping them if the output will be reversed later
+ item = (
+ lzss1[-2] | (lzss1[-1] << 8)
+ if rev else
+ lzss1[-1] | (lzss1[-2] << 8)
+ )
del lzss1[-2:]
#print('c', item)
dist = item & ((1 << DIST_BITS1) - 1)
if bits == 1:
assert count
count -= 1
- bits = lzss.pop() | 0x100 # !!! from end for rev
+ bits = lzss.pop() | 0x100
assert (bits & 1) == 0
bits >>= 1
- # append data block
+ # LZSS data has been reversed by stackwise encoding method
+ # change it back if needed and put the data block on correct end
count ^= 0xffff # inc/test is easier than test/dec
- return lzss + [dest & 0xff, dest >> 8, count & 0xff, count >> 8, bits]
+ data_block = [dest & 0xff, dest >> 8, count & 0xff, count >> 8, bits]
+ if rev:
+ # append data block
+ lzss.extend(data_block)
+ else:
+ # prepend data block
+ lzss.extend(data_block[::-1])
+ lzss = lzss[::-1]
+ return lzss
intelhex = IntelHex(in_ihx)
entry_point = intelhex.start_addr['EIP']
else:
addr3 = -len(section_payload.data)
section_payload.data.extend(
- lzss_pack(addr1 - 1, data)[::-1]
+ lzss_pack(addr1 - 1, data, True)[::-1]
)
addr2 = -len(section_payload.data)
report.append(