Mercurial > repos > blastem
comparison ym2612.c @ 403:f0a3f86595ae
Fix YM2612 timers
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 16 Jun 2013 00:56:23 -0700 |
parents | 09328dbe6700 |
children | b1bc1947d949 |
comparison
equal
deleted
inserted
replaced
402:de2c085ce174 | 403:f0a3f86595ae |
---|---|
157 } | 157 } |
158 | 158 |
159 #define YM_VOLUME_DIVIDER 2 | 159 #define YM_VOLUME_DIVIDER 2 |
160 #define YM_MOD_SHIFT 1 | 160 #define YM_MOD_SHIFT 1 |
161 | 161 |
162 #define TIMER_A_MAX 1023 | |
163 #define TIMER_B_MAX (255*16) | |
164 | |
162 void ym_run(ym2612_context * context, uint32_t to_cycle) | 165 void ym_run(ym2612_context * context, uint32_t to_cycle) |
163 { | 166 { |
164 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle); | 167 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle); |
165 //TODO: Fix channel update order OR remap channels in register write | 168 //TODO: Fix channel update order OR remap channels in register write |
166 for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) { | 169 for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) { |
167 //Update timers at beginning of 144 cycle period | 170 //Update timers at beginning of 144 cycle period |
168 if (!context->current_op && context->timer_control & BIT_TIMERA_ENABLE) { | 171 if (!context->current_op) { |
169 if (context->timer_a) { | 172 if (context->timer_control & BIT_TIMERA_ENABLE) { |
170 context->timer_a--; | 173 if (context->timer_a != TIMER_A_MAX) { |
171 } else { | 174 context->timer_a++; |
172 if (context->timer_control & BIT_TIMERA_OVEREN) { | 175 } else { |
173 context->status |= BIT_STATUS_TIMERA; | 176 if (context->timer_control & BIT_TIMERA_OVEREN) { |
174 } | 177 context->status |= BIT_STATUS_TIMERA; |
175 context->timer_a = context->timer_a_load; | 178 } |
179 context->timer_a = context->timer_a_load; | |
180 } | |
176 } | 181 } |
177 if (context->timer_control & BIT_TIMERB_ENABLE) { | 182 if (context->timer_control & BIT_TIMERB_ENABLE) { |
178 uint32_t b_cyc = (context->current_cycle / OP_UPDATE_PERIOD) % 16; | 183 if (context->timer_b != TIMER_B_MAX) { |
179 if (!b_cyc) { | 184 context->timer_b++; |
180 if (context->timer_b) { | 185 } else { |
181 context->timer_b--; | 186 if (context->timer_control & BIT_TIMERB_OVEREN) { |
182 } else { | 187 context->status |= BIT_STATUS_TIMERB; |
183 if (context->timer_control & BIT_TIMERB_OVEREN) { | 188 } |
184 context->status |= BIT_STATUS_TIMERB; | 189 context->timer_b = context->timer_b_load; |
185 } | |
186 context->timer_b = context->timer_b_load; | |
187 } | |
188 } | 190 } |
189 } | 191 } |
190 } | 192 } |
191 //Update Envelope Generator | 193 //Update Envelope Generator |
192 if (!(context->current_op % 3)) { | 194 if (!(context->current_op % 3)) { |
510 case REG_TIMERA_LOW: | 512 case REG_TIMERA_LOW: |
511 context->timer_a_load &= 0xFFFC; | 513 context->timer_a_load &= 0xFFFC; |
512 context->timer_a_load |= value & 0x3; | 514 context->timer_a_load |= value & 0x3; |
513 break; | 515 break; |
514 case REG_TIMERB: | 516 case REG_TIMERB: |
515 context->timer_b_load = value; | 517 context->timer_b_load = value * 16; |
516 break; | 518 break; |
517 case REG_TIME_CTRL: { | 519 case REG_TIME_CTRL: { |
518 context->timer_control = value & 0x3F; | 520 if (value & BIT_TIMERA_ENABLE && !(context->timer_control & BIT_TIMERA_ENABLE)) { |
521 context->timer_a = context->timer_a_load; | |
522 } | |
523 if (value & BIT_TIMERB_ENABLE && !(context->timer_control & BIT_TIMERB_ENABLE)) { | |
524 context->timer_b = context->timer_b_load; | |
525 } | |
526 context->timer_control = value & 0xF; | |
527 if (value & BIT_TIMERA_RESET) { | |
528 context->status &= ~BIT_STATUS_TIMERA; | |
529 } | |
530 if (value & BIT_TIMERB_RESET) { | |
531 context->status &= ~BIT_STATUS_TIMERB; | |
532 } | |
519 uint8_t old_mode = context->ch3_mode; | 533 uint8_t old_mode = context->ch3_mode; |
520 context->ch3_mode = value & 0xC0; | 534 context->ch3_mode = value & 0xC0; |
521 if (context->ch3_mode != old_mode) { | 535 if (context->ch3_mode != old_mode) { |
522 ym_update_phase_inc(context, context->operators + 2*4, 2*4); | 536 ym_update_phase_inc(context, context->operators + 2*4, 2*4); |
523 ym_update_phase_inc(context, context->operators + 2*4+1, 2*4+1); | 537 ym_update_phase_inc(context, context->operators + 2*4+1, 2*4+1); |