trunk/src/mess/drivers/pc1500.c
| r29189 | r29190 | |
| 264 | 264 | palette.set_pen_color(1, rgb_t(92, 83, 88)); |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | | static const lh5810_interface lh5810_pc1500_config = |
| 268 | | { |
| 269 | | DEVCB_DRIVER_MEMBER(pc1500_state, port_a_r), //port A read |
| 270 | | DEVCB_DRIVER_MEMBER(pc1500_state, kb_matrix_w), //port A write |
| 271 | | DEVCB_DRIVER_MEMBER(pc1500_state, port_b_r), //port B read |
| 272 | | DEVCB_NULL, //port B write |
| 273 | | DEVCB_DRIVER_MEMBER(pc1500_state, port_c_w), //port C write |
| 274 | | DEVCB_CPU_INPUT_LINE("maincpu", LH5801_LINE_MI) //IRQ callback |
| 275 | | }; |
| 276 | | |
| 277 | 267 | static MACHINE_CONFIG_START( pc1500, pc1500_state ) |
| 278 | 268 | MCFG_CPU_ADD("maincpu", LH5801, 1300000) //1.3 MHz |
| 279 | 269 | MCFG_CPU_PROGRAM_MAP( pc1500_mem ) |
| r29189 | r29190 | |
| 292 | 282 | MCFG_PALETTE_ADD("palette", 2) |
| 293 | 283 | MCFG_PALETTE_INIT_OWNER(pc1500_state, pc1500) |
| 294 | 284 | |
| 295 | | MCFG_LH5810_ADD("lh5810", lh5810_pc1500_config) |
| 285 | MCFG_DEVICE_ADD("lh5810", LH5810, 0) |
| 286 | MCFG_LH5810_PORTA_R_CB(READ8(pc1500_state, port_a_r)) |
| 287 | MCFG_LH5810_PORTA_W_CB(WRITE8(pc1500_state, kb_matrix_w)) |
| 288 | MCFG_LH5810_PORTB_R_CB(READ8(pc1500_state, port_b_r)) |
| 289 | MCFG_LH5810_PORTC_W_CB(WRITE8(pc1500_state, port_c_w)) |
| 290 | MCFG_LH5810_OUT_INT_CB(INPUTLINE("maincpu", LH5801_LINE_MI)) |
| 296 | 291 | |
| 297 | 292 | MCFG_UPD1990A_ADD("upd1990a", XTAL_32_768kHz, NULL, NULL) |
| 298 | 293 | MACHINE_CONFIG_END |
trunk/src/emu/machine/lh5810.c
| r29189 | r29190 | |
| 19 | 19 | |
| 20 | 20 | const device_type LH5810 = &device_creator<lh5810_device>; |
| 21 | 21 | |
| 22 | | |
| 23 | | //------------------------------------------------- |
| 24 | | // device_config_complete - perform any |
| 25 | | // operations now that the configuration is |
| 26 | | // complete |
| 27 | | //------------------------------------------------- |
| 28 | | |
| 29 | | void lh5810_device::device_config_complete() |
| 30 | | { |
| 31 | | // inherit a copy of the static data |
| 32 | | const lh5810_interface *intf = reinterpret_cast<const lh5810_interface *>(static_config()); |
| 33 | | if (intf != NULL) |
| 34 | | *static_cast<lh5810_interface *>(this) = *intf; |
| 35 | | |
| 36 | | // or initialize to defaults if none provided |
| 37 | | else |
| 38 | | { |
| 39 | | memset(&m_porta_r_cb, 0, sizeof(m_porta_r_cb)); |
| 40 | | memset(&m_porta_w_cb, 0, sizeof(m_porta_w_cb)); |
| 41 | | memset(&m_portb_r_cb, 0, sizeof(m_portb_r_cb)); |
| 42 | | memset(&m_portb_w_cb, 0, sizeof(m_portb_w_cb)); |
| 43 | | memset(&m_portc_w_cb, 0, sizeof(m_portc_w_cb)); |
| 44 | | memset(&m_out_int_cb, 0, sizeof(m_out_int_cb)); |
| 45 | | } |
| 46 | | } |
| 47 | | |
| 48 | | |
| 49 | 22 | //************************************************************************** |
| 50 | 23 | // LIVE DEVICE |
| 51 | 24 | //************************************************************************** |
| r29189 | r29190 | |
| 55 | 28 | //------------------------------------------------- |
| 56 | 29 | |
| 57 | 30 | lh5810_device::lh5810_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 58 | | : device_t(mconfig, LH5810, "LH5810", tag, owner, clock, "lh5810", __FILE__) |
| 31 | : device_t(mconfig, LH5810, "LH5810", tag, owner, clock, "lh5810", __FILE__), |
| 32 | m_porta_r_cb(*this), |
| 33 | m_porta_w_cb(*this), |
| 34 | m_portb_r_cb(*this), |
| 35 | m_portb_w_cb(*this), |
| 36 | m_portc_w_cb(*this), |
| 37 | m_out_int_cb(*this) |
| 59 | 38 | { |
| 60 | 39 | } |
| 61 | 40 | |
| r29189 | r29190 | |
| 67 | 46 | void lh5810_device::device_start() |
| 68 | 47 | { |
| 69 | 48 | // resolve callbacks |
| 70 | | m_porta_r_func.resolve(m_porta_r_cb, *this); |
| 71 | | m_porta_w_func.resolve(m_porta_w_cb, *this); |
| 72 | | m_portb_r_func.resolve(m_portb_r_cb, *this); |
| 73 | | m_portb_w_func.resolve(m_portb_w_cb, *this); |
| 74 | | m_portc_w_func.resolve(m_portc_w_cb, *this); |
| 75 | | m_out_int_func.resolve(m_out_int_cb, *this); |
| 49 | m_porta_r_cb.resolve_safe(0); |
| 50 | m_porta_w_cb.resolve_safe(); |
| 51 | m_portb_r_cb.resolve_safe(0); |
| 52 | m_portb_w_cb.resolve_safe(); |
| 53 | m_portc_w_cb.resolve_safe(); |
| 54 | m_out_int_cb.resolve_safe(); |
| 76 | 55 | |
| 77 | 56 | // register for state saving |
| 78 | 57 | save_item(NAME(m_irq)); |
| r29189 | r29190 | |
| 109 | 88 | return m_reg[offset]; |
| 110 | 89 | |
| 111 | 90 | case LH5810_IF: |
| 112 | | if (BIT(m_portb_r_func(0) & ~m_reg[LH5810_DDB], 7)) |
| 91 | if (BIT(m_portb_r_cb(0) & ~m_reg[LH5810_DDB], 7)) |
| 113 | 92 | m_reg[offset] |= 2; |
| 114 | 93 | else |
| 115 | 94 | m_reg[offset] &= 0xfd; |
| r29189 | r29190 | |
| 120 | 99 | return (m_reg[offset]&0x0f) | (m_irq<<4) | (BIT(m_reg[LH5810_OPB],7)<<5); |
| 121 | 100 | |
| 122 | 101 | case LH5810_OPA: |
| 123 | | m_reg[offset] = (m_reg[offset] & m_reg[LH5810_DDA]) | (m_porta_r_func(0) & ~m_reg[LH5810_DDA]); |
| 102 | m_reg[offset] = (m_reg[offset] & m_reg[LH5810_DDA]) | (m_porta_r_cb(0) & ~m_reg[LH5810_DDA]); |
| 124 | 103 | return m_reg[offset]; |
| 125 | 104 | |
| 126 | 105 | case LH5810_OPB: |
| 127 | | m_reg[offset] = (m_reg[offset] & m_reg[LH5810_DDB]) | (m_portb_r_func(0) & ~m_reg[LH5810_DDB]); |
| 128 | | m_out_int_func((m_reg[offset] & 0x80 && m_reg[LH5810_MSK] & 0x02) ? ASSERT_LINE : CLEAR_LINE); |
| 106 | m_reg[offset] = (m_reg[offset] & m_reg[LH5810_DDB]) | (m_portb_r_cb(0) & ~m_reg[LH5810_DDB]); |
| 107 | m_out_int_cb((m_reg[offset] & 0x80 && m_reg[LH5810_MSK] & 0x02) ? ASSERT_LINE : CLEAR_LINE); |
| 129 | 108 | return m_reg[offset]; |
| 130 | 109 | |
| 131 | 110 | default: |
| r29189 | r29190 | |
| 175 | 154 | |
| 176 | 155 | case LH5810_OPA: |
| 177 | 156 | m_reg[offset] = (data & m_reg[LH5810_DDA]) | (m_reg[offset] & ~m_reg[LH5810_DDA]); |
| 178 | | m_porta_w_func(0, m_reg[offset]); |
| 157 | m_porta_w_cb((offs_t)0, m_reg[offset]); |
| 179 | 158 | break; |
| 180 | 159 | |
| 181 | 160 | case LH5810_OPB: |
| 182 | 161 | m_reg[offset] = (data & m_reg[LH5810_DDB]) | (m_reg[offset] & ~m_reg[LH5810_DDB]); |
| 183 | | m_portb_w_func(0, m_reg[offset]); |
| 184 | | m_out_int_func((m_reg[offset] & 0x80 && m_reg[LH5810_MSK] & 0x02) ? ASSERT_LINE : CLEAR_LINE); |
| 162 | m_portb_w_cb((offs_t)0, m_reg[offset]); |
| 163 | m_out_int_cb((m_reg[offset] & 0x80 && m_reg[LH5810_MSK] & 0x02) ? ASSERT_LINE : CLEAR_LINE); |
| 185 | 164 | break; |
| 186 | 165 | |
| 187 | 166 | case LH5810_OPC: |
| 188 | 167 | m_reg[offset] = data; |
| 189 | | m_portc_w_func(0, m_reg[offset]); |
| 168 | m_portc_w_cb((offs_t)0, m_reg[offset]); |
| 190 | 169 | break; |
| 191 | 170 | } |
| 192 | 171 | } |
trunk/src/emu/machine/lh5810.h
| r29189 | r29190 | |
| 38 | 38 | // INTERFACE CONFIGURATION MACROS |
| 39 | 39 | //************************************************************************* |
| 40 | 40 | |
| 41 | | #define MCFG_LH5810_ADD(_tag, _config) \ |
| 42 | | MCFG_DEVICE_ADD((_tag), LH5810, 0) \ |
| 43 | | MCFG_DEVICE_CONFIG(_config) |
| 41 | #define MCFG_LH5810_PORTA_R_CB(_devcb) \ |
| 42 | devcb = &lh5810_device::set_porta_r_callback(*device, DEVCB2_##_devcb); |
| 44 | 43 | |
| 44 | #define MCFG_LH5810_PORTA_W_CB(_devcb) \ |
| 45 | devcb = &lh5810_device::set_porta_w_callback(*device, DEVCB2_##_devcb); |
| 46 | |
| 47 | #define MCFG_LH5810_PORTB_R_CB(_devcb) \ |
| 48 | devcb = &lh5810_device::set_portb_r_callback(*device, DEVCB2_##_devcb); |
| 49 | |
| 50 | #define MCFG_LH5810_PORTB_W_CB(_devcb) \ |
| 51 | devcb = &lh5810_device::set_portb_w_callback(*device, DEVCB2_##_devcb); |
| 52 | |
| 53 | #define MCFG_LH5810_PORTC_W_CB(_devcb) \ |
| 54 | devcb = &lh5810_device::set_portc_w_callback(*device, DEVCB2_##_devcb); |
| 55 | |
| 56 | #define MCFG_LH5810_OUT_INT_CB(_devcb) \ |
| 57 | devcb = &lh5810_device::set_out_int_callback(*device, DEVCB2_##_devcb); //currently unused |
| 45 | 58 | |
| 46 | 59 | |
| 60 | |
| 47 | 61 | //************************************************************************* |
| 48 | 62 | // TYPE DEFINITIONS |
| 49 | 63 | //************************************************************************* |
| 50 | 64 | |
| 51 | | // ======================> lh5810_interface |
| 52 | | |
| 53 | | struct lh5810_interface |
| 54 | | { |
| 55 | | devcb_read8 m_porta_r_cb; //port A read |
| 56 | | devcb_write8 m_porta_w_cb; //port A write |
| 57 | | devcb_read8 m_portb_r_cb; //port B read |
| 58 | | devcb_write8 m_portb_w_cb; //port B write |
| 59 | | devcb_write8 m_portc_w_cb; //port C write |
| 60 | | |
| 61 | | devcb_write_line m_out_int_cb; //IRQ callback |
| 62 | | }; |
| 63 | | |
| 64 | 65 | // ======================> lh5810_device |
| 65 | 66 | |
| 66 | | class lh5810_device : public device_t, |
| 67 | | public lh5810_interface |
| 67 | class lh5810_device : public device_t |
| 68 | 68 | { |
| 69 | 69 | public: |
| 70 | 70 | // construction/destruction |
| 71 | 71 | lh5810_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 72 | 72 | |
| 73 | template<class _Object> static devcb2_base &set_porta_r_callback(device_t &device, _Object object) { return downcast<lh5810_device &>(device).m_porta_r_cb.set_callback(object); } |
| 74 | template<class _Object> static devcb2_base &set_porta_w_callback(device_t &device, _Object object) { return downcast<lh5810_device &>(device).m_porta_w_cb.set_callback(object); } |
| 75 | template<class _Object> static devcb2_base &set_portb_r_callback(device_t &device, _Object object) { return downcast<lh5810_device &>(device).m_portb_r_cb.set_callback(object); } |
| 76 | template<class _Object> static devcb2_base &set_portb_w_callback(device_t &device, _Object object) { return downcast<lh5810_device &>(device).m_portb_w_cb.set_callback(object); } |
| 77 | template<class _Object> static devcb2_base &set_portc_w_callback(device_t &device, _Object object) { return downcast<lh5810_device &>(device).m_portc_w_cb.set_callback(object); } |
| 78 | template<class _Object> static devcb2_base &set_out_int_callback(device_t &device, _Object object) { return downcast<lh5810_device &>(device).m_out_int_cb.set_callback(object); } |
| 79 | |
| 73 | 80 | DECLARE_READ8_MEMBER( data_r ); |
| 74 | 81 | DECLARE_WRITE8_MEMBER( data_w ); |
| 75 | 82 | |
| r29189 | r29190 | |
| 77 | 84 | // device-level overrides |
| 78 | 85 | virtual void device_start(); |
| 79 | 86 | virtual void device_reset(); |
| 80 | | virtual void device_config_complete(); |
| 81 | 87 | |
| 82 | 88 | private: |
| 83 | 89 | |
| 84 | | devcb_resolved_read8 m_porta_r_func; |
| 85 | | devcb_resolved_write8 m_porta_w_func; |
| 86 | | devcb_resolved_read8 m_portb_r_func; |
| 87 | | devcb_resolved_write8 m_portb_w_func; |
| 88 | | devcb_resolved_write8 m_portc_w_func; |
| 89 | | devcb_resolved_write_line m_out_int_func; |
| 90 | devcb2_read8 m_porta_r_cb; //port A read |
| 91 | devcb2_write8 m_porta_w_cb; //port A write |
| 92 | devcb2_read8 m_portb_r_cb; //port B read |
| 93 | devcb2_write8 m_portb_w_cb; //port B write |
| 94 | devcb2_write8 m_portc_w_cb; //port C write |
| 90 | 95 | |
| 96 | devcb2_write_line m_out_int_cb; //IRQ callback |
| 97 | |
| 91 | 98 | UINT8 m_reg[0x10]; |
| 92 | 99 | UINT8 m_irq; |
| 93 | 100 | }; |