diff --git a/src/mame/drivers/nexus3d.c b/src/mame/drivers/nexus3d.c index bec7ab8dcaf..4777ae20cb9 100644 --- a/src/mame/drivers/nexus3d.c +++ b/src/mame/drivers/nexus3d.c @@ -16,17 +16,152 @@ #include "cpu/arm7/arm7core.h" //#include "machine/i2cmem.h" + +#define FLASH_PAGE_SIZE (2048+64) + class nexus3d_state : public driver_device { public: nexus3d_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) { } + UINT32* m_mainram; + + // + UINT8 m_last_flash_cmd; + + int m_flash_addr_seq; + UINT32 m_flash_addr; + + int m_flash_page_addr; + UINT8 flash_page_data[FLASH_PAGE_SIZE]; + + UINT8* m_flash_region; + }; + + + + +// Flash handling is very similar (but not 100% identical) to the stuff used in cavesh3 (command structure seems very slightly different, probably due to larger size) +// this is just a skeleton implementation + +void nexus3d_flash_reset(running_machine& machine) +{ + nexus3d_state *state = machine.driver_data(); + state->m_last_flash_cmd = 0x00; + state->m_flash_addr_seq = 0; + state->m_flash_addr = 0; + + state->m_flash_page_addr = 0; +} + +READ8_HANDLER( n3d_flash_r ) +{ + nexus3d_state *state = space->machine().driver_data(); + + if (state->m_last_flash_cmd==0x70) return 0xe0; + + if (state->m_last_flash_cmd==0x00) + { + UINT8 retdat = state->flash_page_data[state->m_flash_page_addr]; + + //logerror("n3d_flash_r %02x %04x\n", offset, state->m_flash_page_addr); + + state->m_flash_page_addr++; + return retdat; + } + + + logerror("n3d_flash_r %02x\n", offset); + return 0x00; + +} + + +WRITE8_HANDLER( n3d_flash_cmd_w ) +{ + nexus3d_state *state = space->machine().driver_data(); + logerror("n3d_flash_cmd_w %02x %02x\n", offset, data); + state->m_last_flash_cmd = data; + + if (data==0x00) + { + memcpy(state->flash_page_data, state->m_flash_region + state->m_flash_addr * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE); + + } + +} + +WRITE8_HANDLER( n3d_flash_addr_w ) +{ + nexus3d_state *state = space->machine().driver_data(); +// logerror("n3d_flash_addr_w %02x %02x\n", offset, data); + + state->m_flash_addr_seq++; + + if (state->m_flash_addr_seq==3) + state->m_flash_addr = (state->m_flash_addr & 0xffff00) | data; + + if (state->m_flash_addr_seq==4) + state->m_flash_addr = (state->m_flash_addr & 0xff00ff) | data << 8; + + if (state->m_flash_addr_seq==5) + state->m_flash_addr = (state->m_flash_addr & 0x00ffff) | data << 16; + + if (state->m_flash_addr_seq==5) + { + state->m_flash_addr_seq = 0; + state->m_flash_page_addr = 0; + logerror("set flash block to %08x\n", state->m_flash_addr); + } + +} + +static READ32_HANDLER( nexus3d_unk_r ) +{ + return space->machine().rand() ^ (space->machine().rand() << 16); +} + +static READ32_HANDLER( nexus3d_unk2_r ) +{ + return 0x00000000;//space->machine().rand() ^ (space->machine().rand() << 16); +} + +static READ32_HANDLER( nexus3d_unk3_r ) +{ + return 0x00000000;//space->machine().rand() ^ (space->machine().rand() << 16); +} + +static WRITE32_HANDLER( nexus3d_unk2_w ) +{ + +} + +static WRITE32_HANDLER( nexus3d_unk3_w ) +{ + +} + static ADDRESS_MAP_START( nexus3d_map, AS_PROGRAM, 32 ) - AM_RANGE(0x00000000, 0x00000fff) AM_ROM AM_REGION("user1", 0) + AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_BASE_MEMBER(nexus3d_state, m_mainram) + + AM_RANGE(0x00400000, 0x01ffffff) AM_RAM // ?? uploads various data, + pointers to data in the 0x01ffxxxx range, might be video system related + + // flash + AM_RANGE(0x9C000000, 0x9C000003) AM_WRITE8( n3d_flash_r, 0xffffffff) + AM_RANGE(0x9C000010, 0x9C000013) AM_WRITE8( n3d_flash_cmd_w, 0xffffffff) + AM_RANGE(0x9C000018, 0x9C00001b) AM_WRITE8( n3d_flash_addr_w, 0xffffffff) + + // lots of accesses in this range + AM_RANGE(0xC0000F44, 0xC0000F47) AM_READWRITE( nexus3d_unk2_r, nexus3d_unk2_w ) // often + AM_RANGE(0xC0000F4C, 0xC0000F4f) AM_READWRITE( nexus3d_unk3_r, nexus3d_unk3_w ) // often + + AM_RANGE(0xE0000014, 0xE0000017) AM_READ( nexus3d_unk_r ) // sits waiting for this + + ADDRESS_MAP_END static INPUT_PORTS_START( nexus3d ) @@ -44,10 +179,15 @@ SCREEN_UPDATE(nexus3d) return 0; } +static MACHINE_RESET (nexus3d) +{ + nexus3d_flash_reset(machine); +} + static MACHINE_CONFIG_START( nexus3d, nexus3d_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", ARM9, 200000000) + MCFG_CPU_ADD("maincpu", ARM920T, 200000000) MCFG_CPU_PROGRAM_MAP(nexus3d_map) MCFG_SCREEN_ADD("screen", RASTER) @@ -60,6 +200,8 @@ static MACHINE_CONFIG_START( nexus3d, nexus3d_state ) MCFG_PALETTE_LENGTH(256) + MCFG_MACHINE_RESET( nexus3d ) + MCFG_VIDEO_START(nexus3d) MACHINE_CONFIG_END @@ -72,7 +214,7 @@ MACHINE_CONFIG_END // that the original game used a smaller flash. It seems highly unlikely that Examu would ship ROMs // containing the entire backcatalog of SNK and Capcom material ;-) // -// It's possible this set should be marked as a bootleg due to this although I imagine the acutal valid +// It's possible this set should be marked as a bootleg due to this although I imagine the actual valid // part of the data will match a clean dump. ROM_START( acheartf ) ROM_REGION( 0x42000898, "user1", 0 ) /* ARM 32 bit code */ @@ -91,7 +233,10 @@ ROM_END static DRIVER_INIT( nexus3d ) { - + nexus3d_state *state = machine.driver_data(); + // the first part of the flash ROM automatically gets copied to RAM + memcpy( state->m_mainram, machine.region("user1")->base(), 4 * 1024); + state->m_flash_region = machine.region("user1")->base(); } GAME( 2006, acheartf, 0, nexus3d, nexus3d, nexus3d, ROT0, "Examu", "Arcana Heart Full", GAME_NO_SOUND|GAME_NOT_WORKING )