diff options
| author | 2025-06-13 23:56:20 -0400 | |
|---|---|---|
| committer | 2025-06-13 23:58:33 -0400 | |
| commit | 63c9c7f475c36f828c65c0145a7423623d323cb0 (patch) | |
| tree | 869cab8975fc426d2cb5b9a209a2527b8f20ec92 | |
| parent | f3abbc8145f3d6850c9e8ab1e5d06c03a54de1bd (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.cpp | 78 | ||||
| -rw-r--r-- | src/mame/nintendo/vt1682_io.cpp | 181 | ||||
| -rw-r--r-- | src/mame/nintendo/vt1682_io.h | 24 |
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 |
