1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
// license:BSD-3-Clause
// copyright-holders:smf
#include "emu.h"
#include "printer.h"
//**************************************************************************
// CENTRONICS PRINTER DEVICE
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(CENTRONICS_PRINTER, centronics_printer_device, "centronics_printer", "Centronics Printer")
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
//-------------------------------------------------
// centronics_printer_device - constructor
//-------------------------------------------------
centronics_printer_device::centronics_printer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, CENTRONICS_PRINTER, tag, owner, clock),
device_centronics_peripheral_interface( mconfig, *this ),
m_strobe(0),
m_data(0),
m_busy(0),
m_printer(*this, "printer")
{
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void centronics_printer_device::device_add_mconfig(machine_config &config)
{
PRINTER(config, m_printer, 0);
m_printer->online_callback().set(FUNC(centronics_printer_device::printer_online));
}
void centronics_printer_device::device_start()
{
m_ack_timer = timer_alloc(FUNC(centronics_printer_device::ack_timer_tick), this);
m_busy_timer = timer_alloc(FUNC(centronics_printer_device::busy_timer_tick), this);
/* register for state saving */
save_item(NAME(m_strobe));
save_item(NAME(m_data));
save_item(NAME(m_busy));
}
void centronics_printer_device::device_reset()
{
m_busy = false;
output_busy(m_busy);
output_fault(1);
output_ack(1);
output_select(1);
}
/*-------------------------------------------------
printer_online - callback that
sets us busy when the printer goes offline
-------------------------------------------------*/
void centronics_printer_device::printer_online(int state)
{
output_perror(!state);
}
/*-------------------------------------------------
ack_timer_tick - update the printer
acknowledge line after an appropriate delay
-------------------------------------------------*/
TIMER_CALLBACK_MEMBER(centronics_printer_device::ack_timer_tick)
{
output_ack(param);
if (!param)
{
/* data is now ready, output it */
m_printer->output(m_data);
/* ready to receive more data, return BUSY to low */
m_busy_timer->adjust(attotime::from_usec(7), 0);
}
}
/*-------------------------------------------------
busy_timer_tick - update the printer's
busy state
-------------------------------------------------*/
TIMER_CALLBACK_MEMBER(centronics_printer_device::busy_timer_tick)
{
m_busy = param;
output_busy(m_busy);
if (param)
{
/* timer to turn ACK low to receive data */
m_ack_timer->adjust(attotime::from_usec(10), 0);
}
else
{
/* timer to return ACK to high state */
m_ack_timer->adjust(attotime::from_usec(5), 1);
}
}
/*-------------------------------------------------
centronics_strobe_w - signal that data is
ready
-------------------------------------------------*/
void centronics_printer_device::input_strobe(int state)
{
/* look for a high -> low transition */
if (m_strobe == true && state == false && m_busy == false)
{
/* STROBE has gone low, data is ready */
m_busy_timer->adjust(attotime::zero, true);
}
m_strobe = state;
}
/*-------------------------------------------------
centronics_prime_w - initialize and reset
printer (centronics mode)
-------------------------------------------------*/
void centronics_printer_device::input_init(int state)
{
/* reset printer if line is low */
if (state == false)
device_reset();
}
|