diff options
Diffstat (limited to 'src/mame/video/itech8.cpp')
-rw-r--r-- | src/mame/video/itech8.cpp | 728 |
1 files changed, 0 insertions, 728 deletions
diff --git a/src/mame/video/itech8.cpp b/src/mame/video/itech8.cpp deleted file mode 100644 index 13493d10a24..00000000000 --- a/src/mame/video/itech8.cpp +++ /dev/null @@ -1,728 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - Incredible Technologies/Strata system - (8-bit blitter variant) - -**************************************************************************** - - The games run in one of two modes, either 4bpp mode with a latched - palette nibble, or straight 8bpp. - - arligntn: 4bpp mode, dp = 00/80, draw to 0xxxx/2xxxx - hstennis: 4bpp mode, dp = 00/80, draw to 0xxxx/2xxxx - neckneck: 4bpp mode, dp = 00/80, draw to 0xxxx/2xxxx - ninclown: 4bpp mode, dp = 00/80, draw to 0xxxx/2xxxx - peggle: 4bpp mode, dp = 00/80, draw to 0xxxx/2xxxx - rimrockn: 4bpp mode, dp = 00/80, draw to 0xxxx/2xxxx - - dynobop: 8bpp mode, dp = 00/FF, draw to 2xxxx/0xxxx - pokrdice: 8bpp mode, dp = 00/FF, draw to 2xxxx/0xxxx - slikshot: 8bpp mode, dp = 00/FF, draw to 2xxxx/0xxxx - - gtg: 8bpp mode, dp = C0 - stratab: 8bpp mode, dp = C0, always draws to 2xxxx - wfortune: 8bpp mode, dp = C0, always draws to 2xxxx - -**************************************************************************** - - 8-bit blitter data format: - - +00 hhhhhhhh MSB of 16-bit source address - +01 llllllll LSB of 16-bit source address - +02 ---t---- Transparent: when set, don't write 0 nibbles - ----r--- RLE: when set, source data is RLE compressed - -----y-- Y-flip: when set, draw up instead of down - ------x- X-flip: when set, draw right instead of left - -------s Shift: when set, offset drawing by one nibble - +03 s------- Blit status: when set, blit is in progress - +03 -------- Blit start: a write here starts the blit - +04 wwwwwwww Width of blit, in bytes - +05 hhhhhhhh Height of blit, in rows - +06 mmmmmmmm Blit mask, applied to each source pixel - +07 ?------- Set by ninclown at startup - -4------ Set by games that use 4bpp latched output - --?----- Set by gtg, gtg2, peggle, pokrdice, stratab - ---l---- Video status LED - ----?--- Set by gtg2, ninclown, peggle, stratab - ------?- Set by arligntn, neckneck, gtg, gtg2, ninclown, peggle, pokrdice, rimrockn, stratab - +08 xxxxxxxx Number of pixels to skip before drawing each row - +09 yyyyyyyy Number of rows to draw (the first height - y rows are skipped) - +0A eeeeeeee Number of pixels to skip at the end of each row - +0B ssssssss Number of rows to skip at the end of drawing - -**************************************************************************** - - Blitter timing - - Times are in 2MHz NOPs (@ 2 cycles/NOP) after issuing a blit start - command: - - 1x1 = 1-2 1x 1 = 1-2 - 2x1 = 2 1x 2 = 2 - 3x1 = 2 1x 3 = 2 - 4x1 = 2 1x 4 = 2 - 5x1 = 3 1x 5 = 3 - 6x1 = 3 1x 6 = 3 - 7x1 = 3-4 1x 7 = 3 - 8x1 = 4 1x 8 = 4 - 9x1 = 4 1x 9 = 4 - 10x1 = 4 1x 10 = 4-5 - 11x1 = 5 1x 11 = 5 - 12x1 = 5 1x 12 = 5 - 13x1 = 5-6 1x 13 = 5 - 14x1 = 6 1x 14 = 6 - 15x1 = 6 1x 15 = 6 - 16x1 = 6-7 1x 16 = 6 - 24x1 = 9-10 1x 24 = 9 - 32x1 = 12 1x 32 = 12 - 48x1 = 17 1x 48 = 17 - 64x1 = 23 1x 64 = 22 - 96x1 = 33 1x 96 = 33 - 128x1 = 44 1x128 = 44 - 192x1 = 65 1x192 = 65 - 240x1 = 81-82 1x240 = 81-82 - - Times are not affected by transparency or RLE settings at all. - Times are slightly variable in nature in my tests (within 1 NOP). - -***************************************************************************/ - -#include "emu.h" -#include "cpu/m6809/m6809.h" -#include "includes/itech8.h" - - -/************************************* - * - * Debugging - * - *************************************/ - -#define FULL_LOGGING 0 -#define BLIT_LOGGING 0 - - - -/************************************* - * - * Blitter constants - * - *************************************/ - -#define BLITTER_ADDRHI m_blitter_data[0] -#define BLITTER_ADDRLO m_blitter_data[1] -#define BLITTER_FLAGS m_blitter_data[2] -#define BLITTER_STATUS m_blitter_data[3] -#define BLITTER_WIDTH m_blitter_data[4] -#define BLITTER_HEIGHT m_blitter_data[5] -#define BLITTER_MASK m_blitter_data[6] -#define BLITTER_OUTPUT m_blitter_data[7] -#define BLITTER_XSTART m_blitter_data[8] -#define BLITTER_YCOUNT m_blitter_data[9] -#define BLITTER_XSTOP m_blitter_data[10] -#define BLITTER_YSKIP m_blitter_data[11] - -#define BLITFLAG_SHIFT 0x01 -#define BLITFLAG_XFLIP 0x02 -#define BLITFLAG_YFLIP 0x04 -#define BLITFLAG_RLE 0x08 -#define BLITFLAG_TRANSPARENT 0x10 - - - -/************************************* - * - * Video start - * - *************************************/ - -void itech8_state::video_start() -{ - /* get the TMS34061 display state */ - m_tms34061->get_display_state(); - - /* reset statics */ - m_page_select = 0xc0; - m_blit_in_progress = 0; - - save_item(NAME(m_blitter_data)); - save_item(NAME(m_blit_in_progress)); - save_item(NAME(m_page_select)); - save_item(NAME(m_fetch_offset)); - save_item(NAME(m_fetch_rle_count)); - save_item(NAME(m_fetch_rle_value)); - save_item(NAME(m_fetch_rle_literal)); -} - - - -/************************************* - * - * Palette I/O - * - *************************************/ - -void itech8_state::palette_w(offs_t offset, uint8_t data) -{ - m_tlc34076->write(offset/2, data); -} - - - -/************************************* - * - * Paging control - * - *************************************/ - -void itech8_state::page_w(u8 data) -{ - m_screen->update_partial(m_screen->vpos()); - logerror("%04x:display_page = %02X (%d)\n", m_maincpu->pc(), data, m_screen->vpos()); - m_page_select = data; -} - - - - -/************************************* - * - * Blitter data fetchers - * - *************************************/ - -inline uint8_t itech8_state::fetch_next_raw() -{ - return m_grom[m_fetch_offset++ % m_grom.length()]; -} - - -inline void itech8_state::consume_raw(int count) -{ - m_fetch_offset += count; -} - - -inline uint8_t itech8_state::fetch_next_rle() -{ - if (m_fetch_rle_count == 0) - { - m_fetch_rle_count = m_grom[m_fetch_offset++ % m_grom.length()]; - m_fetch_rle_literal = m_fetch_rle_count & 0x80; - m_fetch_rle_count &= 0x7f; - - if (!m_fetch_rle_literal) - m_fetch_rle_value = m_grom[m_fetch_offset++ % m_grom.length()]; - } - - m_fetch_rle_count--; - if (m_fetch_rle_literal) - m_fetch_rle_value = m_grom[m_fetch_offset++ % m_grom.length()]; - - return m_fetch_rle_value; -} - - -inline void itech8_state::consume_rle(int count) -{ - while (count) - { - int num_to_consume; - - if (m_fetch_rle_count == 0) - { - m_fetch_rle_count = m_grom[m_fetch_offset++ % m_grom.length()]; - m_fetch_rle_literal = m_fetch_rle_count & 0x80; - m_fetch_rle_count &= 0x7f; - - if (!m_fetch_rle_literal) - m_fetch_rle_value = m_grom[m_fetch_offset++ % m_grom.length()]; - } - - num_to_consume = (count < m_fetch_rle_count) ? count : m_fetch_rle_count; - count -= num_to_consume; - - m_fetch_rle_count -= num_to_consume; - if (m_fetch_rle_literal) - m_fetch_offset += num_to_consume; - } -} - - - -/************************************* - * - * Core blitter - * - *************************************/ - -void itech8_state::perform_blit() -{ - offs_t addr = m_tms34061->xyaddress() | ((m_tms34061->xyoffset() & 0x300) << 8); - uint8_t shift = (BLITTER_FLAGS & BLITFLAG_SHIFT) ? 4 : 0; - int transparent = (BLITTER_FLAGS & BLITFLAG_TRANSPARENT); - int ydir = (BLITTER_FLAGS & BLITFLAG_YFLIP) ? -1 : 1; - int xdir = (BLITTER_FLAGS & BLITFLAG_XFLIP) ? -1 : 1; - int xflip = (BLITTER_FLAGS & BLITFLAG_XFLIP); - int rle = (BLITTER_FLAGS & BLITFLAG_RLE); - int color = m_tms34061->latch_r(); - int width = BLITTER_WIDTH; - int height = BLITTER_HEIGHT; - uint8_t transmaskhi, transmasklo; - uint8_t mask = BLITTER_MASK; - uint8_t skip[3]; - int x, y; - - /* debugging */ - if (FULL_LOGGING) - logerror("Blit: scan=%d src=%06x @ (%05x) for %dx%d ... flags=%02x\n", - m_screen->vpos(), - (m_grom_bank << 16) | (BLITTER_ADDRHI << 8) | BLITTER_ADDRLO, - m_tms34061->xyaddress() | ((m_tms34061->xyoffset() & 0x300) << 8), - BLITTER_WIDTH, BLITTER_HEIGHT, BLITTER_FLAGS); - - /* initialize the fetcher */ - m_fetch_offset = (m_grom_bank << 16) | (BLITTER_ADDRHI << 8) | BLITTER_ADDRLO; - m_fetch_rle_count = 0; - - /* RLE starts with a couple of extra 0's */ - if (rle) - m_fetch_offset += 2; - - /* select 4-bit versus 8-bit transparency */ - if (BLITTER_OUTPUT & 0x40) - transmaskhi = 0xf0, transmasklo = 0x0f; - else - transmaskhi = transmasklo = 0xff; - - /* compute horiz skip counts */ - skip[0] = BLITTER_XSTART; - skip[1] = (width <= BLITTER_XSTOP) ? 0 : width - 1 - BLITTER_XSTOP; - if (xdir == -1) { int temp = skip[0]; skip[0] = skip[1]; skip[1] = temp; } - width -= skip[0] + skip[1]; - - /* compute vertical skip counts */ - if (ydir == 1) - { - skip[2] = (height <= BLITTER_YCOUNT) ? 0 : height - BLITTER_YCOUNT; - if (BLITTER_YSKIP > 1) height -= BLITTER_YSKIP - 1; - } - else - { - skip[2] = (height <= BLITTER_YSKIP) ? 0 : height - BLITTER_YSKIP; - if (BLITTER_YCOUNT > 1) height -= BLITTER_YCOUNT - 1; - } - - /* skip top */ - for (y = 0; y < skip[2]; y++) - { - /* skip src and dest */ - addr += xdir * (width + skip[0] + skip[1]); - if (rle) - consume_rle(width + skip[0] + skip[1]); - else - consume_raw(width + skip[0] + skip[1]); - - /* back up one and reverse directions */ - addr -= xdir; - addr += ydir * 256; - addr &= VRAM_MASK; - xdir = -xdir; - } - - /* loop over height */ - for (y = skip[2]; y < height; y++) - { - /* skip left */ - addr += xdir * skip[y & 1]; - if (rle) - consume_rle(skip[y & 1]); - else - consume_raw(skip[y & 1]); - - /* loop over width */ - for (x = 0; x < width; x++) - { - uint8_t pix = rle ? fetch_next_rle() : fetch_next_raw(); - - /* swap pixels for X flip in 4bpp mode */ - if (xflip && transmaskhi != 0xff) - pix = (pix >> 4) | (pix << 4); - pix &= mask; - - /* draw upper pixel */ - if (!transparent || (pix & transmaskhi)) - { - m_tms34061->m_display.vram[addr] = (m_tms34061->m_display.vram[addr] & (0x0f << shift)) | ((pix & 0xf0) >> shift); - m_tms34061->m_display.latchram[addr] = (m_tms34061->m_display.latchram[addr] & (0x0f << shift)) | ((color & 0xf0) >> shift); - } - - /* draw lower pixel */ - if (!transparent || (pix & transmasklo)) - { - offs_t addr1 = addr + shift/4; - m_tms34061->m_display.vram[addr1] = (m_tms34061->m_display.vram[addr1] & (0xf0 >> shift)) | ((pix & 0x0f) << shift); - m_tms34061->m_display.latchram[addr1] = (m_tms34061->m_display.latchram[addr1] & (0xf0 >> shift)) | ((color & 0x0f) << shift); - } - - /* advance to the next byte */ - addr += xdir; - addr &= VRAM_MASK; - } - - /* skip right */ - addr += xdir * skip[~y & 1]; - if (rle) - consume_rle(skip[~y & 1]); - else - consume_raw(skip[~y & 1]); - - /* back up one and reverse directions */ - addr -= xdir; - addr += ydir * 256; - addr &= VRAM_MASK; - xdir = -xdir; - } -} - - - -/************************************* - * - * Blitter finished callback - * - *************************************/ - -TIMER_CALLBACK_MEMBER(itech8_state::blitter_done) -{ - /* turn off blitting and generate an interrupt */ - m_blit_in_progress = 0; - update_interrupts(-1, -1, 1); - - if (FULL_LOGGING) logerror("------------ BLIT DONE (%d) --------------\n", m_screen->vpos()); -} - - - -/************************************* - * - * Blitter I/O - * - *************************************/ - -uint8_t itech8_state::blitter_r(offs_t offset) -{ - int result = m_blitter_data[offset / 2]; - - /* debugging */ - if (FULL_LOGGING) logerror("%s:blitter_r(%02x)\n", machine().describe_context(), offset / 2); - - /* low bit seems to be ignored */ - offset /= 2; - - /* a read from offset 3 clears the interrupt and returns the status */ - if (offset == 3) - { - update_interrupts(-1, -1, 0); - if (m_blit_in_progress) - result |= 0x80; - else - result &= 0x7f; - } - - /* a read from offsets 12-15 return input port values */ - if (offset >= 12 && offset <= 15) - result = m_an[offset - 12].read_safe(0); - - return result; -} - - -void itech8_state::blitter_w(offs_t offset, uint8_t data) -{ - /* low bit seems to be ignored */ - offset /= 2; - m_blitter_data[offset] = data; - - /* a write to offset 3 starts things going */ - if (offset == 3) - { - /* log to the blitter file */ - if (BLIT_LOGGING) - { - logerror("Blit: XY=%1X%04X SRC=%02X%02X%02X SIZE=%3dx%3d FLAGS=%02x", - (m_tms34061->xyoffset() >> 8) & 0x0f, m_tms34061->xyaddress(), - m_grom_bank, m_blitter_data[0], m_blitter_data[1], - m_blitter_data[4], m_blitter_data[5], - m_blitter_data[2]); - logerror(" %02X %02X %02X [%02X] %02X %02X %02X [%02X]-%02X %02X %02X %02X [%02X %02X %02X %02X]\n", - m_blitter_data[0], m_blitter_data[1], - m_blitter_data[2], m_blitter_data[3], - m_blitter_data[4], m_blitter_data[5], - m_blitter_data[6], m_blitter_data[7], - m_blitter_data[8], m_blitter_data[9], - m_blitter_data[10], m_blitter_data[11], - m_blitter_data[12], m_blitter_data[13], - m_blitter_data[14], m_blitter_data[15]); - } - - /* perform the blit */ - perform_blit(); - m_blit_in_progress = 1; - - /* set a timer to go off when we're done */ - m_blitter_done_timer->adjust(attotime::from_hz(12000000/4) * (BLITTER_WIDTH * BLITTER_HEIGHT + 12)); - } - - /* debugging */ - if (FULL_LOGGING) logerror("%04x:blitter_w(%02x)=%02x\n", m_subcpu->pcbase(), offset, data); -} - - - -/************************************* - * - * TMS34061 I/O - * - *************************************/ - -void itech8_state::tms34061_w(offs_t offset, uint8_t data) -{ - int func = (offset >> 9) & 7; - int col = offset & 0xff; - - /* Column address (CA0-CA8) is hooked up the A0-A7, with A1 being inverted - during register access. CA8 is ignored */ - if (func == 0 || func == 2) - col ^= 2; - - /* Row address (RA0-RA8) is not dependent on the offset */ - m_tms34061->write(col, 0xff, func, data); -} - - -uint8_t itech8_state::tms34061_r(offs_t offset) -{ - int func = (offset >> 9) & 7; - int col = offset & 0xff; - - /* Column address (CA0-CA8) is hooked up the A0-A7, with A1 being inverted - during register access. CA8 is ignored */ - if (func == 0 || func == 2) - col ^= 2; - - /* Row address (RA0-RA8) is not dependent on the offset */ - return m_tms34061->read(col, 0xff, func); -} - - - -/************************************* - * - * Special Grudge Match handlers - * - *************************************/ - -void grmatch_state::palette_w(uint8_t data) -{ - /* set the palette control; examined in the scanline callback */ - m_palcontrol = data; -} - - -void grmatch_state::xscroll_w(uint8_t data) -{ - /* update the X scroll value */ - //m_screen->update_now(); - m_screen->update_partial(m_screen->vpos()); - m_xscroll = data; -} - - -void grmatch_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_PALETTE: - palette_update(); - break; - default: - itech8_state::device_timer(timer, id, param, ptr); - break; - } -} - -void grmatch_state::palette_update() -{ - /* if the high bit is set, we are supposed to latch the palette values */ - if (m_palcontrol & 0x80) - { - /* the TMS34070s latch at the start of the frame, based on the first few bytes */ - uint32_t page_offset = (m_tms34061->m_display.dispstart & 0x0ffff) | m_xscroll; - - /* iterate over both pages */ - for (int page = 0; page < 2; page++) - { - const uint8_t *base = &m_tms34061->m_display.vram[(page * 0x20000 + page_offset) & VRAM_MASK]; - for (int x = 0; x < 16; x++) - { - uint8_t data0 = base[x * 2 + 0]; - uint8_t data1 = base[x * 2 + 1]; - m_palette[page][x] = rgb_t(pal4bit(data0 >> 0), pal4bit(data1 >> 4), pal4bit(data1 >> 0)); - } - } - } - - m_palette_timer->adjust(m_screen->time_until_pos(m_screen->vpos()+1)); -} - - - -/************************************* - * - * Main refresh - * - *************************************/ - -uint32_t itech8_state::screen_update_2layer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - pen_t const *const pens = m_tlc34076->pens(); - - /* first get the current display state */ - m_tms34061->get_display_state(); - - /* if we're blanked, just fill with black */ - if (m_tms34061->blanked()) - { - bitmap.fill(rgb_t::black(), cliprect); - return 0; - } - - // there are two layers: - // top layer @ 0x00000 is only 4bpp, colors come from the first 16 palettes - // bottom layer @ 0x20000 is full 8bpp - uint32_t const page_offset = m_tms34061->m_display.dispstart & 0x0ffff; - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint8_t const *const base0 = &m_tms34061->m_display.vram[(0x00000 + page_offset + y * 256) & VRAM_MASK]; - uint8_t const *const base2 = &m_tms34061->m_display.vram[(0x20000 + page_offset + y * 256) & VRAM_MASK]; - uint32_t *const dest = &bitmap.pix(y); - - for (int x = cliprect.min_x; x <= cliprect.max_x; x++) - { - int const pix0 = base0[x] & 0x0f; - dest[x] = pens[pix0 ? pix0 : base2[x]]; - } - } - return 0; -} - - -uint32_t grmatch_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - /* first get the current display state */ - m_tms34061->get_display_state(); - - /* if we're blanked, just fill with black */ - if (m_tms34061->blanked()) - { - bitmap.fill(rgb_t::black(), cliprect); - return 0; - } - - // there are two layers: - // top layer @ 0x00000 is 4bpp, colors come from TMS34070, enabled via palette control - // bottom layer @ 0x20000 is 4bpp, colors come from TMS34070, enabled via palette control - // 4bpp pixels are packed 2 to a byte - // xscroll is set via a separate register - uint32_t const page_offset = (m_tms34061->m_display.dispstart & 0x0ffff) | m_xscroll; - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint8_t const *const base0 = &m_tms34061->m_display.vram[0x00000 + ((page_offset + y * 256) & 0xffff)]; - uint8_t const *const base2 = &m_tms34061->m_display.vram[0x20000 + ((page_offset + y * 256) & 0xffff)]; - uint32_t *const dest = &bitmap.pix(y); - - for (int x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2) - { - uint8_t const pix0 = base0[x / 2]; - uint8_t const pix2 = base2[x / 2]; - - if ((pix0 & 0xf0) != 0) - dest[x] = m_palette[0][pix0 >> 4]; - else - dest[x] = m_palette[1][pix2 >> 4]; - - if ((pix0 & 0x0f) != 0) - dest[x + 1] = m_palette[0][pix0 & 0x0f]; - else - dest[x + 1] = m_palette[1][pix2 & 0x0f]; - } - } - return 0; -} - - -uint32_t itech8_state::screen_update_2page(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - pen_t const *const pens = m_tlc34076->pens(); - - /* first get the current display state */ - m_tms34061->get_display_state(); - - /* if we're blanked, just fill with black */ - if (m_tms34061->blanked()) - { - bitmap.fill(rgb_t::black(), cliprect); - return 0; - } - - // there are two pages, each of which is a full 8bpp - // page index is selected by the top bit of the page_select register - uint32_t const page_offset = ((m_page_select & 0x80) << 10) | (m_tms34061->m_display.dispstart & 0x0ffff); - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint8_t const *const base = &m_tms34061->m_display.vram[(page_offset + y * 256) & VRAM_MASK]; - uint32_t *const dest = &bitmap.pix(y); - - for (int x = cliprect.min_x; x <= cliprect.max_x; x++) - dest[x] = pens[base[x]]; - } - return 0; -} - - -uint32_t itech8_state::screen_update_2page_large(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - pen_t const *const pens = m_tlc34076->pens(); - - /* first get the current display state */ - m_tms34061->get_display_state(); - - /* if we're blanked, just fill with black */ - if (m_tms34061->blanked()) - { - bitmap.fill(rgb_t::black(), cliprect); - return 0; - } - - // there are two pages, each of which is a full 8bpp - // the low 4 bits come from the bitmap directly - // the upper 4 bits were latched on each write into a separate bitmap - // page index is selected by the top bit of the page_select register - uint32_t const page_offset = ((~m_page_select & 0x80) << 10) | (m_tms34061->m_display.dispstart & 0x0ffff); - for (int y = cliprect.min_y; y <= cliprect.max_y; y++) - { - uint8_t const *const base = &m_tms34061->m_display.vram[(page_offset + y * 256) & VRAM_MASK]; - uint8_t const *const latch = &m_tms34061->m_display.latchram[(page_offset + y * 256) & VRAM_MASK]; - uint32_t *const dest = &bitmap.pix(y); - - for (int x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2) - { - dest[x + 0] = pens[(latch[x/2] & 0xf0) | (base[x/2] >> 4)]; - dest[x + 1] = pens[((latch[x/2] << 4) & 0xf0) | (base[x/2] & 0x0f)]; - } - } - return 0; -} |