mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +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
|
||||
/*
|
||||
* Epson LX-810L dot matrix printer emulation
|
||||
|
||||
*
|
||||
* IC list:
|
||||
* uPD7810HG (cpu)
|
||||
* E05A30 (gate array)
|
||||
@ -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;
|
||||
@ -22,12 +20,9 @@
|
||||
* - Reset device;
|
||||
* - Toggle Line Feed button again;
|
||||
* - Press Online button (press 'O');
|
||||
* - Press Online button again;
|
||||
*
|
||||
* 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()).
|
||||
* The printer's carriage will seek home and it will start printing
|
||||
* some test data. The Online LED will blink at each line.
|
||||
*/
|
||||
|
||||
#include "epson_lx810l.h"
|
||||
@ -139,9 +134,17 @@ 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_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
|
||||
MCFG_DAC_ADD("dac")
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
|
||||
|
||||
/* gate array */
|
||||
@ -160,19 +163,12 @@ static MACHINE_CONFIG_FRAGMENT( epson_lx810l )
|
||||
MCFG_EEPROM_SERIAL_93C06_ADD("eeprom")
|
||||
|
||||
/* steppers */
|
||||
//should this have MCFG_STEPPER_MAX_STEPS(200*2) ? code shows 200 steps...
|
||||
MCFG_STEPPER_ADD("pf_stepper")
|
||||
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(0)
|
||||
MCFG_STEPPER_INIT_PHASE(4)
|
||||
|
||||
MCFG_STEPPER_ADD("cr_stepper")
|
||||
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)
|
||||
|
||||
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_cr_stepper(*this, "cr_stepper"),
|
||||
m_eeprom(*this, "eeprom"),
|
||||
m_speaker(*this, "speaker"),
|
||||
m_dac(*this, "dac"),
|
||||
m_e05a30(*this, "e05a30"),
|
||||
m_screen(*this, "screen"),
|
||||
m_93c06_clk(0),
|
||||
m_93c06_cs(0),
|
||||
m_printhead(0),
|
||||
m_pf_pos_abs(200),
|
||||
m_cr_pos_abs(200),
|
||||
m_real_cr_pos(200),
|
||||
m_pf_pos_abs(1),
|
||||
m_cr_pos_abs(1),
|
||||
m_real_cr_pos(1),
|
||||
m_real_cr_steps(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_cr_stepper(*this, "cr_stepper"),
|
||||
m_eeprom(*this, "eeprom"),
|
||||
m_speaker(*this, "speaker"),
|
||||
m_dac(*this, "dac"),
|
||||
m_e05a30(*this, "e05a30"),
|
||||
m_screen(*this, "screen"),
|
||||
m_93c06_clk(0),
|
||||
m_93c06_cs(0),
|
||||
m_printhead(0),
|
||||
m_pf_pos_abs(200),
|
||||
m_cr_pos_abs(200),
|
||||
m_real_cr_pos(200),
|
||||
m_pf_pos_abs(1),
|
||||
m_cr_pos_abs(1),
|
||||
m_real_cr_pos(1),
|
||||
m_real_cr_steps(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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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 )
|
||||
{
|
||||
m_pf_stepper->update(data);
|
||||
m_pf_pos_abs = 200 - m_pf_stepper->get_absolute_position();
|
||||
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);
|
||||
}
|
||||
@ -528,7 +534,7 @@ WRITE8_MEMBER( epson_lx810l_t::cr_stepper )
|
||||
int m_cr_pos_abs_prev = m_cr_pos_abs;
|
||||
|
||||
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) {
|
||||
/* 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
|
||||
***************************************************************************/
|
||||
|
||||
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
|
||||
@ -572,13 +592,19 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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/eepromser.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
|
||||
//**************************************************************************
|
||||
@ -91,6 +101,11 @@ public:
|
||||
/* 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();
|
||||
@ -102,8 +117,9 @@ private:
|
||||
required_device<stepper_device> m_pf_stepper;
|
||||
required_device<stepper_device> m_cr_stepper;
|
||||
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<screen_device> m_screen;
|
||||
|
||||
int m_93c06_clk;
|
||||
int m_93c06_cs;
|
||||
@ -114,6 +130,7 @@ private:
|
||||
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
|
||||
|
@ -97,11 +97,11 @@ void e05a30_device::device_reset()
|
||||
void e05a30_device::update_printhead(int pos, UINT8 data)
|
||||
{
|
||||
if (pos == 0) {
|
||||
m_printhead &= 0x00ff;
|
||||
m_printhead |= (UINT16) !!data << 8;
|
||||
m_printhead &= 0x01fe;
|
||||
m_printhead |= (data >> 7);
|
||||
} else {
|
||||
m_printhead &= 0xff00;
|
||||
m_printhead |= data;
|
||||
m_printhead &= 0x0001;
|
||||
m_printhead |= (UINT16) (data << 1);
|
||||
}
|
||||
m_write_printhead(m_printhead);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user