trunk/src/mame/drivers/metro.c
| r22809 | r22810 | |
| 437 | 437 | m_portb = data; |
| 438 | 438 | } |
| 439 | 439 | |
| 440 | | static const ymf278b_interface ymf278b_config = |
| 441 | | { |
| 442 | | DEVCB_DRIVER_LINE_MEMBER(metro_state,ymf278b_interrupt) |
| 443 | | }; |
| 444 | 440 | |
| 445 | | |
| 446 | 441 | /*************************************************************************** |
| 447 | 442 | |
| 448 | 443 | |
| r22809 | r22810 | |
| 770 | 765 | |
| 771 | 766 | static ADDRESS_MAP_START( balcube_map, AS_PROGRAM, 16, metro_state ) |
| 772 | 767 | AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM |
| 773 | | AM_RANGE(0x300000, 0x300001) AM_DEVREAD8_LEGACY("ymf", ymf278b_r, 0x00ff) // Sound |
| 774 | | AM_RANGE(0x300000, 0x30000b) AM_DEVWRITE8_LEGACY("ymf", ymf278b_w, 0x00ff) // Sound |
| 768 | AM_RANGE(0x300000, 0x300001) AM_DEVREAD8("ymf", ymf278b_device, read, 0x00ff) // Sound |
| 769 | AM_RANGE(0x300000, 0x30000b) AM_DEVWRITE8("ymf", ymf278b_device, write, 0x00ff) // Sound |
| 775 | 770 | AM_RANGE(0x400000, 0x41ffff) AM_READ(balcube_dsw_r) // DSW x 3 |
| 776 | 771 | AM_RANGE(0x500000, 0x500001) AM_READ_PORT("IN0") // Inputs |
| 777 | 772 | AM_RANGE(0x500002, 0x500003) AM_READ_PORT("IN1") // |
| r22809 | r22810 | |
| 829 | 824 | AM_RANGE(0x200006, 0x200007) AM_READNOP // |
| 830 | 825 | AM_RANGE(0x200002, 0x200009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout |
| 831 | 826 | AM_RANGE(0x300000, 0x31ffff) AM_READ(balcube_dsw_r) // DSW x 3 |
| 832 | | AM_RANGE(0x400000, 0x400001) AM_DEVREAD8_LEGACY("ymf", ymf278b_r, 0x00ff) // Sound |
| 833 | | AM_RANGE(0x400000, 0x40000b) AM_DEVWRITE8_LEGACY("ymf", ymf278b_w, 0x00ff) // Sound |
| 827 | AM_RANGE(0x400000, 0x400001) AM_DEVREAD8("ymf", ymf278b_device, read, 0x00ff) // Sound |
| 828 | AM_RANGE(0x400000, 0x40000b) AM_DEVWRITE8("ymf", ymf278b_device, write, 0x00ff) // Sound |
| 834 | 829 | AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) |
| 835 | 830 | ADDRESS_MAP_END |
| 836 | 831 | |
| r22809 | r22810 | |
| 841 | 836 | |
| 842 | 837 | static ADDRESS_MAP_START( bangball_map, AS_PROGRAM, 16, metro_state ) |
| 843 | 838 | AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM |
| 844 | | AM_RANGE(0xb00000, 0xb00001) AM_DEVREAD8_LEGACY("ymf", ymf278b_r, 0x00ff) // Sound |
| 845 | | AM_RANGE(0xb00000, 0xb0000b) AM_DEVWRITE8_LEGACY("ymf", ymf278b_w, 0x00ff) // Sound |
| 839 | AM_RANGE(0xb00000, 0xb00001) AM_DEVREAD8("ymf", ymf278b_device, read, 0x00ff) // Sound |
| 840 | AM_RANGE(0xb00000, 0xb0000b) AM_DEVWRITE8("ymf", ymf278b_device, write, 0x00ff) // Sound |
| 846 | 841 | AM_RANGE(0xc00000, 0xc1ffff) AM_READ(balcube_dsw_r) // DSW x 3 |
| 847 | 842 | AM_RANGE(0xd00000, 0xd00001) AM_READ_PORT("IN0") // Inputs |
| 848 | 843 | AM_RANGE(0xd00002, 0xd00003) AM_READ_PORT("IN1") // |
| r22809 | r22810 | |
| 900 | 895 | AM_RANGE(0x200006, 0x200007) AM_READ_PORT("IN2") // |
| 901 | 896 | AM_RANGE(0x200002, 0x200009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout |
| 902 | 897 | AM_RANGE(0x300000, 0x31ffff) AM_READ(balcube_dsw_r) // read but ignored? |
| 903 | | AM_RANGE(0x400000, 0x400001) AM_DEVREAD8_LEGACY("ymf", ymf278b_r, 0x00ff) // Sound |
| 904 | | AM_RANGE(0x400000, 0x40000b) AM_DEVWRITE8_LEGACY("ymf", ymf278b_w, 0x00ff) // |
| 898 | AM_RANGE(0x400000, 0x400001) AM_DEVREAD8("ymf", ymf278b_device, read, 0x00ff) // Sound |
| 899 | AM_RANGE(0x400000, 0x40000b) AM_DEVWRITE8("ymf", ymf278b_device, write, 0x00ff) // |
| 905 | 900 | AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) |
| 906 | 901 | ADDRESS_MAP_END |
| 907 | 902 | |
| r22809 | r22810 | |
| 935 | 930 | AM_RANGE(0x200006, 0x200007) AM_READNOP // |
| 936 | 931 | AM_RANGE(0x200002, 0x200009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout |
| 937 | 932 | AM_RANGE(0x300000, 0x31ffff) AM_READ(balcube_dsw_r) // 3 x DSW |
| 938 | | AM_RANGE(0x400000, 0x400001) AM_DEVREAD8_LEGACY("ymf", ymf278b_r, 0x00ff) // Sound |
| 939 | | AM_RANGE(0x400000, 0x40000b) AM_DEVWRITE8_LEGACY("ymf", ymf278b_w, 0x00ff) // |
| 933 | AM_RANGE(0x400000, 0x400001) AM_DEVREAD8("ymf", ymf278b_device, read, 0x00ff) // Sound |
| 934 | AM_RANGE(0x400000, 0x40000b) AM_DEVWRITE8("ymf", ymf278b_device, write, 0x00ff) // |
| 940 | 935 | AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) |
| 941 | 936 | ADDRESS_MAP_END |
| 942 | 937 | |
| r22809 | r22810 | |
| 3593 | 3588 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 3594 | 3589 | |
| 3595 | 3590 | MCFG_SOUND_ADD("ymf", YMF278B, YMF278B_STD_CLOCK) |
| 3596 | | MCFG_SOUND_CONFIG(ymf278b_config) |
| 3591 | MCFG_YMF278B_IRQ_HANDLER(WRITELINE(metro_state, ymf278b_interrupt)) |
| 3597 | 3592 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 3598 | 3593 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 3599 | 3594 | MACHINE_CONFIG_END |
| r22809 | r22810 | |
| 3626 | 3621 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 3627 | 3622 | |
| 3628 | 3623 | MCFG_SOUND_ADD("ymf", YMF278B, YMF278B_STD_CLOCK) |
| 3629 | | MCFG_SOUND_CONFIG(ymf278b_config) |
| 3624 | MCFG_YMF278B_IRQ_HANDLER(WRITELINE(metro_state, ymf278b_interrupt)) |
| 3630 | 3625 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 3631 | 3626 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 3632 | 3627 | MACHINE_CONFIG_END |
| r22809 | r22810 | |
| 3659 | 3654 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 3660 | 3655 | |
| 3661 | 3656 | MCFG_SOUND_ADD("ymf", YMF278B, YMF278B_STD_CLOCK) |
| 3662 | | MCFG_SOUND_CONFIG(ymf278b_config) |
| 3657 | MCFG_YMF278B_IRQ_HANDLER(WRITELINE(metro_state, ymf278b_interrupt)) |
| 3663 | 3658 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 3664 | 3659 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 3665 | 3660 | MACHINE_CONFIG_END |
| r22809 | r22810 | |
| 3692 | 3687 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 3693 | 3688 | |
| 3694 | 3689 | MCFG_SOUND_ADD("ymf", YMF278B, YMF278B_STD_CLOCK) |
| 3695 | | MCFG_SOUND_CONFIG(ymf278b_config) |
| 3690 | MCFG_YMF278B_IRQ_HANDLER(WRITELINE(metro_state, ymf278b_interrupt)) |
| 3696 | 3691 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 3697 | 3692 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 3698 | 3693 | MACHINE_CONFIG_END |
| r22809 | r22810 | |
| 3725 | 3720 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 3726 | 3721 | |
| 3727 | 3722 | MCFG_SOUND_ADD("ymf", YMF278B, YMF278B_STD_CLOCK) |
| 3728 | | MCFG_SOUND_CONFIG(ymf278b_config) |
| 3723 | MCFG_YMF278B_IRQ_HANDLER(WRITELINE(metro_state, ymf278b_interrupt)) |
| 3729 | 3724 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 3730 | 3725 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 3731 | 3726 | MACHINE_CONFIG_END |
trunk/src/emu/sound/ymf278b.c
| r22809 | r22810 | |
| 71 | 71 | #define VERBOSE 0 |
| 72 | 72 | #define LOG(x) do { if (VERBOSE) logerror x; } while (0) |
| 73 | 73 | |
| 74 | | struct YMF278BChip; |
| 75 | | |
| 76 | | struct YMF278BSlot |
| 74 | void ymf278b_device::write_memory(UINT32 offset, UINT8 data) |
| 77 | 75 | { |
| 78 | | INT16 wave; /* wavetable number */ |
| 79 | | INT16 F_NUMBER; /* frequency */ |
| 80 | | INT8 octave; /* octave */ |
| 81 | | INT8 preverb; /* pseudo-reverb */ |
| 82 | | INT8 DAMP; /* damping */ |
| 83 | | INT8 CH; /* output channel */ |
| 84 | | INT8 LD; /* level direct */ |
| 85 | | INT8 TL; /* total level */ |
| 86 | | INT8 pan; /* panpot */ |
| 87 | | INT8 LFO; /* LFO */ |
| 88 | | INT8 VIB; /* vibrato */ |
| 89 | | INT8 AM; /* tremolo */ |
| 90 | | |
| 91 | | INT8 AR; /* attack rate */ |
| 92 | | INT8 D1R; /* decay 1 rate */ |
| 93 | | INT8 DL; /* decay level */ |
| 94 | | INT8 D2R; /* decay 2 rate */ |
| 95 | | INT8 RC; /* rate correction */ |
| 96 | | INT8 RR; /* release rate */ |
| 97 | | |
| 98 | | UINT32 step; /* fixed-point frequency step */ |
| 99 | | UINT64 stepptr; /* fixed-point pointer into the sample */ |
| 100 | | |
| 101 | | INT8 active; /* channel is playing */ |
| 102 | | INT8 KEY_ON; /* slot keyed on */ |
| 103 | | INT8 bits; /* width of the samples */ |
| 104 | | UINT32 startaddr; |
| 105 | | UINT32 loopaddr; |
| 106 | | UINT32 endaddr; |
| 107 | | |
| 108 | | int env_step; |
| 109 | | UINT32 env_vol; |
| 110 | | UINT32 env_vol_step; |
| 111 | | UINT32 env_vol_lim; |
| 112 | | INT8 env_preverb; |
| 113 | | |
| 114 | | int num; /* slot number (for debug only) */ |
| 115 | | YMF278BChip *chip; /* pointer back to parent chip */ |
| 116 | | }; |
| 117 | | |
| 118 | | struct YMF278BChip |
| 119 | | { |
| 120 | | UINT8 pcmregs[256]; |
| 121 | | YMF278BSlot slots[24]; |
| 122 | | INT8 wavetblhdr; |
| 123 | | INT8 memmode; |
| 124 | | INT32 memadr; |
| 125 | | |
| 126 | | UINT8 status_busy, status_ld; |
| 127 | | emu_timer *timer_busy; |
| 128 | | emu_timer *timer_ld; |
| 129 | | UINT8 exp; |
| 130 | | |
| 131 | | INT32 fm_l, fm_r; |
| 132 | | INT32 pcm_l, pcm_r; |
| 133 | | |
| 134 | | attotime timer_base; |
| 135 | | UINT8 timer_a_count, timer_b_count; |
| 136 | | UINT8 enable, current_irq; |
| 137 | | emu_timer *timer_a, *timer_b; |
| 138 | | int irq_line; |
| 139 | | |
| 140 | | UINT8 port_C, port_AB, lastport; |
| 141 | | devcb_resolved_write_line irq_callback; |
| 142 | | device_t *device; |
| 143 | | |
| 144 | | const UINT8 *rom; |
| 145 | | UINT32 romsize; |
| 146 | | int clock; |
| 147 | | |
| 148 | | // precomputed tables |
| 149 | | UINT32 lut_ar[64]; // attack rate |
| 150 | | UINT32 lut_dr[64]; // decay rate |
| 151 | | INT32 volume[256*4]; // precalculated attenuation values with some margin for envelope and pan levels |
| 152 | | int pan_left[16],pan_right[16]; // pan volume offsets |
| 153 | | INT32 mix_level[8]; |
| 154 | | |
| 155 | | sound_stream * stream; |
| 156 | | }; |
| 157 | | |
| 158 | | INLINE YMF278BChip *get_safe_token(device_t *device) |
| 159 | | { |
| 160 | | assert(device != NULL); |
| 161 | | assert(device->type() == YMF278B); |
| 162 | | return (YMF278BChip *)downcast<ymf278b_device *>(device)->token(); |
| 163 | | } |
| 164 | | |
| 165 | | static void ymf278b_write_memory(YMF278BChip *chip, UINT32 offset, UINT8 data) |
| 166 | | { |
| 167 | 76 | logerror("YMF278B: Memory write %02x to %x\n", data, offset); |
| 168 | 77 | } |
| 169 | 78 | |
| 170 | | INLINE UINT8 ymf278b_read_memory(YMF278BChip *chip, UINT32 offset) |
| 79 | UINT8 ymf278b_device::read_memory(UINT32 offset) |
| 171 | 80 | { |
| 172 | | if (offset >= chip->romsize) |
| 81 | if (offset >= m_romsize) |
| 173 | 82 | { |
| 174 | 83 | // logerror("YMF278B: Memory read overflow %x\n", offset); |
| 175 | 84 | return 0xff; |
| 176 | 85 | } |
| 177 | | return chip->rom[offset]; |
| 86 | return m_rom[offset]; |
| 178 | 87 | } |
| 179 | 88 | |
| 180 | 89 | |
| 181 | 90 | /**************************************************************************/ |
| 182 | 91 | |
| 183 | | static int ymf278b_compute_rate(YMF278BSlot *slot, int val) |
| 92 | int ymf278b_device::compute_rate(YMF278BSlot *slot, int val) |
| 184 | 93 | { |
| 185 | 94 | int res, oct; |
| 186 | 95 | |
| r22809 | r22810 | |
| 206 | 115 | return res; |
| 207 | 116 | } |
| 208 | 117 | |
| 209 | | static UINT32 ymf278_compute_decay_env_vol_step(YMF278BSlot *slot, int val) |
| 118 | UINT32 ymf278b_device::compute_decay_env_vol_step(YMF278BSlot *slot, int val) |
| 210 | 119 | { |
| 211 | 120 | int rate; |
| 212 | 121 | UINT32 res; |
| r22809 | r22810 | |
| 221 | 130 | rate = 5; |
| 222 | 131 | } |
| 223 | 132 | else |
| 224 | | rate = ymf278b_compute_rate(slot, val); |
| 133 | rate = compute_rate(slot, val); |
| 225 | 134 | |
| 226 | 135 | if (rate < 4) |
| 227 | 136 | res = 0; |
| 228 | 137 | else |
| 229 | | res = (256U<<23) / slot->chip->lut_dr[rate]; |
| 138 | res = (256U<<23) / m_lut_dr[rate]; |
| 230 | 139 | |
| 231 | 140 | return res; |
| 232 | 141 | } |
| 233 | 142 | |
| 234 | | static void ymf278b_compute_freq_step(YMF278BSlot *slot) |
| 143 | void ymf278b_device::compute_freq_step(YMF278BSlot *slot) |
| 235 | 144 | { |
| 236 | 145 | UINT32 step; |
| 237 | 146 | int oct; |
| r22809 | r22810 | |
| 244 | 153 | slot->step = step >> 3; |
| 245 | 154 | } |
| 246 | 155 | |
| 247 | | static void ymf278b_compute_envelope(YMF278BSlot *slot) |
| 156 | void ymf278b_device::compute_envelope(YMF278BSlot *slot) |
| 248 | 157 | { |
| 249 | 158 | switch (slot->env_step) |
| 250 | 159 | { |
| r22809 | r22810 | |
| 252 | 161 | case 0: |
| 253 | 162 | { |
| 254 | 163 | // Attack |
| 255 | | int rate = ymf278b_compute_rate(slot, slot->AR); |
| 164 | int rate = compute_rate(slot, slot->AR); |
| 256 | 165 | slot->env_vol = 256U<<23; |
| 257 | 166 | slot->env_vol_lim = (256U<<23) - 1; |
| 258 | 167 | |
| r22809 | r22810 | |
| 262 | 171 | LOG(("YMF278B: Attack skipped - ")); |
| 263 | 172 | slot->env_vol = 0; |
| 264 | 173 | slot->env_step++; |
| 265 | | ymf278b_compute_envelope(slot); |
| 174 | compute_envelope(slot); |
| 266 | 175 | } |
| 267 | 176 | else if (rate<4) |
| 268 | 177 | { |
| r22809 | r22810 | |
| 271 | 180 | else |
| 272 | 181 | { |
| 273 | 182 | // NOTE: attack rate is linear here, but datasheet shows a smooth curve |
| 274 | | LOG(("YMF278B: Attack, val = %d, rate = %d, delay = %g\n", slot->AR, rate, slot->chip->lut_ar[rate]*1000.0)); |
| 275 | | slot->env_vol_step = ~((256U<<23) / slot->chip->lut_ar[rate]); |
| 183 | LOG(("YMF278B: Attack, val = %d, rate = %d, delay = %g\n", slot->AR, rate, m_lut_ar[rate]*1000.0)); |
| 184 | slot->env_vol_step = ~((256U<<23) / m_lut_ar[rate]); |
| 276 | 185 | } |
| 277 | 186 | |
| 278 | 187 | break; |
| r22809 | r22810 | |
| 282 | 191 | case 1: |
| 283 | 192 | if(slot->DL) |
| 284 | 193 | { |
| 285 | | LOG(("YMF278B: Decay step 1, dl=%d, val = %d rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->DL, slot->D1R, ymf278b_compute_rate(slot, slot->D1R), slot->chip->lut_dr[ymf278b_compute_rate(slot, slot->D1R)]*1000.0, slot->preverb, slot->DAMP)); |
| 286 | | slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->D1R); |
| 194 | LOG(("YMF278B: Decay step 1, dl=%d, val = %d rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->DL, slot->D1R, compute_rate(slot, slot->D1R), m_lut_dr[compute_rate(slot, slot->D1R)]*1000.0, slot->preverb, slot->DAMP)); |
| 195 | slot->env_vol_step = compute_decay_env_vol_step(slot, slot->D1R); |
| 287 | 196 | slot->env_vol_lim = (slot->DL*8)<<23; |
| 288 | 197 | } |
| 289 | 198 | else |
| 290 | 199 | { |
| 291 | 200 | LOG(("YMF278B: Decay 1 skipped - ")); |
| 292 | 201 | slot->env_step++; |
| 293 | | ymf278b_compute_envelope(slot); |
| 202 | compute_envelope(slot); |
| 294 | 203 | } |
| 295 | 204 | |
| 296 | 205 | break; |
| 297 | 206 | |
| 298 | 207 | // Decay 2 |
| 299 | 208 | case 2: |
| 300 | | LOG(("YMF278B: Decay step 2, val = %d, rate = %d, delay = %g, , PRVB = %d, DAMP = %d, current vol = %d\n", slot->D2R, ymf278b_compute_rate(slot, slot->D2R), slot->chip->lut_dr[ymf278b_compute_rate(slot, slot->D2R)]*1000.0, slot->preverb, slot->DAMP, slot->env_vol >> 23)); |
| 301 | | slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->D2R); |
| 209 | LOG(("YMF278B: Decay step 2, val = %d, rate = %d, delay = %g, , PRVB = %d, DAMP = %d, current vol = %d\n", slot->D2R, compute_rate(slot, slot->D2R), m_lut_dr[compute_rate(slot, slot->D2R)]*1000.0, slot->preverb, slot->DAMP, slot->env_vol >> 23)); |
| 210 | slot->env_vol_step = compute_decay_env_vol_step(slot, slot->D2R); |
| 302 | 211 | slot->env_vol_lim = 256U<<23; |
| 303 | 212 | break; |
| 304 | 213 | |
| r22809 | r22810 | |
| 313 | 222 | |
| 314 | 223 | // Release |
| 315 | 224 | case 4: |
| 316 | | LOG(("YMF278B: Release, val = %d, rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->RR, ymf278b_compute_rate(slot, slot->RR), slot->chip->lut_dr[ymf278b_compute_rate(slot, slot->RR)]*1000.0, slot->preverb, slot->DAMP)); |
| 317 | | slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->RR); |
| 225 | LOG(("YMF278B: Release, val = %d, rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->RR, compute_rate(slot, slot->RR), m_lut_dr[compute_rate(slot, slot->RR)]*1000.0, slot->preverb, slot->DAMP)); |
| 226 | slot->env_vol_step = compute_decay_env_vol_step(slot, slot->RR); |
| 318 | 227 | slot->env_vol_lim = 256U<<23; |
| 319 | 228 | break; |
| 320 | 229 | |
| r22809 | r22810 | |
| 331 | 240 | } |
| 332 | 241 | } |
| 333 | 242 | |
| 334 | | static STREAM_UPDATE( ymf278b_pcm_update ) |
| 243 | //------------------------------------------------- |
| 244 | // sound_stream_update - handle a stream update |
| 245 | //------------------------------------------------- |
| 246 | |
| 247 | void ymf278b_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 335 | 248 | { |
| 336 | | YMF278BChip *chip = (YMF278BChip *)param; |
| 337 | 249 | int i, j; |
| 338 | 250 | YMF278BSlot *slot = NULL; |
| 339 | 251 | INT16 sample = 0; |
| r22809 | r22810 | |
| 345 | 257 | |
| 346 | 258 | for (i = 0; i < 24; i++) |
| 347 | 259 | { |
| 348 | | slot = &chip->slots[i]; |
| 260 | slot = &m_slots[i]; |
| 349 | 261 | |
| 350 | 262 | if (slot->active) |
| 351 | 263 | { |
| r22809 | r22810 | |
| 364 | 276 | { |
| 365 | 277 | // 8 bit |
| 366 | 278 | case 0: |
| 367 | | sample = ymf278b_read_memory(chip, slot->startaddr + (slot->stepptr>>16))<<8; |
| 279 | sample = read_memory(slot->startaddr + (slot->stepptr>>16))<<8; |
| 368 | 280 | break; |
| 369 | 281 | |
| 370 | 282 | // 12 bit |
| 371 | 283 | case 1: |
| 372 | 284 | if (slot->stepptr & 0x10000) |
| 373 | | sample = ymf278b_read_memory(chip, slot->startaddr + (slot->stepptr>>17)*3+2)<<8 | |
| 374 | | (ymf278b_read_memory(chip, slot->startaddr + (slot->stepptr>>17)*3+1) << 4 & 0xf0); |
| 285 | sample = read_memory(slot->startaddr + (slot->stepptr>>17)*3+2)<<8 | |
| 286 | (read_memory(slot->startaddr + (slot->stepptr>>17)*3+1) << 4 & 0xf0); |
| 375 | 287 | else |
| 376 | | sample = ymf278b_read_memory(chip, slot->startaddr + (slot->stepptr>>17)*3)<<8 | |
| 377 | | (ymf278b_read_memory(chip, slot->startaddr + (slot->stepptr>>17)*3+1) & 0xf0); |
| 288 | sample = read_memory(slot->startaddr + (slot->stepptr>>17)*3)<<8 | |
| 289 | (read_memory(slot->startaddr + (slot->stepptr>>17)*3+1) & 0xf0); |
| 378 | 290 | break; |
| 379 | 291 | |
| 380 | 292 | // 16 bit |
| 381 | 293 | case 2: |
| 382 | | sample = ymf278b_read_memory(chip, slot->startaddr + ((slot->stepptr>>16)*2))<<8 | |
| 383 | | ymf278b_read_memory(chip, slot->startaddr + ((slot->stepptr>>16)*2)+1); |
| 294 | sample = read_memory(slot->startaddr + ((slot->stepptr>>16)*2))<<8 | |
| 295 | read_memory(slot->startaddr + ((slot->stepptr>>16)*2)+1); |
| 384 | 296 | break; |
| 385 | 297 | |
| 386 | 298 | // ?? bit, effect is unknown, datasheet says it's prohibited |
| r22809 | r22810 | |
| 389 | 301 | break; |
| 390 | 302 | } |
| 391 | 303 | |
| 392 | | *mixp++ += (sample * chip->volume[slot->TL+chip->pan_left [slot->pan]+(slot->env_vol>>23)])>>17; |
| 393 | | *mixp++ += (sample * chip->volume[slot->TL+chip->pan_right[slot->pan]+(slot->env_vol>>23)])>>17; |
| 304 | *mixp++ += (sample * m_volume[slot->TL+m_pan_left [slot->pan]+(slot->env_vol>>23)])>>17; |
| 305 | *mixp++ += (sample * m_volume[slot->TL+m_pan_right[slot->pan]+(slot->env_vol>>23)])>>17; |
| 394 | 306 | |
| 395 | 307 | // update frequency |
| 396 | 308 | slot->stepptr += slot->step; |
| r22809 | r22810 | |
| 400 | 312 | if (((INT32)(slot->env_vol - slot->env_vol_lim)) >= 0) |
| 401 | 313 | { |
| 402 | 314 | slot->env_step++; |
| 403 | | ymf278b_compute_envelope(slot); |
| 315 | compute_envelope(slot); |
| 404 | 316 | } |
| 405 | 317 | else if (slot->preverb && !slot->env_preverb && slot->env_step && slot->env_vol > ((6*8)<<23)) |
| 406 | | ymf278b_compute_envelope(slot); |
| 318 | compute_envelope(slot); |
| 407 | 319 | } |
| 408 | 320 | } |
| 409 | 321 | } |
| 410 | 322 | |
| 411 | 323 | mixp = mix; |
| 412 | | vl = chip->mix_level[chip->pcm_l]; |
| 413 | | vr = chip->mix_level[chip->pcm_r]; |
| 324 | vl = m_mix_level[m_pcm_l]; |
| 325 | vr = m_mix_level[m_pcm_r]; |
| 414 | 326 | for (i = 0; i < samples; i++) |
| 415 | 327 | { |
| 416 | 328 | outputs[0][i] = (*mixp++ * vl) >> 16; |
| r22809 | r22810 | |
| 418 | 330 | } |
| 419 | 331 | } |
| 420 | 332 | |
| 421 | | static void ymf278b_irq_check(running_machine &machine, YMF278BChip *chip) |
| 333 | void ymf278b_device::irq_check() |
| 422 | 334 | { |
| 423 | | int prev_line = chip->irq_line; |
| 424 | | chip->irq_line = chip->current_irq ? ASSERT_LINE : CLEAR_LINE; |
| 425 | | if(chip->irq_line != prev_line && !chip->irq_callback.isnull()) |
| 426 | | chip->irq_callback(chip->irq_line); |
| 335 | int prev_line = m_irq_line; |
| 336 | m_irq_line = m_current_irq ? ASSERT_LINE : CLEAR_LINE; |
| 337 | if(m_irq_line != prev_line && !m_irq_handler.isnull()) |
| 338 | m_irq_handler(m_irq_line); |
| 427 | 339 | } |
| 428 | 340 | |
| 429 | | static TIMER_CALLBACK( ymf278b_timer_a_tick ) |
| 341 | enum |
| 430 | 342 | { |
| 431 | | YMF278BChip *chip = (YMF278BChip *)ptr; |
| 432 | | if(!(chip->enable & 0x40)) |
| 433 | | { |
| 434 | | chip->current_irq |= 0x40; |
| 435 | | ymf278b_irq_check(machine, chip); |
| 436 | | } |
| 437 | | } |
| 343 | TIMER_A = 0, |
| 344 | TIMER_B, |
| 345 | TIMER_BUSY_CLEAR, |
| 346 | TIMER_LD_CLEAR |
| 347 | }; |
| 438 | 348 | |
| 439 | | static TIMER_CALLBACK( ymf278b_timer_b_tick ) |
| 349 | void ymf278b_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 440 | 350 | { |
| 441 | | YMF278BChip *chip = (YMF278BChip *)ptr; |
| 442 | | if(!(chip->enable & 0x20)) |
| 351 | switch(id) |
| 443 | 352 | { |
| 444 | | chip->current_irq |= 0x20; |
| 445 | | ymf278b_irq_check(machine, chip); |
| 353 | case TIMER_A: |
| 354 | if(!(m_enable & 0x40)) |
| 355 | { |
| 356 | m_current_irq |= 0x40; |
| 357 | irq_check(); |
| 358 | } |
| 359 | break; |
| 360 | |
| 361 | case TIMER_B: |
| 362 | if(!(m_enable & 0x20)) |
| 363 | { |
| 364 | m_current_irq |= 0x20; |
| 365 | irq_check(); |
| 366 | } |
| 367 | break; |
| 368 | |
| 369 | case TIMER_BUSY_CLEAR: |
| 370 | m_status_busy = 0; |
| 371 | break; |
| 372 | |
| 373 | case TIMER_LD_CLEAR: |
| 374 | m_status_ld = 0; |
| 375 | break; |
| 446 | 376 | } |
| 447 | 377 | } |
| 448 | 378 | |
| 449 | 379 | |
| 450 | 380 | /**************************************************************************/ |
| 451 | 381 | |
| 452 | | static void ymf278b_A_w(running_machine &machine, YMF278BChip *chip, UINT8 reg, UINT8 data) |
| 382 | void ymf278b_device::A_w(UINT8 reg, UINT8 data) |
| 453 | 383 | { |
| 454 | 384 | // FM register array 0 (compatible with YMF262) |
| 455 | 385 | switch(reg) |
| r22809 | r22810 | |
| 461 | 391 | |
| 462 | 392 | // timer a count |
| 463 | 393 | case 0x02: |
| 464 | | if (data != chip->timer_a_count) |
| 394 | if (data != m_timer_a_count) |
| 465 | 395 | { |
| 466 | | chip->timer_a_count = data; |
| 396 | m_timer_a_count = data; |
| 467 | 397 | |
| 468 | 398 | // change period, ~80.8us * t |
| 469 | | if (chip->enable & 1) |
| 470 | | chip->timer_a->adjust(chip->timer_a->remaining(), 0, chip->timer_base * (256-data) * 4); |
| 399 | if (m_enable & 1) |
| 400 | m_timer_a->adjust(m_timer_a->remaining(), 0, m_timer_base * (256-data) * 4); |
| 471 | 401 | } |
| 472 | 402 | break; |
| 473 | 403 | |
| 474 | 404 | // timer b count |
| 475 | 405 | case 0x03: |
| 476 | | if (data != chip->timer_b_count) |
| 406 | if (data != m_timer_b_count) |
| 477 | 407 | { |
| 478 | | chip->timer_b_count = data; |
| 408 | m_timer_b_count = data; |
| 479 | 409 | |
| 480 | 410 | // change period, ~323.1us * t |
| 481 | | if (chip->enable & 2) |
| 482 | | chip->timer_b->adjust(chip->timer_b->remaining(), 0, chip->timer_base * (256-data) * 16); |
| 411 | if (m_enable & 2) |
| 412 | m_timer_b->adjust(m_timer_b->remaining(), 0, m_timer_base * (256-data) * 16); |
| 483 | 413 | } |
| 484 | 414 | break; |
| 485 | 415 | |
| 486 | 416 | // timer control |
| 487 | 417 | case 0x04: |
| 488 | 418 | if(data & 0x80) |
| 489 | | chip->current_irq = 0; |
| 419 | m_current_irq = 0; |
| 490 | 420 | else |
| 491 | 421 | { |
| 492 | 422 | // reset timers |
| 493 | | if((chip->enable ^ data) & 1) |
| 423 | if((m_enable ^ data) & 1) |
| 494 | 424 | { |
| 495 | | attotime period = (data & 1) ? chip->timer_base * (256-chip->timer_a_count) * 4 : attotime::never; |
| 496 | | chip->timer_a->adjust(period, 0, period); |
| 425 | attotime period = (data & 1) ? m_timer_base * (256-m_timer_a_count) * 4 : attotime::never; |
| 426 | m_timer_a->adjust(period, 0, period); |
| 497 | 427 | } |
| 498 | | if((chip->enable ^ data) & 2) |
| 428 | if((m_enable ^ data) & 2) |
| 499 | 429 | { |
| 500 | | attotime period = (data & 2) ? chip->timer_base * (256-chip->timer_b_count) * 16 : attotime::never; |
| 501 | | chip->timer_b->adjust(period, 0, period); |
| 430 | attotime period = (data & 2) ? m_timer_base * (256-m_timer_b_count) * 16 : attotime::never; |
| 431 | m_timer_b->adjust(period, 0, period); |
| 502 | 432 | } |
| 503 | 433 | |
| 504 | | chip->enable = data; |
| 505 | | chip->current_irq &= ~data; |
| 434 | m_enable = data; |
| 435 | m_current_irq &= ~data; |
| 506 | 436 | } |
| 507 | | ymf278b_irq_check(machine, chip); |
| 437 | irq_check(); |
| 508 | 438 | break; |
| 509 | 439 | |
| 510 | 440 | default: |
| r22809 | r22810 | |
| 513 | 443 | } |
| 514 | 444 | } |
| 515 | 445 | |
| 516 | | static void ymf278b_B_w(YMF278BChip *chip, UINT8 reg, UINT8 data) |
| 446 | void ymf278b_device::B_w(UINT8 reg, UINT8 data) |
| 517 | 447 | { |
| 518 | 448 | // FM register array 1 (compatible with YMF262) |
| 519 | 449 | switch(reg) |
| r22809 | r22810 | |
| 525 | 455 | |
| 526 | 456 | // expansion register (NEW2/NEW) |
| 527 | 457 | case 0x05: |
| 528 | | chip->exp = data; |
| 458 | m_exp = data; |
| 529 | 459 | break; |
| 530 | 460 | |
| 531 | 461 | default: |
| r22809 | r22810 | |
| 534 | 464 | } |
| 535 | 465 | } |
| 536 | 466 | |
| 537 | | static TIMER_CALLBACK( ymf278b_timer_ld_clear ) |
| 467 | void ymf278b_device::retrigger_note(YMF278BSlot *slot) |
| 538 | 468 | { |
| 539 | | YMF278BChip *chip = (YMF278BChip *)ptr; |
| 540 | | chip->status_ld = 0; |
| 541 | | } |
| 542 | | |
| 543 | | static void ymf278b_retrigger_note(YMF278BSlot *slot) |
| 544 | | { |
| 545 | 469 | // activate channel |
| 546 | 470 | if (slot->octave != 8) |
| 547 | 471 | slot->active = 1; |
| r22809 | r22810 | |
| 551 | 475 | slot->env_step = 0; |
| 552 | 476 | slot->env_preverb = 0; |
| 553 | 477 | |
| 554 | | ymf278b_compute_freq_step(slot); |
| 555 | | ymf278b_compute_envelope(slot); |
| 478 | compute_freq_step(slot); |
| 479 | compute_envelope(slot); |
| 556 | 480 | } |
| 557 | 481 | |
| 558 | | static void ymf278b_C_w(YMF278BChip *chip, UINT8 reg, UINT8 data, int init) |
| 482 | void ymf278b_device::C_w(UINT8 reg, UINT8 data, int init) |
| 559 | 483 | { |
| 560 | 484 | if (!init) |
| 561 | 485 | { |
| 562 | 486 | // PCM regs are only accessible if NEW2 is set |
| 563 | | if (~chip->exp & 2) |
| 487 | if (~m_exp & 2) |
| 564 | 488 | return; |
| 565 | 489 | |
| 566 | | chip->stream->update(); |
| 490 | m_stream->update(); |
| 567 | 491 | } |
| 568 | 492 | |
| 569 | 493 | // Handle slot registers specifically |
| r22809 | r22810 | |
| 572 | 496 | YMF278BSlot *slot = NULL; |
| 573 | 497 | int snum; |
| 574 | 498 | snum = (reg-8) % 24; |
| 575 | | slot = &chip->slots[snum]; |
| 499 | slot = &m_slots[snum]; |
| 576 | 500 | switch((reg-8) / 24) |
| 577 | 501 | { |
| 578 | 502 | case 0: |
| r22809 | r22810 | |
| 586 | 510 | slot->wave |= data; |
| 587 | 511 | |
| 588 | 512 | // load wavetable header |
| 589 | | if(slot->wave < 384 || !chip->wavetblhdr) |
| 513 | if(slot->wave < 384 || !m_wavetblhdr) |
| 590 | 514 | offset = slot->wave * 12; |
| 591 | 515 | else |
| 592 | | offset = chip->wavetblhdr*0x80000 + (slot->wave - 384) * 12; |
| 516 | offset = m_wavetblhdr*0x80000 + (slot->wave - 384) * 12; |
| 593 | 517 | for (i = 0; i < 12; i++) |
| 594 | | p[i] = ymf278b_read_memory(chip, offset+i); |
| 518 | p[i] = read_memory(offset+i); |
| 595 | 519 | |
| 596 | 520 | slot->bits = (p[0]&0xc0)>>6; |
| 597 | 521 | slot->startaddr = (p[2] | (p[1]<<8) | ((p[0]&0x3f)<<16)); |
| r22809 | r22810 | |
| 602 | 526 | |
| 603 | 527 | // copy internal registers data |
| 604 | 528 | for (i = 7; i < 12; i++) |
| 605 | | ymf278b_C_w(chip, 8 + snum + (i-2) * 24, p[i], 1); |
| 529 | C_w(8 + snum + (i-2) * 24, p[i], 1); |
| 606 | 530 | |
| 607 | 531 | // status register LD bit is on for approx 300us |
| 608 | | chip->status_ld = 1; |
| 532 | m_status_ld = 1; |
| 609 | 533 | period = attotime::from_usec(300); |
| 610 | | if (chip->clock != YMF278B_STD_CLOCK) |
| 611 | | period = (period * chip->clock) / YMF278B_STD_CLOCK; |
| 612 | | chip->timer_ld->adjust(period); |
| 534 | if (m_clock != YMF278B_STD_CLOCK) |
| 535 | period = (period * m_clock) / YMF278B_STD_CLOCK; |
| 536 | m_timer_ld->adjust(period); |
| 613 | 537 | |
| 614 | 538 | // retrigger if key is on |
| 615 | 539 | if (slot->KEY_ON) |
| 616 | | ymf278b_retrigger_note(slot); |
| 540 | retrigger_note(slot); |
| 617 | 541 | else if (slot->active) |
| 618 | 542 | { |
| 619 | 543 | // deactivate channel |
| 620 | 544 | slot->env_step = 5; |
| 621 | | ymf278b_compute_envelope(slot); |
| 545 | compute_envelope(slot); |
| 622 | 546 | } |
| 623 | 547 | |
| 624 | 548 | break; |
| r22809 | r22810 | |
| 629 | 553 | slot->wave |= ((data&0x1)<<8); |
| 630 | 554 | slot->F_NUMBER &= 0x380; |
| 631 | 555 | slot->F_NUMBER |= (data>>1); |
| 632 | | if (slot->active && (data ^ chip->pcmregs[reg]) & 0xfe) |
| 556 | if (slot->active && (data ^ m_pcmregs[reg]) & 0xfe) |
| 633 | 557 | { |
| 634 | | ymf278b_compute_freq_step(slot); |
| 635 | | ymf278b_compute_envelope(slot); |
| 558 | compute_freq_step(slot); |
| 559 | compute_envelope(slot); |
| 636 | 560 | } |
| 637 | 561 | break; |
| 638 | 562 | |
| r22809 | r22810 | |
| 641 | 565 | slot->F_NUMBER |= ((data&0x07)<<7); |
| 642 | 566 | slot->preverb = (data&0x8)>>3; |
| 643 | 567 | slot->octave = (data&0xf0)>>4; |
| 644 | | if (data != chip->pcmregs[reg]) |
| 568 | if (data != m_pcmregs[reg]) |
| 645 | 569 | { |
| 646 | 570 | // channel goes off if octave is set to -8 (datasheet says it's prohibited) |
| 647 | | // (it is ok if this activates the channel while it was off: ymf278b_compute_envelope will reset it again if needed) |
| 571 | // (it is ok if this activates the channel while it was off: compute_envelope will reset it again if needed) |
| 648 | 572 | slot->active = (slot->octave != 8); |
| 649 | 573 | |
| 650 | 574 | if (slot->active) |
| 651 | 575 | { |
| 652 | 576 | slot->env_preverb = 0; |
| 653 | | ymf278b_compute_freq_step(slot); |
| 654 | | ymf278b_compute_envelope(slot); |
| 577 | compute_freq_step(slot); |
| 578 | compute_envelope(slot); |
| 655 | 579 | } |
| 656 | 580 | } |
| 657 | 581 | break; |
| r22809 | r22810 | |
| 675 | 599 | // don't retrigger if key was already on |
| 676 | 600 | if (slot->KEY_ON) |
| 677 | 601 | { |
| 678 | | if ((data ^ chip->pcmregs[reg]) & 0x40) |
| 679 | | ymf278b_compute_envelope(slot); |
| 602 | if ((data ^ m_pcmregs[reg]) & 0x40) |
| 603 | compute_envelope(slot); |
| 680 | 604 | |
| 681 | 605 | break; |
| 682 | 606 | } |
| 683 | 607 | |
| 684 | | ymf278b_retrigger_note(slot); |
| 608 | retrigger_note(slot); |
| 685 | 609 | } |
| 686 | 610 | else if (slot->active) |
| 687 | 611 | { |
| 688 | 612 | // release |
| 689 | 613 | slot->env_step = 4; |
| 690 | | ymf278b_compute_envelope(slot); |
| 614 | compute_envelope(slot); |
| 691 | 615 | } |
| 692 | 616 | slot->KEY_ON = (data&0x80)>>7; |
| 693 | 617 | break; |
| r22809 | r22810 | |
| 701 | 625 | case 6: |
| 702 | 626 | slot->AR = data>>4; |
| 703 | 627 | slot->D1R = data&0xf; |
| 704 | | if (slot->active && data != chip->pcmregs[reg]) |
| 705 | | ymf278b_compute_envelope(slot); |
| 628 | if (slot->active && data != m_pcmregs[reg]) |
| 629 | compute_envelope(slot); |
| 706 | 630 | break; |
| 707 | 631 | |
| 708 | 632 | case 7: |
| 709 | 633 | slot->DL = data>>4; |
| 710 | 634 | slot->D2R = data&0xf; |
| 711 | | if (slot->active && data != chip->pcmregs[reg]) |
| 712 | | ymf278b_compute_envelope(slot); |
| 635 | if (slot->active && data != m_pcmregs[reg]) |
| 636 | compute_envelope(slot); |
| 713 | 637 | break; |
| 714 | 638 | |
| 715 | 639 | case 8: |
| 716 | 640 | slot->RC = data>>4; |
| 717 | 641 | slot->RR = data&0xf; |
| 718 | | if (slot->active && data != chip->pcmregs[reg]) |
| 719 | | ymf278b_compute_envelope(slot); |
| 642 | if (slot->active && data != m_pcmregs[reg]) |
| 643 | compute_envelope(slot); |
| 720 | 644 | break; |
| 721 | 645 | |
| 722 | 646 | case 9: |
| r22809 | r22810 | |
| 736 | 660 | break; |
| 737 | 661 | |
| 738 | 662 | case 0x02: |
| 739 | | chip->wavetblhdr = (data>>2)&0x7; |
| 740 | | chip->memmode = data&3; |
| 663 | m_wavetblhdr = (data>>2)&0x7; |
| 664 | m_memmode = data&3; |
| 741 | 665 | break; |
| 742 | 666 | |
| 743 | 667 | case 0x03: |
| r22809 | r22810 | |
| 745 | 669 | break; |
| 746 | 670 | case 0x05: |
| 747 | 671 | // set memory address |
| 748 | | chip->memadr = (chip->pcmregs[3] & 0x3f) << 16 | chip->pcmregs[4] << 8 | data; |
| 672 | m_memadr = (m_pcmregs[3] & 0x3f) << 16 | m_pcmregs[4] << 8 | data; |
| 749 | 673 | break; |
| 750 | 674 | |
| 751 | 675 | case 0x06: |
| 752 | 676 | // memory data (ignored, we don't support RAM) |
| 753 | | ymf278b_write_memory(chip, chip->memadr, data); |
| 754 | | chip->memadr = (chip->memadr + 1) & 0x3fffff; |
| 677 | write_memory(m_memadr, data); |
| 678 | m_memadr = (m_memadr + 1) & 0x3fffff; |
| 755 | 679 | break; |
| 756 | 680 | |
| 757 | 681 | case 0x07: |
| 758 | 682 | break; // unused |
| 759 | 683 | |
| 760 | 684 | case 0xf8: |
| 761 | | chip->fm_l = data & 0x7; |
| 762 | | chip->fm_r = (data>>3)&0x7; |
| 685 | m_fm_l = data & 0x7; |
| 686 | m_fm_r = (data>>3)&0x7; |
| 763 | 687 | break; |
| 764 | 688 | |
| 765 | 689 | case 0xf9: |
| 766 | | chip->pcm_l = data & 0x7; |
| 767 | | chip->pcm_r = (data>>3)&0x7; |
| 690 | m_pcm_l = data & 0x7; |
| 691 | m_pcm_r = (data>>3)&0x7; |
| 768 | 692 | break; |
| 769 | 693 | |
| 770 | 694 | default: |
| r22809 | r22810 | |
| 773 | 697 | } |
| 774 | 698 | } |
| 775 | 699 | |
| 776 | | chip->pcmregs[reg] = data; |
| 700 | m_pcmregs[reg] = data; |
| 777 | 701 | } |
| 778 | 702 | |
| 779 | | static TIMER_CALLBACK( ymf278b_timer_busy_clear ) |
| 703 | void ymf278b_device::timer_busy_start(int is_pcm) |
| 780 | 704 | { |
| 781 | | YMF278BChip *chip = (YMF278BChip *)ptr; |
| 782 | | chip->status_busy = 0; |
| 783 | | } |
| 784 | | |
| 785 | | static void ymf278b_timer_busy_start(YMF278BChip *chip, int is_pcm) |
| 786 | | { |
| 787 | 705 | // status register BUSY bit is on for 56(FM) or 88(PCM) cycles |
| 788 | | chip->status_busy = 1; |
| 789 | | chip->timer_busy->adjust(attotime::from_hz(chip->clock / (is_pcm ? 88 : 56))); |
| 706 | m_status_busy = 1; |
| 707 | m_timer_busy->adjust(attotime::from_hz(m_clock / (is_pcm ? 88 : 56))); |
| 790 | 708 | } |
| 791 | 709 | |
| 792 | | WRITE8_DEVICE_HANDLER( ymf278b_w ) |
| 710 | WRITE8_MEMBER( ymf278b_device::write ) |
| 793 | 711 | { |
| 794 | | YMF278BChip *chip = get_safe_token(device); |
| 795 | | |
| 796 | 712 | switch (offset) |
| 797 | 713 | { |
| 798 | 714 | case 0: |
| 799 | 715 | case 2: |
| 800 | | ymf278b_timer_busy_start(chip, 0); |
| 801 | | chip->port_AB = data; |
| 802 | | chip->lastport = offset>>1 & 1; |
| 716 | timer_busy_start(0); |
| 717 | m_port_AB = data; |
| 718 | m_lastport = offset>>1 & 1; |
| 803 | 719 | break; |
| 804 | 720 | |
| 805 | 721 | case 1: |
| 806 | 722 | case 3: |
| 807 | | ymf278b_timer_busy_start(chip, 0); |
| 808 | | if (chip->lastport) ymf278b_B_w(chip, chip->port_AB, data); |
| 809 | | else ymf278b_A_w(device->machine(), chip, chip->port_AB, data); |
| 723 | timer_busy_start(0); |
| 724 | if (m_lastport) B_w(m_port_AB, data); |
| 725 | else A_w(m_port_AB, data); |
| 810 | 726 | break; |
| 811 | 727 | |
| 812 | 728 | case 4: |
| 813 | | ymf278b_timer_busy_start(chip, 1); |
| 814 | | chip->port_C = data; |
| 729 | timer_busy_start(1); |
| 730 | m_port_C = data; |
| 815 | 731 | break; |
| 816 | 732 | |
| 817 | 733 | case 5: |
| 818 | | ymf278b_timer_busy_start(chip, 1); |
| 819 | | ymf278b_C_w(chip, chip->port_C, data, 0); |
| 734 | timer_busy_start(1); |
| 735 | C_w(m_port_C, data, 0); |
| 820 | 736 | break; |
| 821 | 737 | |
| 822 | 738 | default: |
| 823 | | logerror("%s: unexpected write at offset %X to ymf278b = %02X\n", device->machine().describe_context(), offset, data); |
| 739 | logerror("%s: unexpected write at offset %X to ymf278b = %02X\n", machine().describe_context(), offset, data); |
| 824 | 740 | break; |
| 825 | 741 | } |
| 826 | 742 | } |
| 827 | 743 | |
| 828 | 744 | |
| 829 | | READ8_DEVICE_HANDLER( ymf278b_r ) |
| 745 | READ8_MEMBER( ymf278b_device::read ) |
| 830 | 746 | { |
| 831 | | YMF278BChip *chip = get_safe_token(device); |
| 832 | 747 | UINT8 ret = 0; |
| 833 | 748 | |
| 834 | 749 | switch (offset) |
| r22809 | r22810 | |
| 838 | 753 | { |
| 839 | 754 | // bits 0 and 1 are only valid if NEW2 is set |
| 840 | 755 | UINT8 newbits = 0; |
| 841 | | if (chip->exp & 2) |
| 842 | | newbits = (chip->status_ld << 1) | chip->status_busy; |
| 756 | if (m_exp & 2) |
| 757 | newbits = (m_status_ld << 1) | m_status_busy; |
| 843 | 758 | |
| 844 | | ret = newbits | chip->current_irq | (chip->irq_line == ASSERT_LINE ? 0x80 : 0x00); |
| 759 | ret = newbits | m_current_irq | (m_irq_line == ASSERT_LINE ? 0x80 : 0x00); |
| 845 | 760 | break; |
| 846 | 761 | } |
| 847 | 762 | |
| r22809 | r22810 | |
| 854 | 769 | // PCM regs |
| 855 | 770 | case 5: |
| 856 | 771 | // only accessible if NEW2 is set |
| 857 | | if (~chip->exp & 2) |
| 772 | if (~m_exp & 2) |
| 858 | 773 | break; |
| 859 | 774 | |
| 860 | | switch (chip->port_C) |
| 775 | switch (m_port_C) |
| 861 | 776 | { |
| 862 | 777 | // special cases |
| 863 | 778 | case 2: |
| 864 | | ret = (chip->pcmregs[chip->port_C] & 0x1f) | 0x20; // device ID in upper bits |
| 779 | ret = (m_pcmregs[m_port_C] & 0x1f) | 0x20; // device ID in upper bits |
| 865 | 780 | break; |
| 866 | 781 | case 6: |
| 867 | | ret = ymf278b_read_memory(chip, chip->memadr); |
| 868 | | chip->memadr = (chip->memadr + 1) & 0x3fffff; |
| 782 | ret = read_memory(m_memadr); |
| 783 | m_memadr = (m_memadr + 1) & 0x3fffff; |
| 869 | 784 | break; |
| 870 | 785 | |
| 871 | 786 | default: |
| 872 | | ret = chip->pcmregs[chip->port_C]; |
| 787 | ret = m_pcmregs[m_port_C]; |
| 873 | 788 | break; |
| 874 | 789 | } |
| 875 | 790 | break; |
| 876 | 791 | |
| 877 | 792 | default: |
| 878 | | logerror("%s: unexpected read at offset %X from ymf278b\n", device->machine().describe_context(), offset); |
| 793 | logerror("%s: unexpected read at offset %X from ymf278b\n", machine().describe_context(), offset); |
| 879 | 794 | break; |
| 880 | 795 | } |
| 881 | 796 | |
| r22809 | r22810 | |
| 885 | 800 | |
| 886 | 801 | /**************************************************************************/ |
| 887 | 802 | |
| 888 | | static DEVICE_RESET( ymf278b ) |
| 803 | //------------------------------------------------- |
| 804 | // device_reset - device-specific reset |
| 805 | //------------------------------------------------- |
| 806 | |
| 807 | void ymf278b_device::device_reset() |
| 889 | 808 | { |
| 890 | | YMF278BChip *chip = get_safe_token(device); |
| 891 | 809 | int i; |
| 892 | 810 | |
| 893 | 811 | // clear registers |
| 894 | 812 | for (i = 0; i <= 4; i++) |
| 895 | | ymf278b_A_w(device->machine(), chip, i, 0); |
| 896 | | ymf278b_B_w(chip, 5, 0); |
| 813 | A_w(i, 0); |
| 814 | B_w(5, 0); |
| 897 | 815 | for (i = 0; i < 8; i++) |
| 898 | | ymf278b_C_w(chip, i, 0, 1); |
| 816 | C_w(i, 0, 1); |
| 899 | 817 | for (i = 0xff; i >= 8; i--) |
| 900 | | ymf278b_C_w(chip, i, 0, 1); |
| 901 | | ymf278b_C_w(chip, 0xf8, 0x1b, 1); |
| 818 | C_w(i, 0, 1); |
| 819 | C_w(0xf8, 0x1b, 1); |
| 902 | 820 | |
| 903 | | chip->port_AB = chip->port_C = 0; |
| 904 | | chip->lastport = 0; |
| 905 | | chip->memadr = 0; |
| 821 | m_port_AB = m_port_C = 0; |
| 822 | m_lastport = 0; |
| 823 | m_memadr = 0; |
| 906 | 824 | |
| 907 | 825 | // init/silence channels |
| 908 | 826 | for (i = 0; i < 24 ; i++) |
| 909 | 827 | { |
| 910 | | YMF278BSlot *slot = &chip->slots[i]; |
| 828 | YMF278BSlot *slot = &m_slots[i]; |
| 911 | 829 | |
| 912 | 830 | slot->LFO = 0; |
| 913 | 831 | slot->VIB = 0; |
| r22809 | r22810 | |
| 924 | 842 | slot->endaddr = 0; |
| 925 | 843 | |
| 926 | 844 | slot->env_step = 5; |
| 927 | | ymf278b_compute_envelope(slot); |
| 845 | compute_envelope(slot); |
| 928 | 846 | } |
| 929 | 847 | |
| 930 | | chip->timer_a->reset(); |
| 931 | | chip->timer_b->reset(); |
| 932 | | chip->timer_busy->reset(); chip->status_busy = 0; |
| 933 | | chip->timer_ld->reset(); chip->status_ld = 0; |
| 848 | m_timer_a->reset(); |
| 849 | m_timer_b->reset(); |
| 850 | m_timer_busy->reset(); m_status_busy = 0; |
| 851 | m_timer_ld->reset(); m_status_ld = 0; |
| 934 | 852 | |
| 935 | | chip->irq_line = CLEAR_LINE; |
| 853 | m_irq_line = CLEAR_LINE; |
| 936 | 854 | } |
| 937 | 855 | |
| 938 | | static void ymf278b_init(device_t *device, YMF278BChip *chip, const devcb_write_line *cb) |
| 856 | void ymf278b_device::precompute_rate_tables() |
| 939 | 857 | { |
| 940 | 858 | int i; |
| 941 | 859 | |
| 942 | | chip->rom = *device->region(); |
| 943 | | chip->romsize = device->region()->bytes(); |
| 944 | | chip->clock = device->clock(); |
| 945 | | chip->irq_callback.resolve(*cb, *device); |
| 946 | | |
| 947 | | chip->timer_base = attotime::from_hz(chip->clock) * (19*36); |
| 948 | | chip->timer_a = device->machine().scheduler().timer_alloc(FUNC(ymf278b_timer_a_tick), chip); |
| 949 | | chip->timer_b = device->machine().scheduler().timer_alloc(FUNC(ymf278b_timer_b_tick), chip); |
| 950 | | chip->timer_busy = device->machine().scheduler().timer_alloc(FUNC(ymf278b_timer_busy_clear), chip); |
| 951 | | chip->timer_ld = device->machine().scheduler().timer_alloc(FUNC(ymf278b_timer_ld_clear), chip); |
| 952 | | |
| 953 | | for (i = 0; i < 24; i++) |
| 954 | | { |
| 955 | | chip->slots[i].num = i; |
| 956 | | chip->slots[i].chip = chip; |
| 957 | | } |
| 958 | | } |
| 959 | | |
| 960 | | static void precompute_rate_tables(YMF278BChip *chip) |
| 961 | | { |
| 962 | | int i; |
| 963 | | |
| 964 | 860 | // decay rate |
| 965 | 861 | for (i = 0; i < 64; i++) |
| 966 | 862 | { |
| 967 | 863 | if (i <= 3) |
| 968 | | chip->lut_dr[i] = 0; |
| 864 | m_lut_dr[i] = 0; |
| 969 | 865 | else if (i >= 60) |
| 970 | | chip->lut_dr[i] = 15 << 4; |
| 866 | m_lut_dr[i] = 15 << 4; |
| 971 | 867 | else |
| 972 | | chip->lut_dr[i] = (15 << (21 - i / 4)) / (4 + i % 4); |
| 868 | m_lut_dr[i] = (15 << (21 - i / 4)) / (4 + i % 4); |
| 973 | 869 | } |
| 974 | 870 | |
| 975 | 871 | // attack rate (manual shows curve instead of linear though, so this is not entirely accurate) |
| 976 | 872 | for (i = 0; i < 64; i++) |
| 977 | 873 | { |
| 978 | 874 | if (i <= 3 || i == 63) |
| 979 | | chip->lut_ar[i] = 0; |
| 875 | m_lut_ar[i] = 0; |
| 980 | 876 | else if (i >= 60) |
| 981 | | chip->lut_ar[i] = 17; |
| 877 | m_lut_ar[i] = 17; |
| 982 | 878 | else |
| 983 | | chip->lut_ar[i] = (67 << (15 - i / 4)) / (4 + i % 4); |
| 879 | m_lut_ar[i] = (67 << (15 - i / 4)) / (4 + i % 4); |
| 984 | 880 | } |
| 985 | 881 | } |
| 986 | 882 | |
| 987 | | static void ymf278b_register_save_state(device_t *device, YMF278BChip *chip) |
| 883 | void ymf278b_device::register_save_state() |
| 988 | 884 | { |
| 989 | 885 | int i; |
| 990 | 886 | |
| 991 | | device->save_item(NAME(chip->pcmregs)); |
| 992 | | device->save_item(NAME(chip->wavetblhdr)); |
| 993 | | device->save_item(NAME(chip->memmode)); |
| 994 | | device->save_item(NAME(chip->memadr)); |
| 995 | | device->save_item(NAME(chip->status_busy)); |
| 996 | | device->save_item(NAME(chip->status_ld)); |
| 997 | | device->save_item(NAME(chip->exp)); |
| 998 | | device->save_item(NAME(chip->fm_l)); |
| 999 | | device->save_item(NAME(chip->fm_r)); |
| 1000 | | device->save_item(NAME(chip->pcm_l)); |
| 1001 | | device->save_item(NAME(chip->pcm_r)); |
| 1002 | | device->save_item(NAME(chip->timer_a_count)); |
| 1003 | | device->save_item(NAME(chip->timer_b_count)); |
| 1004 | | device->save_item(NAME(chip->enable)); |
| 1005 | | device->save_item(NAME(chip->current_irq)); |
| 1006 | | device->save_item(NAME(chip->irq_line)); |
| 1007 | | device->save_item(NAME(chip->port_AB)); |
| 1008 | | device->save_item(NAME(chip->port_C)); |
| 1009 | | device->save_item(NAME(chip->lastport)); |
| 887 | save_item(NAME(m_pcmregs)); |
| 888 | save_item(NAME(m_wavetblhdr)); |
| 889 | save_item(NAME(m_memmode)); |
| 890 | save_item(NAME(m_memadr)); |
| 891 | save_item(NAME(m_status_busy)); |
| 892 | save_item(NAME(m_status_ld)); |
| 893 | save_item(NAME(m_exp)); |
| 894 | save_item(NAME(m_fm_l)); |
| 895 | save_item(NAME(m_fm_r)); |
| 896 | save_item(NAME(m_pcm_l)); |
| 897 | save_item(NAME(m_pcm_r)); |
| 898 | save_item(NAME(m_timer_a_count)); |
| 899 | save_item(NAME(m_timer_b_count)); |
| 900 | save_item(NAME(m_enable)); |
| 901 | save_item(NAME(m_current_irq)); |
| 902 | save_item(NAME(m_irq_line)); |
| 903 | save_item(NAME(m_port_AB)); |
| 904 | save_item(NAME(m_port_C)); |
| 905 | save_item(NAME(m_lastport)); |
| 1010 | 906 | |
| 1011 | 907 | for (i = 0; i < 24; ++i) |
| 1012 | 908 | { |
| 1013 | | device->save_item(NAME(chip->slots[i].wave), i); |
| 1014 | | device->save_item(NAME(chip->slots[i].F_NUMBER), i); |
| 1015 | | device->save_item(NAME(chip->slots[i].octave), i); |
| 1016 | | device->save_item(NAME(chip->slots[i].preverb), i); |
| 1017 | | device->save_item(NAME(chip->slots[i].DAMP), i); |
| 1018 | | device->save_item(NAME(chip->slots[i].CH), i); |
| 1019 | | device->save_item(NAME(chip->slots[i].LD), i); |
| 1020 | | device->save_item(NAME(chip->slots[i].TL), i); |
| 1021 | | device->save_item(NAME(chip->slots[i].pan), i); |
| 1022 | | device->save_item(NAME(chip->slots[i].LFO), i); |
| 1023 | | device->save_item(NAME(chip->slots[i].VIB), i); |
| 1024 | | device->save_item(NAME(chip->slots[i].AM), i); |
| 909 | save_item(NAME(m_slots[i].wave), i); |
| 910 | save_item(NAME(m_slots[i].F_NUMBER), i); |
| 911 | save_item(NAME(m_slots[i].octave), i); |
| 912 | save_item(NAME(m_slots[i].preverb), i); |
| 913 | save_item(NAME(m_slots[i].DAMP), i); |
| 914 | save_item(NAME(m_slots[i].CH), i); |
| 915 | save_item(NAME(m_slots[i].LD), i); |
| 916 | save_item(NAME(m_slots[i].TL), i); |
| 917 | save_item(NAME(m_slots[i].pan), i); |
| 918 | save_item(NAME(m_slots[i].LFO), i); |
| 919 | save_item(NAME(m_slots[i].VIB), i); |
| 920 | save_item(NAME(m_slots[i].AM), i); |
| 1025 | 921 | |
| 1026 | | device->save_item(NAME(chip->slots[i].AR), i); |
| 1027 | | device->save_item(NAME(chip->slots[i].D1R), i); |
| 1028 | | device->save_item(NAME(chip->slots[i].DL), i); |
| 1029 | | device->save_item(NAME(chip->slots[i].D2R), i); |
| 1030 | | device->save_item(NAME(chip->slots[i].RC), i); |
| 1031 | | device->save_item(NAME(chip->slots[i].RR), i); |
| 922 | save_item(NAME(m_slots[i].AR), i); |
| 923 | save_item(NAME(m_slots[i].D1R), i); |
| 924 | save_item(NAME(m_slots[i].DL), i); |
| 925 | save_item(NAME(m_slots[i].D2R), i); |
| 926 | save_item(NAME(m_slots[i].RC), i); |
| 927 | save_item(NAME(m_slots[i].RR), i); |
| 1032 | 928 | |
| 1033 | | device->save_item(NAME(chip->slots[i].step), i); |
| 1034 | | device->save_item(NAME(chip->slots[i].stepptr), i); |
| 929 | save_item(NAME(m_slots[i].step), i); |
| 930 | save_item(NAME(m_slots[i].stepptr), i); |
| 1035 | 931 | |
| 1036 | | device->save_item(NAME(chip->slots[i].active), i); |
| 1037 | | device->save_item(NAME(chip->slots[i].KEY_ON), i); |
| 1038 | | device->save_item(NAME(chip->slots[i].bits), i); |
| 1039 | | device->save_item(NAME(chip->slots[i].startaddr), i); |
| 1040 | | device->save_item(NAME(chip->slots[i].loopaddr), i); |
| 1041 | | device->save_item(NAME(chip->slots[i].endaddr), i); |
| 932 | save_item(NAME(m_slots[i].active), i); |
| 933 | save_item(NAME(m_slots[i].KEY_ON), i); |
| 934 | save_item(NAME(m_slots[i].bits), i); |
| 935 | save_item(NAME(m_slots[i].startaddr), i); |
| 936 | save_item(NAME(m_slots[i].loopaddr), i); |
| 937 | save_item(NAME(m_slots[i].endaddr), i); |
| 1042 | 938 | |
| 1043 | | device->save_item(NAME(chip->slots[i].env_step), i); |
| 1044 | | device->save_item(NAME(chip->slots[i].env_vol), i); |
| 1045 | | device->save_item(NAME(chip->slots[i].env_vol_step), i); |
| 1046 | | device->save_item(NAME(chip->slots[i].env_vol_lim), i); |
| 1047 | | device->save_item(NAME(chip->slots[i].env_preverb), i); |
| 939 | save_item(NAME(m_slots[i].env_step), i); |
| 940 | save_item(NAME(m_slots[i].env_vol), i); |
| 941 | save_item(NAME(m_slots[i].env_vol_step), i); |
| 942 | save_item(NAME(m_slots[i].env_vol_lim), i); |
| 943 | save_item(NAME(m_slots[i].env_preverb), i); |
| 1048 | 944 | } |
| 1049 | 945 | } |
| 1050 | 946 | |
| 1051 | | static DEVICE_START( ymf278b ) |
| 947 | //------------------------------------------------- |
| 948 | // device_start - device-specific startup |
| 949 | //------------------------------------------------- |
| 950 | |
| 951 | void ymf278b_device::device_start() |
| 1052 | 952 | { |
| 1053 | | static const ymf278b_interface defintrf = { DEVCB_NULL }; |
| 1054 | | const ymf278b_interface *intf; |
| 1055 | 953 | int i; |
| 1056 | | YMF278BChip *chip = get_safe_token(device); |
| 1057 | 954 | |
| 1058 | | chip->device = device; |
| 1059 | | intf = (device->static_config() != NULL) ? (const ymf278b_interface *)device->static_config() : &defintrf; |
| 955 | m_rom = *region(); |
| 956 | m_romsize = region()->bytes(); |
| 957 | m_clock = clock(); |
| 958 | m_irq_handler.resolve(); |
| 1060 | 959 | |
| 1061 | | ymf278b_init(device, chip, &intf->irq_callback); |
| 1062 | | chip->stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock()/768, chip, ymf278b_pcm_update); |
| 960 | m_timer_base = attotime::from_hz(m_clock) * (19*36); |
| 961 | m_timer_a = timer_alloc(TIMER_A); |
| 962 | m_timer_b = timer_alloc(TIMER_B); |
| 963 | m_timer_busy = timer_alloc(TIMER_BUSY_CLEAR); |
| 964 | m_timer_ld = timer_alloc(TIMER_LD_CLEAR); |
| 1063 | 965 | |
| 966 | for (i = 0; i < 24; i++) |
| 967 | { |
| 968 | m_slots[i].num = i; |
| 969 | } |
| 970 | |
| 971 | m_stream = machine().sound().stream_alloc(*this, 0, 2, clock()/768); |
| 972 | |
| 1064 | 973 | // rate tables |
| 1065 | | precompute_rate_tables(chip); |
| 974 | precompute_rate_tables(); |
| 1066 | 975 | |
| 1067 | 976 | // Volume table, 1 = -0.375dB, 8 = -3dB, 256 = -96dB |
| 1068 | 977 | for(i = 0; i < 256; i++) |
| 1069 | | chip->volume[i] = 65536*pow(2.0, (-0.375/6)*i); |
| 978 | m_volume[i] = 65536*pow(2.0, (-0.375/6)*i); |
| 1070 | 979 | for(i = 256; i < 256*4; i++) |
| 1071 | | chip->volume[i] = 0; |
| 980 | m_volume[i] = 0; |
| 1072 | 981 | |
| 1073 | 982 | // Pan values, units are -3dB, i.e. 8. |
| 1074 | 983 | for(i = 0; i < 16; i++) |
| 1075 | 984 | { |
| 1076 | | chip->pan_left[i] = i < 7 ? i*8 : i < 9 ? 256 : 0; |
| 1077 | | chip->pan_right[i] = i < 8 ? 0 : i < 10 ? 256 : (16-i)*8; |
| 985 | m_pan_left[i] = i < 7 ? i*8 : i < 9 ? 256 : 0; |
| 986 | m_pan_right[i] = i < 8 ? 0 : i < 10 ? 256 : (16-i)*8; |
| 1078 | 987 | } |
| 1079 | 988 | |
| 1080 | 989 | // Mixing levels, units are -3dB, and add some margin to avoid clipping |
| 1081 | 990 | for(i=0; i<7; i++) |
| 1082 | | chip->mix_level[i] = chip->volume[8*i+13]; |
| 1083 | | chip->mix_level[7] = 0; |
| 991 | m_mix_level[i] = m_volume[8*i+13]; |
| 992 | m_mix_level[7] = 0; |
| 1084 | 993 | |
| 1085 | 994 | // Register state for saving |
| 1086 | | ymf278b_register_save_state(device, chip); |
| 995 | register_save_state(); |
| 1087 | 996 | } |
| 1088 | 997 | |
| 1089 | 998 | |
| r22809 | r22810 | |
| 1091 | 1000 | |
| 1092 | 1001 | ymf278b_device::ymf278b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 1093 | 1002 | : device_t(mconfig, YMF278B, "YMF278B", tag, owner, clock), |
| 1094 | | device_sound_interface(mconfig, *this) |
| 1003 | device_sound_interface(mconfig, *this), |
| 1004 | m_irq_handler(*this) |
| 1095 | 1005 | { |
| 1096 | | m_token = global_alloc_clear(YMF278BChip); |
| 1097 | 1006 | } |
| 1098 | 1007 | |
| 1099 | 1008 | //------------------------------------------------- |
| r22809 | r22810 | |
| 1105 | 1014 | void ymf278b_device::device_config_complete() |
| 1106 | 1015 | { |
| 1107 | 1016 | } |
| 1108 | | |
| 1109 | | //------------------------------------------------- |
| 1110 | | // device_start - device-specific startup |
| 1111 | | //------------------------------------------------- |
| 1112 | | |
| 1113 | | void ymf278b_device::device_start() |
| 1114 | | { |
| 1115 | | DEVICE_START_NAME( ymf278b )(this); |
| 1116 | | } |
| 1117 | | |
| 1118 | | //------------------------------------------------- |
| 1119 | | // device_reset - device-specific reset |
| 1120 | | //------------------------------------------------- |
| 1121 | | |
| 1122 | | void ymf278b_device::device_reset() |
| 1123 | | { |
| 1124 | | DEVICE_RESET_NAME( ymf278b )(this); |
| 1125 | | } |
| 1126 | | |
| 1127 | | //------------------------------------------------- |
| 1128 | | // sound_stream_update - handle a stream update |
| 1129 | | //------------------------------------------------- |
| 1130 | | |
| 1131 | | void ymf278b_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 1132 | | { |
| 1133 | | // should never get here |
| 1134 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 1135 | | } |