trunk/src/mess/machine/isa_sblaster.c
| r17772 | r17773 | |
| 38 | 38 | #define ym3812_StdClock XTAL_3_579545MHz |
| 39 | 39 | #define ymf262_StdClock XTAL_14_31818MHz |
| 40 | 40 | |
| 41 | | static INPUT_PORTS_START( sblaster ) |
| 42 | | PORT_START("pc_joy") |
| 43 | | PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) // x/y ad stick to digital converters |
| 44 | | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("SB: Joystick Button 1") |
| 45 | | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("SB: Joystick Button 2") |
| 46 | | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("SB: Joystick Button 3") |
| 47 | | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("SB: Joystick Button 4") |
| 48 | | |
| 49 | | PORT_START("pc_joy_1") |
| 50 | | PORT_BIT(0xff,0x80,IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(KEYCODE_LEFT) PORT_CODE_INC(KEYCODE_RIGHT) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) |
| 51 | | |
| 52 | | PORT_START("pc_joy_2") |
| 53 | | PORT_BIT(0xff,0x80,IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(KEYCODE_UP) PORT_CODE_INC(KEYCODE_DOWN) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) |
| 54 | | INPUT_PORTS_END |
| 55 | | |
| 56 | | ioport_constructor sb_device::device_input_ports() const |
| 57 | | { |
| 58 | | return INPUT_PORTS_NAME( sblaster ); |
| 59 | | } |
| 60 | | |
| 61 | 41 | static const int m_cmd_fifo_length[256] = |
| 62 | 42 | { |
| 63 | 43 | /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
| r17772 | r17773 | |
| 79 | 59 | -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1 /* Fx */ |
| 80 | 60 | }; |
| 81 | 61 | |
| 82 | | static const int protection_magic[4][9] = |
| 83 | | { |
| 84 | | { 1, -2, -4, 8, -16, 32, 64, -128, -106 }, |
| 85 | | { -1, 2, -4, 8, 16, -32, 64, -128, 165 }, |
| 86 | | { -1, 2, 4, -8, 16, -32, -64, 128, -151 }, |
| 87 | | { 1, -2, 4, -8, -16, 32, -64, 128, 90 } |
| 88 | | }; |
| 62 | static const int protection_magic[4] = { 0x96, 0xa5, 0x69, 0x5a }; |
| 89 | 63 | |
| 90 | 64 | static const ym3812_interface pc_ym3812_interface = |
| 91 | 65 | { |
| r17772 | r17773 | |
| 114 | 88 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.00) |
| 115 | 89 | MCFG_SOUND_ADD("sbdacr", DAC, 0) |
| 116 | 90 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.00) |
| 91 | |
| 92 | MCFG_PC_JOY_ADD("joy") |
| 117 | 93 | MACHINE_CONFIG_END |
| 118 | 94 | |
| 119 | 95 | static MACHINE_CONFIG_FRAGMENT( sblaster1_5_config ) |
| r17772 | r17773 | |
| 128 | 104 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.00) |
| 129 | 105 | MCFG_SOUND_ADD("sbdacr", DAC, 0) |
| 130 | 106 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.00) |
| 107 | |
| 108 | MCFG_PC_JOY_ADD("joy") |
| 131 | 109 | MACHINE_CONFIG_END |
| 132 | 110 | |
| 133 | 111 | static MACHINE_CONFIG_FRAGMENT( sblaster_16_config ) |
| r17772 | r17773 | |
| 142 | 120 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.00) |
| 143 | 121 | MCFG_SOUND_ADD("sbdacr", DAC, 0) |
| 144 | 122 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.00) |
| 123 | |
| 124 | MCFG_PC_JOY_ADD("joy") |
| 145 | 125 | MACHINE_CONFIG_END |
| 146 | 126 | |
| 147 | 127 | static READ8_DEVICE_HANDLER( ym3812_16_r ) |
| r17772 | r17773 | |
| 354 | 334 | m_dsp.adpcm_new_ref = true; |
| 355 | 335 | m_dsp.adpcm_step = 0; |
| 356 | 336 | case 0x16: // 2-bit ADPCM |
| 337 | m_dsp.adpcm_count = 0; |
| 357 | 338 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 358 | 339 | m_dsp.dma_transferred = 0; |
| 359 | 340 | m_dsp.dma_autoinit = 0; |
| r17772 | r17773 | |
| 395 | 376 | m_dsp.adpcm_new_ref = true; |
| 396 | 377 | m_dsp.adpcm_step = 0; |
| 397 | 378 | case 0x74: // 4-bit ADPCM |
| 379 | m_dsp.adpcm_count = 0; |
| 398 | 380 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 399 | 381 | m_dsp.dma_transferred = 0; |
| 400 | 382 | m_dsp.dma_autoinit = 0; |
| r17772 | r17773 | |
| 408 | 390 | m_dsp.adpcm_new_ref = true; |
| 409 | 391 | m_dsp.adpcm_step = 0; |
| 410 | 392 | case 0x76: // 2.6-bit ADPCM |
| 393 | m_dsp.adpcm_count = 0; |
| 411 | 394 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 412 | 395 | m_dsp.dma_transferred = 0; |
| 413 | 396 | m_dsp.dma_autoinit = 0; |
| r17772 | r17773 | |
| 448 | 431 | break; |
| 449 | 432 | |
| 450 | 433 | case 0xe2: // DSP protection |
| 451 | | for (int i = 0; i < 8; i++) |
| 452 | | { |
| 453 | | if ((m_dsp.fifo[1] >> i) & 0x01) |
| 454 | | { |
| 455 | | m_dsp.prot_value += protection_magic[m_dsp.prot_count % 4][i]; |
| 456 | | } |
| 457 | | } |
| 458 | | |
| 459 | | m_dsp.prot_value += protection_magic[m_dsp.prot_count % 4][8]; |
| 460 | | m_dsp.prot_count++; |
| 461 | | |
| 434 | m_dsp.prot_value += protection_magic[m_dsp.prot_count++] ^ m_dsp.fifo[1]; |
| 435 | m_dsp.prot_count &= 3; |
| 436 | m_dsp.adc_transferred = 0; |
| 437 | m_dsp.adc_length = 1; |
| 462 | 438 | m_dack_out = (UINT8)(m_dsp.prot_value & 0xff); |
| 463 | 439 | drq_w(1); |
| 464 | 440 | break; |
| r17772 | r17773 | |
| 487 | 463 | case 0x1f: // 2-bit autoinit ADPCM w/new reference |
| 488 | 464 | m_dsp.adpcm_new_ref = true; |
| 489 | 465 | m_dsp.adpcm_step = 0; |
| 466 | m_dsp.adpcm_count = 0; |
| 490 | 467 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 491 | 468 | m_dsp.dma_transferred = 0; |
| 492 | 469 | m_dsp.dma_autoinit = 1; |
| r17772 | r17773 | |
| 498 | 475 | case 0x7d: // 4-bit autoinit ADPCM w/new reference |
| 499 | 476 | m_dsp.adpcm_new_ref = true; |
| 500 | 477 | m_dsp.adpcm_step = 0; |
| 478 | m_dsp.adpcm_count = 0; |
| 501 | 479 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 502 | 480 | m_dsp.dma_transferred = 0; |
| 503 | 481 | m_dsp.dma_autoinit = 1; |
| r17772 | r17773 | |
| 509 | 487 | case 0x7f: // 2.6-bit autoinit ADPCM w/new reference |
| 510 | 488 | m_dsp.adpcm_new_ref = true; |
| 511 | 489 | m_dsp.adpcm_step = 0; |
| 490 | m_dsp.adpcm_count = 0; |
| 512 | 491 | m_dsp.dma_length = (m_dsp.fifo[1] + (m_dsp.fifo[2]<<8)) + 1; |
| 513 | 492 | m_dsp.dma_transferred = 0; |
| 514 | 493 | m_dsp.dma_autoinit = 1; |
| r17772 | r17773 | |
| 640 | 619 | |
| 641 | 620 | void sb_device::adpcm_decode(UINT8 sample, int size) |
| 642 | 621 | { |
| 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)); |
| 622 | const UINT8 adpcm_2_table[] = {0, 1, 1, 3, 2, 6, 4, 12, 8, 24, 16, 48}; |
| 623 | const UINT8 step_2_table[] = {0, 2, 0, 4, 2, 6, 4, 8, 6, 10, 8, 10}; |
| 646 | 624 | |
| 625 | const UINT8 adpcm_3_table[] = {0, 1, 2, 3, 1, 3, 5, 7, |
| 626 | 2, 6, 10, 14, 4, 12, 20, 28, |
| 627 | 8, 24, 40, 56}; |
| 628 | const UINT8 step_3_table[] = {0, 0, 0, 4, 0, 4, 4, 8, |
| 629 | 4, 8, 8, 12, 8, 12, 12, 16, |
| 630 | 12, 16, 16, 16}; |
| 631 | |
| 632 | const UINT8 adpcm_4_table[] = {0, 1, 2, 3, 4, 5, 6, 7, |
| 633 | 1, 3, 5, 7, 9, 11, 13, 15, |
| 634 | 2, 6, 10, 14, 18, 22, 26, 30, |
| 635 | 4, 12, 20, 28, 36, 44, 52, 60}; |
| 636 | const UINT8 step_4_table[] = {0, 0, 0, 0, 0, 8, 8, 8, |
| 637 | 0, 8, 8, 8, 8, 16, 16, 16, |
| 638 | 8, 16, 16, 16, 16, 24, 24, 24, |
| 639 | 16, 24, 24, 24, 24, 24, 24, 24}; |
| 640 | |
| 641 | INT16 dec_sample = m_dsp.adpcm_ref; |
| 642 | UINT8 index; |
| 643 | switch(size) |
| 644 | { |
| 645 | case 2: |
| 646 | index = (sample & 1) | m_dsp.adpcm_step; |
| 647 | dec_sample += ((sample & 2)?-1:1) * adpcm_2_table[index]; |
| 648 | m_dsp.adpcm_step = step_2_table[index]; |
| 649 | break; |
| 650 | case 3: |
| 651 | index = (sample & 3) | m_dsp.adpcm_step; |
| 652 | dec_sample += ((sample & 4)?-1:1) * adpcm_3_table[index]; |
| 653 | m_dsp.adpcm_step = step_3_table[index]; |
| 654 | break; |
| 655 | case 4: |
| 656 | index = (sample & 7) | m_dsp.adpcm_step; |
| 657 | dec_sample += ((sample & 8)?-1:1) * adpcm_4_table[index]; |
| 658 | m_dsp.adpcm_step = step_4_table[index]; |
| 659 | break; |
| 660 | } |
| 661 | |
| 647 | 662 | if(dec_sample > 255) |
| 648 | 663 | dec_sample = 255; |
| 649 | 664 | else if(dec_sample < 0) |
| r17772 | r17773 | |
| 651 | 666 | m_dsp.adpcm_ref = dec_sample; |
| 652 | 667 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 653 | 668 | 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 | 669 | } |
| 663 | 670 | |
| 664 | | READ8_MEMBER ( sb_device::joy_port_r ) |
| 665 | | { |
| 666 | | UINT8 data = 0; |
| 667 | | int delta; |
| 668 | | attotime new_time = machine().time(); |
| 669 | | |
| 670 | | { |
| 671 | | data = ioport("pc_joy")->read() | 0x0f; |
| 672 | | |
| 673 | | { |
| 674 | | delta = ((new_time - m_joy_time) * 256 * 1000).seconds; |
| 675 | | |
| 676 | | if (ioport("pc_joy_1")->read() < delta) data &= ~0x01; |
| 677 | | if (ioport("pc_joy_2")->read() < delta) data &= ~0x02; |
| 678 | | } |
| 679 | | } |
| 680 | | |
| 681 | | return data; |
| 682 | | } |
| 683 | | |
| 684 | | WRITE8_MEMBER ( sb_device::joy_port_w ) |
| 685 | | { |
| 686 | | m_joy_time = machine().time(); |
| 687 | | } |
| 688 | | |
| 689 | 671 | READ8_MEMBER( sb16_device::mpu401_r ) |
| 690 | 672 | { |
| 691 | 673 | UINT8 res; |
| r17772 | r17773 | |
| 804 | 786 | sb_device::sb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, const char *name) : |
| 805 | 787 | device_t(mconfig, type, name, tag, owner, clock), |
| 806 | 788 | m_dacl(*this, "sbdacl"), |
| 807 | | m_dacr(*this, "sbdacr") |
| 789 | m_dacr(*this, "sbdacr"), |
| 790 | m_joy(*this, "joy") |
| 808 | 791 | { |
| 809 | 792 | } |
| 810 | 793 | |
| r17772 | r17773 | |
| 845 | 828 | |
| 846 | 829 | void sb8_device::device_start() |
| 847 | 830 | { |
| 848 | | m_isa->install_device( 0x0200, 0x0207, 0, 0, read8_delegate(FUNC(sb_device::joy_port_r), this), write8_delegate(FUNC(sb_device::joy_port_w), this)); |
| 831 | m_isa->install_device( 0x0200, 0x0207, 0, 0, read8_delegate(FUNC(pc_joy_device::joy_port_r), subdevice<pc_joy_device>("joy")), write8_delegate(FUNC(pc_joy_device::joy_port_w), subdevice<pc_joy_device>("joy"))); |
| 849 | 832 | m_isa->install_device( 0x0226, 0x0227, 0, 0, read8_delegate(FUNC(sb_device::dsp_reset_r), this), write8_delegate(FUNC(sb_device::dsp_reset_w), this)); |
| 850 | 833 | m_isa->install_device( 0x022a, 0x022b, 0, 0, read8_delegate(FUNC(sb_device::dsp_data_r), this), write8_delegate(FUNC(sb_device::dsp_data_w), this) ); |
| 851 | 834 | m_isa->install_device( 0x022c, 0x022d, 0, 0, read8_delegate(FUNC(sb_device::dsp_wbuf_status_r), this), write8_delegate(FUNC(sb_device::dsp_cmd_w), this) ); |
| r17772 | r17773 | |
| 888 | 871 | |
| 889 | 872 | void sb16_device::device_start() |
| 890 | 873 | { |
| 891 | | m_isa->install_device( 0x0200, 0x0207, 0, 0, read8_delegate(FUNC(sb_device::joy_port_r), this), write8_delegate(FUNC(sb_device::joy_port_w), this)); |
| 874 | m_isa->install_device( 0x0200, 0x0207, 0, 0, read8_delegate(FUNC(pc_joy_device::joy_port_r), subdevice<pc_joy_device>("joy")), write8_delegate(FUNC(pc_joy_device::joy_port_w), subdevice<pc_joy_device>("joy"))); |
| 892 | 875 | m_isa->install_device( 0x0224, 0x0225, 0, 0, read8_delegate(FUNC(sb_device::mixer_r), this), write8_delegate(FUNC(sb_device::mixer_w), this)); |
| 893 | 876 | m_isa->install_device( 0x0226, 0x0227, 0, 0, read8_delegate(FUNC(sb_device::dsp_reset_r), this), write8_delegate(FUNC(sb_device::dsp_reset_w), this)); |
| 894 | 877 | m_isa->install_device( 0x022a, 0x022b, 0, 0, read8_delegate(FUNC(sb_device::dsp_data_r), this), write8_delegate(FUNC(sb_device::dsp_data_w), this) ); |
| r17772 | r17773 | |
| 926 | 909 | m_dsp.fifo_r_ptr = 0; |
| 927 | 910 | m_dsp.wbuf_status = 0; |
| 928 | 911 | m_dsp.rbuf_status = 0; |
| 929 | | m_dsp.frequency = 22050; //? |
| 912 | m_dsp.frequency = 8000; // per stereo-fx |
| 930 | 913 | m_dsp.irq_active = 0; |
| 931 | 914 | m_mixer_index = 0; |
| 932 | 915 | } |
| r17772 | r17773 | |
| 1130 | 1113 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1131 | 1114 | break; |
| 1132 | 1115 | } |
| 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); |
| 1116 | lsample = m_dsp.data[m_dsp.d_rptr]; |
| 1117 | switch(m_dsp.adpcm_count++) |
| 1118 | { |
| 1119 | case 0: |
| 1120 | adpcm_decode(lsample >> 6, 2); |
| 1121 | break; |
| 1122 | case 1: |
| 1123 | adpcm_decode((lsample >> 4) & 3, 2); |
| 1124 | break; |
| 1125 | case 2: |
| 1126 | adpcm_decode((lsample >> 2) & 3, 2); |
| 1127 | break; |
| 1128 | case 3: |
| 1129 | adpcm_decode(lsample & 3, 2); |
| 1130 | m_dsp.data[m_dsp.d_rptr++] = 0x80; |
| 1131 | m_dsp.adpcm_count = 0; |
| 1132 | break; |
| 1133 | } |
| 1138 | 1134 | break; |
| 1139 | 1135 | case ADPCM3: |
| 1140 | 1136 | if(m_dsp.adpcm_new_ref) |
| r17772 | r17773 | |
| 1145 | 1141 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1146 | 1142 | break; |
| 1147 | 1143 | } |
| 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); |
| 1144 | lsample = m_dsp.data[m_dsp.d_rptr]; |
| 1145 | switch(m_dsp.adpcm_count++) |
| 1146 | { |
| 1147 | case 0: |
| 1148 | adpcm_decode(lsample >> 5, 3); |
| 1149 | break; |
| 1150 | case 1: |
| 1151 | adpcm_decode((lsample >> 2) & 7, 3); |
| 1152 | break; |
| 1153 | case 2: |
| 1154 | adpcm_decode(((lsample & 2) << 1) | (lsample & 1), 3); |
| 1155 | m_dsp.data[m_dsp.d_rptr++] = 0x80; |
| 1156 | m_dsp.adpcm_count = 0; |
| 1157 | break; |
| 1158 | } |
| 1152 | 1159 | break; |
| 1153 | 1160 | case ADPCM4: |
| 1154 | 1161 | if(m_dsp.adpcm_new_ref) |
| r17772 | r17773 | |
| 1159 | 1166 | m_dacl->write_unsigned8(m_dsp.adpcm_ref); |
| 1160 | 1167 | break; |
| 1161 | 1168 | } |
| 1162 | | lsample = m_dsp.data[m_dsp.d_rptr++]; |
| 1163 | | adpcm_decode(lsample >> 4, 4); |
| 1164 | | adpcm_decode(lsample & 15, 4); |
| 1169 | lsample = m_dsp.data[m_dsp.d_rptr]; |
| 1170 | switch(m_dsp.adpcm_count++) |
| 1171 | { |
| 1172 | case 0: |
| 1173 | adpcm_decode(lsample >> 4, 4); |
| 1174 | break; |
| 1175 | case 1: |
| 1176 | adpcm_decode(lsample & 15, 4); |
| 1177 | m_dsp.data[m_dsp.d_rptr++] = 0x80; |
| 1178 | m_dsp.adpcm_count = 0; |
| 1179 | break; |
| 1180 | } |
| 1165 | 1181 | break; |
| 1166 | 1182 | default: |
| 1167 | 1183 | logerror("SB: unimplemented sample type %x\n", m_dsp.flags); |