itech/itech8.cpp: Cleaned up code. (#12235)

* Removed TLC34076 for games that lack it.
* Use palette devices for palettes.
* Use input merger for VIA/YM3812 FIRQ.
* Reduced tag lookups, suppress side effects for debugger accesses, use more const.
* Changed single-line comments to C++ line comments.
This commit is contained in:
cam900 2024-04-14 00:57:13 +09:00 committed by GitHub
parent ad7fdda12b
commit 4bc523f8ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 492 additions and 486 deletions

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
#include "machine/nvram.h"
#include "video/tlc34076.h"
#include "video/tms34061.h"
#include "emupal.h"
#include "screen.h"
@ -67,7 +68,7 @@ protected:
required_device<nvram_device> m_nvram;
required_device<generic_latch_8_device> m_soundlatch;
required_device<tms34061_device> m_tms34061;
required_device<tlc34076_device> m_tlc34076;
optional_device<tlc34076_device> m_tlc34076;
required_device<screen_device> m_screen;
required_device<ticket_dispenser_device> m_ticket;
required_region_ptr<u8> m_grom;
@ -192,12 +193,12 @@ private:
u8 m_curx = 0;
s8 m_xbuffer[YBUFFER_COUNT]{};
s8 m_ybuffer[YBUFFER_COUNT]{};
int m_ybuffer_next = 0;
int m_curxpos = 0;
int m_last_ytotal = 0;
u8 m_ybuffer_next = 0;
s32 m_curxpos = 0;
s32 m_last_ytotal = 0;
u8 m_crosshair_vis = 0;
/*----------- defined in machine/itech8.cpp -----------*/
//----------- defined in itech/itech8_m.cpp -----------
u8 z80_port_r();
void z80_port_w(u8 data);
@ -207,14 +208,14 @@ private:
void z80_control_w(u8 data);
void inters_to_vels(u16 inter1, u16 inter2, u16 inter3, u8 beams,
u8 *xres, u8 *vxres, u8 *vyres);
u8 &xres, u8 &vxres, u8 &vyres);
void vels_to_inters(u8 x, u8 vx, u8 vy,
u16 *inter1, u16 *inter2, u16 *inter3, u8 *beams);
void inters_to_words(u16 inter1, u16 inter2, u16 inter3, u8 *beams,
u16 *word1, u16 *word2, u16 *word3);
u16 &inter1, u16 &inter2, u16 &inter3, u8 &beams);
void inters_to_words(u16 inter1, u16 inter2, u16 inter3, u8 &beams,
u16 &word1, u16 &word2, u16 &word3);
void words_to_sensors(u16 word1, u16 word2, u16 word3, u8 beams,
u16 *sens0, u16 *sens1, u16 *sens2, u16 *sens3);
u16 &sens0, u16 &sens1, u16 &sens2, u16 &sens3);
void compute_sensors();
TIMER_CALLBACK_MEMBER(delayed_z80_control_w);
@ -249,6 +250,7 @@ class grmatch_state : public itech8_state
public:
grmatch_state(const machine_config &mconfig, device_type type, const char *tag) :
itech8_state(mconfig, type, tag),
m_palette(*this, "palette_%u", 0U),
m_palette_timer(nullptr)
{
}
@ -259,6 +261,12 @@ protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_device_array<palette_device, 2> m_palette;
emu_timer *m_palette_timer = nullptr;
u8 m_palcontrol = 0U;
u8 m_xscroll = 0U;
void palette_w(u8 data);
void xscroll_w(u8 data);
@ -266,10 +274,5 @@ protected:
TIMER_CALLBACK_MEMBER(palette_update);
emu_timer *m_palette_timer = nullptr;
u8 m_palcontrol = 0U;
u8 m_xscroll = 0U;
rgb_t m_palette[2][16]{};
void grmatch_map(address_map &map);
};

View File

