x68k: compose the gfx and sprite/bg layers individually before drawing to the screen [Carl]

This commit is contained in:
cracyc 2014-06-01 19:19:37 +00:00
parent eb8068f22e
commit e67b7aeeba
3 changed files with 115 additions and 99 deletions

View File

@ -101,13 +101,14 @@
Keyboard doesn't work properly (MFP USART). Keyboard doesn't work properly (MFP USART).
Supervisor area set isn't implemented. Supervisor area set isn't implemented.
Some minor game-specific issues (at 28/12/08): Some minor game-specific issues:
Pacmania: Black squares on the maze (transparency?).
Salamander: System error when using keys in-game. No error if a joystick is used. Salamander: System error when using keys in-game. No error if a joystick is used.
Some text is drawn incorrectly. Some text is drawn incorrectly.
Dragon Buster: Text is black and unreadable. (Text layer actually covers it) Dragon Buster: Text is black and unreadable. (Text layer actually covers it)
Tetris: Black dots over screen (text layer). Tetris: Black dots over screen (text layer).
Parodius Da!: Black squares in areas. Parodius Da!: Black squares in areas.
PacLand: Leftover garbage on title screen
Akumajo Drac: Missing transparency, no sfx starting on second stage (m68000 only, 030 is fine), text layer not being cleared properly
More detailed documentation at http://x68kdev.emuvibes.com/iomap.html - if you can stand broken english :) More detailed documentation at http://x68kdev.emuvibes.com/iomap.html - if you can stand broken english :)
@ -916,30 +917,12 @@ READ16_MEMBER(x68k_state::x68k_sram_r)
WRITE16_MEMBER(x68k_state::x68k_vid_w) WRITE16_MEMBER(x68k_state::x68k_vid_w)
{ {
int val;
if(offset < 0x100) // Graphic layer palette
{
COMBINE_DATA(m_video.gfx_pal+offset);
val = m_video.gfx_pal[offset];
m_gfxpalette->set_pen_color(offset, pal555(val, 6, 11, 1));
return;
}
if(offset >= 0x100 && offset < 0x200) // Text / Sprites / Tilemap palette
{
offset -= 0x100;
COMBINE_DATA(m_video.text_pal + offset);
val = m_video.text_pal[offset];
m_pcgpalette->set_pen_color(offset, pal555(val, 6, 11, 1));
return;
}
switch(offset) switch(offset)
{ {
case 0x200: case 0x000:
COMBINE_DATA(m_video.reg); COMBINE_DATA(m_video.reg);
break; break;
case 0x280: // priority levels case 0x080: // priority levels
COMBINE_DATA(m_video.reg+1); COMBINE_DATA(m_video.reg+1);
if(ACCESSING_BITS_0_7) if(ACCESSING_BITS_0_7)
{ {
@ -961,7 +944,7 @@ WRITE16_MEMBER(x68k_state::x68k_vid_w)
m_video.sprite_pri--; m_video.sprite_pri--;
} }
break; break;
case 0x300: case 0x100:
COMBINE_DATA(m_video.reg+2); COMBINE_DATA(m_video.reg+2);
break; break;
default: default:
@ -971,19 +954,13 @@ WRITE16_MEMBER(x68k_state::x68k_vid_w)
READ16_MEMBER(x68k_state::x68k_vid_r) READ16_MEMBER(x68k_state::x68k_vid_r)
{ {
if(offset < 0x100)
return m_video.gfx_pal[offset];
if(offset >= 0x100 && offset < 0x200)
return m_video.text_pal[offset-0x100];
switch(offset) switch(offset)
{ {
case 0x200: case 0x000:
return m_video.reg[0]; return m_video.reg[0];
case 0x280: case 0x080:
return m_video.reg[1]; return m_video.reg[1];
case 0x300: case 0x100:
return m_video.reg[2]; return m_video.reg[2];
default: default:
logerror("VC: Invalid video controller read (offset = 0x%04x)\n",offset); logerror("VC: Invalid video controller read (offset = 0x%04x)\n",offset);
@ -1196,7 +1173,9 @@ static ADDRESS_MAP_START(x68k_map, AS_PROGRAM, 16, x68k_state )
AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(x68k_gvram_r, x68k_gvram_w) AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(x68k_gvram_r, x68k_gvram_w)
AM_RANGE(0xe00000, 0xe7ffff) AM_READWRITE(x68k_tvram_r, x68k_tvram_w) AM_RANGE(0xe00000, 0xe7ffff) AM_READWRITE(x68k_tvram_r, x68k_tvram_w)
AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE(x68k_crtc_r, x68k_crtc_w) AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE(x68k_crtc_r, x68k_crtc_w)
AM_RANGE(0xe82000, 0xe83fff) AM_READWRITE(x68k_vid_r, x68k_vid_w) AM_RANGE(0xe82000, 0xe821ff) AM_DEVREADWRITE("gfxpalette", palette_device, read, write) AM_SHARE("gfxpalette")
AM_RANGE(0xe82200, 0xe823ff) AM_DEVREADWRITE("pcgpalette", palette_device, read, write) AM_SHARE("pcgpalette")
AM_RANGE(0xe82400, 0xe83fff) AM_READWRITE(x68k_vid_r, x68k_vid_w)
AM_RANGE(0xe84000, 0xe85fff) AM_DEVREADWRITE("hd63450", hd63450_device, read, write) AM_RANGE(0xe84000, 0xe85fff) AM_DEVREADWRITE("hd63450", hd63450_device, read, write)
AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w) AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w)
AM_RANGE(0xe88000, 0xe89fff) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff) AM_RANGE(0xe88000, 0xe89fff) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff)
@ -1231,7 +1210,9 @@ static ADDRESS_MAP_START(x68kxvi_map, AS_PROGRAM, 16, x68k_state )
AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(x68k_gvram_r, x68k_gvram_w) AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(x68k_gvram_r, x68k_gvram_w)
AM_RANGE(0xe00000, 0xe7ffff) AM_READWRITE(x68k_tvram_r, x68k_tvram_w) AM_RANGE(0xe00000, 0xe7ffff) AM_READWRITE(x68k_tvram_r, x68k_tvram_w)
AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE(x68k_crtc_r, x68k_crtc_w) AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE(x68k_crtc_r, x68k_crtc_w)
AM_RANGE(0xe82000, 0xe83fff) AM_READWRITE(x68k_vid_r, x68k_vid_w) AM_RANGE(0xe82000, 0xe821ff) AM_DEVREADWRITE("gfxpalette", palette_device, read, write) AM_SHARE("gfxpalette")
AM_RANGE(0xe82200, 0xe823ff) AM_DEVREADWRITE("pcgpalette", palette_device, read, write) AM_SHARE("pcgpalette")
AM_RANGE(0xe82400, 0xe83fff) AM_READWRITE(x68k_vid_r, x68k_vid_w)
AM_RANGE(0xe84000, 0xe85fff) AM_DEVREADWRITE("hd63450", hd63450_device, read, write) AM_RANGE(0xe84000, 0xe85fff) AM_DEVREADWRITE("hd63450", hd63450_device, read, write)
AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w) AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w)
AM_RANGE(0xe88000, 0xe89fff) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff) AM_RANGE(0xe88000, 0xe89fff) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff)
@ -1268,7 +1249,9 @@ static ADDRESS_MAP_START(x68030_map, AS_PROGRAM, 32, x68k_state )
AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE16(x68k_gvram_r, x68k_gvram_w, 0xffffffff) AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE16(x68k_gvram_r, x68k_gvram_w, 0xffffffff)
AM_RANGE(0xe00000, 0xe7ffff) AM_READWRITE16(x68k_tvram_r, x68k_tvram_w, 0xffffffff) AM_RANGE(0xe00000, 0xe7ffff) AM_READWRITE16(x68k_tvram_r, x68k_tvram_w, 0xffffffff)
AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE16(x68k_crtc_r, x68k_crtc_w,0xffffffff) AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE16(x68k_crtc_r, x68k_crtc_w,0xffffffff)
AM_RANGE(0xe82000, 0xe83fff) AM_READWRITE16(x68k_vid_r, x68k_vid_w,0xffffffff) AM_RANGE(0xe82000, 0xe821ff) AM_DEVREADWRITE("gfxpalette", palette_device, read, write) AM_SHARE("gfxpalette")
AM_RANGE(0xe82200, 0xe823ff) AM_DEVREADWRITE("pcgpalette", palette_device, read, write) AM_SHARE("pcgpalette")
AM_RANGE(0xe82400, 0xe83fff) AM_READWRITE16(x68k_vid_r, x68k_vid_w,0xffffffff)
AM_RANGE(0xe84000, 0xe85fff) AM_DEVREADWRITE16("hd63450", hd63450_device, read, write, 0xffffffff) AM_RANGE(0xe84000, 0xe85fff) AM_DEVREADWRITE16("hd63450", hd63450_device, read, write, 0xffffffff)
AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE16(x68k_areaset_r, x68k_areaset_w,0xffffffff) AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE16(x68k_areaset_r, x68k_areaset_w,0xffffffff)
AM_RANGE(0xe88000, 0xe89fff) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff00ff) AM_RANGE(0xe88000, 0xe89fff) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff00ff)
@ -1552,11 +1535,11 @@ MACHINE_RESET_MEMBER(x68k_state,x68000)
// start VBlank timer // start VBlank timer
m_crtc.vblank = 1; m_crtc.vblank = 1;
irq_time = machine().first_screen()->time_until_pos(m_crtc.reg[6],2); irq_time = m_screen->time_until_pos(m_crtc.reg[6],2);
m_vblank_irq->adjust(irq_time); m_vblank_irq->adjust(irq_time);
// start HBlank timer // start HBlank timer
m_scanline_timer->adjust(machine().first_screen()->scan_period(), 1); m_scanline_timer->adjust(m_screen->scan_period(), 1);
/// TODO: get callbacks to trigger these /// TODO: get callbacks to trigger these
m_mfpdev->i0_w(1); // alarm m_mfpdev->i0_w(1); // alarm

