From 8a1d3ce2c7963d14c849f46ddf5be411d40f9f08 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Tue, 11 Jun 2019 14:02:38 +0200 Subject: mindset: Hackless graphics copro pass [O. Galibert] --- src/mame/drivers/mindset.cpp | 199 +++++++++++++++++++++++++++---------------- 1 file changed, 127 insertions(+), 72 deletions(-) diff --git a/src/mame/drivers/mindset.cpp b/src/mame/drivers/mindset.cpp index 59fd50a2694..c2e27adc259 100644 --- a/src/mame/drivers/mindset.cpp +++ b/src/mame/drivers/mindset.cpp @@ -26,6 +26,8 @@ protected: memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_gcos; + u16 m_dispctrl; + static u16 gco_blend_0(u16, u16); static u16 gco_blend_1(u16, u16); static u16 gco_blend_2(u16, u16); @@ -43,7 +45,12 @@ protected: void maincpu_mem(address_map &map); void maincpu_io(address_map &map); + void display_mode(); + void blit(u16 packet_seg, u16 packet_adr); + void gco_w(u16 data); + u16 dispctrl_r(); + void dispctrl_w(u16 data); u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -71,6 +78,17 @@ void mindset_state::machine_reset() { } +u16 mindset_state::dispctrl_r() +{ + return m_dispctrl; +} + +void mindset_state::dispctrl_w(u16 data) +{ + m_dispctrl = data; + // logerror("display control %04x\n", data); +} + u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { static const u32 pal[4] = { 0x000000, 0x555555, 0xaaaaaa, 0xffffff }; @@ -179,18 +197,8 @@ u16 (*const mindset_state::gco_blend[8])(u16, u16) = { }; -static bool done = false; - -void mindset_state::gco_w(u16 data) +void mindset_state::blit(u16 packet_seg, u16 packet_adr) { - u16 packet_seg = sw(m_gcos->read_word(0xbfd7a)); - u16 packet_adr = sw(m_gcos->read_word(0xbfd78)); - - // Low byte could be packet count, high byte mode - u16 global_mode = sw(m_gcos->read_word(0xbfd76)); - - logerror("GCO: start %04x:%04x mode %04x (%05x)\n", packet_seg, packet_adr, global_mode, m_maincpu->pc()); - u16 mode = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 0) & 0xffff))); u16 src_adr = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 2) & 0xffff))); u16 src_sft = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 4) & 0xffff))); @@ -198,85 +206,131 @@ void mindset_state::gco_w(u16 data) u16 dst_sft = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 8) & 0xffff))); u16 width = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 10) & 0xffff))); u16 height = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 12) & 0xffff))); - u16 sx = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 14) & 0xffff))); - u16 sy = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 16) & 0xffff))); - u16 v9 = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 18) & 0xffff))); + u16 sy = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 14) & 0xffff))); + u16 dy = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 16) & 0xffff))); + u16 rmask = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 18) & 0xffff))); u16 src_seg = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 20) & 0xffff))); u16 dst_seg = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 22) & 0xffff))); - u16 mask = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 24) & 0xffff))); - u16 vd = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 26) & 0xffff))); - - logerror("GCO: p src %04x:%04x.%x dst %04x:%04x.%x sz %xx%x step %x:%x mode %04x mask %04x\n", src_seg, src_adr, src_sft, dst_seg, dst_adr, dst_sft, width, height, sx, sy, mode, mask); - - logerror("GCO: p 9:%04x d:%04x\n", v9, vd); - - if(global_mode == 0x0101) { - auto blend = gco_blend[(mode >> 2) & 7]; - - u16 wmask = ((mask << 16) | mask) >> (15 - dst_sft); - u16 swmask, mwmask, ewmask; - if(dst_sft >= width) { - swmask = msk(dst_sft+1) & ~msk(dst_sft - width + 1) & wmask; - mwmask = 0; - ewmask = 0; - } else { - swmask = msk(dst_sft+1) & wmask; - mwmask = wmask; - ewmask = (~msk((dst_sft - width + 1) & 15)) & wmask; - } + u16 wmask = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 24) & 0xffff))); + u16 kmask = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 26) & 0xffff))); + logerror("GCO: p src %04x:%04x.%x dst %04x:%04x.%x sz %xx%x step %x:%x mask %04x:%04x k %x:%x mode %c%c%c%d%c%d%c%c%c\n", src_seg, src_adr, src_sft, dst_seg, dst_adr, dst_sft, width, height, sy, dy, rmask, wmask, (kmask >> 8) & 15, kmask & 15, + mode & 0x80 ? 'k' : '-', + mode & 0x40 ? 't' : 'o', + mode & 0x20 ? 'x' : '-', + (mode >> 2) & 7, + mode & 0x4000 ? 'f' : '-', + (mode >> 11) & 3, + mode & 0x400 ? 'n' : '-', + mode & 0x200 ? 'p' : '-', + mode & 0x100 ? 'i' : 'f'); + + // k = detect collision (unimplemented) + // t/o = transparent/opaque + // x = go right to left (unimplemented) + // f = fast (no idea what it means) + // n = invert collision flag (unimplemented) + // p = pattern fill (unimplemented, use by fill_dest_buffer) + // i/f = increment source / don't (unimplemented, compare with p?, used by blt_copy_word) + + auto blend = gco_blend[(mode >> 2) & 7]; + + u16 awmask = ((wmask << 16) | wmask) >> (15 - dst_sft); + u16 swmask, mwmask, ewmask; + if(dst_sft >= width) { + swmask = msk(dst_sft+1) & ~msk(dst_sft - width + 1); + mwmask = 0xffff; + ewmask = swmask; + } else { + swmask = msk(dst_sft+1); + mwmask = 0xffff; + ewmask = ~msk((dst_sft - width + 1) & 15); + } - u16 nw = ((width + (15 - dst_sft)) + 15) >> 4; - logerror("GCO: m %04x %04x %04x nw %x\n", swmask, mwmask, ewmask, nw); + swmask &= awmask; + mwmask &= awmask; + ewmask &= awmask; + + u16 nw = ((width + (15 - dst_sft)) + 15) >> 4; + + for(u32 y=0; yread_word((src_seg << 4) + src_cadr)); + src_cadr += 2; + do { + srcs = (srcs << 16) | sw(m_gcos->read_word((src_seg << 4) + src_cadr)); + u16 src = (srcs >> (src_sft + 1)) & rmask; + u16 dst = sw(m_gcos->read_word((dst_seg << 4) + dst_cadr)); + u16 res = blend(src, dst); + if(mode & 0x40) { + u16 tmask; + switch((mode >> 10) & 3) { + case 0: + tmask = dst; + break; + case 1: + tmask = ((dst & 0xaaaa) >> 1) | (dst & 0x5555); + tmask = tmask * 0x3; + break; + case 2: + tmask = ((dst & 0xcccc) >> 2) | (dst & 0x3333); + tmask = ((dst & 0x2222) >> 1) | (dst & 0x1111); + tmask = tmask * 0xf; + break; + case 3: + tmask = ((dst & 0xf0f0) >> 4) | (dst & 0x0f0f); + tmask = ((dst & 0x0c0c) >> 2) | (dst & 0x0303); + tmask = ((dst & 0x0202) >> 1) | (dst & 0x0101); + tmask = tmask * 0xff; + break; + } + cmask &= ~tmask; + } - if(!done) - for(u32 y=0; yread_word((src_seg << 4) + src_cadr)); - src_cadr += sx; - do { - srcs = (srcs << 16) | sw(m_gcos->read_word((src_seg << 4) + src_cadr)); - u16 src = srcs >> (src_sft + 1); - u16 dst = sw(m_gcos->read_word((dst_seg << 4) + dst_cadr)); - u16 res = (dst & ~cmask) | (blend(src, dst) & cmask); - logerror("GCO: %04x * %04x = %04x @ %04x\n", src, dst, res, cmask); + logerror("GCO: %04x * %04x = %04x @ %04x\n", src, dst, res, cmask); + + m_gcos->write_word((dst_seg << 4) + dst_cadr, sw(res)); + src_cadr += 2; + dst_cadr += 2; - // Gross hack number one - if(mode == 0x0140 && dst == 0xffff) - res = 0xffff; + nw1 --; - m_gcos->write_word((dst_seg << 4) + dst_cadr, sw(res)); - src_cadr += sx; - dst_cadr += sx; + cmask = nw1 == 1 ? ewmask : mwmask; + } while(nw1); - nw1 --; + src_adr += sy; + dst_adr += dy; + } +} - cmask = nw1 == 1 ? ewmask : mwmask; - } while(nw1); +void mindset_state::gco_w(u16 data) +{ + u16 packet_seg = sw(m_gcos->read_word(0xbfd7a)); + u16 packet_adr = sw(m_gcos->read_word(0xbfd78)); + u16 global_mode = sw(m_gcos->read_word(0xbfd76)); - src_adr += sy; - dst_adr += sy; - } + logerror("GCO: start %04x:%04x mode %04x (%05x)\n", packet_seg, packet_adr, global_mode, m_maincpu->pc()); - // Gross hack number two - if(!done) - if(sx == 0x50 && sy == 8) { - for(u32 i=0; i<16; i+=2) - m_gcos->write_word(0x1040 + i, m_gcos->read_word(0xf8000+0x6106 + i)); - done = true; - } + switch(global_mode) { + case 0x0101: + blit(packet_seg, packet_adr); + break; } - // 100 = done, 400 = collision? + // 100 = done, 200 = done too???, 400 = collision? m_gcos->write_word(0xbfd74, m_gcos->read_word(0xbfd74) | 0x0700); + + // Can trigger an irq, on mode & 2 (or is it 200?) (0x40 on 8282, ack on 0x41) } void mindset_state::maincpu_mem(address_map &map) { - map(0x00000, 0x07fff).ram(); + map(0x00000, 0x3ffff).ram(); map(0xb8000, 0xbffff).ram().share("vram"); map(0xf8000, 0xfffff).rom().region("maincpu", 0); } @@ -285,6 +339,7 @@ void mindset_state::maincpu_io(address_map &map) { map(0x8300, 0x8301).w(FUNC(mindset_state::gco_w)); map(0x8320, 0x8321).lr16("8320", []() -> u16 { return 0xa005; }); // To pass the display test + map(0x8322, 0x8323).rw(FUNC(mindset_state::dispctrl_r), FUNC(mindset_state::dispctrl_w)); } void mindset_state::mindset(machine_config &config) -- cgit v1.2.3