summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/rabbit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/rabbit.c')
-rw-r--r--src/mame/drivers/rabbit.c1291
1 files changed, 1291 insertions, 0 deletions
diff --git a/src/mame/drivers/rabbit.c b/src/mame/drivers/rabbit.c
new file mode 100644
index 00000000000..8b41c179e76
--- /dev/null
+++ b/src/mame/drivers/rabbit.c
@@ -0,0 +1,1291 @@
+/***************************************************************************
+
+ -= 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 )