summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/sunplus_gcm394.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/sunplus_gcm394.cpp')
-rw-r--r--src/devices/machine/sunplus_gcm394.cpp126
1 files changed, 92 insertions, 34 deletions
diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp
index 44b17fdfc92..44fee3c6f78 100644
--- a/src/devices/machine/sunplus_gcm394.cpp
+++ b/src/devices/machine/sunplus_gcm394.cpp
@@ -136,8 +136,19 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7803_w) { LOGMASKED(LOG_GCM39
WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7807_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7807_w %04x\n", machine().describe_context(), data); m_7807 = data; }
-READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7810_r\n", machine().describe_context()); return m_7810; }
-WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7810_w %04x\n", machine().describe_context(), data); m_7810 = data; }
+
+// this gets stored / modified / restored before certain memory accesses (in practical terms it just seems to flip from 0/1) maybe it changes the memory mapping (as 7820 seems to)
+READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_r)
+{
+ LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7810_r\n", machine().describe_context());
+ return m_7810;
+}
+
+WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7810_w)
+{
+ printf( "%s:sunplus_gcm394_base_device::unkarea_7810_w %04x\n", machine().describe_context().c_str(), data);
+ m_7810 = data;
+}
WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7816_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7816_w %04x\n", machine().describe_context(), data); m_7816 = data; }
@@ -154,24 +165,25 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7821_w)
{
LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7821_w %04x\n", machine().describe_context(), data); m_7821 = data;
}
-
+// these seem to be related to the above but don't change after startup. maybe it's how different devices see memory?
WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7822_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7822_w %04x\n", machine().describe_context(), data); m_7822 = data; }
WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7823_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7823_w %04x\n", machine().describe_context(), data); m_7823 = data; }
WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7824_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7824_w %04x\n", machine().describe_context(), data); m_7824 = data; }
+
WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7835_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7835_w %04x\n", machine().describe_context(), data); m_7835 = data; }
// IO here?
-READ16_MEMBER(sunplus_gcm394_base_device::ioport_a_r)
+READ16_MEMBER(sunplus_gcm394_base_device::ioarea_7860_porta_r)
{
- LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioport_a_r\n", machine().describe_context());
+ LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioarea_7860_porta_r\n", machine().describe_context());
return m_porta_in();
}
-WRITE16_MEMBER(sunplus_gcm394_base_device::ioport_a_w)
+WRITE16_MEMBER(sunplus_gcm394_base_device::ioarea_7860_porta_w)
{
- LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioport_a_w %04x\n", machine().describe_context(), data);
+ LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioarea_7860_porta_w %04x\n", machine().describe_context(), data);
m_porta_out(data);
}
@@ -207,8 +219,17 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7863_w)
// similar read/write pattern to above, 2nd group?
-READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7870_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7870_r\n", machine().describe_context()); return m_portb_in(); }
-WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7870_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7870_w %04x\n", machine().describe_context(), data); m_7870 = data; }
+READ16_MEMBER(sunplus_gcm394_base_device::ioarea_7870_portb_r)
+{
+ LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioarea_7870_portb_r\n", machine().describe_context());
+ return m_portb_in();
+}
+
+WRITE16_MEMBER(sunplus_gcm394_base_device::ioarea_7870_portb_w)
+{
+ LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioarea_7870_portb_w %04x\n", machine().describe_context(), data);
+ m_7870 = data;
+}
READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7871_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7871_r\n", machine().describe_context()); return 0xffff;// m_7871;
}
@@ -317,44 +338,48 @@ void sunplus_gcm394_base_device::internal_map(address_map &map)
// note, tilemaps are at the same address offsets in video device as spg2xx (but unknown devices are extra)
- map(0x007000, 0x007007).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_regs_w));
- map(0x007008, 0x00700f).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_regs_w));
+ map(0x007000, 0x007007).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_regs_w)); // written with other unknown_video_device1 LSB/MSB regs below (roz layer or line layer?)
+ map(0x007008, 0x00700f).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_regs_w)); // written with other unknown_video_device2 LSB/MSB regs below (roz layer or line layer?)
map(0x007010, 0x007015).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap0_regs_r), FUNC(gcm394_base_video_device::tmap0_regs_w));
map(0x007016, 0x00701b).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_regs_r), FUNC(gcm394_base_video_device::tmap1_regs_w));
- map(0x007020, 0x007020).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_lsb_w)); // probably tilebase, written with other tmap0 regs
- map(0x007021, 0x007021).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_lsb_w)); // probably tilebase, written with other tmap1 regs
- map(0x007022, 0x007022).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid0_gfxbase_lsb_w)); // another tilebase? maybe sprites? written as 7022, 702d and 7042 group
- map(0x007023, 0x007023).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_gfxbase_lsb_w)); // written with other unknown_video_device0 regs
- map(0x007024, 0x007024).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_gfxbase_lsb_w)); // written with other unknown_video_device1 regs
+ // tilebase LSBs
+ map(0x007020, 0x007020).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_lsb_w)); // tilebase, written with other tmap0 regs
+ map(0x007021, 0x007021).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_lsb_w)); // tilebase, written with other tmap1 regs
+ map(0x007022, 0x007022).w(m_spg_video, FUNC(gcm394_base_video_device::sprite_7022_gfxbase_lsb_w)); // sprite tilebase written as 7022, 702d and 7042 group
+ map(0x007023, 0x007023).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_gfxbase_lsb_w)); // written with other unknown_video_device1 regs (roz layer or line layer?)
+ map(0x007024, 0x007024).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_gfxbase_lsb_w)); // written with other unknown_video_device2 regs (roz layer or line layer?)
- map(0x00702a, 0x00702a).w(m_spg_video, FUNC(gcm394_base_video_device::video_702a_w));
+ map(0x00702a, 0x00702a).w(m_spg_video, FUNC(gcm394_base_video_device::video_702a_w)); // blend level control
- map(0x00702b, 0x00702b).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_msb_w)); // written with other tmap0 regs
- map(0x00702c, 0x00702c).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_msb_w)); // written with other tmap1 regs
- map(0x00702d, 0x00702d).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid0_gfxbase_msb_w)); // maybe sprites? written as 7022, 702d and 7042 group
- map(0x00702e, 0x00702e).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_gfxbase_msb_w)); // written with other unknown_video_device0 regs
- map(0x00702f, 0x00702f).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_gfxbase_msb_w)); // written with other unknown_video_device1 regs
+ // tilebase MSBs
+ map(0x00702b, 0x00702b).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_tilebase_msb_w)); // written with other tmap0 regs
+ map(0x00702c, 0x00702c).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_tilebase_msb_w)); // written with other tmap1 regs
+ map(0x00702d, 0x00702d).w(m_spg_video, FUNC(gcm394_base_video_device::sprite_702d_gfxbase_msb_w)); // sprites, written as 7022, 702d and 7042 group
+ map(0x00702e, 0x00702e).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid1_gfxbase_msb_w)); // written with other unknown_video_device1 regs (roz layer or line layer?)
+ map(0x00702f, 0x00702f).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid2_gfxbase_msb_w)); // written with other unknown_video_device2 regs (roz layer or line layer?)
map(0x007030, 0x007030).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7030_brightness_r), FUNC(gcm394_base_video_device::video_7030_brightness_w));
- map(0x00703a, 0x00703a).rw(m_spg_video, FUNC(gcm394_base_video_device::video_703a_r), FUNC(gcm394_base_video_device::video_703a_w));
- map(0x00703c, 0x00703c).w(m_spg_video, FUNC(gcm394_base_video_device::video_703c_w));
+ map(0x00703a, 0x00703a).rw(m_spg_video, FUNC(gcm394_base_video_device::video_703a_palettebank_r), FUNC(gcm394_base_video_device::video_703a_palettebank_w));
+ map(0x00703c, 0x00703c).w(m_spg_video, FUNC(gcm394_base_video_device::video_703c_w)); // TV Control 1
- map(0x007042, 0x007042).w(m_spg_video, FUNC(gcm394_base_video_device::unk_vid0_extra_w)); // maybe sprites? written as 7022, 702d and 7042 group
+ map(0x007042, 0x007042).rw(m_spg_video, FUNC(gcm394_base_video_device::sprite_7042_extra_r), FUNC(gcm394_base_video_device::sprite_7042_extra_w)); // maybe sprites, written as 7022, 702d and 7042 group
- map(0x007051, 0x007051).r(m_spg_video, FUNC(gcm394_base_video_device::video_7051_r)); // wrlshunt checks this
+ map(0x007051, 0x007051).r(m_spg_video, FUNC(gcm394_base_video_device::video_7051_r)); // wrlshunt checks this (doesn't exist on older SPG?)
map(0x007062, 0x007062).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7062_r), FUNC(gcm394_base_video_device::video_7062_w));
- map(0x007063, 0x007063).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7063_r), FUNC(gcm394_base_video_device::video_7063_w));
+ map(0x007063, 0x007063).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7063_videoirq_source_r), FUNC(gcm394_base_video_device::video_7063_videoirq_source_ack_w));
// note, 70 / 71 / 72 are the same offsets used for DMA as in spg2xx video device
map(0x007070, 0x007070).w(m_spg_video, FUNC(gcm394_base_video_device::video_dma_source_w)); // video dma, not system dma? (sets pointers to ram buffers)
map(0x007071, 0x007071).w(m_spg_video, FUNC(gcm394_base_video_device::video_dma_dest_w)); // sets pointers to 7300, 7400 ram areas below
- map(0x007072, 0x007072).rw(m_spg_video, FUNC(gcm394_base_video_device::video_dma_size_r), FUNC(gcm394_base_video_device::video_dma_size_w)); //
- map(0x00707e, 0x00707e).w(m_spg_video, FUNC(gcm394_base_video_device::video_dma_unk_w)); // written around same time as DMA, seems to select alt sprite bank
+ map(0x007072, 0x007072).rw(m_spg_video, FUNC(gcm394_base_video_device::video_dma_size_busy_r), FUNC(gcm394_base_video_device::video_dma_size_trigger_w)); //
+ // these don't exist on older SPG
map(0x00707c, 0x00707c).r(m_spg_video, FUNC(gcm394_base_video_device::video_707c_r)); // wrlshunt polls this waiting for 0x8000, is this some kind of manual port based data upload?
+
+ map(0x00707e, 0x00707e).w(m_spg_video, FUNC(gcm394_base_video_device::video_dma_unk_w)); // written around same time as DMA, seems to select alt sprite bank
map(0x00707f, 0x00707f).rw(m_spg_video, FUNC(gcm394_base_video_device::video_707f_r), FUNC(gcm394_base_video_device::video_707f_w));
// another set of registers for something?
@@ -377,7 +402,7 @@ void sunplus_gcm394_base_device::internal_map(address_map &map)
map(0x007300, 0x0073ff).rw(m_spg_video, FUNC(gcm394_base_video_device::palette_r), FUNC(gcm394_base_video_device::palette_w));
- map(0x007400, 0x0077ff).ram().share("spriteram");
+ map(0x007400, 0x0077ff).rw(m_spg_video, FUNC(gcm394_base_video_device::spriteram_r), FUNC(gcm394_base_video_device::spriteram_w));
// ######################################################################################################################################################################################
// 78xx region = io + other?
@@ -407,7 +432,7 @@ void sunplus_gcm394_base_device::internal_map(address_map &map)
map(0x007835, 0x007835).w(FUNC(sunplus_gcm394_base_device::unkarea_7835_w));
- map(0x007860, 0x007860).rw(FUNC(sunplus_gcm394_base_device::ioport_a_r), FUNC(sunplus_gcm394_base_device::ioport_a_w));
+ map(0x007860, 0x007860).rw(FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_r), FUNC(sunplus_gcm394_base_device::ioarea_7860_porta_w));
map(0x007861, 0x007861).r(FUNC(sunplus_gcm394_base_device::unkarea_7861_r));
map(0x007862, 0x007862).rw(FUNC(sunplus_gcm394_base_device::unkarea_7862_r), FUNC(sunplus_gcm394_base_device::unkarea_7862_w));
@@ -415,7 +440,7 @@ void sunplus_gcm394_base_device::internal_map(address_map &map)
map(0x007868, 0x007868).r(FUNC(sunplus_gcm394_base_device::unkarea_7868_r)); // on startup
- map(0x007870, 0x007870).rw(FUNC(sunplus_gcm394_base_device::unkarea_7870_r) ,FUNC(sunplus_gcm394_base_device::unkarea_7870_w));
+ map(0x007870, 0x007870).rw(FUNC(sunplus_gcm394_base_device::ioarea_7870_portb_r) ,FUNC(sunplus_gcm394_base_device::ioarea_7870_portb_w));
map(0x007871, 0x007871).r(FUNC(sunplus_gcm394_base_device::unkarea_7871_r));
map(0x007872, 0x007872).rw(FUNC(sunplus_gcm394_base_device::unkarea_7872_r), FUNC(sunplus_gcm394_base_device::unkarea_7872_w));
@@ -579,6 +604,9 @@ IRQ_CALLBACK_MEMBER(sunplus_gcm394_base_device::irq_vector_cb)
if (irqline == UNSP_IRQ6_LINE)
set_state_unsynced(UNSP_IRQ6_LINE, CLEAR_LINE);
+ if (irqline == UNSP_IRQ4_LINE)
+ set_state_unsynced(UNSP_IRQ4_LINE, CLEAR_LINE);
+
return 0;
}
@@ -593,6 +621,31 @@ void sunplus_gcm394_base_device::checkirq6()
*/
}
+/* the IRQ6 interrupt on Wrlshunt
+ reads 78a1, checks bit 0400
+ if it IS set, just increases value in RAM at 1a2e (no ack)
+ if it ISN'T set, then read/write 78b2 (ack something?) then increase value in RAM at 1a2e
+ (smartfp doesn't touch these addresses? but instead reads/writes 7935, alt ack?)
+
+ wrlshunt also has an IRQ4
+ it always reads/writes 78c0 before executing payload (ack?)
+ payload is a lot of manipulation of values in RAM, no registers touched
+
+ wrlshunt also has FIQ
+ no ack mechanism, for sound timer maybe (as it appears to be on spg110)
+
+
+ ----
+
+ IRQ5 is video IRQ
+ in both games writing 0x0001 to 7063 seems to be an ack mechanism
+ wrlshunt also checks bit 0x0040 of 7863 and will ack that too with alt code paths
+
+ 7863 is therefore some kind of 'video irq source' ?
+
+*/
+
+
void sunplus_gcm394_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
@@ -601,6 +654,8 @@ void sunplus_gcm394_base_device::device_timer(emu_timer &timer, device_timer_id
{
m_7935 |= 0x0100;
set_state_unsynced(UNSP_IRQ6_LINE, ASSERT_LINE);
+ //set_state_unsynced(UNSP_IRQ4_LINE, ASSERT_LINE);
+
// checkirq6();
break;
}
@@ -620,8 +675,11 @@ WRITE_LINE_MEMBER(sunplus_gcm394_base_device::videoirq_w)
uint16_t sunplus_gcm394_base_device::read_space(uint32_t offset)
{
- uint16_t b = m_gfxregion[(offset * 2) & (m_gfxregionsize - 1)] | (m_gfxregion[(offset * 2 + 1) & (m_gfxregionsize - 1)] << 8);
- return b;
+// uint16_t b = m_gfxregion[(offset * 2) & (m_gfxregionsize - 1)] | (m_gfxregion[(offset * 2 + 1) & (m_gfxregionsize - 1)] << 8);
+// return b;
+ address_space& mem = this->space(AS_PROGRAM);
+ uint16_t retdata = mem.read_word(offset);
+ return retdata;
}