summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ariedlmayer@gmail.com>2025-06-13 23:56:20 -0400
committer AJR <ariedlmayer@gmail.com>2025-06-13 23:58:33 -0400
commit63c9c7f475c36f828c65c0145a7423623d323cb0 (patch)
tree869cab8975fc426d2cb5b9a209a2527b8f20ec92
parentf3abbc8145f3d6850c9e8ab1e5d06c03a54de1bd (diff)
nintendo/vt1682.cpp: I/O enhancements
- Add ports E & F - Add 24C02 serial EEPROM to njp60in1 and pgs268 - Add provisional A/D interface (not hooked up to anything yet) - Respect direction settings when reading from ports
-rw-r--r--src/mame/nintendo/vt1682.cpp78
-rw-r--r--src/mame/nintendo/vt1682_io.cpp181
-rw-r--r--src/mame/nintendo/vt1682_io.h24
3 files changed, 214 insertions, 69 deletions
diff --git a/src/mame/nintendo/vt1682.cpp b/src/mame/nintendo/vt1682.cpp
index e4b681a5694..6a14733c39c 100644
--- a/src/mame/nintendo/vt1682.cpp
+++ b/src/mame/nintendo/vt1682.cpp
@@ -63,6 +63,7 @@
#include "vt1682_alu.h"
#include "vt1682_timer.h"
#include "machine/bankdev.h"
+#include "machine/i2cmem.h"
#include "machine/timer.h"
#include "sound/dac.h"
#include "emupal.h"
@@ -113,6 +114,7 @@ public:
m_bank(*this, "cartbank"),
m_screen(*this, "screen"),
m_soundcpu(*this, "soundcpu"),
+ m_seeprom(*this, "seeprom"),
m_soundcpu_timer_a_dev(*this, "snd_timera_dev"),
m_soundcpu_timer_b_dev(*this, "snd_timerb_dev"),
m_system_timer_dev(*this, "sys_timer_dev"),
@@ -150,6 +152,7 @@ protected:
required_memory_bank m_bank;
required_device<screen_device> m_screen;
required_device<cpu_device> m_soundcpu;
+ optional_device<i2cmem_device> m_seeprom;
void soundcpu_timera_irq(int state);
void soundcpu_timerb_irq(int state);
@@ -374,8 +377,6 @@ private:
uint8_t vt1682_2030_r();
void vt1682_2030_w(uint8_t data);
- uint8_t io_ef_r() { return 0x00; }
-
/* Video Helpers */
uint16_t get_spriteram_addr()
@@ -717,6 +718,7 @@ public:
{ }
void vt1682_lxts3(machine_config& config);
+ void vt1682_24c02(machine_config& config);
void vt1682_unk1682(machine_config& config);
void unk1682_init();
@@ -726,6 +728,9 @@ public:
protected:
uint8_t uio_porta_r();
+ uint8_t iof_i2c_r() { return m_seeprom->read_sda() ? 0xc : 0x8; }
+ void iof_i2c_w(uint8_t data) { m_seeprom->write_sda(BIT(data, 2)); m_seeprom->write_scl(BIT(data, 3)); }
+
private:
required_ioport m_io_p1;
};
@@ -3372,30 +3377,6 @@ void vt_vt1682_state::vt1682_211c_regs_ext2421_w(uint8_t data)
*/
/*
- Address 0x211e WRITE (MAIN CPU)
-
- 0x80 - ADCEN
- 0x40 - ADCS1
- 0x20 - ADCS0
- 0x10 - (unused)
- 0x08 - IOFOEN3
- 0x04 - IOFOEN2
- 0x02 - IOFOEN1
- 0x01 - IOFOEN0
-
- Address 0x211e READ (MAIN CPU)
-
- 0x80 - ADC DATA:7
- 0x40 - ADC DATA:6
- 0x20 - ADC DATA:5
- 0x10 - ADC DATA:4
- 0x08 - ADC DATA:3
- 0x04 - ADC DATA:2
- 0x02 - ADC DATA:1
- 0x01 - ADC DATA:0
-*/
-
-/*
Address 0x211f r/w (MAIN CPU)
0x80 - VGCEN
@@ -4056,32 +4037,6 @@ void vt_vt1682_state::vt1682_212c_prng_seed_w(uint8_t data)
0x01 - UIOB ATTRIBUTE
*/
-/*
- Address 0x214c r/w (MAIN CPU)
-
- 0x80 - (unused)
- 0x40 - (unused)
- 0x20 - Keychange Enable
- 0x10 - Keychange Enable
- 0x08 - IOFEN
- 0x04 - (unused)
- 0x02 - (unused)
- 0x01 - IOEOEN
-*/
-
-/*
- Address 0x214d r/w (MAIN CPU)
-
- 0x80 - IOF:3
- 0x40 - IOF:2
- 0x20 - IOF:1
- 0x10 - IOF:0
- 0x08 - IOE:3
- 0x04 - IOE:2
- 0x02 - IOE:1
- 0x01 - IOE:0
-*/
-
/************************************************************************************************************************************
VT1682 Sound CPU Registers
@@ -5428,7 +5383,7 @@ void vt_vt1682_state::vt_vt1682_map(address_map &map)
// 211b UART
map(0x211c, 0x211c).w(FUNC(vt_vt1682_state::vt1682_211c_regs_ext2421_w));
// 211d misc enable regs
- // 211e ADC
+ map(0x211e, 0x211e).rw(m_io, FUNC(vrt_vt1682_io_device::vt1682_211e_adc_data_r), FUNC(vrt_vt1682_io_device::vt1682_211e_adconfig_w));
// 211f voice gain
// 2120 sleep period
// 2121 misc interrupt masks / clears
@@ -5460,7 +5415,8 @@ void vt_vt1682_state::vt_vt1682_map(address_map &map)
map(0x214a, 0x214a).rw(m_uio, FUNC(vrt_vt1682_uio_device::inteact_214a_uio_b_direction_r), FUNC(vrt_vt1682_uio_device::inteact_214a_uio_b_direction_w));
map(0x214b, 0x214b).rw(m_uio, FUNC(vrt_vt1682_uio_device::inteact_214b_uio_b_attribute_r), FUNC(vrt_vt1682_uio_device::inteact_214b_uio_b_attribute_w));
- map(0x214d, 0x214d).r(FUNC(vt_vt1682_state::io_ef_r));
+ map(0x214c, 0x214c).rw(m_io, FUNC(vrt_vt1682_io_device::vt1682_214c_ioefconfig_r),FUNC(vrt_vt1682_io_device::vt1682_214c_ioefconfig_w));
+ map(0x214d, 0x214d).rw(m_io, FUNC(vrt_vt1682_io_device::vt1682_214d_io_ef_r),FUNC(vrt_vt1682_io_device::vt1682_214d_io_ef_w));
// 3000-3fff internal ROM if enabled
map(0x4000, 0x7fff).r(FUNC(vt_vt1682_state::rom_4000_to_7fff_r));
@@ -6281,6 +6237,16 @@ void vt1682_lxts3_state::vt1682_lxts3(machine_config& config)
m_uio->porta_in().set(FUNC(vt1682_lxts3_state::uio_porta_r));
}
+void vt1682_lxts3_state::vt1682_24c02(machine_config& config)
+{
+ vt1682_lxts3(config);
+
+ m_io->portf_in().set(FUNC(vt1682_lxts3_state::iof_i2c_r));
+ m_io->portf_out().set(FUNC(vt1682_lxts3_state::iof_i2c_w));
+
+ I2C_24C02(config, m_seeprom);
+}
+
void vt1682_mx10_state::mx10(machine_config& config)
{
vt_vt1682_ntscbase(config);
@@ -6653,10 +6619,10 @@ CONS( 200?, dance555, 0, 0, vt1682_exsportp, dance555, vt1682_exsport_state
// manual explicitly states it has NTSC output only (unit can be connected to a TV) and both Ranning Horse + Explosion (Bomberman) are the NTSC versions
// has 21.477 Mhz XTAL
-CONS( 200?, njp60in1, 0, 0, vt1682_lxts3, njp60in1, vt1682_lxts3_state, njp60in1_init, "<unknown>", "NJ Pocket 60-in-1 handheld 'X zero' (NTSC)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND)
+CONS( 200?, njp60in1, 0, 0, vt1682_24c02, njp60in1, vt1682_lxts3_state, njp60in1_init, "<unknown>", "NJ Pocket 60-in-1 handheld 'X zero' (NTSC)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND)
// fewer than 268 games, there are repeats
-CONS( 200?, pgs268, 0, 0, vt1682_lxts3, njp60in1, vt1682_lxts3_state, pgs268_init, "<unknown>", "Portable Game Station 268-in-1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND)
+CONS( 200?, pgs268, 0, 0, vt1682_24c02, njp60in1, vt1682_lxts3_state, pgs268_init, "<unknown>", "Portable Game Station 268-in-1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND)
// this appears to be related to the NJ Pocket, claims 101-in-1 but has some duplicates.
// Like the 'Wow Wireless gaming' it incorrectly mixes the PAL version of 'Ranning Horse' with the NTSC version of 'Bomberman', it has no TV output.
diff --git a/src/mame/nintendo/vt1682_io.cpp b/src/mame/nintendo/vt1682_io.cpp
index 09a7eee5db6..ce7ad61f36f 100644
--- a/src/mame/nintendo/vt1682_io.cpp
+++ b/src/mame/nintendo/vt1682_io.cpp
@@ -20,21 +20,37 @@ vrt_vt1682_io_device::vrt_vt1682_io_device(const machine_config &mconfig, const
m_portb_out(*this),
m_portc_out(*this),
m_portd_out(*this),
+ m_porte_out(*this),
+ m_portf_out(*this),
m_porta_in(*this, 0),
m_portb_in(*this, 0),
m_portc_in(*this, 0),
- m_portd_in(*this, 0)
+ m_portd_in(*this, 0),
+ m_porte_in(*this, 0),
+ m_portf_in(*this, 0),
+ m_xiof_in(*this, 0)
{
}
void vrt_vt1682_io_device::device_start()
{
+ m_io_ab_o = 0;
+ m_io_cd_o = 0;
+ m_io_ef_o = 0;
+
save_item(NAME(m_210d_ioconfig));
+ save_item(NAME(m_211e_adconfig));
+ save_item(NAME(m_214c_ioefconfig));
+ save_item(NAME(m_io_ab_o));
+ save_item(NAME(m_io_cd_o));
+ save_item(NAME(m_io_ef_o));
}
void vrt_vt1682_io_device::device_reset()
{
m_210d_ioconfig = 0;
+ m_211e_adconfig = 0;
+ m_214c_ioefconfig = 0;
}
@@ -88,16 +104,33 @@ void vrt_vt1682_io_device::vt1682_210d_ioconfig_w(uint8_t data)
uint8_t vrt_vt1682_io_device::vt1682_210e_io_ab_r()
{
- uint8_t ret = (m_porta_in(0, 0x0f) & 0x0f) | ((m_portb_in(0, 0x0f) & 0x0f)<<4);
- LOGMASKED(LOG_IO, "%s: vt1682_210e_io_ab_r returning: %02x\n", machine().describe_context(), ret);
+ uint8_t ret;
+ if (BIT(m_210d_ioconfig, 0))
+ ret = m_io_ab_o & 0x0f;
+ else
+ ret = m_porta_in(0, 0x0f) & 0x0f;
+ if (BIT(m_210d_ioconfig, 2))
+ ret |= m_io_ab_o & 0xf0;
+ else
+ ret |= m_portb_in(0, 0x0f) << 4;
+
return ret;
}
void vrt_vt1682_io_device::vt1682_210e_io_ab_w(uint8_t data)
{
- LOGMASKED(LOG_IO, "%s: vt1682_210e_io_ab_w writing: %02x (portb: %1x porta: %1x)\n", machine().describe_context(), data, (data & 0xf0) >> 4, data & 0x0f);
- m_porta_out(0, (data & 0x0f), 0x0f);
- m_portb_out(0, ((data & 0xf0)>>4), 0x0f);
+ if (((m_io_ab_o ^ data) & 0x0f) != 0)
+ {
+ LOGMASKED(LOG_IO, "%s: IOA_O = %1x\n", machine().describe_context(), data & 0x0f);
+ m_porta_out(0, data & 0x0f, 0x0f);
+ }
+ if (((m_io_ab_o ^ data) & 0xf0) != 0)
+ {
+ LOGMASKED(LOG_IO, "%s: IOB_O = %1x\n", machine().describe_context(), data >> 4);
+ m_portb_out(0, data >> 4, 0x0f);
+ }
+
+ m_io_ab_o = data;
}
/*
@@ -115,14 +148,140 @@ void vrt_vt1682_io_device::vt1682_210e_io_ab_w(uint8_t data)
uint8_t vrt_vt1682_io_device::vt1682_210f_io_cd_r()
{
- uint8_t ret = (m_portc_in(0, 0x0f) & 0x0f) | ((m_portd_in(0, 0x0f) & 0x0f)<<4);
- LOGMASKED(LOG_IO, "%s: vt1682_210f_io_cd_r returning: %02x\n", machine().describe_context(), ret);
+ uint8_t ret;
+ if (BIT(m_210d_ioconfig, 4))
+ ret = m_io_cd_o & 0x0f;
+ else
+ ret = m_portc_in(0, 0x0f) & 0x0f;
+ if (BIT(m_210d_ioconfig, 6))
+ ret |= m_io_cd_o & 0xf0;
+ else
+ ret |= m_portd_in(0, 0x0f) << 4;
+
return ret;
}
void vrt_vt1682_io_device::vt1682_210f_io_cd_w(uint8_t data)
{
- LOGMASKED(LOG_IO, "%s: vt1682_210f_io_cd_w writing: %02x (portd: %1x portc: %1x)\n", machine().describe_context(), data, (data & 0xf0) >> 4, data & 0x0f);
- m_portc_out(0, (data & 0x0f), 0x0f);
- m_portd_out(0, ((data & 0xf0)>>4), 0x0f);
+ if (((m_io_cd_o ^ data) & 0x0f) != 0)
+ {
+ LOGMASKED(LOG_IO, "%s: IOC_O = %1x\n", machine().describe_context(), data & 0x0f);
+ m_portc_out(0, data & 0x0f, 0x0f);
+ }
+ if (((m_io_cd_o ^ data) & 0xf0) != 0)
+ {
+ LOGMASKED(LOG_IO, "%s: IOD_O = %1x\n", machine().describe_context(), data >> 4);
+ m_portd_out(0, data >> 4, 0x0f);
+ }
+
+ m_io_cd_o = data;
+}
+
+/*
+ Address 0x211e WRITE (MAIN CPU)
+
+ 0x80 - ADCEN
+ 0x40 - ADCS1
+ 0x20 - ADCS0
+ 0x10 - (unused)
+ 0x08 - IOFOEN3
+ 0x04 - IOFOEN2
+ 0x02 - IOFOEN1
+ 0x01 - IOFOEN0
+
+ Address 0x211e READ (MAIN CPU)
+
+ 0x80 - ADC DATA:7
+ 0x40 - ADC DATA:6
+ 0x20 - ADC DATA:5
+ 0x10 - ADC DATA:4
+ 0x08 - ADC DATA:3
+ 0x04 - ADC DATA:2
+ 0x02 - ADC DATA:1
+ 0x01 - ADC DATA:0
+*/
+
+uint8_t vrt_vt1682_io_device::vt1682_211e_adc_data_r()
+{
+ if (!machine().side_effects_disabled())
+ LOGMASKED(LOG_IO, "%s: vt1682_211e_adc_data_r (ADCSEL = %d)\n", machine().describe_context(), (m_211e_adconfig & 0x60) >> 5);
+ return m_xiof_in[(m_211e_adconfig & 0x60) >> 5]();
+}
+
+void vrt_vt1682_io_device::vt1682_211e_adconfig_w(uint8_t data)
+{
+ LOGMASKED(LOG_IO, "%s: vt1682_211e_adconfig_w writing: %02x ( ADCEN:%d | ADCSEL:%d | IOF_OE:%1x )\n", machine().describe_context(), data,
+ (data & 0x80) ? 1 : 0,
+ (data & 0x60) >> 5,
+ (data & 0x0f));
+ if (((data ^ m_211e_adconfig) & 0x0f) != 0)
+ m_portf_out(0, (m_io_ef_o >> 4 | ~data) & 0x0f, 0x0f);
+ m_211e_adconfig = data;
+}
+
+/*
+ Address 0x214c r/w (MAIN CPU)
+
+ 0x80 - (unused)
+ 0x40 - (unused)
+ 0x20 - Keychange Enable
+ 0x10 - Keychange Enable
+ 0x08 - IOFEN
+ 0x04 - (unused)
+ 0x02 - (unused)
+ 0x01 - IOEOEN
+*/
+
+uint8_t vrt_vt1682_io_device::vt1682_214c_ioefconfig_r()
+{
+ return m_214c_ioefconfig;
+}
+
+void vrt_vt1682_io_device::vt1682_214c_ioefconfig_w(uint8_t data)
+{
+ LOGMASKED(LOG_IO, "%s: vt1682_214c_ioefconfig_w writing: %02x ( IOF_ENB:%1x | IOE_OE:%1x )\n", machine().describe_context(), data,
+ (data & 0x08) ? 1 : 0,
+ (data & 0x01) ? 1 : 0);
+ m_214c_ioefconfig = data;
+}
+
+/*
+ Address 0x214d r/w (MAIN CPU)
+
+ 0x80 - IOF:3
+ 0x40 - IOF:2
+ 0x20 - IOF:1
+ 0x10 - IOF:0
+ 0x08 - IOE:3
+ 0x04 - IOE:2
+ 0x02 - IOE:1
+ 0x01 - IOE:0
+*/
+
+uint8_t vrt_vt1682_io_device::vt1682_214d_io_ef_r()
+{
+ uint8_t ioe_imask = (BIT(m_214c_ioefconfig, 0) ? 0 : 0x07) | (BIT(m_211e_adconfig, 4) ? 0 : 0x08);
+ uint8_t ret = m_io_ef_o & ((~ioe_imask & 0x0f) | ((m_211e_adconfig & 0x0f) << 4));
+ if (ioe_imask != 0)
+ ret |= m_porte_in(0, ioe_imask) & ioe_imask;
+ if ((m_211e_adconfig & 0x0f) != 0x0f)
+ ret |= (m_portf_in(0, ~m_211e_adconfig & 0x0f) & ~m_211e_adconfig & 0x0f) << 4;
+ return ret;
+}
+
+void vrt_vt1682_io_device::vt1682_214d_io_ef_w(uint8_t data)
+{
+ uint8_t ioe_omask = (BIT(m_214c_ioefconfig, 0) ? 0x07 : 0) | (BIT(m_211e_adconfig, 4) ? 0x08 : 0);
+ if (((m_io_ef_o ^ data) & ioe_omask) != 0)
+ {
+ LOGMASKED(LOG_IO, "%s: IOE_O = %1x & %1x\n", machine().describe_context(), data & ioe_omask, ioe_omask);
+ m_porte_out(0, data & ioe_omask, ioe_omask);
+ }
+ if ((((m_io_ef_o ^ data) >> 4) & (m_211e_adconfig & 0x0f)) != 0)
+ {
+ LOGMASKED(LOG_IO, "%s: IOF_O = %1x & %1x\n", machine().describe_context(), (data >> 4) & m_211e_adconfig & 0x0f, m_211e_adconfig & 0x0f);
+ m_portf_out(0, (data >> 4 | ~m_211e_adconfig) & 0x0f, 0x0f);
+ }
+
+ m_io_ef_o = data;
}
diff --git a/src/mame/nintendo/vt1682_io.h b/src/mame/nintendo/vt1682_io.h
index b68036c19db..547bd652616 100644
--- a/src/mame/nintendo/vt1682_io.h
+++ b/src/mame/nintendo/vt1682_io.h
@@ -18,38 +18,58 @@ public:
auto portb_out() { return m_portb_out.bind(); }
auto portc_out() { return m_portc_out.bind(); }
auto portd_out() { return m_portd_out.bind(); }
+ auto porte_out() { return m_porte_out.bind(); }
+ auto portf_out() { return m_portf_out.bind(); }
auto porta_in() { return m_porta_in.bind(); }
auto portb_in() { return m_portb_in.bind(); }
auto portc_in() { return m_portc_in.bind(); }
auto portd_in() { return m_portd_in.bind(); }
-
+ auto porte_in() { return m_porte_in.bind(); }
+ auto portf_in() { return m_portf_in.bind(); }
+ template <int N> auto xiof_in() { return m_xiof_in[N].bind(); }
uint8_t vt1682_210e_io_ab_r();
uint8_t vt1682_210f_io_cd_r();
+ uint8_t vt1682_214d_io_ef_r();
void vt1682_210e_io_ab_w(uint8_t data);
void vt1682_210f_io_cd_w(uint8_t data);
+ void vt1682_214d_io_ef_w(uint8_t data);
uint8_t vt1682_210d_ioconfig_r();
void vt1682_210d_ioconfig_w(uint8_t data);
-
+ uint8_t vt1682_211e_adc_data_r();
+ void vt1682_211e_adconfig_w(uint8_t data);
+ uint8_t vt1682_214c_ioefconfig_r();
+ void vt1682_214c_ioefconfig_w(uint8_t data);
protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
private:
+ uint8_t m_io_ab_o;
+ uint8_t m_io_cd_o;
+ uint8_t m_io_ef_o;
+
uint8_t m_210d_ioconfig;
+ uint8_t m_211e_adconfig;
+ uint8_t m_214c_ioefconfig;
// actually 4-bit ports
devcb_write8 m_porta_out;
devcb_write8 m_portb_out;
devcb_write8 m_portc_out;
devcb_write8 m_portd_out;
+ devcb_write8 m_porte_out;
+ devcb_write8 m_portf_out;
devcb_read8 m_porta_in;
devcb_read8 m_portb_in;
devcb_read8 m_portc_in;
devcb_read8 m_portd_in;
+ devcb_read8 m_porte_in;
+ devcb_read8 m_portf_in;
+ devcb_read8::array<4> m_xiof_in;
};
#endif // MAME_NINTENDO_VT1682_IO_H