View File

@ -60,6 +60,7 @@ public:
m_scc(*this, "scc"), m_scc(*this, "scc"),
m_ym2151(*this, "ym2151"), m_ym2151(*this, "ym2151"),
m_ppi(*this, "ppi8255"), m_ppi(*this, "ppi8255"),
m_screen(*this, "screen"),
m_options(*this, "options"), m_options(*this, "options"),
m_mouse1(*this, "mouse1"), m_mouse1(*this, "mouse1"),
m_mouse2(*this, "mouse2"), m_mouse2(*this, "mouse2"),
@ -89,6 +90,7 @@ public:
required_device<scc8530_t> m_scc; required_device<scc8530_t> m_scc;
required_device<ym2151_device> m_ym2151; required_device<ym2151_device> m_ym2151;
required_device<i8255_device> m_ppi; required_device<i8255_device> m_ppi;
required_device<screen_device> m_screen;
required_ioport m_options; required_ioport m_options;
required_ioport m_mouse1; required_ioport m_mouse1;
@ -107,6 +109,9 @@ public:
dynamic_array<UINT16> m_gvram; dynamic_array<UINT16> m_gvram;
dynamic_array<UINT16> m_spritereg; dynamic_array<UINT16> m_spritereg;
bitmap_ind16 *m_pcgbitmap;
bitmap_ind16 *m_gfxbitmap;
void floppy_load_unload(); void floppy_load_unload();
int floppy_load(floppy_image_device *dev); int floppy_load(floppy_image_device *dev);
void floppy_unload(floppy_image_device *dev); void floppy_unload(floppy_image_device *dev);
@ -178,8 +183,6 @@ public:
} m_crtc; // CRTC } m_crtc; // CRTC
struct struct
{ // video controller at 0xe82000 { // video controller at 0xe82000
unsigned short text_pal[0x100];
unsigned short gfx_pal[0x100];
unsigned short reg[3]; unsigned short reg[3];
int text_pri; int text_pri;
int sprite_pri; int sprite_pri;
@ -336,9 +339,9 @@ private:
void x68k_crtc_text_copy(int src, int dest); void x68k_crtc_text_copy(int src, int dest);
void x68k_crtc_refresh_mode(); void x68k_crtc_refresh_mode();
void x68k_draw_text(bitmap_rgb32 &bitmap, int xscr, int yscr, rectangle rect); void x68k_draw_text(bitmap_rgb32 &bitmap, int xscr, int yscr, rectangle rect);
void x68k_draw_gfx_scanline(bitmap_rgb32 &bitmap, rectangle cliprect, UINT8 priority); void x68k_draw_gfx_scanline(bitmap_ind16 &bitmap, rectangle cliprect, UINT8 priority);
void x68k_draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect); void x68k_draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect);
void x68k_draw_sprites(bitmap_rgb32 &bitmap, int priority, rectangle cliprect); void x68k_draw_sprites(bitmap_ind16 &bitmap, int priority, rectangle cliprect);
public: public:
bitmap_rgb32* x68k_get_gfx_page(int pri,int type); bitmap_rgb32* x68k_get_gfx_page(int pri,int type);

