trunk/src/emu/sound/rf5c68.c
| r29530 | r29531 | |
| 24 | 24 | m_stream(NULL), |
| 25 | 25 | m_cbank(0), |
| 26 | 26 | m_wbank(0), |
| 27 | | m_enable(0), |
| 28 | | m_sample_callback(NULL) |
| 27 | m_enable(0) |
| 29 | 28 | { |
| 30 | 29 | memset(m_data, 0, sizeof(UINT8)*0x10000); |
| 31 | 30 | } |
| r29530 | r29531 | |
| 37 | 36 | |
| 38 | 37 | void rf5c68_device::device_start() |
| 39 | 38 | { |
| 40 | | const rf5c68_interface* intf = (const rf5c68_interface*)static_config(); |
| 41 | | |
| 39 | m_sample_end_cb.bind_relative_to(*owner()); |
| 40 | |
| 42 | 41 | /* allocate memory for the chip */ |
| 43 | 42 | memset(m_data, 0xff, sizeof(m_data)); |
| 44 | 43 | |
| 45 | 44 | /* allocate the stream */ |
| 46 | 45 | m_stream = stream_alloc(0, 2, clock() / 384); |
| 47 | | |
| 48 | | /* set up callback */ |
| 49 | | if(intf != NULL) |
| 50 | | m_sample_callback = intf->sample_end_callback; |
| 51 | | else |
| 52 | | m_sample_callback = NULL; |
| 53 | 46 | } |
| 54 | 47 | |
| 55 | 48 | |
| r29530 | r29531 | |
| 88 | 81 | int sample; |
| 89 | 82 | |
| 90 | 83 | /* trigger sample callback */ |
| 91 | | if(m_sample_callback) |
| 84 | if(!m_sample_end_cb.isnull()) |
| 92 | 85 | { |
| 93 | 86 | if(((chan->addr >> 11) & 0xfff) == 0xfff) |
| 94 | | m_sample_callback(this, ((chan->addr >> 11)/0x2000)); |
| 87 | m_sample_end_cb((chan->addr >> 11)/0x2000); |
| 95 | 88 | } |
| 96 | 89 | |
| 97 | 90 | /* fetch the sample and handle looping */ |
trunk/src/emu/sound/rf5c68.h
| r29530 | r29531 | |
| 19 | 19 | #define MCFG_RF5C68_REPLACE(_tag, _clock) \ |
| 20 | 20 | MCFG_DEVICE_REPLACE(_tag, RF5C68, _clock) |
| 21 | 21 | |
| 22 | #define MCFG_RF5C68_SAMPLE_END_CB(_class, _method) \ |
| 23 | rf5c68_device::set_end_callback(*device, rf5c68_sample_end_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); |
| 22 | 24 | |
| 23 | 25 | //************************************************************************** |
| 24 | 26 | // TYPE DEFINITIONS |
| 25 | 27 | //************************************************************************** |
| 26 | 28 | |
| 27 | | struct rf5c68_interface |
| 28 | | { |
| 29 | | void (*sample_end_callback)(device_t* device, int channel); |
| 30 | | }; |
| 29 | typedef device_delegate<void (int channel)> rf5c68_sample_end_cb_delegate; |
| 31 | 30 | |
| 31 | #define RF5C68_SAMPLE_END_CB_MEMBER(_name) void _name(int channel) |
| 32 | 32 | |
| 33 | |
| 33 | 34 | struct rf5c68_pcm_channel |
| 34 | 35 | { |
| 35 | 36 | rf5c68_pcm_channel() : |
| r29530 | r29531 | |
| 51 | 52 | }; |
| 52 | 53 | |
| 53 | 54 | |
| 54 | | |
| 55 | 55 | // ======================> rf5c68_device |
| 56 | 56 | |
| 57 | 57 | class rf5c68_device : public device_t, |
| r29530 | r29531 | |
| 61 | 61 | rf5c68_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 62 | 62 | ~rf5c68_device() { } |
| 63 | 63 | |
| 64 | static void set_end_callback(device_t &device, rf5c68_sample_end_cb_delegate callback) { downcast<rf5c68_device &>(device).m_sample_end_cb = callback; } |
| 65 | |
| 64 | 66 | protected: |
| 65 | 67 | // device-level overrides |
| 66 | 68 | virtual void device_start(); |
| r29530 | r29531 | |
| 82 | 84 | UINT8 m_wbank; |
| 83 | 85 | UINT8 m_enable; |
| 84 | 86 | UINT8 m_data[0x10000]; |
| 85 | | void (*m_sample_callback)(device_t* device,int channel); |
| 87 | |
| 88 | rf5c68_sample_end_cb_delegate m_sample_end_cb; |
| 86 | 89 | }; |
| 87 | 90 | |
| 88 | 91 | extern const device_type RF5C68; |
trunk/src/mess/drivers/fmtowns.c
| r29530 | r29531 | |
| 2078 | 2078 | } |
| 2079 | 2079 | |
| 2080 | 2080 | // PCM interrupt (IRQ 13) |
| 2081 | | static void towns_pcm_irq(device_t* device, int channel) |
| 2081 | RF5C68_SAMPLE_END_CB_MEMBER(towns_state::towns_pcm_irq) |
| 2082 | 2082 | { |
| 2083 | | towns_state* state = device->machine().driver_data<towns_state>(); |
| 2084 | | pic8259_device* pic = state->m_pic_slave; |
| 2085 | | |
| 2086 | | if(state->m_towns_pcm_channel_mask & (1 << channel)) |
| 2083 | if (m_towns_pcm_channel_mask & (1 << channel)) |
| 2087 | 2084 | { |
| 2088 | | state->m_towns_pcm_irq_flag = 1; |
| 2089 | | state->m_towns_pcm_channel_flag |= (1 << channel); |
| 2090 | | pic->ir5_w(1); |
| 2085 | m_towns_pcm_irq_flag = 1; |
| 2086 | m_towns_pcm_channel_flag |= (1 << channel); |
| 2087 | m_pic_slave->ir5_w(1); |
| 2091 | 2088 | if(IRQ_LOG) logerror("PIC: IRQ13 (PCM) set high (channel %i)\n",channel); |
| 2092 | 2089 | } |
| 2093 | 2090 | } |
| r29530 | r29531 | |
| 2670 | 2667 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL } |
| 2671 | 2668 | }; |
| 2672 | 2669 | |
| 2673 | | static const rf5c68_interface rf5c68_intf = |
| 2674 | | { |
| 2675 | | towns_pcm_irq |
| 2676 | | }; |
| 2677 | | |
| 2678 | 2670 | static const gfx_layout fnt_chars_16x16 = |
| 2679 | 2671 | { |
| 2680 | 2672 | 16,16, |
| r29530 | r29531 | |
| 2733 | 2725 | MCFG_SOUND_ADD("fm", YM3438, 53693100 / 7) // actual clock speed unknown |
| 2734 | 2726 | MCFG_YM2612_IRQ_HANDLER(WRITELINE(towns_state, towns_fm_irq)) |
| 2735 | 2727 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |
| 2728 | |
| 2736 | 2729 | MCFG_RF5C68_ADD("pcm", 53693100 / 7) // actual clock speed unknown |
| 2737 | | MCFG_SOUND_CONFIG(rf5c68_intf) |
| 2730 | MCFG_RF5C68_SAMPLE_END_CB(towns_state, towns_pcm_irq) |
| 2738 | 2731 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.50) |
| 2739 | 2732 | MCFG_SOUND_ADD("cdda",CDDA,0) |
| 2740 | 2733 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |