# HG changeset patch # User Michael Pavone # Date 1582603589 28800 # Node ID 32a3aa7b4a45e821c7f2efe536ce75c7370ed86e # Parent 5433252329fbf6f9f124176ebe76138ec07313fd Fix YM2612 busy flag timing diff -r 5433252329fb -r 32a3aa7b4a45 genesis.c --- a/genesis.c Sun Feb 16 10:46:35 2020 -0800 +++ b/genesis.c Mon Feb 24 20:06:29 2020 -0800 @@ -403,11 +403,8 @@ } context->current_cycle -= deduction; z80_adjust_cycles(z_context, deduction); - gen->ym->current_cycle -= deduction; + ym_adjust_cycles(gen->ym, deduction); gen->psg->cycles -= deduction; - if (gen->ym->write_cycle != CYCLE_NEVER) { - gen->ym->write_cycle = gen->ym->write_cycle >= deduction ? gen->ym->write_cycle - deduction : 0; - } if (gen->reset_cycle != CYCLE_NEVER) { gen->reset_cycle -= deduction; } @@ -878,7 +875,7 @@ value = gen->zram[location & 0x1FFF]; } else if (location < 0x6000) { sync_sound(gen, context->current_cycle); - value = ym_read_status(gen->ym); + value = ym_read_status(gen->ym, context->current_cycle); } else { value = 0xFF; } @@ -991,7 +988,7 @@ z80_context * context = vcontext; genesis_context * gen = context->system; sync_sound(gen, context->Z80_CYCLE); - return ym_read_status(gen->ym); + return ym_read_status(gen->ym, context->Z80_CYCLE); } static uint8_t z80_read_bank(uint32_t location, void * vcontext) diff -r 5433252329fb -r 32a3aa7b4a45 ym2612.c --- a/ym2612.c Sun Feb 16 10:46:35 2020 -0800 +++ b/ym2612.c Mon Feb 24 20:06:29 2020 -0800 @@ -21,9 +21,7 @@ #define dfopen(var, fname, mode) #endif -#define BUSY_CYCLES_ADDRESS 17 -#define BUSY_CYCLES_DATA_LOW 83 -#define BUSY_CYCLES_DATA_HIGH 47 +#define BUSY_CYCLES 32 #define OP_UPDATE_PERIOD 144 #define BIT_TIMERA_ENABLE 0x1 @@ -122,6 +120,21 @@ render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS); } +void ym_adjust_cycles(ym2612_context *context, uint32_t deduction) +{ + context->current_cycle -= deduction; + if (context->write_cycle != CYCLE_NEVER && context->write_cycle >= deduction) { + context->write_cycle -= deduction; + } else { + context->write_cycle = CYCLE_NEVER; + } + if (context->busy_start != CYCLE_NEVER && context->busy_start >= deduction) { + context->busy_start -= deduction; + } else { + context->busy_start = CYCLE_NEVER; + } +} + #ifdef __ANDROID__ #define log2(x) (log(x)/log(2)) #endif @@ -173,6 +186,7 @@ dfopen(debug_file, "ym_debug.txt", "w"); memset(context, 0, sizeof(*context)); context->clock_inc = clock_div * 6; + context->busy_cycles = BUSY_CYCLES * context->clock_inc; context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2); //some games seem to expect that the LR flags start out as 1 @@ -635,10 +649,6 @@ } } - if (context->current_cycle >= context->write_cycle + (context->busy_cycles * context->clock_inc / 6)) { - context->status &= 0x7F; - context->write_cycle = CYCLE_NEVER; - } //printf("Done running YM2612 at cycle %d\n", context->current_cycle, to_cycle); } @@ -647,9 +657,6 @@ //printf("address_write_part1: %X\n", address); context->selected_reg = address; context->selected_part = 0; - context->write_cycle = context->current_cycle; - context->busy_cycles = BUSY_CYCLES_ADDRESS; - context->status |= 0x80; } void ym_address_write_part2(ym2612_context * context, uint8_t address) @@ -657,9 +664,6 @@ //printf("address_write_part2: %X\n", address); context->selected_reg = address; context->selected_part = 1; - context->write_cycle = context->current_cycle; - context->busy_cycles = BUSY_CYCLES_ADDRESS; - context->status |= 0x80; } static uint8_t fnum_to_keycode[] = { @@ -768,6 +772,9 @@ void ym_data_write(ym2612_context * context, uint8_t value) { + context->write_cycle = context->current_cycle; + context->busy_start = context->current_cycle + context->clock_inc; + if (context->selected_reg >= YM_REG_END) { return; } @@ -1108,15 +1115,15 @@ } } } - - context->write_cycle = context->current_cycle; - context->busy_cycles = context->selected_reg < 0xA0 ? BUSY_CYCLES_DATA_LOW : BUSY_CYCLES_DATA_HIGH; - context->status |= 0x80; } -uint8_t ym_read_status(ym2612_context * context) +uint8_t ym_read_status(ym2612_context * context, uint32_t cycle) { - return context->status; + uint8_t status = context->status; + if (cycle >= context->busy_start && cycle < context->busy_start + context->busy_cycles) { + status |= 0x80; + } + return status; } void ym_print_channel_info(ym2612_context *context, int channel) @@ -1228,7 +1235,7 @@ save_int8(buf, context->selected_part); save_int32(buf, context->current_cycle); save_int32(buf, context->write_cycle); - save_int32(buf, context->busy_cycles); + save_int32(buf, context->busy_start); } void ym_deserialize(deserialize_buffer *buf, void *vcontext) @@ -1303,5 +1310,5 @@ context->selected_part = load_int8(buf); context->current_cycle = load_int32(buf); context->write_cycle = load_int32(buf); - context->busy_cycles = load_int32(buf); + context->busy_start = load_int32(buf); } diff -r 5433252329fb -r 32a3aa7b4a45 ym2612.h --- a/ym2612.h Sun Feb 16 10:46:35 2020 -0800 +++ b/ym2612.h Mon Feb 24 20:06:29 2020 -0800 @@ -69,8 +69,8 @@ audio_source *audio; uint32_t clock_inc; uint32_t current_cycle; - //TODO: Condense the next two fields into one uint32_t write_cycle; + uint32_t busy_start; uint32_t busy_cycles; int32_t volume_mult; int32_t volume_div; @@ -134,11 +134,12 @@ void ym_free(ym2612_context *context); void ym_enable_zero_offset(ym2612_context *context, uint8_t enabled); void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock); +void ym_adjust_cycles(ym2612_context *context, uint32_t deduction); void ym_run(ym2612_context * context, uint32_t to_cycle); void ym_address_write_part1(ym2612_context * context, uint8_t address); void ym_address_write_part2(ym2612_context * context, uint8_t address); void ym_data_write(ym2612_context * context, uint8_t value); -uint8_t ym_read_status(ym2612_context * context); +uint8_t ym_read_status(ym2612_context * context, uint32_t cycle); uint8_t ym_load_gst(ym2612_context * context, FILE * gstfile); uint8_t ym_save_gst(ym2612_context * context, FILE * gstfile); void ym_print_channel_info(ym2612_context *context, int channel);