mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +03:00
sega/segapico.cpp: Initial external interrupt support for Copera (#11722)
This commit is contained in:
parent
68c73d6144
commit
77a3e13a96
@ -5,7 +5,7 @@ license:CC0-1.0
|
||||
|
||||
Games for the MIXT BOOK PLAYER COPERA
|
||||
|
||||
* おしゃれの国のアリス - Oshare no Kuni no Alice (Yamaha - ???? - MMGS-8)
|
||||
Missing / Unconfirmed:
|
||||
* 冒険!メロリン島 - Bouken! Merorin Shima (Yamaha - ???? - MMGS-10)
|
||||
-->
|
||||
|
||||
@ -117,9 +117,24 @@ Games for the MIXT BOOK PLAYER COPERA
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="aliceosh">
|
||||
<description>Alice in Oshare-Land</description>
|
||||
<year>1994?</year> <!-- PCB date -->
|
||||
<publisher>Yamaha</publisher>
|
||||
<info name="serial" value="MMGS-8"/>
|
||||
<info name="alt_title" value="おしゃれの国のアリス"/>
|
||||
<part name="cart" interface="copera_cart">
|
||||
<feature name="pcb" value="171-6882A" />
|
||||
<feature name="ic1" value="MPR-17989-H" />
|
||||
<dataarea name="rom" size="524288">
|
||||
<rom name="mpr-17989-h.ic1" size="524288" crc="e330151a" sha1="20b9f4624188b90fdc0122cb80896c809e1b324b" loadflag="load16_word_swap" />
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<software name="copechik">
|
||||
<description>Copera no Chikyuu Daisuki</description>
|
||||
<year>1994?</year>
|
||||
<year>1994?</year> <!-- PCB date -->
|
||||
<publisher>Yamaha</publisher>
|
||||
<info name="serial" value="MMGS-9"/>
|
||||
<info name="alt_title" value="コペラのちきゅうだいすき"/>
|
||||
|
@ -126,6 +126,8 @@ C = MB3514 / 9325 M36
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -585,29 +587,49 @@ public:
|
||||
void copera(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_reset() override;
|
||||
virtual void machine_start() override;
|
||||
|
||||
void copera_pcm_cb(int state);
|
||||
uint16_t copera_io_read(offs_t offset);
|
||||
void copera_io_write(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(process_ext_timer);
|
||||
|
||||
private:
|
||||
void copera_mem(address_map &map);
|
||||
|
||||
required_device<copera_cart_slot_device> m_picocart;
|
||||
|
||||
std::unique_ptr<uint16_t[]> m_ext_regs;
|
||||
bool m_is_ext_requested;
|
||||
emu_timer *m_ext_timer;
|
||||
};
|
||||
|
||||
|
||||
TIMER_CALLBACK_MEMBER(copera_state::process_ext_timer)
|
||||
{
|
||||
// TODO: When is it enabled? Expected even if games don't set bit 3 of VDP mode register 3...
|
||||
if (m_is_ext_requested)
|
||||
{
|
||||
m_maincpu->set_input_line(2, HOLD_LINE);
|
||||
m_is_ext_requested = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_maincpu->set_input_line(2, CLEAR_LINE);
|
||||
m_is_ext_requested = true;
|
||||
}
|
||||
}
|
||||
|
||||
void copera_state::copera_mem(address_map &map)
|
||||
{
|
||||
map(0x000000, 0x3fffff).rom();
|
||||
|
||||
map(0x800000, 0x80001f).rw(FUNC(copera_state::pico_68k_io_read), FUNC(copera_state::pico_68k_io_write));
|
||||
|
||||
map(0xbff800, 0xbff87f).rw(FUNC(copera_state::copera_io_read), FUNC(copera_state::copera_io_write)); // FIXME: Guessed range.
|
||||
map(0xc00000, 0xc0001f).rw(m_vdp, FUNC(sega315_5313_device::vdp_r), FUNC(sega315_5313_device::vdp_w));
|
||||
|
||||
map(0xe00000, 0xe0ffff).ram().mirror(0x1f0000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void copera_cart(device_slot_interface &device)
|
||||
{
|
||||
device.option_add_internal("rom", MD_STD_ROM);
|
||||
@ -631,6 +653,28 @@ void copera_state::machine_start()
|
||||
m_sega_315_5641_pcm->start_w(1);
|
||||
|
||||
m_vdp->stop_timers();
|
||||
|
||||
m_ext_regs = make_unique_clear<uint16_t[]>(0x80/2);
|
||||
|
||||
// FIXME: Guessed timing.
|
||||
//
|
||||
// It must be less than HBLANK. Games have a busy loop where they read
|
||||
// VDP status register and check if bit 7 (vertical interrupt pending) is
|
||||
// set and then cleared (e.g. Copera no Chikyuu Daisuki @ 0xfb3c4).
|
||||
// Too frequent EXT interrupts result in that subroutine only executing after
|
||||
// scanline 224 and will never catch bit 7 set.
|
||||
m_ext_timer = timer_alloc(FUNC(copera_state::process_ext_timer), this);
|
||||
m_ext_timer->adjust(attotime::zero, 0, m_vdp->screen().scan_period() * 20);
|
||||
}
|
||||
|
||||
void copera_state::machine_reset()
|
||||
{
|
||||
pico_base_state::machine_reset();
|
||||
|
||||
m_is_ext_requested = true;
|
||||
m_ext_regs[0] = 0;
|
||||
m_ext_regs[0x2/2] = 0xffff;
|
||||
m_ext_regs[0x4/2] = 0xffff;
|
||||
}
|
||||
|
||||
void copera_state::copera(machine_config &config)
|
||||
@ -649,11 +693,41 @@ void copera_state::copera(machine_config &config)
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
||||
SEGA_315_5641_PCM(config, m_sega_315_5641_pcm, upd7759_device::STANDARD_CLOCK);
|
||||
m_sega_315_5641_pcm->fifo_cb().set(FUNC(copera_state::sound_cause_irq));
|
||||
m_sega_315_5641_pcm->fifo_cb().set(FUNC(copera_state::copera_pcm_cb));
|
||||
m_sega_315_5641_pcm->add_route(ALL_OUTPUTS, "lspeaker", 0.16);
|
||||
m_sega_315_5641_pcm->add_route(ALL_OUTPUTS, "rspeaker", 0.16);
|
||||
}
|
||||
|
||||
void copera_state::copera_pcm_cb(int state)
|
||||
{
|
||||
// TODO: Not IRQ3 (games assign an infinite loop handler), likely handled by an EXT callback.
|
||||
}
|
||||
|
||||
uint16_t copera_state::copera_io_read(offs_t offset)
|
||||
{
|
||||
LOG("COPERA IO r @ %08x: %08x = %04x\n", m_maincpu->pc(), 0xbff800 + offset * 2, m_ext_regs[offset]);
|
||||
return m_ext_regs[offset];
|
||||
}
|
||||
|
||||
void copera_state::copera_io_write(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
if (ACCESSING_BITS_8_15)
|
||||
{
|
||||
m_ext_regs[offset] = (data & mem_mask) | (m_ext_regs[offset] & 0x00FF);
|
||||
}
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
m_ext_regs[offset] = (data & mem_mask) | (m_ext_regs[offset] & 0xFF00);
|
||||
}
|
||||
|
||||
// TODO: We only enable EXT handler callback 3.
|
||||
if (((m_ext_regs[0x4/2] & 0xFF) == 0xd) && ((m_ext_regs[0x2/2] & 0xff) == 0x3f))
|
||||
{
|
||||
m_ext_regs[0] |= 1 << 3;
|
||||
}
|
||||
|
||||
LOG("COPERA IO w @ %08x: %08x = %04x (mask %08x)\n", m_maincpu->pc(), 0xbff800 + offset * 2, data, mem_mask);
|
||||
}
|
||||
|
||||
|
||||
ROM_START( copera )
|
||||
|
Loading…
Reference in New Issue
Block a user