diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua index 6fd7e6398d7..b3d605d9dc7 100644 --- a/scripts/src/sound.lua +++ b/scripts/src/sound.lua @@ -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 diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 27deeddb3a4..a8d2f4e8b1d 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -257,6 +257,7 @@ SOUNDS["SB0400"] = true SOUNDS["AC97"] = true SOUNDS["ES1373"] = true SOUNDS["L7A1045"] = true +SOUNDS["AD1848"] = true -------------------------------------------------- -- specify available video cores diff --git a/src/devices/bus/isa/sblaster.cpp b/src/devices/bus/isa/sblaster.cpp index 6895716c7af..20dd6c6b2ed 100644 --- a/src/devices/bus/isa/sblaster.cpp +++ b/src/devices/bus/isa/sblaster.cpp @@ -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) { } diff --git a/src/devices/bus/isa/sblaster.h b/src/devices/bus/isa/sblaster.h index 25bdc0f4b56..4481193c6fe 100644 --- a/src/devices/bus/isa/sblaster.h +++ b/src/devices/bus/isa/sblaster.h @@ -103,6 +103,7 @@ public: required_device m_dacr; required_device m_joy; required_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 diff --git a/src/devices/bus/pc_joy/pc_joy.cpp b/src/devices/bus/pc_joy/pc_joy.cpp index 14c2b99e8a1..bf530eb6ab5 100644 --- a/src/devices/bus/pc_joy/pc_joy.cpp +++ b/src/devices/bus/pc_joy/pc_joy.cpp @@ -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(); } diff --git a/src/devices/sound/ad1848.cpp b/src/devices/sound/ad1848.cpp new file mode 100644 index 00000000000..4c299be37be --- /dev/null +++ b/src/devices/sound/ad1848.cpp @@ -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(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); +} diff --git a/src/devices/sound/ad1848.h b/src/devices/sound/ad1848.h new file mode 100644 index 00000000000..d2c93c57329 --- /dev/null +++ b/src/devices/sound/ad1848.h @@ -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 static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast(device).m_irq_cb.set_callback(object); } + template static devcb_base &set_drq_callback(device_t &device, _Object object) { return downcast(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 m_dacl; + required_device m_dacr; + emu_timer *m_timer; +}; + +extern const device_type AD1848; + +#endif diff --git a/src/mame/drivers/pcat_dyn.cpp b/src/mame/drivers/pcat_dyn.cpp index 30aba863158..4131129cb82 100644 --- a/src/mame/drivers/pcat_dyn.cpp +++ b/src/mame/drivers/pcat_dyn.cpp @@ -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 m_isabus; required_memory_bank m_prgbank; required_memory_bank m_nvram_bank; std::vector 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 )