Mercurial > repos > blastem
diff lc8951.c @ 2144:10e4439d8f13
Fix speed of CDC to PCM RAM DMA
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 26 Mar 2022 00:54:47 -0700 |
parents | d9151d0894c7 |
children | 4cd60eecb0b1 |
line wrap: on
line diff
--- a/lc8951.c Fri Mar 25 21:41:33 2022 -0700 +++ b/lc8951.c Sat Mar 26 00:54:47 2022 -0700 @@ -85,11 +85,22 @@ //unclear if the difference is in the lc8951 or gate array context->regs[IFSTAT] = 0xFF; context->ar_mask = 0x1F; - context->clock_step = (2 + 2) * 6; // external divider, internal divider + DMA period + context->clock_step = (2 + 2); // external divider, internal divider + context->cycles_per_byte = context->clock_step * 6; context->byte_handler = byte_handler; context->handler_data = handler_data; context->decode_end = CYCLE_NEVER; context->transfer_end = CYCLE_NEVER; + context->next_byte_cycle = CYCLE_NEVER; +} + +void lc8951_set_dma_multiple(lc8951 *context, uint32_t multiple) +{ + context->cycles_per_byte = context->clock_step * multiple; + if (context->transfer_end != CYCLE_NEVER) { + uint16_t transfer_size = context->regs[DBCL] | (context->regs[DBCH] << 8); + context->transfer_end = context->next_byte_cycle + transfer_size * context->cycles_per_byte; + } } void lc8951_reg_write(lc8951 *context, uint8_t value) @@ -130,7 +141,8 @@ if (context->ifctrl & BIT_DOUTEN) { context->regs[IFSTAT] &= ~BIT_DTBSY; uint16_t transfer_size = context->regs[DBCL] | (context->regs[DBCH] << 8); - context->transfer_end = context->cycle + transfer_size * context->clock_step; + context->transfer_end = context->cycle + transfer_size * context->cycles_per_byte; + context->next_byte_cycle = context->cycle; printf("DTTRG: size %u, cycle %u, end %u\n", transfer_size, context->cycle, context->transfer_end); } break; @@ -251,8 +263,9 @@ } context->regs[STAT3] |= BIT_WLONG; } - if (context->transfer_end != CYCLE_NEVER) { + if (context->cycle >= context->next_byte_cycle) { if (context->byte_handler(context->handler_data, context->buffer[context->dac & (sizeof(context->buffer)-1)])) { + context->next_byte_cycle += context->cycles_per_byte; context->dac++; context->regs[DBCL]--; if (context->regs[DBCL] == 0xFF) { @@ -264,10 +277,12 @@ printf("Expected transfer end at %u but ended at %u\n", context->transfer_end, context->cycle); } context->transfer_end = CYCLE_NEVER; + context->next_byte_cycle = CYCLE_NEVER; } } } else { // pause transfer + context->next_byte_cycle = CYCLE_NEVER; context->transfer_end = CYCLE_NEVER; } } @@ -284,7 +299,8 @@ if (step_diff) { context->cycle -= step_diff * context->clock_step; } - context->transfer_end = context->cycle + transfer_size * context->clock_step; + context->transfer_end = context->cycle + transfer_size * context->cycles_per_byte; + context->next_byte_cycle = context->cycle; if (step_diff) { lc8951_run(context, cycle); }