trunk/src/emu/sound/262intf.c
| r22798 | r22799 | |
| 10 | 10 | #include "ymf262.h" |
| 11 | 11 | |
| 12 | 12 | |
| 13 | | struct ymf262_state |
| 13 | /* IRQ Handler */ |
| 14 | static void IRQHandler(void *param,int irq) |
| 14 | 15 | { |
| 15 | | sound_stream * stream; |
| 16 | | emu_timer * timer[2]; |
| 17 | | void * chip; |
| 18 | | const ymf262_interface *intf; |
| 19 | | device_t *device; |
| 20 | | devcb_resolved_write_line irqhandler; |
| 21 | | }; |
| 22 | | |
| 23 | | |
| 24 | | INLINE ymf262_state *get_safe_token(device_t *device) |
| 25 | | { |
| 26 | | assert(device != NULL); |
| 27 | | assert(device->type() == YMF262); |
| 28 | | return (ymf262_state *)downcast<ymf262_device *>(device)->token(); |
| 16 | ymf262_device *ymf262 = (ymf262_device *) param; |
| 17 | ymf262->_IRQHandler(irq); |
| 29 | 18 | } |
| 30 | 19 | |
| 31 | | |
| 32 | | |
| 33 | | |
| 34 | | static void IRQHandler_262(void *param,int irq) |
| 20 | void ymf262_device::_IRQHandler(int irq) |
| 35 | 21 | { |
| 36 | | ymf262_state *info = (ymf262_state *)param; |
| 37 | | if (!info->irqhandler.isnull()) |
| 38 | | info->irqhandler(irq); |
| 22 | if (!m_irq_handler.isnull()) |
| 23 | m_irq_handler(irq); |
| 39 | 24 | } |
| 40 | 25 | |
| 41 | | static TIMER_CALLBACK( timer_callback_262_0 ) |
| 26 | /* Timer overflow callback from timer.c */ |
| 27 | void ymf262_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 42 | 28 | { |
| 43 | | ymf262_state *info = (ymf262_state *)ptr; |
| 44 | | ymf262_timer_over(info->chip, 0); |
| 29 | switch(id) |
| 30 | { |
| 31 | case 0: |
| 32 | ymf262_timer_over(m_chip,0); |
| 33 | break; |
| 34 | |
| 35 | case 1: |
| 36 | ymf262_timer_over(m_chip,1); |
| 37 | break; |
| 38 | } |
| 45 | 39 | } |
| 46 | 40 | |
| 47 | | static TIMER_CALLBACK( timer_callback_262_1 ) |
| 41 | |
| 42 | static void timer_handler(void *param, int c, attotime period) |
| 48 | 43 | { |
| 49 | | ymf262_state *info = (ymf262_state *)ptr; |
| 50 | | ymf262_timer_over(info->chip, 1); |
| 44 | ymf262_device *ymf262 = (ymf262_device *) param; |
| 45 | ymf262->_timer_handler(c, period); |
| 51 | 46 | } |
| 52 | 47 | |
| 53 | | static void timer_handler_262(void *param,int timer, attotime period) |
| 48 | void ymf262_device::_timer_handler(int c, attotime period) |
| 54 | 49 | { |
| 55 | | ymf262_state *info = (ymf262_state *)param; |
| 56 | 50 | if( period == attotime::zero ) |
| 57 | 51 | { /* Reset FM Timer */ |
| 58 | | info->timer[timer]->enable(false); |
| 52 | m_timer[c]->enable(false); |
| 59 | 53 | } |
| 60 | 54 | else |
| 61 | 55 | { /* Start FM Timer */ |
| 62 | | info->timer[timer]->adjust(period); |
| 56 | m_timer[c]->adjust(period); |
| 63 | 57 | } |
| 64 | 58 | } |
| 65 | 59 | |
| 66 | | static STREAM_UPDATE( ymf262_stream_update ) |
| 60 | void ymf262_update_request(void *param, int interval) |
| 67 | 61 | { |
| 68 | | ymf262_state *info = (ymf262_state *)param; |
| 69 | | ymf262_update_one(info->chip, outputs, samples); |
| 62 | ymf262_device *ymf262 = (ymf262_device *) param; |
| 63 | ymf262->_ymf262_update_request(); |
| 70 | 64 | } |
| 71 | 65 | |
| 72 | | static void _stream_update(void *param, int interval) |
| 66 | void ymf262_device::_ymf262_update_request() |
| 73 | 67 | { |
| 74 | | ymf262_state *info = (ymf262_state *)param; |
| 75 | | info->stream->update(); |
| 68 | m_stream->update(); |
| 76 | 69 | } |
| 77 | 70 | |
| 78 | 71 | |
| 79 | | static DEVICE_START( ymf262 ) |
| 72 | |
| 73 | //------------------------------------------------- |
| 74 | // sound_stream_update - handle a stream update |
| 75 | //------------------------------------------------- |
| 76 | |
| 77 | void ymf262_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 80 | 78 | { |
| 81 | | static const ymf262_interface dummy = { DEVCB_NULL }; |
| 82 | | ymf262_state *info = get_safe_token(device); |
| 83 | | int rate = device->clock()/288; |
| 79 | ymf262_update_one(m_chip, outputs, samples); |
| 80 | } |
| 84 | 81 | |
| 85 | | info->intf = device->static_config() ? (const ymf262_interface *)device->static_config() : &dummy; |
| 86 | | info->device = device; |
| 87 | | info->irqhandler.resolve(info->intf->irqhandler, *device); |
| 82 | //------------------------------------------------- |
| 83 | // device_start - device-specific startup |
| 84 | //------------------------------------------------- |
| 88 | 85 | |
| 86 | void ymf262_device::device_start() |
| 87 | { |
| 88 | int rate = clock()/288; |
| 89 | |
| 90 | m_irq_handler.resolve(); |
| 91 | |
| 89 | 92 | /* stream system initialize */ |
| 90 | | info->chip = ymf262_init(device,device->clock(),rate); |
| 91 | | assert_always(info->chip != NULL, "Error creating YMF262 chip"); |
| 93 | m_chip = ymf262_init(this,clock(),rate); |
| 94 | assert_always(m_chip != NULL, "Error creating YMF262 chip"); |
| 92 | 95 | |
| 93 | | info->stream = device->machine().sound().stream_alloc(*device,0,4,rate,info,ymf262_stream_update); |
| 96 | m_stream = machine().sound().stream_alloc(*this,0,4,rate); |
| 94 | 97 | |
| 95 | 98 | /* YMF262 setup */ |
| 96 | | ymf262_set_timer_handler (info->chip, timer_handler_262, info); |
| 97 | | ymf262_set_irq_handler (info->chip, IRQHandler_262, info); |
| 98 | | ymf262_set_update_handler(info->chip, _stream_update, info); |
| 99 | ymf262_set_timer_handler (m_chip, timer_handler, this); |
| 100 | ymf262_set_irq_handler (m_chip, IRQHandler, this); |
| 101 | ymf262_set_update_handler(m_chip, ymf262_update_request, this); |
| 99 | 102 | |
| 100 | | info->timer[0] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_262_0), info); |
| 101 | | info->timer[1] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_262_1), info); |
| 103 | m_timer[0] = timer_alloc(0); |
| 104 | m_timer[1] = timer_alloc(1); |
| 102 | 105 | } |
| 103 | 106 | |
| 104 | | static DEVICE_STOP( ymf262 ) |
| 107 | //------------------------------------------------- |
| 108 | // device_stop - device-specific stop |
| 109 | //------------------------------------------------- |
| 110 | |
| 111 | void ymf262_device::device_stop() |
| 105 | 112 | { |
| 106 | | ymf262_state *info = get_safe_token(device); |
| 107 | | ymf262_shutdown(info->chip); |
| 113 | ymf262_shutdown(m_chip); |
| 108 | 114 | } |
| 109 | 115 | |
| 110 | | /* reset */ |
| 111 | | static DEVICE_RESET( ymf262 ) |
| 116 | //------------------------------------------------- |
| 117 | // device_reset - device-specific reset |
| 118 | //------------------------------------------------- |
| 119 | |
| 120 | void ymf262_device::device_reset() |
| 112 | 121 | { |
| 113 | | ymf262_state *info = get_safe_token(device); |
| 114 | | ymf262_reset_chip(info->chip); |
| 122 | ymf262_reset_chip(m_chip); |
| 115 | 123 | } |
| 116 | 124 | |
| 117 | 125 | |
| 118 | | READ8_DEVICE_HANDLER( ymf262_r ) |
| 126 | READ8_MEMBER( ymf262_device::read ) |
| 119 | 127 | { |
| 120 | | ymf262_state *info = get_safe_token(device); |
| 121 | | return ymf262_read(info->chip, offset & 3); |
| 128 | return ymf262_read(m_chip, offset & 3); |
| 122 | 129 | } |
| 123 | 130 | |
| 124 | | WRITE8_DEVICE_HANDLER( ymf262_w ) |
| 131 | WRITE8_MEMBER( ymf262_device::write ) |
| 125 | 132 | { |
| 126 | | ymf262_state *info = get_safe_token(device); |
| 127 | | ymf262_write(info->chip, offset & 3, data); |
| 133 | ymf262_write(m_chip, offset & 3, data); |
| 128 | 134 | } |
| 129 | 135 | |
| 130 | | READ8_DEVICE_HANDLER ( ymf262_status_r ) { return ymf262_r(device, space, 0); } |
| 131 | | WRITE8_DEVICE_HANDLER( ymf262_register_a_w ) { ymf262_w(device, space, 0, data); } |
| 132 | | WRITE8_DEVICE_HANDLER( ymf262_register_b_w ) { ymf262_w(device, space, 2, data); } |
| 133 | | WRITE8_DEVICE_HANDLER( ymf262_data_a_w ) { ymf262_w(device, space, 1, data); } |
| 134 | | WRITE8_DEVICE_HANDLER( ymf262_data_b_w ) { ymf262_w(device, space, 3, data); } |
| 135 | | |
| 136 | 136 | const device_type YMF262 = &device_creator<ymf262_device>; |
| 137 | 137 | |
| 138 | 138 | ymf262_device::ymf262_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 139 | 139 | : device_t(mconfig, YMF262, "YMF262", tag, owner, clock), |
| 140 | | device_sound_interface(mconfig, *this) |
| 140 | device_sound_interface(mconfig, *this), |
| 141 | m_irq_handler(*this) |
| 141 | 142 | { |
| 142 | | m_token = global_alloc_clear(ymf262_state); |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | //------------------------------------------------- |
| r22798 | r22799 | |
| 151 | 151 | void ymf262_device::device_config_complete() |
| 152 | 152 | { |
| 153 | 153 | } |
| 154 | | |
| 155 | | //------------------------------------------------- |
| 156 | | // device_start - device-specific startup |
| 157 | | //------------------------------------------------- |
| 158 | | |
| 159 | | void ymf262_device::device_start() |
| 160 | | { |
| 161 | | DEVICE_START_NAME( ymf262 )(this); |
| 162 | | } |
| 163 | | |
| 164 | | //------------------------------------------------- |
| 165 | | // device_reset - device-specific reset |
| 166 | | //------------------------------------------------- |
| 167 | | |
| 168 | | void ymf262_device::device_reset() |
| 169 | | { |
| 170 | | DEVICE_RESET_NAME( ymf262 )(this); |
| 171 | | } |
| 172 | | |
| 173 | | //------------------------------------------------- |
| 174 | | // device_stop - device-specific stop |
| 175 | | //------------------------------------------------- |
| 176 | | |
| 177 | | void ymf262_device::device_stop() |
| 178 | | { |
| 179 | | DEVICE_STOP_NAME( ymf262 )(this); |
| 180 | | } |
| 181 | | |
| 182 | | //------------------------------------------------- |
| 183 | | // sound_stream_update - handle a stream update |
| 184 | | //------------------------------------------------- |
| 185 | | |
| 186 | | void ymf262_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 187 | | { |
| 188 | | // should never get here |
| 189 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 190 | | } |
trunk/src/mess/machine/isa_sblaster.c
| r22798 | r22799 | |
| 66 | 66 | DEVCB_NULL |
| 67 | 67 | }; |
| 68 | 68 | |
| 69 | | static const ymf262_interface pc_ymf262_interface = |
| 70 | | { |
| 71 | | DEVCB_NULL |
| 72 | | }; |
| 73 | | |
| 74 | 69 | static SLOT_INTERFACE_START(midiin_slot) |
| 75 | 70 | SLOT_INTERFACE("midiin", MIDIIN_PORT) |
| 76 | 71 | SLOT_INTERFACE_END |
| r22798 | r22799 | |
| 133 | 128 | static MACHINE_CONFIG_FRAGMENT( sblaster_16_config ) |
| 134 | 129 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 135 | 130 | MCFG_SOUND_ADD("ymf262", YMF262, ymf262_StdClock) |
| 136 | | MCFG_SOUND_CONFIG(pc_ymf262_interface) |
| 137 | 131 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.00) |
| 138 | 132 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.00) |
| 139 | 133 | MCFG_SOUND_ROUTE(2, "lspeaker", 1.00) |
| r22798 | r22799 | |
| 1164 | 1158 | |
| 1165 | 1159 | void sb8_device::device_start() |
| 1166 | 1160 | { |
| 1167 | | m_isa->install_device( 0x0200, 0x0207, 0, 0, read8_delegate(FUNC(pc_joy_device::joy_port_r), subdevice<pc_joy_device>("pc_joy")), write8_delegate(FUNC(pc_joy_device::joy_port_w), subdevice<pc_joy_device>("pc_joy"))); |
| 1168 | | m_isa->install_device( 0x0226, 0x0227, 0, 0, read8_delegate(FUNC(sb_device::dsp_reset_r), this), write8_delegate(FUNC(sb_device::dsp_reset_w), this)); |
| 1169 | | m_isa->install_device( 0x022a, 0x022b, 0, 0, read8_delegate(FUNC(sb_device::dsp_data_r), this), write8_delegate(FUNC(sb_device::dsp_data_w), this) ); |
| 1170 | | m_isa->install_device( 0x022c, 0x022d, 0, 0, read8_delegate(FUNC(sb_device::dsp_wbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_cmd_w), this) ); |
| 1171 | | m_isa->install_device( 0x022e, 0x022f, 0, 0, read8_delegate(FUNC(sb_device::dsp_rbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_rbuf_status_w), this) ); |
| 1161 | m_isa->install_device(0x0200, 0x0207, 0, 0, read8_delegate(FUNC(pc_joy_device::joy_port_r), subdevice<pc_joy_device>("pc_joy")), write8_delegate(FUNC(pc_joy_device::joy_port_w), subdevice<pc_joy_device>("pc_joy"))); |
| 1162 | m_isa->install_device(0x0226, 0x0227, 0, 0, read8_delegate(FUNC(sb_device::dsp_reset_r), this), write8_delegate(FUNC(sb_device::dsp_reset_w), this)); |
| 1163 | m_isa->install_device(0x022a, 0x022b, 0, 0, read8_delegate(FUNC(sb_device::dsp_data_r), this), write8_delegate(FUNC(sb_device::dsp_data_w), this) ); |
| 1164 | m_isa->install_device(0x022c, 0x022d, 0, 0, read8_delegate(FUNC(sb_device::dsp_wbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_cmd_w), this) ); |
| 1165 | m_isa->install_device(0x022e, 0x022f, 0, 0, read8_delegate(FUNC(sb_device::dsp_rbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_rbuf_status_w), this) ); |
| 1172 | 1166 | if(m_dsp.version >= 0x0301) |
| 1173 | 1167 | { |
| 1174 | | //m_isa->install_device(0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb8_device::mixer_r), this), write8_delegate(FUNC(sb8_device::mixer_w), this)); |
| 1175 | | m_isa->install_device(subdevice("ymf262"), 0x0388, 0x038b, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) ); |
| 1176 | | m_isa->install_device(subdevice("ymf262"), 0x0220, 0x0223, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) ); |
| 1177 | | m_isa->install_device(subdevice("ymf262"), 0x0228, 0x0229, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) ); |
| 1168 | ymf262_device *ymf262 = subdevice<ymf262_device>("ymf262"); |
| 1169 | |
| 1170 | m_isa->install_device(0x0388, 0x038b, 0, 0, read8_delegate(FUNC(ymf262_device::read), ymf262), write8_delegate(FUNC(ymf262_device::write), ymf262)); |
| 1171 | m_isa->install_device(0x0220, 0x0223, 0, 0, read8_delegate(FUNC(ymf262_device::read), ymf262), write8_delegate(FUNC(ymf262_device::write), ymf262)); |
| 1172 | m_isa->install_device(0x0228, 0x0229, 0, 0, read8_delegate(FUNC(ymf262_device::read), ymf262), write8_delegate(FUNC(ymf262_device::write), ymf262)); |
| 1178 | 1173 | } |
| 1179 | 1174 | else |
| 1180 | 1175 | { |
| r22798 | r22799 | |
| 1222 | 1217 | |
| 1223 | 1218 | void sb16_device::device_start() |
| 1224 | 1219 | { |
| 1225 | | m_isa->install_device( 0x0200, 0x0207, 0, 0, read8_delegate(FUNC(pc_joy_device::joy_port_r), subdevice<pc_joy_device>("pc_joy")), write8_delegate(FUNC(pc_joy_device::joy_port_w), subdevice<pc_joy_device>("pc_joy"))); |
| 1226 | | m_isa->install_device( 0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb16_device::mixer_r), this), write8_delegate(FUNC(sb16_device::mixer_w), this)); |
| 1227 | | m_isa->install_device( 0x0226, 0x0227, 0, 0, read8_delegate(FUNC(sb_device::dsp_reset_r), this), write8_delegate(FUNC(sb_device::dsp_reset_w), this)); |
| 1228 | | m_isa->install_device( 0x022a, 0x022b, 0, 0, read8_delegate(FUNC(sb_device::dsp_data_r), this), write8_delegate(FUNC(sb_device::dsp_data_w), this) ); |
| 1229 | | m_isa->install_device( 0x022c, 0x022d, 0, 0, read8_delegate(FUNC(sb_device::dsp_wbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_cmd_w), this) ); |
| 1230 | | m_isa->install_device( 0x022e, 0x022f, 0, 0, read8_delegate(FUNC(sb_device::dsp_rbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_rbuf_status_w), this) ); |
| 1231 | | m_isa->install_device( 0x0330, 0x0331, 0, 0, read8_delegate(FUNC(sb16_device::mpu401_r), this), write8_delegate(FUNC(sb16_device::mpu401_w), this)); |
| 1232 | | m_isa->install_device(subdevice("ymf262"), 0x0388, 0x038b, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) ); |
| 1233 | | m_isa->install_device(subdevice("ymf262"), 0x0220, 0x0223, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) ); |
| 1234 | | m_isa->install_device(subdevice("ymf262"), 0x0228, 0x0229, 0, 0, FUNC(ymf262_r), FUNC(ymf262_w) ); |
| 1220 | ymf262_device *ymf262 = subdevice<ymf262_device>("ymf262"); |
| 1235 | 1221 | |
| 1222 | m_isa->install_device(0x0200, 0x0207, 0, 0, read8_delegate(FUNC(pc_joy_device::joy_port_r), subdevice<pc_joy_device>("pc_joy")), write8_delegate(FUNC(pc_joy_device::joy_port_w), subdevice<pc_joy_device>("pc_joy"))); |
| 1223 | m_isa->install_device(0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb16_device::mixer_r), this), write8_delegate(FUNC(sb16_device::mixer_w), this)); |
| 1224 | m_isa->install_device(0x0226, 0x0227, 0, 0, read8_delegate(FUNC(sb_device::dsp_reset_r), this), write8_delegate(FUNC(sb_device::dsp_reset_w), this)); |
| 1225 | m_isa->install_device(0x022a, 0x022b, 0, 0, read8_delegate(FUNC(sb_device::dsp_data_r), this), write8_delegate(FUNC(sb_device::dsp_data_w), this) ); |
| 1226 | m_isa->install_device(0x022c, 0x022d, 0, 0, read8_delegate(FUNC(sb_device::dsp_wbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_cmd_w), this) ); |
| 1227 | m_isa->install_device(0x022e, 0x022f, 0, 0, read8_delegate(FUNC(sb_device::dsp_rbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_rbuf_status_w), this) ); |
| 1228 | m_isa->install_device(0x0330, 0x0331, 0, 0, read8_delegate(FUNC(sb16_device::mpu401_r), this), write8_delegate(FUNC(sb16_device::mpu401_w), this)); |
| 1229 | m_isa->install_device(0x0388, 0x038b, 0, 0, read8_delegate(FUNC(ymf262_device::read), ymf262), write8_delegate(FUNC(ymf262_device::write), ymf262)); |
| 1230 | m_isa->install_device(0x0220, 0x0223, 0, 0, read8_delegate(FUNC(ymf262_device::read), ymf262), write8_delegate(FUNC(ymf262_device::write), ymf262)); |
| 1231 | m_isa->install_device(0x0228, 0x0229, 0, 0, read8_delegate(FUNC(ymf262_device::read), ymf262), write8_delegate(FUNC(ymf262_device::write), ymf262)); |
| 1232 | |
| 1236 | 1233 | m_timer = timer_alloc(0, NULL); |
| 1237 | 1234 | |
| 1238 | 1235 | save_item(NAME(m_mixer.data)); |