mirror of
https://github.com/holub/mame
synced 2025-06-05 04:16:28 +03:00
-spg2xx: Revised ADC behavior. Does not currently work properly. Checking in so that others can debug. nw
This commit is contained in:
parent
1496a22bc0
commit
d3b6eab150
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user