aboutsummaryrefslogtreecommitdiff
path: root/fmdriver
diff options
context:
space:
mode:
Diffstat (limited to 'fmdriver')
-rw-r--r--fmdriver/fmdriver.h8
-rw-r--r--fmdriver/fmdriver_fmp.c10
-rw-r--r--fmdriver/fmdriver_pmd.c13
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 {