mirror of
https://github.com/holub/mame
synced 2025-07-05 01:48:29 +03:00
Merge pull request #335 from ramiropolla/lx810l
lx810l: add screen simulating paper output
This commit is contained in:
commit
12a6bc6aa6
@ -2,7 +2,7 @@
|
|||||||
// copyright-holders:Ramiro Polla, Felipe Sanches
|
// copyright-holders:Ramiro Polla, Felipe Sanches
|
||||||
/*
|
/*
|
||||||
* Epson LX-810L dot matrix printer emulation
|
* Epson LX-810L dot matrix printer emulation
|
||||||
|
*
|
||||||
* IC list:
|
* IC list:
|
||||||
* uPD7810HG (cpu)
|
* uPD7810HG (cpu)
|
||||||
* E05A30 (gate array)
|
* E05A30 (gate array)
|
||||||
@ -12,9 +12,7 @@
|
|||||||
* uPC494C (pulse width modulation control)
|
* uPC494C (pulse width modulation control)
|
||||||
*
|
*
|
||||||
* Devices boot and enter main input loop. Data is received through the
|
* Devices boot and enter main input loop. Data is received through the
|
||||||
* centronics bus and printed as expected. The actual paper output is
|
* centronics bus and printed as expected in a separate screen.
|
||||||
* still not implemented, though. Look at the output from the fire signal
|
|
||||||
* (epson_lx810l_t::co0_w()) to see what's actually being printed.
|
|
||||||
*
|
*
|
||||||
* It is possible to run the printers' self test with this procedure:
|
* It is possible to run the printers' self test with this procedure:
|
||||||
* - Turn on device;
|
* - Turn on device;
|
||||||
@ -22,12 +20,9 @@
|
|||||||
* - Reset device;
|
* - Reset device;
|
||||||
* - Toggle Line Feed button again;
|
* - Toggle Line Feed button again;
|
||||||
* - Press Online button (press 'O');
|
* - Press Online button (press 'O');
|
||||||
* - Press Online button again;
|
|
||||||
*
|
*
|
||||||
* The printer's carriage will seek home, it will pull in paper for a while,
|
* The printer's carriage will seek home and it will start printing
|
||||||
* and it will start printing some test data. The Online LED will blink at
|
* some test data. The Online LED will blink at each line.
|
||||||
* each line. Look at the output from the fire signal to see what's actually
|
|
||||||
* being printed (epson_lx810l_t::co0_w()).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "epson_lx810l.h"
|
#include "epson_lx810l.h"
|
||||||
@ -139,9 +134,17 @@ static MACHINE_CONFIG_FRAGMENT( epson_lx810l )
|
|||||||
|
|
||||||
MCFG_DEFAULT_LAYOUT(layout_lx800)
|
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 */
|
/* audio hardware */
|
||||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||||
MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
|
MCFG_DAC_ADD("dac")
|
||||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||||
|
|
||||||
/* gate array */
|
/* gate array */
|
||||||
@ -160,19 +163,12 @@ static MACHINE_CONFIG_FRAGMENT( epson_lx810l )
|
|||||||
MCFG_EEPROM_SERIAL_93C06_ADD("eeprom")
|
MCFG_EEPROM_SERIAL_93C06_ADD("eeprom")
|
||||||
|
|
||||||
/* steppers */
|
/* steppers */
|
||||||
//should this have MCFG_STEPPER_MAX_STEPS(200*2) ? code shows 200 steps...
|
|
||||||
MCFG_STEPPER_ADD("pf_stepper")
|
MCFG_STEPPER_ADD("pf_stepper")
|
||||||
MCFG_STEPPER_REEL_TYPE(NOT_A_REEL)
|
MCFG_STEPPER_REEL_TYPE(NOT_A_REEL)
|
||||||
MCFG_STEPPER_START_INDEX(16)
|
MCFG_STEPPER_INIT_PHASE(4)
|
||||||
MCFG_STEPPER_END_INDEX(24)
|
|
||||||
MCFG_STEPPER_INDEX_PATTERN(0x00)
|
|
||||||
MCFG_STEPPER_INIT_PHASE(0)
|
|
||||||
|
|
||||||
MCFG_STEPPER_ADD("cr_stepper")
|
MCFG_STEPPER_ADD("cr_stepper")
|
||||||
MCFG_STEPPER_REEL_TYPE(NOT_A_REEL)
|
MCFG_STEPPER_REEL_TYPE(NOT_A_REEL)
|
||||||
MCFG_STEPPER_START_INDEX(16)
|
|
||||||
MCFG_STEPPER_END_INDEX(24)
|
|
||||||
MCFG_STEPPER_INDEX_PATTERN(0x00)
|
|
||||||
MCFG_STEPPER_INIT_PHASE(2)
|
MCFG_STEPPER_INIT_PHASE(2)
|
||||||
|
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
@ -296,14 +292,15 @@ epson_lx810l_t::epson_lx810l_t(const machine_config &mconfig, const char *tag, d
|
|||||||
m_pf_stepper(*this, "pf_stepper"),
|
m_pf_stepper(*this, "pf_stepper"),
|
||||||
m_cr_stepper(*this, "cr_stepper"),
|
m_cr_stepper(*this, "cr_stepper"),
|
||||||
m_eeprom(*this, "eeprom"),
|
m_eeprom(*this, "eeprom"),
|
||||||
m_speaker(*this, "speaker"),
|
m_dac(*this, "dac"),
|
||||||
m_e05a30(*this, "e05a30"),
|
m_e05a30(*this, "e05a30"),
|
||||||
|
m_screen(*this, "screen"),
|
||||||
m_93c06_clk(0),
|
m_93c06_clk(0),
|
||||||
m_93c06_cs(0),
|
m_93c06_cs(0),
|
||||||
m_printhead(0),
|
m_printhead(0),
|
||||||
m_pf_pos_abs(200),
|
m_pf_pos_abs(1),
|
||||||
m_cr_pos_abs(200),
|
m_cr_pos_abs(1),
|
||||||
m_real_cr_pos(200),
|
m_real_cr_pos(1),
|
||||||
m_real_cr_steps(0),
|
m_real_cr_steps(0),
|
||||||
m_real_cr_dir(0)
|
m_real_cr_dir(0)
|
||||||
{
|
{
|
||||||
@ -316,14 +313,15 @@ epson_lx810l_t::epson_lx810l_t(const machine_config &mconfig, device_type type,
|
|||||||
m_pf_stepper(*this, "pf_stepper"),
|
m_pf_stepper(*this, "pf_stepper"),
|
||||||
m_cr_stepper(*this, "cr_stepper"),
|
m_cr_stepper(*this, "cr_stepper"),
|
||||||
m_eeprom(*this, "eeprom"),
|
m_eeprom(*this, "eeprom"),
|
||||||
m_speaker(*this, "speaker"),
|
m_dac(*this, "dac"),
|
||||||
m_e05a30(*this, "e05a30"),
|
m_e05a30(*this, "e05a30"),
|
||||||
|
m_screen(*this, "screen"),
|
||||||
m_93c06_clk(0),
|
m_93c06_clk(0),
|
||||||
m_93c06_cs(0),
|
m_93c06_cs(0),
|
||||||
m_printhead(0),
|
m_printhead(0),
|
||||||
m_pf_pos_abs(200),
|
m_pf_pos_abs(1),
|
||||||
m_cr_pos_abs(200),
|
m_cr_pos_abs(1),
|
||||||
m_real_cr_pos(200),
|
m_real_cr_pos(1),
|
||||||
m_real_cr_steps(0),
|
m_real_cr_steps(0),
|
||||||
m_real_cr_dir(0)
|
m_real_cr_dir(0)
|
||||||
{
|
{
|
||||||
@ -343,6 +341,8 @@ epson_ap2000_t::epson_ap2000_t(const machine_config &mconfig, const char *tag, d
|
|||||||
|
|
||||||
void epson_lx810l_t::device_start()
|
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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -352,7 +352,7 @@ void epson_lx810l_t::device_start()
|
|||||||
|
|
||||||
void epson_lx810l_t::device_reset()
|
void epson_lx810l_t::device_reset()
|
||||||
{
|
{
|
||||||
m_speaker->level_w(0);
|
m_dac->write_unsigned8(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -517,8 +517,14 @@ WRITE16_MEMBER( epson_lx810l_t::printhead )
|
|||||||
|
|
||||||
WRITE8_MEMBER( epson_lx810l_t::pf_stepper )
|
WRITE8_MEMBER( epson_lx810l_t::pf_stepper )
|
||||||
{
|
{
|
||||||
m_pf_stepper->update(data);
|
int changed = m_pf_stepper->update(data);
|
||||||
m_pf_pos_abs = 200 - m_pf_stepper->get_absolute_position();
|
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);
|
LX810LLOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_pf_pos_abs);
|
||||||
}
|
}
|
||||||
@ -528,7 +534,7 @@ WRITE8_MEMBER( epson_lx810l_t::cr_stepper )
|
|||||||
int m_cr_pos_abs_prev = m_cr_pos_abs;
|
int m_cr_pos_abs_prev = m_cr_pos_abs;
|
||||||
|
|
||||||
m_cr_stepper->update(data);
|
m_cr_stepper->update(data);
|
||||||
m_cr_pos_abs = 200 - m_cr_stepper->get_absolute_position();
|
m_cr_pos_abs = -m_cr_stepper->get_absolute_position();
|
||||||
|
|
||||||
if (m_cr_pos_abs > m_cr_pos_abs_prev) {
|
if (m_cr_pos_abs > m_cr_pos_abs_prev) {
|
||||||
/* going right */
|
/* going right */
|
||||||
@ -551,14 +557,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
|
Extended Timer Output
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( epson_lx810l_t::co0_w )
|
WRITE_LINE_MEMBER( epson_lx810l_t::co0_w )
|
||||||
{
|
{
|
||||||
/* TODO Draw the dots on the paper using this information. */
|
|
||||||
|
|
||||||
/* Printhead is being fired on !state. */
|
/* Printhead is being fired on !state. */
|
||||||
if (!state) {
|
if (!state) {
|
||||||
/* The firmware expects a 300 microseconds delay between the fire
|
/* The firmware expects a 300 microseconds delay between the fire
|
||||||
@ -572,13 +592,19 @@ WRITE_LINE_MEMBER( epson_lx810l_t::co0_w )
|
|||||||
* lines which are being printed in different directions is
|
* lines which are being printed in different directions is
|
||||||
* noticeably off in the 20+ years old printer used for testing =).
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( epson_lx810l_t::co1_w )
|
WRITE_LINE_MEMBER( epson_lx810l_t::co1_w )
|
||||||
{
|
{
|
||||||
m_speaker->level_w(state);
|
m_dac->write_unsigned8(0 - !state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,9 +16,19 @@
|
|||||||
#include "machine/e05a30.h"
|
#include "machine/e05a30.h"
|
||||||
#include "machine/eepromser.h"
|
#include "machine/eepromser.h"
|
||||||
#include "machine/steppers.h"
|
#include "machine/steppers.h"
|
||||||
#include "sound/speaker.h"
|
#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
|
// TYPE DEFINITIONS
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -91,6 +101,11 @@ public:
|
|||||||
/* Panel buttons */
|
/* Panel buttons */
|
||||||
DECLARE_INPUT_CHANGED_MEMBER(online_sw);
|
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:
|
protected:
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start();
|
virtual void device_start();
|
||||||
@ -102,8 +117,9 @@ private:
|
|||||||
required_device<stepper_device> m_pf_stepper;
|
required_device<stepper_device> m_pf_stepper;
|
||||||
required_device<stepper_device> m_cr_stepper;
|
required_device<stepper_device> m_cr_stepper;
|
||||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||||
required_device<speaker_sound_device> m_speaker;
|
required_device<dac_device> m_dac;
|
||||||
required_device<e05a30_device> m_e05a30;
|
required_device<e05a30_device> m_e05a30;
|
||||||
|
required_device<screen_device> m_screen;
|
||||||
|
|
||||||
int m_93c06_clk;
|
int m_93c06_clk;
|
||||||
int m_93c06_cs;
|
int m_93c06_cs;
|
||||||
@ -114,6 +130,7 @@ private:
|
|||||||
int m_real_cr_steps;
|
int m_real_cr_steps;
|
||||||
int m_real_cr_dir; /* 1 is going right, -1 is going left */
|
int m_real_cr_dir; /* 1 is going right, -1 is going left */
|
||||||
UINT8 m_fakemem;
|
UINT8 m_fakemem;
|
||||||
|
bitmap_rgb32 m_bitmap;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TIMER_CR
|
TIMER_CR
|
||||||
|
@ -97,11 +97,11 @@ void e05a30_device::device_reset()
|
|||||||
void e05a30_device::update_printhead(int pos, UINT8 data)
|
void e05a30_device::update_printhead(int pos, UINT8 data)
|
||||||
{
|
{
|
||||||
if (pos == 0) {
|
if (pos == 0) {
|
||||||
m_printhead &= 0x00ff;
|
m_printhead &= 0x01fe;
|
||||||
m_printhead |= (UINT16) !!data << 8;
|
m_printhead |= (data >> 7);
|
||||||
} else {
|
} else {
|
||||||
m_printhead &= 0xff00;
|
m_printhead &= 0x0001;
|
||||||
m_printhead |= data;
|
m_printhead |= (UINT16) (data << 1);
|
||||||
}
|
}
|
||||||
m_write_printhead(m_printhead);
|
m_write_printhead(m_printhead);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user