Naomi update [Deunan Knute, R. Belmont]

- Implemented cartridge protection chip mechanism
- Added protection data for doa2 and doa2m
- Added real dumped cartridge X76F100 data for doa2/doa2m



doa2 now hangs in a loop at c001192 waiting for some interrupt(?) that
never occurs.  doa2m is similar.  Kale, would you mind having a look?

Encryption fairies may wish to look and see if the protection data is derived
from the ROM contents at all, although it appears there's maybe just a ROM 
inside the protection ASIC.
This commit is contained in:
R. Belmont 2009-07-18 22:11:57 +00:00
parent afcb49623a
commit e48daa45ae
2 changed files with 157 additions and 11 deletions

View File

@ -2026,6 +2026,29 @@ ROM_START( doa2 )
ROM_LOAD("mpr-22118.ic19",0x9800000, 0x0800000, CRC(8d631cbf) SHA1(fe8a65d35b1cdaed650ddde931e59f0768ffff53) )
ROM_LOAD("mpr-22119.ic20",0xa000000, 0x0800000, CRC(d608fa86) SHA1(54c8107cccec8cbb536f13cda5b220b7972190b7) )
ROM_LOAD("mpr-22120.ic21",0xa800000, 0x0800000, CRC(a30facb4) SHA1(70415ca34095c795297486bce1f956f6a8d4817f) )
// on-cart X76F100 eeprom contents
ROM_REGION( 0x100, "naomibd_eeprom", ROMREGION_ERASE00 )
ROM_LOAD( "841-0003.sf", 0x000000, 0x000084, CRC(3a119a17) SHA1(d37a092cca7c9cfc5f2637b355af90a65d04013e) )
// trojaned protection data (filename is word offset)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "00000500.bin", 0x000500, 0x020000, CRC(3751d50e) SHA1(08d56e7befd3e1bc2c29217c60dee0c862af65ed) )
ROM_LOAD( "00020504.bin", 0x020504, 0x020000, CRC(6b4ab9f6) SHA1(205c355a5a55659f35645d3e66dc1dcff703727c) )
ROM_LOAD( "00040508.bin", 0x040508, 0x020000, CRC(dae5d37d) SHA1(63d0cde73b86e77ea7b5e1d71643566c500f9933) )
ROM_LOAD( "0006050c.bin", 0x06050c, 0x020000, CRC(c2b7ea51) SHA1(59f1cb01b140e7fdea7d945acad464e08e3adf44) )
ROM_LOAD( "00080510.bin", 0x080510, 0x020000, CRC(7b84acb4) SHA1(e48448795c058c0fc3a9e9108de18a3181db5417) )
ROM_LOAD( "000a0514.bin", 0x0a0514, 0x020000, CRC(f954ffcd) SHA1(3015dfc298de1e16db07406e9ecb5fc0e2aae0a8) )
ROM_LOAD( "000c0518.bin", 0x0c0518, 0x020000, CRC(28fce8ad) SHA1(180ae2dc9181bbe4215093e4e933c9e78d3af7a8) )
ROM_LOAD( "000e051c.bin", 0x0e051c, 0x020000, CRC(a7f7a5c1) SHA1(6b39aa8f8a762ffe61b07f77713cca5c95a8dfcf) )
ROM_LOAD( "00100520.bin", 0x100520, 0x020000, CRC(85417674) SHA1(0d35aa0f3d5f451bbf4daad343b9ad1ebd9d9551) )
ROM_LOAD( "00118a3a.bin", 0x118a3a, 0x020000, CRC(72e58444) SHA1(09ae85c131f7b4a0638efd1dff0807cc20b59637) )
ROM_LOAD( "0012c0d8.bin", 0x12c0d8, 0x020000, CRC(84e8e517) SHA1(f1e81913181b9c6276a430988fefc00597e33e89) )
ROM_LOAD( "00147e22.bin", 0x147e22, 0x020000, CRC(66efd53e) SHA1(40cfc20df93f9ec1f260fc3f56bb5ac0be775cc6) )
ROM_LOAD( "001645ce.bin", 0x1645ce, 0x020000, CRC(adc73d19) SHA1(4df4bd7db6bf2f9af06d9d3ec9466970bec7833c) )
ROM_LOAD( "0017c6b2.bin", 0x17c6b2, 0x020000, CRC(717f2e91) SHA1(e03d778a1c39cf01827f79a1b10c03a4a6047962) )
ROM_LOAD( "0019902e.bin", 0x19902e, 0x020000, CRC(f4882ea8) SHA1(a27e52062780e095675f749191e0ea22755152eb) )
ROM_LOAD( "001b562a.bin", 0x1b562a, 0x013e00, CRC(01ae0721) SHA1(b9f24e0bb8609b8cb1a45e7c1e1dc1f271bbdcaf) )
ROM_END
/*
@ -2091,6 +2114,29 @@ ROM_START( doa2m )
ROM_LOAD("mpr-22118.ic19",0x9800000, 0x0800000, CRC(8d631cbf) SHA1(fe8a65d35b1cdaed650ddde931e59f0768ffff53) )
ROM_LOAD("mpr-22119.ic20",0xa000000, 0x0800000, CRC(d608fa86) SHA1(54c8107cccec8cbb536f13cda5b220b7972190b7) )
ROM_LOAD("mpr-22120.ic21",0xa800000, 0x0800000, CRC(a30facb4) SHA1(70415ca34095c795297486bce1f956f6a8d4817f) )
// on-cart X76F100 eeprom contents
ROM_REGION( 0x100, "naomibd_eeprom", ROMREGION_ERASE00 )
ROM_LOAD( "841-0003.sf", 0x000000, 0x000084, CRC(3a119a17) SHA1(d37a092cca7c9cfc5f2637b355af90a65d04013e) )
// trojaned protection data (filename is word offset)
ROM_REGION( 0x200000, "naomibd_prot", ROMREGION_ERASE00 )
ROM_LOAD( "00000500.bin", 0x000500, 0x020000, CRC(a42f0337) SHA1(0aaeff753a4e2f9b5d287cd80952533f0ced430c) )
ROM_LOAD( "00020504.bin", 0x020504, 0x020000, CRC(3d3bfbe4) SHA1(4748ca4c14a31da623ebd3a1acff93635c039888) )
ROM_LOAD( "00040508.bin", 0x040508, 0x020000, CRC(d0c3699c) SHA1(11a4e8b47cb6ae827307cd44689477ebfe23d690) )
ROM_LOAD( "0006050c.bin", 0x06050c, 0x020000, CRC(bc2e8e71) SHA1(253561a58caf15607d87d932d9b98d6ffa779669) )
ROM_LOAD( "00080510.bin", 0x080510, 0x020000, CRC(a26a6159) SHA1(8e4f0a2091b5b2eb825bb9220c5e4dfe9ab935fe) )
ROM_LOAD( "000a0514.bin", 0x0a0514, 0x020000, CRC(83138b3b) SHA1(6b69e43b6e6c4b75278045a883337cb7abcf9501) )
ROM_LOAD( "000c0518.bin", 0x0c0518, 0x020000, CRC(9f246058) SHA1(bc54f3bdc23a278b14867e096c3f644447b9c0a6) )
ROM_LOAD( "000e051c.bin", 0x0e051c, 0x020000, CRC(7cfd53d5) SHA1(d77ff8d3edbc2d41334d6416d17339ea2c764887) )
ROM_LOAD( "00100520.bin", 0x100520, 0x020000, CRC(8dd856d3) SHA1(9952fdf9017bdb8c50b413de5817a746c24901e9) )
ROM_LOAD( "0011a5b4.bin", 0x11a5b4, 0x020000, CRC(484c511d) SHA1(02c8c1b46ce8a27b85652d3f032f4f42be5341ba) )
ROM_LOAD( "0012e7c4.bin", 0x12e7c4, 0x020000, CRC(ceffdd4b) SHA1(36dfa9fd4857429cf9b505d04d7a82d3bc161b90) )
ROM_LOAD( "001471f6.bin", 0x1471f6, 0x020000, CRC(263d0706) SHA1(194e259b78d3006372ad007a7e3b9456f607b922) )
ROM_LOAD( "001640c4.bin", 0x1640c4, 0x020000, CRC(3addb31e) SHA1(97794166b0811ff9535b3a3f598e0cb3da9fc7b3) )
ROM_LOAD( "001806ca.bin", 0x1806ca, 0x020000, CRC(dbfddad2) SHA1(72696b5ed942fe3ef0bc271f6d66d5f089221192) )
ROM_LOAD( "00199df4.bin", 0x199df4, 0x020000, CRC(2ab0d0c3) SHA1(10642e9d8c9c24f366359fbe7890a0f1347a7a1a) )
ROM_LOAD( "001b5d0a.bin", 0x1b5d0a, 0x017e00, CRC(c9c3bbd5) SHA1(6f3853e3e1614993b5d658ebec6bf5183577ab36) )
ROM_END
/*

View File

@ -3,6 +3,7 @@
Naomi plug-in board emulator
emulator by Samuele Zannoli
protection chip by R. Belmont, reverse engineering by Deunan Knute
**************************************************************************/
@ -40,6 +41,35 @@
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
Cartridge protection info from Deunan Knute:
NAOMI cart can hold up to 256MB of data (well, 512 is possible too I guess), so the highest bits are used for other, dark and scary purposes.
I call those bits "mode selector".
First it's important to note that DMA and PIO seem to have separate address counters, as well as separate mode selector registers.
* bit 31 (mode bit 3) is auto-advance bit
When set to one the address will be automatically incremented when data is read, so you need only set it once and can just keep polling
the PIO port. When zero it will stay on current address. Now this works exactly the same for DMA, and even if DMA engine is 32-byte
per block it will repeatedly read only the first 16-bit word.
* bit 30 (mode bit 2) is most often as special mode switch
DMA transfer with this bit set will hang. PIO will return semi-random data (floating bus?). So one function of that bit is "disable".
PIO read will return all ones if DMA mode has this bit cleared, so it seems you can do either PIO or DMA but not both at the same time.
In other words, disable DMA once before using PIO (most games using both access types do that when the DMA terminates).
This bit is also used to reset the chip's internal protection mechanism on "Oh! My Goddess" to a known state.
* bit 29 (mode bit 1) is address shuffle bit
It's actually the opposite, when set the addressing is following the chip layout and when cleared the protection chip will have it's fun
with address lines 10 to 23(?). It's not a simple swap function, rather a lookup table and one with repeating results too.
The few games I got to work never made any use of that bit, it's always set for all normal reads.
* bit 28 (mode bit 0) is unused (so far)
Or it could really be the last address bit to allow up to 512MB of data on a cart?
Normal address starts with 0xa0000000 to enable auto-advance and standard addressing mode.
*/
// NOTE: all accesses are 16 or 32 bits wide but only 16 bits are valid
@ -52,6 +82,9 @@
#include "cdrom.h"
#include "naomibd.h"
#define NAOMIBD_FLAG_AUTO_ADVANCE (8) // address auto-advances on read
#define NAOMIBD_FLAG_SPECIAL_MODE (4) // used to access protection registers
#define NAOMIBD_FLAG_ADDRESS_SHUFFLE (2) // 0 to let protection chip scramble address lines, 1 for normal
/*************************************
*
@ -76,10 +109,12 @@ struct _naomibd_state
const device_config *device; /* pointer to our containing device */
UINT8 * memory;
UINT8 * protdata;
chd_file * gdromchd;
UINT8 * picdata;
UINT32 rom_offset, rom_offset_flags, dma_count;
UINT32 dma_offset;
UINT32 dma_offset, dma_offset_flags;
UINT32 prot_offset, prot_key;
};
@ -152,6 +187,9 @@ static void init_save_state(const device_config *device)
state_save_register_device_item(device, 0, v->rom_offset_flags);
state_save_register_device_item(device, 0, v->dma_count);
state_save_register_device_item(device, 0, v->dma_offset);
state_save_register_device_item(device, 0, v->dma_offset_flags);
state_save_register_device_item(device, 0, v->prot_offset);
state_save_register_device_item(device, 0, v->prot_key);
}
@ -182,11 +220,38 @@ READ64_DEVICE_HANDLER( naomibd_r )
// ROM_DATA
if ((offset == 1) && ACCESSING_BITS_0_15)
{
UINT64 ret;
UINT64 ret = 0;
if (v->rom_offset_flags & NAOMIBD_FLAG_SPECIAL_MODE)
{
if (v->rom_offset == 0x1fffe)
{
UINT8 *prot = (UINT8 *)v->protdata;
UINT32 byte_offset = v->prot_offset * 2;
if (!prot)
{
logerror("naomibd: reading protection data, but none was supplied\n");
}
ret = (UINT64)(prot[byte_offset] | (prot[byte_offset+1]<<8));
v->prot_offset++;
}
else
{
mame_printf_verbose("Bad protection offset read %x\n", v->rom_offset);
}
}
else
{
ret = (UINT64)(ROM[v->rom_offset] | (ROM[v->rom_offset+1]<<8));
}
if (v->rom_offset_flags & NAOMIBD_FLAG_AUTO_ADVANCE)
{
v->rom_offset += 2;
}
return ret;
}
@ -249,7 +314,7 @@ WRITE64_DEVICE_HANDLER( naomibd_w )
// ROM_OFFSETH
v->rom_offset &= 0xffff;
v->rom_offset |= (data & 0x1fff)<<16;
v->rom_offset_flags = data >> 13;
v->rom_offset_flags = data >> 12;
}
if(ACCESSING_BITS_32_47)
{
@ -266,12 +331,33 @@ WRITE64_DEVICE_HANDLER( naomibd_w )
// DMA_OFFSETH
v->dma_offset &= 0xffff;
v->dma_offset |= (data >> 16) & 0x1fff0000;
v->dma_offset_flags = (data>>28);
}
if(ACCESSING_BITS_0_15)
{
// ROM_DATA
// Doa2 writes here (16 bit decryption key ?)
//mame_printf_verbose("%s:ROM: write %llx to 5f7008\n", cpuexec_describe_context(machine), data);
// ROM_DATA - used to access registers in the protection chip
switch (v->rom_offset)
{
case 0x1fff8: // offset low
v->prot_offset &= 0xffff0000;
v->prot_offset |= (UINT32)data;
break;
case 0x1fffa: // offset high
v->prot_offset &= 0xffff;
v->prot_offset |= (UINT32)data<<16;
break;
case 0x1fffc: // decryption key
v->prot_key = data;
mame_printf_verbose("Protection: set up read @ %x, key %x [%s]\n", v->prot_offset, v->prot_key, cpuexec_describe_context(device->machine));
break;
default:
mame_printf_verbose("naomibd: unknown protection write %x @ %x\n", (UINT32)data, offset);
break;
}
}
}
break;
@ -327,7 +413,7 @@ WRITE64_DEVICE_HANDLER( naomibd_w )
}
break;
default:
//mame_printf_verbose("%s: ROM: write %llx to %x, mask %llx\n", cpuexec_describe_context(machine), data, offset, mem_mask);
mame_printf_verbose("%s: ROM: write %llx to %x, mask %llx\n", cpuexec_describe_context(device->machine), data, offset, mem_mask);
break;
}
}
@ -542,6 +628,7 @@ static DEVICE_START( naomibd )
{
case ROM_BOARD:
v->memory = (UINT8 *)memory_region(device->machine, config->regiontag);
v->protdata = (UINT8 *)memory_region(device->machine, "naomibd_prot");
break;
case DIMM_BOARD:
@ -565,6 +652,8 @@ static DEVICE_START( naomibd )
v->rom_offset_flags = 0;
v->dma_count = 0;
v->dma_offset = 0;
v->dma_offset_flags = 0;
v->prot_offset = 0;
/* do a soft reset to reset everything else */
soft_reset(v);
@ -604,6 +693,7 @@ static DEVICE_NVRAM( naomibd )
{
//naomibd_state *v = get_safe_token(device);
static UINT8 eeprom_romboard[20+48] = {0x19,0x00,0xaa,0x55,0,0,0,0,0,0,0,0,0x69,0x79,0x68,0x6b,0x74,0x6d,0x68,0x6d};
UINT8 *games_contents;
if (read_or_write)
/*eeprom_save(file)*/;
@ -612,9 +702,19 @@ static DEVICE_NVRAM( naomibd )
/*if (file)
eeprom_load(file);
else*/
games_contents = memory_region(device->machine, "naomibd_eeprom");
if (games_contents)
{
x76f100_init( device->machine, 0, games_contents );
}
else
{
x76f100_init( device->machine, 0, eeprom_romboard );
memcpy(eeprom_romboard+20,"\241\011 0000000000000000",48);
}
}
}
/*-------------------------------------------------