diff --git a/src/emu/sound/tms5220.c b/src/emu/sound/tms5220.c index 5bf6ac33fe0..a5cc4c2b67c 100644 --- a/src/emu/sound/tms5220.c +++ b/src/emu/sound/tms5220.c @@ -974,7 +974,7 @@ static void tms5220_process(tms5220_state *tms, INT16 *buffer, unsigned int size else /*tms->pitch_count < 51*/ tms->excitation_data = tms->coeff->chirptable[tms->pitch_count]; #else // hack based sort of on the D68_10.ASM file from qboxpro, which has 0x580 and 0x3A80 at the end of its chirp table - if (tms->pitch_count >= 45) + if ((tms->pitch_count >= 45) || tms->pitch_count == 0) tms->excitation_data = -128; else /*tms->pitch_count < 45*/ tms->excitation_data = tms->coeff->chirptable[tms->pitch_count]; @@ -1115,7 +1115,7 @@ static INT32 lattice_filter(tms5220_state *tms) { /* Lattice filter here */ /* Aug/05/07: redone as unrolled loop, for clarity - LN*/ - /* Copied verbatim from table I in US patent 4,209,804: + /* Originally Copied verbatim from table I in US patent 4,209,804, now updated to be in same order as the actual chip does it, not that it matters. notation equivalencies from table: Yn(i) == tms->u[n-1] Kn = tms->current_k[n-1] @@ -1124,22 +1124,22 @@ static INT32 lattice_filter(tms5220_state *tms) tms->u[10] = matrix_multiply(tms->previous_energy, (tms->excitation_data*64)); //Y(11) tms->u[9] = tms->u[10] - matrix_multiply(tms->current_k[9], tms->x[9]); tms->u[8] = tms->u[9] - matrix_multiply(tms->current_k[8], tms->x[8]); - tms->x[9] = tms->x[8] + matrix_multiply(tms->current_k[8], tms->u[8]); tms->u[7] = tms->u[8] - matrix_multiply(tms->current_k[7], tms->x[7]); - tms->x[8] = tms->x[7] + matrix_multiply(tms->current_k[7], tms->u[7]); tms->u[6] = tms->u[7] - matrix_multiply(tms->current_k[6], tms->x[6]); - tms->x[7] = tms->x[6] + matrix_multiply(tms->current_k[6], tms->u[6]); tms->u[5] = tms->u[6] - matrix_multiply(tms->current_k[5], tms->x[5]); - tms->x[6] = tms->x[5] + matrix_multiply(tms->current_k[5], tms->u[5]); tms->u[4] = tms->u[5] - matrix_multiply(tms->current_k[4], tms->x[4]); - tms->x[5] = tms->x[4] + matrix_multiply(tms->current_k[4], tms->u[4]); tms->u[3] = tms->u[4] - matrix_multiply(tms->current_k[3], tms->x[3]); - tms->x[4] = tms->x[3] + matrix_multiply(tms->current_k[3], tms->u[3]); tms->u[2] = tms->u[3] - matrix_multiply(tms->current_k[2], tms->x[2]); - tms->x[3] = tms->x[2] + matrix_multiply(tms->current_k[2], tms->u[2]); tms->u[1] = tms->u[2] - matrix_multiply(tms->current_k[1], tms->x[1]); - tms->x[2] = tms->x[1] + matrix_multiply(tms->current_k[1], tms->u[1]); tms->u[0] = tms->u[1] - matrix_multiply(tms->current_k[0], tms->x[0]); + tms->x[9] = tms->x[8] + matrix_multiply(tms->current_k[8], tms->u[8]); + tms->x[8] = tms->x[7] + matrix_multiply(tms->current_k[7], tms->u[7]); + tms->x[7] = tms->x[6] + matrix_multiply(tms->current_k[6], tms->u[6]); + tms->x[6] = tms->x[5] + matrix_multiply(tms->current_k[5], tms->u[5]); + tms->x[5] = tms->x[4] + matrix_multiply(tms->current_k[4], tms->u[4]); + tms->x[4] = tms->x[3] + matrix_multiply(tms->current_k[3], tms->u[3]); + tms->x[3] = tms->x[2] + matrix_multiply(tms->current_k[2], tms->u[2]); + tms->x[2] = tms->x[1] + matrix_multiply(tms->current_k[1], tms->u[1]); tms->x[1] = tms->x[0] + matrix_multiply(tms->current_k[0], tms->u[0]); tms->x[0] = tms->u[0]; tms->previous_energy = tms->current_energy; @@ -1553,6 +1553,9 @@ static TIMER_CALLBACK( io_ready_cb ) update_ready_state(tms); } +/* + * /RS line write handler + */ WRITE_LINE_DEVICE_HANDLER( tms5220_rsq_w ) { tms5220_state *tms = get_safe_token(device); @@ -1590,21 +1593,22 @@ WRITE_LINE_DEVICE_HANDLER( tms5220_rsq_w ) } else { - /* high to low - schedule ready cycle*/ + /* high to low - schedule ready cycle */ #ifdef DEBUG_RS_WS - logerror("Schedule write ready\n"); + logerror("Scheduling ready cycle for /RS...\n"); #endif - //tms->io_ready = 1; - /* 100 nsec from data sheet, through 3 asynchronous gates on patent */ - //timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock), tms, 0, io_ready_cb); // /READY goes inactive immediately, within one clock... for that matter, what do we even need a timer for then? + /* 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. */ tms->io_ready = 0; update_ready_state(tms); - /* 25 usec (16 clocks) in datasheet */ + /* 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) */ timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock/16), tms, 1, io_ready_cb); // this should take around 10-16 (closer to ~11?) cycles to complete } } } +/* + * /WS line write handler + */ WRITE_LINE_DEVICE_HANDLER( tms5220_wsq_w ) { tms5220_state *tms = get_safe_token(device); @@ -1642,12 +1646,24 @@ WRITE_LINE_DEVICE_HANDLER( tms5220_wsq_w ) } else { - ///* high to low - schedule ready cycle*/ - //tms->io_ready = 1; - /* 100 nsec from data sheet, through 3 asynchronous gates on patent */ - //timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock), tms, 0, io_ready_cb); // /READY goes inactive immediately, within one clock... for that matter, what do we even need a timer for then? + /* 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. */ tms->io_ready = 0; update_ready_state(tms); + /* 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... + 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 only): ? cycles (probably ~16) + */ + // TODO: actually HANDLE the timing differences! currently just assuming always 16 cycles timer_set(tms->device->machine, ATTOTIME_IN_HZ(device->clock/16), tms, 1, io_ready_cb); // 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 } }