furnace/extern/YM2608-LLE/fmopna_impl.c
tildearrow b447fa9e68 fix ssg noise
commit 83e571634a9144d48eb4089f5ae1c3d31319e11e of https://github.com/nukeykt/YM2608-LLE
by nukeykt
2024-04-29 01:39:53 -05:00

5856 lines
217 KiB
C

/*
* Copyright (C) 2023-2024 nukeykt
*
* This file is part of YM2608-LLE.
*
* 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.
*
* YM2608/YM2610/YM2612 emulator.
* Thanks:
* Raki (ika-musume):
* YM2608B decap
* John McMaster (siliconpr0n.org):
* YM2610 decap
* HardWareMan:
* YM2612 decap
*
*/
#include <string.h>
#include "fmopna_impl.h"
#ifdef FMOPNA_YM2608
#include "fmopna_rom.h"
#endif
enum {
eg_state_attack = 0,
eg_state_decay,
eg_state_sustain,
eg_state_release
};
static const int 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 */
}
};
#ifdef FMOPNA_YM2608
void FMOPNA_Clock(fmopna_t* chip, int clk)
#elif defined (FMOPNA_YM2610)
void FMOPNA_2610_Clock(fmopna_2610_t* chip, int clk)
#else
void FMOPNA_2612_Clock(fmopna_2612_t* chip, int clk)
#endif
{
int i;
chip->input.clk = clk;
chip->mclk1 = !chip->input.clk;
chip->mclk2 = chip->input.clk;
chip->ic = !chip->input.ic;
if (chip->mclk1)
{
int prescaler_of = 0;
int dclk = 1;
#ifdef FMOPNA_YM2608
switch (chip->prescaler_sel[1])
{
case 2:
prescaler_of = (chip->prescaler_latch[1] & 0x7ff) == 0;
dclk = (chip->prescaler_latch[1] & 0xffc) == 0;
break;
case 0:
prescaler_of = (chip->prescaler_latch[1] & 7) == 0;
dclk = (chip->prescaler_latch[1] & 7) != 0;
break;
case 3:
prescaler_of = (chip->prescaler_latch[1] & 0x1f) == 0;
dclk = (chip->prescaler_latch[1] & 0x1f) == 0;
break;
}
#endif
#ifdef FMOPNA_YM2610
prescaler_of = (chip->prescaler_latch[1] & 0x7ff) == 0;
dclk = (chip->prescaler_latch[1] & 0xffc) == 0;
#endif
#ifdef FMOPNA_YM2612
prescaler_of = (chip->prescaler_latch[1] & 0x1f) == 0;
#endif
chip->ic_latch1[0] = chip->ic;
chip->ic_latch2[0] = (chip->ic_latch2[1] << 1) | chip->ic_latch1[1];
chip->ic_latch3[0] = (chip->ic_latch3[1] << 1) | chip->ic_check1;
chip->prescaler_latch[0] = chip->prescaler_latch[1] << 1;
chip->prescaler_latch[0] |= !chip->ic_check1 && prescaler_of;
#ifdef FMOPNA_YM2608
chip->pssel_l[0][0] = (chip->prescaler_latch[1] & 0x861) != 0;
chip->pssel_l[1][0] = (chip->prescaler_latch[1] & 0x30c) != 0;
chip->pssel_l[2][0] = (chip->prescaler_latch[1] & 0x12) != 0;
chip->pssel_l[3][0] = (chip->prescaler_latch[1] & 0x24) != 0;
chip->pssel_l[4][0] = chip->pssel_l[4][1] << 1;
chip->pssel_l[4][0] |= (chip->prescaler_latch[1] & 0x5) != 0;
chip->pssel_l[5][0] = (chip->prescaler_latch[1] & 0x3c) != 0;
chip->pssel_l[6][0] = (chip->prescaler_latch[1] & 0xf00) != 0;
chip->pssel_l[7][0] = (chip->prescaler_latch[1] & 0xc) != 0;
chip->pssel_l[8][0] = (chip->prescaler_latch[1] & 0x21) != 0;
chip->pssel_l[9][0] = (chip->prescaler_latch[1] & 0x2) != 0;
chip->pssel_l[10][0] = (chip->prescaler_latch[1] & 0x1) != 0;
chip->pssel_l[11][0] = (chip->prescaler_latch[1] & 0x924) != 0;
chip->pssel_l[12][0] = (chip->prescaler_latch[1] & 0x249) != 0;
chip->pssel_l[13][0] = chip->pssel_l[13][1] << 1;
chip->pssel_l[13][0] |= (chip->prescaler_latch[1] & 9) == 0;
chip->pssel_l[14][0] = (chip->prescaler_latch[1] & 0x555) != 0;
chip->dclk = dclk;
#endif
#ifdef FMOPNA_YM2610
chip->pssel_l[0][0] = (chip->prescaler_latch[1] & 0x861) != 0;
chip->pssel_l[1][0] = (chip->prescaler_latch[1] & 0x30c) != 0;
chip->pssel_l[5][0] = (chip->prescaler_latch[1] & 0x3c) != 0;
chip->pssel_l[6][0] = (chip->prescaler_latch[1] & 0xf00) != 0;
chip->pssel_l[11][0] = (chip->prescaler_latch[1] & 0x924) != 0;
chip->pssel_l[12][0] = (chip->prescaler_latch[1] & 0x249) != 0;
chip->pssel_l[14][0] = (chip->prescaler_latch[1] & 0x555) != 0;
chip->dclk = dclk;
#endif
#ifdef FMOPNA_YM2612
chip->pssel_l[0][0] = (chip->prescaler_latch[1] & 0x21) != 0;
chip->pssel_l[1][0] = (chip->prescaler_latch[1] & 0xc) != 0;
#endif
}
if (chip->mclk2)
{
chip->ic_latch1[1] = chip->ic_latch1[0];
chip->ic_latch2[1] = chip->ic_latch2[0];
chip->ic_latch3[1] = chip->ic_latch3[0];
#ifndef FMOPNA_YM2612
chip->ic_check1 = chip->ic_latch1[1] && (chip->ic_latch2[1] & 0x20000) == 0;
chip->ic_check2 = (chip->ic_latch3[1] & 4) != 0;
#else
chip->ic_check1 = chip->ic_latch1[1] && (chip->ic_latch2[1] & 0x800) == 0;
#endif
chip->ic_check3 = (chip->ic_latch3[1] & 8) != 0;
chip->prescaler_latch[1] = chip->prescaler_latch[0];
#ifndef FMOPNA_YM2612
for (i = 0; i < 15; i++)
chip->pssel_l[i][1] = chip->pssel_l[i][0];
#else
chip->pssel_l[0][1] = chip->pssel_l[0][0];
chip->pssel_l[1][1] = chip->pssel_l[1][0];
#endif
}
if (chip->clk1)
{
chip->ic_latch_fm[0] = chip->ic;
}
if (chip->clk2)
{
chip->ic_latch_fm[1] = chip->ic_latch_fm[0];
}
{
#ifndef FMOPNA_YM2612
int clk1 = 1;
int clk2 = 1;
int aclk1 = 1;
int aclk2 = 1;
int bclk1 = 1;
int bclk2 = 1;
#ifdef FMOPNA_YM2608
switch (chip->prescaler_sel[1])
{
case 2:
clk1 = chip->pssel_l[0][1];
clk2 = chip->pssel_l[1][1];
aclk1 = chip->pssel_l[5][1];
aclk2 = chip->pssel_l[6][1];
bclk1 = chip->pssel_l[11][1];
bclk2 = chip->pssel_l[12][1];
break;
case 0:
clk1 = (chip->pssel_l[4][1] & 2) != 0 && (chip->pssel_l[4][0] & 4) != 0;
clk2 = (chip->pssel_l[4][1] & 1) != 0 && (chip->pssel_l[4][0] & 2) != 0;
aclk1 = chip->pssel_l[9][1];
aclk2 = chip->pssel_l[10][1];
bclk1 = !chip->mclk2;
bclk2 = !chip->mclk1;
break;
case 3:
clk1 = chip->pssel_l[2][1];
clk2 = chip->pssel_l[3][1];
aclk1 = chip->pssel_l[7][1];
aclk2 = chip->pssel_l[8][1];
bclk1 = ((chip->pssel_l[13][1] & 4) == 0 && (chip->pssel_l[13][0] & 8) != 0)
|| ((chip->pssel_l[13][1] & 1) == 0 && (chip->pssel_l[13][0] & 2) == 0);
bclk2 = ((chip->pssel_l[13][1] & 1) == 0 && (chip->pssel_l[13][0] & 2) != 0)
|| ((chip->pssel_l[13][1] & 2) == 0 && (chip->pssel_l[13][0] & 4) == 0);
break;
}
#endif
#ifdef FMOPNA_YM2610
clk1 = chip->pssel_l[0][1];
clk2 = chip->pssel_l[1][1];
aclk1 = chip->pssel_l[5][1];
aclk2 = chip->pssel_l[6][1];
bclk1 = chip->pssel_l[11][1];
bclk2 = chip->pssel_l[12][1];
#endif
chip->clk1 = clk1;
chip->clk2 = clk2;
chip->aclk1 = aclk1;
chip->aclk2 = aclk2;
chip->bclk1 = bclk1;
chip->bclk2 = bclk2;
chip->cclk1 = !chip->pssel_l[14][1];
chip->cclk2 = chip->pssel_l[14][1];
#else
chip->clk1 = chip->pssel_l[0][1];
chip->clk2 = chip->pssel_l[1][1];
#endif
}
// if (clk)
// return;
{
int read = !chip->ic && !chip->input.rd && !chip->input.cs;
chip->read0 = !chip->ic && !chip->input.rd && !chip->input.cs && !chip->input.a1 && !chip->input.a0;
int write = !chip->input.wr && !chip->input.cs;
int writeaddr = chip->ic || (!chip->input.wr && !chip->input.cs && !chip->input.a0);
int writedata = !chip->ic && !chip->input.wr && !chip->input.cs && chip->input.a0;
#ifndef FMOPNA_YM2612
int read1 = !chip->ic && !chip->input.rd && !chip->input.cs && !chip->input.a1 && chip->input.a0;
chip->read2 = !chip->ic && !chip->input.rd && !chip->input.cs && chip->input.a1 && !chip->input.a0;
#ifdef FMOPNA_YM2608
chip->read3 = !chip->ic && !chip->input.rd && !chip->input.cs && chip->input.a1 && chip->input.a0;
chip->write2 = !chip->ic && !chip->input.wr && !chip->input.cs && chip->input.a1 && !chip->input.a0;
chip->write3 = !chip->ic && !chip->input.wr && !chip->input.cs && chip->input.a1 && chip->input.a0;
#endif
#ifdef FMOPNA_YM2610
chip->write2 = !chip->ic && !chip->input.wr && !chip->input.cs && !chip->input.a1 && !chip->input.a0;
chip->write3 = !chip->ic && !chip->input.wr && !chip->input.cs && !chip->input.a1 && chip->input.a0;
#endif
chip->ssg_write0 = writeaddr && !chip->input.a1;
chip->ssg_write1 = (writedata && !chip->input.a1) || chip->ic;
chip->ssg_read1 = read1;
#endif
chip->o_data_d = !read;
if (writeaddr)
chip->write0_trig0 = 1;
else if (chip->write0_l[0])
chip->write0_trig0 = 0;
if (chip->clk1)
{
chip->write0_trig1 = chip->write0_trig0;
chip->write0_l[1] = chip->write0_l[0];
}
if (chip->clk2)
{
chip->write0_l[0] = chip->write0_trig1;
chip->write0_l[2] = chip->write0_l[1];
}
chip->write0_en = chip->write0_l[0] && !chip->write0_l[2];
if (writedata)
chip->write1_trig0 = 1;
else if (chip->write1_l[0])
chip->write1_trig0 = 0;
if (chip->clk1)
{
chip->write1_trig1 = chip->write1_trig0;
chip->write1_l[1] = chip->write1_l[0];
}
if (chip->clk2)
{
chip->write1_l[0] = chip->write1_trig1;
chip->write1_l[2] = chip->write1_l[1];
}
chip->write1_en = chip->write1_l[0] && !chip->write1_l[2];
#ifdef FMOPNA_YM2608
if (writeaddr)
chip->write2_trig0 = 1;
else if (chip->write2_l[0])
chip->write2_trig0 = 0;
if (chip->mclk1)
{
chip->write2_trig1 = chip->write2_trig0;
chip->write2_l[1] = chip->write2_l[0];
}
if (chip->mclk2)
{
chip->write2_l[0] = chip->write2_trig1;
chip->write2_l[2] = chip->write2_l[1];
}
chip->write2_en = chip->write2_l[0] && !chip->write2_l[2];
#endif
#ifndef FMOPNA_YM2612
if (writedata)
chip->write3_trig0 = 1;
else if (chip->write3_l[0])
chip->write3_trig0 = 0;
#endif
if (write)
chip->data_l = (chip->input.data & 255) | (chip->input.a1 << 8);
#ifndef FMOPNA_YM2612
if (chip->ic)
chip->data_bus2 |= 0x2f;
else
#endif
if (!read && !chip->ic)
chip->data_bus2 = chip->data_l ^ 0x1ff;
if (chip->ic_latch_fm[1])
{
chip->data_bus1 &= ~255;
}
else if (!read && !chip->ic)
{
chip->data_bus1 = chip->data_l;
}
#ifdef FMOPNA_YM2608
else if (read1 && chip->addr_ff[1])
{
chip->data_bus1 &= ~255;
chip->data_bus1 |= 1;
}
#endif
#define ADDRESS_MATCH(x) ((chip->data_bus2 & x) == 0 && (chip->data_bus1 & (x^511)) == 0)
#ifdef FMOPNA_YM2608
if (chip->mclk1)
{
int addr2d = chip->write2_en && ADDRESS_MATCH(0x2d);
int addr2e = chip->write2_en && ADDRESS_MATCH(0x2e);
int addr2f = chip->write2_en && ADDRESS_MATCH(0x2f);
chip->prescaler_sel[0] = chip->prescaler_sel[1];
if (addr2f)
chip->prescaler_sel[0] = 0;
if (chip->ic)
chip->prescaler_sel[0] = 2;
if (addr2d)
chip->prescaler_sel[0] |= 2;
if (addr2e)
chip->prescaler_sel[0] |= 1;
}
if (chip->mclk2)
{
chip->prescaler_sel[1] = chip->prescaler_sel[0];
}
#endif
if (chip->clk1)
{
int is_fm = (chip->data_bus1 & 0xf0) != 0;
chip->write_fm_address[0] = chip->write0_en ? is_fm : chip->write_fm_address[1];
if (chip->ic)
chip->fm_address[0] = 0;
else if (is_fm && chip->write0_en)
chip->fm_address[0] = chip->data_bus1;
else
chip->fm_address[0] = chip->fm_address[1];
if (chip->ic)
chip->fm_data[0] = 0;
else if (chip->write_fm_address[1] && chip->write1_en)
chip->fm_data[0] = chip->data_bus1 & 255;
else
chip->fm_data[0] = chip->fm_data[1];
chip->write_fm_data[0] = (chip->write_fm_address[1] && chip->write1_en) || (chip->write_fm_data[1] && !chip->write0_en);
#ifdef FMOPNA_YM2608
chip->addr_10[0] = chip->write0_en ? ADDRESS_MATCH(0x10) : chip->addr_10[1];
chip->addr_10h[0] = chip->write0_en ? ADDRESS_MATCH(0x110) : chip->addr_10h[1];
chip->addr_12[0] = chip->write0_en ? ADDRESS_MATCH(0x12) : chip->addr_12[1];
chip->addr_29[0] = chip->write0_en ? ADDRESS_MATCH(0x29) : chip->addr_29[1];
chip->addr_ff[0] = chip->write0_en ? ADDRESS_MATCH(0xff) : chip->addr_ff[1];
int write10 = chip->addr_10h[1] && (chip->data_bus1 & 0x100) != 0 && chip->write1_en;
int irq_rst = write10 && (chip->data_bus2 & 0x80) == 0;
#endif
#ifdef FMOPNA_YM2610
chip->addr_00[0] = chip->write0_en ? ADDRESS_MATCH(0x100) : chip->addr_00[1];
chip->addr_02[0] = chip->write0_en ? ADDRESS_MATCH(0x102) : chip->addr_02[1];
chip->addr_1c[0] = chip->write0_en ? ADDRESS_MATCH(0x11c) : chip->addr_1c[1];
#endif
#ifdef FMOPNA_YM2612
chip->addr_2a[0] = chip->write0_en ? ADDRESS_MATCH(0x2a) : chip->addr_2a[1];
chip->addr_2b[0] = chip->write0_en ? ADDRESS_MATCH(0x2b) : chip->addr_2b[1];
chip->addr_2c[0] = chip->write0_en ? ADDRESS_MATCH(0x2c) : chip->addr_2c[1];
#endif
chip->addr_21[0] = chip->write0_en ? ADDRESS_MATCH(0x21) : chip->addr_21[1];
chip->addr_22[0] = chip->write0_en ? ADDRESS_MATCH(0x22) : chip->addr_22[1];
chip->addr_24[0] = chip->write0_en ? ADDRESS_MATCH(0x24) : chip->addr_24[1];
chip->addr_25[0] = chip->write0_en ? ADDRESS_MATCH(0x25) : chip->addr_25[1];
chip->addr_26[0] = chip->write0_en ? ADDRESS_MATCH(0x26) : chip->addr_26[1];
chip->addr_27[0] = chip->write0_en ? ADDRESS_MATCH(0x27) : chip->addr_27[1];
chip->addr_28[0] = chip->write0_en ? ADDRESS_MATCH(0x28) : chip->addr_28[1];
if (chip->ic)
{
chip->reg_test_21[0] = 0;
chip->reg_lfo[0] = 0;
chip->reg_timer_a[0] = 0;
chip->reg_timer_b[0] = 0;
chip->reg_ch3[0] = 0;
chip->reg_timer_a_load[0] = 0;
chip->reg_timer_b_load[0] = 0;
chip->reg_timer_a_enable[0] = 0;
chip->reg_timer_b_enable[0] = 0;
chip->reg_timer_a_reset[0] = 0;
chip->reg_timer_b_reset[0] = 0;
chip->reg_kon_operator[0] = 0;
chip->reg_kon_channel[0] = 0;
#ifdef FMOPNA_YM2608
chip->reg_test_12[0] = 0;
chip->reg_sch[0] = 0;
chip->reg_irq[0] = 31;
chip->reg_mask[0] = 28;
#endif
#ifdef FMOPNA_YM2610
chip->reg_test_12[0] = 0;
#endif
#ifdef FMOPNA_YM2612
chip->reg_dac_en[0] = 0;
chip->reg_dac_data[0] = 0x80;
chip->reg_test_2c[0] = 0;
#endif
}
else
{
#ifdef FMOPNA_YM2608
int write10r = write10 && (chip->data_bus2 & 0x80) != 0;
if (write10r)
{
chip->reg_mask[0] = chip->data_bus1 & 3;
chip->reg_mask[0] |= (chip->data_bus2 ^ 28) & 28;
}
else
{
chip->reg_mask[0] = chip->reg_mask[1];
}
if (chip->addr_12[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_test_12[0] = chip->data_bus1 & 252;
}
else
{
chip->reg_test_12[0] = chip->reg_test_12[1];
}
#endif
#ifdef FMOPNA_YM2610
if (chip->addr_1c[1] && (chip->data_bus1 & 0x100) != 0 && chip->write1_en)
{
chip->reg_flags[0] = chip->data_bus1 & 0xbf;
}
else
{
chip->reg_flags[0] = chip->reg_flags[1];
}
if (chip->addr_02[1] && (chip->data_bus1 & 0x100) != 0 && chip->write1_en)
{
chip->reg_test_12[0] = chip->data_bus1 & 0xb8;
}
else
{
chip->reg_test_12[0] = chip->reg_test_12[1];
}
#endif
if (chip->addr_21[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_test_21[0] = chip->data_bus1 & 255;
}
else
{
chip->reg_test_21[0] = chip->reg_test_21[1];
}
if (chip->addr_22[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_lfo[0] = chip->data_bus1 & 15;
}
else
{
chip->reg_lfo[0] = chip->reg_lfo[1];
}
chip->reg_timer_a[0] = 0;
if (chip->addr_24[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_timer_a[0] |= (chip->data_bus1 & 255) << 2;
}
else
{
chip->reg_timer_a[0] |= chip->reg_timer_a[1] & 0x3fc;
}
if (chip->addr_25[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_timer_a[0] |= chip->data_bus1 & 3;
}
else
{
chip->reg_timer_a[0] |= chip->reg_timer_a[1] & 3;
}
if (chip->addr_26[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_timer_b[0] = chip->data_bus1 & 255;
}
else
{
chip->reg_timer_b[0] = chip->reg_timer_b[1];
}
if (chip->addr_27[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_ch3[0] = (chip->data_bus1 >> 6) & 3;
chip->reg_timer_a_load[0] = (chip->data_bus1 >> 0) & 1;
chip->reg_timer_b_load[0] = (chip->data_bus1 >> 1) & 1;
chip->reg_timer_a_enable[0] = (chip->data_bus1 >> 2) & 1;
chip->reg_timer_b_enable[0] = (chip->data_bus1 >> 3) & 1;
chip->reg_timer_a_reset[0] = (chip->data_bus1 >> 4) & 1;
chip->reg_timer_b_reset[0] = (chip->data_bus1 >> 5) & 1;
}
else
{
chip->reg_ch3[0] = chip->reg_ch3[1];
chip->reg_timer_a_load[0] = chip->reg_timer_a_load[1];
chip->reg_timer_b_load[0] = chip->reg_timer_b_load[1];
chip->reg_timer_a_enable[0] = chip->reg_timer_a_enable[1];
chip->reg_timer_b_enable[0] = chip->reg_timer_b_enable[1];
chip->reg_timer_a_reset[0] = 0;
chip->reg_timer_b_reset[0] = 0;
}
if (chip->addr_28[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_kon_operator[0] = (chip->data_bus1 >> 4) & 15;
chip->reg_kon_channel[0] = (chip->data_bus1 >> 0) & 7;
}
else
{
chip->reg_kon_operator[0] = chip->reg_kon_operator[1];
chip->reg_kon_channel[0] = chip->reg_kon_channel[1];
}
#ifdef FMOPNA_YM2608
if (chip->addr_29[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_sch[0] = (chip->data_bus1 >> 7) & 1;
chip->reg_irq[0] = (chip->data_bus2 & 31) ^ 31;
}
else
{
chip->reg_sch[0] = chip->reg_sch[1];
chip->reg_irq[0] = chip->reg_irq[1];
}
#endif
#ifdef FMOPNA_YM2612
if (chip->addr_2a[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_dac_data[0] = chip->data_bus1 & 255;
}
else
{
chip->reg_dac_data[0] = chip->reg_dac_data[1];
}
if (chip->addr_2b[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_dac_en[0] = (chip->data_bus1 & 128) != 0;
}
else
{
chip->reg_dac_en[0] = chip->reg_dac_en[1];
}
if (chip->addr_2c[1] && (chip->data_bus1 & 0x100) == 0 && chip->write1_en)
{
chip->reg_test_2c[0] = chip->data_bus1 & 0xf8;
}
else
{
chip->reg_test_2c[0] = chip->reg_test_2c[1];
}
#endif
}
int rst1 = chip->reg_cnt_sync || chip->ic;
int of = (chip->reg_cnt1[1] & 2) != 0;
chip->reg_cnt1[0] = (rst1 || of) ? 0 : ((chip->reg_cnt1[1] + 1) & 3);
chip->reg_cnt2[0] = rst1 ? 0 : ((chip->reg_cnt2[1] + of) & 3);
#ifdef FMOPNA_YM2608
int rst2 = chip->reg_cnt_sync || chip->reg_cnt_rss_of;
chip->reg_cnt_rss[0] = rst2 ? 0 : ((chip->reg_cnt_rss[1] + 1) & 15);
#endif
int of2 = (chip->reg_key_cnt1[1] & 2) != 0;
chip->reg_key_cnt1[0] = (rst1 || of2) ? 0 : ((chip->reg_key_cnt1[1] + 1) & 3);
chip->reg_key_cnt2[0] = rst1 ? 0 : ((chip->reg_key_cnt2[1] + of2) & 7);
chip->reg_kon[0][0] = chip->reg_kon[0][1] << 1;
chip->reg_kon[1][0] = chip->reg_kon[1][1] << 1;
chip->reg_kon[2][0] = chip->reg_kon[2][1] << 1;
chip->reg_kon[3][0] = chip->reg_kon[3][1] << 1;
if (chip->reg_kon_match)
{
chip->reg_kon[0][0] |= (chip->reg_kon_operator[1] >> 0) & 1;
chip->reg_kon[1][0] |= (chip->reg_kon_operator[1] >> 3) & 1;
chip->reg_kon[2][0] |= (chip->reg_kon_operator[1] >> 1) & 1;
chip->reg_kon[3][0] |= (chip->reg_kon_operator[1] >> 2) & 1;
}
else
{
if (!chip->ic)
chip->reg_kon[0][0] |= (chip->reg_kon[3][1] >> 5) & 1;
chip->reg_kon[1][0] |= (chip->reg_kon[0][1] >> 5) & 1;
chip->reg_kon[2][0] |= (chip->reg_kon[1][1] >> 5) & 1;
chip->reg_kon[3][0] |= (chip->reg_kon[2][1] >> 5) & 1;
}
chip->reg_sync_timer_l[0] = chip->reg_sync_timer;
int time = chip->timer_a_cnt[1];
time += (chip->reg_test_21[1] & 4) != 0 || (chip->timer_a_reg_load && chip->reg_sync_timer);
chip->timer_a_cnt[0] = chip->timer_a_load ? chip->reg_timer_a[1] : (!chip->timer_a_reg_load ? 0 : (time & 1023));
chip->timer_a_of[0] = (time & 1024) != 0;
chip->timer_a_reg_load_l[0] = chip->timer_a_reg_load;
int rst_a = chip->reg_timer_a_reset[1] || chip->ic;
int rst_a2 = rst_a
#ifdef FMOPNA_YM2608
|| irq_rst || (chip->reg_mask[1] & 1) != 0
#endif
;
if (rst_a2)
chip->timer_a_status[0] = 0;
else
chip->timer_a_status[0] = chip->timer_a_status[1];
chip->timer_a_status[0] |= !rst_a
#ifdef FMOPNA_YM2608
&& (chip->reg_mask[1] & 1) == 0
#endif
&& chip->reg_timer_a_enable[1] && chip->timer_a_of[1];
int subcnt = chip->timer_b_subcnt[1] + chip->reg_sync_timer;
chip->timer_b_subcnt[0] = chip->ic ? 0 : subcnt & 15;
chip->timer_b_subcnt_of[0] = (subcnt & 16) != 0;
time = chip->timer_b_cnt[1];
time += (chip->reg_test_21[1] & 4) != 0 || (chip->timer_b_reg_load && chip->timer_b_subcnt_of[1]);
chip->timer_b_cnt[0] = chip->timer_b_load ? chip->reg_timer_b[1] : (!chip->timer_b_reg_load ? 0 : (time & 255));
chip->timer_b_of[0] = (time & 256) != 0;
chip->timer_b_reg_load_l[0] = chip->timer_b_reg_load;
int rst_b = chip->reg_timer_b_reset[1] || chip->ic;
int rst_b2 = rst_b
#ifdef FMOPNA_YM2608
|| irq_rst || (chip->reg_mask[1] & 2) != 0
#endif
;
if (rst_b2)
chip->timer_b_status[0] = 0;
else
chip->timer_b_status[0] = chip->timer_b_status[1];
chip->timer_b_status[0] |= !rst_b
#ifdef FMOPNA_YM2608
&& (chip->reg_mask[1] & 2) == 0
#endif
&& chip->reg_timer_b_enable[1] && chip->timer_b_of[1];
memcpy(&chip->reg_freq[0][1], &chip->reg_freq[1][0], 5 * sizeof(unsigned short));
memcpy(&chip->reg_freq_3ch[0][1], &chip->reg_freq_3ch[1][0], 5 * sizeof(unsigned short));
memcpy(&chip->reg_connect_fb[0][1], &chip->reg_connect_fb[1][0], 5 * sizeof(unsigned char));
memcpy(&chip->reg_b4[0][1], &chip->reg_b4[1][0], 5 * sizeof(unsigned char));
#ifdef FMOPNA_YM2608
memcpy(&chip->reg_rss[0][1], &chip->reg_rss[1][0], 5 * sizeof(unsigned char));
#endif
memcpy(&chip->op_multi_dt[0][1][0], &chip->op_multi_dt[1][0][0], 11 * 2 * sizeof(unsigned char));
memcpy(&chip->op_tl[0][1][0], &chip->op_tl[1][0][0], 11 * 2 * sizeof(unsigned char));
memcpy(&chip->op_ar_ks[0][1][0], &chip->op_ar_ks[1][0][0], 11 * 2 * sizeof(unsigned char));
memcpy(&chip->op_dr_a[0][1][0], &chip->op_dr_a[1][0][0], 11 * 2 * sizeof(unsigned char));
memcpy(&chip->op_sr[0][1][0], &chip->op_sr[1][0][0], 11 * 2 * sizeof(unsigned char));
memcpy(&chip->op_rr_sl[0][1][0], &chip->op_rr_sl[1][0][0], 11 * 2 * sizeof(unsigned char));
memcpy(&chip->op_ssg[0][1][0], &chip->op_ssg[1][0][0], 11 * 2 * sizeof(unsigned char));
if (chip->ic)
{
chip->reg_a4[0] = 0;
chip->reg_freq[0][0] = 0;
chip->reg_ac[0] = 0;
chip->reg_freq_3ch[0][0] = 0;
chip->reg_connect_fb[0][0] = 0;
chip->reg_b4[0][0] = 0xc0;
#ifdef FMOPNA_YM2608
chip->reg_rss[0][0] = 0;
#endif
chip->op_multi_dt[0][0][0] = 0;
chip->op_multi_dt[0][0][1] = 0;
chip->op_tl[0][0][0] = 0;
chip->op_tl[0][0][1] = 0;
chip->op_ar_ks[0][0][0] = 0;
chip->op_ar_ks[0][0][1] = 0;
chip->op_dr_a[0][0][0] = 0;
chip->op_dr_a[0][0][1] = 0;
chip->op_sr[0][0][0] = 0;
chip->op_sr[0][0][1] = 0;
chip->op_rr_sl[0][0][0] = 0;
chip->op_rr_sl[0][0][1] = 0;
chip->op_ssg[0][0][0] = 0;
chip->op_ssg[0][0][1] = 0;
}
else
{
chip->reg_a4[0] = chip->fm_isa4 ? (chip->fm_data[1] & 0x3f) : chip->reg_a4[1];
chip->reg_freq[0][0] = chip->fm_isa0 ? (chip->fm_data[1] & 0xff) | (chip->reg_a4[1] << 8) : chip->reg_freq[1][5];
chip->reg_ac[0] = chip->fm_isac ? (chip->fm_data[1] & 0x3f) : chip->reg_ac[1];
chip->reg_freq_3ch[0][0] = chip->fm_isa8 ? (chip->fm_data[1] & 0xff) | (chip->reg_ac[1] << 8) : chip->reg_freq_3ch[1][5];
chip->reg_connect_fb[0][0] = chip->fm_isb0 ? (chip->fm_data[1] & 0x3f) : chip->reg_connect_fb[1][5];
chip->reg_b4[0][0] = chip->fm_isb4 ? (chip->fm_data[1] & 0xf7) : chip->reg_b4[1][5];
#ifdef FMOPNA_YM2608
chip->reg_rss[0][0] = chip->rss_18 ? (chip->fm_data[1] & 0xdf) : chip->reg_rss[1][5];
#endif
int bank = (chip->fm_address[1] & 8) != 0;
chip->op_multi_dt[0][0][0] = (chip->fm_is30 && !bank) ? (chip->fm_data[1] & 0x7f) : chip->op_multi_dt[1][11][0];
chip->op_multi_dt[0][0][1] = (chip->fm_is30 && bank) ? (chip->fm_data[1] & 0x7f) : chip->op_multi_dt[1][11][1];
chip->op_tl[0][0][0] = (chip->fm_is40 && !bank) ? (chip->fm_data[1] & 0x7f) : chip->op_tl[1][11][0];
chip->op_tl[0][0][1] = (chip->fm_is40 && bank) ? (chip->fm_data[1] & 0x7f) : chip->op_tl[1][11][1];
chip->op_ar_ks[0][0][0] = (chip->fm_is50 && !bank) ? (chip->fm_data[1] & 0xdf) : chip->op_ar_ks[1][11][0];
chip->op_ar_ks[0][0][1] = (chip->fm_is50 && bank) ? (chip->fm_data[1] & 0xdf) : chip->op_ar_ks[1][11][1];
chip->op_dr_a[0][0][0] = (chip->fm_is60 && !bank) ? (chip->fm_data[1] & 0x9f) : chip->op_dr_a[1][11][0];
chip->op_dr_a[0][0][1] = (chip->fm_is60 && bank) ? (chip->fm_data[1] & 0x9f) : chip->op_dr_a[1][11][1];
chip->op_sr[0][0][0] = (chip->fm_is70 && !bank) ? (chip->fm_data[1] & 0x1f) : chip->op_sr[1][11][0];
chip->op_sr[0][0][1] = (chip->fm_is70 && bank) ? (chip->fm_data[1] & 0x1f) : chip->op_sr[1][11][1];
chip->op_rr_sl[0][0][0] = (chip->fm_is80 && !bank) ? (chip->fm_data[1] & 0xff) : chip->op_rr_sl[1][11][0];
chip->op_rr_sl[0][0][1] = (chip->fm_is80 && bank) ? (chip->fm_data[1] & 0xff) : chip->op_rr_sl[1][11][1];
chip->op_ssg[0][0][0] = (chip->fm_is90 && !bank) ? (chip->fm_data[1] & 0xf) : chip->op_ssg[1][11][0];
chip->op_ssg[0][0][1] = (chip->fm_is90 && bank) ? (chip->fm_data[1] & 0xf) : chip->op_ssg[1][11][1];
}
int rst_cc = chip->ic || chip->ch_cnt_sync;
int cc_of = (chip->ch_cnt1[1] & 2) != 0;
chip->ch_cnt1[0] = (rst_cc || cc_of) ? 0 : (chip->ch_cnt1[1] + 1) & 3;
chip->ch_cnt2[0] = rst_cc ? 0 : (chip->ch_cnt2[1] + cc_of) & 7;
int cc_cnt = (chip->ch_cnt2[1] << 2) | chip->ch_cnt1[1];
int freq;
if (chip->ch3_en && cc_cnt == 1)
freq = chip->reg_freq_3ch[1][5];
else if (chip->ch3_en && cc_cnt == 9)
freq = chip->reg_freq_3ch[1][0];
else if (chip->ch3_en && cc_cnt == 17)
freq = chip->reg_freq_3ch[1][4];
else
freq = chip->reg_freq[1][4];
chip->fnum[0] = freq & 0x7ff;
chip->kcode[0] = ((freq >> 11) & 7) << 2;
if (freq & 0x400)
{
chip->kcode[0] |= 2;
if ((freq & 0x380) != 0)
chip->kcode[0] |= 1;
}
else
{
if ((freq & 0x380) == 0x380)
chip->kcode[0] |= 1;
}
chip->fnum[2] = chip->fnum[1];
chip->kcode[2] = chip->kcode[1];
}
if (chip->clk2)
{
chip->fm_address[1] = chip->fm_address[0];
chip->write_fm_address[1] = chip->write_fm_address[0];
chip->fm_data[1] = chip->fm_data[0];
chip->write_fm_data[1] = chip->write_fm_data[0];
chip->addr_21[1] = chip->addr_21[0];
chip->addr_22[1] = chip->addr_22[0];
chip->addr_24[1] = chip->addr_24[0];
chip->addr_25[1] = chip->addr_25[0];
chip->addr_26[1] = chip->addr_26[0];
chip->addr_27[1] = chip->addr_27[0];
chip->addr_28[1] = chip->addr_28[0];
#ifdef FMOPNA_YM2608
chip->addr_10[1] = chip->addr_10[0];
chip->addr_10h[1] = chip->addr_10h[0];
chip->addr_12[1] = chip->addr_12[0];
chip->addr_29[1] = chip->addr_29[0];
chip->addr_ff[1] = chip->addr_ff[0];
#endif
#ifdef FMOPNA_YM2610
chip->addr_00[1] = chip->addr_00[0];
chip->addr_02[1] = chip->addr_02[0];
chip->addr_1c[1] = chip->addr_1c[0];
#endif
#ifdef FMOPNA_YM2612
chip->addr_2a[1] = chip->addr_2a[0];
chip->addr_2b[1] = chip->addr_2b[0];
chip->addr_2c[1] = chip->addr_2c[0];
#endif
#ifdef FMOPNA_YM2608
chip->reg_mask[1] = chip->reg_mask[0];
chip->reg_sch[1] = chip->reg_sch[0];
chip->reg_irq[1] = chip->reg_irq[0];
chip->reg_test_12[1] = chip->reg_test_12[0];
#endif
#ifdef FMOPNA_YM2610
chip->reg_flags[1] = chip->reg_flags[0];
chip->reg_test_12[1] = chip->reg_test_12[0];
#endif
#ifdef FMOPNA_YM2612
chip->reg_dac_en[1] = chip->reg_dac_en[0];
chip->reg_dac_data[1] = chip->reg_dac_data[0];
chip->reg_test_2c[1] = chip->reg_test_2c[0];
#endif
chip->reg_test_21[1] = chip->reg_test_21[0];
chip->reg_lfo[1] = chip->reg_lfo[0];
chip->reg_timer_a[1] = chip->reg_timer_a[0];
chip->reg_timer_b[1] = chip->reg_timer_b[0];
chip->reg_ch3[1] = chip->reg_ch3[0];
chip->reg_timer_a_load[1] = chip->reg_timer_a_load[0];
chip->reg_timer_b_load[1] = chip->reg_timer_b_load[0];
chip->reg_timer_a_enable[1] = chip->reg_timer_a_enable[0];
chip->reg_timer_b_enable[1] = chip->reg_timer_b_enable[0];
chip->reg_timer_a_reset[1] = chip->reg_timer_a_reset[0];
chip->reg_timer_b_reset[1] = chip->reg_timer_b_reset[0];
chip->reg_kon_operator[1] = chip->reg_kon_operator[0];
chip->reg_kon_channel[1] = chip->reg_kon_channel[0];
int op_match = chip->write_fm_data[0] && (chip->reg_cnt1[0] == (chip->fm_address[0] & 3))
&& (chip->reg_cnt2[0] & 1) == ((chip->fm_address[0] >> 8) & 1)
&& ((chip->reg_cnt2[0] >> 1) & 1) == ((chip->fm_address[0] >> 2) & 1);
int ch_match = chip->write_fm_data[0] && (chip->reg_cnt1[0] == (chip->fm_address[0] & 3))
&& (chip->reg_cnt2[0] & 1) == ((chip->fm_address[0] >> 8) & 1);
chip->fm_is30 = op_match && (chip->fm_address[0] & 0xf0) == 0x30;
chip->fm_is40 = op_match && (chip->fm_address[0] & 0xf0) == 0x40;
chip->fm_is50 = op_match && (chip->fm_address[0] & 0xf0) == 0x50;
chip->fm_is60 = op_match && (chip->fm_address[0] & 0xf0) == 0x60;
chip->fm_is70 = op_match && (chip->fm_address[0] & 0xf0) == 0x70;
chip->fm_is80 = op_match && (chip->fm_address[0] & 0xf0) == 0x80;
chip->fm_is90 = op_match && (chip->fm_address[0] & 0xf0) == 0x90;
chip->fm_isa0 = ch_match && (chip->fm_address[0] & 0xfc) == 0xa0;
chip->fm_isa4 = ch_match && (chip->fm_address[0] & 0xfc) == 0xa4;
chip->fm_isa8 = ch_match && (chip->fm_address[0] & 0xfc) == 0xa8;
chip->fm_isac = ch_match && (chip->fm_address[0] & 0xfc) == 0xac;
chip->fm_isb0 = ch_match && (chip->fm_address[0] & 0xfc) == 0xb0;
chip->fm_isb4 = ch_match && (chip->fm_address[0] & 0xfc) == 0xb4;
chip->reg_cnt1[1] = chip->reg_cnt1[0];
chip->reg_cnt2[1] = chip->reg_cnt2[0];
chip->reg_cnt_sync = chip->fsm_sel23[1];
#ifdef FMOPNA_YM2608
chip->reg_cnt_rss[1] = chip->reg_cnt_rss[0];
chip->reg_cnt_rss_of = (chip->reg_cnt_rss[0] & 11) == 11;
chip->rss_18 = chip->write_fm_data[0]
&& chip->reg_cnt_rss[0] == (chip->fm_address[0] & 7) && (chip->fm_address[0] & 6) != 6
&& (chip->fm_address[0] & 0x1f8) == 0x18;
#endif
chip->reg_kon_match = chip->reg_key_cnt1[0] == (chip->reg_kon_channel[0] & 3)
&& chip->reg_key_cnt2[0] == (((chip->reg_kon_channel[0] >> 2) & 1)
#ifdef FMOPNA_YM2608
&& chip->reg_sch[0]
#endif
)
#ifdef FMOPNA_YM2610
// tildearrow: changed to allow YM2610B emulation
&& (chip->ym2610b || (chip->reg_kon_channel[0] & 3) != 0)
#endif
;
chip->reg_key_cnt1[1] = chip->reg_key_cnt1[0];
chip->reg_key_cnt2[1] = chip->reg_key_cnt2[0];
chip->reg_kon[0][1] = chip->reg_kon[0][0];
chip->reg_kon[1][1] = chip->reg_kon[1][0];
chip->reg_kon[2][1] = chip->reg_kon[2][0];
chip->reg_kon[3][1] = chip->reg_kon[3][0];
chip->reg_ch3_sel = chip->fsm_sel_ch3[1];
chip->ch3_en = chip->reg_ch3[0] != 0;
chip->ch3_csm = chip->reg_ch3[0] == 2;
chip->timer_a_cnt[1] = chip->timer_a_cnt[0];
chip->timer_a_of[1] = chip->timer_a_of[0];
chip->reg_sync_timer = chip->fsm_sel1[1];
chip->reg_sync_timer_l[1] = chip->reg_sync_timer_l[0];
chip->timer_a_reg_load_l[1] = chip->timer_a_reg_load_l[0];
chip->reg_sync_timer_load = chip->reg_sync_timer_l[0] && chip->reg_sync_timer_l[1];
if (chip->reg_sync_timer_load)
{
chip->timer_a_reg_load = chip->reg_timer_a_load[1];
chip->timer_b_reg_load = chip->reg_timer_b_load[1];
}
chip->timer_a_load = chip->timer_a_of[1] || (!chip->timer_a_reg_load_l[1] && chip->timer_a_reg_load);
if (chip->reg_sync_timer_load)
{
chip->ch3_csm_load = chip->ch3_csm && chip->timer_a_load;
}
chip->kon_comb = (chip->reg_kon[3][1] >> 5) & 1;
chip->kon_comb |= chip->reg_ch3_sel && chip->ch3_csm_load;
chip->timer_a_status[1] = chip->timer_a_status[0];
chip->timer_b_subcnt[1] = chip->timer_b_subcnt[0];
chip->timer_b_subcnt_of[1] = chip->timer_b_subcnt_of[0];
chip->timer_b_cnt[1] = chip->timer_b_cnt[0];
chip->timer_b_of[1] = chip->timer_b_of[0];
chip->timer_b_reg_load_l[1] = chip->timer_b_reg_load_l[0];
chip->timer_b_load = chip->timer_b_of[1] || (!chip->timer_b_reg_load_l[1] && chip->timer_b_reg_load);
chip->timer_b_status[1] = chip->timer_b_status[0];
#ifndef FMOPNA_YM2612
chip->irq_eos_l = chip->eos_repeat;
#endif
memcpy(&chip->reg_freq[1][0], &chip->reg_freq[0][0], 6 * sizeof(unsigned short));
memcpy(&chip->reg_freq_3ch[1][0], &chip->reg_freq_3ch[0][0], 6 * sizeof(unsigned short));
memcpy(&chip->reg_connect_fb[1][0], &chip->reg_connect_fb[0][0], 6 * sizeof(unsigned char));
memcpy(&chip->reg_b4[1][0], &chip->reg_b4[0][0], 6 * sizeof(unsigned char));
#ifdef FMOPNA_YM2608
memcpy(&chip->reg_rss[1][0], &chip->reg_rss[0][0], 6 * sizeof(unsigned char));
#endif
memcpy(&chip->op_multi_dt[1][0][0], &chip->op_multi_dt[0][0][0], 12 * 2 * sizeof(unsigned char));
memcpy(&chip->op_tl[1][0][0], &chip->op_tl[0][0][0], 12 * 2 * sizeof(unsigned char));
memcpy(&chip->op_ar_ks[1][0][0], &chip->op_ar_ks[0][0][0], 12 * 2 * sizeof(unsigned char));
memcpy(&chip->op_dr_a[1][0][0], &chip->op_dr_a[0][0][0], 12 * 2 * sizeof(unsigned char));
memcpy(&chip->op_sr[1][0][0], &chip->op_sr[0][0][0], 12 * 2 * sizeof(unsigned char));
memcpy(&chip->op_rr_sl[1][0][0], &chip->op_rr_sl[0][0][0], 12 * 2 * sizeof(unsigned char));
memcpy(&chip->op_ssg[1][0][0], &chip->op_ssg[0][0][0], 12 * 2 * sizeof(unsigned char));
chip->reg_a4[1] = chip->reg_a4[0];
chip->reg_ac[1] = chip->reg_ac[0];
chip->ch_cnt_sync = chip->fsm_sel23[1];
chip->ch_cnt1[1] = chip->ch_cnt1[0];
chip->ch_cnt2[1] = chip->ch_cnt2[0];
chip->fnum[1] = chip->fnum[0];
chip->fnum[3] = chip->fnum[2];
chip->kcode[1] = chip->kcode[0];
chip->kcode[3] = chip->kcode[2];
}
#ifdef FMOPNA_YM2608
{
int write10 = chip->addr_10h[1] && (chip->data_bus1 & 0x100) != 0 && chip->write1_en;
int irq_rst = write10 && (chip->data_bus2 & 0x80) == 0;
chip->irq_mask_eos = (chip->reg_mask[1] & 4) != 0 || chip->irq_eos_l || irq_rst;
chip->irq_mask_brdy = (chip->reg_mask[1] & 8) != 0 || irq_rst;
chip->irq_mask_zero = (chip->reg_mask[1] & 16) != 0 || irq_rst;
}
#endif
}
{
if (chip->clk1)
{
int fsm_cnt;
int of1 = (chip->fsm_cnt1[1] & 2) != 0;
chip->fsm_cnt1[0] = (chip->ic_check3 || of1) ? 0 : (chip->fsm_cnt1[1] + 1) & 3;
chip->fsm_cnt2[0] = chip->ic_check3 ? 0 : (chip->fsm_cnt2[1] + of1) & 7;
fsm_cnt = (chip->fsm_cnt2[0] << 2) | chip->fsm_cnt1[0];
chip->fsm_out[0] = (fsm_cnt & 30) == 30;
chip->fsm_out[1] = (fsm_cnt & 28) == 0;
chip->fsm_out[2] = (fsm_cnt & 30) == 4;
chip->fsm_out[3] = (fsm_cnt & 30) == 22;
chip->fsm_out[4] = (fsm_cnt & 28) == 24;
chip->fsm_out[5] = (fsm_cnt & 30) == 28;
chip->fsm_out[6] = (fsm_cnt & 30) == 14;
chip->fsm_out[7] = (fsm_cnt & 28) == 16;
chip->fsm_out[8] = (fsm_cnt & 30) == 20;
chip->fsm_out[9] = (fsm_cnt & 30) == 6;
chip->fsm_out[10] = (fsm_cnt & 28) == 8;
chip->fsm_out[11] = (fsm_cnt & 30) == 12;
chip->fsm_out[12] = (fsm_cnt & 30) == 30;
chip->fsm_out[13] = fsm_cnt == 0;
chip->fsm_out[14] = fsm_cnt == 1;
#ifndef FMOPNA_YM2612
chip->fsm_out[15] = fsm_cnt == 13;
#endif
chip->fsm_out[16] = fsm_cnt == 29;
chip->fsm_out[17] = (fsm_cnt & 7) == 1;
chip->fsm_out[18] = (fsm_cnt & 28) == 4;
chip->fsm_out[19] = fsm_cnt == 8;
#ifndef FMOPNA_YM2612
chip->fsm_out[20] = (fsm_cnt & 28) == 20;
chip->fsm_out[21] = fsm_cnt == 24;
#endif
#ifdef FMOPNA_YM2612
chip->fsm_out[20] = (fsm_cnt & 15) == 14;
chip->fsm_out[21] = (fsm_cnt & 15) == 4;
chip->fsm_out[22] = (fsm_cnt & 15) == 9;
chip->fsm_out[23] = fsm_cnt == 14;
chip->fsm_out[24] = (fsm_cnt & 24) == 16;
chip->fsm_out[25] = (fsm_cnt & 28) == 24;
chip->fsm_out[26] = (fsm_cnt & 30) == 28;
#endif
chip->alg_mod_op1_0_l = 0;
chip->alg_mod_op1_1_l = 0;
chip->alg_mod_op2_l = 0;
chip->alg_mod_prev_0_l = 0;
chip->alg_mod_prev_1_l = 0;
chip->alg_output_l = 0;
if (chip->fsm_op2_sel_l)
{
chip->alg_mod_op1_0_l |= fm_algorithm[0][0][chip->fsm_connect];
chip->alg_mod_op1_1_l |= fm_algorithm[0][1][chip->fsm_connect];
chip->alg_mod_op2_l |= fm_algorithm[0][2][chip->fsm_connect];
chip->alg_mod_prev_0_l |= fm_algorithm[0][3][chip->fsm_connect];
chip->alg_mod_prev_1_l |= fm_algorithm[0][4][chip->fsm_connect];
chip->alg_output_l |= fm_algorithm[2][5][chip->fsm_connect];
}
if (chip->fsm_op4_sel_l)
{
chip->alg_mod_op1_0_l |= fm_algorithm[1][0][chip->fsm_connect];
chip->alg_mod_op1_1_l |= fm_algorithm[1][1][chip->fsm_connect];
chip->alg_mod_op2_l |= fm_algorithm[1][2][chip->fsm_connect];
chip->alg_mod_prev_0_l |= fm_algorithm[1][3][chip->fsm_connect];
chip->alg_mod_prev_1_l |= fm_algorithm[1][4][chip->fsm_connect];
chip->alg_output_l |= fm_algorithm[3][5][chip->fsm_connect];
}
if (chip->fsm_op1_sel_l)
{
chip->alg_mod_op1_0_l |= fm_algorithm[2][0][chip->fsm_connect];
chip->alg_mod_op1_1_l |= fm_algorithm[2][1][chip->fsm_connect];
chip->alg_mod_op2_l |= fm_algorithm[2][2][chip->fsm_connect];
chip->alg_mod_prev_0_l |= fm_algorithm[2][3][chip->fsm_connect];
chip->alg_mod_prev_1_l |= fm_algorithm[2][4][chip->fsm_connect];
chip->alg_output_l |= fm_algorithm[0][5][chip->fsm_connect];
}
if (chip->fsm_op3_sel_l)
{
chip->alg_mod_op1_0_l |= fm_algorithm[3][0][chip->fsm_connect];
chip->alg_mod_op1_1_l |= fm_algorithm[3][1][chip->fsm_connect];
chip->alg_mod_op2_l |= fm_algorithm[3][2][chip->fsm_connect];
chip->alg_mod_prev_0_l |= fm_algorithm[3][3][chip->fsm_connect];
chip->alg_mod_prev_1_l |= fm_algorithm[3][4][chip->fsm_connect];
chip->alg_output_l |= fm_algorithm[1][5][chip->fsm_connect];
}
chip->alg_do_fb[1] = chip->alg_do_fb[0];
chip->alg_load_fb = chip->fsm_op1_sel_l;
chip->fsm_sel0[1] = chip->fsm_sel0[0];
chip->fsm_sel1[1] = chip->fsm_sel1[0];
chip->fsm_sel2[1] = chip->fsm_sel2[0];
chip->fsm_sel23[1] = chip->fsm_sel23[0];
chip->fsm_sel_ch3[1] = chip->fsm_sel_ch3[0];
#ifndef FMOPNA_YM2612
chip->fsm_sel11[1] = chip->fsm_sel11[0];
chip->fsm_sh1[1] = chip->fsm_sh1[0];
chip->fsm_sh2[1] = chip->fsm_sh2[0];
chip->fsm_rss2 = !chip->fsm_out[16] && !chip->fsm_sel23[1];
#endif
#ifdef FMOPNA_YM2612
chip->fsm_dac_ch6[1] = chip->fsm_dac_ch6[0];
chip->fsm_dac_load[1] = chip->fsm_dac_load[0];
chip->fsm_dac_out_sel[1] = chip->fsm_dac_out_sel[0];
#endif
}
if (chip->clk2)
{
chip->fsm_cnt1[1] = chip->fsm_cnt1[0];
chip->fsm_cnt2[1] = chip->fsm_cnt2[0];
chip->fsm_op4_sel_l = chip->fsm_out[0] || chip->fsm_out[1] || chip->fsm_out[2];
chip->fsm_op2_sel_l = chip->fsm_out[3] || chip->fsm_out[4] || chip->fsm_out[5];
chip->fsm_op3_sel_l = chip->fsm_out[6] || chip->fsm_out[7] || chip->fsm_out[8];
chip->fsm_op1_sel_l = chip->fsm_out[9] || chip->fsm_out[10] || chip->fsm_out[11];
chip->fsm_connect = chip->reg_connect_fb[0][4] & 7;
chip->alg_do_fb[0] = chip->alg_mod_op1_1_l;
chip->fsm_sel0[0] = chip->fsm_out[12];
chip->fsm_sel1[0] = chip->fsm_out[13];
chip->fsm_sel2[0] = chip->fsm_out[14];
chip->fsm_sel23[0] = chip->fsm_out[16];
chip->fsm_sel_ch3[0] = chip->fsm_out[17];
#ifndef FMOPNA_YM2612
chip->fsm_sel11[0] = chip->fsm_out[15];
chip->fsm_sh1[0] = chip->fsm_out[18] || chip->fsm_out[19];
chip->fsm_sh2[0] = chip->fsm_out[20] || chip->fsm_out[21];
chip->fsm_rss = (chip->fsm_cnt2[0] & 2) != 0;
#endif
#ifdef FMOPNA_YM2612
chip->fsm_dac_ch6[0] = chip->fsm_out[18] || chip->fsm_out[19];
chip->fsm_dac_load[0] = chip->fsm_out[20] || chip->fsm_out[21] || chip->fsm_out[22];
chip->fsm_dac_out_sel[0] = chip->fsm_out[23] || chip->fsm_out[24] || chip->fsm_out[25] || chip->fsm_out[26];
#endif
}
}
{
if (chip->clk1)
{
int inc = chip->lfo_sync[0]
#ifndef FMOPNA_YM2610
|| (chip->reg_test_21[1] & 2) != 0
#endif
;
int subcnt_rst = chip->ic || chip->lfo_subcnt_of;
chip->lfo_subcnt[0] = subcnt_rst ? 0 : (chip->lfo_subcnt[1] + inc) & 127;
int cnt = chip->lfo_cnt[1] + chip->lfo_subcnt_of;
#ifdef FMOPNA_YM2608
chip->lfo_cnt_of = (cnt & 128) != 0 && chip->lfo_mode;
#endif
chip->lfo_cnt[0] = chip->lfo_cnt_rst ? 0 : cnt & 127;
chip->lfo_sync[1] = chip->lfo_sync[0];
chip->lfo_sync[3] = chip->lfo_sync[2];
// LFO shift
static const int 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 }
};
#if 0
// YM2608/YM2610 decap, doesn't match YM2608 nor YM2610 hardware tests though
static const int 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, 2, 2, 7, 7, 2, 2, 7 },
{ 7, 2, 7, 2, 7, 2, 2, 1 },
{ 7, 2, 7, 2, 7, 2, 2, 1 },
{ 7, 2, 7, 2, 7, 2, 2, 1 }
};
#endif
#if 1
// YM2612/YM3438 decap, matches to YM2608 and YM2610 hardware tests O_O
static const int 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 }
};
#endif
int pms = chip->reg_b4[1][5] & 7;
int lfo = (chip->lfo_cnt_load >> 2) & 7;
if (chip->lfo_cnt_load & 32)
lfo ^= 7;
int fnum_h = chip->fnum[1] >> 4;
chip->lfo_fnum1 = fnum_h >> pg_lfo_sh1[pms][lfo];
chip->lfo_fnum2 = fnum_h >> pg_lfo_sh2[pms][lfo];
chip->lfo_shift = 2;
if (pms > 5)
chip->lfo_shift = 7 - pms;
chip->lfo_sign = (chip->lfo_cnt_load >> 6) & 1;
chip->lfo_fnum = ((chip->fnum[3] << 1) + chip->lfo_pm) & 0xfff;
}
if (chip->clk2)
{
static const int lfo_cycles[8] = {
108, 77, 71, 67, 62, 44, 8, 5
};
chip->lfo_sync[0] = chip->fsm_sel23[1];
chip->lfo_sync[2] = chip->lfo_sync[1];
chip->lfo_subcnt[1] = chip->lfo_subcnt[0];
int of = (chip->lfo_subcnt[0] & lfo_cycles[chip->reg_lfo[0] & 7]) == lfo_cycles[chip->reg_lfo[0] & 7];
#ifdef FMOPNA_YM2608
chip->lfo_mode = chip->ad_sample_l[2] || (chip->ad_reg_rec && chip->ad_start_l[1]);
chip->lfo_subcnt_of = chip->lfo_mode ? (chip->lfo_subcnt[0] & 127) == 127 : of;
chip->lfo_cnt_rst = chip->lfo_mode ? chip->ad_ad_quiet : (chip->reg_lfo[0] & 8) == 0;
#else
chip->lfo_subcnt_of = of;
chip->lfo_cnt_rst = (chip->reg_lfo[0] & 8) == 0;
#endif
chip->lfo_cnt[1] = chip->lfo_cnt[0];
if (!chip->lfo_sync[3] && chip->lfo_sync[2])
{
chip->lfo_cnt_load = chip->lfo_cnt[1];
}
if (chip->lfo_cnt_load & 64)
chip->lfo_am = chip->lfo_cnt_load & 63;
else
chip->lfo_am = (chip->lfo_cnt_load & 63) ^ 63;
chip->lfo_pm = (chip->lfo_fnum1 + chip->lfo_fnum2) >> chip->lfo_shift;
if (chip->lfo_sign)
chip->lfo_pm = -chip->lfo_pm;
}
}
{
if (chip->clk1)
{
chip->pg_block = chip->kcode[3] >> 2;
chip->pg_dt_multi = (chip->reg_key_cnt2[1] & 4) == 0 ? chip->op_multi_dt[1][11][0]
: chip->op_multi_dt[1][11][1];
chip->dt_note[1] = chip->dt_note[0];
chip->dt_blockmax[1] = chip->dt_blockmax[0];
chip->dt_enable[1] = chip->dt_enable[0];
chip->dt_sign[1] = chip->dt_sign[0];
chip->dt_sum = chip->dt_add1 + chip->dt_add2 + 1;
chip->pg_freqdt[0] = (chip->pg_freq + chip->pg_dt_add) & 0x1ffff;
chip->pg_multi[1] = chip->pg_multi[0];
chip->pg_multi[3] = chip->pg_multi[2];
chip->pg_add[0] = chip->pg_multi[4] ? chip->pg_freqdt[1] * chip->pg_multi[4] :
(chip->pg_freqdt[1] >> 1);
chip->pg_add[2] = chip->pg_add[1];
chip->pg_add[4] = chip->pg_add[3];
chip->pg_reset[1] = chip->pg_reset[0];
chip->pg_reset[3] = chip->pg_reset[2];
memcpy(&chip->pg_phase[0][1], &chip->pg_phase[1][0], 22 * sizeof(int));
chip->pg_phase2[0] = chip->pg_phase[1][22];
chip->pg_phase[0][0] = (chip->pg_phase2[1] + chip->pg_add[5]) & 0xfffff;
chip->pg_dbg[0] = chip->pg_dbg[1] >> 1;
if (chip->pg_dbgsync)
chip->pg_dbg[0] |= chip->pg_phase[1][22] & 1023;
#ifdef FMOPNA_YM2610
chip->pg_dbgsync_l[1] = chip->pg_dbgsync_l[0];
#endif
}
if (chip->clk2)
{
chip->pg_freq = (chip->lfo_fnum << chip->pg_block) >> 2;
chip->dt_note[0] = chip->kcode[2] & 3;
chip->dt_blockmax[0] = (chip->kcode[2] & 28) == 28;
chip->dt_add1 = (chip->kcode[2] >> 2) & 7;
if ((chip->pg_dt_multi & 0x30) != 0)
chip->dt_add1 |= 8;
chip->dt_add2 = 0;
if ((chip->pg_dt_multi & 0x30) == 0x30)
chip->dt_add2 |= 1;
if (chip->pg_dt_multi & 0x20)
chip->dt_add2 |= 2;
chip->dt_enable[0] = (chip->pg_dt_multi & 0x30) != 0;
chip->dt_sign[0] = (chip->pg_dt_multi & 0x40) != 0;
int dt_l = (chip->dt_sum & 1) << 2;
if (!chip->dt_blockmax[1])
dt_l |= chip->dt_note[1];
int dt_h = chip->dt_sum >> 1;
static const int pg_detune[8] = { 16, 17, 19, 20, 22, 24, 27, 29 };
int dt_freq = pg_detune[dt_l] >> (9 - dt_h);
if (chip->dt_sign[1])
dt_freq = -dt_freq;
chip->pg_dt_add = dt_freq;
chip->pg_multi[0] = chip->pg_dt_multi & 15;
chip->pg_multi[2] = chip->pg_multi[1];
chip->pg_multi[4] = chip->pg_multi[3];
chip->pg_freqdt[1] = chip->pg_freqdt[0];
chip->pg_add[1] = chip->pg_add[0];
chip->pg_add[3] = chip->pg_reset[1] ? 0 : chip->pg_add[2];
chip->pg_add[5] = chip->pg_add[4];
chip->pg_reset[0] = (chip->eg_pg_reset[0] & 2) != 0;
chip->pg_reset[2] = chip->pg_reset[1];
memcpy(&chip->pg_phase[1][0], &chip->pg_phase[0][0], 23 * sizeof(int));
chip->pg_out = chip->pg_phase[1][18] >> 10;
chip->pg_phase2[1] = chip->pg_reset[3] ? 0 : chip->pg_phase2[0];
#ifdef FMOPNA_YM2610
chip->pg_dbgsync_l[0] = chip->fsm_sel2[1];
chip->pg_dbgsync = chip->pg_dbgsync_l[1];
#else
chip->pg_dbgsync = chip->fsm_sel2[1];
#endif
chip->pg_dbg[1] = chip->pg_dbg[0];
}
}
{
if (chip->clk1)
{
chip->eg_prescaler_clock_l[0] = chip->eg_sync;
chip->eg_prescaler[0] = (chip->eg_prescaler[1] + chip->eg_sync) & 3;
if (((chip->eg_prescaler[1] & 2) != 0 && chip->eg_sync) || chip->ic)
chip->eg_prescaler[0] = 0;
chip->eg_step[0] = chip->eg_prescaler[1] >> 1;
chip->eg_step[2] = chip->eg_step[1];
chip->eg_timer_step[1] = chip->eg_timer_step[0];
chip->eg_ic[0] = chip->ic;
chip->eg_clock_delay[0] = (chip->eg_clock_delay[1] << 1) | chip->eg_prescaler_clock_l[1];
int sum = (chip->eg_timer[1] >> 10) & 1;
int add = chip->eg_timer_carry[1];
if ((chip->eg_prescaler[1] & 2) != 0 && chip->eg_prescaler_clock_l[1])
add = 1;
sum += add;
chip->eg_timer[0] = (chip->eg_timer[1] << 1) | chip->eg_timer_sum[1];
chip->eg_timer_carry[0] = sum >> 1;
chip->eg_timer_sum[0] = sum & 1;
chip->eg_timer_test = (chip->reg_test_21[1] & 32) != 0;
chip->eg_timer_test_bit[0] = chip->input.test;
int timer_bit = chip->eg_timer_sum[1] ||
(!chip->eg_timer_test_bit[1]
#ifdef FMOPNA_YM2612
&& (chip->reg_test_2c[1] & 64) != 0
#endif
);
chip->eg_timer_mask[0] = timer_bit | chip->eg_timer_mask[1];
if (chip->eg_prescaler_clock_l[1] || ((chip->eg_clock_delay[1] >> 11) & 1) != 0 || chip->eg_ic[1])
chip->eg_timer_mask[0] = 0;
int timer_bit_masked = timer_bit && !chip->eg_timer_mask[1];
chip->eg_timer_masked[0] = (chip->eg_timer_masked[1] << 1) | timer_bit_masked;
if (chip->eg_timer_step[0] && chip->eg_timer_step[1])
{
int b0, b1, b2, b3;
b0 = (chip->eg_timer[0] >> 11) & 1;
b1 = (chip->eg_timer[0] >> 10) & 1;
chip->eg_timer_low_lock = b1 * 2 + b0;
b0 = (chip->eg_timer_masked[0] & 0xaaa) != 0;
b1 = (chip->eg_timer_masked[0] & 0x666) != 0;
b2 = (chip->eg_timer_masked[0] & 0x1e1) != 0;
b3 = (chip->eg_timer_masked[0] & 0x1f) != 0;
chip->eg_shift_lock = b3 * 8 + b2 * 4 + b1 * 2 + b0;
}
int bank = (chip->reg_key_cnt2[1] & 4) != 0;
chip->eg_rate_ar = chip->op_ar_ks[1][11][bank] & 0x1f;
chip->eg_ks = (chip->op_ar_ks[1][11][bank] >> 6) & 3;
chip->eg_rate_dr = chip->op_dr_a[1][11][bank] & 0x1f;
chip->eg_rate_sr = chip->op_sr[1][11][bank] & 0x1f;
chip->eg_rate_rr = chip->op_rr_sl[1][11][bank] & 0xf;
chip->eg_rate_nonzero[1] = chip->eg_rate_nonzero[0];
chip->eg_rate2 = (chip->eg_rate << 1) + chip->eg_ksv;
chip->eg_maxrate[1] = chip->eg_maxrate[0];
int inc1 = 0;
if (chip->eg_rate_slow && chip->eg_rate_nonzero[2])
{
switch (chip->eg_rate_sum)
{
case 12:
inc1 = chip->eg_ratenz;
break;
case 13:
inc1 = (chip->eg_rate_low >> 1) & 1;
break;
case 14:
inc1 = chip->eg_rate_low & 1;
break;
}
}
chip->eg_incsh0[0] = inc1;
chip->eg_incsh3[0] = chip->eg_rate15;
if (!chip->eg_inc2)
{
chip->eg_incsh0[0] |= chip->eg_rate12;
chip->eg_incsh1[0] = chip->eg_rate13;
chip->eg_incsh2[0] = chip->eg_rate14;
}
else
{
chip->eg_incsh1[0] = chip->eg_rate12;
chip->eg_incsh2[0] = chip->eg_rate13;
chip->eg_incsh3[0] |= chip->eg_rate14;
}
chip->eg_kon_latch[0] = (chip->eg_kon_latch[1] << 1) | chip->kon_comb;
int csm_kon = chip->reg_ch3_sel && chip->ch3_csm_load;
chip->eg_kon_csm[0] = (chip->eg_kon_csm[1] << 1) | csm_kon;
int kon = (chip->eg_kon_latch[1] >> 1) & 1;
int okon = (chip->eg_key[1] >> 23) & 1;
int pg_reset = (kon && !okon) || (chip->eg_ssg_pgreset[1] & 2) != 0;
chip->eg_pg_reset[0] = (chip->eg_pg_reset[1] << 1) | pg_reset;
chip->eg_kon_event = (kon && !okon) || (okon && (chip->eg_ssg_egrepeat[1] & 2) != 0);
chip->eg_key[0] = (chip->eg_key[1] << 1) | kon;
int okon2 = (chip->eg_key[1] >> 21) & 1;
chip->eg_ssg_sign[0] = (chip->eg_level[1][18] & 0x200) != 0;
int ssg_eg = chip->op_ssg[1][11][bank] & 15;
int ssg_enable = (ssg_eg & 8) != 0;
chip->eg_ssg_enable[0] = (chip->eg_ssg_enable[1] << 1) | ssg_enable;
int ssg_inv_e = ssg_enable && (ssg_eg & 4) != 0;
int ssg_holdup = ssg_enable && ((ssg_eg & 7) == 3 || (ssg_eg & 7) == 5) && chip->kon_comb;
chip->eg_ssg_holdup[0] = (chip->eg_ssg_holdup[1] << 1) | ssg_holdup;
int ssg_pgreset = ssg_enable && chip->eg_ssg_sign[1] && (ssg_eg & 3) == 0;
chip->eg_ssg_pgreset[0] = (chip->eg_ssg_pgreset[1] << 1) | ssg_pgreset;
int ssg_egrepeat = ssg_enable && chip->eg_ssg_sign[1] && (ssg_eg & 1) == 0;
chip->eg_ssg_egrepeat[0] = (chip->eg_ssg_egrepeat[1] << 1) | ssg_egrepeat;
chip->eg_rate_sel = (okon2 ? ssg_egrepeat : chip->kon_comb) ? eg_state_attack : chip->eg_state[1][20];
int ssg_odir = (chip->eg_ssg_dir[1] >> 23) & 1;
int ssg_dir = ssg_enable && okon2 &&
((ssg_odir ^ ((ssg_eg & 3) == 2 && chip->eg_ssg_sign[1])) || ((ssg_eg & 3) == 3 && chip->eg_ssg_sign[1]));
chip->eg_ssg_dir[0] = (chip->eg_ssg_dir[1] << 1) | ssg_dir;
int ssg_inv = okon2 && (ssg_odir ^ ssg_inv_e);
chip->eg_ssg_inv = ssg_inv;
chip->eg_level_ssg[0] = chip->eg_output;
int eg_output = chip->eg_output;
if (chip->reg_test_21[1] & 32)
eg_output = 0;
int sl = (chip->op_rr_sl[1][11][bank] >> 4) & 15;
if (sl == 15)
sl |= 16;
chip->eg_sl[0][0] = sl;
chip->eg_sl[1][0] = chip->eg_sl[0][1];
chip->eg_tl[0][0] = chip->op_tl[1][11][bank];
chip->eg_tl[1][0] = chip->eg_tl[0][1];
chip->eg_tl[2][0] = chip->eg_tl[1][1];
int level = (okon && !kon) ? chip->eg_level_ssg[1] : chip->eg_level[1][21];
chip->eg_off = (chip->eg_ssg_enable[1] & 2) != 0 ? (level & 512) != 0 : (level & 0x3f0) == 0x3f0;
chip->eg_slreach = (level >> 4) == (chip->eg_sl[1][1] << 1);
chip->eg_zeroreach = level == 0;
chip->eg_level_l[0] = level;
chip->eg_state_l = chip->eg_state[1][22];
memcpy(&chip->eg_state[0][1], &chip->eg_state[1][0], 22 * sizeof(unsigned char));
chip->eg_state[0][0] = chip->eg_nextstate;
int inc_total = 0;
if (chip->eg_exp)
{
if (chip->eg_incsh0[1])
inc_total |= ~chip->eg_level_l[1] >> 4;
if (chip->eg_incsh1[1])
inc_total |= ~chip->eg_level_l[1] >> 3;
if (chip->eg_incsh2[1])
inc_total |= ~chip->eg_level_l[1] >> 2;
if (chip->eg_incsh3[1])
inc_total |= ~chip->eg_level_l[1] >> 1;
}
if (chip->eg_linear)
{
if (chip->eg_ssg_enable[1] & 4)
{
if (chip->eg_incsh0[1])
inc_total |= 4;
if (chip->eg_incsh1[1])
inc_total |= 8;
if (chip->eg_incsh2[1])
inc_total |= 16;
if (chip->eg_incsh3[1])
inc_total |= 32;
}
else
{
if (chip->eg_incsh0[1])
inc_total |= 1;
if (chip->eg_incsh1[1])
inc_total |= 2;
if (chip->eg_incsh2[1])
inc_total |= 4;
if (chip->eg_incsh3[1])
inc_total |= 8;
}
}
chip->eg_inc_total = inc_total;
int nextlevel = 0;
if (!chip->eg_istantattack)
nextlevel |= chip->eg_level_l[1];
if (chip->eg_kon_csm[1] & 4)
nextlevel |= chip->eg_tl[2][1] << 3;
if (chip->eg_mute || chip->ic)
nextlevel |= 0x3ff;
chip->eg_nextlevel[0] = nextlevel;
memcpy(&chip->eg_level[0][1], &chip->eg_level[1][0], 21 * sizeof(unsigned short));
chip->eg_level[0][0] = chip->eg_nextlevel[1];
chip->eg_am_l[0] = chip->lfo_am;
chip->eg_am_shift[0] = (chip->op_dr_a[1][11][bank] & 0x80) != 0 ? (chip->reg_b4[1][5] >> 4) & 3 : 0;
static const int eg_am_shift[4] = {
7, 3, 1, 0
};
int lfo_add = (chip->eg_am_l[1] << 1) >> eg_am_shift[chip->eg_am_shift[1]];
eg_output += lfo_add;
chip->eg_of1 = (eg_output & 1024) != 0;
chip->eg_output_lfo = eg_output & 1023;
chip->eg_ch3_l[1] = chip->eg_ch3_l[0];
chip->eg_csm_tl = (chip->ch3_csm && (chip->eg_ch3_l[0] & 2) != 0) ? 0 : chip->eg_tl[1][0];
chip->eg_debug[0] = chip->eg_debug[1] << 1;
if (chip->eg_dbg_sync)
{
chip->eg_debug[0] |= chip->eg_out;
}
chip->eg_debug_inc = chip->eg_incsh0[1] || chip->eg_incsh1[1] || chip->eg_incsh2[1] || chip->eg_incsh3[1];
}
if (chip->clk2)
{
chip->eg_sync = chip->fsm_sel0[1];
chip->eg_prescaler_clock_l[1] = chip->eg_prescaler_clock_l[0];
chip->eg_prescaler[1] = chip->eg_prescaler[0];
chip->eg_step[1] = chip->eg_step[0];
chip->eg_timer_step[0] = chip->eg_step[0] && chip->eg_prescaler_clock_l[0];
chip->eg_ic[1] = chip->eg_ic[0];
chip->eg_timer_test_bit[1] = chip->eg_timer_test_bit[0];
chip->eg_timer_sum[1] = chip->eg_timer_sum[0] && !chip->eg_ic[0] && !chip->eg_timer_test;
chip->eg_timer[1] = chip->eg_timer[0];
chip->eg_clock_delay[1] = chip->eg_clock_delay[0];
chip->eg_timer_carry[1] = chip->eg_timer_carry[0];
chip->eg_timer_mask[1] = chip->eg_timer_mask[0];
chip->eg_timer_masked[1] = chip->eg_timer_masked[0];
int rate = 0;
switch (chip->eg_rate_sel)
{
case eg_state_attack:
rate = chip->eg_rate_ar;
break;
case eg_state_decay:
rate = chip->eg_rate_dr;
break;
case eg_state_sustain:
rate = chip->eg_rate_sr;
break;
case eg_state_release:
rate = (chip->eg_rate_rr * 2) | 1;
break;
}
chip->eg_rate_nonzero[0] = rate != 0;
chip->eg_rate_nonzero[2] = chip->eg_rate_nonzero[1];
chip->eg_rate = rate;
chip->eg_ksv = chip->kcode[2] >> (chip->eg_ks ^ 3);
int rate2 = chip->eg_rate2;
if (rate2 & 64)
rate2 = 63;
rate2 &= 63;
static const int eg_stephi[4][4] = {
{ 0, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 1, 0, 1, 0 },
{ 1, 1, 1, 0 }
};
chip->eg_inc2 = eg_stephi[rate2 & 3][chip->eg_timer_low_lock];
chip->eg_ratenz = rate2 != 0;
chip->eg_rate12 = (rate2 & 60) == 48;
chip->eg_rate13 = (rate2 & 60) == 52;
chip->eg_rate14 = (rate2 & 60) == 56;
chip->eg_rate15 = (rate2 & 60) == 60;
chip->eg_maxrate[0] = (rate2 & 62) == 62;
chip->eg_rate_low = rate2 & 3;
chip->eg_rate_slow = (rate2 & 48) != 48;
chip->eg_rate_sum = (chip->eg_shift_lock + (rate2 >> 2)) & 15;
chip->eg_incsh0[1] = chip->eg_step[2] && chip->eg_incsh0[0];
chip->eg_incsh1[1] = chip->eg_step[2] && chip->eg_incsh1[0];
chip->eg_incsh2[1] = chip->eg_step[2] && chip->eg_incsh2[0];
chip->eg_incsh3[1] = chip->eg_step[2] && chip->eg_incsh3[0];
chip->eg_kon_latch[1] = chip->eg_kon_latch[0];
chip->eg_key[1] = chip->eg_key[0];
chip->eg_level_ssg[1] = chip->eg_level_ssg[0];
chip->eg_pg_reset[1] = chip->eg_pg_reset[0];
chip->eg_ssg_sign[1] = chip->eg_ssg_sign[0];
chip->eg_ssg_enable[1] = chip->eg_ssg_enable[0];
chip->eg_ssg_dir[1] = chip->eg_ssg_dir[0];
chip->eg_ssg_holdup[1] = chip->eg_ssg_holdup[0];
chip->eg_ssg_pgreset[1] = chip->eg_ssg_pgreset[0];
chip->eg_ssg_egrepeat[1] = chip->eg_ssg_egrepeat[0];
chip->eg_sl[0][1] = chip->eg_sl[0][0];
chip->eg_sl[1][1] = chip->eg_sl[1][0];
chip->eg_tl[0][1] = chip->eg_tl[0][0];
chip->eg_tl[1][1] = chip->eg_tl[1][0];
chip->eg_tl[2][1] = chip->eg_tl[2][0];
chip->eg_nextlevel[1] = chip->eg_nextlevel[0] + chip->eg_inc_total;
chip->eg_kon_csm[1] = chip->eg_kon_csm[0];
int inv = ((chip->eg_level[0][20] ^ 1023) + 513) & 1023;
chip->eg_output = chip->eg_ssg_inv ? inv : chip->eg_level[0][20];
chip->eg_level_l[1] = chip->eg_level_l[0];
int nextstate = eg_state_attack;
int eg_mute = !chip->eg_kon_event && chip->eg_off && (chip->eg_ssg_holdup[0] & 4) == 0 && chip->eg_state_l != eg_state_attack;
chip->eg_mute = eg_mute;
if (eg_mute)
{
nextstate |= eg_state_release;
}
if (!chip->eg_kon_event && chip->eg_state_l == eg_state_sustain)
{
nextstate |= eg_state_sustain;
}
if (!chip->eg_kon_event && chip->eg_state_l == eg_state_decay && !chip->eg_slreach)
{
nextstate |= eg_state_decay;
}
if (!chip->eg_kon_event && chip->eg_state_l == eg_state_decay && chip->eg_slreach)
{
nextstate |= eg_state_sustain;
}
if ((chip->eg_kon_latch[0] & 4) == 0 && !chip->eg_kon_event)
{
nextstate |= eg_state_release;
}
if (!chip->eg_kon_event && chip->eg_state_l == eg_state_release)
{
nextstate |= eg_state_release;
}
if (!chip->eg_kon_event && chip->eg_state_l == eg_state_attack && chip->eg_zeroreach)
{
nextstate |= eg_state_decay;
}
if (chip->eg_ic[0])
{
nextstate |= eg_state_release;
}
chip->eg_nextstate = nextstate;
memcpy(&chip->eg_state[1][0], &chip->eg_state[0][0], 23 * sizeof(unsigned char));
chip->eg_exp = (chip->eg_kon_latch[0] & 4) != 0 && (chip->eg_state_l == eg_state_attack) && !chip->eg_maxrate[1] && !chip->eg_zeroreach;
chip->eg_linear = !chip->eg_kon_event && !chip->eg_off && (chip->eg_state_l == eg_state_sustain || chip->eg_state_l == eg_state_release);
chip->eg_linear |= !chip->eg_kon_event && !chip->eg_off && !chip->eg_slreach && chip->eg_state_l == eg_state_decay;
chip->eg_istantattack = chip->eg_maxrate[1] && (!chip->eg_maxrate[1] || chip->eg_kon_event);
memcpy(&chip->eg_level[1][0], &chip->eg_level[0][0], 22 * sizeof(unsigned short));
chip->eg_am_l[1] = chip->eg_am_l[0];
chip->eg_am_shift[1] = chip->eg_am_shift[0];
chip->eg_ch3_l[0] = (chip->eg_ch3_l[1] << 1) | chip->fsm_sel_ch3[1];
int levelsum = chip->eg_output_lfo + (chip->eg_csm_tl << 3);
int eg_of = (levelsum & 1024) != 0;
if (eg_of || chip->eg_of1)
levelsum = 1023;
chip->eg_out = levelsum;
chip->eg_dbg_sync = chip->fsm_sel2[1];
chip->eg_debug[1] = chip->eg_debug[0];
}
}
{
if (chip->clk1)
{
chip->op_phase1 = chip->pg_out;
chip->op_phase2 = chip->op_mod[1][5];
chip->op_sign[1] = chip->op_sign[0];
static const int logsin[128] = {
0x6c3, 0x58b, 0x4e4, 0x471, 0x41a, 0x3d3, 0x398, 0x365, 0x339, 0x311, 0x2ed, 0x2cd, 0x2af, 0x293, 0x279, 0x261,
0x24b, 0x236, 0x222, 0x20f, 0x1fd, 0x1ec, 0x1dc, 0x1cd, 0x1be, 0x1b0, 0x1a2, 0x195, 0x188, 0x17c, 0x171, 0x166,
0x15b, 0x150, 0x146, 0x13c, 0x133, 0x129, 0x121, 0x118, 0x10f, 0x107, 0x0ff, 0x0f8, 0x0f0, 0x0e9, 0x0e2, 0x0db,
0x0d4, 0x0cd, 0x0c7, 0x0c1, 0x0bb, 0x0b5, 0x0af, 0x0a9, 0x0a4, 0x09f, 0x099, 0x094, 0x08f, 0x08a, 0x086, 0x081,
0x07d, 0x078, 0x074, 0x070, 0x06c, 0x068, 0x064, 0x060, 0x05c, 0x059, 0x055, 0x052, 0x04e, 0x04b, 0x048, 0x045,
0x042, 0x03f, 0x03c, 0x039, 0x037, 0x034, 0x031, 0x02f, 0x02d, 0x02a, 0x028, 0x026, 0x024, 0x022, 0x020, 0x01e,
0x01c, 0x01a, 0x018, 0x017, 0x015, 0x014, 0x012, 0x011, 0x00f, 0x00e, 0x00d, 0x00c, 0x00a, 0x009, 0x008, 0x007,
0x007, 0x006, 0x005, 0x004, 0x004, 0x003, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000
};
static const int logsin_d[128] = {
0x196, 0x07c, 0x04a, 0x035, 0x029, 0x022, 0x01d, 0x019, 0x015, 0x013, 0x012, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c,
0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x009, 0x008, 0x007, 0x007, 0x007, 0x007, 0x006, 0x007, 0x006, 0x006, 0x005,
0x005, 0x005, 0x005, 0x005, 0x004, 0x005, 0x004, 0x004, 0x005, 0x004, 0x004, 0x003, 0x004, 0x003, 0x003, 0x003,
0x003, 0x004, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x002, 0x003, 0x003, 0x003, 0x003, 0x002, 0x002,
0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x002, 0x002, 0x002, 0x001,
0x001, 0x001, 0x002, 0x002, 0x001, 0x001, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001,
0x001, 0x001, 0x001, 0x000, 0x001, 0x000, 0x001, 0x000, 0x001, 0x001, 0x000, 0x000, 0x001, 0x001, 0x001, 0x001,
0x000, 0x000, 0x000, 0x001, 0x000, 0x000, 0x001, 0x000, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
};
static const int pow[128] = {
0x3f5, 0x3ea, 0x3df, 0x3d4, 0x3c9, 0x3bf, 0x3b4, 0x3a9, 0x39f, 0x394, 0x38a, 0x37f, 0x375, 0x36a, 0x360, 0x356,
0x34c, 0x342, 0x338, 0x32e, 0x324, 0x31a, 0x310, 0x306, 0x2fd, 0x2f3, 0x2e9, 0x2e0, 0x2d6, 0x2cd, 0x2c4, 0x2ba,
0x2b1, 0x2a8, 0x29e, 0x295, 0x28c, 0x283, 0x27a, 0x271, 0x268, 0x25f, 0x257, 0x24e, 0x245, 0x23c, 0x234, 0x22b,
0x223, 0x21a, 0x212, 0x209, 0x201, 0x1f9, 0x1f0, 0x1e8, 0x1e0, 0x1d8, 0x1d0, 0x1c8, 0x1c0, 0x1b8, 0x1b0, 0x1a8,
0x1a0, 0x199, 0x191, 0x189, 0x181, 0x17a, 0x172, 0x16b, 0x163, 0x15c, 0x154, 0x14d, 0x146, 0x13e, 0x137, 0x130,
0x129, 0x122, 0x11b, 0x114, 0x10c, 0x106, 0x0ff, 0x0f8, 0x0f1, 0x0ea, 0x0e3, 0x0dc, 0x0d6, 0x0cf, 0x0c8, 0x0c2,
0x0bb, 0x0b5, 0x0ae, 0x0a8, 0x0a1, 0x09b, 0x094, 0x08e, 0x088, 0x082, 0x07b, 0x075, 0x06f, 0x069, 0x063, 0x05d,
0x057, 0x051, 0x04b, 0x045, 0x03f, 0x039, 0x033, 0x02d, 0x028, 0x022, 0x01c, 0x016, 0x011, 0x00b, 0x006, 0x000,
};
static const int pow_d[128] = {
0x005, 0x005, 0x005, 0x006, 0x006, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x006, 0x005, 0x005,
0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x004, 0x005,
0x004, 0x004, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x005, 0x004, 0x004, 0x004, 0x005, 0x004, 0x005,
0x004, 0x004, 0x004, 0x005, 0x004, 0x004, 0x005, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
0x004, 0x003, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x003, 0x004, 0x004, 0x004,
0x003, 0x003, 0x003, 0x003, 0x004, 0x003, 0x003, 0x003, 0x003, 0x003, 0x004, 0x004, 0x003, 0x003, 0x004, 0x003,
0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x004, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003,
0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x003, 0x002, 0x003, 0x003, 0x003, 0x003, 0x003, 0x002, 0x003,
};
chip->op_logsin_base = logsin[(chip->op_phase_index >> 1) & 127];
chip->op_logsin_delta = (chip->op_phase_index & 1) != 0 ? 0 : logsin_d[(chip->op_phase_index >> 1) & 127];
chip->op_eglevel = chip->eg_out;
chip->op_shift[0] = chip->op_att >> 8;
chip->op_pow_base = pow[(chip->op_att >> 1) & 127];
chip->op_pow_delta = (chip->op_att & 1) != 0 ? 0 : pow_d[(chip->op_att >> 1) & 127];
int output = chip->op_pow;
output = (output << 2) >> chip->op_shift[1];
if (chip->reg_test_21[1] & 16)
output ^= 1 << 13;
if (chip->op_sign[0] & 4)
output ^= 0x3fff;
chip->op_output[0] = output;
chip->op_output[2] = chip->op_output[1];
memcpy(&chip->op_op1_0[0][1], &chip->op_op1_0[1][0], 5 * sizeof(unsigned short));
memcpy(&chip->op_op1_1[0][1], &chip->op_op1_1[1][0], 5 * sizeof(unsigned short));
memcpy(&chip->op_op2[0][1], &chip->op_op2[1][0], 5 * sizeof(unsigned short));
chip->op_op1_0[0][0] = chip->op_loadfb ? chip->op_output[3] : chip->op_op1_0[1][5];
chip->op_op1_1[0][0] = chip->op_loadfb ? chip->op_op1_0[1][5] : chip->op_op1_1[1][5];
chip->op_op2[0][0] = chip->op_loadop2 ? chip->op_output[3] : chip->op_op2[1][5];
int mod1 = 0;
int mod2 = 0;
if (chip->op_mod_op1_0)
{
mod2 |= chip->op_op1_0[1][5];
}
if (chip->op_mod_op1_1)
{
mod1 |= chip->op_op1_1[1][5];
}
if (chip->op_mod_op2)
{
mod1 |= chip->op_op2[1][5];
}
if (chip->op_mod_prev_0)
{
mod2 |= chip->op_output[3];
}
if (chip->op_mod_prev_1)
{
mod1 |= chip->op_output[3];
}
if (mod1 & (1 << 13))
mod1 |= 1 << 14;
if (mod2 & (1 << 13))
mod2 |= 1 << 14;
chip->op_mod1 = mod1;
chip->op_mod2 = mod2;
int mod;
if (chip->op_do_fb)
{
if (!chip->op_fb)
mod = 0;
else
{
mod = chip->op_mod_sum;
if (mod & (1 << 13))
mod |= ~0x3fff;
mod = mod >> (9 - chip->op_fb);
}
}
else
mod = chip->op_mod_sum;
memcpy(&chip->op_mod[0][1], &chip->op_mod[1][0], 5 * sizeof(unsigned short));
chip->op_mod[0][0] = mod;
}
if (chip->clk2)
{
int phase = chip->op_phase1 + chip->op_phase2;
int phase2 = phase & 255;
if (phase & 256)
phase2 ^= 255;
chip->op_phase_index = phase2;
chip->op_sign[0] = chip->op_sign[1] << 1;
if (phase & 512)
chip->op_sign[0] |= 1;
//chip->op_eglevel = 256; //
int level = chip->op_logsin_base + chip->op_logsin_delta + (chip->op_eglevel << 2);
if (level & 4096)
level = 4095;
chip->op_att = level;
chip->op_shift[1] = chip->op_shift[0];
chip->op_pow = (chip->op_pow_base + chip->op_pow_delta) | 0x400;
int output = chip->op_output[0];
if (chip->op_sign[1] & 4)
output++;
chip->op_output[1] = output & 0x3fff;
chip->op_output[3] = chip->op_output[2];
chip->op_loadfb = chip->alg_load_fb;
chip->op_loadop2 = chip->alg_mod_op1_1_l;
chip->op_mod_op1_0 = chip->alg_mod_op1_0_l;
chip->op_mod_op1_1 = chip->alg_mod_op1_1_l;
chip->op_mod_op2 = chip->alg_mod_op2_l;
chip->op_mod_prev_0 = chip->alg_mod_prev_0_l;
chip->op_mod_prev_1 = chip->alg_mod_prev_1_l;
chip->op_do_fb = chip->alg_do_fb[1];
chip->op_fb = (chip->reg_connect_fb[0][0] >> 3) & 7;
memcpy(&chip->op_op1_0[1][0], &chip->op_op1_0[0][0], 6 * sizeof(unsigned short));
memcpy(&chip->op_op1_1[1][0], &chip->op_op1_1[0][0], 6 * sizeof(unsigned short));
memcpy(&chip->op_op2[1][0], &chip->op_op2[0][0], 6 * sizeof(unsigned short));
int mod = (chip->op_mod1 + chip->op_mod2) >> 1;
mod &= 0x3fff;
chip->op_mod_sum = mod;
memcpy(&chip->op_mod[1][0], &chip->op_mod[0][0], 6 * sizeof(unsigned short));
}
}
#ifndef FMOPNA_YM2612
{
#ifdef FMOPNA_YM2608
if (!chip->mclk2)
{
int addr2d = chip->write2_en && ADDRESS_MATCH(0x2d);
int addr2e = chip->write2_en && ADDRESS_MATCH(0x2e);
int addr2f = chip->write2_en && ADDRESS_MATCH(0x2f);
chip->ssg_prescaler1[0] = (chip->ssg_prescaler1[1] && !addr2f) || addr2e;
chip->ssg_prescaler2[0] = (chip->ssg_prescaler2[1] && !addr2f) || addr2d || chip->ic;
}
else
{
chip->ssg_prescaler1[1] = chip->ssg_prescaler1[0] && !chip->ic;
chip->ssg_prescaler2[1] = chip->ssg_prescaler2[0];
}
#endif
if (!chip->mclk2)
{
chip->ssg_div1[0] = !chip->ssg_div1[1];
}
else
{
chip->ssg_div1[1] = chip->ssg_div1[0];
}
if (!chip->ssg_div1[0])
{
chip->ssg_div2[0] = !chip->ssg_div2[1];
}
else
{
chip->ssg_div2[1] = chip->ssg_div2[0];
}
if (!chip->ssg_div2[0])
{
chip->ssg_div3[0] = !chip->ssg_div3[1];
}
else
{
chip->ssg_div3[1] = chip->ssg_div3[0];
}
if (chip->ic_check2)
{
chip->ssg_div1[0] = 0;
chip->ssg_div1[1] = 0;
chip->ssg_div2[0] = 0;
chip->ssg_div2[1] = 0;
chip->ssg_div3[0] = 0;
chip->ssg_div3[1] = 0;
}
#ifdef FMOPNA_YM2608
if (chip->ssg_prescaler2[1])
{
if (chip->ssg_prescaler1[1])
{
chip->ssg_clk = chip->ssg_div2[0];
}
else
{
chip->ssg_clk = chip->ssg_div3[0];
}
}
else
chip->ssg_clk = chip->ssg_div1[0];
#else
chip->ssg_clk = chip->ssg_div3[0];
#endif
chip->ssg_clk1 = !chip->ssg_clk;
chip->ssg_clk2 = chip->ssg_clk;
if (chip->ic)
chip->ssg_ssg_addr = 0;
else if (chip->ssg_write0)
chip->ssg_ssg_addr = (chip->data_bus1 & 0xf0) == 0;
if (chip->ic)
chip->ssg_address = 0;
else if (chip->ssg_write0 && (chip->data_bus1 & 0xe0) == 0)
chip->ssg_address = chip->data_bus1 & 0x1f;
int ssg_access = chip->ssg_ssg_addr && (chip->ssg_write1 || chip->ssg_read1);
if (chip->ssg_egtrig_rst)
chip->ssg_egtrig = 0;
if (chip->ic)
{
chip->ssg_freq_a[0] = chip->data_bus1 & 255;
chip->ssg_freq_a[1] = chip->data_bus1 & 15;
chip->ssg_freq_b[0] = chip->data_bus1 & 255;
chip->ssg_freq_b[1] = chip->data_bus1 & 15;
chip->ssg_freq_c[0] = chip->data_bus1 & 255;
chip->ssg_freq_c[1] = chip->data_bus1 & 15;
chip->ssg_noise = chip->data_bus1 & 31;
chip->ssg_mode = chip->data_bus1 & 255;
chip->ssg_level_a = chip->data_bus1 & 31;
chip->ssg_level_b = chip->data_bus1 & 31;
chip->ssg_level_c = chip->data_bus1 & 31;
chip->ssg_env[0] = chip->data_bus1 & 255;
chip->ssg_env[1] = chip->data_bus1 & 255;
chip->ssg_envmode = chip->data_bus1 & 15;
#ifdef FMOPNA_YM2608
chip->o_gpio_a = chip->data_bus1 & 255;
chip->o_gpio_b = chip->data_bus1 & 255;
#endif
chip->ssg_egtrig = 1;
}
else if (chip->ssg_ssg_addr && chip->ssg_write1)
{
switch (chip->ssg_address)
{
case 0x0:
chip->ssg_freq_a[0] = chip->data_bus1 & 255;
break;
case 0x1:
chip->ssg_freq_a[1] = chip->data_bus1 & 15;
break;
case 0x2:
chip->ssg_freq_b[0] = chip->data_bus1 & 255;
break;
case 0x3:
chip->ssg_freq_b[1] = chip->data_bus1 & 15;
break;
case 0x4:
chip->ssg_freq_c[0] = chip->data_bus1 & 255;
break;
case 0x5:
chip->ssg_freq_c[1] = chip->data_bus1 & 15;
break;
case 0x6:
chip->ssg_noise = chip->data_bus1 & 31;
break;
case 0x7:
chip->ssg_mode = chip->data_bus1 & 255;
break;
case 0x8:
chip->ssg_level_a = chip->data_bus1 & 31;
break;
case 0x9:
chip->ssg_level_b = chip->data_bus1 & 31;
break;
case 0xa:
chip->ssg_level_c = chip->data_bus1 & 31;
break;
case 0xb:
chip->ssg_env[0] = chip->data_bus1 & 255;
break;
case 0xc:
chip->ssg_env[1] = chip->data_bus1 & 255;
break;
case 0xd:
chip->ssg_envmode = chip->data_bus1 & 15;
chip->ssg_egtrig = 1;
break;
#ifdef FMOPNA_YM2608
case 0xe:
chip->o_gpio_a = chip->data_bus1 & 255;
break;
case 0xf:
chip->o_gpio_b = chip->data_bus1 & 255;
break;
#endif
}
}
if (chip->ssg_ssg_addr && chip->ssg_read1)
{
switch (chip->ssg_address)
{
case 0x0:
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ssg_freq_a[0] & 255;
break;
case 0x1:
chip->data_bus1 &= ~15;
chip->data_bus1 |= chip->ssg_freq_a[1] & 15;
break;
case 0x2:
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ssg_freq_b[0] & 255;
break;
case 0x3:
chip->data_bus1 &= ~15;
chip->data_bus1 |= chip->ssg_freq_b[1] & 15;
break;
case 0x4:
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ssg_freq_c[0] & 255;
break;
case 0x5:
chip->data_bus1 &= ~15;
chip->data_bus1 |= chip->ssg_freq_c[1] & 15;
break;
case 0x6:
chip->data_bus1 &= ~31;
chip->data_bus1 |= chip->ssg_noise & 31;
break;
case 0x7:
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ssg_mode & 255;
break;
case 0x8:
chip->data_bus1 &= ~31;
chip->data_bus1 |= chip->ssg_level_a & 31;
break;
case 0x9:
chip->data_bus1 &= ~31;
chip->data_bus1 |= chip->ssg_level_b & 31;
break;
case 0xa:
chip->data_bus1 &= ~31;
chip->data_bus1 |= chip->ssg_level_c & 31;
break;
case 0xb:
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ssg_env[0] & 255;
break;
case 0xc:
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ssg_env[1] & 255;
break;
case 0xd:
chip->data_bus1 &= ~15;
chip->data_bus1 |= chip->ssg_envmode & 15;
break;
#ifdef FMOPNA_YM2608
case 0xe:
chip->data_bus1 &= ~15;
chip->data_bus1 |= chip->input.gpio_a & 15;
break;
case 0xf:
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->input.gpio_b & 255;
break;
#endif
}
}
if (chip->ssg_clk1)
{
chip->ssg_envadd = (chip->ssg_eg_of[1] & 4) != 0 && (chip->ssg_sel[1] & 8) != 0;
chip->ssg_envcnt[1] = chip->ssg_hold[0] ? 31 : chip->ssg_envcnt[0];
chip->ssg_dir[1] = chip->ssg_dir[0];
chip->ssg_hold[1] = chip->ssg_hold[0];
chip->ssg_t2[1] = chip->ssg_t2[0];
chip->ssg_egtrig_s = chip->ssg_egtrig;
chip->ssg_eg_sel_l = (chip->ssg_sel[1] & 8) != 0;
chip->ssg_sel[0] = chip->ssg_sel[1] << 1;
chip->ssg_sel[0] |= (chip->ssg_sel[1] & 7) == 0 && !chip->ic;
chip->ssg_sel_freq = 0;
if (chip->ssg_sel[1] & 1)
chip->ssg_sel_freq |= (chip->ssg_freq_c[1] << 8) | chip->ssg_freq_c[0];
if (chip->ssg_sel[1] & 2)
chip->ssg_sel_freq |= (chip->ssg_freq_b[1] << 8) | chip->ssg_freq_b[0];
if (chip->ssg_sel[1] & 4)
chip->ssg_sel_freq |= (chip->ssg_freq_a[1] << 8) | chip->ssg_freq_a[0];
if (chip->ssg_sel[1] & 8)
chip->ssg_sel_freq |= (chip->ssg_env[1] << 8) | chip->ssg_env[0];
int cnt = chip->ssg_freq_cnt[7] + 1;
int of = (cnt & 0x1000) != 0;
chip->ssg_freq_cnt[0] = cnt & 0xfff;
chip->ssg_freq_cnt[4] = chip->ssg_freq_cnt[3];
chip->ssg_freq_cnt[6] = chip->ssg_freq_cnt[5];
chip->ssg_cnt_of[1] = chip->ssg_cnt_of[0];
if (chip->ssg_sel[1] & 8)
chip->ssg_sign_toggle = chip->ssg_cnt_of[0] & 7;
else
chip->ssg_sign_toggle = 0;
chip->ssg_freq_cnt2[1] = chip->ssg_freq_cnt2[0];
chip->ssg_freq_cnt2[3] = chip->ssg_freq_cnt2[2];
chip->ssg_freq_cnt2[5] = chip->ssg_freq_cnt2[4];
chip->ssg_freq_cnt2[7] = chip->ssg_freq_cnt2[6];
chip->ssg_sign[1] = chip->ssg_sign[0];
int cnt_of = !chip->ssg_cnt_reload && (chip->ssg_sel_freq_l - chip->ssg_cnt_of_l < chip->ssg_freq_cnt2[0]);
chip->ssg_cnt2_add = (chip->ssg_sel[1] & 8) != 0 && of;
chip->ssg_sel_eg_l[0] = (chip->ssg_sel[1] & 8) != 0;
chip->ssg_eg_of[0] = (chip->ssg_eg_of[1] << 1) | cnt_of;
int fr_rst = chip->ssg_ch_of || ((cnt_of || chip->ssg_cnt_reload) && chip->ssg_sel_eg_l[1]);
chip->ssg_freq_cnt[2] = fr_rst ? 0 : chip->ssg_freq_cnt[1];
chip->ssg_fr_rst_l = fr_rst;
chip->ssg_noise_add = (chip->ssg_sel[1] & 1) != 0;
chip->ssg_noise_cnt[1] = chip->ssg_noise_cnt[0];
int noise_of = chip->ssg_noise <= (chip->ssg_noise_cnt[0] >> 1);
chip->ssg_noise_of = noise_of && chip->ssg_noise_of_low;
chip->ssg_test = chip->input.test;
chip->ssg_noise_step = chip->ssg_noise_of || !chip->ssg_test;
}
if (chip->ssg_clk2)
{
int sum = chip->ssg_envcnt[1] + chip->ssg_envadd;
int of = (sum & 32) != 0;
chip->ssg_envcnt[0] = chip->ssg_egtrig_s ? 0 : sum & 31;
int dir = of && (chip->ssg_envmode & 2) != 0 && !chip->ssg_hold[1];
chip->ssg_dir[0] = chip->ssg_egtrig_s ? 0 : chip->ssg_dir[1] ^ dir;
chip->ssg_hold[0] = chip->ssg_egtrig_s ? 0 : chip->ssg_hold[1] || (of && (chip->ssg_envmode & 1) != 0);
chip->ssg_t2[0] = chip->ssg_egtrig_s ? 0 : chip->ssg_t2[1] || of;
chip->ssg_egtrig_rst = chip->ssg_egtrig_s && chip->ssg_eg_sel_l;
chip->ssg_sel[1] = chip->ssg_sel[0];
chip->ssg_freq_cnt[1] = chip->ssg_freq_cnt[0];
chip->ssg_freq_cnt[3] = chip->ssg_freq_cnt[2];
chip->ssg_freq_cnt[5] = chip->ssg_freq_cnt[4];
chip->ssg_freq_cnt[7] = chip->ssg_freq_cnt[6];
int cnt_of = (chip->ssg_sel_freq & 0xfff) <= chip->ssg_freq_cnt[0];
chip->ssg_cnt_of_l = cnt_of;
chip->ssg_sel_freq_l = (chip->ssg_sel_freq >> 12) & 0xf;
chip->ssg_cnt_of[0] = (chip->ssg_cnt_of[1] << 1) | cnt_of;
if (chip->ic)
chip->ssg_sign[0] = 0;
else
chip->ssg_sign[0] = chip->ssg_sign[1] ^ chip->ssg_sign_toggle;
int cnt = chip->ssg_freq_cnt2[7] + chip->ssg_cnt2_add;
chip->ssg_freq_cnt2[0] = cnt & 0xf;
chip->ssg_freq_cnt2[2] = chip->ssg_fr_rst_l ? 0 : chip->ssg_freq_cnt2[1];
chip->ssg_freq_cnt2[4] = chip->ssg_freq_cnt2[3];
chip->ssg_freq_cnt2[6] = chip->ssg_freq_cnt2[5];
chip->ssg_sel_eg_l[1] = chip->ssg_sel_eg_l[0];
chip->ssg_ch_of = (!chip->ssg_sel_eg_l[0] && cnt_of) || chip->ic;
chip->ssg_cnt_reload = chip->ssg_sel_eg_l[0] && chip->ssg_egtrig_s;
chip->ssg_eg_of[1] = chip->ssg_eg_of[0];
chip->ssg_noise_cnt[0] = chip->ssg_noise_step ? 0 : ((chip->ssg_noise_cnt[1] + chip->ssg_noise_add) & 63);
chip->ssg_noise_of_low = (chip->ssg_noise_cnt[1] & 1) != 0 && chip->ssg_noise_add;
}
if (!chip->ssg_noise_step)
{
int bit = ((chip->ssg_noise_lfsr[1] >> 16) ^ (chip->ssg_noise_lfsr[1] >> 13)) & 1;
if ((chip->ssg_noise_lfsr[1] & 0x1ffff) == 0)
bit |= 1;
chip->ssg_noise_lfsr[0] = (chip->ssg_noise_lfsr[1] << 1) | bit;
}
else
{
chip->ssg_noise_lfsr[1] = chip->ic ? 0 : chip->ssg_noise_lfsr[0];
}
if (chip->ssg_clk2)
chip->ssg_noise_bit = (chip->ssg_noise_lfsr[1] >> 16) & 1;
int envlevel = chip->ssg_hold[0] ? 31 : chip->ssg_envcnt[0];
envlevel = (chip->ssg_dir[0] ^ ((chip->ssg_envmode >> 2) & 1)) == 0 ? (envlevel ^ 31) : envlevel;
envlevel = (chip->ssg_t2[0] && (chip->ssg_envmode & 8) == 0) ? 0 : envlevel;
int vol_a = (chip->ssg_level_a & 0x10) != 0 ? envlevel : (((chip->ssg_level_a & 15) << 1) | 1);
int vol_b = (chip->ssg_level_b & 0x10) != 0 ? envlevel : (((chip->ssg_level_b & 15) << 1) | 1);
int vol_c = (chip->ssg_level_c & 0x10) != 0 ? envlevel : (((chip->ssg_level_c & 15) << 1) | 1);
int sign_a = ((chip->ssg_mode & 1) == 0 && (chip->ssg_sign[0] & 1) != 0) || ((chip->ssg_mode & 8) == 0 && chip->ssg_noise_bit);
int sign_b = ((chip->ssg_mode & 2) == 0 && (chip->ssg_sign[0] & 2) != 0) || ((chip->ssg_mode & 16) == 0 && chip->ssg_noise_bit);
int sign_c = ((chip->ssg_mode & 4) == 0 && (chip->ssg_sign[0] & 4) != 0) || ((chip->ssg_mode & 32) == 0 && chip->ssg_noise_bit);
static const float volume_lut[32] = {
0.0000, 0.0000, 0.0049, 0.0075, 0.0105, 0.0131, 0.0156, 0.0183,
0.0228, 0.0276, 0.0321, 0.0367, 0.0448, 0.0535, 0.0626, 0.0713,
0.0884, 0.1057, 0.1225, 0.1392, 0.1691, 0.2013, 0.2348, 0.2670,
0.3307, 0.3951, 0.4573, 0.5196, 0.6316, 0.7528, 0.8787, 1.0000
};
// tildearrow: per-channel oscilloscope for SSG
chip->o_analog = 0;
chip->o_analog += chip->o_analog_ch[0] = volume_lut[sign_a ? 0 : vol_a];
chip->o_analog += chip->o_analog_ch[1] = volume_lut[sign_b ? 0 : vol_b];
chip->o_analog += chip->o_analog_ch[2] = volume_lut[sign_c ? 0 : vol_c];
}
{
if (chip->mclk2)
{
chip->rss_dclk_l = chip->dclk;
}
if (chip->clk2)
{
chip->rss_cnt1_sync = !chip->fsm_rss2;
}
if (chip->aclk1)
{
int cnt1_rst = chip->rss_cnt1[1] == 5 || chip->rss_cnt1_sync;
chip->rss_cnt1[0] = cnt1_rst ? 0 : (chip->rss_cnt1[1] + 1) & 7;
chip->rss_eclk1_l = chip->rss_cnt1[1] == 2 || chip->rss_cnt1[1] == 3;
chip->rss_eclk2_l = chip->rss_cnt1[1] == 5 || chip->rss_cnt1[1] == 0;
chip->rss_fclk_sel[0] = chip->rss_cnt1[1] == 5 || chip->rss_cnt1[1] == 0 || chip->rss_cnt1[1] == 1;
}
if (chip->aclk2)
{
chip->rss_cnt1[1] = chip->rss_cnt1[0];
chip->rss_eclk1 = chip->rss_eclk1_l;
chip->rss_eclk2 = chip->rss_eclk2_l;
chip->rss_fclk_sel[1] = chip->rss_fclk_sel[0];
}
chip->rss_fclk1 = !chip->rss_dclk_l && chip->aclk1 && chip->rss_fclk_sel[1];
chip->rss_fclk2 = !chip->rss_dclk_l && chip->aclk2 && chip->rss_fclk_sel[1];
if (chip->clk1)
{
int clk_rst = chip->rss_fmcnt_of || chip->rss_fmcnt_sync;
chip->rss_fmcnt[0] = clk_rst ? 0 : (chip->rss_fmcnt[1] + 1) & 15;
#ifdef FMOPNA_YM2608
chip->rss_tl_sel[0] = chip->write0_en ? chip->data_bus1 == 0x11 : chip->rss_tl_sel[1];
#else
chip->rss_tl_sel[0] = chip->write0_en ? chip->data_bus1 == 0x101 : chip->rss_tl_sel[1];
#endif
if (chip->ic)
chip->rss_tl[0] = 0;
else
chip->rss_tl[0] = chip->rss_tl_sel[1]
#ifdef FMOPNA_YM2608
&& (chip->data_bus1 & 0x100) == 0
#else
&& (chip->data_bus1 & 0x100) != 0
#endif
&& chip->write1_en ? chip->data_bus1 & 0x3f : chip->rss_tl[1];
}
if (chip->clk2)
{
chip->rss_fmcnt[1] = chip->rss_fmcnt[0];
chip->rss_fmcnt_of = (chip->rss_fmcnt[0] & 11) == 11;
chip->rss_fmcnt_sync = chip->fsm_sel23[1];
chip->rss_tl_sel[1] = chip->rss_tl_sel[0];
chip->rss_tl[1] = chip->rss_tl[0];
}
if (chip->rss_eclk1)
{
int cnt2_rst = chip->ic || chip->rss_cnt2[1] == 5 || (chip->fsm_rss && chip->rss_cnt2[0] == 0);
chip->rss_cnt2[0] = cnt2_rst ? 0 : (chip->rss_cnt2[1] + 1) & 7;
}
if (chip->rss_eclk2)
{
chip->rss_cnt2[1] = chip->rss_cnt2[0];
}
#ifdef FMOPNA_YM2610
if (chip->clk1)
{
if (chip->write0_en && (chip->data_bus1 & 0x3c) != 0)
{
chip->rss_address[0] = chip->data_bus1;
}
else
{
chip->rss_address[0] = chip->rss_address[1];
}
if (chip->rss_address_wr[1] && chip->write1_en)
{
chip->rss_data[0] = chip->data_bus1 & 0xff;
}
else
{
chip->rss_data[0] = chip->rss_data[1];
}
chip->rss_address_wr[0] = chip->write0_en ? (chip->data_bus1 & 0x3c) != 0 : chip->rss_address_wr[1];
chip->rss_data_wr[0] = (chip->write1_en && chip->rss_address_wr[1])
|| (!chip->write0_en && chip->rss_data_wr[1]);
memcpy(&chip->rss_reg_pan_tl[0][1], &chip->rss_reg_pan_tl[1][0], 5 * sizeof(unsigned char));
memcpy(&chip->rss_reg_start_l[0][1], &chip->rss_reg_start_l[1][0], 5 * sizeof(unsigned char));
memcpy(&chip->rss_reg_start_h[0][1], &chip->rss_reg_start_h[1][0], 5 * sizeof(unsigned char));
memcpy(&chip->rss_reg_stop_l[0][1], &chip->rss_reg_stop_l[1][0], 5 * sizeof(unsigned char));
memcpy(&chip->rss_reg_stop_h[0][1], &chip->rss_reg_stop_h[1][0], 5 * sizeof(unsigned char));
if (chip->ic)
{
chip->rss_reg_pan_tl[0][0] = 0;
chip->rss_reg_start_l[0][0] = 0;
chip->rss_reg_start_h[0][0] = 0;
chip->rss_reg_stop_l[0][0] = 0;
chip->rss_reg_stop_h[0][0] = 0;
}
else
{
if (chip->rss_write08)
{
chip->rss_reg_pan_tl[0][0] = chip->rss_data[1] & 0xdf;
}
else
{
chip->rss_reg_pan_tl[0][0] = chip->rss_reg_pan_tl[1][5];
}
if (chip->rss_write10)
{
chip->rss_reg_start_l[0][0] = chip->rss_data[1];
}
else
{
chip->rss_reg_start_l[0][0] = chip->rss_reg_start_l[1][5];
}
if (chip->rss_write18)
{
chip->rss_reg_start_h[0][0] = chip->rss_data[1];
}
else
{
chip->rss_reg_start_h[0][0] = chip->rss_reg_start_h[1][5];
}
if (chip->rss_write20)
{
chip->rss_reg_stop_l[0][0] = chip->rss_data[1];
}
else
{
chip->rss_reg_stop_l[0][0] = chip->rss_reg_stop_l[1][5];
}
if (chip->rss_write28)
{
chip->rss_reg_stop_h[0][0] = chip->rss_data[1] & 0xf;
}
else
{
chip->rss_reg_stop_h[0][0] = chip->rss_reg_stop_h[1][5];
}
}
}
if (chip->clk2)
{
if (chip->ic)
{
chip->rss_address[1] = 0;
chip->rss_data[1] = 0;
}
else
{
chip->rss_address[1] = chip->rss_address[0];
chip->rss_data[1] = chip->rss_data[0];
}
chip->rss_address_wr[1] = chip->rss_address_wr[0];
chip->rss_data_wr[1] = chip->rss_data_wr[0];
int addr_match = (chip->rss_fmcnt[0] == (chip->rss_address[0] & 7) && (chip->rss_address[0] & 6) != 6)
&& chip->rss_data_wr[0] && (chip->rss_address[0] & 0x100) != 0;
chip->rss_write08 = addr_match && (chip->rss_address[0] & 0xf8) == 0x08;
chip->rss_write10 = addr_match && (chip->rss_address[0] & 0xf8) == 0x10;
chip->rss_write18 = addr_match && (chip->rss_address[0] & 0xf8) == 0x18;
chip->rss_write20 = addr_match && (chip->rss_address[0] & 0xf8) == 0x20;
chip->rss_write28 = addr_match && (chip->rss_address[0] & 0xf8) == 0x28;
memcpy(&chip->rss_reg_pan_tl[1][0], &chip->rss_reg_pan_tl[0][0], 6 * sizeof(unsigned char));
memcpy(&chip->rss_reg_start_l[1][0], &chip->rss_reg_start_l[0][0], 6 * sizeof(unsigned char));
memcpy(&chip->rss_reg_start_h[1][0], &chip->rss_reg_start_h[0][0], 6 * sizeof(unsigned char));
memcpy(&chip->rss_reg_stop_l[1][0], &chip->rss_reg_stop_l[0][0], 6 * sizeof(unsigned char));
memcpy(&chip->rss_reg_stop_h[1][0], &chip->rss_reg_stop_h[0][0], 6 * sizeof(unsigned char));
}
#endif
int rss_fm_match = chip->rss_fmcnt[1] == chip->rss_cnt2[1];
#ifdef FMOPNA_YM2608
if (chip->clk1 && rss_fm_match)
{
chip->rss_params[0] = chip->reg_rss[1][5];
}
if (chip->rss_cnt1[1] == 3)
{
chip->rss_params[1] = chip->rss_params[0];
}
#endif
#ifdef FMOPNA_YM2610
if (chip->clk1)
chip->rss_fm_match_l = rss_fm_match;
if (rss_fm_match && !chip->rss_fm_match_l)
{
chip->rss_params[0] = chip->rss_reg_pan_tl[1][5];
chip->rss_params_start[0] = chip->rss_reg_start_l[1][4] | (chip->rss_reg_start_h[1][4] << 8);
chip->rss_params_stop[0] = chip->rss_reg_stop_l[1][4] | (chip->rss_reg_stop_h[1][4] << 8);
}
if (chip->rss_cnt1[1] == 1)
{
chip->rss_params_start_h = (chip->rss_params_start[2] >> 12) & 15;
}
if (chip->rss_cnt1[1] == 3)
{
chip->rss_params[1] = chip->rss_params[0];
chip->rss_params_start[1] = chip->rss_params_start[0];
chip->rss_params_stop[1] = chip->rss_params_stop[0];
}
if (chip->rss_cnt1[1] == 5)
{
chip->rss_params_stop[2] = chip->rss_params_stop[1];
chip->rss_params_start[2] = chip->rss_params_start[1] & 0xfff;
}
#endif
if (chip->rss_cnt1[1] == 3)
{
chip->rss_tl_l = chip->rss_tl[1];
chip->rss_tl_shift[1] = chip->rss_tl_shift[0];
}
int tl = (((chip->rss_params[1] & 0x1f) | 0x20) + chip->rss_tl_l + 1) ^ 63;
int key = (chip->rss_key[1] & 0x20) != 0;
if ((tl & 64) == 0 || !key)
tl = 63;
else
tl &= 63;
if (chip->rss_cnt1[1] == 5)
{
chip->rss_tl_shift[0] = (tl >> 3);
chip->rss_tl_shift[2] = chip->rss_tl_shift[1];
}
int dbg_load = ((chip->reg_test_12[1] & 16) != 0 && chip->rss_cnt1[1] == 5)
|| ((chip->reg_test_12[1] & 8) != 0 && chip->rss_cnt1[1] == 1);
if (chip->aclk1)
{
int load = chip->rss_cnt1[1] == 5 && tl != 63;
chip->rss_multi_ctrl[0] = chip->rss_multi_ctrl[1] >> 1;
if (load)
{
chip->rss_multi_ctrl[0] |= (15 - (tl & 7)) << 1;
}
chip->rss_sample_load = chip->rss_cnt1[1] == 5;
chip->rss_sample_shift_load = chip->rss_cnt1[1] == 0;
int add1 = 0;
if (chip->rss_multi_ctrl[1] & 1)
{
add1 = chip->rss_sample;
if (add1 & 0x800)
add1 |= 0x1000;
}
int add2 = 0;
if (chip->rss_cnt1[1] != 5)
{
add2 = chip->rss_multi_accum[1] >> 1;
if (add2 & 0x800)
add2 |= 0x1000;
}
chip->rss_multi_accum[0] = (add1 + add2) & 0x1fff;
chip->rss_dbg_load = dbg_load;
}
if (chip->aclk2)
{
chip->rss_multi_ctrl[1] = chip->rss_multi_ctrl[0];
chip->rss_multi_accum[1] = chip->rss_multi_accum[0];
}
if (chip->rss_cnt1[1] == 5 && !chip->rss_sample_load)
{
chip->rss_sample = chip->rss_regs[1][16] & 0xfff;
chip->rss_multi_accum_load = chip->rss_multi_accum[1];
}
if (chip->rss_cnt1[1] == 0 && !chip->rss_sample_shift_load)
{
int sample = chip->rss_multi_accum_load;
if (sample & 0x1000)
sample |= ~0x1fff;
chip->rss_sample_shift = sample >> chip->rss_tl_shift[2];
}
if (dbg_load && !chip->rss_dbg_load)
{
#ifdef FMOPNA_YM2608
chip->rss_dbg_data = chip->rss_regs[1][16] | (chip->rss_isend << 15);
#else
chip->rss_dbg_data = chip->rss_regs[1][16] & 0xfff;
#endif
}
if (chip->rss_eclk1)
{
chip->write3_trig1 = chip->write3_trig0;
chip->write3_l[1] = chip->write3_l[0];
}
if (chip->rss_eclk2)
{
chip->write3_l[0] = chip->write3_trig1;
chip->write3_l[2] = chip->write3_l[1];
}
chip->write3_en = chip->write3_l[0] && !chip->write3_l[2];
if (chip->rss_eclk1)
{
if (chip->ic)
{
chip->rss_keydm[0] = 0;
chip->rss_keymask[0] = 0;
}
else
{
#ifdef FMOPNA_YM2608
int key_write = chip->write3_en && chip->addr_10[1] && (chip->data_bus1 & 0x100) == 0;
#else
int key_write = chip->write3_en && chip->addr_00[1] && (chip->data_bus1 & 0x100) != 0;
#endif
if (key_write)
{
chip->rss_keydm[0] = (chip->data_bus1 & 0x80) != 0;
chip->rss_keymask[0] = chip->data_bus1 & 0x3f;
}
else
{
chip->rss_keydm[0] = chip->rss_keydm[1];
chip->rss_keymask[0] = chip->rss_keymask[1];
}
}
int mask = chip->rss_keymask[1] & (1 << chip->rss_cnt2[1]);
int key_event = mask != 0;
chip->rss_keymask[0] &= ~mask;
int kon_event = key_event && !chip->rss_keydm[1];
int koff_event = key_event && chip->rss_keydm[1];
chip->rss_ic[0] = (chip->rss_ic[1] << 1) | chip->ic;
int ic = chip->ic || (chip->rss_ic[1] & 0x3f) != 0;
int key = (chip->rss_key[1] & 0x20) != 0;
int key_next = !ic && !koff_event && (key || kon_event);
chip->rss_key[0] = (chip->rss_key[1] << 1) | key_next;
int stop = (chip->rss_stop[1] & 0x20) != 0;
int eos = chip->rss_eos_l && !(chip->reg_test_12[1] & 16);
int stop_next = !kon_event && (stop || ic || koff_event || eos);
chip->rss_stop[0] = (chip->rss_stop[1] << 1) | stop_next;
#ifdef FMOPNA_YM2610
chip->rss_stop_flag[0] = 0;
if (!stop && eos)
chip->rss_stop_flag[0] |= 1 << chip->rss_cnt2[1];
#endif
}
if (chip->rss_eclk2)
{
chip->rss_keydm[1] = chip->rss_keydm[0];
chip->rss_keymask[1] = chip->rss_keymask[0];
chip->rss_ic[1] = chip->rss_ic[0];
chip->rss_key[1] = chip->rss_key[0];
chip->rss_stop[1] = chip->rss_stop[0];
#ifdef FMOPNA_YM2610
chip->rss_stop_flag[1] = chip->rss_stop_flag[0];
#endif
}
#ifdef FMOPNA_YM2608
if (chip->rss_cnt1[1] == 0)
{
chip->rss_eos_l = chip->rss_isend;
chip->rss_step = (chip->rss_ix & 1) == 0;
}
#endif
#ifdef FMOPNA_YM2610
if (chip->aclk1)
chip->rss_eos_load = chip->rss_cnt1[1] == 0;
if (chip->rss_cnt1[1] == 0 && !chip->rss_eos_load)
{
chip->rss_eos_l = (chip->rss_ix >> 1) == ((chip->rss_params_stop[2] << 8) | 0xff);
chip->rss_nibble = chip->rss_rad_bus;
if (chip->rss_ix & 1)
chip->rss_nibble &= 15;
else
chip->rss_nibble >>= 4;
}
#endif
static const int rss_delta[64] = {
16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66,
73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411,
1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552, 1552
};
static const int rss_adjust[8] = {
63, 63, 63, 63, 2, 5, 7, 9
};
#ifdef FMOPNA_YM2608
static const int rss_start[8] = {
0, 0x1c0, 0x440, 0x1b80, 0x1d00, 0x1f80, 0, 0
};
#endif
{
if (chip->aclk1)
{
int mask = chip->rss_keymask[1] & (1 << chip->rss_cnt2[1]);
int key_event = mask != 0;
int kon_event = key_event && !chip->rss_keydm[1];
int koff_event = key_event && chip->rss_keydm[1];
int eos = chip->rss_eos_l && !(chip->reg_test_12[1] & 16);
int stop = (chip->rss_stop[1] & 0x20) != 0;
int nibble = chip->rss_nibble;
int adjust = rss_adjust[chip->rss_nibble & 7];
if (chip->reg_test_12[1] & 16)
{
nibble = 4;
adjust = 1;
}
int c5 = chip->rss_cnt1[1] == 2;
int c6 = chip->rss_cnt1[1] == 3 || chip->rss_cnt1[1] == 4;
int c8 = (!kon_event && chip->rss_cnt1[1] == 0) || (!kon_event && chip->rss_cnt1[1] == 1)
|| (chip->rss_cnt1[1] == 5 && !eos && !kon_event && !(chip->reg_test_12[1] & 16));
int c0 = !kon_event && !eos && (nibble & 8) != 0 && chip->rss_cnt1[1] == 5
#ifdef FMOPNA_YM2608
&& chip->rss_step
#endif
;
int c1 = !kon_event && !eos && (nibble & 8) == 0 && chip->rss_cnt1[1] == 5
#ifdef FMOPNA_YM2608
&& chip->rss_step
#endif
;
int c2 = !kon_event && chip->rss_cnt1[1] == 1
#ifdef FMOPNA_YM2608
&& chip->rss_step
#endif
;
int c3 = kon_event && chip->rss_cnt1[1] == 0;
int c4 = !kon_event && !eos && !stop && chip->rss_cnt1[1] == 0;
int c7 = (chip->rss_cnt1[1] == 2 && (nibble & 1) != 0) || (chip->rss_cnt1[1] == 3 && (nibble & 2) != 0)
|| (chip->rss_cnt1[1] == 4 && (nibble & 4) != 0);
int delta = rss_delta[chip->rss_delta_ix];
// c5 c6 c8
// c0 c1 c2 c3 c4 c7
int carry = c4 || c0;
int add1 = 0;
int add2 = 0;
if (c7)
{
add1 |= delta;
}
if (c1)
{
add1 |= chip->rss_accum[1] & 0xfff;
}
if (c0)
{
add1 |= (chip->rss_accum[1] & 0xfff) ^ 0xfff;
}
if (c2)
{
add1 |= adjust;
}
if (c3)
{
#ifdef FMOPNA_YM2608
add1 |= rss_start[chip->rss_cnt2[1]] << 2;
#else
add1 |= (chip->rss_params_start[2] & 0xfff) << 9;
#endif
}
#ifdef FMOPNA_YM2608
if (c4)
{
if (chip->rss_cnt2[1] == 0 || chip->rss_cnt2[1] == 1 || chip->rss_cnt2[1] == 2 || chip->rss_cnt2[1] == 3)
add1 |= 1;
}
#endif
if (c8)
{
add2 |= chip->rss_regs[1][16];
}
if (c6)
{
add2 |= (chip->rss_accum[1] >> 1) & 0x7ff;
}
if (c5)
{
add2 |= delta >> 1;
}
#ifdef FMOPNA_YM2608
chip->rss_accum[0] = (add1 + add2 + carry) & 0x7fff;
#else
chip->rss_accum[0] = (add1 + add2 + carry) & 0x1fffff;
#endif
chip->rss_delta_ix_load = chip->rss_cnt1[1] == 5;
chip->rss_ix_load = chip->rss_cnt1[1] == 1;
chip->rss_cnt1_is1 = chip->rss_cnt1[1] == 1;
}
if (chip->aclk2)
{
chip->rss_accum[1] = chip->rss_accum[0];
if (chip->rss_cnt1_is1)
{
if ((chip->rss_accum[0] & 0x3f) == 0x3f)
chip->rss_accum[1] &= ~0x3f;
if ((chip->rss_accum[0] & 0x38) == 0x30 || (chip->rss_accum[0] & 0x3c) == 0x38)
chip->rss_accum[1] &= ~0xf;
}
}
if (chip->rss_cnt1[1] == 5 && !chip->rss_delta_ix_load)
{
chip->rss_delta_ix = chip->rss_regs[1][14] & 63;
}
#ifdef FMOPNA_YM2608
if (chip->rss_cnt1[1] == 1 && !chip->rss_ix_load)
{
chip->rss_ix = chip->rss_regs[1][14] & 0x7fff;
int ix = chip->rss_ix >> 2;
chip->rss_isend = ix == 0x1bf || ix == 0x43f ||
ix == 0x1b7f || ix == 0x1cff ||
ix == 0x1f7f || ix == 0x1fff;
}
if (chip->rss_cnt1[1] == 0)
{
chip->rss_nibble = rss_rom[(chip->rss_ix >> 2) & 0x1fff];
if (chip->rss_ix & 2)
chip->rss_nibble >>= 4;
else
chip->rss_nibble &= 15;
}
#endif
#ifdef FMOPNA_YM2610
if (chip->rss_cnt1[1] == 1 && !chip->rss_ix_load)
{
chip->rss_ix = chip->rss_regs[1][14] & 0x1fffff;
}
#endif
if (chip->rss_fclk1)
{
memcpy(&chip->rss_regs[0][1], &chip->rss_regs[1][0], 16 * sizeof(int));
chip->rss_regs[0][0] = chip->rss_accum[1];
}
if (chip->rss_fclk2)
{
memcpy(&chip->rss_regs[1][0], &chip->rss_regs[0][0], 17 * sizeof(int));
}
}
if (chip->rss_cnt1[1] == 5)
{
chip->rss_pan[0] = (chip->rss_params[1] >> 6) & 3;
chip->rss_pan[2] = chip->rss_pan[1];
}
if (chip->rss_cnt1[1] == 3)
{
chip->rss_pan[1] = chip->rss_pan[0];
}
#ifdef FMOPNA_YM2610
int is1_2 = chip->rss_cnt1[1] == 1 || chip->rss_cnt1[1] == 2;
if (chip->aclk1)
{
chip->rss_rmpx[0] = is1_2;
chip->rss_roe[0] = chip->rss_rmpx[1];
chip->rss_roe[2] = chip->rss_roe[1];
}
if (chip->aclk2)
{
chip->rss_rmpx[1] = chip->rss_rmpx[0];
chip->rss_roe[1] = chip->rss_roe[0];
chip->rss_roe[3] = chip->rss_roe[2];
}
chip->o_rmpx = chip->rss_rmpx[1];
chip->o_roe = !chip->rss_roe[1];
int io_dir = is1_2 || chip->rss_roe[1];
if (io_dir)
{
chip->rss_rad_bus = is1_2 ? (chip->rss_ix >> 1) & 255 : (chip->rss_ix >> 11) & 255;
}
else
{
chip->rss_rad_bus = chip->input.rad;
}
chip->o_ra8 = is1_2 ? (chip->rss_ix >> 9) & 3 : (chip->rss_ix >> 19) & 3;
chip->o_ra20 = chip->rss_params_start_h;
chip->o_rad = chip->rss_rad_bus;
chip->o_rad_d = !io_dir;
#endif
}
// adpcm-b
{
if (chip->write2)
{
#ifdef FMOPNA_YM2608
chip->ad_is0 = (chip->data_bus1 & 0xff) == 0x0;
chip->ad_is1 = (chip->data_bus1 & 0xff) == 0x1;
chip->ad_is2 = (chip->data_bus1 & 0xff) == 0x2;
chip->ad_is3 = (chip->data_bus1 & 0xff) == 0x3;
chip->ad_is4 = (chip->data_bus1 & 0xff) == 0x4;
chip->ad_is5 = (chip->data_bus1 & 0xff) == 0x5;
chip->ad_is6 = (chip->data_bus1 & 0xff) == 0x6;
chip->ad_is7 = (chip->data_bus1 & 0xff) == 0x7;
chip->ad_is8 = (chip->data_bus1 & 0xff) == 0x8;
chip->ad_is9 = (chip->data_bus1 & 0xff) == 0x9;
chip->ad_isa = (chip->data_bus1 & 0xff) == 0xa;
chip->ad_isb = (chip->data_bus1 & 0xff) == 0xb;
chip->ad_isc = (chip->data_bus1 & 0xff) == 0xc;
chip->ad_isd = (chip->data_bus1 & 0xff) == 0xd;
chip->ad_ise = (chip->data_bus1 & 0xff) == 0xe;
chip->ad_isf = (chip->data_bus1 & 0xff) == 0xf;
#else
chip->ad_is0 = (chip->data_bus1 & 0xff) == 0x10;
chip->ad_is1 = (chip->data_bus1 & 0xff) == 0x11;
chip->ad_is2 = (chip->data_bus1 & 0xff) == 0x12;
chip->ad_is3 = (chip->data_bus1 & 0xff) == 0x13;
chip->ad_is4 = (chip->data_bus1 & 0xff) == 0x14;
chip->ad_is5 = (chip->data_bus1 & 0xff) == 0x15;
chip->ad_is9 = (chip->data_bus1 & 0xff) == 0x19;
chip->ad_isa = (chip->data_bus1 & 0xff) == 0x1a;
chip->ad_isb = (chip->data_bus1 & 0xff) == 0x1b;
#endif
}
if (chip->ic)
{
#ifdef FMOPNA_YM2608
chip->ad_reg_spoff = 0;
chip->ad_reg_memdata = 0;
chip->ad_reg_rec = 0;
chip->ad_reg_rom = 0;
chip->ad_reg_ramtype = 0;
chip->ad_reg_da_ad = 0;
chip->ad_reg_sample = 0;
#endif
chip->ad_reg_reset = 0;
chip->ad_reg_repeat = 0;
chip->ad_reg_start = 0;
chip->ad_reg_r = 0;
chip->ad_reg_l = 0;
}
else if (chip->write3)
{
if (chip->ad_is0)
{
#ifdef FMOPNA_YM2608
chip->ad_reg_spoff = (chip->data_bus1 >> 3) & 1;
chip->ad_reg_memdata = (chip->data_bus1 >> 5) & 1;
chip->ad_reg_rec = (chip->data_bus1 >> 6) & 1;
#endif
chip->ad_reg_reset = (chip->data_bus1 >> 0) & 1;
chip->ad_reg_repeat = (chip->data_bus1 >> 4) & 1;
chip->ad_reg_start = (chip->data_bus1 >> 7) & 1;
}
if (chip->ad_is1)
{
#ifdef FMOPNA_YM2608
chip->ad_reg_rom = (chip->data_bus1 >> 0) & 1;
chip->ad_reg_ramtype = (chip->data_bus1 >> 1) & 1;
chip->ad_reg_da_ad = (chip->data_bus1 >> 2) & 1;
chip->ad_reg_sample = (chip->data_bus1 >> 3) & 1;
#endif
chip->ad_reg_r = (chip->data_bus1 >> 6) & 1;
chip->ad_reg_l = (chip->data_bus1 >> 7) & 1;
}
}
if (chip->write3)
{
if (chip->ad_is9)
{
chip->ad_reg_delta_l = chip->data_bus1 & 255;
}
if (chip->ad_isa)
{
chip->ad_reg_delta_h = chip->data_bus1 & 255;
}
if (chip->ad_is2)
{
chip->ad_reg_start_l = chip->data_bus1 & 255;
}
if (chip->ad_is3)
{
chip->ad_reg_start_h = chip->data_bus1 & 255;
}
if (chip->ad_is4)
{
chip->ad_reg_stop_l = chip->data_bus1 & 255;
}
if (chip->ad_is5)
{
chip->ad_reg_stop_h = chip->data_bus1 & 255;
}
if (chip->ad_isb)
{
chip->ad_reg_level = chip->data_bus1 & 255;
}
#ifdef FMOPNA_YM2608
if (chip->ad_isc)
{
chip->ad_reg_limit_l = chip->data_bus1 & 255;
}
if (chip->ad_isd)
{
chip->ad_reg_limit_h = chip->data_bus1 & 255;
}
if (chip->ad_is6)
{
chip->ad_reg_prescale_l = chip->data_bus1 & 255;
}
if (chip->ad_is7)
{
chip->ad_reg_prescale_h = chip->data_bus1 & 7;
}
if (chip->ad_ise)
{
chip->ad_da_data = (chip->data_bus1 & 255) ^ 128;
}
#endif
}
int reset = chip->ad_reg_reset || chip->ic;
#ifdef FMOPNA_YM2608
int mode1 = chip->ad_reg_memdata && chip->ad_reg_rec && !chip->ad_start_l[2]
&& (chip->ad_w2_l[1] & 16) != 0
&& (chip->ad_write_port_l[1] & 4) != 0; // cpu->mem
int mode2 = !chip->ad_start_l[2] && (chip->ad_w2_l[1] & 16) != 0;
int mode3 = !chip->ad_reg_memdata && !chip->ad_start_l[2];
int mode4 = chip->ad_reg_memdata && chip->ad_start_l[2]
&& (chip->ad_w2_l[1] & 16) != 0;
int mode5 = chip->ad_reg_memdata && chip->ad_reg_rec && chip->ad_start_l[2]; // enc->mem
int mode6 = chip->ad_reg_memdata && !chip->ad_reg_rec && chip->ad_start_l[2]; // mem->dec
int mode7 = !chip->ad_reg_ramtype && chip->ad_reg_rom && chip->ad_reg_memdata
&& !chip->ad_reg_rec && !chip->ad_start_l[2] && (chip->ad_w2_l[1] & 16) != 0
&& (chip->ad_read_port_l[1] & 4) != 0; // mem(rom)->cpu
int mode8 = !chip->ad_reg_memdata && !chip->ad_reg_rec && chip->ad_start_l[2]
&& (chip->ad_write_port_l[1] & 4) != 0; // cpu->dec
int mode9 = chip->ad_reg_ramtype && !chip->ad_reg_rom && chip->ad_reg_memdata
&& !chip->ad_reg_rec && !chip->ad_start_l[2] && (chip->ad_w2_l[1] & 16) != 0
&& (chip->ad_read_port_l[1] & 4) != 0; // mem(8bit)->cpu
int mode10 = !chip->ad_reg_memdata && chip->ad_reg_rec && chip->ad_start_l[2]
&& (chip->ad_read_port_l[1] & 4) != 0; // enc->cpu
int mode11 = !chip->ad_reg_ramtype && !chip->ad_reg_rom && chip->ad_reg_memdata
&& !chip->ad_reg_rec && !chip->ad_start_l[2] && (chip->ad_w2_l[1] & 16) != 0
&& (chip->ad_read_port_l[1] & 4) != 0; // mem(1bit)->cpu
#else
int mode6 = chip->ad_start_l[2];
#endif
int code_end = chip->ad_code_end[1] && (chip->ad_w2_l[1] & 16) != 0;
int repeat = chip->ad_reg_repeat && code_end && !chip->ad_code_ed_end[1];
#ifdef FMOPNA_YM2608
int w28 = repeat || (!chip->ad_mode6_l[1] && mode6);
int w6 = mode7 || mode9 || (w28 &&
((!chip->ad_reg_rom && chip->ad_reg_ramtype)
|| (!chip->ad_reg_ramtype && chip->ad_reg_rom)));
int sync = chip->ad_mem_sync_run || !chip->ad_mem_w20[1];
int w16 = !chip->ad_mem_w10[1] && sync;
int w18 = !(chip->ad_mem_w17[1] && (sync || !chip->ad_reg_memdata));
int p5 = (chip->ad_code_ctrl_l & 1) != 0 && !chip->ad_reg_rec && chip->ad_start_l[2] && (w16 || !chip->ad_reg_memdata);
int w19 = !(w18 && chip->ad_start_l[2] && !p5);
int p1 = chip->ad_reg_rec && w16 && w19 && chip->ad_reg_memdata && chip->ad_mem_w15[1];
int p2 = !chip->ad_reg_rec && w16 && w19 && chip->ad_reg_memdata && chip->ad_mem_w15[1];
int p3 = chip->ad_reg_rec && !w18;
int p4 = (!chip->ad_reg_rec && (w16 || !chip->ad_reg_memdata) && !w18) || p5;
int w23 = p1 || p2;
int w24 = (p4 && !chip->ad_reg_memdata) || (!chip->ad_start_l[2] && p1);
int w25 = p2 || p3;
int w26 = mode5 && !chip->ad_rec_start_l[1];
int w27 = mode11 || (!chip->ad_reg_rom && w28 && !chip->ad_reg_ramtype);
int w29 = w28 || w26 || mode10 || mode8; // start dsp
#else
int w28 = repeat || (!chip->ad_mode6_l[1] && mode6);
int w16 = !chip->ad_mem_w10[1];
int w18 = !chip->ad_mem_w17[1];
int p5 = (chip->ad_code_ctrl_l & 1) != 0 && chip->ad_start_l[2] && w16;
int w19 = !(w18 && !p5);
int p2 = w16 && w19 && chip->ad_mem_w15[1];
int p4 = (w16 && !w18) || p5;
int w23 = p2;
int w29 = w28; // start dsp
#endif
if (chip->cclk1)
{
#ifdef FMOPNA_YM2608
chip->ad_sample_l[1] = chip->ad_sample_l[0];
int read_sample = chip->read3 && chip->ad_is8;
int write_sample = chip->write3 && chip->ad_is8;
chip->ad_read_port_l[0] = (chip->ad_read_port_l[1] << 1) | read_sample;
chip->ad_write_port_l[0] = (chip->ad_write_port_l[1] << 1) | write_sample;
chip->ad_rw_l[1] = chip->ad_rw_l[0];
int w3 = chip->ad_addr_isend_l && chip->ad_reg_rec;
#endif
chip->ad_start_l[1] = chip->ad_start_l[0];
int t1 = !chip->ad_addr_isend_l2[1] || chip->ad_addr_isend_l;
#ifdef FMOPNA_YM2608
chip->ad_w2[0] = (chip->ad_w2[1] && t1) || (chip->ad_rw_en && chip->ad_w4[1])
|| (t1 && (reset || w3 || (chip->ad_w4[1] && chip->ad_start_l[2])));
chip->ad_w4[0] = (chip->ad_w4[1] && t1) || w3 || (chip->ad_addr_isend_l && p2);
#else
chip->ad_w2[0] = (chip->ad_w2[1] && t1)
|| (t1 && (reset || (chip->ad_w4[1] && chip->ad_start_l[2])));
chip->ad_w4[0] = (chip->ad_w4[1] && t1) || (chip->ad_addr_isend_l && p2);
#endif
chip->ad_w2_l[0] = (chip->ad_w2_l[1] << 1) | chip->ad_w2[1];
chip->ad_addr_isend_l2[0] = chip->ad_addr_isend_l;
#ifdef FMOPNA_YM2608
int t2 = mode2 || mode3 || mode4;
#else
int t2 = (chip->ad_w2_l[1] & 16) != 0;
#endif
chip->ad_w12[0] = chip->ad_w12[1] << 1;
chip->ad_w12[0] |= t2;
chip->ad_w13[0] = (chip->ad_w12[1] & 3) == 1;
chip->ad_mode6_l[0] = mode6;
chip->ad_code_ed_end[0] = code_end;
}
if (chip->cclk2)
{
#ifdef FMOPNA_YM2608
chip->ad_sample_l[0] = chip->ad_reg_sample;
chip->ad_sample_l[2] = chip->ad_sample_l[1];
chip->ad_read_port_l[1] = chip->ad_read_port_l[0];
chip->ad_write_port_l[1] = chip->ad_write_port_l[0];
chip->ad_rw_l[0] = chip->ad_rw_l[1] << 1;
chip->ad_rw_l[0] |= (chip->ad_read_port_l[0] & 1) != 0 || (chip->ad_write_port_l[0] & 1) != 0;
chip->ad_rw_en = (chip->ad_rw_l[0] & 1) == 0 && (chip->ad_rw_l[0] & 2) != 0;
chip->ad_rec_start_l[1] = chip->ad_rec_start_l[0];
#endif
chip->ad_start_l[0] = chip->ad_reg_start;
chip->ad_start_l[2] = chip->ad_start_l[1];
chip->ad_w2[1] = chip->ad_w2[0];
chip->ad_w4[1] = chip->ad_w4[0];
chip->ad_w2_l[1] = chip->ad_w2_l[0];
chip->ad_addr_isend_l = chip->ad_stop_match2[0];
chip->ad_addr_isend_l2[1] = chip->ad_addr_isend_l2[0];
chip->ad_w12[1] = chip->ad_w12[0];
chip->ad_w13[1] = chip->ad_w13[0];
chip->ad_mode6_l[1] = chip->ad_mode6_l[0];
chip->ad_code_ed_end[1] = chip->ad_code_ed_end[0];
}
#ifdef FMOPNA_YM2608
int cond = 0;
if (chip->cclk1)
{
if (chip->ic || (chip->ad_mem_ctrl_l & 64) != 0)
chip->ad_mem_sync[0] = 0;
else
chip->ad_mem_sync[0] = (chip->ad_mem_sync[1] + chip->ad_mem_sync_run) & 63;
int next_ptr = 0;
chip->ad_mem_ctrl = 0;
int cond_next = 0;
if (mode1)
{
cond_next |= 1;
}
if (w26)
{
cond_next |= 2;
}
if (w27)
{
cond_next |= 4;
}
if (w6)
{
cond_next |= 8;
}
if (w23)
{
cond_next |= 16;
}
if (sync)
{
cond = chip->ad_mem_cond[1];
}
else
{
cond_next |= chip->ad_mem_cond[1];
}
if ((cond & 15) == 0)
cond |= 32;
chip->ad_mem_cond[0] = cond_next;
int store_addr = 0;
#if 0
if ((chip->ad_mem_code_ptr[1] & 0x2f) == 0xf)
{
next_ptr |= 0;
chip->ad_mem_ctrl |= 0;
}
#endif
// common code
switch (chip->ad_mem_code_ptr[1] & 0xf)
{
case 0x0:
chip->ad_mem_ctrl |= 0b00100000000000;
break;
case 0x1:
chip->ad_mem_ctrl |= 0b00100000000000;
break;
case 0x2:
chip->ad_mem_ctrl |= 0b00100000000000;
break;
case 0x3:
chip->ad_mem_ctrl |= 0b10011000000000;
break;
case 0x4:
chip->ad_mem_ctrl |= 0b10111000010000;
break;
case 0x5:
chip->ad_mem_ctrl |= 0b11010000000000;
break;
case 0x6:
chip->ad_mem_ctrl |= 0b11110000000000;
break;
case 0x7:
chip->ad_mem_ctrl |= 0b11000000000001;
break;
case 0x8:
chip->ad_mem_ctrl |= 0b11100000000001;
break;
}
switch (chip->ad_mem_code_ptr[1])
{
case 0x9:
chip->ad_mem_ctrl |= 0b11100000000010;
break;
case 0xa:
chip->ad_mem_ctrl |= 0b11000010000000;
break;
case 0xb:
chip->ad_mem_ctrl |= 0b00000110000000;
break;
case 0xd:
if (sync)
{
if (chip->ad_stop_match2[1])
{
next_ptr |= 0x3f|0x40;
}
if (!chip->ad_mem_w22)
{
next_ptr |= 0x4|0x40;
chip->ad_mem_ctrl |= 0b10011000000000;
}
if ((cond & 16) == 0 && chip->ad_mem_w22)
{
next_ptr |= 0xd|0x40;
}
if ((cond & 16) != 0 && chip->ad_mem_w22)
{
next_ptr |= 0x4|0x40;
chip->ad_mem_ctrl |= 0b10011000000000;
}
}
else
{
next_ptr = 0x3a | 0x40;
chip->ad_mem_ctrl |= 0b00100000000000;
store_addr = 1;
}
break;
case 0x19:
chip->ad_mem_ctrl |= 0b00100100001000;
break;
case 0x1b:
if (sync)
{
if (chip->ad_stop_match2[1])
{
next_ptr |= 0x3f|0x40;
}
if (!chip->ad_mem_w22)
{
next_ptr |= 0x14|0x40;
chip->ad_mem_ctrl |= 0b10011000000000;
}
if ((cond & 16) == 0 && chip->ad_mem_w22)
{
next_ptr |= 0x1b|0x40;
}
if ((cond & 16) != 0 && chip->ad_mem_w22)
{
next_ptr |= 0x14|0x40;
chip->ad_mem_ctrl |= 0b10011000000000;
}
}
else
{
next_ptr = 0x3a | 0x40;
chip->ad_mem_ctrl |= 0b00100000000000;
store_addr = 1;
}
break;
case 0x29:
chip->ad_mem_ctrl |= 0b00100000000100;
break;
case 0x2b:
if (sync)
{
if (chip->ad_stop_match2[1])
{
next_ptr |= 0x3f|0x40;
}
if ((cond & 16) == 0)
{
next_ptr |= 0x2b|0x40;
}
if ((cond & 16) != 0)
{
next_ptr |= 0x24|0x40;
chip->ad_mem_ctrl |= 0b10011000000000;
}
}
else
{
next_ptr = 0x3a | 0x40;
chip->ad_mem_ctrl |= 0b00100000000000;
store_addr = 1;
}
break;
case 0x3a:
chip->ad_mem_ctrl |= 0b00100000000000;
break;
case 0x3b:
chip->ad_mem_ctrl |= 0b00100000000000;
break;
case 0x3c:
chip->ad_mem_ctrl |= 0b10011000000000;
break;
case 0x3d:
chip->ad_mem_ctrl |= 0b00111001000000;
break;
case 0x2f:
if (sync)
{
if ((cond & 16) == 0)
{
next_ptr = 0x2f | 0x40;
}
else
{
next_ptr = 0x0 | 0x40;
chip->ad_mem_ctrl |= 0b00100000100000;
}
}
else
{
next_ptr = 0x3a | 0x40;
chip->ad_mem_ctrl |= 0b00100000000000;
store_addr = 1;
}
break;
case 0x3f:
if (sync)
{
if (cond & 1)
{
next_ptr |= 0x0 | 0x40;
chip->ad_mem_ctrl = 0b00100000100000;
}
if (cond & 2)
{
next_ptr |= 0x2f | 0x40;
}
if (cond & 4)
{
next_ptr |= 0x10 | 0x40;
chip->ad_mem_ctrl = 0b00100000100000;
}
if (cond & 8)
{
next_ptr |= 0x20 | 0x40;
chip->ad_mem_ctrl = 0b00100000100000;
}
if (cond & 32)
{
next_ptr |= 0x3f | 0x40;
}
}
else
{
next_ptr = 0x3a | 0x40;
chip->ad_mem_ctrl |= 0b00100000000000;
store_addr = 1;
}
break;
}
if ((chip->ad_mem_ctrl_l & 64) != 0)
{
next_ptr |= chip->ad_mem_ptr_store | 0x40;
}
if (chip->ic)
{
next_ptr |= 0x3f | 0x40;
}
if (next_ptr & 64)
chip->ad_mem_code_ptr[0] = next_ptr & 63;
else
chip->ad_mem_code_ptr[0] = (chip->ad_mem_code_ptr[1] + 1) & 63;
if (store_addr)
chip->ad_mem_ptr_store = chip->ad_mem_code_ptr[1];
}
if (chip->cclk2)
{
chip->ad_mem_code_ptr[1] = chip->ad_mem_code_ptr[0];
chip->ad_mem_ctrl_l = chip->ad_mem_ctrl;
chip->ad_mem_cond[1] = chip->ad_mem_cond[0];
chip->ad_mem_sync[1] = chip->ad_mem_sync[0];
chip->ad_mem_sync_run = (chip->ad_mem_sync[0] & 40) != 40;
}
if (chip->cclk1)
{
chip->ad_end_sel[0] = chip->ad_end_sel[1];
int stop_val = 0;
int limit_val = 0;
if (chip->ad_end_sel[1] & 1)
{
stop_val |= ((chip->ad_reg_stop_l & 15) << 5) | 31;
limit_val |= ((chip->ad_reg_limit_l & 15) << 5) | 31;
}
if (chip->ad_end_sel[1] & 4)
{
stop_val |= ((chip->ad_reg_stop_h & 31) << 4) | ((chip->ad_reg_stop_l >> 4) & 15);
limit_val |= ((chip->ad_reg_limit_h & 31) << 4) | ((chip->ad_reg_limit_l >> 4) & 15);
}
if (chip->ad_end_sel[1] & 8)
{
stop_val |= (chip->ad_reg_stop_h >> 5) & 7;
limit_val |= (chip->ad_reg_limit_h >> 5) & 7;
}
chip->ad_stop_match[0] = chip->ad_stop_match[1] << 1;
if (stop_val == chip->ad_address_cnt[3][1])
chip->ad_stop_match[0] |= 1;
chip->ad_limit_match[0] = chip->ad_limit_match[1] << 1;
if (limit_val == chip->ad_address_cnt[3][1])
chip->ad_limit_match[0] |= 1;
int rst = (chip->ad_mem_cond[1] & 2) != 0 || (chip->ad_start_sel[1] & 1) != 0;
int stop_match = (chip->ad_stop_match[0] & 11) == 11 && (chip->ad_end_sel[1] & 8) != 0;
chip->ad_stop_match2[0] = ((stop_match || chip->ad_stop_match2[1])
&& !rst) || reset;
chip->ad_limit_match2[0] = (chip->ad_limit_match[0] & 11) == 11 && (chip->ad_end_sel[1] & 8) != 0;
chip->ad_start_sel[0] = chip->ad_start_sel[1];
int start_val = 0;
if (chip->ad_start_sel[1] & 1)
start_val |= ((chip->ad_reg_start_l & 15) << 5);
if (chip->ad_start_sel[1] & 2)
start_val |= ((chip->ad_reg_start_h & 31) << 4) | ((chip->ad_reg_start_l >> 4) & 15);
if (chip->ad_start_sel[1] & 4)
start_val |= (chip->ad_reg_start_h >> 5) & 7;
chip->ad_address_cnt[0][0] = 0;
chip->ad_address_cnt[1][0] = 0;
chip->ad_address_cnt[2][0] = 0;
chip->ad_address_cnt[3][0] = 0;
int add = chip->ad_address_cnt[3][1];
if ((chip->ad_mem_ctrl_l & 0x200) != 0 || chip->ad_address_carry[1])
add++;
int carry = ((add >> 9) & 1) != 0 && (chip->ad_mem_ctrl_l & 0x40) == 0;
add &= 0x1ff;
if (!chip->ad_limit_match2[1])
{
if (chip->ad_mem_ctrl_l & 0x800)
{
if ((chip->ad_start_sel[1] & 7) != 0)
chip->ad_address_cnt[0][0] = start_val;
else
chip->ad_address_cnt[0][0] = add;
chip->ad_address_cnt[1][0] = chip->ad_address_cnt[0][1];
chip->ad_address_cnt[2][0] = chip->ad_address_cnt[1][1];
}
else if (!chip->ic)
{
chip->ad_address_cnt[0][0] = chip->ad_address_cnt[0][1];
chip->ad_address_cnt[1][0] = chip->ad_address_cnt[1][1];
chip->ad_address_cnt[2][0] = chip->ad_address_cnt[2][1];
}
}
if (chip->ad_mem_ctrl_l & 0x800)
{
chip->ad_address_cnt[3][0] = chip->ad_address_cnt[2][1];
}
else if (!chip->ic)
{
chip->ad_address_cnt[3][0] = chip->ad_address_cnt[3][1];
}
if (chip->ad_mem_ctrl_l & 0x800)
chip->ad_address_carry[0] = carry;
else
chip->ad_address_carry[0] = chip->ad_address_carry[1];
}
if (chip->cclk2)
{
chip->ad_end_sel[1] = chip->ad_end_sel[0] << 1;
if (chip->ad_mem_ctrl & 16)
chip->ad_end_sel[1] |= 1;
chip->ad_start_sel[1] = chip->ad_start_sel[0] << 1;
if (chip->ad_mem_ctrl & 32)
chip->ad_start_sel[1] |= 1;
chip->ad_stop_match[1] = chip->ad_stop_match[0];
chip->ad_limit_match[1] = chip->ad_limit_match[0];
chip->ad_stop_match2[1] = chip->ad_stop_match2[0];
chip->ad_limit_match2[1] = chip->ad_limit_match2[0];
chip->ad_address_cnt[0][1] = chip->ad_address_cnt[0][0];
chip->ad_address_cnt[1][1] = chip->ad_address_cnt[1][0];
chip->ad_address_cnt[2][1] = chip->ad_address_cnt[2][0];
chip->ad_address_cnt[3][1] = chip->ad_address_cnt[3][0];
chip->ad_address_carry[1] = chip->ad_address_carry[0];
}
if (chip->cclk1)
{
if (chip->ad_mem_ctrl_l & 1)
chip->ad_mem_addr_bank = chip->ad_address_cnt[3][1] & 7;
int t1 = 0;
if (chip->ad_mem_ctrl_l & 1)
{
t1 |= chip->ad_mem_bus & 254;
t1 |= chip->input.dt0;
}
if (chip->ad_mem_ctrl_l & 2)
{
if (chip->ad_reg_ramtype)
{
t1 |= chip->ad_mem_data_l2;
}
else
{
if (chip->ad_mem_data_l2 & (1 << chip->ad_mem_bit_cnt[1]))
t1 |= 255;
}
}
if (((chip->ad_mem_ctrl_l & 2) != 0 && chip->ad_reg_ramtype) || (chip->ad_mem_ctrl_l & 1) != 0)
{
chip->ad_mem_data_l1 = t1;
}
else if (chip->ad_mem_ctrl_l & 2)
{
int mask = 1 << chip->ad_mem_addr_bank;
chip->ad_mem_data_l1 &= ~mask;
chip->ad_mem_data_l1 |= mask & t1;
}
if (chip->ad_mem_ctrl_l & 32)
chip->ad_mem_bit_cnt[0] = 0;
else
{
int add = !chip->ad_reg_ramtype && (chip->ad_mem_ctrl_l & 0x100) != 0;
chip->ad_mem_bit_cnt[0] = (chip->ad_mem_bit_cnt[1] + add) & 7;
}
int t2 = 0;
if (p1)
{
t2 |= chip->ad_mem_data_bus;
}
if (chip->ad_mem_ctrl_l & 4)
{
t2 |= chip->ad_mem_data_l1;
}
if (chip->ad_mem_ctrl_l & 8)
{
if (chip->ad_mem_data_l1 & (1 << chip->ad_mem_addr_bank))
t2 |= 255;
}
if ((chip->ad_mem_ctrl_l & 4) != 0 || p1)
{
chip->ad_mem_data_l2 = t2;
}
else if (chip->ad_mem_ctrl_l & 8)
{
int mask = 1 << chip->ad_mem_bit_cnt[1];
chip->ad_mem_data_l2 &= ~mask;
chip->ad_mem_data_l2 |= mask & t2;
}
int t4;
if (p4)
t4 = chip->ad_mem_data_bus;
else if (chip->ad_mem_w7[1])
t4 = ((chip->ad_mem_data_l4[1] & 127) << 1) | !chip->ad_dsp_enc_bit;
else
t4 = chip->ad_mem_data_l4[1];
chip->ad_mem_data_l4[0] = t4;
chip->ad_mem_w7[0] = (chip->ad_code_ctrl_l & 0x1000) != 0;
chip->ad_mem_w8[0] = (chip->ad_code_ctrl_l & 0x800) != 0;
int add = chip->ad_mem_shift_cnt[1] + chip->ad_mem_w7[1];
int of = (add & 8) != 0;
if (!chip->ad_start_l[2])
chip->ad_mem_shift_cnt[0] = 0;
else
chip->ad_mem_shift_cnt[0] = add & 7;
chip->ad_mem_shift_cnt0_l[0] = (chip->ad_mem_shift_cnt[1] & 3) == 0;
int mem_en = chip->ad_start_l[2] && chip->ad_reg_memdata;
chip->ad_mem_mem_en_l[0] = mem_en;
int w9 = (mem_en && !chip->ad_mem_mem_en_l[1] && !chip->ad_reg_rec) ||
(!chip->ad_reg_memdata && chip->ad_start_l[2]) ||
repeat ||
w23;
chip->ad_mem_mem_stop[0] = !mem_en && chip->ad_mem_mem_en_l[1];
int w11 = reset || chip->ad_mem_mem_stop[1] || chip->ad_w13[1] || chip->ad_mem_w21;
chip->ad_mem_w10[0] = w9 || (chip->ad_mem_w10[1] && !w11);
int w14 = reset || chip->ad_mem_mem_stop[1] || chip->ad_w13[1] || w16 || (!chip->ad_reg_memdata && (p3 || p4));
chip->ad_mem_w15[0] = (mem_en || chip->ad_rw_en) || (chip->ad_mem_w15[1] && !w14);
chip->ad_brdy_set_l[0] = chip->ad_reg_memdata ? (!chip->ad_mem_w15[1] && w16)
: !chip->ad_mem_w15[1];
chip->ad_mem_w17[0] = of || (chip->ad_mem_w17[1] && w18);
chip->ad_mem_rw_en[0] = chip->ad_mem_rw_en[1] << 1;
chip->ad_mem_rw_en[0] |= chip->ad_rw_en;
chip->ad_mem_w20[0] = ((chip->ad_mem_rw_en[1] & 2) != 0 || chip->ad_start_l[2] || reset) ||
(chip->ad_mem_w20[1] && (cond & 32) != 0);
if (chip->ad_mem_ctrl_l & 32)
chip->ad_mem_ucnt[0] = 0;
else
{
int inc = !chip->ad_reg_ramtype && (chip->ad_mem_ctrl_l & 0x100) != 0;
chip->ad_mem_ucnt[0] = (chip->ad_mem_ucnt[1] + inc) & 7;
}
chip->ad_mem_we[0] = (chip->ad_mem_ctrl_l & 0x80) != 0;
chip->ad_mem_cas[0] = (chip->ad_mem_ctrl_l & 0x1000) != 0;
chip->ad_mem_ras[0] = (chip->ad_mem_ctrl_l & 0x2000) != 0;
}
if (chip->cclk2)
{
chip->ad_mem_bit_cnt[1] = chip->ad_mem_bit_cnt[0];
chip->ad_mem_data_l4[1] = chip->ad_mem_data_l4[0];
chip->ad_mem_w7[1] = chip->ad_mem_w7[0];
chip->ad_mem_w8[1] = chip->ad_mem_w8[0];
chip->ad_mem_shift_cnt[1] = chip->ad_mem_shift_cnt[0];
chip->ad_mem_shift_cnt0_l[1] = chip->ad_mem_shift_cnt0_l[0];
chip->ad_mem_mem_en_l[1] = chip->ad_mem_mem_en_l[0];
chip->ad_mem_mem_stop[1] = chip->ad_mem_mem_stop[0];
chip->ad_mem_w10[1] = chip->ad_mem_w10[0];
chip->ad_mem_w15[1] = chip->ad_mem_w15[0];
chip->ad_brdy_set_l[1] = chip->ad_brdy_set_l[0];
chip->ad_mem_w17[1] = chip->ad_mem_w17[0];
chip->ad_mem_rw_en[1] = chip->ad_mem_rw_en[0];
chip->ad_mem_ucnt[1] = chip->ad_mem_ucnt[0];
chip->ad_mem_w20[1] = chip->ad_mem_w20[0];
chip->ad_mem_w21 = (chip->ad_mem_ctrl & 4) != 0 ||
(chip->ad_reg_ramtype && (chip->ad_mem_ctrl & 0x100) != 0) ||
(!chip->ad_reg_ramtype && (chip->ad_mem_ctrl & 0x100) != 0 && chip->ad_mem_ucnt[0] == 7);
chip->ad_mem_w22 = chip->ad_mem_ucnt[0] == 0;
chip->ad_mem_we[1] = chip->ad_mem_we[0];
chip->ad_mem_cas[1] = chip->ad_mem_cas[0];
chip->ad_mem_ras[1] = chip->ad_mem_ras[0];
chip->ad_mem_dir = (chip->ad_mem_ctrl & 0x80) != 0 || (chip->ad_mem_ctrl & 0x400) != 0;
}
{
int nibble_load;
if (chip->ad_reg_rec)
nibble_load = (chip->ad_mem_shift_cnt[1] & 3) == 0 && !chip->ad_mem_shift_cnt0_l[1];
else
nibble_load = (chip->ad_mem_shift_cnt[1] & 3) == 0 && chip->ad_mem_w7[1];
if (chip->cclk1)
chip->ad_mem_nibble_load = nibble_load;
if (nibble_load && !chip->ad_mem_nibble_load)
{
int nibble;
if (chip->ad_reg_rec)
nibble = (chip->ad_mem_data_l4[1] & 15) ^ 8;
else
nibble = (chip->ad_mem_data_l4[1] >> 4) & 15;
chip->ad_mem_nibble = nibble;
}
chip->ad_mem_nibble_msb = chip->ad_mem_w8[1] && (chip->ad_mem_nibble & 8) != 0;
}
int write8 = chip->ad_is8 && chip->write3;
int read8 = chip->ad_is8 && chip->read3;
if (write8 || w25)
{
int t3 = 0;
if (write8)
t3 |= chip->data_bus1 & 255;
if (w25)
t3 |= chip->ad_mem_data_bus;
chip->ad_mem_data_l3 = t3;
}
if (read8)
{
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ad_mem_data_l3 & 255;
}
if (!chip->ad_mem_dir)
chip->ad_mem_bus = chip->input.dm;
if (chip->ad_mem_ctrl_l & 0x400)
chip->ad_mem_bus = chip->ad_address_cnt[3][1];
if (chip->ad_mem_ctrl_l & 0x80)
{
chip->ad_mem_bus &= ~255;
chip->ad_mem_bus = chip->ad_mem_data_l1;
}
if (p2)
chip->ad_mem_data_bus = chip->ad_mem_data_l2;
if (w24)
chip->ad_mem_data_bus = chip->ad_mem_data_l3;
if (p3)
chip->ad_mem_data_bus = chip->ad_mem_data_l4[1] ^ 0x88;
#else
if (chip->cclk1)
{
int next_ptr = 0;
chip->ad_mem_ctrl = 0;
chip->ad_mem_cond[0] = 0;
if (p2)
chip->ad_mem_cond[0] |= 1;
if (w29)
chip->ad_mem_cond[0] |= 2;
switch (chip->ad_mem_code_ptr[1])
{
case 0x0:
chip->ad_mem_ctrl = 0b00100000;
break;
case 0x1:
chip->ad_mem_ctrl = 0b01010000;
break;
case 0x2:
chip->ad_mem_ctrl = 0b01110100;
break;
case 0x3:
chip->ad_mem_ctrl = 0b00010000;
break;
case 0x4:
chip->ad_mem_ctrl = 0b00110000;
break;
case 0x5:
chip->ad_mem_ctrl = 0b10000000;
break;
case 0x6:
chip->ad_mem_ctrl = 0b10000001;
break;
case 0x7:
chip->ad_mem_ctrl = 0b00000010;
break;
case 0x9:
if (chip->ad_stop_match2[1])
next_ptr = 0xf | 0x10;
if ((chip->ad_mem_cond[1] & 1) == 0)
next_ptr |= 0x9 | 0x10;
else
{
chip->ad_mem_ctrl = 0b01010000;
next_ptr |= 0x2 | 0x10;
}
break;
case 0xf:
if ((chip->ad_mem_cond[1] & 2) != 0)
{
chip->ad_mem_ctrl = 0b00101000;
next_ptr = 0x0 | 0x10;
}
else
next_ptr = 0xf | 0x10;
break;
}
if (chip->ic)
{
next_ptr |= 0xf | 0x10;
}
if (next_ptr & 0x10)
chip->ad_mem_code_ptr[0] = next_ptr & 0xf;
else
chip->ad_mem_code_ptr[0] = (chip->ad_mem_code_ptr[1] + 1) & 0xf;
}
if (chip->cclk2)
{
chip->ad_mem_code_ptr[1] = chip->ad_mem_code_ptr[0];
chip->ad_mem_ctrl_l = chip->ad_mem_ctrl;
chip->ad_mem_cond[1] = chip->ad_mem_cond[0];
}
if (chip->cclk1)
{
chip->ad_end_sel[0] = chip->ad_end_sel[1];
int stop_val;
if (chip->ad_end_sel[1] & 1)
{
stop_val = ((chip->ad_reg_stop_l & 15) << 8) | 0xff;
}
else
{
stop_val = (chip->ad_reg_stop_h << 4) | ((chip->ad_reg_stop_l >> 4) & 15);
}
chip->ad_stop_match[0] = chip->ad_stop_match[1] << 1;
if (stop_val == chip->ad_address_cnt[1][1])
chip->ad_stop_match[0] |= 1;
int rst = (chip->ad_start_sel[1] & 1) != 0;
int stop_match = (chip->ad_stop_match[0] & 5) == 5 && (chip->ad_end_sel[1] & 4) != 0;
chip->ad_stop_match2[0] = ((stop_match || chip->ad_stop_match2[1])
&& !rst) || reset;
chip->ad_start_sel[0] = chip->ad_start_sel[1];
if (chip->ad_mem_ctrl_l & 0x20)
{
int add = chip->ad_address_cnt[1][1];
if ((chip->ad_mem_ctrl_l & 0x40) != 0 || chip->ad_address_carry[1])
add++;
int carry = ((add >> 12) & 1) != 0;
add &= 0xfff;
int start_val;
if (chip->ad_start_sel[1] & 1)
start_val = ((chip->ad_reg_start_l & 15) << 8);
else if (chip->ad_start_sel[1] & 2)
start_val = (chip->ad_reg_start_h << 4) | ((chip->ad_reg_start_l >> 4) & 15);
else
start_val = add;
chip->ad_address_cnt[0][0] = start_val;
chip->ad_address_cnt[1][0] = chip->ad_address_cnt[0][1];
chip->ad_address_carry[0] = carry;
}
else
{
chip->ad_address_cnt[0][0] = chip->ad_address_cnt[0][1];
chip->ad_address_cnt[1][0] = chip->ad_address_cnt[1][1];
chip->ad_address_carry[0] = chip->ad_address_carry[1];
}
}
if (chip->cclk2)
{
chip->ad_end_sel[1] = chip->ad_end_sel[0] << 1;
if (chip->ad_mem_ctrl & 4)
chip->ad_end_sel[1] |= 1;
chip->ad_start_sel[1] = chip->ad_start_sel[0] << 1;
if (chip->ad_mem_ctrl & 8)
chip->ad_start_sel[1] |= 1;
chip->ad_stop_match[1] = chip->ad_stop_match[0];
chip->ad_stop_match2[1] = chip->ad_stop_match2[0];
chip->ad_address_cnt[0][1] = chip->ad_address_cnt[0][0];
chip->ad_address_cnt[1][1] = chip->ad_address_cnt[1][0];
chip->ad_address_carry[1] = chip->ad_address_carry[0];
}
if (chip->cclk1)
{
int t4;
if (p4)
t4 = chip->ad_mem_data_l3;
else if (chip->ad_mem_w7[1])
t4 = (chip->ad_mem_data_l4[1] & 127) << 1;
else
t4 = chip->ad_mem_data_l4[1];
chip->ad_mem_data_l4[0] = t4;
chip->ad_mem_w7[0] = (chip->ad_code_ctrl_l & 0x1000) != 0;
chip->ad_mem_w8[0] = (chip->ad_code_ctrl_l & 0x800) != 0;
int add = chip->ad_mem_shift_cnt[1] + chip->ad_mem_w7[1];
int of = (add & 8) != 0;
if (!chip->ad_start_l[2])
chip->ad_mem_shift_cnt[0] = 0;
else
chip->ad_mem_shift_cnt[0] = add & 7;
int mem_en = chip->ad_start_l[2];
chip->ad_mem_mem_en_l[0] = mem_en;
int w9 = (mem_en && !chip->ad_mem_mem_en_l[1]) ||
repeat ||
w23;
chip->ad_mem_mem_stop[0] = !mem_en && chip->ad_mem_mem_en_l[1];
int w11 = reset || chip->ad_mem_mem_stop[1] || chip->ad_w13[1] || chip->ad_mem_w21;
chip->ad_mem_w10[0] = w9 || (chip->ad_mem_w10[1] && !w11);
int w14 = reset || chip->ad_mem_mem_stop[1] || chip->ad_w13[1] || w16;
chip->ad_mem_w15[0] = mem_en || (chip->ad_mem_w15[1] && !w14);
chip->ad_mem_w17[0] = of;
chip->ad_mem_pmpx[0] = (chip->ad_mem_ctrl_l & 0x40) != 0;
chip->ad_mem_poe[0] = (chip->ad_mem_ctrl_l & 0x80) != 0;
}
if (chip->cclk2)
{
chip->ad_mem_data_l4[1] = chip->ad_mem_data_l4[0];
chip->ad_mem_w7[1] = chip->ad_mem_w7[0];
chip->ad_mem_w8[1] = chip->ad_mem_w8[0];
chip->ad_mem_shift_cnt[1] = chip->ad_mem_shift_cnt[0];
chip->ad_mem_mem_en_l[1] = chip->ad_mem_mem_en_l[0];
chip->ad_mem_mem_stop[1] = chip->ad_mem_mem_stop[0];
chip->ad_mem_w10[1] = chip->ad_mem_w10[0];
chip->ad_mem_w15[1] = chip->ad_mem_w15[0];
chip->ad_mem_w17[1] = chip->ad_mem_w17[0];
chip->ad_mem_w21 = (chip->ad_mem_ctrl & 2) != 0;
chip->ad_mem_dir = (chip->ad_mem_ctrl & 0x10) != 0;
chip->ad_mem_pmpx[1] = chip->ad_mem_pmpx[0];
chip->ad_mem_poe[1] = chip->ad_mem_poe[0];
}
{
int nibble_load = (chip->ad_mem_shift_cnt[0] & 3) == 0 && chip->ad_mem_w7[0];
if (chip->cclk2)
chip->ad_mem_nibble_load = nibble_load;
if (nibble_load && !chip->ad_mem_nibble_load)
chip->ad_mem_nibble = (chip->ad_mem_data_l4[1] >> 4) & 15;;
chip->ad_mem_nibble_msb = chip->ad_mem_w8[1] && (chip->ad_mem_nibble & 8) != 0;
}
if (chip->ad_mem_ctrl_l & 0x10)
chip->ad_mem_bus = chip->ad_address_cnt[1][1] & 0xff;
if (!chip->ad_mem_dir)
chip->ad_mem_bus = chip->input.pad;
if ((chip->ad_mem_ctrl & 1) != 0 && (chip->ad_mem_ctrl_l & 1) == 0)
chip->ad_mem_data_l3 = chip->ad_mem_bus;
#endif
if (chip->cclk1)
{
#ifdef FMOPNA_YM2608
#define PLAYBACK_BIT 0x40
#else
#define PLAYBACK_BIT 0x00
#endif
int w44 = (chip->ad_dsp_cnt1_run[1] & 3) == 0;
int next_ptr = 0;
chip->ad_code_ctrl = 0;
int carry_mode = 0;
int vol_o = 0;
switch (chip->ad_code_ptr[1])
{
#ifdef FMOPNA_YM2608
case 0x3f:
#endif
case 0x3f|PLAYBACK_BIT:
if (w29)
{
chip->ad_code_ctrl = 0b000100000011110011001;
next_ptr = 0x32;
}
else
next_ptr = 0x3f;
break;
#ifdef FMOPNA_YM2608
case 0x32:
#endif
case 0x32|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000001110111001;
break;
#ifdef FMOPNA_YM2608
case 0x33:
#endif
case 0x33|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000110111101;
break;
#ifdef FMOPNA_YM2608
case 0x34:
#endif
case 0x34|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000110011011;
break;
#ifdef FMOPNA_YM2608
case 0x35:
#endif
case 0x35|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000110111011;
break;
#ifdef FMOPNA_YM2608
case 0x36:
#endif
case 0x36|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000010011100;
break;
#ifdef FMOPNA_YM2608
case 0x3b:
next_ptr = 0x31;
break;
#endif
case 0x37|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000110011111;
break;
case 0x38|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000110111111;
break;
case 0x39|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000000000110011001;
break;
case 0x3a|PLAYBACK_BIT:
if (!p5)
{
next_ptr = 0x3a;
chip->ad_code_ctrl = 0b000000000000110011001;
}
break;
case 0x3b|PLAYBACK_BIT:
if (chip->ad_code_sync[2])
{
chip->ad_code_ctrl = 0b000000100010110010000;
next_ptr = 0x7;
}
else
next_ptr = 0x3b;
break;
#ifdef FMOPNA_YM2608
case 0x01:
chip->ad_code_ctrl = 0b000011000010000000000;
break;
case 0x02:
chip->ad_code_ctrl = 0b000010001000110010000;
break;
case 0x03:
chip->ad_code_ctrl = 0b001110000000000000010;
break;
case 0x04:
chip->ad_code_ctrl = 0b000110000000000100010;
break;
case 0x05:
if (chip->ad_dsp_enc_bit_l[1])
chip->ad_code_ctrl = 0b100011000000010000010;
else
{
chip->ad_code_ctrl = 0b100010100000000000010;
next_ptr = 0xa;
}
break;
case 0x06:
chip->ad_code_ctrl = 0b100010000000000100010;
break;
case 0x07:
chip->ad_code_ctrl = 0b001110000000000000010;
break;
case 0x08:
chip->ad_code_ctrl = 0b000110000000000100010;
break;
case 0x09:
chip->ad_code_ctrl = 0b100010100000000000010;
break;
case 0x0a:
chip->ad_code_ctrl = 0b100010000000000100010;
break;
case 0x0b:
chip->ad_code_ctrl = 0b100011000000000000100;
break;
case 0x0c:
chip->ad_code_ctrl = 0b100010001000000100100;
break;
case 0x0e:
chip->ad_code_ctrl = 0b000000000000010000000;
break;
case 0x0f:
if (chip->ad_dsp_enc_bit_l[1])
{
next_ptr = 0x13;
chip->ad_code_ctrl = 0b100000100000000000000;
}
break;
case 0x10:
chip->ad_code_ctrl = 0b011100100000000000000;
break;
case 0x11:
chip->ad_code_ctrl = 0b000100000000010110000;
break;
case 0x12:
next_ptr = 0x15;
break;
case 0x13:
chip->ad_code_ctrl = 0b100000000000010110000;
break;
case 0x15:
chip->ad_code_ctrl = 0b011001000000000000000;
break;
case 0x17:
chip->ad_code_ctrl = 0b100010100000100010010;
break;
case 0x18:
chip->ad_code_ctrl = 0b100010001000100110010;
break;
case 0x1a:
chip->ad_code_ctrl = 0b000000000000010000000;
break;
case 0x1b:
if (chip->ad_dsp_enc_bit_l[1])
{
next_ptr = 0x20;
chip->ad_code_ctrl = 0b100001000000000000100;
}
else
chip->ad_code_ctrl = 0b000000000000100010000;
break;
case 0x1c:
chip->ad_code_ctrl = 0b000000000000100010000;
break;
case 0x1d:
chip->ad_code_ctrl = 0b001100000000100010000;
break;
case 0x1e:
chip->ad_code_ctrl = 0b000100000000000100000;
break;
case 0x1f:
chip->ad_code_ctrl = 0b100001000000000000100;
break;
case 0x20:
chip->ad_code_ctrl = 0b100000000000000100100;
break;
case 0x21:
if (!chip->ad_dsp_alu_mask[1] && chip->ad_dsp_alu_shift == 2)
chip->ad_code_ctrl = 0b000000000000000011000;
else
{
next_ptr = 0x13;
chip->ad_code_ctrl = 0b100000100000000000000;
}
break;
case 0x22:
chip->ad_code_ctrl = 0b100000000000010010100;
break;
case 0x23:
chip->ad_code_ctrl = 0b100000000000000100100;
break;
case 0x24:
chip->ad_code_ctrl = 0b100000100000000000000;
break;
case 0x25:
chip->ad_code_ctrl = 0b100000000000000100000;
break;
case 0x26:
chip->ad_code_ctrl = 0b001100000000000000000;
break;
case 0x27:
chip->ad_code_ctrl = 0b000100000000000100000;
break;
case 0x28:
chip->ad_code_ctrl = 0b100001000000110010000;
break;
case 0x29:
chip->ad_code_ctrl = 0b100000000100000100000;
break;
case 0x2a:
chip->ad_code_ctrl = 0b000000100110100011000;
break;
case 0x2b:
chip->ad_code_ctrl = 0b000000000100000000000;
break;
case 0x2c:
chip->ad_code_ctrl = 0b001000000111000000000;
break;
case 0x2d:
chip->ad_code_ctrl = 0b000000000001000000000;
break;
case 0x2e:
chip->ad_code_ctrl = 0b000100000000001000100;
break;
case 0x2f:
chip->ad_code_ctrl = 0b000100000000000100100;
break;
case 0x31:
if (chip->ad_w12[1] & 1)
next_ptr = 0x3f;
if (chip->ad_ad_w56)
{
next_ptr |= 1;
chip->ad_code_ctrl = 0b000010010000100001000;
}
else
next_ptr |= 0x31;
break;
#endif
case 0x01|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000000000110110010;
break;
case 0x02|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000001000000000001000;
break;
case 0x03|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000000000100000000;
break;
case 0x04|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b001100000000100000010;
break;
case 0x05|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000100100010;
break;
case 0x06|PLAYBACK_BIT:
if (chip->ad_dsp_alu_of)
chip->ad_code_ctrl = 0b000000100010110010000;
else
{
next_ptr = 0x24;
chip->ad_code_ctrl = 0b100000000000010101010;
}
break;
case 0x08|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100001000000000000000;
break;
case 0x09|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000000000000100000;
break;
case 0x0a|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b011000001011000000000;
break;
case 0x0b|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000000001010000000;
break;
case 0x0c|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000000000000011000;
break;
case 0x0d|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100001001000000000100;
if (chip->ad_mem_data_l4[0] & 128)
chip->ad_code_ctrl |= 0b000000100000000000000;
break;
case 0x0e|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000000000010110100;
break;
case 0x0f|PLAYBACK_BIT:
if ((chip->ad_mem_data_l4[0] & 128) == 0)
chip->ad_code_ctrl = 0b000000000000000010000;
break;
case 0x10|PLAYBACK_BIT:
if ((chip->ad_mem_data_l4[0] & 128) == 0)
chip->ad_code_ctrl = 0b000000000000000010000;
break;
case 0x11|PLAYBACK_BIT:
case 0x15|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b011000101000100011000;
break;
case 0x12|PLAYBACK_BIT:
case 0x16|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000000000010010000;
break;
case 0x13|PLAYBACK_BIT:
if ((chip->ad_mem_data_l4[0] & 128) == 0)
chip->ad_code_ctrl = 0b000000000000000010000;
break;
case 0x14|PLAYBACK_BIT:
if ((chip->ad_mem_data_l4[0] & 128) == 0)
chip->ad_code_ctrl = 0b000000000000000010000;
break;
case 0x18|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b011001000000010010000;
break;
case 0x1a|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000100100010010110;
carry_mode = 1;
break;
case 0x1b|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000000100000100110;
carry_mode = 1;
break;
case 0x1c|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b001100000100000000000;
carry_mode = 1;
break;
case 0x1d|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000100000100000;
carry_mode = 1;
break;
case 0x1e|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000000100010000000;
break;
case 0x1f|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b001100000100000000110;
break;
case 0x20|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000000100110;
break;
case 0x21|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000001000100;
break;
case 0x22|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000100000000000100100;
break;
case 0x23|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000000000010101010;
break;
case 0x24|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000000000000000000;
break;
case 0x25|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b100000000000000100000;
break;
case 0x26|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000100010000000000;
break;
case 0x29|PLAYBACK_BIT:
if (!w44)
next_ptr = 0x29;
else
chip->ad_code_ctrl = 0b000001000000111010000;
break;
case 0x2b|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b000000000000110001000;
vol_o = 1;
break;
case 0x2c|PLAYBACK_BIT:
chip->ad_code_ctrl = 0b001000000000000000000;
break;
case 0x2f|PLAYBACK_BIT:
if (chip->ad_w12[1] & 1)
next_ptr = 0x3f;
if (chip->ad_code_sync[2])
{
next_ptr |= 1;
chip->ad_code_ctrl = 0b100000100000000000010;
}
else
next_ptr |= 0x2f;
break;
}
#ifdef FMOPNA_YM2608
if (!chip->ad_reg_rec)
next_ptr |= 64; // dec/enc
#endif
if (reset)
next_ptr |= 63; // reset
if (next_ptr & 63)
chip->ad_code_ptr[0] = next_ptr;
else
#ifdef FMOPNA_YM2608
chip->ad_code_ptr[0] = (chip->ad_code_ptr[1] + 1) & 127;
#else
chip->ad_code_ptr[0] = (chip->ad_code_ptr[1] + 1) & 63;
#endif
chip->ad_code_end[0] = (chip->ad_code_ptr[1] & 63) == 63;
chip->ad_dsp_carry_mode[0] = carry_mode;
#ifdef FMOPNA_YM2608
chip->ad_dsp_enc_bit_l[0] = chip->ad_dsp_enc_bit;
#endif
chip->ad_dsp_vol_o[0] = vol_o;
}
if (chip->cclk2)
{
chip->ad_code_ptr[1] = chip->ad_code_ptr[0];
chip->ad_code_end[1] = chip->ad_code_end[0];
chip->ad_code_ctrl_l = chip->ad_code_ctrl;
chip->ad_dsp_ctrl = 0;
if (chip->ad_code_ctrl & 8)
chip->ad_dsp_ctrl |= 1;
if (chip->ad_code_ctrl & 16)
chip->ad_dsp_ctrl |= 2;
if (chip->ad_code_ctrl & 0x80)
chip->ad_dsp_ctrl |= 4;
if (chip->ad_code_ctrl & 0x100)
chip->ad_dsp_ctrl |= 8;
chip->ad_dsp_carry_mode[1] = chip->ad_dsp_carry_mode[0];
#ifdef FMOPNA_YM2608
chip->ad_dsp_enc_bit_l[1] = chip->ad_dsp_enc_bit_l[0];
#endif
chip->ad_code_reg_id = 0;
if (chip->ad_code_ctrl & 32)
chip->ad_code_reg_id |= 1;
if (chip->ad_code_ctrl & 4)
chip->ad_code_reg_id |= 2;
if (chip->ad_code_ctrl & 2)
chip->ad_code_reg_id |= 4;
chip->ad_dsp_vol_o[1] = chip->ad_dsp_vol_o[0];
}
int w30 = chip->ad_dsp_ctrl == 5 || chip->ad_dsp_ctrl == 13;
int w31 = chip->ad_dsp_ctrl == 5 || chip->ad_dsp_ctrl == 13
|| chip->ad_dsp_ctrl == 3;
int w35 = chip->ad_dsp_w36[1];
if ((chip->ad_dsp_w31_l[1] & 2) != 0)
w35 |= chip->ad_dsp_w33;
int cnt1;
if ((chip->ad_dsp_w31_l[1] & 2) != 0)
cnt1 = 0;
else
{
int inc = (chip->ad_dsp_cnt1_run[1] & 1) != 0;
cnt1 = (chip->ad_dsp_cnt1[1] + inc) & 7;
}
if (chip->ad_dsp_ctrl == 1)
chip->ad_dsp_bus = chip->ad_reg_delta_l;
if (chip->ad_dsp_delta_sel[1])
chip->ad_dsp_bus = chip->ad_reg_delta_h;
if ((chip->ad_code_ctrl_l & 0x40) != 0)
chip->ad_dsp_bus = chip->ad_dsp_w45 & 255;
if (chip->ad_dsp_w46[1])
chip->ad_dsp_bus = (chip->ad_dsp_w45 >> 8) & 255;
if (chip->ad_dsp_ctrl == 3)
{
static const int adjust[8] = {
57, 57, 57, 57, 77, 102, 128, 153
};
chip->ad_dsp_bus = adjust[chip->ad_mem_nibble & 7];
}
if ((chip->ad_code_ctrl_l & 0x40000) != 0)
chip->ad_dsp_bus = chip->ad_dsp_alu_res & 255;
if (chip->ad_dsp_read_res[1])
chip->ad_dsp_bus = (chip->ad_dsp_alu_res >> 8) & 255;
#ifdef FMOPNA_YM2608
if ((chip->ad_code_ctrl_l & 0x2000) != 0)
chip->ad_dsp_bus = chip->ad_ad_buf;
#endif
if (chip->ad_dsp_vol_o[1])
chip->ad_dsp_bus = chip->ad_reg_level;
if ((chip->ad_code_ctrl_l & 0x200) == 0 && chip->ad_dsp_w69[1])
chip->ad_dsp_bus = chip->ad_dsp_sregs2[0][1];
if ((chip->ad_code_ctrl_l & 0x200) == 0 && (chip->ad_code_ctrl_l & 0x400) != 0)
chip->ad_dsp_bus = chip->ad_dsp_sregs2[1][1];
if (chip->ad_dsp_ctrl == 7)
chip->ad_dsp_bus = 127;
if (chip->ad_dsp_ctrl == 15)
chip->ad_dsp_bus = 0;
if (chip->cclk1)
{
chip->ad_dsp_delta_sel[0] = chip->ad_dsp_ctrl == 1;
chip->ad_dsp_w30_l[0] = chip->ad_dsp_w30_l[1] << 1;
chip->ad_dsp_w30_l[0] |= w30;
chip->ad_dsp_w31_l[0] = chip->ad_dsp_w31_l[1] << 1;
chip->ad_dsp_w31_l[0] |= w31;
chip->ad_dsp_w36[0] = w35 >> 1;
chip->ad_dsp_w35_l = w35 & 1;
chip->ad_dsp_cnt1[0] = cnt1;
chip->ad_dsp_cnt1_run[0] = chip->ad_dsp_cnt1_run[1];
int accm2 = chip->ad_dsp_mul_accm2_add1 + chip->ad_dsp_mul_accm2_add2 + chip->ad_dsp_mul_accm1_c;
chip->ad_dsp_mul_accm1_add1 = (w35 & 1) != 0 ? chip->ad_dsp_w34 : 0;
chip->ad_dsp_mul_accm1_add2 = cnt1 != 0 ? (chip->ad_dsp_mul_accm1[0] >> 1) | ((accm2 & 1) << 7) : 0;
chip->ad_dsp_mul_accm1[1] = chip->ad_dsp_mul_accm1[0];
chip->ad_dsp_w32_l = chip->ad_dsp_w32;
chip->ad_dsp_mul_accm2_load = cnt1 != 0;
chip->ad_dsp_mul_accm2 = accm2 & 0x1ff;
chip->ad_dsp_w38[0] = chip->ad_dsp_w38[1] << 1;
if (cnt1 != 0 && (chip->ad_dsp_mul_accm1[0] & 1) != 0)
chip->ad_dsp_w38[0] |= 1;
chip->ad_dsp_w41[0] = chip->ad_dsp_w41[1] << 1;
if (chip->ad_dsp_ctrl == 11)
chip->ad_dsp_w41[0] |= 1;
chip->ad_dsp_w43[0] = (chip->ad_dsp_w43[1] << 1) | ((chip->ad_dsp_cnt1_run[1] & 3) == 2);
chip->ad_dsp_w46[0] = (chip->ad_code_ctrl_l & 0x40) != 0;
if (chip->ad_dsp_ctrl == 14)
chip->ad_dsp_cnt2[0] = 0;
else
{
int add = chip->ad_dsp_ctrl == 6;
chip->ad_dsp_cnt2[0] = (chip->ad_dsp_cnt2[1] + add) & 3;
}
#ifdef FMOPNA_YM2608
chip->ad_dsp_ctrl10_l = chip->ad_dsp_ctrl == 10;
#endif
chip->ad_dsp_load_alu1[0] = chip->ad_dsp_load_alu1[1] << 1;
chip->ad_dsp_load_alu2[0] = chip->ad_dsp_load_alu2[1] << 1;
chip->ad_dsp_load_alu1_h = (chip->ad_dsp_load_alu1[1] & 1) != 0
#ifdef FMOPNA_YM2608
|| chip->ad_dsp_ctrl == 9
#endif
;
if ((chip->ad_code_ctrl_l & 0x4000) != 0)
chip->ad_dsp_load_alu1[0] |= 1;
if ((chip->ad_code_ctrl_l & 0x8000) != 0)
chip->ad_dsp_load_alu2[0] |= 1;
chip->ad_dsp_load_res[0] = (chip->ad_code_ctrl_l & 0x80000) != 0;
chip->ad_dsp_alu_mask[0] = chip->ad_dsp_ctrl == 2;
#ifdef FMOPNA_YM2608
chip->ad_dsp_alu_neg[0] = (chip->ad_code_ctrl_l & 0x10000) != 0;
#endif
chip->ad_dsp_read_res[0] = (chip->ad_code_ctrl_l & 0x40000) != 0;
chip->ad_dsp_w52[0] = (chip->ad_code_ctrl_l & 0x2000) != 0;
chip->ad_dsp_sregs2[0][0] = (chip->ad_dsp_w69[1] && (chip->ad_code_ctrl_l & 0x200) != 0) ? chip->ad_dsp_bus : chip->ad_dsp_sregs2[0][1];
chip->ad_dsp_sregs2[1][0] = ((chip->ad_code_ctrl_l & 0x400) != 0 && (chip->ad_code_ctrl_l & 0x200) != 0) ? chip->ad_dsp_bus : chip->ad_dsp_sregs2[1][1];
chip->ad_dsp_w69[0] = (chip->ad_code_ctrl_l & 0x400) != 0;
}
if (chip->cclk2)
{
chip->ad_dsp_delta_sel[1] = chip->ad_dsp_delta_sel[0];
chip->ad_dsp_w30_l[1] = chip->ad_dsp_w30_l[0];
chip->ad_dsp_w31_l[1] = chip->ad_dsp_w31_l[0];
chip->ad_dsp_w36[1] = chip->ad_dsp_w36[0];
chip->ad_dsp_cnt1[1] = chip->ad_dsp_cnt1[0];
chip->ad_dsp_cnt1_run[1] = chip->ad_dsp_cnt1_run[0] << 1;
if (chip->ad_dsp_cnt1[0] != 7)
chip->ad_dsp_cnt1_run[1] |= 1;
int accm1 = chip->ad_dsp_mul_accm1_add1 + chip->ad_dsp_mul_accm1_add2;
chip->ad_dsp_mul_accm1_c = (accm1 & 256) != 0;
chip->ad_dsp_mul_accm1[0] = accm1 & 255;
int w37 = (chip->ad_dsp_w38[0] & 2) == 0 && (chip->ad_dsp_mul_accm1[1] & 63) == 0;
int w39 = (chip->ad_dsp_mul_accm1[1] & 192) == 0 && (chip->ad_dsp_mul_accm2 & 511) == 0;
int b8 = (chip->ad_dsp_w32_l & 0x100) == 0 && !(w37 && w39);
chip->ad_dsp_mul_accm2_add1 = chip->ad_dsp_w35_l ? (chip->ad_dsp_w32_l ^ 0x100) : 0;
chip->ad_dsp_mul_accm2_add2 = chip->ad_dsp_mul_accm2_load ? (chip->ad_dsp_mul_accm2 >> 1) | (b8 << 8) : 0;
chip->ad_dsp_w38[1] = chip->ad_dsp_w38[0];
chip->ad_dsp_w41[1] = chip->ad_dsp_w41[0];
int w42 = (chip->ad_dsp_mul_accm2 & 0x1c0) != 0x00 || (chip->ad_dsp_mul_accm2 & 0x30) == 0x30;
if (chip->ad_dsp_w41[0] & 2)
{
chip->ad_dsp_w40 = 0;
if (!w42)
{
if ((chip->ad_dsp_w38[0] & 2) != 0)
chip->ad_dsp_w40 |= 1;
chip->ad_dsp_w40 |= (chip->ad_dsp_mul_accm1[1] & 255) << 1;
chip->ad_dsp_w40 |= (chip->ad_dsp_mul_accm2 & 15) << 9;
}
chip->ad_dsp_w40 |= (chip->ad_dsp_mul_accm2 & 0x30) << 9;
if (w42)
chip->ad_dsp_w40 |= 0x6000;
if (w39)
chip->ad_dsp_w40 |= 127;
}
else
{
chip->ad_dsp_w40 = (chip->ad_dsp_mul_accm1[1] >> 1) & 127;
chip->ad_dsp_w40 |= (chip->ad_dsp_mul_accm2 & 511) << 7;
}
chip->ad_dsp_w43[1] = chip->ad_dsp_w43[0];
chip->ad_dsp_w46[1] = chip->ad_dsp_w46[0];
chip->ad_dsp_cnt2[1] = chip->ad_dsp_cnt2[0];
chip->ad_dsp_load_alu1[1] = chip->ad_dsp_load_alu1[0];
chip->ad_dsp_load_alu2[1] = chip->ad_dsp_load_alu2[0];
chip->ad_dsp_load_res[1] = chip->ad_dsp_load_res[0];
chip->ad_dsp_alu_mask[1] = chip->ad_dsp_alu_mask[0];
chip->ad_dsp_alu_shift =
#ifdef FMOPNA_YM2608
chip->ad_dsp_ctrl10_l ? 0 :
#endif
chip->ad_dsp_cnt2[0];
#ifdef FMOPNA_YM2608
chip->ad_dsp_alu_neg[1] = chip->ad_dsp_alu_neg[0];
#endif
chip->ad_dsp_read_res[1] = chip->ad_dsp_read_res[0];
chip->ad_dsp_w52[1] = chip->ad_dsp_w52[0];
chip->ad_dsp_sregs2[0][1] = chip->ad_dsp_sregs2[0][0];
chip->ad_dsp_sregs2[1][1] = chip->ad_dsp_sregs2[1][0];
chip->ad_dsp_w69[1] = chip->ad_dsp_w69[0];
}
{
int w47 = (chip->ad_code_ctrl_l & 0x100000) != 0;
int w48 = (chip->ad_code_ctrl & 0x100000) != 0 && chip->cclk2;
int w49 = (chip->ad_code_ctrl & 0x100000) == 0 && (chip->ad_code_ctrl_l & 0x20000) != 0;
int w51 = (chip->ad_code_ctrl_l & 0x100000) != 0 && !chip->cclk2;
int reg_id = 0;
if (w49)
{
if (!w51)
{
if (chip->ad_code_reg_id == 0)
{
if (((chip->ad_code_ctrl_l & 0x20000) != 0 || (chip->ad_code_ctrl_l & 0x100000) != 0))
chip->ad_dsp_regs[0] = chip->ad_dsp_bus;
}
else
chip->ad_dsp_regs[chip->ad_code_reg_id] = chip->ad_dsp_bus;
}
}
if (chip->ad_dsp_w52[1])
{
chip->ad_dsp_regs[0] = 0;
chip->ad_dsp_regs[1] = 0;
}
if (w48)
{
if (!w51)
{
chip->ad_dsp_regs_o = chip->ad_dsp_regs[chip->ad_code_reg_id];
}
}
if (w47)
{
chip->ad_dsp_bus = chip->ad_dsp_regs_o;
}
}
#ifdef FMOPNA_YM2608
// FIXME: guesswork
if (chip->ad_ad_w57[2])
chip->ad_ad_cmp_i = chip->ad_comp_da < chip->ad_ad_input;
else
chip->ad_comp_da = chip->input.da;
int w54 = (chip->ad_ad_shift & 1) == 0 && !chip->ad_ad_w53[1];
int w64 = w54 ? (chip->ad_ad_w65_l ^ 127) : chip->ad_ad_w65_l;
int w63 = (w64 + (w54 && chip->ad_ad_w55)) & 127;
if (chip->cclk1)
{
if (chip->ad_ad_cnt3_of[1])
chip->ad_ad_cnt1[0] = 0;
else
{
int inc = chip->ad_ad_w57[2];
chip->ad_ad_cnt1[0] = (chip->ad_ad_cnt1[1] + inc) & 15;
}
chip->ad_ad_w53[0] = chip->ad_ad_w57[2]
? !(w54 || ((chip->ad_ad_shift & 1) != 0 && !chip->ad_ad_cmp_i))
: chip->ad_ad_w53[1];
chip->ad_ad_w55_l[0] = chip->ad_ad_w55;
int rst = chip->ad_ad_w57[2] || chip->ad_ad_cnt3_of[1];
if (rst)
chip->ad_ad_cnt2[0] = 0;
else
{
int inc = chip->ad_ad_w55;
chip->ad_ad_cnt2[0] = (chip->ad_ad_cnt2[1] + inc) & 31;
}
chip->ad_ad_w62[0] = rst;
chip->ad_ad_w57[1] = chip->ad_ad_w57[0];
chip->ad_ad_w58[1] = chip->ad_ad_w58[0];
chip->ad_ad_w61[0] = chip->ad_ad_w61[1] >> 1;
if (chip->ad_ad_w62[1])
{
chip->ad_ad_w61[0] |= w63;
if (!w54)
chip->ad_ad_w61[0] |= 128;
}
int w59 = w54 ^ chip->ad_ad_w60;
chip->ad_ad_w66[0] = chip->ad_ad_w57[2] ? (w59 ? chip->ad_ad_w65_l : chip->ad_ad_w68)
: chip->ad_ad_w66[1];
int inc3 = !chip->ad_ad_cnt3_of[1] && chip->ad_ad_cnt3_en[1];
int cnt3 = chip->ad_ad_cnt3[1] + inc3;
int en = chip->ad_sample_l[2] || chip->ad_start_l[2];
chip->ad_ad_cnt3[0] = cnt3 & 0x7ff;
chip->ad_ad_cnt3_of[0] = (cnt3 & 0x800) != 0;
chip->ad_ad_cnt3_en[0] = en;
chip->ad_ad_cnt3_load = chip->ad_ad_cnt3_of[1] || (en && !chip->ad_ad_cnt3_en[1]);
chip->ad_ad_cnt3_load_val = (chip->ad_reg_prescale_l | (chip->ad_reg_prescale_h << 8)) ^ 0x7ff;
}
if (chip->cclk2)
{
int cnt1 = chip->ad_ad_cnt1[0];
if (chip->ic)
cnt1 |= 8;
int shift = 0;
int shift2 = 0;
if ((cnt1 & 8) == 0)
{
shift = 1 << (cnt1 & 7);
shift2 = 128 >> (cnt1 & 7);
}
chip->ad_ad_shift = shift;
chip->ad_ad_cnt1[1] = cnt1;
chip->ad_ad_w53[1] = chip->ad_ad_w53[0];
chip->ad_ad_w55 = (cnt1 & 8) == 0;
chip->ad_ad_w55_l[1] = chip->ad_ad_w55_l[0];
chip->ad_ad_cnt2[1] = chip->ad_ad_cnt2[0];
chip->ad_ad_w57[0] = chip->ad_ad_cnt2[0] == 23;
chip->ad_ad_w57[2] = chip->ad_ad_w57[1];
chip->ad_ad_w58[0] = (chip->ad_ad_cnt2[0] & 24) == 0;
chip->ad_ad_w58[2] = chip->ad_ad_w58[1];
chip->ad_ad_w61[1] = chip->ad_ad_w61[0];
chip->ad_ad_w62[1] = chip->ad_ad_w62[0];
int w67 = chip->ad_ad_w66[0];
if (shift & 1)
w67 = 0;
int sum = shift2 + w67;
chip->ad_ad_w65_l = sum & 127;
chip->ad_ad_w66[1] = chip->ad_ad_w66[0];
chip->ad_ad_w68 = w67;
chip->ad_ad_cnt3[1] = chip->ad_ad_cnt3[0];
if (chip->ad_ad_cnt3_load)
chip->ad_ad_cnt3[1] |= chip->ad_ad_cnt3_load_val;
chip->ad_ad_cnt3_of[1] = chip->ad_ad_cnt3_of[0];
chip->ad_ad_cnt3_en[1] = chip->ad_ad_cnt3_en[0];
}
if (chip->ad_ad_w57[2])
chip->ad_ad_w60 = chip->ad_ad_cmp_i;
if (!chip->ad_ad_w55)
chip->ad_ad_input = chip->input.ad;
chip->ad_ad_w56 = !chip->ad_ad_w55 && chip->ad_ad_w55_l[1];
if (chip->ad_ad_w56)
{
chip->ad_ad_buf = w63;
if (w54)
chip->ad_ad_buf |= 128;
}
if (chip->ad_isf && chip->read3)
{
chip->data_bus1 &= ~255;
chip->data_bus1 |= chip->ad_ad_buf & 255;
}
#endif
chip->ad_set_eos = chip->ad_w13[1]
#ifdef FMOPNA_YM2608
|| (chip->ad_ad_w56 && chip->ad_sample_l[2])
#endif
;
if (w31 && (chip->ad_dsp_w31_l[0] & 1) == 0)
chip->ad_dsp_w33 = chip->ad_dsp_bus;
if ((chip->ad_dsp_w31_l[1] & 1) != 0 && (chip->ad_dsp_w31_l[0] & 2) == 0)
chip->ad_dsp_w34 = chip->ad_dsp_bus;
if ((chip->ad_dsp_w31_l[1] & 2) != 0 && (chip->ad_dsp_w31_l[0] & 4) == 0)
{
chip->ad_dsp_w32 = chip->ad_dsp_bus;
if ((chip->ad_dsp_w32 & 128) == 0 || (chip->ad_dsp_w30_l[1] & 2) == 0)
chip->ad_dsp_w32 |= 256;
}
if ((chip->ad_dsp_w43[1] & 1) != 0 && (chip->ad_dsp_w43[0] & 2) == 0)
chip->ad_dsp_w45 = chip->ad_dsp_w40;
if ((chip->ad_dsp_w45 >> 3) == 0x1fff || ((chip->ad_dsp_w45 >> 3) & 0x1ffe) == 0)
chip->ad_output = 0;
else
chip->ad_output = chip->ad_dsp_w45 >> 3;
if ((chip->ad_code_ctrl_l & 0x4000) != 0 && (chip->ad_dsp_load_alu1[0] & 1) == 0)
{
chip->ad_dsp_alu_in1 &= ~255;
chip->ad_dsp_alu_in1 |= chip->ad_dsp_bus;
}
if ((chip->ad_code_ctrl_l & 0x8000) != 0 && (chip->ad_dsp_load_alu2[0] & 1) == 0)
{
chip->ad_dsp_alu_in2 &= ~255;
chip->ad_dsp_alu_in2 |= chip->ad_dsp_bus;
}
if (((chip->ad_dsp_load_alu1[1] & 1) != 0
#ifdef FMOPNA_YM2608
|| chip->ad_dsp_ctrl == 9
#endif
) && !chip->ad_dsp_load_alu1_h)
{
chip->ad_dsp_alu_in1 &= ~0xff00;
chip->ad_dsp_alu_in1 |= chip->ad_dsp_bus << 8;
}
if ((chip->ad_dsp_load_alu2[1] & 1) != 0 && (chip->ad_dsp_load_alu2[0] & 2) == 0)
{
chip->ad_dsp_alu_in2 &= ~0xff00;
chip->ad_dsp_alu_in2 |= chip->ad_dsp_bus << 8;
}
if (chip->ad_dsp_ctrl == 4)
chip->ad_dsp_alu_in1 = 0;
#ifdef FMOPNA_YM2608
if (chip->ad_dsp_ctrl == 9)
chip->ad_dsp_alu_in1 &= ~255;
#endif
// alu
{
int i1 = chip->ad_dsp_alu_in1;
int i2;
if (chip->ad_dsp_alu_mask[1])
i2 = 0;
else
i2 = chip->ad_dsp_alu_in2 >> chip->ad_dsp_alu_shift;
int c1 = chip->ad_dsp_carry_mode[1] && (chip->ad_dsp_alu_in2 & 1) != 0;
int c2 = chip->ad_mem_nibble_msb;
int neg =
#ifdef FMOPNA_YM2608
chip->ad_dsp_alu_neg[1] ||
#endif
c2;
int b15_i1 = (i1 & 0x8000) != 0;
int b15_i2 = (i2 & 0x8000) != 0;
if (neg)
i2 = i2 ^ 0xffff;
int carry = !(!neg && (c2 || !c1)) && (!c2 || !c1);
int sum = i1 + i2 + carry;
int of = (sum >> 16) & 1;
sum &= 0xffff;
sum ^= 0x8000;
int b15_s = (sum & 0x8000) != 0;
if ((chip->ad_code_ctrl_l & 0x80000) == 0 && chip->ad_dsp_load_res[1] == 0)
{
int clip_h = (!b15_s && chip->ad_dsp_ctrl != 8 && !neg && !b15_i2 && !b15_i1)
|| (!b15_s && chip->ad_dsp_ctrl != 8 && neg && b15_i2 && !b15_i1);
int clip_l = (b15_s && chip->ad_dsp_ctrl != 8 && !neg && b15_i2 && b15_i1)
|| (b15_s && chip->ad_dsp_ctrl != 8 && neg && !b15_i2 && b15_i1);
chip->ad_dsp_alu_res = clip_h ? 0xffff : (clip_l ? 0 : sum);
chip->ad_dsp_alu_res ^= 0x8000;
}
chip->ad_dsp_alu_of = of;
#ifdef FMOPNA_YM2608
chip->ad_dsp_enc_bit = (b15_i1 && !b15_i2) || (!b15_i1 && !of && !b15_i2)
|| (b15_i1 && !of && b15_i2);
#endif
}
if (chip->clk2)
chip->ad_code_sync[0] = chip->fsm_sel23[1];
if (chip->cclk1)
chip->ad_code_sync[1] = chip->ad_code_sync[0];
if (chip->cclk2)
chip->ad_code_sync[2] = chip->ad_code_sync[1];
#ifdef FMOPNA_YM2608
chip->ad_ad_quiet = (chip->ad_ad_buf & 0xf8) == 0 || (chip->ad_ad_buf & 0xf8) == 0xf8;
chip->o_spoff = chip->ad_reg_spoff;
chip->o_a8 = (chip->ad_mem_bus & 0x100) != 0;
chip->o_romcs = !(chip->ad_reg_rom && (chip->ad_mem_ctrl_l & 1) != 0);
chip->o_mden = !chip->ad_reg_rom && (chip->ad_mem_ctrl_l & 1) != 0;
chip->o_we = !chip->ad_mem_we[1];
chip->o_cas = !chip->ad_mem_cas[1];
chip->o_ras = !chip->ad_mem_ras[1];
chip->o_dm = chip->ad_mem_bus & 0xff;
chip->o_dm_d = !chip->ad_mem_dir;
#else
chip->o_pad = chip->ad_mem_bus & 0xff;
chip->o_pad_d = !chip->ad_mem_dir;
chip->o_pa8 = (chip->ad_address_cnt[1][1] >> 8) & 15;
chip->o_pmpx = chip->ad_mem_pmpx[1];
chip->o_poe = !chip->ad_mem_poe[1];
#endif
}
// accumulator
{
if (chip->clk1)
{
#ifdef FMOPNA_YM2608
chip->ac_da_w70[0] = (!chip->ac_da_sync && chip->ac_da_w70[1]) || (chip->ad_ise && chip->write1_en);
#endif
chip->ac_da_sync3[0] = chip->ac_da_sync;
int accm1 = chip->ac_rss_sum_l;
if (chip->ac_rss_sum_l & 0x8000)
accm1 |= 0x30000;
if (
#ifdef FMOPNA_YM2608
!chip->ad_reg_rec &&
#endif
chip->ad_reg_l && chip->ad_start_l[2])
accm1 += chip->ac_ad_output;
chip->ac_fm_accm1[0] = chip->ac_da_sync2 ? accm1 : chip->ac_fm_accm1[1];
if ((chip->ac_fm_pan & 2) != 0 && chip->ac_fm_output_en)
chip->ac_fm_accm1[0] += chip->ac_fm_output;
chip->ac_fm_accm1[0] &= 0x3ffff;
int accm2 = chip->ac_rss_sum_r;
if (chip->ac_rss_sum_r & 0x8000)
accm2 |= 0x30000;
if (
#ifdef FMOPNA_YM2608
!chip->ad_reg_rec &&
#endif
chip->ad_reg_r && chip->ad_start_l[2])
accm2 += chip->ac_ad_output;
chip->ac_fm_accm2[0] = chip->ac_da_sync ? accm2 : chip->ac_fm_accm2[1];
if ((chip->ac_fm_pan & 1) != 0 && chip->ac_fm_output_en)
chip->ac_fm_accm2[0] += chip->ac_fm_output;
chip->ac_fm_accm2[0] &= 0x3ffff;
chip->ac_shifter_load_l = chip->ac_da_sync2;
chip->ac_shifter_load_r = chip->ac_da_sync;
}
if (chip->clk2)
{
#ifdef FMOPNA_YM2608
chip->ac_da_w70[1] = chip->ac_da_w70[0];
#endif
chip->ac_da_sync = chip->fsm_sel23[1];
chip->ac_fm_output = (chip->op_output[2] & 0x1fff) >> 1;
if (chip->op_output[2] & 0x2000)
chip->ac_fm_output |= 0x3f000;
chip->ac_fm_output_en = chip->alg_output_l;
chip->ac_fm_pan = (chip->reg_b4[0][5] >> 6) & 3;
chip->ac_da_sync2 = chip->fsm_sel11[1];
chip->ac_da_sync3[1] = chip->ac_da_sync3[0];
chip->ac_fm_accm1[1] = chip->ac_fm_accm1[0];
chip->ac_fm_accm2[1] = chip->ac_fm_accm2[0];
}
if (chip->rss_eclk1)
{
int rss_sample = (chip->rss_sample_shift & 0xfff) << 2;
if (chip->rss_sample_shift & 0x1000)
rss_sample |= 0xc000;
int accm1 = chip->rss_cnt2[1] == 0 ? 0 : chip->ac_rss_accm1[1];
if (chip->rss_pan[2] & 2)
accm1 += rss_sample;
chip->ac_rss_accm1[0] = accm1 & 0xffff;
int accm2 = chip->rss_cnt2[1] == 0 ? 0 : chip->ac_rss_accm2[1];
if (chip->rss_pan[2] & 1)
accm2 += rss_sample;
chip->ac_rss_accm2[0] = accm2 & 0xffff;
chip->ac_rss_load = chip->rss_cnt2[1] == 0;
// tildearrow: per-channel osc
chip->last_rss_sample = rss_sample & 0xffff;
}
if (chip->rss_eclk2)
{
chip->ac_rss_accm1[1] = chip->ac_rss_accm1[0];
chip->ac_rss_accm2[1] = chip->ac_rss_accm2[0];
}
if (chip->rss_cnt2[1] == 0 && !chip->ac_rss_load)
{
chip->ac_rss_sum_l = chip->ac_rss_accm1[1];
chip->ac_rss_sum_r = chip->ac_rss_accm2[1];
}
if (chip->ac_da_sync3[1])
{
chip->ac_ad_output = (chip->ad_output & 0xfff) << 2;
if (chip->ad_output & 0x1000)
chip->ac_ad_output |= 0x3c000;
}
int load_l = chip->ac_da_sync2 && !chip->ac_shifter_load_l;
int load_r = chip->ac_da_sync && !chip->ac_shifter_load_r;
if (load_l)
chip->ac_shifter_top = (chip->ac_fm_accm1[1] >> 15) & 7;
else if (load_r)
chip->ac_shifter_top = (chip->ac_fm_accm2[1] >> 15) & 7;
if (chip->bclk1)
{
#ifdef FMOPNA_YM2608
chip->ac_da_shift[1] = chip->ac_da_shift[0];
chip->ac_da_set[1] = chip->ac_da_set[0];
chip->opo_da[1] = chip->opo_da[0];
#endif
chip->ac_shifter[0] = chip->ac_shifter[1] >> 1;
chip->ac_shifter_bit = chip->ac_shifter[1] & 1;
chip->opo_fm = chip->ac_opo;
}
if (chip->bclk2)
{
#ifdef FMOPNA_YM2608
int set = chip->ac_da_w70[1] && chip->ac_da_sync;
chip->opo_da[0] = chip->ac_da_shift[1] & 1;
int bit = !chip->ic && (chip->ac_da_shift[1] & 1) != 0;
chip->ac_da_shift[0] = (chip->ac_da_shift[1] >> 1) | (bit << 23);
if (set && !chip->ac_da_set[1])
{
chip->ac_da_shift[0] &= ~(0xffff << 8);
chip->ac_da_shift[0] |= chip->ad_da_data << 8;
}
chip->ac_da_set[0] = set;
#endif
chip->ac_shifter[1] = chip->ac_shifter[0];
if (load_l || load_r)
{
int sample = 0;
if (load_l)
sample = chip->ac_fm_accm1[1];
else if (load_r)
sample = chip->ac_fm_accm2[1];
int sample16 = sample & 0x7fff;
if ((sample & 0x20000) == 0)
sample16 |= 0x8000;
chip->ac_shifter[1] |= sample16;
}
int clipl = chip->ac_shifter_top == 6 || (chip->ac_shifter_top & 6) == 4;
int cliph = chip->ac_shifter_top == 1 || (chip->ac_shifter_top & 6) == 2;
chip->ac_opo = cliph ? 1 : (clipl ? 0 : chip->ac_shifter_bit);
}
if (chip->clk2)
{
chip->sh1_l = chip->fsm_sh1[1];
chip->sh2_l = chip->fsm_sh2[1];
}
#ifdef FMOPNA_YM2608
if (chip->cclk2)
{
chip->opo_ad = chip->ad_ad_w61[0] & 1;
}
#endif
#ifdef FMOPNA_YM2608
int dac_damode = chip->ad_reg_da_ad && chip->ad_sample_l[2];
int dac_admode = (chip->ad_reg_rec && chip->ad_start_l[2]) || (!chip->ad_reg_da_ad && chip->ad_sample_l[2]);
if (dac_damode)
chip->o_sh1 = chip->ad_reg_l && chip->sh1_l;
else if (dac_admode)
chip->o_sh1 = 0;
else
chip->o_sh1 = chip->sh1_l;
if (dac_damode)
chip->o_sh2 = chip->ad_reg_r && chip->sh2_l;
else if (dac_admode)
chip->o_sh2 = chip->ad_ad_w58[2];
else
chip->o_sh2 = chip->sh2_l;
if (dac_damode)
chip->o_opo = chip->opo_da[1];
else if (dac_admode)
chip->o_opo = chip->opo_ad;
else
chip->o_opo = chip->opo_fm;
if (dac_admode)
chip->o_s = chip->cclk2;
else
chip->o_s = chip->bclk1;
#else
chip->o_sh1 = chip->sh1_l;
chip->o_sh2 = chip->sh2_l;
chip->o_opo = chip->opo_fm;
chip->o_s = chip->bclk1;
#endif
}
#endif
{
if (chip->clk1)
{
int inc = chip->busy_cnt_en[1];
int sum = chip->busy_cnt[1] + inc;
int of = (sum & 32) != 0;
if (chip->ic)
chip->busy_cnt[0] = 0;
else
chip->busy_cnt[0] = sum & 31;
chip->busy_cnt_en[0] = chip->write1_en || (chip->busy_cnt_en[1] && !(of || chip->ic));
#ifndef FMOPNA_YM2612
chip->eos_l[0] = chip->eos_flag;
chip->eos_repeat = chip->eos_l[1] && chip->ad_set_eos && chip->ad_reg_repeat;
#endif
}
if (chip->clk2)
{
chip->busy_cnt[1] = chip->busy_cnt[0];
chip->busy_cnt_en[1] = chip->busy_cnt_en[0];
#ifdef FMOPNA_YM2608
chip->zero_set = chip->lfo_cnt_of;
#endif
#ifndef FMOPNA_YM2612
chip->eos_l[1] = chip->eos_l[0];
#endif
chip->eg_dbg = chip->reg_test_21[0] ? (chip->eg_debug[0] & 0x200) != 0 :
chip->eg_debug_inc;
}
#ifdef FMOPNA_YM2608
if (chip->irq_mask_eos)
chip->eos_flag = 0;
else
chip->eos_flag |= chip->ad_set_eos;
if (chip->irq_mask_brdy)
chip->brdy_flag = 0;
else
chip->brdy_flag |= chip->ad_brdy_set_l[1];
if (chip->irq_mask_zero)
chip->zero_flag = 0;
else
chip->zero_flag |= chip->zero_set;
if (!chip->read0 && !chip->read2)
{
chip->status_timer_a = chip->timer_a_status[1];
chip->status_timer_b = chip->timer_b_status[1];
chip->status_eos = chip->eos_flag;
chip->status_brdy = chip->brdy_flag;
chip->status_zero = chip->zero_flag;
}
#endif
#ifdef FMOPNA_YM2610
if (chip->ic || (chip->reg_flags[1] & 1) != 0)
chip->flag_rss_0 = 0;
else if (chip->rss_stop_flag[1] & 1)
chip->flag_rss_0 = 1;
if (chip->ic || (chip->reg_flags[1] & 2) != 0)
chip->flag_rss_1 = 0;
else if (chip->rss_stop_flag[1] & 2)
chip->flag_rss_1 = 1;
if (chip->ic || (chip->reg_flags[1] & 4) != 0)
chip->flag_rss_2 = 0;
else if (chip->rss_stop_flag[1] & 4)
chip->flag_rss_2 = 1;
if (chip->ic || (chip->reg_flags[1] & 8) != 0)
chip->flag_rss_3 = 0;
else if (chip->rss_stop_flag[1] & 8)
chip->flag_rss_3 = 1;
if (chip->ic || (chip->reg_flags[1] & 16) != 0)
chip->flag_rss_4 = 0;
else if (chip->rss_stop_flag[1] & 16)
chip->flag_rss_4 = 1;
if (chip->ic || (chip->reg_flags[1] & 32) != 0)
chip->flag_rss_5 = 0;
else if (chip->rss_stop_flag[1] & 32)
chip->flag_rss_5 = 1;
if (chip->ic || (chip->reg_flags[1] & 128) != 0 || chip->irq_eos_l)
chip->eos_flag = 0;
else if (chip->ad_set_eos)
chip->eos_flag = 1;
if (!chip->read0 && !chip->read2)
{
chip->status_timer_a = chip->timer_a_status[1];
chip->status_timer_b = chip->timer_b_status[1];
chip->status_rss_0 = chip->flag_rss_0;
chip->status_rss_1 = chip->flag_rss_1;
chip->status_rss_2 = chip->flag_rss_2;
chip->status_rss_3 = chip->flag_rss_3;
chip->status_rss_4 = chip->flag_rss_4;
chip->status_rss_5 = chip->flag_rss_5;
chip->status_eos = chip->eos_flag;
}
#endif
#ifdef FMOPNA_YM2612
if (!chip->read0)
{
chip->status_timer_a = chip->timer_a_status[1];
chip->status_timer_b = chip->timer_b_status[1];
}
#endif
#ifdef FMOPNA_YM2608
chip->o_irq_pull = 0;
if (chip->reg_irq[1] & 1)
chip->o_irq_pull |= chip->status_timer_a;
if (chip->reg_irq[1] & 2)
chip->o_irq_pull |= chip->status_timer_b;
if (chip->reg_irq[1] & 4)
chip->o_irq_pull |= chip->status_eos;
if (chip->reg_irq[1] & 8)
chip->o_irq_pull |= chip->status_brdy;
if (chip->reg_irq[1] & 16)
chip->o_irq_pull |= chip->status_zero;
#else
chip->o_irq_pull = chip->status_timer_a | chip->status_timer_b;
#endif
chip->read_bus = 0; // FIXME
#ifndef FMOPNA_YM2612
if (chip->ssg_read1
#ifdef FMOPNA_YM2608
|| chip->read3
#endif
)
chip->read_bus = chip->data_bus1 & 255;
#endif
if ((chip->reg_test_21[1] & 0x40) == 0
#ifndef FMOPNA_YM2612
&& (chip->reg_test_12[1] & 0x20) == 0
#endif
)
{
if (chip->read0)
{
if (chip->busy_cnt_en[1])
chip->read_bus |= 128;
if (chip->status_timer_a)
chip->read_bus |= 1;
if (chip->status_timer_b)
chip->read_bus |= 2;
}
#ifdef FMOPNA_YM2608
if (chip->read2)
{
if (chip->busy_cnt_en[1])
chip->read_bus |= 128;
if (chip->status_timer_a)
chip->read_bus |= 1;
if (chip->status_timer_b)
chip->read_bus |= 2;
if (chip->status_eos)
chip->read_bus |= 4;
if (chip->status_brdy)
chip->read_bus |= 8;
if (chip->status_zero)
chip->read_bus |= 16;
if (chip->ad_start_l[0])
chip->read_bus |= 32;
}
#endif
#ifdef FMOPNA_YM2610
if (chip->read2)
{
if (chip->status_rss_0)
chip->read_bus |= 1;
if (chip->status_rss_1)
chip->read_bus |= 2;
if (chip->status_rss_2)
chip->read_bus |= 4;
if (chip->status_rss_3)
chip->read_bus |= 8;
if (chip->status_rss_4)
chip->read_bus |= 16;
if (chip->status_rss_5)
chip->read_bus |= 32;
if (chip->status_eos)
chip->read_bus |= 128;
}
#endif
}
#ifndef FMOPNA_YM2612
if ((chip->reg_test_12[1] & 0x20) != 0 && chip->read0)
{
#ifdef FMOPNA_YM2608
if ((chip->reg_test_12[1] & 0x40) == 0)
{
// FIXME
chip->read_bus = rss_rom[(chip->rss_ix >> 2) & 0x1fff];
}
else
#endif
if ((chip->reg_test_12[1] & 0x80) == 0)
{
chip->read_bus = (chip->rss_dbg_data >> 8) & 255;
}
else
{
chip->read_bus = chip->rss_dbg_data & 255;
}
}
#endif
if ((chip->reg_test_21[1] & 0x40) != 0 && chip->read0)
{
int testdata = 0;
#ifndef FMOPNA_YM2612
testdata = chip->op_output[3] & 0x3fff;
#endif
#ifdef FMOPNA_YM2612
if (chip->reg_test_2c[1] & 16)
testdata |= chip->ch_dbg[1] & 0x1ff;
else
testdata |= chip->op_output[3] & 0x3fff;
#endif
testdata |= (chip->pg_dbg[1] & 1) << 15;
testdata |= chip->eg_dbg << 14;
if ((chip->reg_test_21[1] & 0x80) == 0)
{
chip->read_bus = (testdata >> 8) & 255;
}
else
{
chip->read_bus = testdata & 255;
}
}
chip->o_data = chip->read_bus;
}
#ifdef FMOPNA_YM2612
// YM2612 channel accumulator
{
int test_dac = (chip->reg_test_2c[1] & 32) != 0;
if (chip->clk1)
{
int add = (!test_dac && chip->ch_op_add) ? chip->ch_op_output : 0;
int load = chip->ch_accm_load || test_dac;
int clear = !test_dac && load;
int acc = clear ? 0 : chip->ch_accm[1][5];
int sum1 = (add + acc + test_dac) & 0x1ff;
if ((acc & 0x100) == 0 && (add & 0x100) == 0 && (sum1 & 0x100) != 0)
sum1 = 255;
else if ((acc & 0x100) != 0 && (add & 0x100) != 0 && (sum1 & 0x100) == 0)
sum1 = 256;
chip->ch_accm[0][0] = sum1;
memcpy(&chip->ch_accm[0][1], &chip->ch_accm[1][0], 5 * sizeof(short));
memcpy(&chip->ch_buf[0][1], &chip->ch_buf[1][0], 5 * sizeof(short));
chip->ch_buf[0][0] = load ? chip->ch_accm[1][5] : chip->ch_buf[1][5];
chip->ch_load[1] = chip->ch_load[0];
chip->ch_dbg[0] = chip->ch_output;
}
if (chip->clk2)
{
chip->ch_op_output = (chip->op_output[2] >> 5) & 0x1ff;
chip->ch_op_add = chip->alg_output_l;
chip->ch_accm_load = chip->alg_mod_op1_1_l;
memcpy(&chip->ch_accm[1][0], &chip->ch_accm[0][0], 6 * sizeof(short));
memcpy(&chip->ch_buf[1][0], &chip->ch_buf[0][0], 6 * sizeof(short));
chip->ch_load[0] = chip->fsm_dac_load[1];
chip->ch_sel = chip->fsm_dac_out_sel[1];
chip->ch_ch6 = chip->fsm_dac_ch6[1];
chip->ch_dbg[1] = chip->ch_dbg[0];
chip->o_test = chip->fsm_sel23[1];
}
{
if (test_dac || (chip->ch_load[0] && !chip->ch_load[1]))
{
int sel = test_dac || chip->ch_sel;
chip->ch_output = sel ? chip->ch_buf[1][5] : chip->ch_buf[1][4];
}
if (chip->ch_load[0] && !chip->ch_load[1])
{
int sel = chip->ch_sel;
if (sel)
chip->ch_pan = (chip->reg_b4[1][5] >> 6) & 3;
else
chip->ch_pan = (chip->reg_b4[1][4] >> 6) & 3;
}
int dac_sel = test_dac || (chip->reg_dac_en[1] && chip->ch_ch6);
int ch_val;
if (dac_sel)
{
ch_val = (chip->reg_dac_data[1] ^ 0x80) << 1;
ch_val |= (chip->reg_test_2c[1] & 8) != 0;
}
else
ch_val = chip->ch_output;
int do_out = test_dac || chip->ch_load[0];
int sign;
if (ch_val & 256)
{
sign = -1;
ch_val |= ~0x1ff;
}
else
{
sign = 1;
ch_val++;
}
if (do_out && (chip->ch_pan & 2) != 0)
chip->o_mol = ch_val;
else
chip->o_mol = sign;
if (do_out && (chip->ch_pan & 1) != 0)
chip->o_mor = ch_val;
else
chip->o_mor = sign;
}
chip->o_test_d = (chip->reg_test_2c[1] & 128) == 0;
}
#endif
#undef ADDRESS_MATCH
}