diff options
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 |
commit | 8fa9e7d9419bde7f958fcf5b8aabbd9493f229d6 (patch) | |
tree | 463a6f8dda6f04ad1755a3f4413dba38ce6a41f0 | |
parent | 914d50d78f5041bea136aa269b240559e2a13fe9 (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.cpp | 176 | ||||
-rw-r--r-- | src/devices/bus/a2bus/a2ssc.h | 25 | ||||
-rw-r--r-- | src/mame/drivers/apple2.cpp | 1 | ||||
-rw-r--r-- | src/mame/drivers/apple2e.cpp | 1 | ||||
-rw-r--r-- | src/mame/drivers/apple2gs.cpp | 1 |
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) */ |