fout.write(f'draw_misc_table: ; {draw_misc_table:04x}\n')
dot = draw_misc_table
for i in range(0x20):
+ value = data[i]['value']
+
+ # entry < 8 (decimal) must be 4 strings of 1 character each
+ # an exception is in the case of null entries which are never drawn
+ assert i >= 8 or (
+ len(value) in [0, 4] and all([len(j['string']) == 1 for j in value])
+ )
+
addr1 = draw_misc_table + (i + 1) * 0x10
- for span in data[i]['value']:
+ for span in value:
x = span['x']
y = span['y']
string = span['string']
fout.write(f'\t.db\t{shape:s}\n')
dot += len(string)
assert dot <= addr1
+
if dot < addr1:
# don't use .ds here, as tiny holes in the .ihx file are annoying
fout.write('\t.db\t{0:s}\n'.format(','.join(['0'] * (addr1 - dot))))
for i in range(0x20):
addr0 = draw_misc_table + i * 0x10
addr1 = draw_misc_table + (i + 1) * 0x10
- name = draw_misc_entries.get(i)
+ name = f'decimal_{i:d}' if i < 8 else f'entry_{i:02x}'
+ if i in draw_misc_entries:
+ name += '_' + draw_misc_entries[i]
addr = addr0
value = []
UCODE_DRAW_MISC_MASK_6 = 0xc000
; sound effect
-UCODE_SOUND_EFFECT_0 = 0x0000
-UCODE_SOUND_EFFECT_1 = 0x0100
-UCODE_SOUND_EFFECT_2 = 0x0200
+UCODE_SOUND_EFFECT_0_SHIP_IMPACT = 0x0000
+UCODE_SOUND_EFFECT_1_BOMBS_EMPTY = 0x0100
+UCODE_SOUND_EFFECT_2_PLAYER_FIRE = 0x0200
UCODE_SOUND_EFFECT_3 = 0x0300
-UCODE_SOUND_EFFECT_4 = 0x0400
-UCODE_SOUND_EFFECT_5 = 0x0500
-UCODE_SOUND_EFFECT_6 = 0x0600
+UCODE_SOUND_EFFECT_4_TREE_IMPACT = 0x0400
+UCODE_SOUND_EFFECT_5_MISSION_COMPLETE = 0x0500
+UCODE_SOUND_EFFECT_6_MISSION_START = 0x0600
UCODE_SOUND_EFFECT_7 = 0x0700
-UCODE_SOUND_EFFECT_8 = 0x0800
-UCODE_SOUND_EFFECT_9 = 0x0900
-UCODE_SOUND_EFFECT_A = 0x0a00
-UCODE_SOUND_EFFECT_B = 0x0b00
-UCODE_SOUND_EFFECT_C = 0x0c00
-UCODE_SOUND_EFFECT_D = 0x0d00
-UCODE_SOUND_EFFECT_E = 0x0e00
-UCODE_SOUND_EFFECT_F = 0x0f00
+UCODE_SOUND_EFFECT_8_SUPPLIES_IMPACT = 0x0800
+UCODE_SOUND_EFFECT_9_HELICOPTER_IMPACT = 0x0900
+UCODE_SOUND_EFFECT_A_MISSILE_IMPACT = 0x0a00
+UCODE_SOUND_EFFECT_B_TANK_ENGINE = 0x0b00
+UCODE_SOUND_EFFECT_C_EXPLOSION = 0x0c00
+UCODE_SOUND_EFFECT_D_EXPLOSION = 0x0d00
+UCODE_SOUND_EFFECT_E_EXPLOSION = 0x0e00
+UCODE_SOUND_EFFECT_F_EXPLOSION = 0x0f00
; the following occur by themselves
j = int(i, 0)
if j in defs['byte-wide sections']:
i = defs['byte-wide sections'][j]
- #elif j in defs['objects']:
- # i = defs['objects'][j]
+ elif j in defs['objects']:
+ i = defs['objects'][j]
value.append(i)
return value
print(f'[{segments[i]:04x}, {segments[i + 1]:04x})')
print('extracting')
-data = [
- {'name': f'{i:02x}_{objects[i]}' if i in objects else None}
- for i in range(object0, object1)
-]
+data = []
+for i in range(object0, object1):
+ name = f'object_{i:02x}'
+ if i in objects:
+ name += '_' + objects[i]
+ data.append({'name': name})
for table, (addr, index0, index1, word) in object_tables.items():
i = bisect.bisect_right(segments, addr) - 1
table_data = [data[i][table] for i in range(0x100)]
if table == 'data_ptr' or table == 'size_bytes':
for i in range(0x100):
- name = data[i]['name']
- if name is not None:
+ if data[i]['data'] is not None:
+ name = data[i]['name']
size_bytes = int(data[i]['size_bytes'], 0)
if table == 'data_ptr':
- table_data[i] = 'shape_' + name
+ table_data[i] = name
if size_bytes:
width_bytes = int(data[i]['width_bytes'], 0)
height = int(data[i]['height'], 0)
# used for merging duplicate shape data
addrs = {}
for i in range(0x100):
- name = data[i]['name']
- if name is not None:
+ if data[i]['name'] is not None:
addr = int(data[i]['data_ptr'], 0)
if addr not in addrs:
addrs[addr] = []
# generate output
out = []
for i in range(0x100):
- name = data[i]['name']
- if name is not None:
- value = data[i]['data']
+ data1 = data[i]['data']
+ if data1 is not None:
+ name = data[i]['name']
addr = int(data[i]['data_ptr'], 0)
size_bytes = int(data[i]['size_bytes'], 0)
- text = f'shape_{name:s}: ; {max(addr - 3 * size_bytes, 0):04x}\n'
+ text = f'{name:s}: ; {max(addr - 3 * size_bytes, 0):04x}\n'
# only output data if different from next entry at same address
same_addr = addrs[addr]
j = same_addr.index(i) + 1
- if j >= len(same_addr) or data[same_addr[j]]['data'] != value:
+ if j >= len(same_addr) or data[same_addr[j]]['data'] != data1:
text += ''.join(
[
''.join(['\t.db\t{0:s}\n'.format(', '.join(k)) for k in j]) + '\n'
- for j in value
+ for j in data1
]
)
assert len(fields) == 2
index = int(fields[0], 0)
name = fields[1]
- # shape < 8 is a single pixel masked by the shape number
- # ignore these lines in addrs file unless --pixel requested
- if index >= 8 or pixel:
- shapes[index] = name
+ shapes[index] = name
fields = get_line()
continue
print(f'[{segments[i]:04x}, {segments[i + 1]:04x})')
print('extracting')
-data = [{'name': None} for i in range(0x100)]
+data = []
+for i in range(0x100):
+ name = f'shape_{i:02x}'
+ if i in shapes:
+ name += '_' + shapes[i]
+ data.append({'name': name})
i = 0
shape_tables1 = list(shape_tables.items())
data[j][table] = str(value)
i += 1
-# do this here so that item ordering is nicer in the json file
for i in range(0x100):
- data[i]['data'] = None
-
-for index, name in shapes.items():
- data[index]['name'] = f'{index:02x}_{name:s}'
-
# shape < 8 is a single pixel masked by the shape number
# transform the special data tables for pixel drawing into ordinary data
- if index < 8:
- data[index]['data_ptr'] = '0x0000' # make them be compiled first
- data[index]['width_bytes'] = '2'
- data[index]['height'] = '1'
- data[index]['size_bytes'] = '2'
- data[index]['width'] = '1'
+ data1 = None
+ if pixel and i < 8:
+ data[i]['data_ptr'] = '0x0000' # make them be compiled first
+ data[i]['width_bytes'] = '2'
+ data[i]['height'] = '1'
+ data[i]['size_bytes'] = '2'
+ data[i]['width'] = '1'
data_table_left = pixel_tables['data_table_left']
data_table_right = pixel_tables['data_table_right']
mask_table_left = pixel_tables['mask_table_left']
mask_table_right = pixel_tables['mask_table_right']
- value = [
+ data1 = [
[
[
- f'0x{intelhex[data_table_left + ((i * 2) % 7)] & intelhex[mask_table_left + index]:02x}',
- f'0x{intelhex[data_table_right + ((i * 2) % 7)] & intelhex[mask_table_right + index]:02x}'
+ f'0x{intelhex[data_table_left + ((j * 2) % 7)] & intelhex[mask_table_left + i]:02x}',
+ f'0x{intelhex[data_table_right + ((j * 2) % 7)] & intelhex[mask_table_right + i]:02x}'
]
]
- for i in range(7)
+ for j in range(7)
]
- else:
- addr = int(data[index]['data_ptr'], 0)
- height = int(data[index]['height'], 0)
- width_bytes = int(data[index]['width_bytes'], 0)
- size_bytes = int(data[index]['size_bytes'], 0)
- value = [
- [
+ else:
+ addr = int(data[i]['data_ptr'], 0)
+ if addr != 0x5d01: # strange sentinel value for never drawn shape
+ height = int(data[i]['height'], 0)
+ width_bytes = int(data[i]['width_bytes'], 0)
+ size_bytes = int(data[i]['size_bytes'], 0)
+ data1 = [
[
- f'0x{intelhex[addr + (i - 3) * size_bytes + j * width_bytes + k]:02x}'
- for k in range(width_bytes)
+ [
+ f'0x{intelhex[addr + (j - 3) * size_bytes + k * width_bytes + l]:02x}'
+ for l in range(width_bytes)
+ ]
+ for k in range(height)
]
- for j in range(height)
+ for j in range(7 if size_bytes else 1)
]
- for i in range(7 if size_bytes else 1)
- ]
- data[index]['data'] = value
+ data[i]['data'] = data1
print('writing json')
with open(out_json, 'w') as fout:
0x7f,draw_star_blazer_by_tony_suzuki
draw_misc_entries
-0x00,decimal_0_score
-0x01,decimal_1_high_score
-0x02,decimal_2
-0x03,decimal_3_mission
-0x04,decimal_4_fuel
-0x05,decimal_5_bomb
-0x06,decimal_6_ship_left
-0x07,decimal_7_bonus
-0x08,entry_08_score
-0x09,entry_09_high_score
-0x0a,entry_0a_scoring
-0x0b,entry_0b_ground
-0x0c,entry_0c_ground
-0x0d,entry_0d_ground
-0x0e,entry_0e_ground
-0x0f,entry_0f_fuel
-0x10,entry_10_bomb
-0x11,entry_11_ship_left
-0x12,entry_12_great_performance
-0x13,entry_13_complete
-0x14,entry_14_empty_fuel
-0x15,entry_15_copyright_1981_star_craft_inc
-0x16,entry_16_bonus
-0x17,entry_17_game_over
-0x18,entry_18_bomb_the_radar
-0x19,entry_19_attack_the_tank
-0x1a,entry_1a_bomb_the_icbm
-0x1b,entry_1b_scoring
-0x1c,entry_1c_bomb_the_headquarters
-0x1d,entry_1d_star_blazer
-0x1e,entry_1e_by_tony_suzuki
-0x1f,entry_1f_thanks_a_lot_comma_raly
+0x00,score
+0x01,high_score
+0x03,mission
+0x04,fuel
+0x05,bomb
+0x06,ship_left
+0x07,bonus
+0x08,score
+0x09,high_score
+0x0a,scoring
+0x0b,ground
+0x0c,ground
+0x0d,ground
+0x0e,ground
+0x0f,fuel
+0x10,bomb
+0x11,ship_left
+0x12,great_performance
+0x13,complete
+0x14,empty_fuel
+0x15,copyright_1981_star_craft_inc
+0x16,bonus
+0x17,game_over
+0x18,bomb_the_radar
+0x19,attack_the_tank
+0x1a,bomb_the_icbm
+0x1b,scoring
+0x1c,bomb_the_headquarters
+0x1d,star_blazer
+0x1e,by_tony_suzuki
+0x1f,thanks_a_lot_comma_raly
+
+sound_effects
+0x00,ship_impact
+0x01,bombs_empty
+0x02,player_fire
+# also when supplies caught by player
+0x04,tree_impact
+0x05,mission_complete
+0x06,mission_start
+0x08,supplies_impact
+0x09,helicopter_impact
+0x0a,missile_impact
+0x0b,tank_engine
+# multiple explosion sounds are played simultaneously
+# this might be because each participant plays its own sound
+0x0c,explosion
+0x0d,explosion
+# also missile launch
+0x0e,explosion
+0x0f,explosion
uint8_t max_bitwise;
} trace[MEM_SIZE][N_TRACE_REGS];
#endif
-#if 0
+#if 1
uint8_t start_at_mission = 1;
#endif
uint8_t key_waiting;
}
#endif
-#if 0 // start at level
+#if 0 // start at mission
if (addr == 0x1726) // opcode fetch
vrEmu6502SetX(cpu, start_at_mission);
#endif
}
#endif
+#if 0 // sound effects
+ if (addr >= 0xab80 && addr < 0xab90) {
+ int pc = vrEmu6502GetPC(cpu);
+ fprintf(stderr, "pc=%04x w=%04x v=%02x\r\n", pc, addr, val);
+ }
+#endif
+
#if 0 // decimals
if (addr >= 0xb0 && addr < 0xc0) {
int pc = vrEmu6502GetPC(cpu);
SDL_TextInputEvent *e = (SDL_TextInputEvent *)&event;
int i = e->text[0];
switch (i) {
+#if 0 // sound effects
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ i += '0' + 10 - 'a';
+ // fallthru
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ mem[0xab80 + (i & 0xf)] = 1;
+ break;
+#endif
+
#if 0
case '1':
case '2':