// license:BSD-3-Clause // copyright-holders:Manuel Abadia #include "emu.h" #include "includes/baraduke.h" /*************************************************************************** Convert the color PROMs. The palette PROMs are connected to the RGB output this way: bit 3 -- 220 ohm resistor -- RED/GREEN/BLUE -- 470 ohm resistor -- RED/GREEN/BLUE -- 1 kohm resistor -- RED/GREEN/BLUE bit 0 -- 2.2kohm resistor -- RED/GREEN/BLUE ***************************************************************************/ void baraduke_state::baraduke_palette(palette_device &palette) const { const uint8_t *color_prom = memregion("proms")->base(); for (int i = 0; i < 2048; i++) { int bit0, bit1, bit2, bit3; // red component bit0 = BIT(color_prom[2048], 0); bit1 = BIT(color_prom[2048], 1); bit2 = BIT(color_prom[2048], 2); bit3 = BIT(color_prom[2048], 3); int const r = 0x0e*bit0 + 0x1f*bit1 + 0x43*bit2 + 0x8f*bit3; // green component bit0 = BIT(color_prom[0], 0); bit1 = BIT(color_prom[0], 1); bit2 = BIT(color_prom[0], 2); bit3 = BIT(color_prom[0], 3); int const g = 0x0e*bit0 + 0x1f*bit1 + 0x43*bit2 + 0x8f*bit3; // blue component bit0 = BIT(color_prom[0], 4); bit1 = BIT(color_prom[0], 5); bit2 = BIT(color_prom[0], 6); bit3 = BIT(color_prom[0], 7); int const b = 0x0e*bit0 + 0x1f*bit1 + 0x43*bit2 + 0x8f*bit3; palette.set_pen_color(i, rgb_t(r, g, b)); color_prom++; } } /*************************************************************************** Callbacks for the TileMap code ***************************************************************************/ /* convert from 32x32 to 36x28 */ TILEMAP_MAPPER_MEMBER(baraduke_state::tx_tilemap_scan) { int offs; row += 2; col -= 2; if (col & 0x20) offs = row + ((col & 0x1f) << 5); else offs = col + (row << 5); return offs; } TILE_GET_INFO_MEMBER(baraduke_state::tx_get_tile_info) { tileinfo.set(0, m_textram[tile_index], (m_textram[tile_index+0x400] << 2) & 0x1ff, 0); } TILE_GET_INFO_MEMBER(baraduke_state::get_tile_info0) { int code = m_videoram[2*tile_index]; int attr = m_videoram[2*tile_index + 1]; tileinfo.set(1, code + ((attr & 0x03) << 8), attr, 0); } TILE_GET_INFO_MEMBER(baraduke_state::get_tile_info1) { int code = m_videoram[0x1000 + 2*tile_index]; int attr = m_videoram[0x1000 + 2*tile_index + 1]; tileinfo.set(2, code + ((attr & 0x03) << 8), attr, 0); } /*************************************************************************** Start the video hardware emulation. ***************************************************************************/ void baraduke_state::video_start() { m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(baraduke_state::tx_get_tile_info)), tilemap_mapper_delegate(*this, FUNC(baraduke_state::tx_tilemap_scan)), 8,8, 36,28); m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(baraduke_state::get_tile_info0)), TILEMAP_SCAN_ROWS, 8,8, 64,32); m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(baraduke_state::get_tile_info1)), TILEMAP_SCAN_ROWS, 8,8, 64,32); m_tx_tilemap->set_transparent_pen(3); m_bg_tilemap[0]->set_transparent_pen(7); m_bg_tilemap[1]->set_transparent_pen(7); m_bg_tilemap[0]->set_scrolldx(-26, -227+26); m_bg_tilemap[1]->set_scrolldx(-24, -227+24); m_bg_tilemap[0]->set_scrolldy(-9, 9); m_bg_tilemap[1]->set_scrolldy(-9, 9); m_tx_tilemap->set_scrolldy(16,16); } /*************************************************************************** Memory handlers ***************************************************************************/ uint8_t baraduke_state::baraduke_videoram_r(offs_t offset) { return m_videoram[offset]; } void baraduke_state::baraduke_videoram_w(offs_t offset, uint8_t data) { m_videoram[offset] = data; m_bg_tilemap[offset/0x1000]->mark_tile_dirty((offset&0xfff)/2); } uint8_t baraduke_state::baraduke_textram_r(offs_t offset) { return m_textram[offset]; } void baraduke_state::baraduke_textram_w(offs_t offset, uint8_t data) { m_textram[offset] = data; m_tx_tilemap->mark_tile_dirty(offset & 0x3ff); } void baraduke_state::scroll_w(int layer, int offset, int data) { switch (offset) { case 0: /* high scroll x */ m_xscroll[layer] = (m_xscroll[layer] & 0xff) | (data << 8); break; case 1: /* low scroll x */ m_xscroll[layer] = (m_xscroll[layer] & 0xff00) | data; break; case 2: /* scroll y */ m_yscroll[layer] = data; break; } } void baraduke_state::baraduke_scroll0_w(offs_t offset, uint8_t data) { scroll_w(0, offset, data); } void baraduke_state::baraduke_scroll1_w(offs_t offset, uint8_t data) { scroll_w(1, offset, data); } uint8_t baraduke_state::baraduke_spriteram_r(offs_t offset) { return m_spriteram[offset]; } void baraduke_state::baraduke_spriteram_w(offs_t offset, uint8_t data) { m_spriteram[offset] = data; /* a write to this offset tells the sprite chip to buffer the sprite list */ if (offset == 0x1ff2) m_copy_sprites = 1; } /*************************************************************************** Display Refresh ***************************************************************************/ void baraduke_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int sprite_priority) { uint8_t *spriteram = m_spriteram + 0x1800; const uint8_t *source = &spriteram[0x0000]; const uint8_t *finish = &spriteram[0x0800-16]; /* the last is NOT a sprite */ int sprite_xoffs = spriteram[0x07f5] - 256 * (spriteram[0x07f4] & 1); int sprite_yoffs = spriteram[0x07f7]; while( source> 5; int flipy = (attr2 & 0x01); int sizex = (attr1 & 0x80) >> 7; int sizey = (attr2 & 0x04) >> 2; int sprite = (source[11] & 0xff)*4; int x,y; if ((attr1 & 0x10) && !sizex) sprite += 1; if ((attr2 & 0x10) && !sizey) sprite += 2; color = color >> 1; sx += sprite_xoffs; sy -= sprite_yoffs; sy -= 16 * sizey; if (flip_screen()) { sx = 496+3 - 16 * sizex - sx; sy = 240 - 16 * sizey - sy; flipx ^= 1; flipy ^= 1; } for (y = 0;y <= sizey;y++) { for (x = 0;x <= sizex;x++) { m_gfxdecode->gfx(3)->transpen(bitmap,cliprect, sprite + gfx_offs[y ^ (sizey * flipy)][x ^ (sizex * flipx)], color, flipx,flipy, -71 + ((sx + 16*x) & 0x1ff), 1 + ((sy + 16*y) & 0xff),0xf); } } } source+=16; } } void baraduke_state::set_scroll(int layer) { int scrollx = m_xscroll[layer]; int scrolly = m_yscroll[layer]; if (flip_screen()) { scrollx = -scrollx; scrolly = -scrolly; } m_bg_tilemap[layer]->set_scrollx(0, scrollx); m_bg_tilemap[layer]->set_scrolly(0, scrolly); } uint32_t baraduke_state::screen_update_baraduke(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { uint8_t *spriteram = m_spriteram + 0x1800; int back; /* flip screen is embedded in the sprite control registers */ flip_screen_set(spriteram[0x07f6] & 0x01); set_scroll(0); set_scroll(1); if (((m_xscroll[0] & 0x0e00) >> 9) == 6) back = 1; else back = 0; m_bg_tilemap[back]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE,0); draw_sprites(bitmap,cliprect,0); m_bg_tilemap[back ^ 1]->draw(screen, bitmap, cliprect, 0,0); draw_sprites(bitmap,cliprect,1); m_tx_tilemap->draw(screen, bitmap, cliprect, 0,0); return 0; } WRITE_LINE_MEMBER(baraduke_state::screen_vblank_baraduke) { // rising edge if (state) { if (m_copy_sprites) { uint8_t *spriteram = m_spriteram + 0x1800; int i,j; for (i = 0;i < 0x800;i += 16) { for (j = 10;j < 16;j++) spriteram[i+j] = spriteram[i+j - 6]; } m_copy_sprites = 0; } m_maincpu->set_input_line(0, ASSERT_LINE); m_mcu->set_input_line(0, HOLD_LINE); } }