/***************************************************************************
-= 68020 + Imagetek 15000 Games =-
driver by David Haywood ( hazemamewip (at) hotmail.com )
partly based on metro.c driver by Luca Elia
Main CPU : MC68020
Video Chips : Imagetek 15000 |
Sound Chips : Imagetek 15000 |\- both sound and gfx
Other Features: Memory Blitter (part of Imagetek 15000)
---------------------------------------------------------------------------
Year + Game PCB Video Chip Issues / Notes
---------------------------------------------------------------------------
97 Rabbit VG5330-B 15000
97? Tokimeki Mahjong Paradise VG5550-B 15000
---------------------------------------------------------------------------
Not dumped yet:
unknown
To Do:
- raster effects (rabbit only?, see left side of one of the levels in rabbit)
- clean up zoom code and make zoom effect more accurate
- sound (adpcm of some kind)
- tilemap.c can't handle tiles with different transpens so we have to invert
the tilegfx, this means we also have to invert the palette write addresses,
low bits of the palette number for 4bpp tiles, the blitter data as it
is read from the gfx roms, and the data read by the rom test.
*/
/*
Rabbit PCB Layout
-----------------
VG5330-B
|---------------------------------|
| 62256 62256 61 60 |
| 62256 62256 51 50 |
| 62256 62256 |
| 62256 62256 43 42 |
| 41 40 |
| |
|J IMAGETEK 33 32 |
|A 15000 23 22 |
|M 40MHz |
|M 13 12 |
|A 68EC020 03 02 |
| ALTERA |
| EPM7032 24MHz 31 30 |
| 93C46 21 20 |
| |
| JPR2 JPR0 62256 11 10 |
| JPR3 JPR1 62256 01 00 |
|---------------------------------|
Notes:
68020 clock: 24.000MHz
VSync: 60Hz
Tokimeki Mahjong Paradise - Dear My Love Board Notes
----------------------------------------------------
Board: VG5550-B
CPU: MC68EC020FG25
OSC: 40.00000MHz
24.00000MHz
Custom: Imagetek 15000 (2ch video & 2ch sound)
*/
#include "driver.h"
#include "machine/eeprom.h"
#define VERBOSE_AUDIO_LOG (0) // enable to show audio writes (very noisy when music is playing)
/* debug */
static UINT32 *rabbit_viewregs0;
static UINT32 *rabbit_viewregs6;
static UINT32 *rabbit_viewregs7;
static UINT32 *rabbit_viewregs9;
static UINT32 *rabbit_viewregs10;
static UINT32 *rabbit_tilemap_regs[4];
static UINT32 *rabbit_spriteregs;
static UINT32 *rabbit_blitterregs;
static mame_bitmap *rabbit_sprite_bitmap;
static rectangle rabbit_sprite_clip;
static int rabbit_vblirqlevel, rabbit_bltirqlevel, rabbit_banking;
static UINT32 *rabbit_tilemap_ram[4];
static UINT32 *rabbit_spriteram;
static tilemap *rabbit_tilemap[4];
/* call with tilesize = 0 for 8x8 or 1 for 16x16 */
INLINE void get_rabbit_tilemap_info(running_machine *machine, tile_data *tileinfo, int tile_index, int whichtilemap, int tilesize)
{
int tileno,colour,flipxy, depth;
int bank;
depth = (rabbit_tilemap_ram[whichtilemap][tile_index]&0x10000000)>>28;
tileno = rabbit_tilemap_ram[whichtilemap][tile_index]&0xffff;
bank = (rabbit_tilemap_ram[whichtilemap][tile_index]&0x000f0000)>>16;
colour = (rabbit_tilemap_ram[whichtilemap][tile_index]>>20)&0xff;
flipxy = (rabbit_tilemap_ram[whichtilemap][tile_index]>>29)&3;
if(rabbit_banking)
{
switch (bank)
{
case 0x8:
tileno += 0x10000;
break;
case 0xc:
tileno += 0x20000;
break;
}
}
else
tileno += (bank << 16);
if (depth)
{
tileno >>=(1+tilesize*2);
colour&=0x0f;
colour+=0x20;
SET_TILE_INFO(6+tilesize,tileno,colour,TILE_FLIPXY(flipxy));
}
else
{
tileno >>=(0+tilesize*2);
colour+=0x200;
colour ^=0xf; // ^0xf because we've inverted palette writes (see notes in driver init)
SET_TILE_INFO(4+tilesize,tileno,colour,TILE_FLIPXY(flipxy));
}
}
static TILE_GET_INFO( get_rabbit_tilemap0_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,0,1);
}
static TILE_GET_INFO( get_rabbit_tilemap1_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,1,1);
}
static TILE_GET_INFO( get_rabbit_tilemap2_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,2,1);
}
/* some bad colours on life bars for this layer .. fix them ..
(needs mask of 0x3f but this breaks other gfx..) */
static TILE_GET_INFO( get_rabbit_tilemap3_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,3,0);
}
static WRITE32_HANDLER( rabbit_tilemap0_w )
{
COMBINE_DATA(&rabbit_tilemap_ram[0][offset]);
tilemap_mark_tile_dirty(rabbit_tilemap[0],offset);
}
static WRITE32_HANDLER( rabbit_tilemap1_w )
{
COMBINE_DATA(&rabbit_tilemap_ram[1][offset]);
tilemap_mark_tile_dirty(rabbit_tilemap[1],offset);
}
static WRITE32_HANDLER( rabbit_tilemap2_w )
{
COMBINE_DATA(&rabbit_tilemap_ram[2][offset]);
tilemap_mark_tile_dirty(rabbit_tilemap[2],offset);
}
static WRITE32_HANDLER( rabbit_tilemap3_w )
{
COMBINE_DATA(&rabbit_tilemap_ram[3][offset]);
tilemap_mark_tile_dirty(rabbit_tilemap[3],offset);
}
/*
'spriteregs' format (7 dwords)
00000XXX 0YYYAAAA 0000BBBB 0000CCCC 03065000 00720008 00a803bc
zoom zoom zoom Strt/End
XXX = global Xpos
YYY = global Ypos
AAAA = 0100 when normal, 018c when zoomed out
BBBB = 9f80 when normal, f6ba when zoomed out 0x9f80 / 128 = 319
CCCC = 6f80 when normal, ac7a when zoomed out 0x6f80 / 128 = 223
sprites invisible at the end of a round in rabbit, why?
*/
static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect )
{
int xpos,ypos,tileno,xflip,yflip, colr;
const gfx_element *gfx = machine->gfx[1];
int todraw = (rabbit_spriteregs[5]&0x0fff0000)>>16; // how many sprites to draw (start/end reg..) what is the other half?
UINT32 *source = (rabbit_spriteram+ (todraw*2))-2;
UINT32 *finish = rabbit_spriteram;
// fillbitmap(rabbit_sprite_bitmap, 0x0, &rabbit_sprite_clip); // sloooow
while( source>=finish )
{
xpos = (source[0]&0x00000fff);
ypos = (source[0]&0x0fff0000)>>16;
xflip = (source[0]&0x00008000)>>15;
yflip = (source[0]&0x00004000)>>14;
colr = (source[1]&0x0ff00000)>>15;
tileno = (source[1]&0x0001ffff);
colr = (source[1]&0x0ff00000)>>20;
colr ^= 0xf;
if(xpos&0x800)xpos-=0x1000;
drawgfx(rabbit_sprite_bitmap,gfx,tileno,colr,!xflip/*wrongdecode?*/,yflip,xpos+0x20-8/*-(rabbit_spriteregs[0]&0x00000fff)*/,ypos-24/*-((rabbit_spriteregs[1]&0x0fff0000)>>16)*/,&rabbit_sprite_clip,TRANSPARENCY_PEN,0);
// drawgfx(bitmap,gfx,tileno,colr,!xflip/*wrongdecode?*/,yflip,xpos+0xa0-8/*-(rabbit_spriteregs[0]&0x00000fff)*/,ypos-24+0x80/*-((rabbit_spriteregs[1]&0x0fff0000)>>16)*/,cliprect,TRANSPARENCY_PEN,0);
source-=2;
}
}
/* the sprite bitmap can probably be handled better than this ... */
static void rabbit_clearspritebitmap( mame_bitmap *bitmap, const rectangle *cliprect )
{
int startx, starty;
int y;
int amountx,amounty;
UINT16 *dstline;
/* clears a *sensible* amount of the sprite bitmap */
startx = (rabbit_spriteregs[0]&0x00000fff);
starty = (rabbit_spriteregs[1]&0x0fff0000)>>16;
startx-=200;
starty-=200;
amountx =650;
amounty =600;
if (startx < 0) { amountx += startx; startx = 0; }
if ((startx+amountx)>=0x1000) amountx-=(0x1000-(startx+amountx));
for (y=0; y<amounty;y++)
{
dstline = BITMAP_ADDR16(rabbit_sprite_bitmap, (starty+y)&0xfff, 0);
memset(dstline+startx,0x00,amountx*2);
}
}
/* todo: fix zoom, its inaccurate and this code is ugly */
static void draw_sprite_bitmap( mame_bitmap *bitmap, const rectangle *cliprect )
{
UINT32 x,y;
UINT16 *srcline;
UINT16 *dstline;
UINT16 pixdata;
UINT32 xsize, ysize;
UINT32 xdrawpos, ydrawpos;
UINT32 xstep,ystep;
int startx, starty;
startx = ((rabbit_spriteregs[0]&0x00000fff));
starty = ((rabbit_spriteregs[1]&0x0fff0000)>>16);
/* zoom compensation? */
startx-=((rabbit_spriteregs[1]&0x000001ff)>>1);
starty-=((rabbit_spriteregs[1]&0x000001ff)>>1);
xsize = ((rabbit_spriteregs[2]&0x0000ffff));
ysize = ((rabbit_spriteregs[3]&0x0000ffff));
xsize+=0x80;
ysize+=0x80;
xstep = ((320*128)<<16) / xsize;
ystep = ((224*128)<<16) / ysize;
ydrawpos = 0;
for (y=0;y<ysize;y+=0x80)
{
ydrawpos = ((y>>7)*ystep);
ydrawpos >>=16;
if ((ydrawpos >= cliprect->min_y) && (ydrawpos <= cliprect->max_y))
{
srcline = BITMAP_ADDR16(rabbit_sprite_bitmap, (starty+(y>>7))&0xfff, 0);
dstline = BITMAP_ADDR16(bitmap, ydrawpos, 0);
for (x=0;x<xsize;x+=0x80)
{
xdrawpos = ((x>>7)*xstep);
xdrawpos >>=16;
pixdata = srcline[(startx+(x>>7))&0xfff];
if (pixdata)
if ((xdrawpos >= cliprect->min_x) && (xdrawpos <= cliprect->max_x))
dstline[xdrawpos] = pixdata;
}
}
}
}
static VIDEO_START(rabbit)
{
/* the tilemaps are bigger than the regions the cpu can see, need to allocate the ram here */
/* or maybe not for this game/hw .... */
rabbit_tilemap_ram[0] = auto_malloc(0x20000);
rabbit_tilemap_ram[1] = auto_malloc(0x20000);
rabbit_tilemap_ram[2] = auto_malloc(0x20000);
rabbit_tilemap_ram[3] = auto_malloc(0x20000);
memset(rabbit_tilemap_ram[0], 0, 0x20000);
memset(rabbit_tilemap_ram[1], 0, 0x20000);
memset(rabbit_tilemap_ram[2], 0, 0x20000);
memset(rabbit_tilemap_ram[3], 0, 0x20000);
rabbit_tilemap[0] = tilemap_create(get_rabbit_tilemap0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 16, 16, 128,32);
rabbit_tilemap[1] = tilemap_create(get_rabbit_tilemap1_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 16, 16, 128,32);
rabbit_tilemap[2] = tilemap_create(get_rabbit_tilemap2_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 16, 16, 128,32);
rabbit_tilemap[3] = tilemap_create(get_rabbit_tilemap3_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 8, 8, 128,32);
tilemap_set_transparent_pen(rabbit_tilemap[0],0x0);
tilemap_set_transparent_pen(rabbit_tilemap[1],0x0);
tilemap_set_transparent_pen(rabbit_tilemap[2],0x0);
tilemap_set_transparent_pen(rabbit_tilemap[3],0x0);
rabbit_sprite_bitmap = auto_bitmap_alloc(0x1000,0x1000,machine->screen[0].format);
rabbit_sprite_clip.min_x = 0;
rabbit_sprite_clip.max_x = 0x1000-1;
rabbit_sprite_clip.min_y = 0;
rabbit_sprite_clip.max_y = 0x1000-1;
}
/*
info based on rabbit
tilemap regs format (6 dwords, 1 set for each tilemap)
each line represents the differences on each tilemap for unknown variables
(tilemap)
(0) 0P660000 YYYYXXXX 0000**00 0000AAAA BBBB0000 00fx0000 ** = 00 during title, 8f during game, x = 0 during title, 1 during game
(1) 1 00 0
(2) 2 00 0
(3) 263 00 0
0123456789abcdef = never change?
P = priority
Y = Yscroll
X = Xscroll
A = Yzoom (maybe X) (0800 = normal, 0C60 = fully zoomed out)
B = Xzoom (maybe Y) (0800 = normal, 0C60 = fully zoomed out)
*/
static void rabbit_drawtilemap( mame_bitmap *bitmap, const rectangle *cliprect, int whichtilemap )
{
INT32 startx, starty, incxx, incxy, incyx, incyy, tran;
startx=((rabbit_tilemap_regs[whichtilemap][1]&0x0000ffff)); // >>4 for nonzoomed pixel scroll value
starty=((rabbit_tilemap_regs[whichtilemap][1]&0xffff0000)>>16); // >> 20 for nonzoomed pixel scroll value
incxx= ((rabbit_tilemap_regs[whichtilemap][3]&0x00000fff)); // 0x800 when non-zoomed
incyy= ((rabbit_tilemap_regs[whichtilemap][4]&0x0fff0000)>>16);
incxy = 0; incyx = 0;
tran = 1;
/* incxx and incyy and standard zoom, 16.16, a value of 0x10000 means no zoom
startx/starty are also 16.16 scrolling
*/
tilemap_draw_roz(bitmap,cliprect,rabbit_tilemap[whichtilemap],startx << 12,starty << 12,
incxx << 5,incxy << 8,incyx << 8,incyy << 5,
1, /* wraparound */
tran ? 0 : TILEMAP_DRAW_OPAQUE,0);
}
static VIDEO_UPDATE(rabbit)
{
int prilevel;
fillbitmap(bitmap,get_black_pen(machine),cliprect);
// popmessage("%08x %08x", rabbit_viewregs0[0], rabbit_viewregs0[1]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[0][0],rabbit_tilemap_regs[0][1],rabbit_tilemap_regs[0][2],rabbit_tilemap_regs[0][3],rabbit_tilemap_regs[0][4],rabbit_tilemap_regs[0][5]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[1][0],rabbit_tilemap_regs[1][1],rabbit_tilemap_regs[1][2],rabbit_tilemap_regs[1][3],rabbit_tilemap_regs[1][4],rabbit_tilemap_regs[1][5]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[2][0],rabbit_tilemap_regs[2][1],rabbit_tilemap_regs[2][2],rabbit_tilemap_regs[2][3],rabbit_tilemap_regs[2][4],rabbit_tilemap_regs[2][5]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[3][0],rabbit_tilemap_regs[3][1],rabbit_tilemap_regs[3][2],rabbit_tilemap_regs[3][3],rabbit_tilemap_regs[3][4],rabbit_tilemap_regs[3][5]);
// popmessage("%08x %08x %08x %08x %08x %08x %08x", rabbit_spriteregs[0],rabbit_spriteregs[1],rabbit_spriteregs[2],rabbit_spriteregs[3],rabbit_spriteregs[4],rabbit_spriteregs[5], rabbit_spriteregs[6]);
// popmessage("%08x %08x %08x %08x %08x", rabbit_viewregs6[0],rabbit_viewregs6[1],rabbit_viewregs6[2],rabbit_viewregs6[3],rabbit_viewregs6[4]);
// popmessage("%08x", rabbit_viewregs7[0]);
// popmessage("%08x %08x %08x %08x", rabbit_blitterregs[0],rabbit_blitterregs[1],rabbit_blitterregs[2],rabbit_blitterregs[3]);
// popmessage("%08x %08x %08x %08x", rabbit_viewregs9[0],rabbit_viewregs9[1],rabbit_viewregs9[2],rabbit_viewregs9[3]);
// popmessage("%08x %08x %08x %08x %08x", rabbit_viewregs10[0],rabbit_viewregs10[1],rabbit_viewregs10[2],rabbit_viewregs10[3],rabbit_viewregs10[4]);
/* prio isnt certain but seems to work.. */
for (prilevel = 0xf; prilevel >0; prilevel--)
{
if (prilevel == ((rabbit_tilemap_regs[3][0]&0x0f000000)>>24)) rabbit_drawtilemap(bitmap,cliprect, 3);
if (prilevel == ((rabbit_tilemap_regs[2][0]&0x0f000000)>>24)) rabbit_drawtilemap(bitmap,cliprect, 2);
if (prilevel == ((rabbit_tilemap_regs[1][0]&0x0f000000)>>24)) rabbit_drawtilemap(bitmap,cliprect, 1);
if (prilevel == ((rabbit_tilemap_regs[0][0]&0x0f000000)>>24)) rabbit_drawtilemap(bitmap,cliprect, 0);
if (prilevel == 0x09) // should it be selectable?
{
rabbit_clearspritebitmap(bitmap,cliprect);
draw_sprites(machine,bitmap,cliprect); // render to bitmap
draw_sprite_bitmap(bitmap,cliprect); // copy bitmap to screen
}
}
return 0;
}
static READ32_HANDLER( rabbit_input_r )
{
int rv;
rv = (readinputport(1)<<16)|(readinputport(0));
rv &= ~1;
rv |= EEPROM_read_bit(); // as per code at 4d932
return rv;
}
static READ32_HANDLER( tmmjprd_input_r )
{
int rv;
rv = (readinputport(1)<<16)|(readinputport(0));
rv &= ~0x80;
rv |= (EEPROM_read_bit()<<7); // as per code at 778
return rv;
}
static WRITE32_HANDLER( rabbit_paletteram_dword_w )
{
int r,g,b;
COMBINE_DATA(&paletteram32[offset]);
b = ((paletteram32[offset] & 0x000000ff) >>0);
r = ((paletteram32[offset] & 0x0000ff00) >>8);
g = ((paletteram32[offset] & 0x00ff0000) >>16);
palette_set_color(Machine,offset^0xff,MAKE_RGB(r,g,b));
}
static READ32_HANDLER( rabbit_tilemap0_r )
{
return rabbit_tilemap_ram[0][offset];
}
static READ32_HANDLER( rabbit_tilemap1_r )
{
return rabbit_tilemap_ram[1][offset];
}
static READ32_HANDLER( rabbit_tilemap2_r )
{
return rabbit_tilemap_ram[2][offset];
}
static READ32_HANDLER( rabbit_tilemap3_r )
{
return rabbit_tilemap_ram[3][offset];
}
static READ32_HANDLER( randomrabbits )
{
return mame_rand(Machine);
}
static ADDRESS_MAP_START( rabbit_readmem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x1fffff) AM_READ(MRA32_ROM)
AM_RANGE(0x200000, 0x200003) AM_READ(rabbit_input_r)
AM_RANGE(0x400010, 0x400013) AM_READ(randomrabbits) // gfx chip status?
AM_RANGE(0x400980, 0x400983) AM_READ(randomrabbits) // sound chip status?
AM_RANGE(0x400984, 0x400987) AM_READ(randomrabbits) // sound chip status?
AM_RANGE(0x440000, 0x47ffff) AM_READ(MRA32_BANK1) // roms read from here during testing
/* tilemaps */
AM_RANGE(0x480000, 0x483fff) AM_READ(rabbit_tilemap0_r)
AM_RANGE(0x484000, 0x487fff) AM_READ(rabbit_tilemap1_r)
AM_RANGE(0x488000, 0x48bfff) AM_READ(rabbit_tilemap2_r)
AM_RANGE(0x48c000, 0x48ffff) AM_READ(rabbit_tilemap3_r)
AM_RANGE(0x494000, 0x49ffff) AM_READ(MRA32_RAM)
AM_RANGE(0x4a0000, 0x4affff) AM_READ(MRA32_RAM) /* palette */
AM_RANGE(0xff0000, 0xffffff) AM_READ(MRA32_RAM)
ADDRESS_MAP_END
/* rom bank is used when testing roms, not currently hooked up */
static WRITE32_HANDLER ( rabbit_rombank_w )
{
UINT8 *dataroms = memory_region(REGION_USER1);
int bank;
// mame_printf_debug("rabbit rombank %08x\n",data&0x3ff);
bank = data & 0x3ff;
// memory_set_bankptr(1,&dataroms[0x40000*(bank&0x3ff)]);
memory_set_bankptr(1,&dataroms[0]);
}
/*
Audio notes:
There are 16 PCM voices. Each voice has 4 16-bit wide registers.
Voice 0 uses registers 0-3, 1 uses registers 4-7, etc.
The first 2 registers for each voice are the LSW and MSW of the sample
starting address. The remaining 2 haven't been figured out yet.
Registers 64 and up are "global", they don't belong to any specific voice.
Register 66 is key-on (bitmapped so bit 0 = voice 0, bit 15 = voice 15).
Register 67 is key-off (bitmapped identically to the key-on register).
There are a few other "global" registers, their purpose is unknown at this
time (timer? the game seems to "play music" fine with just the VBL).
*/
static WRITE32_HANDLER( rabbit_audio_w )
{
#if VERBOSE_AUDIO_LOG
int reg, voice, base, i;
if (mem_mask == 0x0000ffff)
{
reg = offset*2;
data >>= 16;
}
else if (mem_mask == 0xffff0000)
{
reg = (offset*2)+1;
data &= 0xffff;
}
else logerror("audio error: unknown mask %08x\n", mem_mask);
if (reg < 64)
{
voice = reg / 4;
base = voice*4;
logerror("V%02d: parm %d = %04x\n", voice, reg-base, data);
}
else
{
if (reg == 66)
{
logerror("Key on [%04x]: ", data);
for (i = 0; i < 16; i++)
{
if (data & (1<<i))
{
logerror("%02d ", i);
}
}
logerror("\n");
}
else if (reg == 67)
{
logerror("Key off [%04x]: ", data);
for (i = 0; i < 16; i++)
{
if (data & (1<<i))
{
logerror("%02d ", i);
}
}
logerror("\n");
}
else
{
logerror("Unknown write %04x to global reg %d\n", data, reg);
}
}
#endif
}
#define BLITCMDLOG 0
#define BLITLOG 0
static TIMER_CALLBACK( rabbit_blit_done )
{
cpunum_set_input_line(0, rabbit_bltirqlevel, HOLD_LINE);
}
static void rabbit_do_blit(void)
{
UINT8 *blt_data = memory_region(REGION_USER1);
int blt_source = (rabbit_blitterregs[0]&0x000fffff)>>0;
int blt_column = (rabbit_blitterregs[1]&0x00ff0000)>>16;
int blt_line = (rabbit_blitterregs[1]&0x000000ff);
int blt_tilemp = (rabbit_blitterregs[2]&0x0000e000)>>13;
int blt_oddflg = (rabbit_blitterregs[2]&0x00000001)>>0;
int mask,shift;
if(BLITCMDLOG) mame_printf_debug("BLIT command %08x %08x %08x\n", rabbit_blitterregs[0], rabbit_blitterregs[1], rabbit_blitterregs[2]);
if (blt_oddflg&1)
{
mask = 0xffff0000;
shift= 0;
}
else
{
mask = 0x0000ffff;
shift= 16;
}
blt_oddflg>>=1; /* blt_oddflg is now in dword offsets*/
blt_oddflg+=0x80*blt_line;
blt_source<<=1; /* blitsource is in word offsets */
while(1)
{
int blt_commnd = blt_data[blt_source+1]^0xff;
int blt_amount = blt_data[blt_source+0]^0xff;
int blt_value;
int loopcount;
int writeoffs;
blt_source+=2;
switch (blt_commnd)
{
case 0x00: /* copy nn bytes */
if (!blt_amount)
{
if(BLITLOG) mame_printf_debug("end of blit list\n");
timer_set(ATTOTIME_IN_USEC(500),0,rabbit_blit_done);
return;
}
if(BLITLOG) mame_printf_debug("blit copy %02x bytes\n", blt_amount);
for (loopcount=0;loopcount<blt_amount;loopcount++)
{
blt_value = ((blt_data[blt_source+1]<<8)|(blt_data[blt_source+0]))^0xffff;
blt_source+=2;
writeoffs=blt_oddflg+blt_column;
rabbit_tilemap_ram[blt_tilemp][writeoffs]=(rabbit_tilemap_ram[blt_tilemp][writeoffs]&mask)|(blt_value<<shift);
tilemap_mark_tile_dirty(rabbit_tilemap[blt_tilemp],writeoffs);
blt_column++;
blt_column&=0x7f;
}
break;
case 0x02: /* fill nn bytes */
if(BLITLOG) mame_printf_debug("blit fill %02x bytes\n", blt_amount);
blt_value = ((blt_data[blt_source+1]<<8)|(blt_data[blt_source+0]))^0xffff;
blt_source+=2;
for (loopcount=0;loopcount<blt_amount;loopcount++)
{
writeoffs=blt_oddflg+blt_column;
rabbit_tilemap_ram[blt_tilemp][writeoffs]=(rabbit_tilemap_ram[blt_tilemp][writeoffs]&mask)|(blt_value<<shift);
tilemap_mark_tile_dirty(rabbit_tilemap[blt_tilemp],writeoffs);
blt_column++;
blt_column&=0x7f;
}
break;
case 0x03: /* next line */
if(BLITLOG) mame_printf_debug("blit: move to next line\n");
blt_column = (rabbit_blitterregs[1]&0x00ff0000)>>16; /* --CC---- */
blt_oddflg+=128;
break;
default: /* unknown / illegal */
if(BLITLOG) mame_printf_debug("uknown blit command %02x\n",blt_commnd);
break;
}
}
}
static WRITE32_HANDLER( rabbit_blitter_w )
{
COMBINE_DATA(&rabbit_blitterregs[offset]);
if (offset == 0x0c/4)
{
rabbit_do_blit();
}
}
static WRITE32_HANDLER( rabbit_eeprom_write )
{
// don't disturb the EEPROM if we're not actually writing to it
// (in particular, data & 0x100 here with mask = ffff00ff looks to be the watchdog)
if (mem_mask == 0x00ffffff)
{
// latch the bit
EEPROM_write_bit(data & 0x01000000);
// reset line asserted: reset.
EEPROM_set_cs_line((data & 0x04000000) ? CLEAR_LINE : ASSERT_LINE );
// clock line asserted: write latch or select next bit to read
EEPROM_set_clock_line((data & 0x02000000) ? ASSERT_LINE : CLEAR_LINE );
}
}
static ADDRESS_MAP_START( rabbit_writemem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x000003) AM_WRITE(MWA32_NOP) // bug in code / emulation?
AM_RANGE(0x000010, 0x000013) AM_WRITE(MWA32_NOP) // bug in code / emulation?
AM_RANGE(0x000024, 0x000027) AM_WRITE(MWA32_NOP) // bug in code / emulation?
AM_RANGE(0x00719C, 0x00719F) AM_WRITE(MWA32_NOP) // bug in code / emulation?
AM_RANGE(0x000000, 0x1fffff) AM_WRITE(MWA32_ROM)
AM_RANGE(0x200000, 0x200003) AM_WRITE(rabbit_eeprom_write)
/* this lot are probably gfxchip/blitter etc. related */
AM_RANGE(0x400010, 0x400013) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs0 )
AM_RANGE(0x400100, 0x400117) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[0] ) // tilemap regs1
AM_RANGE(0x400120, 0x400137) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[1] ) // tilemap regs2
AM_RANGE(0x400140, 0x400157) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[2] ) // tilemap regs3
AM_RANGE(0x400160, 0x400177) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[3] ) // tilemap regs4
AM_RANGE(0x400200, 0x40021b) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_spriteregs ) // sprregs?
AM_RANGE(0x400300, 0x400303) AM_WRITE(rabbit_rombank_w) // used during rom testing, rombank/area select + something else?
AM_RANGE(0x400400, 0x400413) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs6 ) // some global controls? (brightness etc.?)
AM_RANGE(0x400500, 0x400503) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs7 )
AM_RANGE(0x400700, 0x40070f) AM_WRITE(rabbit_blitter_w) AM_BASE( &rabbit_blitterregs )
AM_RANGE(0x400800, 0x40080f) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs9 ) // never changes?
AM_RANGE(0x400900, 0x40098f) AM_WRITE(rabbit_audio_w)
/* hmm */
AM_RANGE(0x479700, 0x479713) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs10 )
/* tilemaps */
AM_RANGE(0x480000, 0x483fff) AM_WRITE(rabbit_tilemap0_w)
AM_RANGE(0x484000, 0x487fff) AM_WRITE(rabbit_tilemap1_w)
AM_RANGE(0x488000, 0x48bfff) AM_WRITE(rabbit_tilemap2_w)
AM_RANGE(0x48c000, 0x48ffff) AM_WRITE(rabbit_tilemap3_w)
AM_RANGE(0x494000, 0x497fff) AM_WRITE(MWA32_RAM) AM_BASE(&rabbit_spriteram) // sprites?
AM_RANGE(0x4a0000, 0x4affff) AM_WRITE(rabbit_paletteram_dword_w) AM_BASE(&paletteram32)
AM_RANGE(0xff0000, 0xffffff) AM_WRITE(MWA32_RAM)
ADDRESS_MAP_END
/* tmmjprd has a different memory map */
static ADDRESS_MAP_START( tmmjprd_readmem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x1fffff) AM_READ(MRA32_ROM)
AM_RANGE(0x200010, 0x200013) AM_READ(randomrabbits) // gfx chip status?
AM_RANGE(0x200980, 0x200983) AM_READ(randomrabbits) // sound chip status?
AM_RANGE(0x200984, 0x200987) AM_READ(randomrabbits) // sound chip status?
AM_RANGE(0x280000, 0x283fff) AM_READ(rabbit_tilemap0_r)
AM_RANGE(0x284000, 0x287fff) AM_READ(rabbit_tilemap1_r)
AM_RANGE(0x288000, 0x28bfff) AM_READ(rabbit_tilemap2_r)
AM_RANGE(0x28c000, 0x28ffff) AM_READ(rabbit_tilemap3_r)
AM_RANGE(0x290000, 0x29ffff) AM_READ(MRA32_RAM)
AM_RANGE(0x400000, 0x400003) AM_READ(tmmjprd_input_r)
AM_RANGE(0xf00000, 0xffffff) AM_READ(MRA32_RAM)
ADDRESS_MAP_END
static WRITE32_HANDLER( tmmjprd_paletteram_dword_w )
{
int r,g,b;
COMBINE_DATA(&paletteram32[offset]);
b = ((paletteram32[offset] & 0x000000ff) >>0);
r = ((paletteram32[offset] & 0x0000ff00) >>8);
g = ((paletteram32[offset] & 0x00ff0000) >>16);
palette_set_color(Machine,(offset^0xff)+0x2000,MAKE_RGB(r,g,b));
}
static ADDRESS_MAP_START( tmmjprd_writemem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x1fffff) AM_WRITE(MWA32_ROM)
/* check these are used .. */
// AM_RANGE(0x200010, 0x200013) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs0 )
AM_RANGE(0x200100, 0x200117) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[0] ) // tilemap regs1
AM_RANGE(0x200120, 0x200137) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[1] ) // tilemap regs2
AM_RANGE(0x200140, 0x200157) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[2] ) // tilemap regs3
AM_RANGE(0x200160, 0x200177) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_tilemap_regs[3] ) // tilemap regs4
AM_RANGE(0x200200, 0x20021b) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_spriteregs ) // sprregs?
// AM_RANGE(0x200300, 0x200303) AM_WRITE(rabbit_rombank_w) // used during rom testing, rombank/area select + something else?
// AM_RANGE(0x200400, 0x200413) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs6 ) // some global controls? (brightness etc.?)
// AM_RANGE(0x200500, 0x200503) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs7 )
// AM_RANGE(0x200700, 0x20070f) AM_WRITE(rabbit_blitter_w) AM_BASE( &rabbit_blitterregs )
// AM_RANGE(0x200800, 0x20080f) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs9 ) // never changes?
// AM_RANGE(0x200900, 0x20098f) AM_WRITE(rabbit_audio_w)
/* hmm */
// AM_RANGE(0x279700, 0x279713) AM_WRITE(MWA32_RAM) AM_BASE( &rabbit_viewregs10 )
/* tilemaps */
AM_RANGE(0x280000, 0x283fff) AM_WRITE(rabbit_tilemap0_w)
AM_RANGE(0x284000, 0x287fff) AM_WRITE(rabbit_tilemap1_w)
AM_RANGE(0x288000, 0x28bfff) AM_WRITE(rabbit_tilemap2_w)
AM_RANGE(0x28c000, 0x28ffff) AM_WRITE(rabbit_tilemap3_w)
/* ?? is palette ram shared with sprites in this case or just a different map */
AM_RANGE(0x290000, 0x29bfff) AM_WRITE(MWA32_RAM) AM_BASE(&rabbit_spriteram)
AM_RANGE(0x29c000, 0x29ffff) AM_WRITE(tmmjprd_paletteram_dword_w) AM_BASE(&paletteram32)
AM_RANGE(0x400000, 0x400003) AM_WRITE(rabbit_eeprom_write)
AM_RANGE(0xf00000, 0xffffff) AM_WRITE(MWA32_RAM)
ADDRESS_MAP_END
static INPUT_PORTS_START( rabbit )
PORT_START /* 16bit */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SPECIAL ) // Eeprom
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN ) // unlabeled in input test
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_SERVICE( 0x0020, IP_ACTIVE_LOW )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
PORT_START /* 16bit */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
INPUT_PORTS_END
static INPUT_PORTS_START( tmmjprd )
PORT_START /* 16bit */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN ) // unlabeled in input test
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_SERVICE( 0x0020, IP_ACTIVE_LOW )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_SPECIAL ) // Eeprom
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
PORT_START /* 16bit */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
INPUT_PORTS_END
static const gfx_layout rabbit_sprite_8x8x4_layout =
{
8,8,
RGN_FRAC(1,1),
4,
{ 0,1,2,3 },
{ 8,12,0,4, 24,28,16,20 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
8*32
};
static const gfx_layout rabbit_sprite_8x8x8_layout =
{
8,8,
RGN_FRAC(1,1),
8,
{ 0,1,2,3,4,5,6,7 },
{ 8,0, 40,32,24,16,56, 48 },
{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 },
8*64
};
static const gfx_layout rabbit_sprite_16x16x4_layout =
{
16,16,
RGN_FRAC(1,2),
4,
{ 0,1,2,3 },
{ RGN_FRAC(1,2)+8,RGN_FRAC(1,2)+12,RGN_FRAC(1,2)+0,RGN_FRAC(1,2)+4,RGN_FRAC(1,2)+24,RGN_FRAC(1,2)+28,RGN_FRAC(1,2)+16,RGN_FRAC(1,2)+20, 8,12,0,4, 24,28,16,20 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32,8*32,9*32,10*32,11*32,12*32,13*32,14*32,15*32 },
16*32
};
static const gfx_layout rabbit_sprite_16x16x8_layout =
{
16,16,
RGN_FRAC(1,2),
8,
{ 0,1,2,3,4,5,6,7 },
{ RGN_FRAC(1,2)+8,RGN_FRAC(1,2)+0,RGN_FRAC(1,2)+24,RGN_FRAC(1,2)+16,RGN_FRAC(1,2)+40,RGN_FRAC(1,2)+32,RGN_FRAC(1,2)+56,RGN_FRAC(1,2)+48, 8,0,24,16, 40,32,56,48 },
{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,8*64,9*64,10*64,11*64,12*64,13*64,14*64,15*64 },
16*64
};
static const gfx_layout rabbit_8x8x4_layout =
{
8,8,
RGN_FRAC(1,1),
4,
{ 0,1,2,3 },
{ 4,0,12,8,20,16,28,24 },
{ 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
8*32
};
static const gfx_layout rabbit_16x16x4_layout =
{
16,16,
RGN_FRAC(1,1),
4,
{ 0,1,2,3 },
{ 4,0,12,8, 20,16,28,24,36,32,44,40,52,48,60,56 },
{ 0*64, 1*64, 2*64,3*64,4*64,5*64,6*64,7*64,8*64,9*64,10*64,11*64,12*64,13*64,14*64,15*64 },
16*64
};
static const gfx_layout rabbit_8x8x8_layout =
{
8,8,
RGN_FRAC(1,1),
8,
{ 0,1,2,3,4,5,6,7 },
{ 0,8,16,24,32,40,48,56 },
{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 },
8*64
};
static const gfx_layout rabbit_16x16x8_layout =
{
16,16,
RGN_FRAC(1,1),
8,
{ 0,1,2,3,4,5,6,7 },
{ 0,8,16,24,32,40,48,56, 64, 72, 80, 88, 96, 104, 112, 120 },
{ 0*128, 1*128, 2*128,3*128,4*128,5*128,6*128,7*128,8*128,9*128,10*128,11*128,12*128,13*128,14*128,15*128 },
16*128
};
static GFXDECODE_START( rabbit )
/* this seems to be sprites */
GFXDECODE_ENTRY( REGION_USER1, 0, rabbit_sprite_8x8x4_layout, 0x0, 0x1000 )
GFXDECODE_ENTRY( REGION_USER1, 0, rabbit_sprite_16x16x4_layout, 0x0, 0x1000 )
GFXDECODE_ENTRY( REGION_USER1, 0, rabbit_sprite_8x8x8_layout, 0x0, 0x1000 ) // wrong
GFXDECODE_ENTRY( REGION_USER1, 0, rabbit_sprite_16x16x8_layout, 0x0, 0x1000 ) // wrong
/* this seems to be backgrounds and tilemap gfx */
GFXDECODE_ENTRY( REGION_USER2, 0, rabbit_8x8x4_layout, 0x0, 0x1000 )
GFXDECODE_ENTRY( REGION_USER2, 0, rabbit_16x16x4_layout, 0x0, 0x1000 )
GFXDECODE_ENTRY( REGION_USER2, 0, rabbit_8x8x8_layout, 0x0, 0x1000 )
GFXDECODE_ENTRY( REGION_USER2, 0, rabbit_16x16x8_layout, 0x0, 0x1000 )
GFXDECODE_END
/* irq 6 = vblank
irq 4 = blitter done?
irq 5 = ?
irq 1 = ?
*/
static INTERRUPT_GEN( rabbit_interrupts )
{
int intlevel = 0;
int line = 262 - cpu_getiloops();
if(line==262)
{
intlevel = rabbit_vblirqlevel;
}
else
{
return;
}
cpunum_set_input_line(0, intlevel, HOLD_LINE);
}
static MACHINE_DRIVER_START( rabbit )
MDRV_CPU_ADD_TAG("main",M68EC020,24000000) /* 24 MHz */
MDRV_CPU_PROGRAM_MAP(rabbit_readmem,rabbit_writemem)
MDRV_CPU_VBLANK_INT(rabbit_interrupts,262)
/* (rabbit) */
/* lev 1 : 0x64 : 0000 027c -
lev 2 : 0x68 : 0000 3106 - unused?
lev 3 : 0x6c : 0000 3106 - unused?
lev 4 : 0x70 : 0000 0268 -
lev 5 : 0x74 : 0000 0278 -
lev 6 : 0x78 : 0000 0204 -
lev 7 : 0x7c : 0000 3106 - unused?
*/
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
MDRV_NVRAM_HANDLER(93C46)
MDRV_GFXDECODE(rabbit)
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_SCREEN_SIZE(64*16, 64*16)
MDRV_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 0*8, 28*8-1)
// MDRV_SCREEN_VISIBLE_AREA(0*8, 64*16-1, 0*16, 64*16-1)
// MDRV_SCREEN_VISIBLE_AREA(0*8, 20*16-1, 32*16, 48*16-1)
MDRV_PALETTE_LENGTH(0x4000)
MDRV_VIDEO_START(rabbit)
MDRV_VIDEO_UPDATE(rabbit)
MACHINE_DRIVER_END
static TILE_GET_INFO( get_tmmjprd_tilemap0_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,0,0);
}
static TILE_GET_INFO( get_tmmjprd_tilemap1_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,1,0);
}
static TILE_GET_INFO( get_tmmjprd_tilemap2_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,2,0);
}
static TILE_GET_INFO( get_tmmjprd_tilemap3_tile_info )
{
get_rabbit_tilemap_info(machine,tileinfo,tile_index,3,0);
}
static VIDEO_START(tmmjprd)
{
/* NOTE tilemap sizes are different.. game can also select between 16x16 and 8x8.. it NEEDS this to work */
/* the tilemaps are bigger than the regions the cpu can see, need to allocate the ram here */
/* or maybe not for this game/hw .... */
rabbit_tilemap_ram[0] = auto_malloc(0x20000);
rabbit_tilemap_ram[1] = auto_malloc(0x20000);
rabbit_tilemap_ram[2] = auto_malloc(0x20000);
rabbit_tilemap_ram[3] = auto_malloc(0x20000);
memset(rabbit_tilemap_ram[0], 0, 0x20000);
memset(rabbit_tilemap_ram[1], 0, 0x20000);
memset(rabbit_tilemap_ram[2], 0, 0x20000);
memset(rabbit_tilemap_ram[3], 0, 0x20000);
rabbit_tilemap[0] = tilemap_create(get_tmmjprd_tilemap0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 8, 8, 64, 64);
rabbit_tilemap[1] = tilemap_create(get_tmmjprd_tilemap1_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 16, 16, 64, 64);
rabbit_tilemap[2] = tilemap_create(get_tmmjprd_tilemap2_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 16, 16, 64, 64);
rabbit_tilemap[3] = tilemap_create(get_tmmjprd_tilemap3_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN , 16, 16, 64, 64);
tilemap_set_transparent_pen(rabbit_tilemap[0],0x0);
tilemap_set_transparent_pen(rabbit_tilemap[1],0x0);
tilemap_set_transparent_pen(rabbit_tilemap[2],0x0);
tilemap_set_transparent_pen(rabbit_tilemap[3],0x0);
rabbit_sprite_bitmap = auto_bitmap_alloc(0x1000,0x1000,machine->screen[0].format);
rabbit_sprite_clip.min_x = 0;
rabbit_sprite_clip.max_x = 0x1000-1;
rabbit_sprite_clip.min_y = 0;
rabbit_sprite_clip.max_y = 0x1000-1;
}
static VIDEO_UPDATE( tmmjprd )
{
tilemap_set_scrolly(rabbit_tilemap[3], 0, rabbit_tilemap_regs[3][2] >> 20);
tilemap_set_scrolly(rabbit_tilemap[2], 0, rabbit_tilemap_regs[2][2] >> 20);
tilemap_set_scrolly(rabbit_tilemap[1], 0, rabbit_tilemap_regs[1][2] >> 20);
tilemap_set_scrolly(rabbit_tilemap[0], 0, rabbit_tilemap_regs[0][2] >> 20);
// popmessage("%08x %08x", rabbit_viewregs0[0], rabbit_viewregs0[1]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[0][0],rabbit_tilemap_regs[0][1],rabbit_tilemap_regs[0][2],rabbit_tilemap_regs[0][3],rabbit_tilemap_regs[0][4],rabbit_tilemap_regs[0][5]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[1][0],rabbit_tilemap_regs[1][1],rabbit_tilemap_regs[1][2],rabbit_tilemap_regs[1][3],rabbit_tilemap_regs[1][4],rabbit_tilemap_regs[1][5]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[2][0],rabbit_tilemap_regs[2][1],rabbit_tilemap_regs[2][2],rabbit_tilemap_regs[2][3],rabbit_tilemap_regs[2][4],rabbit_tilemap_regs[2][5]);
// popmessage("%08x %08x %08x %08x %08x %08x", rabbit_tilemap_regs[3][0],rabbit_tilemap_regs[3][1],rabbit_tilemap_regs[3][2],rabbit_tilemap_regs[3][3],rabbit_tilemap_regs[3][4],rabbit_tilemap_regs[3][5]);
// popmessage("%08x %08x %08x %08x %08x %08x %08x", rabbit_spriteregs[0],rabbit_spriteregs[1],rabbit_spriteregs[2],rabbit_spriteregs[3],rabbit_spriteregs[4],rabbit_spriteregs[5], rabbit_spriteregs[6]);
// popmessage("%08x %08x %08x %08x %08x", rabbit_viewregs6[0],rabbit_viewregs6[1],rabbit_viewregs6[2],rabbit_viewregs6[3],rabbit_viewregs6[4]);
// popmessage("%08x", rabbit_viewregs7[0]);
// popmessage("%08x %08x %08x %08x", rabbit_blitterregs[0],rabbit_blitterregs[1],rabbit_blitterregs[2],rabbit_blitterregs[3]);
// popmessage("%08x %08x %08x %08x", rabbit_viewregs9[0],rabbit_viewregs9[1],rabbit_viewregs9[2],rabbit_viewregs9[3]);
// popmessage("%08x %08x %08x %08x %08x", rabbit_viewregs10[0],rabbit_viewregs10[1],rabbit_viewregs10[2],rabbit_viewregs10[3],rabbit_viewregs10[4]);
fillbitmap(bitmap,get_black_pen(machine),cliprect);
tilemap_draw(bitmap,cliprect,rabbit_tilemap[3],0,0);
tilemap_draw(bitmap,cliprect,rabbit_tilemap[1],0,0); //same as 3?
tilemap_draw(bitmap,cliprect,rabbit_tilemap[2],0,0);
tilemap_draw(bitmap,cliprect,rabbit_tilemap[0],0,0);
return 0;
}
static INTERRUPT_GEN( tmmjprd_interrupt )
{
int intlevel = 0;
if (cpu_getiloops()==0)
intlevel = 5;
else
intlevel = 3;
cpunum_set_input_line(0, intlevel, HOLD_LINE);
}
static MACHINE_DRIVER_START( tmmjprd )
MDRV_IMPORT_FROM(rabbit)
MDRV_CPU_MODIFY("main")
MDRV_CPU_PROGRAM_MAP(tmmjprd_readmem,tmmjprd_writemem)
MDRV_CPU_VBLANK_INT(tmmjprd_interrupt,2)
MDRV_VIDEO_START(tmmjprd)
MDRV_VIDEO_UPDATE(tmmjprd)
MACHINE_DRIVER_END
static DRIVER_INIT(rabbit)
{
rabbit_banking = 1;
rabbit_vblirqlevel = 6;
rabbit_bltirqlevel = 4;
/* 5 and 1 are also valid and might be raster related */
}
static DRIVER_INIT(tmmjprd)
{
rabbit_banking = 0;
rabbit_vblirqlevel = 5;
rabbit_bltirqlevel = 3; // actually palette related?
/* other irqs aren't valid */
}
ROM_START( rabbit )
ROM_REGION( 0x200000, REGION_CPU1, 0 ) /* 68020 Code */
ROM_LOAD32_BYTE( "jpr0.0", 0x000000, 0x080000, CRC(52bb18c0) SHA1(625bc8a4daa6d08cacd92d9110cf67a95a91325a) )
ROM_LOAD32_BYTE( "jpr1.1", 0x000001, 0x080000, CRC(38299d0d) SHA1(72ccd51781b47636bb16ac18037cb3121d17199f) )
ROM_LOAD32_BYTE( "jpr2.2", 0x000002, 0x080000, CRC(fa3fd91a) SHA1(ac0e658af30b37b752ede833b44ff5423b93bdb1) )
ROM_LOAD32_BYTE( "jpr3.3", 0x000003, 0x080000, CRC(d22727ca) SHA1(8415cb2d3864b11fe5623ac65f2e28fd62c61bd1) )
// ROM_REGION( 0x9000000, REGION_USER1, ROMREGION_ERASE ) /* Other Roms probably accessable by cpu / blitter, order is no doubt wrong */
/* this seems to be how it tests them? weird ... */
// ROM_LOAD32_WORD( "jfv0.00", 0x0000000, 0x400000, CRC(b2a4d3d3) SHA1(0ab71d82a37ff94442b91712a28d3470619ba575) )
// ROM_LOAD32_WORD( "jfv1.01", 0x0000002, 0x400000, CRC(83f3926e) SHA1(b1c479e675d35fc08c9a7648ff40348a24654e7e) )
// ROM_LOAD32_WORD( "jsn0.11", 0x0800002, 0x400000, CRC(e1f726e8) SHA1(598d75f3ff9e43ec8ce6131ed37f4345bf2f2d8e) )
// ROM_LOAD32_WORD( "jfv2.02", 0x2000000, 0x400000, CRC(b264bfb5) SHA1(8fafedb6af74150465b1773e80aef0edc3da4678) )
// ROM_LOAD32_WORD( "jfv3.03", 0x2000002, 0x400000, CRC(3e1a9be2) SHA1(2082a4ae8cda84cec5ea0fc08753db387bb70d41) )
// ROM_LOAD16_BYTE( "jbg0.40", 0x4000001, 0x200000, CRC(89662944) SHA1(ca916ba38480fa588af19fc9682603f5195ad6c7) ) // how should this one be, it won't pass it.
// ROM_LOAD16_BYTE( "jbg1.50", 0x6000000, 0x200000, CRC(1fc7f6e0) SHA1(b36062d2a9683683ffffd3003d5244a185f53280) )
// ROM_LOAD16_BYTE( "jbg2.60", 0x8000001, 0x200000, CRC(aee265fc) SHA1(ec420ab30b9b5141162223fc1fbf663ad9f211e6) )
ROM_REGION( 0x1000000, REGION_USER1, ROMREGION_INVERT ) /* Sprite Roms (and Blitter Data) */
ROM_LOAD32_WORD( "jfv0.00", 0x0000002, 0x400000, CRC(b2a4d3d3) SHA1(0ab71d82a37ff94442b91712a28d3470619ba575) )
ROM_LOAD32_WORD( "jfv1.01", 0x0000000, 0x400000, CRC(83f3926e) SHA1(b1c479e675d35fc08c9a7648ff40348a24654e7e) )
ROM_LOAD32_WORD( "jfv2.02", 0x0800002, 0x400000, CRC(b264bfb5) SHA1(8fafedb6af74150465b1773e80aef0edc3da4678) )
ROM_LOAD32_WORD( "jfv3.03", 0x0800000, 0x400000, CRC(3e1a9be2) SHA1(2082a4ae8cda84cec5ea0fc08753db387bb70d41) )
ROM_REGION( 0x600000, REGION_USER2, ROMREGION_INVERT ) /* BG Roms */
ROM_LOAD( "jbg0.40", 0x000000, 0x200000, CRC(89662944) SHA1(ca916ba38480fa588af19fc9682603f5195ad6c7) )
ROM_LOAD( "jbg1.50", 0x200000, 0x200000, CRC(1fc7f6e0) SHA1(b36062d2a9683683ffffd3003d5244a185f53280) )
ROM_LOAD( "jbg2.60", 0x400000, 0x200000, CRC(aee265fc) SHA1(ec420ab30b9b5141162223fc1fbf663ad9f211e6) )
ROM_REGION( 0x400000, REGION_USER3, 0 ) /* sound rom */
ROM_LOAD( "jsn0.11", 0x0000000, 0x400000, CRC(e1f726e8) SHA1(598d75f3ff9e43ec8ce6131ed37f4345bf2f2d8e) )
ROM_END
ROM_START( tmmjprd )
ROM_REGION( 0x200000, REGION_CPU1, 0 ) /* 68020 Code - doesn't seem to dsam quite right, bitswap? */
ROM_LOAD32_BYTE( "p00.bin", 0x000000, 0x080000, CRC(a1efd960) SHA1(7f41ab58de32777bccbfe28e6e5a1f2dca35bb90) )
ROM_LOAD32_BYTE( "p01.bin", 0x000001, 0x080000, CRC(9c325374) SHA1(1ddf1c292fc1bcf4dcefb5d4aa3abdeb1489c020) )
ROM_LOAD32_BYTE( "p02.bin", 0x000002, 0x080000, CRC(729a5f12) SHA1(615704d36afdceb4b1ff2e5dc34856e614181e16) )
ROM_LOAD32_BYTE( "p03.bin", 0x000003, 0x080000, CRC(595615ab) SHA1(aca746d74aa6e7e856eb5c9b740d884778743b27) )
ROM_REGION( 0x2000000, REGION_USER1, ROMREGION_INVERT ) /* Sprite Roms */
ROM_LOAD16_WORD_SWAP( "00.bin", 0x1000000, 0x400000, CRC(303e91a1) SHA1(c29a22061ab8af8b72e0e6bdb36915a0cb5b2a5c) )
ROM_LOAD16_WORD_SWAP( "01.bin", 0x1400000, 0x400000, CRC(3371b775) SHA1(131dd850bd01dac52fa82c41948d900c4833db3c) )
ROM_LOAD16_WORD_SWAP( "10.bin", 0x1800000, 0x400000, CRC(5ab6af41) SHA1(e29cee23c84e17dd8dabd2ec71e622c25418646e) )
ROM_LOAD16_WORD_SWAP( "11.bin", 0x1c00000, 0x400000, CRC(1d1fd633) SHA1(655be5b72bb70a90d23e49512ca84d9978d87b0b) )
ROM_LOAD16_WORD_SWAP( "02.bin", 0x0000000, 0x400000, CRC(4c1e13b9) SHA1(d244eb74f755350604824670db58ab2a56a856cb) )
ROM_LOAD16_WORD_SWAP( "03.bin", 0x0400000, 0x400000, CRC(9cf86152) SHA1(e27e0d9befb12ad5c2acf547afe80d1c7921a4d1) )
ROM_LOAD16_WORD_SWAP( "12.bin", 0x0800000, 0x400000, CRC(5b8bb9d6) SHA1(ee93774077d8a2ddcf70869a9c2f4961219a85b4) )
ROM_LOAD16_WORD_SWAP( "13.bin", 0x0c00000, 0x400000, CRC(d950df0a) SHA1(3b109341ab4ad87005113fb481b5d1ed9a82f50f) )
ROM_REGION( 0x2000000, REGION_USER2, ROMREGION_INVERT ) /* BG Roms */
ROM_LOAD32_WORD( "40.bin", 0x0000000, 0x400000, CRC(8bedc606) SHA1(7159c8b86e8d7d5ae202c239638483ccdc7dfc25) )
ROM_LOAD32_WORD( "41.bin", 0x0000002, 0x400000, CRC(e19713dd) SHA1(a8f1b716913f2e391abf277e5bf0e9986cc75898) )
ROM_LOAD32_WORD( "50.bin", 0x0800000, 0x400000, CRC(85ca9ce9) SHA1(c5a7270507522e11e9485196be325508846fda90) )
ROM_LOAD32_WORD( "51.bin", 0x0800002, 0x400000, CRC(6ba1d2ec) SHA1(bbe7309b33f213c8cb9ab7adb3221ea79f89e8b0) )
ROM_LOAD32_WORD( "60.bin", 0x1000000, 0x400000, CRC(7cb132e0) SHA1(f9c366befec46c7f6e307111a62eede029202b16) )
ROM_LOAD32_WORD( "61.bin", 0x1000002, 0x400000, CRC(caa7e854) SHA1(592867e001abd0781f83a5124bf9aa62ad1aa7f3) )
ROM_LOAD32_WORD( "70.bin", 0x1800000, 0x400000, CRC(9b737ae4) SHA1(0b62a90d42ace81ee32db073a57731a55a32f989) )
ROM_LOAD32_WORD( "71.bin", 0x1800002, 0x400000, CRC(189f694e) SHA1(ad0799d4aadade51be38d824910d299257a758a3) )
ROM_REGION( 0x800000, REGION_USER3, 0 ) /* Sound Roms? */
ROM_LOAD16_BYTE( "21.bin", 0x0000001, 0x400000, CRC(bb5fa8da) SHA1(620e609b3e2524d06d58844625f186fd4682205f))
ROM_END
GAME( 1997, rabbit, 0, rabbit, rabbit, rabbit, ROT0, "Electronic Arts / Aorn", "Rabbit", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND ) // somewhat playable
GAME( 1997, tmmjprd, 0, tmmjprd, tmmjprd, tmmjprd, ROT0, "Media / Sonnet", "Tokimeki Mahjong Paradise - Dear My Love", GAME_NOT_WORKING | GAME_NO_SOUND )