From 5bf3dbd3a49974fcec742a60f8b40eecd4a7db26 Mon Sep 17 00:00:00 2001 From: AJR Date: Sat, 9 Jan 2021 12:26:37 -0500 Subject: [PATCH] metro.cpp, hyprduel.cpp: Move interrupt control (mostly) down into VDP --- src/devices/video/imagetek_i4100.cpp | 140 ++++++++++++- src/devices/video/imagetek_i4100.h | 34 +++- src/mame/drivers/hyprduel.cpp | 78 ++------ src/mame/drivers/metro.cpp | 289 +++++++-------------------- src/mame/includes/metro.h | 21 +- 5 files changed, 255 insertions(+), 307 deletions(-) diff --git a/src/devices/video/imagetek_i4100.cpp b/src/devices/video/imagetek_i4100.cpp index cba8a4b4034..f760f148254 100644 --- a/src/devices/video/imagetek_i4100.cpp +++ b/src/devices/video/imagetek_i4100.cpp @@ -71,6 +71,12 @@ #include +#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(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); - m_spriteram->copy(); + if (m_spriteram_buffered) + m_spriteram->copy(); } } diff --git a/src/devices/video/imagetek_i4100.h b/src/devices/video/imagetek_i4100.h index b0888686604..35b3116a611 100644 --- a/src/devices/video/imagetek_i4100.h +++ b/src/devices/video/imagetek_i4100.h @@ -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 m_vram; required_shared_ptr m_scratchram; required_shared_ptr m_blitter_regs; @@ -81,7 +92,12 @@ protected: std::unique_ptr 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 diff --git a/src/mame/drivers/hyprduel.cpp b/src/mame/drivers/hyprduel.cpp index 320c6e318c7..64707e3469d 100644 --- a/src/mame/drivers/hyprduel.cpp +++ b/src/mame/drivers/hyprduel.cpp @@ -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 m_irq_enable; required_shared_ptr_array 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 m_maincpu; required_device m_subcpu; required_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 ) diff --git a/src/mame/drivers/metro.cpp b/src/mame/drivers/metro.cpp index ffbbd321ca7..8cc7bbe8cf6 100644 --- a/src/mame/drivers/metro.cpp +++ b/src/mame/drivers/metro.cpp @@ -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 diff --git a/src/mame/includes/metro.h b/src/mame/includes/metro.h index e654f6bdc68..ac849b894f5 100644 --- a/src/mame/includes/metro.h +++ b/src/mame/includes/metro.h @@ -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 m_soundlatch; /* memory pointers */ - optional_shared_ptr m_irq_enable; - optional_shared_ptr m_irq_levels; - optional_shared_ptr m_irq_vectors; optional_shared_ptr m_input_sel; optional_shared_ptr 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(); };