rom_inject.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import sys
  4. import struct
  5. def usage():
  6. print "%s <rom> <code> <addr>" % sys.argv[0]
  7. sys.exit(0)
  8. def error(msg):
  9. print "ERROR: %s" % msg
  10. sys.exit(-1)
  11. def main():
  12. if len(sys.argv) != 4:
  13. usage()
  14. if not os.path.isfile(sys.argv[1]):
  15. error("Can't open %s file" % sys.argv[1])
  16. if not os.path.isfile(sys.argv[2]):
  17. error("Can't open %s file" % sys.argv[2])
  18. rom = open(sys.argv[1], "r").read()
  19. code = open(sys.argv[2], "r").read()
  20. out_filename = sys.argv[1].split(".")[0] + ".inject"
  21. out = open(out_filename, "w")
  22. irq_vector = 0x7FE0
  23. bank_size = 1 << 15
  24. code_len = len(code)
  25. rom_len = len(rom)
  26. bank_cnt = rom_len / bank_size
  27. try:
  28. addr = int(sys.argv[3], 16)
  29. except:
  30. error("Expect %s in hex" % sys.argv[3])
  31. addr_patch = struct.pack(">H", addr)
  32. if addr > bank_size:
  33. error("Addr 0x%04x is not within first bank" % addr)
  34. if addr + code_len > (bank_size - 256):
  35. error("Code is %s bytes, and so too big to fit from 0x%04x into first bank" % (
  36. code_len, addr))
  37. print "Rom size: 0x%08x (%i)" % (rom_len, rom_len)
  38. print "Code size: 0x%04x (%i)" % (code_len, code_len)
  39. print "Banks: 0x%04x (%i)" % (bank_cnt, bank_cnt)
  40. print "Patch addr: 0x%08x" % addr
  41. print "IRQ addr: 0x%08x" % irq_vector
  42. out.write(rom[:addr])
  43. out.write(code)
  44. out.write(rom[addr + code_len:irq_vector])
  45. out.write(addr_patch)
  46. out.write(rom[irq_vector + 2:])
  47. print "%i Bytes written to %s" % (out.tell(), out_filename)
  48. out.close()
  49. print "Apply checksum fix"
  50. cmd = "ucon64 -snes -chk %s 2>&1 > /dev/null" % out_filename
  51. os.system(cmd)
  52. if __name__ == '__main__':
  53. main()