From e370f5432e54fbef66eecb365df3154dd858c89e Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Tue, 16 Apr 2024 14:49:44 +0200 Subject: [PATCH] bmc/koftball: decode bitmap layer, add back layer pen (#12255) --- src/mame/bmc/koftball.cpp | 108 ++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/src/mame/bmc/koftball.cpp b/src/mame/bmc/koftball.cpp index d6f5ac4489d..994518a229a 100644 --- a/src/mame/bmc/koftball.cpp +++ b/src/mame/bmc/koftball.cpp @@ -7,15 +7,12 @@ King Of Football (c)1995 BMC preliminary driver by Tomasz Slanina TODO: -- uses a 'pixmap' like bmc/bmcpokr.cpp. Noted uses are for jxzh's test mode and bookkeeping. - For now implementation is just copied over, but it needs to be adapted; - lots of unknown writes / reads; - one of the customs could contain a VIA6522-like core. bmc/bmcbowl.cpp uses the VIA6522 and the accesses are similar; - probably jxzh also supports the mahjong keyboard. Check if one of the dips enable it and where it is read; - better understanding of the koftball protection; -- hardware has a lot in common with that in bmc/bmcpokr.cpp. Merge? -- @@ -91,7 +88,6 @@ public: protected: virtual void machine_start() override; virtual void video_start() override; - virtual void device_post_load() override; private: required_device m_maincpu; @@ -105,6 +101,7 @@ private: uint8_t m_irq_enable = 0; uint8_t m_gfx_ctrl = 0; uint8_t m_priority = 0; + uint8_t m_backpen = 0; std::unique_ptr m_pixbitmap; uint8_t m_pixpal = 0; @@ -112,12 +109,14 @@ private: uint16_t random_number_r(); uint16_t prot_r(); void prot_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void pixbitmap_redraw(); - void pixram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void pixpal_w(offs_t offset, uint8_t data, uint8_t mem_mask = ~0); template void videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + template TILE_GET_INFO_MEMBER(get_tile_info); + void draw_pixlayer(bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_DEVICE_CALLBACK_MEMBER(interrupt); void jxzh_mem(address_map &map); void koftball_mem(address_map &map); @@ -133,6 +132,7 @@ void koftball_state::machine_start() save_item(NAME(m_irq_enable)); save_item(NAME(m_gfx_ctrl)); save_item(NAME(m_priority)); + save_item(NAME(m_backpen)); save_item(NAME(m_pixpal)); } @@ -143,58 +143,9 @@ TILE_GET_INFO_MEMBER(koftball_state::get_tile_info) tileinfo.set(0, data, 0, 0); } -// TODO: the following 'pixpal' methods were copied from bmc/bmcpokr.cpp. They need adapting. - -void koftball_state::pixram_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_pixram[offset]); - - int const x = (offset & 0xff) << 2; - int const y = (offset >> 8); - - uint16_t const pixpal = (m_pixpal & 0xf) << 4; - - uint16_t pen; - if (ACCESSING_BITS_8_15) - { - pen = (data >> 12) & 0xf; m_pixbitmap->pix(y, x + 0) = pen ? pixpal + pen : 0; - pen = (data >> 8) & 0xf; m_pixbitmap->pix(y, x + 1) = pen ? pixpal + pen : 0; - } - if (ACCESSING_BITS_0_7) - { - pen = (data >> 4) & 0xf; m_pixbitmap->pix(y, x + 2) = pen ? pixpal + pen : 0; - pen = (data >> 0) & 0xf; m_pixbitmap->pix(y, x + 3) = pen ? pixpal + pen : 0; - } -} - -void koftball_state::pixbitmap_redraw() -{ - uint16_t const pixpal = (m_pixpal & 0xf) << 4; - int offset = 0; - for (int y = 0; y < 512; y++) - { - for (int x = 0; x < 1024; x += 4) - { - uint16_t const data = m_pixram[offset++]; - uint16_t pen; - pen = (data >> 12) & 0xf; m_pixbitmap->pix(y, x + 0) = pen ? pixpal + pen : 0; - pen = (data >> 8) & 0xf; m_pixbitmap->pix(y, x + 1) = pen ? pixpal + pen : 0; - pen = (data >> 4) & 0xf; m_pixbitmap->pix(y, x + 2) = pen ? pixpal + pen : 0; - pen = (data >> 0) & 0xf; m_pixbitmap->pix(y, x + 3) = pen ? pixpal + pen : 0; - } - } -} - void koftball_state::pixpal_w(offs_t offset, uint8_t data, uint8_t mem_mask) { - uint8_t const old = m_pixpal; - if (old != COMBINE_DATA(&m_pixpal)) - pixbitmap_redraw(); -} - -void koftball_state::device_post_load() -{ - pixbitmap_redraw(); + COMBINE_DATA(&m_pixpal); } void koftball_state::video_start() @@ -207,7 +158,31 @@ void koftball_state::video_start() m_tilemap[0]->set_transparent_pen(0); m_tilemap[2]->set_transparent_pen(0); - m_pixbitmap = std::make_unique(0x400, 0x200); + m_tilemap[1]->set_transparent_pen(0); + m_tilemap[3]->set_transparent_pen(0); + + m_pixbitmap = std::make_unique(512, 256); +} + +// linear 512x256x4bpp +void koftball_state::draw_pixlayer(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + const u8 pix_bank = (m_pixpal & 0xf) << 4; + + for (int y = cliprect.min_y; y <= cliprect.max_y; y++) + { + const u16 pitch = y * 0x80; + for (int x = cliprect.min_x; x <= cliprect.max_x >> 2; x++) + { + const u16 tile_data = m_pixram[(pitch + x) & 0xffff]; + for (int xi = 0; xi < 4; xi ++) + { + const u8 nibble = (tile_data >> ((3 - xi) * 4)) & 0xf; + if (nibble) + bitmap.pix(y, (x << 2) + xi) = pix_bank | nibble; + } + } + } } uint32_t koftball_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -238,10 +213,16 @@ uint32_t koftball_state::screen_update(screen_device &screen, bitmap_ind16 &bitm girl select after coin up prev screen prev screen over under 0x13 0x3a */ + m_pixbitmap->fill(0, cliprect); + draw_pixlayer(*m_pixbitmap, cliprect); + + bitmap.fill(m_backpen, cliprect); + if (BIT(m_priority, 3)) copyscrollbitmap_trans(bitmap, *m_pixbitmap, 0, 0, 0, 0, cliprect, 0); - if (BIT(m_gfx_ctrl, 5)) // TODO: or bit 1? + // TODO: or bit 1? + if (BIT(m_gfx_ctrl, 5)) { m_tilemap[3]->draw(screen, bitmap, cliprect, 0, 0); m_tilemap[2]->draw(screen, bitmap, cliprect, 0, 0); @@ -297,6 +278,7 @@ void koftball_state::irq_ack_w(uint8_t data) m_maincpu->set_input_line(i, CLEAR_LINE); } +// FIXME: merge video maps void koftball_state::koftball_mem(address_map &map) { map(0x000000, 0x01ffff).rom(); @@ -308,11 +290,12 @@ void koftball_state::koftball_mem(address_map &map) map(0x263000, 0x263fff).ram().w(FUNC(koftball_state::videoram_w<3>)).share(m_videoram[3]); map(0x268000, 0x26ffff).ram(); - map(0x280000, 0x29ffff).ram().w(FUNC(koftball_state::pixram_w)).share(m_pixram); + map(0x280000, 0x29ffff).ram().share(m_pixram); map(0x2a0007, 0x2a0007).w(FUNC(koftball_state::irq_ack_w)); map(0x2a0009, 0x2a0009).lw8(NAME([this] (uint8_t data) { m_irq_enable = data; })); - map(0x2a000f, 0x2a000f).lw8(NAME([this] (uint8_t data) { m_priority = data; LOGGFX("GFX ctrl 2a000f %02x\n", data); })); + map(0x2a000f, 0x2a000f).lw8(NAME([this] (uint8_t data) { m_priority = data; LOGGFX("GFX ctrl $2a000f (priority) %02x\n", data); })); map(0x2a0017, 0x2a0017).w(FUNC(koftball_state::pixpal_w)); + map(0x2a0019, 0x2a0019).lw8(NAME([this] (uint8_t data) { m_backpen = data; LOGGFX("GFX ctrl $2a0019 (backpen) %02x\n", data); })); map(0x2a001a, 0x2a001b).nopw(); map(0x2a0000, 0x2a001f).r(FUNC(koftball_state::random_number_r)); map(0x2b0000, 0x2b0001).portr("DSW"); @@ -344,11 +327,12 @@ void koftball_state::jxzh_mem(address_map &map) map(0x264b00, 0x264dff).ram(); // TODO: writes here at least at girl selection after coin up. Some kind of effect? map(0x268000, 0x26ffff).ram(); - map(0x280000, 0x29ffff).ram().w(FUNC(koftball_state::pixram_w)).share(m_pixram); + map(0x280000, 0x29ffff).ram().share(m_pixram); map(0x2a0007, 0x2a0007).w(FUNC(koftball_state::irq_ack_w)); map(0x2a0009, 0x2a0009).lw8(NAME([this] (uint8_t data) { m_irq_enable = data; })); - map(0x2a000f, 0x2a000f).lw8(NAME([this] (uint8_t data) { m_priority = data; LOGGFX("GFX ctrl 2a000f %02x\n", data); })); + map(0x2a000f, 0x2a000f).lw8(NAME([this] (uint8_t data) { m_priority = data; LOGGFX("GFX ctrl $2a000f (priority) %02x\n", data); })); map(0x2a0017, 0x2a0017).w(FUNC(koftball_state::pixpal_w)); + map(0x2a0019, 0x2a0019).lw8(NAME([this] (uint8_t data) { m_backpen = data; LOGGFX("GFX ctrl $2a0019 (backpen) %02x\n", data); })); map(0x2a001a, 0x2a001d).nopw(); map(0x2a0000, 0x2a001f).r(FUNC(koftball_state::random_number_r)); map(0x2b0000, 0x2b0001).portr("DSW");