summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/imagetek_i4100.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/imagetek_i4100.cpp')
-rw-r--r--src/devices/video/imagetek_i4100.cpp115
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)
{