From 898353b652eeacac902876d5979d6fea4165fccd Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Thu, 13 Nov 2025 16:33:46 +0800 Subject: [PATCH] =?UTF-8?q?MAME:ADPCMA=5Fcalc=5Fchan=E5=86=85=E8=81=94?= =?UTF-8?q?=EF=BC=8C=E5=87=8F=E5=B0=91adpcm[c]=E5=AF=BB=E5=9D=80=20|=20MC6?= =?UTF-8?q?8000=20CMPI=E5=86=85=E8=81=94ReadValueB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cpu/m68000/Instructions/IntegerMath.cs | 103 +++++++++++- .../Assets/Plugins/Mame.Core/sound/FM.cs | 7 +- .../Assets/Plugins/Mame.Core/sound/YM2610.cs | 147 +++++++++++++----- 3 files changed, 213 insertions(+), 44 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m68000/Instructions/IntegerMath.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m68000/Instructions/IntegerMath.cs index df5368ee..947f82c3 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m68000/Instructions/IntegerMath.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/cpu/m68000/Instructions/IntegerMath.cs @@ -1320,6 +1320,57 @@ namespace cpu.m68000 } + //void CMPI() + //{ + // int size = (op >> 6) & 3; + // int mode = (op >> 3) & 7; + // int reg = (op >> 0) & 7; + + // switch (size) + // { + // case 0: // byte + // { + // sbyte b = (sbyte)ReadOpWord(PC); PC += 2; + // sbyte a = ReadValueB(mode, reg); + // int result = a - b; + // N = (result & 0x80) != 0; + // Z = result == 0; + // V = result > sbyte.MaxValue || result < sbyte.MinValue; + // C = ((a < b) ^ ((a ^ b) >= 0) == false); + // if (mode == 0) pendingCycles -= 8; + // else pendingCycles -= 8 + EACyclesBW[mode, reg]; + // return; + // } + // case 1: // word + // { + // short b = ReadOpWord(PC); PC += 2; + // short a = ReadValueW(mode, reg); + // int result = a - b; + // N = (result & 0x8000) != 0; + // Z = result == 0; + // V = result > short.MaxValue || result < short.MinValue; + // C = ((a < b) ^ ((a ^ b) >= 0) == false); + // if (mode == 0) pendingCycles -= 8; + // else pendingCycles -= 8 + EACyclesBW[mode, reg]; + // return; + // } + // case 2: // long + // { + // int b = ReadOpLong(PC); PC += 4; + // int a = ReadValueL(mode, reg); + // long result = a - b; + // N = (result & 0x80000000) != 0; + // Z = result == 0; + // V = result > int.MaxValue || result < int.MinValue; + // C = ((a < b) ^ ((a ^ b) >= 0) == false); + // if (mode == 0) pendingCycles -= 14; + // else pendingCycles -= 12 + EACyclesL[mode, reg]; + // return; + // } + // } + //} + + //手动内联 void CMPI() { int size = (op >> 6) & 3; @@ -1331,7 +1382,57 @@ namespace cpu.m68000 case 0: // byte { sbyte b = (sbyte)ReadOpWord(PC); PC += 2; - sbyte a = ReadValueB(mode, reg); + //sbyte a = ReadValueB(mode, reg); + sbyte a = 0; + { + sbyte value; + switch (mode) + { + case 0: // Dn + a = D[reg].s8; break; + case 1: // An + a = A[reg].s8; break; + case 2: // (An) + a = ReadByte(A[reg].s32); break; + case 3: // (An)+ + value = ReadByte(A[reg].s32); + A[reg].s32 += reg == 7 ? 2 : 1; + a = value; break; + case 4: // -(An) + A[reg].s32 -= reg == 7 ? 2 : 1; + a = ReadByte(A[reg].s32); break; + case 5: // (d16,An) + value = ReadByte((A[reg].s32 + ReadOpWord(PC))); PC += 2; + a = value; break; + case 6: // (d8,An,Xn) + a = ReadByte(A[reg].s32 + GetIndex()); break; + case 7: + switch (reg) + { + case 0: // (imm).W + value = ReadByte(ReadOpWord(PC)); PC += 2; + a = value; break; + case 1: // (imm).L + value = ReadByte(ReadOpLong(PC)); PC += 4; + a = value; break; + case 2: // (d16,PC) + value = ReadOpByte(PC + ReadOpWord(PC)); PC += 2; + a = value; break; + case 3: // (d8,PC,Xn) + int pc = PC; + value = ReadOpByte((pc + GetIndex())); + a = value; break; + case 4: // immediate + value = (sbyte)ReadOpWord(PC); PC += 2; + a = value;break; + default: + throw new Exception("Invalid addressing mode!"); + } + break; + default: + throw new Exception("Invalid addressing mode!"); + } + } int result = a - b; N = (result & 0x80) != 0; Z = result == 0; diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/FM.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/FM.cs index 6705c644..e920e857 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/FM.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/FM.cs @@ -620,11 +620,12 @@ namespace MAME.Core //鎵嬪姩鍐呰仈 //public unsafe void chan_calc(int c, int chnum) + //public unsafe void chan_calc(int c, bool chnum_is_2) public unsafe void chan_calc(int c, bool chnum_is_2) { uint eg_out; //鍑忓皯瀵诲潃 - int imem_To_c = imem[c]; + int imem_ToIndex_c = imem[c]; fixed (FM_SLOT* CH_c_SLOT = &CH[c].SLOT[0])//鍥犱负鏄紩鐢ㄧ被鍨嬶紝鎵浠ユ暍杩欎箞鐜 fixed (int* out_fm_ptr = &out_fm[0]) { @@ -637,8 +638,8 @@ namespace MAME.Core out_fm_ptr[8] = out_fm_ptr[9] = out_fm_ptr[10] = out_fm_ptr[11] = 0; //set_mem(c); - if (imem_To_c == 8 || imem_To_c == 10 || imem_To_c == 11) - out_fm_ptr[imem_To_c] = CH[c].mem_value; + if (imem_ToIndex_c == 8 || imem_ToIndex_c == 10 || imem_ToIndex_c == 11) + out_fm_ptr[imem_ToIndex_c] = CH[c].mem_value; //eg_out = volume_calc(c, 0); eg_out = (uint)(cslot_0->vol_out + ((LFO_AM >> CH[c].ams) & cslot_0->AMmask)); diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2610.cs b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2610.cs index cffe2a89..e40e7e7e 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2610.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/sound/YM2610.cs @@ -1,4 +1,9 @@ 锘 +using Sony.Vita.Dialog; +using System; +using static MAME.Core.FM; +using static MAME.Core.YM2151; + namespace MAME.Core { public unsafe class YM2610 @@ -41,49 +46,102 @@ namespace MAME.Core { Sound.ym2610stream.stream_update(); } + //public void ADPCMA_calc_chan(int c) + //{ + // uint step; + // byte data; + // int i; + // adpcm[c].now_step += adpcm[c].step; + // if (adpcm[c].now_step >= (1 << 16)) + // { + // step = adpcm[c].now_step >> 16; + // adpcm[c].now_step &= (1 << 16) - 1; + // for (i = 0; i < step; i++) + // { + // if ((adpcm[c].now_addr & ((1 << 21) - 1)) == ((adpcm[c].end << 1) & ((1 << 21) - 1))) + // { + // adpcm[c].flag = 0; + // adpcm_arrivedEndAddress |= adpcm[c].flagMask; + // return; + // } + // if ((adpcm[c].now_addr & 1) != 0) + // { + // data = (byte)(adpcm[c].now_data & 0x0f); + // } + // else + // { + // adpcm[c].now_data = FM.ymsndrom[adpcm[c].now_addr >> 1]; + // data = (byte)((adpcm[c].now_data >> 4) & 0x0f); + // } + // adpcm[c].now_addr++; + // adpcm[c].adpcm_acc += FM.jedi_table[adpcm[c].adpcm_step + data]; + // if ((adpcm[c].adpcm_acc & ~0x7ff) != 0) + // { + // adpcm[c].adpcm_acc |= ~0xfff; + // } + // else + // { + // adpcm[c].adpcm_acc &= 0xfff; + // } + // adpcm[c].adpcm_step += FM.step_inc[data & 7]; + // adpcm[c].adpcm_step = FM.Limit(adpcm[c].adpcm_step, 48 * 16, 0); + // } + // adpcm[c].adpcm_out = ((adpcm[c].adpcm_acc * adpcm[c].vol_mul) >> adpcm[c].vol_shift) & ~3; + // } + // FM.out_adpcm[FM.ipan[c]] += adpcm[c].adpcm_out; + //} + + //鎵嬪姩鍐呰仈 public void ADPCMA_calc_chan(int c) { uint step; byte data; int i; - adpcm[c].now_step += adpcm[c].step; - if (adpcm[c].now_step >= (1 << 16)) + fixed (FM.ADPCM_CH* adpcm_c = &adpcm[c]) { - step = adpcm[c].now_step >> 16; - adpcm[c].now_step &= (1 << 16) - 1; - for (i = 0; i < step; i++) + adpcm_c->now_step += adpcm_c->step; + if (adpcm_c->now_step >= (1 << 16)) { - if ((adpcm[c].now_addr & ((1 << 21) - 1)) == ((adpcm[c].end << 1) & ((1 << 21) - 1))) + step = adpcm_c->now_step >> 16; + adpcm_c->now_step &= (1 << 16) - 1; + for (i = 0; i < step; i++) { - adpcm[c].flag = 0; - adpcm_arrivedEndAddress |= adpcm[c].flagMask; - return; + if ((adpcm_c->now_addr & ((1 << 21) - 1)) == ((adpcm_c->end << 1) & ((1 << 21) - 1))) + { + adpcm_c->flag = 0; + adpcm_arrivedEndAddress |= adpcm_c->flagMask; + return; + } + if ((adpcm_c->now_addr & 1) != 0) + { + data = (byte)(adpcm_c->now_data & 0x0f); + } + else + { + adpcm_c->now_data = FM.ymsndrom[adpcm_c->now_addr >> 1]; + data = (byte)((adpcm_c->now_data >> 4) & 0x0f); + } + adpcm_c->now_addr++; + adpcm_c->adpcm_acc += FM.jedi_table[adpcm_c->adpcm_step + data]; + if ((adpcm_c->adpcm_acc & ~0x7ff) != 0) + { + adpcm_c->adpcm_acc |= ~0xfff; + } + else + { + adpcm_c->adpcm_acc &= 0xfff; + } + adpcm_c->adpcm_step += FM.step_inc[data & 7]; + //adpcm_c->adpcm_step = FM.Limit(adpcm_c->adpcm_step, 48 * 16, 0);//(int val, int max, int min) + int val = adpcm_c->adpcm_step; + const int max = 48 * 16; + adpcm_c->adpcm_step = Math.Min(max, adpcm_c->adpcm_step); + adpcm_c->adpcm_step = Math.Max(0, adpcm_c->adpcm_step); } - if ((adpcm[c].now_addr & 1) != 0) - { - data = (byte)(adpcm[c].now_data & 0x0f); - } - else - { - adpcm[c].now_data = FM.ymsndrom[adpcm[c].now_addr >> 1]; - data = (byte)((adpcm[c].now_data >> 4) & 0x0f); - } - adpcm[c].now_addr++; - adpcm[c].adpcm_acc += FM.jedi_table[adpcm[c].adpcm_step + data]; - if ((adpcm[c].adpcm_acc & ~0x7ff) != 0) - { - adpcm[c].adpcm_acc |= ~0xfff; - } - else - { - adpcm[c].adpcm_acc &= 0xfff; - } - adpcm[c].adpcm_step += FM.step_inc[data & 7]; - adpcm[c].adpcm_step = FM.Limit(adpcm[c].adpcm_step, 48 * 16, 0); + adpcm_c->adpcm_out = ((adpcm_c->adpcm_acc * adpcm_c->vol_mul) >> adpcm_c->vol_shift) & ~3; } - adpcm[c].adpcm_out = ((adpcm[c].adpcm_acc * adpcm[c].vol_mul) >> adpcm[c].vol_shift) & ~3; + FM.out_adpcm[FM.ipan[c]] += adpcm_c->adpcm_out; } - FM.out_adpcm[FM.ipan[c]] += adpcm[c].adpcm_out; } @@ -513,10 +571,10 @@ namespace MAME.Core //OPN.chan_calc(2, 2); //OPN.chan_calc(4, 4); //OPN.chan_calc(5, 5); - OPN.chan_calc(1, false); - OPN.chan_calc(2, true); - OPN.chan_calc(4, false); - OPN.chan_calc(5, false); + OPN.chan_calc(1,false); + OPN.chan_calc(2,true); + OPN.chan_calc(4,false); + OPN.chan_calc(5,false); if ((YMDeltat.DELTAT.portstate & 0x80) != 0) { YMDeltat.YM_DELTAT_ADPCM_CALC(); @@ -541,8 +599,12 @@ namespace MAME.Core rt += (int)((FM.out_fm[4] >> 1) & OPN.pan[9]); lt += (int)((FM.out_fm[5] >> 1) & OPN.pan[10]); rt += (int)((FM.out_fm[5] >> 1) & OPN.pan[11]); - lt = FM.Limit(lt, 32767, -32768); - rt = FM.Limit(rt, 32767, -32768); + //lt = FM.Limit(lt, 32767, -32768); + //rt = FM.Limit(rt, 32767, -32768); + lt = Math.Min(lt, 32767); + lt = Math.Max(lt, -32768); + rt = Math.Min(rt, 32767); + rt = Math.Max(rt, -32768); Sound.ym2610stream.streamoutput_Ptrs[0][offset + i] = lt; Sound.ym2610stream.streamoutput_Ptrs[1][offset + i] = rt; } @@ -569,6 +631,7 @@ namespace MAME.Core OPN.refresh_fc_eg_chan(F2610.OPN.type, 3); OPN.refresh_fc_eg_chan(F2610.OPN.type, 4); OPN.refresh_fc_eg_chan(F2610.OPN.type, 5); + for (i = 0; i < length; i++) { OPN.advance_lfo(); @@ -632,8 +695,12 @@ namespace MAME.Core rt += (int)((FM.out_fm[4] >> 1) & OPN.pan[9]); lt += (int)((FM.out_fm[5] >> 1) & OPN.pan[10]); rt += (int)((FM.out_fm[5] >> 1) & OPN.pan[11]); - lt = FM.Limit(lt, 32767, -32768); - rt = FM.Limit(rt, 32767, -32768); + //lt = FM.Limit(lt, 32767, -32768); + //rt = FM.Limit(rt, 32767, -32768); + lt = Math.Min(lt, 32767); + lt = Math.Max(lt, -32768); + rt = Math.Min(rt, 32767); + rt = Math.Max(rt, -32768); Sound.ym2610stream.streamoutput_Ptrs[0][offset + i] = lt; Sound.ym2610stream.streamoutput_Ptrs[1][offset + i] = rt; }