Added support for the address high byte to i2cmem for devices greater than 4096 bytes. [smf]

Hooked up a 24C64 to the Domyos games in Xavix2 [smf, N. Gilbert]
This commit is contained in:
smf- 2020-03-13 12:28:09 +00:00
parent a8920c68c8
commit f89888fc34
3 changed files with 117 additions and 27 deletions

View File

@ -18,22 +18,22 @@ outputs:
The memory address is only 8 bits, devices larger than this have multiple slave addresses. The memory address is only 8 bits, devices larger than this have multiple slave addresses.
The top five address bits are set at manufacture time, two values are standard. The top five address bits are set at manufacture time, two values are standard.
Up to 4096 bytes can be addressed.
***************************************************************************/ ***************************************************************************/
#include "emu.h" #include "emu.h"
#include "machine/i2cmem.h" #include "machine/i2cmem.h"
#define STATE_IDLE ( 0 ) constexpr int STATE_IDLE(0);
#define STATE_DEVSEL ( 1 ) constexpr int STATE_DEVSEL(1);
#define STATE_BYTEADDR ( 2 ) constexpr int STATE_ADDRESSHIGH(2);
#define STATE_DATAIN ( 3 ) constexpr int STATE_ADDRESSLOW(3);
#define STATE_DATAOUT ( 4 ) constexpr int STATE_DATAIN(4);
#define STATE_RESET ( 5 ) constexpr int STATE_DATAOUT(5);
constexpr int STATE_RESET(6);
#define DEVSEL_RW ( 1 ) constexpr int DEVSEL_RW(1);
#define DEVSEL_ADDRESS ( 0xfe ) constexpr int DEVSEL_ADDRESS(0xfe);
//************************************************************************** //**************************************************************************
// DEBUGGING // DEBUGGING
@ -100,6 +100,8 @@ i2cmem_device::i2cmem_device(
m_sdar(1), m_sdar(1),
m_state(STATE_IDLE), m_state(STATE_IDLE),
m_shift(0), m_shift(0),
m_devsel(0),
m_addresshigh(0),
m_byteaddr(0), m_byteaddr(0),
m_page_offset(0), m_page_offset(0),
m_page_written_size(0) m_page_written_size(0)
@ -173,6 +175,8 @@ void i2cmem_device::device_start()
save_item( NAME(m_bits) ); save_item( NAME(m_bits) );
save_item( NAME(m_shift) ); save_item( NAME(m_shift) );
save_item( NAME(m_devsel) ); save_item( NAME(m_devsel) );
if (!skip_addresshigh())
save_item( NAME(m_addresshigh) );
save_item( NAME(m_byteaddr) ); save_item( NAME(m_byteaddr) );
save_item( NAME(m_page_offset) ); save_item( NAME(m_page_offset) );
save_item( NAME(m_page_written_size) ); save_item( NAME(m_page_written_size) );
@ -315,7 +319,8 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
switch( m_state ) switch( m_state )
{ {
case STATE_DEVSEL: case STATE_DEVSEL:
case STATE_BYTEADDR: case STATE_ADDRESSHIGH:
case STATE_ADDRESSLOW:
case STATE_DATAIN: case STATE_DATAIN:
if( m_bits < 8 ) if( m_bits < 8 )
{ {
@ -350,7 +355,7 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
else if( ( m_devsel & DEVSEL_RW ) == 0 ) else if( ( m_devsel & DEVSEL_RW ) == 0 )
{ {
verboselog( this, 1, "devsel %02x: write\n", m_devsel ); verboselog( this, 1, "devsel %02x: write\n", m_devsel );
m_state = STATE_BYTEADDR; m_state = skip_addresshigh() ? STATE_ADDRESSLOW : STATE_ADDRESSHIGH;
} }
else else
{ {
@ -359,12 +364,20 @@ WRITE_LINE_MEMBER( i2cmem_device::write_scl )
} }
break; break;
case STATE_BYTEADDR: case STATE_ADDRESSHIGH:
m_byteaddr = ((m_devsel << 7) & 0xff00) | m_shift; m_addresshigh = m_shift;
verboselog(this, 1, "addresshigh %02x\n", m_addresshigh);
m_state = STATE_ADDRESSLOW;
break;
case STATE_ADDRESSLOW:
m_byteaddr = m_shift | (skip_addresshigh() ? (m_devsel & DEVSEL_ADDRESS) << 7 : m_addresshigh << 8);
m_page_offset = 0; m_page_offset = 0;
m_page_written_size = 0; m_page_written_size = 0;
verboselog( this, 1, "byteaddr %02x\n", m_shift ); verboselog( this, 1, "addresslow %02x (byteaddr %04x)\n", m_shift, m_byteaddr );
m_state = STATE_DATAIN; m_state = STATE_DATAIN;
break; break;
@ -508,7 +521,7 @@ int i2cmem_device::address_mask()
int i2cmem_device::select_device() int i2cmem_device::select_device()
{ {
int device = ( m_slave_address & 0xf0 ) | ( m_e2 << 3 ) | ( m_e1 << 2 ) | ( m_e0 << 1 ); int device = ( m_slave_address & 0xf0 ) | ( m_e2 << 3 ) | ( m_e1 << 2 ) | ( m_e0 << 1 );
int mask = DEVSEL_ADDRESS & ~( address_mask() >> 7 ); int mask = DEVSEL_ADDRESS & ~( skip_addresshigh() ? address_mask() >> 7 : 0 );
if( ( m_devsel & mask ) == ( device & mask ) ) if( ( m_devsel & mask ) == ( device & mask ) )
{ {

View File

@ -69,6 +69,7 @@ protected:
int address_mask(); int address_mask();
int select_device(); int select_device();
int data_offset(); int data_offset();
bool skip_addresshigh() const { return m_data_size <= 0x800; }
optional_memory_region m_region; optional_memory_region m_region;
@ -88,6 +89,7 @@ protected:
int m_bits; int m_bits;
int m_shift; int m_shift;
int m_devsel; int m_devsel;
int m_addresshigh;
int m_byteaddr; int m_byteaddr;
std::vector<uint8_t> m_page; std::vector<uint8_t> m_page;
int m_page_offset; int m_page_offset;

View File

@ -31,9 +31,9 @@ public:
, m_pio(*this, "pio") , m_pio(*this, "pio")
{ } { }
void xavix2(machine_config &config); virtual void config(machine_config &config);
private: protected:
enum { enum {
IRQ_TIMER = 7, IRQ_TIMER = 7,
IRQ_DMA = 12 IRQ_DMA = 12
@ -41,7 +41,7 @@ private:
required_device<xavix2_device> m_maincpu; required_device<xavix2_device> m_maincpu;
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
required_device<i2c_24c08_device> m_i2cmem; optional_device<i2cmem_device> m_i2cmem;
required_ioport m_pio; required_ioport m_pio;
u32 m_dma_src; u32 m_dma_src;
@ -122,7 +122,7 @@ private:
void pio_mode_w(offs_t offset, u32 data, u32 mem_mask); void pio_mode_w(offs_t offset, u32 data, u32 mem_mask);
u32 pio_mode_r(offs_t offset); u32 pio_mode_r(offs_t offset);
void pio_update(); virtual void pio_update() = 0;
void pio_w(offs_t offset, u32 data, u32 mem_mask); void pio_w(offs_t offset, u32 data, u32 mem_mask);
u32 pio_r(); u32 pio_r();
@ -136,6 +136,26 @@ private:
void mem(address_map &map); void mem(address_map &map);
}; };
class naruto_state : public xavix2_state
{
public:
using xavix2_state::xavix2_state;
virtual void config(machine_config& config) override;
protected:
virtual void pio_update() override;
};
class domyos_state : public xavix2_state
{
public:
using xavix2_state::xavix2_state;
virtual void config(machine_config& config) override;
protected:
virtual void pio_update() override;
};
u32 xavix2_state::rgb555_888(u16 color) u32 xavix2_state::rgb555_888(u16 color)
{ {
u8 r = (color >> 0) & 31; u8 r = (color >> 0) & 31;
@ -461,7 +481,7 @@ u32 xavix2_state::pio_mode_r(offs_t offset)
return m_pio_mode[offset]; return m_pio_mode[offset];
} }
void xavix2_state::pio_update() void naruto_state::pio_update()
{ {
if (BIT(m_pio_mask_out, 21)) if (BIT(m_pio_mask_out, 21))
m_i2cmem->write_sda(BIT(m_pio_dataw, 21)); m_i2cmem->write_sda(BIT(m_pio_dataw, 21));
@ -469,6 +489,14 @@ void xavix2_state::pio_update()
m_i2cmem->write_scl(BIT(m_pio_dataw, 20)); m_i2cmem->write_scl(BIT(m_pio_dataw, 20));
} }
void domyos_state::pio_update()
{
if (BIT(m_pio_mask_out, 16))
m_i2cmem->write_sda(BIT(m_pio_dataw, 16));
if (BIT(m_pio_mask_out, 17))
m_i2cmem->write_scl(BIT(m_pio_dataw, 17));
}
void xavix2_state::pio_w(offs_t offset, u32 data, u32 mem_mask) void xavix2_state::pio_w(offs_t offset, u32 data, u32 mem_mask)
{ {
COMBINE_DATA(&m_pio_dataw); COMBINE_DATA(&m_pio_dataw);
@ -595,7 +623,7 @@ void xavix2_state::machine_reset()
m_bg_color = 0; m_bg_color = 0;
} }
static INPUT_PORTS_START( xavix2 ) static INPUT_PORTS_START( naruto )
PORT_START("pio") PORT_START("pio")
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_BUTTON3)
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_BUTTON4)
@ -631,7 +659,43 @@ static INPUT_PORTS_START( xavix2 )
PORT_BIT(0x80000000, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_PLAYER(2) PORT_BIT(0x80000000, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_PLAYER(2)
INPUT_PORTS_END INPUT_PORTS_END
void xavix2_state::xavix2(machine_config &config) static INPUT_PORTS_START(domyos)
PORT_START("pio")
PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_BUTTON1)
PORT_BIT(0x00000002, IP_ACTIVE_HIGH, IPT_BUTTON2)
PORT_BIT(0x00000004, IP_ACTIVE_HIGH, IPT_BUTTON3)
PORT_BIT(0x00000008, IP_ACTIVE_HIGH, IPT_BUTTON4)
PORT_BIT(0x00000010, IP_ACTIVE_HIGH, IPT_BUTTON5)
PORT_BIT(0x00000020, IP_ACTIVE_HIGH, IPT_BUTTON6)
PORT_BIT(0x00000040, IP_ACTIVE_HIGH, IPT_BUTTON7)
PORT_BIT(0x00000080, IP_ACTIVE_HIGH, IPT_BUTTON8)
PORT_BIT(0x00000100, IP_ACTIVE_HIGH, IPT_BUTTON9)
PORT_BIT(0x00000200, IP_ACTIVE_HIGH, IPT_BUTTON10)
PORT_BIT(0x00000400, IP_ACTIVE_HIGH, IPT_BUTTON11)
PORT_BIT(0x00000800, IP_ACTIVE_HIGH, IPT_BUTTON12)
PORT_BIT(0x00001000, IP_ACTIVE_HIGH, IPT_BUTTON13)
PORT_BIT(0x00002000, IP_ACTIVE_HIGH, IPT_BUTTON14)
PORT_BIT(0x00004000, IP_ACTIVE_HIGH, IPT_BUTTON15)
PORT_BIT(0x00008000, IP_ACTIVE_HIGH, IPT_BUTTON16)
PORT_BIT(0x00010000, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_READ_LINE_DEVICE_MEMBER("i2cmem", i2cmem_device, read_sda)
PORT_BIT(0x00020000, IP_ACTIVE_HIGH, IPT_CUSTOM) // i2c clock
PORT_BIT(0x00040000, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_PLAYER(2)
PORT_BIT(0x00080000, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_PLAYER(2)
PORT_BIT(0x00100000, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_PLAYER(2)
PORT_BIT(0x00200000, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_PLAYER(2)
PORT_BIT(0x00400000, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_PLAYER(2)
PORT_BIT(0x00800000, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_PLAYER(2)
PORT_BIT(0x01000000, IP_ACTIVE_HIGH, IPT_BUTTON9) PORT_PLAYER(2)
PORT_BIT(0x02000000, IP_ACTIVE_HIGH, IPT_BUTTON10) PORT_PLAYER(2)
PORT_BIT(0x04000000, IP_ACTIVE_HIGH, IPT_BUTTON11) PORT_PLAYER(2)
PORT_BIT(0x08000000, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_PLAYER(2)
PORT_BIT(0x10000000, IP_ACTIVE_HIGH, IPT_BUTTON13) PORT_PLAYER(2)
PORT_BIT(0x20000000, IP_ACTIVE_HIGH, IPT_BUTTON14) PORT_PLAYER(2)
PORT_BIT(0x40000000, IP_ACTIVE_HIGH, IPT_BUTTON15) PORT_PLAYER(2)
PORT_BIT(0x80000000, IP_ACTIVE_HIGH, IPT_BUTTON16) PORT_PLAYER(2)
INPUT_PORTS_END
void xavix2_state::config(machine_config &config)
{ {
// unknown CPU 'SSD 2002-2004 NEC 800208-51' // unknown CPU 'SSD 2002-2004 NEC 800208-51'
XAVIX2(config, m_maincpu, 98'000'000); XAVIX2(config, m_maincpu, 98'000'000);
@ -645,8 +709,6 @@ void xavix2_state::xavix2(machine_config &config)
m_screen->set_size(640, 400); m_screen->set_size(640, 400);
m_screen->set_visarea(0, 639, 0, 399); m_screen->set_visarea(0, 639, 0, 399);
I2C_24C08(config, m_i2cmem);
/* sound hardware */ /* sound hardware */
SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right(); SPEAKER(config, "rspeaker").front_right();
@ -654,6 +716,19 @@ void xavix2_state::xavix2(machine_config &config)
// unknown sound hardware // unknown sound hardware
} }
void naruto_state::config(machine_config& config)
{
xavix2_state::config(config);
I2C_24C08(config, m_i2cmem);
}
void domyos_state::config(machine_config& config)
{
xavix2_state::config(config);
I2C_24C64(config, m_i2cmem);
}
ROM_START( ltv_naru ) ROM_START( ltv_naru )
ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 ) ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASE00 )
@ -671,13 +746,13 @@ ROM_START( dombikec )
ROM_END ROM_END
CONS( 2006, ltv_naru, 0, 0, xavix2, xavix2, xavix2_state, empty_init, "Bandai / SSD Company LTD", "Let's TV Play Naruto", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 2006, ltv_naru, 0, 0, config, naruto, naruto_state, empty_init, "Bandai / SSD Company LTD", "Let's TV Play Naruto", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
// These are for the 'Domyos Interactive System' other Domyos Interactive System games can be found in xavix.cpp (the SoC is inside the cartridge, base acts as a 'TV adapter' only) // These are for the 'Domyos Interactive System' other Domyos Interactive System games can be found in xavix.cpp (the SoC is inside the cartridge, base acts as a 'TV adapter' only)
// Has SEEPROM and an RTC. Adventure has the string DOMYSSDCOLTD a couple of times. // Has SEEPROM and an RTC. Adventure has the string DOMYSSDCOLTD a couple of times.
CONS( 2008, domfitad, 0, 0, xavix2, xavix2, xavix2_state, empty_init, "Decathlon / SSD Company LTD", "Domyos Fitness Adventure (Domyos Interactive System)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 2008, domfitad, 0, 0, config, domyos, domyos_state, empty_init, "Decathlon / SSD Company LTD", "Domyos Fitness Adventure (Domyos Interactive System)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
CONS( 2008, dombikec, 0, 0, xavix2, xavix2, xavix2_state, empty_init, "Decathlon / SSD Company LTD", "Domyos Bike Concept (Domyos Interactive System)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) CONS( 2008, dombikec, 0, 0, config, domyos, domyos_state, empty_init, "Decathlon / SSD Company LTD", "Domyos Bike Concept (Domyos Interactive System)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )