# draw_y0 + 1: for erasing
0x0012,0x0002,draw_y0,byte
0x0014,0x0002,video_line_ptr,word
+0x0016,0x0001,draw_misc_x_save,byte
# lo byte of (shift count * 0x80) + shape
# also y coordinate temporary storage
0x0017,0x0001,draw_temp,byte
0x7600,0x0380,shape_data_ptr_hi,byte
0x7980,0x0380,shape_width_bytes,byte
0x7d80,0x0080,shape_height,byte
+0x7e80,0x0001,draw_misc_data,byte
+0x8a80,0x0080,draw_misc_data_ptr_lo,byte
+0x8b00,0x0080,draw_misc_data_ptr_hi,byte
+0x8b80,0x0080,draw_misc_width_bytes,byte
+0x8c00,0x0080,draw_misc_height,byte
0x8cf1,0x0008,y_8cf1,byte
0x8d01,0x0008,velocity_hi_8d01,byte
0x8d11,0x0008,x_hi_8d11,byte
0x94e5,0x0001,,code_ign # accessing video_line_table before clipping y
0x94fe,0x0001,,code_ign # self-modifying code assembled with garbage word
0x94ff,0x0002,,word
+0x951c,0x0002,draw_misc_data_ptr_base,word
# draws over previous video contents
+# a = shape to draw
+# draw_x1 = x0 for drawing and is advanced by routine
0x951e,0x0001,draw_misc,code
0x955d,0x0001,,code_ign # self-modifying code assembled with garbage word
0x955e,0x0002,,word
print('reading addrs')
shape_tables = {}
shape_data_ptr_base = -1
+draw_misc_tables = {}
+draw_misc_data_ptr_base = -1
shapes = {}
with open(addrs_txt) as fin:
def get_line():
size = int(fields[1], 0)
name = fields[2]
_type = fields[3]
- if _type == 'byte' and name[:6] == 'shape_':
- shape_tables[name[6:]] = (addr, size // 0x80)
- elif _type == 'word' and name == 'shape_data_ptr_base':
- shape_data_ptr_base = addr
+ if _type == 'byte':
+ if name[:6] == 'shape_':
+ shape_tables[name[6:]] = (addr, size // 0x80)
+ elif name[:10] == 'draw_misc_':
+ draw_misc_tables[name[10:]] = (addr, size // 0x80)
+ elif _type == 'word':
+ if name == 'shape_data_ptr_base':
+ shape_data_ptr_base = addr
+ elif name == 'draw_misc_data_ptr_base':
+ draw_misc_data_ptr_base = addr
fields = get_line()
continue
while len(fields) >= 2:
fields = get_line()
assert shape_data_ptr_base != -1
+assert draw_misc_data_ptr_base != -1
print('reading ihx')
intelhex = IntelHex(in_ihx)
print('extracting')
data = []
-for i in range(0x80):
- name = f'shape_{i:02x}'
+for i in range(0x100):
+ name = f'shape_{i:02x}' if i < 0x80 else f'draw_misc_{i - 0x80:02x}'
if i in shapes:
name += '_' + shapes[i]
data.append({'name': name})
-i = 0
-shape_tables1 = list(shape_tables.items())
-while i < len(shape_tables1):
- if (
- i + 2 <= len(shape_tables1) and
- shape_tables1[i][0][-3:] == '_lo' and
- shape_tables1[i + 1][0][-3:] == '_hi'
- ):
- table, (addr_lo, shifts) = shape_tables1[i]
- _, (addr_hi, _) = shape_tables1[i + 1]
- table = table[:-3]
- for j in range(0x80):
- value = [
- intelhex[addr_lo + j + k * 0x80] |
- (intelhex[addr_hi + j + k * 0x80] << 8)
- for k in range(shifts)
- ]
- data[j][table] = [f'0x{k:04x}' for k in value]
- i += 2
- else:
- table, (addr, shifts) = shape_tables1[i]
- for j in range(0x80):
- value = [intelhex[addr + j + k * 0x80] for k in range(shifts)]
- data[j][table] = [str(k) for k in value]
- i += 1
+for base, tables in [(0, shape_tables), (0x80, draw_misc_tables)]:
+ i = 0
+ tables1 = list(tables.items())
+ while i < len(tables1):
+ if (
+ i + 2 <= len(tables1) and
+ tables1[i][0][-3:] == '_lo' and
+ tables1[i + 1][0][-3:] == '_hi'
+ ):
+ table, (data_ptr_lo, shifts) = tables1[i]
+ _, (data_ptr_hi, _) = tables1[i + 1]
+ table = table[:-3]
+ for j in range(0x80):
+ value = [
+ intelhex[data_ptr_lo + j + k * 0x80] |
+ (intelhex[data_ptr_hi + j + k * 0x80] << 8)
+ for k in range(shifts)
+ ]
+ data[base + j][table] = [f'0x{k:04x}' for k in value]
+ i += 2
+ else:
+ table, (data_ptr, shifts) = tables1[i]
+ for j in range(0x80):
+ value = [
+ intelhex[data_ptr + j + k * 0x80]
+ for k in range(shifts)
+ ]
+ data[base + j][table] = [str(k) for k in value]
+ i += 1
-for i in range(0x80):
- height = int(data[i]['height'][0], 0)
- addr0 = int(data[i]['data_ptr'][0], 0)
+for base, data_ptr_base in [
+ (
+ 0,
+ intelhex[shape_data_ptr_base] |
+ (intelhex[shape_data_ptr_base + 1] << 8)
+ ),
+ (
+ 0x80,
+ intelhex[draw_misc_data_ptr_base] |
+ (intelhex[draw_misc_data_ptr_base + 1] << 8)
+ )
+]:
+ for i in range(0x80):
+ height = int(data[base + i]['height'][0], 0)
+ width_bytes = [int(j, 0) for j in data[base + i]['width_bytes']]
+ data_ptr = [int(j, 0) for j in data[base + i]['data_ptr']]
- # only try to extract if pointers are sensible
- data1 = None
- addr = addr0
- for j in range(6):
- width_bytes = int(data[i]['width_bytes'][j], 0)
- addr += width_bytes * height
- if addr != int(data[i]['data_ptr'][j + 1], 0):
- break
- else:
- # good to go
- data1 = []
- addr = (
- addr0 +
- intelhex[shape_data_ptr_base] +
- (intelhex[shape_data_ptr_base + 1] << 8)
- )
- for j in range(7):
- width_bytes = int(data[i]['width_bytes'][j], 0)
- data1.append(
+ # only try to extract if data is sensible
+ data1 = None
+ if (
+ height >= 1 and
+ height < 46 and
+ all([j >= 1 and j < 40 for j in width_bytes]) and
+ all([j < 0x1000 for j in data_ptr])
+ ):
+ data1 = [
[
[
- f'0x{intelhex[addr + k * width_bytes + l]:02x}'
- for l in range(width_bytes)
+ f'0x{intelhex[data_ptr_base + data_ptr[j] + k * width_bytes[j] + l]:02x}'
+ for l in range(width_bytes[j])
]
for k in range(height)
]
- )
- addr += width_bytes * height
- data[i]['data'] = data1
+ for j in range(len(width_bytes))
+ ]
+ data[base + i]['data'] = data1
print('writing json')
with open(out_json, 'w') as fout: