diff options
Diffstat (limited to 'fmdriver')
| -rw-r--r-- | fmdriver/fmdriver.h | 8 | ||||
| -rw-r--r-- | fmdriver/fmdriver_fmp.c | 10 | ||||
| -rw-r--r-- | fmdriver/fmdriver_pmd.c | 13 | 
3 files changed, 27 insertions, 4 deletions
| diff --git a/fmdriver/fmdriver.h b/fmdriver/fmdriver.h index aebe27e..b31c31e 100644 --- a/fmdriver/fmdriver.h +++ b/fmdriver/fmdriver.h @@ -101,11 +101,17 @@ struct fmdriver_work {    uint8_t ssg_noise_freq;    struct fmdriver_track_status track_status[FMDRIVER_TRACK_NUM];    uint8_t loop_cnt; +  // timerb value +  uint8_t timerb;    // current timerb count    uint32_t timerb_cnt; -  // loop length +  // current timerb count, reset on loop +  uint32_t timerb_cnt_loop; +  // loop length, calculated before playing    uint32_t loop_timerb_cnt;    // fm3ex part map +  bool playing; +  bool paused;  };  #endif // MYON_FMDRIVER_H_INCLUDED diff --git a/fmdriver/fmdriver_fmp.c b/fmdriver/fmdriver_fmp.c index 41d0a48..5e01089 100644 --- a/fmdriver/fmdriver_fmp.c +++ b/fmdriver/fmdriver_fmp.c @@ -304,6 +304,7 @@ static bool fmp_cmd62_tempo(struct fmdriver_work *work,    uint8_t tempo = fmp_part_cmdload(fmp, part);
    fmp->timerb_bak = tempo;
    fmp->timerb = tempo;
 +  work->timerb = fmp->timerb;
    fmp_set_tempo(work, fmp);
    return true;
  }
 @@ -876,6 +877,7 @@ static bool fmp_cmd74_loop(struct fmdriver_work *work,      // 248c
      fmp->loop_cnt++;
      work->loop_cnt = fmp->loop_cnt;
 +    work->timerb_cnt_loop = 0;
      fmp->part_loop_bit = fmp->part_playing_bit;
      // al=2; 1b64();
    }
 @@ -2854,6 +2856,7 @@ static void fmp_timerb(struct fmdriver_work *work, struct driver_fmp *fmp) {    if (fmp->status.stopped) {
      // TODO: stopped
      // jmp 18c7
 +    work->playing = false;
    }
    // 1829
    if (!--fmp->clock_divider) {
 @@ -2989,6 +2992,7 @@ static void fmp_init_parts(struct fmdriver_work *work,    // work->opna_writereg(work, 0x110, 0x80);
    fmp->timerb = 0xca;
 +  work->timerb = fmp->timerb;
    fmp->timerb_bak = 0xca;
    // 3c79
 @@ -3150,7 +3154,10 @@ static void fmp_opna_interrupt(struct fmdriver_work *work) {    struct driver_fmp *fmp = (struct driver_fmp *)work->driver;
    if (work->opna_status(work, 0) & 0x02) {
      fmp_timerb(work, fmp);
 -    work->timerb_cnt++;
 +    if (work->playing) {
 +      work->timerb_cnt++;
 +      work->timerb_cnt_loop++;
 +    }
    }
  }
 @@ -3495,6 +3502,7 @@ void fmp_init(struct fmdriver_work *work, struct driver_fmp *fmp) {    fmp_work_status_init(work, fmp);
    fmdriver_fillpcmname(work->pcmname[0], fmp->pvi_name);
    fmdriver_fillpcmname(work->pcmname[1], fmp->ppz_name);
 +  work->playing = true;
  }
  // 4235
 diff --git a/fmdriver/fmdriver_pmd.c b/fmdriver/fmdriver_pmd.c index 14459a5..ac2cad2 100644 --- a/fmdriver/fmdriver_pmd.c +++ b/fmdriver/fmdriver_pmd.c @@ -353,8 +353,8 @@ static void pmd_calc_tempo_rev(    int timerb = 0;    if (tempo) {      timerb = 0x112c / tempo; -    if (0x112c % tempo) timerb++;      timerb = 0x100 - timerb; +    if ((0x112c % tempo) & 0x80) timerb--;      if (timerb < 0) timerb = 0;    }    pmd->timerb = timerb; @@ -377,6 +377,7 @@ static void pmd_reset_timer(    struct driver_pmd *pmd  ) {    pmd->timerb = 200; +  work->timerb = pmd->timerb;    pmd->timerb_bak = pmd->timerb;    pmd_calc_tempo(pmd);    pmd_timerb_write(work, pmd); @@ -2345,6 +2346,7 @@ static void pmd_cmdfc_tempo(      pmd->tempo_bak = tempo;      pmd_calc_tempo_rev(pmd);    } +  work->timerb = pmd->timerb;  }  // 236b @@ -5537,9 +5539,12 @@ static void pmd_proc_parts(    }    // 130d    if (!pmd->loop.looped || !pmd->loop.ended || pmd->loop.env) { +    work->timerb_cnt_loop = 0;      if (++pmd->status2 == 0xff) pmd->status2 = 1;    } else {      pmd->status2 = 0xff; +    // stop +    work->playing = false;    }    work->loop_cnt = pmd->status2;  } @@ -5627,7 +5632,10 @@ static void pmd_timer(    }    if (status & 2) {      pmd_timerb(work, pmd); -    work->timerb_cnt++; +    if (work->playing) { +      work->timerb_cnt++; +      work->timerb_cnt_loop++; +    }    }  } @@ -5887,6 +5895,7 @@ void pmd_init(struct fmdriver_work *work,    }    fmdriver_fillpcmname(work->pcmname[0], pmd->ppcfile);    fmdriver_fillpcmname(work->pcmname[1], pmd->ppzfile); +  work->playing = true;  }  enum { | 
