2021-01-03 23:41:07 -05:00
/*
* Copyright ( C ) 2017 - 2018 Alexey Khokholov ( Nuke . YKT )
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
*
* Nuked OPN2 ( Yamaha YM3438 ) emulator .
* Thanks :
* Silicon Pr0n :
* Yamaha YM3438 decap and die shot ( digshadow ) .
* OPLx decapsulated ( Matthew Gambrell , Olli Niemitalo ) :
* OPL2 ROMs .
*
* version : 1.0 .10
2021-08-09 00:44:44 +02:00
* - Pierre Althinsson 2021 - 08 - 09 Added Rhythm channels from Bambootracker source
2021-01-03 23:41:07 -05:00
*/
# include "stdafx.h"
# include <string.h>
# include "ym3438.h"
2021-08-09 00:44:44 +02:00
# include "fmopn_2608rom.h"
2021-01-03 23:41:07 -05:00
enum {
eg_num_attack = 0 ,
eg_num_decay = 1 ,
eg_num_sustain = 2 ,
eg_num_release = 3
} ;
/* logsin table */
static const Bit16u logsinrom [ 256 ] = {
0x859 , 0x6c3 , 0x607 , 0x58b , 0x52e , 0x4e4 , 0x4a6 , 0x471 ,
0x443 , 0x41a , 0x3f5 , 0x3d3 , 0x3b5 , 0x398 , 0x37e , 0x365 ,
0x34e , 0x339 , 0x324 , 0x311 , 0x2ff , 0x2ed , 0x2dc , 0x2cd ,
0x2bd , 0x2af , 0x2a0 , 0x293 , 0x286 , 0x279 , 0x26d , 0x261 ,
0x256 , 0x24b , 0x240 , 0x236 , 0x22c , 0x222 , 0x218 , 0x20f ,
0x206 , 0x1fd , 0x1f5 , 0x1ec , 0x1e4 , 0x1dc , 0x1d4 , 0x1cd ,
0x1c5 , 0x1be , 0x1b7 , 0x1b0 , 0x1a9 , 0x1a2 , 0x19b , 0x195 ,
0x18f , 0x188 , 0x182 , 0x17c , 0x177 , 0x171 , 0x16b , 0x166 ,
0x160 , 0x15b , 0x155 , 0x150 , 0x14b , 0x146 , 0x141 , 0x13c ,
0x137 , 0x133 , 0x12e , 0x129 , 0x125 , 0x121 , 0x11c , 0x118 ,
0x114 , 0x10f , 0x10b , 0x107 , 0x103 , 0x0ff , 0x0fb , 0x0f8 ,
0x0f4 , 0x0f0 , 0x0ec , 0x0e9 , 0x0e5 , 0x0e2 , 0x0de , 0x0db ,
0x0d7 , 0x0d4 , 0x0d1 , 0x0cd , 0x0ca , 0x0c7 , 0x0c4 , 0x0c1 ,
0x0be , 0x0bb , 0x0b8 , 0x0b5 , 0x0b2 , 0x0af , 0x0ac , 0x0a9 ,
0x0a7 , 0x0a4 , 0x0a1 , 0x09f , 0x09c , 0x099 , 0x097 , 0x094 ,
0x092 , 0x08f , 0x08d , 0x08a , 0x088 , 0x086 , 0x083 , 0x081 ,
0x07f , 0x07d , 0x07a , 0x078 , 0x076 , 0x074 , 0x072 , 0x070 ,
0x06e , 0x06c , 0x06a , 0x068 , 0x066 , 0x064 , 0x062 , 0x060 ,
0x05e , 0x05c , 0x05b , 0x059 , 0x057 , 0x055 , 0x053 , 0x052 ,
0x050 , 0x04e , 0x04d , 0x04b , 0x04a , 0x048 , 0x046 , 0x045 ,
0x043 , 0x042 , 0x040 , 0x03f , 0x03e , 0x03c , 0x03b , 0x039 ,
0x038 , 0x037 , 0x035 , 0x034 , 0x033 , 0x031 , 0x030 , 0x02f ,
0x02e , 0x02d , 0x02b , 0x02a , 0x029 , 0x028 , 0x027 , 0x026 ,
0x025 , 0x024 , 0x023 , 0x022 , 0x021 , 0x020 , 0x01f , 0x01e ,
0x01d , 0x01c , 0x01b , 0x01a , 0x019 , 0x018 , 0x017 , 0x017 ,
0x016 , 0x015 , 0x014 , 0x014 , 0x013 , 0x012 , 0x011 , 0x011 ,
0x010 , 0x00f , 0x00f , 0x00e , 0x00d , 0x00d , 0x00c , 0x00c ,
0x00b , 0x00a , 0x00a , 0x009 , 0x009 , 0x008 , 0x008 , 0x007 ,
0x007 , 0x007 , 0x006 , 0x006 , 0x005 , 0x005 , 0x005 , 0x004 ,
0x004 , 0x004 , 0x003 , 0x003 , 0x003 , 0x002 , 0x002 , 0x002 ,
0x002 , 0x001 , 0x001 , 0x001 , 0x001 , 0x001 , 0x001 , 0x001 ,
0x000 , 0x000 , 0x000 , 0x000 , 0x000 , 0x000 , 0x000 , 0x000
} ;
/* exp table */
static const Bit16u exprom [ 256 ] = {
0x000 , 0x003 , 0x006 , 0x008 , 0x00b , 0x00e , 0x011 , 0x014 ,
0x016 , 0x019 , 0x01c , 0x01f , 0x022 , 0x025 , 0x028 , 0x02a ,
0x02d , 0x030 , 0x033 , 0x036 , 0x039 , 0x03c , 0x03f , 0x042 ,
0x045 , 0x048 , 0x04b , 0x04e , 0x051 , 0x054 , 0x057 , 0x05a ,
0x05d , 0x060 , 0x063 , 0x066 , 0x069 , 0x06c , 0x06f , 0x072 ,
0x075 , 0x078 , 0x07b , 0x07e , 0x082 , 0x085 , 0x088 , 0x08b ,
0x08e , 0x091 , 0x094 , 0x098 , 0x09b , 0x09e , 0x0a1 , 0x0a4 ,
0x0a8 , 0x0ab , 0x0ae , 0x0b1 , 0x0b5 , 0x0b8 , 0x0bb , 0x0be ,
0x0c2 , 0x0c5 , 0x0c8 , 0x0cc , 0x0cf , 0x0d2 , 0x0d6 , 0x0d9 ,
0x0dc , 0x0e0 , 0x0e3 , 0x0e7 , 0x0ea , 0x0ed , 0x0f1 , 0x0f4 ,
0x0f8 , 0x0fb , 0x0ff , 0x102 , 0x106 , 0x109 , 0x10c , 0x110 ,
0x114 , 0x117 , 0x11b , 0x11e , 0x122 , 0x125 , 0x129 , 0x12c ,
0x130 , 0x134 , 0x137 , 0x13b , 0x13e , 0x142 , 0x146 , 0x149 ,
0x14d , 0x151 , 0x154 , 0x158 , 0x15c , 0x160 , 0x163 , 0x167 ,
0x16b , 0x16f , 0x172 , 0x176 , 0x17a , 0x17e , 0x181 , 0x185 ,
0x189 , 0x18d , 0x191 , 0x195 , 0x199 , 0x19c , 0x1a0 , 0x1a4 ,
0x1a8 , 0x1ac , 0x1b0 , 0x1b4 , 0x1b8 , 0x1bc , 0x1c0 , 0x1c4 ,
0x1c8 , 0x1cc , 0x1d0 , 0x1d4 , 0x1d8 , 0x1dc , 0x1e0 , 0x1e4 ,
0x1e8 , 0x1ec , 0x1f0 , 0x1f5 , 0x1f9 , 0x1fd , 0x201 , 0x205 ,
0x209 , 0x20e , 0x212 , 0x216 , 0x21a , 0x21e , 0x223 , 0x227 ,
0x22b , 0x230 , 0x234 , 0x238 , 0x23c , 0x241 , 0x245 , 0x249 ,
0x24e , 0x252 , 0x257 , 0x25b , 0x25f , 0x264 , 0x268 , 0x26d ,
0x271 , 0x276 , 0x27a , 0x27f , 0x283 , 0x288 , 0x28c , 0x291 ,
0x295 , 0x29a , 0x29e , 0x2a3 , 0x2a8 , 0x2ac , 0x2b1 , 0x2b5 ,
0x2ba , 0x2bf , 0x2c4 , 0x2c8 , 0x2cd , 0x2d2 , 0x2d6 , 0x2db ,
0x2e0 , 0x2e5 , 0x2e9 , 0x2ee , 0x2f3 , 0x2f8 , 0x2fd , 0x302 ,
0x306 , 0x30b , 0x310 , 0x315 , 0x31a , 0x31f , 0x324 , 0x329 ,
0x32e , 0x333 , 0x338 , 0x33d , 0x342 , 0x347 , 0x34c , 0x351 ,
0x356 , 0x35b , 0x360 , 0x365 , 0x36a , 0x370 , 0x375 , 0x37a ,
0x37f , 0x384 , 0x38a , 0x38f , 0x394 , 0x399 , 0x39f , 0x3a4 ,
0x3a9 , 0x3ae , 0x3b4 , 0x3b9 , 0x3bf , 0x3c4 , 0x3c9 , 0x3cf ,
0x3d4 , 0x3da , 0x3df , 0x3e4 , 0x3ea , 0x3ef , 0x3f5 , 0x3fa
} ;
/* Note table */
static const Bit32u fn_note [ 16 ] = {
0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3
} ;
/* Envelope generator */
static const Bit32u eg_stephi [ 4 ] [ 4 ] = {
{ 0 , 0 , 0 , 0 } ,
{ 1 , 0 , 0 , 0 } ,
{ 1 , 0 , 1 , 0 } ,
{ 1 , 1 , 1 , 0 }
} ;
static const Bit8u eg_am_shift [ 4 ] = {
7 , 3 , 1 , 0
} ;
/* Phase generator */
static const Bit32u pg_detune [ 8 ] = { 16 , 17 , 19 , 20 , 22 , 24 , 27 , 29 } ;
static const Bit32u pg_lfo_sh1 [ 8 ] [ 8 ] = {
{ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 } ,
{ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 } ,
{ 7 , 7 , 7 , 7 , 7 , 7 , 1 , 1 } ,
{ 7 , 7 , 7 , 7 , 1 , 1 , 1 , 1 } ,
{ 7 , 7 , 7 , 1 , 1 , 1 , 1 , 0 } ,
{ 7 , 7 , 1 , 1 , 0 , 0 , 0 , 0 } ,
{ 7 , 7 , 1 , 1 , 0 , 0 , 0 , 0 } ,
{ 7 , 7 , 1 , 1 , 0 , 0 , 0 , 0 }
} ;
static const Bit32u pg_lfo_sh2 [ 8 ] [ 8 ] = {
{ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 } ,
{ 7 , 7 , 7 , 7 , 2 , 2 , 2 , 2 } ,
{ 7 , 7 , 7 , 2 , 2 , 2 , 7 , 7 } ,
{ 7 , 7 , 2 , 2 , 7 , 7 , 2 , 2 } ,
{ 7 , 7 , 2 , 7 , 7 , 7 , 2 , 7 } ,
{ 7 , 7 , 7 , 2 , 7 , 7 , 2 , 1 } ,
{ 7 , 7 , 7 , 2 , 7 , 7 , 2 , 1 } ,
{ 7 , 7 , 7 , 2 , 7 , 7 , 2 , 1 }
} ;
/* Address decoder */
static const Bit32u op_offset [ 12 ] = {
0x000 , /* Ch1 OP1/OP2 */
0x001 , /* Ch2 OP1/OP2 */
0x002 , /* Ch3 OP1/OP2 */
0x100 , /* Ch4 OP1/OP2 */
0x101 , /* Ch5 OP1/OP2 */
0x102 , /* Ch6 OP1/OP2 */
0x004 , /* Ch1 OP3/OP4 */
0x005 , /* Ch2 OP3/OP4 */
0x006 , /* Ch3 OP3/OP4 */
0x104 , /* Ch4 OP3/OP4 */
0x105 , /* Ch5 OP3/OP4 */
0x106 /* Ch6 OP3/OP4 */
} ;
static const Bit32u ch_offset [ 6 ] = {
0x000 , /* Ch1 */
0x001 , /* Ch2 */
0x002 , /* Ch3 */
0x100 , /* Ch4 */
0x101 , /* Ch5 */
0x102 /* Ch6 */
} ;
/* LFO */
static const Bit32u lfo_cycles [ 8 ] = {
108 , 77 , 71 , 67 , 62 , 44 , 8 , 5
} ;
/* FM algorithm */
static const Bit32u fm_algorithm [ 4 ] [ 6 ] [ 8 ] = {
{
{ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } , /* OP1_0 */
{ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } , /* OP1_1 */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* OP2 */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* Last operator */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* Last operator */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } /* Out */
} ,
{
{ 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 } , /* OP1_0 */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* OP1_1 */
{ 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 } , /* OP2 */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* Last operator */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* Last operator */
{ 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 } /* Out */
} ,
{
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* OP1_0 */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* OP1_1 */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* OP2 */
{ 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 } , /* Last operator */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* Last operator */
{ 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 } /* Out */
} ,
{
{ 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 } , /* OP1_0 */
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } , /* OP1_1 */
{ 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 } , /* OP2 */
{ 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 } , /* Last operator */
{ 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 } , /* Last operator */
{ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } /* Out */
}
} ;
2021-08-09 00:44:44 +02:00
const unsigned int YM2608_ADPCM_ROM_addr [ 2 * 6 ] = {
0x0000 , 0x01bf , /* bass drum */
0x01c0 , 0x043f , /* snare drum */
0x0440 , 0x1b7f , /* top cymbal */
0x1b80 , 0x1cff , /* high hat */
0x1d00 , 0x1f7f , /* tom tom */
0x1f80 , 0x1fff /* rim shot */
} ;
/*OPN-MOD: ADPCM jedi table*/
static const Bit16s adpcm_jedi_table [ 49 * 16 ] =
{
2 , 6 , 10 , 14 , 18 , 22 , 26 , 30 , - 2 , - 6 , - 10 , - 14 , - 18 , - 22 , - 26 , - 30 ,
2 , 6 , 10 , 14 , 19 , 23 , 27 , 31 , - 2 , - 6 , - 10 , - 14 , - 19 , - 23 , - 27 , - 31 ,
2 , 7 , 11 , 16 , 21 , 26 , 30 , 35 , - 2 , - 7 , - 11 , - 16 , - 21 , - 26 , - 30 , - 35 ,
2 , 7 , 13 , 18 , 23 , 28 , 34 , 39 , - 2 , - 7 , - 13 , - 18 , - 23 , - 28 , - 34 , - 39 ,
2 , 8 , 14 , 20 , 25 , 31 , 37 , 43 , - 2 , - 8 , - 14 , - 20 , - 25 , - 31 , - 37 , - 43 ,
3 , 9 , 15 , 21 , 28 , 34 , 40 , 46 , - 3 , - 9 , - 15 , - 21 , - 28 , - 34 , - 40 , - 46 ,
3 , 10 , 17 , 24 , 31 , 38 , 45 , 52 , - 3 , - 10 , - 17 , - 24 , - 31 , - 38 , - 45 , - 52 ,
3 , 11 , 19 , 27 , 34 , 42 , 50 , 58 , - 3 , - 11 , - 19 , - 27 , - 34 , - 42 , - 50 , - 58 ,
4 , 12 , 21 , 29 , 38 , 46 , 55 , 63 , - 4 , - 12 , - 21 , - 29 , - 38 , - 46 , - 55 , - 63 ,
4 , 13 , 23 , 32 , 41 , 50 , 60 , 69 , - 4 , - 13 , - 23 , - 32 , - 41 , - 50 , - 60 , - 69 ,
5 , 15 , 25 , 35 , 46 , 56 , 66 , 76 , - 5 , - 15 , - 25 , - 35 , - 46 , - 56 , - 66 , - 76 ,
5 , 16 , 28 , 39 , 50 , 61 , 73 , 84 , - 5 , - 16 , - 28 , - 39 , - 50 , - 61 , - 73 , - 84 ,
6 , 18 , 31 , 43 , 56 , 68 , 81 , 93 , - 6 , - 18 , - 31 , - 43 , - 56 , - 68 , - 81 , - 93 ,
6 , 20 , 34 , 48 , 61 , 75 , 89 , 103 , - 6 , - 20 , - 34 , - 48 , - 61 , - 75 , - 89 , - 103 ,
7 , 22 , 37 , 52 , 67 , 82 , 97 , 112 , - 7 , - 22 , - 37 , - 52 , - 67 , - 82 , - 97 , - 112 ,
8 , 24 , 41 , 57 , 74 , 90 , 107 , 123 , - 8 , - 24 , - 41 , - 57 , - 74 , - 90 , - 107 , - 123 ,
9 , 27 , 45 , 63 , 82 , 100 , 118 , 136 , - 9 , - 27 , - 45 , - 63 , - 82 , - 100 , - 118 , - 136 ,
10 , 30 , 50 , 70 , 90 , 110 , 130 , 150 , - 10 , - 30 , - 50 , - 70 , - 90 , - 110 , - 130 , - 150 ,
11 , 33 , 55 , 77 , 99 , 121 , 143 , 165 , - 11 , - 33 , - 55 , - 77 , - 99 , - 121 , - 143 , - 165 ,
12 , 36 , 60 , 84 , 109 , 133 , 157 , 181 , - 12 , - 36 , - 60 , - 84 , - 109 , - 133 , - 157 , - 181 ,
13 , 40 , 66 , 93 , 120 , 147 , 173 , 200 , - 13 , - 40 , - 66 , - 93 , - 120 , - 147 , - 173 , - 200 ,
14 , 44 , 73 , 103 , 132 , 162 , 191 , 221 , - 14 , - 44 , - 73 , - 103 , - 132 , - 162 , - 191 , - 221 ,
16 , 48 , 81 , 113 , 146 , 178 , 211 , 243 , - 16 , - 48 , - 81 , - 113 , - 146 , - 178 , - 211 , - 243 ,
17 , 53 , 89 , 125 , 160 , 196 , 232 , 268 , - 17 , - 53 , - 89 , - 125 , - 160 , - 196 , - 232 , - 268 ,
19 , 58 , 98 , 137 , 176 , 215 , 255 , 294 , - 19 , - 58 , - 98 , - 137 , - 176 , - 215 , - 255 , - 294 ,
21 , 64 , 108 , 151 , 194 , 237 , 281 , 324 , - 21 , - 64 , - 108 , - 151 , - 194 , - 237 , - 281 , - 324 ,
23 , 71 , 118 , 166 , 213 , 261 , 308 , 356 , - 23 , - 71 , - 118 , - 166 , - 213 , - 261 , - 308 , - 356 ,
26 , 78 , 130 , 182 , 235 , 287 , 339 , 391 , - 26 , - 78 , - 130 , - 182 , - 235 , - 287 , - 339 , - 391 ,
28 , 86 , 143 , 201 , 258 , 316 , 373 , 431 , - 28 , - 86 , - 143 , - 201 , - 258 , - 316 , - 373 , - 431 ,
31 , 94 , 158 , 221 , 284 , 347 , 411 , 474 , - 31 , - 94 , - 158 , - 221 , - 284 , - 347 , - 411 , - 474 ,
34 , 104 , 174 , 244 , 313 , 383 , 453 , 523 , - 34 , - 104 , - 174 , - 244 , - 313 , - 383 , - 453 , - 523 ,
38 , 115 , 191 , 268 , 345 , 422 , 498 , 575 , - 38 , - 115 , - 191 , - 268 , - 345 , - 422 , - 498 , - 575 ,
42 , 126 , 210 , 294 , 379 , 463 , 547 , 631 , - 42 , - 126 , - 210 , - 294 , - 379 , - 463 , - 547 , - 631 ,
46 , 139 , 231 , 324 , 417 , 510 , 602 , 695 , - 46 , - 139 , - 231 , - 324 , - 417 , - 510 , - 602 , - 695 ,
51 , 153 , 255 , 357 , 459 , 561 , 663 , 765 , - 51 , - 153 , - 255 , - 357 , - 459 , - 561 , - 663 , - 765 ,
56 , 168 , 280 , 392 , 505 , 617 , 729 , 841 , - 56 , - 168 , - 280 , - 392 , - 505 , - 617 , - 729 , - 841 ,
61 , 185 , 308 , 432 , 555 , 679 , 802 , 926 , - 61 , - 185 , - 308 , - 432 , - 555 , - 679 , - 802 , - 926 ,
68 , 204 , 340 , 476 , 612 , 748 , 884 , 1020 , - 68 , - 204 , - 340 , - 476 , - 612 , - 748 , - 884 , - 1020 ,
74 , 224 , 373 , 523 , 672 , 822 , 971 , 1121 , - 74 , - 224 , - 373 , - 523 , - 672 , - 822 , - 971 , - 1121 ,
82 , 246 , 411 , 575 , 740 , 904 , 1069 , 1233 , - 82 , - 246 , - 411 , - 575 , - 740 , - 904 , - 1069 , - 1233 ,
90 , 271 , 452 , 633 , 814 , 995 , 1176 , 1357 , - 90 , - 271 , - 452 , - 633 , - 814 , - 995 , - 1176 , - 1357 ,
99 , 298 , 497 , 696 , 895 , 1094 , 1293 , 1492 , - 99 , - 298 , - 497 , - 696 , - 895 , - 1094 , - 1293 , - 1492 ,
109 , 328 , 547 , 766 , 985 , 1204 , 1423 , 1642 , - 109 , - 328 , - 547 , - 766 , - 985 , - 1204 , - 1423 , - 1642 ,
120 , 361 , 601 , 842 , 1083 , 1324 , 1564 , 1805 , - 120 , - 361 , - 601 , - 842 , - 1083 , - 1324 , - 1564 , - 1805 ,
132 , 397 , 662 , 927 , 1192 , 1457 , 1722 , 1987 , - 132 , - 397 , - 662 , - 927 , - 1192 , - 1457 , - 1722 , - 1987 ,
145 , 437 , 728 , 1020 , 1311 , 1603 , 1894 , 2186 , - 145 , - 437 , - 728 , - 1020 , - 1311 , - 1603 , - 1894 , - 2186 ,
160 , 480 , 801 , 1121 , 1442 , 1762 , 2083 , 2403 , - 160 , - 480 , - 801 , - 1121 , - 1442 , - 1762 , - 2083 , - 2403 ,
176 , 529 , 881 , 1234 , 1587 , 1940 , 2292 , 2645 , - 176 , - 529 , - 881 , - 1234 , - 1587 , - 1940 , - 2292 , - 2645 ,
194 , 582 , 970 , 1358 , 1746 , 2134 , 2522 , 2910 , - 194 , - 582 , - 970 , - 1358 , - 1746 , - 2134 , - 2522 , - 2910
} ;
/*OPN-MOD: ADPCM table*/
extern const unsigned int YM2608_ADPCM_ROM_addr [ 2 * 6 ] ;
extern const unsigned char YM2608_ADPCM_ROM [ 0x2000 ] ;
/*OPN-MOD: ADPCM constants*/
static const Bitu adpcm_shift = 16 ;
static const int adpcm_step_inc [ 8 ] = { - 1 * 16 , - 1 * 16 , - 1 * 16 , - 1 * 16 , 2 * 16 , 5 * 16 , 7 * 16 , 9 * 16 } ;
2021-01-03 23:41:07 -05:00
static Bit32u chip_type = ym3438_mode_readmode ;
2021-08-09 00:44:44 +02:00
/*OPN-MOD: update ADPCM volume*/
void OPNmod_RhythmUpdateVolume ( ym3438_t * chip , Bit32u channel )
{
Bit8u volume = chip - > rhythm_tl + chip - > rhythm_level [ channel ] ;
/* volume formula from MAME OPN */
if ( volume > = 63 ) /* This is correct, 63 = quiet */
{
chip - > rhythm_vol_mul [ channel ] = 0 ;
chip - > rhythm_vol_shift [ channel ] = 0 ;
}
else
{
chip - > rhythm_vol_mul [ channel ] = 15 - ( volume & 7 ) ; /* so called 0.75 dB */
chip - > rhythm_vol_shift [ channel ] = 1 + ( volume > > 3 ) ; /* Yamaha engineers used the approximation: each -6 dB is close to divide by two (shift right) */
}
}
2021-01-03 23:41:07 -05:00
void OPN2_DoIO ( ym3438_t * chip )
{
/* Write signal check */
chip - > write_a_en = ( chip - > write_a & 0x03 ) = = 0x01 ;
chip - > write_d_en = ( chip - > write_d & 0x03 ) = = 0x01 ;
chip - > write_a < < = 1 ;
chip - > write_d < < = 1 ;
/* Busy counter */
chip - > busy = chip - > write_busy ;
chip - > write_busy_cnt + = chip - > write_busy ;
chip - > write_busy = ( chip - > write_busy & & ! ( chip - > write_busy_cnt > > 5 ) ) | | chip - > write_d_en ;
chip - > write_busy_cnt & = 0x1f ;
}
void OPN2_DoRegWrite ( ym3438_t * chip )
{
Bit32u i ;
Bit32u slot = chip - > cycles % 12 ;
Bit32u address ;
Bit32u channel = chip - > channel ;
/* Update registers */
if ( chip - > write_fm_data )
{
/* Slot */
if ( op_offset [ slot ] = = ( chip - > address & 0x107 ) )
{
if ( chip - > address & 0x08 )
{
/* OP2, OP4 */
slot + = 12 ;
}
address = chip - > address & 0xf0 ;
switch ( address )
{
case 0x30 : /* DT, MULTI */
chip - > multi [ slot ] = chip - > data & 0x0f ;
if ( ! chip - > multi [ slot ] )
{
chip - > multi [ slot ] = 1 ;
}
else
{
chip - > multi [ slot ] < < = 1 ;
}
chip - > dt [ slot ] = ( chip - > data > > 4 ) & 0x07 ;
break ;
case 0x40 : /* TL */
chip - > tl [ slot ] = chip - > data & 0x7f ;
break ;
case 0x50 : /* KS, AR */
chip - > ar [ slot ] = chip - > data & 0x1f ;
chip - > ks [ slot ] = ( chip - > data > > 6 ) & 0x03 ;
break ;
case 0x60 : /* AM, DR */
chip - > dr [ slot ] = chip - > data & 0x1f ;
chip - > am [ slot ] = ( chip - > data > > 7 ) & 0x01 ;
break ;
case 0x70 : /* SR */
chip - > sr [ slot ] = chip - > data & 0x1f ;
break ;
case 0x80 : /* SL, RR */
chip - > rr [ slot ] = chip - > data & 0x0f ;
chip - > sl [ slot ] = ( chip - > data > > 4 ) & 0x0f ;
chip - > sl [ slot ] | = ( chip - > sl [ slot ] + 1 ) & 0x10 ;
break ;
case 0x90 : /* SSG-EG */
chip - > ssg_eg [ slot ] = chip - > data & 0x0f ;
break ;
default :
break ;
}
}
/* Channel */
if ( ch_offset [ channel ] = = ( chip - > address & 0x103 ) )
{
address = chip - > address & 0xfc ;
switch ( address )
{
case 0xa0 :
chip - > fnum [ channel ] = ( chip - > data & 0xff ) | ( ( chip - > reg_a4 & 0x07 ) < < 8 ) ;
chip - > block [ channel ] = ( chip - > reg_a4 > > 3 ) & 0x07 ;
chip - > kcode [ channel ] = ( chip - > block [ channel ] < < 2 ) | fn_note [ chip - > fnum [ channel ] > > 7 ] ;
break ;
case 0xa4 :
chip - > reg_a4 = chip - > data & 0xff ;
break ;
case 0xa8 :
chip - > fnum_3ch [ channel ] = ( chip - > data & 0xff ) | ( ( chip - > reg_ac & 0x07 ) < < 8 ) ;
chip - > block_3ch [ channel ] = ( chip - > reg_ac > > 3 ) & 0x07 ;
chip - > kcode_3ch [ channel ] = ( chip - > block_3ch [ channel ] < < 2 ) | fn_note [ chip - > fnum_3ch [ channel ] > > 7 ] ;
break ;
case 0xac :
chip - > reg_ac = chip - > data & 0xff ;
break ;
case 0xb0 :
chip - > connect [ channel ] = chip - > data & 0x07 ;
chip - > fb [ channel ] = ( chip - > data > > 3 ) & 0x07 ;
break ;
case 0xb4 :
chip - > pms [ channel ] = chip - > data & 0x07 ;
chip - > ams [ channel ] = ( chip - > data > > 4 ) & 0x03 ;
chip - > pan_l [ channel ] = ( chip - > data > > 7 ) & 0x01 ;
chip - > pan_r [ channel ] = ( chip - > data > > 6 ) & 0x01 ;
break ;
default :
break ;
}
}
}
if ( chip - > write_a_en | | chip - > write_d_en )
{
/* Data */
if ( chip - > write_a_en )
{
chip - > write_fm_data = 0 ;
}
if ( chip - > write_fm_address & & chip - > write_d_en )
{
chip - > write_fm_data = 1 ;
}
/* Address */
if ( chip - > write_a_en )
{
if ( ( chip - > write_data & 0xf0 ) ! = 0x00 )
{
/* FM Write */
chip - > address = chip - > write_data ;
chip - > write_fm_address = 1 ;
}
else
{
/* SSG write */
chip - > write_fm_address = 0 ;
}
}
/* FM Mode */
/* Data */
if ( chip - > write_d_en & & ( chip - > write_data & 0x100 ) = = 0 )
{
switch ( chip - > write_fm_mode_a )
{
2021-08-09 00:44:44 +02:00
/*OPN-MOD: Rhythm key on/off*/
case 0x10 :
if ( ( chip - > write_data & 0x80 ) = = 0 )
{
for ( i = 0 ; i < 6 ; + + i )
{
if ( chip - > write_data & ( 1 < < i ) )
{
chip - > rhythm_key [ i ] = 1 ;
chip - > rhythm_addr [ i ] = YM2608_ADPCM_ROM_addr [ 2 * i ] < < 1 ;
chip - > rhythm_now_step [ i ] = 0 ;
chip - > rhythm_adpcm_step [ i ] = 0 ;
chip - > rhythm_adpcm_acc [ i ] = 0 ;
}
}
}
else
{
for ( i = 0 ; i < 6 ; + + i )
{
if ( chip - > write_data & ( 1 < < i ) )
{
chip - > rhythm_key [ i ] = 0 ;
chip - > rhythml [ i ] = 0 ;
chip - > rhythmr [ i ] = 0 ;
}
}
}
break ;
/*OPN-MOD: Rhythm total level*/
case 0x11 :
chip - > rhythm_tl = ~ chip - > write_data & 63 ;
for ( i = 0 ; i < 6 ; + + i )
{
OPNmod_RhythmUpdateVolume ( chip , i ) ;
}
break ;
/*OPN-MOD: Rhythm instrument pan/level*/
case 0x18 : case 0x19 : case 0x1a :
case 0x1b : case 0x1c : case 0x1d :
i = chip - > write_fm_mode_a - 0x18 ;
chip - > rhythm_pan [ i ] = ( chip - > write_data > > 6 ) & 3 ;
chip - > rhythm_level [ i ] = ~ chip - > write_data & 31 ;
OPNmod_RhythmUpdateVolume ( chip , i ) ;
break ;
2021-01-03 23:41:07 -05:00
case 0x21 : /* LSI test 1 */
for ( i = 0 ; i < 8 ; i + + )
{
chip - > mode_test_21 [ i ] = ( chip - > write_data > > i ) & 0x01 ;
}
break ;
case 0x22 : /* LFO control */
if ( ( chip - > write_data > > 3 ) & 0x01 )
{
chip - > lfo_en = 0x7f ;
}
else
{
chip - > lfo_en = 0 ;
}
chip - > lfo_freq = chip - > write_data & 0x07 ;
break ;
case 0x24 : /* Timer A */
chip - > timer_a_reg & = 0x03 ;
chip - > timer_a_reg | = ( chip - > write_data & 0xff ) < < 2 ;
break ;
case 0x25 :
chip - > timer_a_reg & = 0x3fc ;
chip - > timer_a_reg | = chip - > write_data & 0x03 ;
break ;
case 0x26 : /* Timer B */
chip - > timer_b_reg = chip - > write_data & 0xff ;
break ;
case 0x27 : /* CSM, Timer control */
chip - > mode_ch3 = ( chip - > write_data & 0xc0 ) > > 6 ;
chip - > mode_csm = chip - > mode_ch3 = = 2 ;
chip - > timer_a_load = chip - > write_data & 0x01 ;
chip - > timer_a_enable = ( chip - > write_data > > 2 ) & 0x01 ;
chip - > timer_a_reset = ( chip - > write_data > > 4 ) & 0x01 ;
chip - > timer_b_load = ( chip - > write_data > > 1 ) & 0x01 ;
chip - > timer_b_enable = ( chip - > write_data > > 3 ) & 0x01 ;
chip - > timer_b_reset = ( chip - > write_data > > 5 ) & 0x01 ;
break ;
case 0x28 : /* Key on/off */
for ( i = 0 ; i < 4 ; i + + )
{
chip - > mode_kon_operator [ i ] = ( chip - > write_data > > ( 4 + i ) ) & 0x01 ;
}
if ( ( chip - > write_data & 0x03 ) = = 0x03 )
{
/* Invalid address */
chip - > mode_kon_channel = 0xff ;
}
else
{
chip - > mode_kon_channel = ( chip - > write_data & 0x03 ) + ( ( chip - > write_data > > 2 ) & 1 ) * 3 ;
}
break ;
case 0x2a : /* DAC data */
chip - > dacdata & = 0x01 ;
chip - > dacdata | = ( chip - > write_data ^ 0x80 ) < < 1 ;
break ;
case 0x2b : /* DAC enable */
chip - > dacen = chip - > write_data > > 7 ;
break ;
case 0x2c : /* LSI test 2 */
for ( i = 0 ; i < 8 ; i + + )
{
chip - > mode_test_2c [ i ] = ( chip - > write_data > > i ) & 0x01 ;
}
chip - > dacdata & = 0x1fe ;
chip - > dacdata | = chip - > mode_test_2c [ 3 ] ;
chip - > eg_custom_timer = ! chip - > mode_test_2c [ 7 ] & & chip - > mode_test_2c [ 6 ] ;
break ;
default :
break ;
}
}
/* Address */
if ( chip - > write_a_en )
{
chip - > write_fm_mode_a = chip - > write_data & 0x1ff ;
}
}
if ( chip - > write_fm_data )
{
chip - > data = chip - > write_data & 0xff ;
}
}
void OPN2_PhaseCalcIncrement ( ym3438_t * chip )
{
Bit32u chan = chip - > channel ;
Bit32u slot = chip - > cycles ;
Bit32u fnum = chip - > pg_fnum ;
Bit32u fnum_h = fnum > > 4 ;
Bit32u fm ;
Bit32u basefreq ;
Bit8u lfo = chip - > lfo_pm ;
Bit8u lfo_l = lfo & 0x0f ;
Bit8u pms = chip - > pms [ chan ] ;
Bit8u dt = chip - > dt [ slot ] ;
Bit8u dt_l = dt & 0x03 ;
Bit8u detune = 0 ;
Bit8u block , note ;
Bit8u sum , sum_h , sum_l ;
Bit8u kcode = chip - > pg_kcode ;
fnum < < = 1 ;
/* Apply LFO */
if ( lfo_l & 0x08 )
{
lfo_l ^ = 0x0f ;
}
fm = ( fnum_h > > pg_lfo_sh1 [ pms ] [ lfo_l ] ) + ( fnum_h > > pg_lfo_sh2 [ pms ] [ lfo_l ] ) ;
if ( pms > 5 )
{
fm < < = pms - 5 ;
}
fm > > = 2 ;
if ( lfo & 0x10 )
{
fnum - = fm ;
}
else
{
fnum + = fm ;
}
fnum & = 0xfff ;
basefreq = ( fnum < < chip - > pg_block ) > > 2 ;
/* Apply detune */
if ( dt_l )
{
if ( kcode > 0x1c )
{
kcode = 0x1c ;
}
block = kcode > > 2 ;
note = kcode & 0x03 ;
sum = block + 9 + ( ( dt_l = = 3 ) | ( dt_l & 0x02 ) ) ;
sum_h = sum > > 1 ;
sum_l = sum & 0x01 ;
detune = pg_detune [ ( sum_l < < 2 ) | note ] > > ( 9 - sum_h ) ;
}
if ( dt & 0x04 )
{
basefreq - = detune ;
}
else
{
basefreq + = detune ;
}
basefreq & = 0x1ffff ;
chip - > pg_inc [ slot ] = ( basefreq * chip - > multi [ slot ] ) > > 1 ;
chip - > pg_inc [ slot ] & = 0xfffff ;
}
void OPN2_PhaseGenerate ( ym3438_t * chip )
{
Bit32u slot ;
/* Mask increment */
slot = ( chip - > cycles + 20 ) % 24 ;
if ( chip - > pg_reset [ slot ] )
{
chip - > pg_inc [ slot ] = 0 ;
}
/* Phase step */
slot = ( chip - > cycles + 19 ) % 24 ;
if ( chip - > pg_reset [ slot ] | | chip - > mode_test_21 [ 3 ] )
{
chip - > pg_phase [ slot ] = 0 ;
}
chip - > pg_phase [ slot ] + = chip - > pg_inc [ slot ] ;
chip - > pg_phase [ slot ] & = 0xfffff ;
}
void OPN2_EnvelopeSSGEG ( ym3438_t * chip )
{
Bit32u slot = chip - > cycles ;
Bit8u direction = 0 ;
chip - > eg_ssg_pgrst_latch [ slot ] = 0 ;
chip - > eg_ssg_repeat_latch [ slot ] = 0 ;
chip - > eg_ssg_hold_up_latch [ slot ] = 0 ;
chip - > eg_ssg_inv [ slot ] = 0 ;
if ( chip - > ssg_eg [ slot ] & 0x08 )
{
direction = chip - > eg_ssg_dir [ slot ] ;
if ( chip - > eg_level [ slot ] & 0x200 )
{
/* Reset */
if ( ( chip - > ssg_eg [ slot ] & 0x03 ) = = 0x00 )
{
chip - > eg_ssg_pgrst_latch [ slot ] = 1 ;
}
/* Repeat */
if ( ( chip - > ssg_eg [ slot ] & 0x01 ) = = 0x00 )
{
chip - > eg_ssg_repeat_latch [ slot ] = 1 ;
}
/* Inverse */
if ( ( chip - > ssg_eg [ slot ] & 0x03 ) = = 0x02 )
{
direction ^ = 1 ;
}
if ( ( chip - > ssg_eg [ slot ] & 0x03 ) = = 0x03 )
{
direction = 1 ;
}
}
/* Hold up */
if ( chip - > eg_kon_latch [ slot ]
& & ( ( chip - > ssg_eg [ slot ] & 0x07 ) = = 0x05 | | ( chip - > ssg_eg [ slot ] & 0x07 ) = = 0x03 ) )
{
chip - > eg_ssg_hold_up_latch [ slot ] = 1 ;
}
direction & = chip - > eg_kon [ slot ] ;
chip - > eg_ssg_inv [ slot ] = ( chip - > eg_ssg_dir [ slot ] ^ ( ( chip - > ssg_eg [ slot ] > > 2 ) & 0x01 ) )
& chip - > eg_kon [ slot ] ;
}
chip - > eg_ssg_dir [ slot ] = direction ;
chip - > eg_ssg_enable [ slot ] = ( chip - > ssg_eg [ slot ] > > 3 ) & 0x01 ;
}
void OPN2_EnvelopeADSR ( ym3438_t * chip )
{
Bit32u slot = ( chip - > cycles + 22 ) % 24 ;
Bit8u nkon = chip - > eg_kon_latch [ slot ] ;
Bit8u okon = chip - > eg_kon [ slot ] ;
Bit8u kon_event ;
Bit8u koff_event ;
Bit8u eg_off ;
Bit16s level ;
Bit16s nextlevel = 0 ;
Bit16s ssg_level ;
Bit8u nextstate = chip - > eg_state [ slot ] ;
Bit16s inc = 0 ;
chip - > eg_read [ 0 ] = chip - > eg_read_inc ;
chip - > eg_read_inc = chip - > eg_inc > 0 ;
/* Reset phase generator */
chip - > pg_reset [ slot ] = ( nkon & & ! okon ) | | chip - > eg_ssg_pgrst_latch [ slot ] ;
/* KeyOn/Off */
kon_event = ( nkon & & ! okon ) | | ( okon & & chip - > eg_ssg_repeat_latch [ slot ] ) ;
koff_event = okon & & ! nkon ;
ssg_level = level = ( Bit16s ) chip - > eg_level [ slot ] ;
if ( chip - > eg_ssg_inv [ slot ] )
{
/* Inverse */
ssg_level = 512 - level ;
ssg_level & = 0x3ff ;
}
if ( koff_event )
{
level = ssg_level ;
}
if ( chip - > eg_ssg_enable [ slot ] )
{
eg_off = level > > 9 ;
}
else
{
eg_off = ( level & 0x3f0 ) = = 0x3f0 ;
}
nextlevel = level ;
if ( kon_event )
{
nextstate = eg_num_attack ;
/* Instant attack */
if ( chip - > eg_ratemax )
{
nextlevel = 0 ;
}
else if ( chip - > eg_state [ slot ] = = eg_num_attack & & level ! = 0 & & chip - > eg_inc & & nkon )
{
inc = ( ~ level < < chip - > eg_inc ) > > 5 ;
}
}
else
{
switch ( chip - > eg_state [ slot ] )
{
case eg_num_attack :
if ( level = = 0 )
{
nextstate = eg_num_decay ;
}
else if ( chip - > eg_inc & & ! chip - > eg_ratemax & & nkon )
{
inc = ( ~ level < < chip - > eg_inc ) > > 5 ;
}
break ;
case eg_num_decay :
if ( ( level > > 5 ) = = chip - > eg_sl [ 1 ] )
{
nextstate = eg_num_sustain ;
}
else if ( ! eg_off & & chip - > eg_inc )
{
inc = 1 < < ( chip - > eg_inc - 1 ) ;
if ( chip - > eg_ssg_enable [ slot ] )
{
inc < < = 2 ;
}
}
break ;
case eg_num_sustain :
case eg_num_release :
if ( ! eg_off & & chip - > eg_inc )
{
inc = 1 < < ( chip - > eg_inc - 1 ) ;
if ( chip - > eg_ssg_enable [ slot ] )
{
inc < < = 2 ;
}
}
break ;
default :
break ;
}
if ( ! nkon )
{
nextstate = eg_num_release ;
}
}
if ( chip - > eg_kon_csm [ slot ] )
{
nextlevel | = chip - > eg_tl [ 1 ] < < 3 ;
}
/* Envelope off */
if ( ! kon_event & & ! chip - > eg_ssg_hold_up_latch [ slot ] & & chip - > eg_state [ slot ] ! = eg_num_attack & & eg_off )
{
nextstate = eg_num_release ;
nextlevel = 0x3ff ;
}
nextlevel + = inc ;
chip - > eg_kon [ slot ] = chip - > eg_kon_latch [ slot ] ;
chip - > eg_level [ slot ] = ( Bit16u ) nextlevel & 0x3ff ;
chip - > eg_state [ slot ] = nextstate ;
}
void OPN2_EnvelopePrepare ( ym3438_t * chip )
{
Bit8u rate ;
Bit8u sum ;
Bit8u inc = 0 ;
Bit32u slot = chip - > cycles ;
Bit8u rate_sel ;
/* Prepare increment */
rate = ( chip - > eg_rate < < 1 ) + chip - > eg_ksv ;
if ( rate > 0x3f )
{
rate = 0x3f ;
}
sum = ( ( rate > > 2 ) + chip - > eg_shift_lock ) & 0x0f ;
if ( chip - > eg_rate ! = 0 & & chip - > eg_quotient = = 2 )
{
if ( rate < 48 )
{
switch ( sum )
{
case 12 :
inc = 1 ;
break ;
case 13 :
inc = ( rate > > 1 ) & 0x01 ;
break ;
case 14 :
inc = rate & 0x01 ;
break ;
default :
break ;
}
}
else
{
inc = eg_stephi [ rate & 0x03 ] [ chip - > eg_timer_low_lock ] + ( rate > > 2 ) - 11 ;
if ( inc > 4 )
{
inc = 4 ;
}
}
}
chip - > eg_inc = inc ;
chip - > eg_ratemax = ( rate > > 1 ) = = 0x1f ;
/* Prepare rate & ksv */
rate_sel = chip - > eg_state [ slot ] ;
if ( ( chip - > eg_kon [ slot ] & & chip - > eg_ssg_repeat_latch [ slot ] )
| | ( ! chip - > eg_kon [ slot ] & & chip - > eg_kon_latch [ slot ] ) )
{
rate_sel = eg_num_attack ;
}
switch ( rate_sel )
{
case eg_num_attack :
chip - > eg_rate = chip - > ar [ slot ] ;
break ;
case eg_num_decay :
chip - > eg_rate = chip - > dr [ slot ] ;
break ;
case eg_num_sustain :
chip - > eg_rate = chip - > sr [ slot ] ;
break ;
case eg_num_release :
chip - > eg_rate = ( chip - > rr [ slot ] < < 1 ) | 0x01 ;
break ;
default :
break ;
}
chip - > eg_ksv = chip - > pg_kcode > > ( chip - > ks [ slot ] ^ 0x03 ) ;
if ( chip - > am [ slot ] )
{
chip - > eg_lfo_am = chip - > lfo_am > > eg_am_shift [ chip - > ams [ chip - > channel ] ] ;
}
else
{
chip - > eg_lfo_am = 0 ;
}
/* Delay TL & SL value */
chip - > eg_tl [ 1 ] = chip - > eg_tl [ 0 ] ;
chip - > eg_tl [ 0 ] = chip - > tl [ slot ] ;
chip - > eg_sl [ 1 ] = chip - > eg_sl [ 0 ] ;
chip - > eg_sl [ 0 ] = chip - > sl [ slot ] ;
}
void OPN2_EnvelopeGenerate ( ym3438_t * chip )
{
Bit32u slot = ( chip - > cycles + 23 ) % 24 ;
Bit16u level ;
level = chip - > eg_level [ slot ] ;
if ( chip - > eg_ssg_inv [ slot ] )
{
/* Inverse */
level = 512 - level ;
}
if ( chip - > mode_test_21 [ 5 ] )
{
level = 0 ;
}
level & = 0x3ff ;
/* Apply AM LFO */
level + = chip - > eg_lfo_am ;
/* Apply TL */
if ( ! ( chip - > mode_csm & & chip - > channel = = 2 + 1 ) )
{
level + = chip - > eg_tl [ 0 ] < < 3 ;
}
if ( level > 0x3ff )
{
level = 0x3ff ;
}
chip - > eg_out [ slot ] = level ;
}
void OPN2_UpdateLFO ( ym3438_t * chip )
{
if ( ( chip - > lfo_quotient & lfo_cycles [ chip - > lfo_freq ] ) = = lfo_cycles [ chip - > lfo_freq ] )
{
chip - > lfo_quotient = 0 ;
chip - > lfo_cnt + + ;
}
else
{
chip - > lfo_quotient + = chip - > lfo_inc ;
}
chip - > lfo_cnt & = chip - > lfo_en ;
}
void OPN2_FMPrepare ( ym3438_t * chip )
{
Bit32u slot = ( chip - > cycles + 6 ) % 24 ;
Bit32u channel = chip - > channel ;
Bit16s mod , mod1 , mod2 ;
Bit32u op = slot / 6 ;
Bit8u connect = chip - > connect [ channel ] ;
Bit32u prevslot = ( chip - > cycles + 18 ) % 24 ;
/* Calculate modulation */
mod1 = mod2 = 0 ;
if ( fm_algorithm [ op ] [ 0 ] [ connect ] )
{
mod2 | = chip - > fm_op1 [ channel ] [ 0 ] ;
}
if ( fm_algorithm [ op ] [ 1 ] [ connect ] )
{
mod1 | = chip - > fm_op1 [ channel ] [ 1 ] ;
}
if ( fm_algorithm [ op ] [ 2 ] [ connect ] )
{
mod1 | = chip - > fm_op2 [ channel ] ;
}
if ( fm_algorithm [ op ] [ 3 ] [ connect ] )
{
mod2 | = chip - > fm_out [ prevslot ] ;
}
if ( fm_algorithm [ op ] [ 4 ] [ connect ] )
{
mod1 | = chip - > fm_out [ prevslot ] ;
}
mod = mod1 + mod2 ;
if ( op = = 0 )
{
/* Feedback */
mod = mod > > ( 10 - chip - > fb [ channel ] ) ;
if ( ! chip - > fb [ channel ] )
{
mod = 0 ;
}
}
else
{
mod > > = 1 ;
}
chip - > fm_mod [ slot ] = mod ;
slot = ( chip - > cycles + 18 ) % 24 ;
/* OP1 */
if ( slot / 6 = = 0 )
{
chip - > fm_op1 [ channel ] [ 1 ] = chip - > fm_op1 [ channel ] [ 0 ] ;
chip - > fm_op1 [ channel ] [ 0 ] = chip - > fm_out [ slot ] ;
}
/* OP2 */
if ( slot / 6 = = 2 )
{
chip - > fm_op2 [ channel ] = chip - > fm_out [ slot ] ;
}
}
void OPN2_ChGenerate ( ym3438_t * chip )
{
Bit32u slot = ( chip - > cycles + 18 ) % 24 ;
Bit32u channel = chip - > channel ;
Bit32u op = slot / 6 ;
Bit32u test_dac = chip - > mode_test_2c [ 5 ] ;
Bit16s acc = chip - > ch_acc [ channel ] ;
Bit16s add = test_dac ;
Bit16s sum = 0 ;
if ( op = = 0 & & ! test_dac )
{
acc = 0 ;
}
if ( fm_algorithm [ op ] [ 5 ] [ chip - > connect [ channel ] ] & & ! test_dac )
{
add + = chip - > fm_out [ slot ] > > 5 ;
}
sum = acc + add ;
/* Clamp */
if ( sum > 255 )
{
sum = 255 ;
}
else if ( sum < - 256 )
{
sum = - 256 ;
}
if ( op = = 0 | | test_dac )
{
chip - > ch_out [ channel ] = chip - > ch_acc [ channel ] ;
}
chip - > ch_acc [ channel ] = sum ;
}
void OPN2_ChOutput ( ym3438_t * chip )
{
Bit32u cycles = chip - > cycles ;
Bit32u slot = chip - > cycles ;
Bit32u channel = chip - > channel ;
Bit32u test_dac = chip - > mode_test_2c [ 5 ] ;
Bit16s out ;
Bit16s sign ;
Bit32u out_en ;
chip - > ch_read = chip - > ch_lock ;
if ( slot < 12 )
{
/* Ch 4,5,6 */
channel + + ;
}
if ( ( cycles & 3 ) = = 0 )
{
if ( ! test_dac )
{
/* Lock value */
chip - > ch_lock = chip - > ch_out [ channel ] ;
}
chip - > ch_lock_l = chip - > pan_l [ channel ] ;
chip - > ch_lock_r = chip - > pan_r [ channel ] ;
}
/* Ch 6 */
if ( ( ( cycles > > 2 ) = = 1 & & chip - > dacen ) | | test_dac )
{
out = ( Bit16s ) chip - > dacdata ;
out < < = 7 ;
out > > = 7 ;
}
else
{
out = chip - > ch_lock ;
}
chip - > mol = 0 ;
chip - > mor = 0 ;
if ( chip_type & ym3438_mode_ym2612 )
{
out_en = ( ( cycles & 3 ) = = 3 ) | | test_dac ;
/* YM2612 DAC emulation(not verified) */
sign = out > > 8 ;
if ( out > = 0 )
{
out + + ;
sign + + ;
}
if ( chip - > ch_lock_l & & out_en )
{
chip - > mol = out ;
}
else
{
chip - > mol = sign ;
}
if ( chip - > ch_lock_r & & out_en )
{
chip - > mor = out ;
}
else
{
chip - > mor = sign ;
}
/* Amplify signal */
chip - > mol * = 3 ;
chip - > mor * = 3 ;
}
else
{
out_en = ( ( cycles & 3 ) ! = 0 ) | | test_dac ;
if ( chip - > ch_lock_l & & out_en )
{
chip - > mol = out ;
}
if ( chip - > ch_lock_r & & out_en )
{
chip - > mor = out ;
}
}
}
void OPN2_FMGenerate ( ym3438_t * chip )
{
Bit32u slot = ( chip - > cycles + 19 ) % 24 ;
/* Calculate phase */
Bit16u phase = ( chip - > fm_mod [ slot ] + ( chip - > pg_phase [ slot ] > > 10 ) ) & 0x3ff ;
Bit16u quarter ;
Bit16u level ;
Bit16s output ;
if ( phase & 0x100 )
{
quarter = ( phase ^ 0xff ) & 0xff ;
}
else
{
quarter = phase & 0xff ;
}
level = logsinrom [ quarter ] ;
/* Apply envelope */
level + = chip - > eg_out [ slot ] < < 2 ;
/* Transform */
if ( level > 0x1fff )
{
level = 0x1fff ;
}
output = ( ( exprom [ ( level & 0xff ) ^ 0xff ] | 0x400 ) < < 2 ) > > ( level > > 8 ) ;
if ( phase & 0x200 )
{
output = ( ( ~ output ) ^ ( chip - > mode_test_21 [ 4 ] < < 13 ) ) + 1 ;
}
else
{
output = output ^ ( chip - > mode_test_21 [ 4 ] < < 13 ) ;
}
output < < = 2 ;
output > > = 2 ;
chip - > fm_out [ slot ] = output ;
}
2021-08-09 00:44:44 +02:00
/*OPN-MOD: generate ADPCM rhythm*/
void OPNmod_RhythmGenerate ( ym3438_t * chip )
{
Bit32u channel = chip - > channel ;
Bit32s out = 0 ;
Bit8u panl = 0 ;
Bit8u panr = 0 ;
Bit32u step ;
Bit8u data ;
Bit16u end = YM2608_ADPCM_ROM_addr [ 2 * channel + 1 ] < < 1 ;
if ( chip - > cycles < 6 & & chip - > rhythm_key [ channel ] )
{
/*Bit32u step;
Bit8u data ;
Bit16u end = YM2608_ADPCM_ROM_addr [ 2 * channel + 1 ] < < 1 ; */
panl = chip - > rhythm_pan [ channel ] & 2 ;
panr = chip - > rhythm_pan [ channel ] & 1 ;
/*from MAME*/
chip - > rhythm_now_step [ channel ] + = chip - > rhythm_step [ channel ] ;
if ( chip - > rhythm_now_step [ channel ] > = ( 1u < < adpcm_shift ) )
{
step = chip - > rhythm_now_step [ channel ] > > adpcm_shift ;
chip - > rhythm_now_step [ channel ] & = ( 1 < < adpcm_shift ) - 1 ;
do
{
/* end check */
/* 11-06-2001 JB: corrected comparison. Was > instead of == */
/* YM2610 checks lower 20 bits only, the 4 MSB bits are sample bank */
/* Here we use 1<<21 to compensate for nibble calculations */
if ( ( chip - > rhythm_addr [ channel ] & ( ( 1 < < 21 ) - 1 ) ) = = ( end & ( ( 1 < < 21 ) - 1 ) ) )
{
chip - > rhythm_key [ channel ] = 0 ;
goto end ;
}
if ( chip - > rhythm_addr [ channel ] & 1 )
{
data = chip - > rhythm_data [ channel ] & 0x0f ;
}
else
{
chip - > rhythm_data [ channel ] = YM2608_ADPCM_ROM [ chip - > rhythm_addr [ channel ] > > 1 ] ;
data = ( chip - > rhythm_data [ channel ] > > 4 ) & 0x0f ;
}
chip - > rhythm_addr [ channel ] + + ;
chip - > rhythm_adpcm_acc [ channel ] + = adpcm_jedi_table [ chip - > rhythm_adpcm_step [ channel ] + data ] ;
/* the 12-bit accumulator wraps on the ym2610 and ym2608 (like the msm5205), it does not saturate (like the msm5218) */
chip - > rhythm_adpcm_acc [ channel ] & = 0xfff ;
/* extend 12-bit signed int */
if ( chip - > rhythm_adpcm_acc [ channel ] & 0x800 )
{
chip - > rhythm_adpcm_acc [ channel ] | = ~ 0xfff ;
}
chip - > rhythm_adpcm_step [ channel ] + = adpcm_step_inc [ data & 7 ] ;
if ( chip - > rhythm_adpcm_step [ channel ] > 48 * 16 )
{
chip - > rhythm_adpcm_step [ channel ] = 48 * 16 ;
}
if ( chip - > rhythm_adpcm_step [ channel ] < 0 )
{
chip - > rhythm_adpcm_step [ channel ] = 0 ;
}
} while ( - - step ) ;
/* calc pcm * volume data */
out = ( ( chip - > rhythm_adpcm_acc [ channel ] * chip - > rhythm_vol_mul [ channel ] ) > > chip - > rhythm_vol_shift [ channel ] ) & ~ 3 ; /* multiply, shift and mask out 2 LSB bits */
end :
chip - > rhythml [ channel ] = panl ? ( out > > 1 ) : 0 ;
chip - > rhythmr [ channel ] = panr ? ( out > > 1 ) : 0 ;
}
}
}
2021-01-03 23:41:07 -05:00
void OPN2_DoTimerA ( ym3438_t * chip )
{
Bit16u time ;
Bit8u load ;
load = chip - > timer_a_overflow ;
if ( chip - > cycles = = 2 )
{
/* Lock load value */
load | = ( ! chip - > timer_a_load_lock & & chip - > timer_a_load ) ;
chip - > timer_a_load_lock = chip - > timer_a_load ;
if ( chip - > mode_csm )
{
/* CSM KeyOn */
chip - > mode_kon_csm = load ;
}
else
{
chip - > mode_kon_csm = 0 ;
}
}
/* Load counter */
if ( chip - > timer_a_load_latch )
{
time = chip - > timer_a_reg ;
}
else
{
time = chip - > timer_a_cnt ;
}
chip - > timer_a_load_latch = load ;
/* Increase counter */
if ( ( chip - > cycles = = 1 & & chip - > timer_a_load_lock ) | | chip - > mode_test_21 [ 2 ] )
{
time + + ;
}
/* Set overflow flag */
if ( chip - > timer_a_reset )
{
chip - > timer_a_reset = 0 ;
chip - > timer_a_overflow_flag = 0 ;
}
else
{
chip - > timer_a_overflow_flag | = chip - > timer_a_overflow & chip - > timer_a_enable ;
}
chip - > timer_a_overflow = ( time > > 10 ) ;
chip - > timer_a_cnt = time & 0x3ff ;
}
void OPN2_DoTimerB ( ym3438_t * chip )
{
Bit16u time ;
Bit8u load ;
load = chip - > timer_b_overflow ;
if ( chip - > cycles = = 2 )
{
/* Lock load value */
load | = ( ! chip - > timer_b_load_lock & & chip - > timer_b_load ) ;
chip - > timer_b_load_lock = chip - > timer_b_load ;
}
/* Load counter */
if ( chip - > timer_b_load_latch )
{
time = chip - > timer_b_reg ;
}
else
{
time = chip - > timer_b_cnt ;
}
chip - > timer_b_load_latch = load ;
/* Increase counter */
if ( chip - > cycles = = 1 )
{
chip - > timer_b_subcnt + + ;
}
if ( ( chip - > timer_b_subcnt = = 0x10 & & chip - > timer_b_load_lock ) | | chip - > mode_test_21 [ 2 ] )
{
time + + ;
}
chip - > timer_b_subcnt & = 0x0f ;
/* Set overflow flag */
if ( chip - > timer_b_reset )
{
chip - > timer_b_reset = 0 ;
chip - > timer_b_overflow_flag = 0 ;
}
else
{
chip - > timer_b_overflow_flag | = chip - > timer_b_overflow & chip - > timer_b_enable ;
}
chip - > timer_b_overflow = ( time > > 8 ) ;
chip - > timer_b_cnt = time & 0xff ;
}
void OPN2_KeyOn ( ym3438_t * chip )
{
Bit32u slot = chip - > cycles ;
Bit32u chan = chip - > channel ;
/* Key On */
chip - > eg_kon_latch [ slot ] = chip - > mode_kon [ slot ] ;
chip - > eg_kon_csm [ slot ] = 0 ;
if ( chip - > channel = = 2 & & chip - > mode_kon_csm )
{
/* CSM Key On */
chip - > eg_kon_latch [ slot ] = 1 ;
chip - > eg_kon_csm [ slot ] = 1 ;
}
if ( chip - > cycles = = chip - > mode_kon_channel )
{
/* OP1 */
chip - > mode_kon [ chan ] = chip - > mode_kon_operator [ 0 ] ;
/* OP2 */
chip - > mode_kon [ chan + 12 ] = chip - > mode_kon_operator [ 1 ] ;
/* OP3 */
chip - > mode_kon [ chan + 6 ] = chip - > mode_kon_operator [ 2 ] ;
/* OP4 */
chip - > mode_kon [ chan + 18 ] = chip - > mode_kon_operator [ 3 ] ;
}
}
void OPN2_Reset ( ym3438_t * chip )
{
Bit32u i ;
memset ( chip , 0 , sizeof ( ym3438_t ) ) ;
for ( i = 0 ; i < 24 ; i + + )
{
chip - > eg_out [ i ] = 0x3ff ;
chip - > eg_level [ i ] = 0x3ff ;
chip - > eg_state [ i ] = eg_num_release ;
chip - > multi [ i ] = 1 ;
}
for ( i = 0 ; i < 6 ; i + + )
{
chip - > pan_l [ i ] = 1 ;
chip - > pan_r [ i ] = 1 ;
}
2021-08-09 00:44:44 +02:00
for ( i = 0 ; i < 6 ; i + + )
{
chip - > rhythm_pan [ i ] = 3 ;
chip - > rhythm_step [ i ] = ( Bit32u ) ( ( 1 < < adpcm_shift ) / ( ( i < 4 ) ? 3.0 : 6.0 ) ) ;
OPNmod_RhythmUpdateVolume ( chip , i ) ;
}
2021-01-03 23:41:07 -05:00
}
void OPN2_SetChipType ( Bit32u type )
{
chip_type = type ;
}
void OPN2_Clock ( ym3438_t * chip , Bit16s * buffer )
{
Bit32u slot = chip - > cycles ;
2021-08-09 00:44:44 +02:00
Bit16s * rhythml = & chip - > rhythml [ chip - > channel ] ;
Bit16s * rhythmr = & chip - > rhythmr [ chip - > channel ] ;
2021-01-03 23:41:07 -05:00
chip - > lfo_inc = chip - > mode_test_21 [ 1 ] ;
chip - > pg_read > > = 1 ;
chip - > eg_read [ 1 ] > > = 1 ;
chip - > eg_cycle + + ;
/* Lock envelope generator timer value */
if ( chip - > cycles = = 1 & & chip - > eg_quotient = = 2 )
{
if ( chip - > eg_cycle_stop )
{
chip - > eg_shift_lock = 0 ;
}
else
{
chip - > eg_shift_lock = chip - > eg_shift + 1 ;
}
chip - > eg_timer_low_lock = chip - > eg_timer & 0x03 ;
}
/* Cycle specific functions */
switch ( chip - > cycles )
{
case 0 :
chip - > lfo_pm = chip - > lfo_cnt > > 2 ;
if ( chip - > lfo_cnt & 0x40 )
{
chip - > lfo_am = chip - > lfo_cnt & 0x3f ;
}
else
{
chip - > lfo_am = chip - > lfo_cnt ^ 0x3f ;
}
chip - > lfo_am < < = 1 ;
break ;
case 1 :
chip - > eg_quotient + + ;
chip - > eg_quotient % = 3 ;
chip - > eg_cycle = 0 ;
chip - > eg_cycle_stop = 1 ;
chip - > eg_shift = 0 ;
chip - > eg_timer_inc | = chip - > eg_quotient > > 1 ;
chip - > eg_timer = chip - > eg_timer + chip - > eg_timer_inc ;
chip - > eg_timer_inc = chip - > eg_timer > > 12 ;
chip - > eg_timer & = 0xfff ;
break ;
case 2 :
chip - > pg_read = chip - > pg_phase [ 21 ] & 0x3ff ;
chip - > eg_read [ 1 ] = chip - > eg_out [ 0 ] ;
break ;
case 13 :
chip - > eg_cycle = 0 ;
chip - > eg_cycle_stop = 1 ;
chip - > eg_shift = 0 ;
chip - > eg_timer = chip - > eg_timer + chip - > eg_timer_inc ;
chip - > eg_timer_inc = chip - > eg_timer > > 12 ;
chip - > eg_timer & = 0xfff ;
break ;
case 23 :
chip - > lfo_inc | = 1 ;
break ;
}
chip - > eg_timer & = ~ ( chip - > mode_test_21 [ 5 ] < < chip - > eg_cycle ) ;
if ( ( ( chip - > eg_timer > > chip - > eg_cycle ) | ( chip - > pin_test_in & chip - > eg_custom_timer ) ) & chip - > eg_cycle_stop )
{
chip - > eg_shift = chip - > eg_cycle ;
chip - > eg_cycle_stop = 0 ;
}
OPN2_DoIO ( chip ) ;
OPN2_DoTimerA ( chip ) ;
OPN2_DoTimerB ( chip ) ;
OPN2_KeyOn ( chip ) ;
OPN2_ChOutput ( chip ) ;
OPN2_ChGenerate ( chip ) ;
OPN2_FMPrepare ( chip ) ;
OPN2_FMGenerate ( chip ) ;
2021-08-09 00:44:44 +02:00
OPNmod_RhythmGenerate ( chip ) ;
2021-01-03 23:41:07 -05:00
OPN2_PhaseGenerate ( chip ) ;
OPN2_PhaseCalcIncrement ( chip ) ;
OPN2_EnvelopeADSR ( chip ) ;
OPN2_EnvelopeGenerate ( chip ) ;
OPN2_EnvelopeSSGEG ( chip ) ;
OPN2_EnvelopePrepare ( chip ) ;
/* Prepare fnum & block */
if ( chip - > mode_ch3 )
{
/* Channel 3 special mode */
switch ( slot )
{
case 1 : /* OP1 */
chip - > pg_fnum = chip - > fnum_3ch [ 1 ] ;
chip - > pg_block = chip - > block_3ch [ 1 ] ;
chip - > pg_kcode = chip - > kcode_3ch [ 1 ] ;
break ;
case 7 : /* OP3 */
chip - > pg_fnum = chip - > fnum_3ch [ 0 ] ;
chip - > pg_block = chip - > block_3ch [ 0 ] ;
chip - > pg_kcode = chip - > kcode_3ch [ 0 ] ;
break ;
case 13 : /* OP2 */
chip - > pg_fnum = chip - > fnum_3ch [ 2 ] ;
chip - > pg_block = chip - > block_3ch [ 2 ] ;
chip - > pg_kcode = chip - > kcode_3ch [ 2 ] ;
break ;
case 19 : /* OP4 */
default :
chip - > pg_fnum = chip - > fnum [ ( chip - > channel + 1 ) % 6 ] ;
chip - > pg_block = chip - > block [ ( chip - > channel + 1 ) % 6 ] ;
chip - > pg_kcode = chip - > kcode [ ( chip - > channel + 1 ) % 6 ] ;
break ;
}
}
else
{
chip - > pg_fnum = chip - > fnum [ ( chip - > channel + 1 ) % 6 ] ;
chip - > pg_block = chip - > block [ ( chip - > channel + 1 ) % 6 ] ;
chip - > pg_kcode = chip - > kcode [ ( chip - > channel + 1 ) % 6 ] ;
}
OPN2_UpdateLFO ( chip ) ;
OPN2_DoRegWrite ( chip ) ;
chip - > cycles = ( chip - > cycles + 1 ) % 24 ;
chip - > channel = chip - > cycles % 6 ;
buffer [ 0 ] = chip - > mol ;
buffer [ 1 ] = chip - > mor ;
2021-08-09 00:44:44 +02:00
/*OPN-MOD: Rhythm output*/
buffer [ 2 ] = * rhythml ;
buffer [ 3 ] = * rhythmr ;
2021-01-03 23:41:07 -05:00
if ( chip - > status_time )
chip - > status_time - - ;
}
void OPN2_Write ( ym3438_t * chip , Bit32u port , Bit8u data )
{
port & = 3 ;
chip - > write_data = ( ( port < < 7 ) & 0x100 ) | data ;
if ( port & 1 )
{
/* Data */
chip - > write_d | = 1 ;
}
else
{
/* Address */
chip - > write_a | = 1 ;
}
}
void OPN2_SetTestPin ( ym3438_t * chip , Bit32u value )
{
chip - > pin_test_in = value & 1 ;
}
Bit32u OPN2_ReadTestPin ( ym3438_t * chip )
{
if ( ! chip - > mode_test_2c [ 7 ] )
{
return 0 ;
}
return chip - > cycles = = 23 ;
}
Bit32u OPN2_ReadIRQPin ( ym3438_t * chip )
{
return chip - > timer_a_overflow_flag | chip - > timer_b_overflow_flag ;
}
Bit8u OPN2_Read ( ym3438_t * chip , Bit32u port )
{
if ( ( port & 3 ) = = 0 | | ( chip_type & ym3438_mode_readmode ) )
{
if ( chip - > mode_test_21 [ 6 ] )
{
/* Read test data */
Bit32u slot = ( chip - > cycles + 18 ) % 24 ;
Bit16u testdata = ( ( chip - > pg_read & 0x01 ) < < 15 )
| ( ( chip - > eg_read [ chip - > mode_test_21 [ 0 ] ] & 0x01 ) < < 14 ) ;
if ( chip - > mode_test_2c [ 4 ] )
{
testdata | = chip - > ch_read & 0x1ff ;
}
else
{
testdata | = chip - > fm_out [ slot ] & 0x3fff ;
}
if ( chip - > mode_test_21 [ 7 ] )
{
chip - > status = testdata & 0xff ;
}
else
{
chip - > status = testdata > > 8 ;
}
}
else
{
chip - > status = ( chip - > busy < < 7 ) | ( chip - > timer_b_overflow_flag < < 1 )
| chip - > timer_a_overflow_flag ;
}
if ( chip_type & ym3438_mode_ym2612 )
{
chip - > status_time = 300000 ;
}
else
{
chip - > status_time = 40000000 ;
}
}
if ( chip - > status_time )
{
return chip - > status ;
}
return 0 ;
}