From a4ad409630587a66e6594439c6b2ad0de1f248c0 Mon Sep 17 00:00:00 2001 From: Fabio Priuli Date: Thu, 13 Feb 2014 12:44:18 +0000 Subject: [PATCH] (MESS) nes_datach: documented the eeprom hookups, and the second eeprom used by Battle Rush. they do not work yet. nw. --- hash/nes_datach.xml | 2 +- src/mess/machine/nes_datach.c | 80 ++++++++++++++++++++++++++++++++--- src/mess/machine/nes_datach.h | 17 ++++++++ 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/hash/nes_datach.xml b/hash/nes_datach.xml index ca0a5259910..2697c7c023c 100644 --- a/hash/nes_datach.xml +++ b/hash/nes_datach.xml @@ -10,7 +10,7 @@ - + diff --git a/src/mess/machine/nes_datach.c b/src/mess/machine/nes_datach.c index aaf970e52b2..aac7648e1ec 100644 --- a/src/mess/machine/nes_datach.c +++ b/src/mess/machine/nes_datach.c @@ -27,6 +27,11 @@ #define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0) +#define EEPROM_INTERNAL 0 +#define EEPROM_EXTERNAL 1 + + +#define TEST_EEPROM 0 //-------------------------------- // @@ -40,6 +45,7 @@ datach_cart_interface::datach_cart_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device), + m_i2cmem(*this, "i2cmem"), m_rom(NULL), m_rom_size(0) { @@ -141,6 +147,7 @@ bool nes_datach_slot_device::call_softlist_load(char *swlist, char *swname, rom_ const char * nes_datach_slot_device::get_default_card_software(const machine_config &config, emu_options &options) { + // any way to detect the game with X24C01? return software_get_default_slot(config, options, this, "datach_rom"); } @@ -149,6 +156,11 @@ const char * nes_datach_slot_device::get_default_card_software(const machine_con // // Datach Minicart implementation // +// Two kinds of PCB exist +// * ROM only, used by most games +// * ROM + X24C01 EEPROM, used by +// Battle Rush +// //-------------------------------- ROM_START( datach_rom ) @@ -156,6 +168,13 @@ ROM_START( datach_rom ) ROM_END const device_type NES_DATACH_ROM = &device_creator; +const device_type NES_DATACH_24C01 = &device_creator; + +nes_datach_rom_device::nes_datach_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, "nes_datach_24c01", __FILE__), + datach_cart_interface( mconfig, *this ) +{ +} nes_datach_rom_device::nes_datach_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, NES_DATACH_ROM, "NES Datach ROM", tag, owner, clock, "nes_datach_rom", __FILE__), @@ -163,6 +182,12 @@ nes_datach_rom_device::nes_datach_rom_device(const machine_config &mconfig, cons { } +nes_datach_24c01_device::nes_datach_24c01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_datach_rom_device(mconfig, NES_DATACH_24C01, "NES Datach + 24C01 PCB", tag, owner, clock, "nes_datach_ep1", __FILE__) +{ +} + + void nes_datach_rom_device::device_start() { m_rom = (UINT8*)memregion("datachrom")->base(); @@ -185,6 +210,16 @@ UINT8 *nes_datach_rom_device::get_cart_base() } +MACHINE_CONFIG_FRAGMENT( subcart_i2c_24c01 ) + MCFG_24C01_ADD("i2cmem") +MACHINE_CONFIG_END + +machine_config_constructor nes_datach_24c01_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( subcart_i2c_24c01 ); +} + + //--------------------------------- // // Datach Base Unit implementation @@ -226,6 +261,7 @@ void nes_datach_device::pcb_reset() m_irq_enable = 0; m_irq_count = 0; m_datach_latch = 0; + m_i2c_in_use = EEPROM_INTERNAL; } @@ -261,7 +297,17 @@ void nes_datach_device::pcb_reset() READ8_MEMBER(nes_datach_device::read_m) { LOG_MMC(("Datach read_m, offset: %04x\n", offset)); - return m_datach_latch; + UINT8 i2c_val = 0; +#if TEST_EEPROM + if (m_i2c_dir) + { + if (m_i2c_in_use == EEPROM_INTERNAL) + i2c_val = (m_i2cmem->read_sda() & 1) << 4; + if (m_i2c_in_use == EEPROM_EXTERNAL && m_subslot->m_cart && m_subslot->m_cart->m_i2cmem) + i2c_val = (m_subslot->m_cart->m_i2cmem->read_sda() & 1) << 4; + } +#endif + return m_datach_latch | i2c_val; } @@ -285,16 +331,36 @@ WRITE8_MEMBER(nes_datach_device::write_h) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - // these don't switch CHR bank, but are SCL output - // of the oncart I2C EEPROM! + // these don't switch CHR bank (if you try this, both Battle Rush and SD Gundam Wars will have glitches!) + // bit3 goes to SCL of the external EEPROM (and we use write=1 to enable reading from this EEPROM) + // docs from naruko don't specify the bit, our choice comes from observation of writes performed by Battle Rush +#if TEST_EEPROM + if (m_subslot->m_cart && m_subslot->m_cart->m_i2cmem) + { + if (BIT(data, 3)) + m_i2c_in_use = EEPROM_EXTERNAL; + m_subslot->m_cart->m_i2cmem->write_scl(BIT(data, 3)); + } +#endif break; case 0x08: m_subslot->write_prg_bank(data & 0x0f); break; case 0x0d: - // these should go to the I2C EEPROM on the Datach base - // but SDA line is shared with the oncart I2C EEPROM if - // there is one (only in Datach - Battle Rush) +#if TEST_EEPROM + // bit7, select SDA direction LZ93D50P -> EEPROM or EEPROM -> LZ93D50P + m_i2c_dir = BIT(data, 7); + + // bit6 goes to SDA line, which is in common with the 2nd EEPROM, if present + m_i2cmem->write_sda(BIT(data, 6)); + if (m_subslot->m_cart && m_subslot->m_cart->m_i2cmem) + m_subslot->m_cart->m_i2cmem->write_sda(BIT(data, 6)); + + // bit5 goes to SCL of the internal EEPROM (and we use write=1 to enable reading from this EEPROM) + if (BIT(data, 5)) + m_i2c_in_use = EEPROM_INTERNAL; + m_i2cmem->write_scl(BIT(data, 5)); +#endif break; default: fcg_write(space, offset & 0x0f, data, mem_mask); @@ -302,13 +368,13 @@ WRITE8_MEMBER(nes_datach_device::write_h) } } - //------------------------------------------------- // BARCODE READER + CART SLOT + X24C02 //------------------------------------------------- static SLOT_INTERFACE_START(datach_cart) SLOT_INTERFACE("datach_rom", NES_DATACH_ROM) + SLOT_INTERFACE("datach_ep1", NES_DATACH_24C01) SLOT_INTERFACE_END diff --git a/src/mess/machine/nes_datach.h b/src/mess/machine/nes_datach.h index f2953efbb11..82902b47c0b 100644 --- a/src/mess/machine/nes_datach.h +++ b/src/mess/machine/nes_datach.h @@ -26,6 +26,8 @@ public: UINT8 *get_cart_base() { return m_rom; } void write_prg_bank(UINT8 bank) { m_bank = bank; } + optional_device m_i2cmem; + protected: // internal state UINT8 *m_rom; @@ -94,6 +96,7 @@ class nes_datach_rom_device : public device_t, { public: // construction/destruction + nes_datach_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); nes_datach_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); // optional information overrides @@ -106,8 +109,21 @@ protected: virtual void device_reset(); }; +// ======================> nes_datach_24c01_device + +class nes_datach_24c01_device : public nes_datach_rom_device +{ +public: + // construction/destruction + nes_datach_24c01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual machine_config_constructor device_mconfig_additions() const; +}; + // device type definition extern const device_type NES_DATACH_ROM; +extern const device_type NES_DATACH_24C01; //--------------------------------- @@ -140,6 +156,7 @@ protected: required_device m_reader; required_device m_subslot; UINT8 m_i2c_dir; + UINT8 m_i2c_in_use; static const device_timer_id TIMER_SERIAL = 1; emu_timer *serial_timer;