summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/toaplan2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/toaplan2.c')
-rw-r--r--src/mame/video/toaplan2.c1619
1 files changed, 1619 insertions, 0 deletions
diff --git a/src/mame/video/toaplan2.c b/src/mame/video/toaplan2.c
new file mode 100644
index 00000000000..8c66ee2e45b
--- /dev/null
+++ b/src/mame/video/toaplan2.c
@@ -0,0 +1,1619 @@
+/***************************************************************************
+
+ Functions to emulate the video hardware of some Toaplan games,
+ which use one or more Toaplan L7A0498 GP9001 graphic controllers.
+
+ The simpler hardware of these games use one GP9001 controller.
+ Next we have games that use two GP9001 controllers, whose priority
+ schemes between the two controllers is unknown at this time, and
+ may be game dependant.
+ Finally we have games using one GP9001 controller and an additional
+ text tile layer, which has highest priority. This text tile layer
+ appears to have line-scroll support. Some of these games copy the
+ text tile gfx data to RAM from the main CPU ROM, which easily allows
+ for effects to be added to the tiles, by manipulating the text tile
+ gfx data. The tiles are then dynamically decoded from RAM before
+ displaying them.
+
+
+ To Do / Unknowns
+ - Hack is needed to reset sound CPU and sound chip when machine
+ is 'tilted' in Pipi & Bibis. Otherwise sound CPU interferes
+ with the main CPU test of shared RAM. You get a 'Sub CPU RAM Error'
+ - What do Scroll registers 0Eh and 0Fh really do ????
+ - Snow Bros 2 sets bit 6 of the sprite X info word during weather
+ world map, and bits 4, 5 and 6 of the sprite X info word during
+ the Rabbit boss screen - reasons are unknown.
+ - Fourth set of scroll registers have been used for Sprite scroll
+ though it may not be correct. For most parts this looks right
+ except for Snow Bros 2 when in the rabbit boss screen (all sprites
+ jump when big green nasty (which is the foreground layer) comes
+ in from the left)
+ - Teki Paki tests video RAM from address 0 past SpriteRAM to $37ff.
+ This seems to be a bug in Teki Paki's vram test routine !
+ - Batsugun, relationship between the two video controllers (priority
+ wise) is wrong and unknown.
+
+
+ GP9001 Video RAM address layout:
+
+ Bank data size of video layer
+ -----------------------------------------
+ $0000-07FF 800h words for background layer
+ $0800-0FFF 800h words for foreground layer
+ $1000-17FF 800h words for top (text) layer
+ $1800-1BFF 400h words for sprites (100 possible sprites)
+
+
+
+ GP9001 Tile RAM format (each tile takes up 32 bits)
+
+ 0 1 2 3
+ ---- ---- ---- ---- xxxx xxxx xxxx xxxx = Tile number (0 - FFFFh)
+ ---- ---- -xxx xxxx ---- ---- ---- ---- = Color (0 - 7Fh)
+ ---- ---- ?--- ---- ---- ---- ---- ---- = unknown / unused
+ ---- xxxx ---- ---- ---- ---- ---- ---- = Priority (0 - Fh)
+ ???? ---- ---- ---- ---- ---- ---- ---- = unknown / unused / possible flips
+
+Sprites are of varying sizes between 8x8 and 128x128 with any variation
+in between, in multiples of 8 either way.
+
+Here we draw the first 8x8 part of the sprite, then by using the sprite
+dimensions, we draw the rest of the 8x8 parts to produce the complete
+sprite.
+
+There seems to be sprite buffering - double buffering actually.
+
+ GP9001 Sprite RAM format (data for each sprite takes up 4 words)
+
+ 0
+ ---- ---- ---- --xx = top 2 bits of Sprite number
+ ---- ---- xxxx xx-- = Color (0 - 3Fh)
+ ---- xxxx ---- ---- = Priority (0 - Fh)
+ ---x ---- ---- ---- = Flip X
+ --x- ---- ---- ---- = Flip Y
+ -?-- ---- ---- ---- = unknown / unused
+ x--- ---- ---- ---- = Show sprite ?
+
+ 1
+ xxxx xxxx xxxx xxxx = Sprite number (top two bits in word 0)
+
+ 2
+ ---- ---- ---- xxxx = Sprite X size (add 1, then multiply by 8)
+ ---- ---- -??? ---- = unknown - used in Snow Bros. 2
+ xxxx xxxx x--- ---- = X position
+
+ 3
+ ---- ---- ---- xxxx = Sprite Y size (add 1, then multiply by 8)
+ ---- ---- -??? ---- = unknown / unused
+ xxxx xxxx x--- ---- = Y position
+
+
+ Extra-text RAM format
+
+ Truxton 2, Fixeight and Raizing games have an extra-text layer.
+
+ Text RAM format $0000-1FFF (actually its probably $0000-0FFF)
+ ---- --xx xxxx xxxx = Tile number
+ xxxx xx-- ---- ---- = Color (0 - 3Fh) + 40h
+
+ Text flip / ??? $0000-01EF (some games go to $01FF (excess?))
+ ---x xxxx xxxx xxxx = ??? line something (line to draw ?) ???
+ x--- ---- ---- ---- = flip for the Text tile
+
+ Text X line-scroll ? $0000-01EF (some games go to $01FF (excess?))
+ ---- ---x xxxx xxxx = X-Scroll for each line
+
+
+
+ GP9001 Scroll Registers (hex) :
+
+ 00 Background scroll X (X flip off)
+ 01 Background scroll Y (Y flip off)
+ 02 Foreground scroll X (X flip off)
+ 03 Foreground scroll Y (Y flip off)
+ 04 Top (text) scroll X (X flip off)
+ 05 Top (text) scroll Y (Y flip off)
+ 06 Sprites scroll X (X flip off) ???
+ 07 Sprites scroll Y (Y flip off) ???
+ 0E ??? Initialise Video controller at startup ???
+ 0F Scroll update complete ??? (Not used in Ghox and V-Five)
+
+ 80 Background scroll X (X flip on)
+ 81 Background scroll Y (Y flip on)
+ 82 Foreground scroll X (X flip on)
+ 83 Foreground scroll Y (Y flip on)
+ 84 Top (text) scroll X (X flip on)
+ 85 Top (text) scroll Y (Y flip on)
+ 86 Sprites scroll X (X flip on) ???
+ 87 Sprites scroll Y (Y flip on) ???
+ 8F Same as 0Fh except flip bit is active
+
+
+Scroll Register 0E writes (Video controller inits ?) from different games:
+
+Teki-Paki | Ghox | Knuckle Bash | Truxton 2 |
+0003, 0002, 4000 | ????, ????, ???? | 0202, 0203, 4200 | 0003, 0002, 4000 |
+
+Dogyuun | Batsugun |
+0202, 0203, 4200 | 0202, 0203, 4200 |
+1202, 1203, 5200 | 1202, 1203, 5200 | <--- Second video controller
+
+Pipi & Bibis | Fix Eight | V-Five | Snow Bros. 2 |
+0003, 0002, 4000 | 0202, 0203, 4200 | 0202, 0203, 4200 | 0202, 0203, 4200 |
+
+***************************************************************************/
+
+#include "driver.h"
+#include "cpu/m68000/m68000.h"
+
+
+
+#define TOAPLAN2_BG_VRAM_SIZE 0x1000 /* Background RAM size */
+#define TOAPLAN2_FG_VRAM_SIZE 0x1000 /* Foreground RAM size */
+#define TOAPLAN2_TOP_VRAM_SIZE 0x1000 /* Top Layer RAM size */
+#define TOAPLAN2_SPRITERAM_SIZE 0x800 /* Sprite RAM size */
+#define RAIZING_TX_GFXRAM_SIZE 0x8000 /* GFX data decode RAM size */
+extern size_t toaplan2_tx_vram_size; /* 0x2000 Text layer RAM size */
+extern size_t toaplan2_tx_offs_vram_size; /* 0x200 Text layer tile flip and positon ? */
+extern size_t toaplan2_tx_scroll_vram_size; /* 0x200 Text layer scroll ? */
+extern size_t batrider_paletteram16_size;
+
+
+
+#define TOAPLAN2_SPRITE_FLIPX 0x1000 /* Sprite flip flags */
+#define TOAPLAN2_SPRITE_FLIPY 0x2000
+
+#define CPU_2_NONE 0x00
+#define CPU_2_Z80 0x5a
+#define CPU_2_HD647180 0xa5
+#define CPU_2_V25 0xff
+
+
+static UINT16 *bgvideoram16[2];
+static UINT16 *fgvideoram16[2];
+static UINT16 *topvideoram16[2];
+static UINT16 *spriteram16_now[2]; /* Sprites to draw this frame */
+static UINT16 *spriteram16_new[2]; /* Sprites to add to next frame */
+static UINT16 *spriteram16_n[2];
+UINT16 *toaplan2_txvideoram16; /* Video ram for extra text layer */
+UINT16 *toaplan2_txvideoram16_offs; /* Text layer tile flip and positon ? */
+UINT16 *toaplan2_txscrollram16; /* Text layer scroll ? */
+UINT16 *toaplan2_tx_gfxram16; /* Text Layer RAM based tiles */
+static UINT16 *raizing_tx_gfxram16; /* Text Layer RAM based tiles (Batrider) */
+static int toaplan2_overflow_vram; /* Teki Paki VRAM test is bugged. It goes out of range */
+
+static int toaplan2_scroll_reg[2];
+static int toaplan2_voffs[2];
+static int bg_scrollx[2];
+static int bg_scrolly[2];
+static int fg_scrollx[2];
+static int fg_scrolly[2];
+static int top_scrollx[2];
+static int top_scrolly[2];
+static int sprite_scrollx[2];
+static int sprite_scrolly[2];
+static int objectbank_dirty = 0; /* dirty flag of object bank (for Batrider) */
+static int batrider_object_bank[8]; /* Batrider object bank */
+
+#ifdef MAME_DEBUG
+static int display_bg[2] = { 1, 1 };
+static int display_fg[2] = { 1, 1 };
+static int display_top[2] = { 1, 1 };
+static int displog = 0;
+static int display_tx = 1;
+#endif
+static int display_sp[2] = { 1, 1 };
+
+static int sprite_priority[2][16];
+static int bg_flip[2] = { 0, 0 };
+static int fg_flip[2] = { 0, 0 };
+static int top_flip[2] = { 0, 0 };
+static int sprite_flip[2] = { 0, 0 };
+static int tx_flip = 0;
+
+extern int toaplan2_sub_cpu;
+
+static UINT8 top_tile_priority[2][16];
+static UINT8 fg_tile_priority[2][16];
+static UINT8 bg_tile_priority[2][16];
+
+
+static tilemap *top_tilemap[2], *fg_tilemap[2], *bg_tilemap[2];
+static tilemap *tx_tilemap; /* Tilemap for extra-text-layer */
+
+static int xoffset[4];
+static int yoffset[4];
+
+static void defaultOffsets(void)
+{
+ xoffset[0]=0;
+ xoffset[1]=0;
+ xoffset[2]=0;
+ xoffset[3]=0;
+
+ yoffset[0]=0;
+ yoffset[1]=0;
+ yoffset[2]=0;
+ yoffset[3]=0;
+}
+
+/***************************************************************************
+
+ Callbacks for the TileMap code
+
+***************************************************************************/
+
+static TILE_GET_INFO( get_top0_tile_info )
+{
+ int color, tile_number, attrib;
+
+ attrib = topvideoram16[0][2*tile_index];
+ tile_number = topvideoram16[0][2*tile_index+1];
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 0,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( get_fg0_tile_info )
+{
+ int color, tile_number, attrib;
+
+ attrib = fgvideoram16[0][2*tile_index];
+ tile_number = fgvideoram16[0][2*tile_index+1];
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 0,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( get_bg0_tile_info )
+{
+ int color, tile_number, attrib;
+
+ attrib = bgvideoram16[0][2*tile_index];
+ tile_number = bgvideoram16[0][2*tile_index+1];
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 0,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+/// if ((attrib & 0x0f00) == 0) tileinfo->flags |= TILE_FORCE_LAYER0;
+}
+
+static TILE_GET_INFO( get_top1_tile_info )
+{
+ int color, tile_number, attrib;
+
+ attrib = topvideoram16[1][2*tile_index];
+ tile_number = topvideoram16[1][2*tile_index+1];
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 2,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( get_fg1_tile_info )
+{
+ int color, tile_number, attrib;
+
+ attrib = fgvideoram16[1][2*tile_index];
+ tile_number = fgvideoram16[1][2*tile_index+1];
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 2,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( get_bg1_tile_info )
+{
+ int color, tile_number, attrib;
+
+ attrib = bgvideoram16[1][2*tile_index];
+ tile_number = bgvideoram16[1][2*tile_index+1];
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 2,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( batrider_get_top0_tile_info )
+{
+ int color, tile_number, attrib, tile;
+
+ attrib = topvideoram16[0][2*tile_index];
+ tile = topvideoram16[0][2*tile_index+1];
+ tile_number = ( batrider_object_bank[(tile >> 13) & 7] << 13 ) | ( tile & 0x1fff );
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 0,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( batrider_get_fg0_tile_info )
+{
+ int color, tile_number, attrib, tile;
+
+ attrib = fgvideoram16[0][2*tile_index];
+ tile = fgvideoram16[0][2*tile_index+1];
+ tile_number = ( batrider_object_bank[(tile >> 13) & 7] << 13 ) | ( tile & 0x1fff );
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 0,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( batrider_get_bg0_tile_info )
+{
+ int color, tile_number, attrib, tile;
+
+ attrib = bgvideoram16[0][2*tile_index];
+ tile = bgvideoram16[0][2*tile_index+1];
+ tile_number = ( batrider_object_bank[(tile >> 13) & 7] << 13 ) | ( tile & 0x1fff );
+ color = attrib & 0x7f;
+ SET_TILE_INFO(
+ 0,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = (attrib & 0x0f00) >> 8;
+}
+
+static TILE_GET_INFO( get_text_tile_info )
+{
+ int color, tile_number, attrib;
+
+ attrib = toaplan2_txvideoram16[tile_index];
+ tile_number = attrib & 0x3ff;
+ color = ((attrib >> 10) | 0x40) & 0x7f;
+ SET_TILE_INFO(
+ 2,
+ tile_number,
+ color,
+ 0);
+ tileinfo->category = 0;
+}
+
+/***************************************************************************
+
+ Start the video hardware emulation.
+
+***************************************************************************/
+static void create_tilemaps_0(void)
+{
+ top_tilemap[0] = tilemap_create(get_top0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ fg_tilemap[0] = tilemap_create(get_fg0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ bg_tilemap[0] = tilemap_create(get_bg0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+
+ tilemap_set_transparent_pen(top_tilemap[0],0);
+ tilemap_set_transparent_pen(fg_tilemap[0],0);
+ tilemap_set_transparent_pen(bg_tilemap[0],0);
+}
+
+static void create_tilemaps_1(void)
+{
+ top_tilemap[1] = tilemap_create(get_top1_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ fg_tilemap[1] = tilemap_create(get_fg1_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ bg_tilemap[1] = tilemap_create(get_bg1_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+
+ tilemap_set_transparent_pen(top_tilemap[1],0);
+ tilemap_set_transparent_pen(fg_tilemap[1],0);
+ tilemap_set_transparent_pen(bg_tilemap[1],0);
+}
+
+static void truxton2_create_tilemaps_0(void)
+{
+ tx_tilemap = tilemap_create(get_text_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,32);
+ top_tilemap[0] = tilemap_create(get_top0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ fg_tilemap[0] = tilemap_create(get_fg0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ bg_tilemap[0] = tilemap_create(get_bg0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+
+ tilemap_set_scroll_rows(tx_tilemap,8*32); /* line scrolling */
+ tilemap_set_scroll_cols(tx_tilemap,1);
+
+ tilemap_set_transparent_pen(tx_tilemap,0);
+ tilemap_set_transparent_pen(top_tilemap[0],0);
+ tilemap_set_transparent_pen(fg_tilemap[0],0);
+ tilemap_set_transparent_pen(bg_tilemap[0],0);
+}
+
+static void batrider_create_tilemaps_0(void)
+{
+ tx_tilemap = tilemap_create(get_text_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,64,32);
+ top_tilemap[0] = tilemap_create(batrider_get_top0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ fg_tilemap[0] = tilemap_create(batrider_get_fg0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+ bg_tilemap[0] = tilemap_create(batrider_get_bg0_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32);
+
+ tilemap_set_scroll_rows(tx_tilemap,8*32); /* line scrolling */
+ tilemap_set_scroll_cols(tx_tilemap,1);
+
+ tilemap_set_transparent_pen(tx_tilemap,0);
+ tilemap_set_transparent_pen(top_tilemap[0],0);
+ tilemap_set_transparent_pen(fg_tilemap[0],0);
+ tilemap_set_transparent_pen(bg_tilemap[0],0);
+}
+
+
+static void toaplan2_vram_alloc(int controller)
+{
+ spriteram16_new[controller] = auto_malloc(TOAPLAN2_SPRITERAM_SIZE);
+ memset(spriteram16_new[controller],0,TOAPLAN2_SPRITERAM_SIZE);
+
+ spriteram16_now[controller] = auto_malloc(TOAPLAN2_SPRITERAM_SIZE);
+ memset(spriteram16_now[controller],0,TOAPLAN2_SPRITERAM_SIZE);
+
+ topvideoram16[controller] = auto_malloc(TOAPLAN2_TOP_VRAM_SIZE);
+ memset(topvideoram16[controller],0,TOAPLAN2_TOP_VRAM_SIZE);
+
+ fgvideoram16[controller] = auto_malloc(TOAPLAN2_FG_VRAM_SIZE);
+ memset(fgvideoram16[controller],0,TOAPLAN2_FG_VRAM_SIZE);
+
+ bgvideoram16[controller] = auto_malloc(TOAPLAN2_BG_VRAM_SIZE);
+ memset(bgvideoram16[controller],0,TOAPLAN2_BG_VRAM_SIZE);
+
+ spriteram16_n[controller] = spriteram16_now[controller];
+}
+
+static void toaplan2_vh_start(int controller)
+{
+ toaplan2_vram_alloc(controller);
+
+ if (controller == 0)
+ {
+ create_tilemaps_0();
+ }
+ if (controller == 1)
+ {
+ create_tilemaps_1();
+ }
+}
+
+VIDEO_START( toaplan2_0 )
+{
+ defaultOffsets();
+ toaplan2_vh_start(0);
+}
+
+VIDEO_START( toaplan2_1 )
+{
+ toaplan2_vh_start(0);
+ toaplan2_vh_start(1);
+ defaultOffsets();
+}
+
+VIDEO_START( truxton2_0 )
+{
+ toaplan2_vram_alloc(0);
+ truxton2_create_tilemaps_0();
+
+ if(!strcmp(machine->gamedrv->name,"fixeighb"))
+ {
+ xoffset[0]=-26;
+ xoffset[1]=-22;
+ xoffset[2]=-18;
+ xoffset[3]=8;
+
+ yoffset[0]=-15;
+ yoffset[1]=-15;
+ yoffset[2]=-15;
+ yoffset[3]=8;
+ tilemap_set_scrolldx(tx_tilemap, 0, 0);
+ }
+ else
+ {
+ defaultOffsets();
+ tilemap_set_scrolldx(tx_tilemap, 0x1d4 +1, 0x2a);
+ }
+}
+
+VIDEO_START( bgaregga_0 )
+{
+ toaplan2_vram_alloc(0);
+ truxton2_create_tilemaps_0();
+ tilemap_set_scrolldx(tx_tilemap, 0x1d4, 0x2a);
+ defaultOffsets();
+}
+
+VIDEO_START( batrider_0 )
+{
+ raizing_tx_gfxram16 = auto_malloc(RAIZING_TX_GFXRAM_SIZE);
+ memset(raizing_tx_gfxram16,0,RAIZING_TX_GFXRAM_SIZE);
+
+ toaplan2_vram_alloc(0);
+ spriteram16_n[0] = spriteram16_new[0];
+
+ batrider_create_tilemaps_0();
+
+ tilemap_set_scrolldx(tx_tilemap, 0x1d4, 0x2a);
+ defaultOffsets();
+}
+
+
+/***************************************************************************
+
+ Video I/O port hardware.
+
+***************************************************************************/
+
+static void toaplan2_voffs_w(offs_t offset, UINT16 data, UINT32 mem_mask, int controller)
+{
+ if (data >= 0x1c00)
+ logerror("Hmmm, unknown video controller %01x layer being selected (%08x)\n",controller,data);
+ COMBINE_DATA(&toaplan2_voffs[controller]);
+}
+
+WRITE16_HANDLER( toaplan2_0_voffs_w )
+{
+ toaplan2_voffs_w(offset, data, mem_mask, 0);
+}
+
+WRITE16_HANDLER( toaplan2_1_voffs_w )
+{
+ toaplan2_voffs_w(offset, data, mem_mask, 1);
+}
+
+READ16_HANDLER( toaplan2_txvideoram16_r )
+{
+ return toaplan2_txvideoram16[offset];
+}
+
+WRITE16_HANDLER( toaplan2_txvideoram16_w )
+{
+ COMBINE_DATA(&toaplan2_txvideoram16[offset]);
+ if (offset < (toaplan2_tx_vram_size/4))
+ tilemap_mark_tile_dirty(tx_tilemap,offset);
+}
+
+READ16_HANDLER( toaplan2_txvideoram16_offs_r )
+{
+ return toaplan2_txvideoram16_offs[offset];
+}
+WRITE16_HANDLER( toaplan2_txvideoram16_offs_w )
+{
+ /* Besides containing flip, function of this RAM is still unknown */
+ /* This is however line related as per line-scroll RAM below */
+ /* Maybe specifies which line to draw text info (line number data is */
+ /* opposite when flip bits are on) */
+
+ UINT16 oldword = toaplan2_txvideoram16_offs[offset];
+
+ if (oldword != data)
+ {
+ if (offset == 0) /* Wrong ! */
+ {
+ if (data & 0x8000) /* Flip off */
+ {
+ tx_flip = 0;
+ tilemap_set_flip(tx_tilemap, tx_flip);
+ tilemap_set_scrolly(tx_tilemap, 0, 0);
+ }
+ else /* Flip on */
+ {
+ tx_flip = (TILEMAP_FLIPY | TILEMAP_FLIPX);
+ tilemap_set_flip(tx_tilemap, tx_flip);
+ tilemap_set_scrolly(tx_tilemap, 0, -16);
+ }
+ }
+ COMBINE_DATA(&toaplan2_txvideoram16_offs[offset]);
+ }
+// logerror("Writing %04x to text offs RAM offset %04x\n",data,offset);
+}
+
+READ16_HANDLER( toaplan2_txscrollram16_r )
+{
+ return toaplan2_txscrollram16[offset];
+}
+WRITE16_HANDLER( toaplan2_txscrollram16_w )
+{
+ /*** Line-Scroll RAM for Text Layer ***/
+
+ int data_tx = data;
+
+ tilemap_set_scrollx(tx_tilemap, offset, data_tx);
+
+// logerror("Writing %04x to text scroll RAM offset %04x\n",data,offset);
+ COMBINE_DATA(&toaplan2_txscrollram16[offset]);
+}
+
+READ16_HANDLER( toaplan2_tx_gfxram16_r )
+{
+ return toaplan2_tx_gfxram16[offset];
+}
+
+WRITE16_HANDLER( toaplan2_tx_gfxram16_w )
+{
+ /*** Dynamic GFX decoding for Truxton 2 / FixEight ***/
+
+ UINT16 oldword = toaplan2_tx_gfxram16[offset];
+ UINT8 *toaplan2_tx_gfxram = (UINT8 *)(toaplan2_tx_gfxram16);
+
+ if (oldword != data)
+ {
+ int code = offset/32;
+ COMBINE_DATA(&toaplan2_tx_gfxram16[offset]);
+ decodechar(Machine->gfx[2], code, toaplan2_tx_gfxram,
+ Machine->drv->gfxdecodeinfo[2].gfxlayout);
+
+ tilemap_mark_all_tiles_dirty(tx_tilemap);
+ }
+}
+
+READ16_HANDLER( raizing_tx_gfxram16_r )
+{
+ offset += 0x3400/2;
+ return raizing_tx_gfxram16[offset];
+}
+WRITE16_HANDLER( raizing_tx_gfxram16_w )
+{
+ /*** Dynamic Text GFX decoding for Batrider ***/
+
+ UINT16 oldword = raizing_tx_gfxram16[offset + (0x3400 / 2)];
+
+ if (oldword != data)
+ {
+ offset += 0x3400/2;
+ COMBINE_DATA(&raizing_tx_gfxram16[offset]);
+ }
+}
+
+WRITE16_HANDLER( batrider_textdata_decode )
+{
+ /*** Dynamic Text GFX decoding for Batrider ***/
+ /*** Only done once during start-up ***/
+
+ int code;
+ UINT8 *raizing_tx_gfxram = (UINT8 *)raizing_tx_gfxram16;
+ UINT16 *dest = (UINT16 *)raizing_tx_gfxram16;
+
+ memcpy(dest, toaplan2_txvideoram16, toaplan2_tx_vram_size);
+ dest += (toaplan2_tx_vram_size/2);
+ memcpy(dest, paletteram16, batrider_paletteram16_size);
+ dest += (batrider_paletteram16_size/2);
+ memcpy(dest, toaplan2_txvideoram16_offs, toaplan2_tx_offs_vram_size);
+ dest += (toaplan2_tx_offs_vram_size/2);
+ memcpy(dest, toaplan2_txscrollram16, toaplan2_tx_scroll_vram_size);
+
+ /* Decode text characters */
+ for (code = 0; code < 1024; code++)
+ decodechar (Machine->gfx[2], code, raizing_tx_gfxram, Machine->drv->gfxdecodeinfo[2].gfxlayout);
+ tilemap_mark_all_tiles_dirty(tx_tilemap);
+}
+
+WRITE16_HANDLER( batrider_objectbank_w )
+{
+ if (ACCESSING_LSB)
+ {
+ data &= 0xf;
+ if (batrider_object_bank[offset] != data)
+ {
+ batrider_object_bank[offset] = data;
+ objectbank_dirty = 1;
+ }
+ }
+}
+
+
+
+static int toaplan2_videoram16_r(offs_t offset, int controller)
+{
+ static UINT16 video_data = 0;
+ static offs_t vram_offset;
+
+
+ switch (toaplan2_voffs[controller] & 0xfc00)
+ {
+ case 0x0400:
+ case 0x0000:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_BG_VRAM_SIZE/2)-1);
+ video_data = bgvideoram16[controller][vram_offset];
+ break;
+ case 0x0c00:
+ case 0x0800:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_FG_VRAM_SIZE/2)-1);
+ video_data = fgvideoram16[controller][vram_offset];
+ break;
+ case 0x1400:
+ case 0x1000:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_TOP_VRAM_SIZE/2)-1);
+ video_data = topvideoram16[controller][vram_offset];
+ break;
+ case 0x1800:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_SPRITERAM_SIZE/2)-1);
+ video_data = spriteram16_new[controller][vram_offset];
+ break;
+ default:
+ video_data = toaplan2_overflow_vram;
+ logerror("Hmmm, reading %04x from unknown VC:%01x layer address %06x Offset:%01x !!!\n",video_data,controller,toaplan2_voffs[controller],offset);
+ break;
+ }
+ toaplan2_voffs[controller]++;
+ return video_data;
+}
+
+READ16_HANDLER( toaplan2_0_videoram16_r )
+{
+ return toaplan2_videoram16_r(offset, 0);
+}
+
+READ16_HANDLER( toaplan2_1_videoram16_r )
+{
+ return toaplan2_videoram16_r(offset, 1);
+}
+
+static void toaplan2_videoram16_w(offs_t offset, UINT16 data, UINT32 mem_mask, int controller)
+{
+ offs_t vram_offset;
+
+ switch (toaplan2_voffs[controller] & 0xfc00)
+ {
+ case 0x0400:
+ case 0x0000:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_BG_VRAM_SIZE/2)-1);
+ COMBINE_DATA(&bgvideoram16[controller][vram_offset]);
+ tilemap_mark_tile_dirty(bg_tilemap[controller],vram_offset/2);
+ break;
+ case 0x0c00:
+ case 0x0800:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_FG_VRAM_SIZE/2)-1);
+ COMBINE_DATA(&fgvideoram16[controller][vram_offset]);
+ tilemap_mark_tile_dirty(fg_tilemap[controller],vram_offset/2);
+ break;
+ case 0x1400:
+ case 0x1000:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_TOP_VRAM_SIZE/2)-1);
+ COMBINE_DATA(&topvideoram16[controller][vram_offset]);
+ tilemap_mark_tile_dirty(top_tilemap[controller],vram_offset/2);
+ break;
+ case 0x1800:
+ vram_offset = toaplan2_voffs[controller] & ((TOAPLAN2_SPRITERAM_SIZE/2)-1);
+ COMBINE_DATA(&spriteram16_new[controller][vram_offset]);
+ break;
+ default:
+ toaplan2_overflow_vram = data;
+ logerror("Hmmm, writing %04x to unknown VC:%01x layer address %06x Offset:%01x\n",data,controller,toaplan2_voffs[controller],offset);
+ break;
+ }
+ toaplan2_voffs[controller]++;
+}
+
+WRITE16_HANDLER( toaplan2_0_videoram16_w )
+{
+ toaplan2_videoram16_w(offset, data, mem_mask, 0);
+}
+
+WRITE16_HANDLER( toaplan2_1_videoram16_w )
+{
+ toaplan2_videoram16_w(offset, data, mem_mask, 1);
+}
+
+
+static void toaplan2_scroll_reg_select_w(offs_t offset, UINT16 data, UINT32 mem_mask, int controller)
+{
+ if (ACCESSING_LSB)
+ {
+ toaplan2_scroll_reg[controller] = data & 0x8f;
+ if (data & 0x70)
+ logerror("Hmmm, selecting unknown LSB video control register (%04x) Video controller %01x \n",toaplan2_scroll_reg[controller],controller);
+ }
+ else
+ {
+ logerror("Hmmm, selecting unknown MSB video control register (%04x) Video controller %01x \n",toaplan2_scroll_reg[controller],controller);
+ }
+}
+
+WRITE16_HANDLER( toaplan2_0_scroll_reg_select_w )
+{
+ toaplan2_scroll_reg_select_w(offset, data, mem_mask, 0);
+}
+
+WRITE16_HANDLER( toaplan2_1_scroll_reg_select_w )
+{
+ toaplan2_scroll_reg_select_w(offset, data, mem_mask, 1);
+}
+
+
+static void toaplan2_scroll_reg_data_w(offs_t offset, UINT16 data, UINT32 mem_mask, int controller)
+{
+ /************************************************************************/
+ /***** layer X and Y flips can be set independantly, so emulate it ******/
+ /************************************************************************/
+
+#ifdef MAME_DEBUG
+ int vid_controllers = 1;
+#endif
+
+ switch(toaplan2_scroll_reg[controller])
+ {
+ case 0x00: data -= 0x1d6; /* 1D6h */
+ COMBINE_DATA(&bg_scrollx[controller]);
+ bg_flip[controller] &= (~TILEMAP_FLIPX);
+ tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
+ tilemap_set_scrollx(bg_tilemap[controller],0,bg_scrollx[controller]+xoffset[0]);
+ break;
+ case 0x01: data -= 0x1ef; /* 1EFh */
+ COMBINE_DATA(&bg_scrolly[controller]);
+ bg_flip[controller] &= (~TILEMAP_FLIPY);
+ tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
+ tilemap_set_scrolly(bg_tilemap[controller],0,bg_scrolly[controller]+yoffset[0]);
+ break;
+ case 0x02: data -= 0x1d8; /* 1D0h */
+ COMBINE_DATA(&fg_scrollx[controller]);
+ fg_flip[controller] &= (~TILEMAP_FLIPX);
+ tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
+ tilemap_set_scrollx(fg_tilemap[controller],0,fg_scrollx[controller]+xoffset[1]);
+ break;
+ case 0x03: data -= 0x1ef; /* 1EFh */
+ COMBINE_DATA(&fg_scrolly[controller]);
+ fg_flip[controller] &= (~TILEMAP_FLIPY);
+ tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
+ tilemap_set_scrolly(fg_tilemap[controller],0,fg_scrolly[controller]+yoffset[1]);
+ break;
+ case 0x04: data -= 0x1da; /* 1DAh */
+ COMBINE_DATA(&top_scrollx[controller]);
+ top_flip[controller] &= (~TILEMAP_FLIPX);
+ tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
+ tilemap_set_scrollx(top_tilemap[controller],0,top_scrollx[controller]+xoffset[2]);
+ break;
+ case 0x05: data -= 0x1ef; /* 1EFh */
+ COMBINE_DATA(&top_scrolly[controller]);
+ top_flip[controller] &= (~TILEMAP_FLIPY);
+ tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
+ tilemap_set_scrolly(top_tilemap[controller],0,top_scrolly[controller]+yoffset[2]);
+ break;
+ case 0x06: data -= 0x1cc; /* 1D4h */
+ COMBINE_DATA(&sprite_scrollx[controller]);
+ if (sprite_scrollx[controller] & 0x8000) sprite_scrollx[controller] |= 0xfffffe00;
+ else sprite_scrollx[controller] &= 0x1ff;
+ sprite_flip[controller] &= (~TOAPLAN2_SPRITE_FLIPX);
+ break;
+ case 0x07: data -= 0x1ef; /* 1F7h */
+ COMBINE_DATA(&sprite_scrolly[controller]);
+ if (sprite_scrolly[controller] & 0x8000) sprite_scrolly[controller] |= 0xfffffe00;
+ else sprite_scrolly[controller] &= 0x1ff;
+ sprite_flip[controller] &= (~TOAPLAN2_SPRITE_FLIPY);
+ break;
+ case 0x0f: break;
+ case 0x80: data -= 0x229; /* 169h */
+ COMBINE_DATA(&bg_scrollx[controller]);
+ bg_flip[controller] |= TILEMAP_FLIPX;
+ tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
+ tilemap_set_scrollx(bg_tilemap[controller],0,bg_scrollx[controller]+xoffset[0]);
+ break;
+ case 0x81: data -= 0x210; /* 100h */
+ COMBINE_DATA(&bg_scrolly[controller]);
+ bg_flip[controller] |= TILEMAP_FLIPY;
+ tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
+ tilemap_set_scrolly(bg_tilemap[controller],0,bg_scrolly[controller]+yoffset[0]);
+ break;
+ case 0x82: data -= 0x227; /* 15Fh */
+ COMBINE_DATA(&fg_scrollx[controller]);
+ fg_flip[controller] |= TILEMAP_FLIPX;
+ tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
+ tilemap_set_scrollx(fg_tilemap[controller],0,fg_scrollx[controller]+xoffset[1]);
+ break;
+ case 0x83: data -= 0x210; /* 100h */
+ COMBINE_DATA(&fg_scrolly[controller]);
+ fg_flip[controller] |= TILEMAP_FLIPY;
+ tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
+ tilemap_set_scrolly(fg_tilemap[controller],0,fg_scrolly[controller]+yoffset[1]);
+ break;
+ case 0x84: data -= 0x225; /* 165h */
+ COMBINE_DATA(&top_scrollx[controller]);
+ top_flip[controller] |= TILEMAP_FLIPX;
+ tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
+ tilemap_set_scrollx(top_tilemap[controller],0,top_scrollx[controller]+xoffset[2]);
+ break;
+ case 0x85: data -= 0x210; /* 100h */
+ COMBINE_DATA(&top_scrolly[controller]);
+ top_flip[controller] |= TILEMAP_FLIPY;
+ tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
+ tilemap_set_scrolly(top_tilemap[controller],0,top_scrolly[controller]+yoffset[2]);
+ break;
+ case 0x86: data -= 0x17b; /* 17Bh */
+ COMBINE_DATA(&sprite_scrollx[controller]);
+ if (sprite_scrollx[controller] & 0x8000) sprite_scrollx[controller] |= 0xfffffe00;
+ else sprite_scrollx[controller] &= 0x1ff;
+ sprite_flip[controller] |= TOAPLAN2_SPRITE_FLIPX;
+ break;
+ case 0x87: data -= 0x108; /* 108h */
+ COMBINE_DATA(&sprite_scrolly[controller]);
+ if (sprite_scrolly[controller] & 0x8000) sprite_scrolly[controller] |= 0xfffffe00;
+ else sprite_scrolly[controller] &= 0x1ff;
+ sprite_flip[controller] |= TOAPLAN2_SPRITE_FLIPY;
+ break;
+ case 0x8f: break;
+
+ case 0x0e: /******* Initialise video controller register ? *******/
+ if ((toaplan2_sub_cpu == CPU_2_Z80) && (data == 3))
+ {
+ /* HACK! When tilted, sound CPU needs to be reset. */
+ if (Machine->drv->sound[0].type == SOUND_YM3812)
+ {
+ cpunum_set_input_line(1, INPUT_LINE_RESET, PULSE_LINE);
+ sndti_reset(SOUND_YM3812, 0);
+ }
+ }
+
+ default: logerror("Hmmm, writing %08x to unknown video control register (%08x) Video controller %01x !!!\n",data ,toaplan2_scroll_reg[controller],controller);
+ break;
+ }
+
+#ifdef MAME_DEBUG
+
+ if (spriteram16_now[1] && spriteram16_new[1]
+ && top_tilemap[1] && fg_tilemap[1] && bg_tilemap[1])
+ {
+ vid_controllers = 2;
+ }
+
+ if ( input_code_pressed_once(KEYCODE_W) )
+ {
+ display_tx += 1;
+ display_tx &= 1;
+ if (toaplan2_txvideoram16 != 0)
+ tilemap_set_enable(tx_tilemap, display_tx);
+ }
+ if ( input_code_pressed_once(KEYCODE_L) )
+ {
+ display_sp[0] += 1;
+ display_sp[0] &= 1;
+ }
+ if ( input_code_pressed_once(KEYCODE_K) )
+ {
+ display_top[0] += 1;
+ display_top[0] &= 1;
+ tilemap_set_enable(top_tilemap[0], display_top[0]);
+ }
+ if ( input_code_pressed_once(KEYCODE_J) )
+ {
+ display_fg[0] += 1;
+ display_fg[0] &= 1;
+ tilemap_set_enable(fg_tilemap[0], display_fg[0]);
+ }
+ if ( input_code_pressed_once(KEYCODE_H) )
+ {
+ display_bg[0] += 1;
+ display_bg[0] &= 1;
+ tilemap_set_enable(bg_tilemap[0], display_bg[0]);
+ }
+ if (vid_controllers == 2)
+ {
+ if ( input_code_pressed_once(KEYCODE_O) )
+ {
+ display_sp[1] += 1;
+ display_sp[1] &= 1;
+ }
+ if ( input_code_pressed_once(KEYCODE_I) )
+ {
+ display_top[1] += 1;
+ display_top[1] &= 1;
+ tilemap_set_enable(top_tilemap[1], display_top[1]);
+ }
+ if ( input_code_pressed_once(KEYCODE_U) )
+ {
+ display_fg[1] += 1;
+ display_fg[1] &= 1;
+ tilemap_set_enable(fg_tilemap[1], display_fg[1]);
+ }
+ if ( input_code_pressed_once(KEYCODE_Y) )
+ {
+ display_bg[1] += 1;
+ display_bg[1] &= 1;
+ tilemap_set_enable(bg_tilemap[1], display_bg[1]);
+ }
+ }
+#endif
+}
+
+WRITE16_HANDLER( toaplan2_0_scroll_reg_data_w )
+{
+ toaplan2_scroll_reg_data_w(offset, data, mem_mask, 0);
+}
+
+WRITE16_HANDLER( toaplan2_1_scroll_reg_data_w )
+{
+ toaplan2_scroll_reg_data_w(offset, data, mem_mask, 1);
+}
+
+
+/***************************************************************************/
+/**************** PIPIBIBI interface into this video driver ****************/
+
+WRITE16_HANDLER( pipibibi_scroll_w )
+{
+ if (ACCESSING_MSB && ACCESSING_LSB)
+ {
+ switch(offset)
+ {
+ case 0x00: data -= 0x01f; break;
+ case 0x01: data += 0x1ef; break;
+ case 0x02: data -= 0x01d; break;
+ case 0x03: data += 0x1ef; break;
+ case 0x04: data -= 0x01b; break;
+ case 0x05: data += 0x1ef; break;
+ case 0x06: data += 0x1d4; break;
+ case 0x07: data += 0x1f7; break;
+ default: logerror("PIPIBIBI writing %04x to unknown scroll register %04x",data, offset);
+ }
+
+ toaplan2_scroll_reg[0] = offset;
+ toaplan2_scroll_reg_data_w(offset, data, mem_mask, 0);
+ }
+}
+
+READ16_HANDLER( pipibibi_videoram16_r )
+{
+ toaplan2_voffs_w(0, offset, 0, 0);
+ return toaplan2_videoram16_r(0, 0);
+}
+
+WRITE16_HANDLER( pipibibi_videoram16_w)
+{
+ toaplan2_voffs_w(0, offset, 0, 0);
+ toaplan2_videoram16_w(0, data, mem_mask, 0);
+}
+
+READ16_HANDLER( pipibibi_spriteram16_r )
+{
+ toaplan2_voffs_w(0, (0x1800 + offset), 0, 0);
+ return toaplan2_videoram16_r(0, 0);
+}
+
+WRITE16_HANDLER( pipibibi_spriteram16_w )
+{
+ toaplan2_voffs_w(0, (0x1800 + offset), mem_mask, 0);
+ toaplan2_videoram16_w(0, data, mem_mask, 0);
+}
+
+
+
+#ifdef MAME_DEBUG
+void toaplan2_log_vram(void)
+{
+ offs_t sprite_voffs, tile_voffs;
+ int vid_controllers = 1;
+
+ if (spriteram16_now[1] && spriteram16_new[1]
+ && top_tilemap[1] && fg_tilemap[1] && bg_tilemap[1])
+ {
+ vid_controllers = 2;
+ }
+
+ if ( input_code_pressed_once(KEYCODE_M) )
+ {
+ UINT16 *source_now0 = (UINT16 *)(spriteram16_now[0]);
+ UINT16 *source_new0 = (UINT16 *)(spriteram16_new[0]);
+ UINT16 *source_now1 = (UINT16 *)(spriteram16_now[0]);
+ UINT16 *source_new1 = (UINT16 *)(spriteram16_new[0]);
+
+ int schar[2],sattr[2],sxpos[2],sypos[2];
+
+ if (vid_controllers == 2)
+ {
+ source_now1 = (UINT16 *)(spriteram16_now[1]);
+ source_new1 = (UINT16 *)(spriteram16_new[1]);
+ }
+
+ logerror("Scrolls BG-X BG-Y FG-X FG-Y TOP-X TOP-Y Sprite-X Sprite-Y\n");
+ logerror("---0--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
+ if (vid_controllers == 2)
+ {
+ logerror("---1--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
+ }
+ for ( sprite_voffs = 0; sprite_voffs < (TOAPLAN2_SPRITERAM_SIZE/2); sprite_voffs += 4 )
+ {
+ sattr[0] = source_now0[sprite_voffs];
+ schar[0] = source_now0[sprite_voffs + 1];
+ sxpos[0] = source_now0[sprite_voffs + 2];
+ sypos[0] = source_now0[sprite_voffs + 3];
+ sattr[1] = source_new0[sprite_voffs];
+ schar[1] = source_new0[sprite_voffs + 1];
+ sxpos[1] = source_new0[sprite_voffs + 2];
+ sypos[1] = source_new0[sprite_voffs + 3];
+ logerror("SPoffs Sprt Attr Xpos Ypos Sprt Attr Xpos Ypos\n");
+ logerror("0:%03x now:%04x %04x %04x %04x new:%04x %04x %04x %04x\n",sprite_voffs,
+ schar[0], sattr[0],sxpos[0], sypos[0],
+ schar[1], sattr[1],sxpos[1], sypos[1]);
+ if (vid_controllers == 2)
+ {
+ sattr[0] = source_now1[sprite_voffs];
+ schar[0] = source_now1[sprite_voffs + 1];
+ sxpos[0] = source_now1[sprite_voffs + 2];
+ sypos[0] = source_now1[sprite_voffs + 3];
+ sattr[1] = source_new1[sprite_voffs];
+ schar[1] = source_new1[sprite_voffs + 1];
+ sxpos[1] = source_new1[sprite_voffs + 2];
+ sypos[1] = source_new1[sprite_voffs + 3];
+ logerror("1:%03x now:%04x %04x %04x %04x new:%04x %04x %04x %04x\n",sprite_voffs,
+ schar[0], sattr[0],sxpos[0], sypos[0],
+ schar[1], sattr[1],sxpos[1], sypos[1]);
+ }
+ }
+ }
+ if ( input_code_pressed_once(KEYCODE_N) )
+ {
+ int tchar[2], tattr[2];
+ logerror("Scrolls BG-X BG-Y FG-X FG-Y TOP-X TOP-Y Sprite-X Sprite-Y\n");
+ logerror("---0--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
+ if (vid_controllers == 2)
+ {
+ logerror("---1--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
+ }
+ for ( tile_voffs = 0; tile_voffs < (TOAPLAN2_TOP_VRAM_SIZE/2); tile_voffs += 2 )
+ {
+ tchar[0] = topvideoram16[0][tile_voffs + 1];
+ tattr[0] = topvideoram16[0][tile_voffs];
+ if (vid_controllers == 2)
+ {
+ tchar[1] = topvideoram16[1][tile_voffs + 1];
+ tattr[1] = topvideoram16[1][tile_voffs];
+ logerror("TOPoffs:%04x Tile0:%04x Attr0:%04x Tile1:%04x Attr1:%04x\n", tile_voffs, tchar[0], tattr[0], tchar[1], tattr[1]);
+ }
+ else
+ {
+ logerror("TOPoffs:%04x Tile0:%04x Attr0:%04x\n", tile_voffs, tchar[0], tattr[0]);
+ }
+ }
+ }
+ if ( input_code_pressed_once(KEYCODE_B) )
+ {
+ int tchar[2], tattr[2];
+ logerror("Scrolls BG-X BG-Y FG-X FG-Y TOP-X TOP-Y Sprite-X Sprite-Y\n");
+ logerror("---0--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
+ if (vid_controllers == 2)
+ {
+ logerror("---1--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
+ }
+ for ( tile_voffs = 0; tile_voffs < (TOAPLAN2_FG_VRAM_SIZE/2); tile_voffs += 2 )
+ {
+ tchar[0] = fgvideoram16[0][tile_voffs + 1];
+ tattr[0] = fgvideoram16[0][tile_voffs];
+ if (vid_controllers == 2)
+ {
+ tchar[1] = fgvideoram16[1][tile_voffs + 1];
+ tattr[1] = fgvideoram16[1][tile_voffs];
+ logerror("FGoffs:%04x Tile0:%04x Attr0:%04x Tile1:%04x Attr1:%04x\n", tile_voffs, tchar[0], tattr[0], tchar[1], tattr[1]);
+ }
+ else
+ {
+ logerror("FGoffs:%04x Tile0:%04x Attr0:%04x\n", tile_voffs, tchar[0], tattr[0]);
+ }
+ }
+ }
+ if ( input_code_pressed_once(KEYCODE_V) )
+ {
+ int tchar[2], tattr[2];
+ logerror("Scrolls BG-X BG-Y FG-X FG-Y TOP-X TOP-Y Sprite-X Sprite-Y\n");
+ logerror("---0--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
+ if (vid_controllers == 2)
+ {
+ logerror("---1--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
+ }
+ for ( tile_voffs = 0; tile_voffs < (TOAPLAN2_BG_VRAM_SIZE/2); tile_voffs += 2 )
+ {
+ tchar[0] = bgvideoram16[0][tile_voffs + 1];
+ tattr[0] = bgvideoram16[0][tile_voffs];
+ if (vid_controllers == 2)
+ {
+ tchar[1] = bgvideoram16[1][tile_voffs + 1];
+ tattr[1] = bgvideoram16[1][tile_voffs];
+ logerror("BGoffs:%04x Tile0:%04x Attr0:%04x Tile1:%04x Attr1:%04x\n", tile_voffs, tchar[0], tattr[0], tchar[1], tattr[1]);
+ }
+ else
+ {
+ logerror("BGoffs:%04x Tile0:%04x Attr0:%04x\n", tile_voffs, tchar[0], tattr[0]);
+ }
+ }
+ }
+
+ if ( input_code_pressed_once(KEYCODE_C) )
+ logerror("Mark here\n");
+
+ if ( input_code_pressed_once(KEYCODE_E) )
+ {
+ displog += 1;
+ displog &= 1;
+ }
+ if (displog)
+ {
+ logerror("Scrolls BG-X BG-Y FG-X FG-Y TOP-X TOP-Y Sprite-X Sprite-Y\n");
+ logerror("---0--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
+ if (vid_controllers == 2)
+ {
+ logerror("---1--> %04x %04x %04x %04x %04x %04x %04x %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
+ }
+ }
+}
+#endif
+
+
+
+/***************************************************************************
+ Sprite Handlers
+***************************************************************************/
+
+static void draw_sprites( mame_bitmap *bitmap, const rectangle *cliprect, int controller, int priority_to_display, int bank_sel )
+{
+ const gfx_element *gfx = Machine->gfx[ ((controller*2)+1) ];
+
+ int offs;
+
+ UINT16 *source = (UINT16 *)(spriteram16_n[controller]);
+
+
+ priority_to_display <<= 8;
+
+ for (offs = 0; offs < (TOAPLAN2_SPRITERAM_SIZE/2); offs += 4)
+ {
+ int attrib, sprite, color, priority, flipx, flipy, sx, sy;
+ int sprite_sizex, sprite_sizey, dim_x, dim_y, sx_base, sy_base;
+ int bank, sprite_num;
+
+ attrib = source[offs];
+ priority = (attrib & 0x0f00);
+
+ if ((priority == priority_to_display) && (attrib & 0x8000))
+ {
+ if (!bank_sel) /* No Sprite select bank switching needed */
+ {
+ sprite = ((attrib & 3) << 16) | source[offs + 1]; /* 18 bit */
+ }
+ else /* Batrider Sprite select bank switching required */
+ {
+ sprite_num = source[offs + 1] & 0x7fff;
+ bank = ((attrib & 3) << 1) | (source[offs + 1] >> 15);
+ sprite = (batrider_object_bank[bank] << 15 ) | sprite_num;
+ }
+ color = (attrib >> 2) & 0x3f;
+
+ /***** find out sprite size *****/
+ sprite_sizex = ((source[offs + 2] & 0x0f) + 1) * 8;
+ sprite_sizey = ((source[offs + 3] & 0x0f) + 1) * 8;
+
+ /***** find position to display sprite *****/
+ sx_base = ((source[offs + 2] >> 7) - (sprite_scrollx[controller]+xoffset[3])) & 0x1ff;
+ sy_base = ((source[offs + 3] >> 7) - (sprite_scrolly[controller]+yoffset[3])) & 0x1ff;
+
+ flipx = attrib & TOAPLAN2_SPRITE_FLIPX;
+ flipy = attrib & TOAPLAN2_SPRITE_FLIPY;
+
+ if (flipx)
+ {
+ /***** Wrap sprite position around *****/
+ sx_base -= 7;
+ if (sx_base >= 0x1c0) sx_base -= 0x200;
+ }
+ else
+ {
+ if (sx_base >= 0x180) sx_base -= 0x200;
+ }
+
+ if (flipy)
+ {
+ sy_base -= 7;
+ if (sy_base >= 0x1c0) sy_base -= 0x200;
+ }
+ else
+ {
+ if (sy_base >= 0x180) sy_base -= 0x200;
+ }
+
+ /***** Flip the sprite layer in any active X or Y flip *****/
+ if (sprite_flip[controller])
+ {
+ if (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPX)
+ sx_base = 320 - sx_base;
+ if (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPY)
+ sy_base = 240 - sy_base;
+ }
+
+ /***** Cancel flip, if it, and sprite layer flip are active *****/
+ flipx = (flipx ^ (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPX));
+ flipy = (flipy ^ (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPY));
+
+ /***** Draw the complete sprites using the dimension info *****/
+ for (dim_y = 0; dim_y < sprite_sizey; dim_y += 8)
+ {
+ if (flipy) sy = sy_base - dim_y;
+ else sy = sy_base + dim_y;
+ for (dim_x = 0; dim_x < sprite_sizex; dim_x += 8)
+ {
+ if (flipx) sx = sx_base - dim_x;
+ else sx = sx_base + dim_x;
+
+ drawgfx(bitmap,gfx,sprite,
+ color,
+ flipx,flipy,
+ sx,sy,
+ cliprect,TRANSPARENCY_PEN,0);
+
+ sprite++ ;
+ }
+ }
+ }
+ }
+}
+
+
+/***************************************************************************
+ Mark the sprite priority used list.
+***************************************************************************/
+static void mark_sprite_priority(int controller)
+{
+ int priority, offs;
+
+ UINT16 *source = (UINT16 *)(spriteram16_n[controller]);
+
+
+ for (priority = 0; priority < 16; priority++)
+ sprite_priority[controller][priority] = 0; /* Clear priorities used list */
+
+ for (offs = 0; offs < (TOAPLAN2_SPRITERAM_SIZE/2); offs += 4)
+ {
+ priority = (source[offs] & 0x0f00) >> 8;
+ sprite_priority[controller][priority] = display_sp[controller];
+ }
+}
+
+/***************************************************************************
+ Mark the tile priority used list.
+***************************************************************************/
+static void mark_tile_priority(int controller)
+{
+ int priority, offs;
+
+ for (priority = 0; priority < 16; priority++)
+ {
+ top_tile_priority[controller][priority] = 0;
+ fg_tile_priority[controller][priority] = 0;
+ bg_tile_priority[controller][priority] = 0;
+ }
+
+ for (offs = 0; offs < (TOAPLAN2_BG_VRAM_SIZE/2); offs += 2)
+ {
+ top_tile_priority[controller][(topvideoram16[controller][offs] & 0x0f00) >> 8] = 1;
+ fg_tile_priority[controller][(fgvideoram16[controller][offs] & 0x0f00) >> 8] = 1;
+ bg_tile_priority[controller][(bgvideoram16[controller][offs] & 0x0f00) >> 8] = 1;
+ }
+
+#if 0
+ {
+ static int bg[2]={0,0},fg[2]={0,0},top[2]={0,0};
+ bg[controller]=0;fg[controller]=0;top[controller]=0;
+ for (priority = 0; priority < 16; priority++)
+ {
+ if (bg_tile_priority[controller][priority]) bg[controller]++;
+ if (fg_tile_priority[controller][priority]) fg[controller]++;
+ if (top_tile_priority[controller][priority]) top[controller]++;
+ }
+ popmessage("b=%2d:%2d f=%2d:%2d t=%2d:%2d",bg[0],bg[1],fg[0],fg[1],top[0],top[1]);
+ }
+#endif
+}
+
+/***************************************************************************
+ Draw the game screen in the given mame_bitmap.
+***************************************************************************/
+
+VIDEO_UPDATE( toaplan2_0 )
+{
+ int priority;
+
+
+#ifdef MAME_DEBUG
+ toaplan2_log_vram();
+#endif
+
+ mark_sprite_priority(0);
+ mark_tile_priority(0);
+
+ fillbitmap(bitmap,machine->pens[0],cliprect);
+
+ for (priority = 0; priority < 16; priority++)
+ {
+ if (bg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,bg_tilemap[0],priority,0);
+ if (fg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,fg_tilemap[0],priority,0);
+ if (top_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,top_tilemap[0],priority,0);
+ if (sprite_priority[0][priority])
+ draw_sprites(bitmap,cliprect,0,priority,0);
+ }
+ return 0;
+}
+
+VIDEO_UPDATE( dogyuun_1 )
+{
+ int priority;
+
+
+#ifdef MAME_DEBUG
+ toaplan2_log_vram();
+#endif
+
+ mark_sprite_priority(0);
+ mark_sprite_priority(1);
+ mark_tile_priority(0);
+ mark_tile_priority(1);
+
+ fillbitmap(bitmap,machine->pens[0],cliprect);
+
+ for (priority = 0; priority < 16; priority++)
+ {
+ if (bg_tile_priority[1][priority]) tilemap_draw(bitmap,cliprect,bg_tilemap[1],priority,0);
+ if (fg_tile_priority[1][priority]) tilemap_draw(bitmap,cliprect,fg_tilemap[1],priority,0);
+ if (top_tile_priority[1][priority]) tilemap_draw(bitmap,cliprect,top_tilemap[1],priority,0);
+ if (sprite_priority[1][priority])
+ draw_sprites(bitmap,cliprect,1,priority,0);
+ }
+ for (priority = 0; priority < 16; priority++)
+ {
+ if (bg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,bg_tilemap[0],priority,0);
+ if (fg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,fg_tilemap[0],priority,0);
+ if (top_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,top_tilemap[0],priority,0);
+ if (sprite_priority[0][priority])
+ draw_sprites(bitmap,cliprect,0,priority,0);
+ }
+ return 0;
+}
+
+VIDEO_UPDATE( batsugun_1 )
+{
+ int priority;
+
+
+#ifdef MAME_DEBUG
+ toaplan2_log_vram();
+#endif
+
+ mark_sprite_priority(0);
+ mark_sprite_priority(1);
+ mark_tile_priority(0);
+ mark_tile_priority(1);
+
+ fillbitmap(bitmap,machine->pens[0],cliprect);
+
+ for (priority = 0; priority < 16; priority++)
+ {
+ if (bg_tile_priority[1][priority]) tilemap_draw(bitmap,cliprect,bg_tilemap[1],priority,0);/* 2 */
+ if (bg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,bg_tilemap[0],priority,0);
+ if (fg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,fg_tilemap[0],priority,0);
+ if (fg_tile_priority[1][priority]) tilemap_draw(bitmap,cliprect,fg_tilemap[1],priority,0);
+ if (top_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,top_tilemap[0],priority,0);
+ if (sprite_priority[0][priority])
+ draw_sprites(bitmap,cliprect,0,priority,0);
+ }
+
+ for (priority = 0; priority < 16; priority++)
+ {
+ if (top_tile_priority[1][priority]) tilemap_draw(bitmap,cliprect,top_tilemap[1],priority,0);
+ if (sprite_priority[1][priority])
+ draw_sprites(bitmap,cliprect,1,priority,0);
+ }
+
+ return 0;
+}
+
+VIDEO_UPDATE( truxton2_0 )
+{
+ video_update_toaplan2_0(machine,screen,bitmap,cliprect);
+ tilemap_draw(bitmap,cliprect,tx_tilemap,0,0);
+ return 0;
+}
+
+VIDEO_UPDATE( batrider_0 )
+{
+ int priority;
+
+ int line;
+ rectangle clip;
+
+#ifdef MAME_DEBUG
+ toaplan2_log_vram();
+#endif
+
+ mark_sprite_priority(0);
+ mark_tile_priority(0);
+
+ /* If object bank is changed, all tile must be redrawn to blow off glitches. */
+ /* This causes serious slow down. Is there better algorithm ? */
+ if (objectbank_dirty)
+ {
+ tilemap_mark_all_tiles_dirty(bg_tilemap[0]);
+ tilemap_mark_all_tiles_dirty(fg_tilemap[0]);
+ objectbank_dirty = 0;
+ }
+
+ fillbitmap(bitmap,machine->pens[0],cliprect);
+
+ for (priority = 0; priority < 16; priority++)
+ {
+ if (bg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,bg_tilemap[0],priority,0);
+ if (fg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,fg_tilemap[0],priority,0);
+ if (top_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,top_tilemap[0],priority,0);
+ if (sprite_priority[0][priority])
+ draw_sprites(bitmap,cliprect,0,priority,1); /* consider bank select */
+ }
+
+ clip.min_x = machine->screen[0].visarea.min_x;
+ clip.max_x = machine->screen[0].visarea.max_x;
+ clip.min_y = machine->screen[0].visarea.min_y;
+ clip.max_y = machine->screen[0].visarea.max_y;
+
+ /* used for 'for use in' and '8ing' screen on bbakraid, raizing on batrider */
+ for (line = 0; line < 256;line++)
+ {
+ clip.min_y = clip.max_y = line;
+ tilemap_set_scrolly(tx_tilemap,0,toaplan2_txvideoram16_offs[line&0xff]-line);
+ tilemap_draw(bitmap,&clip,tx_tilemap,0,0);
+ }
+ return 0;
+}
+
+
+VIDEO_UPDATE( mahoudai_0 )
+{
+ int priority;
+
+
+#ifdef MAME_DEBUG
+ toaplan2_log_vram();
+#endif
+
+ mark_sprite_priority(0);
+ mark_tile_priority(0);
+
+ fillbitmap(bitmap,machine->pens[0],cliprect);
+
+ if (bg_tile_priority[0][0]) tilemap_draw(bitmap,cliprect,bg_tilemap[0],0,0);
+ if (fg_tile_priority[0][0]) tilemap_draw(bitmap,cliprect,fg_tilemap[0],0,0);
+ if (top_tile_priority[0][0]) tilemap_draw(bitmap,cliprect,top_tilemap[0],0,0);
+ for (priority = 1; priority < 16; priority++)
+ {
+ if (bg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,bg_tilemap[0],priority,0);
+ if (fg_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,fg_tilemap[0],priority,0);
+ if (top_tile_priority[0][priority]) tilemap_draw(bitmap,cliprect,top_tilemap[0],priority,0);
+ if (sprite_priority[0][priority-1])
+ draw_sprites(bitmap,cliprect,0,priority-1,0);
+ }
+ if (sprite_priority[0][15])
+ draw_sprites(bitmap,cliprect,0,15,0);
+ tilemap_draw(bitmap,cliprect,tx_tilemap,0,0);
+ return 0;
+}
+
+
+VIDEO_EOF( toaplan2_0 )
+{
+ /** Shift sprite RAM buffers *** Used to fix sprite lag **/
+ memcpy(spriteram16_now[0],spriteram16_new[0],TOAPLAN2_SPRITERAM_SIZE);
+}
+
+VIDEO_EOF( toaplan2_1 )
+{
+ /** Shift sprite RAM buffers *** Used to fix sprite lag **/
+ memcpy(spriteram16_now[0],spriteram16_new[0],TOAPLAN2_SPRITERAM_SIZE);
+ memcpy(spriteram16_now[1],spriteram16_new[1],TOAPLAN2_SPRITERAM_SIZE);
+}