Previous 199869 Revisions Next

r33579 Tuesday 25th November, 2014 at 01:08:58 UTC by Ramiro Polla
lx810l: more accurate pixel vertical alignment

The timings of the carriage stepper motor were modelled to accurately
describe the vertical position of the printhead at each fire signal.
[src/emu/bus/centronics]epson_lx810l.c epson_lx810l.h

trunk/src/emu/bus/centronics/epson_lx810l.c
r242090r242091
286286   m_printhead(0),
287287   m_pf_pos_abs(200),
288288   m_cr_pos_abs(200),
289   m_last_fire(0)
289   m_real_cr_pos(200),
290   m_real_cr_steps(0),
291   m_real_cr_dir(0)
290292{
291293}
292294
r242090r242091
302304   m_printhead(0),
303305   m_pf_pos_abs(200),
304306   m_cr_pos_abs(200),
305   m_last_fire(0)
307   m_real_cr_pos(200),
308   m_real_cr_steps(0),
309   m_real_cr_dir(0)
306310{
307311}
308312
r242090r242091
350354}
351355
352356
357//-------------------------------------------------
358//  device_timer - device-specific timer
359//-------------------------------------------------
360
361void epson_lx810l_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
362{
363   switch (id) {
364   case TIMER_CR:
365      /* The firmware issues two half-steps in sequence, one immediately
366       * after the other. At full speed, the motor does two half-steps at
367       * each 833 microseconds. A timer fires the printhead twice, with
368       * the same period as each half-step (417 microseconds), but with
369       * a 356 microseconds delay relative to the motor steps.
370       */
371      m_real_cr_pos += param;
372      m_real_cr_steps--;
373      if (m_real_cr_steps)
374         timer_set(attotime::from_usec(400), TIMER_CR, m_real_cr_dir);
375      break;
376   }
377}
378
379
353380/***************************************************************************
354381    FAKEMEM READ/WRITE
355382***************************************************************************/
r242090r242091
496523
497524WRITE8_MEMBER( epson_lx810l_t::cr_stepper )
498525{
526   int m_cr_pos_abs_prev = m_cr_pos_abs;
527
499528   stepper_update(1, data);
500529   m_cr_pos_abs = 200 - stepper_get_absolute_position(1);
501530
531   if (m_cr_pos_abs > m_cr_pos_abs_prev) {
532      /* going right */
533      m_real_cr_dir =  1;
534   } else {
535      /* going left */
536      m_real_cr_dir = -1;
537   }
538
539   if (!m_real_cr_steps)
540      timer_set(attotime::from_usec(400), TIMER_CR, m_real_cr_dir);
541   m_real_cr_steps++;
542
502543   LX810LLOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_cr_pos_abs);
503544}
504545
r242090r242091
518559
519560   /* Printhead is being fired on !state. */
520561   if (!state) {
521      int pos = m_cr_pos_abs;
522
523      /* HACK to get fire positions for motor in movement. The firmware
524       * issues two half-steps one immediately after the other. A timer
525       * fires the printhead twice. Supposedly, the first time the
526       * printhead is fired, it is midway between one step and the other.
527       * Ideally, the stepper motor interface should model the physics
528       * of the motors. For the moment, we adjust pos to get the
529       * intermediate position.
562      /* The firmware expects a 300 microseconds delay between the fire
563       * signal and the impact of the printhead on the paper. This can be
564       * verified by the timings of the steps and fire signals for the
565       * same positions with different directions (left to right or right
566       * to left). We don't simulate this delay since it is smaller than
567       * the time it takes the printhead to travel one pixel (which would
568       * be 417 microseconds), so it makes no difference to us.
569       * It is interesting to note that the vertical alignment between
570       * lines which are being printed in different directions is
571       * noticeably off in the 20+ years old printer used for testing =).
530572       */
531
532      if      (m_cr_pos_abs > m_last_fire + 1)
533         pos--;
534      else if (m_cr_pos_abs < m_last_fire - 1)
535         pos++;
536
537      LX810LLOG("FIRE0 %d %d %04x\n", m_pf_pos_abs, pos, m_printhead);
538
539      m_last_fire = pos;
573      LX810LLOG("FIRE0 %d %d %04x\n", m_pf_pos_abs, m_real_cr_pos, m_printhead);
540574   }
541575}
542576
trunk/src/emu/bus/centronics/epson_lx810l.h
r242090r242091
9696   // device-level overrides
9797   virtual void device_start();
9898   virtual void device_reset();
99   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
99100
100101private:
101102   required_device<cpu_device> m_maincpu;
r242090r242091
108109   UINT16 m_printhead;
109110   int m_pf_pos_abs;
110111   int m_cr_pos_abs;
111   int m_last_fire; /* HACK to get fire positions for motor in movement */
112   int m_real_cr_pos;
113   int m_real_cr_steps;
114   int m_real_cr_dir; /* 1 is going right, -1 is going left */
112115   UINT8 m_fakemem;
116
117   enum {
118      TIMER_CR,
119   };
113120};
114121
115122// ======================> epson_ap2000_t


Previous 199869 Revisions Next


© 1997-2024 The MAME Team