mirror of
https://github.com/holub/mame
synced 2025-06-03 19:36:26 +03:00
pgm2: ICRW sim improvements [MetalliC, Lord Nightmare]
This commit is contained in:
parent
3070c7e386
commit
8b23bc7b9b
@ -46,11 +46,7 @@
|
|||||||
Identify which regions each game was released in and either dump alt. internal ROMs for each region, or
|
Identify which regions each game was released in and either dump alt. internal ROMs for each region, or
|
||||||
create them until that can be done.
|
create them until that can be done.
|
||||||
properly implement RTC (integrated into the CPU)
|
properly implement RTC (integrated into the CPU)
|
||||||
Memory Card system (there's an MCU on the motherboard that will need simulating or dumping somehow)
|
|
||||||
Verify Sprite Zoom (check exactly which pixels are doubled / missed on hardware for flipped , non-flipped cases etc.)
|
Verify Sprite Zoom (check exactly which pixels are doubled / missed on hardware for flipped , non-flipped cases etc.)
|
||||||
Simplify IGS036 encryption based on tables in internal roms
|
|
||||||
Fix ARM? bug that means Oriental Legend 2 needs a patch (might also be that it needs the card reader, and is running a
|
|
||||||
codepath that would not exist in a real environment at the moment)
|
|
||||||
Fix Save States (is this a driver problem or an ARM core problem, they don't work unless you get through the startup tests)
|
Fix Save States (is this a driver problem or an ARM core problem, they don't work unless you get through the startup tests)
|
||||||
|
|
||||||
Debug features (require DIP SW1:8 On and SW1:1 Off):
|
Debug features (require DIP SW1:8 On and SW1:1 Off):
|
||||||
@ -188,47 +184,86 @@ void pgm2_state::mcu_command(address_space &space, bool is_command)
|
|||||||
m_mcu_result1 = 0;
|
m_mcu_result1 = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// unknown / unimplemented, all C0-C9 commands is IC Card RW related
|
// C0-C9 commands is IC Card RW comms
|
||||||
// (m_mcu_regs[0] >> 8) & 0xff - target RW unit (player)
|
|
||||||
case 0xc0: // insert card or/and check card presence. result: F7 - ok, F4 - no card
|
case 0xc0: // insert card or/and check card presence. result: F7 - ok, F4 - no card
|
||||||
if (m_memcard_device[arg1 & 3]->present() == -1)
|
if (m_memcard_device[arg1 & 3]->present() == -1)
|
||||||
status = 0xf4;
|
status = 0xf4;
|
||||||
m_mcu_result0 = cmd;
|
m_mcu_result0 = cmd;
|
||||||
break;
|
break;
|
||||||
case 0xc1: // check ready/busy ?
|
case 0xc1: // check ready/busy ?
|
||||||
|
if (m_memcard_device[arg1 & 3]->present() == -1)
|
||||||
|
status = 0xf4;
|
||||||
m_mcu_result0 = cmd;
|
m_mcu_result0 = cmd;
|
||||||
break;
|
break;
|
||||||
case 0xc2: // read data to shared ram, args - offset, len
|
case 0xc2: // read data to shared ram
|
||||||
for (int i = 0; i < arg3; i++)
|
for (int i = 0; i < arg3; i++)
|
||||||
{
|
{
|
||||||
if (m_memcard_device[arg1 & 3]->present() != -1)
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
m_shareram[i + (~m_share_bank & 1) * 128] = m_memcard_device[arg1 & 3]->read(space, arg2 + i);
|
m_shareram[i + (~m_share_bank & 1) * 128] = m_memcard_device[arg1 & 3]->read(space, arg2 + i);
|
||||||
|
else
|
||||||
|
status = 0xf4;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mcu_result0 = cmd;
|
m_mcu_result0 = cmd;
|
||||||
break;
|
break;
|
||||||
case 0xc3: // save data from shared ram, args - offset, len
|
case 0xc3: // save data from shared ram
|
||||||
for (int i = 0; i < arg3; i++)
|
for (int i = 0; i < arg3; i++)
|
||||||
{
|
{
|
||||||
if (m_memcard_device[arg1 & 3]->present() != -1)
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
m_memcard_device[arg1 & 3]->write(space, arg2 + i, m_shareram[i + (~m_share_bank & 1) * 128]);
|
m_memcard_device[arg1 & 3]->write(space, arg2 + i, m_shareram[i + (~m_share_bank & 1) * 128]);
|
||||||
|
else
|
||||||
|
status = 0xf4;
|
||||||
}
|
}
|
||||||
m_mcu_result0 = cmd;
|
m_mcu_result0 = cmd;
|
||||||
break;
|
break;
|
||||||
case 0xc7: // get card ID?, no args, result1 expected to be fixed value for new card
|
case 0xc4: // presumable read security mem (password only?)
|
||||||
m_mcu_result1 = 0xf81f0000;
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
|
{
|
||||||
|
m_mcu_result1 = m_memcard_device[arg1 & 3]->read_sec(space, 1) |
|
||||||
|
(m_memcard_device[arg1 & 3]->read_sec(space, 2) << 8) |
|
||||||
|
(m_memcard_device[arg1 & 3]->read_sec(space, 3) << 16);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
status = 0xf4;
|
||||||
m_mcu_result0 = cmd;
|
m_mcu_result0 = cmd;
|
||||||
break;
|
break;
|
||||||
case 0xc8: // write byte, args - offset, data byte
|
case 0xc5: // write security mem
|
||||||
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
|
m_memcard_device[arg1 & 3]->write_sec(space, arg2 & 3, arg3);
|
||||||
|
else
|
||||||
|
status = 0xf4;
|
||||||
|
m_mcu_result0 = cmd;
|
||||||
|
break;
|
||||||
|
case 0xc6: // presumable write protection mem
|
||||||
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
|
m_memcard_device[arg1 & 3]->write_prot(space, arg2 & 3, arg3);
|
||||||
|
else
|
||||||
|
status = 0xf4;
|
||||||
|
m_mcu_result0 = cmd;
|
||||||
|
break;
|
||||||
|
case 0xc7: // read protection mem
|
||||||
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
|
{
|
||||||
|
m_mcu_result1 = m_memcard_device[arg1 & 3]->read_prot(space, 0) |
|
||||||
|
(m_memcard_device[arg1 & 3]->read_prot(space, 1) << 8) |
|
||||||
|
(m_memcard_device[arg1 & 3]->read_prot(space, 2) << 16) |
|
||||||
|
(m_memcard_device[arg1 & 3]->read_prot(space, 3) << 24);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
status = 0xf4;
|
||||||
|
m_mcu_result0 = cmd;
|
||||||
|
break;
|
||||||
|
case 0xc8: // write data mem
|
||||||
if (m_memcard_device[arg1 & 3]->present() != -1)
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
m_memcard_device[arg1 & 3]->write(space, arg2, arg3);
|
m_memcard_device[arg1 & 3]->write(space, arg2, arg3);
|
||||||
|
else
|
||||||
|
status = 0xf4;
|
||||||
m_mcu_result0 = cmd;
|
m_mcu_result0 = cmd;
|
||||||
break;
|
break;
|
||||||
case 0xc4: // not used
|
case 0xc9: // card authentication
|
||||||
case 0xc5: // set new password?, args - offset, data byte (offs 0 - always 7, 1-3 password)
|
if (m_memcard_device[arg1 & 3]->present() != -1)
|
||||||
case 0xc6: // not used
|
m_memcard_device[arg1 & 3]->auth(arg2, arg3, m_mcu_regs[1] & 0xff);
|
||||||
case 0xc9: // card authentication, args - 3 byte password, ('I','G','S' for new cards)
|
else
|
||||||
|
status = 0xf4;
|
||||||
m_mcu_result0 = cmd;
|
m_mcu_result0 = cmd;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -585,8 +620,8 @@ MACHINE_CONFIG_END
|
|||||||
#define ORLEG2_INTERNAL_CHINA \
|
#define ORLEG2_INTERNAL_CHINA \
|
||||||
ROM_REGION( 0x04000, "maincpu", 0 ) \
|
ROM_REGION( 0x04000, "maincpu", 0 ) \
|
||||||
ROM_LOAD( "xyj2_cn.igs036", 0x00000000, 0x0004000, CRC(bcce7641) SHA1(c3b5cf6e9f6eae09b6785314777a52b34c3c7657) ) \
|
ROM_LOAD( "xyj2_cn.igs036", 0x00000000, 0x0004000, CRC(bcce7641) SHA1(c3b5cf6e9f6eae09b6785314777a52b34c3c7657) ) \
|
||||||
ROM_REGION( 0x100, "default_card", 0 ) \
|
ROM_REGION( 0x108, "default_card", 0 ) \
|
||||||
ROM_LOAD( "blank_orleg2_china_card.pg2", 0x000, 0x100, CRC(099156f0) SHA1(a621c9772a98719c657bba3a1bf235487eb78615) )
|
ROM_LOAD( "blank_orleg2_china_card.pg2", 0x000, 0x108, CRC(dc29556f) SHA1(2335cc7af25d4dd9763c6944d3f0eb50276de80a) )
|
||||||
|
|
||||||
#define ORLEG2_INTERNAL_OVERSEAS \
|
#define ORLEG2_INTERNAL_OVERSEAS \
|
||||||
ROM_REGION( 0x04000, "maincpu", 0 ) \
|
ROM_REGION( 0x04000, "maincpu", 0 ) \
|
||||||
@ -667,8 +702,8 @@ ROM_END
|
|||||||
#define KOV2NL_INTERNAL_CHINA \
|
#define KOV2NL_INTERNAL_CHINA \
|
||||||
ROM_REGION( 0x04000, "maincpu", 0 ) \
|
ROM_REGION( 0x04000, "maincpu", 0 ) \
|
||||||
ROM_LOAD( "gsyx_igs036_china.rom", 0x00000000, 0x0004000, CRC(e09fe4ce) SHA1(c0cac64ef8727cbe79d503ec4df66ddb6f2c925e) ) \
|
ROM_LOAD( "gsyx_igs036_china.rom", 0x00000000, 0x0004000, CRC(e09fe4ce) SHA1(c0cac64ef8727cbe79d503ec4df66ddb6f2c925e) ) \
|
||||||
ROM_REGION( 0x100, "default_card", 0 ) \
|
ROM_REGION( 0x108, "default_card", 0 ) \
|
||||||
ROM_LOAD( "blank_kov2nl_china_card.pg2", 0x000, 0x100, CRC(91786244) SHA1(ac0ce11b46c19ffe21f6b94bc83ef061f547b591) )
|
ROM_LOAD( "blank_kov2nl_china_card.pg2", 0x000, 0x108, CRC(02842ae8) SHA1(a6cda633b09a706039a79b73db2c258094826f85) )
|
||||||
|
|
||||||
|
|
||||||
ROM_START( kov2nl )
|
ROM_START( kov2nl )
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
pgm2_memcard.cpp
|
pgm2_memcard.cpp
|
||||||
|
|
||||||
PGM2 Memory card functions.
|
PGM2 Memory card functions.
|
||||||
(based on ng_memcard.cpp)
|
Presumable Siemens SLE 4442 or compatible.
|
||||||
|
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
@ -45,25 +45,36 @@ void pgm2_memcard_device::device_start()
|
|||||||
|
|
||||||
image_init_result pgm2_memcard_device::call_load()
|
image_init_result pgm2_memcard_device::call_load()
|
||||||
{
|
{
|
||||||
if(length() != 0x100)
|
authenticated = false;
|
||||||
|
if(length() != 0x108)
|
||||||
return image_init_result::FAIL;
|
return image_init_result::FAIL;
|
||||||
|
|
||||||
fseek(0, SEEK_SET);
|
fseek(0, SEEK_SET);
|
||||||
size_t ret = fread(m_memcard_data, 0x100);
|
size_t ret = fread(m_memcard_data, 0x100);
|
||||||
if(ret != 0x100)
|
if(ret != 0x100)
|
||||||
return image_init_result::FAIL;
|
return image_init_result::FAIL;
|
||||||
|
ret = fread(m_protection_data, 4);
|
||||||
|
if (ret != 4)
|
||||||
|
return image_init_result::FAIL;
|
||||||
|
ret = fread(m_security_data, 4);
|
||||||
|
if (ret != 4)
|
||||||
|
return image_init_result::FAIL;
|
||||||
|
|
||||||
return image_init_result::PASS;
|
return image_init_result::PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pgm2_memcard_device::call_unload()
|
void pgm2_memcard_device::call_unload()
|
||||||
{
|
{
|
||||||
|
authenticated = false;
|
||||||
fseek(0, SEEK_SET);
|
fseek(0, SEEK_SET);
|
||||||
fwrite(m_memcard_data, 0x100);
|
fwrite(m_memcard_data, 0x100);
|
||||||
|
fwrite(m_protection_data, 4);
|
||||||
|
fwrite(m_security_data, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
image_init_result pgm2_memcard_device::call_create(int format_type, util::option_resolution *format_options)
|
image_init_result pgm2_memcard_device::call_create(int format_type, util::option_resolution *format_options)
|
||||||
{
|
{
|
||||||
|
authenticated = false;
|
||||||
// cards must contain valid defaults for each game / region or they don't work?
|
// cards must contain valid defaults for each game / region or they don't work?
|
||||||
memory_region *rgn = memregion("^default_card");
|
memory_region *rgn = memregion("^default_card");
|
||||||
|
|
||||||
@ -71,14 +82,28 @@ image_init_result pgm2_memcard_device::call_create(int format_type, util::option
|
|||||||
return image_init_result::FAIL;
|
return image_init_result::FAIL;
|
||||||
|
|
||||||
memcpy(m_memcard_data, rgn->base(), 0x100);
|
memcpy(m_memcard_data, rgn->base(), 0x100);
|
||||||
|
memcpy(m_protection_data, rgn->base() + 0x100, 4);
|
||||||
|
memcpy(m_security_data, rgn->base() + 0x104, 4);
|
||||||
|
|
||||||
size_t ret = fwrite(m_memcard_data, 0x100);
|
size_t ret = fwrite(rgn->base(), 0x108);
|
||||||
if(ret != 0x100)
|
if(ret != 0x108)
|
||||||
return image_init_result::FAIL;
|
return image_init_result::FAIL;
|
||||||
|
|
||||||
return image_init_result::PASS;
|
return image_init_result::PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pgm2_memcard_device::auth(uint8_t p1, uint8_t p2, uint8_t p3)
|
||||||
|
{
|
||||||
|
if (m_security_data[0] & 3)
|
||||||
|
{
|
||||||
|
if (m_security_data[1] == p1 && m_security_data[2] == p2 && m_security_data[3] == p3)
|
||||||
|
authenticated = true;
|
||||||
|
else {
|
||||||
|
m_security_data[0] >>= 1; // hacky
|
||||||
|
logerror("Wrong IC Card password !!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
READ8_MEMBER(pgm2_memcard_device::read)
|
READ8_MEMBER(pgm2_memcard_device::read)
|
||||||
{
|
{
|
||||||
@ -87,5 +112,32 @@ READ8_MEMBER(pgm2_memcard_device::read)
|
|||||||
|
|
||||||
WRITE8_MEMBER(pgm2_memcard_device::write)
|
WRITE8_MEMBER(pgm2_memcard_device::write)
|
||||||
{
|
{
|
||||||
m_memcard_data[offset] = data;
|
if (authenticated && (offset >= 0x20 || (m_protection_data[offset>>3] & (1 <<(offset & 7)))))
|
||||||
|
{
|
||||||
|
m_memcard_data[offset] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(pgm2_memcard_device::read_prot)
|
||||||
|
{
|
||||||
|
return m_protection_data[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(pgm2_memcard_device::write_prot)
|
||||||
|
{
|
||||||
|
if (authenticated)
|
||||||
|
m_protection_data[offset] &= data;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ8_MEMBER(pgm2_memcard_device::read_sec)
|
||||||
|
{
|
||||||
|
if (!authenticated)
|
||||||
|
return 0xff; // guess
|
||||||
|
return m_security_data[offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE8_MEMBER(pgm2_memcard_device::write_sec)
|
||||||
|
{
|
||||||
|
if (authenticated)
|
||||||
|
m_security_data[offset] = data;
|
||||||
}
|
}
|
||||||
|
@ -52,11 +52,19 @@ public:
|
|||||||
|
|
||||||
DECLARE_READ8_MEMBER(read);
|
DECLARE_READ8_MEMBER(read);
|
||||||
DECLARE_WRITE8_MEMBER(write);
|
DECLARE_WRITE8_MEMBER(write);
|
||||||
|
DECLARE_READ8_MEMBER(read_prot);
|
||||||
|
DECLARE_WRITE8_MEMBER(write_prot);
|
||||||
|
DECLARE_READ8_MEMBER(read_sec);
|
||||||
|
DECLARE_WRITE8_MEMBER(write_sec);
|
||||||
|
void auth(uint8_t p1, uint8_t p2, uint8_t p3);
|
||||||
|
|
||||||
/* returns the index of the current memory card, or -1 if none */
|
/* returns the index of the current memory card, or -1 if none */
|
||||||
int present() { return is_loaded() ? 0 : -1; }
|
int present() { return is_loaded() ? 0 : -1; }
|
||||||
private:
|
private:
|
||||||
uint8_t m_memcard_data[0x100];
|
uint8_t m_memcard_data[0x100];
|
||||||
|
uint8_t m_protection_data[4];
|
||||||
|
uint8_t m_security_data[4];
|
||||||
|
bool authenticated;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user