Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## BizHawk CDL to IDC converter - Sega GameGear/MasterSystem
- ## By : ehw
- import sys
- ##Variables:
- inputfile = ''
- outputfile = ''
- cdl_ROMseg_addr = 0x2A ##might not be the same every time, and for future versions
- cdl_ROMseg_endbyte = '\x08\x4d\x61\x69' ###.Mai, or, the beginning of the Main RAM segment.
- ## MAIN CODE START
- def main(argv):
- print("BizHawk CDL to IDC converter - Sega GameGear/MasterSystem\n")
- print("By : ehw\n")
- print("\t Usage: smsgg_cdl2idc.py input.cdl output.idc\n")
- ##2.) Check and make sure the user specified both input/output files
- if(len(sys.argv) < 2):
- print("\t Usage: smsgg_cdl2idc.py input.cdl output.idc\n")
- sys.exit(2)
- ##3.) Once the check has passed, get and then parse the cdl file
- inputfile = open(sys.argv[1], 'rb')
- outputfile = open(sys.argv[2], 'w')
- init_idc(outputfile)
- parse_cdl(inputfile, outputfile)
- print("Program End")
- inputfile.close();
- outputfile.close();
- sys.exit(2)
- ## MAIN CODE END
- def parse_cdl(inputfile, outputfile):
- ##Flags:
- ExecFirst_flag = '\x01'
- ExecOperand_flag = '\x02'
- Data_flag= '\x04'
- ExecFirst_Count = 0
- Data_Count = 0
- ExecOperand_Count = 0
- Unknown_Count = 0
- ##1.) Get the ROM segment size from the CDL file
- rom_size = get_romseg_size(inputfile, cdl_ROMseg_endbyte, cdl_ROMseg_addr)
- ##2.) Set the offset to the ROM segment
- print("Conversion Process Start!")
- print("Parsing ROM segment at {:x}".format(cdl_ROMseg_addr))
- inputfile.seek(cdl_ROMseg_addr)
- ##3.) Scan through the cdl file one byte at a time,
- currentAddress = cdl_ROMseg_addr
- while(currentAddress != cdl_ROMseg_addr+rom_size):
- if(inputfile.read(1) == ExecFirst_flag):
- outputfile.write("MakeCode(0x{:x});\n".format(currentAddress-cdl_ROMseg_addr))
- ExecFirst_Count += 1
- if(inputfile.read(1) == Data_flag):
- outputfile.write("MakeData(0x{:x}, FF_BYTE, 0x1, 0);\n".format(currentAddress-cdl_ROMseg_addr))
- Data_Count += 1
- if(inputfile.read(1) == ExecOperand_flag):
- outputfile.write("MakeCode(0x{:x});\n".format(currentAddress-cdl_ROMseg_addr))
- ExecOperand_Count += 1
- if(inputfile.read(1) == '\x00'):
- Unknown_Count += 1
- currentAddress += 1
- inputfile.seek(currentAddress)
- print("ROM segment parsing complete!")
- ##DO Main RAM STUFF HERE
- cdl_RAMseg_addr = currentAddress + 13 ##since currentAddress is now at the end of the ROM segment, we can just add 12 to get to the next RAM segment since the segment header size is fixed
- ram_size = 8192 ##ram is always the same size no matter what
- ##Set the offset in the filestream to the beginning of the RAM segment
- inputfile.seek(cdl_RAMseg_addr)
- currentAddress = cdl_RAMseg_addr
- print("Parsing Main RAM segment at {:x}".format(cdl_RAMseg_addr))
- ##Note: I can probably truncate this to make it more compact but the write out to
- ## the idc file is going to be different for RAM depending on the usage of the game
- ## so more different flags might be set in ram in some games than others. Also,
- ## the write out to the idc file needs to add an additional string for RAM space
- ##
- ##Note 2: The RAM segment in IDA Pro might need to be created with the proper base
- ## address before this script is run.
- while(currentAddress != cdl_RAMseg_addr+ram_size):
- if(inputfile.read(1) == ExecFirst_flag):
- outputfile.write("MakeCode(0xFF{0:0{1}x});\n".format(currentAddress-cdl_RAMseg_addr,4))
- ExecFirst_Count += 1
- if(inputfile.read(1) == Data):
- outputfile.write("MakeData(0xFF{0:0{1}x}, FF_BYTE, 0x1, 0);\n".format(currentAddress-cdl_RAMseg_addr,4))
- Data_Count += 1
- if(inputfile.read(1) == ExecOperand_flag):
- outputfile.write("MakeCode(0xFF{0:0{1}x});\n".format(currentAddress-cdl_RAMseg_addr,4))
- ExecOperand_Count += 1
- if(inputfile.read(1) == '\x00'):
- Unknown_Count += 1
- currentAddress += 1
- inputfile.seek(currentAddress)
- print("Main RAM segment parsing complete!")
- outputfile.write("}") ##close the idc script, we're done
- print("Conversion completed!\n")
- print("Identified Data:\n")
- print("\t ExecFirst : {:x} bytes".format(ExecFirst_Count))
- print("\t ExecOperand : {:x} bytes".format(ExecOperand_Count))
- print("\t Data : {:x} bytes".format(Data_Count))
- print("\t Unknown : {:x} bytes".format(Unknown_Count))
- return
- def get_romseg_size(inputfile, cdl_ROMseg_endbyte, cdl_ROMseg_addr):
- cdl_ROMseg_size = 0x00
- currentAddress = cdl_ROMseg_addr
- inputfile.seek(currentAddress)
- print("...Calculating ROM Segment size...Please Wait...\n")
- while(inputfile.read(4) != cdl_ROMseg_endbyte):
- cdl_ROMseg_size += 1 #add 1 to the total size
- currentAddress += 1 #move to the next byte
- inputfile.seek(currentAddress) #set as current address, necessary?
- print('ROM Size calculated! The size is {:x} bytes\n'.format(cdl_ROMseg_size))
- return cdl_ROMseg_size
- def init_idc(outputfile):
- outputfile.write("#include <idc.idc>\n")
- outputfile.write("static main() {\n")
- ##create RAM segments just in case they havent been made by the user? might take this out, I dont know what the proper address spaces would be yet
- outputfile.write('SegRename(0x000000, "ROM");\n')
- outputfile.write('SegCreate(0xFF0000, 0xFFFFFF,0,0,0,2);\n')
- outputfile.write('SegRename(0xFF0000, "RAM");\n')
- return
- if __name__ == "__main__":
- main(sys.argv[1:])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement