metro.cpp, hyprduel.cpp: Move interrupt control (mostly) down into VDP

This commit is contained in:
AJR 2021-01-09 12:26:37 -05:00
parent fdd9fb1081
commit 5bf3dbd3a4
5 changed files with 255 additions and 307 deletions

View File

@ -71,6 +71,12 @@
#include <algorithm>
#define LOG_INT (1 << 1U)
//#define VERBOSE (LOG_INT)
#include "logmacro.h"
#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__)
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@ -156,6 +162,8 @@ void imagetek_i4100_device::map(address_map &map)
map(0x78880, 0x78881).w(FUNC(imagetek_i4100_device::crtc_vert_w));
map(0x78890, 0x78891).w(FUNC(imagetek_i4100_device::crtc_horz_w));
map(0x788a0, 0x788a1).w(FUNC(imagetek_i4100_device::crtc_unlock_w));
map(0x788a3, 0x788a3).rw(FUNC(imagetek_i4100_device::irq_cause_r), FUNC(imagetek_i4100_device::irq_cause_w));
map(0x788a5, 0x788a5).w(FUNC(imagetek_i4100_device::irq_enable_w));
map(0x788aa, 0x788ab).w(FUNC(imagetek_i4100_device::rombank_w));
map(0x788ac, 0x788ad).w(FUNC(imagetek_i4100_device::screen_ctrl_w));
}
@ -184,6 +192,8 @@ void imagetek_i4220_device::v2_map(address_map &map)
map(0x78880, 0x78881).w(FUNC(imagetek_i4220_device::crtc_vert_w));
map(0x78890, 0x78891).w(FUNC(imagetek_i4220_device::crtc_horz_w));
map(0x788a0, 0x788a1).w(FUNC(imagetek_i4220_device::crtc_unlock_w));
map(0x788a3, 0x788a3).rw(FUNC(imagetek_i4220_device::irq_cause_r), FUNC(imagetek_i4220_device::irq_cause_w));
map(0x788a5, 0x788a5).w(FUNC(imagetek_i4220_device::irq_enable_w));
map(0x788aa, 0x788ab).w(FUNC(imagetek_i4220_device::rombank_w));
map(0x788ac, 0x788ad).w(FUNC(imagetek_i4220_device::screen_ctrl_w));
@ -228,6 +238,11 @@ void imagetek_i4300_device::v3_map(address_map &map)
map(0x78802, 0x78803).w(FUNC(imagetek_i4300_device::crtc_horz_w));
map(0x78804, 0x78805).w(FUNC(imagetek_i4300_device::crtc_vert_w));
map(0x78810, 0x7881f).w(FUNC(imagetek_i4300_device::irq_level_w)).umask16(0x00ff);
map(0x78820, 0x7882f).w(FUNC(imagetek_i4300_device::irq_vector_w)).umask16(0x00ff);
map(0x78831, 0x78831).w(FUNC(imagetek_i4300_device::irq_enable_w));
map(0x78833, 0x78833).rw(FUNC(imagetek_i4300_device::irq_cause_r), FUNC(imagetek_i4300_device::irq_cause_w));
map(0x78840, 0x7884d).w(FUNC(imagetek_i4300_device::blitter_w)).share("blitter_regs");
map(0x78850, 0x7885b).rw(FUNC(imagetek_i4300_device::scroll_r), FUNC(imagetek_i4300_device::scroll_w)).share("scrollregs");
map(0x78860, 0x7886b).rw(FUNC(imagetek_i4300_device::window_r), FUNC(imagetek_i4300_device::window_w)).share("windowregs");
@ -266,7 +281,9 @@ imagetek_i4100_device::imagetek_i4100_device(const machine_config &mconfig, devi
, m_scroll(*this, "scrollregs")
, m_palette(*this, "palette")
, m_gfxrom(*this, DEVICE_SELF)
, m_blit_irq_cb(*this)
, m_irq_cb(*this)
, m_vblank_irq_level(-1)
, m_blit_irq_level(-1)
, m_support_8bpp(has_ext_tiles)
, m_support_16x16(has_ext_tiles)
, m_tilemap_scrolldx{0, 0, 0}
@ -291,6 +308,8 @@ imagetek_i4220_device::imagetek_i4220_device(const machine_config &mconfig, cons
imagetek_i4300_device::imagetek_i4300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: imagetek_i4100_device(mconfig, I4300, tag, owner, clock, true)
{
std::fill(std::begin(m_irq_levels), std::end(m_irq_levels), 0);
std::fill(std::begin(m_irq_vectors), std::end(m_irq_vectors), 0);
}
//-------------------------------------------------
@ -335,6 +354,8 @@ void imagetek_i4100_device::device_start()
m_screen_blank = false;
m_screen_flip = false;
save_item(NAME(m_requested_int));
save_item(NAME(m_irq_enable));
save_item(NAME(m_rombank));
save_item(NAME(m_crtc_unlock));
save_item(NAME(m_sprite_count));
@ -357,13 +378,21 @@ void imagetek_i4100_device::device_start()
m_gfxrom_size = m_gfxrom.bytes();
m_blit_irq_cb.resolve_safe();
m_irq_cb.resolve_safe();
m_blit_done_timer = timer_alloc(TIMER_BLIT_END);
m_spritelist = std::make_unique<sprite_t []>(0x1000 / 8);
m_sprite_end = m_spritelist.get();
}
void imagetek_i4300_device::device_start()
{
imagetek_i4100_device::device_start();
save_item(NAME(m_irq_levels));
save_item(NAME(m_irq_vectors));
}
//-------------------------------------------------
// device_reset - device-specific reset
@ -371,6 +400,8 @@ void imagetek_i4100_device::device_start()
void imagetek_i4100_device::device_reset()
{
m_requested_int = 0;
m_irq_enable = 0xff;
m_rombank = 0;
m_crtc_unlock = false;
m_sprite_count = 0;
@ -378,6 +409,7 @@ void imagetek_i4100_device::device_reset()
m_sprite_xoffset = 0;
m_sprite_yoffset = 0;
m_sprite_color_code = 0;
update_irq_state();
for(int i=0; i != 3; i++) {
m_layer_priority[i] = 0;
@ -393,13 +425,108 @@ void imagetek_i4100_device::device_reset()
expand_gfx1();
}
//**************************************************************************
// INTERRUPTS
//**************************************************************************
u8 imagetek_i4100_device::irq_cause_r()
{
/* interrupt cause, used by
int[0] vblank
int[1] hblank (bangball for faster intermission skip,
puzzli for gameplay water effect,
blzntrnd title screen scroll (enabled all the time then?),
unused/empty in balcube, daitoride, karatour,
unchecked mouja & other i4300 games )
int[2] blitter
int[3] ? KARATOUR
int[4] ?
int[5] ? KARATOUR, BLZNTRND
int[6] unused
int[7] unused
*/
return m_requested_int;
}
void imagetek_i4100_device::irq_cause_w(u8 data)
{
if ((m_requested_int & data) == 0)
return;
LOGINT("%s: Interrupts acknowledged (%02X)\n", machine().describe_context(), data);
m_requested_int &= ~data;
update_irq_state();
}
void imagetek_i4100_device::set_irq(int level)
{
if (!BIT(m_requested_int, level))
{
LOGINT("IRQ %d set\n", level);
m_requested_int |= 1 << level;
update_irq_state();
}
}
void imagetek_i4100_device::clear_irq(int level)
{
if (BIT(m_requested_int, level))
{
LOGINT("IRQ %d cleared\n", level);
m_requested_int &= ~(1 << level);
update_irq_state();
}
}
void imagetek_i4100_device::update_irq_state()
{
m_irq_cb((m_requested_int & ~m_irq_enable) ? ASSERT_LINE : CLEAR_LINE);
}
void imagetek_i4100_device::irq_enable_w(u8 data)
{
LOGINT("%s: IRQ enable register = %02X\n", machine().describe_context(), data);
m_irq_enable = data;
update_irq_state();
}
void imagetek_i4300_device::irq_level_w(offs_t offset, u8 data)
{
m_irq_levels[offset] = data;
}
void imagetek_i4300_device::irq_vector_w(offs_t offset, u8 data)
{
m_irq_vectors[offset] = data;
}
u8 imagetek_i4300_device::irq_vector_r(offs_t offset)
{
return m_irq_vectors[offset];
}
void imagetek_i4300_device::update_irq_state()
{
u8 irqs = m_requested_int & ~m_irq_enable;
int level = 0;
for (int i = 0; i < 8; i++)
if (BIT(irqs, i))
level = std::max(level, m_irq_levels[i] & 7);
m_irq_cb(level);
}
void imagetek_i4100_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case TIMER_BLIT_END:
m_blit_irq_cb(ASSERT_LINE);
if (m_blit_irq_level != -1)
set_irq(m_blit_irq_level);
break;
}
}
@ -1295,9 +1422,10 @@ WRITE_LINE_MEMBER(imagetek_i4100_device::screen_eof)
{
if (state)
{
if (!m_spriteram_buffered)
return;
if (m_vblank_irq_level != -1)
set_irq(m_vblank_irq_level);
if (m_spriteram_buffered)
m_spriteram->copy();
}
}

View File

@ -51,13 +51,22 @@ public:
set_tmap_flip_yoffsets(-y1, -y2, -y3);
}
auto blit_irq_cb() { return m_blit_irq_cb.bind(); }
auto irq_cb() { return m_irq_cb.bind(); }
void set_vblank_irq_level(int level) { m_vblank_irq_level = level; }
void set_blit_irq_level(int level) { m_blit_irq_level = level; }
void set_spriteram_buffered(bool buffer) { m_spriteram_buffered = buffer; }
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void draw_foreground(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_eof);
// TODO: privatize eventually
u8 irq_enable() const { return m_irq_enable; }
void irq_enable_w(u8 data);
void set_irq(int level);
void clear_irq(int level);
u8 irq_cause_r();
protected:
imagetek_i4100_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool has_ext_tiles);
@ -68,6 +77,8 @@ protected:
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual void update_irq_state();
required_shared_ptr_array<u16, 3> m_vram;
required_shared_ptr<u16> m_scratchram;
required_shared_ptr<u16> m_blitter_regs;
@ -81,7 +92,12 @@ protected:
std::unique_ptr<u8[]> m_expanded_gfx1;
devcb_write_line m_blit_irq_cb;
devcb_write8 m_irq_cb;
int m_vblank_irq_level;
int m_blit_irq_level;
u8 m_requested_int;
u8 m_irq_enable;
struct sprite_t
{
@ -127,6 +143,7 @@ protected:
emu_timer *m_blit_done_timer;
// I/O operations
void irq_cause_w(u8 data);
inline u16 vram_r(offs_t offset, int layer) { return m_vram[layer][offset]; }
inline void vram_w(offs_t offset, u16 data, u16 mem_mask, int layer) { COMBINE_DATA(&m_vram[layer][offset]); }
uint16_t vram_0_r(offs_t offset);
@ -225,6 +242,19 @@ public:
imagetek_i4300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
void v3_map(address_map &map);
u8 irq_vector_r(offs_t offset);
protected:
virtual void device_start() override;
virtual void update_irq_state() override;
private:
void irq_level_w(offs_t offset, u8 data);
void irq_vector_w(offs_t offset, u8 data);
u8 m_irq_levels[8];
u8 m_irq_vectors[8];
};
// device type definition

View File

@ -60,7 +60,6 @@ class hyprduel_state : public driver_device
public:
hyprduel_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_irq_enable(*this, "irq_enable")
, m_sharedram(*this, "sharedram%u", 1)
, m_maincpu(*this, "maincpu")
, m_subcpu(*this, "sub")
@ -70,7 +69,6 @@ public:
void magerror(machine_config &config);
void hyprduel(machine_config &config);
void init_magerror();
void init_hyprduel();
protected:
@ -78,16 +76,15 @@ protected:
virtual void machine_reset() override;
private:
uint8_t irq_cause_r();
void irq_cause_w(uint8_t data);
void subcpu_control_w(uint16_t data);
uint16_t hyprduel_cpusync_trigger1_r(offs_t offset);
void hyprduel_cpusync_trigger1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint16_t hyprduel_cpusync_trigger2_r(offs_t offset);
void hyprduel_cpusync_trigger2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
TIMER_CALLBACK_MEMBER(vblank_end_callback);
DECLARE_WRITE_LINE_MEMBER(vdp_blit_end_w);
TIMER_DEVICE_CALLBACK_MEMBER(interrupt);
void hyprduel_int_enable_w(uint8_t data);
void magerror_int_enable_w(uint8_t data);
void i4220_config(machine_config &config);
@ -97,23 +94,17 @@ private:
void magerror_map2(address_map &map);
/* memory pointers */
required_shared_ptr<uint16_t> m_irq_enable;
required_shared_ptr_array<uint16_t, 3> m_sharedram;
/* misc */
emu_timer *m_vblank_end_timer;
int m_blitter_bit;
int m_requested_int;
int m_subcpu_resetline;
int m_cpu_trigger;
int m_int_num;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_subcpu;
required_device<imagetek_i4220_device> m_vdp;
void update_irq_state( );
};
@ -121,16 +112,9 @@ private:
Interrupts
***************************************************************************/
void hyprduel_state::update_irq_state( )
{
int irq = m_requested_int & ~*m_irq_enable;
m_maincpu->set_input_line(3, (irq & m_int_num) ? ASSERT_LINE : CLEAR_LINE);
}
TIMER_CALLBACK_MEMBER(hyprduel_state::vblank_end_callback)
{
m_requested_int &= ~param;
m_vdp->clear_irq(param);
}
TIMER_DEVICE_CALLBACK_MEMBER(hyprduel_state::interrupt)
@ -139,31 +123,27 @@ TIMER_DEVICE_CALLBACK_MEMBER(hyprduel_state::interrupt)
if (line == 0) /* TODO: fix this! */
{
m_requested_int |= 0x01; /* vblank */
m_requested_int |= 0x20;
m_vdp->set_irq(0); /* vblank */
m_vdp->set_irq(5);
m_maincpu->set_input_line(2, HOLD_LINE);
/* the duration is a guess */
m_vblank_end_timer->adjust(attotime::from_usec(2500), 0x20);
m_vblank_end_timer->adjust(attotime::from_usec(2500), 5);
}
else
m_requested_int |= 0x12; /* hsync */
update_irq_state();
{
m_vdp->set_irq(1); /* hsync */
m_vdp->set_irq(4);
}
}
uint8_t hyprduel_state::irq_cause_r()
void hyprduel_state::hyprduel_int_enable_w(u8 data)
{
return m_requested_int;
m_vdp->irq_enable_w(data | 0xfd);
}
void hyprduel_state::irq_cause_w(uint8_t data)
void hyprduel_state::magerror_int_enable_w(u8 data)
{
if (data == m_int_num)
m_requested_int &= ~(m_int_num & ~*m_irq_enable);
else
m_requested_int &= ~(data & *m_irq_enable);
update_irq_state();
m_vdp->irq_enable_w(data | 0xfe);
}
@ -249,12 +229,6 @@ void hyprduel_state::hyprduel_cpusync_trigger2_w(offs_t offset, uint16_t data, u
}
}
WRITE_LINE_MEMBER(hyprduel_state::vdp_blit_end_w)
{
m_requested_int |= 1 << m_blitter_bit;
update_irq_state();
}
/***************************************************************************
Memory Maps
***************************************************************************/
@ -263,8 +237,7 @@ void hyprduel_state::hyprduel_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x400000, 0x47ffff).m(m_vdp, FUNC(imagetek_i4220_device::v2_map));
map(0x4788a3, 0x4788a3).rw(FUNC(hyprduel_state::irq_cause_r), FUNC(hyprduel_state::irq_cause_w)); /* IRQ Cause,Acknowledge */
map(0x4788a4, 0x4788a5).ram().share("irq_enable"); /* IRQ Enable */
map(0x4788a5, 0x4788a5).w(FUNC(hyprduel_state::hyprduel_int_enable_w));
map(0x800000, 0x800001).w(FUNC(hyprduel_state::subcpu_control_w));
map(0xc00000, 0xc07fff).ram().share("sharedram1");
map(0xe00000, 0xe00001).portr("SERVICE").nopw();
@ -296,8 +269,7 @@ void hyprduel_state::magerror_map(address_map &map)
map(0x000000, 0x07ffff).rom();
map(0x400000, 0x400001).w(FUNC(hyprduel_state::subcpu_control_w));
map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4220_device::v2_map));
map(0x8788a3, 0x8788a3).rw(FUNC(hyprduel_state::irq_cause_r), FUNC(hyprduel_state::irq_cause_w)); /* IRQ Cause, Acknowledge */
map(0x8788a4, 0x8788a5).ram().share("irq_enable"); /* IRQ Enable */
map(0x8788a5, 0x8788a5).w(FUNC(hyprduel_state::magerror_int_enable_w));
map(0xc00000, 0xc1ffff).ram().share("sharedram1");
map(0xe00000, 0xe00001).portr("SERVICE").nopw();
map(0xe00002, 0xe00003).portr("DSW");
@ -420,16 +392,10 @@ void hyprduel_state::machine_reset()
m_subcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
m_subcpu_resetline = 1;
m_cpu_trigger = 0;
m_requested_int = 0x00;
m_blitter_bit = 2;
*m_irq_enable = 0xff;
}
void hyprduel_state::machine_start()
{
save_item(NAME(m_blitter_bit));
save_item(NAME(m_requested_int));
save_item(NAME(m_subcpu_resetline));
save_item(NAME(m_cpu_trigger));
@ -439,7 +405,8 @@ void hyprduel_state::machine_start()
void hyprduel_state::i4220_config(machine_config &config)
{
I4220(config, m_vdp, XTAL(26'666'000));
m_vdp->blit_irq_cb().set(FUNC(hyprduel_state::vdp_blit_end_w));
m_vdp->irq_cb().set_inputline(m_maincpu, M68K_IRQ_3);
m_vdp->set_blit_irq_level(2);
m_vdp->set_spriteram_buffered(true); // sprites are 1 frame delayed
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
@ -552,8 +519,6 @@ ROM_END
void hyprduel_state::init_hyprduel()
{
m_int_num = 0x02;
/* cpu synchronization (severe timings) */
m_maincpu->space(AS_PROGRAM).install_write_handler(0xc0040e, 0xc00411, write16s_delegate(*this, FUNC(hyprduel_state::hyprduel_cpusync_trigger1_w)));
m_subcpu->space(AS_PROGRAM).install_read_handler(0xc00408, 0xc00409, read16sm_delegate(*this, FUNC(hyprduel_state::hyprduel_cpusync_trigger1_r)));
@ -561,14 +526,9 @@ void hyprduel_state::init_hyprduel()
m_subcpu->space(AS_PROGRAM).install_read_handler(0xfff34c, 0xfff34d, read16sm_delegate(*this, FUNC(hyprduel_state::hyprduel_cpusync_trigger2_r)));
}
void hyprduel_state::init_magerror()
{
m_int_num = 0x01;
}
} // Anonymous namespace
GAME( 1993, hyprduel, 0, hyprduel, hyprduel, hyprduel_state, init_hyprduel, ROT0, "Technosoft", "Hyper Duel (Japan set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1993, hyprduel2, hyprduel, hyprduel, hyprduel, hyprduel_state, init_hyprduel, ROT0, "Technosoft", "Hyper Duel (Japan set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1994, magerror, 0, magerror, magerror, hyprduel_state, init_magerror, ROT0, "Technosoft / Jaleco", "Magical Error wo Sagase", MACHINE_SUPPORTS_SAVE )
GAME( 1994, magerror, 0, magerror, magerror, hyprduel_state, empty_init, ROT0, "Technosoft / Jaleco", "Magical Error wo Sagase", MACHINE_SUPPORTS_SAVE )

View File

@ -115,98 +115,33 @@ driver modified by Hau
***************************************************************************/
u8 metro_state::irq_cause_r(offs_t offset)
// This is for games that supply an *IRQ Vector* on the data bus together with an IRQ level for each possible IRQ source
void metro_state::ipl_w(u8 data)
{
/* interrupt cause, used by
int[0] vblank
int[1] hblank (bangball for faster intermission skip,
puzzli for gameplay water effect,
blzntrnd title screen scroll (enabled all the time then?),
unused/empty in balcube, daitoride, karatour,
unchecked mouja & other i4300 games )
int[2] blitter
int[3] ? KARATOUR
int[4] ?
int[5] ? KARATOUR, BLZNTRND
int[6] unused
int[7] unused
*/
u8 res = 0;
for (int i = 0; i < 8; i++)
res |= (m_requested_int[i] << i);
return res;
for (int i = 1; i < 8; i++)
m_maincpu->set_input_line(i, (i == data) ? ASSERT_LINE : CLEAR_LINE);
}
/* Update the IRQ state based on all possible causes */
void metro_state::update_irq_state()
{
/* Get the pending IRQs (only the enabled ones, e.g. where irq_enable is *0*) */
u8 irq = irq_cause_r(0) & ~*m_irq_enable;
if (m_irq_line == -1) /* mouja, gakusai, gakusai2, dokyusei, dokyusp */
{
/* This is for games that supply an *IRQ Vector* on the data bus together with an IRQ level for each possible IRQ source */
u8 irq_level[8] = { 0 };
int i;
for (i = 0; i < 8; i++)
if (BIT(irq, i))
irq_level[m_irq_levels[i] & 7] = 1;
for (i = 0; i < 8; i++)
m_maincpu->set_input_line(i, irq_level[i] ? ASSERT_LINE : CLEAR_LINE);
}
else
{
/* This is for games where every IRQ source generates the same IRQ level. The interrupt service routine
then reads the actual source by peeking a register (irq_cause_r) */
int irq_state = (irq ? ASSERT_LINE : CLEAR_LINE);
m_maincpu->set_input_line(m_irq_line, irq_state);
}
}
/* For games that supply an *IRQ Vector* on the data bus */
u8 metro_state::irq_vector_r(offs_t offset)
{
// logerror("%s: irq callback returns %04X\n", machine().describe_context(), m_irq_vectors[offset]);
return m_irq_vectors[offset] & 0xff;
}
void metro_state::cpu_space_map(address_map &map)
{
map(0xfffff0, 0xffffff).r(FUNC(metro_state::irq_vector_r)).umask16(0x00ff);
map(0xfffff0, 0xffffff).r(m_vdp3, FUNC(imagetek_i4300_device::irq_vector_r)).umask16(0x00ff);
}
void metro_state::irq_cause_w(offs_t offset, u8 data)
{
//if (data & ~0x15) logerror("CPU #0 PC %06X : unknown bits of irqcause written: %04X\n", m_maincpu->pc(), data);
data &= ~*m_irq_enable;
for (int i = 0; i < 8; i++)
if (BIT(data, i)) m_requested_int[i] = 0;
update_irq_state();
}
void metro_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case TIMER_KARATOUR_IRQ:
m_requested_int[5] = 0;
if (m_vdp) m_vdp->clear_irq(5);
if (m_vdp2) m_vdp2->clear_irq(5);
if (m_vdp3) m_vdp3->clear_irq(5);
break;
case TIMER_MOUJA_IRQ:
m_requested_int[0] = 1;
update_irq_state();
if (m_vdp) m_vdp->set_irq(0);
if (m_vdp2) m_vdp2->set_irq(0);
if (m_vdp3) m_vdp3->set_irq(0);
break;
default:
throw emu_fatalerror("Unknown id in metro_state::device_timer");
@ -217,8 +152,6 @@ WRITE_LINE_MEMBER(metro_state::vblank_irq)
{
if (state)
{
m_requested_int[m_vblank_bit] = 1;
update_irq_state();
if (m_vdp) m_vdp->screen_eof(state);
if (m_vdp2) m_vdp2->screen_eof(state);
if (m_vdp3) m_vdp3->screen_eof(state);
@ -227,8 +160,9 @@ WRITE_LINE_MEMBER(metro_state::vblank_irq)
INTERRUPT_GEN_MEMBER(metro_state::periodic_interrupt)
{
m_requested_int[4] = 1;
update_irq_state();
if (m_vdp) m_vdp->set_irq(4);
if (m_vdp2) m_vdp2->set_irq(4);
if (m_vdp3) m_vdp3->set_irq(4);
}
TIMER_DEVICE_CALLBACK_MEMBER(metro_state::bangball_scanline)
@ -238,18 +172,13 @@ TIMER_DEVICE_CALLBACK_MEMBER(metro_state::bangball_scanline)
// vblank irq
if(scanline == 224)
{
m_requested_int[m_vblank_bit] = 1;
m_requested_int[4] = 1; // ???
update_irq_state();
if (m_vdp) m_vdp->screen_eof(ASSERT_LINE);
if (m_vdp2) m_vdp2->screen_eof(ASSERT_LINE);
if (m_vdp3) m_vdp3->screen_eof(ASSERT_LINE);
m_vdp2->set_irq(4); // ???
m_vdp2->screen_eof(ASSERT_LINE);
}
else if(scanline < 224 && (*m_irq_enable & 2) == 0)
else if(scanline < 224 && (m_vdp2->irq_enable() & 2) == 0)
{
// pretty likely hblank irq (pressing a button when clearing a stage)
m_requested_int[1] = 1;
update_irq_state();
m_vdp2->set_irq(1);
}
}
@ -258,13 +187,12 @@ WRITE_LINE_MEMBER(metro_state::karatour_vblank_irq)
{
if (state)
{
m_requested_int[m_vblank_bit] = 1;
/* write to scroll registers, the duration is a guess */
m_karatour_irq_timer->adjust(attotime::from_usec(2500));
m_requested_int[5] = 1;
if (m_vdp) m_vdp->set_irq(5);
if (m_vdp2) m_vdp2->set_irq(5);
if (m_vdp3) m_vdp3->set_irq(5);
update_irq_state();
if (m_vdp) m_vdp->screen_eof(state);
if (m_vdp2) m_vdp2->screen_eof(state);
if (m_vdp3) m_vdp3->screen_eof(state);
@ -282,13 +210,9 @@ WRITE_LINE_MEMBER(metro_state::puzzlet_vblank_irq)
{
if (state)
{
m_requested_int[m_vblank_bit] = 1;
m_requested_int[5] = 1;
m_vdp2->set_irq(5);
update_irq_state();
if (m_vdp) m_vdp->screen_eof(state);
if (m_vdp2) m_vdp2->screen_eof(state);
if (m_vdp3) m_vdp3->screen_eof(state);
m_vdp2->screen_eof(state);
}
}
@ -487,12 +411,6 @@ void metro_state::coin_lockout_4words_w(offs_t offset, uint16_t data)
if (data & ~1) logerror("CPU #0 PC %06X : unknown bits of coin lockout written: %04X\n", m_maincpu->pc(), data);
}
WRITE_LINE_MEMBER(metro_state::vdp_blit_end_w)
{
m_requested_int[m_blitter_bit] = 1;
update_irq_state();
}
/***************************************************************************
@ -571,8 +489,6 @@ void metro_state::balcube_map(address_map &map)
map(0x500006, 0x500007).nopr(); //
map(0x500002, 0x500009).w(FUNC(metro_state::coin_lockout_4words_w)); // Coin Lockout
map(0x600000, 0x67ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x6788a3, 0x6788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x6788a4, 0x6788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0xf00000, 0xf0ffff).ram().mirror(0x0f0000); // RAM (mirrored)
}
@ -586,8 +502,6 @@ void metro_state::daitoa_map(address_map &map)
{
map(0x000000, 0x07ffff).rom(); // ROM
map(0x100000, 0x17ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x1788a3, 0x1788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x1788a4, 0x1788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x200000, 0x200001).portr("IN0"); // Inputs
map(0x200002, 0x200003).portr("IN1"); //
map(0x200006, 0x200007).nopr(); //
@ -614,8 +528,6 @@ void metro_state::bangball_map(address_map &map)
map(0xd00006, 0xd00007).nopr(); //
map(0xd00002, 0xd00009).w(FUNC(metro_state::coin_lockout_4words_w)); // Coin Lockout
map(0xe00000, 0xe7ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0xe788a3, 0xe788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0xe788a4, 0xe788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0xf00000, 0xf0ffff).ram().mirror(0x0f0000); // RAM (mirrored)
}
@ -628,8 +540,6 @@ void metro_state::batlbubl_map(address_map &map)
{
map(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x17ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x1788a3, 0x1788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x1788a4, 0x1788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x200000, 0x200001).portr("IN1"); // Inputs
map(0x200002, 0x200003).portr("DSW0"); //
map(0x200004, 0x200005).portr("IN0"); //
@ -650,8 +560,6 @@ void metro_state::msgogo_map(address_map &map)
{
map(0x000000, 0x07ffff).rom(); // ROM
map(0x100000, 0x17ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x1788a3, 0x1788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x1788a4, 0x1788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x200000, 0x200001).portr("COINS"); // Inputs
map(0x200002, 0x200003).portr("JOYS"); //
map(0x200006, 0x200007).nopr(); //
@ -670,8 +578,6 @@ void metro_state::daitorid_map(address_map &map)
{
map(0x000000, 0x03ffff).rom(); // ROM
map(0x400000, 0x47ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x4788a3, 0x4788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x4788a4, 0x4788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x4788a9, 0x4788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0x800000, 0x80ffff).ram().mirror(0x0f0000); // RAM (mirrored)
map(0xc00000, 0xc00001).portr("IN0");
@ -692,8 +598,6 @@ void metro_state::dharma_map(address_map &map)
map(0x000000, 0x03ffff).rom(); // ROM
map(0x400000, 0x40ffff).ram().mirror(0x0f0000); // RAM (mirrored)
map(0x800000, 0x87ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0xc00000, 0xc00001).portr("IN0");
map(0xc00001, 0xc00001).w(FUNC(metro_state::soundstatus_w)); // To Sound CPU
@ -719,8 +623,6 @@ void metro_state::karatour_map(address_map &map)
map(0x40000a, 0x40000b).portr("DSW1"); //
map(0x40000c, 0x40000d).portr("IN2"); //
map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4100_device::map));
map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0xf00000, 0xf0ffff).ram().mirror(0x0f0000); // RAM (mirrored)
}
@ -737,8 +639,6 @@ void metro_state::kokushi_map(address_map &map)
map(0x000000, 0x07ffff).rom(); // ROM
map(0x700000, 0x70ffff).ram().mirror(0x0f0000); // RAM (mirrored)
map(0x800000, 0x87ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0xc00000, 0xc00001).portr("IN0");
map(0xc00001, 0xc00001).w(FUNC(metro_state::soundstatus_w)); // To Sound CPU
@ -757,8 +657,6 @@ void metro_state::lastfort_map(address_map &map)
map(0x000000, 0x03ffff).rom(); // ROM
map(0x400000, 0x40ffff).ram().mirror(0x0f0000); // RAM (mirrored)
map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4100_device::map));
map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0xc00001, 0xc00001).rw(FUNC(metro_state::soundstatus_r), FUNC(metro_state::soundstatus_w)); // From / To Sound CPU
map(0xc00003, 0xc00003).w(FUNC(metro_state::coin_lockout_1word_w)); // Coin Lockout
@ -784,8 +682,6 @@ void metro_state::lastforg_map(address_map &map)
map(0x40000a, 0x40000b).portr("DSW1"); //
map(0x40000c, 0x40000d).portr("IN2"); //
map(0x880000, 0x8fffff).m(m_vdp, FUNC(imagetek_i4100_device::map));
map(0x8f88a3, 0x8f88a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x8f88a4, 0x8f88a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x8f88a9, 0x8f88a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0xc00000, 0xc0ffff).ram().mirror(0x0f0000); // RAM (mirrored)
}
@ -847,10 +743,6 @@ void metro_state::gakusai_map(address_map &map)
{
map(0x000000, 0x07ffff).rom(); // ROM
map(0x200000, 0x27ffff).m(m_vdp3, FUNC(imagetek_i4300_device::v3_map));
map(0x278810, 0x27881f).writeonly().share("irq_levels"); // IRQ Levels
map(0x278820, 0x27882f).writeonly().share("irq_vectors"); // IRQ Vectors
map(0x278830, 0x278831).writeonly().share("irq_enable"); // IRQ Enable
map(0x278833, 0x278833).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x278836, 0x278837).nopr().w("watchdog", FUNC(watchdog_timer_device::reset16_w));
map(0x278880, 0x278881).r(FUNC(metro_state::gakusai_input_r)); // Inputs
map(0x278882, 0x278883).portr("IN0"); //
@ -873,10 +765,6 @@ void metro_state::gakusai2_map(address_map &map)
{
map(0x000000, 0x07ffff).rom(); // ROM
map(0x600000, 0x67ffff).m(m_vdp3, FUNC(imagetek_i4300_device::v3_map));
map(0x678810, 0x67881f).writeonly().share("irq_levels"); // IRQ Levels
map(0x678820, 0x67882f).writeonly().share("irq_vectors"); // IRQ Vectors
map(0x678830, 0x678831).writeonly().share("irq_enable"); // IRQ Enable
map(0x678833, 0x678833).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x678836, 0x678837).nopr().w("watchdog", FUNC(watchdog_timer_device::reset16_w));
map(0x678880, 0x678881).r(FUNC(metro_state::gakusai_input_r)); // Inputs
map(0x678882, 0x678883).portr("IN0"); //
@ -924,10 +812,6 @@ void metro_state::dokyusp_map(address_map &map)
{
map(0x000000, 0x03ffff).rom(); // ROM
map(0x200000, 0x27ffff).m(m_vdp3, FUNC(imagetek_i4300_device::v3_map));
map(0x278810, 0x27881f).writeonly().share("irq_levels"); // IRQ Levels
map(0x278820, 0x27882f).writeonly().share("irq_vectors"); // IRQ Vectors
map(0x278830, 0x278831).writeonly().share("irq_enable"); // IRQ Enable
map(0x278833, 0x278833).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x278836, 0x278837).w("watchdog", FUNC(watchdog_timer_device::reset16_w));
map(0x278880, 0x278881).r(FUNC(metro_state::gakusai_input_r)); // Inputs
map(0x278882, 0x278883).portr("IN0"); //
@ -950,11 +834,6 @@ void metro_state::dokyusei_map(address_map &map)
{
map(0x000000, 0x03ffff).rom(); // ROM
map(0x400000, 0x47ffff).m(m_vdp3, FUNC(imagetek_i4300_device::v3_map));
map(0x478810, 0x47881f).writeonly().share("irq_levels"); // IRQ Levels
map(0x478820, 0x47882f).writeonly().share("irq_vectors"); // IRQ Vectors
map(0x478830, 0x478831).writeonly().share("irq_enable"); // IRQ Enable
// map(0x478833, 0x478833).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)) // IRQ Cause
map(0x478833, 0x478833).w(FUNC(metro_state::irq_cause_w)); // IRQ Acknowledge
map(0x478836, 0x478837).nopw(); // ? watchdog ?
map(0x478880, 0x478881).r(FUNC(metro_state::gakusai_input_r)); // Inputs
map(0x478882, 0x478883).portr("IN0"); //
@ -978,8 +857,6 @@ void metro_state::pangpoms_map(address_map &map)
{
map(0x000000, 0x03ffff).rom(); // ROM
map(0x400000, 0x47ffff).m(m_vdp, FUNC(imagetek_i4100_device::map));
map(0x4788a3, 0x4788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x4788a4, 0x4788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x4788a9, 0x4788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0x800001, 0x800001).rw(FUNC(metro_state::soundstatus_r), FUNC(metro_state::soundstatus_w)); // From / To Sound CPU
map(0x800002, 0x800003).nopr();
@ -1009,8 +886,6 @@ void metro_state::poitto_map(address_map &map)
map(0x800006, 0x800007).portr("IN2"); //
map(0x800002, 0x800009).w(FUNC(metro_state::coin_lockout_4words_w)); // Coin Lockout
map(0xc00000, 0xc7ffff).m(m_vdp, FUNC(imagetek_i4100_device::map));
map(0xc788a3, 0xc788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0xc788a4, 0xc788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0xc788a9, 0xc788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
}
@ -1032,8 +907,6 @@ void metro_state::skyalert_map(address_map &map)
map(0x40000c, 0x40000d).portr("DSW1"); //
map(0x40000e, 0x40000f).portr("IN3"); //
map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4100_device::map));
map(0x8788a3, 0x8788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x8788a4, 0x8788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x8788a9, 0x8788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
map(0xc00000, 0xc0ffff).ram().mirror(0x0f0000); // RAM (mirrored)
}
@ -1054,8 +927,6 @@ void metro_state::pururun_map(address_map &map)
map(0x400002, 0x400009).w(FUNC(metro_state::coin_lockout_4words_w)); // Coin Lockout
map(0x800000, 0x80ffff).ram().mirror(0x0f0000); // RAM (mirrored)
map(0xc00000, 0xc7ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0xc788a3, 0xc788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0xc788a4, 0xc788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0xc788a9, 0xc788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
}
@ -1075,8 +946,6 @@ void metro_state::toride2g_map(address_map &map)
map(0x800006, 0x800007).portr("IN2"); //
map(0x800002, 0x800009).w(FUNC(metro_state::coin_lockout_4words_w)); // Coin Lockout
map(0xc00000, 0xc7ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0xc788a3, 0xc788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0xc788a4, 0xc788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0xc788a9, 0xc788a9).w(FUNC(metro_state::sound_data_w)); // To Sound CPU
}
@ -1109,8 +978,6 @@ void metro_state::blzntrnd_map(address_map &map)
{
map(0x000000, 0x1fffff).rom(); // ROM
map(0x200000, 0x27ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x2788a3, 0x2788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x2788a4, 0x2788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x400000, 0x43ffff).ram().w(FUNC(metro_state::k053936_w)).share("k053936_ram"); // 053936
map(0x500000, 0x500fff).w(m_k053936, FUNC(k053936_device::linectrl_w)); // 053936 line control
@ -1139,10 +1006,6 @@ void metro_state::mouja_map(address_map &map)
{
map(0x000000, 0x07ffff).rom(); // ROM
map(0x400000, 0x47ffff).m(m_vdp3, FUNC(imagetek_i4300_device::v3_map));
map(0x478810, 0x47881f).writeonly().share("irq_levels"); // IRQ Levels
map(0x478820, 0x47882f).writeonly().share("irq_vectors"); // IRQ Vectors
map(0x478830, 0x478831).writeonly().share("irq_enable"); // IRQ Enable
map(0x478833, 0x478833).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x478834, 0x478835).w(FUNC(metro_state::mouja_irq_timer_ctrl_w)); // IRQ set timer count
map(0x478836, 0x478837).w("watchdog", FUNC(watchdog_timer_device::reset16_w));
map(0x478880, 0x478881).portr("IN0"); // Inputs
@ -1166,10 +1029,9 @@ void metro_state::mouja_okimap(address_map &map)
Puzzlet
***************************************************************************/
void metro_state::puzzlet_irq_enable_w(offs_t offset, uint16_t data, uint16_t mem_mask)
void metro_state::puzzlet_irq_enable_w(uint8_t data)
{
if (ACCESSING_BITS_0_7)
*m_irq_enable = data ^ 0xffff;
m_vdp2->irq_enable_w(data ^ 0xff);
}
@ -1185,8 +1047,7 @@ void metro_state::puzzlet_map(address_map &map)
// TODO: !!! i4300 !!!
map(0x700000, 0x77ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x7788a3, 0x7788a3).w(FUNC(metro_state::irq_cause_w)); // IRQ Cause
map(0x7788a4, 0x7788a5).w(FUNC(metro_state::puzzlet_irq_enable_w)).share("irq_enable"); // IRQ Enable
map(0x7788a5, 0x7788a5).w(FUNC(metro_state::puzzlet_irq_enable_w)); // IRQ Enable
map(0x7f2000, 0x7f3fff).ram();
@ -1194,7 +1055,7 @@ void metro_state::puzzlet_map(address_map &map)
map(0x7f8884, 0x7f8885).portr("DSW0");
map(0x7f8886, 0x7f8887).portr("DSW0");
map(0x7f88a2, 0x7f88a3).r(FUNC(metro_state::irq_cause_r)); // IRQ Cause
map(0x7f88a3, 0x7f88a3).r(m_vdp2, FUNC(imagetek_i4220_device::irq_cause_r));
}
@ -1253,8 +1114,6 @@ void metro_state::vmetal_map(address_map &map)
{
map(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x17ffff).m(m_vdp2, FUNC(imagetek_i4220_device::v2_map));
map(0x1788a3, 0x1788a3).rw(FUNC(metro_state::irq_cause_r), FUNC(metro_state::irq_cause_w)); // IRQ Cause / IRQ Acknowledge
map(0x1788a4, 0x1788a5).writeonly().share("irq_enable"); // IRQ Enable
map(0x200000, 0x200001).portr("P1_P2");
map(0x200001, 0x200001).w(FUNC(metro_state::vmetal_control_w));
map(0x200002, 0x200003).portr("SYSTEM");
@ -2932,9 +2791,6 @@ GFXDECODE_END
void metro_state::machine_start()
{
save_item(NAME(m_blitter_bit));
save_item(NAME(m_irq_line));
save_item(NAME(m_requested_int));
save_item(NAME(m_sound_data));
save_item(NAME(m_soundstatus));
save_item(NAME(m_porta));
@ -2947,7 +2803,8 @@ void metro_state::machine_start()
void metro_state::i4100_config(machine_config &config)
{
I4100(config, m_vdp, 26.666_MHz_XTAL);
m_vdp->blit_irq_cb().set(FUNC(metro_state::vdp_blit_end_w));
m_vdp->set_vblank_irq_level(0);
m_vdp->set_blit_irq_level(2);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(58.2328); // VSync 58.2328Hz, HSync 15.32kHz
@ -2960,7 +2817,8 @@ void metro_state::i4100_config(machine_config &config)
void metro_state::i4220_config(machine_config &config)
{
I4220(config, m_vdp2, 26.666_MHz_XTAL);
m_vdp2->blit_irq_cb().set(FUNC(metro_state::vdp_blit_end_w));
m_vdp2->set_vblank_irq_level(0);
m_vdp2->set_blit_irq_level(2);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(58.2328); // VSync 58.2328Hz, HSync 15.32kHz
@ -2973,7 +2831,8 @@ void metro_state::i4220_config(machine_config &config)
void metro_state::i4300_config(machine_config &config)
{
I4300(config, m_vdp3, 26.666_MHz_XTAL);
m_vdp3->blit_irq_cb().set(FUNC(metro_state::vdp_blit_end_w));
m_vdp3->set_vblank_irq_level(1);
m_vdp3->set_blit_irq_level(2);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(58.2328); // VSync 58.2328Hz, HSync 15.32kHz
@ -3034,6 +2893,7 @@ void metro_state::msgogo(machine_config &config)
/* video hardware */
i4220_config(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_1);
m_vdp2->set_tmap_xoffsets(-2,-2,-2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq)); // timing is off, shaking sprites in intro
@ -3043,7 +2903,7 @@ void metro_state::msgogo(machine_config &config)
ymf278b_device &ymf(YMF278B(config, "ymf", 33.8688_MHz_XTAL));
ymf.set_addrmap(0, &metro_state::ymf278_map);
ymf.irq_handler().set_inputline("maincpu", 2);
ymf.irq_handler().set_inputline("maincpu", M68K_IRQ_2);
ymf.add_route(ALL_OUTPUTS, "mono", 1.0);
}
@ -3122,6 +2982,7 @@ void metro_state::daitorid(machine_config &config)
/* video hardware */
i4220_config(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_vdp2->set_tmap_xoffsets(-2,-2,-2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3166,6 +3027,7 @@ void metro_state::dharma(machine_config &config)
/* video hardware */
i4220_config(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3190,6 +3052,7 @@ void metro_state::karatour(machine_config &config)
/* video hardware */
i4100_config(config);
m_vdp->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::karatour_vblank_irq));
@ -3214,6 +3077,7 @@ void metro_state::sankokushi(machine_config &config)
/* video hardware */
i4220_config_320x240(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::karatour_vblank_irq));
@ -3239,6 +3103,7 @@ void metro_state::lastfort(machine_config &config)
/* video hardware */
i4100_config_360x224(config);
m_vdp->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3262,6 +3127,7 @@ void metro_state::lastforg(machine_config &config)
metro_upd7810_sound(config);
i4100_config_360x224(config);
m_vdp->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::karatour_vblank_irq));
@ -3284,6 +3150,8 @@ void metro_state::dokyusei(machine_config &config)
/* video hardware */
i4300_config(config);
m_vdp3->irq_cb().set(FUNC(metro_state::ipl_w));
m_vdp3->set_blit_irq_level(3);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3310,6 +3178,8 @@ void metro_state::dokyusp(machine_config &config)
/* video hardware */
i4300_config_384x224(config);
m_vdp3->irq_cb().set(FUNC(metro_state::ipl_w));
m_vdp3->set_blit_irq_level(3);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3336,6 +3206,8 @@ void metro_state::gakusai(machine_config &config)
/* video hardware */
i4300_config_320x240(config);
m_vdp3->irq_cb().set(FUNC(metro_state::ipl_w));
m_vdp3->set_blit_irq_level(3);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3362,6 +3234,8 @@ void metro_state::gakusai2(machine_config &config)
/* video hardware */
i4300_config_320x240(config);
m_vdp3->irq_cb().set(FUNC(metro_state::ipl_w));
m_vdp3->set_blit_irq_level(3);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3386,6 +3260,7 @@ void metro_state::pangpoms(machine_config &config)
/* video hardware */
i4100_config_360x224(config);
m_vdp->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3410,6 +3285,7 @@ void metro_state::poitto(machine_config &config)
/* video hardware */
i4100_config_360x224(config);
m_vdp->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3434,6 +3310,7 @@ void metro_state::pururun(machine_config &config)
/* video hardware */
i4220_config(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3459,6 +3336,7 @@ void metro_state::skyalert(machine_config &config)
metro_upd7810_sound(config);
i4100_config_360x224(config);
m_vdp->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3484,6 +3362,7 @@ void metro_state::toride2g(machine_config &config)
/* video hardware */
i4220_config(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_2);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3509,6 +3388,7 @@ void metro_state::mouja(machine_config &config)
/* video hardware */
i4300_config(config);
m_vdp3->irq_cb().set(FUNC(metro_state::ipl_w));
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3532,6 +3412,7 @@ void metro_state::vmetal(machine_config &config)
/* video hardware */
i4220_config_304x224(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_1);
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
@ -3569,7 +3450,9 @@ void metro_state::blzntrnd(machine_config &config)
/* video hardware */
I4220(config, m_vdp2, 26.666_MHz_XTAL);
m_vdp2->blit_irq_cb().set(FUNC(metro_state::vdp_blit_end_w));
m_vdp2->irq_cb().set_inputline(m_maincpu, M68K_IRQ_1);
m_vdp2->set_vblank_irq_level(0);
m_vdp2->set_blit_irq_level(3);
m_vdp2->set_spriteram_buffered(true); // sprites are 1 frame delayed
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
@ -3645,6 +3528,9 @@ void metro_state::puzzlet(machine_config &config)
/* video hardware */
// TODO: looks like game is running in i4220 compatibilty mode, $778000 seems to be an id for the chip?
i4220_config(config);
m_vdp2->irq_cb().set_inputline(m_maincpu, 0);
m_vdp2->set_vblank_irq_level(1);
m_vdp2->set_blit_irq_level(3);
m_screen->screen_vblank().set(FUNC(metro_state::puzzlet_vblank_irq));
@ -5488,20 +5374,8 @@ ROM_END
***************************************************************************/
void metro_state::metro_common( )
{
std::fill(std::begin(m_requested_int), std::end(m_requested_int), 0);
m_vblank_bit = 0;
m_blitter_bit = 2;
m_irq_line = 2;
*m_irq_enable = 0;
}
void metro_state::init_metro()
{
metro_common();
if (m_audiobank.found())
{
m_audiobank->configure_entries(0, 8, memregion("audiocpu")->base(), 0x4000);
@ -5531,9 +5405,6 @@ void metro_state::init_balcube()
{
ROM[i] = bitswap<8>(ROM[i],0,1,2,3,4,5,6,7);
}
metro_common();
m_irq_line = 1;
}
@ -5556,46 +5427,22 @@ void metro_state::init_dharmak()
void metro_state::init_blzntrnd()
{
metro_common();
m_irq_line = 1;
m_audiobank->configure_entries(0, 8, memregion("audiocpu")->base(), 0x4000);
m_karatour_irq_timer = timer_alloc(TIMER_KARATOUR_IRQ);
}
void metro_state::init_vmetal()
{
metro_common();
m_irq_line = 1;
m_essnd_gate = false;
save_item(NAME(m_essnd_gate));
}
void metro_state::init_mouja()
{
metro_common();
m_irq_line = -1; /* split interrupt handlers */
m_vblank_bit = 1;
m_mouja_irq_timer = timer_alloc(TIMER_MOUJA_IRQ);
m_okibank->configure_entries(0, 8, memregion("oki")->base(), 0x20000);
}
void metro_state::init_gakusai()
{
metro_common();
m_irq_line = -1;
m_vblank_bit = 1;
m_blitter_bit = 3;
}
void metro_state::init_puzzlet()
{
metro_common();
m_irq_line = 0;
m_vblank_bit = 1;
m_blitter_bit = 3;
}
void metro_state::init_lastfortg()
{
init_metro();
@ -5652,11 +5499,11 @@ GAME( 1996, bangball, 0, bangball, bangball, metro_state, init_balcub
GAME( 1999, batlbubl, bangball, batlbubl, batlbubl, metro_state, init_balcube, ROT0, "Banpresto (Limenko license?)", "Battle Bubble (v2.00)", MACHINE_SUPPORTS_SAVE ) // or bootleg?
// VG330 / VG340 / VG410
GAME( 1995, dokyusei, 0, dokyusei, dokyusei, metro_state, init_gakusai, ROT0, "Make Software / Elf / Media Trading", "Mahjong Doukyuusei", MACHINE_SUPPORTS_SAVE )
GAME( 1995, dokyusp, 0, dokyusp, gakusai, metro_state, init_gakusai, ROT0, "Make Software / Elf / Media Trading", "Mahjong Doukyuusei Special", MACHINE_SUPPORTS_SAVE )
GAME( 1995, dokyusei, 0, dokyusei, dokyusei, metro_state, empty_init, ROT0, "Make Software / Elf / Media Trading", "Mahjong Doukyuusei", MACHINE_SUPPORTS_SAVE )
GAME( 1995, dokyusp, 0, dokyusp, gakusai, metro_state, empty_init, ROT0, "Make Software / Elf / Media Trading", "Mahjong Doukyuusei Special", MACHINE_SUPPORTS_SAVE )
GAME( 1996, mouja, 0, mouja, mouja, metro_state, init_mouja, ROT0, "Etona", "Mouja (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1997, gakusai, 0, gakusai, gakusai, metro_state, init_gakusai, ROT0, "MakeSoft", "Mahjong Gakuensai (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1998, gakusai2, 0, gakusai2, gakusai, metro_state, init_gakusai, ROT0, "MakeSoft", "Mahjong Gakuensai 2 (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1997, gakusai, 0, gakusai, gakusai, metro_state, empty_init, ROT0, "MakeSoft", "Mahjong Gakuensai (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1998, gakusai2, 0, gakusai2, gakusai, metro_state, empty_init, ROT0, "MakeSoft", "Mahjong Gakuensai 2 (Japan)", MACHINE_SUPPORTS_SAVE )
// HUM-002 / HUM-003
GAME( 1994, blzntrnd, 0, blzntrnd, blzntrnd, metro_state, init_blzntrnd, ROT0, "Human Amusement", "Blazing Tornado", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
@ -5668,5 +5515,5 @@ GAME( 1995, vmetal, 0, vmetal, vmetal, metro_state, init_vmetal
GAME( 1995, vmetaln, vmetal, vmetal, vmetal, metro_state, init_vmetal, ROT90, "Excellent System (New Ways Trading Co. license)", "Varia Metal (New Ways Trading Co.)", MACHINE_SUPPORTS_SAVE )
// VG2200
GAME( 2000, puzzlet, 0, puzzlet, puzzlet, metro_state, init_puzzlet, ROT0, "Unies Corporation", "Puzzlet (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 2001, metabee, 0, puzzlet, puzzlet, metro_state, init_puzzlet, ROT0, "Natsume / Banpresto", "Metabee Shot", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) // Hopper problem
GAME( 2000, puzzlet, 0, puzzlet, puzzlet, metro_state, empty_init, ROT0, "Unies Corporation", "Puzzlet (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 2001, metabee, 0, puzzlet, puzzlet, metro_state, empty_init, ROT0, "Natsume / Banpresto", "Metabee Shot", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) // Hopper problem

View File

@ -39,9 +39,6 @@ public:
, m_gfxdecode(*this, "gfxdecode")
, m_screen(*this, "screen")
, m_soundlatch(*this, "soundlatch")
, m_irq_enable(*this, "irq_enable")
, m_irq_levels(*this, "irq_levels")
, m_irq_vectors(*this, "irq_vectors")
, m_input_sel(*this, "input_sel")
, m_k053936_ram(*this, "k053936_ram")
, m_audiobank(*this, "audiobank")
@ -91,9 +88,7 @@ public:
void init_vmetal();
void init_mouja();
void init_balcube();
void init_gakusai();
void init_dharmak();
void init_puzzlet();
void init_metro();
void init_lastfortg();
@ -106,9 +101,7 @@ private:
TIMER_MOUJA_IRQ
};
u8 irq_cause_r(offs_t offset);
void irq_cause_w(offs_t offset, u8 data);
u8 irq_vector_r(offs_t offset);
void ipl_w(u8 data);
void mouja_irq_timer_ctrl_w(uint16_t data);
void sound_data_w(u8 data);
TIMER_CALLBACK_MEMBER(sound_data_sync);
@ -124,7 +117,7 @@ private:
uint16_t balcube_dsw_r(offs_t offset);
uint16_t gakusai_input_r();
void blzntrnd_sh_bankswitch_w(u8 data);
void puzzlet_irq_enable_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void puzzlet_irq_enable_w(uint8_t data);
void puzzlet_portb_w(uint16_t data);
void k053936_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void gakusai_oki_bank_hi_w(u8 data);
@ -135,7 +128,6 @@ private:
void dokyusp_eeprom_bit_w(u8 data);
void dokyusp_eeprom_reset_w(u8 data);
void mouja_sound_rombank_w(u8 data);
DECLARE_WRITE_LINE_MEMBER(vdp_blit_end_w);
// vmetal
void vmetal_control_w(u8 data);
@ -207,9 +199,6 @@ private:
optional_device<generic_latch_8_device> m_soundlatch;
/* memory pointers */
optional_shared_ptr<uint16_t> m_irq_enable;
optional_shared_ptr<uint16_t> m_irq_levels;
optional_shared_ptr<uint16_t> m_irq_vectors;
optional_shared_ptr<uint16_t> m_input_sel;
optional_shared_ptr<uint16_t> m_k053936_ram;
@ -220,10 +209,6 @@ private:
tilemap_t *m_k053936_tilemap;
/* irq_related */
int m_vblank_bit;
int m_blitter_bit;
int m_irq_line;
u8 m_requested_int[8];
emu_timer *m_mouja_irq_timer;
emu_timer *m_karatour_irq_timer;
@ -240,8 +225,6 @@ private:
int m_gakusai_oki_bank_lo;
int m_gakusai_oki_bank_hi;
void update_irq_state();
void metro_common();
void gakusai_oki_bank_set();
};