54 static constexpr
auto tl_tab = [] {
55 std::array<int, TL_TAB_LEN> result = {};
57 double m = (1 << 16) / cstd::exp2<6>((
x + 1) * (
ENV_STEP / 4.0) / 8.0);
71 result[
x * 2 + 0] = n;
72 result[
x * 2 + 1] = -result[
x * 2 + 0];
74 for (
auto i :
xrange(1, 13)) {
75 result[
x * 2 + 0 + i * 2 *
TL_RES_LEN] = result[
x * 2 + 0] >> i;
85 static constexpr
auto sin_tab = [] {
86 std::array<unsigned, SIN_LEN> result = {};
92 double o = -8.0 * cstd::log2<8, 3>(
cstd::abs(m));
101 result[i] = n * 2 + (m >= 0.0 ? 0 : 1);
108 static constexpr
auto d1l_tab = [] {
109 std::array<unsigned, 16> result = {};
111 for (
int i = 0; i < 16; ++i) {
113 result[i] = unsigned((i != 15 ? i : i + 16) * (4.0 /
ENV_STEP));
145 16,16,16,16,16,16,16,16,
150 static constexpr
byte O(
int a) {
return a *
RATE_STEPS; }
155 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
156 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
157 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
158 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
161 O( 0),O( 1),O( 2),O( 3),
162 O( 0),O( 1),O( 2),O( 3),
163 O( 0),O( 1),O( 2),O( 3),
164 O( 0),O( 1),O( 2),O( 3),
165 O( 0),O( 1),O( 2),O( 3),
166 O( 0),O( 1),O( 2),O( 3),
167 O( 0),O( 1),O( 2),O( 3),
168 O( 0),O( 1),O( 2),O( 3),
169 O( 0),O( 1),O( 2),O( 3),
170 O( 0),O( 1),O( 2),O( 3),
171 O( 0),O( 1),O( 2),O( 3),
172 O( 0),O( 1),O( 2),O( 3),
175 O( 4),O( 5),O( 6),O( 7),
178 O( 8),O( 9),O(10),O(11),
181 O(12),O(13),O(14),O(15),
184 O(16),O(16),O(16),O(16),
187 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
188 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
189 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
190 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
199 0, 0, 0, 0, 0, 0, 0, 0,
200 0, 0, 0, 0, 0, 0, 0, 0,
201 0, 0, 0, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0, 0
246 constexpr
unsigned dt2_tab[4] = { 0, 384, 500, 608 };
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
258 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
261 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
262 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
265 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
266 8, 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
270 1299,1300,1301,1302,1303,1304,1305,1306,1308,1309,1310,1311,1313,1314,1315,1316,
271 1318,1319,1320,1321,1322,1323,1324,1325,1327,1328,1329,1330,1332,1333,1334,1335,
272 1337,1338,1339,1340,1341,1342,1343,1344,1346,1347,1348,1349,1351,1352,1353,1354,
273 1356,1357,1358,1359,1361,1362,1363,1364,1366,1367,1368,1369,1371,1372,1373,1374,
274 1376,1377,1378,1379,1381,1382,1383,1384,1386,1387,1388,1389,1391,1392,1393,1394,
275 1396,1397,1398,1399,1401,1402,1403,1404,1406,1407,1408,1409,1411,1412,1413,1414,
276 1416,1417,1418,1419,1421,1422,1423,1424,1426,1427,1429,1430,1431,1432,1434,1435,
277 1437,1438,1439,1440,1442,1443,1444,1445,1447,1448,1449,1450,1452,1453,1454,1455,
278 1458,1459,1460,1461,1463,1464,1465,1466,1468,1469,1471,1472,1473,1474,1476,1477,
279 1479,1480,1481,1482,1484,1485,1486,1487,1489,1490,1492,1493,1494,1495,1497,1498,
280 1501,1502,1503,1504,1506,1507,1509,1510,1512,1513,1514,1515,1517,1518,1520,1521,
281 1523,1524,1525,1526,1528,1529,1531,1532,1534,1535,1536,1537,1539,1540,1542,1543,
282 1545,1546,1547,1548,1550,1551,1553,1554,1556,1557,1558,1559,1561,1562,1564,1565,
283 1567,1568,1569,1570,1572,1573,1575,1576,1578,1579,1580,1581,1583,1584,1586,1587,
284 1590,1591,1592,1593,1595,1596,1598,1599,1601,1602,1604,1605,1607,1608,1609,1610,
285 1613,1614,1615,1616,1618,1619,1621,1622,1624,1625,1627,1628,1630,1631,1632,1633,
286 1637,1638,1639,1640,1642,1643,1645,1646,1648,1649,1651,1652,1654,1655,1656,1657,
287 1660,1661,1663,1664,1666,1667,1669,1670,1672,1673,1675,1676,1678,1679,1681,1682,
288 1685,1686,1688,1689,1691,1692,1694,1695,1697,1698,1700,1701,1703,1704,1706,1707,
289 1709,1710,1712,1713,1715,1716,1718,1719,1721,1722,1724,1725,1727,1728,1730,1731,
290 1734,1735,1737,1738,1740,1741,1743,1744,1746,1748,1749,1751,1752,1754,1755,1757,
291 1759,1760,1762,1763,1765,1766,1768,1769,1771,1773,1774,1776,1777,1779,1780,1782,
292 1785,1786,1788,1789,1791,1793,1794,1796,1798,1799,1801,1802,1804,1806,1807,1809,
293 1811,1812,1814,1815,1817,1819,1820,1822,1824,1825,1827,1828,1830,1832,1833,1835,
294 1837,1838,1840,1841,1843,1845,1846,1848,1850,1851,1853,1854,1856,1858,1859,1861,
295 1864,1865,1867,1868,1870,1872,1873,1875,1877,1879,1880,1882,1884,1885,1887,1888,
296 1891,1892,1894,1895,1897,1899,1900,1902,1904,1906,1907,1909,1911,1912,1914,1915,
297 1918,1919,1921,1923,1925,1926,1928,1930,1932,1933,1935,1937,1939,1940,1942,1944,
298 1946,1947,1949,1951,1953,1954,1956,1958,1960,1961,1963,1965,1967,1968,1970,1972,
299 1975,1976,1978,1980,1982,1983,1985,1987,1989,1990,1992,1994,1996,1997,1999,2001,
300 2003,2004,2006,2008,2010,2011,2013,2015,2017,2019,2021,2022,2024,2026,2028,2029,
301 2032,2033,2035,2037,2039,2041,2043,2044,2047,2048,2050,2052,2054,2056,2058,2059,
302 2062,2063,2065,2067,2069,2071,2073,2074,2077,2078,2080,2082,2084,2086,2088,2089,
303 2092,2093,2095,2097,2099,2101,2103,2104,2107,2108,2110,2112,2114,2116,2118,2119,
304 2122,2123,2125,2127,2129,2131,2133,2134,2137,2139,2141,2142,2145,2146,2148,2150,
305 2153,2154,2156,2158,2160,2162,2164,2165,2168,2170,2172,2173,2176,2177,2179,2181,
306 2185,2186,2188,2190,2192,2194,2196,2197,2200,2202,2204,2205,2208,2209,2211,2213,
307 2216,2218,2220,2222,2223,2226,2227,2230,2232,2234,2236,2238,2239,2242,2243,2246,
308 2249,2251,2253,2255,2256,2259,2260,2263,2265,2267,2269,2271,2272,2275,2276,2279,
309 2281,2283,2285,2287,2288,2291,2292,2295,2297,2299,2301,2303,2304,2307,2308,2311,
310 2315,2317,2319,2321,2322,2325,2326,2329,2331,2333,2335,2337,2338,2341,2342,2345,
311 2348,2350,2352,2354,2355,2358,2359,2362,2364,2366,2368,2370,2371,2374,2375,2378,
312 2382,2384,2386,2388,2389,2392,2393,2396,2398,2400,2402,2404,2407,2410,2411,2414,
313 2417,2419,2421,2423,2424,2427,2428,2431,2433,2435,2437,2439,2442,2445,2446,2449,
314 2452,2454,2456,2458,2459,2462,2463,2466,2468,2470,2472,2474,2477,2480,2481,2484,
315 2488,2490,2492,2494,2495,2498,2499,2502,2504,2506,2508,2510,2513,2516,2517,2520,
316 2524,2526,2528,2530,2531,2534,2535,2538,2540,2542,2544,2546,2549,2552,2553,2556,
317 2561,2563,2565,2567,2568,2571,2572,2575,2577,2579,2581,2583,2586,2589,2590,2593
335 static constexpr
auto freq = [] {
336 std::array<unsigned, 11 * 768> result = {};
344 double mult = 1 << (
FREQ_SH - 10);
346 for (
auto i :
xrange(768)) {
351 result[768 + 2 * 768 + i] = int(phaseinc * mult) & 0xffffffc0;
353 for (
auto j :
xrange(2)) {
355 result[768 + j * 768 + i] = (result[768 + 2 * 768 + i] >> (2 - j)) & 0xffffffc0;
358 for (
auto j :
xrange(3, 8)) {
359 result[768 + j * 768 + i] = result[768 + 2 * 768 + i] << (j - 2);
364 for (
auto i :
xrange(768)) {
365 result[0 * 768 + i] = result[1 * 768 + 0];
369 for (
auto j :
xrange(8, 10)) {
370 for (
auto i :
xrange(768)) {
371 result[768 + j * 768 + i] = result[768 + 8 * 768 - 1];
379 static constexpr
auto dt1_freq = [] {
380 std::array<int, 8 * 32> result = {};
382 for (
auto j :
xrange(4)) {
383 for (
auto i :
xrange(32)) {
385 double phaseinc = double(
dt1_tab[j * 32 + i]) / (1 << 20) *
SIN_LEN;
388 result[(j + 0) * 32 + i] =
int(phaseinc * mult);
389 result[(j + 4) * 32 + i] = -result[(j + 0) * 32 + i];
397 static constexpr
auto noise_tab = [] {
398 std::array<unsigned, 32> result = {};
400 for (
int i = 0; i < 32; ++i) {
401 result[i] = 32 - (i != 31 ? i : 30);
421 0xFF,0xEE,0xD3,0x80,0x58,0xDA,0x7F,0x94,0x9E,0xE3,0xFA,0x00,0x4D,0xFA,0xFF,0x6A,
422 0x7A,0xDE,0x49,0xF6,0x00,0x33,0xBB,0x63,0x91,0x60,0x51,0xFF,0x00,0xD8,0x7F,0xDE,
423 0xDC,0x73,0x21,0x85,0xB2,0x9C,0x5D,0x24,0xCD,0x91,0x9E,0x76,0x7F,0x20,0xFB,0xF3,
424 0x00,0xA6,0x3E,0x42,0x27,0x69,0xAE,0x33,0x45,0x44,0x11,0x41,0x72,0x73,0xDF,0xA2,
426 0x32,0xBD,0x7E,0xA8,0x13,0xEB,0xD3,0x15,0xDD,0xFB,0xC9,0x9D,0x61,0x2F,0xBE,0x9D,
427 0x23,0x65,0x51,0x6A,0x84,0xF9,0xC9,0xD7,0x23,0xBF,0x65,0x19,0xDC,0x03,0xF3,0x24,
428 0x33,0xB6,0x1E,0x57,0x5C,0xAC,0x25,0x89,0x4D,0xC5,0x9C,0x99,0x15,0x07,0xCF,0xBA,
429 0xC5,0x9B,0x15,0x4D,0x8D,0x2A,0x1E,0x1F,0xEA,0x2B,0x2F,0x64,0xA9,0x50,0x3D,0xAB,
431 0x50,0x77,0xE9,0xC0,0xAC,0x6D,0x3F,0xCA,0xCF,0x71,0x7D,0x80,0xA6,0xFD,0xFF,0xB5,
432 0xBD,0x6F,0x24,0x7B,0x00,0x99,0x5D,0xB1,0x48,0xB0,0x28,0x7F,0x80,0xEC,0xBF,0x6F,
433 0x6E,0x39,0x90,0x42,0xD9,0x4E,0x2E,0x12,0x66,0xC8,0xCF,0x3B,0x3F,0x10,0x7D,0x79,
434 0x00,0xD3,0x1F,0x21,0x93,0x34,0xD7,0x19,0x22,0xA2,0x08,0x20,0xB9,0xB9,0xEF,0x51,
436 0x99,0xDE,0xBF,0xD4,0x09,0x75,0xE9,0x8A,0xEE,0xFD,0xE4,0x4E,0x30,0x17,0xDF,0xCE,
437 0x11,0xB2,0x28,0x35,0xC2,0x7C,0x64,0xEB,0x91,0x5F,0x32,0x0C,0x6E,0x00,0xF9,0x92,
438 0x19,0xDB,0x8F,0xAB,0xAE,0xD6,0x12,0xC4,0x26,0x62,0xCE,0xCC,0x0A,0x03,0xE7,0xDD,
439 0xE2,0x4D,0x8A,0xA6,0x46,0x95,0x0F,0x8F,0xF5,0x15,0x97,0x32,0xD4,0x28,0x1E,0x55
442 void YM2151::keyOn(YM2151Operator* op,
unsigned keySet) {
446 op->volume += (~op->volume *
447 (
eg_inc[op->eg_sel_ar + ((eg_cnt >> op->eg_sh_ar)&7)])
457 void YM2151::keyOff(YM2151Operator* op,
unsigned keyClear) {
468 void YM2151::envelopeKONKOFF(YM2151Operator* op,
int v)
473 keyOff(op + 0,
unsigned(~1));
478 keyOff(op + 1,
unsigned(~1));
483 keyOff(op + 2,
unsigned(~1));
488 keyOff(op + 3,
unsigned(~1));
492 void YM2151::setConnect(YM2151Operator* om1,
int cha,
int v)
494 YM2151Operator* om2 = om1 + 1;
495 YM2151Operator* oc1 = om1 + 2;
505 om1->mem_connect = &m2;
514 om1->mem_connect = &m2;
523 om1->mem_connect = &m2;
532 om1->mem_connect = &c2;
540 oc1->connect = &chanout[cha];
542 om1->mem_connect = &mem;
549 om1->connect =
nullptr;
550 oc1->connect = &chanout[cha];
551 om2->connect = &chanout[cha];
552 om1->mem_connect = &m2;
561 oc1->connect = &chanout[cha];
562 om2->connect = &chanout[cha];
563 om1->mem_connect = &mem;
572 om1->connect = &chanout[cha];
573 oc1->connect = &chanout[cha];
574 om2->connect = &chanout[cha];
575 om1->mem_connect = &mem;
580 void YM2151::refreshEG(YM2151Operator* op)
582 unsigned kc = op->kc;
585 unsigned v = kc >> op->ks;
586 if ((op->ar + v) < 32 + 62) {
602 if ((op->ar + v) < 32 + 62) {
618 if ((op->ar + v) < 32 + 62) {
634 if ((op->ar + v) < 32 + 62) {
653 YM2151Operator* op = &oper[(r & 0x07) * 4 + ((r & 0x18) >> 3)];
665 if (v & 2) lfo_phase = 0;
670 envelopeKONKOFF(&oper[(v & 7) * 4], v);
675 noise_f = noise_tab[v & 0x1f];
681 timer_A_val |= v << 2;
682 timer1->setValue(timer_A_val);
686 timer_A_val &= 0x03fc;
687 timer_A_val |= v & 3;
688 timer1->setValue(timer_A_val);
703 timer1->setStart((v & 4) != 0, time);
704 timer2->setStart((v & 8) != 0, time);
708 lfo_overflow = (1 << ((15 - (v >> 4)) + 3));
709 lfo_counter_add = 0x10 + (v & 0x0f);
732 op = &oper[(r & 7) * 4];
735 op->fb_shift = ((v >> 3) & 7) ? ((v >> 3) & 7) + 6 : 0;
736 pan[(r & 7) * 2 + 0] = (v & 0x40) ? ~0 : 0;
737 pan[(r & 7) * 2 + 1] = (v & 0x80) ? ~0 : 0;
738 setConnect(op, r & 7, v & 7);
744 unsigned kc_channel = (v - (v>>2))*64;
746 kc_channel |= (op->kc_i & 63);
749 (op + 0)->kc_i = kc_channel;
751 (op + 1)->kc_i = kc_channel;
753 (op + 2)->kc_i = kc_channel;
755 (op + 3)->kc_i = kc_channel;
758 (op + 0)->dt1 = dt1_freq[(op + 0)->dt1_i + kc];
759 (op + 0)->freq = ((freq[kc_channel + (op + 0)->dt2] + (op + 0)->dt1) * (op + 0)->mul) >> 1;
761 (op + 1)->dt1 = dt1_freq[(op + 1)->dt1_i + kc];
762 (op + 1)->freq = ((freq[kc_channel + (op + 1)->dt2] + (op + 1)->dt1) * (op + 1)->mul) >> 1;
764 (op + 2)->dt1 = dt1_freq[(op + 2)->dt1_i + kc];
765 (op + 2)->freq = ((freq[kc_channel + (op + 2)->dt2] + (op + 2)->dt1) * (op + 2)->mul) >> 1;
767 (op + 3)->dt1 = dt1_freq[(op + 3)->dt1_i + kc];
768 (op + 3)->freq = ((freq[kc_channel + (op + 3)->dt2] + (op + 3)->dt1) * (op + 3)->mul) >> 1;
776 if (v != (op->kc_i & 63)) {
777 unsigned kc_channel = v;
778 kc_channel |= (op->kc_i & ~63);
780 (op + 0)->kc_i = kc_channel;
781 (op + 1)->kc_i = kc_channel;
782 (op + 2)->kc_i = kc_channel;
783 (op + 3)->kc_i = kc_channel;
785 (op + 0)->freq = ((freq[kc_channel + (op + 0)->dt2] + (op + 0)->dt1) * (op + 0)->mul) >> 1;
786 (op + 1)->freq = ((freq[kc_channel + (op + 1)->dt2] + (op + 1)->dt1) * (op + 1)->mul) >> 1;
787 (op + 2)->freq = ((freq[kc_channel + (op + 2)->dt2] + (op + 2)->dt1) * (op + 2)->mul) >> 1;
788 (op + 3)->freq = ((freq[kc_channel + (op + 3)->dt2] + (op + 3)->dt1) * (op + 3)->mul) >> 1;
793 op->pms = (v >> 4) & 7;
800 unsigned olddt1_i = op->dt1_i;
801 unsigned oldmul = op->mul;
803 op->dt1_i = (v & 0x70) << 1;
804 op->mul = (v & 0x0f) ? (v & 0x0f) << 1 : 1;
806 if (olddt1_i != op->dt1_i) {
807 op->dt1 = dt1_freq[op->dt1_i + (op->kc>>2)];
809 if ((olddt1_i != op->dt1_i) || (oldmul != op->mul)) {
810 op->freq = ((freq[op->kc_i + op->dt2] + op->dt1) * op->mul) >> 1;
815 op->tl = (v & 0x7f) << (
ENV_BITS - 7);
819 unsigned oldKs = op->ks;
820 unsigned oldAr = op->ar;
821 op->ks = 5 - (v >> 6);
822 op->ar = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
824 if ((op->ar != oldAr) || (op->ks != oldKs)) {
825 if ((op->ar + (op->kc >> op->ks)) < 32 + 62) {
833 if (op->ks != oldKs) {
834 op->eg_sh_d1r =
eg_rate_shift [op->d1r + (op->kc >> op->ks)];
836 op->eg_sh_d2r =
eg_rate_shift [op->d2r + (op->kc >> op->ks)];
844 op->AMmask = (v & 0x80) ? ~0 : 0;
845 op->d1r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
846 op->eg_sh_d1r =
eg_rate_shift [op->d1r + (op->kc >> op->ks)];
851 unsigned olddt2 = op->dt2;
853 if (op->dt2 != olddt2) {
854 op->freq = ((freq[op->kc_i + op->dt2] + op->dt1) * op->mul) >> 1;
856 op->d2r = (v & 0x1f) ? 32 + ((v & 0x1f) << 1) : 0;
857 op->eg_sh_d2r =
eg_rate_shift [op->d2r + (op->kc >> op->ks)];
862 op->d1l = d1l_tab[v >> 4];
863 op->rr = 34 + ((v & 0x0f) << 2);
870 constexpr
auto INPUT_RATE = unsigned(
cstd::round(3579545 / 64.0));
875 , irq(config.getMotherBoard(),
getName() +
".IRQ")
876 , timer1(
EmuTimer::createOPM_1(config.getScheduler(), *this))
877 , timer2(variant_ ==
Variant::YM2164 ?
EmuTimer::createOPP_2(config.getScheduler(), *this)
878 :
EmuTimer::createOPM_2(config.getScheduler(), *this))
884 memset(regs, 0,
sizeof(regs));
889 std::cout <<
"tl_tab:";
890 for (
const auto&
e : tl_tab) std::cout <<
' ' <<
e;
893 std::cout <<
"sin_tab:";
894 for (
const auto&
e : sin_tab) std::cout <<
' ' <<
e;
897 std::cout <<
"d1l_tab:";
898 for (
const auto&
e : d1l_tab) std::cout <<
' ' <<
e;
901 std::cout <<
"freq:";
902 for (
const auto&
e : freq) std::cout <<
' ' <<
e;
905 std::cout <<
"dt1_freq:";
906 for (
const auto&
e : dt1_freq) std::cout <<
' ' <<
e;
909 std::cout <<
"noise_tab:";
910 for (
const auto&
e : noise_tab) std::cout <<
' ' <<
e;
924 bool YM2151::checkMuteHelper()
932 for (
auto& op : oper) {
933 memset(&op,
'\0',
sizeof(op));
953 timer1->setStart(
false, time);
954 timer2->setStart(
false, time);
959 noise_f = noise_tab[0];
966 for (
auto i :
xrange(0x20, 0x100)) {
973 int YM2151::opCalc(YM2151Operator* OP,
unsigned env,
int pm)
982 int YM2151::opCalc1(YM2151Operator* OP,
unsigned env,
int pm)
992 unsigned YM2151::volumeCalc(YM2151Operator* OP,
unsigned AM)
994 return OP->tl + unsigned(OP->volume) + (AM & OP->AMmask);
997 void YM2151::chanCalc(
unsigned chan)
999 m2 = c1 = c2 = mem = 0;
1000 YM2151Operator* op = &oper[chan*4];
1001 *op->mem_connect = op->mem_value;
1005 AM = lfa << (op->ams-1);
1007 unsigned env = volumeCalc(op, AM);
1009 int out = op->fb_out_prev + op->fb_out_curr;
1010 op->fb_out_prev = op->fb_out_curr;
1014 mem = c1 = c2 = op->fb_out_prev;
1016 *op->connect = op->fb_out_prev;
1018 op->fb_out_curr = 0;
1020 if (!op->fb_shift) {
1023 op->fb_out_curr = opCalc1(op, env, (out << op->fb_shift));
1027 env = volumeCalc(op + 1, AM);
1029 *(op + 1)->connect += opCalc(op + 1, env, m2);
1031 env = volumeCalc(op + 2, AM);
1033 *(op + 2)->connect += opCalc(op + 2, env, c1);
1035 env = volumeCalc(op + 3, AM);
1037 chanout[chan] += opCalc(op + 3, env, c2);
1040 op->mem_value = mem;
1043 void YM2151::chan7Calc()
1045 m2 = c1 = c2 = mem = 0;
1046 YM2151Operator* op = &oper[7 * 4];
1048 *op->mem_connect = op->mem_value;
1052 AM = lfa << (op->ams - 1);
1054 unsigned env = volumeCalc(op, AM);
1056 int out = op->fb_out_prev + op->fb_out_curr;
1057 op->fb_out_prev = op->fb_out_curr;
1061 mem = c1 = c2 = op->fb_out_prev;
1064 *op->connect = op->fb_out_prev;
1066 op->fb_out_curr = 0;
1068 if (!op->fb_shift) {
1071 op->fb_out_curr = opCalc1(op, env, (out << op->fb_shift));
1075 env = volumeCalc(op + 1, AM);
1077 *(op + 1)->connect += opCalc(op + 1, env, m2);
1079 env = volumeCalc(op + 2, AM);
1081 *(op + 2)->connect += opCalc(op + 2, env, c1);
1083 env = volumeCalc(op + 3, AM);
1085 unsigned noiseout = 0;
1087 noiseout = (env ^ 0x3ff) * 2;
1089 chanout[7] += (noise_rng & 0x10000) ? noiseout :
unsigned(-
int(noiseout));
1092 chanout[7] += opCalc(op + 3, env, c2);
1096 op->mem_value = mem;
1303 void YM2151::advanceEG()
1305 if (eg_timer++ != 3) {
1313 for (
auto& op : oper) {
1316 if (!(eg_cnt & ((1 << op.eg_sh_ar) - 1))) {
1317 op.volume += (~op.volume *
1318 (
eg_inc[op.eg_sel_ar + ((eg_cnt >> op.eg_sh_ar) & 7)])
1328 if (!(eg_cnt & ((1 << op.eg_sh_d1r) - 1))) {
1329 op.volume +=
eg_inc[op.eg_sel_d1r + ((eg_cnt >> op.eg_sh_d1r) & 7)];
1330 if (
unsigned(op.volume) >= op.d1l) {
1337 if (!(eg_cnt & ((1 << op.eg_sh_d2r) - 1))) {
1338 op.volume +=
eg_inc[op.eg_sel_d2r + ((eg_cnt >> op.eg_sh_d2r) & 7)];
1347 if (!(eg_cnt & ((1 << op.eg_sh_rr) - 1))) {
1348 op.volume +=
eg_inc[op.eg_sel_rr + ((eg_cnt >> op.eg_sh_rr) & 7)];
1359 void YM2151::advance()
1365 if (lfo_timer++ >= lfo_overflow) {
1367 lfo_counter += lfo_counter_add;
1368 lfo_phase += (lfo_counter >> 4);
1374 unsigned i = lfo_phase;
1377 auto [a, p] = [&]() -> std::pair<int, int> {
1385 ((i < 128) ? i : (i - 255))
1392 ((i < 128) ? 255 : 0),
1393 ((i < 128) ? 128 : -128)
1401 ((i < 128) ? (255 - (i * 2)) : ((i * 2) - 256)),
1405 }
else if (i < 128) {
1407 }
else if (i < 192) {
1428 lfa = a * amd / 128;
1429 lfp = p * pmd / 128;
1443 unsigned j = ((noise_rng ^ (noise_rng >> 3)) & 1) ^ 1;
1444 noise_rng = (j << 16) | (noise_rng >> 1);
1448 YM2151Operator* op = &oper[0];
1455 mod_ind >>= (6 - op->pms);
1457 mod_ind <<= (op->pms - 5);
1460 unsigned kc_channel = op->kc_i + mod_ind;
1461 (op + 0)->phase += ((freq[kc_channel + (op + 0)->dt2] + (op + 0)->dt1) * (op + 0)->mul) >> 1;
1462 (op + 1)->phase += ((freq[kc_channel + (op + 1)->dt2] + (op + 1)->dt1) * (op + 1)->mul) >> 1;
1463 (op + 2)->phase += ((freq[kc_channel + (op + 2)->dt2] + (op + 2)->dt1) * (op + 2)->mul) >> 1;
1464 (op + 3)->phase += ((freq[kc_channel + (op + 3)->dt2] + (op + 3)->dt1) * (op + 3)->mul) >> 1;
1466 (op + 0)->phase += (op + 0)->freq;
1467 (op + 1)->phase += (op + 1)->freq;
1468 (op + 2)->phase += (op + 2)->freq;
1469 (op + 3)->phase += (op + 3)->freq;
1472 (op + 0)->phase += (op + 0)->freq;
1473 (op + 1)->phase += (op + 1)->freq;
1474 (op + 2)->phase += (op + 2)->freq;
1475 (op + 3)->phase += (op + 3)->freq;
1503 keyOff(op,
unsigned(~2));
1512 void YM2151::generateChannels(
float** bufs,
unsigned num)
1514 if (checkMuteHelper()) {
1516 std::fill_n(bufs, 8,
nullptr);
1520 for (
auto i :
xrange(num)) {
1523 for (
auto j :
xrange(8 - 1)) {
1530 for (
auto j :
xrange(8)) {
1531 bufs[j][2 * i + 0] += int(chanout[j] & pan[2 * j + 0]);
1532 bufs[j][2 * i + 1] += int(chanout[j] & pan[2 * j + 1]);
1538 void YM2151::callback(
byte flag)
1540 assert(flag ==
one_of(1, 2));
1543 if ((flag == 1) && (irq_enable & 0x80)) {
1553 void YM2151::setStatus(
byte flags)
1556 auto enable = (irq_enable >> 2) & 3;
1557 if ((status & enable) != 0) {
1562 void YM2151::resetStatus(
byte flags)
1565 auto enable = (irq_enable >> 2) & 3;
1566 if ((status & enable) == 0) {
1572 template<
typename Archive>
1577 a.serialize(
"phase", phase,
1583 "mem_value", mem_value,
1585 "fb_out_curr", fb_out_curr,
1586 "fb_out_prev", fb_out_prev,
1602 "eg_sh_ar", eg_sh_ar,
1603 "eg_sel_ar", eg_sel_ar,
1604 "eg_sh_d1r", eg_sh_d1r,
1605 "eg_sel_d1r", eg_sel_d1r,
1606 "eg_sh_d2r", eg_sh_d2r,
1607 "eg_sel_d2r", eg_sel_d2r,
1608 "eg_sh_rr", eg_sh_rr,
1609 "eg_sel_rr", eg_sel_rr);
1612 template<
typename Archive>
1615 a.serialize(
"irq", irq,
1621 "eg_timer", eg_timer,
1622 "lfo_phase", lfo_phase,
1623 "lfo_timer", lfo_timer,
1624 "lfo_overflow", lfo_overflow,
1625 "lfo_counter", lfo_counter,
1626 "lfo_counter_add", lfo_counter_add,
1630 "noise_rng", noise_rng,
1634 "irq_enable", irq_enable,
1641 "timer_A_val", timer_A_val,
1642 "lfo_wsel", lfo_wsel,
1647 a.serialize_blob(
"registers", regs,
sizeof(regs));
1649 if constexpr (Archive::IS_LOADER) {
1651 EmuTime::param time = timer1->getCurrentTime();
1652 for (
auto r :
xrange(0x20, 0x28)) {
void set()
Set the interrupt request on the bus.
void reset()
Reset the interrupt request on the bus.
void updateStream(EmuTime::param time)
void unregisterSound()
Unregisters this sound device with the Mixer.
void registerSound(const DeviceConfig &config)
Registers this sound device with the Mixer.
void writeReg(byte r, byte v, EmuTime::param time)
void reset(EmuTime::param time)
void serialize(Archive &ar, unsigned version)
YM2151(const std::string &name, static_string_view desc, const DeviceConfig &config, EmuTime::param time, Variant variant)
constexpr double round(double x)
std::string getName(KeyCode keyCode)
Translate key code to key name.
This file implemented 3 utility functions:
constexpr unsigned dt2_tab[4]
constexpr double ENV_STEP
constexpr byte dt1_tab[4 *32]
constexpr byte eg_rate_shift[32+64+32]
constexpr unsigned EG_SUS
constexpr unsigned RATE_STEPS
constexpr byte eg_inc[19 *RATE_STEPS]
constexpr word phaseinc_rom[768]
constexpr unsigned TL_TAB_LEN
constexpr byte lfo_noise_waveform[256]
uint16_t word
16 bit unsigned integer
constexpr KeyMatrixPosition x
Keyboard bindings.
void serialize(Archive &ar, T &t, unsigned version)
constexpr unsigned ENV_QUIET
constexpr unsigned EG_REL
constexpr byte eg_rate_select[32+64+32]
constexpr int MIN_ATT_INDEX
constexpr int MAX_ATT_INDEX
constexpr unsigned EG_DEC
constexpr unsigned EG_OFF
constexpr unsigned EG_ATT
bool all_of(InputRange &&range, UnaryPredicate pred)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)