Advertisement
Guest User

convert.py

a guest
Sep 19th, 2019
787
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.71 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # SPDX-License-Identifier: CC0-1.0
  3. from pathlib import Path
  4. import os
  5. import sys
  6. import argparse
  7. import shutil
  8. import struct
  9.  
  10.  
  11. def split(i, parts):
  12.     '''Splits a file in parts
  13.  
  14.    The parts might be of different sizes. But they must be all
  15.    continuous
  16.  
  17.    '''
  18.     for name, size in parts:
  19.         buf = i.read(size)
  20.         assert len(buf) == size
  21.         with open(name, 'wb+') as o:
  22.             o.write(buf)
  23.  
  24.  
  25. def split_ranges(i, parts):
  26.     for name, ranges in parts:
  27.         with open(name, 'wb+') as o:
  28.             for start, end in ranges:
  29.                 i.seek(start)
  30.                 buf = i.read(end-start)
  31.                 assert i.tell() == end
  32.                 assert len(buf) == end-start
  33.                 o.write(buf)
  34.  
  35.  
  36. def deinterleave16(i, parts, limit = -1):
  37.     with open(parts[0], 'wb+') as o0, open(parts[1], 'wb+') as o1:
  38.         count = 0
  39.         word = i.read(2) if count != limit else None
  40.         while word:
  41.             o0.write(word[0:1])
  42.             o1.write(word[1:2])
  43.             count += 1
  44.             word = i.read(2) if count != limit else None
  45.  
  46.  
  47. def deinterleave32(i, parts):
  48.     with open(parts[0], 'wb+') as o0, open(parts[1], 'wb+') as o1, \
  49.          open(parts[2], 'wb+') as o2, open(parts[3], 'wb+') as o3:
  50.         word = i.read(4)
  51.         while word:
  52.             o0.write(word[0:1])
  53.             o1.write(word[1:2])
  54.             o2.write(word[2:3])
  55.             o3.write(word[3:4])
  56.             word = i.read(4)
  57.  
  58.  
  59. def mkflash(target, prefix):
  60.     target.seek(-1, os.SEEK_END)
  61.     region = target.read(1)
  62.     fn = prefix + f'flash0_blank_region{region[0]:02x}.u1053'
  63.     with open(fn, 'wb+') as o:
  64.         o.write(region)
  65.         for _ in range(0x0F_FFFF):
  66.             o.write(b'\xFF')
  67.  
  68.  
  69. def mkempty(fn, size):
  70.     with open(fn, 'wb+') as o:
  71.         o.seek(size-1)
  72.         o.write(b'\x00')
  73.  
  74.  
  75. def pixel_de4_to_rai4(i, fn):
  76.     with open(fn, 'wb+') as o:
  77.         data_big = i.read(4)
  78.         times = 0
  79.         low = b''
  80.         high = b''
  81.         while data_big:
  82.             pixels, = struct.unpack('<I', data_big)
  83.             rom_pixels = ((pixels & 0x0000_0001) << 7 # -15 + 8
  84.                           | (pixels & 0x0000_0002) << 2 # -10 + 8
  85.                           | (pixels & 0x0000_0004) << 13 # -5 - 8
  86.                           | (pixels & 0x0000_0008) << 8 # 0 - 8
  87.  
  88.                           | (pixels & 0x0000_0100) >> 2 # -6 + 8
  89.                           | (pixels & 0x0000_0200) >> 7 # -1 + 8
  90.                           | (pixels & 0x0000_0400) << 4 # 4 - 8
  91.                           | (pixels & 0x0000_0800) >> 1 # 9 - 8
  92.  
  93.                           | (pixels & 0x0001_0000) >> 11 # 3 + 8
  94.                           | (pixels & 0x0002_0000) >> 16 # 8 + 8
  95.                           | (pixels & 0x0004_0000) >> 5 # 13 - 8
  96.                           | (pixels & 0x0008_0000) >> 10 # 18 - 8
  97.  
  98.                           | (pixels & 0x0100_0000) >> 20 # 12 + 8
  99.                           | (pixels & 0x0200_0000) >> 25 # 17 + 8
  100.                           | (pixels & 0x0400_0000) >> 14 # 22 - 8
  101.                           | (pixels & 0x0800_0000) >> 19) # 27 - 8
  102.  
  103.             assert not (rom_pixels & ~0xFFFF)
  104.             packed = struct.pack('<H', rom_pixels)
  105.             if (times % 4) < 2:
  106.                 low += packed
  107.             else:
  108.                 high += packed
  109.  
  110.             data_big = i.read(4)
  111.             times += 1
  112.             if times == 64:
  113.                 o.write(low)
  114.                 o.write(high)
  115.                 low = b''
  116.                 high = b''
  117.                 times = 0
  118.             assert times < 64
  119.  
  120.  
  121. def encrypt_spi(pixels, key1, key2, key3, tn = 0):
  122.     # to mame style (Big Endian)
  123.     mame = ((pixels & 0x00_00FF) << 16
  124.             | (pixels & 0x00_FF00)
  125.             | (pixels & 0xFF_0000) >> 16)
  126.  
  127.     xor = mame ^ key3
  128.  
  129.     suma = tn + key1
  130.  
  131.     # no carry last
  132.     assert not (key2 & 0x80_0000)
  133.     e = 0
  134.     carry = 0
  135.     for i in range(24):
  136.         bit = ((xor >> i) & 1) ^ ((suma >> i) & 1) ^ carry
  137.         bitsum = bit + ((suma >> i) & 1) + carry
  138.         carry = (bitsum >> 1) if ((key2 >> i) & 1) else 0
  139.         e |= ((bit & 1) << i)
  140.    
  141.     #Reorder bits
  142.     reordered = ((e & 0x80_0000) >> 5
  143.                  | (e & 0x40_0000) >> 3
  144.                  | (e & 0x20_0000) >> 12
  145.                  | (e & 0x10_0020) >> 15
  146.  
  147.                  | (e & 0x08_0000) >> 9
  148.                  | (e & 0x04_0000) >> 1
  149.                  | (e & 0x02_0000) >> 1
  150.                  | (e & 0x01_0000) << 4
  151.  
  152.  
  153.                  | (e & 0x00_8000) << 6
  154.                  | (e & 0x00_4000) << 8
  155.                  | (e & 0x00_2000) >> 7
  156.                  | (e & 0x00_1000) >> 1
  157.  
  158.                  | (e & 0x00_0800) << 4
  159.                  | (e & 0x00_0400) << 4
  160.                  | (e & 0x00_0200) >> 5
  161.                  | (e & 0x00_0100) << 15
  162.  
  163.                  | (e & 0x00_0080) >> 7
  164.                  | (e & 0x00_0040) >> 5
  165.                  | (e & 0x00_0020) << 2
  166.                  | (e & 0x00_0010) << 4
  167.  
  168.                  | (e & 0x00_0008) << 10
  169.                  | (e & 0x00_0004) << 10
  170.                  | (e & 0x00_0002) << 2
  171.                  | (e & 0x00_0001) << 2)
  172.  
  173.     return struct.pack('>I', reordered)[1:]
  174.  
  175.  
  176. def pixel_de5_to_spi6(inp, fn, fix0=False, fix1=False):
  177.     with open(fn, 'wb+') as out:
  178.         group = 0
  179.         data = inp.read(4)
  180.         while data:
  181.             pixels, = struct.unpack('<I', data)
  182.  
  183.             # Pixel color fixes
  184.             for i in range(4):
  185.                 n = i*8
  186.                 if fix0 and pixels >> n & 0xFF == 0x1F:
  187.                     pixels = pixels | 0x20 << n
  188.             # Fix for rdft_gfxdata1.bin
  189.             if fix1 and 61_456 <= group and group <= 61_487:
  190.                 pixels = pixels | 0x2020_2020
  191.  
  192.             # Change format
  193.             spi6_pixels2 = ((pixels & 0x0000_0001) << 16 # 0 + 16 + 0
  194.                             | (pixels & 0x0000_0002) << 19 # -1 + 20 + 0
  195.                             | (pixels & 0x0000_0004) << 6 # -2 + 8 + 0
  196.                             | (pixels & 0x0000_0008) << 9 # -3 + 12 + 0
  197.                             | (pixels & 0x0000_0010) >> 4 # -4 + 0 + 0
  198.                             | (pixels & 0x0000_0020) >> 1 # -5 + 4 + 0
  199.  
  200.                             | (pixels & 0x0000_0100) << 9 # -8 + 16 + 1
  201.                             | (pixels & 0x0000_0200) << 12 # -9 + 20 + 1
  202.                             | (pixels & 0x0000_0400) >> 1 # -10 + 8 + 1
  203.                             | (pixels & 0x0000_0800) << 2 # -11 + 12 + 1
  204.                             | (pixels & 0x0000_1000) >> 11 # -12 + 0 + 1
  205.                             | (pixels & 0x0000_2000) >> 8 # -13 + 4 + 1
  206.  
  207.                             | (pixels & 0x0001_0000) << 2 # -16 + 16 + 2
  208.                             | (pixels & 0x0002_0000) << 5 # -17 + 20 + 2
  209.                             | (pixels & 0x0004_0000) >> 8 # -18 + 8 + 2
  210.                             | (pixels & 0x0008_0000) >> 5 # -19 + 12 + 2
  211.                             | (pixels & 0x0010_0000) >> 18 # -20 + 0 + 2
  212.                             | (pixels & 0x0020_0000) >> 15 # -21 + 4 + 2
  213.  
  214.                             | (pixels & 0x0100_0000) >> 5 # -24 + 16 + 3
  215.                             | (pixels & 0x0200_0000) >> 2 # -25 + 20 + 3
  216.                             | (pixels & 0x0400_0000) >> 15 # -26 + 8 + 3
  217.                             | (pixels & 0x0800_0000) >> 12 # -27 + 12 + 3
  218.                             | (pixels & 0x1000_0000) >> 25 # -28 + 0 + 3
  219.                             | (pixels & 0x2000_0000) >> 22) # -29 + 4 + 3
  220.  
  221.             assert not (spi6_pixels2 & ~0xFF_FFFF)
  222.             packed32 = struct.pack('<I', spi6_pixels2)
  223.             packed = packed32[:-1]
  224.             out.write(packed)
  225.  
  226.             group += 1
  227.             data = inp.read(4)
  228.  
  229.  
  230. def raidenb(prefix):
  231.     try:
  232.         os.mkdir(prefix + 'raidenb')
  233.     except FileExistsError:
  234.         pass
  235.  
  236.     with open('raiden/raiden_maincpu.bin', 'rb') as f:
  237.         maincpu_parts_low = [
  238.             prefix + 'raidenb/1.u0253',
  239.             prefix + 'raidenb/2.u0252',
  240.         ]
  241.         maincpu_parts_high = [
  242.             prefix + 'raidenb/3__(raidenb).u022',
  243.             prefix + 'raidenb/4__(raidenb).u023',
  244.         ]
  245.         deinterleave16(f, maincpu_parts_low, 0x01_0000)
  246.         deinterleave16(f, maincpu_parts_high)
  247.  
  248.     with open('raiden/raiden_subcpu.bin', 'rb') as f:
  249.         sub_parts = [
  250.             prefix + 'raidenb/5__(raidenb).u042',
  251.             prefix + 'raidenb/6__(raidenb).u043',
  252.         ]
  253.         deinterleave16(f, sub_parts)
  254.  
  255.     with open('raiden/raiden_audiocpu.bin', 'rb') as f:
  256.         audiocpu_parts = [
  257.             (prefix + 'raidenb/rai6.u212', [(0, 0x8000),
  258.                                             (0x01_0000, 0x01_8000)]),
  259.         ]
  260.         split_ranges(f, audiocpu_parts)
  261.  
  262.     with open('raiden/raiden_gfx1.bin', 'rb') as f:
  263.         gfx1_parts = [
  264.             (prefix + 'raidenb/9', 0x8000),
  265.             (prefix + 'raidenb/10', 0x8000)
  266.         ]
  267.         split(f, gfx1_parts)
  268.  
  269.     with open('raiden/raiden_gfxdata2.bin', 'rb') as f:
  270.         gfx2 = prefix + 'raidenb/sei420'
  271.         pixel_de4_to_rai4(f, gfx2)
  272.  
  273.     with open('raiden/raiden_gfxdata3.bin', 'rb') as f:
  274.         gfx3 = prefix + 'raidenb/sei430'
  275.         pixel_de4_to_rai4(f, gfx3)
  276.  
  277.     with open('raiden/raiden_gfxdata4.bin', 'rb') as f:
  278.         gfx4 = prefix + 'raidenb/sei440'
  279.         pixel_de4_to_rai4(f, gfx4)
  280.  
  281.     shutil.copyfile('raiden/raiden_okim6295.bin', prefix + 'raidenb/7.u203')
  282.  
  283.     # plds
  284.     mkempty(prefix + 'raidenb/ep910pc-1.bin', 0x0884)
  285.     mkempty(prefix + 'raidenb/ep910pc-2.bin', 0x0884)
  286.  
  287.     # TMP plds?
  288.     mkempty(prefix + 'raidenb/jj3010.u0116', 0x0100)
  289.  
  290.  
  291. def rdft(prefix):
  292.     try:
  293.         os.mkdir(prefix + 'rdft')
  294.     except FileExistsError:
  295.         pass
  296.  
  297.     with open('rdft/rdft_i386.bin', 'rb') as f:
  298.         maincpu_parts = [
  299.             prefix + 'rdft/gd_1.211',
  300.             prefix + 'rdft/gd_2.212',
  301.             prefix + 'rdft/gd_3.210',
  302.             prefix + 'rdft/gd_4.29'
  303.         ]
  304.         deinterleave32(f, maincpu_parts)
  305.  
  306.     with open('rdft/rdft_gfxdata1.bin', 'rb') as f:
  307.         pixel_de5_to_spi6(f, prefix + 'rdft/rdft_gfxdata1.bin.spi', fix0=True,
  308.                           fix1=True)
  309.  
  310.     with open('rdft/rdft_gfxdata2.bin', 'rb') as f:
  311.         pixel_de5_to_spi6(f, prefix + 'rdft/rdft_gfxdata2.bin.spi')
  312.  
  313.     with open('rdft/rdft_gfxdata3.bin', 'rb') as f:
  314.         pixel_de5_to_spi6(f, prefix + 'rdft/rdft_gfxdata3.bin.spi')
  315.  
  316.     with open('rdft/rdft_soundrom.bin', 'rb') as f:
  317.         sound01_parts = [
  318.             (prefix + 'rdft/gd_pcm.217', 0x20_0000),
  319.             (prefix + 'rdft/gd_8.216', 0x08_0000),
  320.         ]
  321.         split(f, sound01_parts)
  322.  
  323.     with open(prefix + 'rdft/gd_1.211', 'rb') as f:
  324.         mkflash(f, prefix + 'rdft/')
  325.  
  326.  
  327. def rdft2(prefix):
  328.     try:
  329.         os.mkdir(prefix + 'rdft2')
  330.     except FileExistsError:
  331.         pass
  332.  
  333.     with open('rdft2/rdft2_i386.bin', 'rb') as f:
  334.         maincpu_parts = [
  335.             prefix + 'rdft2/prg0.tun',
  336.             prefix + 'rdft2/prg1.bin',
  337.             prefix + 'rdft2/prg2.bin',
  338.             prefix + 'rdft2/prg3.bin'
  339.         ]
  340.         deinterleave32(f, maincpu_parts)
  341.  
  342.     with open('rdft2/rdft2_soundrom.bin', 'rb') as f:
  343.         sound01_parts = [
  344.             (prefix + 'rdft2/pcm.u0217', 0x20_0000),
  345.             (prefix + 'rdft2/sound1.u0222', 0x08_0000),
  346.         ]
  347.         split(f, sound01_parts)
  348.  
  349.     with open(prefix + 'rdft2/prg0.tun', 'rb') as f:
  350.         mkflash(f, prefix + 'rdft2/')
  351.  
  352.  
  353. def convert():
  354.     outdir = 'mame/'
  355.     try:
  356.         os.mkdir(outdir)
  357.     except FileExistsError:
  358.         pass
  359.  
  360.     raidenb(outdir)
  361.     rdft(outdir)
  362.     rdft2(outdir)
  363.  
  364.  
  365. if __name__ == '__main__':
  366.     convert()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement