samcoupe: Rework driver (WIP)

- Rewrite memory system, now allows supporting expansion devices and better prepared for contention emulation
- Add expansion interfaces for rear expansion, drive ports and mouse
- Now supports the following rear expansion devices:
  * Blue Alpha Sound Sampler
  * Dallas Clock
  * 1 Mb Interface
  * SAMBUS 4-slot Expansion Interface (with clock)
  * SID Interface (6581 and 8580 variants)
  * S.P.I. SAM Parallel Interface
  * Voicebox
- Added support for the Atom HDD interface, used in place of a floppy drive
- Simplified and cleaned up driver
- Temporarily deactivated joystick code, interferes with the keyboard
This commit is contained in:
Dirk Best 2020-07-13 11:19:39 +02:00
parent 2916f4dee3
commit 4d89de93c0
38 changed files with 3229 additions and 1209 deletions

View File

@ -4276,3 +4276,65 @@ if (BUSES["RTPC_KBD"]~=null) then
MAME_DIR .. "src/devices/bus/rtpc/kbd.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/samcoupe/drive/drive.h,BUSES["SAMCOUPE_DRIVE_PORT"] = true
---------------------------------------------------
if (BUSES["SAMCOUPE_DRIVE_PORT"]~=null) then
files {
MAME_DIR .. "src/devices/bus/samcoupe/drive/drive.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/drive/drive.h",
MAME_DIR .. "src/devices/bus/samcoupe/drive/modules.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/drive/modules.h",
MAME_DIR .. "src/devices/bus/samcoupe/drive/atom.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/drive/atom.h",
MAME_DIR .. "src/devices/bus/samcoupe/drive/floppy.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/drive/floppy.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/samcoupe/expansion/expansion.h,BUSES["SAMCOUPE_EXPANSION"] = true
---------------------------------------------------
if (BUSES["SAMCOUPE_EXPANSION"]~=null) then
files {
MAME_DIR .. "src/devices/bus/samcoupe/expansion/expansion.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/expansion.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/modules.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/modules.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/blue_sampler.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/blue_sampler.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/dallas.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/dallas.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/onemeg.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/onemeg.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/sambus.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/sambus.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/sid.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/sid.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/spi.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/spi.h",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/voicebox.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/expansion/voicebox.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/samcoupe/mouse/mouse.h,BUSES["SAMCOUPE_MOUSE_PORT"] = true
---------------------------------------------------
if (BUSES["SAMCOUPE_MOUSE_PORT"]~=null) then
files {
MAME_DIR .. "src/devices/bus/samcoupe/mouse/mouseport.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/mouse/mouseport.h",
MAME_DIR .. "src/devices/bus/samcoupe/mouse/modules.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/mouse/modules.h",
MAME_DIR .. "src/devices/bus/samcoupe/mouse/mouse.cpp",
MAME_DIR .. "src/devices/bus/samcoupe/mouse/mouse.h",
}
end

View File

@ -892,6 +892,9 @@ BUSES["QL"] = true
BUSES["QBUS"] = true
BUSES["RS232"] = true
BUSES["S100"] = true
BUSES["SAMCOUPE_DRIVE_PORT"] = true
BUSES["SAMCOUPE_EXPANSION"] = true
BUSES["SAMCOUPE_MOUSE_PORT"] = true
BUSES["SAT_CTRL"] = true
BUSES["SATURN"] = true
BUSES["SBUS"] = true
@ -3388,9 +3391,6 @@ files {
createMESSProjects(_target, _subtarget, "samcoupe")
files {
MAME_DIR .. "src/mame/drivers/samcoupe.cpp",
MAME_DIR .. "src/mame/includes/samcoupe.h",
MAME_DIR .. "src/mame/machine/samcoupe.cpp",
MAME_DIR .. "src/mame/video/samcoupe.cpp",
}
createMESSProjects(_target, _subtarget, "samsung")

View File

@ -0,0 +1,116 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
ATOM hard disk interface for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "atom.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_ATOM_HDD, sam_atom_hdd_device, "sam_atom_hdd", "SAM Coupe ATOM HDD interface")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_atom_hdd_device::device_add_mconfig(machine_config &config)
{
ATA_INTERFACE(config, m_ata).options(ata_devices, nullptr, nullptr, false);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_atom_hdd_device - constructor
//-------------------------------------------------
sam_atom_hdd_device::sam_atom_hdd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_ATOM_HDD, tag, owner, clock),
device_samcoupe_drive_interface(mconfig, *this),
m_ata(*this, "ata"),
m_address_latch(0),
m_read_latch(0x00), m_write_latch(0x00)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_atom_hdd_device::device_start()
{
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
uint8_t sam_atom_hdd_device::read(offs_t offset)
{
uint8_t data = 0xff;
switch (offset)
{
// high byte
case 0x06:
if (BIT(m_address_latch, 5))
{
uint16_t result = 0;
if (BIT(m_address_latch, 3) == 0)
result = m_ata->cs0_r(m_address_latch & 0x07);
if (BIT(m_address_latch, 4) == 0)
result = m_ata->cs1_r(m_address_latch & 0x07);
m_read_latch = result;
data = result >> 8;
}
break;
// low byte
case 0x07:
data = m_read_latch;
break;
}
return data;
}
void sam_atom_hdd_device::write(offs_t offset, uint8_t data)
{
switch (offset)
{
// control
case 0x05:
if (BIT(data, 5))
m_address_latch = data;
break;
// high byte
case 0x06:
m_write_latch = data;
break;
// low byte
case 0x07:
if (BIT(m_address_latch, 5))
{
if (BIT(m_address_latch, 3) == 0)
m_ata->cs0_w(m_address_latch & 0x07, (m_write_latch << 8) | data);
if (BIT(m_address_latch, 4) == 0)
m_ata->cs1_w(m_address_latch & 0x07, (m_write_latch << 8) | data);
}
break;
}
}

View File

@ -0,0 +1,48 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
ATOM hard disk interface for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_DRIVE_ATOM_H
#define MAME_BUS_SAMCOUPE_DRIVE_ATOM_H
#pragma once
#include "drive.h"
#include "bus/ata/ataintf.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_atom_hdd_device
class sam_atom_hdd_device : public device_t, public device_samcoupe_drive_interface
{
public:
// construction/destruction
sam_atom_hdd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual uint8_t read(offs_t offset) override;
virtual void write(offs_t offset, uint8_t data) override;
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
private:
required_device<ata_interface_device> m_ata;
int m_address_latch;
uint8_t m_read_latch, m_write_latch;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_ATOM_HDD, sam_atom_hdd_device)
#endif // MAME_BUS_SAMCOUPE_DRIVE_ATOM_H

View File

@ -0,0 +1,94 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Drive Slot
32-pin slot
***************************************************************************/
#include "emu.h"
#include "drive.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAMCOUPE_DRIVE_PORT, samcoupe_drive_port_device, "samcoupe_drive_port", "SAM Coupe Drive Port")
//**************************************************************************
// SLOT DEVICE
//**************************************************************************
//-------------------------------------------------
// samcoupe_drive_port_device - constructor
//-------------------------------------------------
samcoupe_drive_port_device::samcoupe_drive_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAMCOUPE_DRIVE_PORT, tag, owner, clock),
device_single_card_slot_interface<device_samcoupe_drive_interface>(mconfig, *this),
m_module(nullptr)
{
}
//-------------------------------------------------
// samcoupe_drive_port_device - destructor
//-------------------------------------------------
samcoupe_drive_port_device::~samcoupe_drive_port_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void samcoupe_drive_port_device::device_start()
{
// get inserted module
m_module = get_card_device();
}
//-------------------------------------------------
// host to module interface
//-------------------------------------------------
uint8_t samcoupe_drive_port_device::read(offs_t offset)
{
if (m_module)
return m_module->read(offset);
return 0xff;
}
void samcoupe_drive_port_device::write(offs_t offset, uint8_t data)
{
if (m_module)
m_module->write(offset, data);
}
//**************************************************************************
// MODULE INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_samcoupe_drive_interface - constructor
//-------------------------------------------------
device_samcoupe_drive_interface::device_samcoupe_drive_interface(const machine_config &mconfig, device_t &device) :
device_interface(device, "samcoupedrive")
{
m_port = dynamic_cast<samcoupe_drive_port_device *>(device.owner());
}
//-------------------------------------------------
// ~device_samcoupe_drive_interface - destructor
//-------------------------------------------------
device_samcoupe_drive_interface::~device_samcoupe_drive_interface()
{
}

View File

@ -0,0 +1,96 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Drive Slot
32-pin slot
1A 0 VOLTS 1B WR
2A 0 VOLTS 2B A0
3A 0 VOLTS 3B A1
4A 0 VOLTS 4B D0
5A 0 VOLTS 5B D1
6A 0 VOLTS 6B D2
7A 0 VOLTS 7B D3
8A 0 VOLTS 8B D4
9A 0 VOLTS 9B D5
10A 0 VOLTS 10B D6
11A 0 VOLTS 11B D7
12A 0 VOLTS 12B 8 MHz
13A 0 VOLTS 13B RST
14A 0 VOLTS 14B N/C
15A 0 VOLTS 15B A2
16A 0 VOLTS 16B DISK 1 OR DISK 2
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_DRIVE_DRIVE_H
#define MAME_BUS_SAMCOUPE_DRIVE_DRIVE_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class device_samcoupe_drive_interface;
// ======================> samcoupe_drive_port_device
class samcoupe_drive_port_device : public device_t, public device_single_card_slot_interface<device_samcoupe_drive_interface>
{
public:
// construction/destruction
template <typename T>
samcoupe_drive_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, const char *dflt)
: samcoupe_drive_port_device(mconfig, tag, owner, uint32_t(0))
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
}
samcoupe_drive_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~samcoupe_drive_port_device();
// called from host
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
DECLARE_WRITE_LINE_MEMBER( disk1_w );
protected:
// device-level overrides
virtual void device_start() override;
private:
device_samcoupe_drive_interface *m_module;
};
// ======================> device_samcoupe_drive_interface
class device_samcoupe_drive_interface : public device_interface
{
public:
// construction/destruction
virtual ~device_samcoupe_drive_interface();
virtual uint8_t read(offs_t offset) { return 0xff; }
virtual void write(offs_t offset, uint8_t data) { }
protected:
device_samcoupe_drive_interface(const machine_config &mconfig, device_t &device);
samcoupe_drive_port_device *m_port;
};
// device type definition
DECLARE_DEVICE_TYPE(SAMCOUPE_DRIVE_PORT, samcoupe_drive_port_device)
// include here so drivers don't need to
#include "modules.h"
#endif // MAME_BUS_SAMCOUPE_DRIVE_DRIVE_H

View File

@ -0,0 +1,91 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Internal floppy drive for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "floppy.h"
#include "formats/coupedsk.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_FLOPPY, sam_floppy_device, "sam_floppy", "SAM Coupe Internal Floppy")
FLOPPY_FORMATS_MEMBER( sam_floppy_device::floppy_formats )
FLOPPY_MGT_FORMAT
FLOPPY_FORMATS_END
static void samcoupe_floppies(device_slot_interface &device)
{
device.option_add("35dd", FLOPPY_35_DD);
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_floppy_device::device_add_mconfig(machine_config &config)
{
WD1772(config, m_fdc, 24_MHz_XTAL / 3);
FLOPPY_CONNECTOR(config, "fdc:0", samcoupe_floppies, "35dd", sam_floppy_device::floppy_formats);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_floppy_device - constructor
//-------------------------------------------------
sam_floppy_device::sam_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_FLOPPY, tag, owner, clock),
device_samcoupe_drive_interface(mconfig, *this),
m_fdc(*this, "fdc"),
m_drive(*this, "fdc:0")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_floppy_device::device_start()
{
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
uint8_t sam_floppy_device::read(offs_t offset)
{
floppy_image_device *floppy = m_drive->get_device();
if (floppy)
floppy->ss_w(BIT(offset, 2));
m_fdc->set_floppy(floppy);
return m_fdc->read(offset & 0x03);
}
void sam_floppy_device::write(offs_t offset, uint8_t data)
{
floppy_image_device *floppy = m_drive->get_device();
if (floppy)
floppy->ss_w(BIT(offset, 2));
m_fdc->set_floppy(floppy);
m_fdc->write(offset & 0x03, data);
}

View File

@ -0,0 +1,49 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Internal floppy drive for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_DRIVE_FLOPPY_H
#define MAME_BUS_SAMCOUPE_DRIVE_FLOPPY_H
#pragma once
#include "drive.h"
#include "machine/wd_fdc.h"
#include "imagedev/floppy.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_floppy_device
class sam_floppy_device : public device_t, public device_samcoupe_drive_interface
{
public:
// construction/destruction
sam_floppy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual uint8_t read(offs_t offset) override;
virtual void write(offs_t offset, uint8_t data) override;
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
private:
required_device<wd1772_device> m_fdc;
required_device<floppy_connector> m_drive;
DECLARE_FLOPPY_FORMATS( floppy_formats );
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_FLOPPY, sam_floppy_device)
#endif // MAME_BUS_SAMCOUPE_DRIVE_FLOPPY_H

View File

@ -0,0 +1,19 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Drive Port modules
***************************************************************************/
#include "emu.h"
#include "modules.h"
#include "atom.h"
#include "floppy.h"
void samcoupe_drive_modules(device_slot_interface &device)
{
device.option_add("atom", SAM_ATOM_HDD);
device.option_add("floppy", SAM_FLOPPY);
}

View File

@ -0,0 +1,16 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Drive Port modules
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_DRIVE_MODULES_H
#define MAME_BUS_SAMCOUPE_DRIVE_MODULES_H
#pragma once
void samcoupe_drive_modules(device_slot_interface &device);
#endif // MAME_BUS_SAMCOUPE_DRIVE_MODULES_H

View File

@ -0,0 +1,117 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Blue Alpha Sound Sampler for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "machine/rescap.h"
#include "sound/volt_reg.h"
#include "blue_sampler.h"
#include "speaker.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_BLUE_SOUND_SAMPLER, sam_blue_sound_sampler_device, "blue_sampler", "Blue Alpha Sound Sampler")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_blue_sound_sampler_device::device_add_mconfig(machine_config &config)
{
SPEAKER(config, "mono").front_center();
I8255A(config, m_ppi);
m_ppi->out_pa_callback().set("dac", FUNC(dac_byte_interface::data_w));
m_ppi->out_pb_callback().set(FUNC(sam_blue_sound_sampler_device::ppi_portb_w));
m_ppi->in_pc_callback().set(FUNC(sam_blue_sound_sampler_device::ppi_portc_r));
ZN426E(config, m_dac, 0).add_route(ALL_OUTPUTS, "mono", 0.5);
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref"));
vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);
vref.add_route(0, "dac", -1.0, DAC_VREF_NEG_INPUT);
// TODO: ZN449E ADC
// 555 with variable resistor ~19.342hz
TIMER(config, "timer").configure_periodic(FUNC(sam_blue_sound_sampler_device::clock_callback), PERIOD_OF_555_MONOSTABLE(RES_K(1), CAP_N(47)));
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_blue_sound_sampler_device - constructor
//-------------------------------------------------
sam_blue_sound_sampler_device::sam_blue_sound_sampler_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_BLUE_SOUND_SAMPLER, tag, owner, clock),
device_samcoupe_expansion_interface(mconfig, *this),
m_ppi(*this, "ppi"),
m_dac(*this, "dac"),
m_portc(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_blue_sound_sampler_device::device_start()
{
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
TIMER_DEVICE_CALLBACK_MEMBER( sam_blue_sound_sampler_device::clock_callback )
{
m_portc ^= 1;
}
void sam_blue_sound_sampler_device::ppi_portb_w(uint8_t data)
{
// 765432-- not used
// ------1- enable for adc
// -------0 enable for dac and ppi pc6
m_ppi->pc6_w(BIT(data, 0));
}
uint8_t sam_blue_sound_sampler_device::ppi_portc_r()
{
// 7------- not used
// -6------ from ppi pb0
// --5----- not used
// ---4---- busy output from zn449e adc
// ----321- not used
// -------- clock input from 555
return m_portc;
}
uint8_t sam_blue_sound_sampler_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if ((offset & 0xff) == 0x7f)
return m_ppi->read(offset >> 8);
return data;
}
void sam_blue_sound_sampler_device::iorq_w(offs_t offset, uint8_t data)
{
if ((offset & 0xff) == 0x7f)
m_ppi->write(offset >> 8, data);
}

View File

@ -0,0 +1,54 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Blue Alpha Sound Sampler for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_BLUE_SAMPLER_H
#define MAME_BUS_SAMCOUPE_EXPANSION_BLUE_SAMPLER_H
#pragma once
#include "expansion.h"
#include "machine/i8255.h"
#include "machine/timer.h"
#include "sound/dac.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_blue_sound_sampler_device
class sam_blue_sound_sampler_device : public device_t, public device_samcoupe_expansion_interface
{
public:
// construction/destruction
sam_blue_sound_sampler_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
private:
TIMER_DEVICE_CALLBACK_MEMBER(clock_callback);
void ppi_portb_w(uint8_t data);
uint8_t ppi_portc_r();
required_device<i8255_device> m_ppi;
required_device<zn426e_device> m_dac;
uint8_t m_portc;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_BLUE_SOUND_SAMPLER, sam_blue_sound_sampler_device)
#endif // MAME_BUS_SAMCOUPE_EXPANSION_BLUE_SAMPLER_H

View File

@ -0,0 +1,79 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Dallas Clock for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "dallas.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_DALLAS_CLOCK, sam_dallas_clock_device, "sam_dallas_clock", "Dallas Clock")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_dallas_clock_device::device_add_mconfig(machine_config &config)
{
DS12885(config, m_rtc, 32.768_kHz_XTAL); // should be DS12887 or DS1287
m_rtc->set_24hrs(true);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_dallas_clock_device - constructor
//-------------------------------------------------
sam_dallas_clock_device::sam_dallas_clock_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_DALLAS_CLOCK, tag, owner, clock),
device_samcoupe_expansion_interface(mconfig, *this),
m_rtc(*this, "rtc")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_dallas_clock_device::device_start()
{
// register for savestates
save_item(NAME(m_print));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
void sam_dallas_clock_device::print_w(int state)
{
m_print = state;
}
uint8_t sam_dallas_clock_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_print && (offset & 0xfe07) == 0xfe07)
data &= m_rtc->read((offset >> 8) & 0x01);
return data;
}
void sam_dallas_clock_device::iorq_w(offs_t offset, uint8_t data)
{
if (m_print && (offset & 0xfe07) == 0xfe07)
m_rtc->write((offset >> 8) & 0x01, data);
}

View File

@ -0,0 +1,49 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Dallas Clock for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_DALLAS_H
#define MAME_BUS_SAMCOUPE_EXPANSION_DALLAS_H
#pragma once
#include "expansion.h"
#include "machine/ds128x.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_dallas_clock_device
class sam_dallas_clock_device : public device_t, public device_samcoupe_expansion_interface
{
public:
// construction/destruction
sam_dallas_clock_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual void print_w(int state) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
private:
required_device<ds12885_device> m_rtc;
int m_print;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_DALLAS_CLOCK, sam_dallas_clock_device)
#endif // MAME_BUS_SAMCOUPE_EXPANSION_DALLAS_H

View File

@ -0,0 +1,124 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Expansion Slot
64-pin slot
***************************************************************************/
#include "emu.h"
#include "expansion.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAMCOUPE_EXPANSION, samcoupe_expansion_device, "samcoupe_expansion", "SAM Coupe Expansion Bus")
//**************************************************************************
// SLOT DEVICE
//**************************************************************************
//-------------------------------------------------
// samcoupe_expansion_device - constructor
//-------------------------------------------------
samcoupe_expansion_device::samcoupe_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAMCOUPE_EXPANSION, tag, owner, clock),
device_single_card_slot_interface<device_samcoupe_expansion_interface>(mconfig, *this),
m_int_handler(*this),
m_module(nullptr)
{
}
//-------------------------------------------------
// samcoupe_expansion_device - destructor
//-------------------------------------------------
samcoupe_expansion_device::~samcoupe_expansion_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void samcoupe_expansion_device::device_start()
{
// get inserted module
m_module = get_card_device();
// resolve callbacks
m_int_handler.resolve_safe();
}
//-------------------------------------------------
// host to module interface
//-------------------------------------------------
uint8_t samcoupe_expansion_device::mreq_r(offs_t offset)
{
if (m_module)
return m_module->mreq_r(offset);
return 0xff;
}
void samcoupe_expansion_device::mreq_w(offs_t offset, uint8_t data)
{
if (m_module)
m_module->mreq_w(offset, data);
}
uint8_t samcoupe_expansion_device::iorq_r(offs_t offset)
{
if (m_module)
return m_module->iorq_r(offset);
return 0xff;
}
void samcoupe_expansion_device::iorq_w(offs_t offset, uint8_t data)
{
if (m_module)
m_module->iorq_w(offset, data);
}
WRITE_LINE_MEMBER( samcoupe_expansion_device::xmem_w )
{
if (m_module)
m_module->xmem_w(state);
}
WRITE_LINE_MEMBER( samcoupe_expansion_device::print_w )
{
if (m_module)
m_module->print_w(state);
}
//**************************************************************************
// MODULE INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_samcoupe_expansion_interface - constructor
//-------------------------------------------------
device_samcoupe_expansion_interface::device_samcoupe_expansion_interface(const machine_config &mconfig, device_t &device) :
device_interface(device, "samcoupeexp")
{
m_expansion = dynamic_cast<samcoupe_expansion_device *>(device.owner());
}
//-------------------------------------------------
// ~device_samcoupe_expansion_interface - destructor
//-------------------------------------------------
device_samcoupe_expansion_interface::~device_samcoupe_expansion_interface()
{
}

View File

@ -0,0 +1,128 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Expansion Slot
64-pin slot
1A DBDIR 1C IORQL
2A RDL 2C MREQL
3A WRL 3C HALTL
4A BUSAKL 4C NMIL
5A WAITL 5C INTL
6A BUSREQL 6C CD1
7A RESETL 7C CD0
8A CM1L 8C CD7
9A REFRESHL 9C CD2
10A 0 VOLTS 10C +5 VOLTS
11A A0 11C CD6
12A A1 12C CD5
13A A2 13C CD3
14A A3 14C CD4
15A A4 15C CPU CLK
16A A5 16C A15
17A A6 17C A14
18A A7 18C A13
19A A8 19C A12
20A A9 20C A11
21A A10 21C DISK 2L
22A MSEINTL 22C ROMCSL
23A XMEML 23C EARMIC
24A 8 MHz 24C DISK 1L
25A RED 1 25C PRINTL
26A GREEN 1 26C BLUE 1
27A C SYNC 27C ROMCSRL
28A SPEN 28C AUDIO RIGHT
29A BLUE 0 29C AUDIO LEFT
30A RED 0 30C COMP VIDEO
31A BRIGHT 31C GREEN 0
32A +5 VOLTS 32C 0 VOLTS
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_EXPANSION_H
#define MAME_BUS_SAMCOUPE_EXPANSION_EXPANSION_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class device_samcoupe_expansion_interface;
// ======================> samcoupe_expansion_device
class samcoupe_expansion_device : public device_t, public device_single_card_slot_interface<device_samcoupe_expansion_interface>
{
public:
// construction/destruction
template <typename T>
samcoupe_expansion_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts)
: samcoupe_expansion_device(mconfig, tag, owner, uint32_t(0))
{
option_reset();
opts(*this);
set_default_option(nullptr);
set_fixed(false);
}
samcoupe_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~samcoupe_expansion_device();
// callbacks
auto int_handler() { return m_int_handler.bind(); }
// called from cart device
DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_handler(state); }
// called from host
uint8_t mreq_r(offs_t offset);
void mreq_w(offs_t offset, uint8_t data);
uint8_t iorq_r(offs_t offset);
void iorq_w(offs_t offset, uint8_t data);
DECLARE_WRITE_LINE_MEMBER( xmem_w );
DECLARE_WRITE_LINE_MEMBER( print_w );
protected:
// device-level overrides
virtual void device_start() override;
private:
devcb_write_line m_int_handler;
device_samcoupe_expansion_interface *m_module;
};
// ======================> device_samcoupe_expansion_interface
class device_samcoupe_expansion_interface : public device_interface
{
public:
// construction/destruction
virtual ~device_samcoupe_expansion_interface();
virtual uint8_t mreq_r(offs_t offset) { return 0xff; }
virtual void mreq_w(offs_t offset, uint8_t data) { }
virtual uint8_t iorq_r(offs_t offset) { return 0xff; }
virtual void iorq_w(offs_t offset, uint8_t data) { }
virtual void xmem_w(int state) { }
virtual void print_w(int state) { }
protected:
device_samcoupe_expansion_interface(const machine_config &mconfig, device_t &device);
samcoupe_expansion_device *m_expansion;
};
// device type definition
DECLARE_DEVICE_TYPE(SAMCOUPE_EXPANSION, samcoupe_expansion_device)
// include here so drivers don't need to
#include "modules.h"
#endif // MAME_BUS_SAMCOUPE_EXPANSION_EXPANSION_H

