trunk/src/emu/sound/ymz280b.c
| r19045 | r19046 | |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | |
| 146 | | INLINE UINT8 ymz280b_read_memory(UINT8 *base, UINT32 size, UINT32 offset) |
| 146 | INLINE UINT8 ymz280b_read_memory(ymz280b_state *chip, UINT32 offset) |
| 147 | 147 | { |
| 148 | | if (offset < size) |
| 149 | | return base[offset]; |
| 148 | if (chip->ext_ram_read.isnull()) |
| 149 | { |
| 150 | if (offset < chip->region_size) |
| 151 | return chip->region_base[offset]; |
| 150 | 152 | |
| 151 | | /* 16MB chip limit (shouldn't happen) */ |
| 152 | | else if (offset > 0xffffff) |
| 153 | | return base[offset & 0xffffff]; |
| 153 | /* 16MB chip limit (shouldn't happen) */ |
| 154 | else if (offset > 0xffffff) |
| 155 | return chip->region_base[offset & 0xffffff]; |
| 154 | 156 | |
| 157 | else |
| 158 | return 0; |
| 159 | } |
| 155 | 160 | else |
| 156 | | return 0; |
| 161 | return chip->ext_ram_read(offset); |
| 157 | 162 | } |
| 158 | 163 | |
| 159 | 164 | |
| r19045 | r19046 | |
| 277 | 282 | |
| 278 | 283 | ***********************************************************************************************/ |
| 279 | 284 | |
| 280 | | static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, UINT32 size, INT16 *buffer, int samples) |
| 285 | static int generate_adpcm(ymz280b_state *chip, struct YMZ280BVoice *voice, INT16 *buffer, int samples) |
| 281 | 286 | { |
| 282 | 287 | int position = voice->position; |
| 283 | 288 | int signal = voice->signal; |
| r19045 | r19046 | |
| 291 | 296 | while (samples) |
| 292 | 297 | { |
| 293 | 298 | /* compute the new amplitude and update the current step */ |
| 294 | | val = ymz280b_read_memory(base, size, position / 2) >> ((~position & 1) << 2); |
| 299 | val = ymz280b_read_memory(chip, position / 2) >> ((~position & 1) << 2); |
| 295 | 300 | signal += (step * diff_lookup[val & 15]) / 8; |
| 296 | 301 | |
| 297 | 302 | /* clamp to the maximum */ |
| r19045 | r19046 | |
| 330 | 335 | while (samples) |
| 331 | 336 | { |
| 332 | 337 | /* compute the new amplitude and update the current step */ |
| 333 | | val = ymz280b_read_memory(base, size, position / 2) >> ((~position & 1) << 2); |
| 338 | val = ymz280b_read_memory(chip, position / 2) >> ((~position & 1) << 2); |
| 334 | 339 | signal += (step * diff_lookup[val & 15]) / 8; |
| 335 | 340 | |
| 336 | 341 | /* clamp to the maximum */ |
| r19045 | r19046 | |
| 393 | 398 | |
| 394 | 399 | ***********************************************************************************************/ |
| 395 | 400 | |
| 396 | | static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, UINT32 size, INT16 *buffer, int samples) |
| 401 | static int generate_pcm8(ymz280b_state *chip, struct YMZ280BVoice *voice, INT16 *buffer, int samples) |
| 397 | 402 | { |
| 398 | 403 | int position = voice->position; |
| 399 | 404 | int val; |
| r19045 | r19046 | |
| 405 | 410 | while (samples) |
| 406 | 411 | { |
| 407 | 412 | /* fetch the current value */ |
| 408 | | val = ymz280b_read_memory(base, size, position / 2); |
| 413 | val = ymz280b_read_memory(chip, position / 2); |
| 409 | 414 | |
| 410 | 415 | /* output to the buffer, scaling by the volume */ |
| 411 | 416 | *buffer++ = (INT8)val * 256; |
| r19045 | r19046 | |
| 430 | 435 | while (samples) |
| 431 | 436 | { |
| 432 | 437 | /* fetch the current value */ |
| 433 | | val = ymz280b_read_memory(base, size, position / 2); |
| 438 | val = ymz280b_read_memory(chip, position / 2); |
| 434 | 439 | |
| 435 | 440 | /* output to the buffer, scaling by the volume */ |
| 436 | 441 | *buffer++ = (INT8)val * 256; |
| r19045 | r19046 | |
| 467 | 472 | |
| 468 | 473 | ***********************************************************************************************/ |
| 469 | 474 | |
| 470 | | static int generate_pcm16(struct YMZ280BVoice *voice, UINT8 *base, UINT32 size, INT16 *buffer, int samples) |
| 475 | static int generate_pcm16(ymz280b_state *chip, struct YMZ280BVoice *voice, INT16 *buffer, int samples) |
| 471 | 476 | { |
| 472 | 477 | int position = voice->position; |
| 473 | 478 | int val; |
| r19045 | r19046 | |
| 479 | 484 | while (samples) |
| 480 | 485 | { |
| 481 | 486 | /* fetch the current value */ |
| 482 | | val = (INT16)((ymz280b_read_memory(base, size, position / 2 + 1) << 8) + ymz280b_read_memory(base, size, position / 2 + 0)); |
| 487 | val = (INT16)((ymz280b_read_memory(chip, position / 2 + 0) << 8) + ymz280b_read_memory(chip, position / 2 + 1)); |
| 483 | 488 | |
| 484 | 489 | /* output to the buffer, scaling by the volume */ |
| 485 | 490 | *buffer++ = val; |
| r19045 | r19046 | |
| 504 | 509 | while (samples) |
| 505 | 510 | { |
| 506 | 511 | /* fetch the current value */ |
| 507 | | val = (INT16)((ymz280b_read_memory(base, size, position / 2 + 1) << 8) + ymz280b_read_memory(base, size, position / 2 + 0)); |
| 512 | val = (INT16)((ymz280b_read_memory(chip, position / 2 + 0) << 8) + ymz280b_read_memory(chip, position / 2 + 1)); |
| 508 | 513 | |
| 509 | 514 | /* output to the buffer, scaling by the volume */ |
| 510 | 515 | *buffer++ = val; |
| r19045 | r19046 | |
| 603 | 608 | /* generate them into our buffer */ |
| 604 | 609 | switch (voice->playing << 7 | voice->mode) |
| 605 | 610 | { |
| 606 | | case 0x81: samples_left = generate_adpcm(voice, chip->region_base, chip->region_size, chip->scratch, new_samples); break; |
| 607 | | case 0x82: samples_left = generate_pcm8(voice, chip->region_base, chip->region_size, chip->scratch, new_samples); break; |
| 608 | | case 0x83: samples_left = generate_pcm16(voice, chip->region_base, chip->region_size, chip->scratch, new_samples); break; |
| 609 | | default: samples_left = 0; memset(chip->scratch, 0, new_samples * sizeof(chip->scratch[0])); break; |
| 611 | case 0x81: samples_left = generate_adpcm(chip, voice, chip->scratch, new_samples); break; |
| 612 | case 0x82: samples_left = generate_pcm8(chip, voice, chip->scratch, new_samples); break; |
| 613 | case 0x83: samples_left = generate_pcm16(chip, voice, chip->scratch, new_samples); break; |
| 614 | default: samples_left = 0; memset(chip->scratch, 0, new_samples * sizeof(chip->scratch[0])); break; |
| 610 | 615 | } |
| 611 | 616 | |
| 612 | 617 | /* if there are leftovers, ramp back to 0 */ |
| r19045 | r19046 | |
| 1012 | 1017 | return 0xff; |
| 1013 | 1018 | |
| 1014 | 1019 | /* read from external memory */ |
| 1015 | | UINT8 result; |
| 1016 | | if (!chip->ext_ram_read.isnull()) |
| 1017 | | result = chip->ext_ram_read(chip->rom_readback_addr); |
| 1018 | | else |
| 1019 | | result = ymz280b_read_memory(chip->region_base, chip->region_size, chip->rom_readback_addr); |
| 1020 | | |
| 1020 | UINT8 result = ymz280b_read_memory(chip, chip->rom_readback_addr); |
| 1021 | 1021 | chip->rom_readback_addr = (chip->rom_readback_addr + 1) & 0xffffff; |
| 1022 | 1022 | return result; |
| 1023 | 1023 | } |