diff options
Diffstat (limited to 'src/devices/video/imagetek_i4100.cpp')
-rw-r--r-- | src/devices/video/imagetek_i4100.cpp | 115 |
1 files changed, 75 insertions, 40 deletions
diff --git a/src/devices/video/imagetek_i4100.cpp b/src/devices/video/imagetek_i4100.cpp index 69dc3dcd775..1b12799a066 100644 --- a/src/devices/video/imagetek_i4100.cpp +++ b/src/devices/video/imagetek_i4100.cpp @@ -1,6 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Luca Elia, David Haywood, Angelo Salese -/*************************************************************************** +/************************************************************************************************** Imagetek I4100 / I4220 / I4300 device files @@ -18,15 +18,18 @@ but the right palette is not at 00-ff. Related to the unknown table in the RAM mapped just before the palette? Update: the colors should have a common bank of 0xb (so 0x8bxx), it's unknown why the values - diverges, the blitter is responsible of the upload fwiw; - - Some gfx problems in ladykill, 3kokushi, puzzli, gakusai, seem related to how we handle + diverges, the blitter is responsible of the upload; + - gunmast title screen scroll right to left is jerky, again blitter + (uploads a sequence of destination values where bit 7 is first off then on + 1900 -> 1980 -> 1800 -> 1880 -> ... -> 000 -> 080) + - Some gfx problems in ladykill, 3kokushi, puzzli, gakusai seem related to how we handle windows, wrapping, read-modify-write areas; - puzzli: emulate hblank irq and fix video routines here (water effect not emulated, confirmed on PCB ref). Are the screen_ctrl_w "led" bits actually buffer latches for the layers? They get written in the middle of the screen, may also be v2 specific. - Unemulated/Unverified scrolling in flip screen. -============================================================================ +=================================================================================================== driver by Luca Elia (l.elia@tin.it) @@ -64,18 +67,27 @@ and height) -***************************************************************************/ +**************************************************************************************************/ #include "emu.h" #include "imagetek_i4100.h" #include <algorithm> -#define LOG_INT (1 << 1U) -//#define VERBOSE (LOG_INT) +#define LOG_WARN (1U << 1) +#define LOG_INT (1U << 2) +#define LOG_BLIT (1U << 3) +#define LOG_BLITOP (1U << 4) + +#define VERBOSE (LOG_GENERAL | LOG_WARN) +//#define LOG_OUTPUT_FUNC osd_printf_info + #include "logmacro.h" -#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__) +#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__) +#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__) +#define LOGBLIT(...) LOGMASKED(LOG_BLIT, __VA_ARGS__) +#define LOGBLITOP(...) LOGMASKED(LOG_BLITOP, __VA_ARGS__) //************************************************************************** // GLOBAL VARIABLES @@ -291,6 +303,9 @@ imagetek_i4100_device::imagetek_i4100_device(const machine_config &mconfig, devi , m_tilemap_flip_scrolldx{0, 0, 0} , m_tilemap_flip_scrolldy{0, 0, 0} , m_spriteram_buffered(false) + , m_ext_ctrl_0_cb(*this) + , m_ext_ctrl_1_cb(*this) + , m_ext_ctrl_2_cb(*this) { } @@ -380,8 +395,7 @@ void imagetek_i4100_device::device_start() m_gfxrom_size = m_gfxrom.bytes(); - m_irq_cb.resolve_safe(); - m_blit_done_timer = timer_alloc(TIMER_BLIT_END); + m_blit_done_timer = timer_alloc(FUNC(imagetek_i4100_device::blit_done), this); m_spritelist = std::make_unique<sprite_t []>(0x1000 / 8); m_sprite_end = m_spritelist.get(); @@ -459,7 +473,11 @@ void imagetek_i4100_device::irq_cause_w(u8 data) return; LOGINT("%s: Interrupts acknowledged (%02X)\n", machine().describe_context(), data); - m_requested_int &= ~data; + // NB: at least i4100 device doesn't have control over bits 5-6-7 + // it's cleared on top of irq services in karatour & ladykill with a 0xffea + // bit 5 seems more like an external irq service that is acknowledged separately, + // and is necessary for those + 3kokushi for updating scroll registers. + m_requested_int &= ~(data & 0x1f); update_irq_state(); } @@ -522,15 +540,10 @@ void imagetek_i4300_device::update_irq_state() m_irq_cb(level); } -void imagetek_i4100_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(imagetek_i4100_device::blit_done) { - switch (id) - { - case TIMER_BLIT_END: - if (m_blit_irq_level != -1) - set_irq(m_blit_irq_level); - break; - } + if (m_blit_irq_level != -1) + set_irq(m_blit_irq_level); } //************************************************************************** @@ -628,7 +641,13 @@ void imagetek_i4100_device::layer_priority_w(offs_t offset, uint16_t data, uint1 m_layer_priority[1] = (data >> 2) & 3; m_layer_priority[0] = (data >> 0) & 3; if ((data >> 6) != 0) - logerror("%s warning: layer_priority_w write with %04x %04x\n",this->tag(),data,mem_mask); + { + LOGWARN("%s warning: layer_priority_w write with %04x %04x\n" + , this->tag() + , data + , mem_mask + ); + } } /************************************************************* @@ -648,7 +667,7 @@ void imagetek_i4100_device::background_color_w(offs_t offset, uint16_t data, uin m_background_color &= 0x0fff; if (data & 0xf000) - logerror("%s warning: background_color_w write with %04x %04x\n",this->tag(),data,mem_mask); + LOGWARN("%s warning: background_color_w write with %04x %04x\n", this->tag(), data, mem_mask); } /*************************************************************************** @@ -670,32 +689,41 @@ void imagetek_i4100_device::window_w(offs_t offset, uint16_t data, uint16_t mem_ uint16_t imagetek_i4100_device::scroll_r(offs_t offset) { return m_scroll[offset]; } void imagetek_i4100_device::scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask) { COMBINE_DATA(&m_scroll[offset]); } -/**************************************************** +/* * * Screen Control Register: * - * f--- ---- ---- ---- ? + * f--- ---- ---- ---- ? karatour during POST (CRTC i/f sync?) * -edc b--- ---- ---- - * ---- -a98 ---- ---- ? Leds (see gakusai attract) + * ---- -a98 ---- ---- external control pins + * \- gakusai attract, unknown purpose + * (bit 2 enabled during title photo flashes, + * bit 1 always?, + * bit 0 periodically during gal sequences); + * \- (bit 0) karatour/ladykill/3kokushi external irq level 5 enable, (bit 1-2) unknown; + * \- puzzli [hblank] timer stop/start? 0 during transitions, 7 otherwise + * (including individual printouts of ROM statuses during POST); + * \- mouja (1 during POST, 7 otherwise) * ---- ---- 765- ---- 16x16 Tiles (Layer 2-1-0) * ---- ---- ---4 32-- * ---- ---- ---- --1- Blank Screen * ---- ---- ---- ---0 Flip Screen * - ****************************************************/ + */ void imagetek_i4100_device::screen_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask) { - m_layer_tile_select[2] = BIT(data,7); - m_layer_tile_select[1] = BIT(data,6); - m_layer_tile_select[0] = BIT(data,5); + m_ext_ctrl_2_cb(BIT(data, 10)); + m_ext_ctrl_1_cb(BIT(data, 9)); + m_ext_ctrl_0_cb(BIT(data, 8)); + + for (int i = 0; i < 3; i++) + m_layer_tile_select[i] = BIT(data, 5 + i); - // TODO: some of these must be externalized m_screen_blank = BIT(data,1); m_screen_flip = BIT(data,0); - if (data & 0xff1c) - logerror("%s warning: screen_ctrl_w write with %04x %04x\n",this->tag(),data,mem_mask); - + if (data & 0xf81c) + LOGWARN("%s warning: screen_ctrl_w write with %04x %04x\n", this->tag(), data, mem_mask); } @@ -744,7 +772,7 @@ void imagetek_i4100_device::crtc_unlock_w(offs_t offset, uint16_t data, uint16_t { m_crtc_unlock = BIT(data,0); if (data & ~1) - logerror("%s warning: unlock register write with %04x %04x\n",this->tag(),data,mem_mask); + LOGWARN("%s warning: unlock register write with %04x %04x\n",this->tag(),data,mem_mask); } /*************************************************************************** @@ -865,7 +893,7 @@ void imagetek_i4100_device::blitter_w(offs_t offset, uint16_t data, uint16_t mem int const shift = (dst_offs & 0x80) ? 0 : 8; u16 const mask = (dst_offs & 0x80) ? 0x00ff : 0xff00; -// logerror("%s Blitter regs %08X, %08X, %08X\n", machine().describe_context(), tmap, src_offs, dst_offs); + LOGBLIT("Blitter start %08X, %08X, %08X\n", tmap, src_offs, dst_offs); dst_offs >>= 7 + 1; switch (tmap) @@ -875,7 +903,7 @@ void imagetek_i4100_device::blitter_w(offs_t offset, uint16_t data, uint16_t mem case 3: break; default: - logerror("%s Blitter unknown destination: %08X\n", machine().describe_context(), tmap); + LOGWARN("%s Blitter unknown destination: %08X\n", machine().describe_context(), tmap); return; } @@ -885,9 +913,10 @@ void imagetek_i4100_device::blitter_w(offs_t offset, uint16_t data, uint16_t mem src_offs %= m_gfxrom_size; b1 = m_gfxrom[src_offs]; -// logerror("%s Blitter opcode %02X at %06X\n", machine().describe_context(), b1, src_offs); - src_offs++; + LOGBLITOP("%s Blitter opcode %02X at %06X\n", machine().describe_context(), b1, src_offs); + + src_offs++; count = ((~b1) & 0x3f) + 1; switch ((b1 & 0xc0) >> 6) @@ -900,11 +929,12 @@ void imagetek_i4100_device::blitter_w(offs_t offset, uint16_t data, uint16_t mem another blit. */ if (b1 == 0) { + LOGBLITOP("END\n"); m_blit_done_timer->adjust(attotime::from_usec(500)); return; } - /* Copy */ + LOGBLITOP("COPY\n"); while (count--) { src_offs %= m_gfxrom_size; @@ -919,6 +949,7 @@ void imagetek_i4100_device::blitter_w(offs_t offset, uint16_t data, uint16_t mem case 1: /* Fill with an increasing value */ + LOGBLITOP("FILL INC\n"); src_offs %= m_gfxrom_size; b2 = m_gfxrom[src_offs]; src_offs++; @@ -934,6 +965,7 @@ void imagetek_i4100_device::blitter_w(offs_t offset, uint16_t data, uint16_t mem case 2: /* Fill with a fixed value */ + LOGBLITOP("FILL FIX\n"); src_offs %= m_gfxrom_size; b2 = m_gfxrom[src_offs] << shift; src_offs++; @@ -950,18 +982,21 @@ void imagetek_i4100_device::blitter_w(offs_t offset, uint16_t data, uint16_t mem /* Skip to the next line ?? */ if (b1 == 0xc0) { + LOGBLITOP("SKIP LINE\n"); dst_offs += 0x100; dst_offs &= ~(0x100 - 1); dst_offs |= (0x100 - 1) & (m_blitter_regs[0x0a / 2] >> (7 + 1)); } else { + LOGBLITOP("SKIP %d\n", count); dst_offs += count; } break; + // shouldn't happen default: - //logerror("%s Blitter unknown opcode %02X at %06X\n",machine().describe_context(),b1,src_offs-1); + //("%s Blitter unknown opcode %02X at %06X\n",machine().describe_context(),b1,src_offs-1); return; } @@ -1422,7 +1457,7 @@ u32 imagetek_i4100_device::screen_update(screen_device &screen, bitmap_rgb32 &bi return 0; } -WRITE_LINE_MEMBER(imagetek_i4100_device::screen_eof) +void imagetek_i4100_device::screen_eof(int state) { if (state) { |