trunk/src/emu/sound/tms5110.c
| r242479 | r242480 | |
| 8 | 8 | Various fixes by Lord Nightmare |
| 9 | 9 | Additional enhancements by Couriersud |
| 10 | 10 | Sub-interpolation-cycle parameter updating added by Lord Nightmare |
| 11 | Read-bit and Output fixes by Lord Nightmare |
| 11 | 12 | |
| 12 | 13 | Todo: |
| 13 | 14 | - implement CS |
| r242479 | r242480 | |
| 148 | 149 | new_int_write(0, 0, 0, 0); // romclk 0, m0 0, m1 0, addr bus nybble = 0/open bus |
| 149 | 150 | if (!m_data_cb.isnull()) |
| 150 | 151 | return m_data_cb(); |
| 152 | if (DEBUG_5110) logerror("WARNING: CALLBACK MISSING, RETURNING 0!\n"); |
| 151 | 153 | return 0; |
| 152 | 154 | } |
| 153 | 155 | |
| r242479 | r242480 | |
| 230 | 232 | int tms5110_device::extract_bits(int count) |
| 231 | 233 | { |
| 232 | 234 | int val = 0; |
| 233 | | |
| 235 | if (DEBUG_5110) logerror("requesting %d bits from fifo: ", count); |
| 234 | 236 | while (count--) |
| 235 | 237 | { |
| 236 | 238 | val = (val << 1) | (m_fifo[m_fifo_head] & 1); |
| 237 | 239 | m_fifo_count--; |
| 238 | 240 | m_fifo_head = (m_fifo_head + 1) % FIFO_SIZE; |
| 239 | 241 | } |
| 242 | if (DEBUG_5110) logerror("returning: %02x\n", val); |
| 240 | 243 | return val; |
| 241 | 244 | } |
| 242 | 245 | |
| r242479 | r242480 | |
| 245 | 248 | for (int i = 0; i < no; i++) |
| 246 | 249 | { |
| 247 | 250 | UINT8 data = new_int_read(); |
| 251 | if (DEBUG_5110) logerror("bit added to fifo: %d\n", data); |
| 248 | 252 | FIFO_data_write(data); |
| 249 | 253 | } |
| 250 | 254 | } |
| r242479 | r242480 | |
| 591 | 595 | m_PDC = data & 0x1; |
| 592 | 596 | if (m_PDC == 0) /* toggling 1->0 processes command on CTL_pins */ |
| 593 | 597 | { |
| 598 | if (DEBUG_5110) logerror("PDC falling edge: "); |
| 594 | 599 | /* first pdc toggles output, next toggles input */ |
| 595 | 600 | switch (m_state) |
| 596 | 601 | { |
| r242479 | r242480 | |
| 598 | 603 | /* continue */ |
| 599 | 604 | break; |
| 600 | 605 | case CTL_STATE_NEXT_TTALK_OUTPUT: |
| 606 | if (DEBUG_5110) logerror("Switching CTL bus direction to output for Test Talk\n"); |
| 601 | 607 | m_state = CTL_STATE_TTALK_OUTPUT; |
| 602 | 608 | return; |
| 603 | 609 | case CTL_STATE_TTALK_OUTPUT: |
| 610 | if (DEBUG_5110) logerror("Switching CTL bus direction back to input from Test Talk\n"); |
| 604 | 611 | m_state = CTL_STATE_INPUT; |
| 605 | 612 | return; |
| 606 | 613 | case CTL_STATE_NEXT_OUTPUT: |
| 614 | if (DEBUG_5110) logerror("Switching CTL bus direction for Read Bit Buffer Output\n"); |
| 607 | 615 | m_state = CTL_STATE_OUTPUT; |
| 608 | 616 | return; |
| 609 | 617 | case CTL_STATE_OUTPUT: |
| 618 | if (DEBUG_5110) logerror("Switching CTL bus direction back to input from Read Bit Buffer Output\n"); |
| 610 | 619 | m_state = CTL_STATE_INPUT; |
| 611 | 620 | return; |
| 612 | 621 | } |
| 613 | 622 | /* the only real commands we handle now are SPEAK and RESET */ |
| 614 | 623 | if (m_next_is_address) |
| 615 | 624 | { |
| 625 | if (DEBUG_5110) logerror("Loading address nybble %02x to VSMs\n", m_CTL_pins); |
| 616 | 626 | m_next_is_address = FALSE; |
| 617 | 627 | m_address = m_address | ((m_CTL_pins & 0x0F)<<m_addr_bit); |
| 618 | 628 | m_addr_bit = (m_addr_bit + 4) % 12; |
| r242479 | r242480 | |
| 621 | 631 | } |
| 622 | 632 | else |
| 623 | 633 | { |
| 634 | if (DEBUG_5110) logerror("Got command nybble %02x: ", m_CTL_pins); |
| 624 | 635 | switch (m_CTL_pins & 0xe) /*CTL1 - don't care*/ |
| 625 | 636 | { |
| 626 | 637 | case TMS5110_CMD_RESET: |
| 638 | if (DEBUG_5110) logerror("RESET\n"); |
| 627 | 639 | perform_dummy_read(); |
| 628 | 640 | reset(); |
| 629 | 641 | break; |
| 630 | 642 | |
| 631 | 643 | case TMS5110_CMD_LOAD_ADDRESS: |
| 644 | if (DEBUG_5110) logerror("LOAD ADDRESS\n"); |
| 632 | 645 | m_next_is_address = TRUE; |
| 633 | 646 | break; |
| 634 | 647 | |
| 635 | 648 | case TMS5110_CMD_OUTPUT: |
| 649 | if (DEBUG_5110) logerror("OUTPUT (from read-bit buffer)\n"); |
| 636 | 650 | m_state = CTL_STATE_NEXT_OUTPUT; |
| 637 | 651 | break; |
| 638 | 652 | |
| 639 | 653 | case TMS5110_CMD_SPKSLOW: |
| 654 | if (DEBUG_5110) logerror("SPKSLOW (todo: this isn't implemented right yet)\n"); |
| 640 | 655 | perform_dummy_read(); |
| 641 | 656 | m_speaking_now = 1; |
| 642 | 657 | //should FIFO be cleared now ????? there is no fifo! the fifo is a lie! |
| 643 | 658 | break; |
| 644 | 659 | |
| 645 | 660 | case TMS5110_CMD_READ_BIT: |
| 661 | if (DEBUG_5110) logerror("READ BIT\n"); |
| 646 | 662 | if (m_schedule_dummy_read) |
| 647 | 663 | perform_dummy_read(); |
| 648 | 664 | else |
| 649 | 665 | { |
| 666 | if (DEBUG_5110) logerror("actually reading a bit now\n"); |
| 650 | 667 | request_bits(1); |
| 651 | | //m_CTL_pins = (m_CTL_pins & 0x0E) | extract_bits(1); |
| 652 | | m_CTL_buffer <<= 1; |
| 653 | | m_CTL_buffer |= extract_bits(1); |
| 668 | m_CTL_buffer >>= 1; |
| 669 | m_CTL_buffer |= (extract_bits(1)<<3); |
| 654 | 670 | m_CTL_buffer &= 0xF; |
| 655 | 671 | } |
| 656 | 672 | break; |
| 657 | 673 | |
| 658 | 674 | case TMS5110_CMD_SPEAK: |
| 675 | if (DEBUG_5110) logerror("SPEAK\n"); |
| 659 | 676 | perform_dummy_read(); |
| 660 | 677 | m_speaking_now = 1; |
| 661 | 678 | //should FIFO be cleared now ????? there is no fifo! the fifo is a lie! |
| 662 | 679 | break; |
| 663 | 680 | |
| 664 | 681 | case TMS5110_CMD_READ_BRANCH: |
| 682 | if (DEBUG_5110) logerror("READ AND BRANCH\n"); |
| 665 | 683 | new_int_write(0,1,1,0); |
| 666 | 684 | new_int_write(1,1,1,0); |
| 667 | 685 | new_int_write(0,1,1,0); |
| r242479 | r242480 | |
| 672 | 690 | break; |
| 673 | 691 | |
| 674 | 692 | case TMS5110_CMD_TEST_TALK: |
| 693 | if (DEBUG_5110) logerror("TEST TALK\n"); |
| 675 | 694 | m_state = CTL_STATE_NEXT_TTALK_OUTPUT; |
| 676 | 695 | break; |
| 677 | 696 | |
| r242479 | r242480 | |
| 1009 | 1028 | |
| 1010 | 1029 | /****************************************************************************** |
| 1011 | 1030 | |
| 1012 | | tms5110_ctl_r -- read status from the sound chip |
| 1013 | | |
| 1014 | | bit 0 = TS - Talk Status is active (high) when the VSP is processing speech data. |
| 1031 | tms5110_ctl_r -- read from the VSP (51xx) control bus |
| 1032 | The CTL bus can be in three states: |
| 1033 | 1. Test talk output: |
| 1034 | bit 0 = TS - Talk Status is active (high) when the VSP is processing speech data. |
| 1015 | 1035 | Talk Status goes active at the initiation of a SPEAK command. |
| 1016 | 1036 | It goes inactive (low) when the stop code (Energy=1111) is processed, or |
| 1017 | 1037 | immediately(?????? not TMS5110) by a RESET command. |
| 1018 | | TMS5110 datasheets mention this is only available as a result of executing |
| 1019 | | TEST TALK command. |
| 1038 | other bits may be open bus |
| 1039 | 2. 'read bit' buffer contents output: |
| 1040 | bits 0-3 = buffer contents |
| 1041 | 3. Input 'open bus' state: |
| 1042 | bits 0-3 = high-z |
| 1020 | 1043 | |
| 1021 | | FIXME: data read not implemented, CTL1 only available after TALK command |
| 1022 | | |
| 1023 | 1044 | ******************************************************************************/ |
| 1024 | 1045 | |
| 1025 | 1046 | READ8_MEMBER( tms5110_device::ctl_r ) |
| r242479 | r242480 | |
| 1028 | 1049 | m_stream->update(); |
| 1029 | 1050 | if (m_state == CTL_STATE_TTALK_OUTPUT) |
| 1030 | 1051 | { |
| 1031 | | //if (DEBUG_5110) logerror("Status read (status=%2d)\n", m_talk_status); |
| 1052 | if (DEBUG_5110) logerror("Status read while outputting Test Talk (status=%2d)\n", m_talk_status); |
| 1032 | 1053 | return (m_talk_status << 0); /*CTL1 = still talking ? */ |
| 1033 | 1054 | } |
| 1034 | 1055 | else if (m_state == CTL_STATE_OUTPUT) |
| 1035 | 1056 | { |
| 1036 | | //if (DEBUG_5110) logerror("Status read (status=%2d)\n", m_talk_status); |
| 1057 | if (DEBUG_5110) logerror("Status read while outputting buffer (buffer=%2d)\n", m_CTL_buffer); |
| 1037 | 1058 | return (m_CTL_buffer); |
| 1038 | 1059 | } |
| 1039 | | else |
| 1060 | else // we're reading with the bus in input mode! just return the last thing written to the bus |
| 1040 | 1061 | { |
| 1041 | | //if (DEBUG_5110) logerror("Status read (not in output mode)\n"); |
| 1042 | | return (0); |
| 1062 | if (DEBUG_5110) logerror("Status read (not in output mode), returning %02x\n", m_CTL_pins); |
| 1063 | return (m_CTL_pins); |
| 1043 | 1064 | } |
| 1044 | 1065 | } |
| 1045 | 1066 | |
| r242479 | r242480 | |
| 1128 | 1149 | /****************************************************************************** |
| 1129 | 1150 | |
| 1130 | 1151 | tms5110_set_frequency -- adjusts the playback frequency |
| 1152 | TODO: kill this function; we should be adjusting the tms51xx device clock itself, |
| 1153 | not setting it here! |
| 1131 | 1154 | |
| 1132 | 1155 | ******************************************************************************/ |
| 1133 | 1156 | |
| r242479 | r242480 | |
| 1136 | 1159 | m_stream->set_sample_rate(frequency / 80); |
| 1137 | 1160 | } |
| 1138 | 1161 | |
| 1162 | |
| 1163 | |
| 1164 | /* from here on in this file is a VSM 'Emulator' circuit used by bagman and ad2083 */ |
| 1165 | |
| 1139 | 1166 | /* |
| 1140 | 1167 | * |
| 1141 | 1168 | * General Interface design (Bagman) |
trunk/src/mess/drivers/tispeak.c
| r242479 | r242480 | |
| 9 | 9 | #include "emu.h" |
| 10 | 10 | #include "cpu/tms0980/tms0980.h" |
| 11 | 11 | #include "sound/tms5110.h" |
| 12 | #include "machine/tms6100.h" |
| 12 | 13 | |
| 13 | 14 | #include "tispeak.lh" |
| 14 | 15 | |
| r242479 | r242480 | |
| 256 | 257 | static MACHINE_CONFIG_START( tispeak, tispeak_state ) |
| 257 | 258 | |
| 258 | 259 | /* basic machine hardware */ |
| 259 | | MCFG_CPU_ADD("maincpu", TMS0270, MASTER_CLOCK) |
| 260 | MCFG_CPU_ADD("maincpu", TMS0270, XTAL_640kHz/2) |
| 260 | 261 | MCFG_TMS1XXX_READ_K_CB(READ8(tispeak_state, read_k)) |
| 261 | 262 | MCFG_TMS1XXX_WRITE_O_CB(WRITE16(tispeak_state, write_o)) |
| 262 | 263 | MCFG_TMS1XXX_WRITE_R_CB(WRITE16(tispeak_state, write_r)) |
| r242479 | r242480 | |
| 271 | 272 | /* no video! */ |
| 272 | 273 | |
| 273 | 274 | /* sound hardware */ |
| 275 | MCFG_DEVICE_ADD("tms6100", TMS6100, 0) |
| 276 | |
| 274 | 277 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 275 | 278 | MCFG_SOUND_ADD("tms5100", TMS5100, XTAL_640kHz) |
| 279 | MCFG_TMS5110_M0_CB(DEVWRITELINE("tms6100", tms6100_device, tms6100_m0_w)) |
| 280 | MCFG_TMS5110_M1_CB(DEVWRITELINE("tms6100", tms6100_device, tms6100_m1_w)) |
| 281 | MCFG_TMS5110_ADDR_CB(DEVWRITE8("tms6100", tms6100_device, tms6100_addr_w)) |
| 282 | MCFG_TMS5110_DATA_CB(DEVREADLINE("tms6100", tms6100_device, tms6100_data_r)) |
| 283 | MCFG_TMS5110_ROMCLK_CB(DEVWRITELINE("tms6100", tms6100_device, tms6100_romclock_w)) |
| 276 | 284 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) |
| 285 | |
| 277 | 286 | MACHINE_CONFIG_END |
| 278 | 287 | |
| 279 | 288 | |
| r242479 | r242480 | |
| 295 | 304 | ROM_REGION( 1246, "maincpu:opla", 0 ) |
| 296 | 305 | ROM_LOAD( "tms0270_cd2708_opla.pla", 0, 1246, BAD_DUMP CRC(e70836e2) SHA1(70e7dcdf81ae2052874fb21c504fcc06b2649f9a) ) // " |
| 297 | 306 | |
| 298 | | ROM_REGION( 0x8000, "tms5100", 0 ) |
| 307 | ROM_REGION( 0x8000, "tms6100", 0 ) |
| 299 | 308 | ROM_LOAD( "tmc0351.vsm", 0x0000, 0x4000, CRC(beea3373) SHA1(8b0f7586d2f12c3d4a885fdb528cf23feffa1a3b) ) |
| 300 | 309 | ROM_LOAD( "tmc0352.vsm", 0x4000, 0x4000, CRC(d51f0587) SHA1(ddaa484be1bba5fef46b481cafae517e4acaa8ed) ) |
| 301 | 310 | ROM_END |
| r242479 | r242480 | |
| 311 | 320 | ROM_REGION( 1246, "maincpu:opla", 0 ) |
| 312 | 321 | ROM_LOAD( "tms0270_cd2708_opla.pla", 0, 1246, BAD_DUMP CRC(e70836e2) SHA1(70e7dcdf81ae2052874fb21c504fcc06b2649f9a) ) // " |
| 313 | 322 | |
| 314 | | ROM_REGION( 0x8000, "tms5100", 0 ) |
| 323 | ROM_REGION( 0x8000, "tms6100", 0 ) |
| 315 | 324 | ROM_LOAD( "cd2392.vsm", 0x0000, 0x4000, CRC(4ed2e920) SHA1(8896f29e25126c1e4d9a47c9a325b35dddecc61f) ) |
| 316 | 325 | ROM_LOAD( "cd2393.vsm", 0x4000, 0x4000, CRC(571d5b5a) SHA1(83284755d9b77267d320b5b87fdc39f352433715) ) |
| 317 | 326 | ROM_END |