summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/spg2xx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/spg2xx.cpp')
-rw-r--r--src/devices/machine/spg2xx.cpp159
1 files changed, 84 insertions, 75 deletions
diff --git a/src/devices/machine/spg2xx.cpp b/src/devices/machine/spg2xx.cpp
index 5acaa464456..cf5988f995f 100644
--- a/src/devices/machine/spg2xx.cpp
+++ b/src/devices/machine/spg2xx.cpp
@@ -14,41 +14,55 @@
#include "emu.h"
#include "spg2xx.h"
-DEFINE_DEVICE_TYPE(SPG24X, spg24x_device, "spg24x", "SPG240-series System-on-a-Chip")
-DEFINE_DEVICE_TYPE(SPG28X, spg28x_device, "spg28x", "SPG280-series System-on-a-Chip")
+DEFINE_DEVICE_TYPE(SPG24X, spg24x_device, "spg24x", "SPG240-series System-on-a-Chip") // 256 sprites
+DEFINE_DEVICE_TYPE(SPG2XX_128, spg2xx_128_device, "spg2xx_128", "SPG2xx-series System-on-a-Chip (128 sprites)") // exact SPG part number unknown
+DEFINE_DEVICE_TYPE(SPG28X, spg28x_device, "spg28x", "SPG280-series System-on-a-Chip") // 64 sprites
-spg2xx_device::spg2xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint16_t sprite_limit, address_map_constructor internal)
- : unsp_device(mconfig, type, tag, owner, clock, internal)
- , device_mixer_interface(mconfig, *this, 2)
- , m_spg_audio(*this, "spgaudio")
- , m_spg_io(*this, "spgio")
- , m_spg_sysdma(*this, "spgsysdma")
- , m_spg_video(*this, "spgvideo")
- , m_sprite_limit(sprite_limit)
- , m_rowscrolloffset(15)
- , m_porta_out(*this)
- , m_portb_out(*this)
- , m_portc_out(*this)
- , m_porta_in(*this)
- , m_portb_in(*this)
- , m_portc_in(*this)
- , m_adc_in{{*this}, {*this}}
- , m_eeprom_w(*this)
- , m_eeprom_r(*this)
- , m_uart_tx(*this)
- , m_chip_sel(*this)
- , m_screen(*this, finder_base::DUMMY_TAG)
+spg2xx_device::spg2xx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint16_t sprite_limit, address_map_constructor internal) :
+ unsp_device(mconfig, type, tag, owner, clock, internal),
+ device_mixer_interface(mconfig, *this),
+ m_spg_audio(*this, "spgaudio"),
+ m_spg_io(*this, "spgio"),
+ m_spg_sysdma(*this, "spgsysdma"),
+ m_spg_video(*this, "spgvideo"),
+ m_sprite_limit(sprite_limit),
+ m_porta_out(*this),
+ m_portb_out(*this),
+ m_portc_out(*this),
+ m_porta_in(*this, 0),
+ m_portb_in(*this, 0),
+ m_portc_in(*this, 0),
+ m_adc_in(*this, 0x0fff),
+ m_guny_in(*this, 0),
+ m_gunx_in(*this, 0),
+ m_i2c_w(*this),
+ m_i2c_r(*this, 0),
+ m_uart_tx(*this),
+ m_spi_tx(*this),
+ m_chip_sel(*this),
+ m_screen(*this, finder_base::DUMMY_TAG)
{
}
-spg24x_device::spg24x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : spg2xx_device(mconfig, SPG24X, tag, owner, clock, 256, address_map_constructor(FUNC(spg24x_device::internal_map), this))
+spg24x_device::spg24x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ spg2xx_device(mconfig, SPG24X, tag, owner, clock, 256, address_map_constructor(FUNC(spg24x_device::internal_map), this))
{
}
-spg28x_device::spg28x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : spg2xx_device(mconfig, SPG28X, tag, owner, clock, 64, address_map_constructor(FUNC(spg28x_device::internal_map), this))
+spg24x_device::spg24x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint16_t sprite_limit, address_map_constructor internal) :
+ spg2xx_device(mconfig, type, tag, owner, clock, sprite_limit, internal)
+{
+}
+
+
+spg2xx_128_device::spg2xx_128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ spg24x_device(mconfig, SPG2XX_128, tag, owner, clock, 128, address_map_constructor(FUNC(spg2xx_128_device::internal_map), this))
+{
+}
+
+spg28x_device::spg28x_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ spg24x_device(mconfig, SPG28X, tag, owner, clock, 64, address_map_constructor(FUNC(spg28x_device::internal_map), this))
{
}
@@ -56,7 +70,8 @@ void spg2xx_device::internal_map(address_map &map)
{
map(0x000000, 0x0027ff).ram();
map(0x002800, 0x0028ff).rw(m_spg_video, FUNC(spg2xx_video_device::video_r), FUNC(spg2xx_video_device::video_w));
- map(0x002900, 0x002aff).ram().share("spgvideo:scrollram");
+ map(0x002900, 0x0029ff).ram().share("spgvideo:scrollram");
+ map(0x002a00, 0x002aff).ram().share("spgvideo:hcompram"); // not all models?
map(0x002b00, 0x002bff).ram().share("spgvideo:paletteram");
map(0x002c00, 0x002fff).ram().share("spgvideo:spriteram");
map(0x003000, 0x0031ff).rw(m_spg_audio, FUNC(spg2xx_audio_device::audio_r), FUNC(spg2xx_audio_device::audio_w));
@@ -71,66 +86,72 @@ void spg2xx_device::device_start()
{
unsp_device::device_start();
- m_porta_out.resolve_safe();
- m_portb_out.resolve_safe();
- m_portc_out.resolve_safe();
- m_porta_in.resolve_safe(0);
- m_portb_in.resolve_safe(0);
- m_portc_in.resolve_safe(0);
- m_adc_in[0].resolve_safe(0x0fff);
- m_adc_in[1].resolve_safe(0x0fff);
- m_eeprom_w.resolve_safe();
- m_eeprom_r.resolve_safe(0);
- m_uart_tx.resolve_safe();
- m_chip_sel.resolve_safe();
-
save_item(NAME(m_sprite_limit));
save_item(NAME(m_pal_flag));
+ save_item(NAME(m_fiq_vector));
}
void spg2xx_device::device_reset()
{
unsp_device::device_reset();
+ m_fiq_vector = 0xff;
+}
+
+void spg2xx_device::fiq_vector_w(uint8_t data)
+{
+ m_fiq_vector = data;
}
-WRITE_LINE_MEMBER(spg2xx_device::videoirq_w)
+void spg2xx_device::videoirq_w(int state)
{
- set_state_unsynced(UNSP_IRQ0_LINE, state);
+ if (m_fiq_vector == 0)
+ {
+ set_state_unsynced(UNSP_FIQ_LINE, state);
+ }
+ else
+ {
+ set_state_unsynced(UNSP_IRQ0_LINE, state);
+ }
}
-WRITE_LINE_MEMBER(spg2xx_device::timerirq_w)
+void spg2xx_device::timerirq_w(int state)
{
set_state_unsynced(UNSP_IRQ2_LINE, state);
}
-WRITE_LINE_MEMBER(spg2xx_device::uartirq_w)
+void spg2xx_device::uartirq_w(int state)
{
set_state_unsynced(UNSP_IRQ3_LINE, state);
}
-WRITE_LINE_MEMBER(spg2xx_device::audioirq_w)
+void spg2xx_device::audioirq_w(int state)
{
set_state_unsynced(UNSP_IRQ4_LINE, state);
}
-WRITE_LINE_MEMBER(spg2xx_device::extirq_w)
+void spg2xx_device::audiochirq_w(int state)
+{
+ set_state_unsynced(UNSP_FIQ_LINE, state);
+}
+
+void spg2xx_device::extirq_w(int state)
{
set_state_unsynced(UNSP_IRQ5_LINE, state);
}
-WRITE_LINE_MEMBER(spg2xx_device::ffreq1_w)
+void spg2xx_device::ffreq1_w(int state)
{
set_state_unsynced(UNSP_IRQ6_LINE, state);
}
-WRITE_LINE_MEMBER(spg2xx_device::ffreq2_w)
+void spg2xx_device::ffreq2_w(int state)
{
set_state_unsynced(UNSP_IRQ7_LINE, state);
}
-READ16_MEMBER(spg2xx_device::space_r)
+uint16_t spg2xx_device::space_r(offs_t offset)
{
address_space &cpuspace = this->space(AS_PROGRAM);
return cpuspace.read_word(offset);
@@ -146,9 +167,12 @@ void spg2xx_device::configure_spg_io(spg2xx_io_device* io)
io->portc_out().set(FUNC(spg2xx_device::portc_w));
io->adc_in<0>().set(FUNC(spg2xx_device::adc_r<0>));
io->adc_in<1>().set(FUNC(spg2xx_device::adc_r<1>));
- io->eeprom_w().set(FUNC(spg2xx_device::eepromx_w));
- io->eeprom_r().set(FUNC(spg2xx_device::eepromx_r));
- io->uart_tx().set(FUNC(spg2xx_device::tx_w));
+ io->adc_in<2>().set(FUNC(spg2xx_device::adc_r<2>));
+ io->adc_in<3>().set(FUNC(spg2xx_device::adc_r<3>));
+ io->i2c_w().set(FUNC(spg2xx_device::eepromx_w));
+ io->i2c_r().set(FUNC(spg2xx_device::eepromx_r));
+ io->uart_tx().set(FUNC(spg2xx_device::uart_tx_w));
+ io->spi_tx().set(FUNC(spg2xx_device::spi_tx_w));
io->chip_select().set(FUNC(spg2xx_device::cs_w));
io->pal_read_callback().set(FUNC(spg2xx_device::get_pal_ntsc));
io->write_timer_irq_callback().set(FUNC(spg2xx_device::timerirq_w));
@@ -156,44 +180,29 @@ void spg2xx_device::configure_spg_io(spg2xx_io_device* io)
io->write_external_irq_callback().set(FUNC(spg2xx_device::extirq_w));
io->write_ffrq_tmr1_irq_callback().set(FUNC(spg2xx_device::ffreq1_w));
io->write_ffrq_tmr2_irq_callback().set(FUNC(spg2xx_device::ffreq2_w));
+ io->write_fiq_vector_callback().set(FUNC(spg2xx_device::fiq_vector_w));
+
+ m_spg_video->guny_in().set(FUNC(spg2xx_device::guny_in_r));
+ m_spg_video->gunx_in().set(FUNC(spg2xx_device::gunx_in_r));
}
void spg24x_device::device_add_mconfig(machine_config &config)
{
SPG2XX_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
m_spg_audio->write_irq_callback().set(FUNC(spg24x_device::audioirq_w));
+ m_spg_audio->channel_irq_callback().set(FUNC(spg24x_device::audiochirq_w));
m_spg_audio->space_read_callback().set(FUNC(spg24x_device::space_r));
- m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
- m_spg_audio->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1);
+ m_spg_audio->add_route(0, *this, 1.0, 0);
+ m_spg_audio->add_route(1, *this, 1.0, 1);
SPG24X_IO(config, m_spg_io, DERIVED_CLOCK(1, 1), DEVICE_SELF, m_screen);
- configure_spg_io(m_spg_io);
SPG2XX_SYSDMA(config, m_spg_sysdma, DERIVED_CLOCK(1, 1), DEVICE_SELF);
SPG24X_VIDEO(config, m_spg_video, DERIVED_CLOCK(1, 1), DEVICE_SELF, m_screen);
m_spg_video->sprlimit_read_callback().set(FUNC(spg24x_device::get_sprlimit));
- m_spg_video->rowscrolloffset_read_callback().set(FUNC(spg24x_device::get_rowscrolloffset));
m_spg_video->write_video_irq_callback().set(FUNC(spg24x_device::videoirq_w));
-}
-
-void spg28x_device::device_add_mconfig(machine_config &config)
-{
- SPG2XX_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1));
- m_spg_audio->write_irq_callback().set(FUNC(spg28x_device::audioirq_w));
- m_spg_audio->space_read_callback().set(FUNC(spg28x_device::space_r));
-
- m_spg_audio->add_route(0, *this, 1.0, AUTO_ALLOC_INPUT, 0);
- m_spg_audio->add_route(1, *this, 1.0, AUTO_ALLOC_INPUT, 1);
- SPG28X_IO(config, m_spg_io, DERIVED_CLOCK(1, 1), DEVICE_SELF, m_screen);
configure_spg_io(m_spg_io);
-
- SPG2XX_SYSDMA(config, m_spg_sysdma, DERIVED_CLOCK(1, 1), DEVICE_SELF);
-
- SPG24X_VIDEO(config, m_spg_video, DERIVED_CLOCK(1, 1), DEVICE_SELF, m_screen);
- m_spg_video->sprlimit_read_callback().set(FUNC(spg28x_device::get_sprlimit));
- m_spg_video->rowscrolloffset_read_callback().set(FUNC(spg28x_device::get_rowscrolloffset));
- m_spg_video->write_video_irq_callback().set(FUNC(spg28x_device::videoirq_w));
}