mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
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:
parent
3d7638f066
commit
af31cf37e4
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user