From 3f4424e056e8b4fb5cb063f14d4589da65d990f6 Mon Sep 17 00:00:00 2001 From: David Haywood Date: Sat, 11 May 2019 15:32:40 +0100 Subject: [PATCH] smartfp - some video dma stuff, improved logging, debug stuff (#5037) * debugging help (nw) * better logging (nw) * smartfp - video dma stuff (nw) * tidy (nw) * sprite stuff (nw) * (nw) --- src/devices/machine/sunplus_gcm394.cpp | 22 +- src/devices/machine/sunplus_gcm394.h | 4 +- src/devices/machine/sunplus_gcm394_video.cpp | 222 +++++++++++++++++-- src/devices/machine/sunplus_gcm394_video.h | 15 +- 4 files changed, 230 insertions(+), 33 deletions(-) diff --git a/src/devices/machine/sunplus_gcm394.cpp b/src/devices/machine/sunplus_gcm394.cpp index 468e55b7d16..5e6061582b5 100644 --- a/src/devices/machine/sunplus_gcm394.cpp +++ b/src/devices/machine/sunplus_gcm394.cpp @@ -10,10 +10,12 @@ #include "sunplus_gcm394.h" + +#define LOG_GCM394_SYSDMA (1U << 2) #define LOG_GCM394 (1U << 1) #define LOG_GCM394_UNMAPPED (1U << 0) -#define VERBOSE (LOG_GCM394_UNMAPPED) +#define VERBOSE (LOG_GCM394_UNMAPPED | LOG_GCM394_SYSDMA) #include "logmacro.h" @@ -31,14 +33,14 @@ sunplus_gcm394_device::sunplus_gcm394_device(const machine_config &mconfig, cons READ16_MEMBER(sunplus_gcm394_base_device::system_dma_status_r) { - LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::system_dma_status_r (7abf)\n", machine().describe_context()); + LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::system_dma_status_r (7abf)\n", machine().describe_context()); return 0x0001; } WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_params_w) { m_dma_params[offset] = data; - LOGMASKED(LOG_GCM394, "%s:sunplus_gcm394_base_device::sys_dma_params_w %01x %04x\n", machine().describe_context(), offset, data); + LOGMASKED(LOG_GCM394_SYSDMA, "%s:sunplus_gcm394_base_device::sys_dma_params_w %01x %04x\n", machine().describe_context(), offset, data); } WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) @@ -49,7 +51,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) uint16_t length = m_dma_params[3]; uint16_t srchigh = m_dma_params[4]; - LOGMASKED(LOG_GCM394, "%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:%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]); uint32_t source = sourcelow | (srchigh << 16); @@ -78,7 +80,7 @@ WRITE16_MEMBER(sunplus_gcm394_base_device::system_dma_trigger_w) } else { - LOGMASKED(LOG_GCM394, "unhandled!\n"); + LOGMASKED(LOG_GCM394_SYSDMA, "unhandled!\n"); } m_dma_params[0] = m_dma_params[1] = m_dma_params[2] = m_dma_params[3] = m_dma_params[4] = m_dma_params[5] = m_dma_params[6] = 0x0000; @@ -274,11 +276,8 @@ void sunplus_gcm394_base_device::map(address_map &map) // 73xx-77xx = ram areas? // ###################################################################################################################################################################################### - map(0x007300, 0x0073ff).ram().share("spgvideo:paletteram"); - map(0x007400, 0x0074ff).ram(); - map(0x007500, 0x0075ff).ram(); - map(0x007600, 0x0076ff).ram(); - map(0x007700, 0x0077ff).ram(); + map(0x007300, 0x0073ff).ram().w("palette", FUNC(palette_device::write16)).share("palette"); + map(0x007400, 0x0077ff).ram().share("spriteram"); // ###################################################################################################################################################################################### // 78xx region = ?? @@ -452,8 +451,9 @@ void sunplus_gcm394_base_device::device_add_mconfig(machine_config &config) 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->set_palette(m_palette); - + PALETTE(config, m_palette).set_format(palette_device::xRGB_555, 256); } diff --git a/src/devices/machine/sunplus_gcm394.h b/src/devices/machine/sunplus_gcm394.h index 54d433addc1..70480f4d9ed 100644 --- a/src/devices/machine/sunplus_gcm394.h +++ b/src/devices/machine/sunplus_gcm394.h @@ -24,7 +24,7 @@ public: , device_mixer_interface(mconfig, *this, 2) , m_cpu(*this, finder_base::DUMMY_TAG) , m_screen(*this, finder_base::DUMMY_TAG) - //, m_palette(*this, "palette") + , m_palette(*this, "palette") , m_spg_video(*this, "spgvideo") { } @@ -44,7 +44,7 @@ protected: required_device m_cpu; required_device m_screen; - //required_device m_palette; + required_device m_palette; required_device m_spg_video; uint16_t m_dma_params[7]; diff --git a/src/devices/machine/sunplus_gcm394_video.cpp b/src/devices/machine/sunplus_gcm394_video.cpp index a4f7096e2e8..a07ea7c44f8 100644 --- a/src/devices/machine/sunplus_gcm394_video.cpp +++ b/src/devices/machine/sunplus_gcm394_video.cpp @@ -9,23 +9,26 @@ #include "emu.h" #include "sunplus_gcm394_video.h" -DEFINE_DEVICE_TYPE(GCM394_VIDEO, gcm394_video_device, "gcm394_video", "GCM394-series System-on-a-Chip (Video)") +DEFINE_DEVICE_TYPE(GCM394_VIDEO, gcm394_video_device, "gcm394_video", "SunPlus GCM394 System-on-a-Chip (Video)") +#define LOG_GCM394_VIDEO_DMA (1U << 3) #define LOG_GCM394_TMAP (1U << 2) #define LOG_GCM394 (1U << 1) -#define VERBOSE (LOG_GCM394_TMAP) +#define VERBOSE (LOG_GCM394_VIDEO_DMA) #include "logmacro.h" gcm394_base_video_device::gcm394_base_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) + , device_gfx_interface(mconfig, *this, nullptr) + , device_video_interface(mconfig, *this) , m_cpu(*this, finder_base::DUMMY_TAG) , m_screen(*this, finder_base::DUMMY_TAG) // , m_scrollram(*this, "scrollram") - , m_paletteram(*this, "paletteram") -// , m_spriteram(*this, "spriteram") + , m_paletteram(*this, "^palette") + , m_spriteram(*this, "^spriteram") , m_video_irq_cb(*this) { } @@ -50,6 +53,63 @@ void gcm394_base_video_device::device_start() m_video_irq_cb.resolve(); + uint8_t* gfxregion = memregion(":maincpu")->base(); + int gfxregion_size = memregion(":maincpu")->bytes(); + + int gfxelement = 0; + + if (1) + { + gfx_layout obj_layout = + { + 16,16, + 0, + 4, + { STEP4(0,1) }, + { STEP16(0,4) }, + { STEP16(0,4 * 16) }, + 16 * 16 * 4 + }; + obj_layout.total = gfxregion_size / (16 * 16 * 4 / 8); + set_gfx(gfxelement, std::make_unique(&palette(), obj_layout, gfxregion, 0, 0x10, 0)); + gfxelement++; + } + + if (1) + { + gfx_layout obj_layout = + { + 32,16, + 0, + 4, + { STEP4(0,1) }, + { STEP32(0,4) }, + { STEP16(0,4 * 32) }, + 16 * 32 * 4 + }; + obj_layout.total = gfxregion_size / (16 * 32 * 4 / 8); + set_gfx(gfxelement, std::make_unique(&palette(), obj_layout, gfxregion, 0, 0x10, 0)); + gfxelement++; + } + + if (1) + { + gfx_layout obj_layout = + { + 16,32, + 0, + 4, + { STEP4(0,1) }, + { STEP16(0,4) }, + { STEP32(0,4 * 16) }, + 32 * 16 * 4 + }; + obj_layout.total = gfxregion_size / (32 * 16 * 4 / 8); + set_gfx(gfxelement, std::make_unique(&palette(), obj_layout, gfxregion, 0, 0x10, 0)); + gfxelement++; + } + + save_item(NAME(m_spriteextra)); } void gcm394_base_video_device::device_reset() @@ -60,6 +120,9 @@ void gcm394_base_video_device::device_reset() m_tmap1_regs[i] = 0x0000; } + for (int i=0;i<0x100;i++) + m_spriteextra[i] = 0x0000; + m_707f = 0x0000; m_703a = 0x0000; m_7062 = 0x0000; @@ -80,6 +143,11 @@ void gcm394_base_video_device::device_reset() m_7087 = 0x0000; m_7088 = 0x0000; + m_videodma_bank = 0x0000; + m_videodma_size = 0x0000; + m_videodma_dest = 0x0000; + m_videodma_source = 0x0000; + m_video_irq_status = 0x0000; } @@ -274,6 +342,79 @@ void gcm394_base_video_device::draw_page(const rectangle &cliprect, uint32_t sca } } + +void gcm394_base_video_device::draw_sprite(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t base_addr) +{ + uint32_t bitmap_addr = 0;// 0x40 * m_video_regs[0x22]; + uint16_t tile = m_spriteram[base_addr + 0]; + int16_t x = m_spriteram[base_addr + 1]; + int16_t y = m_spriteram[base_addr + 2]; + uint16_t attr = m_spriteram[base_addr + 3]; + + if (!tile) + { + return; + } + + if (((attr & PAGE_PRIORITY_FLAG_MASK) >> PAGE_PRIORITY_FLAG_SHIFT) != priority) + { + return; + } + + const uint32_t h = 8 << ((attr & PAGE_TILE_HEIGHT_MASK) >> PAGE_TILE_HEIGHT_SHIFT); + const uint32_t w = 8 << ((attr & PAGE_TILE_WIDTH_MASK) >> PAGE_TILE_WIDTH_SHIFT); + + /* + if (!(m_video_regs[0x42] & SPRITE_COORD_TL_MASK)) + { + x = (160 + x) - w / 2; + y = (120 - y) - (h / 2) + 8; + } + */ + + x &= 0x01ff; + y &= 0x01ff; + + uint32_t tile_line = ((scanline - y) + 0x200) % h; + int16_t test_y = (y + tile_line) & 0x1ff; + if (test_y >= 0x01c0) + test_y -= 0x0200; + + if (test_y != scanline) + { + return; + } + + bool blend = (attr & 0x4000); + bool flip_x = (attr & TILE_X_FLIP); + const uint8_t bpp = attr & 0x0003; + const uint32_t yflipmask = attr & TILE_Y_FLIP ? h - 1 : 0; + const uint32_t palette_offset = (attr & 0x0f00) >> 4; + + if (blend) + { + if (flip_x) + draw(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset); + else + draw(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset); + } + else + { + if (flip_x) + draw(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset); + else + draw(cliprect, tile_line, x, y, bitmap_addr, tile, h, w, bpp, yflipmask, palette_offset); + } +} + +void gcm394_base_video_device::draw_sprites(const rectangle &cliprect, uint32_t scanline, int priority) +{ + for (uint32_t n = 0; n < 0x100; n++) + { + draw_sprite(cliprect, scanline, priority, 4 * n); + } +} + uint32_t gcm394_base_video_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { memset(&m_screenbuf[320 * cliprect.min_y], 0, 4 * 320 * ((cliprect.max_y - cliprect.min_y) + 1)); @@ -289,6 +430,7 @@ uint32_t gcm394_base_video_device::screen_update(screen_device &screen, bitmap_r { draw_page(cliprect, scanline, i, page1_addr, page1_regs); draw_page(cliprect, scanline, i, page2_addr, page2_regs); + draw_sprites(cliprect, scanline, i); } } @@ -347,20 +489,19 @@ READ16_MEMBER(gcm394_base_video_device::tmap0_regs_r) { return m_tmap0_regs[offs WRITE16_MEMBER(gcm394_base_video_device::tmap0_regs_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::tmap1_regs_w %01x %04x\n", machine().describe_context(), offset, data); + LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap0_regs_w %01x %04x\n", machine().describe_context(), offset, data); write_tmap_regs(0, m_tmap0_regs, offset, data); } WRITE16_MEMBER(gcm394_base_video_device::tmap0_unk0_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::tmap0_unk0_w %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap0_unk0_w %04x\n", machine().describe_context(), data); m_page1_addr = data; } WRITE16_MEMBER(gcm394_base_video_device::tmap0_unk1_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::tmap0_unk0_w %04x\n", machine().describe_context(), data); - m_page2_addr = data; + LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap0_unk1_w %04x\n", machine().describe_context(), data); } // **************************************** TILEMAP 1 ************************************************* @@ -369,18 +510,19 @@ READ16_MEMBER(gcm394_base_video_device::tmap1_regs_r) { return m_tmap1_regs[offs WRITE16_MEMBER(gcm394_base_video_device::tmap1_regs_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::tmap1_regs_w %01x %04x\n", machine().describe_context(), offset, data); + LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap1_regs_w %01x %04x\n", machine().describe_context(), offset, data); write_tmap_regs(1, m_tmap1_regs, offset, data); } WRITE16_MEMBER(gcm394_base_video_device::tmap1_unk0_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::tmap0_unk0_w %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap1_unk0_w %04x\n", machine().describe_context(), data); + m_page2_addr = data; } WRITE16_MEMBER(gcm394_base_video_device::tmap1_unk1_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::tmap0_unk0_w %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_GCM394_TMAP, "%s:gcm394_base_video_device::tmap1_unk1_w %04x\n", machine().describe_context(), data); } // **************************************** unknown video device 0 (another tilemap? sprite layer?) ************************************************* @@ -444,30 +586,77 @@ WRITE16_MEMBER(gcm394_base_video_device::unknown_video_device2_unk2_w) WRITE16_MEMBER(gcm394_base_video_device::video_dma_source_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::video_dma_source_w %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_GCM394_VIDEO_DMA, "%s:gcm394_base_video_device::video_dma_source_w %04x\n", machine().describe_context(), data); + m_videodma_source = data; } WRITE16_MEMBER(gcm394_base_video_device::video_dma_dest_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::video_dma_dest_w %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_GCM394_VIDEO_DMA, "%s:gcm394_base_video_device::video_dma_dest_w %04x\n", machine().describe_context(), data); + m_videodma_dest = data; } READ16_MEMBER(gcm394_base_video_device::video_dma_size_r) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::video_dma_size_r\n", machine().describe_context()); + LOGMASKED(LOG_GCM394_VIDEO_DMA, "%s:gcm394_base_video_device::video_dma_size_r\n", machine().describe_context()); return 0x0000; } WRITE16_MEMBER(gcm394_base_video_device::video_dma_size_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::video_dma_size_w %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_GCM394_VIDEO_DMA, "%s:gcm394_base_video_device::video_dma_size_w %04x\n", machine().describe_context(), data); + m_videodma_size = data; + + LOGMASKED(LOG_GCM394_VIDEO_DMA, "%s: doing sprite / video DMA source %04x dest %04x size %04x bank %04x\n", machine().describe_context(), m_videodma_source, m_videodma_dest, m_videodma_size, m_videodma_bank ); + + + if (m_videodma_dest == 0x7400) + { + if (m_videodma_bank == 0x0001) // transfers an additional word for each sprite with this bit set + { + m_videodma_size &= 0xff; + + for (int i = 0; i <= m_videodma_size; i++) + { + uint16_t dat = space.read_word(m_videodma_source+i); + m_spriteextra[i] = dat; + } + + } + else if (m_videodma_bank == 0x0000) + { + m_videodma_size &= 0x3ff; + + for (int i = 0; i <= m_videodma_size; i++) + { + uint16_t dat = space.read_word(m_videodma_source+i); + m_spriteram[i] = dat; + } + + } + else + { + logerror("unhandled: m_videodma_bank is %04x\n", m_videodma_bank); + } + } + else + { + logerror("unhandled: m_videodma_dest is %04x\n", m_videodma_dest); + } + + m_videodma_size = 0x0000; + } WRITE16_MEMBER(gcm394_base_video_device::video_dma_unk_w) { - LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::video_dma_unk_w %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_GCM394_VIDEO_DMA, "%s:gcm394_base_video_device::video_dma_unk_w %04x\n", machine().describe_context(), data); + m_videodma_bank = data; } + + + READ16_MEMBER(gcm394_base_video_device::video_707f_r) { LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::video_707f_r\n", machine().describe_context()); return m_707f; } WRITE16_MEMBER(gcm394_base_video_device::video_707f_w) { LOGMASKED(LOG_GCM394, "%s:gcm394_base_video_device::video_707f_w %04x\n", machine().describe_context(), data); m_707f = data; } @@ -520,3 +709,4 @@ WRITE_LINE_MEMBER(gcm394_base_video_device::vblank) check_video_irq(); } } + diff --git a/src/devices/machine/sunplus_gcm394_video.h b/src/devices/machine/sunplus_gcm394_video.h index 05a703f9f47..28ca2d0f1ff 100644 --- a/src/devices/machine/sunplus_gcm394_video.h +++ b/src/devices/machine/sunplus_gcm394_video.h @@ -14,7 +14,7 @@ #include "cpu/unsp/unsp.h" #include "screen.h" -class gcm394_base_video_device : public device_t +class gcm394_base_video_device : public device_t, public device_gfx_interface, public device_video_interface { public: gcm394_base_video_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -83,8 +83,7 @@ public: DECLARE_WRITE16_MEMBER(video_7088_w); DECLARE_READ16_MEMBER(video_7083_r); - - + auto write_video_irq_callback() { return m_video_irq_cb.bind(); }; protected: @@ -135,6 +134,8 @@ protected: template void draw(const rectangle &cliprect, uint32_t line, uint32_t xoff, uint32_t yoff, uint32_t bitmap_addr, uint16_t tile, int32_t h, int32_t w, uint8_t bpp, uint32_t yflipmask, uint32_t palette_offset); void draw_page(const rectangle &cliprect, uint32_t scanline, int priority, uint32_t bitmap_addr, uint16_t *regs); + void draw_sprites(const rectangle& cliprect, uint32_t scanline, int priority); + void draw_sprite(const rectangle& cliprect, uint32_t scanline, int priority, uint32_t base_addr); uint32_t m_screenbuf[320 * 240]; uint8_t m_rgb5_to_rgb8[32]; @@ -144,11 +145,15 @@ protected: required_device m_screen; // required_shared_ptr m_scrollram; required_shared_ptr m_paletteram; -// required_shared_ptr m_spriteram; + required_shared_ptr m_spriteram; uint16_t m_page1_addr; uint16_t m_page2_addr; + uint16_t m_videodma_bank; + uint16_t m_videodma_size; + uint16_t m_videodma_dest; + uint16_t m_videodma_source; devcb_write_line m_video_irq_cb; @@ -179,6 +184,8 @@ protected: uint16_t m_video_irq_status; + uint16_t m_spriteextra[0x100]; + uint16_t read_data(uint32_t offset); };