diff --git a/builds/genesis_plus_gx_libretro.dll b/builds/genesis_plus_gx_libretro.dll index fd26e8a..36b0e78 100644 Binary files a/builds/genesis_plus_gx_libretro.dll and b/builds/genesis_plus_gx_libretro.dll differ diff --git a/core/sound/ym3438.c b/core/sound/ym3438.c index 3917815..01d1c82 100644 --- a/core/sound/ym3438.c +++ b/core/sound/ym3438.c @@ -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 @@ -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]) { diff --git a/core/sound/ym3438.h b/core/sound/ym3438.h index 5ab284f..7123858 100644 --- a/core/sound/ym3438.h +++ b/core/sound/ym3438.h @@ -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 @@ -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