mirror of
https://github.com/holub/mame
synced 2025-06-07 21:33:45 +03:00
bus/cbus: drop PC9801 prefix for AMD-98 sound card
* make it output mono * improve AY3 flip-flop mechanism * add logmacro
This commit is contained in:
parent
652dbc852e
commit
6a28bbbd53
1519
hash/pc98.xml
1519
hash/pc98.xml
File diff suppressed because it is too large
Load Diff
@ -5250,6 +5250,8 @@ end
|
|||||||
|
|
||||||
if (BUSES["CBUS"]~=null) then
|
if (BUSES["CBUS"]~=null) then
|
||||||
files {
|
files {
|
||||||
|
MAME_DIR .. "src/devices/bus/cbus/amd98.cpp",
|
||||||
|
MAME_DIR .. "src/devices/bus/cbus/amd98.h",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_26.cpp",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_26.cpp",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_26.h",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_26.h",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_55.cpp",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_55.cpp",
|
||||||
@ -5258,8 +5260,6 @@ if (BUSES["CBUS"]~=null) then
|
|||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_86.h",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_86.h",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_118.cpp",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_118.cpp",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_118.h",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_118.h",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_amd98.cpp",
|
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_amd98.h",
|
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_snd.cpp",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_snd.cpp",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/pc9801_snd.h",
|
MAME_DIR .. "src/devices/bus/cbus/pc9801_snd.h",
|
||||||
MAME_DIR .. "src/devices/bus/cbus/mpu_pc98.cpp",
|
MAME_DIR .. "src/devices/bus/cbus/mpu_pc98.cpp",
|
||||||
|
@ -2,16 +2,16 @@
|
|||||||
// copyright-holders:Angelo Salese
|
// copyright-holders:Angelo Salese
|
||||||
/**************************************************************************************************
|
/**************************************************************************************************
|
||||||
|
|
||||||
System Sacom AMD-98 (AmuseMent boarD)
|
System Sacom AMD-98 (AmuseMent boarD)
|
||||||
|
|
||||||
3 PSG chips, one of the first sound boards released for PC98
|
3 PSG chips, one of the first sound boards released for PC98
|
||||||
Superseded by later NEC in-house sound boards
|
Superseded by later NEC in-house sound boards
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- not sure if it's AY8910 or YM2203, from a PCB pic it looks with stock AY logos?
|
- not sure if it's AY8910 or YM2203, from a PCB pic it looks with stock AY logos?
|
||||||
- Third AY (uses port B from BOTH AYs);
|
- f/f not completely understood;
|
||||||
- PIT control;
|
- PIT control;
|
||||||
- PCM section;
|
- PCM section;
|
||||||
|
|
||||||
===================================================================================================
|
===================================================================================================
|
||||||
|
|
||||||
@ -28,38 +28,49 @@
|
|||||||
**************************************************************************************************/
|
**************************************************************************************************/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "bus/cbus/pc9801_amd98.h"
|
#include "bus/cbus/amd98.h"
|
||||||
#include "speaker.h"
|
#include "speaker.h"
|
||||||
|
|
||||||
|
#define LOG_LATCH (1U << 1) // Detailed AY3 latch setups
|
||||||
|
|
||||||
|
|
||||||
|
#define VERBOSE (LOG_GENERAL)
|
||||||
|
//#define LOG_OUTPUT_FUNC osd_printf_info
|
||||||
|
#include "logmacro.h"
|
||||||
|
|
||||||
|
#define LOGLATCH(...) LOGMASKED(LOG_LATCH, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// GLOBAL VARIABLES
|
// GLOBAL VARIABLES
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
DEFINE_DEVICE_TYPE(PC9801_AMD98, pc9801_amd98_device, "pc9801_amd98", "System Sacom AMD-98")
|
DEFINE_DEVICE_TYPE(AMD98, amd98_device, "amd98", "System Sacom AMD-98")
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// device_add_mconfig - add device configuration
|
// device_add_mconfig - add device configuration
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void pc9801_amd98_device::device_add_mconfig(machine_config &config)
|
void amd98_device::device_add_mconfig(machine_config &config)
|
||||||
{
|
{
|
||||||
SPEAKER(config, "lspeaker").front_left();
|
// Assume mono, as per highway making engine noise from ay1 only
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "speaker").front_center();
|
||||||
AY8910(config, m_ay1, 1'996'800);
|
AY8910(config, m_ay1, 1'996'800);
|
||||||
m_ay1->port_a_read_callback().set_ioport("OPN_PA1");
|
m_ay1->port_a_read_callback().set_ioport("OPN_PA1");
|
||||||
m_ay1->port_b_write_callback().set(FUNC(pc9801_amd98_device::ay3_address_w));
|
m_ay1->port_b_write_callback().set(FUNC(amd98_device::ay3_address_w));
|
||||||
m_ay1->add_route(ALL_OUTPUTS, "lspeaker", 0.50);
|
m_ay1->add_route(ALL_OUTPUTS, "speaker", 0.50);
|
||||||
|
|
||||||
AY8910(config, m_ay2, 1'996'800);
|
AY8910(config, m_ay2, 1'996'800);
|
||||||
m_ay2->port_a_read_callback().set_ioport("OPN_PA2");
|
m_ay2->port_a_read_callback().set_ioport("OPN_PA2");
|
||||||
m_ay2->port_b_write_callback().set(FUNC(pc9801_amd98_device::ay3_data_latch_w));
|
m_ay2->port_b_write_callback().set(FUNC(amd98_device::ay3_data_latch_w));
|
||||||
m_ay2->add_route(ALL_OUTPUTS, "rspeaker", 0.50);
|
m_ay2->add_route(ALL_OUTPUTS, "speaker", 0.50);
|
||||||
|
|
||||||
AY8910(config, m_ay3, 1'996'800);
|
AY8910(config, m_ay3, 1'996'800);
|
||||||
m_ay3->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
m_ay3->port_b_write_callback().set([this] (u8 data) {
|
||||||
m_ay3->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
LOG("AMD-98 DAC %02x\n", data);
|
||||||
|
});
|
||||||
|
m_ay3->add_route(ALL_OUTPUTS, "speaker", 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INPUT_PORTS_START( pc9801_amd98 )
|
static INPUT_PORTS_START( pc9801_amd98 )
|
||||||
@ -84,7 +95,7 @@ static INPUT_PORTS_START( pc9801_amd98 )
|
|||||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
ioport_constructor pc9801_amd98_device::device_input_ports() const
|
ioport_constructor amd98_device::device_input_ports() const
|
||||||
{
|
{
|
||||||
return INPUT_PORTS_NAME( pc9801_amd98 );
|
return INPUT_PORTS_NAME( pc9801_amd98 );
|
||||||
}
|
}
|
||||||
@ -97,11 +108,11 @@ ioport_constructor pc9801_amd98_device::device_input_ports() const
|
|||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// pc9801_amd98_device - constructor
|
// amd98_device - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
pc9801_amd98_device::pc9801_amd98_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
amd98_device::amd98_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||||
: device_t(mconfig, PC9801_AMD98, tag, owner, clock)
|
: device_t(mconfig, AMD98, tag, owner, clock)
|
||||||
, m_bus(*this, DEVICE_SELF_OWNER)
|
, m_bus(*this, DEVICE_SELF_OWNER)
|
||||||
, m_ay1(*this, "ay1")
|
, m_ay1(*this, "ay1")
|
||||||
, m_ay2(*this, "ay2")
|
, m_ay2(*this, "ay2")
|
||||||
@ -115,7 +126,7 @@ pc9801_amd98_device::pc9801_amd98_device(const machine_config &mconfig, const ch
|
|||||||
// on this device
|
// on this device
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void pc9801_amd98_device::device_validity_check(validity_checker &valid) const
|
void amd98_device::device_validity_check(validity_checker &valid) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +134,7 @@ void pc9801_amd98_device::device_validity_check(validity_checker &valid) const
|
|||||||
// device_start - device-specific startup
|
// device_start - device-specific startup
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void pc9801_amd98_device::device_start()
|
void amd98_device::device_start()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,11 +143,11 @@ void pc9801_amd98_device::device_start()
|
|||||||
// device_reset - device-specific reset
|
// device_reset - device-specific reset
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void pc9801_amd98_device::device_reset()
|
void amd98_device::device_reset()
|
||||||
{
|
{
|
||||||
m_bus->install_io(0x00d8, 0x00df, read8sm_delegate(*this, FUNC(pc9801_amd98_device::read)), write8sm_delegate(*this, FUNC(pc9801_amd98_device::write)));
|
m_bus->install_io(0x00d8, 0x00df, read8sm_delegate(*this, FUNC(amd98_device::read)), write8sm_delegate(*this, FUNC(amd98_device::write)));
|
||||||
// Thexder access with following
|
// thexder access with following
|
||||||
m_bus->install_io(0x38d8, 0x38df, read8sm_delegate(*this, FUNC(pc9801_amd98_device::read)), write8sm_delegate(*this, FUNC(pc9801_amd98_device::write)));
|
m_bus->install_io(0x38d8, 0x38df, read8sm_delegate(*this, FUNC(amd98_device::read)), write8sm_delegate(*this, FUNC(amd98_device::write)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -144,7 +155,7 @@ void pc9801_amd98_device::device_reset()
|
|||||||
// READ/WRITE HANDLERS
|
// READ/WRITE HANDLERS
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
uint8_t pc9801_amd98_device::read(offs_t offset)
|
uint8_t amd98_device::read(offs_t offset)
|
||||||
{
|
{
|
||||||
switch(offset)
|
switch(offset)
|
||||||
{
|
{
|
||||||
@ -154,12 +165,12 @@ uint8_t pc9801_amd98_device::read(offs_t offset)
|
|||||||
return m_ay2->data_r();
|
return m_ay2->data_r();
|
||||||
}
|
}
|
||||||
|
|
||||||
logerror("%02x\n",offset);
|
LOG("AMD-98: unhandled %02x read\n", offset + 0xd8);
|
||||||
|
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pc9801_amd98_device::write(offs_t offset, uint8_t data)
|
void amd98_device::write(offs_t offset, uint8_t data)
|
||||||
{
|
{
|
||||||
switch(offset)
|
switch(offset)
|
||||||
{
|
{
|
||||||
@ -176,27 +187,34 @@ void pc9801_amd98_device::write(offs_t offset, uint8_t data)
|
|||||||
m_ay2->data_w(data);
|
m_ay2->data_w(data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logerror("%02x %02x\n",offset,data);
|
LOG("AMD-98: unhandled %02x write %02x\n", offset + 0xd8, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pc9801_amd98_device::ay3_address_w(uint8_t data)
|
void amd98_device::ay3_address_w(uint8_t data)
|
||||||
{
|
{
|
||||||
|
LOGLATCH("AMD-98 AY3 latch %02x\n", data);
|
||||||
m_ay3_latch = data;
|
m_ay3_latch = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pc9801_amd98_device::ay3_data_latch_w(uint8_t data)
|
void amd98_device::ay3_data_latch_w(uint8_t data)
|
||||||
{
|
{
|
||||||
// TODO: this actually uses a flip flop mechanism, not quite sure about how it works yet
|
// TODO: actually goes 0 -> 1 -> 0
|
||||||
switch(data)
|
// TODO: thexder is the odd one: uses 0x00 -> 0x40 -> 0x47 (address) -> 0x40 -> 0x40 -> 0x43 (data) -> 0x40
|
||||||
|
if (!BIT(m_ay3_ff, 0) && BIT(data, 0))
|
||||||
{
|
{
|
||||||
case 0x47:
|
switch(data & 0xc2)
|
||||||
//logerror("%02x addr\n",m_ay3_latch);
|
{
|
||||||
m_ay3->address_w(m_ay3_latch);
|
case 0x42:
|
||||||
break;
|
LOG("AMD-98 AY3 write %02x address (f/f %02x)\n", m_ay3_latch, m_ay3_ff);
|
||||||
case 0x43:
|
m_ay3->address_w(m_ay3_latch);
|
||||||
//logerror("%02x data\n",m_ay3_latch);
|
break;
|
||||||
m_ay3->data_w(m_ay3_latch);
|
case 0x40:
|
||||||
break;
|
LOG("AMD-98 AY3 write %02x data (f/f %02x)\n", m_ay3_latch, m_ay3_ff);
|
||||||
|
m_ay3->data_w(m_ay3_latch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
LOGLATCH("AMD-98 f/f %02x %02x\n", data, m_ay3_latch);
|
||||||
|
m_ay3_ff = data;
|
||||||
}
|
}
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef MAME_BUS_CBUS_PC9801_AMD98_H
|
#ifndef MAME_BUS_CBUS_AMD98_H
|
||||||
#define MAME_BUS_CBUS_PC9801_AMD98_H
|
#define MAME_BUS_CBUS_AMD98_H
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -18,13 +18,13 @@
|
|||||||
// TYPE DEFINITIONS
|
// TYPE DEFINITIONS
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
// ======================> pc9801_amd98_device
|
// ======================> amd98_device
|
||||||
|
|
||||||
class pc9801_amd98_device : public device_t
|
class amd98_device : public device_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
pc9801_amd98_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
amd98_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
static constexpr feature_type imperfect_features() { return feature::SOUND; }
|
static constexpr feature_type imperfect_features() { return feature::SOUND; }
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ private:
|
|||||||
void ay3_address_w(uint8_t data);
|
void ay3_address_w(uint8_t data);
|
||||||
void ay3_data_latch_w(uint8_t data);
|
void ay3_data_latch_w(uint8_t data);
|
||||||
|
|
||||||
uint8_t m_ay3_latch;
|
uint8_t m_ay3_latch, m_ay3_ff;
|
||||||
|
|
||||||
required_device<pc9801_slot_device> m_bus;
|
required_device<pc9801_slot_device> m_bus;
|
||||||
required_device<ay8910_device> m_ay1;
|
required_device<ay8910_device> m_ay1;
|
||||||
@ -54,6 +54,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
DECLARE_DEVICE_TYPE(PC9801_AMD98, pc9801_amd98_device)
|
DECLARE_DEVICE_TYPE(AMD98, amd98_device)
|
||||||
|
|
||||||
#endif // MAME_BUS_CBUS_PC9801_AMD98_H
|
#endif // MAME_BUS_CBUS_AMD98_H
|
@ -432,7 +432,7 @@ TIMER_CALLBACK_MEMBER(pc9801_86_device::dac_tick)
|
|||||||
//
|
//
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(PC9801_SPEAKBOARD, pc9801_speakboard_device, "pc9801_spb", "NEC PC9801 SpeakBoard")
|
DEFINE_DEVICE_TYPE(PC9801_SPEAKBOARD, pc9801_speakboard_device, "pc9801_spb", "NEC PC-9801 SpeakBoard")
|
||||||
|
|
||||||
ROM_START( pc9801_spb )
|
ROM_START( pc9801_spb )
|
||||||
ROM_REGION( 0x4000, "sound_bios", ROMREGION_ERASEFF )
|
ROM_REGION( 0x4000, "sound_bios", ROMREGION_ERASEFF )
|
||||||
|
@ -605,7 +605,8 @@ uint8_t pc9801_state::f0_r(offs_t offset)
|
|||||||
{
|
{
|
||||||
// iterate thru all devices to check if an AMD98 is present
|
// iterate thru all devices to check if an AMD98 is present
|
||||||
// TODO: move to cbus
|
// TODO: move to cbus
|
||||||
for (pc9801_amd98_device &amd98 : device_type_enumerator<pc9801_amd98_device>(machine().root_device()))
|
// TODO: is this really part of PC-98 spec or it's coming from the device itself, as dip/jumper?
|
||||||
|
for (amd98_device &amd98 : device_type_enumerator<amd98_device>(machine().root_device()))
|
||||||
{
|
{
|
||||||
logerror("%s: Read AMD98 ID %s\n", machine().describe_context(), amd98.tag());
|
logerror("%s: Read AMD98 ID %s\n", machine().describe_context(), amd98.tag());
|
||||||
return 0x18; // return the right ID
|
return 0x18; // return the right ID
|
||||||
@ -1877,15 +1878,15 @@ static void pc9801_cbus_devices(device_slot_interface &device)
|
|||||||
{
|
{
|
||||||
// official HW
|
// official HW
|
||||||
// PC-9801-14
|
// PC-9801-14
|
||||||
device.option_add("pc9801_26", PC9801_26);
|
device.option_add("pc9801_26", PC9801_26);
|
||||||
device.option_add("pc9801_55u", PC9801_55U);
|
device.option_add("pc9801_55u", PC9801_55U);
|
||||||
device.option_add("pc9801_55l", PC9801_55L);
|
device.option_add("pc9801_55l", PC9801_55L);
|
||||||
device.option_add("pc9801_86", PC9801_86);
|
device.option_add("pc9801_86", PC9801_86);
|
||||||
device.option_add("pc9801_118", PC9801_118);
|
device.option_add("pc9801_118", PC9801_118);
|
||||||
device.option_add("pc9801_spb", PC9801_SPEAKBOARD);
|
device.option_add("pc9801_spb", PC9801_SPEAKBOARD);
|
||||||
// Spark Board
|
// Spark Board
|
||||||
device.option_add("pc9801_amd98", PC9801_AMD98); // AmuseMent boarD
|
device.option_add("amd98", AMD98);
|
||||||
device.option_add("mpu_pc98", MPU_PC98);
|
device.option_add("mpu_pc98", MPU_PC98);
|
||||||
|
|
||||||
// doujinshi HW
|
// doujinshi HW
|
||||||
// MAD Factory / Doujin Hard (同人ハード)
|
// MAD Factory / Doujin Hard (同人ハード)
|
||||||
|
@ -44,11 +44,11 @@
|
|||||||
|
|
||||||
#include "video/upd7220.h"
|
#include "video/upd7220.h"
|
||||||
|
|
||||||
|
#include "bus/cbus/amd98.h"
|
||||||
#include "bus/cbus/pc9801_26.h"
|
#include "bus/cbus/pc9801_26.h"
|
||||||
#include "bus/cbus/pc9801_55.h"
|
#include "bus/cbus/pc9801_55.h"
|
||||||
#include "bus/cbus/pc9801_86.h"
|
#include "bus/cbus/pc9801_86.h"
|
||||||
#include "bus/cbus/pc9801_118.h"
|
#include "bus/cbus/pc9801_118.h"
|
||||||
#include "bus/cbus/pc9801_amd98.h"
|
|
||||||
#include "bus/cbus/mpu_pc98.h"
|
#include "bus/cbus/mpu_pc98.h"
|
||||||
#include "bus/cbus/pc9801_cbus.h"
|
#include "bus/cbus/pc9801_cbus.h"
|
||||||
#include "pc9801_kbd.h"
|
#include "pc9801_kbd.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user