View File

@ -125,6 +125,8 @@ void x68k_state::x68k_crtc_refresh_mode()
m_crtc.hend = (m_crtc.reg[3] * 8); m_crtc.hend = (m_crtc.reg[3] * 8);
m_crtc.vbegin = (m_crtc.reg[6]) / m_crtc.vmultiple; m_crtc.vbegin = (m_crtc.reg[6]) / m_crtc.vmultiple;
m_crtc.vend = (m_crtc.reg[7] - 1) / m_crtc.vmultiple; m_crtc.vend = (m_crtc.reg[7] - 1) / m_crtc.vmultiple;
if((m_crtc.vmultiple == 2) && !(m_crtc.reg[7] & 1)) // otherwise if the raster irq line == vblank line, the raster irq fires too late
m_crtc.vend++;
m_crtc.hsync_end = (m_crtc.reg[1]) * 8; m_crtc.hsync_end = (m_crtc.reg[1]) * 8;
m_crtc.vsync_end = (m_crtc.reg[5]) / m_crtc.vmultiple; m_crtc.vsync_end = (m_crtc.reg[5]) / m_crtc.vmultiple;
m_crtc.hsyncadjust = m_crtc.reg[8]; m_crtc.hsyncadjust = m_crtc.reg[8];
@ -161,7 +163,7 @@ void x68k_state::x68k_crtc_refresh_mode()
// logerror("CRTC regs - %i %i %i %i - %i %i %i %i - %i - %i\n",m_crtc.reg[0],m_crtc.reg[1],m_crtc.reg[2],m_crtc.reg[3], // logerror("CRTC regs - %i %i %i %i - %i %i %i %i - %i - %i\n",m_crtc.reg[0],m_crtc.reg[1],m_crtc.reg[2],m_crtc.reg[3],
// m_crtc.reg[4],m_crtc.reg[5],m_crtc.reg[6],m_crtc.reg[7],m_crtc.reg[8],m_crtc.reg[9]); // m_crtc.reg[4],m_crtc.reg[5],m_crtc.reg[6],m_crtc.reg[7],m_crtc.reg[8],m_crtc.reg[9]);
logerror("video_screen_configure(machine.first_screen(),%i,%i,[%i,%i,%i,%i],55.45)\n",scr.max_x,scr.max_y,visiblescr.min_x,visiblescr.min_y,visiblescr.max_x,visiblescr.max_y); logerror("video_screen_configure(machine.first_screen(),%i,%i,[%i,%i,%i,%i],55.45)\n",scr.max_x,scr.max_y,visiblescr.min_x,visiblescr.min_y,visiblescr.max_x,visiblescr.max_y);
machine().first_screen()->configure(scr.max_x,scr.max_y,visiblescr,HZ_TO_ATTOSECONDS(55.45)); m_screen->configure(scr.max_x,scr.max_y,visiblescr,HZ_TO_ATTOSECONDS(55.45));
} }
TIMER_CALLBACK_MEMBER(x68k_state::x68k_hsync) TIMER_CALLBACK_MEMBER(x68k_state::x68k_hsync)
@ -177,31 +179,31 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_hsync)
{ {
if(m_oddscanline == 1) if(m_oddscanline == 1)
{ {
int scan = machine().first_screen()->vpos(); int scan = m_screen->vpos();
if(scan > m_crtc.vend) if(scan > m_crtc.vend)
scan = m_crtc.vbegin; scan = m_crtc.vbegin;
hsync_time = machine().first_screen()->time_until_pos(scan,(m_crtc.htotal + m_crtc.hend) / 2); hsync_time = m_screen->time_until_pos(scan,(m_crtc.htotal + m_crtc.hend) / 2);
m_scanline_timer->adjust(hsync_time); m_scanline_timer->adjust(hsync_time);
if(scan != 0) if(scan != 0)
{ {
if((ioport("options")->read() & 0x04)) if((ioport("options")->read() & 0x04))
{ {
machine().first_screen()->update_partial(scan); m_screen->update_partial(scan);
} }
} }
} }
else else
{ {
int scan = machine().first_screen()->vpos(); int scan = m_screen->vpos();
if(scan > m_crtc.vend) if(scan > m_crtc.vend)
scan = m_crtc.vbegin; scan = m_crtc.vbegin;
hsync_time = machine().first_screen()->time_until_pos(scan,m_crtc.hend / 2); hsync_time = m_screen->time_until_pos(scan,m_crtc.hend / 2);
m_scanline_timer->adjust(hsync_time); m_scanline_timer->adjust(hsync_time);
if(scan != 0) if(scan != 0)
{ {
if((ioport("options")->read() & 0x04)) if((ioport("options")->read() & 0x04))
{ {
machine().first_screen()->update_partial(scan); m_screen->update_partial(scan);
} }
} }
} }
@ -210,18 +212,18 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_hsync)
{ {
if(m_oddscanline == 1) if(m_oddscanline == 1)
{ {
int scan = machine().first_screen()->vpos(); int scan = m_screen->vpos();
if(scan > m_crtc.vend) if(scan > m_crtc.vend)
scan = m_crtc.vbegin; scan = m_crtc.vbegin;
else else
scan++; scan++;
hsync_time = machine().first_screen()->time_until_pos(scan,m_crtc.hbegin / 2); hsync_time = m_screen->time_until_pos(scan,m_crtc.hbegin / 2);
m_scanline_timer->adjust(hsync_time, 1); m_scanline_timer->adjust(hsync_time, 1);
m_oddscanline = 0; m_oddscanline = 0;
} }
else else
{ {
hsync_time = machine().first_screen()->time_until_pos(machine().first_screen()->vpos(),(m_crtc.htotal + m_crtc.hbegin) / 2); hsync_time = m_screen->time_until_pos(m_screen->vpos(),(m_crtc.htotal + m_crtc.hbegin) / 2);
m_scanline_timer->adjust(hsync_time, 1); m_scanline_timer->adjust(hsync_time, 1);
m_oddscanline = 1; m_oddscanline = 1;
} }
@ -231,22 +233,22 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_hsync)
{ {
if(hstate == 1) if(hstate == 1)
{ {
int scan = machine().first_screen()->vpos(); int scan = m_screen->vpos();
if(scan > m_crtc.vend) if(scan > m_crtc.vend)
scan = 0; scan = 0;
hsync_time = machine().first_screen()->time_until_pos(scan,m_crtc.hend); hsync_time = m_screen->time_until_pos(scan,m_crtc.hend);
m_scanline_timer->adjust(hsync_time); m_scanline_timer->adjust(hsync_time);
if(scan != 0) if(scan != 0)
{ {
if((ioport("options")->read() & 0x04)) if((ioport("options")->read() & 0x04))
{ {
machine().first_screen()->update_partial(scan); m_screen->update_partial(scan);
} }
} }
} }
if(hstate == 0) if(hstate == 0)
{ {
hsync_time = machine().first_screen()->time_until_pos(machine().first_screen()->vpos()+1,m_crtc.hbegin); hsync_time = m_screen->time_until_pos(m_screen->vpos()+1,m_crtc.hbegin);
m_scanline_timer->adjust(hsync_time, 1); m_scanline_timer->adjust(hsync_time, 1);
} }
} }
@ -266,13 +268,13 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_raster_irq)
if(scan <= m_crtc.vtotal) if(scan <= m_crtc.vtotal)
{ {
m_mfpdev->i6_w(0); m_mfpdev->i6_w(0);
machine().first_screen()->update_partial(scan); m_screen->update_partial(scan);
irq_time = machine().first_screen()->time_until_pos(scan,m_crtc.hbegin); irq_time = m_screen->time_until_pos(scan,m_crtc.hbegin);
// end of HBlank period clears GPIP6 also? // end of HBlank period clears GPIP6 also?
end_time = machine().first_screen()->time_until_pos(scan,m_crtc.hend); end_time = m_screen->time_until_pos(scan,m_crtc.hend);
m_raster_irq->adjust(irq_time, scan); m_raster_irq->adjust(irq_time, scan);
timer_set(end_time, TIMER_X68K_CRTC_RASTER_END); timer_set(end_time, TIMER_X68K_CRTC_RASTER_END);
logerror("GPIP6: Raster triggered at line %i (%i)\n",scan,machine().first_screen()->vpos()); logerror("GPIP6: Raster triggered at line %i (%i)\n",scan,m_screen->vpos());
} }
} }
@ -286,7 +288,7 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_vblank_irq)
{ {
m_crtc.vblank = 1; m_crtc.vblank = 1;
vblank_line = m_crtc.vbegin; vblank_line = m_crtc.vbegin;
irq_time = machine().first_screen()->time_until_pos(vblank_line,2); irq_time = m_screen->time_until_pos(vblank_line,2);
m_vblank_irq->adjust(irq_time); m_vblank_irq->adjust(irq_time);
logerror("CRTC: VBlank on\n"); logerror("CRTC: VBlank on\n");
} }
@ -296,7 +298,7 @@ TIMER_CALLBACK_MEMBER(x68k_state::x68k_crtc_vblank_irq)
vblank_line = m_crtc.vend; vblank_line = m_crtc.vend;
if(vblank_line > m_crtc.vtotal) if(vblank_line > m_crtc.vtotal)
vblank_line = m_crtc.vtotal; vblank_line = m_crtc.vtotal;
irq_time = machine().first_screen()->time_until_pos(vblank_line,2); irq_time = m_screen->time_until_pos(vblank_line,2);
m_vblank_irq->adjust(irq_time, 1); m_vblank_irq->adjust(irq_time, 1);
logerror("CRTC: VBlank off\n"); logerror("CRTC: VBlank off\n");
} }
@ -373,7 +375,8 @@ WRITE16_MEMBER(x68k_state::x68k_crtc_w )
case 9: // CRTC raster IRQ (GPIP6) case 9: // CRTC raster IRQ (GPIP6)
{ {
attotime irq_time; attotime irq_time;
irq_time = machine().first_screen()->time_until_pos((data) / m_crtc.vmultiple,2); data = m_crtc.reg[9];
irq_time = m_screen->time_until_pos((data) / m_crtc.vmultiple,2);
if(irq_time.as_double() > 0) if(irq_time.as_double() > 0)
m_raster_irq->adjust(irq_time, (data) / m_crtc.vmultiple); m_raster_irq->adjust(irq_time, (data) / m_crtc.vmultiple);
@ -716,15 +719,9 @@ void x68k_state::x68k_draw_text(bitmap_rgb32 &bitmap, int xscr, int yscr, rectan
+ (((m_tvram[loc+0x10000] >> bit) & 0x01) ? 2 : 0) + (((m_tvram[loc+0x10000] >> bit) & 0x01) ? 2 : 0)
+ (((m_tvram[loc+0x20000] >> bit) & 0x01) ? 4 : 0) + (((m_tvram[loc+0x20000] >> bit) & 0x01) ? 4 : 0)
+ (((m_tvram[loc+0x30000] >> bit) & 0x01) ? 8 : 0); + (((m_tvram[loc+0x30000] >> bit) & 0x01) ? 8 : 0);
if(m_video.text_pal[colour] != 0x0000) // any colour but black
{
// Colour 0 is displayable if the text layer is at the priority level 2 // Colour 0 is displayable if the text layer is at the priority level 2
if(colour == 0 && (m_video.reg[1] & 0x0c00) == 0x0800) if((colour && (m_pcgpalette->pen(colour) & 0xffffff)) || (m_video.text_pri == 2))
bitmap.pix32(line, pixel) = m_pcgpalette->pen(colour); bitmap.pix32(line, pixel) = m_pcgpalette->pen(colour);
else
if(colour != 0)
bitmap.pix32(line, pixel) = m_pcgpalette->pen(colour);
}
bit--; bit--;
if(bit < 0) if(bit < 0)
{ {
@ -736,7 +733,7 @@ void x68k_state::x68k_draw_text(bitmap_rgb32 &bitmap, int xscr, int yscr, rectan
} }
} }
void x68k_state::x68k_draw_gfx_scanline( bitmap_rgb32 &bitmap, rectangle cliprect, UINT8 priority) void x68k_state::x68k_draw_gfx_scanline( bitmap_ind16 &bitmap, rectangle cliprect, UINT8 priority)
{ {
int pixel; int pixel;
int page; int page;
@ -775,10 +772,8 @@ void x68k_state::x68k_draw_gfx_scanline( bitmap_rgb32 &bitmap, rectangle cliprec
colour = (m_gvram[(lineoffset - 0xc0000) + (loc & 0x3ff)] & 0xf000) >> 12; colour = (m_gvram[(lineoffset - 0xc0000) + (loc & 0x3ff)] & 0xf000) >> 12;
break; break;
} }
if(colour != 0) if(colour || (priority == 3))
{ bitmap.pix16(scanline, pixel) = colour;
bitmap.pix32(scanline, pixel) = m_gfxpalette->pen(colour);
}
loc++; loc++;
loc &= 0x3ff; loc &= 0x3ff;
} }
@ -801,10 +796,8 @@ void x68k_state::x68k_draw_gfx_scanline( bitmap_rgb32 &bitmap, rectangle cliprec
for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++) for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++)
{ {
colour = ((m_gvram[lineoffset + loc] >> page*shift) & 0x000f); colour = ((m_gvram[lineoffset + loc] >> page*shift) & 0x000f);
if(colour != 0) if(colour || (priority == 3))
{ bitmap.pix16(scanline, pixel) = colour;
bitmap.pix32(scanline, pixel) = m_gfxpalette->pen(colour);
}
loc++; loc++;
loc &= 0x1ff; loc &= 0x1ff;
} }
@ -820,10 +813,8 @@ void x68k_state::x68k_draw_gfx_scanline( bitmap_rgb32 &bitmap, rectangle cliprec
for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++) for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++)
{ {
colour = ((m_gvram[lineoffset + loc] >> page*shift) & 0x00ff); colour = ((m_gvram[lineoffset + loc] >> page*shift) & 0x00ff);
if(colour != 0) if(colour || (priority == 3))
{ bitmap.pix16(scanline, pixel) = colour;
bitmap.pix32(scanline, pixel) = m_gfxpalette->pen(colour);
}
loc++; loc++;
loc &= 0x1ff; loc &= 0x1ff;
} }
@ -837,10 +828,8 @@ void x68k_state::x68k_draw_gfx_scanline( bitmap_rgb32 &bitmap, rectangle cliprec
for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++) for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++)
{ {
colour = m_gvram[lineoffset + loc]; colour = m_gvram[lineoffset + loc];
if(colour != 0) if(colour || (priority == 3))
{ bitmap.pix16(scanline, pixel) = colour;
bitmap.pix32(scanline, pixel) = pal555(colour, 6, 11, 1);
}
loc++; loc++;
loc &= 0x1ff; loc &= 0x1ff;
} }
@ -853,7 +842,7 @@ void x68k_state::x68k_draw_gfx_scanline( bitmap_rgb32 &bitmap, rectangle cliprec
void x68k_state::x68k_draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect) void x68k_state::x68k_draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect)
{ {
int priority; int priority, scanline, pixel;
//rectangle rect; //rectangle rect;
//int xscr,yscr; //int xscr,yscr;
//int gpage; //int gpage;
@ -861,14 +850,36 @@ void x68k_state::x68k_draw_gfx(bitmap_rgb32 &bitmap,rectangle cliprect)
if(m_crtc.reg[20] & 0x0800) // if graphic layers are set to buffer, then they aren't visible if(m_crtc.reg[20] & 0x0800) // if graphic layers are set to buffer, then they aren't visible
return; return;
m_gfxbitmap->fill(0, cliprect);
for(priority=3;priority>=0;priority--) for(priority=3;priority>=0;priority--)
{ {
x68k_draw_gfx_scanline(bitmap,cliprect,priority); x68k_draw_gfx_scanline(*m_gfxbitmap,cliprect,priority);
}
for(scanline=cliprect.min_y;scanline<=cliprect.max_y;scanline++)
{
UINT16 colour;
for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++)
{
if((m_video.reg[0] & 0x03) == 3)
{
colour = m_gfxbitmap->pix16(scanline, pixel);
if(colour || (m_video.gfx_pri == 2))
bitmap.pix32(scanline, pixel) = pal555(colour, 6, 11, 1);
}
else
{
colour = m_gfxbitmap->pix16(scanline, pixel) & 0xff;
if((colour && (m_gfxpalette->pen(colour) & 0xffffff)) || (m_video.gfx_pri == 2))
bitmap.pix32(scanline, pixel) = m_gfxpalette->pen(colour);
}
}
} }
} }
// Sprite controller "Cynthia" at 0xeb0000 // Sprite controller "Cynthia" at 0xeb0000
void x68k_state::x68k_draw_sprites(bitmap_rgb32 &bitmap, int priority, rectangle cliprect) void x68k_state::x68k_draw_sprites(bitmap_ind16 &bitmap, int priority, rectangle cliprect)
{ {
/* /*
0xeb0000 - 0xeb07ff - Sprite registers (up to 128) 0xeb0000 - 0xeb07ff - Sprite registers (up to 128)
@ -1012,6 +1023,12 @@ VIDEO_START_MEMBER(x68k_state,x68000)
m_bg0_16->set_transparent_pen(0); m_bg0_16->set_transparent_pen(0);
m_bg1_16->set_transparent_pen(0); m_bg1_16->set_transparent_pen(0);
m_pcgbitmap = auto_bitmap_ind16_alloc(machine(), 1024, 1024);
m_pcgbitmap->fill(0);
m_gfxbitmap = auto_bitmap_ind16_alloc(machine(), 1024, 1024);
m_gfxbitmap->fill(0);
// m_scanline_timer->adjust(attotime::zero, 0, attotime::from_hz(55.45)/568); // m_scanline_timer->adjust(attotime::zero, 0, attotime::from_hz(55.45)/568);
} }
@ -1023,6 +1040,7 @@ UINT32 x68k_state::screen_update_x68000(screen_device &screen, bitmap_rgb32 &bit
int x; int x;
tilemap_t* x68k_bg0; tilemap_t* x68k_bg0;
tilemap_t* x68k_bg1; tilemap_t* x68k_bg1;
int pixel, scanline;
//UINT8 *rom; //UINT8 *rom;
if((m_spritereg[0x408] & 0x03) == 0x00) // Sprite/BG H-Res 0=8x8, 1=16x16, 2 or 3 = undefined. if((m_spritereg[0x408] & 0x03) == 0x00) // Sprite/BG H-Res 0=8x8, 1=16x16, 2 or 3 = undefined.
@ -1070,7 +1088,8 @@ UINT32 x68k_state::screen_update_x68000(screen_device &screen, bitmap_rgb32 &bit
} }
} }
for(priority=3;priority>=0;priority--)
for(priority=2;priority>=0;priority--)
{ {
// Graphics screen(s) // Graphics screen(s)
if(priority == m_video.gfx_pri) if(priority == m_video.gfx_pri)
@ -1079,39 +1098,50 @@ UINT32 x68k_state::screen_update_x68000(screen_device &screen, bitmap_rgb32 &bit
// Sprite / BG Tiles // Sprite / BG Tiles
if(priority == m_video.sprite_pri /*&& (m_spritereg[0x404] & 0x0200)*/ && (m_video.reg[2] & 0x0040)) if(priority == m_video.sprite_pri /*&& (m_spritereg[0x404] & 0x0200)*/ && (m_video.reg[2] & 0x0040))
{ {
x68k_draw_sprites(bitmap,1,rect); m_pcgbitmap->fill(0, rect);
x68k_draw_sprites(*m_pcgbitmap,1,rect);
if((m_spritereg[0x404] & 0x0008)) if((m_spritereg[0x404] & 0x0008))
{ {
if((m_spritereg[0x404] & 0x0030) == 0x10) // BG1 TXSEL if((m_spritereg[0x404] & 0x0030) == 0x10) // BG1 TXSEL
{ {
x68k_bg0->set_scrollx(0,(m_spritereg[0x402] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff); x68k_bg0->set_scrollx(0,(m_spritereg[0x402] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff);
x68k_bg0->set_scrolly(0,(m_spritereg[0x403] - m_crtc.vbegin) & 0x3ff); x68k_bg0->set_scrolly(0,(m_spritereg[0x403] - m_crtc.vbegin) & 0x3ff);
x68k_bg0->draw(screen, bitmap,rect,0,0); x68k_bg0->draw(screen, *m_pcgbitmap,rect,0,0);
} }
else else
{ {
x68k_bg1->set_scrollx(0,(m_spritereg[0x402] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff); x68k_bg1->set_scrollx(0,(m_spritereg[0x402] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff);
x68k_bg1->set_scrolly(0,(m_spritereg[0x403] - m_crtc.vbegin) & 0x3ff); x68k_bg1->set_scrolly(0,(m_spritereg[0x403] - m_crtc.vbegin) & 0x3ff);
x68k_bg1->draw(screen, bitmap,rect,0,0); x68k_bg1->draw(screen, *m_pcgbitmap,rect,0,0);
} }
} }
x68k_draw_sprites(bitmap,2,rect); x68k_draw_sprites(*m_pcgbitmap,2,rect);
if((m_spritereg[0x404] & 0x0001)) if((m_spritereg[0x404] & 0x0001))
{ {
if((m_spritereg[0x404] & 0x0006) == 0x02) // BG0 TXSEL if((m_spritereg[0x404] & 0x0006) == 0x02) // BG0 TXSEL
{ {
x68k_bg0->set_scrollx(0,(m_spritereg[0x400] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff); x68k_bg0->set_scrollx(0,(m_spritereg[0x400] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff);
x68k_bg0->set_scrolly(0,(m_spritereg[0x401] - m_crtc.vbegin) & 0x3ff); x68k_bg0->set_scrolly(0,(m_spritereg[0x401] - m_crtc.vbegin) & 0x3ff);
x68k_bg0->draw(screen, bitmap,rect,0,0); x68k_bg0->draw(screen, *m_pcgbitmap,rect,0,0);
} }
else else
{ {
x68k_bg1->set_scrollx(0,(m_spritereg[0x400] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff); x68k_bg1->set_scrollx(0,(m_spritereg[0x400] - m_crtc.hbegin - m_crtc.bg_hshift) & 0x3ff);
x68k_bg1->set_scrolly(0,(m_spritereg[0x401] - m_crtc.vbegin) & 0x3ff); x68k_bg1->set_scrolly(0,(m_spritereg[0x401] - m_crtc.vbegin) & 0x3ff);
x68k_bg1->draw(screen, bitmap,rect,0,0); x68k_bg1->draw(screen, *m_pcgbitmap,rect,0,0);
}
}
x68k_draw_sprites(*m_pcgbitmap,3,rect);
for(scanline=rect.min_y;scanline<=rect.max_y;scanline++)
{
for(pixel=m_crtc.hbegin;pixel<=m_crtc.hend;pixel++)
{
UINT8 colour = m_pcgbitmap->pix16(scanline, pixel) & 0xff;
if((colour && (m_pcgpalette->pen(colour) & 0xffffff)) || (priority == 2))
bitmap.pix32(scanline, pixel) = m_pcgpalette->pen(colour);
} }
} }
x68k_draw_sprites(bitmap,3,rect);
} }
// Text screen // Text screen