diff --git a/src/devices/cpu/unsp/unsp_fxxx.cpp b/src/devices/cpu/unsp/unsp_fxxx.cpp index 649bc162160..ea9ad1a2751 100644 --- a/src/devices/cpu/unsp/unsp_fxxx.cpp +++ b/src/devices/cpu/unsp/unsp_fxxx.cpp @@ -345,6 +345,7 @@ void unsp_device::execute_fxxx_101_group(uint16_t op) case 0xf168: case 0xf368: case 0xf568: case 0xf768: case 0xf968: case 0xfb68: case 0xfd68: case 0xff68: case 0xf170: case 0xf370: case 0xf570: case 0xf770: case 0xf970: case 0xfb70: case 0xfd70: case 0xff70: case 0xf178: case 0xf378: case 0xf578: case 0xf778: case 0xf978: case 0xfb78: case 0xfd78: case 0xff78: + // break (call vector fff5?) unimplemented_opcode(op); return; diff --git a/src/devices/machine/spg2xx_audio.cpp b/src/devices/machine/spg2xx_audio.cpp index eabbada8b3f..2e3d53c3612 100644 --- a/src/devices/machine/spg2xx_audio.cpp +++ b/src/devices/machine/spg2xx_audio.cpp @@ -12,6 +12,9 @@ SPG110 Beat interrupt frequency might be different too, seems to trigger an FIQ, but music is very slow in jak_spdmo + GCM394 has 32 channels, and potentially a different register layout + it looks close but might be different enough to split off + **********************************************************************/ #include "emu.h" @@ -19,6 +22,7 @@ DEFINE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device, "spg2xx_audio", "SPG2xx-series System-on-a-Chip Audio") DEFINE_DEVICE_TYPE(SPG110_AUDIO, spg110_audio_device, "spg110_audio", "SPG110-series System-on-a-Chip Audio") +DEFINE_DEVICE_TYPE(SUNPLUS_GCM394_AUDIO, sunplus_gcm394_audio_device, "gcm394_audio", "SunPlus GCM394 System-on-a-Chip (Audio)") #define LOG_SPU_READS (1U << 0) #define LOG_SPU_WRITES (1U << 1) @@ -57,6 +61,10 @@ spg110_audio_device::spg110_audio_device(const machine_config &mconfig, const ch { } +sunplus_gcm394_audio_device::sunplus_gcm394_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : spg2xx_audio_device(mconfig, SUNPLUS_GCM394_AUDIO, tag, owner, clock) +{ +} void spg2xx_audio_device::device_start() @@ -287,7 +295,7 @@ READ16_MEMBER(spg2xx_audio_device::audio_ctrl_r) READ16_MEMBER(spg2xx_audio_device::audio_r) { - const uint16_t channel = (offset & 0x00f0) >> 4; + const uint16_t channel = (offset & 0x01f0) >> 4; uint16_t data = m_audio_regs[offset]; @@ -365,7 +373,7 @@ READ16_MEMBER(spg2xx_audio_device::audio_r) READ16_MEMBER(spg2xx_audio_device::audio_phase_r) { - const uint16_t channel = (offset & 0x00f0) >> 4; + const uint16_t channel = (offset & 0x01f0) >> 4; uint16_t data = m_audio_phase_regs[offset]; switch (offset & AUDIO_CHAN_OFFSET_MASK) @@ -675,7 +683,7 @@ WRITE16_MEMBER(spg2xx_audio_device::audio_ctrl_w) WRITE16_MEMBER(spg2xx_audio_device::audio_phase_w) { - const uint16_t channel = (offset & 0x00f0) >> 4; + const uint16_t channel = (offset & 0x01f0) >> 4; switch (offset & AUDIO_CHAN_OFFSET_MASK) { @@ -734,7 +742,7 @@ WRITE16_MEMBER(spg2xx_audio_device::audio_phase_w) WRITE16_MEMBER(spg2xx_audio_device::audio_w) { - const uint16_t channel = (offset & 0x00f0) >> 4; + const uint16_t channel = (offset & 0x01f0) >> 4; switch (offset & AUDIO_CHAN_OFFSET_MASK) { @@ -1290,3 +1298,38 @@ WRITE16_MEMBER(spg110_audio_device::audio_w) spg2xx_audio_device::audio_w(space,offset,data,mem_mask); } + +uint16_t sunplus_gcm394_audio_device::control_group16_r(uint8_t group, uint8_t offset) +{ + LOGMASKED(LOG_SPU_WRITES, "sunplus_gcm394_audio_device::control_group16_r (group %d) offset %02x\n", group, offset); + return m_control[group][offset]; +} + +void sunplus_gcm394_audio_device::control_group16_w(uint8_t group, uint8_t offset, uint16_t data) +{ + LOGMASKED(LOG_SPU_WRITES, "sunplus_gcm394_audio_device::control_group16_w (group %d) offset %02x data %04x\n", group, offset, data); + m_control[group][offset] = data; + + // offset 0x0b = triggers? +} + +READ16_MEMBER(sunplus_gcm394_audio_device::control_r) +{ + return control_group16_r(offset & 0x20 ? 1 : 0, offset & 0x1f); +} + + +WRITE16_MEMBER(sunplus_gcm394_audio_device::control_w) +{ + control_group16_w(offset & 0x20 ? 1 : 0, offset & 0x1f, data); +} + +void sunplus_gcm394_audio_device::device_start() +{ + spg2xx_audio_device::device_start(); + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 0x20; j++) + m_control[i][j] = 0x0000; + +} \ No newline at end of file diff --git a/src/devices/machine/spg2xx_audio.h b/src/devices/machine/spg2xx_audio.h index 88d21fb1ecf..7154dccfad9 100644 --- a/src/devices/machine/spg2xx_audio.h +++ b/src/devices/machine/spg2xx_audio.h @@ -381,7 +381,25 @@ public: virtual uint32_t get_phase(const offs_t channel) const override { return m_audio_regs[(channel << 4) | 0xe]; } }; +class sunplus_gcm394_audio_device : public spg2xx_audio_device +{ +public: + sunplus_gcm394_audio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ16_MEMBER(control_r); + DECLARE_WRITE16_MEMBER(control_w); + + virtual void device_start() override; + +private: + uint16_t control_group16_r(uint8_t group, uint8_t offset); + void control_group16_w(uint8_t group, uint8_t offset, uint16_t data); + + uint16_t m_control[2][0x20]; +}; + DECLARE_DEVICE_TYPE(SPG2XX_AUDIO, spg2xx_audio_device) DECLARE_DEVICE_TYPE(SPG110_AUDIO, spg110_audio_device) +DECLARE_DEVICE_TYPE(SUNPLUS_GCM394_AUDIO, sunplus_gcm394_audio_device) #endif // MAME_MACHINE_SPG2XX_AUDIO_H diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index f63d69e9bcf..4c50147c57f 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -135,9 +135,10 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7824_w) { LOGMASKED(LOG_GCM39 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::unkarea_7860_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7860_r\n", machine().describe_context()); return m_porta_in(); } -WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7860_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7860_w %04x\n", machine().describe_context(), data); m_7860 = data; } +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; } 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; } @@ -146,7 +147,9 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7862_w) { LOGMASKED(LOG_GCM39 READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7863_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7863_r\n", machine().describe_context()); return m_7863; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7863_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7863_w %04x\n", machine().describe_context(), data); m_7863 = data; } -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_7870; } +// 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::unkarea_7871_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7871_r\n", machine().describe_context()); return m_7871; } @@ -196,6 +199,12 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7935_w) READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7936_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7936_r\n", machine().describe_context()); return 0x0000; } WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7936_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7936_w %04x\n", machine().describe_context(), data); m_7936 = data; } +WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7960_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7960_w %04x\n", machine().describe_context(), data); m_7960 = data; } + +READ16_MEMBER(sunplus_gcm394_base_device::unkarea_7961_r) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7961_r\n", machine().describe_context()); return m_7961; } +WRITE16_MEMBER(sunplus_gcm394_base_device::unkarea_7961_w) { LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::unkarea_7961_w %04x\n", machine().describe_context(), data); m_7961 = data; } + + // **************************************** fallthrough logger etc. ************************************************* READ16_MEMBER(sunplus_gcm394_base_device::unk_r) @@ -232,41 +241,40 @@ void sunplus_gcm394_base_device::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::unknown_video_device0_regs_w)); // gcm394_video_device:: - map(0x007008, 0x00700f).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device1_regs_w)); // gcm394_video_device:: + map(0x007000, 0x007007).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device0_regs_w)); + map(0x007008, 0x00700f).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device1_regs_w)); - map(0x007010, 0x007015).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap0_regs_r), FUNC(gcm394_base_video_device::tmap0_regs_w)); // gcm394_video_device:: - map(0x007016, 0x00701b).rw(m_spg_video, FUNC(gcm394_base_video_device::tmap1_regs_r), FUNC(gcm394_base_video_device::tmap1_regs_w)); // gcm394_video_device:: + 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_unk0_w)); // gcm394_video_device:: probably tilebase, written with other tmap0 regs - map(0x007021, 0x007021).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_unk0_w)); // gcm394_video_device:: probably tilebase, written with other tmap1 regs - map(0x007022, 0x007022).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device2_unk0_w)); // gcm394_video_device:: another tilebase? maybe sprites? written as 7022, 702d and 7042 group - map(0x007023, 0x007023).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device0_unk0_w)); // gcm394_video_device:: written with other unknown_video_device0 regs - map(0x007024, 0x007024).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device1_unk0_w)); // gcm394_video_device:: written with other unknown_video_device1 regs + map(0x007020, 0x007020).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_unk0_w)); // probably tilebase, written with other tmap0 regs + map(0x007021, 0x007021).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_unk0_w)); // probably tilebase, written with other tmap1 regs + map(0x007022, 0x007022).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device2_unk0_w)); // another tilebase? maybe sprites? written as 7022, 702d and 7042 group + map(0x007023, 0x007023).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device0_unk0_w)); // written with other unknown_video_device0 regs + map(0x007024, 0x007024).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device1_unk0_w)); // written with other unknown_video_device1 regs map(0x00702a, 0x00702a).w(m_spg_video, FUNC(gcm394_base_video_device::video_702a_w)); - map(0x00702b, 0x00702b).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_unk1_w)); // gcm394_video_device:: written with other tmap0 regs - map(0x00702c, 0x00702c).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_unk1_w)); // gcm394_video_device:: written with other tmap1 regs - map(0x00702d, 0x00702d).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device2_unk1_w)); // gcm394_video_device:: maybe sprites? written as 7022, 702d and 7042 group - map(0x00702e, 0x00702e).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device0_unk1_w)); // gcm394_video_device:: written with other unknown_video_device0 regs - map(0x00702f, 0x00702f).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device1_unk1_w)); // gcm394_video_device:: written with other unknown_video_device1 regs + map(0x00702b, 0x00702b).w(m_spg_video, FUNC(gcm394_base_video_device::tmap0_unk1_w)); // written with other tmap0 regs + map(0x00702c, 0x00702c).w(m_spg_video, FUNC(gcm394_base_video_device::tmap1_unk1_w)); // written with other tmap1 regs + map(0x00702d, 0x00702d).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device2_unk1_w)); // maybe sprites? written as 7022, 702d and 7042 group + map(0x00702e, 0x00702e).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device0_unk1_w)); // written with other unknown_video_device0 regs + map(0x00702f, 0x00702f).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device1_unk1_w)); // written with other unknown_video_device1 regs map(0x007030, 0x007030).rw(m_spg_video, FUNC(gcm394_base_video_device::video_7030_r), FUNC(gcm394_base_video_device::video_7030_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(0x007042, 0x007042).w(m_spg_video, FUNC(gcm394_base_video_device::unknown_video_device2_unk2_w)); // gcm394_video_device:: maybe sprites? written as 7022, 702d and 7042 group + 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)); // 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)); // gcm394_video_device:: 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)); // gcm394_video_device:: 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)); // gcm394_video_device:: - - map(0x00707e, 0x00707e).w(m_spg_video, FUNC(gcm394_base_video_device::video_dma_unk_w)); // gcm394_video_device:: written around same time as DMA, seems related + 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(0x00707f, 0x00707f).rw(m_spg_video, FUNC(gcm394_base_video_device::video_707f_r), FUNC(gcm394_base_video_device::video_707f_w)); @@ -282,7 +290,7 @@ void sunplus_gcm394_base_device::map(address_map &map) map(0x007088, 0x007088).w(m_spg_video, FUNC(gcm394_base_video_device::video_7088_w)); // ###################################################################################################################################################################################### - // 73xx-77xx = ram areas? + // 73xx-77xx = video ram // ###################################################################################################################################################################################### map(0x007300, 0x0073ff).rw(m_spg_video, FUNC(gcm394_base_video_device::palette_r), FUNC(gcm394_base_video_device::palette_w)); @@ -290,7 +298,7 @@ void sunplus_gcm394_base_device::map(address_map &map) map(0x007400, 0x0077ff).ram().share("spriteram"); // ###################################################################################################################################################################################### - // 78xx region = ?? + // 78xx region = io + other? // ###################################################################################################################################################################################### map(0x007803, 0x007803).rw(FUNC(sunplus_gcm394_base_device::unkarea_7803_r), FUNC(sunplus_gcm394_base_device::unkarea_7803_w)); @@ -317,7 +325,7 @@ void sunplus_gcm394_base_device::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::unkarea_7860_r), FUNC(sunplus_gcm394_base_device::unkarea_7860_w)); + map(0x007860, 0x007860).rw(FUNC(sunplus_gcm394_base_device::ioport_a_r), FUNC(sunplus_gcm394_base_device::ioport_a_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)); @@ -353,34 +361,36 @@ void sunplus_gcm394_base_device::map(address_map &map) map(0x0078fb, 0x0078fb).r(FUNC(sunplus_gcm394_base_device::unkarea_78fb_status_r)); // ###################################################################################################################################################################################### - // 79xx region = ?? + // 79xx region = timers? // ###################################################################################################################################################################################### map(0x007934, 0x007934).rw(FUNC(sunplus_gcm394_base_device::unkarea_7934_r), FUNC(sunplus_gcm394_base_device::unkarea_7934_w)); map(0x007935, 0x007935).rw(FUNC(sunplus_gcm394_base_device::unkarea_7935_r), FUNC(sunplus_gcm394_base_device::unkarea_7935_w)); map(0x007936, 0x007936).rw(FUNC(sunplus_gcm394_base_device::unkarea_7936_r), FUNC(sunplus_gcm394_base_device::unkarea_7936_w)); + map(0x007960, 0x007960).w(FUNC(sunplus_gcm394_base_device::unkarea_7960_w)); + map(0x007961, 0x007961).rw(FUNC(sunplus_gcm394_base_device::unkarea_7961_r), FUNC(sunplus_gcm394_base_device::unkarea_7961_w)); + // ###################################################################################################################################################################################### // 7axx region = system (including dma) // ###################################################################################################################################################################################### - map(0x007a80, 0x007a86).w(FUNC(sunplus_gcm394_base_device::system_dma_params_w)); map(0x007abf, 0x007abf).rw(FUNC(sunplus_gcm394_base_device::system_dma_status_r), FUNC(sunplus_gcm394_base_device::system_dma_trigger_w)); // ###################################################################################################################################################################################### - // 7cxx-7fxx = ram areas? + // 7bxx-7fxx = audio // ###################################################################################################################################################################################### - map(0x007c00, 0x007cff).ram(); - map(0x007d00, 0x007dff).ram(); - map(0x007e00, 0x007eff).ram(); - map(0x007f00, 0x007fff).ram(); + map(0x007b80, 0x007bbf).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::control_r), FUNC(sunplus_gcm394_audio_device::control_w)); + map(0x007c00, 0x007dff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_r), FUNC(sunplus_gcm394_audio_device::audio_w)); + map(0x007e00, 0x007fff).rw(m_spg_audio, FUNC(sunplus_gcm394_audio_device::audio_phase_r), FUNC(sunplus_gcm394_audio_device::audio_phase_w)); } void sunplus_gcm394_base_device::device_start() { m_porta_in.resolve_safe(0); + m_portb_in.resolve_safe(0); m_unk_timer = timer_alloc(0); m_unk_timer->adjust(attotime::never); @@ -453,7 +463,15 @@ void sunplus_gcm394_base_device::device_reset() m_7935 = 0x0000; m_7936 = 0x0000; + m_7960 = 0x0000; + m_7961 = 0x0000; + + m_unk_timer->adjust(attotime::from_hz(60), 0, attotime::from_hz(60)); + + m_gfxregion = memregion(":maincpu")->base(); + m_gfxregionsize = memregion(":maincpu")->bytes(); + } void sunplus_gcm394_base_device::checkirq6() @@ -478,19 +496,35 @@ void sunplus_gcm394_base_device::device_timer(emu_timer &timer, device_timer_id } +WRITE_LINE_MEMBER(sunplus_gcm394_base_device::audioirq_w) +{ + //m_cpu->set_state_unsynced(UNSP_IRQ5_LINE, state); +} + WRITE_LINE_MEMBER(sunplus_gcm394_base_device::videoirq_w) { m_cpu->set_state_unsynced(UNSP_IRQ5_LINE, state); } -void sunplus_gcm394_base_device::device_add_mconfig(machine_config &config) +uint16_t sunplus_gcm394_base_device::read_space(uint32_t offset) { - //SUNPLUS_GCM394_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1)); - //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); - - GCM394_VIDEO(config, m_spg_video, DERIVED_CLOCK(1, 1), m_cpu, m_screen); - m_spg_video->write_video_irq_callback().set(FUNC(sunplus_gcm394_base_device::videoirq_w)); + uint16_t b = m_gfxregion[(offset * 2) & (m_gfxregionsize - 1)] | (m_gfxregion[(offset * 2 + 1) & (m_gfxregionsize - 1)] << 8); + return b; +} + + +void sunplus_gcm394_base_device::device_add_mconfig(machine_config &config) +{ + SUNPLUS_GCM394_AUDIO(config, m_spg_audio, DERIVED_CLOCK(1, 1)); + m_spg_audio->write_irq_callback().set(FUNC(sunplus_gcm394_base_device::audioirq_w)); + m_spg_audio->space_read_callback().set(FUNC(sunplus_gcm394_base_device::read_space)); + + 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); + + GCM394_VIDEO(config, m_spg_video, DERIVED_CLOCK(1, 1), m_cpu, m_screen); + m_spg_video->write_video_irq_callback().set(FUNC(sunplus_gcm394_base_device::videoirq_w)); + m_spg_video->space_read_callback().set(FUNC(sunplus_gcm394_base_device::read_space)); } diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index c822893b543..62cac1380f1 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -15,6 +15,8 @@ #include "screen.h" #include "emupal.h" #include "sunplus_gcm394_video.h" +#include "spg2xx_audio.h" + class sunplus_gcm394_base_device : public device_t, public device_mixer_interface { @@ -25,7 +27,9 @@ public: , m_cpu(*this, finder_base::DUMMY_TAG) , m_screen(*this, finder_base::DUMMY_TAG) , m_spg_video(*this, "spgvideo") + , m_spg_audio(*this, "spgaudio") , m_porta_in(*this) + , m_portb_in(*this) { } @@ -34,6 +38,7 @@ public: uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { return m_spg_video->screen_update(screen, bitmap, cliprect); } auto porta_in() { return m_porta_in.bind(); } + auto portb_in() { return m_portb_in.bind(); } DECLARE_WRITE_LINE_MEMBER(vblank) { m_spg_video->vblank(state); } @@ -47,8 +52,10 @@ protected: required_device m_cpu; required_device m_screen; required_device m_spg_video; + required_device m_spg_audio; devcb_read16 m_porta_in; + devcb_read16 m_portb_in; uint16_t m_dma_params[7]; @@ -115,6 +122,8 @@ protected: uint16_t m_7935; uint16_t m_7936; + uint16_t m_7960; + uint16_t m_7961; private: DECLARE_READ16_MEMBER(unk_r); @@ -155,8 +164,8 @@ private: DECLARE_READ16_MEMBER(unkarea_782d_r); DECLARE_WRITE16_MEMBER(unkarea_782d_w); - DECLARE_READ16_MEMBER(unkarea_7860_r); - DECLARE_WRITE16_MEMBER(unkarea_7860_w); + DECLARE_READ16_MEMBER(ioport_a_r); + DECLARE_WRITE16_MEMBER(ioport_a_w); DECLARE_READ16_MEMBER(unkarea_7861_r); @@ -205,13 +214,23 @@ private: DECLARE_READ16_MEMBER(unkarea_7936_r); DECLARE_WRITE16_MEMBER(unkarea_7936_w); + DECLARE_WRITE16_MEMBER(unkarea_7960_w); + DECLARE_READ16_MEMBER(unkarea_7961_r); + DECLARE_WRITE16_MEMBER(unkarea_7961_w); + + DECLARE_WRITE_LINE_MEMBER(videoirq_w); + DECLARE_WRITE_LINE_MEMBER(audioirq_w); void checkirq6(); emu_timer *m_unk_timer; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + uint8_t* m_gfxregion; + uint32_t m_gfxregionsize; + uint16_t read_space(uint32_t offset); + }; diff --git a/src/devices/machine/sunplus_gcm394_video.cpp b/src/devices/machine/sunplus_gcm394_video.cpp index 81431d1b556..5f3a7a53eb3 100644 --- a/src/devices/machine/sunplus_gcm394_video.cpp +++ b/src/devices/machine/sunplus_gcm394_video.cpp @@ -31,6 +31,7 @@ gcm394_base_video_device::gcm394_base_video_device(const machine_config &mconfig , m_video_irq_cb(*this) , m_palette(*this, "palette") , m_gfxdecode(*this, "gfxdecode") + , m_space_read_cb(*this) { } @@ -167,6 +168,7 @@ void gcm394_base_video_device::device_start() gfxelement++; } save_item(NAME(m_spriteextra)); + m_space_read_cb.resolve_safe(0); } void gcm394_base_video_device::device_reset() @@ -217,13 +219,6 @@ void gcm394_base_video_device::device_reset() * Video Hardware * *************************/ -inline uint16_t gcm394_base_video_device::read_data(uint32_t offset) -{ - uint16_t b = m_gfxregion[(offset * 2) & (m_gfxregionsize - 1)] | (m_gfxregion[(offset * 2 + 1) & (m_gfxregionsize - 1)] << 8); - return b; -} - - template void gcm394_base_video_device::draw(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t bitmap_addr, uint32_t tile, int32_t h, int32_t w, uint8_t bpp, uint32_t yflipmask, uint32_t palette_offset) { @@ -263,7 +258,7 @@ void gcm394_base_video_device::draw(const rectangle &cliprect, uint32_t line, ui if (nbits < nc_bpp) { - uint16_t b = read_data((m++ & 0x3fffff)); + uint16_t b = m_space_read_cb((m++ & 0x3fffff)); b = (b << 8) | (b >> 8); bits |= b << (nc_bpp - nbits); nbits += 16; diff --git a/src/devices/machine/sunplus_gcm394_video.h b/src/devices/machine/sunplus_gcm394_video.h index 4dfe3106e77..3918f4cf0bd 100644 --- a/src/devices/machine/sunplus_gcm394_video.h +++ b/src/devices/machine/sunplus_gcm394_video.h @@ -23,6 +23,8 @@ public: uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); DECLARE_WRITE_LINE_MEMBER(vblank); + auto space_read_callback() { return m_space_read_cb.bind(); } + void write_tmap_regs(int tmap, uint16_t* regs, int offset, uint16_t data); DECLARE_READ16_MEMBER(tmap0_regs_r); @@ -192,11 +194,9 @@ protected: uint16_t m_spriteextra[0x100]; uint16_t m_paletteram[0x100*0x10]; - uint16_t read_data(uint32_t offset); - required_device m_palette; required_device m_gfxdecode; - + devcb_read16 m_space_read_cb; }; class gcm394_video_device : public gcm394_base_video_device diff --git a/src/mame/drivers/sunplus_gcm394.cpp b/src/mame/drivers/sunplus_gcm394.cpp index 0bd86d4a533..a4204a58d97 100644 --- a/src/mame/drivers/sunplus_gcm394.cpp +++ b/src/mame/drivers/sunplus_gcm394.cpp @@ -32,6 +32,7 @@ public: , m_spg(*this, "spg") , m_bank(*this, "cartbank") , m_io_p1(*this, "P1") + , m_io_p2(*this, "P2") { } void base(machine_config &config); @@ -49,6 +50,7 @@ protected: optional_memory_bank m_bank; required_ioport m_io_p1; + required_ioport m_io_p2; virtual void mem_map_4m(address_map &map); @@ -56,6 +58,7 @@ private: uint32_t m_current_bank; DECLARE_READ16_MEMBER(porta_r); + DECLARE_READ16_MEMBER(portb_r); }; READ16_MEMBER(gcm394_game_state::porta_r) @@ -65,10 +68,19 @@ READ16_MEMBER(gcm394_game_state::porta_r) return data; } +READ16_MEMBER(gcm394_game_state::portb_r) +{ + uint16_t data = m_io_p2->read(); + logerror("Port B Read: %04x\n", data); + return data; +} + + void gcm394_game_state::base(machine_config &config) { GCM394(config, m_spg, XTAL(27'000'000), m_maincpu, m_screen); m_spg->porta_in().set(FUNC(gcm394_game_state::porta_r)); + m_spg->portb_in().set(FUNC(gcm394_game_state::portb_r)); UNSP_20(config, m_maincpu, XTAL(27'000'000)); // code at 8019 uses extended opcode, so must be 2.0+? m_maincpu->set_addrmap(AS_PROGRAM, &gcm394_game_state::mem_map_4m); @@ -161,6 +173,56 @@ static INPUT_PORTS_START( gcm394 ) PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON4 ) + + PORT_START("P2") + PORT_DIPNAME( 0x0001, 0x0001, "P2" ) + PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0008, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) INPUT_PORTS_END