trunk/src/mame/drivers/snk.c
| r22790 | r22791 | |
| 473 | 473 | DEVCB_DRIVER_LINE_MEMBER(snk_state,ymirq_callback_1) |
| 474 | 474 | }; |
| 475 | 475 | |
| 476 | | static const y8950_interface y8950_config_2 = |
| 477 | | { |
| 478 | | DEVCB_DRIVER_LINE_MEMBER(snk_state,ymirq_callback_2) |
| 479 | | }; |
| 480 | 476 | |
| 481 | 477 | |
| 482 | | |
| 483 | 478 | WRITE8_MEMBER(snk_state::snk_soundlatch_w) |
| 484 | 479 | { |
| 485 | 480 | soundlatch_byte_w(space, offset, data); |
| r22790 | r22791 | |
| 1462 | 1457 | AM_RANGE(0xe000, 0xe000) AM_READ(soundlatch_byte_r) |
| 1463 | 1458 | AM_RANGE(0xe800, 0xe800) AM_DEVREADWRITE("ym1", ym3526_device, status_port_r, control_port_w) |
| 1464 | 1459 | AM_RANGE(0xec00, 0xec00) AM_DEVWRITE("ym1", ym3526_device, write_port_w) |
| 1465 | | AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE_LEGACY("ym2", y8950_status_port_r, y8950_control_port_w) |
| 1466 | | AM_RANGE(0xf400, 0xf400) AM_DEVWRITE_LEGACY("ym2", y8950_write_port_w) |
| 1460 | AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("ym2", y8950_device, status_port_r, control_port_w) |
| 1461 | AM_RANGE(0xf400, 0xf400) AM_DEVWRITE("ym2", y8950_device, write_port_w) |
| 1467 | 1462 | AM_RANGE(0xf800, 0xf800) AM_READWRITE(snk_sound_status_r, snk_sound_status_w) |
| 1468 | 1463 | ADDRESS_MAP_END |
| 1469 | 1464 | |
| r22790 | r22791 | |
| 1473 | 1468 | AM_RANGE(0xe000, 0xe000) AM_READ(soundlatch_byte_r) |
| 1474 | 1469 | AM_RANGE(0xe800, 0xe800) AM_DEVREADWRITE_LEGACY("ym1", ym3812_status_port_r, ym3812_control_port_w) |
| 1475 | 1470 | AM_RANGE(0xec00, 0xec00) AM_DEVWRITE_LEGACY("ym1", ym3812_write_port_w) |
| 1476 | | AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE_LEGACY("ym2", y8950_status_port_r, y8950_control_port_w) |
| 1477 | | AM_RANGE(0xf400, 0xf400) AM_DEVWRITE_LEGACY("ym2", y8950_write_port_w) |
| 1471 | AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("ym2", y8950_device, status_port_r, control_port_w) |
| 1472 | AM_RANGE(0xf400, 0xf400) AM_DEVWRITE("ym2", y8950_device, write_port_w) |
| 1478 | 1473 | AM_RANGE(0xf800, 0xf800) AM_READWRITE(snk_sound_status_r, snk_sound_status_w) |
| 1479 | 1474 | ADDRESS_MAP_END |
| 1480 | 1475 | |
| r22790 | r22791 | |
| 1482 | 1477 | AM_RANGE(0x0000, 0xbfff) AM_ROM |
| 1483 | 1478 | AM_RANGE(0xc000, 0xcfff) AM_RAM |
| 1484 | 1479 | AM_RANGE(0xe000, 0xe000) AM_READ(soundlatch_byte_r) |
| 1485 | | AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE_LEGACY("ym2", y8950_status_port_r, y8950_control_port_w) |
| 1486 | | AM_RANGE(0xf400, 0xf400) AM_DEVWRITE_LEGACY("ym2", y8950_write_port_w) |
| 1480 | AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("ym2", y8950_device, status_port_r, control_port_w) |
| 1481 | AM_RANGE(0xf400, 0xf400) AM_DEVWRITE("ym2", y8950_device, write_port_w) |
| 1487 | 1482 | AM_RANGE(0xf800, 0xf800) AM_READWRITE(snk_sound_status_r, snk_sound_status_w) |
| 1488 | 1483 | ADDRESS_MAP_END |
| 1489 | 1484 | |
| r22790 | r22791 | |
| 3899 | 3894 | |
| 3900 | 3895 | /* sound hardware */ |
| 3901 | 3896 | MCFG_SOUND_REPLACE("ym2", Y8950, XTAL_8MHz/2) /* verified on pcb */ |
| 3902 | | MCFG_SOUND_CONFIG(y8950_config_2) |
| 3897 | MCFG_Y8950_IRQ_HANDLER(WRITELINE(snk_state, ymirq_callback_2)) |
| 3903 | 3898 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 2.0) |
| 3904 | 3899 | MACHINE_CONFIG_END |
| 3905 | 3900 | |
| r22790 | r22791 | |
| 3942 | 3937 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 2.0) |
| 3943 | 3938 | |
| 3944 | 3939 | MCFG_SOUND_ADD("ym2", Y8950, XTAL_8MHz/2) /* verified on pcb */ |
| 3945 | | MCFG_SOUND_CONFIG(y8950_config_2) |
| 3940 | MCFG_Y8950_IRQ_HANDLER(WRITELINE(snk_state, ymirq_callback_2)) |
| 3946 | 3941 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 2.0) |
| 3947 | 3942 | MACHINE_CONFIG_END |
| 3948 | 3943 | |
| r22790 | r22791 | |
| 4046 | 4041 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) |
| 4047 | 4042 | |
| 4048 | 4043 | MCFG_SOUND_ADD("ym2", Y8950, 4000000) |
| 4049 | | MCFG_SOUND_CONFIG(y8950_config_2) |
| 4044 | MCFG_Y8950_IRQ_HANDLER(WRITELINE(snk_state, ymirq_callback_2)) |
| 4050 | 4045 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) |
| 4051 | 4046 | MACHINE_CONFIG_END |
| 4052 | 4047 | |
trunk/src/emu/sound/8950intf.c
| r22790 | r22791 | |
| 16 | 16 | * NOTES |
| 17 | 17 | * |
| 18 | 18 | ******************************************************************************/ |
| 19 | | #include "emu.h" |
| 20 | 19 | #include "8950intf.h" |
| 21 | 20 | #include "fm.h" |
| 22 | | #include "sound/fmopl.h" |
| 21 | #include "fmopl.h" |
| 23 | 22 | |
| 24 | 23 | |
| 25 | | struct y8950_state |
| 24 | static void IRQHandler(void *param,int irq) |
| 26 | 25 | { |
| 27 | | sound_stream * stream; |
| 28 | | emu_timer * timer[2]; |
| 29 | | void * chip; |
| 30 | | const y8950_interface *intf; |
| 31 | | y8950_device *device; |
| 32 | | }; |
| 26 | y8950_device *y8950 = (y8950_device *) param; |
| 27 | y8950->_IRQHandler(irq); |
| 28 | } |
| 33 | 29 | |
| 34 | | |
| 35 | | INLINE y8950_state *get_safe_token(device_t *device) |
| 30 | void y8950_device::_IRQHandler(int irq) |
| 36 | 31 | { |
| 37 | | assert(device != NULL); |
| 38 | | assert(device->type() == Y8950); |
| 39 | | return (y8950_state *)downcast<y8950_device *>(device)->token(); |
| 32 | m_irq_handler(irq); |
| 40 | 33 | } |
| 41 | 34 | |
| 42 | | |
| 43 | | static void IRQHandler(void *param,int irq) |
| 35 | void y8950_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 44 | 36 | { |
| 45 | | y8950_state *info = (y8950_state *)param; |
| 46 | | if (!info->device->m_handler.isnull()) info->device->m_handler(irq ? ASSERT_LINE : CLEAR_LINE); |
| 37 | switch(id) |
| 38 | { |
| 39 | case 0: |
| 40 | y8950_timer_over(m_chip,0); |
| 41 | break; |
| 42 | |
| 43 | case 1: |
| 44 | y8950_timer_over(m_chip,1); |
| 45 | break; |
| 46 | } |
| 47 | 47 | } |
| 48 | | static TIMER_CALLBACK( timer_callback_0 ) |
| 48 | |
| 49 | static void timer_handler(void *param, int c, attotime period) |
| 49 | 50 | { |
| 50 | | y8950_state *info = (y8950_state *)ptr; |
| 51 | | y8950_timer_over(info->chip,0); |
| 51 | y8950_device *y8950 = (y8950_device *) param; |
| 52 | y8950->_timer_handler(c, period); |
| 52 | 53 | } |
| 53 | | static TIMER_CALLBACK( timer_callback_1 ) |
| 54 | |
| 55 | void y8950_device::_timer_handler(int c, attotime period) |
| 54 | 56 | { |
| 55 | | y8950_state *info = (y8950_state *)ptr; |
| 56 | | y8950_timer_over(info->chip,1); |
| 57 | | } |
| 58 | | static void TimerHandler(void *param,int c,attotime period) |
| 59 | | { |
| 60 | | y8950_state *info = (y8950_state *)param; |
| 61 | 57 | if( period == attotime::zero ) |
| 62 | 58 | { /* Reset FM Timer */ |
| 63 | | info->timer[c]->enable(false); |
| 59 | m_timer[c]->enable(false); |
| 64 | 60 | } |
| 65 | 61 | else |
| 66 | 62 | { /* Start FM Timer */ |
| 67 | | info->timer[c]->adjust(period); |
| 63 | m_timer[c]->adjust(period); |
| 68 | 64 | } |
| 69 | 65 | } |
| 70 | 66 | |
| 71 | 67 | |
| 72 | 68 | static unsigned char Y8950PortHandler_r(void *param) |
| 73 | 69 | { |
| 74 | | y8950_state *info = (y8950_state *)param; |
| 75 | | if (!info->device->m_portread.isnull()) |
| 76 | | return info->device->m_portread(0); |
| 77 | | return 0; |
| 70 | y8950_device *y8950 = (y8950_device *) param; |
| 71 | return y8950->_Y8950PortHandler_r(); |
| 78 | 72 | } |
| 79 | 73 | |
| 74 | unsigned char y8950_device::_Y8950PortHandler_r() |
| 75 | { |
| 76 | return m_io_read_handler(0); |
| 77 | } |
| 78 | |
| 80 | 79 | static void Y8950PortHandler_w(void *param,unsigned char data) |
| 81 | 80 | { |
| 82 | | y8950_state *info = (y8950_state *)param; |
| 83 | | if (!info->device->m_portwrite.isnull()) |
| 84 | | info->device->m_portwrite(0,data); |
| 81 | y8950_device *y8950 = (y8950_device *) param; |
| 82 | y8950->_Y8950PortHandler_w(data); |
| 85 | 83 | } |
| 86 | 84 | |
| 85 | void y8950_device::_Y8950PortHandler_w(unsigned char data) |
| 86 | { |
| 87 | m_io_write_handler((offs_t)0,data); |
| 88 | } |
| 89 | |
| 87 | 90 | static unsigned char Y8950KeyboardHandler_r(void *param) |
| 88 | 91 | { |
| 89 | | y8950_state *info = (y8950_state *)param; |
| 90 | | if (!info->device->m_keyboardread.isnull()) |
| 91 | | return info->device->m_keyboardread(0); |
| 92 | | return 0; |
| 92 | y8950_device *y8950 = (y8950_device *) param; |
| 93 | return y8950->_Y8950KeyboardHandler_r(); |
| 93 | 94 | } |
| 94 | 95 | |
| 96 | unsigned char y8950_device::_Y8950KeyboardHandler_r() |
| 97 | { |
| 98 | return m_keyboard_read_handler(0); |
| 99 | } |
| 100 | |
| 95 | 101 | static void Y8950KeyboardHandler_w(void *param,unsigned char data) |
| 96 | 102 | { |
| 97 | | y8950_state *info = (y8950_state *)param; |
| 98 | | if (!info->device->m_keyboardwrite.isnull()) |
| 99 | | info->device->m_keyboardwrite(0,data); |
| 103 | y8950_device *y8950 = (y8950_device *) param; |
| 104 | y8950->_Y8950KeyboardHandler_w(data); |
| 100 | 105 | } |
| 101 | 106 | |
| 102 | | static STREAM_UPDATE( y8950_stream_update ) |
| 107 | void y8950_device::_Y8950KeyboardHandler_w(unsigned char data) |
| 103 | 108 | { |
| 104 | | y8950_state *info = (y8950_state *)param; |
| 105 | | y8950_update_one(info->chip, outputs[0], samples); |
| 109 | m_keyboard_write_handler((offs_t)0,data); |
| 106 | 110 | } |
| 107 | 111 | |
| 108 | | static void _stream_update(void *param, int interval) |
| 112 | //------------------------------------------------- |
| 113 | // sound_stream_update - handle a stream update |
| 114 | //------------------------------------------------- |
| 115 | |
| 116 | void y8950_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 109 | 117 | { |
| 110 | | y8950_state *info = (y8950_state *)param; |
| 111 | | info->stream->update(); |
| 118 | y8950_update_one(m_chip, outputs[0], samples); |
| 112 | 119 | } |
| 113 | 120 | |
| 121 | static void y8950_update_request(void *param, int interval) |
| 122 | { |
| 123 | y8950_device *y8950 = (y8950_device *) param; |
| 124 | y8950->_y8950_update_request(); |
| 125 | } |
| 114 | 126 | |
| 115 | | static DEVICE_START( y8950 ) |
| 127 | void y8950_device::_y8950_update_request() |
| 116 | 128 | { |
| 117 | | static const y8950_interface dummy = { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL }; |
| 118 | | y8950_state *info = get_safe_token(device); |
| 119 | | int rate = device->clock()/72; |
| 129 | m_stream->update(); |
| 130 | } |
| 120 | 131 | |
| 121 | | info->intf = device->static_config() ? (const y8950_interface *)device->static_config() : &dummy; |
| 122 | | info->device = downcast<y8950_device *>(device); |
| 123 | 132 | |
| 133 | //------------------------------------------------- |
| 134 | // device_start - device-specific startup |
| 135 | //------------------------------------------------- |
| 136 | |
| 137 | void y8950_device::device_start() |
| 138 | { |
| 139 | int rate = clock()/72; |
| 140 | |
| 141 | m_irq_handler.resolve_safe(); |
| 142 | m_keyboard_read_handler.resolve_safe(0); |
| 143 | m_keyboard_write_handler.resolve_safe(); |
| 144 | m_io_read_handler.resolve_safe(0); |
| 145 | m_io_write_handler.resolve_safe(); |
| 146 | |
| 124 | 147 | /* stream system initialize */ |
| 125 | | info->chip = y8950_init(device,device->clock(),rate); |
| 126 | | assert_always(info->chip != NULL, "Error creating Y8950 chip"); |
| 148 | m_chip = y8950_init(this,clock(),rate); |
| 149 | assert_always(m_chip != NULL, "Error creating Y8950 chip"); |
| 127 | 150 | |
| 128 | 151 | /* ADPCM ROM data */ |
| 129 | | y8950_set_delta_t_memory(info->chip, *device->region(), device->region()->bytes()); |
| 152 | y8950_set_delta_t_memory(m_chip, *region(), region()->bytes()); |
| 130 | 153 | |
| 131 | | info->stream = device->machine().sound().stream_alloc(*device,0,1,rate,info,y8950_stream_update); |
| 154 | m_stream = machine().sound().stream_alloc(*this,0,1,rate); |
| 132 | 155 | /* port and keyboard handler */ |
| 133 | | y8950_set_port_handler(info->chip, Y8950PortHandler_w, Y8950PortHandler_r, info); |
| 134 | | y8950_set_keyboard_handler(info->chip, Y8950KeyboardHandler_w, Y8950KeyboardHandler_r, info); |
| 156 | y8950_set_port_handler(m_chip, Y8950PortHandler_w, Y8950PortHandler_r, this); |
| 157 | y8950_set_keyboard_handler(m_chip, Y8950KeyboardHandler_w, Y8950KeyboardHandler_r, this); |
| 135 | 158 | |
| 136 | 159 | /* Y8950 setup */ |
| 137 | | y8950_set_timer_handler (info->chip, TimerHandler, info); |
| 138 | | y8950_set_irq_handler (info->chip, IRQHandler, info); |
| 139 | | y8950_set_update_handler(info->chip, _stream_update, info); |
| 160 | y8950_set_timer_handler (m_chip, timer_handler, this); |
| 161 | y8950_set_irq_handler (m_chip, IRQHandler, this); |
| 162 | y8950_set_update_handler(m_chip, y8950_update_request, this); |
| 140 | 163 | |
| 141 | | info->timer[0] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_0), info); |
| 142 | | info->timer[1] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_1), info); |
| 164 | m_timer[0] = timer_alloc(0); |
| 165 | m_timer[1] = timer_alloc(1); |
| 143 | 166 | } |
| 144 | 167 | |
| 145 | | static DEVICE_STOP( y8950 ) |
| 168 | //------------------------------------------------- |
| 169 | // device_stop - device-specific stop |
| 170 | //------------------------------------------------- |
| 171 | |
| 172 | void y8950_device::device_stop() |
| 146 | 173 | { |
| 147 | | y8950_state *info = get_safe_token(device); |
| 148 | | y8950_shutdown(info->chip); |
| 174 | y8950_shutdown(m_chip); |
| 149 | 175 | } |
| 150 | 176 | |
| 151 | | static DEVICE_RESET( y8950 ) |
| 177 | //------------------------------------------------- |
| 178 | // device_reset - device-specific reset |
| 179 | //------------------------------------------------- |
| 180 | |
| 181 | void y8950_device::device_reset() |
| 152 | 182 | { |
| 153 | | y8950_state *info = get_safe_token(device); |
| 154 | | y8950_reset_chip(info->chip); |
| 183 | y8950_reset_chip(m_chip); |
| 155 | 184 | } |
| 156 | 185 | |
| 157 | 186 | |
| 158 | | READ8_DEVICE_HANDLER( y8950_r ) |
| 187 | READ8_MEMBER( y8950_device::read ) |
| 159 | 188 | { |
| 160 | | y8950_state *info = get_safe_token(device); |
| 161 | | return y8950_read(info->chip, offset & 1); |
| 189 | return y8950_read(m_chip, offset & 1); |
| 162 | 190 | } |
| 163 | 191 | |
| 164 | | WRITE8_DEVICE_HANDLER( y8950_w ) |
| 192 | WRITE8_MEMBER( y8950_device::write ) |
| 165 | 193 | { |
| 166 | | y8950_state *info = get_safe_token(device); |
| 167 | | y8950_write(info->chip, offset & 1, data); |
| 194 | y8950_write(m_chip, offset & 1, data); |
| 168 | 195 | } |
| 169 | 196 | |
| 170 | | READ8_DEVICE_HANDLER( y8950_status_port_r ) { return y8950_r(device, space, 0); } |
| 171 | | READ8_DEVICE_HANDLER( y8950_read_port_r ) { return y8950_r(device, space, 1); } |
| 172 | | WRITE8_DEVICE_HANDLER( y8950_control_port_w ) { y8950_w(device, space, 0, data); } |
| 173 | | WRITE8_DEVICE_HANDLER( y8950_write_port_w ) { y8950_w(device, space, 1, data); } |
| 197 | READ8_MEMBER( y8950_device::status_port_r ) { return read(space, 0); } |
| 198 | READ8_MEMBER( y8950_device::read_port_r ) { return read(space, 1); } |
| 199 | WRITE8_MEMBER( y8950_device::control_port_w ) { write(space, 0, data); } |
| 200 | WRITE8_MEMBER( y8950_device::write_port_w ) { write(space, 1, data); } |
| 174 | 201 | |
| 175 | 202 | |
| 176 | 203 | const device_type Y8950 = &device_creator<y8950_device>; |
| 177 | 204 | |
| 178 | 205 | y8950_device::y8950_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 179 | 206 | : device_t(mconfig, Y8950, "Y8950", tag, owner, clock), |
| 180 | | device_sound_interface(mconfig, *this) |
| 207 | device_sound_interface(mconfig, *this), |
| 208 | m_irq_handler(*this), |
| 209 | m_keyboard_read_handler(*this), |
| 210 | m_keyboard_write_handler(*this), |
| 211 | m_io_read_handler(*this), |
| 212 | m_io_write_handler(*this) |
| 181 | 213 | { |
| 182 | | m_token = global_alloc_clear(y8950_state); |
| 183 | 214 | } |
| 184 | 215 | |
| 185 | 216 | //------------------------------------------------- |
| r22790 | r22791 | |
| 190 | 221 | |
| 191 | 222 | void y8950_device::device_config_complete() |
| 192 | 223 | { |
| 193 | | // inherit a copy of the static data |
| 194 | | const y8950_interface *intf = reinterpret_cast<const y8950_interface *>(static_config()); |
| 195 | | if (intf != NULL) |
| 196 | | *static_cast<y8950_interface *>(this) = *intf; |
| 197 | | |
| 198 | | // or initialize to defaults if none provided |
| 199 | | else |
| 200 | | { |
| 201 | | memset(&m_handler_cb, 0, sizeof(m_handler_cb)); |
| 202 | | memset(&m_keyboardread_cb, 0, sizeof(m_keyboardread_cb)); |
| 203 | | memset(&m_keyboardwrite_cb, 0, sizeof(m_keyboardwrite_cb)); |
| 204 | | memset(&m_portread_cb, 0, sizeof(m_portread_cb)); |
| 205 | | memset(&m_portwrite_cb, 0, sizeof(m_portwrite_cb)); |
| 206 | | } |
| 207 | 224 | } |
| 208 | | |
| 209 | | //------------------------------------------------- |
| 210 | | // device_start - device-specific startup |
| 211 | | //------------------------------------------------- |
| 212 | | |
| 213 | | void y8950_device::device_start() |
| 214 | | { |
| 215 | | m_handler.resolve(m_handler_cb, *this); |
| 216 | | m_keyboardread.resolve(m_keyboardread_cb, *this); |
| 217 | | m_keyboardwrite.resolve(m_keyboardwrite_cb, *this); |
| 218 | | m_portread.resolve(m_portread_cb, *this); |
| 219 | | m_portwrite.resolve(m_portwrite_cb, *this); |
| 220 | | |
| 221 | | DEVICE_START_NAME( y8950 )(this); |
| 222 | | } |
| 223 | | |
| 224 | | //------------------------------------------------- |
| 225 | | // device_reset - device-specific reset |
| 226 | | //------------------------------------------------- |
| 227 | | |
| 228 | | void y8950_device::device_reset() |
| 229 | | { |
| 230 | | DEVICE_RESET_NAME( y8950 )(this); |
| 231 | | } |
| 232 | | |
| 233 | | //------------------------------------------------- |
| 234 | | // device_stop - device-specific stop |
| 235 | | //------------------------------------------------- |
| 236 | | |
| 237 | | void y8950_device::device_stop() |
| 238 | | { |
| 239 | | DEVICE_STOP_NAME( y8950 )(this); |
| 240 | | } |
| 241 | | |
| 242 | | //------------------------------------------------- |
| 243 | | // sound_stream_update - handle a stream update |
| 244 | | //------------------------------------------------- |
| 245 | | |
| 246 | | void y8950_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 247 | | { |
| 248 | | // should never get here |
| 249 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 250 | | } |
trunk/src/emu/sound/8950intf.h
| r22790 | r22791 | |
| 3 | 3 | #ifndef __8950INTF_H__ |
| 4 | 4 | #define __8950INTF_H__ |
| 5 | 5 | |
| 6 | | #include "devlegcy.h" |
| 6 | #include "emu.h" |
| 7 | 7 | |
| 8 | | struct y8950_interface |
| 9 | | { |
| 10 | | devcb_write_line m_handler_cb; |
| 11 | | devcb_read8 m_keyboardread_cb; |
| 12 | | devcb_write8 m_keyboardwrite_cb; |
| 13 | | devcb_read8 m_portread_cb; |
| 14 | | devcb_write8 m_portwrite_cb; |
| 15 | | }; |
| 8 | #define MCFG_Y8950_IRQ_HANDLER(_devcb) \ |
| 9 | devcb = &y8950_device::set_irq_handler(*device, DEVCB2_##_devcb); |
| 16 | 10 | |
| 17 | | DECLARE_READ8_DEVICE_HANDLER( y8950_r ); |
| 18 | | DECLARE_WRITE8_DEVICE_HANDLER( y8950_w ); |
| 11 | #define MCFG_Y8950_KEYBOARD_READ_HANDLER(_devcb) \ |
| 12 | devcb = &y8950_device::set_keyboard_read_handler(*device, DEVCB2_##_devcb); |
| 19 | 13 | |
| 20 | | DECLARE_READ8_DEVICE_HANDLER( y8950_status_port_r ); |
| 21 | | DECLARE_READ8_DEVICE_HANDLER( y8950_read_port_r ); |
| 22 | | DECLARE_WRITE8_DEVICE_HANDLER( y8950_control_port_w ); |
| 23 | | DECLARE_WRITE8_DEVICE_HANDLER( y8950_write_port_w ); |
| 14 | #define MCFG_Y8950_KEYBOARD_WRITE_HANDLER(_devcb) \ |
| 15 | devcb = &y8950_device::set_keyboard_write_handler(*device, DEVCB2_##_devcb); |
| 24 | 16 | |
| 17 | #define MCFG_Y8950_IO_READ_HANDLER(_devcb) \ |
| 18 | devcb = &y8950_device::set_io_read_handler(*device, DEVCB2_##_devcb); |
| 19 | |
| 20 | #define MCFG_Y8950_IO_WRITE_HANDLER(_devcb) \ |
| 21 | devcb = &y8950_device::set_io_write_handler(*device, DEVCB2_##_devcb); |
| 22 | |
| 25 | 23 | class y8950_device : public device_t, |
| 26 | | public device_sound_interface, |
| 27 | | public y8950_interface |
| 24 | public device_sound_interface |
| 28 | 25 | { |
| 29 | 26 | public: |
| 30 | 27 | y8950_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 31 | | ~y8950_device() { global_free(m_token); } |
| 32 | 28 | |
| 33 | | // access to legacy token |
| 34 | | void *token() const { assert(m_token != NULL); return m_token; } |
| 29 | // static configuration helpers |
| 30 | template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<y8950_device &>(device).m_irq_handler.set_callback(object); } |
| 31 | template<class _Object> static devcb2_base &set_keyboard_read_handler(device_t &device, _Object object) { return downcast<y8950_device &>(device).m_keyboard_read_handler.set_callback(object); } |
| 32 | template<class _Object> static devcb2_base &set_keyboard_write_handler(device_t &device, _Object object) { return downcast<y8950_device &>(device).m_keyboard_write_handler.set_callback(object); } |
| 33 | template<class _Object> static devcb2_base &set_io_read_handler(device_t &device, _Object object) { return downcast<y8950_device &>(device).m_io_read_handler.set_callback(object); } |
| 34 | template<class _Object> static devcb2_base &set_io_write_handler(device_t &device, _Object object) { return downcast<y8950_device &>(device).m_io_write_handler.set_callback(object); } |
| 35 | |
| 36 | DECLARE_READ8_MEMBER( read ); |
| 37 | DECLARE_WRITE8_MEMBER( write ); |
| 38 | |
| 39 | DECLARE_READ8_MEMBER( status_port_r ); |
| 40 | DECLARE_READ8_MEMBER( read_port_r ); |
| 41 | DECLARE_WRITE8_MEMBER( control_port_w ); |
| 42 | DECLARE_WRITE8_MEMBER( write_port_w ); |
| 43 | |
| 44 | void _IRQHandler(int irq); |
| 45 | void _timer_handler(int c,attotime period); |
| 46 | void _y8950_update_request(); |
| 47 | unsigned char _Y8950PortHandler_r(); |
| 48 | void _Y8950PortHandler_w(unsigned char data); |
| 49 | unsigned char _Y8950KeyboardHandler_r(); |
| 50 | void _Y8950KeyboardHandler_w(unsigned char data); |
| 51 | |
| 35 | 52 | protected: |
| 36 | 53 | // device-level overrides |
| 37 | 54 | virtual void device_config_complete(); |
| r22790 | r22791 | |
| 39 | 56 | virtual void device_stop(); |
| 40 | 57 | virtual void device_reset(); |
| 41 | 58 | |
| 59 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 60 | |
| 42 | 61 | // sound stream update overrides |
| 43 | 62 | virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); |
| 63 | |
| 44 | 64 | private: |
| 45 | 65 | // internal state |
| 46 | | void *m_token; |
| 47 | | public: |
| 48 | | devcb_resolved_write_line m_handler; |
| 49 | | devcb_resolved_read8 m_keyboardread; |
| 50 | | devcb_resolved_write8 m_keyboardwrite; |
| 51 | | devcb_resolved_read8 m_portread; |
| 52 | | devcb_resolved_write8 m_portwrite; |
| 66 | sound_stream * m_stream; |
| 67 | emu_timer * m_timer[2]; |
| 68 | void * m_chip; |
| 69 | devcb2_write_line m_irq_handler; |
| 70 | devcb2_read8 m_keyboard_read_handler; |
| 71 | devcb2_write8 m_keyboard_write_handler; |
| 72 | devcb2_read8 m_io_read_handler; |
| 73 | devcb2_write8 m_io_write_handler; |
| 53 | 74 | }; |
| 54 | 75 | |
| 55 | 76 | extern const device_type Y8950; |