/* * 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 #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 }