openMSX
opll.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Nuke.YKT
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  *
15  * Yamaha YM2413 emulator
16  * Thanks:
17  * siliconpr0n.org(digshadow, John McMaster):
18  * VRC VII decap and die shot.
19  *
20  * version: 1.0.1
21  */
22 
23 #include "opll.hh"
24 #include <cstring>
25 
26 enum {
30  eg_num_release = 3
31 };
32 
33 enum {
35  rm_num_hh = 1,
38  rm_num_sd = 4,
39  rm_num_tc = 5
40 };
41 
42 /* logsin table */
43 static const uint16_t logsinrom[256] = {
44  0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471,
45  0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365,
46  0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd,
47  0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261,
48  0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f,
49  0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd,
50  0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195,
51  0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166,
52  0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c,
53  0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118,
54  0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8,
55  0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db,
56  0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1,
57  0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9,
58  0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094,
59  0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081,
60  0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070,
61  0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060,
62  0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052,
63  0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045,
64  0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039,
65  0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f,
66  0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026,
67  0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e,
68  0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017,
69  0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011,
70  0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c,
71  0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007,
72  0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004,
73  0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002,
74  0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001,
75  0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
76 };
77 
78 /* exp table */
79 static const uint16_t exprom[256] = {
80  0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4,
81  0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9,
82  0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f,
83  0x77a, 0x775, 0x770, 0x76a, 0x765, 0x760, 0x75b, 0x756,
84  0x751, 0x74c, 0x747, 0x742, 0x73d, 0x738, 0x733, 0x72e,
85  0x729, 0x724, 0x71f, 0x71a, 0x715, 0x710, 0x70b, 0x706,
86  0x702, 0x6fd, 0x6f8, 0x6f3, 0x6ee, 0x6e9, 0x6e5, 0x6e0,
87  0x6db, 0x6d6, 0x6d2, 0x6cd, 0x6c8, 0x6c4, 0x6bf, 0x6ba,
88  0x6b5, 0x6b1, 0x6ac, 0x6a8, 0x6a3, 0x69e, 0x69a, 0x695,
89  0x691, 0x68c, 0x688, 0x683, 0x67f, 0x67a, 0x676, 0x671,
90  0x66d, 0x668, 0x664, 0x65f, 0x65b, 0x657, 0x652, 0x64e,
91  0x649, 0x645, 0x641, 0x63c, 0x638, 0x634, 0x630, 0x62b,
92  0x627, 0x623, 0x61e, 0x61a, 0x616, 0x612, 0x60e, 0x609,
93  0x605, 0x601, 0x5fd, 0x5f9, 0x5f5, 0x5f0, 0x5ec, 0x5e8,
94  0x5e4, 0x5e0, 0x5dc, 0x5d8, 0x5d4, 0x5d0, 0x5cc, 0x5c8,
95  0x5c4, 0x5c0, 0x5bc, 0x5b8, 0x5b4, 0x5b0, 0x5ac, 0x5a8,
96  0x5a4, 0x5a0, 0x59c, 0x599, 0x595, 0x591, 0x58d, 0x589,
97  0x585, 0x581, 0x57e, 0x57a, 0x576, 0x572, 0x56f, 0x56b,
98  0x567, 0x563, 0x560, 0x55c, 0x558, 0x554, 0x551, 0x54d,
99  0x549, 0x546, 0x542, 0x53e, 0x53b, 0x537, 0x534, 0x530,
100  0x52c, 0x529, 0x525, 0x522, 0x51e, 0x51b, 0x517, 0x514,
101  0x510, 0x50c, 0x509, 0x506, 0x502, 0x4ff, 0x4fb, 0x4f8,
102  0x4f4, 0x4f1, 0x4ed, 0x4ea, 0x4e7, 0x4e3, 0x4e0, 0x4dc,
103  0x4d9, 0x4d6, 0x4d2, 0x4cf, 0x4cc, 0x4c8, 0x4c5, 0x4c2,
104  0x4be, 0x4bb, 0x4b8, 0x4b5, 0x4b1, 0x4ae, 0x4ab, 0x4a8,
105  0x4a4, 0x4a1, 0x49e, 0x49b, 0x498, 0x494, 0x491, 0x48e,
106  0x48b, 0x488, 0x485, 0x482, 0x47e, 0x47b, 0x478, 0x475,
107  0x472, 0x46f, 0x46c, 0x469, 0x466, 0x463, 0x460, 0x45d,
108  0x45a, 0x457, 0x454, 0x451, 0x44e, 0x44b, 0x448, 0x445,
109  0x442, 0x43f, 0x43c, 0x439, 0x436, 0x433, 0x430, 0x42d,
110  0x42a, 0x428, 0x425, 0x422, 0x41f, 0x41c, 0x419, 0x416,
111  0x414, 0x411, 0x40e, 0x40b, 0x408, 0x406, 0x403, 0x400
112 };
113 
114 static const opll_patch_t patch_ds1001[opll_patch_max] = {
115  { 0x05, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x03, 0x01 },{ 0x00, 0x00 },{ 0x0e, 0x08 },{ 0x08, 0x01 },{ 0x04, 0x02 },{ 0x02, 0x07 } },
116  { 0x14, 0x00, 0x01, 0x05,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x03, 0x01 },{ 0x00, 0x00 },{ 0x0d, 0x0f },{ 0x08, 0x06 },{ 0x02, 0x01 },{ 0x03, 0x02 } },
117  { 0x08, 0x00, 0x01, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0f, 0x0b },{ 0x0a, 0x02 },{ 0x02, 0x01 },{ 0x00, 0x02 } },
118  { 0x0c, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x06 },{ 0x08, 0x04 },{ 0x06, 0x02 },{ 0x01, 0x07 } },
119  { 0x1e, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x02, 0x01 },{ 0x00, 0x00 },{ 0x0e, 0x07 },{ 0x01, 0x06 },{ 0x00, 0x02 },{ 0x01, 0x08 } },
120  { 0x06, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x02, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x0e },{ 0x03, 0x02 },{ 0x0f, 0x0f },{ 0x04, 0x04 } },
121  { 0x1d, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x08, 0x08 },{ 0x02, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x07 } },
122  { 0x22, 0x01, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x03, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x07 },{ 0x02, 0x02 },{ 0x00, 0x01 },{ 0x01, 0x07 } },
123  { 0x25, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x05, 0x01 },{ 0x00, 0x00 },{ 0x04, 0x07 },{ 0x00, 0x03 },{ 0x07, 0x00 },{ 0x02, 0x01 } },
124  { 0x0f, 0x00, 0x01, 0x07,{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x00 },{ 0x05, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x0a },{ 0x08, 0x05 },{ 0x05, 0x00 },{ 0x01, 0x02 } },
125  { 0x24, 0x00, 0x00, 0x07,{ 0x00, 0x01 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x07, 0x01 },{ 0x00, 0x00 },{ 0x0f, 0x0f },{ 0x08, 0x08 },{ 0x02, 0x01 },{ 0x02, 0x02 } },
126  { 0x11, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x03 },{ 0x00, 0x00 },{ 0x06, 0x07 },{ 0x05, 0x04 },{ 0x01, 0x01 },{ 0x08, 0x06 } },
127  { 0x13, 0x00, 0x00, 0x05,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x02 },{ 0x03, 0x00 },{ 0x0c, 0x09 },{ 0x09, 0x05 },{ 0x00, 0x00 },{ 0x03, 0x02 } },
128  { 0x0c, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x03 },{ 0x00, 0x00 },{ 0x09, 0x0c },{ 0x04, 0x00 },{ 0x03, 0x0f },{ 0x03, 0x06 } },
129  { 0x0d, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x01 },{ 0x01, 0x02 },{ 0x00, 0x00 },{ 0x0c, 0x0d },{ 0x01, 0x05 },{ 0x05, 0x00 },{ 0x06, 0x06 } },
130 
131  { 0x18, 0x00, 0x01, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0d, 0x00 },{ 0x0f, 0x00 },{ 0x06, 0x00 },{ 0x0a, 0x00 } },
132  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0c, 0x00 },{ 0x08, 0x00 },{ 0x0a, 0x00 },{ 0x07, 0x00 } },
133  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x05, 0x00 },{ 0x00, 0x00 },{ 0x0f, 0x00 },{ 0x08, 0x00 },{ 0x05, 0x00 },{ 0x09, 0x00 } },
134  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0f },{ 0x00, 0x08 },{ 0x00, 0x06 },{ 0x00, 0x0d } },
135  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0d },{ 0x00, 0x08 },{ 0x00, 0x06 },{ 0x00, 0x08 } },
136  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0a },{ 0x00, 0x0a },{ 0x00, 0x05 },{ 0x00, 0x05 } }
137 };
138 
139 static const opll_patch_t patch_ym2413[opll_patch_max] = {
140  { 0x1e, 0x01, 0x00, 0x07,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0d, 0x07 },{ 0x00, 0x08 },{ 0x00, 0x01 },{ 0x00, 0x07 } },
141  { 0x1a, 0x00, 0x01, 0x05,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x03, 0x01 },{ 0x00, 0x00 },{ 0x0d, 0x0f },{ 0x08, 0x07 },{ 0x02, 0x01 },{ 0x03, 0x03 } },
142  { 0x19, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x03, 0x01 },{ 0x02, 0x00 },{ 0x0f, 0x0c },{ 0x02, 0x04 },{ 0x01, 0x02 },{ 0x01, 0x03 } },
143  { 0x0e, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x06 },{ 0x08, 0x04 },{ 0x07, 0x02 },{ 0x00, 0x07 } },
144  { 0x1e, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x02, 0x01 },{ 0x00, 0x00 },{ 0x0e, 0x07 },{ 0x00, 0x06 },{ 0x00, 0x02 },{ 0x00, 0x08 } },
145  { 0x16, 0x00, 0x00, 0x05,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x02 },{ 0x00, 0x00 },{ 0x0e, 0x07 },{ 0x00, 0x01 },{ 0x00, 0x01 },{ 0x00, 0x08 } },
146  { 0x1d, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x08, 0x08 },{ 0x02, 0x01 },{ 0x01, 0x00 },{ 0x00, 0x07 } },
147  { 0x2d, 0x01, 0x00, 0x04,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x03, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x07 },{ 0x02, 0x02 },{ 0x00, 0x00 },{ 0x00, 0x07 } },
148  { 0x1b, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x06, 0x06 },{ 0x04, 0x05 },{ 0x01, 0x01 },{ 0x00, 0x07 } },
149  { 0x0b, 0x01, 0x01, 0x00,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x08, 0x0f },{ 0x05, 0x07 },{ 0x07, 0x00 },{ 0x01, 0x07 } },
150  { 0x03, 0x01, 0x00, 0x01,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x03, 0x01 },{ 0x02, 0x00 },{ 0x0f, 0x0e },{ 0x0a, 0x04 },{ 0x01, 0x00 },{ 0x00, 0x04 } },
151  { 0x24, 0x00, 0x00, 0x07,{ 0x00, 0x01 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x07, 0x01 },{ 0x00, 0x00 },{ 0x0f, 0x0f },{ 0x08, 0x08 },{ 0x02, 0x01 },{ 0x02, 0x02 } },
152  { 0x0c, 0x00, 0x00, 0x05,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0c, 0x0f },{ 0x02, 0x05 },{ 0x02, 0x04 },{ 0x00, 0x02 } },
153  { 0x15, 0x00, 0x00, 0x03,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x0c, 0x09 },{ 0x09, 0x05 },{ 0x00, 0x00 },{ 0x03, 0x02 } },
154  { 0x09, 0x00, 0x00, 0x03,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x02, 0x00 },{ 0x0f, 0x0e },{ 0x01, 0x04 },{ 0x04, 0x01 },{ 0x00, 0x03 } },
155 
156  { 0x18, 0x00, 0x01, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0d, 0x00 },{ 0x0f, 0x00 },{ 0x06, 0x00 },{ 0x0a, 0x00 } },
157  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0c, 0x00 },{ 0x08, 0x00 },{ 0x0a, 0x00 },{ 0x07, 0x00 } },
158  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x05, 0x00 },{ 0x00, 0x00 },{ 0x0f, 0x00 },{ 0x08, 0x00 },{ 0x05, 0x00 },{ 0x09, 0x00 } },
159  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0f },{ 0x00, 0x08 },{ 0x00, 0x06 },{ 0x00, 0x0d } },
160  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0d },{ 0x00, 0x08 },{ 0x00, 0x04 },{ 0x00, 0x08 } },
161  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0a },{ 0x00, 0x0a },{ 0x00, 0x05 },{ 0x00, 0x05 } }
162 };
163 
164 static const opll_patch_t patch_ymf281[opll_patch_max] = {
165  { 0x1a, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x02, 0x01 },{ 0x00, 0x00 },{ 0x0f, 0x06 },{ 0x0f, 0x07 },{ 0x00, 0x01 },{ 0x00, 0x06 } },
166  { 0x05, 0x00, 0x00, 0x01,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x0f, 0x08 },{ 0x06, 0x03 },{ 0x08, 0x00 },{ 0x00, 0x03 } },
167  { 0x16, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x03, 0x01 },{ 0x02, 0x00 },{ 0x0f, 0x0d },{ 0x02, 0x03 },{ 0x01, 0x00 },{ 0x01, 0x03 } },
168  { 0x0b, 0x00, 0x01, 0x07,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x06 },{ 0x08, 0x04 },{ 0x07, 0x01 },{ 0x00, 0x07 } },
169  { 0x1e, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x02, 0x01 },{ 0x00, 0x00 },{ 0x0e, 0x07 },{ 0x01, 0x06 },{ 0x00, 0x02 },{ 0x00, 0x08 } },
170  { 0x02, 0x00, 0x01, 0x06,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x02, 0x00 },{ 0x09, 0x06 },{ 0x0a, 0x01 },{ 0x02, 0x02 },{ 0x00, 0x07 } },
171  { 0x1b, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x08, 0x08 },{ 0x04, 0x03 },{ 0x01, 0x00 },{ 0x00, 0x07 } },
172  { 0x0a, 0x00, 0x00, 0x02,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x07, 0x02 },{ 0x03, 0x00 },{ 0x06, 0x06 },{ 0x06, 0x04 },{ 0x04, 0x02 },{ 0x00, 0x07 } },
173  { 0x07, 0x00, 0x00, 0x03,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0c, 0x07 },{ 0x05, 0x07 },{ 0x05, 0x00 },{ 0x01, 0x07 } },
174  { 0x1e, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x00 },{ 0x06, 0x01 },{ 0x01, 0x00 },{ 0x0f, 0x0f },{ 0x02, 0x03 },{ 0x0f, 0x0f },{ 0x00, 0x03 } },
175  { 0x18, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x0f, 0x0e },{ 0x05, 0x03 },{ 0x02, 0x01 },{ 0x00, 0x03 } },
176  { 0x24, 0x00, 0x00, 0x07,{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x07, 0x01 },{ 0x00, 0x00 },{ 0x0f, 0x0f },{ 0x08, 0x08 },{ 0x02, 0x00 },{ 0x02, 0x03 } },
177  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x00 },{ 0x05, 0x04 },{ 0x00, 0x00 },{ 0x0f, 0x0f },{ 0x0f, 0x03 },{ 0x07, 0x0f },{ 0x00, 0x05 } },
178  { 0x03, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x01 },{ 0x0f, 0x01 },{ 0x00, 0x00 },{ 0x0f, 0x0e },{ 0x0c, 0x03 },{ 0x03, 0x0f },{ 0x0f, 0x0c } },
179  { 0x00, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0a, 0x01 },{ 0x00, 0x00 },{ 0x0b, 0x08 },{ 0x0f, 0x04 },{ 0x00, 0x0f },{ 0x00, 0x05 } },
180 
181  { 0x18, 0x00, 0x01, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0d, 0x00 },{ 0x0f, 0x00 },{ 0x06, 0x00 },{ 0x0a, 0x00 } },
182  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0c, 0x00 },{ 0x08, 0x00 },{ 0x0a, 0x00 },{ 0x07, 0x00 } },
183  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x05, 0x00 },{ 0x00, 0x00 },{ 0x0f, 0x00 },{ 0x08, 0x00 },{ 0x05, 0x00 },{ 0x09, 0x00 } },
184  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0f },{ 0x00, 0x08 },{ 0x00, 0x06 },{ 0x00, 0x0d } },
185  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0d },{ 0x00, 0x08 },{ 0x00, 0x04 },{ 0x00, 0x08 } },
186  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0a },{ 0x00, 0x0a },{ 0x00, 0x05 },{ 0x00, 0x05 } }
187 };
188 
189 static const opll_patch_t patch_ym2423[opll_patch_max] = {
190  { 0x1b, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x09, 0x05 },{ 0x04, 0x04 },{ 0x01, 0x00 },{ 0x00, 0x05 } },
191  { 0x12, 0x00, 0x00, 0x04,{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x03, 0x01 },{ 0x01, 0x00 },{ 0x0f, 0x0f },{ 0x03, 0x02 },{ 0x0a, 0x0e },{ 0x00, 0x09 } },
192  { 0x11, 0x00, 0x00, 0x05,{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x02 },{ 0x0f, 0x0f },{ 0x02, 0x02 },{ 0x05, 0x07 },{ 0x00, 0x05 } },
193  { 0x28, 0x00, 0x00, 0x07,{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x03, 0x02 },{ 0x00, 0x00 },{ 0x0f, 0x0f },{ 0x03, 0x02 },{ 0x09, 0x0b },{ 0x00, 0x04 } },
194  { 0x17, 0x00, 0x00, 0x05,{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x02, 0x01 },{ 0x02, 0x00 },{ 0x05, 0x06 },{ 0x01, 0x0f },{ 0x07, 0x00 },{ 0x00, 0x09 } },
195  { 0x18, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x03, 0x00 },{ 0x00, 0x00 },{ 0x0f, 0x0f },{ 0x07, 0x04 },{ 0x05, 0x08 },{ 0x00, 0x05 } },
196  { 0x1c, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x05, 0x07 },{ 0x01, 0x01 },{ 0x02, 0x02 },{ 0x00, 0x06 } },
197  { 0x1b, 0x00, 0x00, 0x07,{ 0x00, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x04 },{ 0x00, 0x00 },{ 0x07, 0x03 },{ 0x03, 0x0f },{ 0x00, 0x00 },{ 0x00, 0x06 } },
198  { 0x0d, 0x00, 0x00, 0x03,{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x04, 0x06 },{ 0x02, 0x0f },{ 0x02, 0x00 },{ 0x00, 0x06 } },
199  { 0x10, 0x00, 0x00, 0x05,{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x02 },{ 0x0f, 0x0f },{ 0x03, 0x03 },{ 0x02, 0x00 },{ 0x00, 0x04 } },
200  { 0x1b, 0x00, 0x00, 0x07,{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x0c, 0x09 },{ 0x05, 0x06 },{ 0x0f, 0x0f },{ 0x00, 0x06 } },
201  { 0x1b, 0x00, 0x00, 0x00,{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x09, 0x01 },{ 0x03, 0x00 },{ 0x0f, 0x0f },{ 0x05, 0x03 },{ 0x07, 0x0f },{ 0x00, 0x02 } },
202  { 0x11, 0x00, 0x00, 0x03,{ 0x00, 0x01 },{ 0x01, 0x00 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x02 },{ 0x02, 0x00 },{ 0x09, 0x0b },{ 0x04, 0x01 },{ 0x0e, 0x0f },{ 0x00, 0x07 } },
203  { 0x17, 0x00, 0x00, 0x06,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x0d, 0x0e },{ 0x03, 0x01 },{ 0x0b, 0x0e },{ 0x00, 0x0b } },
204  { 0x0d, 0x00, 0x00, 0x05,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x01 },{ 0x01, 0x01 },{ 0x01, 0x06 },{ 0x00, 0x00 },{ 0x0f, 0x0f },{ 0x02, 0x04 },{ 0x02, 0x09 },{ 0x00, 0x09 } },
205 
206  { 0x18, 0x00, 0x01, 0x07,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0d, 0x00 },{ 0x0f, 0x00 },{ 0x06, 0x00 },{ 0x0a, 0x00 } },
207  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x01, 0x00 },{ 0x00, 0x00 },{ 0x0c, 0x00 },{ 0x08, 0x00 },{ 0x0a, 0x00 },{ 0x07, 0x00 } },
208  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x05, 0x00 },{ 0x00, 0x00 },{ 0x0f, 0x00 },{ 0x08, 0x00 },{ 0x05, 0x00 },{ 0x09, 0x00 } },
209  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0f },{ 0x00, 0x08 },{ 0x00, 0x06 },{ 0x00, 0x0d } },
210  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0d },{ 0x00, 0x08 },{ 0x00, 0x04 },{ 0x00, 0x08 } },
211  { 0x00, 0x00, 0x00, 0x00,{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x00 },{ 0x00, 0x01 },{ 0x00, 0x00 },{ 0x00, 0x0a },{ 0x00, 0x0a },{ 0x00, 0x05 },{ 0x00, 0x05 } }
212 };
213 
214 static const uint32_t ch_offset[18] = {
215  1, 2, 0, 1, 2, 3, 4, 5, 3, 4, 5, 6, 7, 8, 6, 7, 8, 0
216 };
217 
218 static const uint32_t pg_multi[16] = {
219  1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30
220 };
221 
222 static const uint32_t eg_stephi[4][4] = {
223  { 0, 0, 0, 0 },
224  { 1, 0, 0, 0 },
225  { 1, 0, 1, 0 },
226  { 1, 1, 1, 0 }
227 };
228 
229 static const uint32_t eg_ksltable[16] = {
230  0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64
231 };
232 
233 static void OPLL_DoIO(opll_t *chip) {
234  /* Write signal check */
235  chip->write_a_en = (chip->write_a & 0x03) == 0x01;
236  chip->write_d_en = (chip->write_d & 0x03) == 0x01;
237  chip->write_a <<= 1;
238  chip->write_d <<= 1;
239 }
240 
241 static void OPLL_DoModeWrite(opll_t *chip) {
242  if ((chip->write_mode_address & 0x10) && chip->write_d_en) {
243  uint8_t slot = chip->write_mode_address & 0x01;
244  switch (chip->write_mode_address & 0x0f) {
245  case 0x00:
246  case 0x01:
247  chip->patch.multi[slot] = chip->write_data & 0x0f;
248  chip->patch.ksr[slot] = (chip->write_data >> 4) & 0x01;
249  chip->patch.et[slot] = (chip->write_data >> 5) & 0x01;
250  chip->patch.vib[slot] = (chip->write_data >> 6) & 0x01;
251  chip->patch.am[slot] = (chip->write_data >> 7) & 0x01;
252  break;
253 
254  case 0x02:
255  chip->patch.ksl[0] = (chip->write_data >> 6) & 0x03;
256  chip->patch.tl = chip->write_data & 0x3f;
257  break;
258 
259  case 0x03:
260  chip->patch.ksl[1] = (chip->write_data >> 6) & 0x03;
261  chip->patch.dc = (chip->write_data >> 4) & 0x01;
262  chip->patch.dm = (chip->write_data >> 3) & 0x01;
263  chip->patch.fb = chip->write_data & 0x07;
264  break;
265 
266  case 0x04:
267  case 0x05:
268  chip->patch.dr[slot] = chip->write_data & 0x0f;
269  chip->patch.ar[slot] = (chip->write_data >> 4) & 0x0f;
270  break;
271 
272  case 0x06:
273  case 0x07:
274  chip->patch.rr[slot] = chip->write_data & 0x0f;
275  chip->patch.sl[slot] = (chip->write_data >> 4) & 0x0f;
276  break;
277 
278  case 0x0e:
279  chip->rhythm = chip->write_data & 0x3f;
280  if (chip->chip_type == opll_type_ds1001) {
281  chip->rhythm |= 0x20;
282  }
283  chip->rm_enable = (chip->rm_enable & 0x7f) | ((chip->rhythm << 2) & 0x80);
284  break;
285 
286  case 0x0f:
287  chip->testmode = chip->write_data & 0x0f;
288  break;
289  }
290  }
291 }
292 
293 void OPLL_Reset(opll_t *chip, uint32_t chip_type) {
294  uint32_t i;
295  memset(chip, 0, sizeof(opll_t));
296  chip->chip_type = chip_type;
297  if (chip_type == opll_type_ds1001) {
298  /* Rhythm mode is always on */
299  chip->rhythm = 0x20;
300  chip->rm_enable = int8_t(0x80);
301  }
302  switch (chip_type) {
303  case opll_type_ds1001:
304  chip->patchrom = patch_ds1001;
305  break;
306  case opll_type_ymf281:
307  case opll_type_ymf281b:
308  chip->patchrom = patch_ymf281;
309  break;
310  case opll_type_ym2423:
311  chip->patchrom = patch_ym2423;
312  break;
313  case opll_type_ym2413:
314  case opll_type_ym2413b:
315  case opll_type_ym2420:
316  default:
317  chip->patchrom = patch_ym2413;
318  break;
319  }
320  for (i = 0; i < 18; i++) {
321  chip->eg_state[i] = eg_num_release;
322  chip->eg_level[i] = 0x7f;
323  chip->eg_out = 0x7f;
324  }
325  chip->rm_select = rm_num_tc + 1;
326 }
327 
328 static void OPLL_DoRegWrite(opll_t *chip) {
329  /* Address */
330  if (chip->write_a_en) {
331  if ((chip->write_data & 0xc0) == 0x00) {
332  /* FM Write */
333  chip->write_fm_address = 1;
334  chip->address = chip->write_data;
335  } else {
336  chip->write_fm_address = 0;
337  }
338  }
339  /* Data */
340  if (chip->write_fm_address && chip->write_d_en) {
341  chip->data = chip->write_data;
342  }
343 
344  /* Update registers */
345  if (chip->write_fm_data && !chip->write_a_en) {
346  if ((chip->address & 0x0f) == chip->cycles && chip->cycles < 16) {
347  uint32_t channel = chip->cycles % 9;
348  switch (chip->address & 0xf0) {
349  case 0x10:
350  if (chip->chip_type == opll_type_ym2420)
351  {
352  chip->fnum[channel] = (chip->fnum[channel] & 0x0f) | ((chip->data & 0x1f) << 4);
353  chip->block[channel] = (chip->data >> 5) & 0x07;
354  }
355  else
356  chip->fnum[channel] = (chip->fnum[channel] & 0x100) | chip->data;
357  break;
358  case 0x20:
359  if (chip->chip_type == opll_type_ym2420)
360  chip->fnum[channel] = (chip->fnum[channel] & 0x1f0) | (chip->data & 0x0f);
361  else
362  {
363  chip->fnum[channel] = (chip->fnum[channel] & 0xff) | ((chip->data & 0x01) << 8);
364  chip->block[channel] = (chip->data >> 1) & 0x07;
365  }
366  chip->kon[channel] = (chip->data >> 4) & 0x01;
367  chip->son[channel] = (chip->data >> 5) & 0x01;
368  break;
369  case 0x30:
370  chip->vol[channel] = chip->data & 0x0f;
371  chip->inst[channel] = (chip->data >> 4) & 0x0f;
372  break;
373  }
374  }
375  }
376 
377 
378  if (chip->write_a_en) {
379  chip->write_fm_data = 0;
380  }
381  if (chip->write_fm_address && chip->write_d_en) {
382  chip->write_fm_data = 1;
383  }
384  if (chip->write_a_en) {
385  if (((chip->write_data & 0xf0) == 0x00)) {
386  chip->write_mode_address = 0x10 | (chip->write_data & 0x0f);
387  } else {
388  chip->write_mode_address = 0x00;
389  }
390  }
391 
392 }
393 
394 static void OPLL_PreparePatch1(opll_t *chip) {
395  uint8_t instr;
396  uint32_t mcsel = ((chip->cycles + 1) / 3) & 0x01;
397  uint32_t instr_index;
398  uint32_t ch = ch_offset[chip->cycles];
399  const opll_patch_t *patch;
400  instr = chip->inst[ch];
401  if (instr > 0) {
402  instr_index = opll_patch_1 + instr - 1;
403  }
404  if (chip->rm_select <= rm_num_tc) {
405  instr_index = opll_patch_drum_0 + chip->rm_select;
406  }
407  if (chip->rm_select <= rm_num_tc || instr > 0) {
408  patch = &chip->patchrom[instr_index];
409  } else {
410  patch = &chip->patch;
411  }
412  if (chip->rm_select == rm_num_hh || chip->rm_select == rm_num_tom) {
413  chip->c_tl = chip->inst[ch] << 2;
414  } else if (mcsel == 1) {
415  chip->c_tl = chip->vol[ch] << 2;
416  } else {
417  chip->c_tl = patch->tl;
418  }
419 
420  chip->c_adrr[0] = patch->ar[mcsel];
421  chip->c_adrr[1] = patch->dr[mcsel];
422  chip->c_adrr[2] = patch->rr[mcsel];
423  chip->c_et = patch->et[mcsel];
424  chip->c_ksr = patch->ksr[mcsel];
425  chip->c_ksl = patch->ksl[mcsel];
426  chip->c_ksr_freq = (chip->block[ch] << 1) | (chip->fnum[ch] >> 8);
427  chip->c_ksl_freq = (chip->fnum[ch]>>5);
428  chip->c_ksl_block = (chip->block[ch]);
429 }
430 
431 static void OPLL_PreparePatch2(opll_t *chip) {
432  uint8_t instr;
433  uint32_t mcsel = ((chip->cycles + 1) / 3) & 0x01;
434  uint32_t instr_index;
435  const opll_patch_t *patch;
436  instr = chip->inst[ch_offset[chip->cycles]];
437  if (instr > 0) {
438  instr_index = opll_patch_1 + instr - 1;
439  }
440  if (chip->rm_select <= rm_num_tc) {
441  instr_index = opll_patch_drum_0 + chip->rm_select;
442  }
443  if (chip->rm_select <= rm_num_tc || instr > 0) {
444  patch = &chip->patchrom[instr_index];
445  } else {
446  patch = &chip->patch;
447  }
448 
449  chip->c_fnum = chip->fnum[ch_offset[chip->cycles]];
450  chip->c_block = chip->block[ch_offset[chip->cycles]];
451 
452  chip->c_multi = patch->multi[mcsel];
453  chip->c_sl = patch->sl[mcsel];
454  chip->c_fb = patch->fb;
455  chip->c_vib = patch->vib[mcsel];
456  chip->c_am = patch->am[mcsel];
457  chip->c_dc <<= 1;
458  chip->c_dm <<= 1;
459  chip->c_dc |= patch->dc;
460  chip->c_dm |= patch->dm;
461 }
462 
463 static void OPLL_PhaseGenerate(opll_t *chip) {
464  uint32_t ismod;
465  uint32_t phase;
466  uint16_t pg_out;
467 
468  chip->pg_phase[(chip->cycles + 17) % 18] = chip->pg_phase_next + chip->pg_inc;
469 
470  if ((chip->rm_enable & 0x40) && (chip->cycles == 13 || chip->cycles == 14)) {
471  ismod = 0;
472  } else {
473  ismod = ((chip->cycles + 3) / 3) & 1;
474  }
475  phase = chip->pg_phase[chip->cycles];
476  /* KeyOn event check */
477  if ((chip->testmode & 0x04)
478  || (ismod && (chip->eg_dokon & 0x8000)) || (!ismod && (chip->eg_dokon & 0x01))) {
479  chip->pg_phase_next = 0;
480  } else {
481  chip->pg_phase_next = phase;
482  }
483  /* Rhythm mode */
484  if (chip->cycles == 13) {
485  chip->rm_hh_bit2 = (phase >> (2 + 9)) & 1;
486  chip->rm_hh_bit3 = (phase >> (3 + 9)) & 1;
487  chip->rm_hh_bit7 = (phase >> (7 + 9)) & 1;
488  chip->rm_hh_bit8 = (phase >> (8 + 9)) & 1;
489  } else if (chip->cycles == 17 && (chip->rm_enable & 0x80)) {
490  chip->rm_tc_bit3 = (phase >> (3 + 9)) & 1;
491  chip->rm_tc_bit5 = (phase >> (5 + 9)) & 1;
492  }
493  if ((chip->rm_enable & 0x80)) {
494  switch (chip->cycles) {
495  case 13: {
496  /* HH */
497  uint8_t rm_bit = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7)
498  | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5)
499  | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5);
500  pg_out = rm_bit << 9;
501  if (rm_bit ^ (chip->rm_noise & 1)) {
502  pg_out |= 0xd0;
503  } else {
504  pg_out |= 0x34;
505  }
506  break;
507  }
508  case 16:
509  /* SD */
510  pg_out = (chip->rm_hh_bit8 << 9)
511  | ((chip->rm_hh_bit8 ^ (chip->rm_noise & 1)) << 8);
512  break;
513  case 17: {
514  /* TC */
515  uint8_t rm_bit = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7)
516  | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5)
517  | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5);
518  pg_out = (rm_bit << 9) | 0x100;
519  break;
520  }
521  default:
522  pg_out = phase >> 9;
523  }
524  } else {
525  pg_out = phase >> 9;
526  }
527  chip->pg_out = pg_out;
528 }
529 
530 static void OPLL_PhaseCalcIncrement(opll_t *chip) {
531  uint32_t freq;
532  uint16_t block;
533  freq = chip->c_fnum << 1;
534  block = chip->c_block;
535  /* Apply vibrato */
536  if (chip->c_vib) {
537  switch (chip->lfo_vib_counter) {
538  case 0:
539  case 4:
540  break;
541  case 1:
542  case 3:
543  freq += freq >> 8;
544  break;
545  case 2:
546  freq += freq >> 7;
547  break;
548  case 5:
549  case 7:
550  freq -= freq >> 8;
551  break;
552  case 6:
553  freq -= freq >> 7;
554  break;
555  }
556  }
557  /* Apply block */
558  freq = (freq << block) >> 1;
559 
560  chip->pg_inc = (freq * pg_multi[chip->c_multi]) >> 1;
561 }
562 
563 static void OPLL_EnvelopeKSLTL(opll_t *chip)
564 {
565  int32_t ksl;
566 
567  ksl = eg_ksltable[chip->c_ksl_freq]-((8-chip->c_ksl_block)<<3);
568  if (ksl < 0) {
569  ksl = 0;
570  }
571 
572  ksl <<= 1;
573 
574  if (chip->c_ksl) {
575  ksl = ksl >> (3-chip->c_ksl);
576  } else {
577  ksl = 0;
578  }
579 
580  chip->eg_ksltl = ksl + (chip->c_tl<<1);
581 }
582 
583 static void OPLL_EnvelopeOutput(opll_t *chip)
584 {
585  int32_t level = chip->eg_level[(chip->cycles+17)%18];
586 
587  level += chip->eg_ksltl;
588 
589  if (chip->c_am) {
590  level += chip->lfo_am_out;
591  }
592 
593  if (level >= 128) {
594  level = 127;
595  }
596 
597  if (chip->testmode & 0x01) {
598  level = 0;
599  }
600 
601  chip->eg_out = level;
602 }
603 
604 static void OPLL_EnvelopeGenerate(opll_t *chip) {
605  uint8_t timer_inc;
606  uint8_t timer_bit;
607  uint8_t timer_low;
608  uint8_t rate;
609  uint8_t state_rate;
610  uint8_t ksr;
611  uint8_t sum;
612  uint8_t rate_hi;
613  uint8_t rate_lo;
614  int32_t level;
615  int32_t next_level;
616  uint8_t zero;
617  uint8_t state;
618  uint8_t next_state;
619  int32_t step;
620  int32_t sl;
621  uint32_t mcsel = ((chip->cycles + 1) / 3) & 0x01;
622 
623 
624  /* EG timer */
625  if ((chip->eg_counter_state & 3) != 3) {
626  timer_inc = 0;
627  } else if (chip->cycles == 0) {
628  timer_inc = 1;
629  } else {
630  timer_inc = chip->eg_timer_carry;
631  }
632  timer_low = chip->eg_timer & 3;
633  timer_bit = chip->eg_timer & 1;
634  timer_bit += timer_inc;
635  chip->eg_timer_carry = timer_bit >> 1;
636  chip->eg_timer = ((timer_bit & 1) << 17) | (chip->eg_timer >> 1);
637  if (chip->testmode & 0x08) {
638  chip->eg_timer &= 0x2ffff;
639  chip->eg_timer |= (chip->write_data << (16 - 2)) & 0x10000;
640  }
641  if (!chip->eg_timer_shift_stop && ((chip->eg_timer >> 16) & 1)) {
642  chip->eg_timer_shift = chip->cycles;
643  }
644  if (chip->cycles == 0 && (chip->eg_counter_state_prev & 1) == 1) {
645  chip->eg_timer_low_lock = timer_low;
646  chip->eg_timer_shift_lock = chip->eg_timer_shift;
647  if (chip->eg_timer_shift_lock > 13)
648  chip->eg_timer_shift_lock = 0;
649 
650  chip->eg_timer_shift = 0;
651  }
652  chip->eg_timer_shift_stop |= (chip->eg_timer >> 16) & 1;
653  if (chip->cycles == 0) {
654  chip->eg_timer_shift_stop = 0;
655  }
657  if (chip->cycles == 17) {
658  chip->eg_counter_state++;
659  }
660 
661  level = chip->eg_level[(chip->cycles+16)%18];
662  next_level = level;
663  zero = level == 0;
664  chip->eg_silent = level == 0x7f;
665 
666  if (chip->eg_state[(chip->cycles+16)%18] != eg_num_attack && (chip->eg_off&2) && !(chip->eg_dokon&2)) {
667  next_level = 0x7f;
668  }
669 
670  if (chip->eg_maxrate && (chip->eg_dokon&2)) {
671  next_level = 0x00;
672  }
673 
674 
675  state = chip->eg_state[(chip->cycles+16)%18];
676  next_state = eg_num_attack;
677 
678  step = 0;
679  sl = chip->eg_sl;
680 
681  switch (state) {
682  case eg_num_attack:
683  if (!chip->eg_maxrate && (chip->eg_kon & 2) && !zero) {
684  int32_t shift = (chip->eg_rate_hi < 12) ? chip->eg_inc_lo : (chip->eg_rate_hi - 11 + chip->eg_inc_hi);
685  if (shift > 0) {
686  step = ~level >> (5 - shift);
687  }
688  }
689  if (zero) {
690  next_state = eg_num_decay;
691  } else {
692  next_state = eg_num_attack;
693  }
694  break;
695  case eg_num_decay:
696  if (!(chip->eg_off & 2) && !(chip->eg_dokon & 2) && (level >> 3) != sl)
697  {
698  uint8_t i0 = chip->eg_rate_hi == 15 || (chip->eg_rate_hi == 14 && chip->eg_inc_hi);
699  uint8_t i1 = (chip->eg_rate_hi == 14 && !chip->eg_inc_hi) || (chip->eg_rate_hi == 13 && chip->eg_inc_hi) ||
700  (chip->eg_rate_hi == 13 && !chip->eg_inc_hi && (chip->eg_counter_state_prev & 1))
701  || (chip->eg_rate_hi == 12 && chip->eg_inc_hi && (chip->eg_counter_state_prev & 1))
702  || (chip->eg_rate_hi == 12 && !chip->eg_inc_hi && ((chip->eg_counter_state_prev & 3) == 3))
703  || (chip->eg_inc_lo && ((chip->eg_counter_state_prev & 3) == 3));
704  step = (i0<<1) | i1;
705  }
706  if ((level >> 3) == sl) {
707  next_state = eg_num_sustain;
708  } else {
709  next_state = eg_num_decay;
710  }
711  break;
712  case eg_num_sustain:
713  case eg_num_release:
714  if (!(chip->eg_off & 2) && !(chip->eg_dokon & 2))
715  {
716  uint8_t i0 = chip->eg_rate_hi == 15 || (chip->eg_rate_hi == 14 && chip->eg_inc_hi);
717  uint8_t i1 = (chip->eg_rate_hi == 14 && !chip->eg_inc_hi) || (chip->eg_rate_hi == 13 && chip->eg_inc_hi) ||
718  (chip->eg_rate_hi == 13 && !chip->eg_inc_hi && (chip->eg_counter_state_prev & 1))
719  || (chip->eg_rate_hi == 12 && chip->eg_inc_hi && (chip->eg_counter_state_prev & 1))
720  || (chip->eg_rate_hi == 12 && !chip->eg_inc_hi && ((chip->eg_counter_state_prev & 3) == 3))
721  || (chip->eg_inc_lo && ((chip->eg_counter_state_prev & 3) == 3));
722  step = (i0<<1) | i1;
723  }
724  next_state = state;
725  break;
726  }
727 
728  if (!(chip->eg_kon & 2)) {
729  next_state = eg_num_release;
730  }
731  if (chip->eg_dokon & 2) {
732  next_state = eg_num_attack;
733  }
734 
735  chip->eg_level[(chip->cycles+16)%18] = next_level+step;
736  chip->eg_state[(chip->cycles+16)%18] = next_state;
737 
738  rate_hi = chip->eg_rate >> 2;
739  rate_lo = chip->eg_rate & 3;
740  chip->eg_inc_hi = eg_stephi[rate_lo][chip->eg_timer_low_lock];
741  sum = (chip->eg_timer_shift_lock + rate_hi) & 0x0f;
742  chip->eg_inc_lo = 0;
743  if (rate_hi < 12 && !chip->eg_zerorate) {
744  switch (sum) {
745  case 12:
746  chip->eg_inc_lo = 1;
747  break;
748  case 13:
749  chip->eg_inc_lo = (rate_lo >> 1) & 1;
750  break;
751  case 14:
752  chip->eg_inc_lo = rate_lo & 1;
753  break;
754  }
755  }
756  chip->eg_maxrate = rate_hi == 0x0f;
757 
758  chip->eg_rate_hi = rate_hi;
759 
760  chip->eg_kon <<= 1;
761  chip->eg_kon |= chip->kon[ch_offset[chip->cycles]];
762  chip->eg_off <<= 1;
763  chip->eg_off |= (chip->eg_level[chip->cycles] >> 2) == 0x1f;
764  switch (chip->rm_select) {
765  case rm_num_bd0:
766  case rm_num_bd1:
767  chip->eg_kon |= (chip->rhythm >> 4) & 1;
768  break;
769  case rm_num_sd:
770  chip->eg_kon |= (chip->rhythm >> 3) & 1;
771  break;
772  case rm_num_tom:
773  chip->eg_kon |= (chip->rhythm >> 2) & 1;
774  break;
775  case rm_num_tc:
776  chip->eg_kon |= (chip->rhythm >> 1) & 1;
777  break;
778  case rm_num_hh:
779  chip->eg_kon |= chip->rhythm & 1;
780  break;
781  }
782 
783  /* Calculate rate */
784  rate = 0;
785  chip->eg_dokon <<= 1;
786  state_rate = chip->eg_state[chip->cycles];
787  if (state_rate == eg_num_release && (chip->eg_kon&1) && (chip->eg_off&1)) {
788  state_rate = eg_num_attack;
789  chip->eg_dokon |= 1;
790  }
791  switch (state_rate) {
792  case eg_num_attack:
793  rate = chip->c_adrr[0];
794  break;
795  case eg_num_decay:
796  rate = chip->c_adrr[1];
797  break;
798  case eg_num_sustain:
799  if (!chip->c_et) {
800  rate = chip->c_adrr[2];
801  }
802  break;
803  case eg_num_release:
804  if (chip->son[ch_offset[chip->cycles]]) {
805  rate = 5;
806  } else {
807  rate = chip->c_adrr[2];
808  }
809  break;
810  }
811  if (!(chip->eg_kon&1) && !mcsel && chip->rm_select != rm_num_tom && chip->rm_select != rm_num_hh) {
812  rate = 0;
813  }
814  if ((chip->eg_kon&1) && chip->eg_state[chip->cycles] == eg_num_release && !(chip->eg_off&1)) {
815  rate = 12;
816  }
817  if (!(chip->eg_kon&1) && !chip->son[ch_offset[chip->cycles]] && mcsel == 1 && !chip->c_et) {
818  rate = 7;
819  }
820  chip->eg_zerorate = rate == 0;
821  ksr = chip->c_ksr_freq;
822  if (!chip->c_ksr)
823  ksr >>= 2;
824  chip->eg_rate = (rate << 2) + ksr;
825  if (chip->eg_rate & 0x40) {
826  chip->eg_rate = 0x3c | (ksr & 3);
827  }
828  chip->eg_sl = chip->c_sl;
829 }
830 
831 static void OPLL_Channel(opll_t *chip) {
832  int16_t ch_out = chip->ch_out;
833  uint8_t ismod = (chip->cycles / 3) & 1;
834  uint8_t mute_m = ismod || ((chip->rm_enable&0x40) && (chip->cycles+15)%18 >= 12);
835  if (chip->chip_type == opll_type_ds1001) {
836  chip->output_m = ch_out;
837  if (chip->output_m >= 0) {
838  chip->output_m++;
839  }
840  if (mute_m) {
841  chip->output_m = 0;
842  }
843  chip->output_r = 0;
844  return;
845  } else {
846  uint8_t mute_r = 1;
847  /* TODO: This might be incorrect */
848  if ((chip->rm_enable & 0x40)) {
849  switch (chip->cycles) {
850  case 16: /* HH */
851  case 17: /* TOM */
852  case 0: /* BD */
853  case 1: /* SD */
854  case 2: /* TC */
855  case 3: /* HH */
856  case 4: /* TOM */
857  case 5: /* BD */
858  case 9: /* TOM */
859  case 10: /* TOM */
860  mute_r = 0;
861  break;
862  }
863  }
864  if (chip->chip_type == opll_type_ym2413b || chip->chip_type == opll_type_ymf281b) {
865  if (mute_m)
866  chip->output_m = 0;
867  else
868  chip->output_m = ch_out;
869  if (mute_r)
870  chip->output_r = 0;
871  else
872  chip->output_r = ch_out;
873  } else {
874  int16_t sign = ch_out >> 8;
875  if (ch_out >= 0) {
876  ch_out++;
877  sign++;
878  }
879  if (mute_m)
880  chip->output_m = sign;
881  else
882  chip->output_m = ch_out;
883  if (mute_r)
884  chip->output_r = sign;
885  else
886  chip->output_r = ch_out;
887  }
888  }
889 }
890 
891 static void OPLL_Operator(opll_t *chip) {
892  uint8_t ismod1, ismod2, ismod3;
893  uint32_t op_mod;
894  uint16_t exp_shift;
895  int16_t output;
896  uint32_t level;
897  uint32_t phase;
898  int16_t routput;
899  if ((chip->rm_enable & 0x80) && (chip->cycles == 15 || chip->cycles == 16)) {
900  ismod1 = 0;
901  } else {
902  ismod1 = ((chip->cycles + 1) / 3) & 1;
903  }
904  if ((chip->rm_enable & 0x40) && (chip->cycles == 13 || chip->cycles == 14)) {
905  ismod2 = 0;
906  } else {
907  ismod2 = ((chip->cycles + 3) / 3) & 1;
908  }
909  if ((chip->rm_enable & 0x40) && (chip->cycles == 16 || chip->cycles == 17)) {
910  ismod3 = 0;
911  } else {
912  ismod3 = (chip->cycles / 3) & 1;
913  }
914 
915  op_mod = 0;
916 
917  if (ismod3) {
918  op_mod |= chip->op_mod << 1;
919  }
920 
921  if (ismod2 && chip->c_fb) {
922  op_mod |= chip->op_fbsum >> (7 - chip->c_fb);
923  }
924 
925  exp_shift = chip->op_exp_s;
926  if (chip->eg_silent || ((chip->op_neg&2) && (ismod1 ? (chip->c_dm&4) : (chip->c_dc&4)))) {
927  exp_shift |= 12;
928  }
929 
930  output = chip->op_exp_m>>exp_shift;
931  if (!chip->eg_silent && (chip->op_neg&2)) {
932  output = ~output;
933  }
934 
935  level = chip->op_logsin+(chip->eg_out<<4);
936  if (level >= 4096) {
937  level = 4095;
938  }
939 
940  chip->op_exp_m = exprom[level & 0xff];
941  chip->op_exp_s = level >> 8;
942 
943  phase = (op_mod + chip->pg_out) & 0x3ff;
944  if (phase & 0x100) {
945  phase ^= 0xff;
946  }
947  chip->op_logsin = logsinrom[phase & 0xff];
948  chip->op_neg <<= 1;
949  chip->op_neg |= phase >> 9;
950  chip->op_fbsum = (chip->op_fb1[(chip->cycles + 3) % 9] + chip->op_fb2[(chip->cycles + 3) % 9]) >> 1;
951 
952  if (ismod1) {
953  chip->op_fb2[chip->cycles%9] = chip->op_fb1[chip->cycles%9];
954  chip->op_fb1[chip->cycles%9] = output;
955  }
956  chip->op_mod = output&0x1ff;
957 
958  if (chip->chip_type == opll_type_ds1001) {
959  routput = 0;
960  } else {
961  switch (chip->cycles) {
962  case 2:
963  routput = chip->ch_out_hh;
964  break;
965  case 3:
966  routput = chip->ch_out_tm;
967  break;
968  case 4:
969  routput = chip->ch_out_bd;
970  break;
971  case 8:
972  routput = chip->ch_out_sd;
973  break;
974  case 9:
975  routput = chip->ch_out_tc;
976  break;
977  default:
978  routput = 0; /* TODO: Not quite true */
979  break;
980  }
981  switch (chip->cycles) {
982  case 15:
983  chip->ch_out_hh = output>>3;
984  break;
985  case 16:
986  chip->ch_out_tm = output>>3;
987  break;
988  case 17:
989  chip->ch_out_bd = output>>3;
990  break;
991  case 0:
992  chip->ch_out_sd = output>>3;
993  break;
994  case 1:
995  chip->ch_out_tc = output>>3;
996  break;
997  default:
998  break;
999  }
1000  }
1001 
1002  chip->ch_out = ismod1 ? routput : (output>>3);
1003 }
1004 
1005 static void OPLL_DoRhythm(opll_t *chip) {
1006  uint8_t nbit;
1007 
1008  /* Noise */
1009  nbit = (chip->rm_noise ^ (chip->rm_noise >> 14)) & 0x01;
1010  nbit |= (chip->rm_noise == 0x00) | ((chip->testmode >> 1) & 0x01);
1011  chip->rm_noise = (nbit << 22) | (chip->rm_noise >> 1);
1012 }
1013 
1014 static void OPLL_DoLFO(opll_t *chip) {
1015  uint8_t am_inc = 0;
1016  uint8_t am_bit;
1017 
1018  /* Update counter */
1019  if (chip->cycles == 17) {
1020  uint8_t vib_step = ((chip->lfo_counter & 0x3ff) + 1) >> 10;
1021  chip->lfo_am_step = ((chip->lfo_counter & 0x3f) + 1) >> 6;
1022  vib_step |= (chip->testmode >> 3) & 0x01;
1023  chip->lfo_vib_counter += vib_step;
1024  chip->lfo_vib_counter &= 0x07;
1025  chip->lfo_counter++;
1026  }
1027 
1028  /* LFO AM */
1029  if ((chip->lfo_am_step || (chip->testmode & 0x08)) && chip->cycles < 9) {
1030  am_inc = chip->lfo_am_dir | (chip->cycles == 0);
1031  }
1032 
1033  if (chip->cycles >= 9) {
1034  chip->lfo_am_car = 0;
1035  }
1036 
1037  if (chip->cycles == 0) {
1038  if (chip->lfo_am_dir && (chip->lfo_am_counter & 0x7f) == 0) {
1039  chip->lfo_am_dir = 0;
1040  } else if (!chip->lfo_am_dir && (chip->lfo_am_counter & 0x69) == 0x69) {
1041  chip->lfo_am_dir = 1;
1042  }
1043  }
1044 
1045  am_bit = chip->lfo_am_counter & 0x01;
1046  am_bit += am_inc + chip->lfo_am_car;
1047  chip->lfo_am_car = am_bit >> 1;
1048  am_bit &= 0x01;
1049  chip->lfo_am_counter = (am_bit << 8) | (chip->lfo_am_counter >> 1);
1050 
1051 
1052  /* Reset LFO */
1053  if (chip->testmode & 0x02) {
1054  chip->lfo_vib_counter = 0;
1055  chip->lfo_counter = 0;
1056  chip->lfo_am_dir = 0;
1057  chip->lfo_am_counter &= 0xff;
1058  }
1059 }
1060 
1061 
1062 void OPLL_Clock(opll_t *chip, int32_t *buffer) {
1063  buffer[0] = chip->output_m;
1064  buffer[1] = chip->output_r;
1065  if (chip->cycles == 0) {
1066  chip->lfo_am_out = (chip->lfo_am_counter >> 3) & 0x0f;
1067  }
1068  chip->rm_enable >>= 1;
1069  OPLL_DoModeWrite(chip);
1070  chip->rm_select++;
1071  if (chip->rm_select > rm_num_tc) {
1072  chip->rm_select = rm_num_tc + 1;
1073  }
1074  if (chip->cycles == 11 && (chip->rm_enable & 0x80) == 0x80) {
1075  chip->rm_select = rm_num_bd0;
1076  }
1077  OPLL_PreparePatch1(chip);
1078 
1079  OPLL_Channel(chip);
1080 
1081  OPLL_PhaseGenerate(chip);
1082 
1083  OPLL_Operator(chip);
1084 
1085  OPLL_PhaseCalcIncrement(chip);
1086 
1087  OPLL_EnvelopeOutput(chip);
1088  OPLL_EnvelopeKSLTL(chip);
1089  OPLL_EnvelopeGenerate(chip);
1090 
1091  OPLL_DoLFO(chip);
1092  OPLL_DoRhythm(chip);
1093  OPLL_PreparePatch2(chip);
1094  OPLL_DoRegWrite(chip);
1095  OPLL_DoIO(chip);
1096  chip->cycles = (chip->cycles + 1) % 18;
1097 
1098 }
1099 
1100 
1101 void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data) {
1102  chip->write_data = data;
1103  if (port & 1) {
1104  /* Data */
1105  chip->write_d |= 1;
1106  } else {
1107  /* Address */
1108  chip->write_a |= 1;
1109  }
1110 }
constexpr auto step
Definition: eeprom.cc:9
void OPLL_Reset(opll_t *chip, uint32_t chip_type)
Definition: opll.cc:293
void OPLL_Write(opll_t *chip, uint32_t port, uint8_t data)
Definition: opll.cc:1101
void OPLL_Clock(opll_t *chip, int32_t *buffer)
Definition: opll.cc:1062
@ eg_num_sustain
Definition: opll.cc:29
@ eg_num_decay
Definition: opll.cc:28
@ eg_num_attack
Definition: opll.cc:27
@ eg_num_release
Definition: opll.cc:30
@ rm_num_bd1
Definition: opll.cc:37
@ rm_num_sd
Definition: opll.cc:38
@ rm_num_tc
Definition: opll.cc:39
@ rm_num_tom
Definition: opll.cc:36
@ rm_num_hh
Definition: opll.cc:35
@ rm_num_bd0
Definition: opll.cc:34
@ opll_type_ym2413b
Definition: opll.hh:31
@ opll_type_ym2420
Definition: opll.hh:34
@ opll_type_ds1001
Definition: opll.hh:30
@ opll_type_ymf281b
Definition: opll.hh:33
@ opll_type_ymf281
Definition: opll.hh:32
@ opll_type_ym2423
Definition: opll.hh:35
@ opll_type_ym2413
Definition: opll.hh:29
@ opll_patch_1
Definition: opll.hh:39
@ opll_patch_max
Definition: opll.hh:60
@ opll_patch_drum_0
Definition: opll.hh:54
auto sum(InputRange &&range, Proj proj={})
Definition: stl.hh:244
uint8_t tl
Definition: opll.hh:64
uint8_t rr[2]
Definition: opll.hh:77
uint8_t ar[2]
Definition: opll.hh:74
uint8_t vib[2]
Definition: opll.hh:69
uint8_t dm
Definition: opll.hh:66
uint8_t fb
Definition: opll.hh:67
uint8_t dc
Definition: opll.hh:65
uint8_t sl[2]
Definition: opll.hh:76
uint8_t dr[2]
Definition: opll.hh:75
uint8_t am[2]
Definition: opll.hh:68
uint8_t multi[2]
Definition: opll.hh:72
uint8_t et[2]
Definition: opll.hh:70
uint8_t ksl[2]
Definition: opll.hh:73
uint8_t ksr[2]
Definition: opll.hh:71
Definition: opll.hh:80
uint8_t rm_hh_bit7
Definition: opll.hh:186
uint8_t c_tl
Definition: opll.hh:163
uint8_t address
Definition: opll.hh:94
uint8_t eg_timer_shift_stop
Definition: opll.hh:104
uint8_t write_a_en
Definition: opll.hh:89
uint8_t c_sl
Definition: opll.hh:177
uint16_t c_fnum
Definition: opll.hh:178
uint16_t lfo_counter
Definition: opll.hh:144
uint8_t c_ksl_freq
Definition: opll.hh:172
uint8_t eg_timer_low_lock
Definition: opll.hh:100
uint8_t son[9]
Definition: opll.hh:155
uint32_t pg_phase[18]
Definition: opll.hh:125
uint8_t lfo_vib_counter
Definition: opll.hh:145
uint8_t eg_off
Definition: opll.hh:109
uint8_t write_fm_data
Definition: opll.hh:92
uint8_t c_vib
Definition: opll.hh:168
uint8_t c_am
Definition: opll.hh:167
uint8_t inst[9]
Definition: opll.hh:157
uint8_t lfo_am_car
Definition: opll.hh:149
int16_t op_fb1[9]
Definition: opll.hh:128
uint32_t eg_timer
Definition: opll.hh:99
uint8_t eg_counter_state
Definition: opll.hh:97
uint8_t eg_timer_shift_lock
Definition: opll.hh:103
int16_t ch_out_bd
Definition: opll.hh:140
uint8_t rm_hh_bit3
Definition: opll.hh:185
uint16_t op_logsin
Definition: opll.hh:133
uint16_t op_exp_m
Definition: opll.hh:134
uint32_t rm_noise
Definition: opll.hh:182
uint8_t write_d
Definition: opll.hh:88
uint8_t c_fb
Definition: opll.hh:166
int16_t ch_out_tc
Definition: opll.hh:142
uint32_t cycles
Definition: opll.hh:82
opll_patch_t patch
Definition: opll.hh:160
uint16_t lfo_am_counter
Definition: opll.hh:146
uint8_t testmode
Definition: opll.hh:159
uint8_t eg_rate_hi
Definition: opll.hh:115
int16_t op_fbsum
Definition: opll.hh:130
uint8_t lfo_am_step
Definition: opll.hh:147
int16_t ch_out_hh
Definition: opll.hh:138
uint16_t eg_sl
Definition: opll.hh:116
uint8_t c_multi
Definition: opll.hh:174
uint8_t lfo_am_out
Definition: opll.hh:150
uint32_t eg_dokon
Definition: opll.hh:108
uint8_t rm_hh_bit2
Definition: opll.hh:184
uint8_t c_adrr[3]
Definition: opll.hh:176
uint16_t eg_ksltl
Definition: opll.hh:117
uint8_t c_ksl_block
Definition: opll.hh:173
uint8_t rm_hh_bit8
Definition: opll.hh:187
int8_t rm_enable
Definition: opll.hh:181
uint8_t eg_level[18]
Definition: opll.hh:106
uint8_t write_a
Definition: opll.hh:87
uint8_t rhythm
Definition: opll.hh:158
int16_t op_mod
Definition: opll.hh:131
uint8_t rm_tc_bit3
Definition: opll.hh:188
uint16_t fnum[9]
Definition: opll.hh:152
int16_t ch_out
Definition: opll.hh:137
uint16_t c_block
Definition: opll.hh:179
uint8_t c_ksl
Definition: opll.hh:175
uint8_t eg_state[18]
Definition: opll.hh:105
uint32_t pg_phase_next
Definition: opll.hh:126
uint8_t op_neg
Definition: opll.hh:132
uint8_t eg_maxrate
Definition: opll.hh:111
uint8_t write_d_en
Definition: opll.hh:90
uint8_t eg_silent
Definition: opll.hh:119
uint32_t rm_select
Definition: opll.hh:183
uint8_t rm_tc_bit5
Definition: opll.hh:189
uint8_t eg_timer_carry
Definition: opll.hh:101
uint8_t eg_kon
Definition: opll.hh:107
int16_t output_r
Definition: opll.hh:192
uint8_t lfo_am_dir
Definition: opll.hh:148
uint32_t chip_type
Definition: opll.hh:81
int16_t ch_out_sd
Definition: opll.hh:141
uint8_t eg_timer_shift
Definition: opll.hh:102
uint8_t write_fm_address
Definition: opll.hh:91
uint8_t eg_zerorate
Definition: opll.hh:112
uint16_t op_exp_s
Definition: opll.hh:135
uint16_t pg_out
Definition: opll.hh:123
uint8_t block[9]
Definition: opll.hh:153
uint8_t data
Definition: opll.hh:95
uint32_t pg_inc
Definition: opll.hh:124
uint8_t c_ksr
Definition: opll.hh:170
uint8_t eg_counter_state_prev
Definition: opll.hh:98
uint8_t eg_out
Definition: opll.hh:118
int16_t op_fb2[9]
Definition: opll.hh:129
const opll_patch_t * patchrom
Definition: opll.hh:84
uint8_t c_et
Definition: opll.hh:169
uint8_t write_data
Definition: opll.hh:86
uint8_t c_ksr_freq
Definition: opll.hh:171
uint8_t c_dc
Definition: opll.hh:164
uint8_t write_mode_address
Definition: opll.hh:93
uint8_t eg_inc_lo
Definition: opll.hh:113
uint8_t eg_inc_hi
Definition: opll.hh:114
uint8_t c_dm
Definition: opll.hh:165
uint8_t eg_rate
Definition: opll.hh:110
uint8_t kon[9]
Definition: opll.hh:154
uint8_t vol[9]
Definition: opll.hh:156
int16_t output_m
Definition: opll.hh:191
int16_t ch_out_tm
Definition: opll.hh:139