trunk/src/mess/machine/isa_sblaster.c
r17648 | r17649 | |
62 | 62 | { |
63 | 63 | /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
64 | 64 | -1, -1, -1, -1, 1, 3, -1, -1, -1, -1, -1, -1, -1, -1, 2, 1, /* 0x */ |
65 | | 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, /* 1x */ |
66 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 2x */ |
| 65 | 2, -1, -1, -1, 3, -1, 3, 3, -1, -1, -1, -1, 1, -1, -1, 1, /* 1x */ |
| 66 | -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 2x */ |
67 | 67 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 3x */ |
68 | 68 | 2, 3, 3, -1, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, /* 4x */ |
69 | 69 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 5x */ |
70 | 70 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 6x */ |
71 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 7x */ |
| 71 | -1, -1, -1, -1, 3, 3, 3, 3, -1, -1, -1, -1, -1, 1, -1, 1, /* 7x */ |
72 | 72 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 8x */ |
73 | 73 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 9x */ |
74 | 74 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* Ax */ |
r17648 | r17649 | |
350 | 350 | m_dsp.flags = 0; |
351 | 351 | break; |
352 | 352 | |
353 | | case 0x1c: // 8-bit DMA with autoinit |
354 | | // printf("Start DMA (autoinit, size = %x)\n", m_dsp.dma_length); |
355 | | m_dsp.dma_transferred = 0; |
356 | | m_dsp.dma_autoinit = 1; |
357 | | m_dsp.dma_timer_started = false; |
358 | | m_dsp.dma_throttled = false; |
359 | | drq_w(1); |
| 353 | case 0x17: // 2-bit ADPCM w/new reference |
| 354 | m_dsp.adpcm_new_ref = true; |
| 355 | m_dsp.adpcm_step = 0; |
| 356 | case 0x16: // 2-bit ADPCM |
| 357 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 358 | m_dsp.dma_transferred = 0; |
| 359 | m_dsp.dma_autoinit = 0; |
| 360 | m_dsp.dma_timer_started = false; |
| 361 | m_dsp.dma_throttled = false; |
| 362 | drq_w(1); |
| 363 | m_dsp.flags = ADPCM2; |
| 364 | break; |
| 365 | |
| 366 | case 0x1c: // 8-bit DMA with autoinit |
| 367 | // printf("Start DMA (autoinit, size = %x)\n", m_dsp.dma_length); |
| 368 | m_dsp.dma_transferred = 0; |
| 369 | m_dsp.dma_autoinit = 1; |
| 370 | m_dsp.dma_timer_started = false; |
| 371 | m_dsp.dma_throttled = false; |
| 372 | drq_w(1); |
360 | 373 | m_dsp.flags = 0; |
361 | | break; |
| 374 | break; |
362 | 375 | |
363 | | case 0x40: // set time constant |
364 | | m_dsp.frequency = (1000000 / (256 - m_dsp.fifo[1])); |
365 | | printf("Set time constant: %02x -> %d\n", m_dsp.fifo[1], m_dsp.frequency); |
366 | | break; |
| 376 | case 0x24: // 8-bit ADC DMA |
| 377 | m_dsp.adc_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 378 | // printf("Start DMA (not autoinit, size = %x)\n", m_dsp.adc_length); |
| 379 | m_dsp.adc_transferred = 0; |
| 380 | m_dsp.dma_autoinit = 0; |
| 381 | drq_w(1); |
| 382 | logerror("SB: ADC capture unimplemented\n"); |
| 383 | break; |
367 | 384 | |
| 385 | case 0x40: // set time constant |
| 386 | m_dsp.frequency = (1000000 / (256 - m_dsp.fifo[1])); |
| 387 | //printf("Set time constant: %02x -> %d\n", m_dsp.fifo[1], m_dsp.frequency); |
| 388 | break; |
| 389 | |
368 | 390 | case 0x48: // set DMA block size (for auto-init) |
369 | | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 391 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
370 | 392 | break; |
371 | 393 | |
| 394 | case 0x75: // 4-bit ADPCM w/new reference |
| 395 | m_dsp.adpcm_new_ref = true; |
| 396 | m_dsp.adpcm_step = 0; |
| 397 | case 0x74: // 4-bit ADPCM |
| 398 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 399 | m_dsp.dma_transferred = 0; |
| 400 | m_dsp.dma_autoinit = 0; |
| 401 | m_dsp.dma_timer_started = false; |
| 402 | m_dsp.dma_throttled = false; |
| 403 | drq_w(1); |
| 404 | m_dsp.flags = ADPCM4; |
| 405 | break; |
| 406 | |
| 407 | case 0x77: // 2.6-bit ADPCM w/new reference |
| 408 | m_dsp.adpcm_new_ref = true; |
| 409 | m_dsp.adpcm_step = 0; |
| 410 | case 0x76: // 2.6-bit ADPCM |
| 411 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 412 | m_dsp.dma_transferred = 0; |
| 413 | m_dsp.dma_autoinit = 0; |
| 414 | m_dsp.dma_timer_started = false; |
| 415 | m_dsp.dma_throttled = false; |
| 416 | drq_w(1); |
| 417 | m_dsp.flags = ADPCM3; |
| 418 | break; |
| 419 | |
372 | 420 | case 0xd0: // halt 8-bit DMA |
373 | 421 | m_timer->adjust(attotime::never, 0); |
374 | 422 | drq_w(0); // drop DRQ |
r17648 | r17649 | |
436 | 484 | { |
437 | 485 | switch(cmd) |
438 | 486 | { |
| 487 | case 0x1f: // 2-bit autoinit ADPCM w/new reference |
| 488 | m_dsp.adpcm_new_ref = true; |
| 489 | m_dsp.adpcm_step = 0; |
| 490 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 491 | m_dsp.dma_transferred = 0; |
| 492 | m_dsp.dma_autoinit = 1; |
| 493 | m_dsp.dma_timer_started = false; |
| 494 | m_dsp.dma_throttled = false; |
| 495 | drq_w(1); |
| 496 | m_dsp.flags = ADPCM2; |
| 497 | break; |
| 498 | case 0x7d: // 4-bit autoinit ADPCM w/new reference |
| 499 | m_dsp.adpcm_new_ref = true; |
| 500 | m_dsp.adpcm_step = 0; |
| 501 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 502 | m_dsp.dma_transferred = 0; |
| 503 | m_dsp.dma_autoinit = 1; |
| 504 | m_dsp.dma_timer_started = false; |
| 505 | m_dsp.dma_throttled = false; |
| 506 | drq_w(1); |
| 507 | m_dsp.flags = ADPCM4; |
| 508 | break; |
| 509 | case 0x7f: // 2.6-bit autoinit ADPCM w/new reference |
| 510 | m_dsp.adpcm_new_ref = true; |
| 511 | m_dsp.adpcm_step = 0; |
| 512 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 513 | m_dsp.dma_transferred = 0; |
| 514 | m_dsp.dma_autoinit = 1; |
| 515 | m_dsp.dma_timer_started = false; |
| 516 | m_dsp.dma_throttled = false; |
| 517 | drq_w(1); |
| 518 | m_dsp.flags = ADPCM3; |
| 519 | break; |
439 | 520 | case 0xda: // stop 8-bit autoinit |
440 | 521 | m_dsp.dma_autoinit = 0; |
441 | 522 | break; |
r17648 | r17649 | |
557 | 638 | process_fifo(m_dsp.fifo[0]); |
558 | 639 | } |
559 | 640 | |
| 641 | void sb_device::adpcm_decode(UINT8 sample, int size) |
| 642 | { |
| 643 | int sign = (sample & (1 << (size - 1))) ? -1: 1; |
| 644 | int shift = (size == 2) ? 2 : 0; |
| 645 | INT16 dec_sample = m_dsp.adpcm_ref + sign * (sample << (m_dsp.adpcm_step + shift)); |
560 | 646 | |
| 647 | if(dec_sample > 255) |
| 648 | dec_sample = 255; |
| 649 | else if(dec_sample < 0) |
| 650 | dec_sample = 0; |
| 651 | m_dsp.adpcm_ref = dec_sample; |
| 652 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 653 | m_dacr->write_unsigned8(m_dsp.adpcm_ref); |
| 654 | sample &= (1 << (size - 1)) - 1; |
| 655 | if(sample >= ((size << 1) - 3)) |
| 656 | { |
| 657 | if(m_dsp.adpcm_step < 3) |
| 658 | m_dsp.adpcm_step++; |
| 659 | } |
| 660 | else if(!sample && m_dsp.adpcm_step) |
| 661 | m_dsp.adpcm_step--; |
| 662 | } |
| 663 | |
561 | 664 | READ8_MEMBER ( sb_device::joy_port_r ) |
562 | 665 | { |
563 | 666 | UINT8 data = 0; |
r17648 | r17649 | |
1018 | 1121 | m_dacl->write_unsigned16(lsample + 32768); |
1019 | 1122 | m_dacr->write_unsigned16(rsample + 32768); |
1020 | 1123 | break; |
1021 | | default: // ADPCM, ...? |
1022 | | logerror("SB: unimplemented sample type %x", m_dsp.flags); |
| 1124 | case ADPCM2: |
| 1125 | if(m_dsp.adpcm_new_ref) |
| 1126 | { |
| 1127 | m_dsp.adpcm_ref = m_dsp.data[m_dsp.d_rptr++]; |
| 1128 | m_dsp.adpcm_new_ref = false; |
| 1129 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1130 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1131 | break; |
| 1132 | } |
| 1133 | lsample = m_dsp.data[m_dsp.d_rptr++]; |
| 1134 | adpcm_decode(lsample >> 6, 2); |
| 1135 | adpcm_decode((lsample >> 4) & 3, 2); |
| 1136 | adpcm_decode((lsample >> 2) & 3, 2); |
| 1137 | adpcm_decode(lsample & 3, 2); |
| 1138 | break; |
| 1139 | case ADPCM3: |
| 1140 | if(m_dsp.adpcm_new_ref) |
| 1141 | { |
| 1142 | m_dsp.adpcm_ref = m_dsp.data[m_dsp.d_rptr++]; |
| 1143 | m_dsp.adpcm_new_ref = false; |
| 1144 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1145 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1146 | break; |
| 1147 | } |
| 1148 | lsample = m_dsp.data[m_dsp.d_rptr++]; |
| 1149 | adpcm_decode(lsample >> 5, 3); |
| 1150 | adpcm_decode((lsample >> 2) & 7, 3); |
| 1151 | adpcm_decode(lsample & 3, 2); |
| 1152 | break; |
| 1153 | case ADPCM4: |
| 1154 | if(m_dsp.adpcm_new_ref) |
| 1155 | { |
| 1156 | m_dsp.adpcm_ref = m_dsp.data[m_dsp.d_rptr++]; |
| 1157 | m_dsp.adpcm_new_ref = false; |
| 1158 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1159 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1160 | break; |
| 1161 | } |
| 1162 | lsample = m_dsp.data[m_dsp.d_rptr++]; |
| 1163 | adpcm_decode(lsample >> 4, 4); |
| 1164 | adpcm_decode(lsample & 15, 4); |
| 1165 | break; |
| 1166 | default: |
| 1167 | logerror("SB: unimplemented sample type %x\n", m_dsp.flags); |
1023 | 1168 | } |
1024 | 1169 | m_dsp.d_rptr %= 128; |
1025 | 1170 | |