mirror of
https://github.com/holub/mame
synced 2025-05-15 18:32:02 +03:00
mindset: Implement or fake the display and graphics copro test, the system switches to a tilemap mode for the followup tests [O. Galibert]
This commit is contained in:
parent
5815ddcf8a
commit
fbadcd34a3
@ -24,12 +24,34 @@ protected:
|
||||
required_device<screen_device> m_screen;
|
||||
required_shared_ptr<u16> m_vram;
|
||||
|
||||
memory_access_cache<1, 0, ENDIANNESS_LITTLE> *m_gcos;
|
||||
|
||||
static u16 gco_blend_0(u16, u16);
|
||||
static u16 gco_blend_1(u16, u16);
|
||||
static u16 gco_blend_2(u16, u16);
|
||||
static u16 gco_blend_3(u16, u16);
|
||||
static u16 gco_blend_4(u16, u16);
|
||||
static u16 gco_blend_5(u16, u16);
|
||||
static u16 gco_blend_6(u16, u16);
|
||||
static u16 gco_blend_7(u16, u16);
|
||||
|
||||
static u16 (*const gco_blend[8])(u16, u16);
|
||||
|
||||
static inline u16 msk(int bit) { return (1U << bit) - 1; }
|
||||
static inline u16 sw(u16 data) { return (data >> 8) | (data << 8); }
|
||||
|
||||
void maincpu_mem(address_map &map);
|
||||
void maincpu_io(address_map &map);
|
||||
|
||||
void gco_w(u16 data);
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
};
|
||||
|
||||
|
||||
mindset_state::mindset_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
@ -40,29 +62,201 @@ mindset_state::mindset_state(const machine_config &mconfig, device_type type, co
|
||||
{
|
||||
}
|
||||
|
||||
void mindset_state::machine_start()
|
||||
{
|
||||
m_gcos = m_maincpu->space(AS_PROGRAM).cache<1, 0, ENDIANNESS_LITTLE>();
|
||||
}
|
||||
|
||||
void mindset_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
u32 mindset_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
static const u32 pal[4] = { 0x000000, 0x555555, 0xaaaaaa, 0xffffff };
|
||||
|
||||
for(u32 y=0; y<200; y++) {
|
||||
// Interleaved
|
||||
const u16 *src = m_vram + 40*(y >> 1) + 4096*(y & 1);
|
||||
u32 *dest = &bitmap.pix32(y);
|
||||
for(u32 x=0; x<320; x+=8) {
|
||||
u16 sv = *src++;
|
||||
*dest++ = pal[(sv >> 6) & 3];
|
||||
*dest++ = pal[(sv >> 4) & 3];
|
||||
*dest++ = pal[(sv >> 2) & 3];
|
||||
*dest++ = pal[(sv >> 0) & 3];
|
||||
*dest++ = pal[(sv >> 14) & 3];
|
||||
*dest++ = pal[(sv >> 12) & 3];
|
||||
*dest++ = pal[(sv >> 10) & 3];
|
||||
*dest++ = pal[(sv >> 8) & 3];
|
||||
if(false) {
|
||||
for(u32 y=0; y<200; y++) {
|
||||
// Interleaved
|
||||
const u16 *src = m_vram + 40*(y >> 1) + 4096*(y & 1);
|
||||
u32 *dest = &bitmap.pix32(y);
|
||||
for(u32 x=0; x<320; x+=8) {
|
||||
u16 sv = *src++;
|
||||
*dest++ = pal[(sv >> 6) & 3];
|
||||
*dest++ = pal[(sv >> 4) & 3];
|
||||
*dest++ = pal[(sv >> 2) & 3];
|
||||
*dest++ = pal[(sv >> 0) & 3];
|
||||
*dest++ = pal[(sv >> 14) & 3];
|
||||
*dest++ = pal[(sv >> 12) & 3];
|
||||
*dest++ = pal[(sv >> 10) & 3];
|
||||
*dest++ = pal[(sv >> 8) & 3];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(u32 y=0; y<25; y++) {
|
||||
for(u32 x=0; x<40; x++) {
|
||||
u16 val = m_vram[y*40+x];
|
||||
const u16 *src = m_vram + 0x1000 + ((val >> 1) & 0x7f);
|
||||
for(u32 yy=0; yy<8; yy++) {
|
||||
u8 pix = val & 1 ? *src >> 8 : *src;
|
||||
src += 128;
|
||||
u32 *dest = &bitmap.pix32(8*y+yy, 8*x);
|
||||
for(u32 xx=0; xx<8; xx++)
|
||||
*dest++ = pix & (0x80 >> xx) ? 0xffffff : 0x000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_0(u16 src, u16)
|
||||
{
|
||||
return src;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_1(u16 src, u16 dst)
|
||||
{
|
||||
return src & dst;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_2(u16 src, u16 dst)
|
||||
{
|
||||
return src | dst;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_3(u16 src, u16 dst)
|
||||
{
|
||||
return src ^ dst;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_4(u16 src, u16)
|
||||
{
|
||||
return ~src;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_5(u16 src, u16 dst)
|
||||
{
|
||||
return (~src) & dst;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_6(u16 src, u16 dst)
|
||||
{
|
||||
return (~src) | dst;
|
||||
}
|
||||
|
||||
u16 mindset_state::gco_blend_7(u16 src, u16 dst)
|
||||
{
|
||||
return (~src) ^ dst;
|
||||
}
|
||||
|
||||
u16 (*const mindset_state::gco_blend[8])(u16, u16) = {
|
||||
gco_blend_0,
|
||||
gco_blend_1,
|
||||
gco_blend_2,
|
||||
gco_blend_3,
|
||||
gco_blend_4,
|
||||
gco_blend_5,
|
||||
gco_blend_6,
|
||||
gco_blend_7
|
||||
};
|
||||
|
||||
|
||||
static bool done = false;
|
||||
|
||||
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 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 dst_adr = sw(m_gcos->read_word((packet_seg << 4) + ((packet_adr + 6) & 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 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 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 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?
|
||||
m_gcos->write_word(0xbfd74, m_gcos->read_word(0xbfd74) | 0x0500);
|
||||
}
|
||||
|
||||
void mindset_state::maincpu_mem(address_map &map)
|
||||
{
|
||||
@ -73,24 +267,27 @@ void mindset_state::maincpu_mem(address_map &map)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void mindset_state::mindset(machine_config &config)
|
||||
{
|
||||
I80186(config, m_maincpu, 6000000);
|
||||
I80186(config, m_maincpu, 12_MHz_XTAL/2);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &mindset_state::maincpu_mem);
|
||||
m_maincpu->set_addrmap(AS_IO, &mindset_state::maincpu_io);
|
||||
|
||||
I8042(config, m_syscpu, 6000000);
|
||||
I8042(config, m_syscpu, 12_MHz_XTAL/2);
|
||||
|
||||
I8042(config, m_soundcpu, 6000000);
|
||||
I8042(config, m_soundcpu, 12_MHz_XTAL/2);
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_refresh_hz(60);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(100));
|
||||
m_screen->set_size(320, 200);
|
||||
m_screen->set_visarea(0, 319, 0, 199);
|
||||
m_screen->set_screen_update(FUNC(mindset_state::screen_update));
|
||||
m_screen->screen_vblank().set(m_maincpu, FUNC(i80186_cpu_device::int1_w));
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START(mindset)
|
||||
|
Loading…
Reference in New Issue
Block a user