summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Angelo Salese <angelosa@users.noreply.github.com>2025-08-13 15:36:06 +0200
committer GitHub <noreply@github.com>2025-08-13 15:36:06 +0200
commitdf4120631a31148c2cfb820ab2ff87e9a2799843 (patch)
tree2472451bc6c3c25a2a4689afff9cc3fb0367ff32
parent6b8d54b34a62c425c799b2b3d8ef2be20ef85e56 (diff)
sega/megadriv.cpp: replace irq_callback with vpa_after / vpa_sync cpu_space_map (#14038)
* video/315_5313.cpp: make VDP irq enable times more deterministic Software list items promoted to working --------------------------------------- megadriv: Fatal Rewind, Sesame Street Counting Cafe
-rw-r--r--hash/megadriv.xml19
-rw-r--r--src/devices/video/315_5313.cpp46
-rw-r--r--src/devices/video/315_5313.h19
-rw-r--r--src/mame/sega/calcune.cpp61
-rw-r--r--src/mame/sega/megadriv.cpp59
-rw-r--r--src/mame/sega/megadriv.h7
-rw-r--r--src/mame/sega/segac2.cpp45
-rw-r--r--src/mame/sega/segas18.cpp4
8 files changed, 134 insertions, 126 deletions
diff --git a/hash/megadriv.xml b/hash/megadriv.xml
index c56c4b54c41..aa1a1682880 100644
--- a/hash/megadriv.xml
+++ b/hash/megadriv.xml
@@ -3055,14 +3055,11 @@ No [VDP] sprites
<!-- This was marked as rev. A on the EA sticker, but its header (and ROM markings) uses the Jpn title... weird situation :-) -->
- <software name="fatalrewa" cloneof="fatalrew" supported="no">
+ <software name="fatalrewa" cloneof="fatalrew" supported="yes">
<!-- Originally marked as Fatal Rewind, boots as The Killing Game Show -->
<description>The Killing Game Show (Europe)</description>
<year>1991</year>
<publisher>Electronic Arts</publisher>
- <notes><![CDATA[
-Crashes after EA logo, requires better [VDP] irq handling
-]]></notes>
<part name="cart" interface="megadriv_cart">
<feature name="pcb" value="PWB SC40X1 REV B"/>
<feature name="u1" value="KILLING GAME SHOW KIL03"/> <!-- location not really marked on PCB, using u1 for consistency -->
@@ -3074,13 +3071,10 @@ Crashes after EA logo, requires better [VDP] irq handling
<!-- Only Euro is confirmed -->
- <software name="fatalrew" supported="no">
+ <software name="fatalrew" supported="yes">
<description>Fatal Rewind (Europe, USA, rev. A)</description>
<year>1991</year>
<publisher>Electronic Arts</publisher>
- <notes><![CDATA[
-Crashes after EA logo, requires better [VDP] irq handling
-]]></notes>
<part name="cart" interface="megadriv_cart">
<feature name="pcb" value="PWB SC40X1 REV B"/>
<feature name="u1" value="FATAL REWIND FAT04"/> <!-- location not really marked on PCB, using u1 for consistency -->
@@ -17742,12 +17736,12 @@ https://segaretro.org/Elitserien_96
</part>
</software>
- <software name="killshow" cloneof="fatalrew" supported="no">
+ <software name="killshow" cloneof="fatalrew" supported="partial">
<description>The Killing Game Show (Japan)</description>
<year>1993</year>
<publisher>Electronic Arts Victor</publisher>
<notes><![CDATA[
-Crashes after EA logo, requires better [VDP] irq handling
+No sound in intro opening (verify)
]]></notes>
<info name="serial" value="EM20021"/>
<info name="release" value="19930820"/>
@@ -27237,13 +27231,10 @@ Throws "this game is [...] european megadrive system" even with megadriv system
</part>
</software>
- <software name="sesame" supported="no">
+ <software name="sesame" supported="yes">
<description>Sesame Street Counting Cafe (USA)</description>
<year>1994</year>
<publisher>Electronic Arts</publisher>
- <notes><![CDATA[
-Black screen, requires better [VDP] irq handling
-]]></notes>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="1048576">
<rom name="sesame street counting cafe (usa).bin" size="1048576" crc="0a4f48c3" sha1="d5ef2b50cf1a22e07401f6a14c7946df66d8b605"/>
diff --git a/src/devices/video/315_5313.cpp b/src/devices/video/315_5313.cpp
index 86c3436de01..e42e322ec94 100644
--- a/src/devices/video/315_5313.cpp
+++ b/src/devices/video/315_5313.cpp
@@ -585,30 +585,37 @@ void sega315_5313_device::vdp_set_register(int regnum, u8 value)
{
//osd_printf_debug("setting reg 0, irq enable is now %d\n", MEGADRIVE_REG0_IRQ4_ENABLE);
- // fatalrew and sesame are very fussy about pending interrupts.
- // Former in particular will quickly enable both after the EA logo (cfr. killshow at PC=0x2267a),
- // and irq 6 will jump to illegal addresses because the correlated routine isn't set in stack
- // but delayed a bit.
- // Note that irq 6 is masked for about 5 frames, leaving the assumption that it mustn't
- // be left on during all this time.
- if (m_irq4_pending)
+ // fatalrew/killshow and sesame are very fussy about pending interrupts.
+ // https://jsgroth.dev/blog/posts/emulator-bugs-fatal-rewind/
+ // https://gendev.spritesmind.net/forum/viewtopic.php?t=2202
+ // this gets 1 cycle delay on both HINT and VINT for gen_test_int_delay.bin
+ // TODO: first time around said test prints HINT=20, pressing start gives the correct value
+ if (m_irq4_pending && MEGADRIVE_REG0_IRQ4_ENABLE)
{
- if (MEGADRIVE_REG0_IRQ4_ENABLE)
- m_lv4irqline_callback(true);
- else
- m_lv4irqline_callback(false);
+ m_irq4_on_timer->adjust(attotime::from_ticks(16, clock() / 4));
+// if (MEGADRIVE_REG0_IRQ4_ENABLE)
+// m_lv4irqline_callback(true);
+// else
+// m_lv4irqline_callback(false);
}
+ else
+ m_lv4irqline_callback(false);
+
}
if (regnum == 0x01)
{
- if (m_irq6_pending)
+ if (m_irq6_pending && MEGADRIVE_REG01_IRQ6_ENABLE)
{
- if (MEGADRIVE_REG01_IRQ6_ENABLE)
- m_lv6irqline_callback(true);
- else
- m_lv6irqline_callback(false);
+ m_irq6_on_timer->adjust(attotime::from_ticks(16, clock() / 4));
+
+// if (MEGADRIVE_REG01_IRQ6_ENABLE)
+// m_lv6irqline_callback(true);
+// else
+// m_lv6irqline_callback(false);
}
+ else
+ m_lv6irqline_callback(false);
}
// if (regnum == 0x0a)
@@ -2254,7 +2261,7 @@ void sega315_5313_device::vdp_handle_scanline_callback(int scanline)
if (get_scanline_counter() == m_irq6_scanline)
{
// osd_printf_debug("x %d", get_scanline_counter());
- m_irq6_on_timer->adjust(attotime::from_usec(6));
+ m_irq6_on_timer->adjust(attotime::from_ticks(16, clock() / 4));
m_irq6_pending = 1;
m_vblank_flag = 1;
@@ -2276,8 +2283,7 @@ void sega315_5313_device::vdp_handle_scanline_callback(int scanline)
if (MEGADRIVE_REG0_IRQ4_ENABLE)
{
- // TODO: arbitrary timing
- m_irq4_on_timer->adjust(attotime::from_usec(1));
+ m_irq4_on_timer->adjust(attotime::from_ticks(16, clock() / 4));
//osd_printf_debug("irq4 on scanline %d reload %d\n", get_scanline_counter(), MEGADRIVE_REG0A_HINT_VALUE);
}
else
@@ -2320,7 +2326,7 @@ void sega315_5313_device::vdp_handle_eof()
m_vblank_flag = 0;
// Not here, breaks warlock
- //m_irq6_pending = 0;
+// m_irq6_pending = 0;
/* Set it to -1 here, so it becomes 0 when the first timer kicks in */
if (!m_use_alt_timing) m_scanline_counter = -1;
diff --git a/src/devices/video/315_5313.h b/src/devices/video/315_5313.h
index 188eac08406..f631bff7f9a 100644
--- a/src/devices/video/315_5313.h
+++ b/src/devices/video/315_5313.h
@@ -29,8 +29,8 @@ public:
typedef device_delegate<void (int scanline)> md_32x_scanline_helper_delegate;
auto snd_irq() { return m_sndirqline_callback.bind(); }
- auto lv6_irq() { return m_lv6irqline_callback.bind(); }
- auto lv4_irq() { return m_lv4irqline_callback.bind(); }
+ auto vint_cb() { return m_lv6irqline_callback.bind(); }
+ auto hint_cb() { return m_lv4irqline_callback.bind(); }
void set_lcm_scaling(bool lcm_scaling) { m_lcm_scaling = lcm_scaling; }
void set_alt_timing(int use_alt_timing) { m_use_alt_timing = use_alt_timing; }
@@ -73,8 +73,19 @@ public:
TIMER_CALLBACK_MEMBER(irq4_on_timer_callback);
void vdp_handle_eof();
void device_reset_old();
- void vdp_clear_irq6_pending() { m_irq6_pending = 0; }
- void vdp_clear_irq4_pending() { m_irq4_pending = 0; }
+ void irq_ack()
+ {
+ if (m_irq6_pending)
+ {
+ m_irq6_pending = 0;
+ m_lv6irqline_callback(false);
+ }
+ else if (m_irq4_pending)
+ {
+ m_irq4_pending = 0;
+ m_lv4irqline_callback(false);
+ }
+ }
// set some VDP variables at start (shall be moved to a device interface?)
void set_scanline_counter(int scanline) { m_scanline_counter = scanline; }
diff --git a/src/mame/sega/calcune.cpp b/src/mame/sega/calcune.cpp
index 79b70ebe91c..2e8c49f0649 100644
--- a/src/mame/sega/calcune.cpp
+++ b/src/mame/sega/calcune.cpp
@@ -52,10 +52,10 @@ private:
int m_vdp_state = 0;
void vdp_sndirqline_callback_genesis_z80(int state);
- void vdp_lv6irqline_callback_genesis_68k(int state);
- void vdp_lv4irqline_callback_genesis_68k(int state);
+ void vdp_vint_cb(int state);
+ void vdp_hint_cb(int state);
- IRQ_CALLBACK_MEMBER(genesis_int_callback);
+ void cpu_space_map(address_map &map);
uint16_t cal_700000_r();
void cal_770000_w(uint16_t data);
@@ -206,42 +206,37 @@ void calcune_state::machine_reset()
m_vdp[1]->device_reset_old();
}
-
-IRQ_CALLBACK_MEMBER(calcune_state::genesis_int_callback)
+void calcune_state::cpu_space_map(address_map &map)
{
- if (irqline==4)
- {
- m_vdp[0]->vdp_clear_irq4_pending();
- }
-
- if (irqline==6)
- {
- m_vdp[0]->vdp_clear_irq6_pending();
- }
-
- return (0x60+irqline*4)/4; // vector address
+ map(0xfffff3, 0xfffff3).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 25; }));
+ // IPL0, should be unused by Calcune
+ map(0xfffff5, 0xfffff5).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 26; }));
+ map(0xfffff7, 0xfffff7).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 27; }));
+ map(0xfffff9, 0xfffff9).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([this] () -> u8 {
+ m_vdp[0]->irq_ack();
+ return 28;
+ }));
+ map(0xfffffb, 0xfffffb).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 29; }));
+ map(0xfffffd, 0xfffffd).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([this] () -> u8 {
+ m_vdp[0]->irq_ack();
+ return 30;
+ }));
+ map(0xffffff, 0xffffff).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 31; }));
}
void calcune_state::vdp_sndirqline_callback_genesis_z80(int state)
{
}
-void calcune_state::vdp_lv6irqline_callback_genesis_68k(int state)
+// this looks odd but is the logic the Genesis code requires
+void calcune_state::vdp_vint_cb(int state)
{
- // this looks odd but is the logic the Genesis code requires
- if (state == ASSERT_LINE)
- m_maincpu->set_input_line(6, HOLD_LINE);
- else
- m_maincpu->set_input_line(6, CLEAR_LINE);
+ m_maincpu->set_input_line(6, state ? ASSERT_LINE : CLEAR_LINE);
}
-void calcune_state::vdp_lv4irqline_callback_genesis_68k(int state)
+void calcune_state::vdp_hint_cb(int state)
{
- // this looks odd but is the logic the Genesis code requires
- if (state == ASSERT_LINE)
- m_maincpu->set_input_line(4, HOLD_LINE);
- else
- m_maincpu->set_input_line(4, CLEAR_LINE);
+ m_maincpu->set_input_line(4, state ? ASSERT_LINE : CLEAR_LINE);
}
void calcune_state::machine_start()
@@ -256,7 +251,7 @@ void calcune_state::calcune(machine_config &config)
{
M68000(config, m_maincpu, OSC1_CLOCK / 7); /* 7.67 MHz */
m_maincpu->set_addrmap(AS_PROGRAM, &calcune_state::calcune_map);
- m_maincpu->set_irq_acknowledge_callback(FUNC(calcune_state::genesis_int_callback));
+ m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &calcune_state::cpu_space_map);
Z80(config, "z80", OSC1_CLOCK / 15).set_disable(); /* 3.58 MHz, no code is ever uploaded for the Z80, so it's unused here even if it is present on the PCB */
@@ -271,8 +266,8 @@ void calcune_state::calcune(machine_config &config)
SEGA315_5313(config, m_vdp[0], OSC1_CLOCK, m_maincpu);
m_vdp[0]->set_is_pal(false);
m_vdp[0]->snd_irq().set(FUNC(calcune_state::vdp_sndirqline_callback_genesis_z80));
- m_vdp[0]->lv6_irq().set(FUNC(calcune_state::vdp_lv6irqline_callback_genesis_68k));
- m_vdp[0]->lv4_irq().set(FUNC(calcune_state::vdp_lv4irqline_callback_genesis_68k));
+ m_vdp[0]->vint_cb().set(FUNC(calcune_state::vdp_vint_cb));
+ m_vdp[0]->hint_cb().set(FUNC(calcune_state::vdp_hint_cb));
m_vdp[0]->set_alt_timing(1);
m_vdp[0]->add_route(ALL_OUTPUTS, "speaker", 0.25, 0);
m_vdp[0]->add_route(ALL_OUTPUTS, "speaker", 0.25, 1);
@@ -281,8 +276,8 @@ void calcune_state::calcune(machine_config &config)
m_vdp[1]->set_is_pal(false);
// are these not hooked up or should they OR with the other lines?
// m_vdp[1]->snd_irq().set(FUNC(calcune_state::vdp_sndirqline_callback_genesis_z80));
-// m_vdp[1]->lv6_irq().set(FUNC(calcune_state::vdp_lv6irqline_callback_genesis_68k));
-// m_vdp[1]->lv4_irq().set(FUNC(calcune_state::vdp_lv4irqline_callback_genesis_68k));
+// m_vdp[1]->vint_cb().set(FUNC(calcune_state::vdp_vint_cb));
+// m_vdp[1]->hint_cb().set(FUNC(calcune_state::vdp_hint_cb));
m_vdp[1]->set_alt_timing(1);
m_vdp[1]->add_route(ALL_OUTPUTS, "speaker", 0.25, 0);
m_vdp[1]->add_route(ALL_OUTPUTS, "speaker", 0.25, 1);
diff --git a/src/mame/sega/megadriv.cpp b/src/mame/sega/megadriv.cpp
index 80a846d4aa2..f94fed9595c 100644
--- a/src/mame/sega/megadriv.cpp
+++ b/src/mame/sega/megadriv.cpp
@@ -736,41 +736,36 @@ void md_base_state::vdp_sndirqline_callback_genesis_z80(int state)
}
}
-// this comes from the vdp, and is connected to 68k irq level 6 (main vbl interrupt)
-void md_core_state::vdp_lv6irqline_callback_genesis_68k(int state)
+// this comes from the vdp, and is connected to 68k irq level 6 (IPL2, main vbl interrupt)
+void md_core_state::vdp_vint_cb(int state)
{
- if (state == ASSERT_LINE)
- m_maincpu->set_input_line(6, HOLD_LINE);
- else
- m_maincpu->set_input_line(6, CLEAR_LINE);
+ m_maincpu->set_input_line(6, state ? ASSERT_LINE : CLEAR_LINE);
}
-// this comes from the vdp, and is connected to 68k irq level 4 (raster interrupt)
-void md_core_state::vdp_lv4irqline_callback_genesis_68k(int state)
+// this comes from the vdp, and is connected to 68k irq level 4 (IPL1, raster interrupt)
+void md_core_state::vdp_hint_cb(int state)
{
- if (state == ASSERT_LINE)
- m_maincpu->set_input_line(4, HOLD_LINE);
- else
- m_maincpu->set_input_line(4, CLEAR_LINE);
+ m_maincpu->set_input_line(4, state ? ASSERT_LINE : CLEAR_LINE);
}
-/* Callback when the 68k takes an IRQ */
-IRQ_CALLBACK_MEMBER(md_core_state::genesis_int_callback)
+void md_core_state::cpu_space_map(address_map &map)
{
- if (irqline==4)
- {
- m_vdp->vdp_clear_irq4_pending();
- }
-
- if (irqline==6)
- {
- m_vdp->vdp_clear_irq6_pending();
- }
-
- return (0x60+irqline*4)/4; // vector address
+ map(0xfffff3, 0xfffff3).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 25; }));
+ // TODO: IPL0 (external irq tied to VDP IE2)
+ map(0xfffff5, 0xfffff5).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 26; }));
+ map(0xfffff7, 0xfffff7).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 27; }));
+ map(0xfffff9, 0xfffff9).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([this] () -> u8 {
+ m_vdp->irq_ack();
+ return 28;
+ }));
+ map(0xfffffb, 0xfffffb).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 29; }));
+ map(0xfffffd, 0xfffffd).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([this] () -> u8 {
+ m_vdp->irq_ack();
+ return 30;
+ }));
+ map(0xffffff, 0xffffff).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 31; }));
}
-
void md_core_state::megadriv_timers(machine_config &config)
{
TIMER(config, m_scan_timer).configure_generic(m_vdp, FUNC(sega315_5313_device::megadriv_scanline_timer_callback));
@@ -779,15 +774,15 @@ void md_core_state::megadriv_timers(machine_config &config)
void md_core_state::md_core_ntsc(machine_config &config)
{
M68000(config, m_maincpu, MASTER_CLOCK_NTSC / 7); // 7.67 MHz
- m_maincpu->set_irq_acknowledge_callback(FUNC(md_core_state::genesis_int_callback));
+ m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &md_core_state::cpu_space_map);
// IRQs are handled via the timers
megadriv_timers(config);
SEGA315_5313(config, m_vdp, MASTER_CLOCK_NTSC, m_maincpu);
m_vdp->set_is_pal(false);
- m_vdp->lv6_irq().set(FUNC(md_core_state::vdp_lv6irqline_callback_genesis_68k));
- m_vdp->lv4_irq().set(FUNC(md_core_state::vdp_lv4irqline_callback_genesis_68k));
+ m_vdp->vint_cb().set(FUNC(md_core_state::vdp_vint_cb));
+ m_vdp->hint_cb().set(FUNC(md_core_state::vdp_hint_cb));
m_vdp->set_screen("megadriv");
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
@@ -803,15 +798,15 @@ void md_core_state::md_core_ntsc(machine_config &config)
void md_core_state::md_core_pal(machine_config &config)
{
M68000(config, m_maincpu, MASTER_CLOCK_PAL / 7); // 7.67 MHz
- m_maincpu->set_irq_acknowledge_callback(FUNC(md_core_state::genesis_int_callback));
+ m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &md_core_state::cpu_space_map);
// IRQs are handled via the timers
megadriv_timers(config);
SEGA315_5313(config, m_vdp, MASTER_CLOCK_PAL, m_maincpu);
m_vdp->set_is_pal(true);
- m_vdp->lv6_irq().set(FUNC(md_core_state::vdp_lv6irqline_callback_genesis_68k));
- m_vdp->lv4_irq().set(FUNC(md_core_state::vdp_lv4irqline_callback_genesis_68k));
+ m_vdp->vint_cb().set(FUNC(md_core_state::vdp_vint_cb));
+ m_vdp->hint_cb().set(FUNC(md_core_state::vdp_hint_cb));
m_vdp->set_screen("megadriv");
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
diff --git a/src/mame/sega/megadriv.h b/src/mame/sega/megadriv.h
index 238f8e55757..1605b93518a 100644
--- a/src/mame/sega/megadriv.h
+++ b/src/mame/sega/megadriv.h
@@ -54,10 +54,11 @@ protected:
optional_ioport m_io_reset;
private:
- IRQ_CALLBACK_MEMBER(genesis_int_callback);
+// IRQ_CALLBACK_MEMBER(genesis_int_callback);
+ void cpu_space_map(address_map &map);
- void vdp_lv6irqline_callback_genesis_68k(int state);
- void vdp_lv4irqline_callback_genesis_68k(int state);
+ void vdp_vint_cb(int state);
+ void vdp_hint_cb(int state);
void megadriv_timers(machine_config &config);
};
diff --git a/src/mame/sega/segac2.cpp b/src/mame/sega/segac2.cpp
index 6e528b7e336..041c3e5a569 100644
--- a/src/mame/sega/segac2.cpp
+++ b/src/mame/sega/segac2.cpp
@@ -272,9 +272,8 @@ protected:
void recompute_palette_tables();
void vdp_sndirqline_callback_c2(int state);
- void vdp_lv6irqline_callback_c2(int state);
- void vdp_lv4irqline_callback_c2(int state);
- IRQ_CALLBACK_MEMBER(int_callback);
+ void vdp_vint_cb(int state);
+ void vdp_hint_cb(int state);
uint8_t io_portc_r();
void io_portd_w(uint8_t data);
@@ -311,6 +310,8 @@ protected:
void segac_map(address_map &map) ATTR_COLD;
void segac2_map(address_map &map) ATTR_COLD;
+
+ void cpu_space_map(address_map &map) ATTR_COLD;
};
@@ -1822,27 +1823,34 @@ void segac2_state::vdp_sndirqline_callback_c2(int state)
}
// the line usually used to drive irq6 is not connected
-void segac2_state::vdp_lv6irqline_callback_c2(int state)
+void segac2_state::vdp_vint_cb(int state)
{
//
}
// the scanline interrupt seems connected as usual
-void segac2_state::vdp_lv4irqline_callback_c2(int state)
+void segac2_state::vdp_hint_cb(int state)
{
- if (state == ASSERT_LINE)
- m_maincpu->set_input_line(4, HOLD_LINE);
- else
- m_maincpu->set_input_line(4, CLEAR_LINE);
+ m_maincpu->set_input_line(4, state ? ASSERT_LINE : CLEAR_LINE);
}
-/* Callback when the 68k takes an IRQ */
-IRQ_CALLBACK_MEMBER(segac2_state::int_callback)
+void segac2_state::cpu_space_map(address_map &map)
{
- if (irqline == 4)
- m_vdp->vdp_clear_irq4_pending();
-
- return (0x60 + irqline * 4) / 4; // vector address
+ map(0xfffff3, 0xfffff3).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 25; }));
+ // TODO: IPL0 (external irq tied to VDP IE2)
+ map(0xfffff5, 0xfffff5).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 26; }));
+ map(0xfffff7, 0xfffff7).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 27; }));
+ map(0xfffff9, 0xfffff9).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([this] () -> u8 {
+ m_vdp->irq_ack();
+ return 28;
+ }));
+ map(0xfffffb, 0xfffffb).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 29; }));
+ // TODO: still connected to VDP?
+ map(0xfffffd, 0xfffffd).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 {
+ //m_vdp->irq_ack();
+ return 30;
+ }));
+ map(0xffffff, 0xffffff).before_time(m_maincpu, FUNC(m68000_device::vpa_sync)).after_delay(m_maincpu, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return 31; }));
}
@@ -1868,7 +1876,7 @@ void segac2_state::segac(machine_config &config)
/* basic machine hardware */
M68000(config, m_maincpu, XL2_CLOCK/6);
m_maincpu->set_addrmap(AS_PROGRAM, &segac2_state::segac_map);
- m_maincpu->set_irq_acknowledge_callback(FUNC(segac2_state::int_callback));
+ m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &segac2_state::cpu_space_map);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1); // borencha requires 0xff fill or there is no sound (it lacks some of the init code of the borench set)
@@ -1886,8 +1894,8 @@ void segac2_state::segac(machine_config &config)
SEGA315_5313(config, m_vdp, XL2_CLOCK, m_maincpu);
m_vdp->set_is_pal(false);
m_vdp->snd_irq().set(FUNC(segac2_state::vdp_sndirqline_callback_c2));
- m_vdp->lv6_irq().set(FUNC(segac2_state::vdp_lv6irqline_callback_c2));
- m_vdp->lv4_irq().set(FUNC(segac2_state::vdp_lv4irqline_callback_c2));
+ m_vdp->vint_cb().set(FUNC(segac2_state::vdp_vint_cb));
+ m_vdp->hint_cb().set(FUNC(segac2_state::vdp_hint_cb));
m_vdp->set_alt_timing(1);
m_vdp->set_screen("screen");
m_vdp->add_route(ALL_OUTPUTS, "mono", 0.50);
@@ -1919,6 +1927,7 @@ void segac2_state::segac2(machine_config &config)
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &segac2_state::segac2_map);
+ m_maincpu->set_addrmap(m68000_base_device::AS_CPU_SPACE, &segac2_state::cpu_space_map);
subdevice<sega_315_5296_device>("io")->out_cnt1_callback().set(m_upd7759, FUNC(upd7759_device::reset_w));
/* sound hardware */
diff --git a/src/mame/sega/segas18.cpp b/src/mame/sega/segas18.cpp
index 58b4512a4d2..301b3ef62fd 100644
--- a/src/mame/sega/segas18.cpp
+++ b/src/mame/sega/segas18.cpp
@@ -1393,8 +1393,8 @@ void segas18_state::system18(machine_config &config)
SEGA315_5313(config, m_vdp, 15000000, m_maincpu); // ??? Frequency is a complete guess
m_vdp->set_is_pal(false);
m_vdp->snd_irq().set(FUNC(segas18_state::vdp_sndirqline_callback_s18));
- m_vdp->lv6_irq().set(FUNC(segas18_state::vdp_lv6irqline_callback_s18));
- m_vdp->lv4_irq().set(FUNC(segas18_state::vdp_lv4irqline_callback_s18));
+ m_vdp->vint_cb().set(FUNC(segas18_state::vdp_lv6irqline_callback_s18));
+ m_vdp->hint_cb().set(FUNC(segas18_state::vdp_lv4irqline_callback_s18));
m_vdp->set_alt_timing(1);
m_vdp->set_pal_write_base(0x1000);
m_vdp->set_ext_palette(m_palette);