diff options
Diffstat (limited to 'src/devices/machine/sunplus_gcm394.cpp')
-rw-r--r-- | src/devices/machine/sunplus_gcm394.cpp | 126 |
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; } |