1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
#ifndef MYON_FMDRIVER_PMD_H_INCLUDED
#define MYON_FMDRIVER_PMD_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include "fmdriver.h"
enum {
PMD_FILENAMELEN = 8+1+3
};
enum {
PMD_PART_FM_1,
PMD_PART_FM_2,
PMD_PART_FM_3,
PMD_PART_FM_4,
PMD_PART_FM_5,
PMD_PART_FM_6,
PMD_PART_SSG_1,
PMD_PART_SSG_2,
PMD_PART_SSG_3,
PMD_PART_ADPCM,
PMD_PART_RHYTHM,
PMD_PART_FM_3B,
PMD_PART_FM_3C,
PMD_PART_FM_3D,
PMD_PART_PPZ_1,
PMD_PART_PPZ_2,
PMD_PART_PPZ_3,
PMD_PART_PPZ_4,
PMD_PART_PPZ_5,
PMD_PART_PPZ_6,
PMD_PART_PPZ_7,
PMD_PART_PPZ_8,
PMD_PART_FM_EFF,
PMD_PART_NUM,
};
struct pmd_lfo {
uint8_t delay;
uint8_t speed;
uint8_t step;
uint8_t times;
};
struct pmd_part {
// 0000
uint16_t ptr;
// 0002
uint16_t loop_ptr;
// 0004
uint8_t len_cnt;
// 0005
uint8_t gate;
// 0006
uint16_t actual_freq;
// 0008
int16_t detune;
// 000a
int16_t lfo_diff;
// 000c
int16_t portamento_diff;
// 000e
int16_t portamento_add;
// 0010
int16_t portamento_rem;
// 0012
uint8_t vol;
// 0013
uint8_t transpose;
// 0014
struct pmd_lfo lfo;
// 0018
struct pmd_lfo lfo_set;
// 001c
struct pmd_part_lfo_flags {
// bit 0
bool freq;
// bit 1
bool vol;
// bit 2
bool sync;
// bit 3
bool portamento;
} lfof, lfof_b;
// 001d
uint8_t volume_save;
// 001e
uint8_t md_depth;
// 001f
uint8_t md_speed;
// 0020
uint8_t md_speed_set;
// 0021
uint8_t ssg_env_state_old;
// 0022
uint8_t ssg_env_state_new;
// 0023
uint8_t ssg_env_param_set[4];
// 0027
uint8_t ssg_env_param_sl;
// 0028
uint8_t ssg_env_param_al;
// 0029
uint8_t ssg_env_param[4];
// 002d
int8_t ssg_env_vol;
// 002e
struct pmd_part_flagext {
// bit 0
bool detune;
// bit 1
bool lfo;
// bit 2
bool env;
} flagext, flagext_b;
// 002f
uint8_t fm_pan_ams_pms;
// 0030
uint8_t ssg_mix;
// 0031
uint8_t tonenum;
// 0032
struct {
// bit 0
bool looped;
// bit 1
bool ended;
// bit 2
bool env;
} loop;
// 0033
// bit 7-4: slot 4,3,2,1
uint8_t fm_slotout;
// 0034
// 1,3,2,4
uint8_t fm_tone_tl[4];
// 0038
// 4,3,2,1,0,0,0,0
// when 1, enabled
uint8_t fm_slotmask;
// 0039
// 1,3,2,4,1,3,2,4
uint8_t fm_tone_slotmask;
// 003a
uint8_t lfo_waveform;
// 003b
struct {
// bit 0
bool ext;
// bit 1
bool effect;
// bit 2
bool disabled;
// bit 5
// true when all slots masked (part->fm_slotmask == 0)
bool slot;
// bit 6
bool mml;
// bit 7
bool ff;
} mask;
// 003c
struct {
// bit 0, 2-7
bool off;
// bit 1
bool off_mask;
} keystatus;
// 003d
// default: same as part->fm_slotout
// bit 7-4: mask slot 4,3,2,1
// bit 3-0: if 1, overridden by user
uint8_t vol_lfo_slotmask;
// 003e
// q
uint8_t gate_abs;
// 003f
// Q
uint8_t gate_rel;
// 0040
uint8_t hlfo_delay_set;
// 0041
uint8_t hlfo_delay;
// 0042
int16_t lfo_diff_b;
// 0044
struct pmd_lfo lfo_b;
// 0048
struct pmd_lfo lfo_set_b;
// 004c
uint8_t md_depth_b;
// 004d
uint8_t md_speed_b;
// 004e
uint8_t md_speed_set_b;
// 004f
uint8_t lfo_waveform_b;
// 0050
uint8_t vol_lfo_slotmask_b;
// 0051
uint8_t md_cnt;
// 0052
uint8_t md_cnt_set;
// 0053
uint8_t md_cnt_b;
// 0054
uint8_t md_cnt_set_b;
// 0055
uint8_t actual_note;
// 0056
uint8_t slot_delay;
// 0057
uint8_t slot_delay_cnt;
// 0058
uint8_t slot_delay_mask;
// 0059
uint8_t fb_alg;
// 005a
// increment when new note/rest processed
uint8_t note_proc;
// 005b
uint8_t gate_min;
// 005e
uint8_t curr_note;
// 005f
uint8_t transpose_master;
// 0060
uint8_t gate_rand_range;
// original
// used from pmd_part_proc_ssg, pmd_cmdc0, pmd_cmdcf_slotmask
bool proc_masked;
// for display
uint8_t len;
uint16_t output_freq;
};
struct pmd_ssgeff_data {
// ticks to wait, or 0xff to end
uint8_t wait;
uint16_t tone_freq;
uint8_t noise_freq;
bool tone_mix;
bool noise_mix;
uint8_t env_level;
uint16_t env_freq;
uint8_t env_waveform;
int8_t tonefreq_add;
int8_t noisefreq_add;
uint8_t noisefreq_wait;
};
#include "pmd_ssgeff.h"
struct driver_pmd {
// pmd->data = data+1;
// pmd->datalen = datalen-1;
// data[-1] is valid (OPM flag)
uint8_t *data;
uint16_t datalen;
// 0ee1
const struct pmd_ssgeff_data *ssgeff_ptr;
// 0ee3
uint16_t ssgeff_tonefreq;
// 0ee5
int16_t ssgeff_tonefreq_add;
// 0ee7
uint8_t ssgeff_wait;
// 0ee8
uint8_t ssgeff_noisefreq;
// 0ee9
int8_t ssgeff_noisefreq_add;
uint8_t ssgeff_noisefreq_cnt_set;
// 0eea
uint8_t ssgeff_noisefreq_cnt;
// 0eeb
uint8_t ssgeff_priority;
// 0eec
uint8_t ssgeff_num;
// 0eed
bool ssgeff_internal;
// 0eee
// 2fc2
uint16_t rand;
// 42ae
uint8_t proc_ch;
// 42af
// set with 0xfb
// when next command is 0xfb, disable gate (q/Q)
// used to implement tie
bool no_keyoff;
// 42b0
// set when volume saved for soft echo (W)
bool volume_saved;
// 42b2
bool opna_a1;
// 42b3
// same format as opna 0x28
// 0b4321____
uint8_t fm_slotkey[6];
// 42b9
// compare with part->loop
struct {
// bit 0
bool looped;
// bit 1
bool ended;
// bit 2
bool env;
} loop;
// 42ba
bool ppsdrv_enabled;
// 42c1
// 42c3
// timera_cnt sampled at timerb
uint8_t timera_cnt_b;
// 42c5
// needed when fm3ex_det valid
bool fm3ex_force;
// 42c6
// 1: ch3
// 2: ch3a
// 4: ch3b
// 8: ch3c
// when 0, not needed to extend fm3
uint8_t fm3ex_needed;
// 42d2
uint8_t fm3ex_fb_alg;
// 42d3
bool tonemask_fb_alg;
// 42d5
struct pmd_part_lfo_flags lfoprocf, lfoprocf_b;
// 42d6
// 430e
uint16_t tone_ptr;
// 4310
uint16_t r_offset;
// 4312
uint16_t r_ptr;
// 4314
uint8_t opnarhythm_mask;
// 4317
uint8_t fm_voldown;
// 4318
uint8_t ssg_voldown;
// 4319
uint8_t adpcm_voldown;
// 431a
uint8_t opnarhythm_voldown;
// 431b
bool tone_included;
// 431c
bool opm_flag;
// 431d
uint8_t status1;
// 431e
uint8_t status2;
// 431f
uint8_t timerb;
// 4320
uint8_t fadeout_speed;
// 4321
uint8_t fadeout_vol;
// 4322
uint8_t timerb_bak;
// 4323
uint8_t meas_len;
// 4324
uint8_t tick_cnt;
// 4325
uint8_t timera_cnt;
// 4326
bool ssgeff_disabled;
// 4327
uint8_t ssg_noise_freq;
// 4328
uint8_t ssg_noise_freq_wrote;
// 432a
bool fmeff_playing;
// 432c
bool adpcmeff_playing;
// 432d
uint16_t adpcm_start;
// 432f
uint16_t adpcm_stop;
// 433a
uint8_t opnarhythm;
// 433b
uint8_t opnarhythm_ilpan[6];
// 4341
uint8_t opnarhythm_tl;
// 4342
uint16_t ssgrhythm;
// 4348
bool playing;
// 4349
bool paused;
// 434a
//bool fadeout_mstop;
// 434b
bool ssgrhythm_opna;
// 4350
bool adpcm_disabled;
// 4354
int16_t fm3ex_det[4];
// 4362
uint8_t timerb_wrote;
// 4363
bool faded_out;
// 4366
bool pcm86_vol_spb;
// 4367
uint16_t meas_cnt;
// 436a
uint8_t opna_last22;
// 436b
uint8_t tempo;
// 436c
uint8_t tempo_bak;
// 4370
uint8_t fm_voldown_orig;
// 4371
uint8_t ssg_voldown_orig;
// 4372
uint8_t adpcm_voldown_orig;
// 4373
uint8_t opnarhythm_voldown_orig;
// 4374
bool pcm86_vol_spb_orig;
// 4386
uint8_t opnarhythm_shot_inc[6];
// 438c
uint8_t opnarhythm_dump_inc[6];
// 4392
// 0b0e111111
// output to 0x27
uint8_t fm3ex_mode;
// 4394
uint8_t ppz8_voldown;
// 4395
uint8_t ppz8_voldown_orig;
// 43ce
struct pmd_part parts[PMD_PART_NUM];
bool ssgeff_tone_mix;
bool ssgeff_noise_mix;
bool ssgeff_on;
char ppzfile[PMD_FILENAMELEN+1];
char ppsfile[PMD_FILENAMELEN+1];
char ppcfile[PMD_FILENAMELEN+1];
};
bool pmd_load(struct driver_pmd *pmd, uint8_t *data, uint16_t datalen);
void pmd_init(struct fmdriver_work *work, struct driver_pmd *pmd);
#ifdef __cplusplus
}
#endif
#endif // MYON_FMDRIVER_PMD_H_INCLUDED
|