Previous 199869 Revisions Next

r33458 Wednesday 19th November, 2014 at 22:53:14 UTC by Ramiro Polla
lx810l, ap2000: implement working devices

Improve Epson LX-810L and ActionPrinter 2000 up to a point where they
actually work. Devices boot and enter main input loop, but input is
not yet implemented. It is possible to run the printers' self test.

The code has also been split from lx800.
[src/emu/bus]bus.mak
[src/emu/bus/centronics]ctronics.c epson_lx800.c epson_lx800.h epson_lx810l.c* epson_lx810l.h*
[src/emu/machine]e05a30.c* e05a30.h* machine.mak
[src/mame]mame.mak
[src/mess]mess.mak
[src/mess/includes]amstrad.h
[src/targets]mess.lst

trunk/src/emu/bus/bus.mak
r241969r241970
956956BUSOBJS += $(BUSOBJ)/centronics/dsjoy.o
957957BUSOBJS += $(BUSOBJ)/centronics/epson_ex800.o
958958BUSOBJS += $(BUSOBJ)/centronics/epson_lx800.o
959BUSOBJS += $(BUSOBJ)/centronics/epson_lx810l.o
959960BUSOBJS += $(BUSOBJ)/centronics/printer.o
960961BUSOBJS += $(BUSOBJ)/centronics/digiblst.o
961962$(BUSOBJ)/centronics/epson_ex800.o:    $(EMUOBJ)/layout/ex800.lh
962963$(BUSOBJ)/centronics/epson_lx800.o:    $(EMUOBJ)/layout/lx800.lh
964$(BUSOBJ)/centronics/epson_lx810l.o:   $(EMUOBJ)/layout/lx800.lh
963965endif
964966
965967#-------------------------------------------------
trunk/src/emu/bus/centronics/ctronics.c
r241969r241970
119119#include "comxpl80.h"
120120#include "epson_ex800.h"
121121#include "epson_lx800.h"
122#include "epson_lx810l.h"
122123#include "printer.h"
123124#include "covox.h"
124125
trunk/src/emu/bus/centronics/epson_lx800.c
r241969r241970
1515      input buttons and switches.
1616    - CPU disassembly doesn't seem to indicate conditional JR or RET.
1717
18
19    2014-06-10 Added LX810L, gets caught in a loop almost immediately.
20               IC list:
21               * uPD7810HG (cpu)
22               * E05A30 (gate array)
23               * 2064C (8k RAM)
24               * ER59256 (EEP-ROM - serial nvram)
25               * SLA7020M (step motor driver)
26               * uPC494C (pulse width modulation control)
27               May need to be split off to another driver.
28
29    2014-06-10 Added AP2000, gets caught in the same place as LX810L.
30
3118**********************************************************************/
3219
3320#include "epson_lx800.h"
r241969r241970
4027//**************************************************************************
4128
4229const device_type EPSON_LX800 = &device_creator<epson_lx800_t>;
43const device_type EPSON_LX810L = &device_creator<epson_lx810l_t>;
44const device_type EPSON_AP2000 = &device_creator<epson_ap2000_t>;
4530
4631
4732//-------------------------------------------------
r241969r241970
5540
5641
5742//-------------------------------------------------
58//  ROM( lx810l )
59//-------------------------------------------------
60
61ROM_START( lx810l )
62   ROM_REGION(0x8000, "maincpu", 0)
63   ROM_LOAD("lx810l.ic3c", 0x0000, 0x8000, CRC(a66454e1) SHA1(8e6f2f98abcbd8af6e34b9ba746edf0d18aef843) )
64ROM_END
65
66
67//-------------------------------------------------
68//  ROM( ap2000 )
69//-------------------------------------------------
70
71ROM_START( ap2000 )
72   ROM_REGION(0x8000, "maincpu", 0)
73   ROM_LOAD("ap2k.ic3c", 0x0000, 0x8000, CRC(ee7294b7) SHA1(219ffa6ff661ce95d5772c9fc1967093718f04e9) )
74ROM_END
75
76
77//-------------------------------------------------
7843//  rom_region - device-specific ROM region
7944//-------------------------------------------------
8045
r241969r241970
8550
8651
8752//-------------------------------------------------
88//  rom_region - device-specific ROM region
89//-------------------------------------------------
90
91const rom_entry *epson_lx810l_t::device_rom_region() const
92{
93   return ROM_NAME( lx810l );
94}
95
96
97//-------------------------------------------------
98//  rom_region - device-specific ROM region
99//-------------------------------------------------
100
101const rom_entry *epson_ap2000_t::device_rom_region() const
102{
103   return ROM_NAME( ap2000 );
104}
105
106
107//-------------------------------------------------
10853//  ADDRESS_MAP( lx800_mem )
10954//-------------------------------------------------
11055
r241969r241970
273218{
274219}
275220
276epson_lx810l_t::epson_lx810l_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
277   : epson_lx800_t(mconfig, EPSON_LX810L, "Epson LX-810L", tag, owner, clock, "lx810l", __FILE__) { }
278221
279epson_ap2000_t::epson_ap2000_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
280   : epson_lx800_t(mconfig, EPSON_AP2000, "Epson ActionPrinter 2000", tag, owner, clock, "ap2000", __FILE__) { }
281
282
283222//-------------------------------------------------
284223//  device_start - device-specific startup
285224//-------------------------------------------------
trunk/src/emu/bus/centronics/epson_lx800.h
r241969r241970
6767};
6868
6969
70// ======================> epson_lx810l_t
7170
72class epson_lx810l_t :  public epson_lx800_t
73{
74public:
75   // construction/destruction
76   epson_lx810l_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
77
78   // optional information overrides
79   virtual const rom_entry *device_rom_region() const;
80};
81
82
83// ======================> epson_ap2000_t
84
85class epson_ap2000_t :  public epson_lx800_t
86{
87public:
88   // construction/destruction
89   epson_ap2000_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
90
91   // optional information overrides
92   virtual const rom_entry *device_rom_region() const;
93};
94
95
96
9771// device type definition
9872extern const device_type EPSON_LX800;
99extern const device_type EPSON_LX810L;
100extern const device_type EPSON_AP2000;
10173
10274
10375
trunk/src/emu/bus/centronics/epson_lx810l.c
r0r241970
1/*
2 * Epson LX-810L dot matrix printer emulation
3 *
4 * Copyright: 2014 Ramiro Polla
5 *                 Felipe Sanches
6 * License: BSD-3-Clause
7 *
8 * IC list:
9 *   uPD7810HG (cpu)
10 *   E05A30 (gate array)
11 *   2064C (8k RAM)
12 *   ER59256 (EEP-ROM - serial nvram)
13 *   SLA7020M (step motor driver)
14 *   uPC494C (pulse width modulation control)
15 *
16 * Devices boot and enter main input loop, but input is not yet implemented.
17 *
18 * It is possible to run the printers' self test with this procedure:
19 * - Turn on device;
20 * - Toggle Line Feed button (press 'L');
21 * - Reset device;
22 * - Toggle Line Feed button again;
23 * - Press Online button (press 'O');
24 * - Press Online button again;
25 *
26 * The printer's carriage will seek home, it will pull in paper for a while,
27 * and it will start printing some test data. The Online LED will blink at
28 * each line. Look at the output from the fire signal to see what's actually
29 * being printed (epson_lx810l_t::co0_w()).
30 */
31
32#include "epson_lx810l.h"
33extern const char layout_lx800[]; /* use layout from lx800 */
34
35//#define LX810LDEBUG
36#ifdef LX810LDEBUG
37#define LX810LLOG(...) fprintf(stderr, __VA_ARGS__)
38#else
39#define LX810LLOG(...)
40#endif
41
42//**************************************************************************
43//  DEVICE DEFINITIONS
44//**************************************************************************
45
46const device_type EPSON_LX810L = &device_creator<epson_lx810l_t>;
47const device_type EPSON_AP2000 = &device_creator<epson_ap2000_t>;
48
49
50//-------------------------------------------------
51//  ROM( lx810l )
52//-------------------------------------------------
53
54ROM_START( lx810l )
55   ROM_REGION(0x8000, "maincpu", 0)
56   ROM_LOAD("lx810l.ic3c", 0x0000, 0x8000, CRC(a66454e1) SHA1(8e6f2f98abcbd8af6e34b9ba746edf0d18aef843) )
57   ROM_REGION(0x20, "eeprom", 0)
58   ROM_LOAD( "at93c06", 0x00, 0x20, NO_DUMP )
59ROM_END
60
61
62//-------------------------------------------------
63//  ROM( ap2000 )
64//-------------------------------------------------
65
66ROM_START( ap2000 )
67   ROM_REGION(0x8000, "maincpu", 0)
68   ROM_LOAD("ap2k.ic3c", 0x0000, 0x8000, CRC(ee7294b7) SHA1(219ffa6ff661ce95d5772c9fc1967093718f04e9) )
69   ROM_REGION(0x20, "eeprom", 0)
70   ROM_LOAD( "at93c06", 0x00, 0x20, NO_DUMP )
71ROM_END
72
73
74//-------------------------------------------------
75//  rom_region - device-specific ROM region
76//-------------------------------------------------
77
78const rom_entry *epson_lx810l_t::device_rom_region() const
79{
80   return ROM_NAME( lx810l );
81}
82
83
84//-------------------------------------------------
85//  rom_region - device-specific ROM region
86//-------------------------------------------------
87
88const rom_entry *epson_ap2000_t::device_rom_region() const
89{
90   return ROM_NAME( ap2000 );
91}
92
93
94//-------------------------------------------------
95//  ADDRESS_MAP( lx810l_mem )
96//-------------------------------------------------
97
98static ADDRESS_MAP_START( lx810l_mem, AS_PROGRAM, 8, epson_lx810l_t )
99   AM_RANGE(0x0000, 0x7fff) AM_ROM /* 32k firmware */
100   AM_RANGE(0x8000, 0x9fff) AM_RAM /* 8k external RAM */
101   AM_RANGE(0xa000, 0xbfff) AM_READWRITE(fakemem_r, fakemem_w) /* fake memory, write one, set all */
102   AM_RANGE(0xc000, 0xdfff) AM_MIRROR(0x1ff0) AM_DEVREADWRITE("ic3b", e05a30_device, read, write)
103   AM_RANGE(0xe000, 0xfeff) AM_NOP /* not used */
104   AM_RANGE(0xff00, 0xffff) AM_RAM /* internal CPU RAM */
105ADDRESS_MAP_END
106
107
108//-------------------------------------------------
109//  ADDRESS_MAP( lx810l_io )
110//-------------------------------------------------
111
112static ADDRESS_MAP_START( lx810l_io, AS_IO, 8, epson_lx810l_t )
113   AM_RANGE(UPD7810_PORTA, UPD7810_PORTA) AM_READWRITE(porta_r, porta_w)
114   AM_RANGE(UPD7810_PORTB, UPD7810_PORTB) AM_READWRITE(portb_r, portb_w)
115   AM_RANGE(UPD7810_PORTC, UPD7810_PORTC) AM_READWRITE(portc_r, portc_w)
116ADDRESS_MAP_END
117
118
119//-------------------------------------------------
120//  MACHINE_DRIVER( epson_lx810l )
121//-------------------------------------------------
122
123static MACHINE_CONFIG_FRAGMENT( epson_lx810l )
124   /* basic machine hardware */
125   MCFG_CPU_ADD("maincpu", UPD7810, XTAL_14_7456MHz)
126   MCFG_CPU_PROGRAM_MAP(lx810l_mem)
127   MCFG_CPU_IO_MAP(lx810l_io)
128   MCFG_UPD7810_AN0(READ8(epson_lx810l_t, an0_r))
129   MCFG_UPD7810_AN1(READ8(epson_lx810l_t, an1_r))
130   MCFG_UPD7810_AN2(READ8(epson_lx810l_t, an2_r))
131   MCFG_UPD7810_AN3(READ8(epson_lx810l_t, an3_r))
132   MCFG_UPD7810_AN4(READ8(epson_lx810l_t, an4_r))
133   MCFG_UPD7810_AN5(READ8(epson_lx810l_t, an5_r))
134   MCFG_UPD7810_AN6(READ8(epson_lx810l_t, an6_r))
135   MCFG_UPD7810_AN7(READ8(epson_lx810l_t, an7_r))
136   MCFG_UPD7810_CO0(WRITELINE(epson_lx810l_t, co0_w))
137   MCFG_UPD7810_CO1(WRITELINE(epson_lx810l_t, co1_w))
138
139   MCFG_DEFAULT_LAYOUT(layout_lx800)
140
141   /* audio hardware */
142   MCFG_SPEAKER_STANDARD_MONO("mono")
143   MCFG_SOUND_ADD("beeper", BEEP, 0)
144   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
145   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
146
147   /* gate array */
148   MCFG_DEVICE_ADD("ic3b", E05A30, 0)
149   MCFG_E05A30_PRINTHEAD_CALLBACK(WRITE16(epson_lx810l_t, printhead))
150   MCFG_E05A30_PF_STEPPER_CALLBACK(WRITE8(epson_lx810l_t, pf_stepper))
151   MCFG_E05A30_CR_STEPPER_CALLBACK(WRITE8(epson_lx810l_t, cr_stepper))
152   MCFG_E05A30_READY_CALLBACK(WRITELINE(epson_lx810l_t, e05a30_ready))
153
154   /* 256-bit eeprom */
155   MCFG_EEPROM_SERIAL_93C06_ADD("eeprom")
156MACHINE_CONFIG_END
157
158//-------------------------------------------------
159//  machine_config_additions - device-specific
160//  machine configurations
161//-------------------------------------------------
162
163machine_config_constructor epson_lx810l_t::device_mconfig_additions() const
164{
165   return MACHINE_CONFIG_NAME( epson_lx810l );
166}
167
168
169/***************************************************************************
170    INPUT PORTS
171***************************************************************************/
172
173static INPUT_PORTS_START( epson_lx810l )
174
175   /* Buttons on printer */
176   PORT_START("ONLINE")
177   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("On Line") PORT_CODE(KEYCODE_O) PORT_CHANGED_MEMBER(DEVICE_SELF, epson_lx810l_t, online_sw, NULL)
178   PORT_START("FORMFEED")
179   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Form Feed") PORT_CODE(KEYCODE_F) PORT_TOGGLE
180   PORT_START("LINEFEED")
181   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_L) PORT_TOGGLE
182   PORT_START("LOADEJECT")
183   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Load/Eject") PORT_CODE(KEYCODE_E)
184
185   /* DIPSW1 */
186   PORT_START("DIPSW1")
187
188   PORT_DIPNAME(0x01, 0x01, "Character spacing")
189   PORT_DIPLOCATION("DIP:1")
190   PORT_DIPSETTING(0x01, "12 cpi") /* default */
191   PORT_DIPSETTING(0x00, "10 cpi")
192
193   PORT_DIPNAME(0x02, 0x00, "Shape of zero")
194   PORT_DIPLOCATION("DIP:2")
195   PORT_DIPSETTING(0x02, "Slashed")
196   PORT_DIPSETTING(0x00, "Not slashed") /* default */
197
198   PORT_DIPNAME(0x0c, 0x08, "Page length")
199   PORT_DIPLOCATION("DIP:3,4")
200   PORT_DIPSETTING(0x00, "11 inches")
201   PORT_DIPSETTING(0x04, "12 inches")
202   PORT_DIPSETTING(0x08, "8.5 inches") /* default */
203   PORT_DIPSETTING(0x0c, "11.7 inches")
204
205   PORT_DIPNAME(0x10, 0x10, "Character table")
206   PORT_DIPLOCATION("DIP:5")
207   PORT_DIPSETTING(0x10, "Graphics") /* default */
208   PORT_DIPSETTING(0x00, "Italics")
209
210   PORT_DIPNAME(0xe0, 0xe0, "International characters and PC selection")
211   PORT_DIPLOCATION("DIP:6,7,8")
212   PORT_DIPSETTING(0xe0, "United States") /* default */
213   PORT_DIPSETTING(0x60, "France")
214   PORT_DIPSETTING(0xa0, "Germany")
215   PORT_DIPSETTING(0x20, "United Kingdom")
216   PORT_DIPSETTING(0xc0, "Denmark")
217   PORT_DIPSETTING(0x40, "Sweden")
218   PORT_DIPSETTING(0x80, "Italy")
219   PORT_DIPSETTING(0x00, "Spain")
220
221   /* DIPSW2 */
222   PORT_START("DIPSW2")
223
224   PORT_DIPNAME(0x01, 0x01, "Short tear-off")
225   PORT_DIPLOCATION("DIP:1")
226   PORT_DIPSETTING(0x01, "Invalid") /* default */
227   PORT_DIPSETTING(0x00, "Valid")
228
229   PORT_DIPNAME(0x02, 0x00, "Cut-sheet feeder mode")
230   PORT_DIPLOCATION("DIP:2")
231   PORT_DIPSETTING(0x02, "ON")
232   PORT_DIPSETTING(0x00, "OFF") /* default */
233
234   PORT_DIPNAME(0x04, 0x00, "Skip-over-perforation")
235   PORT_DIPLOCATION("DIP:3")
236   PORT_DIPSETTING(0x04, "ON")
237   PORT_DIPSETTING(0x00, "OFF") /* default */
238
239   PORT_DIPNAME(0x08, 0x00, "Auto line feed")
240   PORT_DIPLOCATION("DIP:4")
241   PORT_DIPSETTING(0x08, "ON")
242   PORT_DIPSETTING(0x00, "OFF") /* default */
243
244INPUT_PORTS_END
245
246
247//-------------------------------------------------
248//  input_ports - device-specific input ports
249//-------------------------------------------------
250
251ioport_constructor epson_lx810l_t::device_input_ports() const
252{
253   return INPUT_PORTS_NAME( epson_lx810l );
254}
255
256INPUT_CHANGED_MEMBER(epson_lx810l_t::online_sw)
257{
258   m_maincpu->set_input_line(UPD7810_INTF2, newval ? CLEAR_LINE : ASSERT_LINE);
259}
260
261
262//**************************************************************************
263//  LIVE DEVICE
264//**************************************************************************
265
266//-------------------------------------------------
267//  epson_lx810l_t - constructor
268//-------------------------------------------------
269
270epson_lx810l_t::epson_lx810l_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
271   device_t(mconfig, EPSON_LX810L, "Epson LX-810L", tag, owner, clock, "lx810l", __FILE__),
272   device_centronics_peripheral_interface(mconfig, *this),
273   m_maincpu(*this, "maincpu"),
274   m_eeprom(*this, "eeprom"),
275   m_speaker(*this, "speaker"),
276   m_93c06_clk(0),
277   m_93c06_cs(0),
278   m_printhead(0),
279   m_pf_pos_abs(200),
280   m_cr_pos_abs(200),
281   m_last_fire(0)
282{
283}
284
285epson_lx810l_t::epson_lx810l_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
286   device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
287   device_centronics_peripheral_interface(mconfig, *this),
288   m_maincpu(*this, "maincpu"),
289   m_eeprom(*this, "eeprom"),
290   m_speaker(*this, "speaker"),
291   m_93c06_clk(0),
292   m_93c06_cs(0),
293   m_printhead(0),
294   m_pf_pos_abs(200),
295   m_cr_pos_abs(200),
296   m_last_fire(0)
297{
298}
299
300epson_ap2000_t::epson_ap2000_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
301   : epson_lx810l_t(mconfig, EPSON_AP2000, "Epson ActionPrinter 2000", tag, owner, clock, "ap2000", __FILE__)
302{ }
303
304
305//-------------------------------------------------
306//  device_start - device-specific startup
307//-------------------------------------------------
308
309static const stepper_interface lx810l_pf_stepper =
310{
311   STARPOINT_48STEP_REEL,
312   16,
313   24,
314   0x00,
315   0
316};
317
318static const stepper_interface lx810l_cr_stepper =
319{
320   STARPOINT_48STEP_REEL,
321   16,
322   24,
323   0x00,
324   2
325};
326
327void epson_lx810l_t::device_start()
328{
329   stepper_config(machine(), 0, &lx810l_pf_stepper);
330   stepper_config(machine(), 1, &lx810l_cr_stepper);
331}
332
333
334//-------------------------------------------------
335//  device_reset - device-specific reset
336//-------------------------------------------------
337
338void epson_lx810l_t::device_reset()
339{
340   m_speaker->level_w(0);
341}
342
343
344/***************************************************************************
345    FAKEMEM READ/WRITE
346***************************************************************************/
347
348READ8_MEMBER(epson_lx810l_t::fakemem_r)
349{
350   return m_fakemem;
351}
352
353WRITE8_MEMBER(epson_lx810l_t::fakemem_w)
354{
355   m_fakemem = data;
356}
357
358
359/***************************************************************************
360    I/O PORTS
361***************************************************************************/
362
363/*
364 * PA0  R   CN7 sensor (Home Position, HP, active low)
365 * PA1  R   CN6 sensor (Paper-End, PE, active low)
366 * PA2  R   CN4 sensor (Release, low = tractor)
367 * PA3   W  Stepper motor voltage reference (these 3 pins make up one voltage)
368 * PA4   W  Stepper motor voltage reference (these 3 pins make up one voltage)
369 * PA5   W  Stepper motor voltage reference (these 3 pins make up one voltage)
370 * PA6  R   Line Feed SWITCH
371 * PA7  R   Form Feed SWITCH
372 */
373READ8_MEMBER( epson_lx810l_t::porta_r )
374{
375   UINT8 result = 0;
376   UINT8 hp_sensor = m_cr_pos_abs <= 0 ? 0 : 1;
377   UINT8 pe_sensor = m_pf_pos_abs <= 0 ? 1 : 0;
378
379   result |= hp_sensor; /* home position */
380   result |= pe_sensor << 1; /* paper end */
381   result |= ioport("LINEFEED")->read() << 6;
382   result |= ioport("FORMFEED")->read() << 7;
383
384   LX810LLOG("%s: lx810l_PA_r(%02x): result %02x\n", machine().describe_context(), offset, result);
385
386   return result;
387}
388
389WRITE8_MEMBER( epson_lx810l_t::porta_w )
390{
391   LX810LLOG("%s: lx810l_PA_w(%02x): %02x: stepper vref %d\n", machine().describe_context(), offset, data, BIT(data, 3) | (BIT(data, 4)<<1) | (BIT(data, 5)<<2));
392}
393
394/*
395 * PB0  R   DIP1.0 & 93C06.DO
396 * PB1  RW  DIP1.1 & 93C06.DI
397 * PB2  R   DIP1.2
398 * PB3  R   DIP1.3
399 * PB4  R   DIP1.4
400 * PB5  R   DIP1.5
401 * PB6  R   DIP1.6
402 * PB7  R   DIP1.7
403 */
404READ8_MEMBER( epson_lx810l_t::portb_r )
405{
406   UINT8 result = ~ioport("DIPSW1")->read();
407
408   /* if 93C06 is selected */
409   if (m_93c06_cs) {
410      UINT8 do_r = m_eeprom->do_read();
411      result &= 0xfe;
412      result |= do_r;
413   }
414
415   LX810LLOG("%s: lx810l_PB_r(%02x): result %02x\n", machine().describe_context(), offset, result);
416
417   return result;
418}
419
420WRITE8_MEMBER( epson_lx810l_t::portb_w )
421{
422   UINT8 data_in = BIT(data, 1);
423
424   /* if 93C06 is selected */
425   if (m_93c06_cs)
426      m_eeprom->di_write(data_in);
427
428   LX810LLOG("%s: lx810l_PB_w(%02x): %02x: 93c06 data %d\n", machine().describe_context(), offset, data, data_in);
429}
430
431/*
432 * PC0   W  TXD        serial i/o txd, also TAMA.25
433 * PC1  R   RXD        serial i/o rxd, also E05A30.28
434 * PC2   W  ONLINE LP  online led
435 * PC3  R   ONLINE SW  online switch
436 * PC4   W  93C06.SK
437 * PC5   W  93C06.CS
438 * PC6   W  FIRE       drive pulse width signal, also E05A30.57
439 * PC7   W  BUZZER     buzzer signal
440 */
441READ8_MEMBER( epson_lx810l_t::portc_r )
442{
443   UINT8 result = 0;
444
445   /* result |= ioport("serial")->read() << 1; */
446   result |= !ioport("ONLINE")->read() << 3;
447   result |= m_93c06_clk << 4;
448   result |= m_93c06_cs  << 5;
449
450   LX810LLOG("%s: lx810l_PC_r(%02x): %02x\n", machine().describe_context(), offset, result);
451
452   return result;
453}
454
455WRITE8_MEMBER( epson_lx810l_t::portc_w )
456{
457   /* ioport("serial")->write(BIT(data, 0)); */
458
459   m_93c06_clk =  BIT(data, 4);
460   m_93c06_cs  = !BIT(data, 5);
461
462   LX810LLOG("%s: PC_w(%02x): %02x 93c06 clk: %d cs: %d\n", machine().describe_context(), offset, data, m_93c06_clk, m_93c06_cs);
463
464   m_eeprom->clk_write(m_93c06_clk ? ASSERT_LINE : CLEAR_LINE);
465   m_eeprom->cs_write (m_93c06_cs  ? ASSERT_LINE : CLEAR_LINE);
466
467   output_set_value("online_led", !BIT(data, 2));
468}
469
470
471/***************************************************************************
472    GATE ARRAY
473***************************************************************************/
474
475WRITE16_MEMBER( epson_lx810l_t::printhead )
476{
477   m_printhead = data;
478}
479
480WRITE8_MEMBER( epson_lx810l_t::pf_stepper )
481{
482   stepper_update(0, data);
483   m_pf_pos_abs = 200 - stepper_get_absolute_position(0);
484
485   LX810LLOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_pf_pos_abs);
486}
487
488WRITE8_MEMBER( epson_lx810l_t::cr_stepper )
489{
490   stepper_update(1, data);
491   m_cr_pos_abs = 200 - stepper_get_absolute_position(1);
492
493   LX810LLOG("%s: %s(%02x); abs %d\n", machine().describe_context(), __func__, data, m_cr_pos_abs);
494}
495
496WRITE_LINE_MEMBER( epson_lx810l_t::e05a30_ready )
497{
498   m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
499}
500
501
502/***************************************************************************
503    Extended Timer Output
504***************************************************************************/
505
506WRITE_LINE_MEMBER( epson_lx810l_t::co0_w )
507{
508   /* TODO Draw the dots on the paper using this information. */
509
510   /* Printhead is being fired on !state. */
511   if (!state) {
512      int pos = m_cr_pos_abs;
513
514      /* HACK to get fire positions for motor in movement. The firmware
515       * issues two half-steps one immediately after the other. A timer
516       * fires the printhead twice. Supposedly, the first time the
517       * printhead is fired, it is midway between one step and the other.
518       * Ideally, the stepper motor interface should model the physics
519       * of the motors. For the moment, we adjust pos to get the
520       * intermediate position.
521       */
522
523      if      (m_cr_pos_abs > m_last_fire + 1)
524         pos--;
525      else if (m_cr_pos_abs < m_last_fire - 1)
526         pos++;
527
528      LX810LLOG("FIRE0 %d %d %04x\n", m_pf_pos_abs, pos, m_printhead);
529
530      m_last_fire = pos;
531   }
532}
533
534WRITE_LINE_MEMBER( epson_lx810l_t::co1_w )
535{
536   m_speaker->level_w(state);
537}
538
539
540/***************************************************************************
541    ADC
542***************************************************************************/
543
544READ8_MEMBER(epson_lx810l_t::an0_r)
545{
546   UINT8 res = !!(ioport("DIPSW2")->read() & 0x01);
547   return res - 1; /* DIPSW2.1 */
548}
549
550READ8_MEMBER(epson_lx810l_t::an1_r)
551{
552   UINT8 res = !!(ioport("DIPSW2")->read() & 0x02);
553   return res - 1; /* DIPSW2.2 */
554}
555
556READ8_MEMBER(epson_lx810l_t::an2_r)
557{
558   UINT8 res = !!(ioport("DIPSW2")->read() & 0x04);
559   return res - 1; /* DIPSW2.3 */
560}
561
562READ8_MEMBER(epson_lx810l_t::an3_r)
563{
564   UINT8 res = !!(ioport("DIPSW2")->read() & 0x08);
565   return res - 1; /* DIPSW2.4 */
566}
567
568READ8_MEMBER(epson_lx810l_t::an4_r)
569{
570   return 0xff;
571}
572
573READ8_MEMBER(epson_lx810l_t::an5_r)
574{
575   return 0xCB; /* motor voltage, 0xcb = 24V */
576}
577
578READ8_MEMBER(epson_lx810l_t::an6_r)
579{
580   UINT8 res = !ioport("LOADEJECT")->read();
581   return res - 1;
582}
583
584READ8_MEMBER(epson_lx810l_t::an7_r)
585{
586   return 0xff;
587}
trunk/src/emu/bus/centronics/epson_lx810l.h
r0r241970
1/*
2 * Epson LX-810L dot matrix printer emulation
3 *
4 * Copyright: 2014 Ramiro Polla
5 *                 Felipe Sanches
6 * License: BSD-3-Clause
7 */
8
9#pragma once
10
11#ifndef __EPSON_LX810L__
12#define __EPSON_LX810L__
13
14#include "emu.h"
15#include "ctronics.h"
16#include "cpu/upd7810/upd7810.h"
17#include "machine/e05a30.h"
18#include "machine/eepromser.h"
19#include "machine/steppers.h"
20#include "sound/beep.h"
21#include "sound/speaker.h"
22
23
24//**************************************************************************
25//  TYPE DEFINITIONS
26//**************************************************************************
27
28// ======================> epson_lx810l_t
29
30class epson_lx810l_t : public device_t,
31                       public device_centronics_peripheral_interface
32{
33public:
34   // construction/destruction
35   epson_lx810l_t(const machine_config &mconfig, const char *tag,
36                  device_t *owner, UINT32 clock);
37   epson_lx810l_t(const machine_config &mconfig, device_type type,
38                  const char *name, const char *tag, device_t *owner,
39                  UINT32 clock, const char *shortname, const char *source);
40
41   // optional information overrides
42   virtual const rom_entry *device_rom_region() const;
43   virtual machine_config_constructor device_mconfig_additions() const;
44   virtual ioport_constructor device_input_ports() const;
45
46   DECLARE_READ8_MEMBER(porta_r);
47   DECLARE_WRITE8_MEMBER(porta_w);
48   DECLARE_READ8_MEMBER(portb_r);
49   DECLARE_WRITE8_MEMBER(portb_w);
50   DECLARE_READ8_MEMBER(portc_r);
51   DECLARE_WRITE8_MEMBER(portc_w);
52
53   /* Extended Timer Output */
54   DECLARE_WRITE_LINE_MEMBER(co0_w);
55   DECLARE_WRITE_LINE_MEMBER(co1_w);
56
57   /* ADC */
58   DECLARE_READ8_MEMBER(an0_r);
59   DECLARE_READ8_MEMBER(an1_r);
60   DECLARE_READ8_MEMBER(an2_r);
61   DECLARE_READ8_MEMBER(an3_r);
62   DECLARE_READ8_MEMBER(an4_r);
63   DECLARE_READ8_MEMBER(an5_r);
64   DECLARE_READ8_MEMBER(an6_r);
65   DECLARE_READ8_MEMBER(an7_r);
66
67   /* fake memory I/O to get past memory reset check */
68   DECLARE_READ8_MEMBER(fakemem_r);
69   DECLARE_WRITE8_MEMBER(fakemem_w);
70
71   /* GATE ARRAY */
72   DECLARE_WRITE16_MEMBER(printhead);
73   DECLARE_WRITE8_MEMBER(pf_stepper);
74   DECLARE_WRITE8_MEMBER(cr_stepper);
75   DECLARE_WRITE_LINE_MEMBER(e05a30_ready);
76
77   /* Panel buttons */
78   DECLARE_INPUT_CHANGED_MEMBER(online_sw);
79
80protected:
81   // device-level overrides
82   virtual void device_start();
83   virtual void device_reset();
84
85private:
86   required_device<cpu_device> m_maincpu;
87   required_device<eeprom_serial_93cxx_device> m_eeprom;
88   required_device<speaker_sound_device> m_speaker;
89
90   int m_93c06_clk;
91   int m_93c06_cs;
92   UINT16 m_printhead;
93   int m_pf_pos_abs;
94   int m_cr_pos_abs;
95   int m_last_fire; /* HACK to get fire positions for motor in movement */
96   UINT8 m_fakemem;
97};
98
99// ======================> epson_ap2000_t
100
101class epson_ap2000_t : public epson_lx810l_t
102{
103public:
104   // construction/destruction
105   epson_ap2000_t(const machine_config &mconfig, const char *tag,
106                  device_t *owner, UINT32 clock);
107
108   // optional information overrides
109   virtual const rom_entry *device_rom_region() const;
110};
111
112
113// device type definition
114extern const device_type EPSON_LX810L;
115extern const device_type EPSON_AP2000;
116
117#endif
trunk/src/emu/machine/e05a30.c
r0r241970
1/*
2 * E05A30 Gate Array (used in the Epson ActionPrinter 2000)
3 *
4 * Copyright: 2014 Ramiro Polla
5 * License: BSD-3-Clause
6 */
7
8#include "emu.h"
9#include "e05a30.h"
10
11//#define E05A30DEBUG
12#ifdef E05A30DEBUG
13#define LOG(...) fprintf(stderr, __VA_ARGS__)
14#else
15#define LOG(...)
16#endif
17
18
19/*****************************************************************************
20    DEVICE INTERFACE
21*****************************************************************************/
22
23const device_type E05A30 = &device_creator<e05a30_device>;
24
25e05a30_device::e05a30_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
26   : device_t(mconfig, E05A30, "E05A30", tag, owner, clock, "e05a30", __FILE__),
27   m_write_printhead(*this),
28   m_write_pf_stepper(*this),
29   m_write_cr_stepper(*this),
30   m_write_ready(*this),
31   m_printhead(0),
32   m_pf_stepper(0),
33   m_cr_stepper(0)
34{
35}
36
37//-------------------------------------------------
38//  device_start - device-specific startup
39//-------------------------------------------------
40
41void e05a30_device::device_start()
42{
43   /* resolve callbacks */
44   m_write_printhead.resolve_safe();
45   m_write_pf_stepper.resolve_safe();
46   m_write_cr_stepper.resolve_safe();
47   m_write_ready.resolve_safe();
48
49   /* register for state saving */
50   save_item(NAME(m_printhead));
51   save_item(NAME(m_pf_stepper));
52   save_item(NAME(m_cr_stepper));
53}
54
55//-------------------------------------------------
56//  device_reset - device-specific reset
57//-------------------------------------------------
58
59void e05a30_device::device_reset()
60{
61   m_printhead  = 0x00;
62   m_pf_stepper = 0x00;
63   m_cr_stepper = 0x00;
64
65   m_write_ready(1);
66}
67
68
69/***************************************************************************
70    PRINT HEAD
71***************************************************************************/
72
73/* The e05a30 controls the printhead through MMIOs 0xC005 and 0xC006.
74 * MMIO 0xC006 keeps the first 8 pins.
75 * MMIO 0xC005 keeps the 9th pin in the MSB.
76 */
77
78void e05a30_device::update_printhead(int pos, UINT8 data)
79{
80   if (pos == 0) {
81      m_printhead &= 0x00ff;
82      m_printhead |= (UINT16) !!data << 8;
83   } else {
84      m_printhead &= 0xff00;
85      m_printhead |= data;
86   }
87   m_write_printhead(m_printhead);
88}
89
90/***************************************************************************
91    STEPPER MOTORS
92***************************************************************************/
93
94/* The e05a30 controls two stepper motors:
95 * - The Paper Feed stepper motor is controlled through MMIO 0xC007
96 * - The Carriage Return stepper motor is controlled through MMIO 0xC008
97 * The Carriage Return stepper motor is used throug the SLA7020M driver. It
98 * is therefore necessary to translate the input data from the SLA7020M
99 * format to a format describing the 4 phases of a stepper motor.
100 * For the PF motor, the output data is fed directly to the stepper motor.
101 */
102
103void e05a30_device::update_pf_stepper(UINT8 data)
104{
105   m_pf_stepper = data & 0x0f;
106   m_write_pf_stepper(m_pf_stepper);
107}
108
109static UINT8 cr_sla7020m(UINT8 data)
110{
111   bool ina = BIT(data, 0);
112   bool inb = BIT(data, 1);
113   bool tda = BIT(data, 2);
114   bool tdb = BIT(data, 3);
115   bool outa0 =  ina && tda;
116   bool outa1 = !ina && tda;
117   bool outb0 =  inb && tdb;
118   bool outb1 = !inb && tdb;
119   return (outb1<<3)|(outb0<<2)|(outa1<<1)|(outa0<<0);
120}
121void e05a30_device::update_cr_stepper(UINT8 data)
122{
123   m_cr_stepper = data & 0x0f;
124   m_write_cr_stepper(cr_sla7020m(m_cr_stepper));
125}
126
127
128/***************************************************************************
129    IMPLEMENTATION
130***************************************************************************/
131
132WRITE8_MEMBER( e05a30_device::write )
133{
134   LOG("%s: e05a30_w([0xC0%02x]): %02x\n", space.machine().describe_context(), offset, data);
135
136   switch (offset) {
137   /* printhead */
138   case 0x05: update_printhead(0, data); break;
139   case 0x06: update_printhead(1, data); break;
140   /* paper feed stepper motor */
141   case 0x07: update_pf_stepper(data); break;
142   /* carriage return stepper motor */
143   case 0x08: update_cr_stepper(data); break;
144   }
145}
146
147READ8_MEMBER( e05a30_device::read )
148{
149   UINT8 result = 0;
150
151   LOG("%s: e05a30_r([0xC0%02x]): ", space.machine().describe_context(), offset);
152
153   switch (offset) {
154   /* paper feed stepper motor */
155   case 0x07: result = m_pf_stepper; break;
156   /* carriage return stepper motor */
157   case 0x08: result = m_cr_stepper; break;
158   }
159
160   LOG("0x%02x\n", result);
161
162   return result;
163}
trunk/src/emu/machine/e05a30.h
r0r241970
1/*
2 * E05A30 Gate Array (used in the Epson ActionPrinter 2000)
3 *
4 * Copyright: 2014 Ramiro Polla
5 * License: BSD-3-Clause
6 */
7
8#ifndef __E05A30_H__
9#define __E05A30_H__
10
11/***************************************************************************
12    DEVICE CONFIGURATION MACROS
13***************************************************************************/
14
15#define MCFG_E05A30_PRINTHEAD_CALLBACK(_write) \
16   devcb = &e05a30_device::set_printhead_wr_callback(*device, DEVCB_##_write);
17
18#define MCFG_E05A30_PF_STEPPER_CALLBACK(_write) \
19   devcb = &e05a30_device::set_pf_stepper_wr_callback(*device, DEVCB_##_write);
20
21#define MCFG_E05A30_CR_STEPPER_CALLBACK(_write) \
22   devcb = &e05a30_device::set_cr_stepper_wr_callback(*device, DEVCB_##_write);
23
24#define MCFG_E05A30_READY_CALLBACK(_write) \
25   devcb = &e05a30_device::set_ready_wr_callback(*device, DEVCB_##_write);
26
27/***************************************************************************
28    TYPE DEFINITIONS
29***************************************************************************/
30
31class e05a30_device : public device_t
32{
33public:
34   e05a30_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
35   ~e05a30_device() {}
36
37   template<class _Object> static devcb_base &set_printhead_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_printhead.set_callback(object); }
38   template<class _Object> static devcb_base &set_pf_stepper_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_pf_stepper.set_callback(object); }
39   template<class _Object> static devcb_base &set_cr_stepper_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_cr_stepper.set_callback(object); }
40   template<class _Object> static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_ready.set_callback(object); }
41
42   DECLARE_WRITE8_MEMBER( write );
43   DECLARE_READ8_MEMBER( read );
44
45protected:
46   // device-level overrides
47   virtual void device_start();
48   virtual void device_reset();
49
50private:
51   /* callbacks */
52   devcb_write16 m_write_printhead;
53   devcb_write8 m_write_pf_stepper;
54   devcb_write8 m_write_cr_stepper;
55   devcb_write_line m_write_ready;
56
57   void update_printhead(int pos, UINT8 data);
58   void update_pf_stepper(UINT8 data);
59   void update_cr_stepper(UINT8 data);
60
61   /* port 0x05 and 0x06 (9-bit) */
62   UINT16 m_printhead;
63   /* port 0x07 (4-bit) */
64   UINT8 m_pf_stepper;
65   /* port 0x08 (4-bit) */
66   UINT8 m_cr_stepper;
67};
68
69extern const device_type E05A30;
70
71#endif /* __E05A30_H__ */
trunk/src/emu/machine/machine.mak
r241969r241970
521521
522522#-------------------------------------------------
523523#
524#@src/emu/machine/e05a30.h,MACHINES += E05A30
525#-------------------------------------------------
526
527ifneq ($(filter E05A30,$(MACHINES)),)
528MACHINEOBJS += $(MACHINEOBJ)/e05a30.o
529endif
530
531#-------------------------------------------------
532#
524533#@src/emu/machine/eeprom.h,MACHINES += EEPROMDEV
525534#@src/emu/machine/eepromser.h,MACHINES += EEPROMDEV
526535#@src/emu/machine/eeprompar.h,MACHINES += EEPROMDEV
trunk/src/mame/mame.mak
r241969r241970
401401MACHINES += DS75161A
402402MACHINES += E0516
403403MACHINES += E05A03
404MACHINES += E05A30
404405MACHINES += EEPROMDEV
405406MACHINES += ER2055
406407MACHINES += F3853
trunk/src/mess/includes/amstrad.h
r241969r241970
2929#include "bus/centronics/comxpl80.h"
3030#include "bus/centronics/epson_ex800.h"
3131#include "bus/centronics/epson_lx800.h"
32#include "bus/centronics/epson_lx810l.h"
3233#include "bus/centronics/printer.h"
3334#include "bus/centronics/digiblst.h"
3435#include "bus/generic/slot.h"
trunk/src/mess/mess.mak
r241969r241970
387387MACHINES += DS75161A
388388MACHINES += E0516
389389MACHINES += E05A03
390MACHINES += E05A30
390391MACHINES += EEPROMDEV
391392MACHINES += ER2055
392393MACHINES += F3853
r241969r241970
552553MACHINES += HDC9234
553554MACHINES += TI99_HD
554555MACHINES += STRATA
556MACHINES += STEPPERS
555557MACHINES += CORVUSHD
556558MACHINES += WOZFDC
557559MACHINES += DIABLO_HD
trunk/src/targets/mess.lst
r241969r241970
285285/mess/drivers/ex800
286286/mess/drivers/hx20
287287/mess/drivers/lx800
288/mess/drivers/lx810l
288289/mess/drivers/px4
289290/mess/drivers/px8
290291/mess/drivers/qx10


Previous 199869 Revisions Next


© 1997-2024 The MAME Team