summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/bus/spc1000
diff options
context:
space:
mode:
author etabeta78 <etabeta78@users.noreply.github.com>2014-10-26 12:48:02 +0100
committer etabeta78 <etabeta78@users.noreply.github.com>2014-10-26 12:48:02 +0100
commit218ea906062104d9c339a2591fbf41e75a3cfa3a (patch)
treef0bba1049213c9b2e7e93e027612d306a579f75e /src/emu/bus/spc1000
parent7e7b1dc0bb5b9c2acd27fa353dce57e1a985adc9 (diff)
(MESS) spc1000: converted the expansion bus EXT1 to be a
slot device, moved FDD expansion to be a slot card, added emulation of the VDP expansion as another slot card. This makes Gun Fright, TwinBee and Zanac playable if you launch them with "-ext1 vdp" option. If you want to emulate a SPC-1000 with floppy drive, you have to add "-ext1 fdd" instead. [Fabio Priuli] out of whatsnew: disk emulation still does not work (unless we use Meeso Kim's patched BIOS), but emulation is now closer to the real functionality and we needed the changes for the VDP unit emulation.
Diffstat (limited to 'src/emu/bus/spc1000')
-rw-r--r--src/emu/bus/spc1000/exp.c80
-rw-r--r--src/emu/bus/spc1000/exp.h48
-rw-r--r--src/emu/bus/spc1000/fdd.c224
-rw-r--r--src/emu/bus/spc1000/fdd.h63
-rw-r--r--src/emu/bus/spc1000/vdp.c104
-rw-r--r--src/emu/bus/spc1000/vdp.h43
6 files changed, 562 insertions, 0 deletions
diff --git a/src/emu/bus/spc1000/exp.c b/src/emu/bus/spc1000/exp.c
new file mode 100644
index 00000000000..8a236b64fb8
--- /dev/null
+++ b/src/emu/bus/spc1000/exp.c
@@ -0,0 +1,80 @@
+/***********************************************************************************************************
+
+ Samsung SPC-1000 Expansion port
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "exp.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type SPC1000_EXP_SLOT = &device_creator<spc1000_exp_device>;
+
+
+device_spc1000_card_interface::device_spc1000_card_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device)
+{
+}
+
+
+device_spc1000_card_interface::~device_spc1000_card_interface()
+{
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spc1000_exp_device - constructor
+//-------------------------------------------------
+spc1000_exp_device::spc1000_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SPC1000_EXP_SLOT, "Samsung SPC-1000 expansion", tag, owner, clock, "spc1000_exp", __FILE__),
+ device_slot_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// spc1000_exp_device - destructor
+//-------------------------------------------------
+
+spc1000_exp_device::~spc1000_exp_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spc1000_exp_device::device_start()
+{
+ m_card = dynamic_cast<device_spc1000_card_interface *>(get_card_device());
+}
+
+/*-------------------------------------------------
+ read
+ -------------------------------------------------*/
+
+READ8_MEMBER(spc1000_exp_device::read)
+{
+ if (m_card)
+ return m_card->read(space, offset);
+ else
+ return 0xff;
+}
+
+/*-------------------------------------------------
+ write
+ -------------------------------------------------*/
+
+WRITE8_MEMBER(spc1000_exp_device::write)
+{
+ if (m_card)
+ m_card->write(space, offset, data);
+}
diff --git a/src/emu/bus/spc1000/exp.h b/src/emu/bus/spc1000/exp.h
new file mode 100644
index 00000000000..44d3a49ae27
--- /dev/null
+++ b/src/emu/bus/spc1000/exp.h
@@ -0,0 +1,48 @@
+#ifndef __SCP1000_SLOT_H
+#define __SCP1000_SLOT_H
+
+// ======================> device_spc1000_card_interface
+
+class device_spc1000_card_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_spc1000_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_spc1000_card_interface();
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read) { return 0xff; }
+ virtual DECLARE_WRITE8_MEMBER(write) {}
+
+protected:
+};
+
+
+// ======================> spc1000_exp_device
+
+class spc1000_exp_device : public device_t,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ spc1000_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~spc1000_exp_device();
+
+ // device-level overrides
+ virtual void device_start();
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read);
+ virtual DECLARE_WRITE8_MEMBER(write);
+
+protected:
+
+ device_spc1000_card_interface* m_card;
+};
+
+
+
+// device type definition
+extern const device_type SPC1000_EXP_SLOT;
+
+#endif
diff --git a/src/emu/bus/spc1000/fdd.c b/src/emu/bus/spc1000/fdd.c
new file mode 100644
index 00000000000..1a9cbb33f81
--- /dev/null
+++ b/src/emu/bus/spc1000/fdd.c
@@ -0,0 +1,224 @@
+/***************************************************************************
+
+ SPC-1000 FDD unit
+
+***************************************************************************/
+
+#include "emu.h"
+#include "fdd.h"
+
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+
+READ8_MEMBER(spc1000_fdd_exp_device::i8255_c_r)
+{
+ return m_i8255_0_pc >> 4;
+}
+
+WRITE8_MEMBER(spc1000_fdd_exp_device::i8255_b_w)
+{
+ m_i8255_portb = data;
+}
+
+WRITE8_MEMBER(spc1000_fdd_exp_device::i8255_c_w)
+{
+ m_i8255_1_pc = data;
+}
+
+//-------------------------------------------------
+// fdc interrupt
+//-------------------------------------------------
+
+READ8_MEMBER( spc1000_fdd_exp_device::tc_r )
+{
+ logerror("%s: tc_r\n", space.machine().describe_context());
+
+ // toggle tc on read
+ m_fdc->tc_w(true);
+ m_timer_tc->adjust(attotime::zero);
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( spc1000_fdd_exp_device::control_w )
+{
+ logerror("%s: control_w(%02x)\n", space.machine().describe_context(), data);
+
+ // bit 0, motor on signal
+ if (m_fd0)
+ m_fd0->mon_w(!BIT(data, 0));
+ if (m_fd1)
+ m_fd1->mon_w(!BIT(data, 0));
+}
+
+static ADDRESS_MAP_START( sd725_mem, AS_PROGRAM, 8, spc1000_fdd_exp_device )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x0000, 0x1fff) AM_ROM
+ AM_RANGE(0x2000, 0xffff) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( sd725_io, AS_IO, 8, spc1000_fdd_exp_device )
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0xf8, 0xf8) AM_READWRITE(tc_r, control_w) // (R) Terminal Count Port (W) Motor Control Port
+ AM_RANGE(0xfa, 0xfb) AM_DEVICE("upd765", upd765a_device, map)
+ AM_RANGE(0xfc, 0xff) AM_DEVREADWRITE("d8255_master", i8255_device, read, write)
+ADDRESS_MAP_END
+
+static SLOT_INTERFACE_START( sd725_floppies )
+ SLOT_INTERFACE("sd320", EPSON_SD_320)
+SLOT_INTERFACE_END
+
+static MACHINE_CONFIG_FRAGMENT(spc1000_fdd)
+
+ /* sub CPU(5 inch floppy drive) */
+ MCFG_CPU_ADD("fdccpu", Z80, XTAL_4MHz) /* 4 MHz */
+ MCFG_CPU_PROGRAM_MAP(sd725_mem)
+ MCFG_CPU_IO_MAP(sd725_io)
+
+ MCFG_DEVICE_ADD("d8255_master", I8255, 0)
+ MCFG_I8255_IN_PORTA_CB(DEVREAD8("d8255_master", i8255_device, pb_r))
+ MCFG_I8255_IN_PORTB_CB(DEVREAD8("d8255_master", i8255_device, pa_r))
+ MCFG_I8255_OUT_PORTB_CB(WRITE8(spc1000_fdd_exp_device, i8255_b_w))
+ MCFG_I8255_IN_PORTC_CB(READ8(spc1000_fdd_exp_device, i8255_c_r))
+ MCFG_I8255_OUT_PORTC_CB(WRITE8(spc1000_fdd_exp_device, i8255_c_w))
+
+ // floppy disk controller
+ MCFG_UPD765A_ADD("upd765", true, true)
+ MCFG_UPD765_INTRQ_CALLBACK(INPUTLINE("fdccpu", INPUT_LINE_IRQ0))
+
+ // floppy drives
+ MCFG_FLOPPY_DRIVE_ADD("upd765:0", sd725_floppies, "sd320", floppy_image_device::default_floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("upd765:1", sd725_floppies, "sd320", floppy_image_device::default_floppy_formats)
+MACHINE_CONFIG_END
+
+//-------------------------------------------------
+// device_mconfig_additions
+//-------------------------------------------------
+
+machine_config_constructor spc1000_fdd_exp_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( spc1000_fdd );
+}
+
+ROM_START( spc1000_fdd )
+ ROM_REGION(0x10000, "fdccpu", 0)
+ ROM_LOAD("sd725a.bin", 0x0000, 0x1000, CRC(96ac2eb8) SHA1(8e9d8f63a7fb87af417e95603e71cf537a6e83f1))
+ROM_END
+
+//-------------------------------------------------
+// device_rom_region
+//-------------------------------------------------
+
+const rom_entry *spc1000_fdd_exp_device::device_rom_region() const
+{
+ return ROM_NAME( spc1000_fdd );
+}
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type SPC1000_FDD_EXP = &device_creator<spc1000_fdd_exp_device>;
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spc1000_fdd_exp_device - constructor
+//-------------------------------------------------
+
+spc1000_fdd_exp_device::spc1000_fdd_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, SPC1000_FDD_EXP, "SPC1000 FDD expansion", tag, owner, clock, "spc1000_fdd_exp", __FILE__),
+ device_spc1000_card_interface(mconfig, *this),
+ m_cpu(*this, "fdccpu"),
+ m_fdc(*this, "upd765"),
+ m_pio(*this, "d8255_master")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spc1000_fdd_exp_device::device_start()
+{
+ m_timer_tc = timer_alloc(TIMER_TC);
+ m_timer_tc->adjust(attotime::never);
+
+ m_fd0 = subdevice<floppy_connector>("upd765:0")->get_device();
+ m_fd1 = subdevice<floppy_connector>("upd765:1")->get_device();
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void spc1000_fdd_exp_device::device_reset()
+{
+ m_cpu->set_input_line_vector(0, 0);
+
+ // enable rom (is this really needed? it does not seem necessary for FDD to work)
+ m_cpu->space(AS_PROGRAM).install_rom(0x0000, 0x0fff, 0, 0x2000, device().machine().root_device().memregion("fdccpu")->base());
+}
+
+void spc1000_fdd_exp_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_TC:
+ m_fdc->tc_w(false);
+ break;
+ }
+}
+
+/*-------------------------------------------------
+ read
+-------------------------------------------------*/
+
+READ8_MEMBER(spc1000_fdd_exp_device::read)
+{
+ // this should be m_pio->read on the whole 0x00-0x03 range?
+ if (offset >= 3)
+ return 0xff;
+ else
+ {
+ UINT8 data = 0;
+ switch (offset)
+ {
+ case 1:
+ data = m_i8255_portb;
+ break;
+ case 2:
+ data = m_i8255_1_pc >> 4;
+ break;
+ }
+ return data;
+ }
+}
+
+//-------------------------------------------------
+// write
+//-------------------------------------------------
+
+WRITE8_MEMBER(spc1000_fdd_exp_device::write)
+{
+ // this should be m_pio->write on the whole 0x00-0x03 range?
+ if (offset < 3)
+ {
+ switch (offset)
+ {
+ case 0:
+ m_pio->write(space, 1, data);
+ break;
+ case 2:
+ m_i8255_0_pc = data;
+ break;
+ }
+ }
+}
diff --git a/src/emu/bus/spc1000/fdd.h b/src/emu/bus/spc1000/fdd.h
new file mode 100644
index 00000000000..b06dc8fa971
--- /dev/null
+++ b/src/emu/bus/spc1000/fdd.h
@@ -0,0 +1,63 @@
+#ifndef __SPC1000_FDD_H__
+#define __SPC1000_FDD_H__
+
+#include "exp.h"
+#include "cpu/z80/z80.h"
+#include "machine/i8255.h"
+#include "machine/upd765.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> spc1000_fdd_exp_device
+
+class spc1000_fdd_exp_device : public device_t,
+ public device_spc1000_card_interface
+{
+public:
+ // construction/destruction
+ spc1000_fdd_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual const rom_entry *device_rom_region() const;
+
+public:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ virtual DECLARE_READ8_MEMBER(read);
+ virtual DECLARE_WRITE8_MEMBER(write);
+
+ DECLARE_READ8_MEMBER(tc_r);
+ DECLARE_WRITE8_MEMBER(control_w);
+ DECLARE_WRITE8_MEMBER(i8255_b_w);
+ DECLARE_READ8_MEMBER(i8255_c_r);
+ DECLARE_WRITE8_MEMBER(i8255_c_w);
+
+private:
+ // internal state
+ required_device<z80_device> m_cpu;
+ required_device<upd765a_device> m_fdc;
+ required_device<i8255_device> m_pio;
+
+ floppy_image_device *m_fd0;
+ floppy_image_device *m_fd1;
+
+ emu_timer *m_timer_tc;
+
+ UINT8 m_i8255_0_pc;
+ UINT8 m_i8255_1_pc;
+ UINT8 m_i8255_portb;
+
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+ static const device_timer_id TIMER_TC = 0;
+};
+
+
+// device type definition
+extern const device_type SPC1000_FDD_EXP;
+
+#endif /* __SPC1000_FDD_H__ */
diff --git a/src/emu/bus/spc1000/vdp.c b/src/emu/bus/spc1000/vdp.c
new file mode 100644
index 00000000000..511a7937bb0
--- /dev/null
+++ b/src/emu/bus/spc1000/vdp.c
@@ -0,0 +1,104 @@
+/***************************************************************************
+
+ SPC-1000 VDP expansion unit
+
+***************************************************************************/
+
+#include "emu.h"
+#include "vdp.h"
+
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
+
+WRITE_LINE_MEMBER(spc1000_vdp_exp_device::vdp_interrupt)
+{
+ // nothing here?
+}
+
+static MACHINE_CONFIG_FRAGMENT(scp1000_vdp)
+
+ MCFG_DEVICE_ADD("tms", TMS9928A, XTAL_10_738635MHz / 2) // TODO: which clock?
+ MCFG_TMS9928A_VRAM_SIZE(0x4000)
+ MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(spc1000_vdp_exp_device, vdp_interrupt))
+ MCFG_TMS9928A_SCREEN_ADD_NTSC("tms_screen")
+ MCFG_SCREEN_UPDATE_DEVICE("tms", tms9928a_device, screen_update)
+MACHINE_CONFIG_END
+
+//-------------------------------------------------
+// device_mconfig_additions
+//-------------------------------------------------
+
+machine_config_constructor spc1000_vdp_exp_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( scp1000_vdp );
+}
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type SPC1000_VDP_EXP = &device_creator<spc1000_vdp_exp_device>;
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spc1000_vdp_exp_device - constructor
+//-------------------------------------------------
+
+spc1000_vdp_exp_device::spc1000_vdp_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, SPC1000_VDP_EXP, "SPC1000 VDP expansion", tag, owner, clock, "spc1000_vdp_exp", __FILE__),
+ device_spc1000_card_interface(mconfig, *this),
+ m_vdp(*this, "tms")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spc1000_vdp_exp_device::device_start()
+{
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void spc1000_vdp_exp_device::device_reset()
+{
+}
+
+/*-------------------------------------------------
+ read
+-------------------------------------------------*/
+READ8_MEMBER(spc1000_vdp_exp_device::read)
+{
+ if (!(offset & 0x800))
+ return 0xff;
+
+ if (offset & 1)
+ return m_vdp->register_read(space, offset);
+ else
+ return m_vdp->vram_read(space, offset);
+}
+
+//-------------------------------------------------
+// write
+//-------------------------------------------------
+
+WRITE8_MEMBER(spc1000_vdp_exp_device::write)
+{
+ if (offset & 0x800)
+ {
+ if (offset & 1)
+ m_vdp->register_write(space, offset, data);
+ else
+ m_vdp->vram_write(space, offset, data);
+ }
+}
diff --git a/src/emu/bus/spc1000/vdp.h b/src/emu/bus/spc1000/vdp.h
new file mode 100644
index 00000000000..8fbc10ad4e1
--- /dev/null
+++ b/src/emu/bus/spc1000/vdp.h
@@ -0,0 +1,43 @@
+#ifndef __SPC1000_VDP_H__
+#define __SPC1000_VDP_H__
+
+#include "exp.h"
+#include "video/tms9928a.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> spc1000_vdp_exp_device
+
+class spc1000_vdp_exp_device : public device_t,
+ public device_spc1000_card_interface
+{
+public:
+ // construction/destruction
+ spc1000_vdp_exp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+
+public:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ virtual DECLARE_READ8_MEMBER(read);
+ virtual DECLARE_WRITE8_MEMBER(write);
+
+ DECLARE_WRITE_LINE_MEMBER(vdp_interrupt);
+
+private:
+ // internal state
+ required_device<tms9928a_device> m_vdp;
+};
+
+
+// device type definition
+extern const device_type SPC1000_VDP_EXP;
+
+#endif /* __SPC1000_VDP_H__ */