[Core/Sound] updated nuked ym2612/ym3438 core to version 1.0.10 (fixes sound issues in Stormlord)

This commit is contained in:
ekeeke 2021-05-10 23:44:57 +02:00
parent 8acd9def6d
commit 6d10dd30ff
3 changed files with 73 additions and 59 deletions

Binary file not shown.

View File

@ -1,6 +1,6 @@
#ifdef HAVE_YM3438_CORE #ifdef HAVE_YM3438_CORE
/* /*
* Copyright (C) 2017 Alexey Khokholov (Nuke.YKT) * Copyright (C) 2017-2018 Alexey Khokholov (Nuke.YKT)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -40,7 +40,7 @@
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): * OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
* OPL2 ROMs. * OPL2 ROMs.
* *
* version: 1.0.8 * version: 1.0.10
*/ */
#include <string.h> #include <string.h>
@ -235,7 +235,7 @@ static const Bit32u fm_algorithm[4][6][8] = {
static Bit32u chip_type = ym3438_mode_readmode; static Bit32u chip_type = ym3438_mode_readmode;
void OPN2_DoIO(ym3438_t *chip) static void OPN2_DoIO(ym3438_t *chip)
{ {
/* Write signal check */ /* Write signal check */
chip->write_a_en = (chip->write_a & 0x03) == 0x01; chip->write_a_en = (chip->write_a & 0x03) == 0x01;
@ -249,10 +249,10 @@ void OPN2_DoIO(ym3438_t *chip)
chip->write_busy_cnt &= 0x1f; chip->write_busy_cnt &= 0x1f;
} }
void OPN2_DoRegWrite(ym3438_t *chip) static void OPN2_DoRegWrite(ym3438_t *chip)
{ {
Bit32u i; Bit32u i;
Bit32u slot = chip->slot % 12; Bit32u slot = chip->cycles % 12;
Bit32u address; Bit32u address;
Bit32u channel = chip->channel; Bit32u channel = chip->channel;
/* Update registers */ /* Update registers */
@ -379,7 +379,7 @@ void OPN2_DoRegWrite(ym3438_t *chip)
/* Data */ /* Data */
if (chip->write_d_en && (chip->write_data & 0x100) == 0) if (chip->write_d_en && (chip->write_data & 0x100) == 0)
{ {
switch (chip->address) switch (chip->write_fm_mode_a)
{ {
case 0x21: /* LSI test 1 */ case 0x21: /* LSI test 1 */
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
@ -458,7 +458,7 @@ void OPN2_DoRegWrite(ym3438_t *chip)
/* Address */ /* Address */
if (chip->write_a_en) if (chip->write_a_en)
{ {
chip->write_fm_mode_a = chip->write_data & 0xff; chip->write_fm_mode_a = chip->write_data & 0x1ff;
} }
} }
@ -468,16 +468,18 @@ void OPN2_DoRegWrite(ym3438_t *chip)
} }
} }
void OPN2_PhaseCalcIncrement(ym3438_t *chip) static void OPN2_PhaseCalcIncrement(ym3438_t *chip)
{ {
Bit32u chan = chip->channel;
Bit32u slot = chip->cycles;
Bit32u fnum = chip->pg_fnum; Bit32u fnum = chip->pg_fnum;
Bit32u fnum_h = fnum >> 4; Bit32u fnum_h = fnum >> 4;
Bit32u fm; Bit32u fm;
Bit32u basefreq; Bit32u basefreq;
Bit8u lfo = chip->lfo_pm; Bit8u lfo = chip->lfo_pm;
Bit8u lfo_l = lfo & 0x0f; Bit8u lfo_l = lfo & 0x0f;
Bit8u pms = chip->pms[chip->channel]; Bit8u pms = chip->pms[chan];
Bit8u dt = chip->dt[chip->slot]; Bit8u dt = chip->dt[slot];
Bit8u dt_l = dt & 0x03; Bit8u dt_l = dt & 0x03;
Bit8u detune = 0; Bit8u detune = 0;
Bit8u block, note; Bit8u block, note;
@ -531,32 +533,32 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
basefreq += detune; basefreq += detune;
} }
basefreq &= 0x1ffff; basefreq &= 0x1ffff;
chip->pg_inc[chip->slot] = (basefreq * chip->multi[chip->slot]) >> 1; chip->pg_inc[slot] = (basefreq * chip->multi[slot]) >> 1;
chip->pg_inc[chip->slot] &= 0xfffff; chip->pg_inc[slot] &= 0xfffff;
} }
void OPN2_PhaseGenerate(ym3438_t *chip) static void OPN2_PhaseGenerate(ym3438_t *chip)
{ {
Bit32u slot; Bit32u slot;
/* Mask increment */ /* Mask increment */
slot = (chip->slot + 20) % 24; slot = (chip->cycles + 20) % 24;
if (chip->pg_reset[slot]) if (chip->pg_reset[slot])
{ {
chip->pg_inc[slot] = 0; chip->pg_inc[slot] = 0;
} }
/* Phase step */ /* Phase step */
slot = (chip->slot + 19) % 24; slot = (chip->cycles + 19) % 24;
chip->pg_phase[slot] += chip->pg_inc[slot];
chip->pg_phase[slot] &= 0xfffff;
if (chip->pg_reset[slot] || chip->mode_test_21[3]) if (chip->pg_reset[slot] || chip->mode_test_21[3])
{ {
chip->pg_phase[slot] = 0; chip->pg_phase[slot] = 0;
} }
chip->pg_phase[slot] += chip->pg_inc[slot];
chip->pg_phase[slot] &= 0xfffff;
} }
void OPN2_EnvelopeSSGEG(ym3438_t *chip) static void OPN2_EnvelopeSSGEG(ym3438_t *chip)
{ {
Bit32u slot = chip->slot; Bit32u slot = chip->cycles;
Bit8u direction = 0; Bit8u direction = 0;
chip->eg_ssg_pgrst_latch[slot] = 0; chip->eg_ssg_pgrst_latch[slot] = 0;
chip->eg_ssg_repeat_latch[slot] = 0; chip->eg_ssg_repeat_latch[slot] = 0;
@ -601,9 +603,9 @@ void OPN2_EnvelopeSSGEG(ym3438_t *chip)
chip->eg_ssg_enable[slot] = (chip->ssg_eg[slot] >> 3) & 0x01; chip->eg_ssg_enable[slot] = (chip->ssg_eg[slot] >> 3) & 0x01;
} }
void OPN2_EnvelopeADSR(ym3438_t *chip) static void OPN2_EnvelopeADSR(ym3438_t *chip)
{ {
Bit32u slot = (chip->slot + 22) % 24; Bit32u slot = (chip->cycles + 22) % 24;
Bit8u nkon = chip->eg_kon_latch[slot]; Bit8u nkon = chip->eg_kon_latch[slot];
Bit8u okon = chip->eg_kon[slot]; Bit8u okon = chip->eg_kon[slot];
@ -725,12 +727,12 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
chip->eg_state[slot] = nextstate; chip->eg_state[slot] = nextstate;
} }
void OPN2_EnvelopePrepare(ym3438_t *chip) static void OPN2_EnvelopePrepare(ym3438_t *chip)
{ {
Bit8u rate; Bit8u rate;
Bit8u sum; Bit8u sum;
Bit8u inc = 0; Bit8u inc = 0;
Bit32u slot = chip->slot; Bit32u slot = chip->cycles;
Bit8u rate_sel; Bit8u rate_sel;
/* Prepare increment */ /* Prepare increment */
@ -813,9 +815,9 @@ void OPN2_EnvelopePrepare(ym3438_t *chip)
chip->eg_sl[0] = chip->sl[slot]; chip->eg_sl[0] = chip->sl[slot];
} }
void OPN2_EnvelopeGenerate(ym3438_t *chip) static void OPN2_EnvelopeGenerate(ym3438_t *chip)
{ {
Bit32u slot = (chip->slot + 23) % 24; Bit32u slot = (chip->cycles + 23) % 24;
Bit16u level; Bit16u level;
level = chip->eg_level[slot]; level = chip->eg_level[slot];
@ -846,7 +848,7 @@ void OPN2_EnvelopeGenerate(ym3438_t *chip)
chip->eg_out[slot] = level; chip->eg_out[slot] = level;
} }
void OPN2_UpdateLFO(ym3438_t *chip) static void OPN2_UpdateLFO(ym3438_t *chip)
{ {
if ((chip->lfo_quotient & lfo_cycles[chip->lfo_freq]) == lfo_cycles[chip->lfo_freq]) if ((chip->lfo_quotient & lfo_cycles[chip->lfo_freq]) == lfo_cycles[chip->lfo_freq])
{ {
@ -860,14 +862,14 @@ void OPN2_UpdateLFO(ym3438_t *chip)
chip->lfo_cnt &= chip->lfo_en; chip->lfo_cnt &= chip->lfo_en;
} }
void OPN2_FMPrepare(ym3438_t *chip) static void OPN2_FMPrepare(ym3438_t *chip)
{ {
Bit32u slot = (chip->slot + 6) % 24; Bit32u slot = (chip->cycles + 6) % 24;
Bit32u channel = chip->channel; Bit32u channel = chip->channel;
Bit16s mod, mod1, mod2; Bit16s mod, mod1, mod2;
Bit32u op = slot / 6; Bit32u op = slot / 6;
Bit8u connect = chip->connect[channel]; Bit8u connect = chip->connect[channel];
Bit32u prevslot = (chip->slot + 18) % 24; Bit32u prevslot = (chip->cycles + 18) % 24;
/* Calculate modulation */ /* Calculate modulation */
mod1 = mod2 = 0; mod1 = mod2 = 0;
@ -908,7 +910,7 @@ void OPN2_FMPrepare(ym3438_t *chip)
} }
chip->fm_mod[slot] = mod; chip->fm_mod[slot] = mod;
slot = (chip->slot + 18) % 24; slot = (chip->cycles + 18) % 24;
/* OP1 */ /* OP1 */
if (slot / 6 == 0) if (slot / 6 == 0)
{ {
@ -922,9 +924,9 @@ void OPN2_FMPrepare(ym3438_t *chip)
} }
} }
void OPN2_ChGenerate(ym3438_t *chip) static void OPN2_ChGenerate(ym3438_t *chip)
{ {
Bit32u slot = (chip->slot + 18) % 24; Bit32u slot = (chip->cycles + 18) % 24;
Bit32u channel = chip->channel; Bit32u channel = chip->channel;
Bit32u op = slot / 6; Bit32u op = slot / 6;
Bit32u test_dac = chip->mode_test_2c[5]; Bit32u test_dac = chip->mode_test_2c[5];
@ -957,16 +959,17 @@ void OPN2_ChGenerate(ym3438_t *chip)
chip->ch_acc[channel] = sum; chip->ch_acc[channel] = sum;
} }
void OPN2_ChOutput(ym3438_t *chip) static void OPN2_ChOutput(ym3438_t *chip)
{ {
Bit32u cycles = chip->cycles; Bit32u cycles = chip->cycles;
Bit32u slot = chip->cycles;
Bit32u channel = chip->channel; Bit32u channel = chip->channel;
Bit32u test_dac = chip->mode_test_2c[5]; Bit32u test_dac = chip->mode_test_2c[5];
Bit16s out; Bit16s out;
Bit16s sign; Bit16s sign;
Bit32u out_en; Bit32u out_en;
chip->ch_read = chip->ch_lock; chip->ch_read = chip->ch_lock;
if (chip->slot < 12) if (slot < 12)
{ {
/* Ch 4,5,6 */ /* Ch 4,5,6 */
channel++; channel++;
@ -1039,9 +1042,9 @@ void OPN2_ChOutput(ym3438_t *chip)
} }
} }
void OPN2_FMGenerate(ym3438_t *chip) static void OPN2_FMGenerate(ym3438_t *chip)
{ {
Bit32u slot = (chip->slot + 19) % 24; Bit32u slot = (chip->cycles + 19) % 24;
/* Calculate phase */ /* Calculate phase */
Bit16u phase = (chip->fm_mod[slot] + (chip->pg_phase[slot] >> 10)) & 0x3ff; Bit16u phase = (chip->fm_mod[slot] + (chip->pg_phase[slot] >> 10)) & 0x3ff;
Bit16u quarter; Bit16u quarter;
@ -1077,7 +1080,7 @@ void OPN2_FMGenerate(ym3438_t *chip)
chip->fm_out[slot] = output; chip->fm_out[slot] = output;
} }
void OPN2_DoTimerA(ym3438_t *chip) static void OPN2_DoTimerA(ym3438_t *chip)
{ {
Bit16u time; Bit16u time;
Bit8u load; Bit8u load;
@ -1126,7 +1129,7 @@ void OPN2_DoTimerA(ym3438_t *chip)
chip->timer_a_cnt = time & 0x3ff; chip->timer_a_cnt = time & 0x3ff;
} }
void OPN2_DoTimerB(ym3438_t *chip) static void OPN2_DoTimerB(ym3438_t *chip)
{ {
Bit16u time; Bit16u time;
Bit8u load; Bit8u load;
@ -1171,27 +1174,29 @@ void OPN2_DoTimerB(ym3438_t *chip)
chip->timer_b_cnt = time & 0xff; chip->timer_b_cnt = time & 0xff;
} }
void OPN2_KeyOn(ym3438_t*chip) static void OPN2_KeyOn(ym3438_t*chip)
{ {
Bit32u slot = chip->cycles;
Bit32u chan = chip->channel;
/* Key On */ /* Key On */
chip->eg_kon_latch[chip->slot] = chip->mode_kon[chip->slot]; chip->eg_kon_latch[slot] = chip->mode_kon[slot];
chip->eg_kon_csm[chip->slot] = 0; chip->eg_kon_csm[slot] = 0;
if (chip->channel == 2 && chip->mode_kon_csm) if (chip->channel == 2 && chip->mode_kon_csm)
{ {
/* CSM Key On */ /* CSM Key On */
chip->eg_kon_latch[chip->slot] = 1; chip->eg_kon_latch[slot] = 1;
chip->eg_kon_csm[chip->slot] = 1; chip->eg_kon_csm[slot] = 1;
} }
if (chip->cycles == chip->mode_kon_channel) if (chip->cycles == chip->mode_kon_channel)
{ {
/* OP1 */ /* OP1 */
chip->mode_kon[chip->channel] = chip->mode_kon_operator[0]; chip->mode_kon[chan] = chip->mode_kon_operator[0];
/* OP2 */ /* OP2 */
chip->mode_kon[chip->channel + 12] = chip->mode_kon_operator[1]; chip->mode_kon[chan + 12] = chip->mode_kon_operator[1];
/* OP3 */ /* OP3 */
chip->mode_kon[chip->channel + 6] = chip->mode_kon_operator[2]; chip->mode_kon[chan + 6] = chip->mode_kon_operator[2];
/* OP4 */ /* OP4 */
chip->mode_kon[chip->channel + 18] = chip->mode_kon_operator[3]; chip->mode_kon[chan + 18] = chip->mode_kon_operator[3];
} }
} }
@ -1220,6 +1225,7 @@ void OPN2_SetChipType(Bit32u type)
void OPN2_Clock(ym3438_t *chip, Bit16s *buffer) void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
{ {
Bit32u slot = chip->cycles;
chip->lfo_inc = chip->mode_test_21[1]; chip->lfo_inc = chip->mode_test_21[1];
chip->pg_read >>= 1; chip->pg_read >>= 1;
chip->eg_read[1] >>= 1; chip->eg_read[1] >>= 1;
@ -1310,7 +1316,7 @@ void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
if (chip->mode_ch3) if (chip->mode_ch3)
{ {
/* Channel 3 special mode */ /* Channel 3 special mode */
switch (chip->slot) switch (slot)
{ {
case 1: /* OP1 */ case 1: /* OP1 */
chip->pg_fnum = chip->fnum_3ch[1]; chip->pg_fnum = chip->fnum_3ch[1];
@ -1345,7 +1351,6 @@ void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
OPN2_UpdateLFO(chip); OPN2_UpdateLFO(chip);
OPN2_DoRegWrite(chip); OPN2_DoRegWrite(chip);
chip->cycles = (chip->cycles + 1) % 24; chip->cycles = (chip->cycles + 1) % 24;
chip->slot = chip->cycles;
chip->channel = chip->cycles % 6; chip->channel = chip->cycles % 6;
buffer[0] = chip->mol; buffer[0] = chip->mol;
@ -1397,6 +1402,7 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
if (chip->mode_test_21[6]) if (chip->mode_test_21[6])
{ {
/* Read test data */ /* Read test data */
Bit32u slot = (chip->cycles + 18) % 24;
Bit16u testdata = ((chip->pg_read & 0x01) << 15) Bit16u testdata = ((chip->pg_read & 0x01) << 15)
| ((chip->eg_read[chip->mode_test_21[0]] & 0x01) << 14); | ((chip->eg_read[chip->mode_test_21[0]] & 0x01) << 14);
if (chip->mode_test_2c[4]) if (chip->mode_test_2c[4])
@ -1405,7 +1411,7 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
} }
else else
{ {
testdata |= chip->fm_out[(chip->slot + 18) % 24] & 0x3fff; testdata |= chip->fm_out[slot] & 0x3fff;
} }
if (chip->mode_test_21[7]) if (chip->mode_test_21[7])
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2017 Alexey Khokholov (Nuke.YKT) * Copyright (C) 2017-2018 Alexey Khokholov (Nuke.YKT)
* *
* Redistribution and use of this code or any derivative works are permitted * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -39,15 +39,19 @@
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): * OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
* OPL2 ROMs. * OPL2 ROMs.
* *
* version: 1.0.8 * version: 1.0.9
*/ */
#ifndef YM3438_H #ifndef YM3438_H
#define YM3438_H #define YM3438_H
#ifdef __cplusplus
extern "C" {
#endif
enum { enum {
ym3438_mode_ym2612 = 0x01, /* Enables YM2612 emulation (MD1, MD2 VA2) */ ym3438_mode_ym2612 = 0x01, /* Enables YM2612 emulation (MD1, MD2 VA2) */
ym3438_mode_readmode = 0x02, /* Enables status read on any port (TeraDrive, MD1 VA7, MD2, etc) */ ym3438_mode_readmode = 0x02 /* Enables status read on any port (TeraDrive, MD1 VA7, MD2, etc) */
}; };
#include <stdint.h> #include <stdint.h>
@ -66,7 +70,6 @@ typedef int8_t Bit8s;
typedef struct typedef struct
{ {
Bit32u cycles; Bit32u cycles;
Bit32u slot;
Bit32u channel; Bit32u channel;
Bit16s mol, mor; Bit16s mol, mor;
/* IO */ /* IO */
@ -79,7 +82,7 @@ typedef struct
Bit8u write_busy_cnt; Bit8u write_busy_cnt;
Bit8u write_fm_address; Bit8u write_fm_address;
Bit8u write_fm_data; Bit8u write_fm_data;
Bit8u write_fm_mode_a; Bit16u write_fm_mode_a;
Bit16u address; Bit16u address;
Bit8u data; Bit8u data;
Bit8u pin_test_in; Bit8u pin_test_in;
@ -155,7 +158,7 @@ typedef struct
Bit8u timer_a_load_latch; Bit8u timer_a_load_latch;
Bit8u timer_a_overflow_flag; Bit8u timer_a_overflow_flag;
Bit8u timer_a_overflow; Bit8u timer_a_overflow;
Bit16u timer_b_cnt; Bit16u timer_b_cnt;
Bit8u timer_b_subcnt; Bit8u timer_b_subcnt;
Bit16u timer_b_reg; Bit16u timer_b_reg;
@ -166,7 +169,7 @@ typedef struct
Bit8u timer_b_load_latch; Bit8u timer_b_load_latch;
Bit8u timer_b_overflow_flag; Bit8u timer_b_overflow_flag;
Bit8u timer_b_overflow; Bit8u timer_b_overflow;
/* Register set */ /* Register set */
Bit8u mode_test_21[8]; Bit8u mode_test_21[8];
Bit8u mode_test_2c[8]; Bit8u mode_test_2c[8];
@ -178,7 +181,7 @@ typedef struct
Bit8u mode_kon_csm; Bit8u mode_kon_csm;
Bit8u dacen; Bit8u dacen;
Bit16s dacdata; Bit16s dacdata;
Bit8u ks[24]; Bit8u ks[24];
Bit8u ar[24]; Bit8u ar[24];
Bit8u sr[24]; Bit8u sr[24];
@ -190,7 +193,7 @@ typedef struct
Bit8u am[24]; Bit8u am[24];
Bit8u tl[24]; Bit8u tl[24];
Bit8u ssg_eg[24]; Bit8u ssg_eg[24];
Bit16u fnum[6]; Bit16u fnum[6];
Bit8u block[6]; Bit8u block[6];
Bit8u kcode[6]; Bit8u kcode[6];
@ -216,4 +219,9 @@ void OPN2_SetTestPin(ym3438_t *chip, Bit32u value);
Bit32u OPN2_ReadTestPin(ym3438_t *chip); Bit32u OPN2_ReadTestPin(ym3438_t *chip);
Bit32u OPN2_ReadIRQPin(ym3438_t *chip); Bit32u OPN2_ReadIRQPin(ym3438_t *chip);
Bit8u OPN2_Read(ym3438_t *chip, Bit32u port); Bit8u OPN2_Read(ym3438_t *chip, Bit32u port);
#ifdef __cplusplus
}
#endif
#endif #endif