You've already forked HackerSM64
mirror of
https://github.com/HackerN64/HackerSM64.git
synced 2026-01-21 10:35:32 -08:00
Refresh 13
This commit is contained in:
@@ -34,11 +34,11 @@ commands['seq'] = {
|
||||
0xc9: ['bitand', 'u8'],
|
||||
0xc8: ['subtract', 'u8'],
|
||||
# arg commands
|
||||
0x00: ['testchdisabled', 'arg'],
|
||||
0x50: ['subvariation', 'ign-arg'],
|
||||
0x70: ['setvariation', 'ign-arg'],
|
||||
0x80: ['getvariation', 'ign-arg'],
|
||||
0x90: ['startchannel', 'arg', 'addr'],
|
||||
0x00: ['testchdisabled', 'bits:4'],
|
||||
0x50: ['subvariation', 'bits:4:ign'],
|
||||
0x70: ['setvariation', 'bits:4:ign'],
|
||||
0x80: ['getvariation', 'bits:4:ign'],
|
||||
0x90: ['startchannel', 'bits:4', 'addr'],
|
||||
}
|
||||
|
||||
commands['chan'] = {
|
||||
@@ -90,25 +90,25 @@ commands['chan'] = {
|
||||
0xc2: ['setdyntable', 'addr'],
|
||||
0xc1: ['setinstr', 'u8'],
|
||||
# arg commands
|
||||
0x00: ['testlayerfinished', 'arg'],
|
||||
0x10: ['startchannel', 'arg', 'addr'],
|
||||
0x20: ['disablechannel', 'arg'],
|
||||
0x30: ['iowriteval2', 'arg', 'u8'],
|
||||
0x40: ['ioreadval2', 'arg', 'u8'],
|
||||
0x50: ['ioreadvalsub', 'arg'],
|
||||
0x60: ['setnotepriority', 'arg'],
|
||||
0x70: ['iowriteval', 'arg'],
|
||||
0x80: ['ioreadval', 'arg'],
|
||||
0x90: ['setlayer', 'arg', 'addr'],
|
||||
0xa0: ['freelayer', 'arg'],
|
||||
0xb0: ['dynsetlayer', 'arg'],
|
||||
0x00: ['testlayerfinished', 'bits:4'],
|
||||
0x10: ['startchannel', 'bits:4', 'addr'],
|
||||
0x20: ['disablechannel', 'bits:4'],
|
||||
0x30: ['iowriteval2', 'bits:4', 'u8'],
|
||||
0x40: ['ioreadval2', 'bits:4', 'u8'],
|
||||
0x50: ['ioreadvalsub', 'bits:4'],
|
||||
0x60: ['setnotepriority', 'bits:4'],
|
||||
0x70: ['iowriteval', 'bits:4'],
|
||||
0x80: ['ioreadval', 'bits:4'],
|
||||
0x90: ['setlayer', 'bits:4', 'addr'],
|
||||
0xa0: ['freelayer', 'bits:4'],
|
||||
0xb0: ['dynsetlayer', 'bits:4'],
|
||||
}
|
||||
|
||||
commands_layer_base = {
|
||||
# non-arg commands
|
||||
0xc0: ['delay', 'var'],
|
||||
0xc1: ['setshortnotevelocity', 'u8'],
|
||||
0xc2: ['transpose', 'u8'],
|
||||
0xc2: ['transpose', 's8'],
|
||||
0xc3: ['setshortnotedefaultplaypercentage', 'var'],
|
||||
0xc4: ['somethingon'], # ?? (something to do with decay behavior)
|
||||
0xc5: ['somethingoff'], # ??
|
||||
@@ -123,22 +123,35 @@ commands_layer_base = {
|
||||
0xfc: ['call', 'addr'],
|
||||
0xff: ['end'],
|
||||
# arg commands
|
||||
0xd0: ['setshortnotevelocityfromtable', 'arg'],
|
||||
0xe0: ['setshortnotedurationfromtable', 'arg'],
|
||||
0xd0: ['setshortnotevelocityfromtable', 'bits:4'],
|
||||
0xe0: ['setshortnotedurationfromtable', 'bits:4'],
|
||||
}
|
||||
|
||||
commands['layer_large'] = dict(list(commands_layer_base.items()) + list({
|
||||
0x00: ['note0', 'arg', 'var', 'u8', 'u8'],
|
||||
0x40: ['note1', 'arg', 'var', 'u8'],
|
||||
0x80: ['note2', 'arg', 'u8', 'u8'],
|
||||
0x00: ['note0', 'bits:6', 'var', 'u8', 'u8'],
|
||||
0x40: ['note1', 'bits:6', 'var', 'u8'],
|
||||
0x80: ['note2', 'bits:6', 'u8', 'u8'],
|
||||
}.items()))
|
||||
|
||||
commands['layer_small'] = dict(list(commands_layer_base.items()) + list({
|
||||
0x00: ['smallnote0', 'arg', 'var'],
|
||||
0x40: ['smallnote1', 'arg'],
|
||||
0x80: ['smallnote2', 'arg'],
|
||||
0x00: ['smallnote0', 'bits:6', 'var'],
|
||||
0x40: ['smallnote1', 'bits:6'],
|
||||
0x80: ['smallnote2', 'bits:6'],
|
||||
}.items()))
|
||||
|
||||
sh_chan_overrides = [
|
||||
(0x80, ['testlayerfinished', 'bits:3']),
|
||||
(0x88, ['setlayer', 'bits:3', 'addr']),
|
||||
(0x60, ['ioreadval', 'bits:4']),
|
||||
(0x90, ['freelayer', 'bits:4']),
|
||||
]
|
||||
|
||||
def valid_cmd_for_nbits(cmd_list, nbits):
|
||||
for arg in cmd_list:
|
||||
if arg.startswith('bits:'):
|
||||
return int(arg.split(':')[1]) == nbits
|
||||
return nbits == 0
|
||||
|
||||
print_end_padding = False
|
||||
if "--print-end-padding" in sys.argv:
|
||||
print_end_padding = True
|
||||
@@ -160,20 +173,20 @@ if sys.argv[1] == "--emit-asm-macros":
|
||||
args = cmd[1:]
|
||||
param_names = []
|
||||
param_list = []
|
||||
nibble_param_name = None
|
||||
bits_param_name = None
|
||||
for i, arg in enumerate(args):
|
||||
param_name = chr(97 + i)
|
||||
param_names.append(param_name)
|
||||
param_list.append(param_name + ("=0" if arg == "ign-arg" else ""))
|
||||
if arg == "ign-arg" or arg == "arg":
|
||||
nibble_param_name = param_name
|
||||
param_list.append(param_name + ("=0" if arg.endswith(":ign") else ""))
|
||||
if arg.startswith("bits:"):
|
||||
bits_param_name = param_name
|
||||
print(f".macro {key}_{mn} {', '.join(param_list)}".rstrip())
|
||||
if nibble_param_name is not None:
|
||||
print(f" .byte {hex(op)} + \\{nibble_param_name}")
|
||||
if bits_param_name is not None:
|
||||
print(f" .byte {hex(op)} + \\{bits_param_name}")
|
||||
else:
|
||||
print(f" .byte {hex(op)}")
|
||||
for arg, param_name in zip(args, param_names):
|
||||
if arg in ['arg', 'ign-arg']:
|
||||
if arg.startswith('bits:'):
|
||||
pass
|
||||
elif arg in ['s8', 'u8', 'hex8']:
|
||||
print(f" .byte \\{param_name}")
|
||||
@@ -192,13 +205,16 @@ if sys.argv[1] == "--emit-asm-macros":
|
||||
|
||||
def emit_env_cmd(op, cmd):
|
||||
mn = cmd[0]
|
||||
param_names = []
|
||||
param_list = []
|
||||
for i, arg in enumerate(cmd[1:]):
|
||||
param_list.append(chr(97 + i))
|
||||
param_name = chr(97 + i)
|
||||
param_names.append(param_name)
|
||||
param_list.append(param_name + ("=0" if arg.endswith(":ign") else ""))
|
||||
print(f".macro envelope_{mn} {', '.join(param_list)}".rstrip())
|
||||
if op is not None:
|
||||
print(f" .byte {hex(op >> 8)}, {hex(op & 0xff)}")
|
||||
for param in param_list:
|
||||
for param in param_names:
|
||||
print_hword("\\" + param)
|
||||
print(".endm\n")
|
||||
|
||||
@@ -211,16 +227,20 @@ if sys.argv[1] == "--emit-asm-macros":
|
||||
emit_cmd(key, op, commands['layer_small'][op])
|
||||
else:
|
||||
cmds = commands[key]
|
||||
eu = []
|
||||
non_eu = []
|
||||
eu_sh = []
|
||||
us_jp = []
|
||||
sh = sh_chan_overrides if key == 'chan' else []
|
||||
non_sh = []
|
||||
for op in sorted(cmds.keys()):
|
||||
mn = cmds[op][0]
|
||||
if mn == 'setnotepriority':
|
||||
eu.append((0xe9, ['setnotepriority', 'u8']))
|
||||
non_eu.append((op, cmds[op]))
|
||||
eu_sh.append((0xe9, ['setnotepriority', 'u8']))
|
||||
us_jp.append((op, cmds[op]))
|
||||
elif mn in ['reservenotes', 'unreservenotes']:
|
||||
eu.append((op - 1, cmds[op]))
|
||||
non_eu.append((op, cmds[op]))
|
||||
eu_sh.append((op - 1, cmds[op]))
|
||||
us_jp.append((op, cmds[op]))
|
||||
elif mn in ['testlayerfinished', 'setlayer', 'ioreadval', 'freelayer']:
|
||||
non_sh.append((op, cmds[op]))
|
||||
elif mn not in ['portamento', 'writeseq']:
|
||||
emit_cmd(key, op, cmds[op])
|
||||
|
||||
@@ -245,21 +265,30 @@ if sys.argv[1] == "--emit-asm-macros":
|
||||
emit_cmd(key, 0xfd, ['delay_long', 'var_long'])
|
||||
if key == 'layer':
|
||||
emit_cmd(key, 0xc0, ['delay_long', 'var_long'])
|
||||
emit_cmd(key, 0x40, ['note1_long', 'arg', 'var_long', 'u8'])
|
||||
if eu:
|
||||
print(".ifdef VERSION_EU\n")
|
||||
for (op, cmd) in eu:
|
||||
emit_cmd(key, 0x40, ['note1_long', 'bits:4', 'var_long', 'u8'])
|
||||
if eu_sh or us_jp or sh or non_sh:
|
||||
print(".ifdef VERSION_SH\n")
|
||||
for (op, cmd) in eu_sh:
|
||||
emit_cmd(key, op, cmd)
|
||||
for (op, cmd) in sh:
|
||||
emit_cmd(key, op, cmd)
|
||||
print(".else\n")
|
||||
for (op, cmd) in non_eu:
|
||||
for (op, cmd) in non_sh:
|
||||
emit_cmd(key, op, cmd)
|
||||
print(".ifdef VERSION_EU\n")
|
||||
for (op, cmd) in eu_sh:
|
||||
emit_cmd(key, op, cmd)
|
||||
print(".else\n")
|
||||
for (op, cmd) in us_jp:
|
||||
emit_cmd(key, op, cmd)
|
||||
print(".endif\n")
|
||||
print(".endif\n")
|
||||
|
||||
print("# envelope commands\n")
|
||||
emit_env_cmd(0, ['disable', 'u16'])
|
||||
emit_env_cmd(2**16-1, ['hang', 'u16'])
|
||||
emit_env_cmd(2**16-1, ['hang', 'u16:ign'])
|
||||
emit_env_cmd(2**16-2, ['goto', 'u16'])
|
||||
emit_env_cmd(2**16-3, ['restart', 'u16'])
|
||||
emit_env_cmd(2**16-3, ['restart', 'u16:ign'])
|
||||
emit_env_cmd(None, ['line', 'u16', 'u16'])
|
||||
|
||||
print("# other commands\n")
|
||||
@@ -281,7 +310,7 @@ if sys.argv[1] == "--emit-asm-macros":
|
||||
filename = sys.argv[1]
|
||||
try:
|
||||
lang = filename.split('/')[-2]
|
||||
assert lang in ['us', 'jp', 'eu']
|
||||
assert lang in ['us', 'jp', 'eu', 'sh']
|
||||
seq_num = int(filename.split('/')[-1].split('_')[0], 16)
|
||||
except Exception:
|
||||
lang = ''
|
||||
@@ -306,7 +335,7 @@ seq_writes = []
|
||||
# For simplicity, we force large notes always instead, which is valid for SM64.
|
||||
force_large_notes = True
|
||||
|
||||
if lang == 'eu':
|
||||
if lang in ['eu', 'sh']:
|
||||
# unreservenotes moved to 0xf0 in EU, and reservenotes took its place
|
||||
commands['chan'][0xf0] = commands['chan'][0xf1]
|
||||
commands['chan'][0xf1] = commands['chan'][0xf2]
|
||||
@@ -319,8 +348,11 @@ if lang == 'eu':
|
||||
commands['chan'][0xe9] = ['setnotepriority', 'u8']
|
||||
del commands['chan'][0x60]
|
||||
|
||||
def is_arg_command(cmd_args):
|
||||
return 'arg' in cmd_args or 'ign-arg' in cmd_args
|
||||
if lang == 'sh':
|
||||
del commands['chan'][0x00]
|
||||
del commands['chan'][0xa0]
|
||||
for op, cmd_list in sh_chan_overrides:
|
||||
commands['chan'][op] = cmd_list
|
||||
|
||||
def gen_label(ind, tp):
|
||||
nice_tp = tp.replace('_small', '').replace('_large', '')
|
||||
@@ -412,18 +444,16 @@ def decode_one(state):
|
||||
ins_byte = u8()
|
||||
|
||||
cmds = commands[tp]
|
||||
if ins_byte in cmds and not is_arg_command(cmds[ins_byte]):
|
||||
used_b = ins_byte
|
||||
arg = None
|
||||
elif ins_byte & 0xf0 in cmds and is_arg_command(cmds[ins_byte & 0xf0]):
|
||||
used_b = ins_byte & 0xf0
|
||||
arg = ins_byte & 0xf
|
||||
elif ins_byte & 0xc0 in cmds and is_arg_command(cmds[ins_byte & 0xc0]) and tp.startswith('layer'):
|
||||
used_b = ins_byte & 0xc0
|
||||
arg = ins_byte & 0x3f
|
||||
else:
|
||||
errors.append(f"unrecognized instruction {hex(ins_byte)} for type {tp} at label {gen_label(orig_pos, tp)}")
|
||||
return
|
||||
nbits = 0
|
||||
used_b = ins_byte
|
||||
while True:
|
||||
if used_b in cmds and valid_cmd_for_nbits(cmds[used_b], nbits):
|
||||
break
|
||||
used_b &= ~(1 << nbits)
|
||||
nbits += 1
|
||||
if nbits == 8:
|
||||
errors.append(f"unrecognized instruction {hex(ins_byte)} for type {tp} at label {gen_label(orig_pos, tp)}")
|
||||
return
|
||||
|
||||
out_mn = gen_mnemonic(tp, used_b)
|
||||
out_args = []
|
||||
@@ -434,10 +464,10 @@ def decode_one(state):
|
||||
for a in cmd_args:
|
||||
if cmd_mn == 'portamento' and len(out_args) == 2 and (int(out_args[0], 0) & 0x80) == 0:
|
||||
a = 'var'
|
||||
if a == 'arg':
|
||||
out_args.append(str(arg))
|
||||
elif a == 'ign-arg' and arg != 0:
|
||||
out_args.append(str(arg))
|
||||
if a.startswith('bits:'):
|
||||
low_bits = ins_byte & ((1 << nbits) - 1)
|
||||
if not (a.endswith(':ign') and low_bits == 0):
|
||||
out_args.append(str(low_bits))
|
||||
elif a == 'u8':
|
||||
out_args.append(str(u8()))
|
||||
elif a == 'hex8':
|
||||
@@ -588,10 +618,10 @@ def main():
|
||||
elif lang == 'eu':
|
||||
sound_banks = [
|
||||
(0x154, 0x70),
|
||||
(0x8FE, 0x38), # stated as 0x30?
|
||||
(0x8FE, 0x38), # stated as 0x30
|
||||
(0xBBC, 0x40),
|
||||
(0xFA5, 0x80),
|
||||
(0x1B0C, 0x28), # stated as 0x20?
|
||||
(0x1B0C, 0x28), # stated as 0x20
|
||||
(0x1E67, 0x80),
|
||||
(0x298A, 0x20),
|
||||
(0x2B36, 0x40),
|
||||
@@ -607,6 +637,30 @@ def main():
|
||||
(0x33CC, 'envelope'),
|
||||
(0x34A8, 'envelope'),
|
||||
]
|
||||
elif lang == 'sh':
|
||||
sound_banks = [
|
||||
(0x154, 0x70),
|
||||
(0x8FE, 0x38), # stated as 0x30
|
||||
(0xBBC, 0x40),
|
||||
(0xFA5, 0x80),
|
||||
(0x1B11, 0x28), # stated as 0x20
|
||||
(0x1E6C, 0x80),
|
||||
(0x298F, 0x20),
|
||||
(0x2B3B, 0x40),
|
||||
# same script as bank 3
|
||||
# same script as bank 5
|
||||
]
|
||||
|
||||
unused = [
|
||||
(0xF9A, 'chan'),
|
||||
(0x218A, 'layer_large'),
|
||||
(0x230F, 'layer_large'),
|
||||
(0x23E9, 'layer_large'),
|
||||
(0x2A8B, 'chan'),
|
||||
(0x33D0, 'envelope'),
|
||||
(0x34AC, 'envelope'),
|
||||
]
|
||||
|
||||
|
||||
for (addr, count) in sound_banks:
|
||||
for i in range(count):
|
||||
|
||||
Reference in New Issue
Block a user