now we can turn on the tms for little robin too, still some issues (bands during boss levels for instance) but it's better than it was in other ways (screen clears) (nw)

This commit is contained in:
David Haywood 2014-03-18 16:59:06 +00:00
parent 3d7638f066
commit af31cf37e4
2 changed files with 40 additions and 583 deletions

View File

@ -6,7 +6,7 @@ David Haywood
*/
// this should use a TMS.. the test mode being the same as MegaPhoenix was a givewaway.. maybe also made by Dinamic / Inder for TCH?
#define USE_TMS 0
#define USE_TMS 1
#define littlerb_printf logerror
#define littlerb_alt_printf logerror
@ -99,13 +99,11 @@ public:
m_screen(*this, "screen"),
m_dacl(*this, "dacl"),
m_dacr(*this, "dacr"),
#if USE_TMS
m_vram(*this, "vram"),
m_palette(*this, "palette")
#else
m_region4(*this, "region4"),
m_1ff80804(-1)
#endif
m_palette(*this, "palette"),
m_shiftfull(0)
{
}
@ -124,106 +122,11 @@ public:
UINT8 sound_data_shift();
TIMER_DEVICE_CALLBACK_MEMBER(littlerb_scanline);
#if USE_TMS
required_shared_ptr<UINT16> m_vram;
required_device<palette_device> m_palette;
#else
required_shared_ptr<UINT16> m_region4;
UINT16 m_vdp_address_low;
UINT16 m_vdp_address_high;
UINT16 m_vdp_writemode;
UINT32 m_write_address;
int m_shiftfull; // this might be a driver specific hack for a TMS bug.
UINT32 m_write_address_laststart;
UINT32 m_write_address_lastend;
int m_type2_writes;
UINT32 m_lasttype2pc;
bitmap_ind16 *m_temp_bitmap_sprites;
bitmap_ind16 *m_temp_bitmap_sprites_back;
DECLARE_WRITE16_MEMBER(spritelist_w);
DECLARE_WRITE16_MEMBER(region4_w);
DECLARE_READ16_MEMBER(buffer_status_r);
DECLARE_READ16_MEMBER(littlerb_vdp_r);
DECLARE_WRITE16_MEMBER(littlerb_vdp_w);
int m_1ff80804;
int m_listoffset;
UINT16* m_spritelist;
DECLARE_READ16_MEMBER( littlerb_1ff80800_r )
{
littlerb_printf("littlerb_1ff80800_r\n");
return 0x0000;
}
DECLARE_WRITE16_MEMBER( littlerb_1ff80800_w )
{
littlerb_printf("littlerb_1ff80800_w %04x\n", data);
}
DECLARE_READ16_MEMBER( littlerb_1ff80802_r )
{
littlerb_printf("littlerb_1ff80802_r\n");
return 0x0000;
}
DECLARE_WRITE16_MEMBER( littlerb_1ff80802_w )
{
littlerb_printf("littlerb_1ff80802_w %04x\n", data);
}
DECLARE_WRITE16_MEMBER( littlerb_1ff80804_w )
{
littlerb_printf("littlerb_1ff80804_w %04x\n", data);
if ((!(m_spritelist[2] & 0x1000)) && (!(m_spritelist[1] & 0x1000)))
{
}
else
{
if (!(m_spritelist[2] & 0x1000))
m_temp_bitmap_sprites_back->fill(0, m_temp_bitmap_sprites_back->cliprect());
}
littlerb_draw_sprites();
m_listoffset = 0;
memset(m_spritelist, 0x00, 0x20000); // clear out the list.. I think it's commands anyway?
}
DECLARE_WRITE16_MEMBER( littlerb_18000012_w )
{
littlerb_printf("littlerb_18000012_w %04x\n", data);
// edfc / fffc alternating (select double buffering?)
}
DECLARE_WRITE16_MEMBER( littlerb_18000014_w )
{
littlerb_printf("littlerb_18000014_w %04x\n", data);
// dosen't seem to be the draw trigger, or you get broken platforms..
}
DECLARE_WRITE16_MEMBER( littlerb_1800003c_w )
{
littlerb_printf("littlerb_1800003c_w %04x\n", data);
// edfc / fffc alternating (display double buffering?)
}
virtual void video_start();
UINT32 screen_update_littlerb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void littlerb_recalc_regs();
UINT16 littlerb_data_read(UINT16 mem_mask);
void littlerb_data_write(UINT16 data, UINT16 mem_mask);
void littlerb_recalc_address();
void draw_sprite(bitmap_ind16 &bitmap, const rectangle &cliprect, int xsize,int ysize, UINT32 fulloffs, int xpos, int ypos );
void littlerb_draw_sprites();
#endif
};
@ -267,11 +170,9 @@ static ADDRESS_MAP_START( littlerb_main, AS_PROGRAM, 16, littlerb_state )
AM_RANGE(0x060004, 0x060007) AM_WRITENOP
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x200000, 0x203fff) AM_RAM // main ram?
#if USE_TMS
AM_RANGE(0x700000, 0x700007) AM_DEVREADWRITE("tms", tms34010_device, host_r, host_w)
#else
AM_RANGE(0x700000, 0x700007) AM_READ(littlerb_vdp_r) AM_WRITE(littlerb_vdp_w)
#endif
AM_RANGE(0x740000, 0x740001) AM_WRITE(littlerb_l_sound_w)
AM_RANGE(0x760000, 0x760001) AM_WRITE(littlerb_r_sound_w)
AM_RANGE(0x780000, 0x780001) AM_WRITENOP // generic outputs
@ -385,20 +286,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(littlerb_state::littlerb_scanline)
m_sound_pointer_r&=0x3ff;
}
#if USE_TMS
// the TMS generates the main interrupt
#else
// logerror("IRQ\n");
if(scanline == 288)
{
m_maincpu->set_input_line(4, HOLD_LINE);
}
#endif
}
#if USE_TMS
static ADDRESS_MAP_START( littlerb_tms_map, AS_PROGRAM, 16, littlerb_state )
AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_SHARE("vram")
@ -434,15 +327,26 @@ static void littlerb_scanline(screen_device &screen, bitmap_rgb32 &bitmap, int s
static void littlerb_to_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg)
{
littlerb_state *state = space.machine().driver_data<littlerb_state>();
memcpy(shiftreg, &state->m_vram[TOWORD(address)/* & ~TOWORD(0x1fff)*/], TOBYTE(0x2000));
if (state->m_shiftfull == 0)
{
//printf("read to shift regs address %08x (%08x)\n", address, TOWORD(address) * 2);
memcpy(shiftreg, &state->m_vram[TOWORD(address)/* & ~TOWORD(0x1fff)*/], TOBYTE(0x2000));
state->m_shiftfull = 1;
}
}
static void littlerb_from_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg)
{
littlerb_state *state = space.machine().driver_data<littlerb_state>();
memcpy(&state->m_vram[TOWORD(address)/* & ~TOWORD(0x1fff)*/], shiftreg, TOBYTE(0x2000));
state->m_shiftfull = 0;
}
static void m68k_gen_int(device_t *device, int state)
{
littlerb_state *drvstate = device->machine().driver_data<littlerb_state>();
@ -463,460 +367,8 @@ static const tms34010_config tms_config_littlerb =
littlerb_to_shiftreg, /* write to shiftreg function */
littlerb_from_shiftreg /* read from shiftreg function */
};
#else
void littlerb_state::video_start()
{
// m_screen->register_screen_bitmap(m_temp_bitmap_sprites_back);
// m_screen->register_screen_bitmap(m_temp_bitmap_sprites);
m_temp_bitmap_sprites_back = auto_bitmap_ind16_alloc(machine(),512,512);
m_temp_bitmap_sprites = auto_bitmap_ind16_alloc(machine(),512,512);
m_spritelist = (UINT16*)auto_alloc_array_clear(machine(), UINT16, 0x20000);
}
/* sprite format / offset could be completely wrong, this is just based on our (currently incorrect) vram access */
UINT32 littlerb_state::screen_update_littlerb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bitmap.fill(0, cliprect);
copybitmap_trans(bitmap, *m_temp_bitmap_sprites_back, 0, 0, 0, 0, cliprect, 0);
copybitmap_trans(bitmap, *m_temp_bitmap_sprites, 0, 0, 0, 0, cliprect, 0);
return 0;
}
/* this map is wrong because our VDP access is wrong! */
static ADDRESS_MAP_START( littlerb_vdp_map8, AS_0, 16, littlerb_state )
// it ends up writing some gfx here (the bubbles when you shoot an enemy)
AM_RANGE(0x00000000, 0x0007ffff) AM_RAM
AM_RANGE(0x00080000, 0x003fffff) AM_RAM // temp so it doesn't fill the log
/* these are definitely written by a non-incrementing access to the VDP */
AM_RANGE(0x00800000, 0x00800001) AM_DEVWRITE8("^ramdac", ramdac_device, index_w, 0x00ff)
AM_RANGE(0x00800002 ,0x00800003) AM_DEVWRITE8("^ramdac", ramdac_device, pal_w, 0x00ff)
AM_RANGE(0x00800004 ,0x00800005) AM_DEVWRITE8("^ramdac", ramdac_device, mask_w, 0x00ff)
AM_RANGE(0x18000012, 0x18000013) AM_DEVWRITE("^", littlerb_state, littlerb_18000012_w)
AM_RANGE(0x18000014, 0x18000015) AM_DEVWRITE("^", littlerb_state, littlerb_18000014_w)
AM_RANGE(0x1800003c, 0x1800003d) AM_DEVWRITE("^", littlerb_state, littlerb_1800003c_w)
AM_RANGE(0x1ff80800, 0x1ff80801) AM_DEVREADWRITE("^", littlerb_state, littlerb_1ff80800_r, littlerb_1ff80800_w)
AM_RANGE(0x1ff80802, 0x1ff80803) AM_DEVREADWRITE("^", littlerb_state, littlerb_1ff80802_r, littlerb_1ff80802_w)
AM_RANGE(0x1ff80804, 0x1ff80805) AM_DEVREADWRITE("^", littlerb_state, buffer_status_r, littlerb_1ff80804_w)
AM_RANGE(0x1ff80806, 0x1ff80807) AM_RAM AM_DEVWRITE("^", littlerb_state, spritelist_w)
// most gfx end up here including the sprite list
AM_RANGE(0x1ff80000, 0x1fffffff) AM_RAM AM_DEVWRITE("^", littlerb_state, region4_w) AM_SHARE("region4")
ADDRESS_MAP_END
/* VDP device to give us our own memory map */
class littlerb_vdp_device;
class littlerb_vdp_device : public device_t,
public device_memory_interface
{
public:
littlerb_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
virtual void device_start() { }
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const
{
return (spacenum == 0) ? &m_space_config : NULL;
}
address_space_config m_space_config;
};
const device_type LITTLERBVDP = &device_creator<littlerb_vdp_device>;
littlerb_vdp_device::littlerb_vdp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, LITTLERBVDP, "LITTLERBVDP", tag, owner, clock, "littlerb_vdp", __FILE__),
device_memory_interface(mconfig, *this),
m_space_config("littlerb_vdp", ENDIANNESS_LITTLE, 16,32, 0, NULL, *ADDRESS_MAP_NAME(littlerb_vdp_map8))
{
}
/* end VDP device to give us our own memory map */
void littlerb_state::draw_sprite(bitmap_ind16 &bitmap, const rectangle &cliprect, int xsize,int ysize, UINT32 fulloffs, int xpos, int ypos )
{
int x,y;
fulloffs >>= 3;
address_space &vdp_space = machine().device<littlerb_vdp_device>("littlerbvdp")->space();
for (y=0;y<ysize;y++)
{
for (x=0;x<xsize;x++)
{
int drawxpos, drawypos;
// the addresses provided are the same as the offsets as the vdp writes
UINT16 pix = vdp_space.read_byte(fulloffs);
drawxpos = xpos+x;
drawypos = ypos+y;
// odd clipping behavior, count is only increased for visible lines?
// I suspect the sprite corruption if you're near the top of the screen
// between level changes is related to this too, data offset values are
// probably being adjusted as layer is scrolled (and the cliprect is changed)
// even if they don't move.
if(drawypos>=cliprect.min_y)
{
fulloffs++;
}
if(cliprect.contains(drawxpos, drawypos))
{
if(pix&0xff) bitmap.pix16(drawypos, drawxpos) = pix;
}
drawxpos++;
}
}
}
void littlerb_state::littlerb_draw_sprites()
{
int x,y,offs;
int xsize,ysize;
UINT16* spriteregion = m_spritelist;
//littlerb_printf("frame\n");
int layer = 0;
int yoffset = 0;
littlerb_printf("m_listoffset %04x\n", m_listoffset );
littlerb_printf("%04x %04x %04x %04x\n", spriteregion[0], spriteregion[1], spriteregion[2], spriteregion[3]);
littlerb_alt_printf("start\n");
int minx = 0 , maxx = 0x14f;
int miny = 0 , maxy = 0x11f;
for (offs=0;offs<(m_listoffset);)
{
UINT32 read_dword = ((spriteregion[offs+1])<<16)+ (spriteregion[offs+0]);
littlerb_printf("read %08x\n", read_dword);
// some kind of control words?? (layer selection, layer scrolls?, layer clears?)
// but the low bits are the sprite offset??? how can this work
if (spriteregion[offs+0] == 0x0060)
{
offs += 6;
}
else if (spriteregion[offs+0] == 0x0040)
{
littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x ---- ---- ---- ----\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5]);
// some scroll stuff is here (title -> high score transition)
// maybe also copy area operations?
// this isn't understood ... note, we still have a hack before draw_sprites is called too
// usual start of frame
// Control Word 0040 0090 6000 0026 0000 0012 ---- ---- ---- ----
// happens in the middle of list during boss death, causes sprites to vanish atm
// Control Word 0040 ffd6 00aa 00f8 0088 0018 ---- ---- ---- ----
if (spriteregion[offs+4]==0x6000)
{
if (spriteregion[offs+3] & 0x1000)
m_temp_bitmap_sprites_back->fill(0, m_temp_bitmap_sprites_back->cliprect());
}
else
{
if (spriteregion[offs+1] != 0xffd6) m_temp_bitmap_sprites->fill(0, m_temp_bitmap_sprites->cliprect());
}
// this is some kind of scroll or copy area..
// also some of the other values change
// this is set AFTER the graphics which need to be scrolled are sent and causes the credit text to bounce up and down instead of
// anything scrolling
//yoffset = spriteregion[offs+1] - 0x90;
offs += 6;
}
else if (read_dword == 0x00e40020)
{
littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5], spriteregion[offs+6], spriteregion[offs+7], spriteregion[offs+8], spriteregion[offs+9]);
if (spriteregion[offs+4]==0x6000)
layer = 1;
else
layer = 0;
minx = spriteregion[offs+6];
maxx = spriteregion[offs+8];
miny = spriteregion[offs+7];
maxy = spriteregion[offs+9];
offs += 10;
}
else if (read_dword == 0x00e40000)
{
// same as above?
littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5], spriteregion[offs+6], spriteregion[offs+7], spriteregion[offs+8], spriteregion[offs+9]);
if (spriteregion[offs+4]==0x6000)
layer = 1;
else
layer = 0;
minx = spriteregion[offs+6];
maxx = spriteregion[offs+8];
miny = spriteregion[offs+7];
maxy = spriteregion[offs+9];
offs += 10;
}
else if (read_dword == 0x00000000)
{
offs += 1;
}
else
{
UINT32 fullcode = ((spriteregion[offs+1])<<16)+ (spriteregion[offs+0]);
x = spriteregion[offs+2] & 0x07ff;
y = (spriteregion[offs+3] & 0x03ff); // 1?
if (x&0x400) x-=0x800;
if (y&0x200) y-=0x400;
y+= yoffset;
xsize = (spriteregion[offs+4] & 0x01ff); // background gfx for many places at 0x1ff wide
ysize = (spriteregion[offs+5] & 0x00ff); // player1/player2 texts in service mode sides are 0xff high
rectangle clip;
clip.min_x = minx;
clip.max_x = maxx;
clip.min_y = miny;
clip.max_y = maxy;
// used between levels, and on boss death to clip sprite at the ground for sinking effect
if (clip.min_x > m_temp_bitmap_sprites->cliprect().max_x)
clip.min_x = m_temp_bitmap_sprites->cliprect().max_x;
if (clip.min_x < m_temp_bitmap_sprites->cliprect().min_x)
clip.min_x = m_temp_bitmap_sprites->cliprect().min_x;
if (clip.max_x > m_temp_bitmap_sprites->cliprect().max_x)
clip.max_x = m_temp_bitmap_sprites->cliprect().max_x;
if (clip.max_x < m_temp_bitmap_sprites->cliprect().min_x)
clip.max_x = m_temp_bitmap_sprites->cliprect().min_x;
if (clip.min_y > m_temp_bitmap_sprites->cliprect().max_y)
clip.min_y = m_temp_bitmap_sprites->cliprect().max_y;
if (clip.min_y < m_temp_bitmap_sprites->cliprect().min_y)
clip.min_y = m_temp_bitmap_sprites->cliprect().min_y;
if (clip.max_y > m_temp_bitmap_sprites->cliprect().max_y)
clip.max_y = m_temp_bitmap_sprites->cliprect().max_y;
if (clip.max_y < m_temp_bitmap_sprites->cliprect().min_y)
clip.max_y = m_temp_bitmap_sprites->cliprect().min_y;
littlerb_alt_printf("%04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5]);
if (layer==0) draw_sprite(*m_temp_bitmap_sprites, clip,xsize,ysize,fullcode,x,y);
else draw_sprite(*m_temp_bitmap_sprites_back, clip,xsize,ysize,fullcode,x,y);
offs += 6;
}
}
}
WRITE16_MEMBER(littlerb_state::region4_w)
{
COMBINE_DATA(&m_region4[offset]);
}
READ16_MEMBER(littlerb_state::buffer_status_r)
{
return 0;
}
WRITE16_MEMBER(littlerb_state::spritelist_w)
{
littlerb_printf("spritelist_w %04x\n", data);
COMBINE_DATA(&m_spritelist[m_listoffset]);
m_listoffset++;
}
void littlerb_state::littlerb_recalc_regs()
{
m_vdp_address_low = m_write_address&0xffff;
m_vdp_address_high = (m_write_address>>16)&0xffff;
}
UINT16 littlerb_state::littlerb_data_read(UINT16 mem_mask)
{
UINT32 addr = m_write_address >> 3; // almost surely raw addresses are actually shifted by 3
address_space &vdp_space = machine().device<littlerb_vdp_device>("littlerbvdp")->space();
return vdp_space.read_word(addr, mem_mask);
}
void littlerb_state::littlerb_data_write(UINT16 data, UINT16 mem_mask)
{
UINT32 addr = m_write_address >> 3; // almost surely raw addresses are actually shifted by 3
address_space &vdp_space = machine().device<littlerb_vdp_device>("littlerbvdp")->space();
int mode = m_vdp_writemode;
logerror("mode %04x, data %04x, mem_mask %04x (address %08x)\n", mode, data, mem_mask, m_write_address >> 3);
if ((mode!=0x3800) && (mode !=0x2000) && (mode != 0xe000) && (mode != 0xf800))
{
}
else
{
vdp_space.write_word(addr, data, mem_mask);
// 2000 is used for palette writes which appears to be a RAMDAC, no auto-inc.
// 1ff80806 is our 'spritelist'
if (mode!=0x2000 && mode != 0xe000 && addr != 0x1ff80806) m_write_address+=0x10;
littlerb_recalc_regs();
}
}
void littlerb_state::littlerb_recalc_address()
{
m_write_address = m_vdp_address_low | m_vdp_address_high<<16;
}
READ16_MEMBER(littlerb_state::littlerb_vdp_r)
{
logerror("%06x littlerb_vdp_r offs %04x mask %04x (address %08x)\n", space.device().safe_pc(), offset, mem_mask, m_write_address);
UINT16 res = 0;
switch (offset & 3)
{
case 0: res = m_vdp_address_low; break;
case 1: res = m_vdp_address_high; break;
case 2: res = littlerb_data_read(mem_mask); break;
case 3: res = m_vdp_writemode; break;
}
return res;
}
#define LOG_VDP 1
WRITE16_MEMBER(littlerb_state::littlerb_vdp_w)
{
if (offset!=2)
{
if (m_type2_writes)
{
if (m_type2_writes>2)
{
if (LOG_VDP) logerror("******************************* BIG WRITE OCCURRED BEFORE THIS!!! ****************************\n");
}
littlerb_printf("~%06x big write occured with start %08x end %08x (size %04x bytes)\n", m_lasttype2pc, m_write_address_laststart >> 3, m_write_address_lastend >> 3, m_type2_writes*2);
if (LOG_VDP) logerror("~%06x previously wrote %08x data bytes\n", m_lasttype2pc, m_type2_writes*2);
m_type2_writes = 0;
}
if (LOG_VDP) logerror("%06x littlerb_vdp_w offs %04x data %04x mask %04x\n", space.device().safe_pc(), offset, data, mem_mask);
}
else
{
if (mem_mask==0xffff)
{
if (m_type2_writes==0)
{
if (LOG_VDP) logerror("data write started %06x %04x data %04x mask %04x\n", space.device().safe_pc(), offset, data, mem_mask);
}
if (m_type2_writes==0) m_write_address_laststart = m_write_address;
m_write_address_lastend = m_write_address;
m_type2_writes++;
m_lasttype2pc = space.device().safe_pc();
}
else
{
if (LOG_VDP) logerror("xxx %06x littlerb_vdp_w offs %04x data %04x mask %04x\n", space.device().safe_pc(), offset, data, mem_mask);
}
}
switch (offset)
{
case 0:
COMBINE_DATA(&m_vdp_address_low);
littlerb_recalc_address();
break;
case 1:
COMBINE_DATA(&m_vdp_address_high);
littlerb_recalc_address();
break;
case 2:
littlerb_data_write(data, mem_mask);
break;
case 3:
COMBINE_DATA(&m_vdp_writemode);
int mode = m_vdp_writemode;
if ((mode!=0x3800) && (mode !=0x2000)) logerror("WRITE MODE CHANGED TO %04x\n",mode);
break;
}
}
#endif
static MACHINE_CONFIG_START( littlerb, littlerb_state )
@ -925,7 +377,6 @@ static MACHINE_CONFIG_START( littlerb, littlerb_state )
MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", littlerb_state, littlerb_scanline, "screen", 0, 1)
#if USE_TMS
MCFG_CPU_ADD("tms", TMS34010, XTAL_40MHz)
MCFG_CPU_CONFIG(tms_config_littlerb)
MCFG_CPU_PROGRAM_MAP(littlerb_tms_map)
@ -933,16 +384,7 @@ static MACHINE_CONFIG_START( littlerb, littlerb_state )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS(XTAL_40MHz/12, 424, 0, 338-1, 262, 0, 246-1)
MCFG_SCREEN_UPDATE_DEVICE("tms", tms34010_device, tms340x0_rgb32)
#else
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50) // guess based on high vertical resolution
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(512+22, 312)
MCFG_SCREEN_VISIBLE_AREA(0*8, 336-1, 0*8, 288-1)
MCFG_SCREEN_UPDATE_DRIVER(littlerb_state, screen_update_littlerb)
MCFG_SCREEN_PALETTE("palette")
MCFG_DEVICE_ADD("littlerbvdp", LITTLERBVDP, 0)
#endif
MCFG_PALETTE_ADD("palette", 0x100)

