pc9801.cpp: added SpeakBoard sound card emulation [Angelo Salese, Takahiro Nogi]

This commit is contained in:
angelosa 2018-05-25 22:32:57 +02:00
parent acfd09004e
commit 66153a3df5
3 changed files with 122 additions and 11 deletions

View File

@ -3,15 +3,20 @@
/***************************************************************************
NEC PC-9801-86 sound card
NEC PC-9801-SpeakBoard sound card
Similar to PC-9801-26, this one has YM2608 instead of YM2203 and an
additional DAC port
SpeakBoard sound card seems to be derived design from -86, with an additional
OPNA mapped at 0x58*
TODO:
- joystick code should be shared between -26, -86 and -118
- Test all pcm modes
- Make volume work
- Recording
- actual stereo sound routing (currently routes to ALL_OUTPUTS)
- SpeakBoard: no idea about software that uses this;
***************************************************************************/
@ -52,7 +57,7 @@ WRITE_LINE_MEMBER(pc9801_86_device::sound_irq)
// device_add_mconfig - add device configuration
//-------------------------------------------------
MACHINE_CONFIG_START(pc9801_86_device::device_add_mconfig)
MACHINE_CONFIG_START(pc9801_86_device::pc9801_86_config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
MCFG_DEVICE_ADD("opna", YM2608, 7.987_MHz_XTAL)
@ -71,6 +76,10 @@ MACHINE_CONFIG_START(pc9801_86_device::device_add_mconfig)
MCFG_SOUND_ROUTE(0, "rdac", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE(0, "rdac", -1.0, DAC_VREF_NEG_INPUT)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(pc9801_86_device::device_add_mconfig)
pc9801_86_config(config);
MACHINE_CONFIG_END
// to load a different bios for slots:
// -cbusX pc9801_86,bios=N
ROM_START( pc9801_86 )
@ -136,8 +145,8 @@ ioport_constructor pc9801_86_device::device_input_ports() const
// pc9801_86_device - constructor
//-------------------------------------------------
pc9801_86_device::pc9801_86_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, PC9801_86, tag, owner, clock),
pc9801_86_device::pc9801_86_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock),
m_bus(*this, DEVICE_SELF_OWNER),
m_opna(*this, "opna"),
m_ldac(*this, "ldac"),
@ -146,6 +155,12 @@ pc9801_86_device::pc9801_86_device(const machine_config &mconfig, const char *ta
{
}
pc9801_86_device::pc9801_86_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pc9801_86_device(mconfig, PC9801_86, tag, owner, clock)
{
}
//-------------------------------------------------
// device_validity_check - perform validity checks
@ -375,3 +390,81 @@ void pc9801_86_device::device_timer(emu_timer& timer, device_timer_id id, int pa
m_bus->int_w<5>(ASSERT_LINE);
}
}
//**************************************************************************
// SpeakBoard device section
//**************************************************************************
DEFINE_DEVICE_TYPE(PC9801_SPEAKBOARD, pc9801_speakboard_device, "pc9801_spb", "NEC PC9801 SpeakBoard")
ROM_START( pc9801_spb )
ROM_REGION( 0x4000, "sound_bios", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "spb lh5764 ic21_pink.bin", 0x0001, 0x2000, CRC(5bcefa1f) SHA1(ae88e45d411bf5de1cb42689b12b6fca0146c586) )
ROM_LOAD16_BYTE( "spb lh5764 ic22_green.bin", 0x0000, 0x2000, CRC(a7925ced) SHA1(3def9ee386ab6c31436888261bded042cd64a0eb) )
// RAM
ROM_REGION( 0x100000, "opna", ROMREGION_ERASE00 )
ROM_REGION( 0x100000, "opna_slave", ROMREGION_ERASE00 )
ROM_END
const tiny_rom_entry *pc9801_speakboard_device::device_rom_region() const
{
return ROM_NAME( pc9801_spb );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// pc9801_86_device - constructor
//-------------------------------------------------
pc9801_speakboard_device::pc9801_speakboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pc9801_86_device(mconfig, PC9801_SPEAKBOARD, tag, owner, clock),
m_opna_slave(*this, "opna_slave")
{
}
MACHINE_CONFIG_START(pc9801_speakboard_device::device_add_mconfig)
pc9801_86_config(config);
MCFG_DEVICE_ADD("opna_slave", YM2608, 7.987_MHz_XTAL)
MCFG_AY8910_OUTPUT_TYPE(0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.00)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.00)
MACHINE_CONFIG_END
void pc9801_speakboard_device::device_start()
{
pc9801_86_device::device_start();
install_device(0x0588, 0x058f, read8_delegate(FUNC(pc9801_speakboard_device::opna_slave_r), this), write8_delegate(FUNC(pc9801_speakboard_device::opna_slave_w), this) );
}
void pc9801_speakboard_device::device_reset()
{
pc9801_86_device::device_reset();
}
READ8_MEMBER(pc9801_speakboard_device::opna_slave_r)
{
if((offset & 1) == 0)
return m_opna_slave->read(space, offset >> 1);
else // odd
{
logerror("PC9801-SPB: Read to undefined port [%02x]\n",offset+0x588);
return 0xff;
}
}
WRITE8_MEMBER(pc9801_speakboard_device::opna_slave_w)
{
if((offset & 1) == 0)
m_opna_slave->write(space, offset >> 1,data);
else // odd
logerror("PC9801-SPB: Write to undefined port [%02x] %02x\n",offset+0x588,data);
}

