diff options
Diffstat (limited to 'src/devices/sound/tms5220.cpp')
-rw-r--r-- | src/devices/sound/tms5220.cpp | 214 |
1 files changed, 144 insertions, 70 deletions
diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index ca743e73d70..bb050d53182 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -525,7 +525,7 @@ static void printbits(long data, int num) { int i; for (i=(num-1); i>=0; i--) - fprintf(stderr,"%0ld", (data>>i)&1); + logerror("%0ld", (data>>i)&1); } #endif #ifdef DEBUG_PARSE_FRAME_DUMP_HEX @@ -534,19 +534,19 @@ static void printbits(long data, int num) switch((num-1)&0xFC) { case 0: - fprintf(stderr,"%0lx", data); + logerror("%0lx", data); break; case 4: - fprintf(stderr,"%02lx", data); + logerror("%02lx", data); break; case 8: - fprintf(stderr,"%03lx", data); + logerror("%03lx", data); break; case 12: - fprintf(stderr,"%04lx", data); + logerror("%04lx", data); break; default: - fprintf(stderr,"%04lx", data); + logerror("%04lx", data); break; } } @@ -625,7 +625,7 @@ void tms5220_device::data_write(int data) m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE; m_fifo_count++; #ifdef DEBUG_FIFO - fprintf(stderr,"data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count); + logerror("data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count); #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) @@ -633,7 +633,7 @@ void tms5220_device::data_write(int data) { int i; #ifdef DEBUG_FIFO - fprintf(stderr,"data_write triggered SPEN to go active!\n"); + 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 = 1; @@ -662,7 +662,7 @@ void tms5220_device::data_write(int data) else { #ifdef DEBUG_FIFO - fprintf(stderr,"data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n"); + logerror("data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n"); // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it. #endif } @@ -736,7 +736,7 @@ void tms5220_device::update_fifo_status_and_ints() if (m_previous_TALK_STATUS == 1 && (TALK_STATUS == 0)) { #ifdef VERBOSE - fprintf(stderr,"Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); + logerror("Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); #endif set_interrupt_state(1); m_DDIS = 0; @@ -825,7 +825,7 @@ int tms5220_device::status_read() /* clear the interrupt pin on status read */ set_interrupt_state(0); #ifdef DEBUG_PIN_READS - fprintf(stderr,"Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS, m_buffer_low, m_buffer_empty); + logerror("Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS, m_buffer_low, m_buffer_empty); #endif return (TALK_STATUS << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5); } @@ -841,7 +841,7 @@ int tms5220_device::status_read() int tms5220_device::ready_read() { #ifdef DEBUG_PIN_READS - fprintf(stderr,"ready_read: ready pin read, io_ready is %d, fifo count is %d, DDIS(speak external) is %d\n", m_io_ready, m_fifo_count, m_DDIS); + logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d, DDIS(speak external) is %d\n", m_io_ready, m_fifo_count, m_DDIS); #endif return ((m_fifo_count < FIFO_SIZE)||(!m_DDIS)) && m_io_ready; } @@ -899,7 +899,7 @@ int tms5220_device::cycles_to_ready() int tms5220_device::int_read() { #ifdef DEBUG_PIN_READS - fprintf(stderr,"int_read: irq pin read, state is %d\n", m_irq_pin); + logerror("int_read: irq pin read, state is %d\n", m_irq_pin); #endif return m_irq_pin; } @@ -918,7 +918,7 @@ void tms5220_device::process(INT16 *buffer, unsigned int size) INT32 this_sample; #ifdef VERBOSE - fprintf(stderr,"process called with size of %d; IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", size, m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); + logerror("process called with size of %d; IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", size, m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); #endif /* loop until the buffer is full or we've stopped speaking */ @@ -975,14 +975,14 @@ void tms5220_device::process(INT16 *buffer, unsigned int size) #ifdef DEBUG_GENERATION /* Debug info for current parsed frame */ - fprintf(stderr, "OLDE: %d; NEWE: %d; OLDP: %d; NEWP: %d ", OLD_FRAME_SILENCE_FLAG, NEW_FRAME_SILENCE_FLAG, OLD_FRAME_UNVOICED_FLAG, NEW_FRAME_UNVOICED_FLAG); - fprintf(stderr,"Processing new 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 == 0) - fprintf(stderr, "Normal Frame\n"); + logerror( "Normal Frame\n"); else - fprintf(stderr,"Interpolation Inhibited\n"); - fprintf(stderr,"*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); - fprintf(stderr,"*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n", + logerror("Interpolation Inhibited\n"); + logerror("*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); + logerror("*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n", (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)), m_new_frame_energy_idx, (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)), @@ -1006,7 +1006,7 @@ void tms5220_device::process(INT16 *buffer, unsigned int size) 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 int current_sample = (m_subcycle - m_subc_reload)+(m_PC*(3-m_subc_reload))+((m_subc_reload?25:38)*((m_IP-1)&7)); - //fprintf(stderr, "CS: %03d", current_sample); + //logerror( "CS: %03d", current_sample); // reset the current energy, pitch, etc to what it was at frame start m_current_energy = (m_coeff->energytable[m_old_frame_energy_idx] * (1-m_old_zpar)); m_current_pitch = (m_coeff->pitchtable[m_old_frame_pitch_idx] * (1-m_old_zpar)); @@ -1089,18 +1089,18 @@ void tms5220_device::process(INT16 *buffer, unsigned int size) } this_sample = lattice_filter(); /* execute lattice filter */ #ifdef DEBUG_GENERATION_VERBOSE - //fprintf(stderr,"C:%01d; ",m_subcycle); - fprintf(stderr,"IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); - //fprintf(stderr,"X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); + //logerror("C:%01d; ",m_subcycle); + logerror("IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); + //logerror("X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); for (i=0; i<10; i++) - fprintf(stderr,"K%d:%04d ", i+1, m_current_k[i]); - fprintf(stderr,"Out:%06d ", this_sample); + logerror("K%d:%04d ", i+1, m_current_k[i]); + logerror("Out:%06d ", this_sample); //#ifdef PERFECT_INTERPOLATION_HACK -// fprintf(stderr,"%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar); +// logerror("%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar); //#else -// fprintf(stderr,"x%dx%d",m_zpar,m_uv_zpar); +// logerror("x%dx%d",m_zpar,m_uv_zpar); //#endif - fprintf(stderr,"\n"); + logerror("\n"); #endif /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */ while (this_sample > 16383) this_sample -= 32768; @@ -1145,17 +1145,17 @@ void tms5220_device::process(INT16 *buffer, unsigned int size) OLD_FRAME_UNVOICED_FLAG = NEW_FRAME_UNVOICED_FLAG; // 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 - fprintf(stderr,"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); + 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); #endif #ifdef DEBUG_GENERATION if ((!m_TALK) && (!m_SPEN)) - fprintf(stderr,"tms5220_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n"); + logerror("tms5220_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n"); #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 = 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 - fprintf(stderr,"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); + 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 } m_subcycle = m_subc_reload; @@ -1217,7 +1217,7 @@ static INT16 clip_analog(INT16 cliptemp) * 0x xxxx xxxx xxxx -> 0b01111111 */ #ifdef DEBUG_CLIP - if ((cliptemp > 2047) || (cliptemp < -2048)) fprintf(stderr,"clipping cliptemp to range; was %d\n", cliptemp); + if ((cliptemp > 2047) || (cliptemp < -2048)) logerror("clipping cliptemp to range; was %d\n", cliptemp); #endif if (cliptemp > 2047) cliptemp = 2047; else if (cliptemp < -2048) cliptemp = -2048; @@ -1257,8 +1257,8 @@ static INT32 matrix_multiply(INT32 a, INT32 b) while (b<-16384) { b+=32768; } result = ((a*b)>>9); /** TODO: this isn't technically right to the chip, which truncates the lowest result bit, but it causes glitches otherwise. **/ #ifdef VERBOSE - if (result>16383) fprintf(stderr,"matrix multiplier overflowed! a: %x, b: %x, result: %x", a, b, result); - if (result<-16384) fprintf(stderr,"matrix multiplier underflowed! a: %x, b: %x, result: %x", a, b, result); + if (result>16383) logerror("matrix multiplier overflowed! a: %x, b: %x, result: %x", a, b, result); + if (result<-16384) logerror("matrix multiplier underflowed! a: %x, b: %x, result: %x", a, b, result); #endif return result; } @@ -1321,18 +1321,18 @@ INT32 tms5220_device::lattice_filter() m_previous_energy = m_current_energy; #ifdef DEBUG_LATTICE int i; - fprintf(stderr,"V:%04d ", m_u[10]); + logerror("V:%04d ", m_u[10]); for (i = 9; i >= 0; i--) { - fprintf(stderr,"Y%d:%04d ", i+1, m_u[i]); + logerror("Y%d:%04d ", i+1, m_u[i]); } - fprintf(stderr,"\n"); - fprintf(stderr,"E:%04d ", err); + logerror("\n"); + logerror("E:%04d ", err); for (i = 9; i >= 0; i--) { - fprintf(stderr,"b%d:%04d ", i+1, m_x[i]); + logerror("b%d:%04d ", i+1, m_x[i]); } - fprintf(stderr,"\n"); + logerror("\n"); #endif return m_u[0]; } @@ -1348,7 +1348,7 @@ void tms5220_device::process_command(unsigned char cmd) { int i; #ifdef DEBUG_COMMAND_DUMP - fprintf(stderr,"process_command called with parameter %02X\n",cmd); + logerror("process_command called with parameter %02X\n",cmd); #endif /* parse the command */ switch (cmd & 0x70) @@ -1379,7 +1379,7 @@ void tms5220_device::process_command(unsigned char cmd) if (TALK_STATUS == 0) /* TALKST must be clear for RB */ { #ifdef VERBOSE - fprintf(stderr,"read and branch command received\n"); + logerror("read and branch command received\n"); #endif m_RDB_flag = FALSE; if (m_speechrom) @@ -1495,7 +1495,7 @@ void tms5220_device::parse_frame() i = extract_bits(2); #ifdef DEBUG_PARSE_FRAME_DUMP printbits(i,2); - fprintf(stderr," "); + logerror(" "); #endif m_IP = reload_table[i]; } @@ -1509,7 +1509,7 @@ void tms5220_device::parse_frame() m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits); #ifdef DEBUG_PARSE_FRAME_DUMP printbits(m_new_frame_energy_idx,m_coeff->energy_bits); - fprintf(stderr," "); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1522,14 +1522,14 @@ void tms5220_device::parse_frame() rep_flag = extract_bits(1); #ifdef DEBUG_PARSE_FRAME_DUMP printbits(rep_flag, 1); - fprintf(stderr," "); + logerror(" "); #endif // attempt to extract the pitch m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits); #ifdef DEBUG_PARSE_FRAME_DUMP printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits); - fprintf(stderr," "); + logerror(" "); #endif // if the new frame is unvoiced, be sure to zero out the k5-k10 parameters m_uv_zpar = NEW_FRAME_UNVOICED_FLAG; @@ -1545,7 +1545,7 @@ void tms5220_device::parse_frame() m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); - fprintf(stderr," "); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1564,25 +1564,25 @@ void tms5220_device::parse_frame() m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); - fprintf(stderr," "); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; } #ifdef DEBUG_PARSE_FRAME_DUMP - fprintf(stderr,"\n"); + logerror("\n"); #endif #ifdef VERBOSE if (m_DDIS) - fprintf(stderr,"Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); + logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); else - fprintf(stderr,"Parsed a frame successfully in ROM\n"); + logerror("Parsed a frame successfully in ROM\n"); #endif return; ranout: #ifdef DEBUG_FRAME_ERRORS - fprintf(stderr,"Ran out of bits on a parse!\n"); + logerror("Ran out of bits on a parse!\n"); #endif return; } @@ -1597,7 +1597,7 @@ 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 #ifdef DEBUG_PIN_READS - fprintf(stderr,"irq pin set to state %d\n", state); + logerror("irq pin set to state %d\n", state); #endif if (!m_irq_handler.isnull() && state != m_irq_pin) m_irq_handler(!state); @@ -1614,7 +1614,7 @@ void tms5220_device::update_ready_state() { int state = ready_read(); #ifdef DEBUG_PIN_READS - fprintf(stderr,"ready pin set to state %d\n", state); + logerror("ready pin set to state %d\n", state); #endif if (!m_readyq_handler.isnull() && state != m_ready_pin) m_readyq_handler(!state); @@ -1759,7 +1759,7 @@ void tms5220_device::device_reset() m_speechrom->read(1); m_schedule_dummy_read = FALSE; } - + // 5110 specific stuff m_PDC = 0; m_CTL_pins = 0; @@ -1790,8 +1790,8 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para /* Write */ /* bring up to date first */ #ifdef DEBUG_IO_READY - fprintf(stderr,"Serviced write: %02x\n", m_write_latch); - //fprintf(stderr, "Processed write data: %02X\n", m_write_latch); + logerror("Serviced write: %02x\n", m_write_latch); + //logerror( "Processed write data: %02X\n", m_write_latch); #endif m_stream->update(); data_write(m_write_latch); @@ -1802,7 +1802,7 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para m_stream->update(); m_read_latch = status_read(); #ifdef DEBUG_IO_READY - fprintf(stderr,"Serviced read, returning %02x\n", m_read_latch); + logerror("Serviced read, returning %02x\n", m_read_latch); #endif break; case 0x03: @@ -1829,7 +1829,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) m_true_timing = 1; state &= 0x01; #ifdef DEBUG_RS_WS - fprintf(stderr,"/RS written with data: %d\n", state); + logerror("/RS written with data: %d\n", state); #endif new_val = (m_rs_ws & 0x01) | (state<<1); if (new_val != m_rs_ws) @@ -1842,7 +1842,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) #ifdef DEBUG_RS_WS else /* illegal */ - fprintf(stderr,"tms5220_rs_w: illegal\n"); + logerror("tms5220_rsq_w: illegal\n"); #endif return; } @@ -1860,7 +1860,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) { /* high to low - schedule ready cycle */ #ifdef DEBUG_RS_WS - fprintf(stderr,"Scheduling ready cycle for /RS...\n"); + 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 = 0; @@ -1881,7 +1881,7 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) m_true_timing = 1; state &= 0x01; #ifdef DEBUG_RS_WS - fprintf(stderr,"/WS written with data: %d\n", state); + logerror("/WS written with data: %d\n", state); #endif new_val = (m_rs_ws & 0x02) | (state<<0); if (new_val != m_rs_ws) @@ -1889,12 +1889,12 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) m_rs_ws = new_val; if (new_val == 0) { - if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, ? for cd2501ecd + if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, probably also correct for cd2501ecd reset(); #ifdef DEBUG_RS_WS else /* illegal */ - fprintf(stderr,"tms5220_ws_w: illegal\n"); + logerror("tms5220_wsq_w: illegal\n"); #endif return; } @@ -1912,12 +1912,12 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) { /* high to low - schedule ready cycle */ #ifdef DEBUG_RS_WS - fprintf(stderr,"Scheduling ready cycle for /WS...\n"); + 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 = 0; update_ready_state(); - /* Now comes the complicated part: 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... + /* 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 Command Mode: SPK: ? cycles @@ -1933,6 +1933,80 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) } } +/* + * combined /RS and /WS line write handler; + * /RS is bit 1, /WS is bit 0 + * Note this is a hack and probably can be removed later, once the 'real' line handlers above defer by at least 4 clock cycles before taking effect + */ +WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) +{ + UINT8 new_val; + UINT8 falling_edges; + 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 + new_val = data&0x03; + if (new_val != m_rs_ws) + { + falling_edges = ((m_rs_ws^new_val)&(~new_val)); + m_rs_ws = new_val; + switch(new_val) + { + case 0: + if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, probably also correct for cd2501ecd + reset(); +#ifdef DEBUG_RS_WS + else + /* illegal */ + logerror("tms5220_combined_rsq_wsq_w: illegal\n"); +#endif + return; + case 3: + /* high impedance */ + m_read_latch = 0xff; + return; + case 2: // /WS active, /RS not + /* check for falling or rising edge */ + if (!(falling_edges&0x01)) return; /* low to high, do nothing */ + /* high to low - schedule ready cycle */ +#ifdef DEBUG_RS_WS + 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 = 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 + Command Mode: + SPK: ? cycles + SPKEXT: ? cycles + RDBY: between 60 and 140 cycles + RB: ? cycles (80?) + RST: between 60 and 140 cycles + SET RATE (5220C and CD2501ECD only): ? cycles (probably ~16) + */ + // TODO: actually HANDLE the timing differences! currently just assuming always 16 cycles + m_timer_io_ready->adjust(attotime::from_hz(clock()/16), 1); // this should take around 10-16 (closer to ~15) cycles to complete for fifo writes, TODO: but actually depends on what command is written if in command mode + return; + case 1: // /RS active, /WS not + /* check for falling or rising edge */ + if (!(falling_edges&0x02)) return; /* low to high, do nothing */ + /* high to low - schedule ready cycle */ +#ifdef DEBUG_RS_WS + 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 = 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(attotime::from_hz(clock()/16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete + return; + } + } +} + + /********************************************************************************************** tms5220_data_w -- write data to the sound chip @@ -1945,7 +2019,7 @@ WRITE8_MEMBER( tms5220_device::data_w ) if (space.debugger_access()) return; #ifdef DEBUG_RS_WS - fprintf(stderr,"tms5220_data_w: data %02x\n", data); + logerror("tms5220_data_w: data %02x\n", data); #endif if (!m_true_timing) { @@ -1958,7 +2032,7 @@ WRITE8_MEMBER( tms5220_device::data_w ) /* actually in a write ? */ #ifdef DEBUG_RS_WS if (!(m_rs_ws == 0x02)) - fprintf(stderr,"tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); + logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); #endif m_write_latch = data; } @@ -1990,7 +2064,7 @@ READ8_MEMBER( tms5220_device::status_r ) return m_read_latch; #ifdef DEBUG_RS_WS else - fprintf(stderr,"tms5220_status_r: data read outside rs!\n"); + logerror("tms5220_status_r: data read outside rs!\n"); #endif return 0xff; } |