pcat_dyn: add sound and mark toursol working [Carl]

This commit is contained in:
cracyc 2016-03-19 21:13:00 -05:00
parent 9328fa9028
commit 8fc8fc5ca3
8 changed files with 450 additions and 9 deletions

View File

@ -1314,3 +1314,14 @@ if (SOUNDS["VRC6"]~=null) then
}
end
---------------------------------------------------
-- AD1848
--@src/devices/sound/ad1848.h,SOUNDS["AD1848"] = true
---------------------------------------------------
if (SOUNDS["AD1848"]~=null) then
files {
MAME_DIR .. "src/devices/sound/ad1848.cpp",
MAME_DIR .. "src/devices/sound/ad1848.h",
}
end

View File

@ -257,6 +257,7 @@ SOUNDS["SB0400"] = true
SOUNDS["AC97"] = true
SOUNDS["ES1373"] = true
SOUNDS["L7A1045"] = true
SOUNDS["AD1848"] = true
--------------------------------------------------
-- specify available video cores

View File

@ -1069,6 +1069,118 @@ WRITE8_MEMBER( sb16_device::mixer_w )
return;
}
void sb8_device::drq_w(int state)
{
switch(m_config->read() & 0x0c)
{
case 0:
default:
m_isa->drq1_w(state);
break;
case 4:
m_isa->drq3_w(state);
break;
}
}
void sb8_device::irq_w(int state, int source)
{
switch(m_config->read() & 0x03)
{
case 0:
default:
m_isa->irq5_w(state);
break;
case 1:
m_isa->irq7_w(state);
break;
}
}
// TODO: sb16 irq/drq is software set
void sb16_device::drq_w(int state)
{
switch(m_config->read() & 0x0c)
{
case 0:
default:
m_isa->drq1_w(state);
break;
case 4:
m_isa->drq3_w(state);
break;
}
}
void sb16_device::irq_w(int state, int source)
{
if(state)
m_dsp.irq_active |= source;
else
m_dsp.irq_active &= ~source;
switch(m_config->read() & 0x03)
{
case 0:
default:
m_isa->irq5_w(m_dsp.irq_active != 0);
break;
case 1:
m_isa->irq7_w(m_dsp.irq_active != 0);
break;
}
}
void sb16_device::drq16_w(int state)
{
switch(m_config->read() & 0xc0)
{
case 0:
default:
m_isa->drq5_w(state);
break;
case 0x40:
m_isa->drq6_w(state);
break;
case 0x80:
m_isa->drq7_w(state);
break;
}
}
static INPUT_PORTS_START( sb8 )
PORT_START("CONFIG")
PORT_CONFNAME(0x03, 0x00, "Default IRQ")
PORT_CONFSETTING( 0x00, "IRQ5")
PORT_CONFSETTING( 0x01, "IRQ7")
PORT_CONFNAME(0x0c, 0x00, "Default DMA")
PORT_CONFSETTING( 0x00, "DMA1")
PORT_CONFSETTING( 0x04, "DMA3")
//PORT_CONFNAME(0x30, 0x00, "Default Port Base")
//PORT_CONFSETTING( 0x00, "220")
//PORT_CONFSETTING( 0x10, "240")
//PORT_CONFSETTING( 0x20, "260")
INPUT_PORTS_END
static INPUT_PORTS_START( sb16 )
PORT_INCLUDE(sb8)
PORT_MODIFY("CONFIG")
PORT_CONFNAME(0xc0, 0x00, "Default DMA16")
PORT_CONFSETTING( 0x00, "DMA5")
PORT_CONFSETTING( 0x40, "DMA6")
PORT_CONFSETTING( 0x80, "DMA7")
INPUT_PORTS_END
ioport_constructor sb8_device::device_input_ports() const
{
return INPUT_PORTS_NAME(sb8);
}
ioport_constructor sb16_device::device_input_ports() const
{
return INPUT_PORTS_NAME(sb16);
}
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@ -1107,7 +1219,8 @@ sb_device::sb_device(const machine_config &mconfig, device_type type, const char
m_dacl(*this, "sbdacl"),
m_dacr(*this, "sbdacr"),
m_joy(*this, "pc_joy"),
m_mdout(*this, "mdout"), m_dack_out(0), m_onebyte_midi(false), m_uart_midi(false), m_uart_irq(false), m_mpu_midi(false), m_rx_waiting(0), m_tx_waiting(0), m_xmit_read(0), m_xmit_write(0), m_recv_read(0), m_recv_write(0), m_tx_busy(false), m_timer(nullptr)
m_mdout(*this, "mdout"),
m_config(*this, "CONFIG"), m_dack_out(0), m_onebyte_midi(false), m_uart_midi(false), m_uart_irq(false), m_mpu_midi(false), m_rx_waiting(0), m_tx_waiting(0), m_xmit_read(0), m_xmit_write(0), m_recv_read(0), m_recv_write(0), m_tx_busy(false), m_timer(nullptr)
{
}

View File

@ -103,6 +103,7 @@ public:
required_device<dac_device> m_dacr;
required_device<pc_joy_device> m_joy;
required_device<midi_port_device> m_mdout;
required_ioport m_config;
void process_fifo(UINT8 cmd);
void queue(UINT8 data);
@ -162,10 +163,11 @@ public:
DECLARE_READ8_MEMBER(ym3812_16_r);
DECLARE_WRITE8_MEMBER(ym3812_16_w);
virtual ioport_constructor device_input_ports() const override;
protected:
virtual void device_start() override;
virtual void drq_w(int state) override { m_isa->drq1_w(state); }
virtual void irq_w(int state, int source) override { m_isa->irq5_w(state); }
virtual void drq_w(int state) override;
virtual void irq_w(int state, int source) override;
virtual UINT8 dack_r(int line) override { return sb_device::dack_r(line); }
virtual void dack_w(int line, UINT8 data) override { sb_device::dack_w(line, data); }
private:
@ -217,15 +219,16 @@ public:
DECLARE_WRITE8_MEMBER(mpu401_w);
DECLARE_READ8_MEMBER(mixer_r);
DECLARE_WRITE8_MEMBER(mixer_w);
virtual ioport_constructor device_input_ports() const override;
protected:
virtual void device_start() override;
virtual UINT16 dack16_r(int line) override;
virtual UINT8 dack_r(int line) override { return sb_device::dack_r(line); }
virtual void dack_w(int line, UINT8 data) override { sb_device::dack_w(line, data); }
virtual void dack16_w(int line, UINT16 data) override;
virtual void drq16_w(int state) override { m_isa->drq5_w(state); }
virtual void drq_w(int state) override { m_isa->drq1_w(state); }
virtual void irq_w(int state, int source) override { (state?m_dsp.irq_active|=source:m_dsp.irq_active&=~source); m_isa->irq5_w(m_dsp.irq_active != 0); }
virtual void drq16_w(int state) override;
virtual void drq_w(int state) override;
virtual void irq_w(int state, int source) override;
virtual void mixer_reset() override;
void mixer_set();
virtual void rcv_complete() override; // Rx completed receiving byte

View File

@ -33,6 +33,8 @@ READ8_MEMBER ( pc_joy_device::joy_port_r )
WRITE8_MEMBER ( pc_joy_device::joy_port_w )
{
m_stime = machine().time();
if(!m_dev)
return;
m_dev->port_write();
}

View File

@ -0,0 +1,186 @@
// license:BSD-3-Clause
// copyright-holders:Carl
// Analog Devices AD1848, main codec in Windows Sound System adapters
#include "sound/ad1848.h"
const device_type AD1848 = device_creator<ad1848_device>;
ad1848_device::ad1848_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, AD1848, "Analog Devices AD1848", tag, owner, clock, "ad1848", __FILE__),
m_irq_cb(*this),
m_drq_cb(*this),
m_dacl(*this, "dacl"),
m_dacr(*this, "dacr")
{
}
static MACHINE_CONFIG_FRAGMENT( ad1848_config )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("dacl", DAC, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.00)
MCFG_SOUND_ADD("dacr", DAC, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.00)
MACHINE_CONFIG_END
machine_config_constructor ad1848_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( ad1848_config );
}
void ad1848_device::device_start()
{
m_timer = timer_alloc(0, nullptr);
m_irq_cb.resolve_safe();
m_drq_cb.resolve_safe();
}
void ad1848_device::device_reset()
{
memset(&m_regs.idx[0], '\0', sizeof(m_regs));
m_addr = 0;
m_stat = 0;
m_sam_cnt = 0;
m_samples = 0;
m_play = false;
}
READ8_MEMBER(ad1848_device::read)
{
switch(offset)
{
case 0:
return m_addr | (m_mce ? 0x40 : 0) | (m_trd ? 0x20 : 0);
case 1:
return m_regs.idx[m_addr];
case 2:
return m_stat;
case 3:
break; // capture
}
return 0;
}
WRITE8_MEMBER(ad1848_device::write)
{
const int div_factor[] = {3072, 1536, 896, 768, 448, 384, 512, 2560};
switch(offset)
{
case 0:
m_addr = data & 0xf;
m_mce = data & 0x40 ? true : false;
m_trd = data & 0x20 ? true : false;
break;
case 1:
if(m_addr == 12)
return;
m_regs.idx[m_addr] = data;
switch(m_addr)
{
case 8:
if(m_mce)
return;
m_regs.dform &= 0x7f;
break;
case 9:
{
m_play = (data & 1) ? true : false;
attotime rate = m_play ? attotime::from_hz(((m_regs.dform & 1) ? XTAL_24_576MHz : XTAL_16_9344MHz)
/ div_factor[(m_regs.dform >> 1) & 7]) : attotime::never;
m_timer->adjust(rate, 0 , rate);
m_drq_cb(m_play ? ASSERT_LINE : CLEAR_LINE);
break;
}
case 14:
m_count = (m_regs.ubase << 8) | m_regs.lbase;
break;
}
break;
case 2:
m_irq_cb(CLEAR_LINE);
if(m_regs.iface & 1)
m_play = true;
break;
case 3:
break; // playback
}
}
READ8_MEMBER(ad1848_device::dack_r)
{
m_drq_cb(CLEAR_LINE);
return 0; // not implemented
}
WRITE8_MEMBER(ad1848_device::dack_w)
{
if(!m_play)
return;
m_samples = (m_samples << 8) | data;
m_sam_cnt++;
switch(m_regs.dform >> 4)
{
case 0:
case 2:
case 6:
m_sam_cnt = 0;
break;
case 1:
case 3:
case 4:
case 7:
if(m_sam_cnt == 2)
m_sam_cnt = 0;
break;
case 5:
if(m_sam_cnt == 4)
m_sam_cnt = 0;
break;
}
if(!m_sam_cnt)
m_drq_cb(CLEAR_LINE);
}
void ad1848_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if(!m_play)
return;
switch(m_regs.dform >> 4)
{
case 0: // 8bit mono
m_dacl->write_unsigned8(m_samples & 0xff);
m_dacr->write_unsigned8(m_samples & 0xff);
break;
case 1: // 8bit stereo
m_dacl->write_unsigned8(m_samples & 0xff);
m_dacr->write_unsigned8((m_samples >> 8) & 0xff);
break;
case 2: // ulaw mono
case 3: // ulaw stereo
case 6: // alaw mono
case 7: // alaw stereo
break;
case 4: // 16bit mono
m_dacl->write(m_samples & 0xffff);
m_dacr->write(m_samples & 0xffff);
break;
case 5: // 16bit stereo
m_dacl->write(m_samples & 0xffff);
m_dacr->write(m_samples >> 16);
break;
}
if(!m_count)
{
if(m_regs.pinc & 2)
{
if(m_trd)
m_play = false;
m_irq_cb(ASSERT_LINE);
}
m_count = (m_regs.ubase << 8) | m_regs.lbase;
}
else
m_count--;
m_drq_cb(ASSERT_LINE);
}