View File

@ -26,6 +26,7 @@ class pc9801_86_device : public device_t
public:
// construction/destruction
pc9801_86_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
pc9801_86_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(opna_r);
DECLARE_WRITE8_MEMBER(opna_w);
@ -34,6 +35,10 @@ public:
DECLARE_READ8_MEMBER(pcm_r);
DECLARE_WRITE8_MEMBER(pcm_w);
DECLARE_WRITE_LINE_MEMBER(sound_irq);
DECLARE_READ8_MEMBER(opn_porta_r);
DECLARE_WRITE8_MEMBER(opn_portb_w);
protected:
// device-level overrides
virtual void device_validity_check(validity_checker &valid) const override;
@ -45,6 +50,7 @@ protected:
virtual const tiny_rom_entry *device_rom_region() const override;
void install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
void pc9801_86_config(machine_config &config);
private:
int queue_count();
@ -60,22 +66,34 @@ private:
required_device<dac_word_interface> m_rdac;
std::vector<uint8_t> m_queue;
emu_timer *m_dac_timer;
};
DECLARE_WRITE_LINE_MEMBER(sound_irq);
DECLARE_READ8_MEMBER(opn_porta_r);
DECLARE_WRITE8_MEMBER(opn_portb_w);
class pc9801_speakboard_device : public pc9801_86_device
{
public:
// construction/destruction
pc9801_speakboard_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(opna_slave_r);
DECLARE_WRITE8_MEMBER(opna_slave_w);
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
virtual const tiny_rom_entry *device_rom_region() const override;
private:
required_device<ym2608_device> m_opna_slave;
};
// device type definition
DECLARE_DEVICE_TYPE(PC9801_86, pc9801_86_device)
DECLARE_DEVICE_TYPE(PC9801_SPEAKBOARD, pc9801_speakboard_device)
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#endif // MAME_BUS_CBUS_PC9801_86_H

View File

@ -1979,7 +1979,7 @@ static void pc9801_cbus_devices(device_slot_interface &device)
// PC-9801-26 + PC-9801-86 (?)
// PC-9801-86 + Chibi-Oto
device.option_add("pc9801_118", PC9801_118);
// Speak Board
device.option_add("pc9801_spb", PC9801_SPEAKBOARD);
// Spark Board
// AMD-98 (AmuseMent boarD)
device.option_add("pc9801_amd98", PC9801_AMD98);