fmtowns: handle alternating layer memory layout used by simearth (nw)

This commit is contained in:
cracyc 2018-02-07 15:31:32 -06:00
parent 304abd860c
commit b95700a403
3 changed files with 33 additions and 9 deletions

View File

@ -2205,7 +2205,8 @@ static ADDRESS_MAP_START(towns_mem, AS_PROGRAM, 32, towns_state)
AM_RANGE(0x000f0000, 0x000f7fff) AM_RAM //READWRITE(SMH_BANK(12),SMH_BANK(12))
AM_RANGE(0x000f8000, 0x000fffff) AM_READ_BANK("bank11") AM_WRITE_BANK("bank12")
// AM_RANGE(0x00100000, 0x005fffff) AM_RAM // some extra RAM
AM_RANGE(0x80000000, 0x8007ffff) AM_READWRITE8(towns_gfx_high_r,towns_gfx_high_w,0xffffffff) AM_MIRROR(0x180000) // VRAM
AM_RANGE(0x80000000, 0x8007ffff) AM_READWRITE8(towns_gfx_high_r,towns_gfx_high_w,0xffffffff) AM_MIRROR(0x80000) // VRAM
AM_RANGE(0x80100000, 0x8017ffff) AM_READWRITE8(towns_gfx_packed_r,towns_gfx_packed_w,0xffffffff) AM_MIRROR(0x80000) // VRAM
AM_RANGE(0x81000000, 0x8101ffff) AM_READWRITE8(towns_spriteram_r,towns_spriteram_w,0xffffffff) // Sprite RAM
AM_RANGE(0xc0000000, 0xc0ffffff) AM_DEVREADWRITE8("icmemcard", fmt_icmem_device, static_mem_read, static_mem_write, 0xffffffff)
AM_RANGE(0xc1000000, 0xc1ffffff) AM_DEVREADWRITE8("icmemcard", fmt_icmem_device, mem_read, mem_write, 0xffffffff)

View File

@ -282,6 +282,8 @@ class towns_state : public driver_device
DECLARE_READ8_MEMBER(towns_gfx_high_r);
DECLARE_WRITE8_MEMBER(towns_gfx_high_w);
DECLARE_READ8_MEMBER(towns_gfx_packed_r);
DECLARE_WRITE8_MEMBER(towns_gfx_packed_w);
DECLARE_READ8_MEMBER(towns_gfx_r);
DECLARE_WRITE8_MEMBER(towns_gfx_w);
DECLARE_READ8_MEMBER(towns_video_cff80_r);

View File

@ -142,6 +142,20 @@ WRITE8_MEMBER( towns_state::towns_gfx_high_w )
m_towns_gfxvram[offset] = (mem & ~mask) | (data & mask);
}
READ8_MEMBER( towns_state::towns_gfx_packed_r )
{
return m_towns_gfxvram[bitswap<19>(offset,2,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,1,0)];
}
WRITE8_MEMBER( towns_state::towns_gfx_packed_w )
{
u8 mask = m_vram_mask[offset & 3];
offset = bitswap<19>(offset,2,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,1,0);
u8 mem = m_towns_gfxvram[offset];
m_towns_gfxvram[offset] = (mem & ~mask) | (data & mask);
}
READ8_MEMBER( towns_state::towns_gfx_r )
{
uint8_t ret = 0;
@ -1140,28 +1154,35 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect
page = 1;
}
linesize = m_video.towns_crtc_reg[20] * 8;
linesize = m_video.towns_crtc_reg[20] * 4;
if(!(m_video.towns_crtc_reg[28] & 0x20))
off += m_video.towns_crtc_reg[17] << 3; // initial offset
off += m_video.towns_crtc_reg[17] << 2; // initial offset
else
{
scroll = ((m_video.towns_crtc_reg[17] & 0xfc00) << 3) | (((m_video.towns_crtc_reg[17] & 0x3ff) << 3));
scroll = ((m_video.towns_crtc_reg[17] & 0xfc00) << 2) | (((m_video.towns_crtc_reg[17] & 0x3ff) << 2));
off += scroll;
}
hzoom = (m_video.towns_crtc_reg[27] & 0x000f) + 1;
off += (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]) / hzoom;
int subpix = (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]) / hzoom;
off += line * linesize;
off += (subpix >> 1) & ~3;
subpix = subpix & 7;
for(x=rect->min_x;x<rect->max_x;x+=hzoom)
{
off &= 0x7ffff; // 256 color mode is single-layer only
colour = m_towns_gfxvram[off];
off &= 0x3ffff;
colour = m_towns_gfxvram[off+(subpix >= 4 ? (subpix & 3)+0x40000 : subpix)];
for (pixel = 0; pixel < hzoom; pixel++)
bitmap.pix32(scanline, x+pixel) = m_palette->pen(colour);
off++;
if ((off - (page * 0x20000)) % linesize == 0)
subpix++;
if(subpix == 8)
{
off += 4;
subpix = 0;
}
if ((off - (page * 0x20000)) % linesize == 0 && subpix == 0)
off -= linesize;
}
}