trunk/src/mame/machine/megadriv.c
| r22785 | r22786 | |
| 66 | 66 | //mame_printf_debug("megadriv_68k_YM2612_read %02x %04x\n",offset,mem_mask); |
| 67 | 67 | if ((m_genz80.z80_has_bus == 0) && (m_genz80.z80_is_reset == 0)) |
| 68 | 68 | { |
| 69 | | return ym2612_r(m_ymsnd, space, offset); |
| 69 | return m_ymsnd->read(space, offset); |
| 70 | 70 | } |
| 71 | 71 | else |
| 72 | 72 | { |
| r22785 | r22786 | |
| 83 | 83 | //mame_printf_debug("megadriv_68k_YM2612_write %02x %04x %04x\n",offset,data,mem_mask); |
| 84 | 84 | if ((m_genz80.z80_has_bus == 0) && (m_genz80.z80_is_reset == 0)) |
| 85 | 85 | { |
| 86 | | ym2612_w(m_ymsnd, space, offset, data); |
| 86 | m_ymsnd->write(space, offset, data); |
| 87 | 87 | } |
| 88 | 88 | else |
| 89 | 89 | { |
| r22785 | r22786 | |
| 774 | 774 | |
| 775 | 775 | static ADDRESS_MAP_START( megadriv_z80_map, AS_PROGRAM, 8, md_base_state ) |
| 776 | 776 | AM_RANGE(0x0000, 0x1fff) AM_RAMBANK("bank1") AM_MIRROR(0x2000) // RAM can be accessed by the 68k |
| 777 | | AM_RANGE(0x4000, 0x4003) AM_DEVREADWRITE_LEGACY("ymsnd", ym2612_r,ym2612_w) |
| 777 | AM_RANGE(0x4000, 0x4003) AM_DEVREADWRITE("ymsnd", ym2612_device, read, write) |
| 778 | 778 | |
| 779 | 779 | AM_RANGE(0x6000, 0x6000) AM_WRITE(megadriv_z80_z80_bank_w) |
| 780 | 780 | AM_RANGE(0x6001, 0x6001) AM_WRITE(megadriv_z80_z80_bank_w) // wacky races uses this address |
| r22785 | r22786 | |
| 1288 | 1288 | /* sets the megadrive z80 to it's normal ports / map */ |
| 1289 | 1289 | void mtech_state::megatech_set_megadrive_z80_as_megadrive_z80(const char* tag) |
| 1290 | 1290 | { |
| 1291 | | device_t *ym = machine().device("ymsnd"); |
| 1291 | ym2612_device *ym2612 = machine().device<ym2612_device>("ymsnd"); |
| 1292 | 1292 | |
| 1293 | 1293 | /* INIT THE PORTS *********************************************************************************************/ |
| 1294 | 1294 | machine().device(tag)->memory().space(AS_IO).install_readwrite_handler(0x0000, 0xffff, read8_delegate(FUNC(mtech_state::z80_unmapped_port_r),this), write8_delegate(FUNC(mtech_state::z80_unmapped_port_w),this)); |
| r22785 | r22786 | |
| 1303 | 1303 | machine().device(tag)->memory().space(AS_PROGRAM).install_ram(0x0000, 0x1fff, m_genz80.z80_prgram); |
| 1304 | 1304 | |
| 1305 | 1305 | |
| 1306 | | machine().device(tag)->memory().space(AS_PROGRAM).install_legacy_readwrite_handler(*ym, 0x4000, 0x4003, FUNC(ym2612_r), FUNC(ym2612_w)); |
| 1306 | machine().device(tag)->memory().space(AS_PROGRAM).install_readwrite_handler(0x4000, 0x4003, read8_delegate(FUNC(ym2612_device::read),ym2612), write8_delegate(FUNC(ym2612_device::write),ym2612)); |
| 1307 | 1307 | machine().device(tag)->memory().space(AS_PROGRAM).install_write_handler (0x6000, 0x6000, write8_delegate(FUNC(mtech_state::megadriv_z80_z80_bank_w),this)); |
| 1308 | 1308 | machine().device(tag)->memory().space(AS_PROGRAM).install_write_handler (0x6001, 0x6001, write8_delegate(FUNC(mtech_state::megadriv_z80_z80_bank_w),this)); |
| 1309 | 1309 | machine().device(tag)->memory().space(AS_PROGRAM).install_read_handler (0x6100, 0x7eff, read8_delegate(FUNC(mtech_state::megadriv_z80_unmapped_read),this)); |
trunk/src/mame/drivers/segas32.c
| r22785 | r22786 | |
| 1230 | 1230 | static ADDRESS_MAP_START( system32_sound_portmap, AS_IO, 8, segas32_state ) |
| 1231 | 1231 | ADDRESS_MAP_UNMAP_HIGH |
| 1232 | 1232 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 1233 | | AM_RANGE(0x80, 0x83) AM_MIRROR(0x0c) AM_DEVREADWRITE_LEGACY("ym1", ym3438_r, ym3438_w) |
| 1234 | | AM_RANGE(0x90, 0x93) AM_MIRROR(0x0c) AM_DEVREADWRITE_LEGACY("ym2", ym3438_r, ym3438_w) |
| 1233 | AM_RANGE(0x80, 0x83) AM_MIRROR(0x0c) AM_DEVREADWRITE("ym1", ym3438_device, read, write) |
| 1234 | AM_RANGE(0x90, 0x93) AM_MIRROR(0x0c) AM_DEVREADWRITE("ym2", ym3438_device, read, write) |
| 1235 | 1235 | AM_RANGE(0xa0, 0xaf) AM_WRITE(sound_bank_lo_w) |
| 1236 | 1236 | AM_RANGE(0xb0, 0xbf) AM_WRITE(sound_bank_hi_w) |
| 1237 | 1237 | AM_RANGE(0xc0, 0xcf) AM_WRITE(sound_int_control_lo_w) |
| r22785 | r22786 | |
| 1250 | 1250 | static ADDRESS_MAP_START( multi32_sound_portmap, AS_IO, 8, segas32_state ) |
| 1251 | 1251 | ADDRESS_MAP_UNMAP_HIGH |
| 1252 | 1252 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 1253 | | AM_RANGE(0x80, 0x83) AM_MIRROR(0x0c) AM_DEVREADWRITE_LEGACY("ymsnd", ym3438_r, ym3438_w) |
| 1253 | AM_RANGE(0x80, 0x83) AM_MIRROR(0x0c) AM_DEVREADWRITE("ymsnd", ym3438_device, read, write) |
| 1254 | 1254 | AM_RANGE(0xa0, 0xaf) AM_WRITE(sound_bank_lo_w) |
| 1255 | 1255 | AM_RANGE(0xb0, 0xbf) AM_WRITE(multipcm_bank_w) |
| 1256 | 1256 | AM_RANGE(0xc0, 0xcf) AM_WRITE(sound_int_control_lo_w) |
| r22785 | r22786 | |
| 2130 | 2130 | |
| 2131 | 2131 | /************************************* |
| 2132 | 2132 | * |
| 2133 | | * Sound interfaces |
| 2134 | | * |
| 2135 | | *************************************/ |
| 2136 | | |
| 2137 | | static const ym3438_interface ym3438_config = |
| 2138 | | { |
| 2139 | | DEVCB_DRIVER_LINE_MEMBER(segas32_state,ym3438_irq_handler) |
| 2140 | | }; |
| 2141 | | |
| 2142 | | |
| 2143 | | |
| 2144 | | /************************************* |
| 2145 | | * |
| 2146 | 2133 | * Dual PCB shared memory comms |
| 2147 | 2134 | * |
| 2148 | 2135 | *************************************/ |
| r22785 | r22786 | |
| 2212 | 2199 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 2213 | 2200 | |
| 2214 | 2201 | MCFG_SOUND_ADD("ym1", YM3438, MASTER_CLOCK/4) |
| 2215 | | MCFG_SOUND_CONFIG(ym3438_config) |
| 2202 | MCFG_YM2612_IRQ_HANDLER(WRITELINE(segas32_state, ym3438_irq_handler)) |
| 2216 | 2203 | MCFG_SOUND_ROUTE(0, "lspeaker", 0.40) |
| 2217 | 2204 | MCFG_SOUND_ROUTE(1, "rspeaker", 0.40) |
| 2218 | 2205 | |
| r22785 | r22786 | |
| 2278 | 2265 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 2279 | 2266 | |
| 2280 | 2267 | MCFG_SOUND_ADD("ymsnd", YM3438, MASTER_CLOCK/4) |
| 2281 | | MCFG_SOUND_CONFIG(ym3438_config) |
| 2268 | MCFG_YM2612_IRQ_HANDLER(WRITELINE(segas32_state, ym3438_irq_handler)) |
| 2282 | 2269 | MCFG_SOUND_ROUTE(1, "lspeaker", 0.40) |
| 2283 | 2270 | MCFG_SOUND_ROUTE(0, "rspeaker", 0.40) |
| 2284 | 2271 | |
trunk/src/emu/sound/2612intf.c
| r22785 | r22786 | |
| 12 | 12 | ***************************************************************************/ |
| 13 | 13 | |
| 14 | 14 | #include "emu.h" |
| 15 | | #include "sound/fm.h" |
| 16 | | #include "sound/2612intf.h" |
| 15 | #include "fm.h" |
| 16 | #include "2612intf.h" |
| 17 | 17 | |
| 18 | | |
| 19 | | struct ym2612_state |
| 20 | | { |
| 21 | | sound_stream * stream; |
| 22 | | emu_timer * timer[2]; |
| 23 | | void * chip; |
| 24 | | const ym2612_interface *intf; |
| 25 | | device_t *device; |
| 26 | | devcb_resolved_write_line irqhandler; |
| 27 | | }; |
| 28 | | |
| 29 | | |
| 30 | | INLINE ym2612_state *get_safe_token(device_t *device) |
| 31 | | { |
| 32 | | assert(device != NULL); |
| 33 | | assert(device->type() == YM2612 || device->type() == YM3438); |
| 34 | | return (ym2612_state *)downcast<ym2612_device *>(device)->token(); |
| 35 | | } |
| 36 | | |
| 37 | | |
| 38 | | |
| 39 | 18 | /*------------------------- TM2612 -------------------------------*/ |
| 40 | 19 | /* IRQ Handler */ |
| 41 | 20 | static void IRQHandler(void *param,int irq) |
| 42 | 21 | { |
| 43 | | ym2612_state *info = (ym2612_state *)param; |
| 44 | | if (!info->irqhandler.isnull()) |
| 45 | | info->irqhandler(irq); |
| 22 | ym2612_device *ym2612 = (ym2612_device *) param; |
| 23 | ym2612->_IRQHandler(irq); |
| 46 | 24 | } |
| 47 | 25 | |
| 48 | | /* Timer overflow callback from timer.c */ |
| 49 | | static TIMER_CALLBACK( timer_callback_2612_0 ) |
| 26 | void ym2612_device::_IRQHandler(int irq) |
| 50 | 27 | { |
| 51 | | ym2612_state *info = (ym2612_state *)ptr; |
| 52 | | ym2612_timer_over(info->chip,0); |
| 28 | if (!m_irq_handler.isnull()) |
| 29 | m_irq_handler(irq); |
| 53 | 30 | } |
| 54 | 31 | |
| 55 | | static TIMER_CALLBACK( timer_callback_2612_1 ) |
| 32 | /* Timer overflow callback from timer.c */ |
| 33 | void ym2612_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 56 | 34 | { |
| 57 | | ym2612_state *info = (ym2612_state *)ptr; |
| 58 | | ym2612_timer_over(info->chip,1); |
| 35 | switch(id) |
| 36 | { |
| 37 | case 0: |
| 38 | ym2612_timer_over(m_chip,0); |
| 39 | break; |
| 40 | |
| 41 | case 1: |
| 42 | ym2612_timer_over(m_chip,1); |
| 43 | break; |
| 44 | } |
| 59 | 45 | } |
| 60 | 46 | |
| 61 | 47 | static void timer_handler(void *param,int c,int count,int clock) |
| 62 | 48 | { |
| 63 | | ym2612_state *info = (ym2612_state *)param; |
| 49 | ym2612_device *ym2612 = (ym2612_device *) param; |
| 50 | ym2612->_timer_handler(c, count, clock); |
| 51 | } |
| 52 | |
| 53 | void ym2612_device::_timer_handler(int c,int count,int clock) |
| 54 | { |
| 64 | 55 | if( count == 0 ) |
| 65 | 56 | { /* Reset FM Timer */ |
| 66 | | info->timer[c]->enable(false); |
| 57 | m_timer[c]->enable(false); |
| 67 | 58 | } |
| 68 | 59 | else |
| 69 | 60 | { /* Start FM Timer */ |
| 70 | 61 | attotime period = attotime::from_hz(clock) * count; |
| 71 | | if (!info->timer[c]->enable(1)) |
| 72 | | info->timer[c]->adjust(period); |
| 62 | |
| 63 | if (!m_timer[c]->enable(true)) |
| 64 | m_timer[c]->adjust(period); |
| 73 | 65 | } |
| 74 | 66 | } |
| 75 | 67 | |
| 76 | 68 | /* update request from fm.c */ |
| 77 | 69 | void ym2612_update_request(void *param) |
| 78 | 70 | { |
| 79 | | ym2612_state *info = (ym2612_state *)param; |
| 80 | | info->stream->update(); |
| 71 | ym2612_device *ym2612 = (ym2612_device *) param; |
| 72 | ym2612->_ym2612_update_request(); |
| 81 | 73 | } |
| 82 | 74 | |
| 83 | | /***********************************************************/ |
| 84 | | /* YM2612 */ |
| 85 | | /***********************************************************/ |
| 75 | void ym2612_device::_ym2612_update_request() |
| 76 | { |
| 77 | m_stream->update(); |
| 78 | } |
| 86 | 79 | |
| 87 | | static STREAM_UPDATE( ym2612_stream_update ) |
| 80 | //------------------------------------------------- |
| 81 | // sound_stream_update - handle a stream update |
| 82 | //------------------------------------------------- |
| 83 | |
| 84 | void ym2612_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 88 | 85 | { |
| 89 | | ym2612_state *info = (ym2612_state *)param; |
| 90 | | ym2612_update_one(info->chip, outputs, samples); |
| 86 | ym2612_update_one(m_chip, outputs, samples); |
| 91 | 87 | } |
| 92 | 88 | |
| 93 | 89 | |
| 94 | | static void ym2612_intf_postload(ym2612_state *info) |
| 90 | void ym2612_device::device_post_load() |
| 95 | 91 | { |
| 96 | | ym2612_postload(info->chip); |
| 92 | ym2612_postload(m_chip); |
| 97 | 93 | } |
| 98 | 94 | |
| 99 | 95 | |
| 100 | | static DEVICE_START( ym2612 ) |
| 96 | //------------------------------------------------- |
| 97 | // device_start - device-specific startup |
| 98 | //------------------------------------------------- |
| 99 | |
| 100 | void ym2612_device::device_start() |
| 101 | 101 | { |
| 102 | | static const ym2612_interface dummy = { DEVCB_NULL }; |
| 103 | | ym2612_state *info = get_safe_token(device); |
| 104 | | int rate = device->clock()/72; |
| 102 | int rate = clock()/72; |
| 105 | 103 | |
| 106 | | info->intf = device->static_config() ? (const ym2612_interface *)device->static_config() : &dummy; |
| 107 | | info->device = device; |
| 108 | | info->irqhandler.resolve(info->intf->irqhandler, *device); |
| 104 | m_irq_handler.resolve(); |
| 109 | 105 | |
| 110 | 106 | /* FM init */ |
| 111 | 107 | /* Timer Handler set */ |
| 112 | | info->timer[0] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_2612_0), info); |
| 113 | | info->timer[1] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_2612_1), info); |
| 108 | m_timer[0] = timer_alloc(0); |
| 109 | m_timer[1] = timer_alloc(1); |
| 114 | 110 | |
| 115 | 111 | /* stream system initialize */ |
| 116 | | info->stream = device->machine().sound().stream_alloc(*device,0,2,rate,info,ym2612_stream_update); |
| 112 | m_stream = machine().sound().stream_alloc(*this,0,2,rate); |
| 117 | 113 | |
| 118 | 114 | /**** initialize YM2612 ****/ |
| 119 | | info->chip = ym2612_init(info,device,device->clock(),rate,timer_handler,IRQHandler); |
| 120 | | assert_always(info->chip != NULL, "Error creating YM2612 chip"); |
| 121 | | |
| 122 | | device->machine().save().register_postload(save_prepost_delegate(FUNC(ym2612_intf_postload), info)); |
| 115 | m_chip = ym2612_init(this,this,clock(),rate,timer_handler,IRQHandler); |
| 116 | assert_always(m_chip != NULL, "Error creating YM2612 chip"); |
| 123 | 117 | } |
| 124 | 118 | |
| 125 | 119 | |
| 126 | | static DEVICE_STOP( ym2612 ) |
| 120 | //------------------------------------------------- |
| 121 | // device_stop - device-specific stop |
| 122 | //------------------------------------------------- |
| 123 | |
| 124 | void ym2612_device::device_stop() |
| 127 | 125 | { |
| 128 | | ym2612_state *info = get_safe_token(device); |
| 129 | | ym2612_shutdown(info->chip); |
| 126 | ym2612_shutdown(m_chip); |
| 130 | 127 | } |
| 131 | 128 | |
| 132 | | static DEVICE_RESET( ym2612 ) |
| 129 | //------------------------------------------------- |
| 130 | // device_reset - device-specific reset |
| 131 | //------------------------------------------------- |
| 132 | |
| 133 | void ym2612_device::device_reset() |
| 133 | 134 | { |
| 134 | | ym2612_state *info = get_safe_token(device); |
| 135 | | ym2612_reset_chip(info->chip); |
| 135 | ym2612_reset_chip(m_chip); |
| 136 | 136 | } |
| 137 | 137 | |
| 138 | 138 | |
| 139 | | READ8_DEVICE_HANDLER( ym2612_r ) |
| 139 | READ8_MEMBER( ym2612_device::read ) |
| 140 | 140 | { |
| 141 | | ym2612_state *info = get_safe_token(device); |
| 142 | | return ym2612_read(info->chip, offset & 3); |
| 141 | return ym2612_read(m_chip, offset & 3); |
| 143 | 142 | } |
| 144 | 143 | |
| 145 | | WRITE8_DEVICE_HANDLER( ym2612_w ) |
| 144 | WRITE8_MEMBER( ym2612_device::write ) |
| 146 | 145 | { |
| 147 | | ym2612_state *info = get_safe_token(device); |
| 148 | | ym2612_write(info->chip, offset & 3, data); |
| 146 | ym2612_write(m_chip, offset & 3, data); |
| 149 | 147 | } |
| 150 | 148 | |
| 151 | 149 | |
| 152 | | READ8_DEVICE_HANDLER( ym2612_status_port_a_r ) { return ym2612_r(device, space, 0); } |
| 153 | | READ8_DEVICE_HANDLER( ym2612_status_port_b_r ) { return ym2612_r(device, space, 2); } |
| 154 | | READ8_DEVICE_HANDLER( ym2612_data_port_a_r ) { return ym2612_r(device, space, 1); } |
| 155 | | READ8_DEVICE_HANDLER( ym2612_data_port_b_r ) { return ym2612_r(device, space, 3); } |
| 156 | | |
| 157 | | WRITE8_DEVICE_HANDLER( ym2612_control_port_a_w ) { ym2612_w(device, space, 0, data); } |
| 158 | | WRITE8_DEVICE_HANDLER( ym2612_control_port_b_w ) { ym2612_w(device, space, 2, data); } |
| 159 | | WRITE8_DEVICE_HANDLER( ym2612_data_port_a_w ) { ym2612_w(device, space, 1, data); } |
| 160 | | WRITE8_DEVICE_HANDLER( ym2612_data_port_b_w ) { ym2612_w(device, space, 3, data); } |
| 161 | | |
| 162 | 150 | const device_type YM2612 = &device_creator<ym2612_device>; |
| 163 | 151 | |
| 164 | 152 | ym2612_device::ym2612_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 165 | 153 | : device_t(mconfig, YM2612, "YM2612", tag, owner, clock), |
| 166 | | device_sound_interface(mconfig, *this) |
| 154 | device_sound_interface(mconfig, *this), |
| 155 | m_irq_handler(*this) |
| 167 | 156 | { |
| 168 | | m_token = global_alloc_clear(ym2612_state); |
| 169 | 157 | } |
| 158 | |
| 170 | 159 | ym2612_device::ym2612_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) |
| 171 | 160 | : device_t(mconfig, type, name, tag, owner, clock), |
| 172 | | device_sound_interface(mconfig, *this) |
| 161 | device_sound_interface(mconfig, *this), |
| 162 | m_irq_handler(*this) |
| 173 | 163 | { |
| 174 | | m_token = global_alloc_clear(ym2612_state); |
| 175 | 164 | } |
| 176 | 165 | |
| 177 | 166 | //------------------------------------------------- |
| r22785 | r22786 | |
| 184 | 173 | { |
| 185 | 174 | } |
| 186 | 175 | |
| 187 | | //------------------------------------------------- |
| 188 | | // device_start - device-specific startup |
| 189 | | //------------------------------------------------- |
| 190 | 176 | |
| 191 | | void ym2612_device::device_start() |
| 192 | | { |
| 193 | | DEVICE_START_NAME( ym2612 )(this); |
| 194 | | } |
| 195 | | |
| 196 | | //------------------------------------------------- |
| 197 | | // device_reset - device-specific reset |
| 198 | | //------------------------------------------------- |
| 199 | | |
| 200 | | void ym2612_device::device_reset() |
| 201 | | { |
| 202 | | DEVICE_RESET_NAME( ym2612 )(this); |
| 203 | | } |
| 204 | | |
| 205 | | //------------------------------------------------- |
| 206 | | // device_stop - device-specific stop |
| 207 | | //------------------------------------------------- |
| 208 | | |
| 209 | | void ym2612_device::device_stop() |
| 210 | | { |
| 211 | | DEVICE_STOP_NAME( ym2612 )(this); |
| 212 | | } |
| 213 | | |
| 214 | | //------------------------------------------------- |
| 215 | | // sound_stream_update - handle a stream update |
| 216 | | //------------------------------------------------- |
| 217 | | |
| 218 | | void ym2612_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 219 | | { |
| 220 | | // should never get here |
| 221 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 222 | | } |
| 223 | | |
| 224 | | |
| 225 | 177 | const device_type YM3438 = &device_creator<ym3438_device>; |
| 226 | 178 | |
| 227 | 179 | ym3438_device::ym3438_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 228 | 180 | : ym2612_device(mconfig, YM3438, "YM3438", tag, owner, clock) |
| 229 | 181 | { |
| 230 | 182 | } |
| 231 | | |
| 232 | | //------------------------------------------------- |
| 233 | | // sound_stream_update - handle a stream update |
| 234 | | //------------------------------------------------- |
| 235 | | |
| 236 | | void ym3438_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 237 | | { |
| 238 | | // should never get here |
| 239 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 240 | | } |
trunk/src/emu/sound/2612intf.h
| r22785 | r22786 | |
| 3 | 3 | #ifndef __2612INTF_H__ |
| 4 | 4 | #define __2612INTF_H__ |
| 5 | 5 | |
| 6 | | #include "devlegcy.h" |
| 6 | #include "emu.h" |
| 7 | 7 | |
| 8 | 8 | void ym2612_update_request(void *param); |
| 9 | 9 | |
| 10 | | struct ym2612_interface |
| 11 | | { |
| 12 | | devcb_write_line irqhandler; |
| 13 | | }; |
| 10 | #define MCFG_YM2612_IRQ_HANDLER(_devcb) \ |
| 11 | devcb = &ym2612_device::set_irq_handler(*device, DEVCB2_##_devcb); |
| 14 | 12 | |
| 15 | | DECLARE_READ8_DEVICE_HANDLER( ym2612_r ); |
| 16 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2612_w ); |
| 17 | | |
| 18 | | DECLARE_READ8_DEVICE_HANDLER( ym2612_status_port_a_r ); |
| 19 | | DECLARE_READ8_DEVICE_HANDLER( ym2612_status_port_b_r ); |
| 20 | | DECLARE_READ8_DEVICE_HANDLER( ym2612_data_port_a_r ); |
| 21 | | DECLARE_READ8_DEVICE_HANDLER( ym2612_data_port_b_r ); |
| 22 | | |
| 23 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2612_control_port_a_w ); |
| 24 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2612_control_port_b_w ); |
| 25 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2612_data_port_a_w ); |
| 26 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2612_data_port_b_w ); |
| 27 | | |
| 28 | | |
| 29 | 13 | class ym2612_device : public device_t, |
| 30 | 14 | public device_sound_interface |
| 31 | 15 | { |
| 32 | 16 | public: |
| 33 | 17 | ym2612_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 34 | 18 | ym2612_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 35 | | ~ym2612_device() { global_free(m_token); } |
| 36 | 19 | |
| 37 | | // access to legacy token |
| 38 | | void *token() const { assert(m_token != NULL); return m_token; } |
| 20 | // static configuration helpers |
| 21 | template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<ym2612_device &>(device).m_irq_handler.set_callback(object); } |
| 22 | |
| 23 | DECLARE_READ8_MEMBER( read ); |
| 24 | DECLARE_WRITE8_MEMBER( write ); |
| 25 | |
| 26 | void _IRQHandler(int irq); |
| 27 | void _timer_handler(int c,int count,int clock); |
| 28 | void _ym2612_update_request(); |
| 29 | |
| 39 | 30 | protected: |
| 40 | 31 | // device-level overrides |
| 41 | 32 | virtual void device_config_complete(); |
| 42 | 33 | virtual void device_start(); |
| 34 | virtual void device_post_load(); |
| 43 | 35 | virtual void device_stop(); |
| 44 | 36 | virtual void device_reset(); |
| 45 | 37 | |
| 38 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 39 | |
| 46 | 40 | // sound stream update overrides |
| 47 | 41 | virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); |
| 42 | |
| 48 | 43 | private: |
| 49 | | // internal state |
| 50 | | void *m_token; |
| 44 | sound_stream * m_stream; |
| 45 | emu_timer * m_timer[2]; |
| 46 | void * m_chip; |
| 47 | devcb2_write_line m_irq_handler; |
| 51 | 48 | }; |
| 52 | 49 | |
| 53 | 50 | extern const device_type YM2612; |
| 54 | 51 | |
| 55 | 52 | |
| 56 | | |
| 57 | | struct ym3438_interface |
| 58 | | { |
| 59 | | devcb_write_line irqhandler; |
| 60 | | }; |
| 61 | | |
| 62 | | |
| 63 | | #define ym3438_r ym2612_r |
| 64 | | #define ym3438_w ym2612_w |
| 65 | | |
| 66 | | #define ym3438_status_port_a_r ym2612_status_port_a_r |
| 67 | | #define ym3438_status_port_b_r ym2612_status_port_b_r |
| 68 | | #define ym3438_data_port_a_r ym2612_data_port_a_r |
| 69 | | #define ym3438_data_port_b_r ym2612_data_port_b_r |
| 70 | | |
| 71 | | #define ym3438_control_port_a_w ym2612_control_port_a_w |
| 72 | | #define ym3438_control_port_b_w ym2612_control_port_b_w |
| 73 | | #define ym3438_data_port_a_w ym2612_data_port_a_w |
| 74 | | #define ym3438_data_port_b_w ym2612_data_port_b_w |
| 75 | | |
| 76 | | |
| 77 | 53 | class ym3438_device : public ym2612_device |
| 78 | 54 | { |
| 79 | 55 | public: |
| 80 | 56 | ym3438_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 81 | | |
| 82 | | // sound stream update overrides |
| 83 | | virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); |
| 84 | 57 | }; |
| 85 | 58 | |
| 86 | 59 | extern const device_type YM3438; |