-spg2xx: Revised ADC behavior. Does not currently work properly. Checking in so that others can debug. nw

This commit is contained in:
Ryan Holtz 2020-06-11 05:45:47 +02:00
parent 1496a22bc0
commit d3b6eab150
4 changed files with 142 additions and 27 deletions

View File

@ -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;

View File

@ -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(data, 12) && !BIT(m_io_regs[REG_ADC_CTRL], 1))
{
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)
if (!BIT(old_ctrl, 0))
{
check_irqs(changed);
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));
}
}
else
{
for (int i = 0; i < 4; i++)
{
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];

View File

@ -21,7 +21,7 @@ public:
auto portb_in() { return m_portb_in.bind(); }
auto portc_in() { return m_portc_in.bind(); }
template <size_t Line> auto adc_in() { return m_adc_in[Line].bind(); }
template <size_t Line> 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;

View File

@ -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<jakks_gamekey_slot_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");
}