trunk/src/mame/machine/atari.c
| r31890 | r31891 | |
| 18 | 18 | #define VERBOSE_SERIAL 1 |
| 19 | 19 | #define VERBOSE_TIMERS 1 |
| 20 | 20 | |
| 21 | | void atari_interrupt_cb(pokey_device *device, int mask) |
| 21 | |
| 22 | POKEY_INTERRUPT_CB_MEMBER(atari_common_state::interrupt_cb) |
| 22 | 23 | { |
| 23 | 24 | if (VERBOSE_POKEY) |
| 24 | 25 | { |
| r31890 | r31891 | |
| 46 | 47 | logerror("atari interrupt_cb TIMR1\n"); |
| 47 | 48 | } |
| 48 | 49 | |
| 49 | | device->machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE); |
| 50 | machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE); |
| 50 | 51 | } |
| 51 | 52 | |
| 52 | 53 | |
| r31890 | r31891 | |
| 87 | 88 | |
| 88 | 89 | **************************************************************/ |
| 89 | 90 | |
| 90 | | POKEY_KEYBOARD_HANDLER(atari_a800_keyboard) |
| 91 | POKEY_KEYBOARD_CB_MEMBER(atari_common_state::a800_keyboard) |
| 91 | 92 | { |
| 92 | 93 | int ipt; |
| 93 | 94 | static const char *const tag[] = { |
| r31890 | r31891 | |
| 101 | 102 | { |
| 102 | 103 | case pokey_device::POK_KEY_BREAK: |
| 103 | 104 | /* special case ... */ |
| 104 | | ret |= ((device->machine().root_device().ioport(tag[0])->read_safe(0) & 0x08) ? 0x02 : 0x00); |
| 105 | ret |= ((machine().root_device().ioport(tag[0])->read_safe(0) & 0x08) ? 0x02 : 0x00); |
| 105 | 106 | break; |
| 106 | 107 | case pokey_device::POK_KEY_CTRL: |
| 107 | 108 | /* CTRL */ |
| 108 | | ret |= ((device->machine().root_device().ioport("fake")->read_safe(0) & 0x02) ? 0x02 : 0x00); |
| 109 | ret |= ((machine().root_device().ioport("fake")->read_safe(0) & 0x02) ? 0x02 : 0x00); |
| 109 | 110 | break; |
| 110 | 111 | case pokey_device::POK_KEY_SHIFT: |
| 111 | 112 | /* SHIFT */ |
| 112 | | ret |= ((device->machine().root_device().ioport("fake")->read_safe(0) & 0x01) ? 0x02 : 0x00); |
| 113 | ret |= ((machine().root_device().ioport("fake")->read_safe(0) & 0x01) ? 0x02 : 0x00); |
| 113 | 114 | break; |
| 114 | 115 | } |
| 115 | 116 | |
| r31890 | r31891 | |
| 118 | 119 | return ret; |
| 119 | 120 | |
| 120 | 121 | /* decode regular key */ |
| 121 | | ipt = device->machine().root_device().ioport(tag[k543210 >> 3])->read_safe(0); |
| 122 | ipt = machine().root_device().ioport(tag[k543210 >> 3])->read_safe(0); |
| 122 | 123 | |
| 123 | 124 | if (ipt & (1 << (k543210 & 0x07))) |
| 124 | 125 | ret |= 0x01; |
| r31890 | r31891 | |
| 155 | 156 | |
| 156 | 157 | **************************************************************/ |
| 157 | 158 | |
| 158 | | POKEY_KEYBOARD_HANDLER(atari_a5200_keypads) |
| 159 | POKEY_KEYBOARD_CB_MEMBER(atari_common_state::a5200_keypads) |
| 159 | 160 | { |
| 160 | 161 | int ipt; |
| 161 | 162 | static const char *const tag[] = { "keypad_0", "keypad_1", "keypad_2", "keypad_3" }; |
| r31890 | r31891 | |
| 166 | 167 | { |
| 167 | 168 | case pokey_device::POK_KEY_BREAK: |
| 168 | 169 | /* special case ... */ |
| 169 | | ret |= ((device->machine().root_device().ioport(tag[0])->read_safe(0) & 0x01) ? 0x02 : 0x00); |
| 170 | ret |= ((machine().root_device().ioport(tag[0])->read_safe(0) & 0x01) ? 0x02 : 0x00); |
| 170 | 171 | break; |
| 171 | 172 | case pokey_device::POK_KEY_CTRL: |
| 172 | 173 | case pokey_device::POK_KEY_SHIFT: |
| r31890 | r31891 | |
| 184 | 185 | if (k543210 == 0) |
| 185 | 186 | return ret; |
| 186 | 187 | |
| 187 | | ipt = device->machine().root_device().ioport(tag[k543210 >> 2])->read_safe(0); |
| 188 | ipt = machine().root_device().ioport(tag[k543210 >> 2])->read_safe(0); |
| 188 | 189 | |
| 189 | | if (ipt & (1 <<(k543210 & 0x03))) |
| 190 | if (ipt & (1 << (k543210 & 0x03))) |
| 190 | 191 | ret |= 0x01; |
| 191 | 192 | |
| 192 | 193 | return ret; |
trunk/src/mame/includes/atari.h
| r31890 | r31891 | |
| 39 | 39 | DECLARE_READ8_MEMBER ( atari_antic_r ); |
| 40 | 40 | DECLARE_WRITE8_MEMBER ( atari_antic_w ); |
| 41 | 41 | |
| 42 | POKEY_INTERRUPT_CB_MEMBER(interrupt_cb); |
| 43 | POKEY_KEYBOARD_CB_MEMBER(a5200_keypads); |
| 44 | POKEY_KEYBOARD_CB_MEMBER(a800_keyboard); |
| 45 | |
| 42 | 46 | private: |
| 43 | 47 | UINT32 tv_artifacts ; |
| 44 | 48 | void prio_init(); |
| r31890 | r31891 | |
| 55 | 59 | inline void LMS(int new_cmd); |
| 56 | 60 | void antic_scanline_dma(int param); |
| 57 | 61 | void generic_atari_interrupt(int button_count); |
| 58 | | |
| 59 | 62 | }; |
| 60 | 63 | |
| 61 | | void atari_interrupt_cb(pokey_device *device, int mask); |
| 62 | | POKEY_KEYBOARD_HANDLER(atari_a800_keyboard); |
| 63 | | POKEY_KEYBOARD_HANDLER(atari_a5200_keypads); |
| 64 | | |
| 65 | 64 | /* video */ |
| 66 | 65 | |
| 67 | 66 | #define CYCLES_PER_LINE 114 /* total number of cpu cycles per scanline (incl. hblank) */ |
trunk/src/emu/sound/pokey.c
| r31890 | r31891 | |
| 185 | 185 | device_sound_interface(mconfig, *this), |
| 186 | 186 | device_execute_interface(mconfig, *this), |
| 187 | 187 | device_state_interface(mconfig, *this), |
| 188 | | m_kbd_r(NULL), |
| 189 | | m_irq_f(NULL), |
| 190 | 188 | m_output_type(LEGACY_LINEAR), |
| 191 | 189 | m_icount(0), |
| 192 | 190 | m_stream(NULL), |
| r31890 | r31891 | |
| 225 | 223 | m_channel[CHAN2].m_INTMask = IRQ_TIMR2; |
| 226 | 224 | m_channel[CHAN4].m_INTMask = IRQ_TIMR4; |
| 227 | 225 | |
| 226 | // bind callbacks |
| 227 | m_keyboard_r.bind_relative_to(*owner()); |
| 228 | m_irq_f.bind_relative_to(*owner()); |
| 229 | |
| 228 | 230 | /* calculate the A/D times |
| 229 | 231 | * In normal, slow mode (SKCTL bit SK_PADDLE is clear) the conversion |
| 230 | 232 | * takes N scanlines, where N is the paddle value. A single scanline |
| r31890 | r31891 | |
| 391 | 393 | { |
| 392 | 394 | case 3: |
| 393 | 395 | /* serout_ready_cb */ |
| 394 | | if( m_IRQEN & IRQ_SEROR ) |
| 396 | if (m_IRQEN & IRQ_SEROR) |
| 395 | 397 | { |
| 396 | 398 | m_IRQST |= IRQ_SEROR; |
| 397 | | if( m_irq_f ) |
| 398 | | (m_irq_f)(this, IRQ_SEROR); |
| 399 | if (!m_irq_f.isnull()) |
| 400 | m_irq_f(IRQ_SEROR); |
| 399 | 401 | } |
| 400 | 402 | break; |
| 401 | 403 | case 4: |
| 402 | 404 | /* serout_complete */ |
| 403 | | if( m_IRQEN & IRQ_SEROC ) |
| 405 | if (m_IRQEN & IRQ_SEROC) |
| 404 | 406 | { |
| 405 | 407 | m_IRQST |= IRQ_SEROC; |
| 406 | | if( m_irq_f ) |
| 407 | | (m_irq_f)(this, IRQ_SEROC); |
| 408 | if (!m_irq_f.isnull()) |
| 409 | m_irq_f(IRQ_SEROC); |
| 408 | 410 | } |
| 409 | 411 | break; |
| 410 | 412 | case 5: |
| 411 | 413 | /* serin_ready */ |
| 412 | | if( m_IRQEN & IRQ_SERIN ) |
| 414 | if (m_IRQEN & IRQ_SERIN) |
| 413 | 415 | { |
| 414 | | /* set the enabled timer irq status bits */ |
| 415 | 416 | m_IRQST |= IRQ_SERIN; |
| 416 | | /* call back an application supplied function to handle the interrupt */ |
| 417 | | if( m_irq_f ) |
| 418 | | (m_irq_f)(this, IRQ_SERIN); |
| 417 | if (!m_irq_f.isnull()) |
| 418 | m_irq_f(IRQ_SERIN); |
| 419 | 419 | } |
| 420 | 420 | break; |
| 421 | 421 | case SYNC_WRITE: |
| r31890 | r31891 | |
| 477 | 477 | { |
| 478 | 478 | if (++m_kbd_cnt > 63) |
| 479 | 479 | m_kbd_cnt = 0; |
| 480 | | if (m_kbd_r) { |
| 481 | | UINT8 ret = m_kbd_r(this, m_kbd_cnt); |
| 480 | if (!m_keyboard_r.isnull()) |
| 481 | { |
| 482 | UINT8 ret = m_keyboard_r(m_kbd_cnt); |
| 483 | |
| 482 | 484 | switch (m_kbd_cnt) |
| 483 | 485 | { |
| 484 | 486 | case POK_KEY_BREAK: |
| 485 | 487 | if (ret & 2) |
| 486 | 488 | { |
| 487 | 489 | /* check if the break IRQ is enabled */ |
| 488 | | if( m_IRQEN & IRQ_BREAK ) |
| 490 | if (m_IRQEN & IRQ_BREAK) |
| 489 | 491 | { |
| 490 | | /* set break IRQ status and call back the interrupt handler */ |
| 491 | 492 | m_IRQST |= IRQ_BREAK; |
| 492 | | if( m_irq_f ) |
| 493 | | (*m_irq_f)(this, IRQ_BREAK); |
| 493 | if (!m_irq_f.isnull()) |
| 494 | m_irq_f(IRQ_BREAK); |
| 494 | 495 | } |
| 495 | 496 | } |
| 496 | 497 | break; |
| 497 | 498 | case POK_KEY_SHIFT: |
| 498 | 499 | m_kbd_latch = (m_kbd_latch & 0xbf) | ((ret & 2) << 5); |
| 499 | | if( m_kbd_latch & 0x40 ) |
| 500 | if (m_kbd_latch & 0x40) |
| 500 | 501 | m_SKSTAT |= SK_SHIFT; |
| 501 | 502 | else |
| 502 | 503 | m_SKSTAT &= ~SK_SHIFT; |
| r31890 | r31891 | |
| 522 | 523 | { |
| 523 | 524 | m_KBCODE = m_kbd_latch; |
| 524 | 525 | m_SKSTAT |= SK_KEYBD; |
| 525 | | if( m_IRQEN & IRQ_KEYBD ) |
| 526 | if (m_IRQEN & IRQ_KEYBD) |
| 526 | 527 | { |
| 527 | 528 | /* last interrupt not acknowledged ? */ |
| 528 | | if( m_IRQST & IRQ_KEYBD ) |
| 529 | if(m_IRQST & IRQ_KEYBD) |
| 529 | 530 | m_SKSTAT |= SK_KBERR; |
| 530 | 531 | m_IRQST |= IRQ_KEYBD; |
| 531 | | if( m_irq_f ) |
| 532 | | (*m_irq_f)(this, IRQ_KEYBD); |
| 532 | if (!m_irq_f.isnull()) |
| 533 | m_irq_f(IRQ_KEYBD); |
| 533 | 534 | } |
| 534 | 535 | m_kbd_state++; |
| 535 | 536 | } |
| r31890 | r31891 | |
| 646 | 647 | process_channel(CHAN2); |
| 647 | 648 | |
| 648 | 649 | /* check if some of the requested timer interrupts are enabled */ |
| 649 | | if ((m_IRQST & IRQ_TIMR2) && m_irq_f ) |
| 650 | | (*m_irq_f)(this, IRQ_TIMR2); |
| 650 | if ((m_IRQST & IRQ_TIMR2) && !m_irq_f.isnull()) |
| 651 | m_irq_f(IRQ_TIMR2); |
| 651 | 652 | } |
| 652 | 653 | |
| 653 | 654 | if (m_channel[CHAN1].check_borrow()) |
| r31890 | r31891 | |
| 659 | 660 | m_channel[CHAN1].reset_channel(); |
| 660 | 661 | process_channel(CHAN1); |
| 661 | 662 | /* check if some of the requested timer interrupts are enabled */ |
| 662 | | if ((m_IRQST & IRQ_TIMR1) && m_irq_f ) |
| 663 | | (*m_irq_f)(this, IRQ_TIMR1); |
| 663 | if ((m_IRQST & IRQ_TIMR1) && !m_irq_f.isnull()) |
| 664 | m_irq_f(IRQ_TIMR1); |
| 664 | 665 | } |
| 665 | 666 | |
| 666 | 667 | /* do CHAN4 before CHAN3 because CHAN3 may set borrow! */ |
| r31890 | r31891 | |
| 676 | 677 | m_channel[CHAN2].sample(); |
| 677 | 678 | else |
| 678 | 679 | m_channel[CHAN2].m_filter_sample = 1; |
| 679 | | if ((m_IRQST & IRQ_TIMR4) && m_irq_f ) |
| 680 | | (*m_irq_f)(this, IRQ_TIMR4); |
| 680 | if ((m_IRQST & IRQ_TIMR4) && !m_irq_f.isnull()) |
| 681 | m_irq_f(IRQ_TIMR4); |
| 681 | 682 | } |
| 682 | 683 | |
| 683 | 684 | if (m_channel[CHAN3].check_borrow()) |
trunk/src/emu/sound/pokey.h
| r31890 | r31891 | |
| 58 | 58 | // CALLBACK HANDLERS |
| 59 | 59 | //************************************************************************** |
| 60 | 60 | |
| 61 | | #define POKEY_KEYBOARD_HANDLER(_name) UINT8 _name(pokey_device *device, UINT8 k543210) |
| 62 | | #define POKEY_INTERRUPT_HANDLER(_name) void _name(pokey_device *device, int mask) |
| 61 | typedef device_delegate<UINT8 (UINT8 k543210)> pokey_kb_cb_delegate; |
| 62 | typedef device_delegate<void (int mask)> pokey_int_cb_delegate; |
| 63 | 63 | |
| 64 | #define POKEY_KEYBOARD_CB_MEMBER(_name) UINT8 _name(UINT8 k543210) |
| 65 | #define POKEY_INTERRUPT_CB_MEMBER(_name) void _name(int mask) |
| 64 | 66 | |
| 67 | |
| 65 | 68 | //************************************************************************** |
| 66 | 69 | // INTERFACE CONFIGURATION MACROS |
| 67 | 70 | //************************************************************************** |
| r31890 | r31891 | |
| 101 | 104 | |
| 102 | 105 | /* k543210 = k5 ... k0 returns bit0: kr1, bit1: kr2 */ |
| 103 | 106 | /* all are, in contrast to actual hardware, ACTIVE_HIGH */ |
| 104 | | #define MCFG_POKEY_KEYBOARD_HANDLER(_kbd) \ |
| 105 | | (downcast<pokey_device *>(device))->m_kbd_r = _kbd; |
| 107 | #define MCFG_POKEY_KEYBOARD_CB(_class, _method) \ |
| 108 | pokey_device::set_keyboard_callback(*device, pokey_kb_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); |
| 106 | 109 | |
| 107 | | #define MCFG_POKEY_INTERRUPT_HANDLER(_irqf) \ |
| 108 | | (downcast<pokey_device *>(device))->m_irq_f = _irqf; |
| 110 | #define MCFG_POKEY_INTERRUPT_CB(_class, _method) \ |
| 111 | pokey_device::set_interrupt_callback(*device, pokey_int_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); |
| 109 | 112 | |
| 113 | |
| 110 | 114 | #define MCFG_POKEY_OUTPUT_RC(_R, _C, _V) \ |
| 111 | 115 | (downcast<pokey_device *>(device))->m_output_type = pokey_device::RC_LOWPASS; \ |
| 112 | 116 | (downcast<pokey_device *>(device))->m_r_pullup = (_R); \ |
| r31890 | r31891 | |
| 221 | 225 | template<class _Object> static devcb_base &set_serin_r_callback(device_t &device, _Object object) { return downcast<pokey_device &>(device).m_serin_r_cb.set_callback(object); } |
| 222 | 226 | template<class _Object> static devcb_base &set_serout_w_callback(device_t &device, _Object object) { return downcast<pokey_device &>(device).m_serout_w_cb.set_callback(object); } |
| 223 | 227 | |
| 228 | static void set_keyboard_callback(device_t &device, pokey_kb_cb_delegate callback) { downcast<pokey_device &>(device).m_keyboard_r = callback; } |
| 229 | static void set_interrupt_callback(device_t &device, pokey_int_cb_delegate callback) { downcast<pokey_device &>(device).m_irq_f = callback; } |
| 230 | |
| 224 | 231 | DECLARE_READ8_MEMBER( read ); |
| 225 | 232 | DECLARE_WRITE8_MEMBER( write ); |
| 226 | 233 | |
| r31890 | r31891 | |
| 229 | 236 | |
| 230 | 237 | void serin_ready(int after); |
| 231 | 238 | |
| 232 | | // internal configuration |
| 233 | | |
| 234 | | POKEY_KEYBOARD_HANDLER((*m_kbd_r)); |
| 235 | | POKEY_INTERRUPT_HANDLER((*m_irq_f)); |
| 236 | | |
| 237 | 239 | // analog output configuration |
| 238 | 240 | |
| 239 | 241 | output_type m_output_type; |
| r31890 | r31891 | |
| 346 | 348 | devcb_read8 m_serin_r_cb; |
| 347 | 349 | devcb_write8 m_serout_w_cb; |
| 348 | 350 | |
| 351 | pokey_kb_cb_delegate m_keyboard_r; |
| 352 | pokey_int_cb_delegate m_irq_f; |
| 353 | |
| 349 | 354 | UINT8 m_POTx[8]; /* POTx (R/D200-D207) */ |
| 350 | 355 | UINT8 m_AUDCTL; /* AUDCTL (W/D208) */ |
| 351 | 356 | UINT8 m_ALLPOT; /* ALLPOT (R/D208) */ |
trunk/src/mess/drivers/atari400.c
| r31890 | r31891 | |
| 2028 | 2028 | MCFG_POKEY_POT7_R_CB(IOPORT("analog_7")) |
| 2029 | 2029 | MCFG_POKEY_SERIN_R_CB(DEVREAD8("fdc", atari_fdc_device, serin_r)) |
| 2030 | 2030 | MCFG_POKEY_SEROUT_W_CB(DEVWRITE8("fdc", atari_fdc_device, serout_w)) |
| 2031 | | MCFG_POKEY_KEYBOARD_HANDLER(atari_a800_keyboard) |
| 2032 | | MCFG_POKEY_INTERRUPT_HANDLER(atari_interrupt_cb) |
| 2031 | MCFG_POKEY_KEYBOARD_CB(atari_common_state, a800_keyboard) |
| 2032 | MCFG_POKEY_INTERRUPT_CB(atari_common_state, interrupt_cb) |
| 2033 | 2033 | |
| 2034 | 2034 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 2035 | 2035 | MACHINE_CONFIG_END |
| r31890 | r31891 | |
| 2222 | 2222 | MCFG_SOUND_MODIFY("pokey") |
| 2223 | 2223 | MCFG_POKEY_SERIN_R_CB(NULL) |
| 2224 | 2224 | MCFG_POKEY_SEROUT_W_CB(NULL) |
| 2225 | | MCFG_POKEY_KEYBOARD_HANDLER(atari_a5200_keypads) |
| 2226 | | MCFG_POKEY_INTERRUPT_HANDLER(atari_interrupt_cb) |
| 2225 | MCFG_POKEY_KEYBOARD_CB(atari_common_state, a5200_keypads) |
| 2226 | MCFG_POKEY_INTERRUPT_CB(atari_common_state, interrupt_cb) |
| 2227 | 2227 | |
| 2228 | 2228 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 2229 | 2229 | |