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;