diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index d80d4a88f20..b0cf48a271a 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -198,10 +198,6 @@ Interpolation is inhibited (i.e. interpolation at IP frames will not happen ****Documentation of chip commands:*** - 76543210 (these are in logical 7 thru 0 order with MSB (7) first; TI calls - these bits by the opposite order, D0 thru D7, on the datasheet, - with D0 being the MSB) - x0x0xbcc: on 5200/5220: NOP (does nothing) on 5220C and CD2501ECD: Select frame length by cc, and b selects whether every frame is preceded by 2 bits to select the frame @@ -325,10 +321,9 @@ this), mostly on later pinballs with LPC speech) module (6511 based), IBM PS/2 Speech adapter (parallel port connection device), PES Speech adapter (serial port connection) -Street electronics had two later 1988-1990-era ECHO appleII cards which are -TSP50c0x/1x MCU based speech and not tms52xx based (though it is likely -emulating the tms5220 in MCU code). Look for a 16-pin chip at U6 labeled -"ECHO-2 SN" or "ECHO-3 SN". +Street electronics had a later 1989-era ECHO appleII card which is TSP50c0x/1x +MCU based speech and not tms5xxx based (though it is likely emulating the tms5220 +in MCU code). Look for a 16-pin chip at U6 labeled "ECHO-3 SN". ***********************************************************************************************/ @@ -387,8 +382,6 @@ static int16_t clip_analog(int16_t cliptemp); // above dumps info if a frame ran out of data #undef DEBUG_COMMAND_DUMP // above dumps all non-speech-data command writes -#undef DEBUG_COMMAND_VERBOSE -// above dumps decoded info about command writes #undef DEBUG_PIN_READS // above spams the errorlog with i/o ready messages whenever the ready or irq pin is read #undef DEBUG_GENERATION @@ -400,10 +393,9 @@ static int16_t clip_analog(int16_t cliptemp); #undef DEBUG_CLIP // above dumps info to stderr whenever the analog clip hardware is (or would be) clipping the signal. #undef DEBUG_IO_READY -// above debugs the io ready callback timer +// above debugs the io ready callback #undef DEBUG_RS_WS // above debugs the tms5220_data_r and data_w access methods which actually respect rs and ws -// TODO: switch the comments to be above the defines instead of below them #define MAX_SAMPLE_CHUNK 512 @@ -448,32 +440,12 @@ static const uint8_t reload_table[4] = { 0, 2, 4, 6 }; //sample count reload for void tms5220_device::register_for_save_states() { - // for sanity purposes these variables should be in the same order as in tms5220.h! - - // 5110 specific stuff - save_item(NAME(m_PDC)); - save_item(NAME(m_CTL_pins)); - save_item(NAME(m_state)); - - // new VSM stuff - save_item(NAME(m_address)); - save_item(NAME(m_next_is_address)); - save_item(NAME(m_schedule_dummy_read)); - save_item(NAME(m_addr_bit)); - save_item(NAME(m_CTL_buffer)); - - // old VSM stuff - save_item(NAME(m_read_byte_register)); - save_item(NAME(m_RDB_flag)); - - // FIFO save_item(NAME(m_fifo)); save_item(NAME(m_fifo_head)); save_item(NAME(m_fifo_tail)); save_item(NAME(m_fifo_count)); save_item(NAME(m_fifo_bits_taken)); - // global status bits (booleans) save_item(NAME(m_previous_TALK_STATUS)); save_item(NAME(m_SPEN)); save_item(NAME(m_DDIS)); @@ -484,7 +456,6 @@ void tms5220_device::register_for_save_states() save_item(NAME(m_irq_pin)); save_item(NAME(m_ready_pin)); - // current and previous frames save_item(NAME(m_OLDE)); save_item(NAME(m_OLDP)); @@ -521,59 +492,65 @@ void tms5220_device::register_for_save_states() save_item(NAME(m_RNG)); save_item(NAME(m_excitation_data)); + save_item(NAME(m_schedule_dummy_read)); + save_item(NAME(m_data_register)); + save_item(NAME(m_RDB_flag)); save_item(NAME(m_digital_select)); save_item(NAME(m_io_ready)); - // "proper" rs+ws emulation save_item(NAME(m_true_timing)); save_item(NAME(m_rs_ws)); save_item(NAME(m_read_latch)); save_item(NAME(m_write_latch)); + + // 5110 specific stuff + save_item(NAME(m_PDC)); + save_item(NAME(m_CTL_pins)); + save_item(NAME(m_state)); + save_item(NAME(m_address)); + save_item(NAME(m_next_is_address)); + save_item(NAME(m_addr_bit)); + save_item(NAME(m_CTL_buffer)); } /********************************************************************************************** - printbits helper function: takes an input and prints the resulting bits to a string buffer, passed to it using snprintf. + printbits helper function: takes a long int input and prints the resulting bits to stderr ***********************************************************************************************/ #ifdef DEBUG_PARSE_FRAME_DUMP_BIN -int tms5220_device::printbits(char *buffer, int count, unsigned int data, int num) +static void printbits(long data, int num) { - int retval = 0; int i; for (i=(num-1); i>=0; i--) - { - retval += snprintf(buffer+retval, count-retval, "%0d", (data>>i)&1); - } - retval += snprintf(buffer+retval, count-retval, " "); - return retval; + logerror("%0ld", (data>>i)&1); } #endif #ifdef DEBUG_PARSE_FRAME_DUMP_HEX -int tms5220_device::printbits(char *buffer, int count, unsigned int data, int num) +static void printbits(long data, int num) { - int retval = 0; switch((num-1)&0xFC) { case 0: - retval = snprintf(buffer, count, "%01x ", data); + logerror("%0lx", data); break; case 4: - retval = snprintf(buffer, count, "%02x ", data); + logerror("%02lx", data); break; case 8: - retval = snprintf(buffer, count, "%03x ", data); + logerror("%03lx", data); break; case 12: + logerror("%04lx", data); + break; default: - retval = snprintf(buffer, count, "%04x ", data); + logerror("%04lx", data); break; } - return retval; } #endif @@ -634,9 +611,10 @@ uint8_t tms5220_device::new_int_read() tms5220_device::data_write -- handle a write to the TMS5220 ***********************************************************************************************/ + void tms5220_device::data_write(int data) { - bool old_buffer_low = m_buffer_low; + int old_buffer_low = m_buffer_low; #ifdef DEBUG_DUMP_INPUT_DATA fprintf(stdout, "%c",data); #endif @@ -653,24 +631,24 @@ void tms5220_device::data_write(int data) #endif update_fifo_status_and_ints(); // if we just unset buffer low with that last write, and SPEN *was* zero (see circuit 251, sheet 12) - if ((!m_SPEN) && ((old_buffer_low) && (!m_buffer_low))) // MUST HAVE EDGE DETECT + if ((m_SPEN == 0) && ((old_buffer_low == 1) && (m_buffer_low == 0))) // MUST HAVE EDGE DETECT { int i; #ifdef DEBUG_FIFO logerror("data_write triggered SPEN to go active!\n"); #endif // ...then we now have enough bytes to start talking; set zpar and clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) - m_zpar = true; - m_uv_zpar = true; // zero k4-k10 as well - m_OLDE = true; // 'silence/zpar' frames are zero energy - m_OLDP = true; // 'silence/zpar' frames are zero pitch + m_zpar = 1; + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = true; // zero all the old parameters - m_old_uv_zpar = true; // zero old k4-k10 as well + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well #endif - m_SPEN = true; + m_SPEN = 1; #ifdef FAST_START_HACK - m_TALK = true; + m_TALK = 1; #endif m_new_frame_energy_idx = 0; m_new_frame_pitch_idx = 0; @@ -720,6 +698,7 @@ void tms5220_device::data_write(int data) Speak External command execution is terminated. ***********************************************************************************************/ + void tms5220_device::update_fifo_status_and_ints() { /* update 52xx fifo flags and set ints if needed */ @@ -733,13 +712,11 @@ void tms5220_device::update_fifo_status_and_ints() { // generate an interrupt if necessary; if /BL was inactive and is now active, set int. if (!m_buffer_low) - { - m_buffer_low = true; set_interrupt_state(1); - } + m_buffer_low = 1; } else - m_buffer_low = false; + m_buffer_low = 0; /* BE is set if neither byte 15 nor 14 of the fifo are in use; this translates to having fifo_count equal to exactly 0 @@ -748,25 +725,23 @@ void tms5220_device::update_fifo_status_and_ints() { // generate an interrupt if necessary; if /BE was inactive and is now active, set int. if (!m_buffer_empty) - { - m_buffer_empty = true; set_interrupt_state(1); - } + m_buffer_empty = 1; if (m_DDIS) - m_TALK = m_SPEN = false; // /BE being active clears the TALK status via TCON, which in turn clears SPEN, but ONLY if m_DDIS is set! See patent page 16, gate 232b + m_TALK = m_SPEN = 0; // /BE being active clears the TALK status via TCON, which in turn clears SPEN, but ONLY if m_DDIS is set! See patent page 16, gate 232b } else - m_buffer_empty = false; + m_buffer_empty = 0; // generate an interrupt if /TS was active, and is now inactive. // also, in this case, regardless if DDIS was set, unset it. - if (m_previous_TALK_STATUS && (!TALK_STATUS())) + if ((m_previous_TALK_STATUS == 1) && (TALK_STATUS() == 0)) { #ifdef VERBOSE logerror("Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); #endif set_interrupt_state(1); - m_DDIS = false; + m_DDIS = 0; } m_previous_TALK_STATUS = TALK_STATUS(); @@ -777,6 +752,7 @@ void tms5220_device::update_fifo_status_and_ints() extract_bits -- extract a specific number of bits from the current input stream (FIFO or VSM) ***********************************************************************************************/ + int tms5220_device::extract_bits(int count) { int val = 0; @@ -805,8 +781,6 @@ int tms5220_device::extract_bits(int count) // extract from VSM (speech ROM) if (m_speechrom) val = m_speechrom->read(count); - else - val = (1<> m_fifo_bits_taken) & 0xf; + if (val == 0) + /* 0 -> silence frame: we will only read 4 bits, and we will + * therefore need to read another frame before the FIFO is not + * full any more */ + answer += m_subc_reload?200:304; + /* 15 -> stop frame, we will only read 4 bits, but the FIFO will + * we cleared; otherwise, we need to parse the repeat flag (1 bit) + * and the pitch (6 bits), so everything will be OK. */ + } + } + + return answer; +} + + /********************************************************************************************** tms5220_int_read -- returns the interrupt state of the TMS5220 ***********************************************************************************************/ -bool tms5220_device::int_read() + +int tms5220_device::int_read() { #ifdef DEBUG_PIN_READS logerror("int_read: irq pin read, state is %d\n", m_irq_pin); @@ -889,14 +906,16 @@ bool tms5220_device::int_read() return m_irq_pin; } + /********************************************************************************************** tms5220_process -- fill the buffer with a specific number of samples ***********************************************************************************************/ + void tms5220_device::process(int16_t *buffer, unsigned int size) { - int buf_count = 0; + int buf_count=0; int i, bitout; int32_t this_sample; @@ -936,7 +955,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */ if (NEW_FRAME_STOP_FLAG()) { - m_TALK = m_SPEN = false; + m_TALK = m_SPEN = 0; update_fifo_status_and_ints(); // probably not necessary... } @@ -947,20 +966,20 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) * Old frame was unvoiced, new is voiced * Old frame was unvoiced, new frame is silence/zero energy (non-existent on tms51xx rev D and F (present and working on tms52xx, present but buggy on tms51xx rev A and B)) */ - if ( (!OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_UNVOICED_FLAG()) - || (OLD_FRAME_UNVOICED_FLAG() && !NEW_FRAME_UNVOICED_FLAG()) - || (OLD_FRAME_SILENCE_FLAG() && !NEW_FRAME_SILENCE_FLAG()) - //|| ((m_inhibit == true) && OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_SILENCE_FLAG()) ) //TMS51xx INTERP BUG1 - || (OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_SILENCE_FLAG()) ) - m_inhibit = true; + if ( ((OLD_FRAME_UNVOICED_FLAG() == 0) && NEW_FRAME_UNVOICED_FLAG()) + || ((OLD_FRAME_UNVOICED_FLAG() == 1) && !NEW_FRAME_UNVOICED_FLAG()) + || ((OLD_FRAME_SILENCE_FLAG() == 1) && !NEW_FRAME_SILENCE_FLAG()) + //|| ((m_inhibit == 1) && (OLD_FRAME_UNVOICED_FLAG() == 1) && NEW_FRAME_SILENCE_FLAG()) ) //TMS51xx INTERP BUG1 + || ((OLD_FRAME_UNVOICED_FLAG() == 1) && NEW_FRAME_SILENCE_FLAG()) ) + m_inhibit = 1; else // normal frame, normal interpolation - m_inhibit = false; + m_inhibit = 0; #ifdef DEBUG_GENERATION /* Debug info for current parsed frame */ logerror( "OLDE: %d; NEWE: %d; OLDP: %d; NEWP: %d ", OLD_FRAME_SILENCE_FLAG(), NEW_FRAME_SILENCE_FLAG(), OLD_FRAME_UNVOICED_FLAG(), NEW_FRAME_UNVOICED_FLAG()); logerror("Processing new frame: "); - if (m_inhibit == false) + if (m_inhibit == 0) logerror( "Normal Frame\n"); else logerror("Interpolation Inhibited\n"); @@ -984,7 +1003,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } else // Not a new frame, just interpolate the existing frame. { - bool inhibit_state = ((m_inhibit == true) && (m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value + int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value #ifdef TMS5220_PERFECT_INTERPOLATION_HACK int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW @@ -1005,7 +1024,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } else // we're done, play this frame for 1/8 frame. { - if (m_subcycle == 2) m_pitch_zero = false; // this reset happens around the second subcycle during IP=0 + if (m_subcycle == 2) m_pitch_zero = 0; // this reset happens around the second subcycle during IP=0 m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)); m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)); for (i = 0; i < m_coeff->num_k; i++) @@ -1037,7 +1056,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } // calculate the output - if (OLD_FRAME_UNVOICED_FLAG() == true) + if (OLD_FRAME_UNVOICED_FLAG() == 1) { // generate unvoiced samples here if (m_RNG & 1) @@ -1119,13 +1138,13 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) * According to testing the pitch zeroing lasts approximately 2 samples. * We set the zeroing latch here, and unset it on PC=1 in the generator. */ - if ((m_IP == 7)&&(m_inhibit == true)) m_pitch_zero = true; + if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1; if (m_IP == 7) // RESETL4 { // Latch OLDE and OLDP - //if (OLD_FRAME_SILENCE_FLAG()) m_uv_zpar = false; // TMS51xx INTERP BUG2 - OLD_FRAME_SILENCE_FLAG() = NEW_FRAME_SILENCE_FLAG() ? true : false; // m_OLDE - OLD_FRAME_UNVOICED_FLAG() = NEW_FRAME_UNVOICED_FLAG() ? true : false; // m_OLDP + //if (OLD_FRAME_SILENCE_FLAG()) m_uv_zpar = 0; // TMS51xx INTERP BUG2 + OLD_FRAME_SILENCE_FLAG() = NEW_FRAME_SILENCE_FLAG() ? 1 : 0; // m_OLDE + OLD_FRAME_UNVOICED_FLAG() = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; // m_OLDP /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */ #ifdef DEBUG_GENERATION logerror("RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); @@ -1136,7 +1155,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) #endif m_TALKD = m_TALK; // TALKD is latched from TALK update_fifo_status_and_ints(); // to trigger an interrupt if TALK_STATUS has changed - if ((!m_TALK) && m_SPEN) m_TALK = true; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). + if ((!m_TALK) && m_SPEN) m_TALK = 1; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). #ifdef DEBUG_GENERATION logerror("RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); #endif @@ -1152,7 +1171,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) m_PC++; } m_pitch_count++; - if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == true)) m_pitch_count = 0; + if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0; m_pitch_count &= 0x1FF; } else // m_TALKD == 0 @@ -1164,7 +1183,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) { m_TALKD = m_TALK; // TALKD is latched from TALK update_fifo_status_and_ints(); // probably not necessary - if ((!m_TALK) && m_SPEN) m_TALK = true; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). + if ((!m_TALK) && m_SPEN) m_TALK = 1; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). } m_subcycle = m_subc_reload; m_PC = 0; @@ -1188,6 +1207,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) clip_analog -- clips the 14 bit return value from the lattice filter to its final 10 bit value (-512 to 511), and upshifts/range extends this to 16 bits ***********************************************************************************************/ + static int16_t clip_analog(int16_t cliptemp) { /* clipping, just like the patent shows: @@ -1219,6 +1239,7 @@ static int16_t clip_analog(int16_t cliptemp) #endif } + /********************************************************************************************** matrix_multiply -- does the proper multiply and shift @@ -1251,6 +1272,7 @@ static int32_t matrix_multiply(int32_t a, int32_t b) resulting sample. ***********************************************************************************************/ + int32_t tms5220_device::lattice_filter() { // Lattice filter here @@ -1317,11 +1339,13 @@ int32_t tms5220_device::lattice_filter() return m_u[0]; } + /********************************************************************************************** process_command -- extract a byte from the FIFO and interpret it as a command ***********************************************************************************************/ + void tms5220_device::process_command(unsigned char cmd) { int i; @@ -1332,9 +1356,6 @@ void tms5220_device::process_command(unsigned char cmd) switch (cmd & 0x70) { case 0x10 : /* read byte */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Read Byte command received\n"); -#endif if (TALK_STATUS() == 0) /* TALKST must be clear for RDBY */ { if (m_schedule_dummy_read) @@ -1344,34 +1365,23 @@ void tms5220_device::process_command(unsigned char cmd) m_speechrom->read(1); } if (m_speechrom) - m_read_byte_register = m_speechrom->read(8); /* read one byte from speech ROM... */ + m_data_register = m_speechrom->read(8); /* read one byte from speech ROM... */ m_RDB_flag = true; } -#ifdef DEBUG_COMMAND_VERBOSE - else - logerror("Read Byte command received during TALK state, ignoring!\n"); -#endif break; case 0x00: case 0x20: /* set rate (tms5220c and cd2501ecd only), otherwise NOP */ if (TMS5220_HAS_RATE_CONTROL) -#ifdef DEBUG_COMMAND_VERBOSE { - logerror("Set Rate (or NOP) command received\n"); -#endif m_c_variant_rate = cmd&0x0F; -#ifdef DEBUG_COMMAND_VERBOSE } - else - logerror("NOP command received\n"); -#endif break; case 0x30 : /* read and branch */ if (TALK_STATUS() == 0) /* TALKST must be clear for RB */ { -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Read and Branch command received\n"); +#ifdef VERBOSE + logerror("read and branch command received\n"); #endif m_RDB_flag = false; if (m_speechrom) @@ -1380,9 +1390,6 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x40 : /* load address */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Load Address command received\n"); -#endif if (TALK_STATUS() == 0) /* TALKST must be clear for LA */ { /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. @@ -1391,16 +1398,9 @@ void tms5220_device::process_command(unsigned char cmd) m_speechrom->load_address(cmd & 0x0f); m_schedule_dummy_read = true; } -#ifdef DEBUG_COMMAND_VERBOSE - else - logerror("Load Address command received during TALK state, ignoring!\n"); -#endif break; case 0x50 : /* speak */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Speak (VSM) command received\n"); -#endif if (m_schedule_dummy_read) { m_schedule_dummy_read = false; @@ -1411,14 +1411,14 @@ void tms5220_device::process_command(unsigned char cmd) #ifdef FAST_START_HACK m_TALK = 1; #endif - m_DDIS = false; // speak using VSM - m_zpar = true; // zero all the parameters - m_uv_zpar = true; // zero k4-k10 as well - m_OLDE = true; // 'silence/zpar' frames are zero energy - m_OLDP = true; // 'silence/zpar' frames are zero pitch + m_DDIS = 0; + m_zpar = 1; // zero all the parameters + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = true; // zero all the old parameters - m_old_uv_zpar = true; // zero old k4-k10 as well + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well #endif // following is semi-hack but matches idle state observed on chip m_new_frame_energy_idx = 0; @@ -1432,21 +1432,17 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x60 : /* speak external */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Speak External command received\n"); -#endif - // SPKEXT going active asserts /SPKEE for 2 clocks, which clears the FIFO and its counters - memset(m_fifo, 0, sizeof(m_fifo[0])*FIFO_SIZE); + // SPKEXT going active activates SPKEE which clears the fifo m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; - // SPEN is enabled when the FIFO passes half full (falling edge of BL signal) - m_DDIS = true; // speak using FIFO - m_zpar = true; // zero all the parameters - m_uv_zpar = true; // zero k4-k10 as well - m_OLDE = true; // 'silence/zpar' frames are zero energy - m_OLDP = true; // 'silence/zpar' frames are zero pitch + // SPEN is enabled when the fifo passes half full (falling edge of BL signal) + m_DDIS = 1; + m_zpar = 1; // zero all the parameters + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = true; // zero all the old parameters - m_old_uv_zpar = true; // zero old k4-k10 as well + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well #endif // following is semi-hack but matches idle state observed on chip m_new_frame_energy_idx = 0; @@ -1461,9 +1457,6 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x70 : /* reset */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Reset command received\n"); -#endif if (m_schedule_dummy_read) { m_schedule_dummy_read = false; @@ -1483,17 +1476,9 @@ void tms5220_device::process_command(unsigned char cmd) parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer ******************************************************************************************/ + void tms5220_device::parse_frame() { -#ifdef DEBUG_PARSE_FRAME_DUMP - char p_buffer[64] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - }; - uint8_t p_buffer_count = 0; -#endif int i, rep_flag; #ifdef TMS5220_PERFECT_INTERPOLATION_HACK m_old_uv_zpar = m_uv_zpar; @@ -1511,7 +1496,8 @@ void tms5220_device::parse_frame() { i = extract_bits(2); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, i, 2); + printbits(i,2); + logerror(" "); #endif m_IP = reload_table[i]; } @@ -1524,7 +1510,8 @@ void tms5220_device::parse_frame() // attempt to extract the energy index m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_energy_idx, m_coeff->energy_bits); + printbits(m_new_frame_energy_idx,m_coeff->energy_bits); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1532,16 +1519,19 @@ void tms5220_device::parse_frame() if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15)) return; + // attempt to extract the repeat flag rep_flag = extract_bits(1); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, rep_flag, 1); + printbits(rep_flag, 1); + logerror(" "); #endif // attempt to extract the pitch m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_pitch_idx,m_coeff->pitch_bits); + printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits); + logerror(" "); #endif // if the new frame is unvoiced, be sure to zero out the k5-k10 parameters m_uv_zpar = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; @@ -1556,7 +1546,8 @@ void tms5220_device::parse_frame() { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_k_idx[i],m_coeff->kbits[i]); + printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1574,13 +1565,14 @@ void tms5220_device::parse_frame() { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_k_idx[i],m_coeff->kbits[i]); + printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; } #ifdef DEBUG_PARSE_FRAME_DUMP - logerror("%s\n", p_buffer); + logerror("\n"); #endif #ifdef VERBOSE if (m_DDIS) @@ -1602,6 +1594,7 @@ void tms5220_device::parse_frame() set_interrupt_state -- generate an interrupt ***********************************************************************************************/ + void tms5220_device::set_interrupt_state(int state) { if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin @@ -1618,18 +1611,16 @@ void tms5220_device::set_interrupt_state(int state) update_ready_state -- update the ready line ***********************************************************************************************/ + void tms5220_device::update_ready_state() { - bool state = ready_read(); - if (m_ready_pin != state) - { + int state = ready_read(); #ifdef DEBUG_PIN_READS - logerror("ready pin set to state %d\n", state); + logerror("ready pin set to state %d\n", state); #endif - if (!m_readyq_handler.isnull()) - m_readyq_handler(!state); - m_ready_pin = state; - } + if (!m_readyq_handler.isnull() && state != m_ready_pin) + m_readyq_handler(!state); + m_ready_pin = state; } @@ -1697,13 +1688,11 @@ void tms5220_device::device_start() m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80); m_timer_io_ready = timer_alloc(0); - //m_timer_rsq_wsq_check = timer_alloc(1); /* not during reset which is called from within a write! */ - m_io_ready = true; - m_true_timing = false; + m_io_ready = 1; + m_true_timing = 0; m_rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup - m_write_latch = 0; // assume on start that nothing is driving the data bus register_for_save_states(); } @@ -1716,15 +1705,15 @@ void tms5220_device::device_reset() { m_digital_select = FORCE_DIGITAL; // assume analog output /* initialize the FIFO */ - memset(m_fifo, 0, sizeof(m_fifo[0])*FIFO_SIZE); + /*memset(m_fifo, 0, sizeof(m_fifo));*/ m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; /* initialize the chip state */ /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if m_buffer_empty or m_buffer_low are 0 */ - m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = false; + m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = 0; set_interrupt_state(0); update_ready_state(); - m_buffer_empty = m_buffer_low = true; + m_buffer_empty = m_buffer_low = 1; m_RDB_flag = false; @@ -1732,24 +1721,24 @@ void tms5220_device::device_reset() #ifdef TMS5220_PERFECT_INTERPOLATION_HACK m_old_frame_energy_idx = m_old_frame_pitch_idx = 0; memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx)); - m_old_zpar = false; + m_old_zpar = 0; #endif m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0; m_new_frame_pitch_idx = m_current_pitch = 0; - m_zpar = m_uv_zpar = false; + m_zpar = m_uv_zpar = 0; memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx)); memset(m_current_k, 0, sizeof(m_current_k)); /* initialize the sample generators */ - m_inhibit = true; + m_inhibit = 1; m_subcycle = m_c_variant_rate = m_pitch_count = m_PC = 0; m_subc_reload = FORCE_SUBC_RELOAD; - m_OLDE = m_OLDP = true; + m_OLDE = m_OLDP = 1; m_IP = reload_table[m_c_variant_rate&0x3]; m_RNG = 0x1FFF; memset(m_u, 0, sizeof(m_u)); memset(m_x, 0, sizeof(m_x)); - m_schedule_dummy_read = false; + m_schedule_dummy_read = 0; if (m_speechrom) { @@ -1757,7 +1746,7 @@ void tms5220_device::device_reset() // MZ: Do the dummy read immediately. The previous line will cause a // shift in the address pointer in the VSM. When the next command is a // load_address, no dummy read will occur, hence the address will be - // incorrectly shifted. + // falsely shifted. m_speechrom->read(1); m_schedule_dummy_read = false; } @@ -1783,61 +1772,41 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para { switch(id) { - case 0: // m_timer_io_ready - /* bring up to date first */ - m_stream->update(); -#ifdef DEBUG_IO_READY - logerror("m_timer_io_ready timer fired, param = %02x, m_rs_ws = %02x\n", param, m_rs_ws); -#endif - if (param) // low->high ready state + case 0: + if (param) { switch (m_rs_ws) { case 0x02: /* Write */ + /* bring up to date first */ #ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: Attempting to service write...\n"); + logerror("Serviced write: %02x\n", m_write_latch); + //logerror( "Processed write data: %02X\n", m_write_latch); #endif - if ((m_fifo_count >= FIFO_SIZE) && m_DDIS) // if fifo is full and we're in speak external mode - { -#ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: in SPKEXT and FIFO was full! cannot service write now, delaying 16 cycles...\n"); -#endif - m_timer_io_ready->adjust(clocks_to_attotime(16), 1); - break; - } - else - { -#ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: Serviced write: %02x\n", m_write_latch); -#endif - data_write(m_write_latch); - m_io_ready = param; - break; - } + m_stream->update(); + data_write(m_write_latch); + break; case 0x01: /* Read */ - m_read_latch = status_read(true); + /* bring up to date first */ + m_stream->update(); + m_read_latch = status_read(); #ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: Serviced read, returning %02x\n", m_read_latch); + logerror("Serviced read, returning %02x\n", m_read_latch); #endif - m_io_ready = param; break; case 0x03: /* High Impedance */ - m_io_ready = param; case 0x00: /* illegal */ - m_io_ready = param; break; } } + m_io_ready = param; update_ready_state(); break; - /*case 1: // m_timer_rsq_wsq_check - // TODO: write me, and get rid of the garbage in wsq_w, rsq_w, etc! - break; */ } } @@ -1848,7 +1817,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) { uint8_t new_val; - m_true_timing = true; + m_true_timing = 1; state &= 0x01; #ifdef DEBUG_RS_WS logerror("/RS written with data: %d\n", state); @@ -1859,7 +1828,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) m_rs_ws = new_val; if (new_val == 0) { - if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, probably also correct for cd2501ecd + if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, ? for cd2501ecd reset(); #ifdef DEBUG_RS_WS else @@ -1885,11 +1854,10 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) logerror("Scheduling ready cycle for /RS...\n"); #endif /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); - /* How long does /READY stay inactive, when /RS is pulled low? It might be always ~16 clocks (25 usec at 800khz as shown on the datasheet) - but the patent schematic implies it might be as short as 4 clock cycles. */ - m_timer_io_ready->adjust(clocks_to_attotime(16), 1); + /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */ + m_timer_io_ready->adjust(clocks_to_attotime(16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete } } } @@ -1901,7 +1869,7 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) { uint8_t new_val; - m_true_timing = true; + m_true_timing = 1; state &= 0x01; #ifdef DEBUG_RS_WS logerror("/WS written with data: %d\n", state); @@ -1938,7 +1906,7 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) logerror("Scheduling ready cycle for /WS...\n"); #endif /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); /* Now comes the complicated part: how long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not... Speak external mode: ~16 cycles @@ -1965,7 +1933,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) { uint8_t new_val; uint8_t falling_edges; - m_true_timing = true; + m_true_timing = 1; #ifdef DEBUG_RS_WS logerror("/RS and /WS written with %d and %d respectively\n", (data&2)>>1, data&1); #endif @@ -1997,7 +1965,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) logerror("Scheduling ready cycle for /WS...\n"); #endif /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); /* Now comes the complicated part: how long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not... Speak external mode: ~16 cycles @@ -2020,7 +1988,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) logerror("Scheduling ready cycle for /RS...\n"); #endif /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */ m_timer_io_ready->adjust(clocks_to_attotime(16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete @@ -2038,14 +2006,18 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) void tms5220_device::write_data(uint8_t data) { + // prevent debugger from changing the internal state + if (machine().side_effects_disabled()) return; + #ifdef DEBUG_RS_WS logerror("tms5220_data_w: data %02x\n", data); #endif - /* bring up to date first */ - m_stream->update(); - m_write_latch = data; - if (!m_true_timing) // if we're in the default hacky mode where we don't bother with rsq_w and wsq_w... - data_write(m_write_latch); // ...force the write through instantly. + if (!m_true_timing) + { + /* bring up to date first */ + m_stream->update(); + data_write(data); + } else { /* actually in a write ? */ @@ -2053,9 +2025,12 @@ void tms5220_device::write_data(uint8_t data) if (!(m_rs_ws == 0x02)) logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); #endif + m_write_latch = data; } } + + /********************************************************************************************** tms5220_status_r -- read status or data from the sound chip @@ -2064,15 +2039,14 @@ void tms5220_device::write_data(uint8_t data) uint8_t tms5220_device::read_status() { - /* bring up to date first */ - m_stream->update(); + // prevent debugger from changing the internal state + if (machine().side_effects_disabled()) return 0; if (!m_true_timing) { - // prevent debugger from changing the internal state - if (machine().side_effects_disabled()) - return status_read(false); - return status_read(true); + /* bring up to date first */ + m_stream->update(); + return status_read(); } else { @@ -2083,7 +2057,7 @@ uint8_t tms5220_device::read_status() else logerror("tms5220_status_r: data read outside rs!\n"); #endif - return 0xff; // m_write_latch; // return open bus + return 0xff; } } @@ -2104,6 +2078,21 @@ READ_LINE_MEMBER( tms5220_device::readyq_r ) +/********************************************************************************************** + + tms5220_time_to_ready -- return the time until the ready line is asserted + +***********************************************************************************************/ + +attotime tms5220_device::time_to_ready() +{ + /* bring up to date first */ + m_stream->update(); + return clocks_to_attotime(cycles_to_ready() * 80); +} + + + /********************************************************************************************** tms5220_int_r -- return the int status from the sound chip diff --git a/src/devices/sound/tms5220.h b/src/devices/sound/tms5220.h index 0b7617be505..4cfab5491ef 100644 --- a/src/devices/sound/tms5220.h +++ b/src/devices/sound/tms5220.h @@ -90,6 +90,8 @@ public: READ_LINE_MEMBER( readyq_r ); READ_LINE_MEMBER( intq_r ); + attotime time_to_ready(); + protected: tms5220_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int variant); @@ -116,23 +118,20 @@ private: void data_write(int data); void update_fifo_status_and_ints(); int extract_bits(int count); - uint8_t status_read(bool clear_int); - bool ready_read(); - bool int_read(); + int status_read(); + int ready_read(); + int cycles_to_ready(); + int int_read(); void process(int16_t *buffer, unsigned int size); int32_t lattice_filter(); void process_command(unsigned char cmd); void parse_frame(); void set_interrupt_state(int state); void update_ready_state(); - //debug -#ifdef DEBUG_PARSE_FRAME_DUMP - printbits(char *buffer, int count, unsigned int data, int num); -#endif - bool TALK_STATUS() const { return m_SPEN || m_TALKD; } - bool &OLD_FRAME_SILENCE_FLAG() { return m_OLDE; } // 1 if E=0, 0 otherwise. - bool &OLD_FRAME_UNVOICED_FLAG() { return m_OLDP; } // 1 if P=0 (unvoiced), 0 if voiced + uint8_t TALK_STATUS() const { return m_SPEN | m_TALKD; } + uint8_t &OLD_FRAME_SILENCE_FLAG() { return m_OLDE; } // 1 if E=0, 0 otherwise. + uint8_t &OLD_FRAME_UNVOICED_FLAG() { return m_OLDP; } // 1 if P=0 (unvoiced), 0 if voiced bool NEW_FRAME_STOP_FLAG() const { return m_new_frame_energy_idx == 0x0F; } // 1 if this is a stop (Energy = 0xF) frame bool NEW_FRAME_SILENCE_FLAG() const { return m_new_frame_energy_idx == 0; } // ditto as above bool NEW_FRAME_UNVOICED_FLAG() const { return m_new_frame_pitch_idx == 0; } // ditto as above @@ -145,23 +144,23 @@ private: /* coefficient tables */ const struct tms5100_coeffs *m_coeff; - /* these contain global status bits for the 5100 */ + /* these contain global status bits */ uint8_t m_PDC; uint8_t m_CTL_pins; uint8_t m_state; /* New VSM interface */ uint32_t m_address; - bool m_next_is_address; - bool m_schedule_dummy_read; + uint8_t m_next_is_address; + uint8_t m_schedule_dummy_read; uint8_t m_addr_bit; /* read byte */ uint8_t m_CTL_buffer; /* Old VSM interface; R Nabet : These have been added to emulate speech Roms */ - //bool m_schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */ - uint8_t m_read_byte_register; /* a serial->parallel shifter, used by "read byte" command to store 8 bits from the VSM */ - bool m_RDB_flag; /* whether we should read data register or status register */ + //uint8_t m_schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */ + uint8_t m_data_register; /* data register, used by read command */ + uint8_t m_RDB_flag; /* whether we should read data register or status register */ /* these contain data that describes the 128-bit data FIFO */ uint8_t m_fifo[FIFO_SIZE]; @@ -171,20 +170,20 @@ private: uint8_t m_fifo_bits_taken; - /* these contain global status bits (booleans) */ - bool m_previous_TALK_STATUS;/* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */ - bool m_SPEN; /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */ - bool m_DDIS; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */ - bool m_TALK; /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */ - bool m_TALKD; /* TALK(TCON) value, latched every RESETL4 */ - bool m_buffer_low; /* If 1, FIFO has less than 8 bytes in it */ - bool m_buffer_empty; /* If 1, FIFO is empty */ - bool m_irq_pin; /* state of the IRQ pin (output) */ - bool m_ready_pin; /* state of the READY pin (output) */ + /* these contain global status bits */ + uint8_t m_previous_TALK_STATUS; /* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */ + uint8_t m_SPEN; /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */ + uint8_t m_DDIS; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */ + uint8_t m_TALK; /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */ + uint8_t m_TALKD; /* TALK(TCON) value, latched every RESETL4 */ + uint8_t m_buffer_low; /* If 1, FIFO has less than 8 bytes in it */ + uint8_t m_buffer_empty; /* If 1, FIFO is empty */ + uint8_t m_irq_pin; /* state of the IRQ pin (output) */ + uint8_t m_ready_pin; /* state of the READY pin (output) */ /* these contain data describing the current and previous voice frames */ - bool m_OLDE; - bool m_OLDP; + uint8_t m_OLDE; + uint8_t m_OLDP; uint8_t m_new_frame_energy_idx; uint8_t m_new_frame_pitch_idx; @@ -200,8 +199,8 @@ private: uint8_t m_old_frame_energy_idx; uint8_t m_old_frame_pitch_idx; uint8_t m_old_frame_k_idx[10]; - bool m_old_zpar; - bool m_old_uv_zpar; + uint8_t m_old_zpar; + uint8_t m_old_uv_zpar; int32_t m_current_energy; int32_t m_current_pitch; @@ -215,11 +214,11 @@ private: uint8_t m_PC; /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */ /* NOTE: the interpolation period counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */ uint8_t m_IP; /* the current interpolation period */ - bool m_inhibit; /* If 1, interpolation is inhibited until the DIV1 period */ - bool m_uv_zpar; /* If 1, zero k5 thru k10 coefficients */ - bool m_zpar; /* If 1, zero ALL parameters. */ - bool m_pitch_zero; /* circuit 412; pitch is forced to zero under certain circumstances */ - uint8_t m_c_variant_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */ + uint8_t m_inhibit; /* If 1, interpolation is inhibited until the DIV1 period */ + uint8_t m_uv_zpar; /* If 1, zero k5 thru k10 coefficients */ + uint8_t m_zpar; /* If 1, zero ALL parameters. */ + uint8_t m_pitch_zero; /* circuit 412; pitch is forced to zero under certain circumstances */ + uint8_t m_c_variant_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */ uint16_t m_pitch_count; /* pitch counter; provides chirp rom address */ int32_t m_u[11]; @@ -233,17 +232,17 @@ private: The internal DAC used to feed the analog pin is only 8 bits, and has the funny clipping/clamping logic, while the digital pin gives full 10 bit resolution of the output data. - TODO: add an MCFG macro to set this other than the FORCE_DIGITAL define + TODO: add a way to set/reset this other than the FORCE_DIGITAL define */ - bool m_digital_select; + uint8_t m_digital_select; /* io_ready: page 3 of the datasheet specifies that READY will be asserted until * data is available or processed by the system. */ - bool m_io_ready; + uint8_t m_io_ready; /* flag for "true" timing involving rs/ws */ - bool m_true_timing; + uint8_t m_true_timing; /* rsws - state, rs bit 1, ws bit 0 */ uint8_t m_rs_ws; @@ -252,7 +251,6 @@ private: sound_stream *m_stream; emu_timer *m_timer_io_ready; - //emu_timer *m_timer_rsq_wsq_check; /* callbacks */ devcb_write_line m_irq_handler;