diff options
Diffstat (limited to 'src/devices/machine/sunplus_gcm394.cpp')
-rw-r--r-- | src/devices/machine/sunplus_gcm394.cpp | 96 |
1 files changed, 71 insertions, 25 deletions
diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index 367fb9da077..7016ccfdaa6 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -46,36 +46,52 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_w) WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) { uint16_t mode = m_dma_params[0]; - uint16_t sourcelow = m_dma_params[1]; - uint16_t dest = m_dma_params[2]; - uint16_t length = m_dma_params[3]; - uint16_t srchigh = m_dma_params[4]; + uint32_t source = m_dma_params[1] | (m_dma_params[4] << 16); + uint32_t dest = m_dma_params[2] | (m_dma_params[5] << 16) ; + uint32_t length = m_dma_params[3] | (m_dma_params[6] << 16); - LOGMASKED(LOG_GCM394_SYSDMA, "%s:possible DMA operation (7abf) (trigger %04x) with params mode:%04x source:%04x dest:%04x length:%04x srchigh:%04x unk:%04x unk:%04x\n", machine().describe_context(), data, mode, sourcelow, dest, length, srchigh, m_dma_params[5], m_dma_params[6]); + LOGMASKED(LOG_GCM394_SYSDMA, "%s:possible DMA operation (7abf) (trigger %04x) with params mode:%04x source:%08x (word offset) dest:%08x (word offset) length:%08x (words)\n", machine().describe_context(), data, mode, source, dest, length ); - uint32_t source = sourcelow | (srchigh << 16); + if (source >= 0x20000) + LOGMASKED(LOG_GCM394_SYSDMA, " likely transfer from ROM %08x - %08x\n", (source - 0x20000) * 2, (source - 0x20000) * 2 + (length * 2)- 1); - // wrlshunt uses the extra params, might be doing very large ROM -> RAM transfers with even more upper address bits? + // wrlshunt transfers ROM to RAM, all RAM write addresses have 0x800000 in the destination set - if (mode == 0x0089) // no source inc, used for memory clear operations? (source usually points at stack value) + // mode 0x0089 == no source inc, used for memory clear operations? (source usually points at stack value) + // mode 0x0009 == regular copy? (smartfp does 2 copies like this after the initial clears, source definitely points at a correctly sized data structure) + // what does having bit 0x4000 on mode set mean? (first transfer on wrlshunt - maybe an IRQ disable?) + + if ((mode == 0x0089) || (mode == 0x0009) || (mode == 0x4009)) { for (int i = 0; i < length; i++) { - address_space &mem = this->space(AS_PROGRAM); - uint16_t val = mem.read_word(source); - mem.write_word(dest, val); - dest += 1; - } - } - else if (mode == 0x0009) // regular copy? (smartfp does 2 copies like this after the initial clears, source definitely points at a correctly sized data structure) - { - for (int i = 0; i < length; i++) - { - address_space &mem = this->space(AS_PROGRAM); - uint16_t val = mem.read_word(source); - mem.write_word(dest, val); + uint16_t val = 0x0000; + + address_space& mem = this->space(AS_PROGRAM); + + if (source < 0x20000) + { + val = mem.read_word(source); + } + else + { + // maybe the -0x20000 here should be handled in external space handlers instead + val = m_space_read_cb(space, source - 0x20000); + } + + if (dest < 0x20000) + { + mem.write_word(dest, val); + } + else + { + // maybe the -0x20000 here should be handled in external space handlers instead + m_space_write_cb(space, dest - 0x20000, val); + } + dest += 1; - source += 1; + if ((mode&0x3fff) == 0x0009) + source += 1; } } else @@ -128,7 +144,12 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7816_w) { LOGMASKED(LOG_GCM39 WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7817_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7817_w %04x\n", machine().describe_context(), data); m_7817 = data; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7820_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7820_w %04x\n", machine().describe_context(), data); m_7820 = data; } -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; } + +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; +} + 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; } @@ -138,7 +159,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7835_w) { LOGMASKED(LOG_GCM39 // IO here? READ16_MEMBER(sunplus_gcm394_base_device::ioport_a_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioport_a_r\n", machine().describe_context()); return m_porta_in(); } -WRITE16_MEMBER(sunplus_gcm394_base_device::ioport_a_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioport_a_w %04x\n", machine().describe_context(), data); m_7860 = data; } +WRITE16_MEMBER(sunplus_gcm394_base_device::ioport_a_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::ioport_a_w %04x\n", machine().describe_context(), data); m_porta_out(data); } READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7861_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7861_r\n", machine().describe_context()); return m_7861; } @@ -168,6 +189,12 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7883_w) { LOGMASKED(LOG_GCM39 WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78a0_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a0_w %04x\n", machine().describe_context(), data); m_78a0 = data; } +READ16_MEMBER(sunplus_gcm394_base_device::unkarea_78a1_r) +{ + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a1_r\n", machine().describe_context()); + return machine().rand(); +} + WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78a4_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a4_w %04x\n", machine().describe_context(), data); m_78a4 = data; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78a5_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a5_w %04x\n", machine().describe_context(), data); m_78a5 = data; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78a6_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78a6_w %04x\n", machine().describe_context(), data); m_78a6 = data; } @@ -177,6 +204,13 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78a8_w) { LOGMASKED(LOG_GCM39 WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78b0_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b0_w %04x\n", machine().describe_context(), data); m_78b0 = data; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78b1_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b1_w %04x\n", machine().describe_context(), data); m_78b1 = data; } + +READ16_MEMBER(sunplus_gcm394_base_device::unkarea_78b2_r) +{ + LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b2_r\n", machine().describe_context()); + return machine().rand(); +} + WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78b2_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b2_w %04x\n", machine().describe_context(), data); m_78b2 = data; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_78b8_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_78b8_w %04x\n", machine().describe_context(), data); m_78b8 = data; } @@ -268,7 +302,7 @@ void sunplus_gcm394_base_device::internal_map(address_map &map) map(0x007042, 0x007042).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device2_unk2_w)); // maybe sprites? written as 7022, 702d and 7042 group 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).w(m_spg_video, FUNC(gcm394_base_video_device::video_7063_w)); + map(0x007063, 0x007063).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7063_r), FUNC(gcm394_base_video_device::video_7063_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) @@ -344,6 +378,8 @@ void sunplus_gcm394_base_device::internal_map(address_map &map) map(0x0078a0, 0x0078a0).w(FUNC(sunplus_gcm394_base_device::unkarea_78a0_w)); + map(0x0078a1, 0x0078a1).r(FUNC(sunplus_gcm394_base_device::unkarea_78a1_r)); + map(0x0078a4, 0x0078a4).w(FUNC(sunplus_gcm394_base_device::unkarea_78a4_w)); map(0x0078a5, 0x0078a5).w(FUNC(sunplus_gcm394_base_device::unkarea_78a5_w)); map(0x0078a6, 0x0078a6).w(FUNC(sunplus_gcm394_base_device::unkarea_78a6_w)); @@ -352,6 +388,8 @@ void sunplus_gcm394_base_device::internal_map(address_map &map) map(0x0078b0, 0x0078b0).w(FUNC(sunplus_gcm394_base_device::unkarea_78b0_w)); map(0x0078b1, 0x0078b1).w(FUNC(sunplus_gcm394_base_device::unkarea_78b1_w)); + + map(0x0078b2, 0x0078b2).r(FUNC(sunplus_gcm394_base_device::unkarea_78b2_r)); map(0x0078b2, 0x0078b2).w(FUNC(sunplus_gcm394_base_device::unkarea_78b2_w)); map(0x0078b8, 0x0078b8).w(FUNC(sunplus_gcm394_base_device::unkarea_78b8_w)); @@ -394,6 +432,14 @@ void sunplus_gcm394_base_device::device_start() m_porta_in.resolve_safe(0); m_portb_in.resolve_safe(0); + m_porta_out.resolve(); + + + m_space_read_cb.resolve_safe(0); + m_space_write_cb.resolve(); + m_bank_write_cb.resolve(); + + m_unk_timer = timer_alloc(0); m_unk_timer->adjust(attotime::never); } |