summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/centronics/epson_lx810l.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/centronics/epson_lx810l.cpp')
-rw-r--r--src/devices/bus/centronics/epson_lx810l.cpp169
1 files changed, 67 insertions, 102 deletions
diff --git a/src/devices/bus/centronics/epson_lx810l.cpp b/src/devices/bus/centronics/epson_lx810l.cpp
index ad901edb5b5..bdbb9ffaa06 100644
--- a/src/devices/bus/centronics/epson_lx810l.cpp
+++ b/src/devices/bus/centronics/epson_lx810l.cpp
@@ -42,8 +42,10 @@
* an offset must be used to centralize the pixels.
*/
#define CR_OFFSET (-14)
-#define PAPER_WIDTH 1024
-#define PAPER_HEIGHT 576
+
+#define PAPER_WIDTH 1024 // 120 dpi * 8.5333 inches
+#define PAPER_HEIGHT (11*72) // 72 dpi * 11 inches
+
//**************************************************************************
@@ -140,14 +142,6 @@ void epson_lx810l_device::device_add_mconfig(machine_config &config)
// config.set_default_layout(layout_lx800);
- /* video hardware (simulates paper) */
- screen_device &screen(SCREEN(config, m_screen, SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
- screen.set_size(PAPER_WIDTH, PAPER_HEIGHT);
- screen.set_visarea(0, PAPER_WIDTH-1, 0, PAPER_HEIGHT-1);
- screen.set_screen_update(FUNC(epson_lx810l_device::screen_update_lx810l));
-
/* audio hardware */
SPEAKER(config, "speaker").front_center();
DAC_1BIT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25);
@@ -164,19 +158,21 @@ void epson_lx810l_device::device_add_mconfig(machine_config &config)
e05a30.centronics_fault().set(FUNC(epson_lx810l_device::e05a30_centronics_fault));
e05a30.centronics_select().set(FUNC(epson_lx810l_device::e05a30_centronics_select));
e05a30.cpu_reset().set(FUNC(epson_lx810l_device::e05a30_cpu_reset));
+ e05a30.ready_led().set(FUNC(epson_lx810l_device::e05a30_ready_led));
/* 256-bit eeprom */
EEPROM_93C06_16BIT(config, "eeprom");
- STEPPER(config, m_pf_stepper, (uint8_t)4);
- STEPPER(config, m_cr_stepper, (uint8_t)2);
+ BITMAP_PRINTER(config, m_bitmap_printer, PAPER_WIDTH, PAPER_HEIGHT, 120, 72); // do 72 dpi
+ m_bitmap_printer->set_pf_stepper_ratio(1,6); // pf stepper moves at 216 dpi so at 72dpi half steps
+ m_bitmap_printer->set_cr_stepper_ratio(1,1);
}
-
/***************************************************************************
INPUT PORTS
***************************************************************************/
+
static INPUT_PORTS_START( epson_lx810 )
/* Buttons on printer */
PORT_START("ONLINE")
@@ -297,20 +293,25 @@ epson_lx810l_device::epson_lx810l_device(const machine_config &mconfig, device_t
device_t(mconfig, type, tag, owner, clock),
device_centronics_peripheral_interface(mconfig, *this),
m_maincpu(*this, "maincpu"),
- m_pf_stepper(*this, "pf_stepper"),
- m_cr_stepper(*this, "cr_stepper"),
+ m_bitmap_printer(*this, "bitmap_printer"),
m_eeprom(*this, "eeprom"),
m_e05a30(*this, "e05a30"),
- m_screen(*this, "screen"),
m_online_led(*this, "online_led"),
+ m_ready_led(*this, "ready_led"),
+ m_online_ioport(*this, "ONLINE"),
+ m_formfeed_ioport(*this, "FORMFEED"),
+ m_linefeed_ioport(*this, "LINEFEED"),
+ m_loadeject_ioport(*this, "LOADEJECT"),
+ m_paperend_ioport(*this, "PAPEREND"),
+ m_dipsw1_ioport(*this, "DIPSW1"),
+ m_dipsw2_ioport(*this, "DIPSW2"),
m_93c06_clk(0),
m_93c06_cs(0),
m_printhead(0),
- 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), m_fakemem(0)
+ m_fakemem(0),
+ m_in_between_offset(0),
+ m_rightward_offset(-3)
{
}
@@ -326,11 +327,9 @@ epson_ap2000_device::epson_ap2000_device(const machine_config &mconfig, const ch
void epson_lx810l_device::device_start()
{
m_online_led.resolve();
+ m_ready_led.resolve();
- m_cr_timer = timer_alloc(TIMER_CR);
-
- m_screen->register_screen_bitmap(m_bitmap);
- m_bitmap.fill(0xffffff); /* Start with a clean white piece of paper */
+ m_cr_timer = timer_alloc(FUNC(epson_lx810l_device::cr_tick), this);
}
@@ -340,29 +339,27 @@ void epson_lx810l_device::device_start()
void epson_lx810l_device::device_reset()
{
+ m_in_between_offset = 0;
}
//-------------------------------------------------
-// device_timer - device-specific timer
+// cr_tick - handle a carriage return
//-------------------------------------------------
-void epson_lx810l_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(epson_lx810l_device::cr_tick)
{
- switch (id) {
- case TIMER_CR:
- /* The firmware issues two half-steps in sequence, one immediately
- * after the other. At full speed, the motor does two half-steps at
- * each 833 microseconds. A timer fires the printhead twice, with
- * the same period as each half-step (417 microseconds), but with
- * a 356 microseconds delay relative to the motor steps.
- */
- m_real_cr_pos += param;
- m_real_cr_steps--;
- if (m_real_cr_steps)
- m_cr_timer->adjust(attotime::from_usec(400), m_real_cr_dir);
- break;
- }
+ /* The firmware issues two half-steps in sequence, one immediately
+ * after the other. At full speed, the motor does two half-steps at
+ * each 833 microseconds. A timer fires the printhead twice, with
+ * the same period as each half-step (417 microseconds), but with
+ * a 356 microseconds delay relative to the motor steps.
+ */
+ m_in_between_offset += param;
+
+ m_real_cr_steps--;
+ if (m_real_cr_steps)
+ m_cr_timer->adjust(attotime::from_usec(400), m_bitmap_printer->m_cr_direction);
}
@@ -398,17 +395,20 @@ void epson_lx810l_device::fakemem_w(uint8_t data)
uint8_t epson_lx810l_device::porta_r(offs_t offset)
{
uint8_t result = 0;
- uint8_t hp_sensor = m_real_cr_pos <= 0 ? 0 : 1; // use m_real_cr_pos instead of m_cr_pos_abs (fixes walking carriage on mame soft reset)
+ uint8_t hp_sensor = (m_bitmap_printer->m_xpos <= 0) ? 0 : 1;
+
//uint8_t pe_sensor = m_pf_pos_abs <= 0 ? 1 : 0;
result |= hp_sensor; /* home position */
//result |= pe_sensor << 1; /* paper end */
- result |= ioport("PAPEREND")->read() << 1; // simulate a paper out error
- result |= ioport("LINEFEED")->read() << 6;
- result |= ioport("FORMFEED")->read() << 7;
+ result |= m_paperend_ioport->read() << 1; // simulate a paper out error
+ result |= m_linefeed_ioport->read() << 6;
+ result |= m_formfeed_ioport->read() << 7;
LOG("%s: lx810l_PA_r(%02x): result %02x\n", machine().describe_context(), offset, result);
+ m_bitmap_printer->set_led_state(bitmap_printer_device::LED_ERROR, !m_paperend_ioport->read());
+
return result;
}
@@ -429,7 +429,7 @@ void epson_lx810l_device::porta_w(offs_t offset, uint8_t data)
*/
uint8_t epson_lx810l_device::portb_r(offs_t offset)
{
- uint8_t result = ~ioport("DIPSW1")->read();
+ uint8_t result = ~m_dipsw1_ioport->read();
/* if 93C06 is selected */
if (m_93c06_cs) {
@@ -469,7 +469,7 @@ uint8_t epson_lx810l_device::portc_r(offs_t offset)
uint8_t result = 0;
/* result |= ioport("serial")->read() << 1; */
- result |= !ioport("ONLINE")->read() << 3;
+ result |= !m_online_ioport->read() << 3;
result |= m_93c06_clk << 4;
result |= m_93c06_cs << 5;
@@ -491,6 +491,7 @@ void epson_lx810l_device::portc_w(offs_t offset, uint8_t data)
m_eeprom->cs_write (m_93c06_cs ? ASSERT_LINE : CLEAR_LINE);
m_online_led = !BIT(data, 2);
+ m_bitmap_printer->set_led_state(bitmap_printer_device::LED_ONLINE, m_online_led);
}
@@ -505,41 +506,23 @@ void epson_lx810l_device::printhead(uint16_t data)
void epson_lx810l_device::pf_stepper(uint8_t 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);
- }
-
- LOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_pf_pos_abs);
+ m_bitmap_printer->update_pf_stepper(data);
}
void epson_lx810l_device::cr_stepper(uint8_t data)
{
- int m_cr_pos_abs_prev = m_cr_pos_abs;
+ m_bitmap_printer->update_cr_stepper(bitswap<4>(data, 0, 1, 2, 3)); // reverse bits
- m_cr_stepper->update(data);
- m_cr_pos_abs = -m_cr_stepper->get_absolute_position();
-
- if (m_cr_pos_abs > m_cr_pos_abs_prev) {
- /* going right */
- m_real_cr_dir = 1;
- } else {
- /* going left */
- m_real_cr_dir = -1;
- }
+ m_in_between_offset = 0;
if (!m_real_cr_steps)
- m_cr_timer->adjust(attotime::from_usec(400), m_real_cr_dir);
- m_real_cr_steps++;
-
- LOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_cr_pos_abs);
+ {
+ m_cr_timer->adjust(attotime::from_usec(400), m_bitmap_printer->m_cr_direction);
+ m_real_cr_steps++;
+ }
}
-WRITE_LINE_MEMBER( epson_lx810l_device::e05a30_ready )
+void epson_lx810l_device::e05a30_ready(int state)
{
// must be longer than attotime::zero - 0.09 is minimum to initialize properly
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::from_double(0.09));
@@ -547,28 +530,10 @@ WRITE_LINE_MEMBER( epson_lx810l_device::e05a30_ready )
/***************************************************************************
- Video hardware (simulates paper)
-***************************************************************************/
-
-uint32_t epson_lx810l_device::screen_update_lx810l(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
-{
- int scrolly = -bitmap_line(9);
- copyscrollbitmap(bitmap, m_bitmap, 0, nullptr, 1, &scrolly, cliprect);
-
- /* draw "printhead" */
- int bordersize = 1;
- bitmap.plot_box(m_real_cr_pos + CR_OFFSET - 10 - bordersize, PAPER_HEIGHT - 36 - bordersize, 20 + bordersize * 2, 36 + bordersize * 2, 0x000000 );
- bitmap.plot_box(m_real_cr_pos + CR_OFFSET - 10, PAPER_HEIGHT - 36, 20, 36, m_e05a30->ready_led() ? 0x55ff55 : 0x337733 );
-
- return 0;
-}
-
-
-/***************************************************************************
Extended Timer Output
***************************************************************************/
-WRITE_LINE_MEMBER( epson_lx810l_device::co0_w )
+void epson_lx810l_device::co0_w(int state)
{
/* Printhead is being fired on !state. */
if (!state) {
@@ -583,12 +548,12 @@ WRITE_LINE_MEMBER( epson_lx810l_device::co0_w )
* lines which are being printed in different directions is
* noticeably off in the 20+ years old printer used for testing =).
*/
- if (m_real_cr_pos < m_bitmap.width()) {
- for (int i = 0; i < 9; i++) {
- unsigned int const y = bitmap_line(i);
- if ((m_printhead & (1<<(8-i))) != 0)
- m_bitmap.pix(y, m_real_cr_pos + CR_OFFSET) = 0x000000;
- }
+ for (int i = 0; i < 9; i++)
+ {
+ if ((m_printhead & (1<<(8-i))) != 0)
+ m_bitmap_printer->pix(m_bitmap_printer->m_ypos + i * 1, // * 1 for no interleave at 72 vdpi
+ m_bitmap_printer->m_xpos + CR_OFFSET + m_in_between_offset +
+ (m_bitmap_printer->m_cr_direction > 0 ? m_rightward_offset : 0)) = 0x000000;
}
}
}
@@ -600,25 +565,25 @@ WRITE_LINE_MEMBER( epson_lx810l_device::co0_w )
uint8_t epson_lx810l_device::an0_r()
{
- uint8_t res = !!(ioport("DIPSW2")->read() & 0x01);
+ uint8_t res = !!(m_dipsw2_ioport->read() & 0x01);
return res - 1; /* DIPSW2.1 */
}
uint8_t epson_lx810l_device::an1_r()
{
- uint8_t res = !!(ioport("DIPSW2")->read() & 0x02);
+ uint8_t res = !!(m_dipsw2_ioport->read() & 0x02);
return res - 1; /* DIPSW2.2 */
}
uint8_t epson_lx810l_device::an2_r()
{
- uint8_t res = !!(ioport("DIPSW2")->read() & 0x04);
+ uint8_t res = !!(m_dipsw2_ioport->read() & 0x04);
return res - 1; /* DIPSW2.3 */
}
uint8_t epson_lx810l_device::an3_r()
{
- uint8_t res = !!(ioport("DIPSW2")->read() & 0x08);
+ uint8_t res = !!(m_dipsw2_ioport->read() & 0x08);
return res - 1; /* DIPSW2.4 */
}
@@ -634,7 +599,7 @@ uint8_t epson_lx810l_device::an5_r()
uint8_t epson_lx810l_device::an6_r()
{
- uint8_t res = !ioport("LOADEJECT")->read();
+ uint8_t res = !m_loadeject_ioport->read();
return res - 1;
}