-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
opll.h
199 lines (190 loc) · 4.71 KB
/
opll.h
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
/*
* Copyright (C) 2019 Nuke.YKT
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* Yamaha YM2413 emulator
* Thanks:
* siliconpr0n.org(digshadow, John McMaster):
* VRC VII decap and die shot.
*
* version: 1.0.1
*/
#ifndef OPLL_H
#define OPLL_H
#include <stdint.h>
enum {
opll_type_ym2413 = 0x00, /* Yamaha YM2413 */
opll_type_ds1001, /* Konami VRC VII */
opll_type_ym2413b, /* Yamaha YM2413B */
opll_type_ymf281, /* Yamaha YMF281 */
opll_type_ymf281b, /* Yamaha YMF281B */
opll_type_ym2420, /* Yamaha YM2420 */
opll_type_ym2423, /* Yamaha YM2423 */
};
enum {
opll_patch_1 = 0x00,
opll_patch_2,
opll_patch_3,
opll_patch_4,
opll_patch_5,
opll_patch_6,
opll_patch_7,
opll_patch_8,
opll_patch_9,
opll_patch_10,
opll_patch_11,
opll_patch_12,
opll_patch_13,
opll_patch_14,
opll_patch_15,
opll_patch_drum_0,
opll_patch_drum_1,
opll_patch_drum_2,
opll_patch_drum_3,
opll_patch_drum_4,
opll_patch_drum_5,
opll_patch_max
};
typedef struct {
uint8_t tl;
uint8_t dc;
uint8_t dm;
uint8_t fb;
uint8_t am[2];
uint8_t vib[2];
uint8_t et[2];
uint8_t ksr[2];
uint8_t multi[2];
uint8_t ksl[2];
uint8_t ar[2];
uint8_t dr[2];
uint8_t sl[2];
uint8_t rr[2];
} opll_patch_t;
typedef struct {
uint32_t chip_type;
uint32_t cycles;
uint32_t slot;
const opll_patch_t *patchrom;
/* IO */
uint8_t write_data;
uint8_t write_a;
uint8_t write_d;
uint8_t write_a_en;
uint8_t write_d_en;
uint8_t write_fm_address;
uint8_t write_fm_data;
uint8_t write_mode_address;
uint8_t address;
uint8_t data;
/* Envelope generator */
uint8_t eg_counter_state;
uint8_t eg_counter_state_prev;
uint32_t eg_timer;
uint8_t eg_timer_low_lock;
uint8_t eg_timer_carry;
uint8_t eg_timer_shift;
uint8_t eg_timer_shift_lock;
uint8_t eg_timer_shift_stop;
uint8_t eg_state[18];
uint8_t eg_level[18];
uint8_t eg_kon;
uint32_t eg_dokon;
uint8_t eg_off;
uint8_t eg_rate;
uint8_t eg_maxrate;
uint8_t eg_zerorate;
uint8_t eg_inc_lo;
uint8_t eg_inc_hi;
uint8_t eg_rate_hi;
uint16_t eg_sl;
uint16_t eg_ksltl;
uint8_t eg_out;
uint8_t eg_silent;
/* Phase generator */
uint16_t pg_fnum;
uint8_t pg_block;
uint16_t pg_out;
uint32_t pg_inc;
uint32_t pg_phase[18];
uint32_t pg_phase_next;
/* Operator */
int16_t op_fb1[9];
int16_t op_fb2[9];
int16_t op_fbsum;
int16_t op_mod;
uint8_t op_neg;
uint16_t op_logsin;
uint16_t op_exp_m;
uint16_t op_exp_s;
/* Channel */
int16_t ch_out;
int16_t ch_out_hh;
int16_t ch_out_tm;
int16_t ch_out_bd;
int16_t ch_out_sd;
int16_t ch_out_tc;
/* LFO */
uint16_t lfo_counter;
uint8_t lfo_vib_counter;
uint16_t lfo_am_counter;
uint8_t lfo_am_step;
uint8_t lfo_am_dir;
uint8_t lfo_am_car;
uint8_t lfo_am_out;
/* Register set */
uint16_t fnum[9];
uint8_t block[9];
uint8_t kon[9];
uint8_t son[9];
uint8_t vol[9];
uint8_t inst[9];
uint8_t rhythm;
uint8_t testmode;
opll_patch_t patch;
uint8_t c_instr;
uint8_t c_op;
uint8_t c_tl;
uint8_t c_dc;
uint8_t c_dm;
uint8_t c_fb;
uint8_t c_am;
uint8_t c_vib;
uint8_t c_et;
uint8_t c_ksr;
uint8_t c_ksr_freq;
uint8_t c_ksl_freq;
uint8_t c_ksl_block;
uint8_t c_multi;
uint8_t c_ksl;
uint8_t c_adrr[3];
uint8_t c_sl;
uint16_t c_fnum;
uint16_t c_block;
/* Rhythm mode */
int8_t rm_enable;
uint32_t rm_noise;
uint32_t rm_select;
uint8_t rm_hh_bit2;
uint8_t rm_hh_bit3;
uint8_t rm_hh_bit7;
uint8_t rm_hh_bit8;
uint8_t rm_tc_bit3;
uint8_t rm_tc_bit5;
int16_t output_m;
int16_t output_r;
} opll_t;
void OPLL_Reset(opll_t *chip, uint32_t chip_type);
void OPLL_Clock(opll_t *chip, int32_t *buffer);
void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data);
#endif