From fa2e536e67e6999b56816e304a9970a6d5bde7d6 Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 12 Nov 2020 23:41:28 +0900 Subject: [PATCH] undrfire.cpp: Hooked up TC0360PRI priority controller (fixes priorities in cbombers). (#7460) --- src/mame/drivers/undrfire.cpp | 6 +- src/mame/includes/undrfire.h | 5 +- src/mame/video/tc0360pri.cpp | 7 +- src/mame/video/undrfire.cpp | 130 ++++++++++++++++++++-------------- 4 files changed, 88 insertions(+), 60 deletions(-) diff --git a/src/mame/drivers/undrfire.cpp b/src/mame/drivers/undrfire.cpp index 8d8c062b492..0e708282336 100644 --- a/src/mame/drivers/undrfire.cpp +++ b/src/mame/drivers/undrfire.cpp @@ -76,7 +76,7 @@ Chase Bombers proto sports lots of gfx bugs; - Chase Bombers PCB has TC0360PRI but not hooked up + Sprites are delayed, but not yet implemented Gun calibration --------------- @@ -354,7 +354,7 @@ void undrfire_state::cbombers_cpua_map(address_map &map) map(0x900000, 0x90ffff).rw(m_tc0620scc, FUNC(tc0620scc_device::ram_r), FUNC(tc0620scc_device::ram_w)); /* 6bpp tilemaps */ map(0x920000, 0x92000f).rw(m_tc0620scc, FUNC(tc0620scc_device::ctrl_r), FUNC(tc0620scc_device::ctrl_w)); map(0xa00000, 0xa0ffff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette"); - map(0xb00000, 0xb0000f).ram(); /* TC0360PRI */ + map(0xb00000, 0xb0000f).rw(m_tc0360pri, FUNC(tc0360pri_device::read), FUNC(tc0360pri_device::write)); /* TC0360PRI */ map(0xc00000, 0xc00007).ram(); /* LAN controller? */ map(0xd00000, 0xd00003).w(FUNC(undrfire_state::rotate_control_w)); /* perhaps port based rotate control? */ map(0xe00000, 0xe0ffff).rw(FUNC(undrfire_state::shared_ram_r), FUNC(undrfire_state::shared_ram_w)); @@ -617,6 +617,8 @@ void undrfire_state::cbombers(machine_config &config) m_tc0480scp->set_offsets_tx(-1, 0); m_tc0480scp->set_col_base(4096); + TC0360PRI(config, m_tc0360pri, 0); + /* sound hardware */ SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); diff --git a/src/mame/includes/undrfire.h b/src/mame/includes/undrfire.h index 081cef08770..9486d22a022 100644 --- a/src/mame/includes/undrfire.h +++ b/src/mame/includes/undrfire.h @@ -7,6 +7,7 @@ #include "machine/eepromser.h" #include "video/tc0100scn.h" +#include "video/tc0360pri.h" #include "video/tc0480scp.h" #include "emupal.h" @@ -19,6 +20,7 @@ public: m_subcpu(*this, "sub"), m_tc0620scc(*this, "tc0620scc"), m_tc0480scp(*this, "tc0480scp"), + m_tc0360pri(*this, "tc0360pri"), m_eeprom(*this, "eeprom"), m_ram(*this, "ram"), m_shared_ram(*this, "shared_ram"), @@ -58,6 +60,7 @@ private: optional_device m_subcpu; required_device m_tc0620scc; required_device m_tc0480scp; + optional_device m_tc0360pri; // cbombers required_device m_eeprom; optional_shared_ptr m_ram; optional_shared_ptr m_shared_ram; @@ -89,7 +92,7 @@ private: u32 screen_update_cbombers(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(undrfire_interrupt); void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u32 *primasks,int x_offs,int y_offs); - void draw_sprites_cbombers(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u32 *primasks,int x_offs,int y_offs); + void draw_sprites_cbombers(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u8* pritable,int x_offs,int y_offs); void cbombers_cpua_map(address_map &map); void cbombers_cpub_map(address_map &map); diff --git a/src/mame/video/tc0360pri.cpp b/src/mame/video/tc0360pri.cpp index e672cfe7cf0..5d6d237c495 100644 --- a/src/mame/video/tc0360pri.cpp +++ b/src/mame/video/tc0360pri.cpp @@ -81,11 +81,10 @@ void tc0360pri_device::write(offs_t offset, u8 data) if (offset >= 0x0a) popmessage("write %02x to unused TC0360PRI reg %x", data, offset); #if 0 -#define regs m_regs popmessage("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - regs[0x00], regs[0x01], regs[0x02], regs[0x03], - regs[0x04], regs[0x05], regs[0x06], regs[0x07], - regs[0x08], regs[0x09]); + m_regs[0x00], m_regs[0x01], m_regs[0x02], m_regs[0x03], + m_regs[0x04], m_regs[0x05], m_regs[0x06], m_regs[0x07], + m_regs[0x08], m_regs[0x09]); #endif } diff --git a/src/mame/video/undrfire.cpp b/src/mame/video/undrfire.cpp index d0f07471fd7..1c6db5e3379 100644 --- a/src/mame/video/undrfire.cpp +++ b/src/mame/video/undrfire.cpp @@ -60,6 +60,7 @@ Heavy use is made of sprite zooming. [* 00=over BG0, 01=BG1, 10=BG2, 11=BG3 ] [or 00=over BG1, 01=BG2, 10=BG3, 11=BG3 ] + [or controlled by TC0360PRI ] ***************************************************************/ @@ -197,7 +198,7 @@ logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks); } -void undrfire_state::draw_sprites_cbombers(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u32 *primasks,int x_offs,int y_offs) +void undrfire_state::draw_sprites_cbombers(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,const u8 *pritable,int x_offs,int y_offs) { int sprites_flipscreen = 0; @@ -287,9 +288,9 @@ void undrfire_state::draw_sprites_cbombers(screen_device &screen, bitmap_ind16 & sprite_ptr->zoomx = zx << 12; sprite_ptr->zoomy = zy << 12; - if (primasks) + if (pritable) { - sprite_ptr->primask = primasks[priority]; + sprite_ptr->primask = u32(~1) << pritable[priority]; sprite_ptr++; } else @@ -463,17 +464,36 @@ u32 undrfire_state::screen_update_undrfire(screen_device &screen, bitmap_ind16 & } +/* + TC0360PRI Priority format for chase bombers + + Offset Bits Description + 7654 3210 + 00 0001 1100 Unknown + 01 0000 1111 Unknown + 04 xxxx ---- TC0480SCP Layer 3 Priority + ---- xxxx TC0480SCP Layer 2 Priority + 05 xxxx ---- TC0480SCP Layer 1 Priority + ---- xxxx TC0480SCP Layer 0 Priority + 06 xxxx ---- TC0480SCP Text Layer Priority + ---- 0000 Unknown + 07 xxxx ---- TC0620SCC Layer 0 Priority + ---- xxxx TC0620SCC Layer 1 Priority + 08 xxxx ---- Sprite Priority Bank 1 + ---- xxxx Sprite Priority Bank 0 + 09 xxxx ---- Sprite Priority Bank 3 + ---- xxxx Sprite Priority Bank 2 + + Values are 0 (Bottommost) ... f (Topmost) + Other registers are unknown/unused +*/ + u32 undrfire_state::screen_update_cbombers(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { u8 layer[5]; u8 scclayer[3]; #ifdef MAME_DEBUG - if (machine().input().code_pressed_once (KEYCODE_X)) - { - m_dislayer[5] ^= 1; - popmessage("scc text: %01x",m_dislayer[5]); - } if (machine().input().code_pressed_once (KEYCODE_C)) { m_dislayer[0] ^= 1; @@ -498,10 +518,16 @@ u32 undrfire_state::screen_update_cbombers(screen_device &screen, bitmap_ind16 & popmessage("bg3: %01x",m_dislayer[3]); } - if (machine().input().code_pressed_once (KEYCODE_M)) + if (machine().input().code_pressed_once (KEYCODE_X)) { m_dislayer[4] ^= 1; - popmessage("sprites: %01x",m_dislayer[4]); + popmessage("text: %01x",m_dislayer[4]); + } + + if (machine().input().code_pressed_once (KEYCODE_M)) + { + m_dislayer[5] ^= 1; + popmessage("sprites: %01x",m_dislayer[5]); } #endif @@ -520,63 +546,61 @@ u32 undrfire_state::screen_update_cbombers(screen_device &screen, bitmap_ind16 & scclayer[1] = scclayer[0] ^ 1; scclayer[2] = 2; + u8 tc0480scp_pri[5]; + u8 tc0620scc_pri[2]; + u8 sprite_pri[4]; + + // parse priority values + tc0480scp_pri[layer[0]] = m_tc0360pri->read(5) & 0x0f; + tc0480scp_pri[layer[1]] = (m_tc0360pri->read(5) >> 4) & 0x0f; + tc0480scp_pri[layer[2]] = m_tc0360pri->read(4) & 0x0f; + tc0480scp_pri[layer[3]] = (m_tc0360pri->read(4) >> 4) & 0x0f; + tc0480scp_pri[layer[4]] = (m_tc0360pri->read(6) >> 4) & 0x0f; + + tc0620scc_pri[scclayer[0]] = (m_tc0360pri->read(7) >> 4) & 0x0f; + tc0620scc_pri[scclayer[1]] = m_tc0360pri->read(7) & 0x0f; + + sprite_pri[0] = m_tc0360pri->read(8) & 0x0f; + sprite_pri[1] = (m_tc0360pri->read(8) >> 4) & 0x0f; + sprite_pri[2] = m_tc0360pri->read(9) & 0x0f; + sprite_pri[3] = (m_tc0360pri->read(9) >> 4) & 0x0f; + screen.priority().fill(0, cliprect); bitmap.fill(0, cliprect); /* wrong color? */ - -/* The "SCC" chip seems to be a 6bpp TC0100SCN. It has a - bottom layer usually full of bright garish colors that - vaguely mimic the structure of the layers on top. Seems - pointless - it's always hidden by other layers. Does it - serve some blending pupose ? */ - - // TODO : Wrong; TC0360PRI isn't hooked up - m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[0], TILEMAP_DRAW_OPAQUE, 0); - m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[1], 0, 0); - -#ifdef MAME_DEBUG - if (m_dislayer[layer[0]]==0) -#endif - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], 0, 1); - -#ifdef MAME_DEBUG - if (m_dislayer[layer[1]]==0) -#endif - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2); - -#ifdef MAME_DEBUG - if (m_dislayer[layer[2]]==0) -#endif - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4); - -#ifdef MAME_DEBUG - if (m_dislayer[layer[3]]==0) -#endif - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8); - -#ifdef MAME_DEBUG - if (m_dislayer[4]==0) -#endif - /* Sprites have variable priority (we kludge this on road levels) */ + for (int p = 0; p < 16; p++) { - if ((m_tc0480scp->pri_reg_r() & 0x3) == 3) /* on road levels kludge sprites up 1 priority */ + // TODO: verify layer order when multiple tilemap layers has same priority value + const u8 prival = p + 1; // +1 for pdrawgfx + + for (int scc = 0; scc < 2; scc++) { - static const u32 primasks[4] = {0xfff0, 0xff00, 0x0, 0x0}; - draw_sprites_cbombers(screen, bitmap, cliprect, primasks, 80, -208); + if (tc0620scc_pri[scclayer[scc]] == p) + m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[scc], (scc == 0) ? TILEMAP_DRAW_OPAQUE : 0, prival, 0); } - else + + for (int scp = 0; scp < 4; scp++) { - static const u32 primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0}; - draw_sprites_cbombers(screen, bitmap, cliprect, primasks, 80, -208); +#ifdef MAME_DEBUG + if (m_dislayer[layer[scp]]==0) +#endif + if (tc0480scp_pri[layer[scp]] == p) + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[scp], 0, prival, 0); } +#ifdef MAME_DEBUG + if (m_dislayer[layer[4]]==0) +#endif + if (tc0480scp_pri[layer[4]] == p) + m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, prival, 0); } + /* Sprites have variable priority */ #ifdef MAME_DEBUG if (m_dislayer[5]==0) #endif - m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[2], 0, 0); /* TC0620SCC text layer */ + draw_sprites_cbombers(screen, bitmap, cliprect, sprite_pri, 80, -208); - m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); /* TC0480SCP text layer */ + m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[2], 0, 0); // TODO: correct? /* Enable this to see rotation (?) control words */ #if 0