View File

@ -89,6 +89,7 @@ public:
m_palette(*this, "palette"),
m_tms(*this, "tms")
{
m_shiftfull = 0;
}
required_device<cpu_device> m_maincpu;
@ -160,6 +161,8 @@ public:
int m_soundsent;
UINT8 m_sounddata;
UINT8 m_soundback;
int m_shiftfull; // this might be a driver specific hack for a TMS bug.
};
@ -388,16 +391,28 @@ static void megaphx_scanline(screen_device &screen, bitmap_rgb32 &bitmap, int sc
}
static void megaphx_to_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg)
{
megaphx_state *state = space.machine().driver_data<megaphx_state>();
memcpy(shiftreg, &state->m_vram[TOWORD(address)/* & ~TOWORD(0x1fff)*/], TOBYTE(0x2000));
if (state->m_shiftfull == 0)
{
//printf("read to shift regs address %08x (%08x)\n", address, TOWORD(address) * 2);
memcpy(shiftreg, &state->m_vram[TOWORD(address)/* & ~TOWORD(0x1fff)*/], TOBYTE(0x2000));
state->m_shiftfull = 1;
}
}
static void megaphx_from_shiftreg(address_space &space, UINT32 address, UINT16 *shiftreg)
{
// printf("write from shift regs address %08x (%08x)\n", address, TOWORD(address) * 2);
megaphx_state *state = space.machine().driver_data<megaphx_state>();
memcpy(&state->m_vram[TOWORD(address)/* & ~TOWORD(0x1fff)*/], shiftreg, TOBYTE(0x2000));
state->m_shiftfull = 0;
}
MACHINE_RESET_MEMBER(megaphx_state,megaphx)