diff options
Diffstat (limited to 'src/mame/video/nbmj8891.c')
-rw-r--r-- | src/mame/video/nbmj8891.c | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/src/mame/video/nbmj8891.c b/src/mame/video/nbmj8891.c new file mode 100644 index 00000000000..959d2622ab6 --- /dev/null +++ b/src/mame/video/nbmj8891.c @@ -0,0 +1,569 @@ +/****************************************************************************** + + Video Hardware for Nichibutsu Mahjong series. + + Driver by Takahiro Nogi <nogi@kt.rim.or.jp> 1999/11/05 - + +******************************************************************************/ + +#include "driver.h" +#include "nb1413m3.h" + + +static int nbmj8891_scrolly; +static int blitter_destx, blitter_desty; +static int blitter_sizex, blitter_sizey; +static int blitter_src_addr; +static int blitter_direction_x, blitter_direction_y; +static int nbmj8891_vram; +static int nbmj8891_gfxrom; +static int nbmj8891_dispflag; +static int nbmj8891_flipscreen; +static int nbmj8891_clutsel; +static int nbmj8891_screen_refresh; +static int gfxdraw_mode; + +static mame_bitmap *nbmj8891_tmpbitmap0, *nbmj8891_tmpbitmap1; +static UINT8 *nbmj8891_videoram0, *nbmj8891_videoram1; +static UINT8 *nbmj8891_palette; +static UINT8 *nbmj8891_clut; + + +static void nbmj8891_vramflip(int vram); +static void nbmj8891_gfxdraw(void); + + +/****************************************************************************** + + +******************************************************************************/ +READ8_HANDLER( nbmj8891_palette_type1_r ) +{ + return nbmj8891_palette[offset]; +} + +WRITE8_HANDLER( nbmj8891_palette_type1_w ) +{ + int r, g, b; + + nbmj8891_palette[offset] = data; + + if (!(offset & 1)) return; + + offset &= 0x1fe; + + r = ((nbmj8891_palette[offset + 0] & 0x0f) >> 0); + g = ((nbmj8891_palette[offset + 1] & 0xf0) >> 4); + b = ((nbmj8891_palette[offset + 1] & 0x0f) >> 0); + + palette_set_color_rgb(Machine, (offset >> 1), pal4bit(r), pal4bit(g), pal4bit(b)); +} + +READ8_HANDLER( nbmj8891_palette_type2_r ) +{ + return nbmj8891_palette[offset]; +} + +WRITE8_HANDLER( nbmj8891_palette_type2_w ) +{ + int r, g, b; + + nbmj8891_palette[offset] = data; + + if (!(offset & 0x100)) return; + + offset &= 0x0ff; + + r = ((nbmj8891_palette[offset + 0x000] & 0x0f) >> 0); + g = ((nbmj8891_palette[offset + 0x000] & 0xf0) >> 4); + b = ((nbmj8891_palette[offset + 0x100] & 0x0f) >> 0); + + palette_set_color_rgb(Machine, (offset & 0x0ff), pal4bit(r), pal4bit(g), pal4bit(b)); +} + +READ8_HANDLER( nbmj8891_palette_type3_r ) +{ + return nbmj8891_palette[offset]; +} + +WRITE8_HANDLER( nbmj8891_palette_type3_w ) +{ + int r, g, b; + + nbmj8891_palette[offset] = data; + + if (!(offset & 1)) return; + + offset &= 0x1fe; + + r = ((nbmj8891_palette[offset + 1] & 0x0f) >> 0); + g = ((nbmj8891_palette[offset + 0] & 0xf0) >> 4); + b = ((nbmj8891_palette[offset + 0] & 0x0f) >> 0); + + palette_set_color_rgb(Machine, (offset >> 1), pal4bit(r), pal4bit(g), pal4bit(b)); +} + +WRITE8_HANDLER( nbmj8891_clutsel_w ) +{ + nbmj8891_clutsel = data; +} + +READ8_HANDLER( nbmj8891_clut_r ) +{ + return nbmj8891_clut[offset]; +} + +WRITE8_HANDLER( nbmj8891_clut_w ) +{ + nbmj8891_clut[((nbmj8891_clutsel & 0x7f) * 0x10) + (offset & 0x0f)] = data; +} + +/****************************************************************************** + + +******************************************************************************/ +WRITE8_HANDLER( nbmj8891_blitter_w ) +{ + switch (offset) + { + case 0x00: blitter_src_addr = (blitter_src_addr & 0xff00) | data; break; + case 0x01: blitter_src_addr = (blitter_src_addr & 0x00ff) | (data << 8); break; + case 0x02: blitter_destx = data; break; + case 0x03: blitter_desty = data; break; + case 0x04: blitter_sizex = data; break; + case 0x05: blitter_sizey = data; + /* writing here also starts the blit */ + nbmj8891_gfxdraw(); + break; + case 0x06: blitter_direction_x = (data & 0x01) ? 1 : 0; + blitter_direction_y = (data & 0x02) ? 1 : 0; + nbmj8891_flipscreen = (data & 0x04) ? 1 : 0; + nbmj8891_dispflag = (data & 0x08) ? 0 : 1; + if (gfxdraw_mode) nbmj8891_vramflip(1); + nbmj8891_vramflip(0); + break; + case 0x07: break; + } +} + +WRITE8_HANDLER( nbmj8891_taiwanmb_blitter_w ) +{ + switch (offset) + { + case 0: blitter_src_addr = (blitter_src_addr & 0xff00) | data; break; + case 1: blitter_src_addr = (blitter_src_addr & 0x00ff) | (data << 8); break; + case 2: blitter_destx = data; break; + case 3: blitter_desty = data; break; + case 4: blitter_sizex = (data - 1) & 0xff; break; + case 5: blitter_sizey = (data - 1) & 0xff; break; + } +} + +WRITE8_HANDLER( nbmj8891_taiwanmb_gfxdraw_w ) +{ +// nbmj8891_gfxdraw(); +} + +WRITE8_HANDLER( nbmj8891_taiwanmb_gfxflag_w ) +{ + nbmj8891_flipscreen = (data & 0x04) ? 1 : 0; + + nbmj8891_vramflip(0); +} + +WRITE8_HANDLER( nbmj8891_taiwanmb_mcu_w ) +{ + static int param_old[0x10]; + static int param_cnt = 0; + + param_old[param_cnt & 0x0f] = data; + + if (data == 0x00) + { + blitter_direction_x = 0; + blitter_direction_y = 0; + blitter_destx = 0; + blitter_desty = 0; + blitter_sizex = 0; + blitter_sizey = 0; + nbmj8891_dispflag = 0; + } + +/* + if (data == 0x02) + { + if (param_old[(param_cnt - 1) & 0x0f] == 0x18) + { + nbmj8891_dispflag = 1; + } + else if (param_old[(param_cnt - 1) & 0x0f] == 0x1a) + { + nbmj8891_dispflag = 0; + } + } +*/ + + if (data == 0x04) + { + // CLUT Transfer? + } + + if (data == 0x12) + { + if (param_old[(param_cnt - 1) & 0x0f] == 0x08) + { + blitter_direction_x = 1; + blitter_direction_y = 0; + blitter_destx += blitter_sizex + 1; + blitter_desty += 0; + blitter_sizex ^= 0xff; + blitter_sizey ^= 0x00; + } + else if (param_old[(param_cnt - 1) & 0x0f] == 0x0a) + { + blitter_direction_x = 0; + blitter_direction_y = 1; + blitter_destx += 0; + blitter_desty += blitter_sizey + 1; + blitter_sizex ^= 0x00; + blitter_sizey ^= 0xff; + } + else if (param_old[(param_cnt - 1) & 0x0f] == 0x0c) + { + blitter_direction_x = 1; + blitter_direction_y = 1; + blitter_destx += blitter_sizex + 1; + blitter_desty += blitter_sizey + 1; + blitter_sizex ^= 0xff; + blitter_sizey ^= 0xff; + } + else if (param_old[(param_cnt - 1) & 0x0f] == 0x0e) + { + blitter_direction_x = 0; + blitter_direction_y = 0; + blitter_destx += 0; + blitter_desty += 0; + blitter_sizex ^= 0x00; + blitter_sizey ^= 0x00; + } + + nbmj8891_gfxdraw(); + } + +// blitter_direction_x = 0; // for debug +// blitter_direction_y = 0; // for debug + nbmj8891_dispflag = 1; // for debug + + param_cnt++; +} + +WRITE8_HANDLER( nbmj8891_scrolly_w ) +{ + nbmj8891_scrolly = data; +} + +WRITE8_HANDLER( nbmj8891_vramsel_w ) +{ + /* protection - not sure about this */ + nb1413m3_sndromregion = (data & 0x20) ? REGION_USER1 : REGION_SOUND1; + + nbmj8891_vram = data; +} + +WRITE8_HANDLER( nbmj8891_romsel_w ) +{ + nbmj8891_gfxrom = (data & 0x0f); + + if ((0x20000 * nbmj8891_gfxrom) > (memory_region_length(REGION_GFX1) - 1)) + { +#ifdef MAME_DEBUG + popmessage("GFXROM BANK OVER!!"); +#endif + nbmj8891_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1); + } +} + +/****************************************************************************** + + +******************************************************************************/ +void nbmj8891_vramflip(int vram) +{ + static int nbmj8891_flipscreen_old = 0; + int x, y; + UINT8 color1, color2; + UINT8 *vidram; + + if (nbmj8891_flipscreen == nbmj8891_flipscreen_old) return; + + vidram = vram ? nbmj8891_videoram1 : nbmj8891_videoram0; + + for (y = 0; y < (Machine->screen[0].height / 2); y++) + { + for (x = 0; x < Machine->screen[0].width; x++) + { + color1 = vidram[(y * Machine->screen[0].width) + x]; + color2 = vidram[((y ^ 0xff) * Machine->screen[0].width) + (x ^ 0x1ff)]; + vidram[(y * Machine->screen[0].width) + x] = color2; + vidram[((y ^ 0xff) * Machine->screen[0].width) + (x ^ 0x1ff)] = color1; + } + } + + nbmj8891_flipscreen_old = nbmj8891_flipscreen; + nbmj8891_screen_refresh = 1; +} + + +static void update_pixel0(int x, int y) +{ + UINT8 color = nbmj8891_videoram0[(y * Machine->screen[0].width) + x]; + *BITMAP_ADDR16(nbmj8891_tmpbitmap0, y, x) = Machine->pens[color]; +} + +static void update_pixel1(int x, int y) +{ + UINT8 color = nbmj8891_videoram1[(y * Machine->screen[0].width) + x]; + *BITMAP_ADDR16(nbmj8891_tmpbitmap1, y, x) = Machine->pens[(color == 0x7f) ? 0xff : color]; +} + +static TIMER_CALLBACK( blitter_timer_callback ) +{ + nb1413m3_busyflag = 1; +} + +static void nbmj8891_gfxdraw(void) +{ + UINT8 *GFX = memory_region(REGION_GFX1); + + int x, y; + int dx1, dx2, dy1, dy2; + int startx, starty; + int sizex, sizey; + int skipx, skipy; + int ctrx, ctry; + UINT8 color, color1, color2; + int gfxaddr; + + nb1413m3_busyctr = 0; + + startx = blitter_destx + blitter_sizex; + starty = blitter_desty + blitter_sizey; + + if (blitter_direction_x) + { + sizex = blitter_sizex ^ 0xff; + skipx = 1; + } + else + { + sizex = blitter_sizex; + skipx = -1; + } + + if (blitter_direction_y) + { + sizey = blitter_sizey ^ 0xff; + skipy = 1; + } + else + { + sizey = blitter_sizey; + skipy = -1; + } + + gfxaddr = (nbmj8891_gfxrom << 17) + (blitter_src_addr << 1); + + for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--) + { + for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--) + { + if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1))) + { +#ifdef MAME_DEBUG + popmessage("GFXROM ADDRESS OVER!!"); +#endif + gfxaddr &= (memory_region_length(REGION_GFX1) - 1); + } + + color = GFX[gfxaddr++]; + + // for hanamomo + if ((nb1413m3_type == NB1413M3_HANAMOMO) && ((gfxaddr >= 0x20000) && (gfxaddr < 0x28000))) + { + color |= ((color & 0x0f) << 4); + } + + dx1 = (2 * x + 0) & 0x1ff; + dx2 = (2 * x + 1) & 0x1ff; + + if (gfxdraw_mode) + { + // 2 layer type + dy1 = y & 0xff; + dy2 = (y + nbmj8891_scrolly) & 0xff; + } + else + { + // 1 layer type + dy1 = (y + nbmj8891_scrolly) & 0xff; + dy2 = 0; + } + + if (!nbmj8891_flipscreen) + { + dx1 ^= 0x1ff; + dx2 ^= 0x1ff; + dy1 ^= 0xff; + dy2 ^= 0xff; + } + + if (blitter_direction_x) + { + // flip + color1 = (color & 0x0f) >> 0; + color2 = (color & 0xf0) >> 4; + } + else + { + // normal + color1 = (color & 0xf0) >> 4; + color2 = (color & 0x0f) >> 0; + } + + color1 = nbmj8891_clut[((nbmj8891_clutsel & 0x7f) << 4) + color1]; + color2 = nbmj8891_clut[((nbmj8891_clutsel & 0x7f) << 4) + color2]; + + if ((!gfxdraw_mode) || (nbmj8891_vram & 0x01)) + { + // layer 1 + if (color1 != 0xff) + { + nbmj8891_videoram0[(dy1 * Machine->screen[0].width) + dx1] = color1; + update_pixel0(dx1, dy1); + } + if (color2 != 0xff) + { + nbmj8891_videoram0[(dy1 * Machine->screen[0].width) + dx2] = color2; + update_pixel0(dx2, dy1); + } + } + if (gfxdraw_mode && (nbmj8891_vram & 0x02)) + { + // layer 2 + if (nbmj8891_vram & 0x08) + { + // transparent enable + if (color1 != 0xff) + { + nbmj8891_videoram1[(dy2 * Machine->screen[0].width) + dx1] = color1; + update_pixel1(dx1, dy2); + } + if (color2 != 0xff) + { + nbmj8891_videoram1[(dy2 * Machine->screen[0].width) + dx2] = color2; + update_pixel1(dx2, dy2); + } + } + else + { + // transparent disable + nbmj8891_videoram1[(dy2 * Machine->screen[0].width) + dx1] = color1; + update_pixel1(dx1, dy2); + nbmj8891_videoram1[(dy2 * Machine->screen[0].width) + dx2] = color2; + update_pixel1(dx2, dy2); + } + } + + nb1413m3_busyctr++; + } + } + + nb1413m3_busyflag = 0; + timer_set(attotime_mul(ATTOTIME_IN_HZ(400000), nb1413m3_busyctr), 0, blitter_timer_callback); +} + +/****************************************************************************** + + +******************************************************************************/ +VIDEO_START( nbmj8891_1layer ) +{ + UINT8 *CLUT = memory_region(REGION_USER1); + int i; + + nbmj8891_tmpbitmap0 = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format); + nbmj8891_videoram0 = auto_malloc(machine->screen[0].width * machine->screen[0].height * sizeof(char)); + nbmj8891_palette = auto_malloc(0x200 * sizeof(char)); + nbmj8891_clut = auto_malloc(0x800 * sizeof(char)); + memset(nbmj8891_videoram0, 0xff, (machine->screen[0].width * machine->screen[0].height * sizeof(char))); + gfxdraw_mode = 0; + + if (nb1413m3_type == NB1413M3_TAIWANMB) + for (i = 0; i < 0x0800; i++) nbmj8891_clut[i] = CLUT[i]; +} + +VIDEO_START( nbmj8891_2layer ) +{ + nbmj8891_tmpbitmap0 = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format); + nbmj8891_tmpbitmap1 = auto_bitmap_alloc(machine->screen[0].width, machine->screen[0].height, machine->screen[0].format); + nbmj8891_videoram0 = auto_malloc(machine->screen[0].width * machine->screen[0].height * sizeof(UINT8)); + nbmj8891_videoram1 = auto_malloc(machine->screen[0].width * machine->screen[0].height * sizeof(UINT8)); + nbmj8891_palette = auto_malloc(0x200 * sizeof(UINT8)); + nbmj8891_clut = auto_malloc(0x800 * sizeof(UINT8)); + memset(nbmj8891_videoram0, 0xff, (machine->screen[0].width * machine->screen[0].height * sizeof(UINT8))); + memset(nbmj8891_videoram1, 0xff, (machine->screen[0].width * machine->screen[0].height * sizeof(UINT8))); + gfxdraw_mode = 1; +} + +/****************************************************************************** + + +******************************************************************************/ +VIDEO_UPDATE( nbmj8891 ) +{ + int x, y; + + if (nbmj8891_screen_refresh) + { + nbmj8891_screen_refresh = 0; + for (y = 0; y < machine->screen[0].height; y++) + { + for (x = 0; x < machine->screen[0].width; x++) + { + update_pixel0(x, y); + } + } + if (gfxdraw_mode) + { + for (y = 0; y < machine->screen[0].height; y++) + { + for (x = 0; x < machine->screen[0].width; x++) + { + update_pixel1(x, y); + } + } + } + } + + if (nbmj8891_dispflag) + { + static int scrolly; + if (!nbmj8891_flipscreen) scrolly = nbmj8891_scrolly; + else scrolly = (-nbmj8891_scrolly) & 0xff; + + if (gfxdraw_mode) + { + copyscrollbitmap(bitmap, nbmj8891_tmpbitmap0, 0, 0, 0, 0, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0); + copyscrollbitmap(bitmap, nbmj8891_tmpbitmap1, 0, 0, 1, &scrolly, &machine->screen[0].visarea, TRANSPARENCY_PEN, machine->pens[0xff]); + } + else + { + copyscrollbitmap(bitmap, nbmj8891_tmpbitmap0, 0, 0, 1, &scrolly, &machine->screen[0].visarea, TRANSPARENCY_NONE, 0); + } + } + else + { + fillbitmap(bitmap, machine->pens[0xff], 0); + } + return 0; +} |