mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
x68k: fix 512 line double scan modes
This commit is contained in:
parent
5b2448c084
commit
daf27a573e
@ -203,11 +203,14 @@ void x68k_state::draw_text(bitmap_rgb32 &bitmap, int xscr, int yscr, rectangle r
|
||||
uint32_t loc; // location in TVRAM
|
||||
uint32_t colour;
|
||||
int bit;
|
||||
int divisor = 1;
|
||||
if(m_crtc->gfx_double_scan())
|
||||
divisor = 2;
|
||||
|
||||
for(line=rect.min_y;line<=rect.max_y;line++) // per scanline
|
||||
{
|
||||
// adjust for scroll registers
|
||||
loc = (((line - m_crtc->vbegin()) + yscr) & 0x3ff) * 64;
|
||||
loc = ((((line- m_crtc->vbegin()) / divisor) + yscr) & 0x3ff) * 64;
|
||||
loc += (xscr / 16) & 0x7f;
|
||||
loc &= 0xffff;
|
||||
bit = 15 - (xscr & 0x0f);
|
||||
@ -241,6 +244,9 @@ bool x68k_state::draw_gfx_scanline( bitmap_ind16 &bitmap, rectangle cliprect, ui
|
||||
int shift;
|
||||
bool blend, ret = false;
|
||||
uint16_t *pal = (uint16_t *)m_gfxpalette->basemem().base();
|
||||
int divisor = 1;
|
||||
if(m_crtc->gfx_double_scan())
|
||||
divisor = 2;
|
||||
|
||||
for(int scanline=cliprect.min_y;scanline<=cliprect.max_y;scanline++) // per scanline
|
||||
{
|
||||
@ -296,7 +302,7 @@ bool x68k_state::draw_gfx_scanline( bitmap_ind16 &bitmap, rectangle cliprect, ui
|
||||
case 0x00: // 16 colours
|
||||
xscr = m_crtc->xscr_gfx(page) & 0x1ff;
|
||||
yscr = m_crtc->yscr_gfx(page) & 0x1ff;
|
||||
lineoffset = (((scanline - m_crtc->vbegin()) + yscr) & 0x1ff) * 512;
|
||||
lineoffset = (((scanline - m_crtc->vbegin() / divisor) + yscr) & 0x1ff) * 512;
|
||||
loc = xscr & 0x1ff;
|
||||
shift = 4;
|
||||
if((m_video.reg[2] & 0x1a00) == 0x1a00)
|
||||
@ -342,7 +348,7 @@ bool x68k_state::draw_gfx_scanline( bitmap_ind16 &bitmap, rectangle cliprect, ui
|
||||
{
|
||||
xscr = m_crtc->xscr_gfx(page) & 0x1ff;
|
||||
yscr = m_crtc->yscr_gfx(page) & 0x1ff;
|
||||
lineoffset = (((scanline - m_crtc->vbegin()) + yscr) & 0x1ff) * 512;
|
||||
lineoffset = (((scanline - m_crtc->vbegin() / divisor) + yscr) & 0x1ff) * 512;
|
||||
loc = xscr & 0x1ff;
|
||||
shift = 4;
|
||||
if((m_video.reg[2] & 0x1a00) == 0x1a00)
|
||||
@ -387,7 +393,7 @@ bool x68k_state::draw_gfx_scanline( bitmap_ind16 &bitmap, rectangle cliprect, ui
|
||||
case 0x03: // 65536 colours
|
||||
xscr = m_crtc->xscr_gfx(0) & 0x1ff;
|
||||
yscr = m_crtc->yscr_gfx(0) & 0x1ff;
|
||||
lineoffset = (((scanline - m_crtc->vbegin()) + yscr) & 0x1ff) * 512;
|
||||
lineoffset = (((scanline - m_crtc->vbegin() / divisor) + yscr) & 0x1ff) * 512;
|
||||
loc = xscr & 0x1ff;
|
||||
for(pixel=m_crtc->hbegin();pixel<=m_crtc->hend();pixel++)
|
||||
{
|
||||
@ -409,20 +415,25 @@ void x68k_state::draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect)
|
||||
{
|
||||
int priority, scanline, pixel;
|
||||
bool gfxblend=false;
|
||||
//rectangle rect;
|
||||
//int xscr,yscr;
|
||||
//int gpage;
|
||||
rectangle gfxrect = cliprect;
|
||||
int divisor = 1;
|
||||
if(m_crtc->gfx_double_scan())
|
||||
{
|
||||
gfxrect.max_y >>= 1;
|
||||
gfxrect.min_y >>= 1;
|
||||
divisor = 2;
|
||||
}
|
||||
|
||||
if(m_crtc->gfx_layer_buffer()) // if graphic layers are set to buffer, then they aren't visible
|
||||
return;
|
||||
|
||||
m_gfxbitmap.fill(0, cliprect);
|
||||
m_gfxbitmap.fill(0, gfxrect);
|
||||
if((m_video.reg[2] & 0x1800) == 0x1000)
|
||||
m_special.fill(0, cliprect);
|
||||
m_special.fill(0, gfxrect);
|
||||
|
||||
for(priority=3;priority>=0;priority--)
|
||||
{
|
||||
gfxblend = draw_gfx_scanline(m_gfxbitmap,cliprect,priority);
|
||||
gfxblend = draw_gfx_scanline(m_gfxbitmap,gfxrect,priority);
|
||||
}
|
||||
|
||||
for(scanline=cliprect.min_y;scanline<=cliprect.max_y;scanline++)
|
||||
@ -433,13 +444,13 @@ void x68k_state::draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect)
|
||||
{
|
||||
if((m_video.reg[0] & 0x03) == 3)
|
||||
{
|
||||
colour = m_gfxbitmap.pix(scanline, pixel);
|
||||
colour = m_gfxbitmap.pix(scanline / divisor, pixel);
|
||||
if(colour || (m_video.gfx_pri == 2))
|
||||
bitmap.pix(scanline, pixel) = GGGGGRRRRRBBBBBI(colour);
|
||||
}
|
||||
else if(gfxblend)
|
||||
{
|
||||
colour = m_gfxbitmap.pix(scanline, pixel);
|
||||
colour = m_gfxbitmap.pix(scanline / divisor, pixel);
|
||||
if(((m_video.reg[2] & 0x1900) == 0x1900) && (m_video.gfx_pri != 2) && (colour & 1))
|
||||
blend = true;
|
||||
else
|
||||
@ -454,7 +465,7 @@ void x68k_state::draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect)
|
||||
}
|
||||
else
|
||||
{
|
||||
colour = m_gfxbitmap.pix(scanline, pixel) & 0xff;
|
||||
colour = m_gfxbitmap.pix(scanline / divisor, pixel) & 0xff;
|
||||
if(((m_video.reg[2] & 0x1900) == 0x1900) && (m_video.gfx_pri != 2) && (colour & 1))
|
||||
{
|
||||
blend = true;
|
||||
@ -507,6 +518,9 @@ void x68k_state::draw_sprites(bitmap_ind16 &bitmap, int priority, rectangle clip
|
||||
b1-0, H-Res (0 = 8x8 tilemaps, 1 = 16x16 tilemaps, 2 or 3 = unknown)
|
||||
*/
|
||||
int ptr,pri;
|
||||
int divisor = 1;
|
||||
if(!(m_video.bg_hvres & 0x0c) && m_crtc->gfx_double_scan())
|
||||
divisor = 2;
|
||||
|
||||
for(ptr=508;ptr>=0;ptr-=4) // stepping through sprites
|
||||
{
|
||||
@ -532,7 +546,7 @@ void x68k_state::draw_sprites(bitmap_ind16 &bitmap, int priority, rectangle clip
|
||||
sx += m_video.bg_hshift;
|
||||
sx += m_sprite_shift;
|
||||
|
||||
m_gfxdecode->gfx(1)->zoom_transpen(bitmap,cliprect,code,colour,xflip,yflip,m_crtc->hbegin()+sx,m_crtc->vbegin()+(sy*m_video.bg_double),0x10000,0x10000*m_video.bg_double,0x00);
|
||||
m_gfxdecode->gfx(1)->zoom_transpen(bitmap,cliprect,code,colour,xflip,yflip,m_crtc->hbegin()+sx,(m_crtc->vbegin() / divisor)+(sy*m_video.bg_double),0x10000,0x10000*m_video.bg_double,0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,6 +558,9 @@ void x68k_state::draw_bg(bitmap_ind16 &bitmap, screen_device &screen, int layer,
|
||||
tilemap_t* x68k_bg0;
|
||||
tilemap_t* x68k_bg1;
|
||||
tilemap_t* map;
|
||||
int divisor = 1;
|
||||
if(!(m_video.bg_hvres & 0x0c) && m_crtc->gfx_double_scan())
|
||||
divisor = 2;
|
||||
|
||||
if((m_spritereg[0x408] & 0x03) == 0x00) // Sprite/BG H-Res 0=8x8, 1=16x16, 2 or 3 = undefined.
|
||||
{
|
||||
@ -562,7 +579,7 @@ void x68k_state::draw_bg(bitmap_ind16 &bitmap, screen_device &screen, int layer,
|
||||
map = (m_spritereg[0x404] & 0x0006) == 0x02 ? x68k_bg0 : x68k_bg1;
|
||||
|
||||
map->set_scrollx(0,(sclx - m_crtc->hbegin() - m_video.bg_hshift) & 0x3ff);
|
||||
map->set_scrolly(0,(scly - m_crtc->vbegin()) & 0x3ff);
|
||||
map->set_scrolly(0,(scly - (m_crtc->vbegin() / divisor)) & 0x3ff);
|
||||
map->draw(screen, bitmap, rect, opaque ? TILEMAP_DRAW_OPAQUE : 0, 0);
|
||||
}
|
||||
|
||||
@ -698,24 +715,33 @@ uint32_t x68k_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
bool clear = false;
|
||||
if(m_video.reg[2] & 0x0040)
|
||||
{
|
||||
rectangle pcgrect = rect;
|
||||
if(!(m_video.bg_hvres & 0x0c) && m_crtc->gfx_double_scan())
|
||||
{
|
||||
pcgrect.max_y >>= 1;
|
||||
pcgrect.min_y >>= 1;
|
||||
}
|
||||
if(m_spritereg[0x404] & 0x0008)
|
||||
{
|
||||
clear = true;
|
||||
draw_bg(m_pcgbitmap, screen, 1, true, rect);
|
||||
draw_bg(m_pcgbitmap, screen, 1, true, pcgrect);
|
||||
}
|
||||
else if(m_spritereg[0x404] & 0x0001)
|
||||
{
|
||||
clear = true;
|
||||
draw_bg(m_pcgbitmap, screen, 0, true, rect);
|
||||
draw_bg(m_pcgbitmap, screen, 0, true, pcgrect);
|
||||
}
|
||||
}
|
||||
if(clear)
|
||||
{
|
||||
int divisor = 1;
|
||||
if(!(m_video.bg_hvres & 0x0c) && m_crtc->gfx_double_scan())
|
||||
divisor = 2;
|
||||
for(scanline=rect.min_y;scanline<=rect.max_y;scanline++)
|
||||
{
|
||||
for(pixel=m_crtc->hbegin();pixel<=m_crtc->hend();pixel++)
|
||||
{
|
||||
uint8_t colour = m_pcgbitmap.pix(scanline, pixel) & 0xff;
|
||||
uint8_t colour = m_pcgbitmap.pix(scanline / divisor, pixel) & 0xff;
|
||||
bitmap.pix(scanline, pixel) = m_pcgpalette->pen(colour);
|
||||
}
|
||||
}
|
||||
@ -732,22 +758,30 @@ uint32_t x68k_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
// Sprite / BG Tiles
|
||||
if(priority == m_video.sprite_pri /*&& (m_spritereg[0x404] & 0x0200)*/ && (m_video.reg[2] & 0x0040))
|
||||
{
|
||||
m_pcgbitmap.fill(0, rect);
|
||||
draw_sprites(m_pcgbitmap,1,rect);
|
||||
rectangle pcgrect = rect;
|
||||
int divisor = 1;
|
||||
if(!(m_video.bg_hvres & 0x0c) && m_crtc->gfx_double_scan())
|
||||
{
|
||||
pcgrect.max_y >>= 1;
|
||||
pcgrect.min_y >>= 1;
|
||||
divisor = 2;
|
||||
}
|
||||
m_pcgbitmap.fill(0, pcgrect);
|
||||
draw_sprites(m_pcgbitmap,1,pcgrect);
|
||||
if(m_spritereg[0x404] & 0x0008)
|
||||
draw_bg(m_pcgbitmap, screen, 1, false, rect);
|
||||
draw_bg(m_pcgbitmap, screen, 1, false, pcgrect);
|
||||
|
||||
draw_sprites(m_pcgbitmap,2,rect);
|
||||
draw_sprites(m_pcgbitmap,2,pcgrect);
|
||||
if(m_spritereg[0x404] & 0x0001)
|
||||
draw_bg(m_pcgbitmap, screen, 0, false, rect);
|
||||
draw_bg(m_pcgbitmap, screen, 0, false, pcgrect);
|
||||
|
||||
draw_sprites(m_pcgbitmap,3,rect);
|
||||
draw_sprites(m_pcgbitmap,3,pcgrect);
|
||||
|
||||
for(scanline=rect.min_y;scanline<=rect.max_y;scanline++)
|
||||
{
|
||||
for(pixel=m_crtc->hbegin();pixel<=m_crtc->hend();pixel++)
|
||||
{
|
||||
uint8_t colour = m_pcgbitmap.pix(scanline, pixel) & 0xff;
|
||||
uint8_t colour = m_pcgbitmap.pix(scanline / divisor, pixel) & 0xff;
|
||||
if(colour && (m_pcgpalette->pen(colour) & 0xffffff))
|
||||
bitmap.pix(scanline, pixel) = m_pcgpalette->pen(colour);
|
||||
}
|
||||
@ -767,11 +801,14 @@ uint32_t x68k_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
if((m_video.reg[2] & 0x1800) == 0x1000) // special priority
|
||||
{
|
||||
uint16_t colour;
|
||||
int divisor = 1;
|
||||
if(m_crtc->gfx_double_scan())
|
||||
divisor = 2;
|
||||
for(scanline=rect.min_y;scanline<=rect.max_y;scanline++)
|
||||
{
|
||||
for(pixel=m_crtc->hbegin();pixel<=m_crtc->hend();pixel++)
|
||||
{
|
||||
colour = m_special.pix(scanline, pixel) & 0xff;
|
||||
colour = m_special.pix(scanline / divisor, pixel) & 0xff;
|
||||
if(colour)
|
||||
bitmap.pix(scanline, pixel) = m_gfxpalette->pen(colour & ~1);
|
||||
}
|
||||
|
@ -152,18 +152,14 @@ void x68k_crtc_device::refresh_mode()
|
||||
{
|
||||
// Calculate data from register values
|
||||
m_vmultiple = 1;
|
||||
if ((m_reg[20] & 0x10) != 0 && (m_reg[20] & 0x0c) == 0)
|
||||
m_vmultiple = 2; // 31.5kHz + 256 lines = doublescan
|
||||
if (m_interlace)
|
||||
m_vmultiple = 0.5f; // 31.5kHz + 1024 lines or 15kHz + 512 lines = interlaced
|
||||
m_htotal = (m_reg[0] + 1) * 8;
|
||||
m_vtotal = (m_reg[4] + 1) / m_vmultiple; // default is 567 (568 scanlines)
|
||||
m_hbegin = (m_reg[2] * 8) + 1;
|
||||
m_hend = (m_reg[3] * 8);
|
||||
m_vbegin = (m_reg[6]) / m_vmultiple;
|
||||
m_hend = m_reg[3] * 8;
|
||||
m_vbegin = m_reg[6] / m_vmultiple;
|
||||
m_vend = (m_reg[7] - 1) / m_vmultiple;
|
||||
if ((m_vmultiple == 2) && !(m_reg[7] & 1)) // otherwise if the raster irq line == vblank line, the raster irq fires too late
|
||||
m_vend++;
|
||||
m_hsync_end = (m_reg[1]) * 8;
|
||||
m_vsync_end = (m_reg[5]) / m_vmultiple;
|
||||
m_hsyncadjust = m_reg[8];
|
||||
@ -193,8 +189,8 @@ void x68k_crtc_device::refresh_mode()
|
||||
unsigned div = (m_reg[20] & 0x03) == 0 ? 4 : 2;
|
||||
if (BIT(m_reg[20], 4) && !BIT(m_reg[20], 1))
|
||||
div = BIT(m_reg[20], 0) ? 3 : 6;
|
||||
if ((m_reg[20] & 0x0c) == 0)
|
||||
div *= 2;
|
||||
if (!(m_reg[20] & 0x1f))
|
||||
div = 8;
|
||||
attotime refresh = attotime::from_hz((BIT(m_reg[20], 4) ? clock_69m() : clock_39m()) / div) * (scr.max_x * scr.max_y);
|
||||
LOG("screen().configure(%i,%i,[%i,%i,%i,%i],%f)\n", scr.max_x, scr.max_y, visiblescr.min_x, visiblescr.min_y, visiblescr.max_x, visiblescr.max_y, refresh.as_hz());
|
||||
screen().configure(scr.max_x, scr.max_y, visiblescr, refresh.as_attoseconds());
|
||||
@ -211,46 +207,6 @@ TIMER_CALLBACK_MEMBER(x68k_crtc_device::hsync)
|
||||
if (m_operation & 8)
|
||||
text_copy((m_reg[22] & 0xff00) >> 8, (m_reg[22] & 0x00ff), (m_reg[21] & 0xf));
|
||||
|
||||
if (m_vmultiple == 2) // 256-line (doublescan)
|
||||
{
|
||||
if (hstate == 1)
|
||||
{
|
||||
if (m_oddscanline)
|
||||
{
|
||||
int scan = screen().vpos();
|
||||
hsync_time = screen().time_until_pos(scan, (m_htotal + m_hend) / 2);
|
||||
m_scanline_timer->adjust(hsync_time);
|
||||
if ((scan != 0) && (scan < m_vend))
|
||||
screen().update_partial(scan - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int scan = screen().vpos();
|
||||
hsync_time = screen().time_until_pos(scan, m_hend / 2);
|
||||
m_scanline_timer->adjust(hsync_time);
|
||||
if ((scan != 0) && (scan < m_vend))
|
||||
screen().update_partial(scan - 1);
|
||||
}
|
||||
}
|
||||
if (hstate == 0)
|
||||
{
|
||||
if (m_oddscanline)
|
||||
{
|
||||
int scan = screen().vpos() + 1;
|
||||
hsync_time = screen().time_until_pos(scan, m_hbegin / 2);
|
||||
m_scanline_timer->adjust(hsync_time, 1);
|
||||
m_oddscanline = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hsync_time = screen().time_until_pos(screen().vpos(), (m_htotal + m_hbegin) / 2);
|
||||
m_scanline_timer->adjust(hsync_time, 1);
|
||||
m_oddscanline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // 512-line
|
||||
{
|
||||
if (hstate == 1)
|
||||
{
|
||||
int scan = screen().vpos();
|
||||
@ -265,7 +221,6 @@ TIMER_CALLBACK_MEMBER(x68k_crtc_device::hsync)
|
||||
m_scanline_timer->adjust(hsync_time, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(x68k_crtc_device::raster_end)
|
||||
{
|
||||
@ -390,7 +345,7 @@ void x68k_crtc_device::crtc_w(offs_t offset, u16 data, u16 mem_mask)
|
||||
attotime irq_time = attotime::zero;
|
||||
if ((data / m_vmultiple) != screen().vpos())
|
||||
{
|
||||
irq_time = screen().time_until_pos((data) / m_vmultiple,2);
|
||||
irq_time = screen().time_until_pos((data - 1) / m_vmultiple,2);
|
||||
m_rint_callback(1);
|
||||
}
|
||||
m_raster_irq_timer->adjust(irq_time, (data) / m_vmultiple);
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
u16 yscr_gfx(int page) const { return m_reg[13 + page * 2]; }
|
||||
u8 vfactor() const { return (m_reg[20] & 0x0c) >> 2; }
|
||||
bool is_1024x1024() const { return BIT(m_reg[20], 10); }
|
||||
bool gfx_double_scan() const { return (m_reg[20] & 0x1e) == 0x10; }
|
||||
bool gfx_layer_buffer() const { return BIT(m_reg[20], 11); }
|
||||
bool text_layer_buffer() const { return BIT(m_reg[20], 12); }
|
||||
u16 hbegin() const { return m_hbegin; }
|
||||
|
Loading…
Reference in New Issue
Block a user