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
26enum {
31};
32
33enum {
39 rm_num_tc = 5
40};
41
42/* logsin table */
43static 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 */
79static 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
114static 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
139static 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
164static 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
189static 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
214static 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
218static 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
222static 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
229static 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
233static 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
241static 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 = int8_t((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
293void 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:
308 chip->patchrom = patch_ymf281;
309 break;
310 case opll_type_ym2423:
311 chip->patchrom = patch_ym2423;
312 break;
313 case opll_type_ym2413:
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
328static 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] = uint16_t((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] = uint16_t((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
394static 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 = uint8_t(chip->inst[ch] << 2);
414 } else if (mcsel == 1) {
415 chip->c_tl = uint8_t(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 = uint8_t((chip->block[ch] << 1) | (chip->fnum[ch] >> 8));
427 chip->c_ksl_freq = uint8_t(chip->fnum[ch]>>5);
428 chip->c_ksl_block = (chip->block[ch]);
429}
430
431static 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
463static 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 = uint16_t(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 = uint16_t((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 = uint16_t((rm_bit << 9) | 0x100);
519 break;
520 }
521 default:
522 pg_out = uint16_t(phase >> 9);
523 }
524 } else {
525 pg_out = uint16_t(phase >> 9);
526 }
527 chip->pg_out = pg_out;
528}
529
530static 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
563static 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 = uint16_t(ksl + (chip->c_tl<<1));
581}
582
583static 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 = uint8_t(level);
602}
603
604static 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 = uint8_t(chip->cycles);
643 }
644 if (chip->cycles == 0 && (chip->eg_counter_state_prev & 1) == 1) {
645 chip->eg_timer_low_lock = timer_low;
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] = uint8_t(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 = uint8_t(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 = uint8_t((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
831static 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
891static 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 = int16_t(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 = uint16_t(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 |= uint8_t(phase >> 9);
950 chip->op_fbsum = int16_t((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
1005static 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
1014static 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 auto vib_step = uint8_t(((chip->lfo_counter & 0x3ff) + 1) >> 10);
1021 chip->lfo_am_step = uint8_t(((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 += uint8_t(am_inc + chip->lfo_am_car);
1047 chip->lfo_am_car = am_bit >> 1;
1048 am_bit &= 0x01;
1049 chip->lfo_am_counter = uint16_t((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
1062void 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
1101void 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}
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
@ 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
@ 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
@ 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:245
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