@ -97,27 +97,27 @@
#ifdef STANDALONE
static void sensors_to_words(u16 sens0, u16 sens1, u16 sens2, u16 sens3,
u16 *word1, u16 *word2, u16 *word3, u8 *beams)
u16 &word1, u16 &word2, u16 &word3, u8 &beams)
{
/* word 1 contains the difference between the larger of sensors 2 & 3 and the smaller */
*word1 = (sens3 > sens2) ? (sens3 - sens2) : (sens2 - sens3);
// word 1 contains the difference between the larger of sensors 2 & 3 and the smaller
word1 = (sens3 > sens2) ? (sens3 - sens2) : (sens2 - sens3);
/* word 2 contains the value of the smaller of sensors 2 & 3 */
*word2 = (sens3 > sens2) ? sens2 : sens3;
// word 2 contains the value of the smaller of sensors 2 & 3
word2 = (sens3 > sens2) ? sens2 : sens3;
/* word 3 contains the value of sensor 0 or 1, depending on which fired */
*word3 = sens0 ? sens0 : sens1;
// word 3 contains the value of sensor 0 or 1, depending on which fired
word3 = sens0 ? sens0 : sens1;
/* set the beams bits */
*beams = 0;
// set the beams bits
beams = 0;
/* if sensor 1 fired first, set bit 0 */
// if sensor 1 fired first, set bit 0
if (!sens0)
*beams |= 1;
beams |= 1;
/* if sensor 3 has the larger value, set bit 1 */
// if sensor 3 has the larger value, set bit 1
if (sens3 > sens2)
*beams |= 2;
beams |= 2;
}
#endif
@ -135,37 +135,37 @@ static void sensors_to_words(u16 sens0, u16 sens1, u16 sens2, u16 sens3,
#ifdef STANDALONE
static void words_to_inters(u16 word1, u16 word2, u16 word3, u8 beams,
u16 *inter1, u16 *inter2, u16 *inter3)
u16 &inter1, u16 &inter2, u16 &inter3)
{
/* word 2 is scaled up by 0x1.6553 */
u16 word2mod = ((uint64_t)word2 * 0x16553) >> 16;
// word 2 is scaled up by 0x1.6553
u16 word2mod = ((u64)word2 * 0x16553) >> 16;
/* intermediate values 1 and 2 are determined based on the beams bits */
// intermediate values 1 and 2 are determined based on the beams bits
switch (beams)
{
case 0:
*inter1 = word1 + word2mod;
*inter2 = word2mod + word3;
inter1 = word1 + word2mod;
inter2 = word2mod + word3;
break;
case 1:
*inter1 = word1 + word2mod + word3;
*inter2 = word2mod;
inter1 = word1 + word2mod + word3;
inter2 = word2mod;
break;
case 2:
*inter1 = word2mod;
*inter2 = word1 + word2mod + word3;
inter1 = word2mod;
inter2 = word1 + word2mod + word3;
break;
case 3:
*inter1 = word2mod + word3;
*inter2 = word1 + word2mod;
inter1 = word2mod + word3;
inter2 = word1 + word2mod;
break;
}
/* intermediate value 3 is always equal to the third word */
*inter3 = word3;
// intermediate value 3 is always equal to the third word
inter3 = word3;
}
#endif
@ -181,63 +181,60 @@ static void words_to_inters(u16 word1, u16 word2, u16 word3, u8 beams,
*************************************/
void slikshot_state::inters_to_vels(u16 inter1, u16 inter2, u16 inter3, u8 beams,
u8 *xres, u8 *vxres, u8 *vyres)
u8 &xres, u8 &vxres, u8 &vyres)
{
u32 _27d8, _27c2;
u32 vx, vy, _283a, _283e;
u8 vxsgn;
u16 xoffs = 0x0016;
u8 xscale = 0xe6;
u16 const xoffs = 0x0016;
u8 const xscale = 0xe6;
u16 x;
/* compute Vy */
vy = inter1 ? (0x31c28 / inter1) : 0;
// compute Vy
u32 vy = inter1 ? (0x31c28 / inter1) : 0;
/* compute Vx */
_283a = inter2 ? (0x30f2e / inter2) : 0;
_27d8 = ((uint64_t)vy * 0xfbd3) >> 16;
_27c2 = _283a - _27d8;
vxsgn = 0;
if ((int32_t)_27c2 < 0)
// compute Vx
u32 const _283a = inter2 ? (0x30f2e / inter2) : 0;
u32 _27d8 = ((u64)vy * 0xfbd3) >> 16;
u32 _27c2 = _283a - _27d8;
u8 vxsgn = 0;
if ((s32)_27c2 < 0)
{
vxsgn = 1;
_27c2 = _27d8 - _283a;
}
vx = ((uint64_t)_27c2 * 0x58f8c) >> 16;
u32 vx = ((u64)_27c2 * 0x58f8c) >> 16;
/* compute X */
_27d8 = ((uint64_t)(inter3 << 16) * _283a) >> 16;
_283e = ((uint64_t)_27d8 * 0x4a574b) >> 16;
// compute X
_27d8 = ((u64)(inter3 << 16) * _283a) >> 16;
u32 _283e = ((u64)_27d8 * 0x4a574b) >> 16;
/* adjust X based on the low bit of the beams */
// adjust X based on the low bit of the beams
if (beams & 1)
x = 0x7a + (_283e >> 16) - xoffs;
else
x = 0x7a - (_283e >> 16) - xoffs;
/* apply a constant X scale */
// apply a constant X scale
if (xscale)
x = ((xscale * (x & 0xff)) >> 8) & 0xff;
/* clamp if out of range */
// clamp if out of range
if ((vx & 0xffff) >= 0x80)
x = 0;
/* put the sign back in Vx */
// put the sign back in Vx
vx &= 0xff;
if (!vxsgn)
vx = -vx;
/* clamp VY */
// clamp VY
if ((vy & 0xffff) > 0x7f)
vy = 0x7f;
else
vy &= 0xff;
/* copy the results */
*xres = x;
*vxres = vx;
*vyres = vy;
// copy the results
xres = x;
vxres = vx;
vyres = vy;
}
@ -254,42 +251,39 @@ void slikshot_state::inters_to_vels(u16 inter1, u16 inter2, u16 inter3, u8 beams
*************************************/
void slikshot_state::vels_to_inters(u8 x, u8 vx, u8 vy,
u16 *inter1, u16 *inter2, u16 *inter3, u8 *beams)
u16 &inter1, u16 &inter2, u16 &inter3, u8 &beams)
{
u32 _27d8;
u16 xoffs = 0x0016;
u8 xscale = 0xe6;
u16 const xoffs = 0x0016;
u8 const xscale = 0xe6;
u8 x1, vx1, vy1;
u8 x2, vx2, vy2;
u8 diff1, diff2;
u16 inter2a;
/* inter1 comes from Vy */
*inter1 = vy ? 0x31c28 / vy : 0;
// inter1 comes from Vy
inter1 = vy ? 0x31c28 / vy : 0;
/* inter2 can be derived from Vx and Vy */
_27d8 = ((uint64_t)vy * 0xfbd3) >> 16;
*inter2 = 0x30f2e / (_27d8 + (((u32)abs((s8)vx) << 16) / 0x58f8c));
inter2a = 0x30f2e / (_27d8 - (((u32)abs((s8)vx) << 16) / 0x58f8c));
// inter2 can be derived from Vx and Vy
u32 const _27d8 = ((u64)vy * 0xfbd3) >> 16;
inter2 = 0x30f2e / (_27d8 + (((u32)abs((s8)vx) << 16) / 0x58f8c));
u16 inter2a = 0x30f2e / (_27d8 - (((u32)abs((s8)vx) << 16) / 0x58f8c));
/* compute it back both ways and pick the closer */
inters_to_vels(*inter1, *inter2, 0, 0, &x1, &vx1, &vy1);
inters_to_vels(*inter1, inter2a, 0, 0, &x2, &vx2, &vy2);
diff1 = (vx > vx1) ? (vx - vx1) : (vx1 - vx);
diff2 = (vx > vx2) ? (vx - vx2) : (vx2 - vx);
// compute it back both ways and pick the closer
inters_to_vels(inter1, inter2, 0, 0, x1, vx1, vy1);
inters_to_vels(inter1, inter2a, 0, 0, x2, vx2, vy2);
u8 const diff1 = (vx > vx1) ? (vx - vx1) : (vx1 - vx);
u8 const diff2 = (vx > vx2) ? (vx - vx2) : (vx2 - vx);
if (diff2 < diff1)
*inter2 = inter2a;
inter2 = inter2a;
/* inter3: (beams & 1 == 1), inter3a: (beams & 1) == 0 */
// inter3: (beams & 1 == 1), inter3a: (beams & 1) == 0
if (((x << 8) / xscale) + xoffs >= 0x7a)
{
*beams = 1;
*inter3 = (((((((uint64_t)(((x << 8) / xscale) + xoffs - 0x7a)) << 16) << 16) / 0x4a574b) << 16) / (0x30f2e / *inter2)) >> 16;
beams = 1;
inter3 = (((((((u64)(((x << 8) / xscale) + xoffs - 0x7a)) << 16) << 16) / 0x4a574b) << 16) / (0x30f2e / inter2)) >> 16;
}
else
{
*beams = 0;
*inter3 = (((((((uint64_t)(((x << 8) / xscale) + xoffs - 0x7a) * -1) << 16) << 16) / 0x4a574b) << 16) / (0x30f2e / *inter2)) >> 16;
beams = 0;
inter3 = (((((((u64)(((x << 8) / xscale) + xoffs - 0x7a) * -1) << 16) << 16) / 0x4a574b) << 16) / (0x30f2e / inter2)) >> 16;
}
}
@ -306,53 +300,53 @@ void slikshot_state::vels_to_inters(u8 x, u8 vx, u8 vy,
*
*************************************/
void slikshot_state::inters_to_words(u16 inter1, u16 inter2, u16 inter3, u8 *beams,
u16 *word1, u16 *word2, u16 *word3)
void slikshot_state::inters_to_words(u16 inter1, u16 inter2, u16 inter3, u8 &beams,
u16 &word1, u16 &word2, u16 &word3)
{
u16 word2mod;
/* intermediate value 3 is always equal to the third word */
*word3 = inter3;
// intermediate value 3 is always equal to the third word
word3 = inter3;
/* on input, it is expected that the low bit of beams has already been determined */
if (*beams & 1)
// on input, it is expected that the low bit of beams has already been determined
if (beams & 1)
{
/* make sure we can do it */
// make sure we can do it
if (inter3 <= inter1)
{
/* always go back via case 3 */
*beams |= 2;
// always go back via case 3
beams |= 2;
/* compute an appropriate value for the scaled version of word 2 */
// compute an appropriate value for the scaled version of word 2
word2mod = inter1 - inter3;
/* compute the other values from that */
*word1 = inter2 - word2mod;
*word2 = ((uint64_t)word2mod << 16) / 0x16553;
// compute the other values from that
word1 = inter2 - word2mod;
word2 = ((u64)word2mod << 16) / 0x16553;
}
else
LOGSENSOR("inters_to_words: unable to convert %04x %04x %04x %02x\n",
(u32)inter1, (u32)inter2, (u32)inter3, (u32)*beams);
inter1, inter2, inter3, beams);
}
/* handle the case where low bit of beams is 0 */
// handle the case where low bit of beams is 0
else
{
/* make sure we can do it */
// make sure we can do it
if (inter3 <= inter2)
{
/* always go back via case 0 */
// always go back via case 0
/* compute an appropriate value for the scaled version of word 2 */
// compute an appropriate value for the scaled version of word 2
word2mod = inter2 - inter3;
/* compute the other values from that */
*word1 = inter1 - word2mod;
*word2 = ((uint64_t)word2mod << 16) / 0x16553;
// compute the other values from that
word1 = inter1 - word2mod;
word2 = ((u64)word2mod << 16) / 0x16553;
}
else
LOGSENSOR("inters_to_words: unable to convert %04x %04x %04x %02x\n",
(u32)inter1, (u32)inter2, (u32)inter3, (u32)*beams);
inter1, inter2, inter3, beams);
}
}
@ -369,19 +363,19 @@ void slikshot_state::inters_to_words(u16 inter1, u16 inter2, u16 inter3, u8 *bea
*************************************/
void slikshot_state::words_to_sensors(u16 word1, u16 word2, u16 word3, u8 beams,
u16 *sens0, u16 *sens1, u16 *sens2, u16 *sens3)
u16 &sens0, u16 &sens1, u16 &sens2, u16 &sens3)
{
/* if bit 0 of the beams is set, sensor 1 fired first; otherwise sensor 0 fired */
// if bit 0 of the beams is set, sensor 1 fired first; otherwise sensor 0 fired
if (beams & 1)
*sens0 = 0, *sens1 = word3;
sens0 = 0, sens1 = word3;
else
*sens0 = word3, *sens1 = 0;
sens0 = word3, sens1 = 0;
/* if bit 1 of the beams is set, sensor 3 had a larger value */
// if bit 1 of the beams is set, sensor 3 had a larger value
if (beams & 2)
*sens3 = word2 + word1, *sens2 = word2;
sens3 = word2 + word1, sens2 = word2;
else
*sens2 = word2 + word1, *sens3 = word2;
sens2 = word2 + word1, sens3 = word2;
}
@ -398,14 +392,14 @@ void slikshot_state::compute_sensors()
u16 word1 = 0, word2 = 0, word3 = 0;
u8 beams;
/* skip if we're not ready */
// skip if we're not ready
if (m_sensor0 != 0 || m_sensor1 != 0 || m_sensor2 != 0 || m_sensor3 != 0)
return;
/* reverse map the inputs */
vels_to_inters(m_curx, m_curvx, m_curvy, &inter1, &inter2, &inter3, &beams);
inters_to_words(inter1, inter2, inter3, &beams, &word1, &word2, &word3);
words_to_sensors(word1, word2, word3, beams, &m_sensor0, &m_sensor1, &m_sensor2, &m_sensor3);
// reverse map the inputs
vels_to_inters(m_curx, m_curvx, m_curvy, inter1, inter2, inter3, beams);
inters_to_words(inter1, inter2, inter3, beams, word1, word2, word3);
words_to_sensors(word1, word2, word3, beams, m_sensor0, m_sensor1, m_sensor2, m_sensor3);
LOGSENSOR("%15f: Sensor values: %04x %04x %04x %04x\n", machine().time().as_double(), m_sensor0, m_sensor1, m_sensor2, m_sensor3);
}
@ -420,21 +414,37 @@ void slikshot_state::compute_sensors()
u8 slikshot_state::z80_port_r()
{
int result = 0;
/* if we have nothing, return 0x03 */
// if we have nothing, return 0x03
if (!m_sensor0 && !m_sensor1 && !m_sensor2 && !m_sensor3)
return 0x03 | (m_z80_clear_to_send << 7);
/* 1 bit for each sensor */
u8 result = 0;
// 1 bit for each sensor
if (m_sensor0)
result |= 1, m_sensor0--;
{
result |= 1;
if (!machine().side_effects_disabled())
m_sensor0--;
}
if (m_sensor1)
result |= 2, m_sensor1--;
{
result |= 2;
if (!machine().side_effects_disabled())
m_sensor1--;
}
if (m_sensor2)
result |= 4, m_sensor2--;
{
result |= 4;
if (!machine().side_effects_disabled())
m_sensor2--;
}
if (m_sensor3)
result |= 8, m_sensor3--;
{
result |= 8;
if (!machine().side_effects_disabled())
m_sensor3--;
}
result |= m_z80_clear_to_send << 7;
return result;
@ -464,8 +474,9 @@ void slikshot_state::z80_port_w(u8 data)
u8 slikshot_state::z80_r()
{
/* allow the Z80 to send us stuff now */
m_z80_clear_to_send = 1;
// allow the Z80 to send us stuff now
if (!machine().side_effects_disabled())
m_z80_clear_to_send = 1;
return m_z80_port_val;
}
@ -492,25 +503,25 @@ u8 slikshot_state::z80_control_r()
TIMER_CALLBACK_MEMBER(slikshot_state::delayed_z80_control_w)
{
int data = param;
u8 const data = param;
/* bit 4 controls the reset line on the Z80 */
// bit 4 controls the reset line on the Z80
/* this is a big kludge: only allow a reset if the Z80 is stopped */
/* at its endpoint; otherwise, we never get a result from the Z80 */
// this is a big kludge: only allow a reset if the Z80 is stopped
// at its endpoint; otherwise, we never get a result from the Z80
if ((data & 0x10) || m_subcpu->state_int(Z80_PC) == 0x13a)
{
m_subcpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? CLEAR_LINE : ASSERT_LINE);
/* on the rising edge, make the crosshair visible again */
// on the rising edge, make the crosshair visible again
if ((data & 0x10) && !(m_z80_ctrl & 0x10))
m_crosshair_vis = 1;
}
/* boost the interleave whenever this is written to */
// boost the interleave whenever this is written to
machine().scheduler().perfect_quantum(attotime::from_usec(100));
/* stash the new value */
// stash the new value
m_z80_ctrl = data;
}
@ -558,54 +569,37 @@ void slikshot_state::machine_start()
/*************************************
*
* SCREEN_UPDATE( slikshot )
* slikshot_state::screen_update
*
*************************************/
u32 slikshot_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int totaldy, totaldx;
int temp, i;
/* draw the normal video first */
// draw the normal video first
screen_update_2page(screen, bitmap, cliprect);
/* add the current X,Y positions to the list */
// add the current X,Y positions to the list
m_xbuffer[m_ybuffer_next % YBUFFER_COUNT] = m_fakex->read();
m_ybuffer[m_ybuffer_next % YBUFFER_COUNT] = m_fakey->read();
m_ybuffer_next++;
/* determine where to draw the starting point */
m_curxpos += m_xbuffer[(m_ybuffer_next + 1) % YBUFFER_COUNT];
if (m_curxpos < -0x80) m_curxpos = -0x80;
if (m_curxpos > 0x80) m_curxpos = 0x80;
// determine where to draw the starting point
m_curxpos = std::clamp<s32>(m_curxpos + m_xbuffer[(m_ybuffer_next + 1) % YBUFFER_COUNT], -0x80, 0x80);
/* compute the total X/Y movement */
totaldx = totaldy = 0;
for (i = 0; i < YBUFFER_COUNT - 1; i++)
// compute the total X/Y movement
s32 totaldx = 0, totaldy = 0;
for (int i = 0; i < YBUFFER_COUNT - 1; i++)
{
totaldx += m_xbuffer[(m_ybuffer_next + i + 1) % YBUFFER_COUNT];
totaldy += m_ybuffer[(m_ybuffer_next + i + 1) % YBUFFER_COUNT];
}
/* if the shoot button is pressed, fire away */
// if the shoot button is pressed, fire away
if (totaldy < m_last_ytotal && m_last_ytotal > 50 && m_crosshair_vis)
{
/* compute the updated values */
temp = totaldx;
if (temp <= -0x80) temp = -0x7f;
if (temp >= 0x80) temp = 0x7f;
m_curvx = temp;
temp = m_last_ytotal - 50;
if (temp <= 0x10) temp = 0x10;
if (temp >= 0x7f) temp = 0x7f;
m_curvy = temp;
temp = 0x60 + (m_curxpos * 0x30 / 0x80);
if (temp <= 0x30) temp = 0x30;
if (temp >= 0x90) temp = 0x90;
m_curx = temp;
m_curvx = std::clamp<int>(totaldx, -0x7f, 0x7f);
m_curvy = std::clamp<int>(m_last_ytotal - 50, 0x10, 0x7f);
m_curx = std::clamp<int>(0x60 + ((m_curxpos * 3) >> 3), 0x30, 0x90);
compute_sensors();
// popmessage("V=%02x,%02x X=%02x", m_curvx, m_curvy, m_curx);
@ -613,7 +607,7 @@ u32 slikshot_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, c
}
m_last_ytotal = totaldy;
/* clear the buffer while the crosshair is not visible */
// clear the buffer while the crosshair is not visible
if (!m_crosshair_vis)
{
memset(m_xbuffer, 0, sizeof(m_xbuffer));

View File

@ -133,11 +133,11 @@
#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
static constexpr u8 BLITFLAG_SHIFT = 0x01;
static constexpr u8 BLITFLAG_XFLIP = 0x02;
static constexpr u8 BLITFLAG_YFLIP = 0x04;
static constexpr u8 BLITFLAG_RLE = 0x08;
static constexpr u8 BLITFLAG_TRANSPARENT = 0x10;
@ -149,10 +149,10 @@
void itech8_state::video_start()
{
/* get the TMS34061 display state */
// get the TMS34061 display state
m_tms34061->get_display_state();
/* reset statics */
// reset statics
m_page_select = 0xc0;
m_blit_in_progress = 0;
@ -238,8 +238,6 @@ 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()];
@ -250,7 +248,7 @@ inline void itech8_state::consume_rle(int count)
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;
int const num_to_consume = (count < m_fetch_rle_count) ? count : m_fetch_rle_count;
count -= num_to_consume;
m_fetch_rle_count -= num_to_consume;
@ -270,48 +268,48 @@ inline void itech8_state::consume_rle(int count)
void itech8_state::perform_blit()
{
offs_t addr = m_tms34061->xyaddress() | ((m_tms34061->xyoffset() & 0x300) << 8);
u8 shift = (BLITTER_FLAGS & BLITFLAG_SHIFT) ? 4 : 0;
int transparent = (BLITTER_FLAGS & BLITFLAG_TRANSPARENT);
int ydir = (BLITTER_FLAGS & BLITFLAG_YFLIP) ? -1 : 1;
u8 const shift = (BLITTER_FLAGS & BLITFLAG_SHIFT) ? 4 : 0;
int const transparent = (BLITTER_FLAGS & BLITFLAG_TRANSPARENT);
int const 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 const xflip = (BLITTER_FLAGS & BLITFLAG_XFLIP);
int const rle = (BLITTER_FLAGS & BLITFLAG_RLE);
int const color = m_tms34061->latch_r();
int width = BLITTER_WIDTH;
int height = BLITTER_HEIGHT;
u8 transmaskhi, transmasklo;
u8 mask = BLITTER_MASK;
u8 const mask = BLITTER_MASK;
u8 skip[3];
int x, y;
/* debugging */
// debugging
LOGBLITTER("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 */
// 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 */
// RLE starts with a couple of extra 0's
if (rle)
m_fetch_offset += 2;
/* select 4-bit versus 8-bit transparency */
// select 4-bit versus 8-bit transparency
if (BLITTER_OUTPUT & 0x40)
transmaskhi = 0xf0, transmasklo = 0x0f;
else
transmaskhi = transmasklo = 0xff;
/* compute horiz skip counts */
// 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 */
// compute vertical skip counts
if (ydir == 1)
{
skip[2] = (height <= BLITTER_YCOUNT) ? 0 : height - BLITTER_YCOUNT;
@ -323,71 +321,71 @@ void itech8_state::perform_blit()
if (BLITTER_YCOUNT > 1) height -= BLITTER_YCOUNT - 1;
}
/* skip top */
// skip top
for (y = 0; y < skip[2]; y++)
{
/* skip src and dest */
// 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 */
// back up one and reverse directions
addr -= xdir;
addr += ydir * 256;
addr &= VRAM_MASK;
xdir = -xdir;
}
/* loop over height */
// loop over height
for (y = skip[2]; y < height; y++)
{
/* skip left */
// skip left
addr += xdir * skip[y & 1];
if (rle)
consume_rle(skip[y & 1]);
else
consume_raw(skip[y & 1]);
/* loop over width */
// loop over width
for (x = 0; x < width; x++)
{
u8 pix = rle ? fetch_next_rle() : fetch_next_raw();
/* swap pixels for X flip in 4bpp mode */
// swap pixels for X flip in 4bpp mode
if (xflip && transmaskhi != 0xff)
pix = (pix >> 4) | (pix << 4);
pix &= mask;
/* draw upper pixel */
// 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 */
// draw lower pixel
if (!transparent || (pix & transmasklo))
{
offs_t addr1 = addr + shift/4;
offs_t const 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 */
// advance to the next byte
addr += xdir;
addr &= VRAM_MASK;
}
/* skip right */
// 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 */
// back up one and reverse directions
addr -= xdir;
addr += ydir * 256;
addr &= VRAM_MASK;
@ -405,7 +403,7 @@ void itech8_state::perform_blit()
TIMER_CALLBACK_MEMBER(itech8_state::blitter_done)
{
/* turn off blitting and generate an interrupt */
// turn off blitting and generate an interrupt
m_blit_in_progress = 0;
update_interrupts(-1, -1, 1);
@ -424,23 +422,24 @@ u8 itech8_state::blitter_r(offs_t offset)
{
int result = m_blitter_data[offset / 2];
/* debugging */
// debugging
LOGBLITTER("%s:blitter_r(%02x)\n", machine().describe_context(), offset / 2);
/* low bit seems to be ignored */
// low bit seems to be ignored
offset /= 2;
/* a read from offset 3 clears the interrupt and returns the status */
// a read from offset 3 clears the interrupt and returns the status
if (offset == 3)
{
update_interrupts(-1, -1, 0);
if (!machine().side_effects_disabled())
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 */
// a read from offsets 12-15 return input port values
if (offset >= 12 && offset <= 15)
result = m_an[offset - 12].read_safe(0);
@ -450,14 +449,14 @@ u8 itech8_state::blitter_r(offs_t offset)
void itech8_state::blitter_w(offs_t offset, u8 data)
{
/* low bit seems to be ignored */
// low bit seems to be ignored
offset /= 2;
m_blitter_data[offset] = data;
/* a write to offset 3 starts things going */
// a write to offset 3 starts things going
if (offset == 3)
{
/* log to the blitter file */
// log to the blitter file
LOGBLITTER("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],
@ -473,15 +472,15 @@ void itech8_state::blitter_w(offs_t offset, u8 data)
m_blitter_data[12], m_blitter_data[13],
m_blitter_data[14], m_blitter_data[15]);
/* perform the blit */
// perform the blit
perform_blit();
m_blit_in_progress = 1;
/* set a timer to go off when we're done */
// 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 */
// debugging
LOGBLITTER("%s:blitter_w(%02x)=%02x\n", machine().describe_context(), offset, data);
}
@ -495,7 +494,7 @@ void itech8_state::blitter_w(offs_t offset, u8 data)
void itech8_state::tms34061_w(offs_t offset, u8 data)
{
int func = (offset >> 9) & 7;
int const func = (offset >> 9) & 7;
int col = offset & 0xff;
/* Column address (CA0-CA8) is hooked up the A0-A7, with A1 being inverted
@ -503,14 +502,14 @@ void itech8_state::tms34061_w(offs_t offset, u8 data)
if (func == 0 || func == 2)
col ^= 2;
/* Row address (RA0-RA8) is not dependent on the offset */
// Row address (RA0-RA8) is not dependent on the offset
m_tms34061->write(col, 0xff, func, data);
}
u8 itech8_state::tms34061_r(offs_t offset)
{
int func = (offset >> 9) & 7;
int const func = (offset >> 9) & 7;
int col = offset & 0xff;
/* Column address (CA0-CA8) is hooked up the A0-A7, with A1 being inverted
@ -518,7 +517,7 @@ u8 itech8_state::tms34061_r(offs_t offset)
if (func == 0 || func == 2)
col ^= 2;
/* Row address (RA0-RA8) is not dependent on the offset */
// Row address (RA0-RA8) is not dependent on the offset
return m_tms34061->read(col, 0xff, func);
}
@ -532,14 +531,14 @@ u8 itech8_state::tms34061_r(offs_t offset)
void grmatch_state::palette_w(u8 data)
{
/* set the palette control; examined in the scanline callback */
// set the palette control; examined in the scanline callback
m_palcontrol = data;
}
void grmatch_state::xscroll_w(u8 data)
{
/* update the X scroll value */
// update the X scroll value
//m_screen->update_now();
m_screen->update_partial(m_screen->vpos());
m_xscroll = data;
@ -548,21 +547,21 @@ void grmatch_state::xscroll_w(u8 data)
TIMER_CALLBACK_MEMBER(grmatch_state::palette_update)
{
/* if the high bit is set, we are supposed to latch the palette values */
// 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 */
u32 page_offset = (m_tms34061->m_display.dispstart & 0x0ffff) | m_xscroll;
// the TMS34070s latch at the start of the frame, based on the first few bytes
u32 const page_offset = (m_tms34061->m_display.dispstart & 0x0ffff) | m_xscroll;
/* iterate over both pages */
// iterate over both pages
for (int page = 0; page < 2; page++)
{
const u8 *base = &m_tms34061->m_display.vram[(page * 0x20000 + page_offset) & VRAM_MASK];
for (int x = 0; x < 16; x++)
{
u8 data0 = base[x * 2 + 0];
u8 data1 = base[x * 2 + 1];
m_palette[page][x] = rgb_t(pal4bit(data0 >> 0), pal4bit(data1 >> 4), pal4bit(data1 >> 0));
u8 const data0 = base[x * 2 + 0];
u8 const data1 = base[x * 2 + 1];
m_palette[page]->set_pen_color(x, rgb_t(pal4bit(data0 >> 0), pal4bit(data1 >> 4), pal4bit(data1 >> 0)));
}
}
}
@ -582,10 +581,10 @@ u32 itech8_state::screen_update_2layer(screen_device &screen, bitmap_rgb32 &bitm
{
pen_t const *const pens = m_tlc34076->pens();
/* first get the current display state */
// first get the current display state
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
// if we're blanked, just fill with black
if (m_tms34061->blanked())
{
bitmap.fill(rgb_t::black(), cliprect);
@ -604,7 +603,7 @@ u32 itech8_state::screen_update_2layer(screen_device &screen, bitmap_rgb32 &bitm
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
int const pix0 = base0[x] & 0x0f;
u8 const pix0 = base0[x] & 0x0f;
dest[x] = pens[pix0 ? pix0 : base2[x]];
}
}
@ -614,10 +613,12 @@ u32 itech8_state::screen_update_2layer(screen_device &screen, bitmap_rgb32 &bitm
u32 grmatch_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
/* first get the current display state */
pen_t const *const pens[2] = { m_palette[0]->pens(), m_palette[1]->pens() };
// first get the current display state
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
// if we're blanked, just fill with black
if (m_tms34061->blanked())
{
bitmap.fill(rgb_t::black(), cliprect);
@ -642,14 +643,14 @@ u32 grmatch_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co
u8 const pix2 = base2[x / 2];
if ((pix0 & 0xf0) != 0)
dest[x] = m_palette[0][pix0 >> 4];
dest[x] = pens[0][pix0 >> 4];
else
dest[x] = m_palette[1][pix2 >> 4];
dest[x] = pens[1][pix2 >> 4];
if ((pix0 & 0x0f) != 0)
dest[x + 1] = m_palette[0][pix0 & 0x0f];
dest[x + 1] = pens[0][pix0 & 0x0f];
else
dest[x + 1] = m_palette[1][pix2 & 0x0f];
dest[x + 1] = pens[1][pix2 & 0x0f];
}
}
return 0;
@ -660,10 +661,10 @@ u32 itech8_state::screen_update_2page(screen_device &screen, bitmap_rgb32 &bitma
{
pen_t const *const pens = m_tlc34076->pens();
/* first get the current display state */
// first get the current display state
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
// if we're blanked, just fill with black
if (m_tms34061->blanked())
{
bitmap.fill(rgb_t::black(), cliprect);
@ -689,10 +690,10 @@ u32 itech8_state::screen_update_2page_large(screen_device &screen, bitmap_rgb32
{
pen_t const *const pens = m_tlc34076->pens();
/* first get the current display state */
// first get the current display state
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
// if we're blanked, just fill with black
if (m_tms34061->blanked())
{
bitmap.fill(rgb_t::black(), cliprect);