mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-13 06:15:07 +01:00
[Core/Sound] updated nuked ym2612/ym3438 core to version 1.0.10 (fixes sound issues in Stormlord)
This commit is contained in:
parent
8acd9def6d
commit
6d10dd30ff
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
#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
|
||||
* provided that the following conditions are met:
|
||||
@ -40,7 +40,7 @@
|
||||
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
|
||||
* OPL2 ROMs.
|
||||
*
|
||||
* version: 1.0.8
|
||||
* version: 1.0.10
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -235,7 +235,7 @@ static const Bit32u fm_algorithm[4][6][8] = {
|
||||
|
||||
static Bit32u chip_type = ym3438_mode_readmode;
|
||||
|
||||
void OPN2_DoIO(ym3438_t *chip)
|
||||
static void OPN2_DoIO(ym3438_t *chip)
|
||||
{
|
||||
/* Write signal check */
|
||||
chip->write_a_en = (chip->write_a & 0x03) == 0x01;
|
||||
@ -249,10 +249,10 @@ void OPN2_DoIO(ym3438_t *chip)
|
||||
chip->write_busy_cnt &= 0x1f;
|
||||
}
|
||||
|
||||
void OPN2_DoRegWrite(ym3438_t *chip)
|
||||
static void OPN2_DoRegWrite(ym3438_t *chip)
|
||||
{
|
||||
Bit32u i;
|
||||
Bit32u slot = chip->slot % 12;
|
||||
Bit32u slot = chip->cycles % 12;
|
||||
Bit32u address;
|
||||
Bit32u channel = chip->channel;
|
||||
/* Update registers */
|
||||
@ -379,7 +379,7 @@ void OPN2_DoRegWrite(ym3438_t *chip)
|
||||
/* Data */
|
||||
if (chip->write_d_en && (chip->write_data & 0x100) == 0)
|
||||
{
|
||||
switch (chip->address)
|
||||
switch (chip->write_fm_mode_a)
|
||||
{
|
||||
case 0x21: /* LSI test 1 */
|
||||
for (i = 0; i < 8; i++)
|
||||
@ -458,7 +458,7 @@ void OPN2_DoRegWrite(ym3438_t *chip)
|
||||
/* Address */
|
||||
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_h = fnum >> 4;
|
||||
Bit32u fm;
|
||||
Bit32u basefreq;
|
||||
Bit8u lfo = chip->lfo_pm;
|
||||
Bit8u lfo_l = lfo & 0x0f;
|
||||
Bit8u pms = chip->pms[chip->channel];
|
||||
Bit8u dt = chip->dt[chip->slot];
|
||||
Bit8u pms = chip->pms[chan];
|
||||
Bit8u dt = chip->dt[slot];
|
||||
Bit8u dt_l = dt & 0x03;
|
||||
Bit8u detune = 0;
|
||||
Bit8u block, note;
|
||||
@ -531,32 +533,32 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
|
||||
basefreq += detune;
|
||||
}
|
||||
basefreq &= 0x1ffff;
|
||||
chip->pg_inc[chip->slot] = (basefreq * chip->multi[chip->slot]) >> 1;
|
||||
chip->pg_inc[chip->slot] &= 0xfffff;
|
||||
chip->pg_inc[slot] = (basefreq * chip->multi[slot]) >> 1;
|
||||
chip->pg_inc[slot] &= 0xfffff;
|
||||
}
|
||||
|
||||
void OPN2_PhaseGenerate(ym3438_t *chip)
|
||||
static void OPN2_PhaseGenerate(ym3438_t *chip)
|
||||
{
|
||||
Bit32u slot;
|
||||
/* Mask increment */
|
||||
slot = (chip->slot + 20) % 24;
|
||||
slot = (chip->cycles + 20) % 24;
|
||||
if (chip->pg_reset[slot])
|
||||
{
|
||||
chip->pg_inc[slot] = 0;
|
||||
}
|
||||
/* Phase step */
|
||||
slot = (chip->slot + 19) % 24;
|
||||
chip->pg_phase[slot] += chip->pg_inc[slot];
|
||||
chip->pg_phase[slot] &= 0xfffff;
|
||||
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)
|
||||
static void OPN2_EnvelopeSSGEG(ym3438_t *chip)
|
||||
{
|
||||
Bit32u slot = chip->slot;
|
||||
Bit32u slot = chip->cycles;
|
||||
Bit8u direction = 0;
|
||||
chip->eg_ssg_pgrst_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;
|
||||
}
|
||||
|
||||
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 okon = chip->eg_kon[slot];
|
||||
@ -725,12 +727,12 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
|
||||
chip->eg_state[slot] = nextstate;
|
||||
}
|
||||
|
||||
void OPN2_EnvelopePrepare(ym3438_t *chip)
|
||||
static void OPN2_EnvelopePrepare(ym3438_t *chip)
|
||||
{
|
||||
Bit8u rate;
|
||||
Bit8u sum;
|
||||
Bit8u inc = 0;
|
||||
Bit32u slot = chip->slot;
|
||||
Bit32u slot = chip->cycles;
|
||||
Bit8u rate_sel;
|
||||
|
||||
/* Prepare increment */
|
||||
@ -813,9 +815,9 @@ void OPN2_EnvelopePrepare(ym3438_t *chip)
|
||||
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;
|
||||
|
||||
level = chip->eg_level[slot];
|
||||
@ -846,7 +848,7 @@ void OPN2_EnvelopeGenerate(ym3438_t *chip)
|
||||
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])
|
||||
{
|
||||
@ -860,14 +862,14 @@ void OPN2_UpdateLFO(ym3438_t *chip)
|
||||
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;
|
||||
Bit16s mod, mod1, mod2;
|
||||
Bit32u op = slot / 6;
|
||||
Bit8u connect = chip->connect[channel];
|
||||
Bit32u prevslot = (chip->slot + 18) % 24;
|
||||
Bit32u prevslot = (chip->cycles + 18) % 24;
|
||||
|
||||
/* Calculate modulation */
|
||||
mod1 = mod2 = 0;
|
||||
@ -908,7 +910,7 @@ void OPN2_FMPrepare(ym3438_t *chip)
|
||||
}
|
||||
chip->fm_mod[slot] = mod;
|
||||
|
||||
slot = (chip->slot + 18) % 24;
|
||||
slot = (chip->cycles + 18) % 24;
|
||||
/* OP1 */
|
||||
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 op = slot / 6;
|
||||
Bit32u test_dac = chip->mode_test_2c[5];
|
||||
@ -957,16 +959,17 @@ void OPN2_ChGenerate(ym3438_t *chip)
|
||||
chip->ch_acc[channel] = sum;
|
||||
}
|
||||
|
||||
void OPN2_ChOutput(ym3438_t *chip)
|
||||
static 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 (chip->slot < 12)
|
||||
if (slot < 12)
|
||||
{
|
||||
/* Ch 4,5,6 */
|
||||
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 */
|
||||
Bit16u phase = (chip->fm_mod[slot] + (chip->pg_phase[slot] >> 10)) & 0x3ff;
|
||||
Bit16u quarter;
|
||||
@ -1077,7 +1080,7 @@ void OPN2_FMGenerate(ym3438_t *chip)
|
||||
chip->fm_out[slot] = output;
|
||||
}
|
||||
|
||||
void OPN2_DoTimerA(ym3438_t *chip)
|
||||
static void OPN2_DoTimerA(ym3438_t *chip)
|
||||
{
|
||||
Bit16u time;
|
||||
Bit8u load;
|
||||
@ -1126,7 +1129,7 @@ void OPN2_DoTimerA(ym3438_t *chip)
|
||||
chip->timer_a_cnt = time & 0x3ff;
|
||||
}
|
||||
|
||||
void OPN2_DoTimerB(ym3438_t *chip)
|
||||
static void OPN2_DoTimerB(ym3438_t *chip)
|
||||
{
|
||||
Bit16u time;
|
||||
Bit8u load;
|
||||
@ -1171,27 +1174,29 @@ void OPN2_DoTimerB(ym3438_t *chip)
|
||||
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 */
|
||||
chip->eg_kon_latch[chip->slot] = chip->mode_kon[chip->slot];
|
||||
chip->eg_kon_csm[chip->slot] = 0;
|
||||
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[chip->slot] = 1;
|
||||
chip->eg_kon_csm[chip->slot] = 1;
|
||||
chip->eg_kon_latch[slot] = 1;
|
||||
chip->eg_kon_csm[slot] = 1;
|
||||
}
|
||||
if (chip->cycles == chip->mode_kon_channel)
|
||||
{
|
||||
/* OP1 */
|
||||
chip->mode_kon[chip->channel] = chip->mode_kon_operator[0];
|
||||
chip->mode_kon[chan] = chip->mode_kon_operator[0];
|
||||
/* OP2 */
|
||||
chip->mode_kon[chip->channel + 12] = chip->mode_kon_operator[1];
|
||||
chip->mode_kon[chan + 12] = chip->mode_kon_operator[1];
|
||||
/* OP3 */
|
||||
chip->mode_kon[chip->channel + 6] = chip->mode_kon_operator[2];
|
||||
chip->mode_kon[chan + 6] = chip->mode_kon_operator[2];
|
||||
/* 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)
|
||||
{
|
||||
Bit32u slot = chip->cycles;
|
||||
chip->lfo_inc = chip->mode_test_21[1];
|
||||
chip->pg_read >>= 1;
|
||||
chip->eg_read[1] >>= 1;
|
||||
@ -1310,7 +1316,7 @@ void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
|
||||
if (chip->mode_ch3)
|
||||
{
|
||||
/* Channel 3 special mode */
|
||||
switch (chip->slot)
|
||||
switch (slot)
|
||||
{
|
||||
case 1: /* OP1 */
|
||||
chip->pg_fnum = chip->fnum_3ch[1];
|
||||
@ -1345,7 +1351,6 @@ void OPN2_Clock(ym3438_t *chip, Bit16s *buffer)
|
||||
OPN2_UpdateLFO(chip);
|
||||
OPN2_DoRegWrite(chip);
|
||||
chip->cycles = (chip->cycles + 1) % 24;
|
||||
chip->slot = chip->cycles;
|
||||
chip->channel = chip->cycles % 6;
|
||||
|
||||
buffer[0] = chip->mol;
|
||||
@ -1397,6 +1402,7 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
|
||||
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])
|
||||
@ -1405,7 +1411,7 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
|
||||
}
|
||||
else
|
||||
{
|
||||
testdata |= chip->fm_out[(chip->slot + 18) % 24] & 0x3fff;
|
||||
testdata |= chip->fm_out[slot] & 0x3fff;
|
||||
}
|
||||
if (chip->mode_test_21[7])
|
||||
{
|
||||
|
@ -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
|
||||
* provided that the following conditions are met:
|
||||
@ -39,15 +39,19 @@
|
||||
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
|
||||
* OPL2 ROMs.
|
||||
*
|
||||
* version: 1.0.8
|
||||
* version: 1.0.9
|
||||
*/
|
||||
|
||||
#ifndef YM3438_H
|
||||
#define YM3438_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
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>
|
||||
@ -66,7 +70,6 @@ typedef int8_t Bit8s;
|
||||
typedef struct
|
||||
{
|
||||
Bit32u cycles;
|
||||
Bit32u slot;
|
||||
Bit32u channel;
|
||||
Bit16s mol, mor;
|
||||
/* IO */
|
||||
@ -79,7 +82,7 @@ typedef struct
|
||||
Bit8u write_busy_cnt;
|
||||
Bit8u write_fm_address;
|
||||
Bit8u write_fm_data;
|
||||
Bit8u write_fm_mode_a;
|
||||
Bit16u write_fm_mode_a;
|
||||
Bit16u address;
|
||||
Bit8u data;
|
||||
Bit8u pin_test_in;
|
||||
@ -155,7 +158,7 @@ typedef struct
|
||||
Bit8u timer_a_load_latch;
|
||||
Bit8u timer_a_overflow_flag;
|
||||
Bit8u timer_a_overflow;
|
||||
|
||||
|
||||
Bit16u timer_b_cnt;
|
||||
Bit8u timer_b_subcnt;
|
||||
Bit16u timer_b_reg;
|
||||
@ -166,7 +169,7 @@ typedef struct
|
||||
Bit8u timer_b_load_latch;
|
||||
Bit8u timer_b_overflow_flag;
|
||||
Bit8u timer_b_overflow;
|
||||
|
||||
|
||||
/* Register set */
|
||||
Bit8u mode_test_21[8];
|
||||
Bit8u mode_test_2c[8];
|
||||
@ -178,7 +181,7 @@ typedef struct
|
||||
Bit8u mode_kon_csm;
|
||||
Bit8u dacen;
|
||||
Bit16s dacdata;
|
||||
|
||||
|
||||
Bit8u ks[24];
|
||||
Bit8u ar[24];
|
||||
Bit8u sr[24];
|
||||
@ -190,7 +193,7 @@ typedef struct
|
||||
Bit8u am[24];
|
||||
Bit8u tl[24];
|
||||
Bit8u ssg_eg[24];
|
||||
|
||||
|
||||
Bit16u fnum[6];
|
||||
Bit8u block[6];
|
||||
Bit8u kcode[6];
|
||||
@ -216,4 +219,9 @@ void OPN2_SetTestPin(ym3438_t *chip, Bit32u value);
|
||||
Bit32u OPN2_ReadTestPin(ym3438_t *chip);
|
||||
Bit32u OPN2_ReadIRQPin(ym3438_t *chip);
|
||||
Bit8u OPN2_Read(ym3438_t *chip, Bit32u port);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user