diff --git a/Makefile b/Makefile index 2ebcfd7f8b..06f3bb9a00 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ check: $(ROM) @md5sum -c checksum.md5 $(ROM): $(ROM_FILES) - @python3 ./tools/makerom.py ./tables/makerom_files.txt $@ + @python3 ./tools/makerom.py ./tables/dmadata_table.py $@ boot.bin: code.elf $(MIPS_BINUTILS)objcopy --dump-section boot=$@ $< diff --git a/tables/dmadata_table.py b/tables/dmadata_table.py index 528a09df2a..638179db60 100644 --- a/tables/dmadata_table.py +++ b/tables/dmadata_table.py @@ -2,7 +2,7 @@ [ ('build/baserom/makerom', '', 0x10, 0), ('build/baserom/boot', '', 0x10, 0), - ('dmadata', '', 0x10, 0), + ('build/baserom/dmadata', '', 0x10, 0), ('build/baserom/Audiobank', '', 0x10, 0), ('build/baserom/Audioseq', '', 0x10, 0), ('build/baserom/Audiotable', '', 0x10, 0), diff --git a/tools/dmadata.py b/tools/dmadata.py index a28416a955..b1f3273d07 100644 --- a/tools/dmadata.py +++ b/tools/dmadata.py @@ -18,7 +18,7 @@ if __name__ == "__main__": uncompressed = comp_file == '' missing = base_file == '' and comp_file == '' blank = missing and size_if_missing == 0 - is_dmadata = base_file == 'dmadata' + is_dmadata = base_file.endswith('dmadata') alignment = max(alignment, 0x10) diff --git a/tools/makerom.py b/tools/makerom.py index 7ca04d8fd9..130566d861 100644 --- a/tools/makerom.py +++ b/tools/makerom.py @@ -1,11 +1,37 @@ import os, struct, sys, ast, argparse -def read_uint32_be(offset): - return struct.unpack('>I', fileData[offset:offset+4])[0] +def read_uint32_be(data, offset): + return struct.unpack('>I', data[offset:offset+4])[0] -def read_uint16_be(offset): - return struct.unpack('>H', fileData[offset:offset+2])[0] +def generate_checksum(data): + seed = 0xDF26F436 + t1 = t2 = t3 = t4 = t5 = t6 = seed + + for i in range(0x1000, 0x1000 + 0x100000, 4): + d = read_uint32_be(data, i) + + shift = d & 0x1F + r = ((d << shift) & 0xFFFFFFFF) | ((d >> (32 - shift)) & 0xFFFFFFFF) + + if t6 + d > 0xFFFFFFFF: + t4 += 1 + + t6 = (t6 + d) & 0xFFFFFFFF + t3 ^= d + t5 = (t5 + r) & 0xFFFFFFFF + + if t2 > d: + t2 ^= r + else: + t2 ^= t6 ^ d + + t1 = (t1 + (read_uint32_be(data, 0x0750 + (i & 0xFF)) ^ d)) & 0xFFFFFFFF + + chksum0 = t6 ^ t4 ^ t3 + chksum1 = t5 ^ t2 ^ t1 + + return chksum0, chksum1 if __name__ == "__main__": parser = argparse.ArgumentParser() @@ -13,22 +39,30 @@ if __name__ == "__main__": parser.add_argument('out', help='output file') args = parser.parse_args() + outputBuffer = bytearray() + with open(args.out, 'wb') as w, open(args.files, 'rt') as f: - file_name = f.readline().strip() total_size = 0 - while file_name: - try: - with open(file_name, 'rb') as current_file: - file_data = current_file.read() - w.write(file_data) - total_size += len(file_data) - except: - print('Could not open file ' + file_name) - sys.exit(1) - file_name = f.readline().strip() + dmadata_table = ast.literal_eval(f.read()) + for base_file, comp_file, _, _ in dmadata_table: + file_name = base_file if comp_file == '' else comp_file + if file_name != '': + try: + with open(file_name, 'rb') as current_file: + file_data = current_file.read() + outputBuffer += file_data + total_size += len(file_data) + except: + print('Could not open file ' + file_name) + sys.exit(1) while total_size < 0x2000000: - w.write((total_size % 256).to_bytes(1,"big")) + outputBuffer.append(total_size % 256) total_size += 1 + chksum0, chksum1 = generate_checksum(outputBuffer) + outputBuffer[0x10:0x18] = chksum0.to_bytes(4, byteorder='big') + chksum1.to_bytes(4, byteorder='big') + + w.write(outputBuffer) +