summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2020-12-30 13:57:52 -0500
committer AJR <ajrhacker@users.noreply.github.com>2020-12-30 13:57:52 -0500
commit8fa9e7d9419bde7f958fcf5b8aabbd9493f229d6 (patch)
tree463a6f8dda6f04ad1755a3f4413dba38ce6a41f0
parent914d50d78f5041bea136aa269b240559e2a13fe9 (diff)
apple2, apple2e, apple2gs: Add emulation of Apricorn Super Serial Imager as slot option [AJR, Apple II Documentation Project]
-rw-r--r--src/devices/bus/a2bus/a2ssc.cpp176
-rw-r--r--src/devices/bus/a2bus/a2ssc.h25
-rw-r--r--src/mame/drivers/apple2.cpp1
-rw-r--r--src/mame/drivers/apple2e.cpp1
-rw-r--r--src/mame/drivers/apple2gs.cpp1
5 files changed, 190 insertions, 14 deletions
diff --git a/src/devices/bus/a2bus/a2ssc.cpp b/src/devices/bus/a2bus/a2ssc.cpp
index db2f27aecfc..5db81b70f26 100644
--- a/src/devices/bus/a2bus/a2ssc.cpp
+++ b/src/devices/bus/a2bus/a2ssc.cpp
@@ -6,6 +6,11 @@
Apple II Super Serial Card
+ The Apricorn Super Serial Imager has separate "Modem" and
+ "Printer" pin headers, which carry different arrangements of the
+ same RS232 signals. Its GPI mode also features Videx VideoTerm
+ support when that card is installed in slot 3.
+
*********************************************************************/
#include "emu.h"
@@ -22,16 +27,18 @@
//**************************************************************************
DEFINE_DEVICE_TYPE(A2BUS_SSC, a2bus_ssc_device, "a2ssc", "Apple Super Serial Card")
-
-#define SSC_ROM_REGION "ssc_rom"
-#define SSC_ACIA_TAG "ssc_acia"
-#define SSC_RS232_TAG "ssc_rs232"
+DEFINE_DEVICE_TYPE(APRICORN_SSI, apricorn_ssi_device, "aprissi", "Apricorn Super Serial Imager")
ROM_START( ssc )
- ROM_REGION(0x000800, SSC_ROM_REGION, 0)
+ ROM_REGION(0x800, "program", 0)
ROM_LOAD( "341-0065-a.bin", 0x000000, 0x000800, CRC(b7539d4c) SHA1(6dab633470c6bc4cb3e81d09fda46597caf8ee57) )
ROM_END
+ROM_START( ssi )
+ ROM_REGION(0x2000, "program", 0)
+ ROM_LOAD( "apricorn super serial imager - rom.bin", 0x0000, 0x2000, CRC(d251f7f1) SHA1(19f2bc1e60c3fd5e179c4a38f7ca4e3221553562) )
+ROM_END
+
static INPUT_PORTS_START( ssc )
PORT_START("DSW1")
PORT_DIPNAME( 0xf0, 0xe0, "Baud Rate" ) PORT_DIPLOCATION("SW1:4,3,2,1")
@@ -82,7 +89,7 @@ static INPUT_PORTS_START( ssc )
PORT_DIPNAME( 0x02, 0x02, "End of Line" ) PORT_DIPLOCATION("SW2:5")
PORT_DIPSETTING( 0x00, "Add LF after CR")
PORT_DIPSETTING( 0x02, "Don't add LF after CR")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER(SSC_RS232_TAG, rs232_port_device, cts_r)
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("rs232", rs232_port_device, cts_r)
PORT_START("DSWX") // Non-memory-mapped DIP switches
PORT_DIPNAME( 0x04, 0x04, "Interrupts" ) PORT_DIPLOCATION("SW2:6")
@@ -94,6 +101,100 @@ static INPUT_PORTS_START( ssc )
PORT_DIPSETTING( 0x01, DEF_STR(Off))
INPUT_PORTS_END
+static INPUT_PORTS_START( ssi )
+ PORT_START("DSW1")
+ PORT_DIPNAME( 0x100, 0x100, "Emulation Mode" ) PORT_DIPLOCATION("SW1:8")
+ PORT_DIPSETTING( 0x100, "Off (GPI)" )
+ PORT_DIPSETTING( 0x000, "On (SSC)" )
+ PORT_DIPNAME( 0xf0, 0xe0, "Baud Rate" ) PORT_DIPLOCATION("SW1:4,3,2,1")
+ PORT_DIPSETTING( 0x00, "Undefined" )
+ PORT_DIPSETTING( 0x10, "50" )
+ PORT_DIPSETTING( 0x20, "75" )
+ PORT_DIPSETTING( 0x30, "110" )
+ PORT_DIPSETTING( 0x40, "135" )
+ PORT_DIPSETTING( 0x50, "150" )
+ PORT_DIPSETTING( 0x60, "300" )
+ PORT_DIPSETTING( 0x70, "600" )
+ PORT_DIPSETTING( 0x80, "1200" )
+ PORT_DIPSETTING( 0x90, "1800" )
+ PORT_DIPSETTING( 0xa0, "2400" )
+ PORT_DIPSETTING( 0xb0, "3600" )
+ PORT_DIPSETTING( 0xc0, "4800" )
+ PORT_DIPSETTING( 0xd0, "7200" )
+ PORT_DIPSETTING( 0xe0, "9600" )
+ PORT_DIPSETTING( 0xf0, "19200" )
+ PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_DIPNAME( 0x03, 0x02, "SSC Mode" ) PORT_DIPLOCATION("SW1:6,5") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x000)
+ PORT_DIPSETTING( 0x00, "Communications" )
+ PORT_DIPSETTING( 0x02, "Printer" )
+ PORT_DIPNAME( 0x02, 0x02, "XON/XOFF Handshaking" ) PORT_DIPLOCATION("SW1:5") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x100)
+ PORT_DIPSETTING( 0x02, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0x01, 0x00, "LF After CR" ) PORT_DIPLOCATION("SW1:6") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x100)
+ PORT_DIPSETTING( 0x01, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+
+ PORT_START("DSW2")
+ PORT_DIPNAME( 0x80, 0x80, "Stop Bits" ) PORT_DIPLOCATION("SW2:1") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x000)
+ PORT_DIPSETTING( 0x00, "1")
+ PORT_DIPSETTING( 0x80, "2")
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR(Unused)) PORT_DIPLOCATION("SW2:7") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x000)
+ PORT_DIPSETTING( 0x40, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0x20, 0x00, "Data Bits" ) PORT_DIPLOCATION("SW2:2") PORT_CONDITION("DSW1", 0x103, EQUALS, 0x000)
+ PORT_DIPSETTING( 0x20, "7")
+ PORT_DIPSETTING( 0x00, "8")
+ PORT_DIPNAME( 0x20, 0x00, "CR Delay" ) PORT_DIPLOCATION("SW2:2") PORT_CONDITION("DSW1", 0x103, EQUALS, 0x002)
+ PORT_DIPSETTING( 0x20, DEF_STR(None))
+ PORT_DIPSETTING( 0x00, "32 ms")
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR(Unused)) PORT_DIPLOCATION("SW2:8") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x000)
+ PORT_DIPSETTING( 0x10, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0x0c, 0x08, "Parity" ) PORT_DIPLOCATION("SW2:4,3") PORT_CONDITION("DSW1", 0x103, EQUALS, 0x000)
+ PORT_DIPSETTING( 0x00, DEF_STR(None))
+ PORT_DIPSETTING( 0x08, "None (2)")
+ PORT_DIPSETTING( 0x04, "Odd")
+ PORT_DIPSETTING( 0x0c, "Even")
+ PORT_DIPNAME( 0x0c, 0x00, "Line Width" ) PORT_DIPLOCATION("SW2:4,3") PORT_CONDITION("DSW1", 0x103, EQUALS, 0x002)
+ PORT_DIPSETTING( 0x00, "40 Characters (Echo On)")
+ PORT_DIPSETTING( 0x04, "72 Characters (Echo Off)")
+ PORT_DIPSETTING( 0x08, "80 Characters (Echo Off)")
+ PORT_DIPSETTING( 0x0c, "132 Characters (Echo Off)")
+ PORT_DIPNAME( 0x02, 0x00, "LF After CR" ) PORT_DIPLOCATION("SW2:5") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x000)
+ PORT_DIPSETTING( 0x02, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0xa8, 0x88, "Printer Type" ) PORT_DIPLOCATION("SW2:3,2,1") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x100)
+ PORT_DIPSETTING( 0x08, "ImageWriter" )
+ PORT_DIPSETTING( 0x88, "Epson" )
+ PORT_DIPSETTING( 0x80, "Star Micronics" )
+ PORT_DIPSETTING( 0x20, "Okidata" )
+ PORT_DIPSETTING( 0x00, "C. Itoh" )
+ PORT_DIPSETTING( 0x28, "Unknown (1)" )
+ PORT_DIPSETTING( 0xa0, "Unknown (2)" )
+ PORT_DIPSETTING( 0xa8, "Unknown (3)" )
+ PORT_DIPNAME( 0x40, 0x40, "Video Echo" ) PORT_DIPLOCATION("SW2:7") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x100)
+ PORT_DIPSETTING( 0x40, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0x10, 0x10, "Transparent Mode" ) PORT_DIPLOCATION("SW2:8") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x100)
+ PORT_DIPSETTING( 0x10, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0x04, 0x04, DEF_STR(Unused)) PORT_DIPLOCATION("SW2:4") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x100)
+ PORT_DIPSETTING( 0x04, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0x02, 0x00, "MSB Output" ) PORT_DIPLOCATION("SW2:5") PORT_CONDITION("DSW1", 0x100, EQUALS, 0x100)
+ PORT_DIPSETTING( 0x02, "Clear 8th Bit" )
+ PORT_DIPSETTING( 0x00, "Pass 8th Bit" )
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("rs232", rs232_port_device, cts_r) // TBD: implemented on SSI or not?
+
+ PORT_START("DSWX")
+ PORT_DIPNAME( 0x04, 0x04, "Interrupts" ) PORT_DIPLOCATION("SW2:6")
+ PORT_DIPSETTING( 0x04, DEF_STR(Off))
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_DIPNAME( 0x02, 0x00, "DCD Connected" ) PORT_DIPLOCATION("SW1:7")
+ PORT_DIPSETTING( 0x00, DEF_STR(On))
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+INPUT_PORTS_END
+
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
@@ -103,6 +204,11 @@ ioport_constructor a2bus_ssc_device::device_input_ports() const
return INPUT_PORTS_NAME( ssc );
}
+ioport_constructor apricorn_ssi_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( ssi );
+}
+
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
@@ -112,11 +218,11 @@ void a2bus_ssc_device::device_add_mconfig(machine_config &config)
MOS6551(config, m_acia, 0);
m_acia->set_xtal(1.8432_MHz_XTAL);
m_acia->irq_handler().set(FUNC(a2bus_ssc_device::acia_irq_w));
- m_acia->txd_handler().set(SSC_RS232_TAG, FUNC(rs232_port_device::write_txd));
- m_acia->rts_handler().set(SSC_RS232_TAG, FUNC(rs232_port_device::write_rts));
- m_acia->dtr_handler().set(SSC_RS232_TAG, FUNC(rs232_port_device::write_dtr));
+ m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
+ m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts));
+ m_acia->dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr));
- rs232_port_device &rs232(RS232_PORT(config, SSC_RS232_TAG, default_rs232_devices, nullptr));
+ rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr));
rs232.rxd_handler().set(m_acia, FUNC(mos6551_device::write_rxd));
rs232.dcd_handler().set(m_acia, FUNC(mos6551_device::write_dcd));
rs232.dsr_handler().set(m_acia, FUNC(mos6551_device::write_dsr));
@@ -132,6 +238,11 @@ const tiny_rom_entry *a2bus_ssc_device::device_rom_region() const
return ROM_NAME( ssc );
}
+const tiny_rom_entry *apricorn_ssi_device::device_rom_region() const
+{
+ return ROM_NAME( ssi );
+}
+
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
@@ -147,8 +258,14 @@ a2bus_ssc_device::a2bus_ssc_device(const machine_config &mconfig, device_type ty
m_dsw1(*this, "DSW1"),
m_dsw2(*this, "DSW2"),
m_dswx(*this, "DSWX"),
- m_acia(*this, SSC_ACIA_TAG),
- m_rom(*this, SSC_ROM_REGION)
+ m_acia(*this, "acia"),
+ m_rom(*this, "program")
+{
+}
+
+apricorn_ssi_device::apricorn_ssi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ a2bus_ssc_device(mconfig, APRICORN_SSI, tag, owner, clock),
+ m_alt_bank(false)
{
}
@@ -160,6 +277,11 @@ void a2bus_ssc_device::device_start()
{
}
+void apricorn_ssi_device::device_start()
+{
+ save_item(NAME(m_alt_bank));
+}
+
void a2bus_ssc_device::device_reset()
{
}
@@ -173,6 +295,19 @@ uint8_t a2bus_ssc_device::read_cnxx(uint8_t offset)
return m_rom[(offset&0xff)+0x700];
}
+uint8_t apricorn_ssi_device::read_cnxx(uint8_t offset)
+{
+ if (!machine().side_effects_disabled())
+ m_alt_bank = false;
+ return m_rom[offset | (BIT(m_dsw1->read(), 8) ? 0x1700 : 0x0700)];
+}
+
+void apricorn_ssi_device::write_cnxx(uint8_t offset, uint8_t data)
+{
+ // TBD: behavior guessed
+ m_alt_bank = false;
+}
+
/*-------------------------------------------------
read_c800 - called for reads from this card's c800 space
-------------------------------------------------*/
@@ -182,6 +317,15 @@ uint8_t a2bus_ssc_device::read_c800(uint16_t offset)
return m_rom[offset];
}
+uint8_t apricorn_ssi_device::read_c800(uint16_t offset)
+{
+ if (BIT(m_dsw1->read(), 8))
+ offset |= 0x1000;
+ if (m_alt_bank)
+ offset |= 0x800;
+ return m_rom[offset];
+}
+
/*-------------------------------------------------
read_c0nx - called for reads from this card's c0nx space
-------------------------------------------------*/
@@ -213,6 +357,14 @@ void a2bus_ssc_device::write_c0nx(uint8_t offset, uint8_t data)
m_acia->write(offset & 3, data);
}
+void apricorn_ssi_device::write_c0nx(uint8_t offset, uint8_t data)
+{
+ if (BIT(offset, 3))
+ m_acia->write(offset & 3, data);
+ else
+ m_alt_bank = true;
+}
+
WRITE_LINE_MEMBER( a2bus_ssc_device::acia_irq_w )
{
if (machine().ioport().safe_to_read())
diff --git a/src/devices/bus/a2bus/a2ssc.h b/src/devices/bus/a2bus/a2ssc.h
index a7160735852..2e2bc8edc16 100644
--- a/src/devices/bus/a2bus/a2ssc.h
+++ b/src/devices/bus/a2bus/a2ssc.h
@@ -45,13 +45,34 @@ protected:
required_device<mos6551_device> m_acia;
+ required_region_ptr<uint8_t> m_rom;
+
private:
DECLARE_WRITE_LINE_MEMBER( acia_irq_w );
+};
- required_region_ptr<uint8_t> m_rom;
+class apricorn_ssi_device : public a2bus_ssc_device
+{
+public:
+ // construction/destruction
+ apricorn_ssi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_start() override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual void write_c0nx(uint8_t offset, uint8_t data) override;
+ virtual uint8_t read_cnxx(uint8_t offset) override;
+ virtual void write_cnxx(uint8_t offset, uint8_t data) override;
+ virtual uint8_t read_c800(uint16_t offset) override;
+
+private:
+ bool m_alt_bank;
};
-// device type definition
+// device type declarations
DECLARE_DEVICE_TYPE(A2BUS_SSC, a2bus_ssc_device)
+DECLARE_DEVICE_TYPE(APRICORN_SSI, apricorn_ssi_device)
#endif // MAME_BUS_A2BUS_A2SSC_H
diff --git a/src/mame/drivers/apple2.cpp b/src/mame/drivers/apple2.cpp
index 0a18f7ca088..b8da52f9ae7 100644
--- a/src/mame/drivers/apple2.cpp
+++ b/src/mame/drivers/apple2.cpp
@@ -1291,6 +1291,7 @@ static void apple2_cards(device_slot_interface &device)
device.option_add("softcard", A2BUS_SOFTCARD); /* Microsoft SoftCard */
device.option_add("videoterm", A2BUS_VIDEOTERM); /* Videx VideoTerm */
device.option_add("ssc", A2BUS_SSC); /* Apple Super Serial Card */
+ device.option_add("ssi", APRICORN_SSI); /* Apricorn Super Serial Imager */
device.option_add("swyft", A2BUS_SWYFT); /* IAI SwyftCard */
device.option_add("themill", A2BUS_THEMILL); /* Stellation Two The Mill (6809 card) */
device.option_add("sam", A2BUS_SAM); /* SAM Software Automated Mouth (8-bit DAC + speaker) */
diff --git a/src/mame/drivers/apple2e.cpp b/src/mame/drivers/apple2e.cpp
index 49cb03a14af..de4fef315f9 100644
--- a/src/mame/drivers/apple2e.cpp
+++ b/src/mame/drivers/apple2e.cpp
@@ -4516,6 +4516,7 @@ static void apple2_cards(device_slot_interface &device)
device.option_add("softcard", A2BUS_SOFTCARD); /* Microsoft SoftCard */
device.option_add("videoterm", A2BUS_VIDEOTERM); /* Videx VideoTerm */
device.option_add("ssc", A2BUS_SSC); /* Apple Super Serial Card */
+ device.option_add("ssi", APRICORN_SSI); /* Apricorn Super Serial Imager */
device.option_add("swyft", A2BUS_SWYFT); /* IAI SwyftCard */
device.option_add("themill", A2BUS_THEMILL); /* Stellation Two The Mill (6809 card) */
device.option_add("sam", A2BUS_SAM); /* SAM Software Automated Mouth (8-bit DAC + speaker) */
diff --git a/src/mame/drivers/apple2gs.cpp b/src/mame/drivers/apple2gs.cpp
index 8315e931335..ad9e96a1605 100644
--- a/src/mame/drivers/apple2gs.cpp
+++ b/src/mame/drivers/apple2gs.cpp
@@ -4721,6 +4721,7 @@ static void apple2_cards(device_slot_interface &device)
device.option_add("softcard", A2BUS_SOFTCARD); /* Microsoft SoftCard */
device.option_add("videoterm", A2BUS_VIDEOTERM); /* Videx VideoTerm */
device.option_add("ssc", A2BUS_SSC); /* Apple Super Serial Card */
+ device.option_add("ssi", APRICORN_SSI); /* Apricorn Super Serial Imager */
device.option_add("swyft", A2BUS_SWYFT); /* IAI SwyftCard */
device.option_add("themill", A2BUS_THEMILL); /* Stellation Two The Mill (6809 card) */
device.option_add("sam", A2BUS_SAM); /* SAM Software Automated Mouth (8-bit DAC + speaker) */