trunk/src/emu/bus/centronics/epson_lx810l.c
| r242090 | r242091 | |
| 286 | 286 | m_printhead(0), |
| 287 | 287 | m_pf_pos_abs(200), |
| 288 | 288 | 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) |
| 290 | 292 | { |
| 291 | 293 | } |
| 292 | 294 | |
| r242090 | r242091 | |
| 302 | 304 | m_printhead(0), |
| 303 | 305 | m_pf_pos_abs(200), |
| 304 | 306 | 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) |
| 306 | 310 | { |
| 307 | 311 | } |
| 308 | 312 | |
| r242090 | r242091 | |
| 350 | 354 | } |
| 351 | 355 | |
| 352 | 356 | |
| 357 | //------------------------------------------------- |
| 358 | // device_timer - device-specific timer |
| 359 | //------------------------------------------------- |
| 360 | |
| 361 | void 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 | |
| 353 | 380 | /*************************************************************************** |
| 354 | 381 | FAKEMEM READ/WRITE |
| 355 | 382 | ***************************************************************************/ |
| r242090 | r242091 | |
| 496 | 523 | |
| 497 | 524 | WRITE8_MEMBER( epson_lx810l_t::cr_stepper ) |
| 498 | 525 | { |
| 526 | int m_cr_pos_abs_prev = m_cr_pos_abs; |
| 527 | |
| 499 | 528 | stepper_update(1, data); |
| 500 | 529 | m_cr_pos_abs = 200 - stepper_get_absolute_position(1); |
| 501 | 530 | |
| 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 | |
| 502 | 543 | LX810LLOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_cr_pos_abs); |
| 503 | 544 | } |
| 504 | 545 | |
| r242090 | r242091 | |
| 518 | 559 | |
| 519 | 560 | /* Printhead is being fired on !state. */ |
| 520 | 561 | 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 =). |
| 530 | 572 | */ |
| 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); |
| 540 | 574 | } |
| 541 | 575 | } |
| 542 | 576 | |