// license:BSD-3-Clause // copyright-holders:Angelo Salese /* Internal sound slot options */ #include "emu.h" #include "sound.h" /* * Early CanBe (-86 based) * PC-98GS/9821 Multi/Ap/As/Ae/Ce/Af/Ap2/As2/Cs2/Ce2/An/Ap3/As3/Cf/Cx/Cb/Cx2/Cb2 * * References: * io_sound.txt * */ DEFINE_DEVICE_TYPE(SOUND_PC9821CE, sound_pc9821ce_device, "sound_pc9821ce", "NEC PC-9821Ce built-in sound") sound_pc9821ce_device::sound_pc9821ce_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pc9801_86_device(mconfig, SOUND_PC9821CE, tag, owner, clock) , device_memory_interface(mconfig, *this) , m_space_io_config("pnp_io", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(sound_pc9821ce_device::pnp_io_map), this)) , m_eeprom(*this, "eeprom") { } device_memory_interface::space_config_vector sound_pc9821ce_device::memory_space_config() const { return space_config_vector{ std::make_pair(0, &m_space_io_config) }; } const tiny_rom_entry *sound_pc9821ce_device::device_rom_region() const { // mapped from pc9821ce base return nullptr; } void sound_pc9821ce_device::device_add_mconfig(machine_config &config) { pc9801_86_config(config); EEPROM_93C06_16BIT(config, m_eeprom); } void sound_pc9821ce_device::device_start() { pc9801_86_device::device_start(); } void sound_pc9821ce_device::device_reset() { pc9801_86_device::device_reset(); } void sound_pc9821ce_device::io_map(address_map &map) { pc9801_86_device::io_map(map); // expects writes with 0x54xx for index, 0x41xx for data map(0xac6c, 0xac6d).lrw16( NAME([this] (offs_t offset) { return 0x5400 | m_index; }), NAME([this] (offs_t offset, u16 data, u16 mem_mask) { if (mem_mask != 0xffff || (data & 0xff00) != 0x5400) logerror("sound_pc9821ce: warning access index with %04x & %04x (blocked?)\n", data, mem_mask); m_index = data & 0xff; }) ); map(0xac6e, 0xac6f).lrw16( NAME([this] (offs_t offset) { return 0x4100 | this->space(0).read_byte(m_index); }), NAME([this] (offs_t offset, u16 data, u16 mem_mask) { if (mem_mask != 0xffff || (data & 0xff00) != 0x4100) logerror("sound_pc9821ce: warning access data with %04x & %04x (blocked?)\n", data, mem_mask); this->space(0).write_byte(m_index, data & 0xff); }) ); } // applies to PC-9821 Multi and PC-9821Ce // other models (PC-98GS, A Mate, other early CanBe) maps some stuff differently void sound_pc9821ce_device::pnp_io_map(address_map &map) { map.unmap_value_high(); map(0x00, 0x00).lrw8( NAME([this] (offs_t offset) { return m_eeprom->do_read() << 0; }), NAME([this] (offs_t offset, u8 data) { m_eeprom->cs_write(BIT(data, 2)); m_eeprom->clk_write(BIT(data, 1)); m_eeprom->di_write(BIT(data, 0)); }) ); // ??-? -??- // --x- ---- using SCSI (mapping or mounting?) // ---- x--- Sound ports PnP // map(0x10, 0x10) // ???? ??-- // ---- --xx SCSI I/O port // map(0x20, 0x20) // ???? ?--- // ---- -111 SCSI not used // ---- -000 SCSI used // map(0x21, 0x21) // map(0x30, 0x30) Sound irq related // map(0x40, 0x40) // CPU flag // -100 High // -010 Middle // -001 Low // TODO: repeated in Setup menu, where this comes from? map(0x50, 0x50).lr8( NAME([] () { return 4; }) ); // map(0x52, 0x52) // map(0xf0, 0xf0) } /* * Late CanBe (-118 based) * Cf/Cx/Cb/Cx2/Cb2/Cx3/Cb3/Na12/Na9/Na7/Nb7/Nx * * References: * - io_canbe.txt * */ DEFINE_DEVICE_TYPE(SOUND_PC9821CX3, sound_pc9821cx3_device, "sound_pc9821cx3", "NEC PC-9821Cx3 built-in sound") sound_pc9821cx3_device::sound_pc9821cx3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pc9801_118_device(mconfig, SOUND_PC9821CX3, tag, owner, clock) , device_memory_interface(mconfig, *this) , m_space_io_config("pnp_io", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(sound_pc9821cx3_device::pnp_io_map), this)) { } device_memory_interface::space_config_vector sound_pc9821cx3_device::memory_space_config() const { return space_config_vector{ std::make_pair(0, &m_space_io_config) }; } const tiny_rom_entry *sound_pc9821cx3_device::device_rom_region() const { // mapped from pc9821cx3 base return nullptr; } void sound_pc9821cx3_device::device_add_mconfig(machine_config &config) { pc9801_118_device::device_add_mconfig(config); } void sound_pc9821cx3_device::device_start() { pc9801_118_device::device_start(); } void sound_pc9821cx3_device::device_reset() { pc9801_118_device::device_reset(); } void sound_pc9821cx3_device::io_map(address_map &map) { pc9801_118_device::io_map(map); map(0x0f4a, 0x0f4b).rw(FUNC(sound_pc9821cx3_device::control_r), FUNC(sound_pc9821cx3_device::control_w)); } u8 sound_pc9821cx3_device::control_r(offs_t offset) { if (!offset) { logerror("sound_pc9821cx3: Warning control_r from index (confirm me)\n"); return m_index; } return this->space(0).read_byte(m_index); } void sound_pc9821cx3_device::control_w(offs_t offset, u8 data) { if (!offset) m_index = data & 0xff; else this->space(0).write_byte(m_index, data & 0xff); } /* * [0x00] * [0x01] Windows Sound System related * ---- xxxx irq select * ---- 1000 INT8 * ---- 0011 INT0 * ---- 0010 INT41 * ---- 0000 INT5 * [0x02] * [0x03] Remote control reset * ---- -x-- (1) Mic through (loopback?) * ---- ---x (1) Remote control reset * [0x04] Mute control * ---- ---x (Global?) sound mute * [0x10] Remote control data status * ---- --x- (1) device ready (0) busy * ---- ---x (1) received data available * [0x11] Remote control code * * [0x12] * [0x13] Power control * * [0x14] remote irq control * ---- -x-- irq enable * ---- --xx irq select * ---- --11 INT41 * ---- --10 INT1 * ---- --01 INT2 * ---- --00 INT0 * [0x30] VOL1,2 YMF288 Left sound output * [0x31] VOL1,2 YMF288 Right sound output * [0x32] VOL3,4 Line Left input * [0x33] VOL3,4 Line Right input * [0x34] * [0x35] */ void sound_pc9821cx3_device::pnp_io_map(address_map &map) { map.unmap_value_high(); // throws MICOM ERROR otherwise map(0x10, 0x10).lr8(NAME([] () { return 2; })); }