mirror of
https://github.com/holub/mame
synced 2025-04-16 13:34:55 +03:00
Adding bitmap_printer_device and convert epson_lx810 to use it. (#8863)
This commit is contained in:
parent
fd73621285
commit
c21bea828d
@ -4911,3 +4911,14 @@ if (MACHINES["GLUKRS"]~=null) then
|
|||||||
MAME_DIR .. "src/devices/machine/glukrs.h",
|
MAME_DIR .. "src/devices/machine/glukrs.h",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------
|
||||||
|
--
|
||||||
|
--@src/devices/machine/bitmap_printer.h,MACHINES["BITMAP_PRINTER"] = true
|
||||||
|
---------------------------------------------------
|
||||||
|
if (MACHINES["BITMAP_PRINTER"]~=null) then
|
||||||
|
files {
|
||||||
|
MAME_DIR .. "src/devices/machine/bitmap_printer.cpp",
|
||||||
|
MAME_DIR .. "src/devices/machine/bitmap_printer.h",
|
||||||
|
}
|
||||||
|
end
|
@ -829,6 +829,7 @@ MACHINES["BL_HANDHELDS_MENUCONTROL"] = true
|
|||||||
MACHINES["NS32081"] = true
|
MACHINES["NS32081"] = true
|
||||||
MACHINES["NS32202"] = true
|
MACHINES["NS32202"] = true
|
||||||
MACHINES["NS32082"] = true
|
MACHINES["NS32082"] = true
|
||||||
|
MACHINES["BITMAP_PRINTER"] = true
|
||||||
|
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
-- specify available bus cores
|
-- specify available bus cores
|
||||||
|
@ -42,8 +42,10 @@
|
|||||||
* an offset must be used to centralize the pixels.
|
* an offset must be used to centralize the pixels.
|
||||||
*/
|
*/
|
||||||
#define CR_OFFSET (-14)
|
#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);
|
// 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 */
|
/* audio hardware */
|
||||||
SPEAKER(config, "speaker").front_center();
|
SPEAKER(config, "speaker").front_center();
|
||||||
DAC_1BIT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25);
|
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_fault().set(FUNC(epson_lx810l_device::e05a30_centronics_fault));
|
||||||
e05a30.centronics_select().set(FUNC(epson_lx810l_device::e05a30_centronics_select));
|
e05a30.centronics_select().set(FUNC(epson_lx810l_device::e05a30_centronics_select));
|
||||||
e05a30.cpu_reset().set(FUNC(epson_lx810l_device::e05a30_cpu_reset));
|
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 */
|
/* 256-bit eeprom */
|
||||||
EEPROM_93C06_16BIT(config, "eeprom");
|
EEPROM_93C06_16BIT(config, "eeprom");
|
||||||
|
|
||||||
STEPPER(config, m_pf_stepper, (uint8_t)4);
|
BITMAP_PRINTER(config, m_bitmap_printer, PAPER_WIDTH, PAPER_HEIGHT, 120, 72); // do 72 dpi
|
||||||
STEPPER(config, m_cr_stepper, (uint8_t)2);
|
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
|
INPUT PORTS
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
static INPUT_PORTS_START( epson_lx810 )
|
static INPUT_PORTS_START( epson_lx810 )
|
||||||
/* Buttons on printer */
|
/* Buttons on printer */
|
||||||
PORT_START("ONLINE")
|
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_t(mconfig, type, tag, owner, clock),
|
||||||
device_centronics_peripheral_interface(mconfig, *this),
|
device_centronics_peripheral_interface(mconfig, *this),
|
||||||
m_maincpu(*this, "maincpu"),
|
m_maincpu(*this, "maincpu"),
|
||||||
m_pf_stepper(*this, "pf_stepper"),
|
m_bitmap_printer(*this, "bitmap_printer"),
|
||||||
m_cr_stepper(*this, "cr_stepper"),
|
|
||||||
m_eeprom(*this, "eeprom"),
|
m_eeprom(*this, "eeprom"),
|
||||||
m_e05a30(*this, "e05a30"),
|
m_e05a30(*this, "e05a30"),
|
||||||
m_screen(*this, "screen"),
|
|
||||||
m_online_led(*this, "online_led"),
|
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_clk(0),
|
||||||
m_93c06_cs(0),
|
m_93c06_cs(0),
|
||||||
m_printhead(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_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()
|
void epson_lx810l_device::device_start()
|
||||||
{
|
{
|
||||||
m_online_led.resolve();
|
m_online_led.resolve();
|
||||||
|
m_ready_led.resolve();
|
||||||
|
|
||||||
m_cr_timer = timer_alloc(TIMER_CR);
|
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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -340,6 +339,7 @@ void epson_lx810l_device::device_start()
|
|||||||
|
|
||||||
void epson_lx810l_device::device_reset()
|
void epson_lx810l_device::device_reset()
|
||||||
{
|
{
|
||||||
|
m_in_between_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -357,10 +357,11 @@ void epson_lx810l_device::device_timer(emu_timer &timer, device_timer_id id, int
|
|||||||
* the same period as each half-step (417 microseconds), but with
|
* the same period as each half-step (417 microseconds), but with
|
||||||
* a 356 microseconds delay relative to the motor steps.
|
* a 356 microseconds delay relative to the motor steps.
|
||||||
*/
|
*/
|
||||||
m_real_cr_pos += param;
|
m_in_between_offset += param;
|
||||||
|
|
||||||
m_real_cr_steps--;
|
m_real_cr_steps--;
|
||||||
if (m_real_cr_steps)
|
if (m_real_cr_steps)
|
||||||
m_cr_timer->adjust(attotime::from_usec(400), m_real_cr_dir);
|
m_cr_timer->adjust(attotime::from_usec(400), m_bitmap_printer->m_cr_direction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,17 +399,20 @@ void epson_lx810l_device::fakemem_w(uint8_t data)
|
|||||||
uint8_t epson_lx810l_device::porta_r(offs_t offset)
|
uint8_t epson_lx810l_device::porta_r(offs_t offset)
|
||||||
{
|
{
|
||||||
uint8_t result = 0;
|
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;
|
//uint8_t pe_sensor = m_pf_pos_abs <= 0 ? 1 : 0;
|
||||||
|
|
||||||
result |= hp_sensor; /* home position */
|
result |= hp_sensor; /* home position */
|
||||||
//result |= pe_sensor << 1; /* paper end */
|
//result |= pe_sensor << 1; /* paper end */
|
||||||
result |= ioport("PAPEREND")->read() << 1; // simulate a paper out error
|
result |= m_paperend_ioport->read() << 1; // simulate a paper out error
|
||||||
result |= ioport("LINEFEED")->read() << 6;
|
result |= m_linefeed_ioport->read() << 6;
|
||||||
result |= ioport("FORMFEED")->read() << 7;
|
result |= m_formfeed_ioport->read() << 7;
|
||||||
|
|
||||||
LOG("%s: lx810l_PA_r(%02x): result %02x\n", machine().describe_context(), offset, result);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,7 +433,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 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 93C06 is selected */
|
||||||
if (m_93c06_cs) {
|
if (m_93c06_cs) {
|
||||||
@ -469,7 +473,7 @@ uint8_t epson_lx810l_device::portc_r(offs_t offset)
|
|||||||
uint8_t result = 0;
|
uint8_t result = 0;
|
||||||
|
|
||||||
/* result |= ioport("serial")->read() << 1; */
|
/* result |= ioport("serial")->read() << 1; */
|
||||||
result |= !ioport("ONLINE")->read() << 3;
|
result |= !m_online_ioport->read() << 3;
|
||||||
result |= m_93c06_clk << 4;
|
result |= m_93c06_clk << 4;
|
||||||
result |= m_93c06_cs << 5;
|
result |= m_93c06_cs << 5;
|
||||||
|
|
||||||
@ -491,6 +495,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_eeprom->cs_write (m_93c06_cs ? ASSERT_LINE : CLEAR_LINE);
|
||||||
|
|
||||||
m_online_led = !BIT(data, 2);
|
m_online_led = !BIT(data, 2);
|
||||||
|
m_bitmap_printer->set_led_state(bitmap_printer_device::LED_ONLINE, m_online_led);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -505,38 +510,20 @@ void epson_lx810l_device::printhead(uint16_t data)
|
|||||||
|
|
||||||
void epson_lx810l_device::pf_stepper(uint8_t data)
|
void epson_lx810l_device::pf_stepper(uint8_t data)
|
||||||
{
|
{
|
||||||
int changed = m_pf_stepper->update(data);
|
m_bitmap_printer->update_pf_stepper(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void epson_lx810l_device::cr_stepper(uint8_t 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_in_between_offset = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_real_cr_steps)
|
if (!m_real_cr_steps)
|
||||||
m_cr_timer->adjust(attotime::from_usec(400), m_real_cr_dir);
|
{
|
||||||
m_real_cr_steps++;
|
m_cr_timer->adjust(attotime::from_usec(400), m_bitmap_printer->m_cr_direction);
|
||||||
|
m_real_cr_steps++;
|
||||||
LOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_cr_pos_abs);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( epson_lx810l_device::e05a30_ready )
|
WRITE_LINE_MEMBER( epson_lx810l_device::e05a30_ready )
|
||||||
@ -546,24 +533,6 @@ 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
|
Extended Timer Output
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -583,11 +552,13 @@ WRITE_LINE_MEMBER( epson_lx810l_device::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 =).
|
||||||
*/
|
*/
|
||||||
if (m_real_cr_pos < m_bitmap.width()) {
|
if (m_bitmap_printer->m_xpos < m_bitmap_printer->m_page_bitmap.width()) {
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++)
|
||||||
unsigned int const y = bitmap_line(i);
|
{
|
||||||
if ((m_printhead & (1<<(8-i))) != 0)
|
if ((m_printhead & (1<<(8-i))) != 0)
|
||||||
m_bitmap.pix(y, m_real_cr_pos + CR_OFFSET) = 0x000000;
|
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 +571,25 @@ WRITE_LINE_MEMBER( epson_lx810l_device::co0_w )
|
|||||||
|
|
||||||
uint8_t epson_lx810l_device::an0_r()
|
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 */
|
return res - 1; /* DIPSW2.1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t epson_lx810l_device::an1_r()
|
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 */
|
return res - 1; /* DIPSW2.2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t epson_lx810l_device::an2_r()
|
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 */
|
return res - 1; /* DIPSW2.3 */
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t epson_lx810l_device::an3_r()
|
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 */
|
return res - 1; /* DIPSW2.4 */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,7 +605,7 @@ uint8_t epson_lx810l_device::an5_r()
|
|||||||
|
|
||||||
uint8_t epson_lx810l_device::an6_r()
|
uint8_t epson_lx810l_device::an6_r()
|
||||||
{
|
{
|
||||||
uint8_t res = !ioport("LOADEJECT")->read();
|
uint8_t res = !m_loadeject_ioport->read();
|
||||||
return res - 1;
|
return res - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "cpu/upd7810/upd7810.h"
|
#include "cpu/upd7810/upd7810.h"
|
||||||
#include "machine/e05a30.h"
|
#include "machine/e05a30.h"
|
||||||
#include "machine/eepromser.h"
|
#include "machine/eepromser.h"
|
||||||
|
#include "machine/bitmap_printer.h"
|
||||||
#include "machine/steppers.h"
|
#include "machine/steppers.h"
|
||||||
#include "sound/dac.h"
|
#include "sound/dac.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
@ -105,32 +106,37 @@ private:
|
|||||||
|
|
||||||
DECLARE_WRITE_LINE_MEMBER(e05a30_cpu_reset) { if (!state) m_maincpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero); } // reset cpu
|
DECLARE_WRITE_LINE_MEMBER(e05a30_cpu_reset) { if (!state) m_maincpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero); } // reset cpu
|
||||||
|
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(e05a30_ready_led)
|
||||||
|
{
|
||||||
|
m_ready_led = state;
|
||||||
|
m_bitmap_printer->set_led_state(bitmap_printer_device::LED_READY, m_ready_led);
|
||||||
|
}
|
||||||
|
|
||||||
void lx810l_mem(address_map &map);
|
void lx810l_mem(address_map &map);
|
||||||
|
|
||||||
/* Video hardware (simulates paper) */
|
|
||||||
uint32_t screen_update_lx810l(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
|
||||||
|
|
||||||
unsigned int bitmap_line(int i) { return ((std::abs(m_pf_pos_abs) / 6) + i) % m_bitmap.height(); }
|
|
||||||
|
|
||||||
required_device<cpu_device> m_maincpu;
|
required_device<cpu_device> m_maincpu;
|
||||||
required_device<stepper_device> m_pf_stepper;
|
required_device<bitmap_printer_device> m_bitmap_printer;
|
||||||
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<e05a30_device> m_e05a30;
|
required_device<e05a30_device> m_e05a30;
|
||||||
required_device<screen_device> m_screen;
|
|
||||||
|
|
||||||
output_finder<> m_online_led;
|
output_finder<> m_online_led;
|
||||||
|
output_finder<> m_ready_led;
|
||||||
|
|
||||||
|
required_ioport m_online_ioport;
|
||||||
|
required_ioport m_formfeed_ioport;
|
||||||
|
required_ioport m_linefeed_ioport;
|
||||||
|
required_ioport m_loadeject_ioport;
|
||||||
|
required_ioport m_paperend_ioport;
|
||||||
|
required_ioport m_dipsw1_ioport;
|
||||||
|
required_ioport m_dipsw2_ioport;
|
||||||
|
|
||||||
int m_93c06_clk;
|
int m_93c06_clk;
|
||||||
int m_93c06_cs;
|
int m_93c06_cs;
|
||||||
uint16_t m_printhead;
|
uint16_t m_printhead;
|
||||||
int m_pf_pos_abs;
|
|
||||||
int m_cr_pos_abs;
|
|
||||||
int m_real_cr_pos;
|
|
||||||
int m_real_cr_steps;
|
int m_real_cr_steps;
|
||||||
int m_real_cr_dir; /* 1 is going right, -1 is going left */
|
|
||||||
uint8_t m_fakemem;
|
uint8_t m_fakemem;
|
||||||
bitmap_rgb32 m_bitmap;
|
int m_in_between_offset; // in between cr_stepper phases
|
||||||
|
int m_rightward_offset; // offset pixels when stepper moving rightward
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TIMER_CR
|
TIMER_CR
|
||||||
|
443
src/devices/machine/bitmap_printer.cpp
Normal file
443
src/devices/machine/bitmap_printer.cpp
Normal file
@ -0,0 +1,443 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders: Golden Child
|
||||||
|
/*********************************************************************
|
||||||
|
|
||||||
|
bitmap_printer.cpp
|
||||||
|
|
||||||
|
Implementation of Bitmap Printer
|
||||||
|
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "video.h"
|
||||||
|
#include "screen.h"
|
||||||
|
#include "emuopts.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
#include "png.h"
|
||||||
|
#include "bitmap_printer.h"
|
||||||
|
#include "corestr.h"
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
DEVICE DECLARATION
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
DEFINE_DEVICE_TYPE(BITMAP_PRINTER, bitmap_printer_device, "bitmap_printer", "Bitmap Printer Device")
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// INPUT PORTS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
#define PORT_ADJUSTER_16MASK(_default, _name) \
|
||||||
|
configurer.field_alloc(IPT_ADJUSTER, (_default), 0xffff, (_name)); \
|
||||||
|
configurer.field_set_min_max(0, 100);
|
||||||
|
|
||||||
|
INPUT_PORTS_START(bitmap_printer)
|
||||||
|
PORT_START("DRAWMARKS")
|
||||||
|
PORT_CONFNAME(0x3, 0x02, "Draw Inch Marks")
|
||||||
|
PORT_CONFSETTING(0x0, "Off")
|
||||||
|
PORT_CONFSETTING(0x1, "with marks")
|
||||||
|
PORT_CONFSETTING(0x2, "with numbers")
|
||||||
|
|
||||||
|
PORT_START("TOPMARGIN")
|
||||||
|
PORT_ADJUSTER_16MASK(18, "Printer Top Margin")
|
||||||
|
PORT_MINMAX(0,500)
|
||||||
|
|
||||||
|
PORT_START("BOTTOMMARGIN")
|
||||||
|
PORT_ADJUSTER_16MASK(18, "Printer Bottom Margin")
|
||||||
|
PORT_MINMAX(0,500)
|
||||||
|
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
|
ioport_constructor bitmap_printer_device::device_input_ports() const
|
||||||
|
{
|
||||||
|
return INPUT_PORTS_NAME(bitmap_printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_add_mconfig - add device configuration
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void bitmap_printer_device::device_add_mconfig(machine_config &config)
|
||||||
|
{
|
||||||
|
// 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(m_paper_width, PAPER_SCREEN_HEIGHT);
|
||||||
|
screen.set_visarea(0, m_paper_width - 1, 0, PAPER_SCREEN_HEIGHT - 1);
|
||||||
|
screen.set_screen_update(FUNC(bitmap_printer_device::screen_update_bitmap));
|
||||||
|
|
||||||
|
STEPPER(config, m_pf_stepper, (uint8_t) 0xa);
|
||||||
|
STEPPER(config, m_cr_stepper, (uint8_t) 0xa);
|
||||||
|
}
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// LIVE DEVICE
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
bitmap_printer_device::bitmap_printer_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
device_t(mconfig, type, tag, owner, clock),
|
||||||
|
m_screen(*this, "screen"),
|
||||||
|
m_pf_stepper(*this, "pf_stepper"),
|
||||||
|
m_cr_stepper(*this, "cr_stepper"),
|
||||||
|
m_top_margin_ioport(*this, "TOPMARGIN"),
|
||||||
|
m_bottom_margin_ioport(*this, "BOTTOMMARGIN"),
|
||||||
|
m_draw_marks_ioport(*this, "DRAWMARKS"),
|
||||||
|
m_cr_direction(1),
|
||||||
|
m_pf_stepper_ratio0(1),
|
||||||
|
m_pf_stepper_ratio1(1),
|
||||||
|
m_cr_stepper_ratio0(1),
|
||||||
|
m_cr_stepper_ratio1(1),
|
||||||
|
m_xpos(0),
|
||||||
|
m_ypos(0),
|
||||||
|
m_printhead_color(0x00EE00),
|
||||||
|
m_printhead_bordercolor(0xEE0000),
|
||||||
|
m_printhead_bordersize(2),
|
||||||
|
m_printhead_xsize(10),
|
||||||
|
m_printhead_ysize(20),
|
||||||
|
m_page_dirty(0),
|
||||||
|
m_paper_width(0),
|
||||||
|
m_paper_height(0),
|
||||||
|
m_hdpi(0),
|
||||||
|
m_vdpi(0),
|
||||||
|
m_clear_pos(0),
|
||||||
|
m_newpage_flag(0),
|
||||||
|
m_led_state{0,1,1,1,1},
|
||||||
|
m_num_leds(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap_printer_device::bitmap_printer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
bitmap_printer_device(mconfig, BITMAP_PRINTER, tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void bitmap_printer_device::device_start()
|
||||||
|
{
|
||||||
|
m_page_bitmap.allocate(m_paper_width, m_paper_height);
|
||||||
|
m_page_bitmap.fill(0xffffff); // Start with a white piece of paper
|
||||||
|
|
||||||
|
save_item(NAME(m_page_bitmap));
|
||||||
|
save_item(NAME(m_xpos));
|
||||||
|
save_item(NAME(m_ypos));
|
||||||
|
save_item(NAME(m_cr_direction));
|
||||||
|
save_item(NAME(m_pf_stepper_ratio0));
|
||||||
|
save_item(NAME(m_pf_stepper_ratio1));
|
||||||
|
save_item(NAME(m_cr_stepper_ratio0));
|
||||||
|
save_item(NAME(m_cr_stepper_ratio1));
|
||||||
|
save_item(NAME(m_printhead_color));
|
||||||
|
save_item(NAME(m_printhead_bordercolor));
|
||||||
|
save_item(NAME(m_printhead_bordersize));
|
||||||
|
save_item(NAME(m_printhead_xsize));
|
||||||
|
save_item(NAME(m_printhead_ysize));
|
||||||
|
save_item(NAME(m_page_dirty));
|
||||||
|
save_item(NAME(m_paper_width));
|
||||||
|
save_item(NAME(m_paper_height));
|
||||||
|
save_item(NAME(m_hdpi));
|
||||||
|
save_item(NAME(m_vdpi));
|
||||||
|
save_item(NAME(m_clear_pos));
|
||||||
|
save_item(NAME(m_newpage_flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::device_reset_after_children()
|
||||||
|
{
|
||||||
|
m_ypos = get_top_margin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::device_reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// SCREEN UPDATE FUNCTIONS
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
int bitmap_printer_device::calc_scroll_y(bitmap_rgb32& bitmap)
|
||||||
|
{
|
||||||
|
return bitmap.height() - m_distfrombottom - m_ypos;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t bitmap_printer_device::screen_update_bitmap(screen_device &screen,
|
||||||
|
bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||||
|
{
|
||||||
|
static constexpr u32 top_edge_color = 0xEEE8AA;
|
||||||
|
static constexpr u32 bottom_edge_color = 0xEE8844;
|
||||||
|
static constexpr u32 coverup_color = 0xDDDDDD;
|
||||||
|
|
||||||
|
int scrolly = calc_scroll_y(bitmap);
|
||||||
|
|
||||||
|
copyscrollbitmap(bitmap, m_page_bitmap, 0, nullptr, 1, &scrolly, cliprect);
|
||||||
|
|
||||||
|
// draw a line on the very top of the top edge of page
|
||||||
|
bitmap.plot_box(0, bitmap.height() - m_distfrombottom - m_ypos, m_paper_width, 2, top_edge_color);
|
||||||
|
// draw a line on the bottom edge of page
|
||||||
|
bitmap.plot_box(0, bitmap.height() - m_distfrombottom - m_ypos + m_paper_height, m_paper_width, 2, bottom_edge_color);
|
||||||
|
// cover up visible parts of current page at the bottom
|
||||||
|
bitmap.plot_box(0, bitmap.height() - m_distfrombottom - m_ypos + m_paper_height + 2, m_paper_width, m_distfrombottom, coverup_color);
|
||||||
|
|
||||||
|
draw_printhead(bitmap, std::max(m_xpos, 0) , bitmap.height() - m_distfrombottom);
|
||||||
|
|
||||||
|
draw_inch_marks(bitmap);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// BITMAP CLEARING FUNCTIONS
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void bitmap_printer_device::clear_to_pos(int to_line, u32 color)
|
||||||
|
{
|
||||||
|
int from_line = m_clear_pos;
|
||||||
|
to_line = std::min(m_page_bitmap.height(), to_line);
|
||||||
|
if (to_line >= from_line)
|
||||||
|
{
|
||||||
|
bitmap_clear_band(m_page_bitmap, from_line, to_line, color);
|
||||||
|
}
|
||||||
|
m_clear_pos = std::max(m_clear_pos, to_line + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::bitmap_clear_band(int from_line, int to_line, u32 color)
|
||||||
|
{
|
||||||
|
bitmap_clear_band(m_page_bitmap, from_line, to_line, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::bitmap_clear_band(bitmap_rgb32 &bitmap, int from_line, int to_line, u32 color)
|
||||||
|
{
|
||||||
|
bitmap.plot_box(0, from_line, m_paper_width, to_line - from_line + 1, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// PRINTHEAD FUNCTIONS
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void bitmap_printer_device::set_printhead_color(int headcolor, int bordcolor)
|
||||||
|
{
|
||||||
|
m_printhead_color = headcolor;
|
||||||
|
m_printhead_bordercolor = bordcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::set_printhead_size(int xsize, int ysize, int bordersize)
|
||||||
|
{
|
||||||
|
m_printhead_xsize = xsize;
|
||||||
|
m_printhead_ysize = ysize;
|
||||||
|
m_printhead_bordersize = bordersize;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 bitmap_printer_device::dimcolor(u32 incolor, int factor)
|
||||||
|
{
|
||||||
|
return (((incolor & 0xff0000) >> 16) / factor << 16) |
|
||||||
|
(((incolor & 0xff00) >> 8) / factor << 8) |
|
||||||
|
(((incolor & 0xff) >> 0) / factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::draw_printhead(bitmap_rgb32 &bitmap, int x, int y)
|
||||||
|
{
|
||||||
|
int bordx = m_printhead_bordersize;
|
||||||
|
int bordy = m_printhead_bordersize;
|
||||||
|
int offy = 9 + bordy;
|
||||||
|
int sizex = m_printhead_xsize;
|
||||||
|
int sizey = m_printhead_ysize;
|
||||||
|
bitmap.plot_box(x - sizex / 2- bordx, y + offy - bordy, sizex + 2 * bordx, sizey + bordy * 2,
|
||||||
|
m_led_state[0] ? m_printhead_bordercolor : dimcolor(m_printhead_bordercolor, 4));
|
||||||
|
|
||||||
|
for (int i = 1; i <= m_num_leds; i++)
|
||||||
|
bitmap.plot_box(x - sizex / 2, y + offy + ((i -1) * sizey / m_num_leds), sizex,
|
||||||
|
((i+1) * sizey / m_num_leds) - (i * sizey / m_num_leds),
|
||||||
|
m_led_state[i] ? m_printhead_color : dimcolor(m_printhead_color, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// DRAW INCH MARKS AND NUMBERS
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void bitmap_printer_device::draw7seg(u8 data, bool is_digit, int x0, int y0, int width, int height, int thick, bitmap_rgb32 &bitmap, u32 color, u32 erasecolor)
|
||||||
|
{
|
||||||
|
// pass nonzero erasecolor to erase blank segments
|
||||||
|
const u8 pat[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 };
|
||||||
|
u8 seg = is_digit ? pat[data & 0xf] : data;
|
||||||
|
|
||||||
|
if (BIT(seg,0) || erasecolor) bitmap.plot_box(x0, y0, width, thick, BIT(seg,0) ? color : erasecolor);
|
||||||
|
if (BIT(seg,1) || erasecolor) bitmap.plot_box(x0+width, y0+thick, thick, height, BIT(seg,1) ? color : erasecolor);
|
||||||
|
if (BIT(seg,2) || erasecolor) bitmap.plot_box(x0+width, y0+2*thick+height, thick, height, BIT(seg,2) ? color : erasecolor);
|
||||||
|
if (BIT(seg,3) || erasecolor) bitmap.plot_box(x0, y0+2*thick+2*height, width, thick, BIT(seg,3) ? color : erasecolor);
|
||||||
|
if (BIT(seg,4) || erasecolor) bitmap.plot_box(x0-thick, y0+2*thick+height, thick, height, BIT(seg,4) ? color : erasecolor);
|
||||||
|
if (BIT(seg,5) || erasecolor) bitmap.plot_box(x0-thick, y0+thick, thick, height, BIT(seg,5) ? color : erasecolor);
|
||||||
|
if (BIT(seg,6) || erasecolor) bitmap.plot_box(x0, y0+thick+height, width, thick, BIT(seg,6) ? color : erasecolor);
|
||||||
|
if (BIT(seg,7) || erasecolor) bitmap.plot_box(x0+width+thick, y0+2*thick+2*height, thick, thick, BIT(seg,7) ? color : erasecolor); // draw dot
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::draw_number(int number, int x, int y, bitmap_rgb32& bitmap)
|
||||||
|
{
|
||||||
|
std::string s(std::to_string(number));
|
||||||
|
|
||||||
|
int width = std::max(m_hdpi / 15, 1); // 1/10 of inch
|
||||||
|
int height = std::max(m_vdpi / 30, 1);
|
||||||
|
int thick = std::max(m_vdpi / 72, 1);
|
||||||
|
|
||||||
|
for (int i = s.length() - 1; i >= 0; i--)
|
||||||
|
draw7seg( s.at(i) - 0x30, true,
|
||||||
|
x + ( i - s.length()) * (3 * width) - (width), y + height * 3 / 2,
|
||||||
|
width, height, thick, bitmap, 0x000000, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::draw_inch_marks(bitmap_rgb32& bitmap)
|
||||||
|
{
|
||||||
|
static constexpr u32 dark_grey_color = 0x202020;
|
||||||
|
static constexpr u32 light_grey_color = 0xc0c0c0;
|
||||||
|
|
||||||
|
int drawmarks = m_draw_marks_ioport->read();
|
||||||
|
if (!drawmarks) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_vdpi * 11; i += m_vdpi / 4)
|
||||||
|
{
|
||||||
|
int adj_i = i + calc_scroll_y(bitmap) % m_paper_height;
|
||||||
|
int barbase = m_vdpi / 6;
|
||||||
|
int barwidth = ((i % m_vdpi) == 0) ? barbase * 2 : barbase;
|
||||||
|
int barcolor = ((i % m_vdpi) == 0) ? dark_grey_color : light_grey_color;
|
||||||
|
if (adj_i < bitmap.height())
|
||||||
|
{
|
||||||
|
bitmap.plot_box(bitmap.width() - 1 - barwidth, adj_i, barwidth, 1, barcolor);
|
||||||
|
if ((i % m_vdpi) == 0)
|
||||||
|
{
|
||||||
|
if (drawmarks & 2)
|
||||||
|
draw_number(i / m_vdpi, bitmap.width(), adj_i, bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// DRAW PIXEL FUNCTIONS
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void bitmap_printer_device::draw_pixel(int x, int y, int pixelval)
|
||||||
|
{
|
||||||
|
if (y >= m_page_bitmap.height()) y = m_page_bitmap.height() - 1;
|
||||||
|
if (x >= m_page_bitmap.width()) x = m_page_bitmap.width() - 1;
|
||||||
|
|
||||||
|
m_page_bitmap.pix(y, x) = pixelval;
|
||||||
|
|
||||||
|
m_page_dirty = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
int bitmap_printer_device::get_pixel(int x, int y)
|
||||||
|
{
|
||||||
|
if (y >= m_page_bitmap.height()) y = m_page_bitmap.height() - 1;
|
||||||
|
if (x >= m_page_bitmap.width()) x = m_page_bitmap.width() - 1;
|
||||||
|
|
||||||
|
return m_page_bitmap.pix(y, x);
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int& bitmap_printer_device::pix(int y, int x) // reversed y x
|
||||||
|
{
|
||||||
|
if (y >= m_page_bitmap.height()) y = m_page_bitmap.height() - 1;
|
||||||
|
if (x >= m_page_bitmap.width()) x = m_page_bitmap.width() - 1;
|
||||||
|
|
||||||
|
return m_page_bitmap.pix(y,x);
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// WRITE SNAPSHOT TO FILE
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void bitmap_printer_device::write_snapshot_to_file()
|
||||||
|
{
|
||||||
|
machine().popmessage("writing printer snapshot");
|
||||||
|
|
||||||
|
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
|
||||||
|
std::error_condition const filerr = machine().video().open_next(file, "png");
|
||||||
|
|
||||||
|
if (!filerr)
|
||||||
|
{
|
||||||
|
static const rgb_t png_palette[] = { rgb_t::white(), rgb_t::black() };
|
||||||
|
|
||||||
|
// save the paper into a png
|
||||||
|
util::png_write_bitmap(file, nullptr, m_page_bitmap, 2, png_palette);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// STEPPER AND MARGIN FUNCTIONS
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
int bitmap_printer_device::get_top_margin() { return m_top_margin_ioport->read(); }
|
||||||
|
int bitmap_printer_device::get_bottom_margin() { return m_bottom_margin_ioport->read(); }
|
||||||
|
|
||||||
|
bool bitmap_printer_device::check_new_page()
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
// idea here is that you update the position, then check the page, this will do the saving of the page
|
||||||
|
// if this routine returns true, means there's a new page and you should clear the yposition
|
||||||
|
if (m_newpage_flag == 1)
|
||||||
|
{
|
||||||
|
// if you change m_ypos you have to change the stepper abs position too
|
||||||
|
m_ypos = get_top_margin(); // lock to the top of page until we seek horizontally
|
||||||
|
m_pf_stepper->set_absolute_position(get_top_margin() / m_pf_stepper_ratio0 * m_pf_stepper_ratio1);
|
||||||
|
}
|
||||||
|
if (m_ypos > m_page_bitmap.height() - 1 - get_bottom_margin())
|
||||||
|
// If we are at the bottom of the page we will
|
||||||
|
// write the page to a file, then erase the top part of the page
|
||||||
|
// so we can still see the last page printed.
|
||||||
|
{
|
||||||
|
// clear paper to bottom from current position
|
||||||
|
clear_to_pos(m_paper_height - 1, rgb_t::white());
|
||||||
|
|
||||||
|
// save a snapshot
|
||||||
|
write_snapshot_to_file();
|
||||||
|
|
||||||
|
m_newpage_flag = 1;
|
||||||
|
|
||||||
|
// clear page down to visible area, starting from the top of page
|
||||||
|
m_clear_pos = 0;
|
||||||
|
clear_to_pos(m_paper_height - 1 - PAPER_SCREEN_HEIGHT),
|
||||||
|
|
||||||
|
m_ypos = get_top_margin(); // lock to the top of page until we seek horizontally
|
||||||
|
m_pf_stepper->set_absolute_position(get_top_margin() / m_pf_stepper_ratio0 * m_pf_stepper_ratio1);
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
else { clear_to_pos ( m_ypos + m_distfrombottom); }
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bitmap_printer_device::update_stepper_delta(stepper_device * stepper, uint8_t pattern)
|
||||||
|
{
|
||||||
|
int lastpos = stepper->get_absolute_position();
|
||||||
|
stepper->update(pattern);
|
||||||
|
int delta = stepper->get_absolute_position() - lastpos;
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When sending patterns to the update_cr_stepper and update_pf_stepper
|
||||||
|
// functions, the stepper device uses a "standard drive table"
|
||||||
|
// so you have to match that drive table by using a bitswap function.
|
||||||
|
// If the stepper drive is in the opposite direction, just reverse the
|
||||||
|
// bits in the bitswap.
|
||||||
|
|
||||||
|
void bitmap_printer_device::update_cr_stepper(int pattern)
|
||||||
|
{
|
||||||
|
int delta = update_stepper_delta(m_cr_stepper, pattern);
|
||||||
|
|
||||||
|
if (delta != 0)
|
||||||
|
{
|
||||||
|
m_newpage_flag = 0;
|
||||||
|
|
||||||
|
if (delta > 0) {m_cr_direction = 1;}
|
||||||
|
else if (delta < 0) {m_cr_direction = -1;}
|
||||||
|
}
|
||||||
|
m_xpos = m_cr_stepper->get_absolute_position() * m_cr_stepper_ratio0 / m_cr_stepper_ratio1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_printer_device::update_pf_stepper(int pattern)
|
||||||
|
{
|
||||||
|
update_stepper_delta(m_pf_stepper, pattern);
|
||||||
|
m_ypos = m_pf_stepper->get_absolute_position() * m_pf_stepper_ratio0 / m_pf_stepper_ratio1;
|
||||||
|
check_new_page();
|
||||||
|
}
|
||||||
|
|
130
src/devices/machine/bitmap_printer.h
Normal file
130
src/devices/machine/bitmap_printer.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders: Golden Child
|
||||||
|
/*
|
||||||
|
bitmap printer (dot printer)
|
||||||
|
|
||||||
|
* provides a page bitmap to draw on
|
||||||
|
* reads and writes pixels (representing printer dots)
|
||||||
|
* function to save the bitmap
|
||||||
|
* updates the bitmap to screen and draws the printhead
|
||||||
|
* printhead position given in m_xpos and m_ypos
|
||||||
|
* also provides a cr_stepper and a pf_stepper
|
||||||
|
* moving the cr_stepper/pf_stepper will update m_xpos/m_ypos according to ratio specified
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "screen.h"
|
||||||
|
#include "machine/steppers.h"
|
||||||
|
|
||||||
|
#ifndef MAME_MACHINE_BITMAP_PRINTER_H
|
||||||
|
#define MAME_MACHINE_BITMAP_PRINTER_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class bitmap_printer_device : public device_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bitmap_printer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
bitmap_printer_device(const machine_config &mconfig, const char *tag, device_t *owner, int paper_width, int paper_height, int hdpi, int vdpi) :
|
||||||
|
bitmap_printer_device(mconfig, tag, owner, u32(0))
|
||||||
|
{
|
||||||
|
m_paper_width = paper_width;
|
||||||
|
m_paper_height = paper_height;
|
||||||
|
m_hdpi = hdpi;
|
||||||
|
m_vdpi = vdpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bitmap_printer_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
virtual void device_reset_after_children() override;
|
||||||
|
virtual ioport_constructor device_input_ports() const override;
|
||||||
|
virtual void device_add_mconfig(machine_config &config) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
required_device<screen_device> m_screen;
|
||||||
|
public:
|
||||||
|
required_device<stepper_device> m_pf_stepper;
|
||||||
|
required_device<stepper_device> m_cr_stepper;
|
||||||
|
|
||||||
|
required_ioport m_top_margin_ioport;
|
||||||
|
required_ioport m_bottom_margin_ioport;
|
||||||
|
required_ioport m_draw_marks_ioport;
|
||||||
|
int m_cr_direction; // direction of carriage
|
||||||
|
int m_pf_stepper_ratio0;
|
||||||
|
int m_pf_stepper_ratio1;
|
||||||
|
int m_cr_stepper_ratio0;
|
||||||
|
int m_cr_stepper_ratio1;
|
||||||
|
int m_xpos;
|
||||||
|
int m_ypos;
|
||||||
|
|
||||||
|
bitmap_rgb32 m_page_bitmap; // page bitmap
|
||||||
|
private:
|
||||||
|
static constexpr int PAPER_SCREEN_HEIGHT = 384; // match the height of the apple II driver
|
||||||
|
static constexpr int m_distfrombottom = 50; // print position from bottom of screen
|
||||||
|
|
||||||
|
int m_printhead_color;
|
||||||
|
int m_printhead_bordercolor;
|
||||||
|
int m_printhead_bordersize;
|
||||||
|
int m_printhead_xsize;
|
||||||
|
int m_printhead_ysize;
|
||||||
|
int m_page_dirty;
|
||||||
|
int m_paper_width;
|
||||||
|
int m_paper_height;
|
||||||
|
int m_hdpi;
|
||||||
|
int m_vdpi;
|
||||||
|
int m_clear_pos;
|
||||||
|
int m_newpage_flag; // used to keep printhead at the top of page until actual printing
|
||||||
|
static constexpr int MAX_LEDS = 5;
|
||||||
|
int m_led_state[MAX_LEDS];
|
||||||
|
int m_num_leds;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum { LED_ERROR, LED_READY, LED_ONLINE };
|
||||||
|
|
||||||
|
void set_led_state(int led, int value) { m_led_state[led] = value; m_num_leds = std::max(m_num_leds, led); }
|
||||||
|
void set_printhead_color(int headcolor, int bordcolor);
|
||||||
|
void set_printhead_size(int xsize, int ysize, int bordersize);
|
||||||
|
void setheadpos(int x, int y){ if (m_xpos != x) m_newpage_flag = 0; m_xpos = x; m_ypos = y;}
|
||||||
|
|
||||||
|
void write_snapshot_to_file();
|
||||||
|
|
||||||
|
void draw_pixel(int x, int y, int pixelval);
|
||||||
|
int get_pixel(int x, int y);
|
||||||
|
unsigned int& pix(int y, int x);
|
||||||
|
|
||||||
|
void bitmap_clear_band(bitmap_rgb32 &bitmap, int from_line, int to_line, u32 color);
|
||||||
|
void bitmap_clear_band(int from_line, int to_line, u32 color);
|
||||||
|
void clear_to_pos(int to_line, u32 color = 0xffffff);
|
||||||
|
|
||||||
|
int get_top_margin();
|
||||||
|
int get_bottom_margin();
|
||||||
|
bool check_new_page();
|
||||||
|
|
||||||
|
int update_stepper_delta(stepper_device * stepper, uint8_t pattern);
|
||||||
|
void update_cr_stepper(int pattern);
|
||||||
|
void update_pf_stepper(int pattern);
|
||||||
|
|
||||||
|
void set_pf_stepper_ratio(int ratio0, int ratio1) { m_pf_stepper_ratio0 = ratio0; m_pf_stepper_ratio1 = ratio1;}
|
||||||
|
void set_cr_stepper_ratio(int ratio0, int ratio1) { m_cr_stepper_ratio0 = ratio0; m_cr_stepper_ratio1 = ratio1;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void draw_printhead(bitmap_rgb32 &bitmap, int x, int y);
|
||||||
|
u32 dimcolor(u32 incolor, int factor);
|
||||||
|
|
||||||
|
int calc_scroll_y(bitmap_rgb32& bitmap);
|
||||||
|
uint32_t screen_update_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||||
|
|
||||||
|
void draw7seg(u8 data, bool is_digit, int x0, int y0, int width, int height, int thick, bitmap_rgb32 &bitmap, u32 color, u32 erasecolor);
|
||||||
|
void draw_number(int number, int x, int y, bitmap_rgb32& bitmap);
|
||||||
|
void draw_inch_marks(bitmap_rgb32& bitmap);
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_DEVICE_TYPE(BITMAP_PRINTER, bitmap_printer_device)
|
||||||
|
|
||||||
|
#endif // MAME_MACHINE_BITMAP_PRINTER_H
|
@ -30,6 +30,7 @@ e05a30_device::e05a30_device(const machine_config &mconfig, const char *tag, dev
|
|||||||
m_write_centronics_fault(*this),
|
m_write_centronics_fault(*this),
|
||||||
m_write_centronics_select(*this),
|
m_write_centronics_select(*this),
|
||||||
m_write_cpu_reset(*this),
|
m_write_cpu_reset(*this),
|
||||||
|
m_write_ready_led(*this),
|
||||||
m_printhead(0),
|
m_printhead(0),
|
||||||
m_pf_stepper(0),
|
m_pf_stepper(0),
|
||||||
m_cr_stepper(0), m_centronics_data(0), m_centronics_busy(0), m_centronics_nack(0), m_centronics_init(1), m_centronics_strobe(0), m_centronics_data_latch(0), m_centronics_data_latched(0)
|
m_cr_stepper(0), m_centronics_data(0), m_centronics_busy(0), m_centronics_nack(0), m_centronics_init(1), m_centronics_strobe(0), m_centronics_data_latch(0), m_centronics_data_latched(0)
|
||||||
@ -53,6 +54,7 @@ void e05a30_device::device_start()
|
|||||||
m_write_centronics_fault.resolve_safe();
|
m_write_centronics_fault.resolve_safe();
|
||||||
m_write_centronics_select.resolve_safe();
|
m_write_centronics_select.resolve_safe();
|
||||||
m_write_cpu_reset.resolve_safe();
|
m_write_cpu_reset.resolve_safe();
|
||||||
|
m_write_ready_led.resolve_safe();
|
||||||
|
|
||||||
/* register for state saving */
|
/* register for state saving */
|
||||||
save_item(NAME(m_printhead));
|
save_item(NAME(m_printhead));
|
||||||
@ -74,6 +76,7 @@ void e05a30_device::device_reset()
|
|||||||
/* centronics init */
|
/* centronics init */
|
||||||
m_centronics_nack = false;
|
m_centronics_nack = false;
|
||||||
m_centronics_busy = false;
|
m_centronics_busy = false;
|
||||||
|
m_write_ready_led(get_ready_led());
|
||||||
m_write_centronics_ack (!m_centronics_nack);
|
m_write_centronics_ack (!m_centronics_nack);
|
||||||
m_write_centronics_busy ( m_centronics_busy);
|
m_write_centronics_busy ( m_centronics_busy);
|
||||||
m_write_centronics_perror(false);
|
m_write_centronics_perror(false);
|
||||||
@ -154,6 +157,7 @@ WRITE_LINE_MEMBER( e05a30_device::centronics_input_strobe )
|
|||||||
|
|
||||||
m_centronics_data_latched = true;
|
m_centronics_data_latched = true;
|
||||||
m_centronics_busy = true;
|
m_centronics_busy = true;
|
||||||
|
m_write_ready_led(get_ready_led());
|
||||||
m_write_centronics_busy(m_centronics_busy);
|
m_write_centronics_busy(m_centronics_busy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,13 +205,17 @@ void e05a30_device::write(offs_t offset, uint8_t data)
|
|||||||
case 0x04:
|
case 0x04:
|
||||||
m_centronics_nack = BIT(data,5);
|
m_centronics_nack = BIT(data,5);
|
||||||
m_centronics_busy = BIT(data,0);
|
m_centronics_busy = BIT(data,0);
|
||||||
|
m_write_ready_led(get_ready_led());
|
||||||
/* The ActionPrinter 2000 firmware might overwrite the busy signal at
|
/* The ActionPrinter 2000 firmware might overwrite the busy signal at
|
||||||
* address 20AB if the host depends only on the busy signal and
|
* address 20AB if the host depends only on the busy signal and
|
||||||
* doesn't wait for the ack pulse. To avoid skipping input data, we
|
* doesn't wait for the ack pulse. To avoid skipping input data, we
|
||||||
* assume the busy signal cannot be reset while the data hasn't been
|
* assume the busy signal cannot be reset while the data hasn't been
|
||||||
* read. */
|
* read. */
|
||||||
if (m_centronics_data_latched)
|
if (m_centronics_data_latched)
|
||||||
|
{
|
||||||
m_centronics_busy = true;
|
m_centronics_busy = true;
|
||||||
|
m_write_ready_led(get_ready_led());
|
||||||
|
}
|
||||||
m_write_centronics_ack (!m_centronics_nack);
|
m_write_centronics_ack (!m_centronics_nack);
|
||||||
m_write_centronics_busy( m_centronics_busy);
|
m_write_centronics_busy( m_centronics_busy);
|
||||||
break;
|
break;
|
||||||
|
@ -25,6 +25,7 @@ public:
|
|||||||
auto centronics_fault() { return m_write_centronics_fault.bind(); }
|
auto centronics_fault() { return m_write_centronics_fault.bind(); }
|
||||||
auto centronics_select() { return m_write_centronics_select.bind(); }
|
auto centronics_select() { return m_write_centronics_select.bind(); }
|
||||||
auto cpu_reset() { return m_write_cpu_reset.bind(); }
|
auto cpu_reset() { return m_write_cpu_reset.bind(); }
|
||||||
|
auto ready_led() { return m_write_ready_led.bind(); }
|
||||||
|
|
||||||
void write(offs_t offset, uint8_t data);
|
void write(offs_t offset, uint8_t data);
|
||||||
uint8_t read(offs_t offset);
|
uint8_t read(offs_t offset);
|
||||||
@ -41,7 +42,7 @@ public:
|
|||||||
DECLARE_WRITE_LINE_MEMBER( centronics_input_data6 ) { if (state) m_centronics_data |= 0x40; else m_centronics_data &= ~0x40; }
|
DECLARE_WRITE_LINE_MEMBER( centronics_input_data6 ) { if (state) m_centronics_data |= 0x40; else m_centronics_data &= ~0x40; }
|
||||||
DECLARE_WRITE_LINE_MEMBER( centronics_input_data7 ) { if (state) m_centronics_data |= 0x80; else m_centronics_data &= ~0x80; }
|
DECLARE_WRITE_LINE_MEMBER( centronics_input_data7 ) { if (state) m_centronics_data |= 0x80; else m_centronics_data &= ~0x80; }
|
||||||
|
|
||||||
int ready_led() { return !m_centronics_busy; }
|
int get_ready_led() { return !m_centronics_busy; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
@ -60,6 +61,7 @@ private:
|
|||||||
devcb_write_line m_write_centronics_fault;
|
devcb_write_line m_write_centronics_fault;
|
||||||
devcb_write_line m_write_centronics_select;
|
devcb_write_line m_write_centronics_select;
|
||||||
devcb_write_line m_write_cpu_reset;
|
devcb_write_line m_write_cpu_reset;
|
||||||
|
devcb_write_line m_write_ready_led;
|
||||||
|
|
||||||
void update_printhead(int pos, uint8_t data);
|
void update_printhead(int pos, uint8_t data);
|
||||||
void update_pf_stepper(uint8_t data);
|
void update_pf_stepper(uint8_t data);
|
||||||
|
@ -69,6 +69,8 @@ public:
|
|||||||
int get_position() { return m_step_pos; }
|
int get_position() { return m_step_pos; }
|
||||||
/* get current absolute position in half steps */
|
/* get current absolute position in half steps */
|
||||||
int get_absolute_position() { return m_abs_step_pos; }
|
int get_absolute_position() { return m_abs_step_pos; }
|
||||||
|
/* set absolute position in half steps */
|
||||||
|
void set_absolute_position(int pos) { m_abs_step_pos = pos; }
|
||||||
/* get maximum position in half steps */
|
/* get maximum position in half steps */
|
||||||
int get_max() { return m_max_steps; }
|
int get_max() { return m_max_steps; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user