trunk/src/emu/sound/2608intf.c
| r22751 | r22752 | |
| 16 | 16 | #include "2608intf.h" |
| 17 | 17 | #include "fm.h" |
| 18 | 18 | |
| 19 | | struct ym2608_state |
| 20 | | { |
| 21 | | sound_stream * stream; |
| 22 | | emu_timer * timer[2]; |
| 23 | | void * chip; |
| 24 | | void * psg; |
| 25 | | const ym2608_interface *intf; |
| 26 | | device_t *device; |
| 27 | | devcb_resolved_write_line irqhandler; |
| 28 | | }; |
| 29 | | |
| 30 | | |
| 31 | | INLINE ym2608_state *get_safe_token(device_t *device) |
| 32 | | { |
| 33 | | assert(device != NULL); |
| 34 | | assert(device->type() == YM2608); |
| 35 | | return (ym2608_state *)downcast<ym2608_device *>(device)->token(); |
| 36 | | } |
| 37 | | |
| 38 | | |
| 39 | | |
| 40 | 19 | static void psg_set_clock(void *param, int clock) |
| 41 | 20 | { |
| 42 | | ym2608_state *info = (ym2608_state *)param; |
| 43 | | ay8910_set_clock_ym(info->psg, clock); |
| 21 | ym2608_device *ym2608 = (ym2608_device *) param; |
| 22 | ay8910_set_clock_ym(ym2608->_psg(), clock); |
| 44 | 23 | } |
| 45 | 24 | |
| 46 | 25 | static void psg_write(void *param, int address, int data) |
| 47 | 26 | { |
| 48 | | ym2608_state *info = (ym2608_state *)param; |
| 49 | | ay8910_write_ym(info->psg, address, data); |
| 27 | ym2608_device *ym2608 = (ym2608_device *) param; |
| 28 | ay8910_write_ym(ym2608->_psg(), address, data); |
| 50 | 29 | } |
| 51 | 30 | |
| 52 | 31 | static int psg_read(void *param) |
| 53 | 32 | { |
| 54 | | ym2608_state *info = (ym2608_state *)param; |
| 55 | | return ay8910_read_ym(info->psg); |
| 33 | ym2608_device *ym2608 = (ym2608_device *) param; |
| 34 | return ay8910_read_ym(ym2608->_psg()); |
| 56 | 35 | } |
| 57 | 36 | |
| 58 | 37 | static void psg_reset(void *param) |
| 59 | 38 | { |
| 60 | | ym2608_state *info = (ym2608_state *)param; |
| 61 | | ay8910_reset_ym(info->psg); |
| 39 | ym2608_device *ym2608 = (ym2608_device *) param; |
| 40 | ay8910_reset_ym(ym2608->_psg()); |
| 62 | 41 | } |
| 63 | 42 | |
| 64 | 43 | static const ssg_callbacks psgintf = |
| r22751 | r22752 | |
| 69 | 48 | psg_reset |
| 70 | 49 | }; |
| 71 | 50 | |
| 51 | void *ym2608_device::_psg() |
| 52 | { |
| 53 | return m_psg; |
| 54 | } |
| 72 | 55 | |
| 73 | 56 | /* IRQ Handler */ |
| 74 | 57 | static void IRQHandler(void *param,int irq) |
| 75 | 58 | { |
| 76 | | ym2608_state *info = (ym2608_state *)param; |
| 77 | | if (!info->irqhandler.isnull()) |
| 78 | | info->irqhandler(irq); |
| 59 | ym2608_device *ym2608 = (ym2608_device *) param; |
| 60 | ym2608->_IRQHandler(irq); |
| 79 | 61 | } |
| 80 | 62 | |
| 81 | | /* Timer overflow callback from timer.c */ |
| 82 | | static TIMER_CALLBACK( timer_callback_2608_0 ) |
| 63 | void ym2608_device::_IRQHandler(int irq) |
| 83 | 64 | { |
| 84 | | ym2608_state *info = (ym2608_state *)ptr; |
| 85 | | ym2608_timer_over(info->chip,0); |
| 65 | if (!m_irq_handler.isnull()) |
| 66 | m_irq_handler(irq); |
| 86 | 67 | } |
| 87 | 68 | |
| 88 | | static TIMER_CALLBACK( timer_callback_2608_1 ) |
| 69 | /* Timer overflow callback from timer.c */ |
| 70 | void ym2608_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 89 | 71 | { |
| 90 | | ym2608_state *info = (ym2608_state *)ptr; |
| 91 | | ym2608_timer_over(info->chip,1); |
| 72 | switch(id) |
| 73 | { |
| 74 | case 0: |
| 75 | ym2608_timer_over(m_chip,0); |
| 76 | break; |
| 77 | |
| 78 | case 1: |
| 79 | ym2608_timer_over(m_chip,1); |
| 80 | break; |
| 81 | } |
| 92 | 82 | } |
| 93 | 83 | |
| 94 | 84 | static void timer_handler(void *param,int c,int count,int clock) |
| 95 | 85 | { |
| 96 | | ym2608_state *info = (ym2608_state *)param; |
| 86 | ym2608_device *ym2608 = (ym2608_device *) param; |
| 87 | ym2608->_timer_handler(c, count, clock); |
| 88 | } |
| 89 | |
| 90 | void ym2608_device::_timer_handler(int c,int count,int clock) |
| 91 | { |
| 97 | 92 | if( count == 0 ) |
| 98 | 93 | { /* Reset FM Timer */ |
| 99 | | info->timer[c]->enable(false); |
| 94 | m_timer[c]->enable(false); |
| 100 | 95 | } |
| 101 | 96 | else |
| 102 | 97 | { /* Start FM Timer */ |
| 103 | 98 | attotime period = attotime::from_hz(clock) * count; |
| 104 | | if (!info->timer[c]->enable(true)) |
| 105 | | info->timer[c]->adjust(period); |
| 99 | |
| 100 | if (!m_timer[c]->enable(true)) |
| 101 | m_timer[c]->adjust(period); |
| 106 | 102 | } |
| 107 | 103 | } |
| 108 | 104 | |
| 109 | 105 | /* update request from fm.c */ |
| 110 | 106 | void ym2608_update_request(void *param) |
| 111 | 107 | { |
| 112 | | ym2608_state *info = (ym2608_state *)param; |
| 113 | | info->stream->update(); |
| 108 | ym2608_device *ym2608 = (ym2608_device *) param; |
| 109 | ym2608->_ym2608_update_request(); |
| 114 | 110 | } |
| 115 | 111 | |
| 116 | | static STREAM_UPDATE( ym2608_stream_update ) |
| 112 | void ym2608_device::_ym2608_update_request() |
| 117 | 113 | { |
| 118 | | ym2608_state *info = (ym2608_state *)param; |
| 119 | | ym2608_update_one(info->chip, outputs, samples); |
| 114 | m_stream->update(); |
| 120 | 115 | } |
| 121 | 116 | |
| 117 | //------------------------------------------------- |
| 118 | // sound_stream_update - handle a stream update |
| 119 | //------------------------------------------------- |
| 122 | 120 | |
| 123 | | static void ym2608_intf_postload(ym2608_state *info) |
| 121 | void ym2608_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 124 | 122 | { |
| 125 | | ym2608_postload(info->chip); |
| 123 | ym2608_update_one(m_chip, outputs, samples); |
| 126 | 124 | } |
| 127 | 125 | |
| 128 | 126 | |
| 129 | | static DEVICE_START( ym2608 ) |
| 127 | void ym2608_device::device_post_load() |
| 130 | 128 | { |
| 131 | | static const ym2608_interface generic_2608 = |
| 129 | ym2608_postload(m_chip); |
| 130 | } |
| 131 | |
| 132 | |
| 133 | //------------------------------------------------- |
| 134 | // device_start - device-specific startup |
| 135 | //------------------------------------------------- |
| 136 | |
| 137 | void ym2608_device::device_start() |
| 138 | { |
| 139 | static const ay8910_interface generic_ay8910 = |
| 132 | 140 | { |
| 133 | | { |
| 134 | | AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT, |
| 135 | | AY8910_DEFAULT_LOADS, |
| 136 | | DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL |
| 137 | | }, |
| 138 | | DEVCB_NULL |
| 141 | AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT, |
| 142 | AY8910_DEFAULT_LOADS, |
| 143 | DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL |
| 139 | 144 | }; |
| 140 | | const ym2608_interface *intf = device->static_config() ? (const ym2608_interface *)device->static_config() : &generic_2608; |
| 141 | | int rate = device->clock()/72; |
| 145 | |
| 146 | int rate = clock()/72; |
| 142 | 147 | void *pcmbufa; |
| 143 | 148 | int pcmsizea; |
| 144 | 149 | |
| 145 | | ym2608_state *info = get_safe_token(device); |
| 150 | const ay8910_interface *ay8910_intf = m_ay8910_intf != NULL ? m_ay8910_intf : &generic_ay8910; |
| 146 | 151 | |
| 147 | | info->intf = intf; |
| 148 | | info->device = device; |
| 149 | | |
| 150 | | info->irqhandler.resolve(intf->irqhandler, *device); |
| 151 | | |
| 152 | m_irq_handler.resolve(); |
| 152 | 153 | /* FIXME: Force to use simgle output */ |
| 153 | | info->psg = ay8910_start_ym(NULL, YM2608, device, device->clock(), &intf->ay8910_intf); |
| 154 | | assert_always(info->psg != NULL, "Error creating YM2608/AY8910 chip"); |
| 154 | m_psg = ay8910_start_ym(NULL, type(), this, clock(), ay8910_intf); |
| 155 | assert_always(m_psg != NULL, "Error creating YM2608/AY8910 chip"); |
| 155 | 156 | |
| 156 | 157 | /* Timer Handler set */ |
| 157 | | info->timer[0] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_2608_0), info); |
| 158 | | info->timer[1] = device->machine().scheduler().timer_alloc(FUNC(timer_callback_2608_1), info); |
| 158 | m_timer[0] = timer_alloc(0); |
| 159 | m_timer[1] = timer_alloc(1); |
| 159 | 160 | |
| 160 | 161 | /* stream system initialize */ |
| 161 | | info->stream = device->machine().sound().stream_alloc(*device,0,2,rate,info,ym2608_stream_update); |
| 162 | m_stream = machine().sound().stream_alloc(*this,0,2,rate); |
| 162 | 163 | /* setup adpcm buffers */ |
| 163 | | pcmbufa = *device->region(); |
| 164 | | pcmsizea = device->region()->bytes(); |
| 164 | pcmbufa = *region(); |
| 165 | pcmsizea = region()->bytes(); |
| 165 | 166 | |
| 166 | 167 | /* initialize YM2608 */ |
| 167 | | info->chip = ym2608_init(info,device,device->clock(),rate, |
| 168 | m_chip = ym2608_init(this,this,clock(),rate, |
| 168 | 169 | pcmbufa,pcmsizea, |
| 169 | 170 | timer_handler,IRQHandler,&psgintf); |
| 170 | | assert_always(info->chip != NULL, "Error creating YM2608 chip"); |
| 171 | | |
| 172 | | device->machine().save().register_postload(save_prepost_delegate(FUNC(ym2608_intf_postload), info)); |
| 171 | assert_always(m_chip != NULL, "Error creating YM2608 chip"); |
| 173 | 172 | } |
| 174 | 173 | |
| 175 | | static DEVICE_STOP( ym2608 ) |
| 174 | //------------------------------------------------- |
| 175 | // device_stop - device-specific stop |
| 176 | //------------------------------------------------- |
| 177 | |
| 178 | void ym2608_device::device_stop() |
| 176 | 179 | { |
| 177 | | ym2608_state *info = get_safe_token(device); |
| 178 | | ym2608_shutdown(info->chip); |
| 179 | | ay8910_stop_ym(info->psg); |
| 180 | ym2608_shutdown(m_chip); |
| 181 | ay8910_stop_ym(m_psg); |
| 180 | 182 | } |
| 181 | 183 | |
| 182 | | static DEVICE_RESET( ym2608 ) |
| 184 | //------------------------------------------------- |
| 185 | // device_reset - device-specific reset |
| 186 | //------------------------------------------------- |
| 187 | |
| 188 | void ym2608_device::device_reset() |
| 183 | 189 | { |
| 184 | | ym2608_state *info = get_safe_token(device); |
| 185 | | ym2608_reset_chip(info->chip); |
| 190 | ym2608_reset_chip(m_chip); |
| 186 | 191 | } |
| 187 | 192 | |
| 188 | 193 | |
| 189 | | READ8_DEVICE_HANDLER( ym2608_r ) |
| 194 | READ8_MEMBER( ym2608_device::read ) |
| 190 | 195 | { |
| 191 | | ym2608_state *info = get_safe_token(device); |
| 192 | | return ym2608_read(info->chip, offset & 3); |
| 196 | return ym2608_read(m_chip, offset & 3); |
| 193 | 197 | } |
| 194 | 198 | |
| 195 | | WRITE8_DEVICE_HANDLER( ym2608_w ) |
| 199 | WRITE8_MEMBER( ym2608_device::write ) |
| 196 | 200 | { |
| 197 | | ym2608_state *info = get_safe_token(device); |
| 198 | | ym2608_write(info->chip, offset & 3, data); |
| 201 | ym2608_write(m_chip, offset & 3, data); |
| 199 | 202 | } |
| 200 | 203 | |
| 201 | | READ8_DEVICE_HANDLER( ym2608_read_port_r ) { return ym2608_r(device, space, 1); } |
| 202 | | READ8_DEVICE_HANDLER( ym2608_status_port_a_r ) { return ym2608_r(device, space, 0); } |
| 203 | | READ8_DEVICE_HANDLER( ym2608_status_port_b_r ) { return ym2608_r(device, space, 2); } |
| 204 | | |
| 205 | | WRITE8_DEVICE_HANDLER( ym2608_control_port_a_w ) { ym2608_w(device, space, 0, data); } |
| 206 | | WRITE8_DEVICE_HANDLER( ym2608_control_port_b_w ) { ym2608_w(device, space, 2, data); } |
| 207 | | WRITE8_DEVICE_HANDLER( ym2608_data_port_a_w ) { ym2608_w(device, space, 1, data); } |
| 208 | | WRITE8_DEVICE_HANDLER( ym2608_data_port_b_w ) { ym2608_w(device, space, 3, data); } |
| 209 | | |
| 210 | 204 | const device_type YM2608 = &device_creator<ym2608_device>; |
| 211 | 205 | |
| 212 | 206 | ym2608_device::ym2608_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 213 | 207 | : device_t(mconfig, YM2608, "YM2608", tag, owner, clock), |
| 214 | | device_sound_interface(mconfig, *this) |
| 208 | device_sound_interface(mconfig, *this), |
| 209 | m_irq_handler(*this) |
| 215 | 210 | { |
| 216 | | m_token = global_alloc_clear(ym2608_state); |
| 217 | 211 | } |
| 218 | 212 | |
| 219 | 213 | //------------------------------------------------- |
| r22751 | r22752 | |
| 225 | 219 | void ym2608_device::device_config_complete() |
| 226 | 220 | { |
| 227 | 221 | } |
| 228 | | |
| 229 | | //------------------------------------------------- |
| 230 | | // device_start - device-specific startup |
| 231 | | //------------------------------------------------- |
| 232 | | |
| 233 | | void ym2608_device::device_start() |
| 234 | | { |
| 235 | | DEVICE_START_NAME( ym2608 )(this); |
| 236 | | } |
| 237 | | |
| 238 | | //------------------------------------------------- |
| 239 | | // device_reset - device-specific reset |
| 240 | | //------------------------------------------------- |
| 241 | | |
| 242 | | void ym2608_device::device_reset() |
| 243 | | { |
| 244 | | DEVICE_RESET_NAME( ym2608 )(this); |
| 245 | | } |
| 246 | | |
| 247 | | //------------------------------------------------- |
| 248 | | // device_stop - device-specific stop |
| 249 | | //------------------------------------------------- |
| 250 | | |
| 251 | | void ym2608_device::device_stop() |
| 252 | | { |
| 253 | | DEVICE_STOP_NAME( ym2608 )(this); |
| 254 | | } |
| 255 | | |
| 256 | | //------------------------------------------------- |
| 257 | | // sound_stream_update - handle a stream update |
| 258 | | //------------------------------------------------- |
| 259 | | |
| 260 | | void ym2608_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 261 | | { |
| 262 | | // should never get here |
| 263 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 264 | | } |
trunk/src/emu/sound/2608intf.h
| r22751 | r22752 | |
| 3 | 3 | #ifndef __2608INTF_H__ |
| 4 | 4 | #define __2608INTF_H__ |
| 5 | 5 | |
| 6 | | #include "devlegcy.h" |
| 7 | | |
| 6 | #include "emu.h" |
| 8 | 7 | #include "fm.h" |
| 9 | 8 | #include "ay8910.h" |
| 10 | 9 | |
| 11 | 10 | void ym2608_update_request(void *param); |
| 12 | 11 | |
| 13 | | struct ym2608_interface |
| 14 | | { |
| 15 | | const ay8910_interface ay8910_intf; |
| 16 | | devcb_write_line irqhandler; /* IRQ handler for the YM2608 */ |
| 17 | | }; |
| 12 | #define MCFG_YM2608_IRQ_HANDLER(_devcb) \ |
| 13 | devcb = &ym2608_device::set_irq_handler(*device, DEVCB2_##_devcb); |
| 18 | 14 | |
| 19 | | DECLARE_READ8_DEVICE_HANDLER( ym2608_r ); |
| 20 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2608_w ); |
| 15 | #define MCFG_YM2608_AY8910_INTF(_ay8910_intf) \ |
| 16 | ym2608_device::set_ay8910_intf(*device, _ay8910_intf); |
| 21 | 17 | |
| 22 | | DECLARE_READ8_DEVICE_HANDLER( ym2608_read_port_r ); |
| 23 | | DECLARE_READ8_DEVICE_HANDLER( ym2608_status_port_a_r ); |
| 24 | | DECLARE_READ8_DEVICE_HANDLER( ym2608_status_port_b_r ); |
| 25 | | |
| 26 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2608_control_port_a_w ); |
| 27 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2608_control_port_b_w ); |
| 28 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2608_data_port_a_w ); |
| 29 | | DECLARE_WRITE8_DEVICE_HANDLER( ym2608_data_port_b_w ); |
| 30 | | |
| 31 | 18 | class ym2608_device : public device_t, |
| 32 | 19 | public device_sound_interface |
| 33 | 20 | { |
| 34 | 21 | public: |
| 35 | 22 | ym2608_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 36 | | ~ym2608_device() { global_free(m_token); } |
| 37 | 23 | |
| 38 | | // access to legacy token |
| 39 | | void *token() const { assert(m_token != NULL); return m_token; } |
| 24 | // static configuration helpers |
| 25 | template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<ym2608_device &>(device).m_irq_handler.set_callback(object); } |
| 26 | static void set_ay8910_intf(device_t &device, const ay8910_interface *ay8910_intf) { downcast<ym2608_device &>(device).m_ay8910_intf = ay8910_intf; } |
| 27 | |
| 28 | DECLARE_READ8_MEMBER( read ); |
| 29 | DECLARE_WRITE8_MEMBER( write ); |
| 30 | |
| 31 | void *_psg(); |
| 32 | void _IRQHandler(int irq); |
| 33 | void _timer_handler(int c,int count,int clock); |
| 34 | void _ym2608_update_request(); |
| 35 | |
| 40 | 36 | protected: |
| 41 | 37 | // device-level overrides |
| 42 | 38 | virtual void device_config_complete(); |
| 43 | 39 | virtual void device_start(); |
| 40 | virtual void device_post_load(); |
| 44 | 41 | virtual void device_stop(); |
| 45 | 42 | virtual void device_reset(); |
| 46 | 43 | |
| 44 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 45 | |
| 47 | 46 | // sound stream update overrides |
| 48 | 47 | virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); |
| 48 | |
| 49 | 49 | private: |
| 50 | 50 | // internal state |
| 51 | | void *m_token; |
| 51 | sound_stream * m_stream; |
| 52 | emu_timer * m_timer[2]; |
| 53 | void * m_chip; |
| 54 | void * m_psg; |
| 55 | devcb2_write_line m_irq_handler; |
| 56 | const ay8910_interface *m_ay8910_intf; |
| 52 | 57 | }; |
| 53 | 58 | |
| 54 | 59 | extern const device_type YM2608; |
trunk/src/mess/drivers/pc8801.c
| r22751 | r22752 | |
| 304 | 304 | m_pic(*this, I8214_TAG), |
| 305 | 305 | m_rtc(*this, UPD1990A_TAG), |
| 306 | 306 | m_cassette(*this, "cassette"), |
| 307 | | m_beeper(*this, "beeper") |
| 307 | m_beeper(*this, "beeper"), |
| 308 | m_opna(*this, "opna") |
| 308 | 309 | { } |
| 309 | 310 | |
| 310 | 311 | required_device<cpu_device> m_maincpu; |
| r22751 | r22752 | |
| 313 | 314 | required_device<upd1990a_device> m_rtc; |
| 314 | 315 | required_device<cassette_image_device> m_cassette; |
| 315 | 316 | required_device<beep_device> m_beeper; |
| 317 | required_device<ym2608_device> m_opna; |
| 316 | 318 | UINT8 *m_work_ram; |
| 317 | 319 | UINT8 *m_hi_work_ram; |
| 318 | 320 | UINT8 *m_ext_work_ram; |
| r22751 | r22752 | |
| 1696 | 1698 | READ8_MEMBER(pc8801_state::pc8801_sound_board_r) |
| 1697 | 1699 | { |
| 1698 | 1700 | if(m_has_opna) |
| 1699 | | return ym2608_r(machine().device("opna"), space, offset); |
| 1701 | return m_opna->read(space, offset); |
| 1700 | 1702 | |
| 1701 | 1703 | return (offset & 2) ? 0xff : ym2203_r(machine().device("opn"), space, offset); |
| 1702 | 1704 | } |
| r22751 | r22752 | |
| 1704 | 1706 | WRITE8_MEMBER(pc8801_state::pc8801_sound_board_w) |
| 1705 | 1707 | { |
| 1706 | 1708 | if(m_has_opna) |
| 1707 | | ym2608_w(machine().device("opna"), space, offset,data); |
| 1709 | m_opna->write(space, offset,data); |
| 1708 | 1710 | else if((offset & 2) == 0) |
| 1709 | 1711 | ym2203_w(machine().device("opn"), space, offset,data); |
| 1710 | 1712 | } |
| r22751 | r22752 | |
| 1712 | 1714 | READ8_MEMBER(pc8801_state::pc8801_opna_r) |
| 1713 | 1715 | { |
| 1714 | 1716 | if(m_has_opna && (offset & 2) == 0) |
| 1715 | | return ym2608_r(machine().device("opna"), space, (offset & 1) | ((offset & 4) >> 1)); |
| 1717 | return m_opna->read(space, (offset & 1) | ((offset & 4) >> 1)); |
| 1716 | 1718 | |
| 1717 | 1719 | return 0xff; |
| 1718 | 1720 | } |
| r22751 | r22752 | |
| 1720 | 1722 | WRITE8_MEMBER(pc8801_state::pc8801_opna_w) |
| 1721 | 1723 | { |
| 1722 | 1724 | if(m_has_opna && (offset & 2) == 0) |
| 1723 | | ym2608_w(machine().device("opna"), space, (offset & 1) | ((offset & 4) >> 1),data); |
| 1725 | m_opna->write(space, (offset & 1) | ((offset & 4) >> 1),data); |
| 1724 | 1726 | else if(m_has_opna && offset == 2) |
| 1725 | 1727 | { |
| 1726 | 1728 | m_sound_irq_mask = ((data & 0x80) == 0); |
| r22751 | r22752 | |
| 2599 | 2601 | DEVCB_DRIVER_LINE_MEMBER(pc8801_state,pc8801_sound_irq) |
| 2600 | 2602 | }; |
| 2601 | 2603 | |
| 2602 | | static const ym2608_interface pc88_ym2608_intf = |
| 2604 | static const ay8910_interface ay8910_config = |
| 2603 | 2605 | { |
| 2604 | | { |
| 2605 | | AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT, |
| 2606 | | AY8910_DEFAULT_LOADS, |
| 2607 | | DEVCB_DRIVER_MEMBER(pc8801_state,opn_porta_r), |
| 2608 | | DEVCB_DRIVER_MEMBER(pc8801_state,opn_portb_r), |
| 2609 | | DEVCB_NULL, |
| 2610 | | DEVCB_NULL |
| 2611 | | }, |
| 2612 | | DEVCB_DRIVER_LINE_MEMBER(pc8801_state,pc8801_sound_irq) |
| 2606 | AY8910_LEGACY_OUTPUT | AY8910_SINGLE_OUTPUT, |
| 2607 | AY8910_DEFAULT_LOADS, |
| 2608 | DEVCB_DRIVER_MEMBER(pc8801_state,opn_porta_r), |
| 2609 | DEVCB_DRIVER_MEMBER(pc8801_state,opn_portb_r), |
| 2610 | DEVCB_NULL, |
| 2611 | DEVCB_NULL |
| 2613 | 2612 | }; |
| 2614 | 2613 | |
| 2615 | 2614 | /* Cassette Configuration */ |
| r22751 | r22752 | |
| 2707 | 2706 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 2708 | 2707 | |
| 2709 | 2708 | MCFG_SOUND_ADD("opna", YM2608, MASTER_CLOCK*2) |
| 2710 | | MCFG_SOUND_CONFIG(pc88_ym2608_intf) |
| 2709 | MCFG_YM2608_IRQ_HANDLER(WRITELINE(pc8801_state, pc8801_sound_irq)) |
| 2710 | MCFG_YM2608_AY8910_INTF(&ay8910_config) |
| 2711 | 2711 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 2712 | 2712 | |
| 2713 | 2713 | MCFG_SOUND_ADD("beeper", BEEP, 0) |
trunk/src/mess/machine/pc9801_86.c
| r22751 | r22752 | |
| 41 | 41 | pic8259_ir4_w(machine().device("pic8259_slave"), state); |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | | static const ym2608_interface pc98_ym2608_intf = |
| 44 | static const ay8910_interface ay8910_config = |
| 45 | 45 | { |
| 46 | | { |
| 47 | | AY8910_LEGACY_OUTPUT, |
| 48 | | AY8910_DEFAULT_LOADS, |
| 49 | | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_86_device,opn_porta_r), |
| 50 | | DEVCB_NULL,//(pc9801_state,opn_portb_r), |
| 51 | | DEVCB_NULL,//(pc9801_state,opn_porta_w), |
| 52 | | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_86_device,opn_portb_w), |
| 53 | | }, |
| 54 | | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, pc9801_86_device,pc9801_sound_irq) |
| 46 | AY8910_LEGACY_OUTPUT, |
| 47 | AY8910_DEFAULT_LOADS, |
| 48 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_86_device,opn_porta_r), |
| 49 | DEVCB_NULL,//(pc9801_state,opn_portb_r), |
| 50 | DEVCB_NULL,//(pc9801_state,opn_porta_w), |
| 51 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_86_device,opn_portb_w), |
| 55 | 52 | }; |
| 56 | 53 | |
| 57 | 54 | static MACHINE_CONFIG_FRAGMENT( pc9801_86_config ) |
| 58 | 55 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 59 | 56 | MCFG_SOUND_ADD("opna", YM2608, MAIN_CLOCK_X1*4) // unknown clock / divider |
| 60 | | MCFG_SOUND_CONFIG(pc98_ym2608_intf) |
| 57 | MCFG_YM2608_IRQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, pc9801_86_device, pc9801_sound_irq)) |
| 58 | MCFG_YM2608_AY8910_INTF(&ay8910_config) |
| 61 | 59 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 62 | 60 | MACHINE_CONFIG_END |
| 63 | 61 | |
| r22751 | r22752 | |
| 192 | 190 | READ8_MEMBER(pc9801_86_device::pc9801_86_r) |
| 193 | 191 | { |
| 194 | 192 | if((offset & 1) == 0) |
| 195 | | return ym2608_r(m_opna, space, offset >> 1); |
| 193 | return m_opna->read(space, offset >> 1); |
| 196 | 194 | else // odd |
| 197 | 195 | { |
| 198 | 196 | printf("PC9801-86: Read to undefined port [%02x]\n",offset+0x188); |
| r22751 | r22752 | |
| 204 | 202 | WRITE8_MEMBER(pc9801_86_device::pc9801_86_w) |
| 205 | 203 | { |
| 206 | 204 | if((offset & 1) == 0) |
| 207 | | ym2608_w(m_opna,space, offset >> 1,data); |
| 205 | m_opna->write(space, offset >> 1,data); |
| 208 | 206 | else // odd |
| 209 | 207 | printf("PC9801-86: Write to undefined port [%02x] %02x\n",offset+0x188,data); |
| 210 | 208 | } |
trunk/src/mess/machine/pc9801_118.c
| r22751 | r22752 | |
| 41 | 41 | pic8259_ir4_w(machine().device("pic8259_slave"), state); |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | | static const ym2608_interface pc98_ym2608_intf = |
| 44 | static const ay8910_interface ay8910_config = |
| 45 | 45 | { |
| 46 | | { |
| 47 | | AY8910_LEGACY_OUTPUT, |
| 48 | | AY8910_DEFAULT_LOADS, |
| 49 | | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_118_device,opn_porta_r), |
| 50 | | DEVCB_NULL,//(pc9801_state,opn_portb_r), |
| 51 | | DEVCB_NULL,//(pc9801_state,opn_porta_w), |
| 52 | | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_118_device,opn_portb_w), |
| 53 | | }, |
| 54 | | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, pc9801_118_device,pc9801_sound_irq) |
| 46 | AY8910_LEGACY_OUTPUT, |
| 47 | AY8910_DEFAULT_LOADS, |
| 48 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_118_device,opn_porta_r), |
| 49 | DEVCB_NULL,//(pc9801_state,opn_portb_r), |
| 50 | DEVCB_NULL,//(pc9801_state,opn_porta_w), |
| 51 | DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, pc9801_118_device,opn_portb_w), |
| 55 | 52 | }; |
| 56 | 53 | |
| 57 | 54 | static MACHINE_CONFIG_FRAGMENT( pc9801_118_config ) |
| 58 | 55 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 59 | 56 | MCFG_SOUND_ADD("opn3", YM2608, MAIN_CLOCK_X1*4) // actually YMF288, unknown clock / divider |
| 60 | | MCFG_SOUND_CONFIG(pc98_ym2608_intf) |
| 57 | MCFG_YM2608_IRQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, pc9801_118_device, pc9801_sound_irq)) |
| 58 | MCFG_YM2608_AY8910_INTF(&ay8910_config) |
| 61 | 59 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 62 | 60 | MACHINE_CONFIG_END |
| 63 | 61 | |
| r22751 | r22752 | |
| 192 | 190 | READ8_MEMBER(pc9801_118_device::pc9801_118_r) |
| 193 | 191 | { |
| 194 | 192 | if(((offset & 5) == 0) || m_ext_reg) |
| 195 | | return ym2608_r(m_opn3, space, offset >> 1); |
| 193 | return m_opn3->read(space, offset >> 1); |
| 196 | 194 | else // odd |
| 197 | 195 | { |
| 198 | 196 | //printf("PC9801-118: Read to undefined port [%02x]\n",offset+0x188); |
| r22751 | r22752 | |
| 204 | 202 | WRITE8_MEMBER(pc9801_118_device::pc9801_118_w) |
| 205 | 203 | { |
| 206 | 204 | if(((offset & 5) == 0) || m_ext_reg) |
| 207 | | ym2608_w(m_opn3,space, offset >> 1,data); |
| 205 | m_opn3->write(space, offset >> 1,data); |
| 208 | 206 | //else // odd |
| 209 | 207 | // printf("PC9801-118: Write to undefined port [%02x] %02x\n",offset+0x188,data); |
| 210 | 208 | } |