aboutsummaryrefslogtreecommitdiff
path: root/fmdriver
diff options
context:
space:
mode:
authorTakamichi Horikawa <takamichiho@gmail.com>2017-02-19 17:25:56 +0900
committerTakamichi Horikawa <takamichiho@gmail.com>2017-02-19 17:25:56 +0900
commitd78900cd1497441d7712805b08072e46ee361ff8 (patch)
tree5a696ac5ffa4e6d71992c9329ff5b13ad14cf977 /fmdriver
parentbe500d48fbc381273dfdc600898f68df725aa954 (diff)
add opna status display
Diffstat (limited to 'fmdriver')
-rw-r--r--fmdriver/fmdriver.h35
-rw-r--r--fmdriver/fmdriver_fmp.c99
-rw-r--r--fmdriver/fmdriver_fmp.h30
-rw-r--r--fmdriver/ppz8.c2
4 files changed, 96 insertions, 70 deletions
diff --git a/fmdriver/fmdriver.h b/fmdriver/fmdriver.h
index e858567..a35f9b8 100644
--- a/fmdriver/fmdriver.h
+++ b/fmdriver/fmdriver.h
@@ -6,29 +6,46 @@
#include "ppz8.h"
enum {
- FMDRIVER_TRACK_NUM = 10,
+ FMDRIVER_TRACK_FM_1,
+ FMDRIVER_TRACK_FM_2,
+ FMDRIVER_TRACK_FM_3,
+ FMDRIVER_TRACK_FM_3_EX_1,
+ FMDRIVER_TRACK_FM_3_EX_2,
+ FMDRIVER_TRACK_FM_3_EX_3,
+ FMDRIVER_TRACK_FM_4,
+ FMDRIVER_TRACK_FM_5,
+ FMDRIVER_TRACK_FM_6,
+ FMDRIVER_TRACK_SSG_1,
+ FMDRIVER_TRACK_SSG_2,
+ FMDRIVER_TRACK_SSG_3,
+ FMDRIVER_TRACK_ADPCM,
+ FMDRIVER_TRACK_NUM
+};
+enum {
// 1 line = 80 characters, may contain half-width doublebyte characters
FMDRIVER_TITLE_BUFLEN = 80*2+1,
};
enum fmdriver_track_type {
- FMDRIVER_TRACK_FM,
- FMDRIVER_TRACK_SSG,
- FMDRIVER_TRACK_ADPCM,
+ FMDRIVER_TRACKTYPE_FM,
+ FMDRIVER_TRACKTYPE_SSG,
+ FMDRIVER_TRACKTYPE_ADPCM,
+ FMDRIVER_TRACKTYPE_CNT,
};
enum fmdriver_track_info {
FMDRIVER_TRACK_INFO_NORMAL,
FMDRIVER_TRACK_INFO_SSG_NOISE_ONLY,
FMDRIVER_TRACK_INFO_SSG_NOISE_MIX,
- FMDRIVER_TRACK_INFO_PPZ8
+ FMDRIVER_TRACK_INFO_FM3EX,
+ FMDRIVER_TRACK_INFO_PPZ8,
+ FMDRIVER_TRACK_INFO_PDZF,
};
struct fmdriver_track_status {
bool playing;
- enum fmdriver_track_type type;
+ bool masked;
enum fmdriver_track_info info;
- uint8_t num;
uint8_t ticks;
uint8_t ticks_left;
uint8_t key;
@@ -39,6 +56,10 @@ struct fmdriver_track_status {
uint8_t gate;
int8_t detune;
char status[9];
+ bool fmslotmask[4];
+ // for FMP, ppz8 channel+1 or 0
+ // use for track mask or display
+ uint8_t ppz8_ch;
};
struct fmdriver_work {
diff --git a/fmdriver/fmdriver_fmp.c b/fmdriver/fmdriver_fmp.c
index 8f3c948..efdcbb9 100644
--- a/fmdriver/fmdriver_fmp.c
+++ b/fmdriver/fmdriver_fmp.c
@@ -1594,7 +1594,7 @@ static void fmp_part_lfo_calc(struct driver_fmp *fmp,
static void fmp_part_keyon_fm(struct fmdriver_work *work,
struct driver_fmp *fmp,
struct fmp_part *part) {
- if (part->lfo_f.portamento) return;
+ if (part->lfo_f.mask) return;
// 27df
uint8_t out = part->opna_keyon_out;
if (part->type.fm_3) {
@@ -1734,7 +1734,7 @@ static void fmp_part_keyon(struct fmdriver_work *work,
part->lfo_f.lfo = false;
}
// 281e
- if (part->lfo_f.portamento) {
+ if (part->lfo_f.mask) {
part->u.ssg.env_f.attack = false;
part->u.ssg.env_f.portamento = true;
return;
@@ -2163,7 +2163,7 @@ static void fmp_part_ssg_env_reset(struct fmp_part *part) {
static void fmp_adpcm_addr_set(struct fmdriver_work *work,
struct driver_fmp *fmp,
struct fmp_part *part) {
- if (part->lfo_f.portamento) return;
+ if (part->lfo_f.mask) return;
work->opna_writereg(work, 0x100, 0x00);
work->opna_writereg(work, 0x100, 0x01);
//work->opna_writereg(work, 0x110, 0x08);
@@ -2212,7 +2212,7 @@ static void fmp_part_keyon_pre(struct driver_fmp *fmp, struct fmp_part *part) {
part->status.keyon = true;
if (part->type.ssg && !part->status.tie_cont && !part->u.ssg.env_f.ppz) {
part->u.ssg.env_f.portamento = false;
- if (!part->lfo_f.portamento) {
+ if (!part->lfo_f.mask) {
fmp_part_ssg_env_reset(part);
}
}
@@ -2727,68 +2727,52 @@ static uint8_t fmp_note2key(uint8_t note) {
return key;
}
+static const uint8_t fmp_track_map[FMDRIVER_TRACK_NUM] = {
+ FMP_PART_FM_1,
+ FMP_PART_FM_2,
+ FMP_PART_FM_3,
+ FMP_PART_FM_EX1,
+ FMP_PART_FM_EX2,
+ FMP_PART_FM_EX3,
+ FMP_PART_FM_4,
+ FMP_PART_FM_5,
+ FMP_PART_FM_6,
+ FMP_PART_SSG_1,
+ FMP_PART_SSG_2,
+ FMP_PART_SSG_3,
+ FMP_PART_ADPCM,
+};
+
static void fmp_work_status_init(struct fmdriver_work *work,
const struct driver_fmp *fmp) {
-
- static const uint8_t fmp_track_map[FMDRIVER_TRACK_NUM] = {
- FMP_PART_FM_1,
- FMP_PART_FM_2,
- FMP_PART_FM_3,
- FMP_PART_FM_4,
- FMP_PART_FM_5,
- FMP_PART_FM_6,
- FMP_PART_SSG_1,
- FMP_PART_SSG_2,
- FMP_PART_SSG_3,
- FMP_PART_ADPCM,
- };
-
for (int t = 0; t < FMDRIVER_TRACK_NUM; t++) {
struct fmdriver_track_status *track = &work->track_status[t];
const struct fmp_part *part = &fmp->parts[fmp_track_map[t]];
track->playing = !part->status.off;
- track->num = (part->pdzf.mode ? part->pdzf.ppz8_channel : part->opna_keyon_out)+1;
track->info = FMDRIVER_TRACK_INFO_NORMAL;
- if (part->type.adpcm) {
- track->type = FMDRIVER_TRACK_ADPCM;
- } else if (part->type.ssg) {
- track->type = FMDRIVER_TRACK_SSG;
- } else {
- track->type = FMDRIVER_TRACK_FM;
- }
- if (part->type.fm && part->opna_keyon_out > 3) {
- track->num--;
- }
+ }
+ for (int i = 0; i < 3; i++) {
+ work->track_status[FMDRIVER_TRACK_SSG_1+i].ppz8_ch = 1+i;
+ work->track_status[FMDRIVER_TRACK_FM_3_EX_1+i].ppz8_ch = 4+i;
}
}
static void fmp_work_status_update(struct fmdriver_work *work,
const struct driver_fmp *fmp) {
work->ssg_noise_freq = fmp->ssg_noise_freq;
- static const uint8_t fmp_track_map[FMDRIVER_TRACK_NUM] = {
- FMP_PART_FM_1,
- FMP_PART_FM_2,
- FMP_PART_FM_3,
- FMP_PART_FM_4,
- FMP_PART_FM_5,
- FMP_PART_FM_6,
- FMP_PART_SSG_1,
- FMP_PART_SSG_2,
- FMP_PART_SSG_3,
- FMP_PART_ADPCM,
- };
-
for (int t = 0; t < FMDRIVER_TRACK_NUM; t++) {
struct fmdriver_track_status *track = &work->track_status[t];
const struct fmp_part *part = &fmp->parts[fmp_track_map[t]];
track->playing = !part->status.off;
- track->num = (part->pdzf.mode ? part->pdzf.ppz8_channel : part->opna_keyon_out)+1;
track->info = FMDRIVER_TRACK_INFO_NORMAL;
if (part->type.adpcm) {
track->actual_key = 0xff;
track->volume = part->actual_vol;
} else if (part->type.ssg) {
- if (part->u.ssg.env_f.ppz || part->pdzf.mode) {
+ if (part->pdzf.mode) {
+ track->info = FMDRIVER_TRACK_INFO_PDZF;
+ track->actual_key = 0xff;
+ } else if (part->u.ssg.env_f.ppz) {
track->info = FMDRIVER_TRACK_INFO_PPZ8;
track->actual_key = 0xff;
} else {
@@ -2803,16 +2787,19 @@ static void fmp_work_status_update(struct fmdriver_work *work,
track->volume = part->current_vol - 1;
} else {
if (part->pdzf.mode) {
- track->info = FMDRIVER_TRACK_INFO_PPZ8;
+ track->info = FMDRIVER_TRACK_INFO_PDZF;
track->actual_key = 0xff;
} else {
+ if (part->u.fm.slot_mask & 0xf0) {
+ track->info = FMDRIVER_TRACK_INFO_FM3EX;
+ for (int s = 0; s < 4; s++) {
+ track->fmslotmask[s] = part->u.fm.slot_mask & (1<<(4+s));
+ }
+ }
track->actual_key = part->status.rest ? 0xff : fmp_fm_freq2key(part->prev_freq);
}
track->volume = 0x7f - part->actual_vol;
}
- if (part->type.fm && part->opna_keyon_out > 3) {
- track->num--;
- }
track->ticks = part->status.off ? 0 : part->tonelen-1;
track->ticks_left = part->tonelen_cnt;
track->key = part->status.rest ? 0xff : fmp_note2key(part->prev_note);
@@ -3456,6 +3443,22 @@ bool fmp_load(struct driver_fmp *fmp,
return true;
}
+static const uint8_t fmp_fmdriver_track_map[FMDRIVER_TRACK_NUM] = {
+ FMP_PART_FM_1,
+ FMP_PART_FM_2,
+ FMP_PART_FM_3,
+ FMP_PART_FM_EX1,
+ FMP_PART_FM_EX2,
+ FMP_PART_FM_EX3,
+ FMP_PART_FM_4,
+ FMP_PART_FM_5,
+ FMP_PART_FM_6,
+ FMP_PART_SSG_1,
+ FMP_PART_SSG_2,
+ FMP_PART_SSG_3,
+ FMP_PART_ADPCM
+};
+
void fmp_init(struct fmdriver_work *work, struct driver_fmp *fmp) {
fmp_title(work, fmp, read16le(fmp->data)+4);
fmp_struct_init(work, fmp);
diff --git a/fmdriver/fmdriver_fmp.h b/fmdriver/fmdriver_fmp.h
index d70013c..5211a80 100644
--- a/fmdriver/fmdriver_fmp.h
+++ b/fmdriver/fmdriver_fmp.h
@@ -116,7 +116,7 @@ struct fmp_part {
// 0000
struct {
// 0x01
- bool portamento: 1;
+ bool mask: 1;
// 0x02
bool lfo: 1; // ?
// 0x04
@@ -226,20 +226,20 @@ struct fmp_part {
// SSG backup??
} type;
// 0b00xx x0xx xxxx xxxx
- // || | || |||| ||||
- // || | || |||| |||`- FM#1
- // || | || |||| ||`-- FM#2
- // || | || |||| |`--- FM#3
- // || | || |||| `---- FM#4
- // || | || |||`------ FM#5
- // || | || ||`------- FM#6
- // || | || |`-------- SSG#1
- // || | || `--------- SSG#2
- // || | |`----------- SSG#3
- // || | `------------ rhythm
- // || `-------------- FMEX#1
- // |`---------------- FMEX#2
- // `----------------- FMEX#3
+ // || | || |||| ||||
+ // || | || |||| |||`- FM#1
+ // || | || |||| ||`-- FM#2
+ // || | || |||| |`--- FM#3
+ // || | || |||| `---- FM#4
+ // || | || |||`------ FM#5
+ // || | || ||`------- FM#6
+ // || | || |`-------- SSG#1
+ // || | || `--------- SSG#2
+ // || | |`----------- SSG#3
+ // || | `------------ rhythm
+ // || `-------------- FMEX#1
+ // |`---------------- FMEX#2
+ // `----------------- FMEX#3
// 004c
uint16_t part_bit;
// 004e
diff --git a/fmdriver/ppz8.c b/fmdriver/ppz8.c
index 39caf0d..8838367 100644
--- a/fmdriver/ppz8.c
+++ b/fmdriver/ppz8.c
@@ -1,5 +1,6 @@
#include "ppz8.h"
#include "fmdriver_common.h"
+#include <stdio.h>
void ppz8_init(struct ppz8 *ppz8, uint16_t srate, uint16_t mix_volume) {
for (int i = 0; i < 2; i++) {
@@ -269,6 +270,7 @@ static void ppz8_channel_loopoffset(struct ppz8 *ppz8, uint8_t ch,
struct ppz8_channel *channel = &ppz8->channel[ch];
channel->loopstartoff = startoff;
channel->loopendoff = endoff;
+ fprintf(stderr, "channel: %d, start: %08x, end: %08x\n", ch, startoff, endoff);
}
static void ppz8_channel_pan(struct ppz8 *ppz8, uint8_t ch, uint8_t pan) {