trunk/src/emu/bus/centronics/epson_lx810l.c
| r242089 | r242090 | |
| 13 | 13 | * SLA7020M (step motor driver) |
| 14 | 14 | * uPC494C (pulse width modulation control) |
| 15 | 15 | * |
| 16 | | * Devices boot and enter main input loop, but input is not yet implemented. |
| 16 | * Devices boot and enter main input loop. Data is received through the |
| 17 | * centronics bus and printed as expected. The actual paper output is |
| 18 | * still not implemented, though. Look at the output from the fire signal |
| 19 | * (epson_lx810l_t::co0_w()) to see what's actually being printed. |
| 17 | 20 | * |
| 18 | 21 | * It is possible to run the printers' self test with this procedure: |
| 19 | 22 | * - Turn on device; |
| r242089 | r242090 | |
| 99 | 102 | AM_RANGE(0x0000, 0x7fff) AM_ROM /* 32k firmware */ |
| 100 | 103 | AM_RANGE(0x8000, 0x9fff) AM_RAM /* 8k external RAM */ |
| 101 | 104 | 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) |
| 105 | AM_RANGE(0xc000, 0xdfff) AM_MIRROR(0x1ff0) AM_DEVREADWRITE("e05a30", e05a30_device, read, write) |
| 103 | 106 | AM_RANGE(0xe000, 0xfeff) AM_NOP /* not used */ |
| 104 | 107 | AM_RANGE(0xff00, 0xffff) AM_RAM /* internal CPU RAM */ |
| 105 | 108 | ADDRESS_MAP_END |
| r242089 | r242090 | |
| 144 | 147 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 145 | 148 | |
| 146 | 149 | /* gate array */ |
| 147 | | MCFG_DEVICE_ADD("ic3b", E05A30, 0) |
| 150 | MCFG_DEVICE_ADD("e05a30", E05A30, 0) |
| 148 | 151 | MCFG_E05A30_PRINTHEAD_CALLBACK(WRITE16(epson_lx810l_t, printhead)) |
| 149 | 152 | MCFG_E05A30_PF_STEPPER_CALLBACK(WRITE8(epson_lx810l_t, pf_stepper)) |
| 150 | 153 | MCFG_E05A30_CR_STEPPER_CALLBACK(WRITE8(epson_lx810l_t, cr_stepper)) |
| 151 | 154 | MCFG_E05A30_READY_CALLBACK(WRITELINE(epson_lx810l_t, e05a30_ready)) |
| 155 | MCFG_E05A30_CENTRONICS_ACK_CALLBACK(WRITELINE(epson_lx810l_t, e05a30_centronics_ack)) |
| 156 | MCFG_E05A30_CENTRONICS_BUSY_CALLBACK(WRITELINE(epson_lx810l_t, e05a30_centronics_busy)) |
| 157 | MCFG_E05A30_CENTRONICS_PERROR_CALLBACK(WRITELINE(epson_lx810l_t, e05a30_centronics_perror)) |
| 158 | MCFG_E05A30_CENTRONICS_FAULT_CALLBACK(WRITELINE(epson_lx810l_t, e05a30_centronics_fault)) |
| 159 | MCFG_E05A30_CENTRONICS_SELECT_CALLBACK(WRITELINE(epson_lx810l_t, e05a30_centronics_select)) |
| 152 | 160 | |
| 153 | 161 | /* 256-bit eeprom */ |
| 154 | 162 | MCFG_EEPROM_SERIAL_93C06_ADD("eeprom") |
| r242089 | r242090 | |
| 272 | 280 | m_maincpu(*this, "maincpu"), |
| 273 | 281 | m_eeprom(*this, "eeprom"), |
| 274 | 282 | m_speaker(*this, "speaker"), |
| 283 | m_e05a30(*this, "e05a30"), |
| 275 | 284 | m_93c06_clk(0), |
| 276 | 285 | m_93c06_cs(0), |
| 277 | 286 | m_printhead(0), |
| r242089 | r242090 | |
| 287 | 296 | m_maincpu(*this, "maincpu"), |
| 288 | 297 | m_eeprom(*this, "eeprom"), |
| 289 | 298 | m_speaker(*this, "speaker"), |
| 299 | m_e05a30(*this, "e05a30"), |
| 290 | 300 | m_93c06_clk(0), |
| 291 | 301 | m_93c06_cs(0), |
| 292 | 302 | m_printhead(0), |
trunk/src/emu/bus/centronics/epson_lx810l.h
| r242089 | r242090 | |
| 73 | 73 | DECLARE_WRITE8_MEMBER(cr_stepper); |
| 74 | 74 | DECLARE_WRITE_LINE_MEMBER(e05a30_ready); |
| 75 | 75 | |
| 76 | /* Centronics stuff */ |
| 77 | virtual DECLARE_WRITE_LINE_MEMBER( input_strobe ) { if (m_e05a30) m_e05a30->centronics_input_strobe(state); } |
| 78 | virtual DECLARE_WRITE_LINE_MEMBER( input_data0 ) { if (m_e05a30) m_e05a30->centronics_input_data0(state); } |
| 79 | virtual DECLARE_WRITE_LINE_MEMBER( input_data1 ) { if (m_e05a30) m_e05a30->centronics_input_data1(state); } |
| 80 | virtual DECLARE_WRITE_LINE_MEMBER( input_data2 ) { if (m_e05a30) m_e05a30->centronics_input_data2(state); } |
| 81 | virtual DECLARE_WRITE_LINE_MEMBER( input_data3 ) { if (m_e05a30) m_e05a30->centronics_input_data3(state); } |
| 82 | virtual DECLARE_WRITE_LINE_MEMBER( input_data4 ) { if (m_e05a30) m_e05a30->centronics_input_data4(state); } |
| 83 | virtual DECLARE_WRITE_LINE_MEMBER( input_data5 ) { if (m_e05a30) m_e05a30->centronics_input_data5(state); } |
| 84 | virtual DECLARE_WRITE_LINE_MEMBER( input_data6 ) { if (m_e05a30) m_e05a30->centronics_input_data6(state); } |
| 85 | virtual DECLARE_WRITE_LINE_MEMBER( input_data7 ) { if (m_e05a30) m_e05a30->centronics_input_data7(state); } |
| 86 | DECLARE_WRITE_LINE_MEMBER(e05a30_centronics_ack) { output_ack(state); } |
| 87 | DECLARE_WRITE_LINE_MEMBER(e05a30_centronics_busy) { output_busy(state); } |
| 88 | DECLARE_WRITE_LINE_MEMBER(e05a30_centronics_perror) { output_perror(state); } |
| 89 | DECLARE_WRITE_LINE_MEMBER(e05a30_centronics_fault) { output_fault(state); } |
| 90 | DECLARE_WRITE_LINE_MEMBER(e05a30_centronics_select) { output_select(state); } |
| 91 | |
| 76 | 92 | /* Panel buttons */ |
| 77 | 93 | DECLARE_INPUT_CHANGED_MEMBER(online_sw); |
| 78 | 94 | |
| r242089 | r242090 | |
| 85 | 101 | required_device<cpu_device> m_maincpu; |
| 86 | 102 | required_device<eeprom_serial_93cxx_device> m_eeprom; |
| 87 | 103 | required_device<speaker_sound_device> m_speaker; |
| 104 | required_device<e05a30_device> m_e05a30; |
| 88 | 105 | |
| 89 | 106 | int m_93c06_clk; |
| 90 | 107 | int m_93c06_cs; |
trunk/src/emu/machine/e05a30.c
| r242089 | r242090 | |
| 28 | 28 | m_write_pf_stepper(*this), |
| 29 | 29 | m_write_cr_stepper(*this), |
| 30 | 30 | m_write_ready(*this), |
| 31 | m_write_centronics_ack(*this), |
| 32 | m_write_centronics_busy(*this), |
| 33 | m_write_centronics_perror(*this), |
| 34 | m_write_centronics_fault(*this), |
| 35 | m_write_centronics_select(*this), |
| 31 | 36 | m_printhead(0), |
| 32 | 37 | m_pf_stepper(0), |
| 33 | 38 | m_cr_stepper(0) |
| r242089 | r242090 | |
| 45 | 50 | m_write_pf_stepper.resolve_safe(); |
| 46 | 51 | m_write_cr_stepper.resolve_safe(); |
| 47 | 52 | m_write_ready.resolve_safe(); |
| 53 | m_write_centronics_ack.resolve_safe(); |
| 54 | m_write_centronics_busy.resolve_safe(); |
| 55 | m_write_centronics_perror.resolve_safe(); |
| 56 | m_write_centronics_fault.resolve_safe(); |
| 57 | m_write_centronics_select.resolve_safe(); |
| 48 | 58 | |
| 49 | 59 | /* register for state saving */ |
| 50 | 60 | save_item(NAME(m_printhead)); |
| r242089 | r242090 | |
| 62 | 72 | m_pf_stepper = 0x00; |
| 63 | 73 | m_cr_stepper = 0x00; |
| 64 | 74 | |
| 75 | /* centronics init */ |
| 76 | m_centronics_nack = FALSE; |
| 77 | m_centronics_busy = FALSE; |
| 78 | m_write_centronics_ack (!m_centronics_nack); |
| 79 | m_write_centronics_busy ( m_centronics_busy); |
| 80 | m_write_centronics_perror(FALSE); |
| 81 | m_write_centronics_fault (TRUE); |
| 82 | m_write_centronics_select(TRUE); |
| 83 | |
| 65 | 84 | m_write_ready(1); |
| 66 | 85 | } |
| 67 | 86 | |
| r242089 | r242090 | |
| 126 | 145 | |
| 127 | 146 | |
| 128 | 147 | /*************************************************************************** |
| 148 | Centronics |
| 149 | ***************************************************************************/ |
| 150 | |
| 151 | WRITE_LINE_MEMBER( e05a30_device::centronics_input_strobe ) |
| 152 | { |
| 153 | if (m_centronics_strobe == TRUE && state == FALSE && !m_centronics_busy) { |
| 154 | |
| 155 | m_centronics_data_latch = m_centronics_data; |
| 156 | |
| 157 | m_centronics_data_latched = TRUE; |
| 158 | m_centronics_busy = TRUE; |
| 159 | m_write_centronics_busy(m_centronics_busy); |
| 160 | } |
| 161 | |
| 162 | m_centronics_strobe = state; |
| 163 | } |
| 164 | |
| 165 | |
| 166 | /*************************************************************************** |
| 129 | 167 | IMPLEMENTATION |
| 130 | 168 | ***************************************************************************/ |
| 131 | 169 | |
| r242089 | r242090 | |
| 134 | 172 | LOG("%s: e05a30_w([0xC0%02x]): %02x\n", space.machine().describe_context(), offset, data); |
| 135 | 173 | |
| 136 | 174 | switch (offset) { |
| 175 | case 0x04: |
| 176 | m_centronics_nack = BIT(data,5); |
| 177 | m_centronics_busy = BIT(data,0); |
| 178 | /* The ActionPrinter 2000 firmware might overwrite the busy signal at |
| 179 | * address 20AB if the host depends only on the busy signal and |
| 180 | * doesn't wait for the ack pulse. To avoid skipping input data, we |
| 181 | * assume the busy signal cannot be reset while the data hasn't been |
| 182 | * read. */ |
| 183 | if (m_centronics_data_latched) |
| 184 | m_centronics_busy = TRUE; |
| 185 | m_write_centronics_ack (!m_centronics_nack); |
| 186 | m_write_centronics_busy( m_centronics_busy); |
| 187 | break; |
| 137 | 188 | /* printhead */ |
| 138 | 189 | case 0x05: update_printhead(0, data); break; |
| 139 | 190 | case 0x06: update_printhead(1, data); break; |
| r242089 | r242090 | |
| 151 | 202 | LOG("%s: e05a30_r([0xC0%02x]): ", space.machine().describe_context(), offset); |
| 152 | 203 | |
| 153 | 204 | switch (offset) { |
| 205 | case 0x02: |
| 206 | result = m_centronics_data_latched << 7; |
| 207 | break; |
| 208 | case 0x03: |
| 209 | result = m_centronics_data_latch; |
| 210 | m_centronics_data_latched = FALSE; |
| 211 | break; |
| 212 | case 0x04: |
| 213 | result |= m_centronics_busy << 0; |
| 214 | result |= m_centronics_nack << 5; |
| 215 | break; |
| 154 | 216 | /* paper feed stepper motor */ |
| 155 | 217 | case 0x07: result = m_pf_stepper; break; |
| 156 | 218 | /* carriage return stepper motor */ |
trunk/src/emu/machine/e05a30.h
| r242089 | r242090 | |
| 24 | 24 | #define MCFG_E05A30_READY_CALLBACK(_write) \ |
| 25 | 25 | devcb = &e05a30_device::set_ready_wr_callback(*device, DEVCB_##_write); |
| 26 | 26 | |
| 27 | #define MCFG_E05A30_CENTRONICS_ACK_CALLBACK(_write) \ |
| 28 | devcb = &e05a30_device::set_centronics_ack_wr_callback(*device, DEVCB_##_write); |
| 29 | |
| 30 | #define MCFG_E05A30_CENTRONICS_BUSY_CALLBACK(_write) \ |
| 31 | devcb = &e05a30_device::set_centronics_busy_wr_callback(*device, DEVCB_##_write); |
| 32 | |
| 33 | #define MCFG_E05A30_CENTRONICS_PERROR_CALLBACK(_write) \ |
| 34 | devcb = &e05a30_device::set_centronics_perror_wr_callback(*device, DEVCB_##_write); |
| 35 | |
| 36 | #define MCFG_E05A30_CENTRONICS_FAULT_CALLBACK(_write) \ |
| 37 | devcb = &e05a30_device::set_centronics_fault_wr_callback(*device, DEVCB_##_write); |
| 38 | |
| 39 | #define MCFG_E05A30_CENTRONICS_SELECT_CALLBACK(_write) \ |
| 40 | devcb = &e05a30_device::set_centronics_select_wr_callback(*device, DEVCB_##_write); |
| 41 | |
| 27 | 42 | /*************************************************************************** |
| 28 | 43 | TYPE DEFINITIONS |
| 29 | 44 | ***************************************************************************/ |
| r242089 | r242090 | |
| 38 | 53 | 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 | 54 | 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 | 55 | 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); } |
| 56 | template<class _Object> static devcb_base &set_centronics_ack_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_centronics_ack.set_callback(object); } |
| 57 | template<class _Object> static devcb_base &set_centronics_busy_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_centronics_busy.set_callback(object); } |
| 58 | template<class _Object> static devcb_base &set_centronics_perror_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_centronics_perror.set_callback(object); } |
| 59 | template<class _Object> static devcb_base &set_centronics_fault_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_centronics_fault.set_callback(object); } |
| 60 | template<class _Object> static devcb_base &set_centronics_select_wr_callback(device_t &device, _Object object) { return downcast<e05a30_device &>(device).m_write_centronics_select.set_callback(object); } |
| 41 | 61 | |
| 42 | 62 | DECLARE_WRITE8_MEMBER( write ); |
| 43 | 63 | DECLARE_READ8_MEMBER( read ); |
| 44 | 64 | |
| 65 | /* Centronics stuff */ |
| 66 | DECLARE_WRITE_LINE_MEMBER( centronics_input_strobe ); |
| 67 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data0 ) { if (state) m_centronics_data |= 0x01; else m_centronics_data &= ~0x01; } |
| 68 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data1 ) { if (state) m_centronics_data |= 0x02; else m_centronics_data &= ~0x02; } |
| 69 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data2 ) { if (state) m_centronics_data |= 0x04; else m_centronics_data &= ~0x04; } |
| 70 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data3 ) { if (state) m_centronics_data |= 0x08; else m_centronics_data &= ~0x08; } |
| 71 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data4 ) { if (state) m_centronics_data |= 0x10; else m_centronics_data &= ~0x10; } |
| 72 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data5 ) { if (state) m_centronics_data |= 0x20; else m_centronics_data &= ~0x20; } |
| 73 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data6 ) { if (state) m_centronics_data |= 0x40; else m_centronics_data &= ~0x40; } |
| 74 | DECLARE_WRITE_LINE_MEMBER( centronics_input_data7 ) { if (state) m_centronics_data |= 0x80; else m_centronics_data &= ~0x80; } |
| 75 | |
| 45 | 76 | protected: |
| 46 | 77 | // device-level overrides |
| 47 | 78 | virtual void device_start(); |
| r242089 | r242090 | |
| 53 | 84 | devcb_write8 m_write_pf_stepper; |
| 54 | 85 | devcb_write8 m_write_cr_stepper; |
| 55 | 86 | devcb_write_line m_write_ready; |
| 87 | devcb_write_line m_write_centronics_ack; |
| 88 | devcb_write_line m_write_centronics_busy; |
| 89 | devcb_write_line m_write_centronics_perror; |
| 90 | devcb_write_line m_write_centronics_fault; |
| 91 | devcb_write_line m_write_centronics_select; |
| 56 | 92 | |
| 57 | 93 | void update_printhead(int pos, UINT8 data); |
| 58 | 94 | void update_pf_stepper(UINT8 data); |
| r242089 | r242090 | |
| 64 | 100 | UINT8 m_pf_stepper; |
| 65 | 101 | /* port 0x08 (4-bit) */ |
| 66 | 102 | UINT8 m_cr_stepper; |
| 103 | |
| 104 | /* Centronics stuff */ |
| 105 | UINT8 m_centronics_data; |
| 106 | int m_centronics_busy; |
| 107 | int m_centronics_nack; |
| 108 | UINT8 m_centronics_strobe; |
| 109 | UINT8 m_centronics_data_latch; |
| 110 | UINT8 m_centronics_data_latched; |
| 67 | 111 | }; |
| 68 | 112 | |
| 69 | 113 | extern const device_type E05A30; |