From d3b6eab1505bfe841d832c4de61e771c31e48e34 Mon Sep 17 00:00:00 2001 From: Ryan Holtz Date: Thu, 11 Jun 2020 05:45:47 +0200 Subject: -spg2xx: Revised ADC behavior. Does not currently work properly. Checking in so that others can debug. nw --- src/devices/machine/spg2xx.h | 2 +- src/devices/machine/spg2xx_io.cpp | 119 +++++++++++++++++++++++++++++----- src/devices/machine/spg2xx_io.h | 14 +++- src/mame/drivers/spg2xx_jakks_gkr.cpp | 30 +++++++-- 4 files changed, 140 insertions(+), 25 deletions(-) diff --git a/src/devices/machine/spg2xx.h b/src/devices/machine/spg2xx.h index 95f6f999269..0eb2a29f82a 100644 --- a/src/devices/machine/spg2xx.h +++ b/src/devices/machine/spg2xx.h @@ -110,7 +110,7 @@ protected: devcb_read16 m_portb_in; devcb_read16 m_portc_in; - devcb_read16::array<2> m_adc_in; + devcb_read16::array<4> m_adc_in; devcb_read16 m_guny_in; devcb_read16 m_gunx_in; diff --git a/src/devices/machine/spg2xx_io.cpp b/src/devices/machine/spg2xx_io.cpp index 8505bb5bd99..f795590c688 100644 --- a/src/devices/machine/spg2xx_io.cpp +++ b/src/devices/machine/spg2xx_io.cpp @@ -27,10 +27,11 @@ DEFINE_DEVICE_TYPE(SPG28X_IO, spg28x_io_device, "spg28x_io", "SPG280-series Syst #define LOG_EXT_MEM (1U << 27) #define LOG_EXTINT (1U << 28) #define LOG_SPI (1U << 29) -#define LOG_IO (LOG_IO_READS | LOG_IO_WRITES | LOG_IRQS | LOG_GPIO | LOG_UART | LOG_I2C | LOG_TIMERS | LOG_EXTINT | LOG_UNKNOWN_IO | LOG_SPI) -#define LOG_ALL (LOG_IO | LOG_VLINES | LOG_SEGMENT | LOG_WATCHDOG | LOG_FIQ | LOG_SIO | LOG_EXT_MEM) +#define LOG_ADC (1U << 30) +#define LOG_IO (LOG_IO_READS | LOG_IO_WRITES | LOG_IRQS | LOG_GPIO | LOG_UART | LOG_I2C | LOG_TIMERS | LOG_EXTINT | LOG_UNKNOWN_IO | LOG_SPI | LOG_ADC) +#define LOG_ALL (LOG_IO | LOG_VLINES | LOG_SEGMENT | LOG_WATCHDOG | LOG_FIQ | LOG_SIO | LOG_EXT_MEM | LOG_ADC) -#define VERBOSE (0) +#define VERBOSE (LOG_ADC) #include "logmacro.h" @@ -127,6 +128,12 @@ void spg2xx_io_device::device_start() m_spi_tx_timer = timer_alloc(TIMER_SPI_TX); m_spi_tx_timer->adjust(attotime::never); + for (int i = 0; i < 4; i++) + { + m_adc_timer[i] = timer_alloc(TIMER_ADC0 + i); + m_adc_timer[i]->adjust(attotime::never); + } + save_item(NAME(m_io_regs)); save_item(NAME(m_uart_rx_fifo)); @@ -213,6 +220,20 @@ void spg2xx_io_device::device_reset() m_rng_timer->adjust(attotime::from_hz(1234), 0, attotime::from_hz(1234)); // timer value is arbitrary, maybe should match system clock, but that would result in heavy switching + m_tmb1->adjust(attotime::never); + m_tmb2->adjust(attotime::never); + m_uart_tx_timer->adjust(attotime::never); + m_uart_rx_timer->adjust(attotime::never); + m_timer_src_ab->adjust(attotime::never); + m_timer_src_c->adjust(attotime::never); + m_watchdog_timer->adjust(attotime::never); + m_spi_tx_timer->adjust(attotime::never); + + for (int i = 0; i < 4; i++) + { + m_adc_timer[i]->adjust(attotime::never); + } + m_2khz_divider = 0; m_1khz_divider = 0; m_4hz_divider = 0; @@ -426,7 +447,11 @@ READ16_MEMBER(spg2xx_io_device::io_r) break; case REG_ADC_CTRL: - LOGMASKED(LOG_IO_READS, "%s: io_r: ADC Control = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_IO_READS | LOG_ADC, "%s: io_r: ADC Control = %04x\n", machine().describe_context(), val); + break; + + case REG_ADC_PAD: + LOGMASKED(LOG_IO_READS | LOG_ADC, "%s: io_r: ADC Pad Control = %04x\n", machine().describe_context(), val); break; case REG_ADC_DATA: @@ -437,7 +462,7 @@ READ16_MEMBER(spg2xx_io_device::io_r) const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE); if (changed) check_irqs(changed); - LOGMASKED(LOG_IO_READS, "%s: io_r: ADC Data = %04x\n", machine().describe_context(), val); + LOGMASKED(LOG_IO_READS | LOG_ADC, "%s: io_r: ADC Data = %04x\n", machine().describe_context(), val); break; } @@ -1059,26 +1084,61 @@ WRITE16_MEMBER(spg2xx_io_device::io_w) case REG_ADC_CTRL: { - LOGMASKED(LOG_IO_WRITES, "%s: io_w: ADC Control = %04x\n", machine().describe_context(), data); - m_io_regs[REG_ADC_CTRL] = data & ~0x1000; - if (BIT(data, 0)) + LOGMASKED(LOG_IO_WRITES | LOG_ADC, "%s: io_w: ADC Control = %04x\n", machine().describe_context(), data); + + const uint16_t old_ctrl = m_io_regs[REG_ADC_CTRL]; + m_io_regs[REG_ADC_CTRL] = data & ~0x2000; + + const uint16_t channel = (m_io_regs[REG_ADC_CTRL] >> 4) & 3; + if (BIT(m_io_regs[REG_ADC_CTRL], 0)) { - m_io_regs[REG_ADC_DATA] = 0x8000 | (m_adc_in[BIT(data, 5)]() & 0x7fff); - m_io_regs[REG_ADC_CTRL] |= 0x2000; + if (!BIT(old_ctrl, 0)) + { + m_io_regs[REG_ADC_CTRL] |= 0x2000; + if (BIT(m_io_regs[REG_ADC_CTRL], 9)) + { + const uint16_t old = IO_IRQ_STATUS; + IO_IRQ_STATUS |= 0x2000; + const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE); + if (changed) + check_irqs(changed); + } + } + else if (!BIT(old_ctrl, 12) && BIT(m_io_regs[REG_ADC_CTRL], 12)) + { + m_io_regs[REG_ADC_CTRL] &= ~0x3000; + const uint32_t adc_clocks = 16 << ((m_io_regs[REG_ADC_CTRL] >> 2) & 3); + m_adc_timer[channel]->adjust(attotime::from_ticks(adc_clocks, 27000000)); + } + + // Req_Auto_8K + if (BIT(data, 10)) + { + m_adc_timer[channel]->adjust(attotime::from_hz(8000), 0, attotime::from_hz(8000)); + } } - if (BIT(data, 12) && !BIT(m_io_regs[REG_ADC_CTRL], 1)) + else { - const uint16_t old = IO_IRQ_STATUS; - IO_IRQ_STATUS |= 0x2000; - const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE); - if (changed) + for (int i = 0; i < 4; i++) { - check_irqs(changed); + m_adc_timer[i]->adjust(attotime::never); } } break; } + case REG_ADC_PAD: + LOGMASKED(LOG_IO_WRITES | LOG_ADC, "%s: io_w: ADC Pad Control = %04x\n", machine().describe_context(), data); + m_io_regs[REG_ADC_PAD] = data; + for (int i = 0; i < 4; i++) + { + if (!BIT(data, i)) + { + m_adc_timer[i]->adjust(attotime::never); + } + } + break; + case REG_SLEEP_MODE: LOGMASKED(LOG_IO_WRITES, "%s: io_w: Sleep Mode (%s enter value) = %04x\n", machine().describe_context(), data == 0xaa55 ? "valid" : "invalid", data); m_io_regs[REG_SLEEP_MODE] = data; @@ -1475,6 +1535,13 @@ void spg2xx_io_device::device_timer(emu_timer &timer, device_timer_id id, int pa case TIMER_SPI_TX: do_spi_tx(); break; + + case TIMER_ADC0: + case TIMER_ADC1: + case TIMER_ADC2: + case TIMER_ADC3: + do_adc_capture(id - TIMER_ADC0); + break; } } @@ -1676,6 +1743,26 @@ void spg2xx_io_device::do_gpio(uint32_t offset, bool write) m_io_regs[5 * index + 1] = what; } +void spg2xx_io_device::do_adc_capture(int channel) +{ + m_io_regs[REG_ADC_DATA] = m_adc_in[channel]() & 0x0fff; + if (BIT(m_io_regs[REG_ADC_DATA], 11)) + { + //m_io_regs[REG_ADC_DATA] |= 0xf000; + } + m_io_regs[REG_ADC_CTRL] |= 0x2000; + const uint16_t old = IO_IRQ_STATUS; + if (BIT(m_io_regs[REG_ADC_CTRL], 9)) + { + IO_IRQ_STATUS |= 0x2000; + const uint16_t changed = (old & IO_IRQ_ENABLE) ^ (IO_IRQ_STATUS & IO_IRQ_ENABLE); + if (changed) + { + check_irqs(changed); + } + } +} + void spg2xx_io_device::do_i2c() { const uint16_t addr = ((m_io_regs[REG_I2C_ADDR] & 0x06) << 7) | (uint8_t)m_io_regs[REG_I2C_SUBADDR]; diff --git a/src/devices/machine/spg2xx_io.h b/src/devices/machine/spg2xx_io.h index 5ccf28e91a3..0142cdb827b 100644 --- a/src/devices/machine/spg2xx_io.h +++ b/src/devices/machine/spg2xx_io.h @@ -21,7 +21,7 @@ public: auto portb_in() { return m_portb_in.bind(); } auto portc_in() { return m_portc_in.bind(); } - template auto adc_in() { return m_adc_in[Line].bind(); } + template auto adc_in() { printf("Binding %d\n", (int)Line); return m_adc_in[Line].bind(); } auto i2c_w() { return m_i2c_w.bind(); } auto i2c_r() { return m_i2c_r.bind(); } @@ -95,7 +95,8 @@ protected: REG_EXT_MEMORY_CTRL, REG_WATCHDOG_CLEAR, REG_ADC_CTRL, - REG_ADC_DATA = 0x27, + REG_ADC_PAD, + REG_ADC_DATA, REG_SLEEP_MODE, REG_WAKEUP_SOURCE, @@ -158,6 +159,10 @@ protected: static const device_timer_id TIMER_RNG = 9; static const device_timer_id TIMER_WATCHDOG = 10; static const device_timer_id TIMER_SPI_TX = 11; + static const device_timer_id TIMER_ADC0 = 12; + static const device_timer_id TIMER_ADC1 = 13; + static const device_timer_id TIMER_ADC2 = 14; + static const device_timer_id TIMER_ADC3 = 15; virtual void device_start() override; virtual void device_reset() override; @@ -186,6 +191,8 @@ protected: void do_i2c(); + void do_adc_capture(int channel); + uint16_t m_io_regs[0x100]; uint8_t m_uart_rx_fifo[8]; @@ -219,7 +226,8 @@ protected: devcb_read16 m_portb_in; devcb_read16 m_portc_in; - devcb_read16::array<2> m_adc_in; + devcb_read16::array<4> m_adc_in; + emu_timer *m_adc_timer[4]; devcb_write8 m_i2c_w; devcb_read8 m_i2c_r; diff --git a/src/mame/drivers/spg2xx_jakks_gkr.cpp b/src/mame/drivers/spg2xx_jakks_gkr.cpp index 1e20a3ec42c..88259518a20 100644 --- a/src/mame/drivers/spg2xx_jakks_gkr.cpp +++ b/src/mame/drivers/spg2xx_jakks_gkr.cpp @@ -16,7 +16,9 @@ public: spg2xx_game_state(mconfig, type, tag), m_porta_key_mode(false), m_cart(*this, "cartslot"), - m_cart_region(nullptr) + m_cart_region(nullptr), + m_analog_x(*this, "JOYX"), + m_analog_y(*this, "JOYY") { } void jakks_gkr(machine_config &config); @@ -46,6 +48,9 @@ protected: private: virtual void machine_start() override; + uint16_t joy_x_read(); + uint16_t joy_y_read(); + uint16_t jakks_porta_key_io_r(); void gkr_portc_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); @@ -56,6 +61,9 @@ private: optional_device m_cart; memory_region *m_cart_region; + + optional_ioport m_analog_x; + optional_ioport m_analog_y; }; READ_LINE_MEMBER(jakks_gkr_state::i2c_gkr_r) @@ -104,6 +112,18 @@ void jakks_gkr_state::jakks_portb_w(uint16_t data) //logerror("%s: jakks_portb_w %04x\n", machine().describe_context(), data); } +uint16_t jakks_gkr_state::joy_x_read() +{ + const uint16_t data = m_analog_x->read(); + return data > 0x0fff ? 0x0fff : data; +} + +uint16_t jakks_gkr_state::joy_y_read() +{ + const uint16_t data = m_analog_y->read(); + return data > 0x0fff ? 0x0fff : data; +} + uint16_t jakks_gkr_state::jakks_porta_key_io_r() { //logerror("%s: jakks_porta_key_io_r\n", machine().describe_context()); @@ -148,10 +168,10 @@ static INPUT_PORTS_START( jak_sith_i2c ) PORT_BIT( 0xfff6, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("JOYX") - PORT_BIT(0x0fff, 0x0000, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_MINMAX(0x00,0x0fff) + PORT_BIT(0x1fff, 0x0800, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_MINMAX(0x0000,0x1fff) PORT_START("JOYY") - PORT_BIT(0x0fff, 0x0000, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_MINMAX(0x00,0x0fff) + PORT_BIT(0x1fff, 0x0800, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_MINMAX(0x0000,0x1fff) INPUT_PORTS_END static INPUT_PORTS_START( jak_pooh ) @@ -510,8 +530,8 @@ void jakks_gkr_state::jakks_gkr_sw_i2c(machine_config &config) { jakks_gkr_i2c(config); m_maincpu->set_addrmap(AS_PROGRAM, &jakks_gkr_state::mem_map_1m); - m_maincpu->adc_in<0>().set_ioport("JOYX"); - m_maincpu->adc_in<1>().set_ioport("JOYY"); + m_maincpu->adc_in<0>().set(FUNC(jakks_gkr_state::joy_x_read)); + m_maincpu->adc_in<2>().set(FUNC(jakks_gkr_state::joy_y_read)); SOFTWARE_LIST(config, "jakks_gamekey_sw").set_original("jakks_gamekey_sw"); } -- cgit v1.2.3