From aec47ff63953aada61a83ccbc7330f73bdd23e06 Mon Sep 17 00:00:00 2001 From: angelosa Date: Sun, 22 Apr 2018 17:39:59 +0200 Subject: [PATCH] nb1412m2.cpp: hooked up to mighty guy (nw) seicop.cpp: fix device chip endianness (nw) --- src/mame/drivers/cop01.cpp | 90 ++-------------- src/mame/includes/cop01.h | 23 +++- src/mame/machine/nb1412m2.cpp | 190 +++++++++++++++++++++++++--------- src/mame/machine/nb1412m2.h | 20 +++- src/mame/machine/seicop.cpp | 2 +- 5 files changed, 189 insertions(+), 136 deletions(-) diff --git a/src/mame/drivers/cop01.cpp b/src/mame/drivers/cop01.cpp index 6bf0b79425f..e6337ccba15 100644 --- a/src/mame/drivers/cop01.cpp +++ b/src/mame/drivers/cop01.cpp @@ -145,7 +145,7 @@ void cop01_state::io_map(address_map &map) map(0x45, 0x45).w(this, FUNC(cop01_state::cop01_irq_ack_w)); /* ? */ } -void cop01_state::mightguy_io_map(address_map &map) +void mightguy_state::mightguy_io_map(address_map &map) { map.global_mask(0xff); map(0x00, 0x00).portr("P1"); @@ -174,83 +174,12 @@ void cop01_state::audio_io_map(address_map &map) map(0x06, 0x06).r(this, FUNC(cop01_state::cop01_sound_command_r)); } - -/* - * sound "protection" uses address/data to ports 2/3 (R/W) - * Register map: - * 0x32: always 5, rom read trigger? - * 0x33: - address 1 (source?) - * 0x34: / - * 0x35: - address 2 (adjust value in rom?) - * 0x36: / - * 0x37: R reused for ym3526 register set, read protection rom (same as amatelas) - * - * 0x40: counter set, always 1? - * 0x41: R bit 0 pulse timer? W oneshot timer? - * 0x42: counter set, always 3? - * 0x43: counter set, always 3? - * - * 0x92: data in/out (for dac?) - * 0x94: test register? (W 0xaa, checks if R 0xaa) - */ - -/* this just gets some garbage out of the YM3526 */ -READ8_MEMBER(cop01_state::prot_data_r) -{ - if(m_prot_command == 0x41) - return (m_audiocpu->total_cycles() / 0x34) & 1; // wrong - - if(m_prot_command == 0x37) - { - uint16_t prot_offset = (m_prot_reg[1]<<8)|(m_prot_reg[2]); - uint8_t *prot_rom = memregion("prot_data")->base(); - // 0x37c are BGMs while 0x34e are SFXs? - uint8_t prot_adj = 0x82; //0xbd - - //printf("%02x",(prot_rom[prot_offset] - 0x44) & 0xff); - - return prot_rom[prot_offset & 0x1fff] - prot_adj; // minus value correct? - } - - if(m_prot_command == 0x92) // affects coin SFX playback - return 1; - - if(m_prot_command == 0x94) - return 0; - - return 0; -} - -WRITE8_MEMBER(cop01_state::prot_address_w) -{ - m_prot_command = data; -} - -WRITE8_MEMBER(cop01_state::prot_data_w) -{ - if( m_prot_command >=0x32 && m_prot_command <=0x37 ) - { - m_prot_reg[m_prot_command-0x32] = data; - - #if 0 - if(m_prot_command == 0x32) - { - for(int i=0;i<6;i++) - printf("%02x ",m_prot_reg[i]); - - printf("\n"); - } - #endif - } -} - -void cop01_state::mightguy_audio_io_map(address_map &map) +void mightguy_state::mightguy_audio_io_map(address_map &map) { map.global_mask(0xff); map(0x00, 0x01).w("ymsnd", FUNC(ym3526_device::write)); - map(0x02, 0x02).w(this, FUNC(cop01_state::prot_address_w)); /* 1412M2 address? */ - map(0x03, 0x03).w(this, FUNC(cop01_state::prot_data_w)); /* 1412M2 data? */ - map(0x03, 0x03).r(this, FUNC(cop01_state::prot_data_r)); /* 1412M2? */ + map(0x02, 0x02).w("prot_chip", FUNC(nb1412m2_device::command_w)); + map(0x03, 0x03).rw("prot_chip", FUNC(nb1412m2_device::data_r), FUNC(nb1412m2_device::data_w)); map(0x06, 0x06).r(this, FUNC(cop01_state::cop01_sound_command_r)); } @@ -557,7 +486,7 @@ MACHINE_CONFIG_START(cop01_state::cop01) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) MACHINE_CONFIG_END -MACHINE_CONFIG_START(cop01_state::mightguy) +MACHINE_CONFIG_START(mightguy_state::mightguy) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, MAINCPU_CLOCK/2) /* unknown divider */ @@ -569,6 +498,7 @@ MACHINE_CONFIG_START(cop01_state::mightguy) MCFG_CPU_PROGRAM_MAP(sound_map) MCFG_CPU_IO_MAP(mightguy_audio_io_map) + MCFG_DEVICE_ADD("prot_chip", NB1412M2, XTAL(8'000'000)/2) // divided by 2 maybe /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -682,7 +612,7 @@ ROM_START( mightguy ) ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound cpu) */ ROM_LOAD( "11.15b", 0x0000, 0x4000, CRC(576183ea) SHA1(e3f28e8e8c34ab396d158da122584ed226729c99) ) - ROM_REGION( 0x8000, "prot_data", 0 ) /* 1412M2 protection data, z80 encrypted code presumably */ + ROM_REGION( 0x8000, "prot_chip", 0 ) /* 1412M2 protection data, z80 encrypted code presumably */ ROM_LOAD( "10.ic2", 0x0000, 0x8000, CRC(1a5d2bb1) SHA1(0fd4636133a980ba9ffa076f9010474586d37635) ) ROM_REGION( 0x02000, "gfx1", 0 ) /* alpha */ @@ -736,6 +666,6 @@ DRIVER_INIT_MEMBER(cop01_state,mightguy) * *************************************/ -GAME( 1985, cop01, 0, cop01, cop01, cop01_state, 0, ROT0, "Nichibutsu", "Cop 01 (set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1985, cop01a, cop01, cop01, cop01, cop01_state, 0, ROT0, "Nichibutsu", "Cop 01 (set 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, mightguy, 0, mightguy, mightguy, cop01_state, mightguy, ROT270, "Nichibutsu", "Mighty Guy", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1985, cop01, 0, cop01, cop01, cop01_state, 0, ROT0, "Nichibutsu", "Cop 01 (set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1985, cop01a, cop01, cop01, cop01, cop01_state, 0, ROT0, "Nichibutsu", "Cop 01 (set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, mightguy, 0, mightguy, mightguy, mightguy_state, mightguy, ROT270, "Nichibutsu", "Mighty Guy", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/cop01.h b/src/mame/includes/cop01.h index 2112905a2b3..e48944c476d 100644 --- a/src/mame/includes/cop01.h +++ b/src/mame/includes/cop01.h @@ -7,6 +7,7 @@ *************************************************************************/ #include "machine/gen_latch.h" +#include "machine/nb1412m2.h" class cop01_state : public driver_device { @@ -35,8 +36,6 @@ public: /* sound-related */ int m_pulse; int m_timer; // kludge for ym3526 in mightguy - uint8_t m_prot_command; - uint8_t m_prot_reg[6]; /* devices */ required_device m_maincpu; @@ -66,12 +65,26 @@ public: DECLARE_PALETTE_INIT(cop01); uint32_t screen_update_cop01(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); - void mightguy(machine_config &config); void cop01(machine_config &config); void audio_io_map(address_map &map); void cop01_map(address_map &map); void io_map(address_map &map); - void mightguy_audio_io_map(address_map &map); - void mightguy_io_map(address_map &map); void sound_map(address_map &map); }; + +class mightguy_state : public cop01_state +{ +public: + mightguy_state(const machine_config &mconfig, device_type type, const char *tag) + : cop01_state(mconfig, type, tag) + , m_prot(*this, "prot_chip") + {} + + + void mightguy(machine_config &config); +private: + void mightguy_io_map(address_map &map); + void mightguy_audio_io_map(address_map &map); + + required_device m_prot; +}; diff --git a/src/mame/machine/nb1412m2.cpp b/src/mame/machine/nb1412m2.cpp index 3e1c3ba3c84..dffe8990e7e 100644 --- a/src/mame/machine/nb1412m2.cpp +++ b/src/mame/machine/nb1412m2.cpp @@ -7,51 +7,69 @@ Nichibutsu 1412M2 device emulation Written by Angelo Salese Fancy data decrypter + timer + ? -Most creative usage is hooked up in Mighty Guy sound CPU, -other games just uses it as a much simpler protection chip providing code +Most creative usage is hooked up in Mighty Guy sound CPU, +other games just uses it as a much simpler protection chip providing code snippets. -It is unknown at current stage if inside the chip there's a MCU +It is unknown at current stage if inside the chip there's a MCU (with internal ROM). TODO: -- understand how Mighty Guy decrypts data (uses port adjuster in a +- understand how Mighty Guy decrypts data (uses port adjuster in a different way than the other games); Legacy notes from drivers: -- m_mAmazonProtReg[4] bit 0 used on hiscore data (clear on code), - 0x29f vs 0x29e (not an offset?) +- m_mAmazonProtReg[4] bit 0 used on hiscore data (clear on code), + 0x29f vs 0x29e (not an offset?) - static const uint16_t mAmazonProtData[] = { - 0x0000,0x5000,0x5341,0x4b45,0x5349,0x4755,0x5245, <- default high scores (0x40db4) - wrong data ? - 0x0000,0x4000,0x0e4b,0x4154,0x5544,0x4f4e,0x0e0e, - 0x0000,0x3000,0x414e,0x4b41,0x4b45,0x5544,0x4f4e, - 0x0000,0x2000,0x0e0e,0x4b49,0x5455,0x4e45,0x0e0e, - 0x0000,0x1000,0x0e4b,0x414b,0x4553,0x4f42,0x410e, + 0x0000,0x5000,0x5341,0x4b45,0x5349,0x4755,0x5245, <- default high scores (0x40db4) - wrong data ? + 0x0000,0x4000,0x0e4b,0x4154,0x5544,0x4f4e,0x0e0e, + 0x0000,0x3000,0x414e,0x4b41,0x4b45,0x5544,0x4f4e, + 0x0000,0x2000,0x0e0e,0x4b49,0x5455,0x4e45,0x0e0e, + 0x0000,0x1000,0x0e4b,0x414b,0x4553,0x4f42,0x410e, - 0x4ef9,0x0000,0x62fa,0x0000,0x4ef9,0x0000,0x805E,0x0000, <- code (0x40d92) - 0xc800 <- checksum + 0x4ef9,0x0000,0x62fa,0x0000,0x4ef9,0x0000,0x805E,0x0000, <- code (0x40d92) + 0xc800 <- checksum }; - static const uint16_t mAmatelasProtData[] = { - 0x0000,0x5000,0x5341,0x4b45,0x5349,0x4755,0x5245, <- default high scores (0x40db4) - 0x0000,0x4000,0x0e4b,0x4154,0x5544,0x4f4e,0x0e0e, - 0x0000,0x3000,0x414e,0x4b41,0x4b45,0x5544,0x4f4e, - 0x0000,0x2000,0x0e0e,0x4b49,0x5455,0x4e45,0x0e0e, - 0x0000,0x1000,0x0e4b,0x414b,0x4553,0x4f42,0x410e, - 0x4ef9,0x0000,0x632e,0x0000,0x4ef9,0x0000,0x80C2,0x0000, <- code (0x40d92) - 0x6100 <- checksum + 0x0000,0x5000,0x5341,0x4b45,0x5349,0x4755,0x5245, <- default high scores (0x40db4) + 0x0000,0x4000,0x0e4b,0x4154,0x5544,0x4f4e,0x0e0e, + 0x0000,0x3000,0x414e,0x4b41,0x4b45,0x5544,0x4f4e, + 0x0000,0x2000,0x0e0e,0x4b49,0x5455,0x4e45,0x0e0e, + 0x0000,0x1000,0x0e4b,0x414b,0x4553,0x4f42,0x410e, + 0x4ef9,0x0000,0x632e,0x0000,0x4ef9,0x0000,0x80C2,0x0000, <- code (0x40d92) + 0x6100 <- checksum }; - static const uint16_t mHoreKidProtData[] = { - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, <- N/A - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, - 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, - 0x4e75,0x4e75,0x4e75,0x4e75,0x4e75,0x4e75,0x4e75,0x4e75, <- code (0x40dba) It actually never jumps there? - 0x1800 <- checksum + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, <- N/A + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x4e75,0x4e75,0x4e75,0x4e75,0x4e75,0x4e75,0x4e75,0x4e75, <- code (0x40dba) It actually never jumps there? + 0x1800 <- checksum }; +- mightguy: + * sound "protection" uses address/data to ports 2/3 (R/W) + * Register map: + * 0x32: always 5, rom read trigger? + * 0x33: - address 1 (source?) + * 0x34: / + * 0x35: - address 2 (adjust value in rom?) + * 0x36: / + * 0x37: R reused for ym3526 register set, read protection rom (same as amatelas) + * + * 0x40: counter set, always 1? + * 0x41: R bit 0 pulse timer? W oneshot timer? + * 0x42: counter set, always 3? + * 0x43: counter set, always 3? + * + * 0x92: data in/out (for dac?) + * 0x94: test register? (W 0xaa, checks if R 0xaa) + ***************************************************************************/ #include "emu.h" @@ -71,16 +89,43 @@ DEFINE_DEVICE_TYPE(NB1412M2, nb1412m2_device, "nb1412m2", "NB1412M2 Mahjong Cust // LIVE DEVICE //************************************************************************** +void nb1412m2_device::nb1412m2_map(address_map &map) +{ + map(0x32, 0x32).w(this,FUNC(nb1412m2_device::rom_op_w)); + map(0x33, 0x34).w(this,FUNC(nb1412m2_device::rom_address_w)); + map(0x35, 0x36).w(this,FUNC(nb1412m2_device::rom_adjust_w)); + map(0x37, 0x37).r(this,FUNC(nb1412m2_device::rom_decrypt_r)); + + map(0x40, 0x40).nopw(); + map(0x41, 0x41).r(this,FUNC(nb1412m2_device::timer_r)).nopw(); + map(0x42, 0x43).nopw(); + + map(0x92, 0x92).ram(); // latch? + map(0x94, 0x94).rw(this,FUNC(nb1412m2_device::xor_r),FUNC(nb1412m2_device::xor_w)); + + // 16-bit registers (1=upper), more latches? + map(0xa0, 0xa1).ram(); + map(0xa2, 0xa3).ram(); +} + //------------------------------------------------- // nb1412m2_device - constructor //------------------------------------------------- nb1412m2_device::nb1412m2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, NB1412M2, tag, owner, clock) + , device_memory_interface(mconfig, *this) + , m_space_config("regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(), address_map_constructor(FUNC(nb1412m2_device::nb1412m2_map), this)) , m_data(*this, DEVICE_SELF) { } +device_memory_interface::space_config_vector nb1412m2_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(0, &m_space_config) + }; +} //------------------------------------------------- // device_start - device-specific startup @@ -90,6 +135,9 @@ void nb1412m2_device::device_start() { save_item(NAME(m_command)); save_item(NAME(m_rom_address)); + save_item(NAME(m_adj_address)); + save_item(NAME(m_rom_op)); + save_item(NAME(m_xor)); } @@ -101,6 +149,9 @@ void nb1412m2_device::device_reset() { m_command = 0xff; m_rom_address = 0; + m_adj_address = 0; + m_rom_op = 0; + m_xor = 0; } @@ -108,32 +159,77 @@ void nb1412m2_device::device_reset() // READ/WRITE HANDLERS //************************************************************************** +WRITE8_MEMBER( nb1412m2_device::rom_op_w ) +{ + m_rom_op = data; +} + +WRITE8_MEMBER( nb1412m2_device::rom_address_w ) +{ + if(offset == 0) // rom hi address + { + m_rom_address &= 0x00ff; + m_rom_address |= data << 8; + } + else // rom lo address + { + m_rom_address &= 0xff00; + m_rom_address |= data; + } +} + +WRITE8_MEMBER( nb1412m2_device::rom_adjust_w ) +{ + if(offset == 0) // rom hi address + { + m_adj_address &= 0x00ff; + m_adj_address |= data << 8; + } + else // rom lo address + { + m_adj_address &= 0xff00; + m_adj_address |= data; + } +} + +// readback from ROM data +READ8_MEMBER( nb1412m2_device::rom_decrypt_r ) +{ + // TODO: provided by commands 0x35 & 0x36 (maybe 0x32 too) + uint8_t prot_adj = m_data[m_adj_address] == 0xff ? 0x44 : 0x82; + +// printf("%02x %04x %02x\n",m_data[m_adj_address],m_adj_address,m_rom_op); + + return m_data[m_rom_address & 0x1fff] - prot_adj; +} + +// Mighty Guy specifics +READ8_MEMBER( nb1412m2_device::timer_r ) +{ +// return (this->clock().cycles() / 0x34) & 1; // wrong + return machine().rand() & 1; +} + +WRITE8_MEMBER( nb1412m2_device::xor_w ) +{ + m_xor = data ^ m_xor; +} + +READ8_MEMBER( nb1412m2_device::xor_r ) +{ + // write 0xaa, reads back if register is equal to 0xaa (xor reg?) + return m_xor; +} + +// public accessors READ8_MEMBER( nb1412m2_device::data_r ) { - if(m_command == 0x37) // readback from ROM data - { - // TODO: provided by commands 0x35 & 0x36 (maybe 0x32 too) - uint8_t prot_adj = 0x44; - - return m_data[m_rom_address & 0x1fff] - prot_adj; - } - - return 0; + return this->space().read_byte(m_command); } WRITE8_MEMBER( nb1412m2_device::data_w ) { - switch(m_command) - { - case 0x33: // rom hi - m_rom_address &= 0x00ff; - m_rom_address |= data << 8; - break; - case 0x34: // rom lo - m_rom_address &= 0xff00; - m_rom_address |= data; - break; - } + this->space().write_byte(m_command, data); } WRITE8_MEMBER( nb1412m2_device::command_w ) diff --git a/src/mame/machine/nb1412m2.h b/src/mame/machine/nb1412m2.h index b6965a0ec7e..2e1451f70e9 100644 --- a/src/mame/machine/nb1412m2.h +++ b/src/mame/machine/nb1412m2.h @@ -27,7 +27,7 @@ Nichibutsu 1412M2 device emulation // ======================> nb1412m2_device -class nb1412m2_device : public device_t +class nb1412m2_device : public device_t, public device_memory_interface { public: // construction/destruction @@ -37,17 +37,31 @@ public: DECLARE_WRITE8_MEMBER( command_w ); DECLARE_WRITE8_MEMBER( data_w ); DECLARE_READ8_MEMBER( data_r ); + + DECLARE_WRITE8_MEMBER( rom_address_w ); + DECLARE_READ8_MEMBER( rom_decrypt_r ); + DECLARE_WRITE8_MEMBER( rom_op_w ); + DECLARE_WRITE8_MEMBER( rom_adjust_w ); + DECLARE_READ8_MEMBER( timer_r ); + DECLARE_READ8_MEMBER( xor_r ); + DECLARE_WRITE8_MEMBER( xor_w ); + void nb1412m2_map(address_map &map); protected: // device-level overrides -// virtual void device_validity_check(validity_checker &valid) const override; -// virtual void device_add_mconfig(machine_config &config) override; +// virtual void device_validity_check(validity_checker &valid) const override; +// virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; virtual void device_reset() override; + virtual space_config_vector memory_space_config() const override; private: uint8_t m_command; uint16_t m_rom_address; + uint16_t m_adj_address; + uint8_t m_rom_op; + uint8_t m_xor; + const address_space_config m_space_config; required_region_ptr m_data; }; diff --git a/src/mame/machine/seicop.cpp b/src/mame/machine/seicop.cpp index f0aa292915a..1bae95f8444 100644 --- a/src/mame/machine/seicop.cpp +++ b/src/mame/machine/seicop.cpp @@ -249,7 +249,7 @@ void seibu_cop_bootleg_device::seibucopbl_map(address_map &map) seibu_cop_bootleg_device::seibu_cop_bootleg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SEIBU_COP_BOOTLEG, tag, owner, clock), device_memory_interface(mconfig, *this), - m_space_config("regs", ENDIANNESS_LITTLE, 16, 9, 0, address_map_constructor(), address_map_constructor(FUNC(seibu_cop_bootleg_device::seibucopbl_map), this)) + m_space_config("regs", ENDIANNESS_BIG, 16, 9, 0, address_map_constructor(), address_map_constructor(FUNC(seibu_cop_bootleg_device::seibucopbl_map), this)) { }