diff --git a/include/audio/sidfx.c b/include/audio/sidfx.c index 1434b08..96fe99a 100644 --- a/include/audio/sidfx.c +++ b/include/audio/sidfx.c @@ -15,7 +15,7 @@ static struct SIDFXChannel SIDFX * com; byte delay, cnt; SIDFXState state; - unsigned freq; + unsigned freq, pwm; } channels[3]; @@ -46,86 +46,108 @@ void sidfx_stop(byte chn) channels[chn].state = SIDFX_RESET_0; } +inline void sidfx_loop_ch(byte ch) +{ + switch (channels[ch].state) + { + case SIDFX_IDLE: + break; + case SIDFX_RESET_0: + sid.voices[ch].ctrl = 0; + sid.voices[ch].attdec = 0; + sid.voices[ch].susrel = 0; + channels[ch].state = SIDFX_RESET_1; + break; + case SIDFX_RESET_1: + sid.voices[ch].ctrl = SID_CTRL_TEST; + channels[ch].state = SIDFX_READY; + break; + case SIDFX_READY: + if (channels[ch].com) + { + channels[ch].freq = channels[ch].com->freq; + channels[ch].pwm = channels[ch].com->pwm; + + sid.voices[ch].freq = channels[ch].com->freq; + sid.voices[ch].pwm = channels[ch].com->pwm; + sid.voices[ch].attdec = channels[ch].com->attdec; + sid.voices[ch].susrel = channels[ch].com->susrel; + sid.voices[ch].ctrl = channels[ch].com->ctrl; + + channels[ch].delay = channels[ch].com->time1; + channels[ch].state = SIDFX_PLAY; + } + else + channels[ch].state = SIDFX_IDLE; + break; + case SIDFX_PLAY: + if (channels[ch].com->dfreq) + { + channels[ch].freq += channels[ch].com->dfreq; + sid.voices[ch].freq = channels[ch].freq; + } + if (channels[ch].com->dpwm) + { + channels[ch].pwm += channels[ch].com->dpwm; + sid.voices[ch].pwm = channels[ch].pwm; + } + + if (channels[ch].delay) + channels[ch].delay--; + else if (channels[ch].com->time0) + { + sid.voices[ch].ctrl = channels[ch].com->ctrl & ~SID_CTRL_GATE; + channels[ch].delay = channels[ch].com->time0; + channels[ch].state = SIDFX_WAIT; + } + else if (channels[ch].cnt) + { + channels[ch].cnt--; + channels[ch].com++; + channels[ch].state = SIDFX_READY; + } + else + { + channels[ch].com = nullptr; + channels[ch].state = SIDFX_RESET_0; + } + break; + case SIDFX_WAIT: + if (channels[ch].com->dfreq) + { + channels[ch].freq += channels[ch].com->dfreq; + sid.voices[ch].freq = channels[ch].freq; + } + if (channels[ch].com->dpwm) + { + channels[ch].pwm += channels[ch].com->dpwm; + sid.voices[ch].pwm = channels[ch].pwm; + } + + if (channels[ch].delay) + channels[ch].delay--; + else if (channels[ch].cnt) + { + channels[ch].cnt--; + channels[ch].com++; + channels[ch].state = SIDFX_RESET_0; + } + else + { + channels[ch].com = nullptr; + channels[ch].state = SIDFX_RESET_0; + } + break; + } +} + +void sidfx_loop_2(void) +{ + sidfx_loop_ch(2); +} + void sidfx_loop(void) { for(byte ch=0; ch<3; ch++) - { - switch (channels[ch].state) - { - case SIDFX_IDLE: - break; - case SIDFX_RESET_0: - sid.voices[ch].ctrl = 0; - sid.voices[ch].attdec = 0; - sid.voices[ch].susrel = 0; - channels[ch].state = SIDFX_RESET_1; - break; - case SIDFX_RESET_1: - sid.voices[ch].ctrl = SID_CTRL_TEST; - channels[ch].state = SIDFX_READY; - break; - case SIDFX_READY: - if (channels[ch].com) - { - channels[ch].freq = channels[ch].com->freq; - sid.voices[ch].freq = channels[ch].com->freq; - sid.voices[ch].pwm = channels[ch].com->pwm; - sid.voices[ch].attdec = channels[ch].com->attdec; - sid.voices[ch].susrel = channels[ch].com->susrel; - sid.voices[ch].ctrl = channels[ch].com->ctrl; - channels[ch].delay = channels[ch].com->time1; - channels[ch].state = SIDFX_PLAY; - } - else - channels[ch].state = SIDFX_IDLE; - break; - case SIDFX_PLAY: - if (channels[ch].com->dfreq) - { - channels[ch].freq += channels[ch].com->dfreq; - sid.voices[ch].freq = channels[ch].freq; - } - if (channels[ch].delay) - channels[ch].delay--; - else if (channels[ch].com->time0) - { - sid.voices[ch].ctrl = channels[ch].com->ctrl & ~SID_CTRL_GATE; - channels[ch].delay = channels[ch].com->time0; - channels[ch].state = SIDFX_WAIT; - } - else if (channels[ch].cnt) - { - channels[ch].cnt--; - channels[ch].com++; - channels[ch].state = SIDFX_READY; - } - else - { - channels[ch].com = nullptr; - channels[ch].state = SIDFX_RESET_0; - } - break; - case SIDFX_WAIT: - if (channels[ch].com->dfreq) - { - channels[ch].freq += channels[ch].com->dfreq; - sid.voices[ch].freq = channels[ch].freq; - } - - if (channels[ch].delay) - channels[ch].delay--; - else if (channels[ch].cnt) - { - channels[ch].cnt--; - channels[ch].com++; - channels[ch].state = SIDFX_RESET_0; - } - else - { - channels[ch].com = nullptr; - channels[ch].state = SIDFX_RESET_0; - } - break; - } - } + sidfx_loop_ch(ch); } diff --git a/include/audio/sidfx.h b/include/audio/sidfx.h index 4b615d5..3c091c5 100644 --- a/include/audio/sidfx.h +++ b/include/audio/sidfx.h @@ -13,12 +13,14 @@ struct SIDFX void sidfx_init(void); -void sidfx_play(byte chn, SIDFX * fx, byte cnt); +inline void sidfx_play(byte chn, SIDFX * fx, byte cnt); void sidfx_stop(byte chn); void sidfx_loop(void); +void sidfx_loop_2(void); + #pragma compile("sidfx.c") #endif diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 7a7305c..3ba1d1b 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -16888,7 +16888,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass if (ains->mMode == ASMIM_IMMEDIATE) { mIns[i + 1].mLinkerObject = 0; - mIns[i + 1].mAddress = addr; + mIns[i + 1].mAddress = addr + mIns[i + 0].mAddress; } else { @@ -18162,6 +18162,42 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 3].mMode = ASMIM_IMPLIED; progress = true; } +#endif +#if 1 + else if ( + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 && + mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_LDX; mIns[i + 1].mLive |= LIVE_CPU_REG_X; + mIns[i + 2].mType = ASMIT_INX; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X; + if (mIns[i + 2].mAddress == 2) + mIns[i + 3].mType = ASMIT_INX; + else + mIns[i + 3].mType = ASMIT_NOP; + mIns[i + 3].mMode = ASMIM_IMPLIED; + progress = true; + } +#endif +#if 1 + else if ( + mIns[i + 0].mType == ASMIT_SEC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 && + mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C))) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_LDX; mIns[i + 1].mLive |= LIVE_CPU_REG_X; + mIns[i + 2].mType = ASMIT_DEX; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X; + if (mIns[i + 2].mAddress == 2) + mIns[i + 3].mType = ASMIT_DEX; + else + mIns[i + 3].mType = ASMIT_NOP; + mIns[i + 3].mMode = ASMIM_IMPLIED; + progress = true; + } #endif else if ( mIns[i + 0].mType == ASMIT_TXA &&