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.cpp96
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);
}