Naomi: GD-ROM support
This commit is contained in:
parent
40f2d64b6c
commit
62a3380bfa
|
@ -0,0 +1,613 @@
|
||||||
|
/*
|
||||||
|
* gdcartridge.cpp
|
||||||
|
*
|
||||||
|
* Created on: Nov 16, 2018
|
||||||
|
* Author: flyinghead
|
||||||
|
*
|
||||||
|
* From mame naomigd.cpp
|
||||||
|
* // license:BSD-3-Clause
|
||||||
|
* // copyright-holders:Olivier Galibert
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gdcartridge.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
GPIO pins(main board: EEPROM, DIMM SPDs, option board: PIC16, JPs)
|
||||||
|
|
|
||||||
|
SH4 <-> 315-6154 <-> PCI bus -> Sega 315-6322 -> Host system interface (NAOMI, Triforce, Chihiro)
|
||||||
|
| | -> 2x DIMM RAM modules
|
||||||
|
RAM RAM -> Altera (PCI IDE Bus Master Controller) -> IDE bus -> GD-ROM or CF
|
||||||
|
16MB 4MB -> PCnet-FAST III -> Ethernet
|
||||||
|
|
||||||
|
315-6154 - SH4 CPU to PCI bridge and SDRAM controller, also used in Sega Hikaru (2x)
|
||||||
|
315-6322 - DIMM SDRAM controller, DES decryption, host system communication
|
||||||
|
|
||||||
|
SH4 address space
|
||||||
|
-------------------
|
||||||
|
00000000 - 001FFFFF Flash ROM (1st half - stock firmware, 2nd half - updated firmware)
|
||||||
|
04000000 - 040000FF memory/PCI bridge registers (Sega 315-6154)
|
||||||
|
0C000000 - 0CFFFFFF SH4 local RAM
|
||||||
|
10000000 - 103FFFFF memory/PCI controller RAM
|
||||||
|
14000000 - 1BFFFFFF 8x banked pages
|
||||||
|
|
||||||
|
internal / PCI memory space
|
||||||
|
-------------------
|
||||||
|
00000000 - 000000FF DIMM controller registers (Sega 315-6322)
|
||||||
|
10000000 - 4FFFFFFF DIMM memory, upto 1GB (if register 28 bit 1 is 0, otherwise some unknown MMIO)
|
||||||
|
70000000 - 70FFFFFF SH4 local RAM
|
||||||
|
78000000 - 783FFFFF 315-6154 PCI bridge RAM
|
||||||
|
C00001xx IDE registers \
|
||||||
|
C00003xx IDE registers | software configured in VxWorks, preconfigured or hardcoded in 1.02
|
||||||
|
C000CCxx IDE Bus Master DMA registers /
|
||||||
|
C1xxxxxx Network registers
|
||||||
|
|
||||||
|
PCI configuration space (enabled using memctl 1C reg)
|
||||||
|
-------------------
|
||||||
|
00000000 - 00000FFF unknown, write 142 to reg 04 at very start
|
||||||
|
00001000 - 00001FFF PCI IDE controller (upper board Altera Flex) Vendor 11db Device 189d
|
||||||
|
00002000 - 00002FFF AMD AM79C973BVC PCnet-FAST III Network
|
||||||
|
|
||||||
|
DIMM controller registers
|
||||||
|
-------------------
|
||||||
|
14 5F703C |
|
||||||
|
18 5F7040 |
|
||||||
|
1C 5F7044 | 16bit 4x Communication registers
|
||||||
|
20 5F7048 |
|
||||||
|
24 5F704C 16bit Interrupt register
|
||||||
|
-------c ---b---a
|
||||||
|
a - IRQ to DIMM (SH4 IRL3): 0 set / 1 clear
|
||||||
|
b - unk, mask of a ???
|
||||||
|
c - IRQ to NAOMI (HOLLY EXT 3): 0 set / 1 clear (write 0 from NAOMI seems ignored)
|
||||||
|
|
||||||
|
28 16bit dddd---c ------ba
|
||||||
|
a - 0->1 NAOMI reset
|
||||||
|
b - 1 seems disable DIMM RAM access, followed by write 01010101 to bank 10 offset 000110 or 000190 (some MMIO?)
|
||||||
|
c - unk, set to 1 in VxWorks, 0 in 1.02
|
||||||
|
d - unk, checked for == 1 in 1.02
|
||||||
|
|
||||||
|
2A 8bit possible DES decryption area size 8 MSB bits (16MB units number)
|
||||||
|
VxWorks firmwares set this to ((DIMMsize >> 24) - 1), 1.02 set it to FF
|
||||||
|
|
||||||
|
2C 32bit SDRAM config
|
||||||
|
30 32bit DES key low
|
||||||
|
34 32bit DES key high
|
||||||
|
|
||||||
|
SH4 IO port A bits
|
||||||
|
-------------------
|
||||||
|
9 select input, 0 - main/lower board, 1 - option/upper board (IDE, Net, PIC)
|
||||||
|
0 1
|
||||||
|
0 DIMM SPD clk JP? 0 - enable IDE
|
||||||
|
1 DIMM SPD data JP? 0 - enable Network
|
||||||
|
2 93C46 DI PIC16 D0
|
||||||
|
3 93C46 CS PIC16 D1
|
||||||
|
4 93C46 CLK PIC16 D2
|
||||||
|
5 93C46 DO PIC16 CLK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dimm board communication registers software level usage:
|
||||||
|
|
||||||
|
Name: Naomi Dimm Bd.
|
||||||
|
NAOMI_DIMM_COMMAND = 5f703c 14000014 (16 bit):
|
||||||
|
if bits all 1 no dimm board present and other registers not used
|
||||||
|
bit 15: during an interrupt is 1 if the dimm board has a command to be executed
|
||||||
|
bit 14-9: 6 bit command number (naomi bios understands 0 1 3 4 5 6 8 9 a)
|
||||||
|
bit 7-0: higher 8 bits of 24 bit offset parameter
|
||||||
|
NAOMI_DIMM_OFFSETL = 5f7040 14000018 (16 bit):
|
||||||
|
bit 15-0: lower 16 bits of 24 bit offset parameter
|
||||||
|
NAOMI_DIMM_PARAMETERL = 5f7044 1400001c (16 bit)
|
||||||
|
NAOMI_DIMM_PARAMETERH = 5f7048 14000020 (16 bit)
|
||||||
|
NAOMI_DIMM_STATUS = 5f704c 14000024 (16 bit):
|
||||||
|
bit 0: when 0 signal interrupt from naomi to dimm board
|
||||||
|
bit 8: when 0 signal interrupt from dimm board to naomi
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_LEFTSWAP[] = {
|
||||||
|
0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00010000, 0x00010001, 0x00010100, 0x00010101,
|
||||||
|
0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_RIGHTSWAP[] = {
|
||||||
|
0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100,
|
||||||
|
0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101,
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX1[] = {
|
||||||
|
0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
|
||||||
|
0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
|
||||||
|
0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
|
||||||
|
0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
|
||||||
|
0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
|
||||||
|
0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
|
||||||
|
0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
|
||||||
|
0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX2[] = {
|
||||||
|
0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
|
||||||
|
0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
|
||||||
|
0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
|
||||||
|
0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
|
||||||
|
0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
|
||||||
|
0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
|
||||||
|
0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
|
||||||
|
0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX3[] = {
|
||||||
|
0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
|
||||||
|
0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
|
||||||
|
0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
|
||||||
|
0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
|
||||||
|
0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
|
||||||
|
0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
|
||||||
|
0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
|
||||||
|
0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX4[] = {
|
||||||
|
0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
|
||||||
|
0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
|
||||||
|
0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
|
||||||
|
0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
|
||||||
|
0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
|
||||||
|
0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
|
||||||
|
0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
|
||||||
|
0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX5[] = {
|
||||||
|
0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
|
||||||
|
0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
|
||||||
|
0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
|
||||||
|
0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
|
||||||
|
0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
|
||||||
|
0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
|
||||||
|
0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
|
||||||
|
0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX6[] = {
|
||||||
|
0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
|
||||||
|
0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
|
||||||
|
0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
|
||||||
|
0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
|
||||||
|
0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
|
||||||
|
0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
|
||||||
|
0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
|
||||||
|
0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX7[] = {
|
||||||
|
0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
|
||||||
|
0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
|
||||||
|
0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
|
||||||
|
0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
|
||||||
|
0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
|
||||||
|
0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
|
||||||
|
0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
|
||||||
|
0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_SBOX8[] = {
|
||||||
|
0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
|
||||||
|
0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
|
||||||
|
0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
|
||||||
|
0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
|
||||||
|
0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
|
||||||
|
0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
|
||||||
|
0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
|
||||||
|
0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800
|
||||||
|
};
|
||||||
|
|
||||||
|
const u32 GDCartridge::DES_MASK_TABLE[] = {
|
||||||
|
0x24000000, 0x10000000, 0x08000000, 0x02080000, 0x01000000,
|
||||||
|
0x00200000, 0x00100000, 0x00040000, 0x00020000, 0x00010000,
|
||||||
|
0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200,
|
||||||
|
0x00000100, 0x00000020, 0x00000010, 0x00000008, 0x00000004,
|
||||||
|
0x00000002, 0x00000001, 0x20000000, 0x10000000, 0x08000000,
|
||||||
|
0x04000000, 0x02000000, 0x01000000, 0x00200000, 0x00100000,
|
||||||
|
0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00002000,
|
||||||
|
0x00001000, 0x00000808, 0x00000400, 0x00000200, 0x00000100,
|
||||||
|
0x00000020, 0x00000011, 0x00000004, 0x00000002
|
||||||
|
};
|
||||||
|
|
||||||
|
const u8 GDCartridge::DES_ROTATE_TABLE[16] = {
|
||||||
|
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
void GDCartridge::permutate(u32 &a, u32 &b, u32 m, int shift)
|
||||||
|
{
|
||||||
|
u32 temp;
|
||||||
|
temp = ((a>>shift) ^ b) & m;
|
||||||
|
a ^= temp<<shift;
|
||||||
|
b ^= temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDCartridge::des_generate_subkeys(const u64 key, u32 *subkeys)
|
||||||
|
{
|
||||||
|
u32 l = key >> 32;
|
||||||
|
u32 r = key;
|
||||||
|
|
||||||
|
permutate(r, l, 0x0f0f0f0f, 4);
|
||||||
|
permutate(r, l, 0x10101010, 0);
|
||||||
|
|
||||||
|
l = (DES_LEFTSWAP[(l >> 0) & 0xf] << 3) |
|
||||||
|
(DES_LEFTSWAP[(l >> 8) & 0xf] << 2) |
|
||||||
|
(DES_LEFTSWAP[(l >> 16) & 0xf] << 1) |
|
||||||
|
(DES_LEFTSWAP[(l >> 24) & 0xf] << 0) |
|
||||||
|
(DES_LEFTSWAP[(l >> 5) & 0xf] << 7) |
|
||||||
|
(DES_LEFTSWAP[(l >> 13) & 0xf] << 6) |
|
||||||
|
(DES_LEFTSWAP[(l >> 21) & 0xf] << 5) |
|
||||||
|
(DES_LEFTSWAP[(l >> 29) & 0xf] << 4);
|
||||||
|
|
||||||
|
r = (DES_RIGHTSWAP[(r >> 1) & 0xf] << 3) |
|
||||||
|
(DES_RIGHTSWAP[(r >> 9) & 0xf] << 2) |
|
||||||
|
(DES_RIGHTSWAP[(r >> 17) & 0xf] << 1) |
|
||||||
|
(DES_RIGHTSWAP[(r >> 25) & 0xf] << 0) |
|
||||||
|
(DES_RIGHTSWAP[(r >> 4) & 0xf] << 7) |
|
||||||
|
(DES_RIGHTSWAP[(r >> 12) & 0xf] << 6) |
|
||||||
|
(DES_RIGHTSWAP[(r >> 20) & 0xf] << 5) |
|
||||||
|
(DES_RIGHTSWAP[(r >> 28) & 0xf] << 4);
|
||||||
|
|
||||||
|
l &= 0x0fffffff;
|
||||||
|
r &= 0x0fffffff;
|
||||||
|
|
||||||
|
|
||||||
|
for(int round = 0; round < 16; round++) {
|
||||||
|
l = ((l << DES_ROTATE_TABLE[round]) | (l >> (28 - DES_ROTATE_TABLE[round]))) & 0x0fffffff;
|
||||||
|
r = ((r << DES_ROTATE_TABLE[round]) | (r >> (28 - DES_ROTATE_TABLE[round]))) & 0x0fffffff;
|
||||||
|
|
||||||
|
subkeys[round*2] =
|
||||||
|
((l << 4) & DES_MASK_TABLE[0]) |
|
||||||
|
((l << 28) & DES_MASK_TABLE[1]) |
|
||||||
|
((l << 14) & DES_MASK_TABLE[2]) |
|
||||||
|
((l << 18) & DES_MASK_TABLE[3]) |
|
||||||
|
((l << 6) & DES_MASK_TABLE[4]) |
|
||||||
|
((l << 9) & DES_MASK_TABLE[5]) |
|
||||||
|
((l >> 1) & DES_MASK_TABLE[6]) |
|
||||||
|
((l << 10) & DES_MASK_TABLE[7]) |
|
||||||
|
((l << 2) & DES_MASK_TABLE[8]) |
|
||||||
|
((l >> 10) & DES_MASK_TABLE[9]) |
|
||||||
|
((r >> 13) & DES_MASK_TABLE[10])|
|
||||||
|
((r >> 4) & DES_MASK_TABLE[11])|
|
||||||
|
((r << 6) & DES_MASK_TABLE[12])|
|
||||||
|
((r >> 1) & DES_MASK_TABLE[13])|
|
||||||
|
((r >> 14) & DES_MASK_TABLE[14])|
|
||||||
|
((r >> 0) & DES_MASK_TABLE[15])|
|
||||||
|
((r >> 5) & DES_MASK_TABLE[16])|
|
||||||
|
((r >> 10) & DES_MASK_TABLE[17])|
|
||||||
|
((r >> 3) & DES_MASK_TABLE[18])|
|
||||||
|
((r >> 18) & DES_MASK_TABLE[19])|
|
||||||
|
((r >> 26) & DES_MASK_TABLE[20])|
|
||||||
|
((r >> 24) & DES_MASK_TABLE[21]);
|
||||||
|
|
||||||
|
subkeys[round*2+1] =
|
||||||
|
((l << 15) & DES_MASK_TABLE[22])|
|
||||||
|
((l << 17) & DES_MASK_TABLE[23])|
|
||||||
|
((l << 10) & DES_MASK_TABLE[24])|
|
||||||
|
((l << 22) & DES_MASK_TABLE[25])|
|
||||||
|
((l >> 2) & DES_MASK_TABLE[26])|
|
||||||
|
((l << 1) & DES_MASK_TABLE[27])|
|
||||||
|
((l << 16) & DES_MASK_TABLE[28])|
|
||||||
|
((l << 11) & DES_MASK_TABLE[29])|
|
||||||
|
((l << 3) & DES_MASK_TABLE[30])|
|
||||||
|
((l >> 6) & DES_MASK_TABLE[31])|
|
||||||
|
((l << 15) & DES_MASK_TABLE[32])|
|
||||||
|
((l >> 4) & DES_MASK_TABLE[33])|
|
||||||
|
((r >> 2) & DES_MASK_TABLE[34])|
|
||||||
|
((r << 8) & DES_MASK_TABLE[35])|
|
||||||
|
((r >> 14) & DES_MASK_TABLE[36])|
|
||||||
|
((r >> 9) & DES_MASK_TABLE[37])|
|
||||||
|
((r >> 0) & DES_MASK_TABLE[38])|
|
||||||
|
((r << 7) & DES_MASK_TABLE[39])|
|
||||||
|
((r >> 7) & DES_MASK_TABLE[40])|
|
||||||
|
((r >> 3) & DES_MASK_TABLE[41])|
|
||||||
|
((r << 2) & DES_MASK_TABLE[42])|
|
||||||
|
((r >> 21) & DES_MASK_TABLE[43]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GDCartridge::des_encrypt_decrypt(bool decrypt, u64 src, const u32 *des_subkeys)
|
||||||
|
{
|
||||||
|
u32 r = (src & 0x00000000ffffffffULL) >> 0;
|
||||||
|
u32 l = (src & 0xffffffff00000000ULL) >> 32;
|
||||||
|
|
||||||
|
permutate(l, r, 0x0f0f0f0f, 4);
|
||||||
|
permutate(l, r, 0x0000ffff, 16);
|
||||||
|
permutate(r, l, 0x33333333, 2);
|
||||||
|
permutate(r, l, 0x00ff00ff, 8);
|
||||||
|
permutate(l, r, 0x55555555, 1);
|
||||||
|
|
||||||
|
int subkey;
|
||||||
|
if(decrypt)
|
||||||
|
subkey = 30;
|
||||||
|
else
|
||||||
|
subkey = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < 32 ; i+=4) {
|
||||||
|
u32 temp;
|
||||||
|
|
||||||
|
temp = ((r<<1) | (r>>31)) ^ des_subkeys[subkey];
|
||||||
|
l ^= DES_SBOX8[ (temp>>0) & 0x3f ];
|
||||||
|
l ^= DES_SBOX6[ (temp>>8) & 0x3f ];
|
||||||
|
l ^= DES_SBOX4[ (temp>>16) & 0x3f ];
|
||||||
|
l ^= DES_SBOX2[ (temp>>24) & 0x3f ];
|
||||||
|
subkey++;
|
||||||
|
|
||||||
|
temp = ((r>>3) | (r<<29)) ^ des_subkeys[subkey];
|
||||||
|
l ^= DES_SBOX7[ (temp>>0) & 0x3f ];
|
||||||
|
l ^= DES_SBOX5[ (temp>>8) & 0x3f ];
|
||||||
|
l ^= DES_SBOX3[ (temp>>16) & 0x3f ];
|
||||||
|
l ^= DES_SBOX1[ (temp>>24) & 0x3f ];
|
||||||
|
subkey++;
|
||||||
|
if(decrypt)
|
||||||
|
subkey -= 4;
|
||||||
|
|
||||||
|
temp = ((l<<1) | (l>>31)) ^ des_subkeys[subkey];
|
||||||
|
r ^= DES_SBOX8[ (temp>>0) & 0x3f ];
|
||||||
|
r ^= DES_SBOX6[ (temp>>8) & 0x3f ];
|
||||||
|
r ^= DES_SBOX4[ (temp>>16) & 0x3f ];
|
||||||
|
r ^= DES_SBOX2[ (temp>>24) & 0x3f ];
|
||||||
|
subkey++;
|
||||||
|
|
||||||
|
temp = ((l>>3) | (l<<29)) ^ des_subkeys[subkey];
|
||||||
|
r ^= DES_SBOX7[ (temp>>0) & 0x3f ];
|
||||||
|
r ^= DES_SBOX5[ (temp>>8) & 0x3f ];
|
||||||
|
r ^= DES_SBOX3[ (temp>>16) & 0x3f ];
|
||||||
|
r ^= DES_SBOX1[ (temp>>24) & 0x3f ];
|
||||||
|
subkey++;
|
||||||
|
if(decrypt)
|
||||||
|
subkey -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
permutate(r, l, 0x55555555, 1);
|
||||||
|
permutate(l, r, 0x00ff00ff, 8);
|
||||||
|
permutate(l, r, 0x33333333, 2);
|
||||||
|
permutate(r, l, 0x0000ffff, 16);
|
||||||
|
permutate(r, l, 0x0f0f0f0f, 4);
|
||||||
|
|
||||||
|
return (u64(r) << 32) | u64(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GDCartridge::rev64(u64 src)
|
||||||
|
{
|
||||||
|
u64 ret;
|
||||||
|
|
||||||
|
ret = ((src & 0x00000000000000ffULL) << 56)
|
||||||
|
| ((src & 0x000000000000ff00ULL) << 40)
|
||||||
|
| ((src & 0x0000000000ff0000ULL) << 24)
|
||||||
|
| ((src & 0x00000000ff000000ULL) << 8 )
|
||||||
|
| ((src & 0x000000ff00000000ULL) >> 8 )
|
||||||
|
| ((src & 0x0000ff0000000000ULL) >> 24)
|
||||||
|
| ((src & 0x00ff000000000000ULL) >> 40)
|
||||||
|
| ((src & 0xff00000000000000ULL) >> 56);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GDCartridge::read_to_qword(const u8 *region)
|
||||||
|
{
|
||||||
|
u64 ret = 0;
|
||||||
|
|
||||||
|
for(int i=0;i<8;i++)
|
||||||
|
ret |= u64(region[i]) << (56-(8*i));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDCartridge::write_from_qword(u8 *region, u64 qword)
|
||||||
|
{
|
||||||
|
for(int i=0;i<8;i++)
|
||||||
|
region[i] = qword >> (56-(i*8));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDCartridge::find_file(const char *name, const u8 *dir_sector, u32 &file_start, u32 &file_size)
|
||||||
|
{
|
||||||
|
file_start = 0;
|
||||||
|
file_size = 0;
|
||||||
|
printf("Looking for file [%s]\n", name);
|
||||||
|
for(u32 pos = 0; pos < 2048; pos += dir_sector[pos]) {
|
||||||
|
int fnlen = 0;
|
||||||
|
if(!(dir_sector[pos+25] & 2)) {
|
||||||
|
int len = dir_sector[pos+32];
|
||||||
|
// printf("file: [%s]\n", &dir_sector[pos+33+fnlen]);
|
||||||
|
for(fnlen=0; fnlen < FILENAME_LENGTH; fnlen++) {
|
||||||
|
if((dir_sector[pos+33+fnlen] == ';') && (name[fnlen] == 0)) {
|
||||||
|
fnlen = FILENAME_LENGTH+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(dir_sector[pos+33+fnlen] != name[fnlen])
|
||||||
|
break;
|
||||||
|
if(fnlen == len) {
|
||||||
|
if(name[fnlen] == 0)
|
||||||
|
fnlen = FILENAME_LENGTH+1;
|
||||||
|
else
|
||||||
|
fnlen = FILENAME_LENGTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fnlen == FILENAME_LENGTH+1) {
|
||||||
|
// start sector and size of file
|
||||||
|
file_start = ((dir_sector[pos+2] << 0) |
|
||||||
|
(dir_sector[pos+3] << 8) |
|
||||||
|
(dir_sector[pos+4] << 16) |
|
||||||
|
(dir_sector[pos+5] << 24));
|
||||||
|
file_size = ((dir_sector[pos+10] << 0) |
|
||||||
|
(dir_sector[pos+11] << 8) |
|
||||||
|
(dir_sector[pos+12] << 16) |
|
||||||
|
(dir_sector[pos+13] << 24));
|
||||||
|
|
||||||
|
printf("start %08x size %08x\n", file_start, file_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (dir_sector[pos] == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDCartridge::read_gdrom(Disc *gdrom, u32 sector, u8* dst)
|
||||||
|
{
|
||||||
|
gdrom->ReadSectors(sector + 150, 1, dst, 2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDCartridge::device_start()
|
||||||
|
{
|
||||||
|
dimm_data = NULL;
|
||||||
|
dimm_data_size = 0;
|
||||||
|
|
||||||
|
char name[128];
|
||||||
|
memset(name,'\0',128);
|
||||||
|
|
||||||
|
u64 key;
|
||||||
|
u8 netpic = 0;
|
||||||
|
|
||||||
|
const u8 *picdata = this->RomPtr;
|
||||||
|
|
||||||
|
if (RomSize > 0 && gdrom_name != NULL)
|
||||||
|
{
|
||||||
|
if (RomSize >= 0x4000) {
|
||||||
|
printf("Real PIC binary found\n");
|
||||||
|
for(int i=0;i<7;i++)
|
||||||
|
name[i] = picdata[0x7c0+i*2];
|
||||||
|
for(int i=0;i<7;i++)
|
||||||
|
name[i+7] = picdata[0x7e0+i*2];
|
||||||
|
|
||||||
|
key = 0;
|
||||||
|
for(int i=0;i<7;i++)
|
||||||
|
key |= u64(picdata[0x780+i*2]) << (56 - i*8);
|
||||||
|
|
||||||
|
key |= picdata[0x7a0];
|
||||||
|
|
||||||
|
netpic = picdata[0x6ee];
|
||||||
|
} else {
|
||||||
|
// use extracted pic data
|
||||||
|
//printf("This PIC key hasn't been converted to a proper PIC binary yet!\n");
|
||||||
|
memcpy(name, picdata+33, 7);
|
||||||
|
memcpy(name+7, picdata+25, 7);
|
||||||
|
|
||||||
|
key =((u64(picdata[0x31]) << 56) |
|
||||||
|
(u64(picdata[0x32]) << 48) |
|
||||||
|
(u64(picdata[0x33]) << 40) |
|
||||||
|
(u64(picdata[0x34]) << 32) |
|
||||||
|
(u64(picdata[0x35]) << 24) |
|
||||||
|
(u64(picdata[0x36]) << 16) |
|
||||||
|
(u64(picdata[0x37]) << 8) |
|
||||||
|
(u64(picdata[0x29]) << 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("key is %08x%08x\n", (u32)((key & 0xffffffff00000000ULL)>>32), (u32)(key & 0x00000000ffffffffULL));
|
||||||
|
|
||||||
|
u8 buffer[2048];
|
||||||
|
std::string gdrom_path = get_game_basename() + "/" + gdrom_name;
|
||||||
|
Disc *gdrom = OpenDisc((gdrom_path + ".chd").c_str());
|
||||||
|
if (gdrom == NULL)
|
||||||
|
gdrom = OpenDisc((gdrom_path + ".gdi").c_str());
|
||||||
|
if (gdrom == NULL)
|
||||||
|
return;
|
||||||
|
// primary volume descriptor
|
||||||
|
// read frame 0xb06e (frame=sector+150)
|
||||||
|
// dimm board firmware starts straight from this frame
|
||||||
|
read_gdrom(gdrom, (netpic ? 0 : 45000) + 16, buffer);
|
||||||
|
u32 path_table = ((buffer[0x8c+0] << 0) |
|
||||||
|
(buffer[0x8c+1] << 8) |
|
||||||
|
(buffer[0x8c+2] << 16) |
|
||||||
|
(buffer[0x8c+3] << 24));
|
||||||
|
// path table
|
||||||
|
read_gdrom(gdrom, path_table, buffer);
|
||||||
|
|
||||||
|
// directory
|
||||||
|
u8 dir_sector[2048];
|
||||||
|
// find data of file
|
||||||
|
u32 file_start, file_size;
|
||||||
|
|
||||||
|
if (netpic == 0) {
|
||||||
|
u32 dir = ((buffer[0x2 + 0] << 0) |
|
||||||
|
(buffer[0x2 + 1] << 8) |
|
||||||
|
(buffer[0x2 + 2] << 16) |
|
||||||
|
(buffer[0x2 + 3] << 24));
|
||||||
|
|
||||||
|
read_gdrom(gdrom, dir, dir_sector);
|
||||||
|
find_file(name, dir_sector, file_start, file_size);
|
||||||
|
|
||||||
|
if (file_start && (file_size == 0x100)) {
|
||||||
|
// read file
|
||||||
|
read_gdrom(gdrom, file_start, buffer);
|
||||||
|
// get "rom" file name
|
||||||
|
memset(name, '\0', 128);
|
||||||
|
memcpy(name, buffer + 0xc0, FILENAME_LENGTH - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
u32 i = 0;
|
||||||
|
while (i < 2048 && buffer[i] != 0)
|
||||||
|
{
|
||||||
|
if (buffer[i] == 3 && buffer[i + 8] == 'R' && buffer[i + 9] == 'O' && buffer[i + 10] == 'M') // find ROM dir
|
||||||
|
{
|
||||||
|
u32 dir = ((buffer[i + 2] << 0) |
|
||||||
|
(buffer[i + 3] << 8) |
|
||||||
|
(buffer[i + 4] << 16) |
|
||||||
|
(buffer[i + 5] << 24));
|
||||||
|
memcpy(name, "ROM.BIN", 7);
|
||||||
|
read_gdrom(gdrom, dir, dir_sector);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += buffer[i] + 8 + (buffer[i] & 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
find_file(name, dir_sector, file_start, file_size);
|
||||||
|
|
||||||
|
if (file_start) {
|
||||||
|
u32 file_rounded_size = (file_size + 2047) & -2048;
|
||||||
|
for (dimm_data_size = 4096; dimm_data_size < file_rounded_size; dimm_data_size <<= 1);
|
||||||
|
dimm_data = malloc(dimm_data_size);
|
||||||
|
if (dimm_data_size != file_rounded_size)
|
||||||
|
memset(dimm_data + file_rounded_size, 0, dimm_data_size - file_rounded_size);
|
||||||
|
|
||||||
|
// read encrypted data into dimm_data
|
||||||
|
u32 sectors = file_rounded_size / 2048;
|
||||||
|
for (u32 sec = 0; sec != sectors; sec++)
|
||||||
|
read_gdrom(gdrom, file_start + sec, dimm_data + 2048 * sec);
|
||||||
|
|
||||||
|
u32 des_subkeys[32];
|
||||||
|
des_generate_subkeys(rev64(key), des_subkeys);
|
||||||
|
|
||||||
|
for (int i = 0; i < file_rounded_size; i += 8)
|
||||||
|
write_from_qword(dimm_data + i, rev64(des_encrypt_decrypt(true, rev64(read_to_qword(dimm_data + i)), des_subkeys)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrypt loaded data
|
||||||
|
delete gdrom;
|
||||||
|
|
||||||
|
if (!dimm_data)
|
||||||
|
printf("Naomi GDROM: Could not find the file to decrypt.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDCartridge::device_reset()
|
||||||
|
{
|
||||||
|
dimm_cur_address = 0;
|
||||||
|
}
|
||||||
|
void *GDCartridge::GetDmaPtr(u32 &size)
|
||||||
|
{
|
||||||
|
dimm_cur_address = DmaOffset & (dimm_data_size-1);
|
||||||
|
size = min(size, dimm_data_size - dimm_cur_address);
|
||||||
|
return dimm_data + dimm_cur_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDCartridge::AdvancePtr(u32 size)
|
||||||
|
{
|
||||||
|
dimm_cur_address += size;
|
||||||
|
if(dimm_cur_address >= dimm_data_size)
|
||||||
|
dimm_cur_address %= dimm_data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GDCartridge::Read(u32 offset, u32 size, void *dst)
|
||||||
|
{
|
||||||
|
u32 addr = offset & (dimm_data_size-1);
|
||||||
|
memcpy(dst, &dimm_data[addr], min(size, dimm_data_size - addr));
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* gdcartridge.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 16, 2018
|
||||||
|
* Author: flyinghead
|
||||||
|
*
|
||||||
|
* From mame naomigd.h
|
||||||
|
* // license:BSD-3-Clause
|
||||||
|
* // copyright-holders:Olivier Galibert
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CORE_HW_NAOMI_GDCARTRIDGE_H_
|
||||||
|
#define CORE_HW_NAOMI_GDCARTRIDGE_H_
|
||||||
|
|
||||||
|
#include "naomi_cart.h"
|
||||||
|
#include "imgread/common.h"
|
||||||
|
|
||||||
|
class GDCartridge: public NaomiCartridge {
|
||||||
|
public:
|
||||||
|
GDCartridge(u32 size) : NaomiCartridge(size)
|
||||||
|
{
|
||||||
|
gdrom_name = NULL;
|
||||||
|
}
|
||||||
|
virtual void Init() override
|
||||||
|
{
|
||||||
|
device_start();
|
||||||
|
device_reset();
|
||||||
|
}
|
||||||
|
virtual void* GetDmaPtr(u32 &size) override;
|
||||||
|
virtual void AdvancePtr(u32 size) override;
|
||||||
|
virtual bool Read(u32 offset, u32 size, void* dst) override;
|
||||||
|
void SetGDRomName(const char *name) { this->gdrom_name = name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { FILENAME_LENGTH=24 };
|
||||||
|
|
||||||
|
const char *gdrom_name;
|
||||||
|
|
||||||
|
u32 dimm_cur_address;
|
||||||
|
|
||||||
|
u8 *dimm_data;
|
||||||
|
u32 dimm_data_size;
|
||||||
|
|
||||||
|
static const u32 DES_LEFTSWAP[];
|
||||||
|
static const u32 DES_RIGHTSWAP[];
|
||||||
|
static const u32 DES_SBOX1[];
|
||||||
|
static const u32 DES_SBOX2[];
|
||||||
|
static const u32 DES_SBOX3[];
|
||||||
|
static const u32 DES_SBOX4[];
|
||||||
|
static const u32 DES_SBOX5[];
|
||||||
|
static const u32 DES_SBOX6[];
|
||||||
|
static const u32 DES_SBOX7[];
|
||||||
|
static const u32 DES_SBOX8[];
|
||||||
|
static const u32 DES_MASK_TABLE[];
|
||||||
|
static const u8 DES_ROTATE_TABLE[16];
|
||||||
|
|
||||||
|
void device_start();
|
||||||
|
void device_reset();
|
||||||
|
void find_file(const char *name, const u8 *dir_sector, u32 &file_start, u32 &file_size);
|
||||||
|
|
||||||
|
inline void permutate(u32 &a, u32 &b, u32 m, int shift);
|
||||||
|
void des_generate_subkeys(const u64 key, u32 *subkeys);
|
||||||
|
u64 des_encrypt_decrypt(bool decrypt, u64 src, const u32 *des_subkeys);
|
||||||
|
u64 rev64(u64 src);
|
||||||
|
u64 read_to_qword(const u8 *region);
|
||||||
|
void write_from_qword(u8 *region, u64 qword);
|
||||||
|
void read_gdrom(Disc *gdrom, u32 sector, u8* dst);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CORE_HW_NAOMI_GDCARTRIDGE_H_ */
|
|
@ -10,6 +10,7 @@
|
||||||
#include "m1cartridge.h"
|
#include "m1cartridge.h"
|
||||||
#include "m4cartridge.h"
|
#include "m4cartridge.h"
|
||||||
#include "awcartridge.h"
|
#include "awcartridge.h"
|
||||||
|
#include "gdcartridge.h"
|
||||||
|
|
||||||
Cartridge *CurrentCartridge;
|
Cartridge *CurrentCartridge;
|
||||||
bool bios_loaded = false;
|
bool bios_loaded = false;
|
||||||
|
@ -332,6 +333,13 @@ static bool naomi_cart_LoadZip(char *filename)
|
||||||
case AW:
|
case AW:
|
||||||
CurrentCartridge = new AWCartridge(game->size);
|
CurrentCartridge = new AWCartridge(game->size);
|
||||||
break;
|
break;
|
||||||
|
case GD:
|
||||||
|
{
|
||||||
|
GDCartridge *gdcart = new GDCartridge(game->size);
|
||||||
|
gdcart->SetGDRomName(game->gdrom_name);
|
||||||
|
CurrentCartridge = gdcart;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
die("Unsupported cartridge type\n");
|
die("Unsupported cartridge type\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -39,7 +39,8 @@ enum CartridgeType {
|
||||||
M1,
|
M1,
|
||||||
M2,
|
M2,
|
||||||
M4,
|
M4,
|
||||||
AW
|
AW,
|
||||||
|
GD
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BIOS_t
|
struct BIOS_t
|
||||||
|
@ -184,6 +185,7 @@ struct Game
|
||||||
BlobType blob_type;
|
BlobType blob_type;
|
||||||
u32 src_offset; // For copy
|
u32 src_offset; // For copy
|
||||||
} blobs[MAX_GAME_FILES];
|
} blobs[MAX_GAME_FILES];
|
||||||
|
const char *gdrom_name;
|
||||||
InputDescriptors *inputs;
|
InputDescriptors *inputs;
|
||||||
}
|
}
|
||||||
Games[] =
|
Games[] =
|
||||||
|
@ -294,6 +296,7 @@ Games[] =
|
||||||
|
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&mvsc2_inputs
|
&mvsc2_inputs
|
||||||
},
|
},
|
||||||
// Quiz Ah Megamisama (JPN, USA, EXP, KOR, AUS)
|
// Quiz Ah Megamisama (JPN, USA, EXP, KOR, AUS)
|
||||||
|
@ -451,6 +454,7 @@ Games[] =
|
||||||
{ "copy", 0x0400000, 0xc00000, Copy, 0x1000000 }, // changed
|
{ "copy", 0x0400000, 0xc00000, Copy, 0x1000000 }, // changed
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&vtenis2c_inputs
|
&vtenis2c_inputs
|
||||||
},
|
},
|
||||||
// Naomi M2/M3 Roms
|
// Naomi M2/M3 Roms
|
||||||
|
@ -485,6 +489,7 @@ Games[] =
|
||||||
{ "mpr-22183.ic20s", 0xa000000, 0x800000 },
|
{ "mpr-22183.ic20s", 0xa000000, 0x800000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&_18wheelr_inputs
|
&_18wheelr_inputs
|
||||||
},
|
},
|
||||||
// 18 Wheeler (deluxe)
|
// 18 Wheeler (deluxe)
|
||||||
|
@ -533,6 +538,7 @@ Games[] =
|
||||||
|
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&_18wheelr_inputs
|
&_18wheelr_inputs
|
||||||
},
|
},
|
||||||
// 18 Wheeler (deluxe) (Rev T)
|
// 18 Wheeler (deluxe) (Rev T)
|
||||||
|
@ -581,6 +587,7 @@ Games[] =
|
||||||
|
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&_18wheelr_inputs
|
&_18wheelr_inputs
|
||||||
},
|
},
|
||||||
// 18 Wheeler (standard)
|
// 18 Wheeler (standard)
|
||||||
|
@ -626,6 +633,7 @@ Games[] =
|
||||||
|
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&_18wheelr_inputs
|
&_18wheelr_inputs
|
||||||
},
|
},
|
||||||
// 18 Wheeler (upright)
|
// 18 Wheeler (upright)
|
||||||
|
@ -670,6 +678,7 @@ Games[] =
|
||||||
|
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&_18wheelr_inputs
|
&_18wheelr_inputs
|
||||||
},
|
},
|
||||||
// Airline Pilots (Rev B)
|
// Airline Pilots (Rev B)
|
||||||
|
@ -739,6 +748,7 @@ Games[] =
|
||||||
{ "mpr-23585.ic5", 0x4800000, 0x1000000 },
|
{ "mpr-23585.ic5", 0x4800000, 0x1000000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&alienfnt_inputs
|
&alienfnt_inputs
|
||||||
},
|
},
|
||||||
// Alien Front (Rev A)
|
// Alien Front (Rev A)
|
||||||
|
@ -757,6 +767,7 @@ Games[] =
|
||||||
{ "mpr-23585.ic5", 0x4800000, 0x1000000 },
|
{ "mpr-23585.ic5", 0x4800000, 0x1000000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&alienfnt_inputs
|
&alienfnt_inputs
|
||||||
},
|
},
|
||||||
// Capcom Vs. SNK Millennium Fight 2000 (JPN, USA, EXP, KOR, AUS) (Rev C)
|
// Capcom Vs. SNK Millennium Fight 2000 (JPN, USA, EXP, KOR, AUS) (Rev C)
|
||||||
|
@ -777,6 +788,7 @@ Games[] =
|
||||||
{ "mpr-23510.ic7", 0x6800000, 0x1000000 },
|
{ "mpr-23510.ic7", 0x6800000, 0x1000000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&capsnk_inputs
|
&capsnk_inputs
|
||||||
},
|
},
|
||||||
// Capcom Vs. SNK Millennium Fight 2000 (Rev A)
|
// Capcom Vs. SNK Millennium Fight 2000 (Rev A)
|
||||||
|
@ -797,6 +809,7 @@ Games[] =
|
||||||
{ "mpr-23510.ic7", 0x6800000, 0x1000000 },
|
{ "mpr-23510.ic7", 0x6800000, 0x1000000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&capsnk_inputs
|
&capsnk_inputs
|
||||||
},
|
},
|
||||||
// Capcom Vs. SNK Millennium Fight 2000
|
// Capcom Vs. SNK Millennium Fight 2000
|
||||||
|
@ -817,6 +830,7 @@ Games[] =
|
||||||
{ "mpr-23510.ic7", 0x6800000, 0x1000000 },
|
{ "mpr-23510.ic7", 0x6800000, 0x1000000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&capsnk_inputs
|
&capsnk_inputs
|
||||||
},
|
},
|
||||||
// Crackin' DJ
|
// Crackin' DJ
|
||||||
|
@ -901,6 +915,7 @@ Games[] =
|
||||||
{ "mpr-21683.ic15s", 0x7800000, 0x800000 },
|
{ "mpr-21683.ic15s", 0x7800000, 0x800000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&crzytaxi_inputs
|
&crzytaxi_inputs
|
||||||
},
|
},
|
||||||
// Cosmic Smash (Rev A)
|
// Cosmic Smash (Rev A)
|
||||||
|
@ -966,6 +981,7 @@ Games[] =
|
||||||
{ "mpr-23209.ic12s", 0x6000000, 0x0800000 },
|
{ "mpr-23209.ic12s", 0x6000000, 0x0800000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&cspike_inputs
|
&cspike_inputs
|
||||||
},
|
},
|
||||||
// Death Crimson OX (JPN, USA, EXP, KOR, AUS)
|
// Death Crimson OX (JPN, USA, EXP, KOR, AUS)
|
||||||
|
@ -989,6 +1005,7 @@ Games[] =
|
||||||
{ "mpr-23523.ic10", 0x5000000, 0x0800000 },
|
{ "mpr-23523.ic10", 0x5000000, 0x0800000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&trigger_inputs
|
&trigger_inputs
|
||||||
},
|
},
|
||||||
// Death Crimson OX
|
// Death Crimson OX
|
||||||
|
@ -1012,6 +1029,7 @@ Games[] =
|
||||||
{ "mpr-23523.ic10", 0x5000000, 0x0800000 },
|
{ "mpr-23523.ic10", 0x5000000, 0x0800000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&trigger_inputs
|
&trigger_inputs
|
||||||
},
|
},
|
||||||
// Derby Owners Club 2000 (Rev A)
|
// Derby Owners Club 2000 (Rev A)
|
||||||
|
@ -1525,6 +1543,7 @@ Games[] =
|
||||||
{ "bhf1ma15.6l", 0xf000000, 0x1000000 },
|
{ "bhf1ma15.6l", 0xf000000, 0x1000000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&gunsur2_inputs
|
&gunsur2_inputs
|
||||||
},
|
},
|
||||||
// Gun Survivor 2 Biohazard Code: Veronica (Japan, BHF1 Ver.E)
|
// Gun Survivor 2 Biohazard Code: Veronica (Japan, BHF1 Ver.E)
|
||||||
|
@ -1552,6 +1571,7 @@ Games[] =
|
||||||
{ "bhf1ma15.6l", 0xf000000, 0x1000000 },
|
{ "bhf1ma15.6l", 0xf000000, 0x1000000 },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&gunsur2_inputs
|
&gunsur2_inputs
|
||||||
},
|
},
|
||||||
// Giga Wing 2
|
// Giga Wing 2
|
||||||
|
@ -1933,6 +1953,7 @@ Games[] =
|
||||||
//ROM_LOAD("sflash.ic37", 0x000000, 0x000084, CRC(37a66f3c) SHA1(df6cd2cdc2813caa5da4dc9f171998485bcbdc44))
|
//ROM_LOAD("sflash.ic37", 0x000000, 0x000084, CRC(37a66f3c) SHA1(df6cd2cdc2813caa5da4dc9f171998485bcbdc44))
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&mvsc2_inputs
|
&mvsc2_inputs
|
||||||
},
|
},
|
||||||
// Ninja Assault (NJA3 Ver. A)
|
// Ninja Assault (NJA3 Ver. A)
|
||||||
|
@ -3607,7 +3628,38 @@ Games[] =
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Naomi GD-roms
|
||||||
|
|
||||||
|
// Confidential Mission
|
||||||
|
{
|
||||||
|
"confmiss.zip",
|
||||||
|
0x4000,
|
||||||
|
0,
|
||||||
|
"naomi.zip",
|
||||||
|
GD,
|
||||||
|
{
|
||||||
|
{ "317-0298-com.pic", 0, 0x4000 },
|
||||||
|
{ NULL, 0, 0 },
|
||||||
|
},
|
||||||
|
"gds-0001",
|
||||||
|
},
|
||||||
|
// Slashout
|
||||||
|
{
|
||||||
|
"slashout.zip",
|
||||||
|
0x4000,
|
||||||
|
0,
|
||||||
|
"naomi.zip",
|
||||||
|
GD,
|
||||||
|
{
|
||||||
|
{ "317-0302-com.pic", 0, 0x4000 },
|
||||||
|
{ NULL, 0, 0 },
|
||||||
|
},
|
||||||
|
"gds-0004",
|
||||||
|
},
|
||||||
|
|
||||||
// AtomisWave Roms
|
// AtomisWave Roms
|
||||||
|
|
||||||
// Animal Basket (24 Jan 2005)
|
// Animal Basket (24 Jan 2005)
|
||||||
{
|
{
|
||||||
"anmlbskt.zip",
|
"anmlbskt.zip",
|
||||||
|
@ -3815,6 +3867,7 @@ Games[] =
|
||||||
{ "ax1701f01.bin", 0, 4, Key },
|
{ "ax1701f01.bin", 0, 4, Key },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&ftspeed_inputs,
|
&ftspeed_inputs,
|
||||||
},
|
},
|
||||||
// Guilty Gear Isuka
|
// Guilty Gear Isuka
|
||||||
|
@ -3954,6 +4007,7 @@ Games[] =
|
||||||
{ "ax0501f01.bin", 0, 4, Key },
|
{ "ax0501f01.bin", 0, 4, Key },
|
||||||
{ NULL, 0, 0 },
|
{ NULL, 0, 0 },
|
||||||
},
|
},
|
||||||
|
NULL,
|
||||||
&maxspeed_inputs
|
&maxspeed_inputs
|
||||||
},
|
},
|
||||||
// Metal Slug 6
|
// Metal Slug 6
|
||||||
|
|
Loading…
Reference in New Issue