trunk/src/emu/machine/f3853.c
| r29590 | r29591 | |
| 52 | 52 | { |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | | |
| 56 | 55 | //------------------------------------------------- |
| 57 | | // device_config_complete - perform any |
| 58 | | // operations now that the configuration is |
| 59 | | // complete |
| 60 | | //------------------------------------------------- |
| 61 | | |
| 62 | | void f3853_device::device_config_complete() |
| 63 | | { |
| 64 | | // inherit a copy of the static data |
| 65 | | const f3853_interface *intf = reinterpret_cast<const f3853_interface *>(static_config()); |
| 66 | | if (intf != NULL) |
| 67 | | { |
| 68 | | *static_cast<f3853_interface *>(this) = *intf; |
| 69 | | } |
| 70 | | |
| 71 | | // or initialize to defaults if none provided |
| 72 | | else |
| 73 | | { |
| 74 | | memset(&m_interrupt_request, 0, sizeof(m_interrupt_request)); |
| 75 | | } |
| 76 | | } |
| 77 | | |
| 78 | | |
| 79 | | //------------------------------------------------- |
| 80 | 56 | // device_start - device-specific startup |
| 81 | 57 | //------------------------------------------------- |
| 82 | 58 | |
| r29590 | r29591 | |
| 91 | 67 | INT32 o3 = (reg & 0x08) ? TRUE : FALSE; |
| 92 | 68 | m_value_to_cycle[reg] = i; |
| 93 | 69 | reg <<= 1; |
| 94 | | if(!((o7 != o5) != (o4 != o3))) |
| 70 | if (!((o7 != o5) != (o4 != o3))) |
| 95 | 71 | { |
| 96 | 72 | reg |= 1; |
| 97 | 73 | } |
| r29590 | r29591 | |
| 127 | 103 | } |
| 128 | 104 | |
| 129 | 105 | |
| 130 | | void f3853_device::f3853_set_interrupt_request_line() |
| 106 | void f3853_device::set_interrupt_request_line() |
| 131 | 107 | { |
| 132 | | if(!m_interrupt_request) |
| 133 | | { |
| 108 | if (m_interrupt_req_cb.isnull()) |
| 134 | 109 | return; |
| 135 | | } |
| 136 | 110 | |
| 137 | | if(m_external_enable && !m_priority_line) |
| 138 | | { |
| 139 | | m_interrupt_request(this, INTERRUPT_VECTOR(TRUE), TRUE); |
| 140 | | } |
| 141 | | else if( m_timer_enable && !m_priority_line && m_request_flipflop) |
| 142 | | { |
| 143 | | m_interrupt_request(this, INTERRUPT_VECTOR(FALSE), TRUE); |
| 144 | | } |
| 111 | if (m_external_enable && !m_priority_line) |
| 112 | m_interrupt_req_cb(INTERRUPT_VECTOR(TRUE), TRUE); |
| 113 | else if (m_timer_enable && !m_priority_line && m_request_flipflop) |
| 114 | m_interrupt_req_cb(INTERRUPT_VECTOR(FALSE), TRUE); |
| 145 | 115 | else |
| 146 | | { |
| 147 | | m_interrupt_request(this, 0, FALSE); |
| 148 | | } |
| 116 | m_interrupt_req_cb(0, FALSE); |
| 149 | 117 | } |
| 150 | 118 | |
| 151 | 119 | |
| 152 | | void f3853_device::f3853_timer_start(UINT8 value) |
| 120 | void f3853_device::timer_start(UINT8 value) |
| 153 | 121 | { |
| 154 | 122 | attotime period = (value != 0xff) ? attotime::from_hz(clock()) * (m_value_to_cycle[value]*31) : attotime::never; |
| 155 | 123 | |
| r29590 | r29591 | |
| 159 | 127 | |
| 160 | 128 | TIMER_CALLBACK( f3853_device::f3853_timer_callback ) |
| 161 | 129 | { |
| 162 | | reinterpret_cast<f3853_device*>(ptr)->f3853_timer(); |
| 130 | reinterpret_cast<f3853_device*>(ptr)->timer(); |
| 163 | 131 | } |
| 164 | 132 | |
| 165 | | void f3853_device::f3853_timer() |
| 133 | void f3853_device::timer() |
| 166 | 134 | { |
| 167 | 135 | if(m_timer_enable) |
| 168 | 136 | { |
| 169 | 137 | m_request_flipflop = TRUE; |
| 170 | | f3853_set_interrupt_request_line(); |
| 138 | set_interrupt_request_line(); |
| 171 | 139 | } |
| 172 | | f3853_timer_start(0xfe); |
| 140 | timer_start(0xfe); |
| 173 | 141 | } |
| 174 | 142 | |
| 175 | | void f3853_device::f3853_set_external_interrupt_in_line(int level) |
| 143 | void f3853_device::set_external_interrupt_in_line(int level) |
| 176 | 144 | { |
| 177 | 145 | if(m_external_interrupt_line && !level && m_external_enable) |
| 178 | 146 | { |
| 179 | 147 | m_request_flipflop = TRUE; |
| 180 | 148 | } |
| 181 | 149 | m_external_interrupt_line = level; |
| 182 | | f3853_set_interrupt_request_line(); |
| 150 | set_interrupt_request_line(); |
| 183 | 151 | } |
| 184 | 152 | |
| 185 | | void f3853_device::f3853_set_priority_in_line(int level) |
| 153 | void f3853_device::set_priority_in_line(int level) |
| 186 | 154 | { |
| 187 | 155 | m_priority_line = level; |
| 188 | | f3853_set_interrupt_request_line(); |
| 156 | set_interrupt_request_line(); |
| 189 | 157 | } |
| 190 | 158 | |
| 191 | 159 | |
| 192 | | READ8_MEMBER(f3853_device::f3853_r) |
| 160 | READ8_MEMBER(f3853_device::read) |
| 193 | 161 | { |
| 194 | 162 | UINT8 data = 0; |
| 195 | 163 | |
| r29590 | r29591 | |
| 212 | 180 | } |
| 213 | 181 | |
| 214 | 182 | |
| 215 | | WRITE8_MEMBER(f3853_device::f3853_w) |
| 183 | WRITE8_MEMBER(f3853_device::write) |
| 216 | 184 | { |
| 217 | 185 | switch(offset) |
| 218 | 186 | { |
| r29590 | r29591 | |
| 227 | 195 | case 2: //interrupt control |
| 228 | 196 | m_external_enable = ((data & 3) == 1); |
| 229 | 197 | m_timer_enable = ((data & 3) == 3); |
| 230 | | f3853_set_interrupt_request_line(); |
| 198 | set_interrupt_request_line(); |
| 231 | 199 | break; |
| 232 | 200 | |
| 233 | 201 | case 3: //timer |
| 234 | 202 | m_request_flipflop = FALSE; |
| 235 | | f3853_set_interrupt_request_line(); |
| 236 | | f3853_timer_start(data); |
| 203 | set_interrupt_request_line(); |
| 204 | timer_start(data); |
| 237 | 205 | break; |
| 238 | 206 | } |
| 239 | 207 | } |
trunk/src/emu/machine/f3853.h
| r29590 | r29591 | |
| 38 | 38 | |
| 39 | 39 | #include "emu.h" |
| 40 | 40 | |
| 41 | | |
| 42 | | |
| 43 | | |
| 44 | 41 | //************************************************************************** |
| 45 | 42 | // INTERFACE CONFIGURATION MACROS |
| 46 | 43 | //************************************************************************** |
| 47 | 44 | |
| 48 | | #define MCFG_F3853_ADD(_tag, _clock, _intrf) \ |
| 49 | | MCFG_DEVICE_ADD(_tag, F3853, _clock) \ |
| 50 | | MCFG_DEVICE_CONFIG(_intrf) |
| 45 | #define MCFG_F3853_EXT_INPUT_CB(_class, _method) \ |
| 46 | f3853_device::set_interrupt_req_callback(*device, f3853_interrupt_req_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); |
| 51 | 47 | |
| 52 | | |
| 53 | | |
| 54 | 48 | /*************************************************************************** |
| 55 | 49 | TYPE DEFINITIONS |
| 56 | 50 | ***************************************************************************/ |
| 57 | 51 | |
| 52 | typedef device_delegate<void (UINT16 addr, int level)> f3853_interrupt_req_delegate; |
| 58 | 53 | |
| 59 | | // ======================> f3853_interface |
| 54 | #define F3853_INTERRUPT_REQ_CB(_name) void _name(UINT16 addr, int level) |
| 60 | 55 | |
| 61 | | struct f3853_interface |
| 62 | | { |
| 63 | | void (*m_interrupt_request)(device_t *device, UINT16 addr, int level); |
| 64 | | }; |
| 65 | 56 | |
| 66 | | |
| 67 | 57 | // ======================> f3853_device |
| 68 | 58 | |
| 69 | | class f3853_device : public device_t, |
| 70 | | public f3853_interface |
| 59 | class f3853_device : public device_t |
| 71 | 60 | { |
| 72 | 61 | public: |
| 73 | 62 | // construction/destruction |
| 74 | 63 | f3853_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 75 | 64 | |
| 76 | | DECLARE_READ8_MEMBER( f3853_r ); |
| 77 | | DECLARE_WRITE8_MEMBER( f3853_w ); |
| 65 | static void set_interrupt_req_callback(device_t &device, f3853_interrupt_req_delegate callback) { downcast<f3853_device &>(device).m_interrupt_req_cb = callback; } |
| 78 | 66 | |
| 79 | | void f3853_set_external_interrupt_in_line(int level); |
| 80 | | void f3853_set_priority_in_line(int level); |
| 67 | DECLARE_READ8_MEMBER(read); |
| 68 | DECLARE_WRITE8_MEMBER(write); |
| 81 | 69 | |
| 70 | void set_external_interrupt_in_line(int level); |
| 71 | void set_priority_in_line(int level); |
| 72 | |
| 82 | 73 | protected: |
| 83 | 74 | // device-level overrides |
| 84 | | virtual void device_config_complete(); |
| 85 | 75 | virtual void device_start(); |
| 86 | 76 | virtual void device_reset(); |
| 87 | 77 | virtual void device_post_load() { } |
| r29590 | r29591 | |
| 91 | 81 | |
| 92 | 82 | private: |
| 93 | 83 | |
| 94 | | void f3853_set_interrupt_request_line(); |
| 95 | | void f3853_timer_start(UINT8 value); |
| 96 | | void f3853_timer(); |
| 84 | void set_interrupt_request_line(); |
| 85 | void timer_start(UINT8 value); |
| 86 | void timer(); |
| 97 | 87 | |
| 88 | f3853_interrupt_req_delegate m_interrupt_req_cb; |
| 98 | 89 | UINT8 m_high; |
| 99 | 90 | UINT8 m_low; // Bit 7 is set to 0 for timer interrupts, 1 for external interrupts |
| 100 | 91 | INT32 m_external_enable; |
trunk/src/mess/drivers/mk1.c
| r29590 | r29591 | |
| 58 | 58 | UINT8 m_led[4]; |
| 59 | 59 | virtual void machine_start(); |
| 60 | 60 | TIMER_DEVICE_CALLBACK_MEMBER(mk1_update_leds); |
| 61 | F3853_INTERRUPT_REQ_CB(mk1_interrupt); |
| 61 | 62 | required_device<cpu_device> m_maincpu; |
| 62 | 63 | }; |
| 63 | 64 | |
| r29590 | r29591 | |
| 109 | 110 | |
| 110 | 111 | static ADDRESS_MAP_START( mk1_io, AS_IO, 8, mk1_state ) |
| 111 | 112 | AM_RANGE( 0x0, 0x1 ) AM_READWRITE( mk1_f8_r, mk1_f8_w ) |
| 112 | | AM_RANGE( 0xc, 0xf ) AM_DEVREADWRITE("f3853", f3853_device, f3853_r, f3853_w ) |
| 113 | AM_RANGE( 0xc, 0xf ) AM_DEVREADWRITE("f3853", f3853_device, read, write ) |
| 113 | 114 | ADDRESS_MAP_END |
| 114 | 115 | |
| 115 | 116 | |
| r29590 | r29591 | |
| 151 | 152 | |
| 152 | 153 | TIMER_DEVICE_CALLBACK_MEMBER(mk1_state::mk1_update_leds) |
| 153 | 154 | { |
| 154 | | UINT8 i; |
| 155 | | |
| 156 | | for ( i = 0; i < 4; i++ ) |
| 155 | for (int i = 0; i < 4; i++) |
| 157 | 156 | { |
| 158 | | output_set_digit_value( i, m_led[i] >> 1 ); |
| 159 | | output_set_led_value( i, m_led[i] & 0x01 ); |
| 157 | output_set_digit_value(i, m_led[i] >> 1); |
| 158 | output_set_led_value(i, m_led[i] & 0x01); |
| 160 | 159 | m_led[i] = 0; |
| 161 | 160 | } |
| 162 | 161 | } |
| r29590 | r29591 | |
| 167 | 166 | } |
| 168 | 167 | |
| 169 | 168 | |
| 170 | | static void mk1_interrupt( device_t *device, UINT16 addr, int level ) |
| 169 | F3853_INTERRUPT_REQ_CB(mk1_state::mk1_interrupt) |
| 171 | 170 | { |
| 172 | | mk1_state *drvstate = device->machine().driver_data<mk1_state>(); |
| 173 | | drvstate->m_maincpu->set_input_line_vector(F8_INPUT_LINE_INT_REQ, addr ); |
| 174 | | |
| 175 | | drvstate->m_maincpu->set_input_line(F8_INPUT_LINE_INT_REQ, level ? ASSERT_LINE : CLEAR_LINE ); |
| 171 | m_maincpu->set_input_line_vector(F8_INPUT_LINE_INT_REQ, addr); |
| 172 | m_maincpu->set_input_line(F8_INPUT_LINE_INT_REQ, level ? ASSERT_LINE : CLEAR_LINE); |
| 176 | 173 | } |
| 177 | 174 | |
| 178 | | |
| 179 | | static const f3853_interface mk1_config = |
| 180 | | { |
| 181 | | mk1_interrupt |
| 182 | | }; |
| 183 | | |
| 184 | | |
| 185 | 175 | static MACHINE_CONFIG_START( mk1, mk1_state ) |
| 186 | 176 | /* basic machine hardware */ |
| 187 | 177 | MCFG_CPU_ADD( "maincpu", F8, MAIN_CLOCK ) /* MK3850 */ |
| 188 | | MCFG_CPU_PROGRAM_MAP( mk1_mem) |
| 189 | | MCFG_CPU_IO_MAP( mk1_io) |
| 178 | MCFG_CPU_PROGRAM_MAP(mk1_mem) |
| 179 | MCFG_CPU_IO_MAP(mk1_io) |
| 190 | 180 | MCFG_QUANTUM_TIME(attotime::from_hz(60)) |
| 191 | 181 | |
| 192 | 182 | |
| 193 | | MCFG_F3853_ADD( "f3853", MAIN_CLOCK, mk1_config ) |
| 183 | MCFG_DEVICE_ADD("f3853", F3853, MAIN_CLOCK) |
| 184 | MCFG_F3853_EXT_INPUT_CB(mk1_state, mk1_interrupt) |
| 194 | 185 | |
| 195 | 186 | /* video hardware */ |
| 196 | | MCFG_DEFAULT_LAYOUT( layout_mk1 ) |
| 187 | MCFG_DEFAULT_LAYOUT(layout_mk1) |
| 197 | 188 | |
| 198 | 189 | MCFG_TIMER_DRIVER_ADD_PERIODIC("led_timer", mk1_state, mk1_update_leds, attotime::from_hz(30)) |
| 199 | 190 | MACHINE_CONFIG_END |
trunk/src/mess/drivers/vidbrain.c
| r29590 | r29591 | |
| 255 | 255 | AM_RANGE(0x00, 0x00) AM_WRITE(keyboard_w) |
| 256 | 256 | AM_RANGE(0x01, 0x01) AM_READWRITE(keyboard_r, sound_w) |
| 257 | 257 | AM_RANGE(0x0c, 0x0f) AM_WRITE(f3853_w) |
| 258 | | // AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE(F3853_TAG, f3853_device, f3853_r, f3853_w) |
| 258 | // AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE(F3853_TAG, f3853_device, read, write) |
| 259 | 259 | ADDRESS_MAP_END |
| 260 | 260 | |
| 261 | 261 | |
| r29590 | r29591 | |
| 397 | 397 | //************************************************************************** |
| 398 | 398 | |
| 399 | 399 | //------------------------------------------------- |
| 400 | | // f3853_interface smi_intf |
| 400 | // f3853 interrupt request callback |
| 401 | 401 | //------------------------------------------------- |
| 402 | 402 | |
| 403 | | static void f3853_int_req_w(device_t *device, UINT16 addr, int level) |
| 403 | F3853_INTERRUPT_REQ_CB(vidbrain_state::f3853_int_req_w) |
| 404 | 404 | { |
| 405 | | vidbrain_state *state = device->machine().driver_data<vidbrain_state>(); |
| 406 | | |
| 407 | | state->m_vector = addr; |
| 408 | | state->m_maincpu->set_input_line(F8_INPUT_LINE_INT_REQ, level); |
| 405 | m_vector = addr; |
| 406 | m_maincpu->set_input_line(F8_INPUT_LINE_INT_REQ, level); |
| 409 | 407 | } |
| 410 | 408 | |
| 411 | | static const f3853_interface smi_intf = |
| 412 | | { |
| 413 | | f3853_int_req_w |
| 414 | | }; |
| 415 | | |
| 416 | | |
| 417 | 409 | //------------------------------------------------- |
| 418 | 410 | // UV201_INTERFACE( uv_intf ) |
| 419 | 411 | //------------------------------------------------- |
| r29590 | r29591 | |
| 567 | 559 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 568 | 560 | |
| 569 | 561 | // devices |
| 570 | | MCFG_F3853_ADD(F3853_TAG, XTAL_4MHz/2, smi_intf) |
| 562 | MCFG_DEVICE_ADD(F3853_TAG, F3853, XTAL_4MHz/2) |
| 563 | MCFG_F3853_EXT_INPUT_CB(vidbrain_state, f3853_int_req_w) |
| 571 | 564 | |
| 572 | 565 | // cartridge |
| 573 | 566 | MCFG_VIDEOBRAIN_EXPANSION_SLOT_ADD(VIDEOBRAIN_EXPANSION_SLOT_TAG, vidbrain_expansion_cards, NULL) |