View File

@ -0,0 +1,67 @@
// license:BSD-3-Clause
// copyright-holders:Carl
#ifndef _AD1848_H_
#define _AD1848_H_
#include "emu.h"
#include "sound/dac.h"
#define MCFG_AD1848_IRQ_CALLBACK(_cb) \
devcb = &ad1848_device::set_irq_callback(*device, DEVCB_##_cb);
#define MCFG_AD1848_DRQ_CALLBACK(_cb) \
devcb = &ad1848_device::set_drq_callback(*device, DEVCB_##_cb);
class ad1848_device : public device_t
{
public:
ad1848_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
DECLARE_READ8_MEMBER(dack_r);
DECLARE_WRITE8_MEMBER(dack_w);
template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<ad1848_device &>(device).m_irq_cb.set_callback(object); }
template<class _Object> static devcb_base &set_drq_callback(device_t &device, _Object object) { return downcast<ad1848_device &>(device).m_drq_cb.set_callback(object); }
virtual machine_config_constructor device_mconfig_additions() const override;
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
union {
struct {
UINT8 linp;
UINT8 rinp;
UINT8 laux1;
UINT8 raux1;
UINT8 laux2;
UINT8 raux2;
UINT8 lout;
UINT8 rout;
UINT8 dform;
UINT8 iface;
UINT8 pinc;
UINT8 init;
UINT8 misc;
UINT8 mix;
UINT8 ubase;
UINT8 lbase;
};
UINT8 idx[15];
} m_regs;
UINT8 m_addr;
UINT8 m_stat;
UINT16 m_count;
UINT32 m_samples;
UINT8 m_sam_cnt;
bool m_play, m_mce, m_trd;
devcb_write_line m_irq_cb;
devcb_write_line m_drq_cb;
required_device<dac_device> m_dacl;
required_device<dac_device> m_dacr;
emu_timer *m_timer;
};
extern const device_type AD1848;
#endif

View File

@ -9,7 +9,7 @@ Unmodified 486 PC-AT HW.
Jet Way Information Co. OP495SLC motherboard
- AMD Am486-DX40 CPU
- Trident TVGA9000i video card
- Breve Technologies audio adapter
- Breve Technologies audio adapter, WSS+Sound Blaster
- CH Products RollerMouse serial trackball, Mouse Systems compatible
preliminary driver by Angelo Salese
@ -28,23 +28,30 @@ If the output isn't satisfactory, it prints "I/O BOARD FAILURE".
#include "machine/ds128x.h"
#include "machine/ins8250.h"
#include "machine/nvram.h"
#include "sound/ad1848.h"
#include "bus/rs232/rs232.h"
#include "bus/rs232/ser_mouse.h"
#include "bus/isa/isa.h"
#include "bus/isa/sblaster.h"
class pcat_dyn_state : public pcat_base_state
{
public:
pcat_dyn_state(const machine_config &mconfig, device_type type, const char *tag)
: pcat_base_state(mconfig, type, tag)
, m_isabus(*this, "isa")
, m_prgbank(*this, "prgbank")
, m_nvram_bank(*this, "nvram_bank")
, m_nvram_mem(0x2000){ }
required_device<isa8_device> m_isabus;
required_memory_bank m_prgbank;
required_memory_bank m_nvram_bank;
std::vector<UINT8> m_nvram_mem;
DECLARE_WRITE8_MEMBER(bank1_w);
DECLARE_WRITE8_MEMBER(bank2_w);
DECLARE_READ8_MEMBER(audio_r);
DECLARE_WRITE8_MEMBER(dma8237_1_dack_w);
virtual void machine_start() override;
void nvram_init(nvram_device &nvram, void *base, size_t size);
};
@ -61,6 +68,16 @@ void pcat_dyn_state::nvram_init(nvram_device &nvram, void *base, size_t size)
memcpy(base, memregion("nvram")->base(), size);
}
READ8_MEMBER(pcat_dyn_state::audio_r)
{
switch(offset)
{
case 3:
return 4;
}
return 0;
}
WRITE8_MEMBER(pcat_dyn_state::bank1_w)
{
m_prgbank->set_entry(data);
@ -91,9 +108,12 @@ static ADDRESS_MAP_START( pcat_io, AS_IO, 32, pcat_dyn_state )
AM_RANGE(0x03c0, 0x03cf) AM_DEVREADWRITE8("vga", trident_vga_device, port_03c0_r, port_03c0_w, 0xffffffff)
AM_RANGE(0x03d0, 0x03df) AM_DEVREADWRITE8("vga", trident_vga_device, port_03d0_r, port_03d0_w, 0xffffffff)
AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ns16550", ns16550_device, ins8250_r, ins8250_w, 0xffffffff)
AM_RANGE(0x0530, 0x0533) AM_READ8(audio_r, 0xffffffff)
AM_RANGE(0x0534, 0x0537) AM_DEVREADWRITE8("ad1848", ad1848_device, read, write, 0xffffffff)
ADDRESS_MAP_END
//TODO: use atmb device
WRITE8_MEMBER( pcat_dyn_state::dma8237_1_dack_w ){ m_isabus->dack_w(1, data); }
static INPUT_PORTS_START( pcat_dyn )
// M,N,Numpad 6 -- Hang
@ -114,6 +134,19 @@ static SLOT_INTERFACE_START(pcat_dyn_com)
SLOT_INTERFACE("msmouse", MSYSTEM_SERIAL_MOUSE)
SLOT_INTERFACE_END
static SLOT_INTERFACE_START( pcat_dyn_isa8_cards )
SLOT_INTERFACE("sb15", ISA8_SOUND_BLASTER_1_5)
SLOT_INTERFACE_END
static DEVICE_INPUT_DEFAULTS_START( pcat_dyn_sb_def )
DEVICE_INPUT_DEFAULTS("CONFIG", 0x03, 0x01)
DEVICE_INPUT_DEFAULTS_END
static MACHINE_CONFIG_FRAGMENT( pcat_dyn_sb_conf )
MCFG_DEVICE_MODIFY("pc_joy")
MCFG_DEVICE_SLOT_INTERFACE(pc_joysticks, nullptr, true) // remove joystick
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( pcat_dyn, pcat_dyn_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", I486, 40000000) /* Am486 DX-40 */
@ -134,6 +167,14 @@ static MACHINE_CONFIG_START( pcat_dyn, pcat_dyn_state )
MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_2", pic8259_device, ir0_w))
MCFG_MC146818_CENTURY_INDEX(0x32)
MCFG_SOUND_ADD("ad1848", AD1848, 0)
MCFG_AD1848_IRQ_CALLBACK(DEVWRITELINE("pic8259_1", pic8259_device, ir5_w))
MCFG_AD1848_DRQ_CALLBACK(DEVWRITELINE("dma8237_1", am9517a_device, dreq0_w))
MCFG_DEVICE_MODIFY("dma8237_1")
MCFG_I8237_OUT_IOW_0_CB(DEVWRITE8("ad1848", ad1848_device, dack_w))
MCFG_I8237_OUT_IOW_1_CB(WRITE8(pcat_dyn_state, dma8237_1_dack_w))
MCFG_NVRAM_ADD_CUSTOM_DRIVER("nvram", pcat_dyn_state, nvram_init)
MCFG_DEVICE_ADD( "ns16550", NS16550, XTAL_1_8432MHz )
@ -148,6 +189,22 @@ static MACHINE_CONFIG_START( pcat_dyn, pcat_dyn_state )
MCFG_RS232_DSR_HANDLER(DEVWRITELINE("ns16550", ins8250_uart_device, dsr_w))
MCFG_RS232_RI_HANDLER(DEVWRITELINE("ns16550", ins8250_uart_device, ri_w))
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("ns16550", ins8250_uart_device, cts_w))
MCFG_DEVICE_ADD("isa", ISA8, 0)
MCFG_ISA8_CPU(":maincpu")
MCFG_ISA_OUT_IRQ2_CB(DEVWRITELINE("pic8259_2", pic8259_device, ir2_w))
MCFG_ISA_OUT_IRQ3_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir3_w))
//MCFG_ISA_OUT_IRQ4_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir4_w))
//MCFG_ISA_OUT_IRQ5_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir5_w))
MCFG_ISA_OUT_IRQ6_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir6_w))
MCFG_ISA_OUT_IRQ7_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir7_w))
MCFG_ISA_OUT_DRQ1_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq1_w))
MCFG_ISA_OUT_DRQ2_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq2_w))
MCFG_ISA_OUT_DRQ3_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq3_w))
MCFG_ISA8_SLOT_ADD("isa", "isa1", pcat_dyn_isa8_cards, "sb15", true)
MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("sb15", pcat_dyn_sb_def)
MCFG_DEVICE_CARD_MACHINE_CONFIG("sb15", pcat_dyn_sb_conf)
MACHINE_CONFIG_END
/***************************************
@ -170,6 +227,7 @@ ROM_START(toursol)
ROM_LOAD("sol.u23", 0x80000, 0x40000, CRC(d1e39bd4) SHA1(39c7ee43cddb53fba0f7c0572ddc40289c4edd07))
ROM_LOAD("sol.u24", 0xc0000, 0x40000, CRC(555341e0) SHA1(81fee576728855e234ff7aae06f54ae9705c3ab5))
ROM_FILL(0x2a3e6, 1, 0xeb) // skip prot(?) check
ROM_FILL(0x51bd2, 2, 0x90) // opl2 probe expects timer expiration too quickly
ROM_REGION(0x2000, "nvram", 0)
ROM_LOAD("sol.u28", 0, 0x2000, CRC(c9374d50) SHA1(49173bc69f70bb2a7e8af9d03e2538b34aa881d8))
@ -201,5 +259,5 @@ ROM_START(toursol1)
ROM_END
GAME( 1995, toursol, 0, pcat_dyn, pcat_dyn, driver_device, 0, ROT0, "Dynamo", "Tournament Solitaire (V1.06, 08/03/95)", MACHINE_NOT_WORKING|MACHINE_NO_SOUND )
GAME( 1995, toursol, 0, pcat_dyn, pcat_dyn, driver_device, 0, ROT0, "Dynamo", "Tournament Solitaire (V1.06, 08/03/95)", MACHINE_UNEMULATED_PROTECTION )
GAME( 1995, toursol1, toursol, pcat_dyn, pcat_dyn, driver_device, 0, ROT0, "Dynamo", "Tournament Solitaire (V1.04, 06/22/95)", MACHINE_NOT_WORKING|MACHINE_NO_SOUND )