GenesisFan64

GemsExtract

Oct 27th, 2020
1,197
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # ======================================================================
  2. # GEMS extract
  3. # Extracts GEMS sound data from ROM with the help of
  4. # a snapshot of the z80 while it was running
  5. # (saved as a .ram file)
  6. #
  7. # Usage: gemsextract.py ROM_FILE
  8. # ram file must have the same filename as ROM
  9. # ======================================================================
  10.  
  11. import sys
  12. import os.path
  13.  
  14. # ======================================================================
  15. # -------------------------------------------------
  16. # Settings
  17. # -------------------------------------------------
  18.      
  19. # Guess the size of each sound data sections since there's no way
  20. # to detect the size of each one
  21. #
  22. # change these values as you like.
  23.  
  24. SIZE_GUESS_PAT = 0x20000
  25. SIZE_GUESS_ENV = 0x20000
  26. SIZE_GUESS_SEQ = 0x20000
  27. SIZE_GUESS_SMP = 0x80000
  28.  
  29. # ======================================================================
  30. # -------------------------------------------------
  31. # Init
  32. # -------------------------------------------------
  33.  
  34. if len(sys.argv) == 1:
  35.     print("ARGS: inputfile [pattnumloop]")
  36.     exit()
  37.    
  38. if os.path.exists(sys.argv[1]) == False:
  39.     print("File not found")
  40.     exit()
  41.    
  42. MASTERNAME = sys.argv[1][:-4]
  43. input_file = open(sys.argv[1],"rb")
  44. input_ram  = open(MASTERNAME+".ram","rb")
  45.  
  46. out_pat = open("output/"+MASTERNAME+"_PBANK.bin","wb")
  47. out_env = open("output/"+MASTERNAME+"_MBANK.bin","wb")
  48. out_seq = open("output/"+MASTERNAME+"_SBANK.bin","wb")
  49. out_smp = open("output/"+MASTERNAME+"_DBANK.bin","wb")
  50. out_drv = open("output/"+MASTERNAME+"_Z80.bin","wb")
  51.  
  52. # ======================================================================
  53. # -------------------------------------------------
  54. # Start
  55. # -------------------------------------------------
  56.  
  57. # search and extract driver
  58. romPos=0
  59. romSearch=True
  60. print("Searching for driver in ROM...")
  61. while romSearch:
  62.     input_file.seek(romPos)
  63.     a = ord(input_file.read(1)) << 24
  64.     b = ord(input_file.read(1)) << 16
  65.     c = ord(input_file.read(1)) << 8
  66.     d = ord(input_file.read(1))
  67.     romPos += 1
  68.     e = a+b+c+d
  69.     if e == 0xF3ED5631: # magic value
  70.         input_file.seek(-4,1)   # 2 bytes next
  71.         print("FOUND driver at:",hex(input_file.tell())+"\n")
  72.         drvStart=input_file.tell()
  73.         romSearch=False
  74. # search end
  75. romSearch=True
  76. print("Searching for driver in ROM...")
  77. while romSearch:
  78.     input_file.seek(romPos)
  79.     a = ord(input_file.read(1)) << 24
  80.     b = ord(input_file.read(1)) << 16
  81.     c = ord(input_file.read(1)) << 8
  82.     d = ord(input_file.read(1))
  83.     romPos += 1
  84.     e = a+b+c+d
  85.     if e == 0x77007CC9:
  86.         drvEnd=input_file.tell()
  87.         romSearch=False
  88. #print(hex(drvStart),hex(drvEnd))
  89. drvLen=drvEnd-drvStart
  90. input_file.seek(drvStart)
  91. for a in range(drvLen):
  92.     a = ord(input_file.read(1)) & 0xFF
  93.     out_drv.write(bytes([a]))
  94.  
  95. # search por pointers
  96. ramPos=0
  97. ramSearch=True
  98. print("Searching for pointers in Z80RAM...")
  99. while ramSearch:
  100.     input_ram.seek(ramPos)
  101.     a = ord(input_ram.read(1)) << 16
  102.     b = ord(input_ram.read(1)) << 8
  103.     c = ord(input_ram.read(1))
  104.     ramPos += 1
  105.     d = a+b+c
  106.     if d == 0x10F9C3:   # magic value
  107.         input_ram.seek(2,True)  # 2 bytes next
  108.         print("FOUND pointers at:",hex(input_ram.tell()))
  109.         ramSearch=False
  110. a = ord(input_ram.read(1))&0xFF
  111. b = (ord(input_ram.read(1))&0xFF) << 8
  112. c = (ord(input_ram.read(1))&0xFF) << 16
  113. addrPAT = a|b|c
  114. a = ord(input_ram.read(1))&0xFF
  115. b = (ord(input_ram.read(1))&0xFF) << 8
  116. c = (ord(input_ram.read(1))&0xFF) << 16
  117. addrENV = a|b|c
  118. a = ord(input_ram.read(1))&0xFF
  119. b = (ord(input_ram.read(1))&0xFF) << 8
  120. c = (ord(input_ram.read(1))&0xFF) << 16
  121. addrSEQ = a|b|c
  122. a = ord(input_ram.read(1))&0xFF
  123. b = (ord(input_ram.read(1))&0xFF) << 8
  124. c = (ord(input_ram.read(1))&0xFF) << 16
  125. addrSMP = a|b|c
  126. print("PATCH:   ",hex(addrPAT))
  127. print("ENVELOPE:",hex(addrENV))
  128. print("SEQUENCE:",hex(addrSEQ))
  129. print("SAMPLES: ",hex(addrSMP))
  130.  
  131. input_file.seek(addrPAT)
  132. for b in range(SIZE_GUESS_PAT):
  133.     a = ord(input_file.read(1))&0xFF
  134.     out_pat.write(bytes([a]))
  135. input_file.seek(addrENV)
  136. for b in range(SIZE_GUESS_ENV):
  137.     a = ord(input_file.read(1))&0xFF
  138.     out_env.write(bytes([a]))
  139. input_file.seek(addrSEQ)
  140. for b in range(SIZE_GUESS_SEQ):
  141.     a = ord(input_file.read(1))&0xFF
  142.     out_seq.write(bytes([a]))
  143. input_file.seek(addrSMP)
  144. for b in range(SIZE_GUESS_SMP):
  145.     a = ord(input_file.read(1))&0xFF
  146.     out_smp.write(bytes([a]))
  147.    
  148. # ----------------------------
  149. # End
  150. # ----------------------------
  151.  
  152. input_file.close()
  153. input_ram.close()
  154. out_pat.close()
  155. out_env.close()
  156. out_seq.close()
  157. out_smp.close()
  158. out_drv.close()
  159.  
RAW Paste Data