// license:BSD-3-Clause // copyright-holders:Angelo Salese /*************************************************************************** NEC PC-9801-26 sound card Legacy sound card for PC-98xx family, composed by a single YM2203 TODO: - verify sound irq; ***************************************************************************/ #include "emu.h" #include "bus/cbus/pc9801_26.h" #include "sound/2203intf.h" #include "speaker.h" //************************************************************************** // GLOBAL VARIABLES //************************************************************************** // device type definition DEFINE_DEVICE_TYPE(PC9801_26, pc9801_26_device, "pc9801_26", "pc9801_26") WRITE_LINE_MEMBER(pc9801_26_device::sound_irq) { /* TODO: seems to die very often */ m_bus->int_w<5>(state); } //------------------------------------------------- // device_add_mconfig - add device configuration //------------------------------------------------- void pc9801_26_device::device_add_mconfig(machine_config &config) { SPEAKER(config, "mono").front_center(); YM2203(config, m_opn, 15.9744_MHz_XTAL / 4); // divider not verified m_opn->irq_handler().set(FUNC(pc9801_26_device::sound_irq)); m_opn->port_a_read_callback().set(FUNC(pc9801_26_device::opn_porta_r)); //m_opn->port_b_read_callback().set(FUNC(pc8801_state::opn_portb_r)); //m_opn->port_a_write_callback().set(FUNC(pc8801_state::opn_porta_w)); m_opn->port_b_write_callback().set(FUNC(pc9801_26_device::opn_portb_w)); m_opn->add_route(ALL_OUTPUTS, "mono", 1.00); } // to load a different bios for slots: // -cbus0 pc9801_26,bios=N ROM_START( pc9801_26 ) ROM_REGION( 0x4000, "sound_bios", ROMREGION_ERASEFF ) // PC9801_26k is a minor change that applies to 286+ CPUs ROM_SYSTEM_BIOS( 0, "26k", "nec26k" ) ROMX_LOAD( "26k_wyka01_00.bin", 0x0000, 0x2000, CRC(f071bf69) SHA1(f3cdef94e9fee116cf4a9b54881e77c6cd903815), ROM_SKIP(1) | ROM_BIOS(0) ) ROMX_LOAD( "26k_wyka02_00.bin", 0x0001, 0x2000, CRC(eaa01052) SHA1(5d47edae49aad591f139d5599fe04b61aefd5ecd), ROM_SKIP(1) | ROM_BIOS(0) ) // regular BIOS, for V30 and downward CPUs ROM_SYSTEM_BIOS( 1, "26", "nec26" ) ROMX_LOAD( "sound.rom", 0x0000, 0x4000, CRC(80eabfde) SHA1(e09c54152c8093e1724842c711aed6417169db23), ROM_BIOS(1) ) // following rom is unchecked and of dubious quality // we also currently mark it based off where they originally belonged to, lacking a better info ROM_SYSTEM_BIOS( 2, "26_9821", "nec26_9821" ) ROMX_LOAD( "sound_9821.rom", 0x0000, 0x4000, BAD_DUMP CRC(a21ef796) SHA1(34137c287c39c44300b04ee97c1e6459bb826b60), ROM_BIOS(2) ) ROM_END const tiny_rom_entry *pc9801_26_device::device_rom_region() const { return ROM_NAME( pc9801_26 ); } //------------------------------------------------- // input_ports - device-specific input ports //------------------------------------------------- static INPUT_PORTS_START( pc9801_26 ) PORT_INCLUDE( pc9801_joy_port ) PORT_START("OPN_DSW") PORT_CONFNAME( 0x01, 0x01, "PC-9801-26: Port Base" ) PORT_CONFSETTING( 0x00, "0x088" ) PORT_CONFSETTING( 0x01, "0x188" ) INPUT_PORTS_END ioport_constructor pc9801_26_device::device_input_ports() const { return INPUT_PORTS_NAME( pc9801_26 ); } //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // pc9801_26_device - constructor //------------------------------------------------- pc9801_26_device::pc9801_26_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pc9801_snd_device(mconfig, PC9801_26, tag, owner, clock), m_bus(*this, DEVICE_SELF_OWNER), m_opn(*this, "opn") { } //------------------------------------------------- // device_validity_check - perform validity checks // on this device //------------------------------------------------- void pc9801_26_device::device_validity_check(validity_checker &valid) const { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void pc9801_26_device::device_start() { m_bus->program_space().install_rom(0xcc000,0xcffff,memregion(this->subtag("sound_bios").c_str())->base()); } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- void pc9801_26_device::device_reset() { uint16_t port_base = (ioport("OPN_DSW")->read() & 1) << 8; m_bus->io_space().unmap_readwrite(0x0088, 0x008b, 0x100); m_bus->install_io(port_base + 0x0088, port_base + 0x008b, read8_delegate(FUNC(pc9801_26_device::opn_r), this), write8_delegate(FUNC(pc9801_26_device::opn_w), this) ); } //************************************************************************** // READ/WRITE HANDLERS //************************************************************************** // TODO: leftover mirrors? Doesn't match to what installs above READ8_MEMBER(pc9801_26_device::opn_r) { if((offset & 1) == 0) { return offset & 4 ? 0xff : m_opn->read(offset >> 1); } else // odd { printf("Read to undefined port [%02x]\n",offset+0x188); return 0xff; } } WRITE8_MEMBER(pc9801_26_device::opn_w) { if((offset & 5) == 0) m_opn->write(offset >> 1, data); else // odd printf("PC9801-26: Write to undefined port [%02x] %02x\n",offset+0x188,data); }