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);