Skip to content
Permalink
Browse files

lx810l: add screen simulating paper output

  • Loading branch information...
ramiropolla committed Sep 19, 2015
1 parent 15c5d9e commit 9c518d44bc2099cfa82a63a10ee3e43f1645a216
Showing with 61 additions and 9 deletions.
  1. +44 −9 src/devices/bus/centronics/epson_lx810l.c
  2. +17 −0 src/devices/bus/centronics/epson_lx810l.h
@@ -12,9 +12,7 @@
* uPC494C (pulse width modulation control)
*
* Devices boot and enter main input loop. Data is received through the
* centronics bus and printed as expected. The actual paper output is
* still not implemented, though. Look at the output from the fire signal
* (epson_lx810l_t::co0_w()) to see what's actually being printed.
* centronics bus and printed as expected in a separate screen.
*
* It is possible to run the printers' self test with this procedure:
* - Turn on device;
@@ -26,8 +24,7 @@
*
* The printer's carriage will seek home, it will pull in paper for a while,
* and it will start printing some test data. The Online LED will blink at
* each line. Look at the output from the fire signal to see what's actually
* being printed (epson_lx810l_t::co0_w()).
* each line.
*/

#include "epson_lx810l.h"
@@ -139,6 +136,14 @@ static MACHINE_CONFIG_FRAGMENT( epson_lx810l )

MCFG_DEFAULT_LAYOUT(layout_lx800)

/* video hardware (simulates paper) */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
MCFG_SCREEN_SIZE(PAPER_WIDTH, PAPER_HEIGHT)
MCFG_SCREEN_VISIBLE_AREA(0, PAPER_WIDTH-1, 0, PAPER_HEIGHT-1)
MCFG_SCREEN_UPDATE_DRIVER(epson_lx810l_t, screen_update_lx810l)

/* audio hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_DAC_ADD("dac")
@@ -291,6 +296,7 @@ epson_lx810l_t::epson_lx810l_t(const machine_config &mconfig, const char *tag, d
m_eeprom(*this, "eeprom"),
m_dac(*this, "dac"),
m_e05a30(*this, "e05a30"),
m_screen(*this, "screen"),
m_93c06_clk(0),
m_93c06_cs(0),
m_printhead(0),
@@ -311,6 +317,7 @@ epson_lx810l_t::epson_lx810l_t(const machine_config &mconfig, device_type type,
m_eeprom(*this, "eeprom"),
m_dac(*this, "dac"),
m_e05a30(*this, "e05a30"),
m_screen(*this, "screen"),
m_93c06_clk(0),
m_93c06_cs(0),
m_printhead(0),
@@ -336,6 +343,8 @@ epson_ap2000_t::epson_ap2000_t(const machine_config &mconfig, const char *tag, d

void epson_lx810l_t::device_start()
{
machine().first_screen()->register_screen_bitmap(m_bitmap);
m_bitmap.fill(0xffffff); /* Start with a clean white piece of paper */
}


@@ -510,9 +519,15 @@ WRITE16_MEMBER( epson_lx810l_t::printhead )

WRITE8_MEMBER( epson_lx810l_t::pf_stepper )
{
m_pf_stepper->update(data);
int changed = m_pf_stepper->update(data);
m_pf_pos_abs = -m_pf_stepper->get_absolute_position();

/* clear last line of paper */
if (changed > 0) {
void *line = m_bitmap.raw_pixptr(bitmap_line(9), 0);
memset(line, 0xff, m_bitmap.width() * 4);
}

LX810LLOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_pf_pos_abs);
}

@@ -544,14 +559,28 @@ WRITE_LINE_MEMBER( epson_lx810l_t::e05a30_ready )
}


/***************************************************************************
Video hardware (simulates paper)
***************************************************************************/

UINT32 epson_lx810l_t::screen_update_lx810l(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int scrolly = -bitmap_line(9);
copyscrollbitmap(bitmap, m_bitmap, 0, NULL, 1, &scrolly, cliprect);

/* draw "printhead" */
bitmap.plot_box(m_real_cr_pos + CR_OFFSET - 10, PAPER_HEIGHT - 36, 20, 36, 0x888888);

return 0;
}


/***************************************************************************
Extended Timer Output
***************************************************************************/

WRITE_LINE_MEMBER( epson_lx810l_t::co0_w )
{
/* TODO Draw the dots on the paper using this information. */

/* Printhead is being fired on !state. */
if (!state) {
/* The firmware expects a 300 microseconds delay between the fire
@@ -565,7 +594,13 @@ WRITE_LINE_MEMBER( epson_lx810l_t::co0_w )
* lines which are being printed in different directions is
* noticeably off in the 20+ years old printer used for testing =).
*/
LX810LLOG("FIRE0 %d %d %04x\n", m_pf_pos_abs, m_real_cr_pos, m_printhead);
if (m_real_cr_pos < m_bitmap.width()) {
for (int i = 0; i < 9; i++) {
unsigned int y = bitmap_line(i);
if ((m_printhead & (1<<(8-i))) != 0)
m_bitmap.pix32(y, m_real_cr_pos + CR_OFFSET) = 0x000000;
}
}
}
}

@@ -19,6 +19,16 @@
#include "sound/dac.h"


/* The printer starts printing at x offset 44 and stops printing at x
* offset 1009, giving a total of 965 printable pixels. Supposedly, the
* border at the far right would be at x offset 1053. I've chosen the
* width for the paper as 1024, since it's a nicer number than 1053, so
* an offset must be used to centralize the pixels.
*/
#define CR_OFFSET (-14)
#define PAPER_WIDTH 1024
#define PAPER_HEIGHT 576

//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -91,6 +101,11 @@ class epson_lx810l_t : public device_t,
/* Panel buttons */
DECLARE_INPUT_CHANGED_MEMBER(online_sw);

/* Video hardware (simulates paper) */
UINT32 screen_update_lx810l(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
#define uabs(x) ((x) > 0 ? (x) : -(x))
unsigned int bitmap_line(int i) { return ((uabs(m_pf_pos_abs) / 6) + i) % m_bitmap.height(); }

protected:
// device-level overrides
virtual void device_start();
@@ -104,6 +119,7 @@ class epson_lx810l_t : public device_t,
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<dac_device> m_dac;
required_device<e05a30_device> m_e05a30;
required_device<screen_device> m_screen;

int m_93c06_clk;
int m_93c06_cs;
@@ -114,6 +130,7 @@ class epson_lx810l_t : public device_t,
int m_real_cr_steps;
int m_real_cr_dir; /* 1 is going right, -1 is going left */
UINT8 m_fakemem;
bitmap_rgb32 m_bitmap;

enum {
TIMER_CR

0 comments on commit 9c518d4

Please sign in to comment.
You can’t perform that action at this time.