View File

@ -0,0 +1,30 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Expansion Slot modules
***************************************************************************/
#include "emu.h"
#include "modules.h"
#include "blue_sampler.h"
#include "dallas.h"
#include "onemeg.h"
#include "sambus.h"
#include "sid.h"
#include "spi.h"
#include "voicebox.h"
void samcoupe_expansion_modules(device_slot_interface &device)
{
device.option_add("blue_sampler", SAM_BLUE_SOUND_SAMPLER);
device.option_add("dallas", SAM_DALLAS_CLOCK);
device.option_add("onemeg", SAM_ONEMEG);
device.option_add("sambus", SAM_SAMBUS);
device.option_add("sid6581", SAM_SID6581);
device.option_add("sid8580", SAM_SID8580);
device.option_add("spi", SAM_SPI);
device.option_add("voicebox", SAM_VOICEBOX);
}

View File

@ -0,0 +1,16 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Expansion Slot modules
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_MODULES_H
#define MAME_BUS_SAMCOUPE_EXPANSION_MODULES_H
#pragma once
void samcoupe_expansion_modules(device_slot_interface &device);
#endif // MAME_BUS_SAMCOUPE_EXPANSION_MODULES_H

View File

@ -0,0 +1,110 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
1 Mb Interface for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "onemeg.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_ONEMEG, sam_onemeg_device, "onemeg", "1 Mb Interface")
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
static INPUT_PORTS_START( onemeg )
PORT_START("dip")
PORT_DIPNAME(0x03, 0x03, "Board ID")
PORT_DIPSETTING(0x00, "1")
PORT_DIPSETTING(0x01, "2")
PORT_DIPSETTING(0x02, "3")
PORT_DIPSETTING(0x03, "4")
INPUT_PORTS_END
ioport_constructor sam_onemeg_device::device_input_ports() const
{
return INPUT_PORTS_NAME( onemeg );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_onemeg_device - constructor
//-------------------------------------------------
sam_onemeg_device::sam_onemeg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_ONEMEG, tag, owner, clock),
device_samcoupe_expansion_interface(mconfig, *this),
m_dip(*this, "dip"),
m_xmem(0),
m_expage{ 0x00, 0x00 }
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_onemeg_device::device_start()
{
// init ram
m_ram = std::make_unique<uint8_t[]>(0x100000);
memset(m_ram.get(), 0x55, 0x100000);
// register for savestates
save_item(NAME(m_xmem));
save_item(NAME(m_expage[0]));
save_item(NAME(m_expage[1]));
save_pointer(NAME(m_ram), 0x100000);
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
void sam_onemeg_device::xmem_w(int state)
{
m_xmem = state;
}
uint8_t sam_onemeg_device::mreq_r(offs_t offset)
{
uint8_t data = 0xff;
// read if external memory is enabled and the id matches
if (m_xmem && (m_expage[BIT(offset, 14)] >> 6 == m_dip->read()))
data = m_ram[((m_expage[BIT(offset, 14)] & 0x3f) << 14) | (offset & 0x3fff)];
return data;
}
void sam_onemeg_device::mreq_w(offs_t offset, uint8_t data)
{
// write if external memory is enabled and the id matches
if (m_xmem && (m_expage[BIT(offset, 14)] >> 6 == m_dip->read()))
m_ram[((m_expage[BIT(offset, 14)] & 0x3f) << 14) | (offset & 0x3fff)] = data;
}
void sam_onemeg_device::iorq_w(offs_t offset, uint8_t data)
{
// 0x80: EXPAGE-C
// 0x81: EXPAGE-D
// 76------ selected memory expansion
// --543210 memory bank
if ((offset & 0xfe) == 0x80)
m_expage[BIT(offset, 0)] = data;
}

View File

@ -0,0 +1,52 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
1 Mb Interface for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_ONEMEG_H
#define MAME_BUS_SAMCOUPE_EXPANSION_ONEMEG_H
#pragma once
#include "expansion.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_onemeg_device
class sam_onemeg_device : public device_t, public device_samcoupe_expansion_interface
{
public:
// construction/destruction
sam_onemeg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual void xmem_w(int state) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
protected:
virtual ioport_constructor device_input_ports() const override;
virtual void device_start() override;
private:
required_ioport m_dip;
int m_xmem;
uint8_t m_expage[2];
std::unique_ptr<uint8_t[]> m_ram;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_ONEMEG, sam_onemeg_device)
#endif // MAME_BUS_SAMCOUPE_EXPANSION_ONEMEG_H

View File

@ -0,0 +1,116 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAMBUS 4-slot Expansion Interface for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "sambus.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_SAMBUS, sam_sambus_device, "sambus", "SAMBUS 4-slot Expansion Interface")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_sambus_device::device_add_mconfig(machine_config &config)
{
MSM6242(config, m_rtc, 32.768_kHz_XTAL);
SAMCOUPE_EXPANSION(config, m_exp[0], samcoupe_expansion_modules);
SAMCOUPE_EXPANSION(config, m_exp[1], samcoupe_expansion_modules);
SAMCOUPE_EXPANSION(config, m_exp[2], samcoupe_expansion_modules);
SAMCOUPE_EXPANSION(config, m_exp[3], samcoupe_expansion_modules);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_sambus_device - constructor
//-------------------------------------------------
sam_sambus_device::sam_sambus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_SAMBUS, tag, owner, clock),
device_samcoupe_expansion_interface(mconfig, *this),
m_rtc(*this, "rtc"),
m_exp(*this, "%u", 0U),
m_print(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_sambus_device::device_start()
{
// register for savestates
save_item(NAME(m_print));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
void sam_sambus_device::xmem_w(int state)
{
for (int i = 0; i < 4; i++)
m_exp[i]->xmem_w(state);
}
void sam_sambus_device::print_w(int state)
{
for (int i = 0; i < 4; i++)
m_exp[i]->print_w(state);
m_print = state;
}
uint8_t sam_sambus_device::mreq_r(offs_t offset)
{
uint8_t data = 0xff;
for (int i = 0; i < 4; i++)
data &= m_exp[i]->mreq_r(offset);
return data;
}
void sam_sambus_device::mreq_w(offs_t offset, uint8_t data)
{
for (int i = 0; i < 4; i++)
m_exp[i]->mreq_w(offset, data);
}
uint8_t sam_sambus_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_print && (offset & 0x07) == 0x07)
data &= m_rtc->read(offset >> 12);
for (int i = 0; i < 4; i++)
data &= m_exp[i]->iorq_r(offset);
return data;
}
void sam_sambus_device::iorq_w(offs_t offset, uint8_t data)
{
if (m_print && (offset & 0x07) == 0x07)
m_rtc->write(offset >> 12, data);
for (int i = 0; i < 4; i++)
m_exp[i]->iorq_w(offset, data);
}

View File

@ -0,0 +1,53 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAMBUS 4-slot Expansion Interface for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_SAMBUS_H
#define MAME_BUS_SAMCOUPE_EXPANSION_SAMBUS_H
#pragma once
#include "expansion.h"
#include "machine/msm6242.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_sambus_device
class sam_sambus_device : public device_t, public device_samcoupe_expansion_interface
{
public:
// construction/destruction
sam_sambus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual void xmem_w(int state) override;
virtual void print_w(int state) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
private:
required_device<msm6242_device> m_rtc;
required_device_array<samcoupe_expansion_device, 4> m_exp;
int m_print;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_SAMBUS, sam_sambus_device)
#endif // MAME_BUS_SAMCOUPE_EXPANSION_SAMBUS_H

View File

@ -0,0 +1,90 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SID Soundchip Interface for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "sid.h"
#include "speaker.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_SID6581, sam_sid6581_device, "sid6581", "SID Soundchip Interface (6581)")
DEFINE_DEVICE_TYPE(SAM_SID8580, sam_sid8580_device, "sid8580", "SID Soundchip Interface (8580)")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_sid6581_device::device_add_mconfig(machine_config &config)
{
SPEAKER(config, "mono").front_center();
MOS6581(config, m_sid, 1_MHz_XTAL);
m_sid->add_route(ALL_OUTPUTS, "mono", 1.00);
}
void sam_sid8580_device::device_add_mconfig(machine_config &config)
{
SPEAKER(config, "mono").front_center();
MOS8580(config, m_sid, 1_MHz_XTAL);
m_sid->add_route(ALL_OUTPUTS, "mono", 1.00);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_sid_device - constructor
//-------------------------------------------------
sam_sid_device::sam_sid_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_samcoupe_expansion_interface(mconfig, *this),
m_sid(*this, "sid")
{
}
//-------------------------------------------------
// sam_sid6581_device - constructor
//-------------------------------------------------
sam_sid6581_device::sam_sid6581_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
sam_sid_device(mconfig, SAM_SID6581, tag, owner, clock)
{
}
//-------------------------------------------------
// sam_sid8580_device - constructor
//-------------------------------------------------
sam_sid8580_device::sam_sid8580_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
sam_sid_device(mconfig, SAM_SID8580, tag, owner, clock)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_sid_device::device_start()
{
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
void sam_sid_device::iorq_w(offs_t offset, uint8_t data)
{
if ((offset & 0xff) == 0xd4)
m_sid->write(offset >> 8, data);
}

View File

@ -0,0 +1,67 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SID Soundchip Interface for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_SID_H
#define MAME_BUS_SAMCOUPE_EXPANSION_SID_H
#pragma once
#include "expansion.h"
#include "sound/mos6581.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_sid_device
class sam_sid_device : public device_t, public device_samcoupe_expansion_interface
{
public:
// construction/destruction
sam_sid_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual void iorq_w(offs_t offset, uint8_t data) override;
protected:
virtual void device_start() override;
required_device<mos6581_device> m_sid;
};
// ======================> sam_sid6581_device
class sam_sid6581_device : public sam_sid_device
{
public:
// construction/destruction
sam_sid6581_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_add_mconfig(machine_config &config) override;
};
// ======================> sam_sid8580_device
class sam_sid8580_device : public sam_sid_device
{
public:
// construction/destruction
sam_sid8580_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_add_mconfig(machine_config &config) override;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_SID6581, sam_sid6581_device)
DECLARE_DEVICE_TYPE(SAM_SID8580, sam_sid8580_device)
#endif // MAME_BUS_SAMCOUPE_EXPANSION_SID_H

View File

@ -0,0 +1,120 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
S.P.I. SAM Parallel Interface for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "spi.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_SPI, sam_spi_device, "spi", "S.P.I. SAM Parallel Interface")
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_spi_device::device_add_mconfig(machine_config &config)
{
OUTPUT_LATCH(config, m_data_out);
CENTRONICS(config, m_centronics, centronics_devices, "printer");
m_centronics->busy_handler().set(FUNC(sam_spi_device::centronics_busy_w));
m_centronics->set_output_latch(*m_data_out);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sambus_device - constructor
//-------------------------------------------------
sam_spi_device::sam_spi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_SPI, tag, owner, clock),
device_samcoupe_expansion_interface(mconfig, *this),
m_data_out(*this, "data_out"),
m_centronics(*this, "centronics"),
m_print(0),
m_busy(0),
m_mode(0)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_spi_device::device_start()
{
// register for savestates
save_item(NAME(m_print));
save_item(NAME(m_busy));
save_item(NAME(m_mode));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
WRITE_LINE_MEMBER( sam_spi_device::centronics_busy_w )
{
m_busy = state;
}
void sam_spi_device::print_w(int state)
{
m_print = state;
}
uint8_t sam_spi_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_print)
{
switch (offset & 0x07)
{
case 0x01:
data = 0xfe | m_busy;
break;
case 0x02:
logerror("Warning: Data read unsupported\n");
data = 0xff;
break;
}
}
return data;
}
void sam_spi_device::iorq_w(offs_t offset, uint8_t data)
{
if (m_print)
{
switch (offset & 0x07)
{
case 0x00:
m_data_out->write(data);
break;
case 0x01:
m_centronics->write_strobe(BIT(data, 0));
break;
case 0x02:
m_mode = BIT(data, 0); // 0 = output (default), 1 = input
break;
}
}
}

View File

@ -0,0 +1,54 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
S.P.I. SAM Parallel Interface for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_SPI_H
#define MAME_BUS_SAMCOUPE_EXPANSION_SPI_H
#pragma once
#include "expansion.h"
#include "bus/centronics/ctronics.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_spi_device
class sam_spi_device : public device_t, public device_samcoupe_expansion_interface
{
public:
// construction/destruction
sam_spi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual void print_w(int state) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
private:
required_device<output_latch_device> m_data_out;
required_device<centronics_device> m_centronics;
DECLARE_WRITE_LINE_MEMBER(centronics_busy_w);
int m_print;
int m_busy;
int m_mode;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_SPI, sam_spi_device)
#endif // MAME_BUS_SAMCOUPE_EXPANSION_SPI_H

View File

@ -0,0 +1,88 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Voicebox for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "voicebox.h"
#include "speaker.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_VOICEBOX, sam_voicebox_device, "voicebox", "Voicebox")
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
ROM_START( sp0256 )
ROM_REGION(0x10000, "sp0256", 0)
ROM_LOAD("sp0256a-al2.bin", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc))
ROM_END
const tiny_rom_entry *sam_voicebox_device::device_rom_region() const
{
return ROM_NAME( sp0256 );
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sam_voicebox_device::device_add_mconfig(machine_config &config)
{
SPEAKER(config, "mono").front_center();
SP0256(config, m_sp0256, 3000000); // ???
m_sp0256->add_route(ALL_OUTPUTS, "mono", 1.00);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_voicebox_device - constructor
//-------------------------------------------------
sam_voicebox_device::sam_voicebox_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_VOICEBOX, tag, owner, clock),
device_samcoupe_expansion_interface(mconfig, *this),
m_sp0256(*this, "sp0256")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_voicebox_device::device_start()
{
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
uint8_t sam_voicebox_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if ((offset & 0xff) == 0x7f)
data = 0x18 | m_sp0256->lrq_r();
return data;
}
void sam_voicebox_device::iorq_w(offs_t offset, uint8_t data)
{
if ((offset & 0xff) == 0x7f)
m_sp0256->ald_w(data);
}

View File

@ -0,0 +1,46 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
Voicebox for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_EXPANSION_VOICEBOX_H
#define MAME_BUS_SAMCOUPE_EXPANSION_VOICEBOX_H
#pragma once
#include "expansion.h"
#include "sound/sp0256.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_voicebox_device
class sam_voicebox_device : public device_t, public device_samcoupe_expansion_interface
{
public:
// construction/destruction
sam_voicebox_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
protected:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
private:
required_device<sp0256_device> m_sp0256;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_VOICEBOX, sam_voicebox_device)
#endif // MAME_BUS_SAMCOUPE_EXPANSION_VOICEBOX_H

View File

@ -0,0 +1,17 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Mouse Port modules
***************************************************************************/
#include "emu.h"
#include "modules.h"
#include "mouse.h"
void samcoupe_mouse_modules(device_slot_interface &device)
{
device.option_add("mouse", SAM_MOUSE);
}

View File

@ -0,0 +1,16 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Mouse Port modules
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_MOUSE_MODULES_H
#define MAME_BUS_SAMCOUPE_MOUSE_MODULES_H
#pragma once
void samcoupe_mouse_modules(device_slot_interface &device);
#endif // MAME_BUS_SAMCOUPE_MOUSE_MODULES_H

View File

@ -0,0 +1,131 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Mouse Interface for SAM Coupe
***************************************************************************/
#include "emu.h"
#include "mouse.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAM_MOUSE, sam_mouse_device, "sam_mouse", "SAM Coupe Mouse Interface")
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
static INPUT_PORTS_START( mouse )
PORT_START("buttons")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_CODE(MOUSECODE_BUTTON1) PORT_NAME("Mouse Button 1")
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_CODE(MOUSECODE_BUTTON3) PORT_NAME("Mouse Button 3")
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_CODE(MOUSECODE_BUTTON2) PORT_NAME("Mouse Button 2")
PORT_BIT(0xf8, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("x")
PORT_BIT(0xfff, 0x000, IPT_MOUSE_X) PORT_PLAYER(1) PORT_SENSITIVITY(50) PORT_KEYDELTA(0) PORT_REVERSE
PORT_START("y")
PORT_BIT(0xfff, 0x000, IPT_MOUSE_Y) PORT_PLAYER(1) PORT_SENSITIVITY(50) PORT_KEYDELTA(0)
INPUT_PORTS_END
ioport_constructor sam_mouse_device::device_input_ports() const
{
return INPUT_PORTS_NAME( mouse );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sam_mouse_device - constructor
//-------------------------------------------------
sam_mouse_device::sam_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAM_MOUSE, tag, owner, clock),
device_samcoupe_mouse_interface(mconfig, *this),
m_io_buttons(*this, "buttons"),
m_io_x(*this, "x"),
m_io_y(*this, "y")
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sam_mouse_device::device_start()
{
// allocate timer
m_reset = timer_alloc();
}
//-------------------------------------------------
// device_reset - device-specific startup
//-------------------------------------------------
void sam_mouse_device::device_reset()
{
m_mouse_index = 0;
m_mouse_data[0] = 0xff;
m_mouse_data[1] = 0xff;
}
//-------------------------------------------------
// device_timer - handler timer events
//-------------------------------------------------
void sam_mouse_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
m_mouse_index = 0;
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
uint8_t sam_mouse_device::read()
{
uint8_t data;
// on a read, reset the timer
m_reset->adjust(attotime::from_usec(50));
// update when we are about to read the first real values
if (m_mouse_index == 2)
{
int mouse_x = m_io_x->read();
int mouse_y = m_io_y->read();
// distance moved
int mouse_dx = m_mouse_x - mouse_x;
int mouse_dy = m_mouse_y - mouse_y;
m_mouse_x = mouse_x;
m_mouse_y = mouse_y;
m_mouse_data[2] = m_io_buttons->read();
m_mouse_data[3] = (mouse_dy & 0xf00) >> 8;
m_mouse_data[4] = (mouse_dy & 0x0f0) >> 4;
m_mouse_data[5] = (mouse_dy & 0x00f) >> 0;
m_mouse_data[6] = (mouse_dx & 0xf00) >> 8;
m_mouse_data[7] = (mouse_dx & 0x0f0) >> 4;
m_mouse_data[8] = (mouse_dx & 0x00f) >> 0;
}
data = m_mouse_data[m_mouse_index++];
// reset if we are at the end
if (m_mouse_index == sizeof(m_mouse_data))
m_mouse_index = 1;
return data;
}

View File

@ -0,0 +1,53 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Mouse Interface for SAM Coupe
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_MOUSE_MOUSE_H
#define MAME_BUS_SAMCOUPE_MOUSE_MOUSE_H
#pragma once
#include "mouseport.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> sam_mouse_device
class sam_mouse_device : public device_t, public device_samcoupe_mouse_interface
{
public:
// construction/destruction
sam_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// from host
virtual uint8_t read() override;
protected:
virtual ioport_constructor device_input_ports() const override;
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:
required_ioport m_io_buttons;
required_ioport m_io_x;
required_ioport m_io_y;
emu_timer *m_reset;
int m_mouse_index;
uint8_t m_mouse_data[9];
int m_mouse_x, m_mouse_y;
};
// device type definition
DECLARE_DEVICE_TYPE(SAM_MOUSE, sam_mouse_device)
#endif // MAME_BUS_SAMCOUPE_MOUSE_MOUSE_H

View File

@ -0,0 +1,92 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Mouse Port
8-pin connector
***************************************************************************/
#include "emu.h"
#include "mouseport.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SAMCOUPE_MOUSE_PORT, samcoupe_mouse_port_device, "samcoupe_mouse_port", "SAM Coupe Mouse Port")
//**************************************************************************
// SLOT DEVICE
//**************************************************************************
//-------------------------------------------------
// samcoupe_mouse_port_device - constructor
//-------------------------------------------------
samcoupe_mouse_port_device::samcoupe_mouse_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SAMCOUPE_MOUSE_PORT, tag, owner, clock),
device_single_card_slot_interface<device_samcoupe_mouse_interface>(mconfig, *this),
m_mseint_handler(*this),
m_module(nullptr)
{
}
//-------------------------------------------------
// samcoupe_mouse_port_device - destructor
//-------------------------------------------------
samcoupe_mouse_port_device::~samcoupe_mouse_port_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void samcoupe_mouse_port_device::device_start()
{
// get inserted module
m_module = get_card_device();
// resolve callbacks
m_mseint_handler.resolve_safe();
}
//-------------------------------------------------
// host to module interface
//-------------------------------------------------
uint8_t samcoupe_mouse_port_device::read()
{
if (m_module)
return m_module->read();
return 0xff;
}
//**************************************************************************
// MODULE INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_samcoupe_mouse_interface - constructor
//-------------------------------------------------
device_samcoupe_mouse_interface::device_samcoupe_mouse_interface(const machine_config &mconfig, device_t &device) :
device_interface(device, "samcoupemouse")
{
m_port = dynamic_cast<samcoupe_mouse_port_device *>(device.owner());
}
//-------------------------------------------------
// ~device_samcoupe_mouse_interface - destructor
//-------------------------------------------------
device_samcoupe_mouse_interface::~device_samcoupe_mouse_interface()
{
}

View File

@ -0,0 +1,92 @@
// license: GPL-2.0+
// copyright-holders: Dirk Best
/***************************************************************************
SAM Coupe Mouse Port
8-pin connector
1 K3
2 K2
3 K1
4 K5
5 K4
6 MSEINT
7 RDMSEL
8 5V
***************************************************************************/
#ifndef MAME_BUS_SAMCOUPE_MOUSE_MOUSEPORT_H
#define MAME_BUS_SAMCOUPE_MOUSE_MOUSEPORT_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class device_samcoupe_mouse_interface;
// ======================> samcoupe_mouse_port_device
class samcoupe_mouse_port_device : public device_t, public device_single_card_slot_interface<device_samcoupe_mouse_interface>
{
public:
// construction/destruction
template <typename T>
samcoupe_mouse_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts)
: samcoupe_mouse_port_device(mconfig, tag, owner, uint32_t(0))
{
option_reset();
opts(*this);
set_default_option(nullptr);
set_fixed(false);
}
samcoupe_mouse_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~samcoupe_mouse_port_device();
// callbacks
auto mseint_handler() { return m_mseint_handler.bind(); }
// called from cart device
DECLARE_WRITE_LINE_MEMBER( mseint_w ) { m_mseint_handler(state); }
// called from host
uint8_t read();
protected:
// device-level overrides
virtual void device_start() override;
private:
devcb_write_line m_mseint_handler;
device_samcoupe_mouse_interface *m_module;
};
// ======================> device_samcoupe_mouse_interface
class device_samcoupe_mouse_interface : public device_interface
{
public:
// construction/destruction
virtual ~device_samcoupe_mouse_interface();
virtual uint8_t read() { return 0xff; }
protected:
device_samcoupe_mouse_interface(const machine_config &mconfig, device_t &device);
samcoupe_mouse_port_device *m_port;
};
// device type definition
DECLARE_DEVICE_TYPE(SAMCOUPE_MOUSE_PORT, samcoupe_mouse_port_device)
// include here so drivers don't need to
#include "modules.h"
#endif // MAME_BUS_SAMCOUPE_MOUSE_MOUSEPORT_H

File diff suppressed because it is too large Load Diff

View File

@ -1,221 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Lee Hammerton, Dirk Best
/*****************************************************************************
*
* includes/coupe.h
*
* SAM Coupe
*
* Driver by Lee Hammerton
*
****************************************************************************/
#ifndef MAME_INCLUDES_SAMCOUPE_H
#define MAME_INCLUDES_SAMCOUPE_H
#pragma once
#include "bus/centronics/ctronics.h"
#include "imagedev/cassette.h"
#include "imagedev/floppy.h"
#include "machine/msm6242.h"
#include "machine/ram.h"
#include "machine/wd_fdc.h"
#include "sound/spkrdev.h"
#include "emupal.h"
#include "screen.h"
/* screen dimensions */
#define SAM_BLOCK 8
#define SAM_TOTAL_WIDTH SAM_BLOCK*96
#define SAM_TOTAL_HEIGHT 312
#define SAM_SCREEN_WIDTH SAM_BLOCK*64
#define SAM_SCREEN_HEIGHT 192
#define SAM_BORDER_LEFT SAM_BLOCK*4
#define SAM_BORDER_RIGHT SAM_BLOCK*4
#define SAM_BORDER_TOP 37
#define SAM_BORDER_BOTTOM 46
/* interrupt sources */
#define SAM_LINE_INT 0x01
#define SAM_MOUSE_INT 0x02
#define SAM_MIDIIN_INT 0x04
#define SAM_FRAME_INT 0x08
#define SAM_MIDIOUT_INT 0x10
class samcoupe_state : public driver_device
{
public:
samcoupe_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_screen(*this, "screen"),
m_speaker(*this, "speaker"),
m_cassette(*this, "cassette"),
m_lpt1(*this, "lpt1"),
m_lpt2(*this, "lpt2"),
m_ram(*this, RAM_TAG),
m_rtc(*this, "sambus_clock"),
m_fdc(*this, "wd1772"),
m_wd1772_0(*this, "wd1772:0"),
m_wd1772_1(*this, "wd1772:1"),
m_region_maincpu(*this, "maincpu"),
m_keyboard_row_fe(*this, "keyboard_row_fe"),
m_keyboard_row_fd(*this, "keyboard_row_fd"),
m_keyboard_row_fb(*this, "keyboard_row_fb"),
m_keyboard_row_f7(*this, "keyboard_row_f7"),
m_keyboard_row_ef(*this, "keyboard_row_ef"),
m_keyboard_row_df(*this, "keyboard_row_df"),
m_keyboard_row_bf(*this, "keyboard_row_bf"),
m_keyboard_row_7f(*this, "keyboard_row_7f"),
m_keyboard_row_ff(*this, "keyboard_row_ff"),
m_mouse_buttons(*this, "mouse_buttons"),
m_io_mouse_x(*this, "mouse_x"),
m_io_mouse_y(*this, "mouse_y"),
m_config(*this, "config"),
m_joy1(*this, "joy_1"),
m_joy2(*this, "joy_2")
{
sam_bank_read_ptr[0] = nullptr;
sam_bank_write_ptr[0] = nullptr;
sam_bank_read_ptr[1] = nullptr;
sam_bank_write_ptr[1] = nullptr;
sam_bank_read_ptr[2] = nullptr;
sam_bank_write_ptr[2] = nullptr;
sam_bank_read_ptr[3] = nullptr;
sam_bank_write_ptr[3] = nullptr;
}
void samcoupe(machine_config &config);
protected:
enum
{
TIMER_IRQ_OFF,
TIMER_MOUSE_RESET,
TIMER_VIDEO_UPDATE
};
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
bitmap_ind16 m_bitmap;
emu_timer *m_video_update_timer;
uint8_t m_lmpr, m_hmpr, m_vmpr; /* memory pages */
uint8_t m_lext, m_hext; /* extended memory page */
uint8_t m_border; /* border */
uint8_t m_clut[16]; /* color lookup table, 16 entries */
uint8_t m_line_int; /* line interrupt */
uint8_t m_status; /* status register */
/* attribute */
uint8_t m_attribute;
/* mouse */
int m_mouse_index;
emu_timer *m_mouse_reset;
uint8_t m_mouse_data[9];
int m_mouse_x, m_mouse_y;
uint8_t *m_videoram;
void samcoupe_ext_mem_w(offs_t offset, uint8_t data);
uint8_t samcoupe_disk_r(offs_t offset);
void samcoupe_disk_w(offs_t offset, uint8_t data);
uint8_t samcoupe_pen_r(offs_t offset);
void samcoupe_clut_w(offs_t offset, uint8_t data);
uint8_t samcoupe_status_r(offs_t offset);
void samcoupe_line_int_w(uint8_t data);
uint8_t samcoupe_lmpr_r();
void samcoupe_lmpr_w(uint8_t data);
uint8_t samcoupe_hmpr_r();
void samcoupe_hmpr_w(uint8_t data);
uint8_t samcoupe_vmpr_r();
void samcoupe_vmpr_w(uint8_t data);
uint8_t samcoupe_midi_r();
void samcoupe_midi_w(uint8_t data);
uint8_t samcoupe_keyboard_r(offs_t offset);
void samcoupe_border_w(uint8_t data);
uint8_t samcoupe_attributes_r();
void samcoupe_palette(palette_device &palette) const;
INTERRUPT_GEN_MEMBER(samcoupe_frame_interrupt);
TIMER_CALLBACK_MEMBER(irq_off);
TIMER_CALLBACK_MEMBER(samcoupe_mouse_reset);
TIMER_CALLBACK_MEMBER(sam_video_update_callback);
uint8_t samcoupe_lpt1_busy_r();
void samcoupe_lpt1_strobe_w(uint8_t data);
uint8_t samcoupe_lpt2_busy_r();
void samcoupe_lpt2_strobe_w(uint8_t data);
uint8_t samcoupe_rtc_r(offs_t offset);
void samcoupe_rtc_w(offs_t offset, uint8_t data);
uint8_t sam_bank1_r(offs_t offset);
void sam_bank1_w(offs_t offset, uint8_t data);
uint8_t sam_bank2_r(offs_t offset);
void sam_bank2_w(offs_t offset, uint8_t data);
uint8_t sam_bank3_r(offs_t offset);
void sam_bank3_w(offs_t offset, uint8_t data);
uint8_t sam_bank4_r(offs_t offset);
void sam_bank4_w(offs_t offset, uint8_t data);
uint8_t* sam_bank_read_ptr[4];
uint8_t* sam_bank_write_ptr[4];
DECLARE_FLOPPY_FORMATS( floppy_formats );
required_device<cpu_device> m_maincpu;
required_device<screen_device> m_screen;
required_device<speaker_sound_device> m_speaker;
required_device<cassette_image_device> m_cassette;
required_device<centronics_device> m_lpt1;
required_device<centronics_device> m_lpt2;
required_device<ram_device> m_ram;
required_device<msm6242_device> m_rtc;
required_device<wd1772_device> m_fdc;
required_device<floppy_connector> m_wd1772_0;
required_device<floppy_connector> m_wd1772_1;
required_memory_region m_region_maincpu;
required_ioport m_keyboard_row_fe;
required_ioport m_keyboard_row_fd;
required_ioport m_keyboard_row_fb;
required_ioport m_keyboard_row_f7;
required_ioport m_keyboard_row_ef;
required_ioport m_keyboard_row_df;
required_ioport m_keyboard_row_bf;
required_ioport m_keyboard_row_7f;
required_ioport m_keyboard_row_ff;
required_ioport m_mouse_buttons;
required_ioport m_io_mouse_x;
required_ioport m_io_mouse_y;
required_ioport m_config;
required_ioport m_joy1;
required_ioport m_joy2;
void draw_mode4_line(int y, int hpos);
void draw_mode3_line(int y, int hpos);
void draw_mode12_block(bitmap_ind16 &bitmap, int vpos, int hpos, uint8_t mask);
void draw_mode2_line(int y, int hpos);
void draw_mode1_line(int y, int hpos);
void samcoupe_update_bank(address_space &space, int bank_num, uint8_t *memory, int is_readonly);
void samcoupe_install_ext_mem(address_space &space);
void samcoupe_update_memory(address_space &space);
uint8_t samcoupe_mouse_r();
void samcoupe_irq(uint8_t src);
DECLARE_WRITE_LINE_MEMBER(write_lpt1_busy);
DECLARE_WRITE_LINE_MEMBER(write_lpt2_busy);
int m_lpt1_busy;
int m_lpt2_busy;
void samcoupe_io(address_map &map);
void samcoupe_mem(address_map &map);
};
#endif // MAME_INCLUDES_SAMCOUPE_H

View File

@ -1,334 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Lee Hammerton, Dirk Best
/***************************************************************************
Miles Gordon Technology SAM Coupe
***************************************************************************/
#include "emu.h"
#include "includes/samcoupe.h"
/***************************************************************************
CONSTANTS
***************************************************************************/
#define LMPR_RAM0 0x20 /* If bit set ram is paged into bank 0, else its rom0 */
#define LMPR_ROM1 0x40 /* If bit set rom1 is paged into bank 3, else its ram */
#define HMPR_MCNTRL 0x80 /* If set external RAM is enabled */
/***************************************************************************
MEMORY BANKING
***************************************************************************/
uint8_t samcoupe_state::sam_bank1_r(offs_t offset)
{
if (sam_bank_read_ptr[0])
return sam_bank_read_ptr[0][offset];
return 0xff;
}
void samcoupe_state::sam_bank1_w(offs_t offset, uint8_t data)
{
if (sam_bank_write_ptr[0])
sam_bank_write_ptr[0][offset] = data;
}
uint8_t samcoupe_state::sam_bank2_r(offs_t offset)
{
if (sam_bank_read_ptr[1])
return sam_bank_read_ptr[1][offset];
return 0xff;
}
void samcoupe_state::sam_bank2_w(offs_t offset, uint8_t data)
{
if (sam_bank_write_ptr[1])
sam_bank_write_ptr[1][offset] = data;
}
uint8_t samcoupe_state::sam_bank3_r(offs_t offset)
{
if (sam_bank_read_ptr[2])
return sam_bank_read_ptr[2][offset];
return 0xff;
}
void samcoupe_state::sam_bank3_w(offs_t offset, uint8_t data)
{
if (sam_bank_write_ptr[2])
sam_bank_write_ptr[2][offset] = data;
}
uint8_t samcoupe_state::sam_bank4_r(offs_t offset)
{
if (sam_bank_read_ptr[3])
return sam_bank_read_ptr[3][offset];
return 0xff;
}
void samcoupe_state::sam_bank4_w(offs_t offset, uint8_t data)
{
if (sam_bank_write_ptr[3])
sam_bank_write_ptr[3][offset] = data;
}
void samcoupe_state::samcoupe_update_bank(address_space &space, int bank_num, uint8_t *memory, int is_readonly)
{
sam_bank_read_ptr[bank_num-1] = memory;
if (!is_readonly)
sam_bank_write_ptr[bank_num-1] = memory;
else
sam_bank_write_ptr[bank_num-1] = nullptr;
// installing banks on the fly is too slow (20% speed in Manic Miner gameplay vs 300% speed)
#if 0
char bank[10];
sprintf(bank,"bank%d",bank_num);
if (memory)
{
membank(bank)->set_base(memory);
space.install_read_bank (((bank_num-1) * 0x4000), ((bank_num-1) * 0x4000) + 0x3FFF, bank);
if (is_readonly) {
space.unmap_write(((bank_num-1) * 0x4000), ((bank_num-1) * 0x4000) + 0x3FFF);
} else {
space.install_write_bank(((bank_num-1) * 0x4000), ((bank_num-1) * 0x4000) + 0x3FFF, bank);
}
} else {
space.nop_readwrite(((bank_num-1) * 0x4000), ((bank_num-1) * 0x4000) + 0x3FFF);
}
#endif
}
void samcoupe_state::samcoupe_install_ext_mem(address_space &space)
{
uint8_t *mem;
/* bank 3 */
if (m_lext >> 6 < m_ram->size() >> 20)
mem = &m_ram->pointer()[(m_ram->size() & 0xfffff) + (m_lext >> 6) * 0x100000 + (m_lext & 0x3f) * 0x4000];
else
mem = nullptr;
samcoupe_update_bank(space, 3, mem, false);
/* bank 4 */
if (m_hext >> 6 < m_ram->size() >> 20)
mem = &m_ram->pointer()[(m_ram->size() & 0xfffff) + (m_hext >> 6) * 0x100000 + (m_hext & 0x3f) * 0x4000];
else
mem = nullptr;
samcoupe_update_bank(space, 4, mem, false);
}
void samcoupe_state::samcoupe_update_memory(address_space &space)
{
const int page_mask = ((m_ram->size() & 0xfffff) / 0x4000) - 1;
uint8_t *rom = m_region_maincpu->base();
uint8_t *memory;
int is_readonly;
/* BANK1 */
if (m_lmpr & LMPR_RAM0) /* Is ram paged in at bank 1 */
{
if ((m_lmpr & 0x1F) <= page_mask)
memory = &m_ram->pointer()[(m_lmpr & page_mask) * 0x4000];
else
memory = nullptr; /* Attempt to page in non existent ram region */
is_readonly = false;
}
else
{
memory = rom; /* Rom0 paged in */
is_readonly = true;
}
samcoupe_update_bank(space, 1, memory, is_readonly);
/* BANK2 */
if (((m_lmpr + 1) & 0x1f) <= page_mask)
memory = &m_ram->pointer()[((m_lmpr + 1) & page_mask) * 0x4000];
else
memory = nullptr; /* Attempt to page in non existent ram region */
samcoupe_update_bank(space, 2, memory, false);
/* only update bank 3 and 4 when external memory is not enabled */
if (m_hmpr & HMPR_MCNTRL)
{
samcoupe_install_ext_mem(space);
}
else
{
/* BANK3 */
if ((m_hmpr & 0x1F) <= page_mask )
memory = &m_ram->pointer()[(m_hmpr & page_mask)*0x4000];
else
memory = nullptr; /* Attempt to page in non existent ram region */
samcoupe_update_bank(space, 3, memory, false);
/* BANK4 */
if (m_lmpr & LMPR_ROM1) /* Is Rom1 paged in at bank 4 */
{
memory = rom + 0x4000;
is_readonly = true;
}
else
{
if (((m_hmpr + 1) & 0x1f) <= page_mask)
memory = &m_ram->pointer()[((m_hmpr + 1) & page_mask) * 0x4000];
else
memory = nullptr; /* Attempt to page in non existent ram region */
is_readonly = false;
}
samcoupe_update_bank(space, 4, memory, false);
}
/* video memory location */
if (m_vmpr & 0x40) /* if bit set in 2 bank screen mode */
m_videoram = &m_ram->pointer()[((m_vmpr & 0x1e) & page_mask) * 0x4000];
else
m_videoram = &m_ram->pointer()[((m_vmpr & 0x1f) & page_mask) * 0x4000];
}
void samcoupe_state::samcoupe_ext_mem_w(offs_t offset, uint8_t data)
{
address_space &space_program = m_maincpu->space(AS_PROGRAM);
if (offset & 1)
m_hext = data;
else
m_lext = data;
/* external RAM enabled? */
if (m_hmpr & HMPR_MCNTRL)
{
samcoupe_install_ext_mem(space_program);
}
}
/***************************************************************************
REAL TIME CLOCK
***************************************************************************/
uint8_t samcoupe_state::samcoupe_rtc_r(offs_t offset)
{
return m_rtc->read(offset >> 12);
}
void samcoupe_state::samcoupe_rtc_w(offs_t offset, uint8_t data)
{
m_rtc->write(offset >> 12, data);
}
/***************************************************************************
MOUSE
***************************************************************************/
TIMER_CALLBACK_MEMBER(samcoupe_state::samcoupe_mouse_reset)
{
m_mouse_index = 0;
}
uint8_t samcoupe_state::samcoupe_mouse_r()
{
uint8_t result;
/* on a read, reset the timer */
m_mouse_reset->adjust(attotime::from_usec(50));
/* update when we are about to read the first real values */
if (m_mouse_index == 2)
{
/* update values */
int mouse_x = m_io_mouse_x->read();
int mouse_y = m_io_mouse_y->read();
int mouse_dx = m_mouse_x - mouse_x;
int mouse_dy = m_mouse_y - mouse_y;
m_mouse_x = mouse_x;
m_mouse_y = mouse_y;
/* button state */
m_mouse_data[2] = m_mouse_buttons->read();
/* y-axis */
m_mouse_data[3] = (mouse_dy & 0xf00) >> 8;
m_mouse_data[4] = (mouse_dy & 0x0f0) >> 4;
m_mouse_data[5] = (mouse_dy & 0x00f) >> 0;
/* x-axis */
m_mouse_data[6] = (mouse_dx & 0xf00) >> 8;
m_mouse_data[7] = (mouse_dx & 0x0f0) >> 4;
m_mouse_data[8] = (mouse_dx & 0x00f) >> 0;
}
/* get current value */
result = m_mouse_data[m_mouse_index++];
/* reset if we are at the end */
if (m_mouse_index == sizeof(m_mouse_data))
m_mouse_index = 1;
return result;
}
void samcoupe_state::machine_start()
{
m_mouse_reset = timer_alloc(TIMER_MOUSE_RESET);
/* schedule our video updates */
m_video_update_timer = timer_alloc(TIMER_VIDEO_UPDATE);
m_video_update_timer->adjust(m_screen->time_until_pos(0, 0));
}
/***************************************************************************
RESET
***************************************************************************/
void samcoupe_state::machine_reset()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
address_space &spaceio = m_maincpu->space(AS_IO);
/* initialize state */
m_lmpr = 0x0f; /* ROM0 paged in, ROM1 paged out RAM Banks */
m_hmpr = 0x01;
m_vmpr = 0x81;
m_line_int = 0xff; /* line interrupts disabled */
m_status = 0x1f; /* no interrupts active */
/* initialize mouse */
m_mouse_index = 0;
m_mouse_data[0] = 0xff;
m_mouse_data[1] = 0xff;
if (m_config->read() & 0x01)
{
/* install RTC */
spaceio.install_readwrite_handler(0xef, 0xef, 0, 0, 0xff00, read8sm_delegate(*this, FUNC(samcoupe_state::samcoupe_rtc_r)), write8sm_delegate(*this, FUNC(samcoupe_state::samcoupe_rtc_w)));
}
else
{
/* no RTC support */
spaceio.unmap_readwrite(0xef, 0xef, 0xff00);
}
/* initialize memory */
samcoupe_update_memory(space);
}

