summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/centronics/epson_ex800.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/centronics/epson_ex800.c')
-rw-r--r--src/devices/bus/centronics/epson_ex800.c496
1 files changed, 496 insertions, 0 deletions
diff --git a/src/devices/bus/centronics/epson_ex800.c b/src/devices/bus/centronics/epson_ex800.c
new file mode 100644
index 00000000000..9555284c711
--- /dev/null
+++ b/src/devices/bus/centronics/epson_ex800.c
@@ -0,0 +1,496 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/******************************************************************************
+
+ Epson EX-800 Dot Matrix printer
+
+
+ --
+
+ Main CPU is a UPD7810H6 running at 12 MHz.
+
+ --
+
+ On startup, the ports are initialized as follows:
+
+ Port A lines PA0-PA7 are configured as output
+ Port B lines PB0-PB7 are configured as output
+ Port C lines PC2, PC4 and PC5 are configured as output
+ the other lines are control lines
+ PC0: TxD output
+ PC1: RxD input
+ PC3: TI input
+ PC6: CO0 output
+ PC7: CO1 output
+
+The I/O lines are connected as follows:
+
+PA0: \
+PA1: Carriage motor
+PA2: driving pulses
+PA3: /
+PA4: High when carriage assembly reaches either end
+PA5: High when carriage assembly reaches either end
+PA6: Bank 0
+PA7: Bank 1
+
+PB0: Line feed motor driving pulses
+PB1: Line feed motor driving pulses
+PB2: Line feed motor current control
+PB3: LED09, Online
+PB4: (used for serial port)
+PB5: ERR signal
+PB6: ACKNLG signal, data received at printer
+PB7: LED12, Paper empty
+
+PC0: TxD output
+PC1: RxD input
+PC2:
+PC3: TI input
+PC4:
+PC5:
+PC6: PWD signal of 5a
+PC7: Buzzer
+
+PD0-7: Data bus D0-D7
+
+PF0-7: Address bus A8-A15
+
+AN0: DSW 2
+AN1: DSW 1
+AN2:
+AN3:
+AN4: Print head operating temperature sensor
+AN5: Scanner Unit, Color Home sensor
+AN6:
+AN7: Color Home sensor adjust
+
+INT: Online switch
+
+
+Gate array 5a (parallel port, printer head)
+
+IN0-IN7: DATA1 to DATA8 from parallel port
+HD1-HD9: Head driving pulses
+STROBE: STROBE signal
+PWD: PC6 of CPU
+ALE: ALE of CPU
+
+Gate array 7a (inputs)
+
+- activated when carriage assembly reaches either end?
+
+PA0: Draft switch
+PA1: NLQ Roman switch
+PA2: Pica switch
+PA3: NLQ sans-serif switch
+PA4: Elite switch
+PA5: Proportional switch
+PA6: Normal switch
+PA7: Condensed switch
+
+PB0: Form feed switch
+PB1: Line feed switch
+PB2: Autoload switch
+PB3: Low when paper empty
+PB4: Low when carriage assembly is in home position
+PB5: SLCTIN (connected to parallel port), disable with DSW2-1
+PB6: AUTO FEEDXT (connected to parallel port), disable with DSW2-4
+ "When this signal is LOW, the paper is automatically fed 1 line after
+ printing."
+PB7:
+
+PC0: Dipswitch SW1-1 and SW1-2, Draft LED
+PC1: Dipswitch SW1-3 and SW1-4, Roman LED
+PC2: Dipswitch SW1-5 and SW1-6, Pica LED
+PC3: Dipswitch SW1-7 and SW1-8, Sans-Serif LED
+PC4: Dipswitch SW2-2 and SW2-3, Elite LED
+PC5: Dipswitch SW2-5 and SW2-6, Proportional LED
+PC6: Normal LED
+PC7: Condensed LED
+
+--
+
+LED state on startup:
+
+The power light comes on, then draft, pica and normal. If there is no paper,
+the paper empty LED comes on.
+
+Power LED is green, selectype LED is orange, paper out LED is red.
+
+--
+
+TODO: - The UPD7810 core is missing analog port emulation
+ - Figure out the gate arrays (using trojan code?)
+ - (much later) write an interface so that other drivers can hook
+ into this one and use to print
+
+******************************************************************************/
+
+#include "epson_ex800.h"
+#include "ex800.lh"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define PA0 (data & 0x01)
+#define PA1 (data & 0x02)
+#define PA2 (data & 0x04)
+#define PA3 (data & 0x08)
+#define PA4 (data & 0x10)
+#define PA5 (data & 0x20)
+#define PA6 (data & 0x40)
+#define PA7 (data & 0x80)
+
+#define PB0 (data & 0x01)
+#define PB1 (data & 0x02)
+#define PB2 (data & 0x04)
+#define PB3 (data & 0x08)
+#define PB4 (data & 0x10)
+#define PB5 (data & 0x20)
+#define PB6 (data & 0x40)
+#define PB7 (data & 0x80)
+
+#define PC0 (data & 0x01)
+#define PC1 (data & 0x02)
+#define PC2 (data & 0x04)
+#define PC3 (data & 0x08)
+#define PC4 (data & 0x10)
+#define PC5 (data & 0x20)
+#define PC6 (data & 0x40)
+#define PC7 (data & 0x80)
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type EPSON_EX800 = &device_creator<epson_ex800_t>;
+
+
+//-------------------------------------------------
+// ROM( ex800 )
+//-------------------------------------------------
+
+ROM_START( ex800 )
+ ROM_REGION(0x8000, "maincpu", 0)
+ ROM_LOAD("w8_pe9.9b", 0x0000, 0x8000, CRC(6dd41e9b) SHA1(8e30ead727b9317154742efd881206e9f9bbf95b))
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *epson_ex800_t::device_rom_region() const
+{
+ return ROM_NAME( ex800 );
+}
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( ex800_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( ex800_mem, AS_PROGRAM, 8, epson_ex800_t )
+ AM_RANGE(0x0000, 0x7fff) AM_ROM AM_REGION("maincpu", 0)
+ AM_RANGE(0x8000, 0xbfff) AM_RAM /* external RAM */
+ AM_RANGE(0xc000, 0xc7ff) AM_MIRROR(0x1800) AM_READWRITE(devsel_r, devsel_w)
+ AM_RANGE(0xe000, 0xe7ff) AM_READWRITE(gate5a_r, gate5a_w)
+ AM_RANGE(0xe800, 0xefff) AM_READWRITE(iosel_r, iosel_w)
+ AM_RANGE(0xf000, 0xf001) AM_MIRROR(0x07fc) AM_READ(gate7a_r)
+ AM_RANGE(0xf002, 0xf003) AM_MIRROR(0x07fc) AM_WRITE(gate7a_w)
+ AM_RANGE(0xf800, 0xfeff) AM_NOP /* not connected */
+ AM_RANGE(0xff00, 0xffff) AM_RAM /* internal CPU RAM */
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( ex800_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( ex800_io, AS_IO, 8, epson_ex800_t )
+ AM_RANGE(UPD7810_PORTA, UPD7810_PORTA) AM_READ(porta_r) AM_WRITE(porta_w)
+ AM_RANGE(UPD7810_PORTB, UPD7810_PORTB) AM_READ(portb_r) AM_WRITE(portb_w)
+ AM_RANGE(UPD7810_PORTC, UPD7810_PORTC) AM_READ(portc_r) AM_WRITE(portc_w)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// MACHINE_DRIVER( epson_ex800 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( epson_ex800 )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", UPD7810, 12000000) /* 12 MHz? */
+ MCFG_CPU_PROGRAM_MAP(ex800_mem)
+ MCFG_CPU_IO_MAP(ex800_io)
+
+
+ MCFG_DEFAULT_LAYOUT(layout_ex800)
+
+ /* audio hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("beeper", BEEP, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor epson_ex800_t::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( epson_ex800 );
+}
+
+
+/* The ON LINE switch is directly connected to the INT1 input of the CPU */
+INPUT_CHANGED_MEMBER(epson_ex800_t::online_switch)
+{
+ if (newval)
+ {
+ m_maincpu->set_input_line(UPD7810_INTF1, m_irq_state);
+ m_irq_state = (m_irq_state == ASSERT_LINE) ? CLEAR_LINE : ASSERT_LINE;
+ }
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( epson_ex800 )
+//-------------------------------------------------
+
+INPUT_PORTS_START( epson_ex800 )
+ PORT_START("ONLISW")
+ PORT_BIT(0xfe, IP_ACTIVE_HIGH, IPT_UNUSED)
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ON LINE") PORT_CODE(KEYCODE_F9) PORT_CHANGED_MEMBER(DEVICE_SELF, epson_ex800_t, online_switch, NULL)
+
+ PORT_START("FEED")
+ PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_UNUSED)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("FORM FEED") PORT_CODE(KEYCODE_F10)
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINE FEED") PORT_CODE(KEYCODE_F11)
+
+ PORT_START("SelecType")
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Draft") PORT_CODE(KEYCODE_F8)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NLQ Roman") PORT_CODE(KEYCODE_F7)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Pica") PORT_CODE(KEYCODE_F6)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("NLQ Sans Serif") PORT_CODE(KEYCODE_F5)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Elite") PORT_CODE(KEYCODE_F4)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Proportional") PORT_CODE(KEYCODE_F3)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(DEF_STR(Normal)) PORT_CODE(KEYCODE_F2)
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Condensed") PORT_CODE(KEYCODE_F1)
+
+ PORT_START("DSW_1")
+ PORT_DIPNAME(0x01, 0x00, "Condensed characters")
+ PORT_DIPSETTING( 0x00, DEF_STR(Off))
+ PORT_DIPSETTING( 0x01, DEF_STR(On))
+ PORT_DIPNAME(0x02, 0x00, "Slashed zero")
+ PORT_DIPSETTING( 0x00, DEF_STR(Off))
+ PORT_DIPSETTING( 0x02, DEF_STR(On))
+ PORT_DIPNAME(0x04, 0x00, "Character table")
+ PORT_DIPSETTING( 0x00, "Italics")
+ PORT_DIPSETTING( 0x04, "Graphics")
+ PORT_DIPNAME(0x08, 0x00, "Printer commands")
+ PORT_DIPSETTING( 0x00, "ESC/P")
+ PORT_DIPSETTING( 0x08, "IBM printer emulation")
+ PORT_DIPNAME(0x10, 0x00, "Print quality")
+ PORT_DIPSETTING( 0x00, "Draft")
+ PORT_DIPSETTING( 0x10, "NLQ")
+ PORT_DIPNAME(0xe0, 0x00, "Int. character set")
+ PORT_DIPSETTING( 0x00, DEF_STR(USA))
+ PORT_DIPSETTING( 0x20, DEF_STR(French))
+ PORT_DIPSETTING( 0x30, DEF_STR(German))
+ PORT_DIPSETTING( 0x40, "UK")
+ PORT_DIPSETTING( 0x50, "Danish")
+ PORT_DIPSETTING( 0x60, "Swedish")
+ PORT_DIPSETTING( 0x70, DEF_STR(Italian))
+ PORT_DIPSETTING( 0x80, DEF_STR(Spanish))
+
+ PORT_START("DSW_2")
+ PORT_DIPNAME(0x01, 0x00, "Page length")
+ PORT_DIPSETTING( 0x00, "11 inch")
+ PORT_DIPSETTING( 0x01, "12 inch")
+ PORT_DIPNAME(0x02, 0x00, "Auto. sheet feeder")
+ PORT_DIPSETTING( 0x00, "Canceled")
+ PORT_DIPSETTING( 0x02, "Selected")
+ PORT_DIPNAME(0x04, 0x00, "Skip-over-perforation")
+ PORT_DIPSETTING( 0x00, DEF_STR(None))
+ PORT_DIPSETTING( 0x04, "1 inch")
+ PORT_DIPNAME(0x08, 0x00, "Add LF after CR")
+ PORT_DIPSETTING( 0x00, "CR only")
+ PORT_DIPSETTING( 0x08, "CR + LF")
+ PORT_DIPNAME(0x30, 0x00, "Interface type")
+ PORT_DIPSETTING( 0x00, "Parallel")
+ PORT_DIPSETTING( 0x10, "Serial (odd parity)")
+ PORT_DIPSETTING( 0x20, "Serial (even parity)")
+ PORT_DIPSETTING( 0x30, "Serial (no parity)")
+ PORT_DIPNAME(0xc0, 0x00, "Baud rate")
+ PORT_DIPSETTING( 0x00, "9600")
+ PORT_DIPSETTING( 0x40, "4800")
+ PORT_DIPSETTING( 0x80, "1200")
+ PORT_DIPSETTING( 0xc0, "300")
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor epson_ex800_t::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( epson_ex800 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// epson_ex800_t - constructor
+//-------------------------------------------------
+
+epson_ex800_t::epson_ex800_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, EPSON_EX800, "Epson EX-800", tag, owner, clock, "ex800", __FILE__),
+ device_centronics_peripheral_interface(mconfig, *this),
+ m_maincpu(*this, "maincpu"),
+ m_beeper(*this, "beeper")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void epson_ex800_t::device_start()
+{
+ m_irq_state = ASSERT_LINE;
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void epson_ex800_t::device_reset()
+{
+ /* Setup beep */
+ m_beeper->set_state(0);
+ m_beeper->set_frequency(4000); /* measured at 4000 Hz */
+}
+
+
+READ8_MEMBER(epson_ex800_t::porta_r)
+{
+ logerror("PA R @%x\n", space.device().safe_pc());
+ return machine().rand();
+}
+
+READ8_MEMBER(epson_ex800_t::portb_r)
+{
+ logerror("PB R @%x\n", space.device().safe_pc());
+ return machine().rand();
+}
+
+READ8_MEMBER(epson_ex800_t::portc_r)
+{
+ logerror("PC R @%x\n", space.device().safe_pc());
+ return machine().rand();
+}
+
+WRITE8_MEMBER(epson_ex800_t::porta_w)
+{
+ if (PA6) logerror("BNK0 selected.\n");
+ if (PA7) logerror("BNK1 selected.\n");
+
+ logerror("PA W %x @%x\n", data, space.device().safe_pc());
+}
+
+WRITE8_MEMBER(epson_ex800_t::portb_w)
+{
+ if (data & 3)
+ logerror("PB0/1 Line feed @%x\n", space.device().safe_pc());
+ if (!(data & 4))
+ logerror("PB2 Line feed @%x\n", space.device().safe_pc());
+ if (data & 8)
+ logerror("PB3 Online LED on @%x\n", space.device().safe_pc());
+ else
+ logerror("PB3 Online LED off @%x\n", space.device().safe_pc());
+ if (data & 16)
+ logerror("PB4 Serial @%x\n", space.device().safe_pc());
+ if (data & 32)
+ logerror("PB4 Serial @%x\n", space.device().safe_pc());
+ if (data & 64)
+ logerror("PB4 Serial @%x\n", space.device().safe_pc());
+ if (data & 128)
+ logerror("PB3 Paper empty LED on @%x\n", space.device().safe_pc());
+ else
+ logerror("PB3 Paper empty LED off @%x\n", space.device().safe_pc());
+
+// logerror("PB W %x @%x\n", data, space.device().safe_pc());
+}
+
+WRITE8_MEMBER(epson_ex800_t::portc_w)
+{
+ if (data & 0x80)
+ m_beeper->set_state(0);
+ else
+ m_beeper->set_state(1);
+
+ logerror("PC W %x @%x\n", data, space.device().safe_pc());
+}
+
+
+/* Memory mapped I/O access */
+
+READ8_MEMBER(epson_ex800_t::devsel_r)
+{
+ logerror("DEVSEL R @%x with offset %x\n", space.device().safe_pc(), offset);
+ return machine().rand();
+}
+
+WRITE8_MEMBER(epson_ex800_t::devsel_w)
+{
+ logerror("DEVSEL W %x @%x with offset %x\n", data, space.device().safe_pc(), offset);
+}
+
+READ8_MEMBER(epson_ex800_t::gate5a_r)
+{
+ logerror("GATE5A R @%x with offset %x\n", space.device().safe_pc(), offset);
+ return machine().rand();
+}
+
+WRITE8_MEMBER(epson_ex800_t::gate5a_w)
+{
+ logerror("GATE5A W %x @%x with offset %x\n", data, space.device().safe_pc(), offset);
+}
+
+READ8_MEMBER(epson_ex800_t::iosel_r)
+{
+ logerror("IOSEL R @%x with offset %x\n", space.device().safe_pc(), offset);
+ return machine().rand();
+}
+
+WRITE8_MEMBER(epson_ex800_t::iosel_w)
+{
+ logerror("IOSEL W %x @%x with offset %x\n", data, space.device().safe_pc(), offset);
+}
+
+READ8_MEMBER(epson_ex800_t::gate7a_r)
+{
+ logerror("GATE7A R @%x with offset %x\n", space.device().safe_pc(), offset);
+ return machine().rand();
+}
+
+WRITE8_MEMBER(epson_ex800_t::gate7a_w)
+{
+ logerror("GATE7A W %x @%x with offset %x\n", data, space.device().safe_pc(), offset);
+}