mirror of
https://github.com/holub/mame
synced 2025-05-13 17:38:21 +03:00
mindset: Hackless graphics copro pass [O. Galibert]
This commit is contained in:
parent
1f9e370b8e
commit
8a1d3ce2c7
@ -26,6 +26,8 @@ protected:
|
|||||||
|
|
||||||
memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_gcos;
|
memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_gcos;
|
||||||
|
|
||||||
|
u16 m_dispctrl;
|
||||||
|
|
||||||
static u16 gco_blend_0(u16, u16);
|
static u16 gco_blend_0(u16, u16);
|
||||||
static u16 gco_blend_1(u16, u16);
|
static u16 gco_blend_1(u16, u16);
|
||||||
static u16 gco_blend_2(u16, u16);
|
static u16 gco_blend_2(u16, u16);
|
||||||
@ -43,7 +45,12 @@ protected:
|
|||||||
void maincpu_mem(address_map &map);
|
void maincpu_mem(address_map &map);
|
||||||
void maincpu_io(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);
|
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);
|
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)
|
u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||||
{
|
{
|
||||||
static const u32 pal[4] = { 0x000000, 0x555555, 0xaaaaaa, 0xffffff };
|
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::blit(u16 packet_seg, u16 packet_adr)
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
// 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 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_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)));
|
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 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 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 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 + 14) & 0xffff)));
|
||||||
u16 sy = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 16) & 0xffff)));
|
u16 dy = 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 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 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 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 wmask = 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)));
|
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');
|
||||||
|
|
||||||
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);
|
// 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)
|
||||||
|
|
||||||
logerror("GCO: p 9:%04x d:%04x\n", v9, vd);
|
auto blend = gco_blend[(mode >> 2) & 7];
|
||||||
|
|
||||||
if(global_mode == 0x0101) {
|
u16 awmask = ((wmask << 16) | wmask) >> (15 - dst_sft);
|
||||||
auto blend = gco_blend[(mode >> 2) & 7];
|
u16 swmask, mwmask, ewmask;
|
||||||
|
if(dst_sft >= width) {
|
||||||
u16 wmask = ((mask << 16) | mask) >> (15 - dst_sft);
|
swmask = msk(dst_sft+1) & ~msk(dst_sft - width + 1);
|
||||||
u16 swmask, mwmask, ewmask;
|
mwmask = 0xffff;
|
||||||
if(dst_sft >= width) {
|
ewmask = swmask;
|
||||||
swmask = msk(dst_sft+1) & ~msk(dst_sft - width + 1) & wmask;
|
} else {
|
||||||
mwmask = 0;
|
swmask = msk(dst_sft+1);
|
||||||
ewmask = 0;
|
mwmask = 0xffff;
|
||||||
} else {
|
ewmask = ~msk((dst_sft - width + 1) & 15);
|
||||||
swmask = msk(dst_sft+1) & wmask;
|
|
||||||
mwmask = wmask;
|
|
||||||
ewmask = (~msk((dst_sft - width + 1) & 15)) & wmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 nw = ((width + (15 - dst_sft)) + 15) >> 4;
|
|
||||||
logerror("GCO: m %04x %04x %04x nw %x\n", swmask, mwmask, ewmask, nw);
|
|
||||||
|
|
||||||
if(!done)
|
|
||||||
for(u32 y=0; y<height; y++) {
|
|
||||||
u16 src_cadr = src_adr;
|
|
||||||
u16 dst_cadr = dst_adr;
|
|
||||||
|
|
||||||
u16 cmask = swmask;
|
|
||||||
u16 nw1 = nw;
|
|
||||||
u32 srcs = sw(m_gcos->read_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);
|
|
||||||
|
|
||||||
// Gross hack number one
|
|
||||||
if(mode == 0x0140 && dst == 0xffff)
|
|
||||||
res = 0xffff;
|
|
||||||
|
|
||||||
m_gcos->write_word((dst_seg << 4) + dst_cadr, sw(res));
|
|
||||||
src_cadr += sx;
|
|
||||||
dst_cadr += sx;
|
|
||||||
|
|
||||||
nw1 --;
|
|
||||||
|
|
||||||
cmask = nw1 == 1 ? ewmask : mwmask;
|
|
||||||
} while(nw1);
|
|
||||||
|
|
||||||
src_adr += sy;
|
|
||||||
dst_adr += sy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 100 = done, 400 = collision?
|
swmask &= awmask;
|
||||||
|
mwmask &= awmask;
|
||||||
|
ewmask &= awmask;
|
||||||
|
|
||||||
|
u16 nw = ((width + (15 - dst_sft)) + 15) >> 4;
|
||||||
|
|
||||||
|
for(u32 y=0; y<height; y++) {
|
||||||
|
u16 src_cadr = src_adr;
|
||||||
|
u16 dst_cadr = dst_adr;
|
||||||
|
|
||||||
|
u16 cmask = swmask;
|
||||||
|
u16 nw1 = nw;
|
||||||
|
u32 srcs = sw(m_gcos->read_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = (dst & ~cmask) | (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;
|
||||||
|
|
||||||
|
nw1 --;
|
||||||
|
|
||||||
|
cmask = nw1 == 1 ? ewmask : mwmask;
|
||||||
|
} while(nw1);
|
||||||
|
|
||||||
|
src_adr += sy;
|
||||||
|
dst_adr += dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
logerror("GCO: start %04x:%04x mode %04x (%05x)\n", packet_seg, packet_adr, global_mode, m_maincpu->pc());
|
||||||
|
|
||||||
|
switch(global_mode) {
|
||||||
|
case 0x0101:
|
||||||
|
blit(packet_seg, packet_adr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 100 = done, 200 = done too???, 400 = collision?
|
||||||
m_gcos->write_word(0xbfd74, m_gcos->read_word(0xbfd74) | 0x0700);
|
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)
|
void mindset_state::maincpu_mem(address_map &map)
|
||||||
{
|
{
|
||||||
map(0x00000, 0x07fff).ram();
|
map(0x00000, 0x3ffff).ram();
|
||||||
map(0xb8000, 0xbffff).ram().share("vram");
|
map(0xb8000, 0xbffff).ram().share("vram");
|
||||||
map(0xf8000, 0xfffff).rom().region("maincpu", 0);
|
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(0x8300, 0x8301).w(FUNC(mindset_state::gco_w));
|
||||||
map(0x8320, 0x8321).lr16("8320", []() -> u16 { return 0xa005; }); // To pass the display test
|
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)
|
void mindset_state::mindset(machine_config &config)
|
||||||
|
Loading…
Reference in New Issue
Block a user