summaryrefslogtreecommitdiff
path: root/pokemontools/redsfxdisasm.py
diff options
context:
space:
mode:
Diffstat (limited to 'pokemontools/redsfxdisasm.py')
-rwxr-xr-xpokemontools/redsfxdisasm.py908
1 files changed, 455 insertions, 453 deletions
diff --git a/pokemontools/redsfxdisasm.py b/pokemontools/redsfxdisasm.py
index f1cfece..63b8dd1 100755
--- a/pokemontools/redsfxdisasm.py
+++ b/pokemontools/redsfxdisasm.py
@@ -1,454 +1,456 @@
-import configuration
-config = configuration.Config()
-rom = bytearray(open(config.rom_path, "r").read())
-
-sfx_names = [
- "Snare1_2",
- "Snare2_2",
- "Snare3_2",
- "Snare4_2",
- "Snare5_2",
- "Triangle1_2",
- "Triangle2_2",
- "Snare6_2",
- "Snare7_2",
- "Snare8_2",
- "Snare9_2",
- "Cymbal1_2",
- "Cymbal2_2",
- "Cymbal3_2",
- "Muted_Snare1_2",
- "Triangle3_2",
- "Muted_Snare2_2",
- "Muted_Snare3_2",
- "Muted_Snare4_2",
- "Cry00_2",
- "Cry01_2",
- "Cry02_2",
- "Cry03_2",
- "Cry04_2",
- "Cry05_2",
- "Cry06_2",
- "Cry07_2",
- "Cry08_2",
- "Cry09_2",
- "Cry0A_2",
- "Cry0B_2",
- "Cry0C_2",
- "Cry0D_2",
- "Cry0E_2",
- "Cry0F_2",
- "Cry10_2",
- "Cry11_2",
- "Cry12_2",
- "Cry13_2",
- "Cry14_2",
- "Cry15_2",
- "Cry16_2",
- "Cry17_2",
- "Cry18_2",
- "Cry19_2",
- "Cry1A_2",
- "Cry1B_2",
- "Cry1C_2",
- "Cry1D_2",
- "Cry1E_2",
- "Cry1F_2",
- "Cry20_2",
- "Cry21_2",
- "Cry22_2",
- "Cry23_2",
- "Cry24_2",
- "Cry25_2",
- "Level_Up",
- "Get_Item2_2",
- "Tink_2",
- "Heal_HP_2",
- "Heal_Ailment_2",
- "Start_Menu_2",
- "Press_AB_2",
- "Ball_Toss",
- "Ball_Poof",
- "Faint_Thud",
- "Run",
- "Dex_Page_Added",
- "Caught_Mon",
- "Peck",
- "Faint_Fall",
- "Battle_09",
- "Pound",
- "Battle_0B",
- "Battle_0C",
- "Battle_0D",
- "Battle_0E",
- "Battle_0F",
- "Damage",
- "Not_Very_Effective",
- "Battle_12",
- "Battle_13",
- "Battle_14",
- "Vine_Whip",
- "Battle_16",
- "Battle_17",
- "Battle_18",
- "Battle_19",
- "Super_Effective",
- "Battle_1B",
- "Battle_1C",
- "Doubleslap",
- "Battle_1E",
- "Horn_Drill",
- "Battle_20",
- "Battle_21",
- "Battle_22",
- "Battle_23",
- "Battle_24",
- "Battle_25",
- "Battle_26",
- "Battle_27",
- "Battle_28",
- "Battle_29",
- "Battle_2A",
- "Battle_2B",
- "Battle_2C",
- "Psybeam",
- "Battle_2E",
- "Battle_2F",
- "Psychic_M",
- "Battle_31",
- "Battle_32",
- "Battle_33",
- "Battle_34",
- "Battle_35",
- "Battle_36",
- "Silph_Scope",
- "Snare1_1",
- "Snare2_1",
- "Snare3_1",
- "Snare4_1",
- "Snare5_1",
- "Triangle1_1",
- "Triangle2_1",
- "Snare6_1",
- "Snare7_1",
- "Snare8_1",
- "Snare9_1",
- "Cymbal1_1",
- "Cymbal2_1",
- "Cymbal3_1",
- "Muted_Snare1_1",
- "Triangle3_1",
- "Muted_Snare2_1",
- "Muted_Snare3_1",
- "Muted_Snare4_1",
- "Cry00_1",
- "Cry01_1",
- "Cry02_1",
- "Cry03_1",
- "Cry04_1",
- "Cry05_1",
- "Cry06_1",
- "Cry07_1",
- "Cry08_1",
- "Cry09_1",
- "Cry0A_1",
- "Cry0B_1",
- "Cry0C_1",
- "Cry0D_1",
- "Cry0E_1",
- "Cry0F_1",
- "Cry10_1",
- "Cry11_1",
- "Cry12_1",
- "Cry13_1",
- "Cry14_1",
- "Cry15_1",
- "Cry16_1",
- "Cry17_1",
- "Cry18_1",
- "Cry19_1",
- "Cry1A_1",
- "Cry1B_1",
- "Cry1C_1",
- "Cry1D_1",
- "Cry1E_1",
- "Cry1F_1",
- "Cry20_1",
- "Cry21_1",
- "Cry22_1",
- "Cry23_1",
- "Cry24_1",
- "Cry25_1",
- "Get_Item1_1",
- "Get_Item2_1",
- "Tink_1",
- "Heal_HP_1",
- "Heal_Ailment_1",
- "Start_Menu_1",
- "Press_AB_1",
- "Pokedex_Rating_1",
- "Get_Key_Item_1",
- "Poisoned_1",
- "Trade_Machine_1",
- "Turn_On_PC_1",
- "Turn_Off_PC_1",
- "Enter_PC_1",
- "Shrink_1",
- "Switch_1",
- "Healing_Machine_1",
- "Teleport_Exit1_1",
- "Teleport_Enter1_1",
- "Teleport_Exit2_1",
- "Ledge_1",
- "Teleport_Enter2_1",
- "Fly_1",
- "Denied_1",
- "Arrow_Tiles_1",
- "Push_Boulder_1",
- "SS_Anne_Horn_1",
- "Withdraw_Deposit_1",
- "Cut_1",
- "Go_Inside_1",
- "Swap_1",
- "59_1",
- "Purchase_1",
- "Collision_1",
- "Go_Outside_1",
- "Save_1",
- "Pokeflute",
- "Safari_Zone_PA",
- "Snare1_3",
- "Snare2_3",
- "Snare3_3",
- "Snare4_3",
- "Snare5_3",
- "Triangle1_3",
- "Triangle2_3",
- "Snare6_3",
- "Snare7_3",
- "Snare8_3",
- "Snare9_3",
- "Cymbal1_3",
- "Cymbal2_3",
- "Cymbal3_3",
- "Muted_Snare1_3",
- "Triangle3_3",
- "Muted_Snare2_3",
- "Muted_Snare3_3",
- "Muted_Snare4_3",
- "Cry00_3",
- "Cry01_3",
- "Cry02_3",
- "Cry03_3",
- "Cry04_3",
- "Cry05_3",
- "Cry06_3",
- "Cry07_3",
- "Cry08_3",
- "Cry09_3",
- "Cry0A_3",
- "Cry0B_3",
- "Cry0C_3",
- "Cry0D_3",
- "Cry0E_3",
- "Cry0F_3",
- "Cry10_3",
- "Cry11_3",
- "Cry12_3",
- "Cry13_3",
- "Cry14_3",
- "Cry15_3",
- "Cry16_3",
- "Cry17_3",
- "Cry18_3",
- "Cry19_3",
- "Cry1A_3",
- "Cry1B_3",
- "Cry1C_3",
- "Cry1D_3",
- "Cry1E_3",
- "Cry1F_3",
- "Cry20_3",
- "Cry21_3",
- "Cry22_3",
- "Cry23_3",
- "Cry24_3",
- "Cry25_3",
- "Get_Item1_3",
- "Get_Item2_3",
- "Tink_3",
- "Heal_HP_3",
- "Heal_Ailment_3",
- "Start_Menu_3",
- "Press_AB_3",
- "Pokedex_Rating_3",
- "Get_Key_Item_3",
- "Poisoned_3",
- "Trade_Machine_3",
- "Turn_On_PC_3",
- "Turn_Off_PC_3",
- "Enter_PC_3",
- "Shrink_3",
- "Switch_3",
- "Healing_Machine_3",
- "Teleport_Exit1_3",
- "Teleport_Enter1_3",
- "Teleport_Exit2_3",
- "Ledge_3",
- "Teleport_Enter2_3",
- "Fly_3",
- "Denied_3",
- "Arrow_Tiles_3",
- "Push_Boulder_3",
- "SS_Anne_Horn_3",
- "Withdraw_Deposit_3",
- "Cut_3",
- "Go_Inside_3",
- "Swap_3",
- "59_3",
- "Purchase_3",
- "Collision_3",
- "Go_Outside_3",
- "Save_3",
- "Intro_Lunge",
- "Intro_Hip",
- "Intro_Hop",
- "Intro_Raise",
- "Intro_Crash",
- "Intro_Whoosh",
- "Slots_Stop_Wheel",
- "Slots_Reward",
- "Slots_New_Spin",
- "Shooting_Star",
- ]
-
-banks = {
- 0x02: 0x60,
- 0x08: 0x78,
- 0x1f: 0x68,
- }
-
-music_commands = {
- 0xd0: ["notetype", {"type": "nibble"}, 2],
- 0xe0: ["octave", 1],
- 0xe8: ["toggleperfectpitch", 1],
- 0xea: ["vibrato", {"type": "byte"}, {"type": "nibble"}, 3],
- 0xec: ["duty", {"type": "byte"}, 2],
- 0xed: ["tempo", {"type": "word"}, 3],
- 0xf0: ["volume", {"type": "nibble"}, 2],
- 0xf8: ["executemusic", 1],
- 0xfc: ["dutycycle", {"type": "byte"}, 2],
- 0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
- 0xff: ["endchannel", 1],
- }
-
-param_lengths = {
- "nibble": 1,
- "byte": 1,
- "word": 2,
- "label": 2,
- }
-
-music_notes = {
- 0x0: "C_",
- 0x1: "C#",
- 0x2: "D_",
- 0x3: "D#",
- 0x4: "E_",
- 0x5: "F_",
- 0x6: "F#",
- 0x7: "G_",
- 0x8: "G#",
- 0x9: "A_",
- 0xa: "A#",
- 0xb: "B_",
- }
-
-sfxnum = 0
-
-for bank in banks:
- print bank
- header = bank * 0x4000 + 3
- for sfx in range(1,banks[bank]):
- sfxname = sfx_names[sfxnum]
- sfxfile = open("music/sfx/" + sfx_names[sfxnum].lower() + ".asm", 'w')
- sfxname = "SFX_" + sfxname
- startingaddress = rom[header + 2] * 0x100 + rom[header + 1] + (0x4000 * (bank - 1))
- end = 0
- curchannel = 1
- lastchannel = (rom[header] >> 6) + 1
- channelnumber = rom[header] % 0x10
- output = ''
- while 1:
- address = startingaddress
- if curchannel != lastchannel:
- end = rom[header + 5] * 0x100 + rom[header + 4] + (0x4000 * (bank - 1))
- byte = rom[address]
- if byte == 0xf8 or (bank == 2 and sfx == 0x5e): executemusic = True
- else: executemusic = False
- output += "{}_Ch{}: ; {:02x} ({:0x}:{:02x})\n".format(sfxname, curchannel, address, bank, address % 0x4000 + 0x4000)
- while 1:
- if address == 0x2062a or address == 0x2063d or address == 0x20930:
- output += "\n{}_branch_{:02x}:\n".format(sfxname, address)
- if byte == 0x10 and not executemusic:
- output += "\tunknownsfx0x{:02x} {}".format(byte, rom[address + 1])
- command_length = 2
- elif byte < 0x30 and not executemusic:
- if channelnumber == 7:
- output += "\tunknownnoise0x20 {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2])
- command_length = 3
- else:
- output += "\tunknownsfx0x20 {}, {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2], rom[address + 3])
- command_length = 4
- elif byte < 0xc0:
- output += "\t{} {}".format(music_notes[byte >> 4], byte % 0x10 + 1)
- command_length = 1
- elif byte < 0xd0:
- output += "\trest {}".format(byte % 0x10 + 1)
- command_length = 1
- else:
- if byte < 0xe0:
- command = music_commands[0xd0]
- output += "\t{} {},".format(command[0], byte % 0x10)
- byte = 0xd0
- elif byte < 0xe8:
- command = music_commands[0xe0]
- output += "\t{} {}".format(command[0], 0xe8 - byte)
- byte = 0xe0
- else:
- command = music_commands[byte]
- output += "\t{}".format(command[0])
- command_length = 1
- params = 1
- # print all params for current command
- while params != len(music_commands[byte]) - 1:
- param_type = music_commands[byte][params]["type"]
- address += command_length
- command_length = param_lengths[param_type]
- param = rom[address]
- if param_type == "nibble":
- output += " {}, {}".format(param >> 4, param % 0x10)
- elif param_type == "byte":
- output += " {}".format(param)
- elif param_type == "word":
- output += " {}".format(param * 0x100 + rom[address + 1])
- else:
- param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
- if param == startingaddress: output += " {}_Ch{}".format(sfxname, curchannel)
- else: output += " {}_branch_{:02x}".format(sfxname, param)
- params += 1
- if params != len(music_commands[byte]) - 1: output += ","
- output += "\n"
- address += command_length
- if byte == 0xff or address == end: break
- byte = rom[address]
- header += 3
- channelnumber = rom[header]
- if curchannel == lastchannel:
- # output += "; {}".format(hex(address))
- sfxfile.write(output)
- break
- output += "\n\n"
- startingaddress = address
- curchannel += 1
+from __future__ import print_function
+from __future__ import absolute_import
+from . import configuration
+config = configuration.Config()
+rom = bytearray(open(config.rom_path, "r").read())
+
+sfx_names = [
+ "Snare1_2",
+ "Snare2_2",
+ "Snare3_2",
+ "Snare4_2",
+ "Snare5_2",
+ "Triangle1_2",
+ "Triangle2_2",
+ "Snare6_2",
+ "Snare7_2",
+ "Snare8_2",
+ "Snare9_2",
+ "Cymbal1_2",
+ "Cymbal2_2",
+ "Cymbal3_2",
+ "Muted_Snare1_2",
+ "Triangle3_2",
+ "Muted_Snare2_2",
+ "Muted_Snare3_2",
+ "Muted_Snare4_2",
+ "Cry00_2",
+ "Cry01_2",
+ "Cry02_2",
+ "Cry03_2",
+ "Cry04_2",
+ "Cry05_2",
+ "Cry06_2",
+ "Cry07_2",
+ "Cry08_2",
+ "Cry09_2",
+ "Cry0A_2",
+ "Cry0B_2",
+ "Cry0C_2",
+ "Cry0D_2",
+ "Cry0E_2",
+ "Cry0F_2",
+ "Cry10_2",
+ "Cry11_2",
+ "Cry12_2",
+ "Cry13_2",
+ "Cry14_2",
+ "Cry15_2",
+ "Cry16_2",
+ "Cry17_2",
+ "Cry18_2",
+ "Cry19_2",
+ "Cry1A_2",
+ "Cry1B_2",
+ "Cry1C_2",
+ "Cry1D_2",
+ "Cry1E_2",
+ "Cry1F_2",
+ "Cry20_2",
+ "Cry21_2",
+ "Cry22_2",
+ "Cry23_2",
+ "Cry24_2",
+ "Cry25_2",
+ "Level_Up",
+ "Get_Item2_2",
+ "Tink_2",
+ "Heal_HP_2",
+ "Heal_Ailment_2",
+ "Start_Menu_2",
+ "Press_AB_2",
+ "Ball_Toss",
+ "Ball_Poof",
+ "Faint_Thud",
+ "Run",
+ "Dex_Page_Added",
+ "Caught_Mon",
+ "Peck",
+ "Faint_Fall",
+ "Battle_09",
+ "Pound",
+ "Battle_0B",
+ "Battle_0C",
+ "Battle_0D",
+ "Battle_0E",
+ "Battle_0F",
+ "Damage",
+ "Not_Very_Effective",
+ "Battle_12",
+ "Battle_13",
+ "Battle_14",
+ "Vine_Whip",
+ "Battle_16",
+ "Battle_17",
+ "Battle_18",
+ "Battle_19",
+ "Super_Effective",
+ "Battle_1B",
+ "Battle_1C",
+ "Doubleslap",
+ "Battle_1E",
+ "Horn_Drill",
+ "Battle_20",
+ "Battle_21",
+ "Battle_22",
+ "Battle_23",
+ "Battle_24",
+ "Battle_25",
+ "Battle_26",
+ "Battle_27",
+ "Battle_28",
+ "Battle_29",
+ "Battle_2A",
+ "Battle_2B",
+ "Battle_2C",
+ "Psybeam",
+ "Battle_2E",
+ "Battle_2F",
+ "Psychic_M",
+ "Battle_31",
+ "Battle_32",
+ "Battle_33",
+ "Battle_34",
+ "Battle_35",
+ "Battle_36",
+ "Silph_Scope",
+ "Snare1_1",
+ "Snare2_1",
+ "Snare3_1",
+ "Snare4_1",
+ "Snare5_1",
+ "Triangle1_1",
+ "Triangle2_1",
+ "Snare6_1",
+ "Snare7_1",
+ "Snare8_1",
+ "Snare9_1",
+ "Cymbal1_1",
+ "Cymbal2_1",
+ "Cymbal3_1",
+ "Muted_Snare1_1",
+ "Triangle3_1",
+ "Muted_Snare2_1",
+ "Muted_Snare3_1",
+ "Muted_Snare4_1",
+ "Cry00_1",
+ "Cry01_1",
+ "Cry02_1",
+ "Cry03_1",
+ "Cry04_1",
+ "Cry05_1",
+ "Cry06_1",
+ "Cry07_1",
+ "Cry08_1",
+ "Cry09_1",
+ "Cry0A_1",
+ "Cry0B_1",
+ "Cry0C_1",
+ "Cry0D_1",
+ "Cry0E_1",
+ "Cry0F_1",
+ "Cry10_1",
+ "Cry11_1",
+ "Cry12_1",
+ "Cry13_1",
+ "Cry14_1",
+ "Cry15_1",
+ "Cry16_1",
+ "Cry17_1",
+ "Cry18_1",
+ "Cry19_1",
+ "Cry1A_1",
+ "Cry1B_1",
+ "Cry1C_1",
+ "Cry1D_1",
+ "Cry1E_1",
+ "Cry1F_1",
+ "Cry20_1",
+ "Cry21_1",
+ "Cry22_1",
+ "Cry23_1",
+ "Cry24_1",
+ "Cry25_1",
+ "Get_Item1_1",
+ "Get_Item2_1",
+ "Tink_1",
+ "Heal_HP_1",
+ "Heal_Ailment_1",
+ "Start_Menu_1",
+ "Press_AB_1",
+ "Pokedex_Rating_1",
+ "Get_Key_Item_1",
+ "Poisoned_1",
+ "Trade_Machine_1",
+ "Turn_On_PC_1",
+ "Turn_Off_PC_1",
+ "Enter_PC_1",
+ "Shrink_1",
+ "Switch_1",
+ "Healing_Machine_1",
+ "Teleport_Exit1_1",
+ "Teleport_Enter1_1",
+ "Teleport_Exit2_1",
+ "Ledge_1",
+ "Teleport_Enter2_1",
+ "Fly_1",
+ "Denied_1",
+ "Arrow_Tiles_1",
+ "Push_Boulder_1",
+ "SS_Anne_Horn_1",
+ "Withdraw_Deposit_1",
+ "Cut_1",
+ "Go_Inside_1",
+ "Swap_1",
+ "59_1",
+ "Purchase_1",
+ "Collision_1",
+ "Go_Outside_1",
+ "Save_1",
+ "Pokeflute",
+ "Safari_Zone_PA",
+ "Snare1_3",
+ "Snare2_3",
+ "Snare3_3",
+ "Snare4_3",
+ "Snare5_3",
+ "Triangle1_3",
+ "Triangle2_3",
+ "Snare6_3",
+ "Snare7_3",
+ "Snare8_3",
+ "Snare9_3",
+ "Cymbal1_3",
+ "Cymbal2_3",
+ "Cymbal3_3",
+ "Muted_Snare1_3",
+ "Triangle3_3",
+ "Muted_Snare2_3",
+ "Muted_Snare3_3",
+ "Muted_Snare4_3",
+ "Cry00_3",
+ "Cry01_3",
+ "Cry02_3",
+ "Cry03_3",
+ "Cry04_3",
+ "Cry05_3",
+ "Cry06_3",
+ "Cry07_3",
+ "Cry08_3",
+ "Cry09_3",
+ "Cry0A_3",
+ "Cry0B_3",
+ "Cry0C_3",
+ "Cry0D_3",
+ "Cry0E_3",
+ "Cry0F_3",
+ "Cry10_3",
+ "Cry11_3",
+ "Cry12_3",
+ "Cry13_3",
+ "Cry14_3",
+ "Cry15_3",
+ "Cry16_3",
+ "Cry17_3",
+ "Cry18_3",
+ "Cry19_3",
+ "Cry1A_3",
+ "Cry1B_3",
+ "Cry1C_3",
+ "Cry1D_3",
+ "Cry1E_3",
+ "Cry1F_3",
+ "Cry20_3",
+ "Cry21_3",
+ "Cry22_3",
+ "Cry23_3",
+ "Cry24_3",
+ "Cry25_3",
+ "Get_Item1_3",
+ "Get_Item2_3",
+ "Tink_3",
+ "Heal_HP_3",
+ "Heal_Ailment_3",
+ "Start_Menu_3",
+ "Press_AB_3",
+ "Pokedex_Rating_3",
+ "Get_Key_Item_3",
+ "Poisoned_3",
+ "Trade_Machine_3",
+ "Turn_On_PC_3",
+ "Turn_Off_PC_3",
+ "Enter_PC_3",
+ "Shrink_3",
+ "Switch_3",
+ "Healing_Machine_3",
+ "Teleport_Exit1_3",
+ "Teleport_Enter1_3",
+ "Teleport_Exit2_3",
+ "Ledge_3",
+ "Teleport_Enter2_3",
+ "Fly_3",
+ "Denied_3",
+ "Arrow_Tiles_3",
+ "Push_Boulder_3",
+ "SS_Anne_Horn_3",
+ "Withdraw_Deposit_3",
+ "Cut_3",
+ "Go_Inside_3",
+ "Swap_3",
+ "59_3",
+ "Purchase_3",
+ "Collision_3",
+ "Go_Outside_3",
+ "Save_3",
+ "Intro_Lunge",
+ "Intro_Hip",
+ "Intro_Hop",
+ "Intro_Raise",
+ "Intro_Crash",
+ "Intro_Whoosh",
+ "Slots_Stop_Wheel",
+ "Slots_Reward",
+ "Slots_New_Spin",
+ "Shooting_Star",
+ ]
+
+banks = {
+ 0x02: 0x60,
+ 0x08: 0x78,
+ 0x1f: 0x68,
+ }
+
+music_commands = {
+ 0xd0: ["notetype", {"type": "nibble"}, 2],
+ 0xe0: ["octave", 1],
+ 0xe8: ["toggleperfectpitch", 1],
+ 0xea: ["vibrato", {"type": "byte"}, {"type": "nibble"}, 3],
+ 0xec: ["duty", {"type": "byte"}, 2],
+ 0xed: ["tempo", {"type": "word"}, 3],
+ 0xf0: ["volume", {"type": "nibble"}, 2],
+ 0xf8: ["executemusic", 1],
+ 0xfc: ["dutycycle", {"type": "byte"}, 2],
+ 0xfe: ["loopchannel", {"type": "byte"}, {"type": "label"}, 4],
+ 0xff: ["endchannel", 1],
+ }
+
+param_lengths = {
+ "nibble": 1,
+ "byte": 1,
+ "word": 2,
+ "label": 2,
+ }
+
+music_notes = {
+ 0x0: "C_",
+ 0x1: "C#",
+ 0x2: "D_",
+ 0x3: "D#",
+ 0x4: "E_",
+ 0x5: "F_",
+ 0x6: "F#",
+ 0x7: "G_",
+ 0x8: "G#",
+ 0x9: "A_",
+ 0xa: "A#",
+ 0xb: "B_",
+ }
+
+sfxnum = 0
+
+for bank in banks:
+ print(bank)
+ header = bank * 0x4000 + 3
+ for sfx in range(1,banks[bank]):
+ sfxname = sfx_names[sfxnum]
+ sfxfile = open("music/sfx/" + sfx_names[sfxnum].lower() + ".asm", 'w')
+ sfxname = "SFX_" + sfxname
+ startingaddress = rom[header + 2] * 0x100 + rom[header + 1] + (0x4000 * (bank - 1))
+ end = 0
+ curchannel = 1
+ lastchannel = (rom[header] >> 6) + 1
+ channelnumber = rom[header] % 0x10
+ output = ''
+ while 1:
+ address = startingaddress
+ if curchannel != lastchannel:
+ end = rom[header + 5] * 0x100 + rom[header + 4] + (0x4000 * (bank - 1))
+ byte = rom[address]
+ if byte == 0xf8 or (bank == 2 and sfx == 0x5e): executemusic = True
+ else: executemusic = False
+ output += "{}_Ch{}: ; {:02x} ({:0x}:{:02x})\n".format(sfxname, curchannel, address, bank, address % 0x4000 + 0x4000)
+ while 1:
+ if address == 0x2062a or address == 0x2063d or address == 0x20930:
+ output += "\n{}_branch_{:02x}:\n".format(sfxname, address)
+ if byte == 0x10 and not executemusic:
+ output += "\tunknownsfx0x{:02x} {}".format(byte, rom[address + 1])
+ command_length = 2
+ elif byte < 0x30 and not executemusic:
+ if channelnumber == 7:
+ output += "\tunknownnoise0x20 {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2])
+ command_length = 3
+ else:
+ output += "\tunknownsfx0x20 {}, {}, {}, {}".format(byte % 0x10, rom[address + 1], rom[address + 2], rom[address + 3])
+ command_length = 4
+ elif byte < 0xc0:
+ output += "\t{} {}".format(music_notes[byte >> 4], byte % 0x10 + 1)
+ command_length = 1
+ elif byte < 0xd0:
+ output += "\trest {}".format(byte % 0x10 + 1)
+ command_length = 1
+ else:
+ if byte < 0xe0:
+ command = music_commands[0xd0]
+ output += "\t{} {},".format(command[0], byte % 0x10)
+ byte = 0xd0
+ elif byte < 0xe8:
+ command = music_commands[0xe0]
+ output += "\t{} {}".format(command[0], 0xe8 - byte)
+ byte = 0xe0
+ else:
+ command = music_commands[byte]
+ output += "\t{}".format(command[0])
+ command_length = 1
+ params = 1
+ # print all params for current command
+ while params != len(music_commands[byte]) - 1:
+ param_type = music_commands[byte][params]["type"]
+ address += command_length
+ command_length = param_lengths[param_type]
+ param = rom[address]
+ if param_type == "nibble":
+ output += " {}, {}".format(param >> 4, param % 0x10)
+ elif param_type == "byte":
+ output += " {}".format(param)
+ elif param_type == "word":
+ output += " {}".format(param * 0x100 + rom[address + 1])
+ else:
+ param += rom[address + 1] * 0x100 - 0x4000 + (bank * 0x4000)
+ if param == startingaddress: output += " {}_Ch{}".format(sfxname, curchannel)
+ else: output += " {}_branch_{:02x}".format(sfxname, param)
+ params += 1
+ if params != len(music_commands[byte]) - 1: output += ","
+ output += "\n"
+ address += command_length
+ if byte == 0xff or address == end: break
+ byte = rom[address]
+ header += 3
+ channelnumber = rom[header]
+ if curchannel == lastchannel:
+ # output += "; {}".format(hex(address))
+ sfxfile.write(output)
+ break
+ output += "\n\n"
+ startingaddress = address
+ curchannel += 1
sfxnum += 1 \ No newline at end of file