View File

@ -1,171 +0,0 @@
// license:GPL-2.0+
// copyright-holders:Lee Hammerton, Dirk Best
/***************************************************************************
Miles Gordon Technology SAM Coupe
***************************************************************************/
#include "emu.h"
#include "includes/samcoupe.h"
/***************************************************************************
MACROS
***************************************************************************/
/* border color from border register */
#define BORDER_COLOR(x) ((x & 0x20) >> 2 | (x & 0x07))
/* foreground and background color from attribute byte in mode 1 and 2 */
#define ATTR_BG(x) ((x >> 3) & 0x0f)
#define ATTR_FG(x) (((x >> 3) & 0x08) | (x & 0x07))
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
void samcoupe_state::video_start()
{
m_screen->register_screen_bitmap(m_bitmap);
}
uint32_t samcoupe_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
return 0;
}
void samcoupe_state::draw_mode4_line(int y, int hpos)
{
uint8_t *videoram = m_videoram;
/* get start address */
uint8_t *vram = videoram + ((y - SAM_BORDER_TOP) * 128) + ((hpos - SAM_BORDER_LEFT) / 4);
for (int i = 0; i < (SAM_BLOCK*2)/4; i++)
{
/* draw 2 pixels (doublewidth) */
m_bitmap.pix16(y, hpos + i * 4 + 0) = m_clut[(*vram >> 4) & 0x0f];
m_bitmap.pix16(y, hpos + i * 4 + 1) = m_clut[(*vram >> 4) & 0x0f];
m_bitmap.pix16(y, hpos + i * 4 + 2) = m_clut[(*vram >> 0) & 0x0f];
m_bitmap.pix16(y, hpos + i * 4 + 3) = m_clut[(*vram >> 0) & 0x0f];
/* move to next address */
vram++;
/* attribute register contains the third displayed byte */
if (i == 2)
m_attribute = *vram;
}
}
void samcoupe_state::draw_mode3_line(int y, int hpos)
{
uint8_t *videoram = m_videoram;
/* get start address */
uint8_t *vram = videoram + ((y - SAM_BORDER_TOP) * 128) + ((hpos - SAM_BORDER_LEFT) / 4);
for (int i = 0; i < (SAM_BLOCK*2)/4; i++)
{
/* draw 4 pixels */
m_bitmap.pix16(y, hpos + i * 4 + 0) = m_clut[(*vram >> 6) & 0x03];
m_bitmap.pix16(y, hpos + i * 4 + 1) = m_clut[(*vram >> 4) & 0x03];
m_bitmap.pix16(y, hpos + i * 4 + 2) = m_clut[(*vram >> 2) & 0x03];
m_bitmap.pix16(y, hpos + i * 4 + 3) = m_clut[(*vram >> 0) & 0x03];
/* move to next address */
vram++;
/* attribute register contains the third displayed byte */
if (i == 2)
m_attribute = *vram;
}
}
void samcoupe_state::draw_mode12_block(bitmap_ind16 &bitmap, int vpos, int hpos, uint8_t mask)
{
/* extract colors from attribute */
uint8_t ink = m_clut[ATTR_FG(m_attribute)];
uint8_t pap = m_clut[ATTR_BG(m_attribute)];
/* draw block of 8 pixels (doubled to 16) */
for (int i = 0; i < SAM_BLOCK; i++)
{
bitmap.pix16(vpos, hpos + i*2 + 0) = BIT(mask, 7 - i) ? ink : pap;
bitmap.pix16(vpos, hpos + i*2 + 1) = BIT(mask, 7 - i) ? ink : pap;
}
}
void samcoupe_state::draw_mode2_line(int y, int hpos)
{
uint8_t *videoram = m_videoram;
int cell = (y - SAM_BORDER_TOP) * 32 + (hpos - SAM_BORDER_LEFT) / SAM_BLOCK / 2;
uint8_t mask = videoram[cell];
m_attribute = videoram[cell + 0x2000];
draw_mode12_block(m_bitmap, y, hpos, mask);
}
void samcoupe_state::draw_mode1_line(int y, int hpos)
{
uint8_t *videoram = m_videoram;
uint8_t mask = videoram[((((y - SAM_BORDER_TOP) & 0xc0) << 5) | (((y - SAM_BORDER_TOP) & 0x07) << 8) | (((y - SAM_BORDER_TOP) & 0x38) << 2)) + (hpos - SAM_BORDER_LEFT) / SAM_BLOCK / 2];
m_attribute = videoram[32*192 + (((y - SAM_BORDER_TOP) & 0xf8) << 2) + (hpos - SAM_BORDER_LEFT) / SAM_BLOCK / 2];
draw_mode12_block(m_bitmap, y, hpos, mask);
}
TIMER_CALLBACK_MEMBER(samcoupe_state::sam_video_update_callback)
{
int vpos = m_screen->vpos();
int hpos = m_screen->hpos();
int next_vpos = vpos;
int next_hpos = hpos + SAM_BLOCK*2;
/* next scanline? */
if (next_hpos >= SAM_BORDER_LEFT + SAM_SCREEN_WIDTH + SAM_BORDER_RIGHT)
{
next_vpos = (vpos + 1) % (SAM_BORDER_TOP + SAM_SCREEN_HEIGHT + SAM_BORDER_BOTTOM);
next_hpos = 0;
}
/* display disabled? (only in mode 3 or 4) */
if (BIT(m_vmpr, 6) && BIT(m_border, 7))
{
m_bitmap.plot_box(hpos, vpos, SAM_BLOCK*2, 1, 0);
}
else
{
/* border area? */
if (vpos < SAM_BORDER_TOP || vpos >= SAM_BORDER_TOP + SAM_SCREEN_HEIGHT || hpos < SAM_BORDER_LEFT || hpos >= SAM_BORDER_LEFT + SAM_SCREEN_WIDTH)
{
m_attribute = 0xff;
m_bitmap.plot_box(hpos, vpos, SAM_BLOCK*2, 1, m_clut[BORDER_COLOR(m_border)]);
}
else
{
/* main screen area */
switch ((m_vmpr & 0x60) >> 5)
{
case 0: draw_mode1_line(vpos, hpos); break;
case 1: draw_mode2_line(vpos, hpos); break;
case 2: draw_mode3_line(vpos, hpos); break;
case 3: draw_mode4_line(vpos, hpos); break;
}
}
}
/* do we need to trigger the scanline interrupt (interrupt happens at the start of the right border before the specified line)? */
if (m_line_int < SAM_SCREEN_HEIGHT && hpos == SAM_BORDER_LEFT + SAM_SCREEN_WIDTH && vpos == (m_line_int + SAM_BORDER_TOP - 1))
samcoupe_irq(SAM_LINE_INT);
/* schedule next update */
m_video_update_timer->adjust(m_screen->time_until_pos(next_vpos, next_hpos));
}