diff options
Diffstat (limited to 'src/devices/bus/cbus/pc9801_118.cpp')
-rw-r--r-- | src/devices/bus/cbus/pc9801_118.cpp | 120 |
1 files changed, 95 insertions, 25 deletions
diff --git a/src/devices/bus/cbus/pc9801_118.cpp b/src/devices/bus/cbus/pc9801_118.cpp index 7f45cdf5d5e..403a23b4658 100644 --- a/src/devices/bus/cbus/pc9801_118.cpp +++ b/src/devices/bus/cbus/pc9801_118.cpp @@ -1,16 +1,24 @@ // license:BSD-3-Clause // copyright-holders:Angelo Salese -/*************************************************************************** +/************************************************************************************************** - NEC PC-9801-118 sound card + NEC PC-9801-118 sound card "CanBe Sound 2" - YMF297 + some extra ports + YMF297 + some extra ports, apparently derived from -86. + Introduced around the same time as Windows 95 release, it has various compatibility issues + under DOS (especially when PnP is enabled). + Doesn't have a sound ROM, it also cannot be installed with an environment also sporting a -86. TODO: - - preliminary, presumably needs CS-4232 too, it's an extended clone of the already emulated AD1848 used on the Windows Sound System + - Fix sound chip type (YMF297-F); + - Add CS-4232 support, it's an extended clone of the already emulated AD1848 used on the + Windows Sound System; + - Understand what the obfuscated NEC "ANCHOR" and "MAZE" chips really are; + - PnP interface (missing BIOS); - verify sound irq; + - test if driver can be installed under Windows 95; -***************************************************************************/ +**************************************************************************************************/ #include "emu.h" #include "bus/cbus/pc9801_118.h" @@ -27,11 +35,11 @@ //************************************************************************** // device type definition -DEFINE_DEVICE_TYPE(PC9801_118, pc9801_118_device, "pc9801_118", "pc9801_118") +DEFINE_DEVICE_TYPE(PC9801_118, pc9801_118_device, "pc9801_118", "NEC PC-9801-118") WRITE_LINE_MEMBER(pc9801_118_device::sound_irq) { - /* TODO: seems to die very often */ + // TODO: sometimes misfired irq causes sound or even host hang m_bus->int_w<5>(state); } @@ -41,9 +49,15 @@ WRITE_LINE_MEMBER(pc9801_118_device::sound_irq) void pc9801_118_device::device_add_mconfig(machine_config &config) { + // TODO: "ANCHOR" & "MAZE" custom NEC chips + // sourced by 5D clock + SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - YM2608(config, m_opn3, XTAL_5B * 2 / 5); // actually YMF297-F, unknown clock / divider, more likely uses 5D clock + + // actually YMF297-F (YMF288 + OPL3 compatible FM sources), unknown clock / divider + // 5B is near both CS-4232 and this + YM2608(config, m_opn3, XTAL_5B * 2 / 5); m_opn3->irq_handler().set(FUNC(pc9801_118_device::sound_irq)); m_opn3->port_a_read_callback().set(FUNC(pc9801_118_device::opn_porta_r)); //m_opn3->port_b_read_callback().set(FUNC(pc8801_state::opn_portb_r)); @@ -61,10 +75,48 @@ void pc9801_118_device::device_add_mconfig(machine_config &config) static INPUT_PORTS_START( pc9801_118 ) PORT_INCLUDE( pc9801_joy_port ) - PORT_START("OPN3_DSW") - PORT_CONFNAME( 0x01, 0x00, "PC-9801-118: Port Base" ) - PORT_CONFSETTING( 0x00, "0x088" ) - PORT_CONFSETTING( 0x01, "0x188" ) + // 12 line Jumper settings @ 8F + // documented at https://sammargh.github.io/pc98/ext_card_doc/9801-118.txt + // TODO: understand how SW can read these + PORT_START("OPN3_JP_8F") + PORT_CONFNAME( 0x001, 0x000, "PC-9801-118: Enable Plug and Play" ) // [1] + PORT_CONFSETTING( 0x000, DEF_STR( No ) ) + PORT_CONFSETTING( 0x001, DEF_STR( Yes ) ) + // "group" is basically a obnoxious machine ID + // details are in the aforementioned link, in a nutshell should be: + // Group 1: later CanBe (Cb onward) + // Group 2: early CanBe (Ce, Ce2, Cs2), 9821 MATE A + // Group 4: several ValueStar models + // Group 5: 9821 MATE B, Notebooks, 9801 BX, some H98 models + // Group 3: anything not covered above (link also mentions BX4 here?) + // In practice this should really be tested on field ... + PORT_CONFNAME( 0x406, 0x000, "PC-9801-118: PCM Group select") // [2, 3, 11] + PORT_CONFSETTING( 0x000, "Groups 2, 3, 4, 5" ) // uses -118 PCM + PORT_CONFSETTING( 0x404, "Group 3" ) // uses PCM host + PORT_CONFSETTING( 0x002, "Group 1" ) // ? + // all other settings "prohibited" + PORT_CONFNAME( 0x008, 0x008, "PC-9801-118: unknown [4]" ) // [4] "prohibited", always ON + PORT_CONFSETTING( 0x000, DEF_STR( Off ) ) + PORT_CONFSETTING( 0x008, DEF_STR( On ) ) + PORT_CONFNAME( 0x030, 0x000, "PC-9801-118: FM Interrupt setting" ) // [5,6] + PORT_CONFSETTING( 0x000, "INT5 (IRQ12)" ) + PORT_CONFSETTING( 0x010, "INT6 (IRQ13)" ) + PORT_CONFSETTING( 0x020, "INT41 (IRQ10)" ) + PORT_CONFSETTING( 0x030, "INT0 (IRQ3)") + PORT_CONFNAME( 0x040, 0x000, "PC-9801-118: DMA channel" ) // [7] + PORT_CONFSETTING( 0x000, "1" ) + PORT_CONFSETTING( 0x040, "2" ) + PORT_CONFNAME( 0x180, 0x000, "PC-9801-118: PCM Interrupt setting" ) // [8,9] + PORT_CONFSETTING( 0x000, "INT5 (IRQ12)" ) + PORT_CONFSETTING( 0x080, "INT1 (IRQ5)" ) + PORT_CONFSETTING( 0x100, "INT41 (IRQ10)" ) + PORT_CONFSETTING( 0x180, "INT0 (IRQ3)" ) + PORT_CONFNAME( 0x200, 0x000, "PC-9801-118: enable MIDI Interrupt" ) // [10] + PORT_CONFSETTING( 0x000, DEF_STR( No ) ) + PORT_CONFSETTING( 0x200, DEF_STR( Yes ) ) // auto for PnP, INT41 for non-PnP + PORT_CONFNAME( 0x800, 0x000, "PC-9801-118: unknown [12]" ) // [12] "prohibited", always OFF + PORT_CONFSETTING( 0x000, DEF_STR( Off ) ) + PORT_CONFSETTING( 0x800, DEF_STR( On ) ) INPUT_PORTS_END ioport_constructor pc9801_118_device::device_input_ports() const @@ -72,8 +124,14 @@ ioport_constructor pc9801_118_device::device_input_ports() const return INPUT_PORTS_NAME( pc9801_118 ); } -// RAM ROM_START( pc9801_118 ) + ROM_REGION( 0x20000, "pnp_bios", ROMREGION_ERASE00 ) + // NB: either socket is exclusively populated, earlier models populates 1E while later populates 2E. + // Most likely contains same data or slight revision bump. + // μPD27c1024 socket + ROM_LOAD( "118 e316.1e", 0x00000, 0x20000, NO_DUMP ) + // LH531024N socket at .2e (unreadable label) + ROM_REGION( 0x100000, "opn3", ROMREGION_ERASE00 ) ROM_END @@ -111,11 +169,24 @@ void pc9801_118_device::device_validity_check(validity_checker &valid) const // device_start - device-specific startup //------------------------------------------------- +u16 pc9801_118_device::read_io_base() +{ + // hardwired on this board + return 0x0188; +} void pc9801_118_device::device_start() { + m_io_base = read_io_base(); m_bus->install_io(0xa460, 0xa463, read8sm_delegate(*this, FUNC(pc9801_118_device::id_r)), write8sm_delegate(*this, FUNC(pc9801_118_device::ext_w))); + m_bus->install_io( + m_io_base, + m_io_base + 7, + read8sm_delegate(*this, FUNC(pc9801_118_device::opn3_r)), + write8sm_delegate(*this, FUNC(pc9801_118_device::opn3_w)) + ); + save_item(NAME(m_ext_reg)); } @@ -126,10 +197,8 @@ void pc9801_118_device::device_start() void pc9801_118_device::device_reset() { - uint16_t port_base = (ioport("OPN3_DSW")->read() & 1) << 8; - m_bus->io_space().unmap_readwrite(0x0088, 0x008b, 0x100); - m_bus->install_io(port_base + 0x0088, port_base + 0x008f, read8sm_delegate(*this, FUNC(pc9801_118_device::opn3_r)), write8sm_delegate(*this, FUNC(pc9801_118_device::opn3_w))); - m_ext_reg = 1; // TODO: enabled or disabled? + // TODO: is this enabled or disabled at boot? + m_ext_reg = 1; } @@ -140,7 +209,7 @@ void pc9801_118_device::device_reset() uint8_t pc9801_118_device::opn3_r(offs_t offset) { - if(((offset & 5) == 0) || m_ext_reg) + if(((offset & 5) == 0) || m_ext_reg ) return m_opn3->read(offset >> 1); else // odd { @@ -152,7 +221,7 @@ uint8_t pc9801_118_device::opn3_r(offs_t offset) void pc9801_118_device::opn3_w(offs_t offset, uint8_t data) { - if(((offset & 5) == 0) || m_ext_reg) + if( ((offset & 5) == 0) || m_ext_reg ) m_opn3->write(offset >> 1,data); //else // odd // printf("PC9801-118: Write to undefined port [%02x] %02x\n",offset+0x188,data); @@ -162,11 +231,13 @@ uint8_t pc9801_118_device::id_r(offs_t offset) { if(offset == 0) { - printf("OPN3 EXT read ID [%02x]\n",offset); + logerror("OPN3 EXT read ID [%02x]\n",offset); + // TODO: confirm ID + // by assumption we make this same as later CanBe releases, may or may not be right return 0x80 | (m_ext_reg & 1); } - printf("OPN3 EXT read unk [%02x]\n",offset); + logerror("OPN3 EXT read unk [%02x]\n", offset); return 0xff; } @@ -175,11 +246,10 @@ void pc9801_118_device::ext_w(offs_t offset, uint8_t data) if(offset == 0) { m_ext_reg = data & 1; - /* TODO: apparently writing a 1 doubles the available channels (and presumably enables CS-4231 too) */ - if(data) - printf("PC-9801-118: extended register %02x write\n",data); + if(data & 2) + logerror("%s: extended register %02x write\n", machine().describe_context(), data); return; } - printf("OPN3 EXT write unk %02x -> [%02x]\n",data,offset); + logerror("%s: EXT write unk %02x -> [%02x]\n", machine().describe_context(), data, offset); } |