From 9c56c3d01b8e4d83bc4abe8d105ecda1d4774066 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 2 Apr 2023 14:32:47 +0900 Subject: [PATCH 01/20] [WIP] K063260 skeleton --- CMakeLists.txt | 1 + .../vgsound_emu/src/k053260/k053260.cpp | 101 ++-- .../vgsound_emu/src/k053260/k053260.hpp | 73 ++- src/engine/dispatchContainer.cpp | 4 + src/engine/instrument.cpp | 4 + src/engine/instrument.h | 1 + src/engine/platform/k053260.cpp | 475 ++++++++++++++++++ src/engine/platform/k053260.h | 96 ++++ src/engine/song.h | 3 +- src/engine/sysDef.cpp | 10 + src/engine/vgmOps.cpp | 42 +- src/gui/dataList.cpp | 4 + src/gui/debug.cpp | 20 + src/gui/doAction.cpp | 3 +- src/gui/gui.h | 1 + src/gui/guiConst.cpp | 4 + src/gui/insEdit.cpp | 17 +- src/gui/presets.cpp | 41 ++ src/gui/settings.cpp | 1 + src/gui/sysConf.cpp | 20 + 20 files changed, 837 insertions(+), 84 deletions(-) create mode 100644 src/engine/platform/k053260.cpp create mode 100644 src/engine/platform/k053260.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 78a68aa83..7105990b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -551,6 +551,7 @@ src/engine/platform/k007232.cpp src/engine/platform/ga20.cpp src/engine/platform/sm8521.cpp src/engine/platform/pv1000.cpp +src/engine/platform/k053260.cpp src/engine/platform/pcmdac.cpp src/engine/platform/dummy.cpp diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp index bf056b816..2ee4efac3 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp @@ -8,18 +8,19 @@ #include "k053260.hpp" -void k053260_core::tick() +void k053260_core::tick(u32 cycle) { m_out[0] = m_out[1] = 0; if (m_ctrl.sound_en()) { for (int i = 0; i < 4; i++) { - m_voice[i].tick(); + m_voice[i].tick(cycle); m_out[0] += m_voice[i].out(0); m_out[1] += m_voice[i].out(1); } } + /* // dac clock (YM3012 format) u8 dac_clock = m_dac.clock(); if (bitfield(++dac_clock, 0, 4) == 0) @@ -34,62 +35,59 @@ void k053260_core::tick() m_dac.set_state(bitfield(dac_state, 0, 2)); } m_dac.set_clock(bitfield(dac_clock, 0, 4)); + */ } -void k053260_core::voice_t::tick() +void k053260_core::voice_t::tick(u32 cycle) { if (m_enable && m_busy) { bool update = false; // update counter - if (bitfield(++m_counter, 0, 12) == 0) + m_counter += cycle; + if (m_counter >= 0x1000) { if (m_bitpos < 8) { m_bitpos += 8; m_addr = bitfield(m_addr + 1, 0, 21); m_remain--; + if (m_remain < 0) // check end flag + { + if (m_loop) + { + m_addr = m_start; + m_remain = m_length; + m_output = 0; + } + else + { + m_busy = false; + } + } } + m_data = m_host.m_intf.read_sample(bitfield(m_addr, 0, 21)); // fetch ROM if (m_adpcm) { - m_bitpos -= 4; - update = true; + m_bitpos -= 4; + const u8 nibble = bitfield(m_data, m_bitpos & 4, 4); // get nibble from ROM + if (nibble) + { + m_output += m_host.adpcm_lut(nibble); + } } else { m_bitpos -= 8; } - m_counter = bitfield(m_pitch, 0, 12); - } - m_data = m_host.m_intf.read_sample(bitfield(m_addr, 0, 21)); // fetch ROM - if (update) - { - const u8 nibble = bitfield(m_data, m_bitpos & 4, 4); // get nibble from ROM - if (nibble) - { - m_adpcm_buf += bitfield(nibble, 3) ? s8(0x80 >> bitfield(nibble, 0, 3)) - : (1 << bitfield(nibble - 1, 0, 3)); - } + m_counter = 0x1000 - bitfield(m_pitch, 0, 12); } - if (m_remain < 0) // check end flag - { - if (m_loop) - { - m_addr = m_start; - m_remain = m_length; - m_adpcm_buf = 0; - } - else - { - m_busy = false; - } - } // calculate output - s32 output = m_adpcm ? m_adpcm_buf : sign_ext(m_data, 8) * s32(m_volume); + s32 output = (m_adpcm ? m_output : sign_ext(m_data, 8)) * s32(m_volume); // use math for now; actually fomula unknown - m_out[0] = (m_pan >= 0) ? s32(output * cos(f64(m_pan) * PI / 180)) : 0; - m_out[1] = (m_pan >= 0) ? s32(output * sin(f64(m_pan) * PI / 180)) : 0; + m_out[0] = (output * m_host.pan_lut(m_pan, 0)) >> 7; + m_out[1] = (output * m_host.pan_lut(m_pan, 1)) >> 7; } else { @@ -244,7 +242,8 @@ void k053260_core::voice_t::keyon() m_addr = m_start; m_remain = m_length; m_bitpos = 4; - m_adpcm_buf = 0; + m_data = 0; + m_output = 0; std::fill(m_out.begin(), m_out.end(), 0); } @@ -259,12 +258,12 @@ void k053260_core::reset() elem.reset(); } - m_intf.write_int(0); + //m_intf.write_int(0); std::fill(m_host2snd.begin(), m_host2snd.end(), 0); std::fill(m_snd2host.begin(), m_snd2host.end(), 0); m_ctrl.reset(); - m_dac.reset(); + //m_dac.reset(); std::fill(m_reg.begin(), m_reg.end(), 0); std::fill(m_out.begin(), m_out.end(), 0); @@ -273,20 +272,20 @@ void k053260_core::reset() // reset voice void k053260_core::voice_t::reset() { - m_enable = 0; - m_busy = 0; - m_loop = 0; - m_adpcm = 0; - m_pitch = 0; - m_start = 0; - m_length = 0; - m_volume = 0; - m_pan = -1; - m_counter = 0; - m_addr = 0; - m_remain = 0; - m_bitpos = 4; - m_data = 0; - m_adpcm_buf = 0; + m_enable = 0; + m_busy = 0; + m_loop = 0; + m_adpcm = 0; + m_pitch = 0; + m_start = 0; + m_length = 0; + m_volume = 0; + m_pan = 4; + m_counter = 0; + m_addr = 0; + m_remain = 0; + m_bitpos = 4; + m_data = 0; + m_output = 0; m_out[0] = m_out[1] = 0; } diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp index a8668a0df..feaffeac5 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp @@ -25,7 +25,7 @@ class k053260_intf : public vgsound_emu_core virtual u8 read_sample(u32 address) { return 0; } // sample fetch - virtual void write_int(u8 out) {} // timer interrupt + //virtual void write_int(u8 out) {} // timer interrupt }; class k053260_core : public vgsound_emu_core @@ -33,7 +33,19 @@ class k053260_core : public vgsound_emu_core friend class k053260_intf; // k053260 specific interface private: - const int pan_dir[8] = {-1, 0, 24, 35, 45, 55, 66, 90}; // pan direction + const s32 m_pan_lut[8][2] = { + {0x00, 0x00}, + {0x7f, 0x00}, + {0x74, 0x34}, + {0x68, 0x49}, + {0x5a, 0x5a}, + {0x49, 0x68}, + {0x34, 0x74}, + {0x00, 0x7f} + }; // pan LUT + + const s8 m_adpcm_lut[16] = + {0, 1, 2, 4, 8, 16, 32, 64, -128, -64, -32, -16, -8, -4, -2, -1}; // ADPCM LUT class voice_t : public vgsound_emu_core { @@ -50,20 +62,20 @@ class k053260_core : public vgsound_emu_core , m_start(0) , m_length(0) , m_volume(0) - , m_pan(-1) + , m_pan(4) , m_counter(0) , m_addr(0) , m_remain(0) , m_bitpos(4) , m_data(0) - , m_adpcm_buf(0) + , m_output(0) { m_out.fill(0); } // internal state void reset(); - void tick(); + void tick(u32 cycle); // accessors void write(u8 address, u8 data); @@ -81,7 +93,7 @@ class k053260_core : public vgsound_emu_core inline void length_inc() { m_length = (m_length + 1) & 0xffff; } - inline void set_pan(u8 pan) { m_pan = m_host.pan_dir[pan & 7]; } + inline void set_pan(u8 pan) { m_pan = pan & 7; } // getters inline bool enable() { return m_enable; } @@ -97,21 +109,21 @@ class k053260_core : public vgsound_emu_core private: // registers k053260_core &m_host; - u16 m_enable : 1; // enable flag - u16 m_busy : 1; // busy status - u16 m_loop : 1; // loop flag - u16 m_adpcm : 1; // ADPCM flag - u16 m_pitch : 12; // pitch - u32 m_start = 0; // start position - u16 m_length = 0; // source length - u8 m_volume = 0; // master volume - int m_pan = -1; // master pan - u16 m_counter = 0; // frequency counter - u32 m_addr = 0; // current address - s32 m_remain = 0; // remain for end sample - u8 m_bitpos = 4; // bit position for ADPCM decoding - u8 m_data = 0; // current data - s8 m_adpcm_buf = 0; // ADPCM buffer + u16 m_enable : 1; // enable flag + u16 m_busy : 1; // busy status + u16 m_loop : 1; // loop flag + u16 m_adpcm : 1; // ADPCM flag + u16 m_pitch : 12; // pitch + u32 m_start = 0; // start position + u16 m_length = 0; // source length + u8 m_volume = 0; // master volume + int m_pan = -1; // master pan + u16 m_counter = 0; // frequency counter + u32 m_addr = 0; // current address + s32 m_remain = 0; // remain for end sample + u8 m_bitpos = 4; // bit position for ADPCM decoding + u8 m_data = 0; // current data + s8 m_output = 0; // ADPCM buffer std::array m_out; // current output }; @@ -152,6 +164,7 @@ class k053260_core : public vgsound_emu_core u8 m_input_en : 2; // Input enable }; + /* class ym3012_t { public: @@ -177,7 +190,9 @@ class k053260_core : public vgsound_emu_core std::array m_in; std::array m_out; }; + */ + /* class dac_t { public: @@ -205,6 +220,7 @@ class k053260_core : public vgsound_emu_core u8 m_clock : 4; // DAC clock (16 clock) u8 m_state : 2; // DAC state (4 state - SAM1, SAM2) }; + */ public: // constructor @@ -213,8 +229,8 @@ class k053260_core : public vgsound_emu_core , m_voice{*this, *this, *this, *this} , m_intf(intf) , m_ctrl(ctrl_t()) - , m_ym3012(ym3012_t()) - , m_dac(dac_t()) + //, m_ym3012(ym3012_t()) + //, m_dac(dac_t()) { m_host2snd.fill(0); m_snd2host.fill(0); @@ -233,7 +249,7 @@ class k053260_core : public vgsound_emu_core // internal state void reset(); - void tick(); + void tick(u32 cycle); // getters for debug, trackers, etc inline s32 output(u8 ch) { return m_out[ch & 1]; } // output for each channels @@ -245,6 +261,11 @@ class k053260_core : public vgsound_emu_core return (voice < 4) ? m_voice[voice].out(ch & 1) : 0; } + protected: + inline s32 pan_lut(const u8 pan, const u8 out) { return m_pan_lut[pan][out]; } + + inline s32 adpcm_lut(const u8 nibble) { return m_adpcm_lut[nibble]; } + private: std::array m_voice; k053260_intf &m_intf; // common memory interface @@ -254,8 +275,8 @@ class k053260_core : public vgsound_emu_core ctrl_t m_ctrl; // chip control - ym3012_t m_ym3012; // YM3012 output - dac_t m_dac; // YM3012 interface + //ym3012_t m_ym3012; // YM3012 output + //dac_t m_dac; // YM3012 interface std::array m_reg; // register pool std::array m_out; // stereo output diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index c30d7f231..319630d6e 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -78,6 +78,7 @@ #include "platform/ga20.h" #include "platform/sm8521.h" #include "platform/pv1000.h" +#include "platform/k053260.h" #include "platform/pcmdac.h" #include "platform/dummy.h" #include "../ta-log.h" @@ -501,6 +502,9 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do case DIV_SYSTEM_PV1000: dispatch=new DivPlatformPV1000; break; + case DIV_SYSTEM_K053260: + dispatch=new DivPlatformK053260; + break; case DIV_SYSTEM_PCM_DAC: dispatch=new DivPlatformPCMDAC; break; diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index faa9f86c3..c51805ab5 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -930,6 +930,10 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song) { break; case DIV_INS_PV1000: break; + case DIV_INS_K053260: + featureSM=true; + featureSL=true; + break; case DIV_INS_MAX: break; diff --git a/src/engine/instrument.h b/src/engine/instrument.h index c53688ec6..932d44ffb 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -80,6 +80,7 @@ enum DivInstrumentType: unsigned short { DIV_INS_POKEMINI=47, DIV_INS_SM8521=48, DIV_INS_PV1000=49, + DIV_INS_K053260=50, DIV_INS_MAX, DIV_INS_NULL }; diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp new file mode 100644 index 000000000..47e7636d1 --- /dev/null +++ b/src/engine/platform/k053260.cpp @@ -0,0 +1,475 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "k053260.h" +#include "../engine.h" +#include "../../ta-log.h" +#include + +#define rWrite(a,v) {if(!skipRegisterWrites) {k053260.write(a,v); regPool[a]=v; if(dumpWrites) addWrite(a,v);}} + +#define CHIP_DIVIDER 64 +#define TICK_DIVIDER 4 + +const char* regCheatSheetK053260[]={ + "FreqL", "0", + "FreqH", "1", + "LengthL", "2", + "LengthH", "3", + "StartL", "4", + "StartM", "5", + "StartH", "6", + "Volume", "7", + NULL +}; + +const char** DivPlatformK053260::getRegisterSheet() { + return regCheatSheetK053260; +} + +inline void DivPlatformK053260::chWrite(unsigned char ch, unsigned int addr, unsigned char val) { + if (!skipRegisterWrites) { + rWrite(8+((ch<<3)|(addr&7)),val); + } +} + +// TODO: this code is weird +// make sure newDispatch didn't break it up +void DivPlatformK053260::acquire(short** buf, size_t len) { + for (int i=0; i32767) lout=32767; + if (lout<-32768) lout=-32768; + if (rout>32767) rout=32767; + if (rout<-32768) rout=-32768; + buf[0][i]=lout; + buf[1][i]=rout; + + for (int i=0; i<4; i++) { + oscBuf[i]->data[oscBuf[i]->needle++]=(k053260.voice_out(i,0)+k053260.voice_out(i,1))>>1; + } + } +} + +void DivPlatformK053260::tick(bool sysTick) { + unsigned char panMask=0; + for (int i=0; i<4; i++) { + chan[i].std.next(); + if (chan[i].std.vol.had) { + chan[i].outVol=((chan[i].vol&0x7f)*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul; + chWrite(i,7,chan[i].outVol); + } + if (NEW_ARP_STRAT) { + chan[i].handleArp(); + } else if (chan[i].std.arp.had) { + if (!chan[i].inPorta) { + chan[i].baseFreq=NOTE_PERIODIC(parent->calcArp(chan[i].note,chan[i].std.arp.val)); + } + chan[i].freqChanged=true; + } + if (chan[i].std.pitch.had) { + if (chan[i].std.pitch.mode) { + chan[i].pitch2+=chan[i].std.pitch.val; + CLAMP_VAR(chan[i].pitch2,-32768,32767); + } else { + chan[i].pitch2=chan[i].std.pitch.val; + } + chan[i].freqChanged=true; + } + if (chan[i].std.panL.had) { // panning + chan[i].panning=4+chan[i].std.panL.val; + if (!isMuted[i]) { + panMask|=1<=0 && samplesong.sampleLen) { + DivSample* s=parent->getSample(sample); + if (s->centerRate<1) { + off=1.0; + } else { + off=8363.0/s->centerRate; + } + } + DivSample* s=parent->getSample(chan[i].sample); + chan[i].freq=0x1000-(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER)); + if (chan[i].freq>4095) chan[i].freq=4095; + if (chan[i].freq<0) chan[i].freq=0; + if (chan[i].keyOn) { + unsigned int start=0; + unsigned int length=0; + if (chan[i].sample>=0 && chan[i].samplesong.sampleLen) { + start=sampleOffK053260[chan[i].sample]; + length=start+s->length8; + } + if (chan[i].audPos>0) { + start=start+MIN(chan[i].audPos,s->length8); + } + start=MIN(start,getSampleMemCapacity()-31); + length=MIN(length,getSampleMemCapacity()-31); + rWrite(0x28,keyoff); // force keyoff first + rWrite(0x2a,loopoff); + chWrite(i,2,length&0xff); + chWrite(i,3,length>>8); + chWrite(i,4,start&0xff); + chWrite(i,5,start>>8); + chWrite(i,6,start>>16); + if (!chan[i].std.vol.had) { + chan[i].outVol=chan[i].vol; + chWrite(i,7,chan[i].outVol); + } + rWrite(0x28,keyon); + if (s->isLoopable()) { + rWrite(0x2a,loopon); + } + chan[i].keyOn=false; + } + if (chan[i].keyOff) { + rWrite(0x28,keyoff); + rWrite(0x2a,loopoff); + chan[i].keyOff=false; + } + if (chan[i].freqChanged) { + chWrite(i,0,chan[i].freq&0xff); + chWrite(i,1,chan[i].freq>>8); + chan[i].freqChanged=false; + } + } + } + if (panMask) { + updatePanning(panMask); + } +} + +void DivPlatformK053260::updatePanning(unsigned char mask) { + if (mask&3) { + rWrite(0x2c, + (isMuted[0]?0:chan[0].panning)| + (isMuted[1]?0:chan[1].panning<<3)); + } + if (mask&0xc) { + rWrite(0x2d, + (isMuted[2]?0:chan[2].panning)| + (isMuted[3]?0:chan[3].panning<<3)); + } +} + +int DivPlatformK053260::dispatch(DivCommand c) { + switch (c.cmd) { + case DIV_CMD_NOTE_ON: { + DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); + chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:127; + if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); + if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); + } + if (chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) { + chan[c.chan].sample=-1; + } + if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].freqChanged=true; + chan[c.chan].note=c.value; + } + chan[c.chan].active=true; + chan[c.chan].keyOn=true; + chan[c.chan].macroInit(ins); + if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { + chan[c.chan].outVol=chan[c.chan].vol; + } + break; + } + case DIV_CMD_NOTE_OFF: + chan[c.chan].sample=-1; + chan[c.chan].active=false; + chan[c.chan].keyOff=true; + chan[c.chan].macroInit(NULL); + break; + case DIV_CMD_NOTE_OFF_ENV: + case DIV_CMD_ENV_RELEASE: + chan[c.chan].std.release(); + break; + case DIV_CMD_INSTRUMENT: + if (chan[c.chan].ins!=c.value || c.value2==1) { + chan[c.chan].ins=c.value; + } + break; + case DIV_CMD_VOLUME: + if (chan[c.chan].vol!=c.value) { + chan[c.chan].vol=c.value; + if (!chan[c.chan].std.vol.has) { + chan[c.chan].outVol=c.value; + chWrite(c.chan,7,chan[c.chan].outVol); + } + } + break; + case DIV_CMD_GET_VOLUME: + if (chan[c.chan].std.vol.has) { + return chan[c.chan].vol; + } + return chan[c.chan].outVol; + break; + case DIV_CMD_PANNING: + chan[c.chan].panning=MIN(parent->convertPanSplitToLinearLR(c.value,c.value2,7)+1,7); + if (!isMuted[c.chan]) { + updatePanning(1<chan[c.chan].baseFreq) { + chan[c.chan].baseFreq+=c.value; + if (chan[c.chan].baseFreq>=destFreq) { + chan[c.chan].baseFreq=destFreq; + return2=true; + } + } else { + chan[c.chan].baseFreq-=c.value; + if (chan[c.chan].baseFreq<=destFreq) { + chan[c.chan].baseFreq=destFreq; + return2=true; + } + } + chan[c.chan].freqChanged=true; + if (return2) { + chan[c.chan].inPorta=false; + return 2; + } + break; + } + case DIV_CMD_LEGATO: { + chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val-12):(0))); + chan[c.chan].freqChanged=true; + chan[c.chan].note=c.value; + break; + } + case DIV_CMD_PRE_PORTA: + if (chan[c.chan].active && c.value2) { + if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA)); + } + if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note); + chan[c.chan].inPorta=c.value; + break; + case DIV_CMD_SAMPLE_POS: + chan[c.chan].audPos=c.value; + chan[c.chan].setPos=true; + break; + case DIV_CMD_GET_VOLMAX: + return 127; + break; + case DIV_CMD_MACRO_OFF: + chan[c.chan].std.mask(c.value,true); + break; + case DIV_CMD_MACRO_ON: + chan[c.chan].std.mask(c.value,false); + break; + case DIV_ALWAYS_SET_VOLUME: + return 1; + break; + default: + break; + } + return 1; +} + +void DivPlatformK053260::muteChannel(int ch, bool mute) { + isMuted[ch]=mute; + updatePanning(1<rate=rate; + } +} + +void DivPlatformK053260::poke(unsigned int addr, unsigned short val) { + rWrite(addr&0x0f,val); +} + +void DivPlatformK053260::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) rWrite(i.addr&0x0f,i.val); +} + +unsigned char* DivPlatformK053260::getRegisterPool() { + return regPool; +} + +int DivPlatformK053260::getRegisterPoolSize() { + return 48; +} + +const void* DivPlatformK053260::getSampleMem(int index) { + return index == 0 ? sampleMem : NULL; +} + +size_t DivPlatformK053260::getSampleMemCapacity(int index) { + return index == 0 ? 2097152 : 0; +} + +size_t DivPlatformK053260::getSampleMemUsage(int index) { + return index == 0 ? sampleMemLen : 0; +} + +bool DivPlatformK053260::isSampleLoaded(int index, int sample) { + if (index!=0) return false; + if (sample<0 || sample>255) return false; + return sampleLoaded[sample]; +} + +void DivPlatformK053260::renderSamples(int sysID) { + memset(sampleMem,0,getSampleMemCapacity()); + memset(sampleOffK053260,0,256*sizeof(unsigned int)); + memset(sampleLoaded,0,256*sizeof(bool)); + + size_t memPos=1; // for avoid silence + for (int i=0; isong.sampleLen; i++) { + DivSample* s=parent->song.sample[i]; + if (!s->renderOn[0][sysID]) { + sampleOffK053260[i]=0; + continue; + } + + int length=MIN(65535,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)); + int actualLength=MIN((int)(getSampleMemCapacity()-memPos),length); + if (actualLength>0) { + sampleOffK053260[i]=memPos-1; + for (int j=0; jdata8[j]; + } + } + if (actualLength +#include "vgsound_emu/src/k053260/k053260.hpp" + +class DivPlatformK053260: public DivDispatch, public k053260_intf { + struct Channel: public SharedChannel { + unsigned int audPos; + int sample, wave; + int panning; + bool setPos; + int macroVolMul; + Channel(): + SharedChannel(127), + audPos(0), + sample(-1), + wave(-1), + panning(4), + setPos(false), + macroVolMul(64) {} + }; + Channel chan[4]; + DivDispatchOscBuffer* oscBuf[4]; + bool isMuted[4]; + int chipType; + unsigned char curChan; + unsigned int sampleOffK053260[256]; + bool sampleLoaded[256]; + + unsigned char* sampleMem; + size_t sampleMemLen; + k053260_core k053260; + unsigned char regPool[48]; + void updatePanning(unsigned char mask); + + friend void putDispatchChip(void*,int); + friend void putDispatchChan(void*,int,int); + + public: + void acquire(short** buf, size_t len); + int dispatch(DivCommand c); + void* getChanState(int chan); + DivMacroInt* getChanMacroInt(int ch); + DivDispatchOscBuffer* getOscBuffer(int chan); + unsigned char* getRegisterPool(); + int getRegisterPoolSize(); + void reset(); + void forceIns(); + void tick(bool sysTick=true); + void muteChannel(int ch, bool mute); + int getOutputCount(); + void setChipModel(int type); + void notifyInsChange(int ins); + void notifyWaveChange(int wave); + void notifyInsDeletion(void* ins); + void setFlags(const DivConfig& flags); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); + const char** getRegisterSheet(); + const void* getSampleMem(int index = 0); + size_t getSampleMemCapacity(int index = 0); + size_t getSampleMemUsage(int index = 0); + bool isSampleLoaded(int index, int sample); + void renderSamples(int chipID); + int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); + void quit(); + DivPlatformK053260(): + DivDispatch(), + k053260_intf(), + k053260(*this) {} + private: + void chWrite(unsigned char ch, unsigned int addr, unsigned char val); +}; + +#endif diff --git a/src/engine/song.h b/src/engine/song.h index 8b6da13b2..bc2dc7501 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -127,7 +127,8 @@ enum DivSystem { DIV_SYSTEM_YM2203_CSM, DIV_SYSTEM_YM2608_CSM, DIV_SYSTEM_SM8521, - DIV_SYSTEM_PV1000 + DIV_SYSTEM_PV1000, + DIV_SYSTEM_K053260 }; struct DivGroovePattern { diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index fbb718cb5..f236fcd2c 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1855,6 +1855,16 @@ void DivEngine::registerSystems() { } ); + sysDefs[DIV_SYSTEM_K053260]=new DivSysDef( + "Konami K053260", NULL, 0xfe/*placeholder*/, 0, 4, false, true, 0x161, false, 1U<writeC(0xff); break; case DIV_SYSTEM_GA20: - for (int i=0; i<3; i++) { + for (int i=0; i<4; i++) { w->writeC(0xbf); // mute w->writeC((baseAddr2|5)+(i*8)); w->writeC(0); @@ -573,6 +573,16 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write w->writeC(0); } break; + case DIV_SYSTEM_K053260: + for (int i=0; i<4; i++) { + w->writeC(0xba); // mute + w->writeC(baseAddr2|0x2f); + w->writeC(0); + w->writeC(0xba); // keyoff + w->writeC(baseAddr2|0x28); + w->writeC(0); + } + break; default: break; } @@ -928,6 +938,11 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write w->writeC(baseAddr2|(write.addr&0x7f)); w->writeC(write.val); break; + case DIV_SYSTEM_K053260: + w->writeC(0xba); + w->writeC(baseAddr2|(write.addr&0x3f)); + w->writeC(write.val&0xff); + break; default: logW("write not handled!"); break; @@ -1093,6 +1108,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p DivDispatch* writeRF5C68[2]={NULL,NULL}; DivDispatch* writeMSM6295[2]={NULL,NULL}; DivDispatch* writeGA20[2]={NULL,NULL}; + DivDispatch* writeK053260[2]={NULL,NULL}; for (int i=0; ichipClock; + CHIP_VOL(40,0.4); + willExport[i]=true; + writeK053260[0]=disCont[i].dispatch; + } else if (!(hasK053260&0x40000000)) { + isSecond[i]=true; + CHIP_VOL_SECOND(40,0.4); + willExport[i]=true; + writeK053260[1]=disCont[i].dispatch; + hasK053260|=0x40000000; + howManyChips++; + } + break; case DIV_SYSTEM_T6W28: if (!hasSN) { hasSN=0xc0000000|disCont[i].dispatch->chipClock; @@ -1964,6 +1995,15 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p w->writeI(0); w->write(writeGA20[i]->getSampleMem(),writeGA20[i]->getSampleMemUsage()); } + if (writeK053260[i]!=NULL && writeK053260[i]->getSampleMemUsage()>0) { + w->writeC(0x67); + w->writeC(0x66); + w->writeC(0x8e); + w->writeI((writeK053260[i]->getSampleMemUsage()+8)|(i*0x80000000)); + w->writeI(writeK053260[i]->getSampleMemCapacity()); + w->writeI(0); + w->write(writeK053260[i]->getSampleMem(),writeK053260[i]->getSampleMemUsage()); + } } // TODO diff --git a/src/gui/dataList.cpp b/src/gui/dataList.cpp index 2a37c7e8e..859a0d0dc 100644 --- a/src/gui/dataList.cpp +++ b/src/gui/dataList.cpp @@ -438,6 +438,10 @@ void FurnaceGUI::drawInsList(bool asChild) { ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_PV1000]); name=fmt::sprintf(ICON_FA_GAMEPAD "##_INS%d",i); break; + case DIV_INS_K053260: + ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_K053260]); + name=fmt::sprintf(ICON_FA_BAR_CHART "##_INS%d",i); + break; default: ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_UNKNOWN]); name=fmt::sprintf(ICON_FA_QUESTION "##_INS%d",i); diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index 49d568b3c..7a01edf8e 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -53,6 +53,7 @@ #include "../engine/platform/ga20.h" #include "../engine/platform/sm8521.h" #include "../engine/platform/pv1000.h" +#include "../engine/platform/k053260.h" #include "../engine/platform/dummy.h" #define COMMON_CHIP_DEBUG \ @@ -545,6 +546,13 @@ void putDispatchChip(void* data, int type) { COMMON_CHIP_DEBUG_BOOL; break; } + case DIV_SYSTEM_K053260: { + DivPlatformK053260* ch=(DivPlatformK053260*)data; + ImGui::Text("> K053260"); + COMMON_CHIP_DEBUG; + COMMON_CHIP_DEBUG_BOOL; + break; + } default: ImGui::Text("Unimplemented chip! Help!"); break; @@ -1083,6 +1091,18 @@ void putDispatchChan(void* data, int chanNum, int type) { COMMON_CHAN_DEBUG_BOOL; break; } + case DIV_SYSTEM_K053260: { + DivPlatformK053260::Channel* ch=(DivPlatformK053260::Channel*)data; + ImGui::Text("> K053260"); + COMMON_CHAN_DEBUG; + ImGui::Text("* Sample: %d",ch->sample); + ImGui::Text(" - pos: %d",ch->audPos); + ImGui::Text("- panning: %d",ch->panning); + ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + break; + } default: ImGui::Text("Unimplemented chip! Help!"); break; diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 4e6cdec5b..475798643 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -1344,7 +1344,8 @@ void FurnaceGUI::doAction(int what) { i==DIV_INS_SNES || i==DIV_INS_ES5506 || i==DIV_INS_K007232 || - i==DIV_INS_GA20) { + i==DIV_INS_GA20 || + i==DIV_INS_K053260) { makeInsTypeList.push_back(i); } } diff --git a/src/gui/gui.h b/src/gui/gui.h index 7dddb53e7..9fcabf6c7 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -193,6 +193,7 @@ enum FurnaceGUIColors { GUI_COLOR_INSTR_POKEMINI, GUI_COLOR_INSTR_SM8521, GUI_COLOR_INSTR_PV1000, + GUI_COLOR_INSTR_K053260, GUI_COLOR_INSTR_UNKNOWN, GUI_COLOR_CHANNEL_BG, diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index 214eb4688..15b4e8c7f 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -131,6 +131,7 @@ const char* insTypes[DIV_INS_MAX+1]={ "Pokémon Mini/QuadTone", "SM8521", "PV-1000", + "K053260", NULL }; @@ -822,6 +823,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={ D(GUI_COLOR_INSTR_POKEMINI,"",ImVec4(1.0f,1.0f,0.3f,1.0f)), D(GUI_COLOR_INSTR_SM8521,"",ImVec4(0.5f,0.55f,0.6f,1.0f)), D(GUI_COLOR_INSTR_PV1000,"",ImVec4(0.4f,0.6f,0.7f,1.0f)), + D(GUI_COLOR_INSTR_K053260,"",ImVec4(1.0f,0.8f,0.1f,1.0f)), D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)), D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)), @@ -1005,6 +1007,7 @@ const int availableSystems[]={ DIV_SYSTEM_GA20, DIV_SYSTEM_SM8521, DIV_SYSTEM_PV1000, + DIV_SYSTEM_K053260, DIV_SYSTEM_PCM_DAC, DIV_SYSTEM_PONG, 0 // don't remove this last one! @@ -1113,6 +1116,7 @@ const int chipsSample[]={ DIV_SYSTEM_GA20, DIV_SYSTEM_PCM_DAC, DIV_SYSTEM_ES5506, + DIV_SYSTEM_K053260, 0 // don't remove this last one! }; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index abac70c1a..92692ce5d 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -4338,7 +4338,8 @@ void FurnaceGUI::drawInsEdit() { ins->type==DIV_INS_SNES || ins->type==DIV_INS_ES5506 || ins->type==DIV_INS_K007232 || - ins->type==DIV_INS_GA20) { + ins->type==DIV_INS_GA20 || + ins->type==DIV_INS_K053260) { if (ImGui::BeginTabItem((ins->type==DIV_INS_SU)?"Sound Unit":"Sample")) { String sName; if (ins->amiga.initSample<0 || ins->amiga.initSample>=e->song.sampleLen) { @@ -5078,7 +5079,8 @@ void FurnaceGUI::drawInsEdit() { } if (ins->type==DIV_INS_FM || ins->type==DIV_INS_SEGAPCM || ins->type==DIV_INS_MIKEY || ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_SU || ins->type==DIV_INS_OPZ || - ins->type==DIV_INS_OPM || ins->type==DIV_INS_SNES || ins->type==DIV_INS_MSM5232) { + ins->type==DIV_INS_OPM || ins->type==DIV_INS_SNES || ins->type==DIV_INS_MSM5232 || + ins->type==DIV_INS_K053260) { volMax=127; } if (ins->type==DIV_INS_GB) { @@ -5167,7 +5169,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SCC || ins->type==DIV_INS_PET || ins->type==DIV_INS_SEGAPCM || ins->type==DIV_INS_FM || ins->type==DIV_INS_K007232 || ins->type==DIV_INS_GA20 || - ins->type==DIV_INS_SM8521 || ins->type==DIV_INS_PV1000) { + ins->type==DIV_INS_SM8521 || ins->type==DIV_INS_PV1000 || ins->type==DIV_INS_K053260) { dutyMax=0; } if (ins->type==DIV_INS_VBOY) { @@ -5267,6 +5269,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_SEGAPCM) waveMax=0; if (ins->type==DIV_INS_K007232) waveMax=0; if (ins->type==DIV_INS_GA20) waveMax=0; + if (ins->type==DIV_INS_K053260) waveMax=0; if (ins->type==DIV_INS_POKEMINI) waveMax=0; if (ins->type==DIV_INS_SU || ins->type==DIV_INS_POKEY) waveMax=7; if (ins->type==DIV_INS_PET) { @@ -5385,6 +5388,11 @@ void FurnaceGUI::drawInsEdit() { panMax=7; panSingleNoBit=true; } + if (ins->type==DIV_INS_K053260) { + panMin=-3; + panMax=3; + panSingleNoBit=true; + } if (ins->type==DIV_INS_SU) { panMin=-127; panMax=127; @@ -5475,7 +5483,8 @@ void FurnaceGUI::drawInsEdit() { ins->type==DIV_INS_VBOY || (ins->type==DIV_INS_X1_010 && ins->amiga.useSample) || ins->type==DIV_INS_K007232 || - ins->type==DIV_INS_GA20) { + ins->type==DIV_INS_GA20 || + ins->type==DIV_INS_K053260) { macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); } if (ex1Max>0) { diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index 3354914c1..33924b846 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -1245,6 +1245,42 @@ void FurnaceGUI::initSystemPresets() { CH(DIV_SYSTEM_K007232, 1.0f, 0, "") // "" } ); + ENTRY( + "Konami Rollergames", { + CH(DIV_SYSTEM_OPL2, 1.0f, 0, ""), // 3.58MHz + CH(DIV_SYSTEM_K053260, 1.0f, 0, ""), // "" + } + ); + ENTRY( + "Konami Rollergames (drums mode)", { + CH(DIV_SYSTEM_OPL2_DRUMS, 1.0f, 0, ""), // 3.58MHz + CH(DIV_SYSTEM_K053260, 1.0f, 0, ""), // "" + } + ); + ENTRY( + "Konami Golfing Greats", { + CH(DIV_SYSTEM_K053260, 1.0f, 0, ""), // 3.58MHz + } + ); + ENTRY( + "Konami Lightning Fighters", { + CH(DIV_SYSTEM_YM2151, 1.0f, 0, ""), // 3.58MHz + CH(DIV_SYSTEM_K053260, 1.0f, 0, ""), // "" + } + ); + ENTRY( + "Konami Over Drive", { + CH(DIV_SYSTEM_YM2151, 1.0f, 0, ""), // 3.58MHz + CH(DIV_SYSTEM_K053260, 1.0f, 0, ""), // "" + CH(DIV_SYSTEM_K053260, 1.0f, 0, ""), // "" + } + ); + ENTRY( + "Konami Asterix", { + CH(DIV_SYSTEM_YM2151, 1.0f, 0, "clockSel=2"), // 4MHz + CH(DIV_SYSTEM_K053260, 1.0f, 0, "clockSel=1"), // "" + } + ); ENTRY( "Konami Hexion", { CH(DIV_SYSTEM_SCC, 1.0f, 0, "clockSel=2"), // 1.5MHz (3MHz input) @@ -2449,6 +2485,11 @@ void FurnaceGUI::initSystemPresets() { CH(DIV_SYSTEM_ES5506, 1.0f, 0, "channels=31") } ); + ENTRY( + "Konami K053260", { + CH(DIV_SYSTEM_K053260, 1.0f, 0, "") + } + ); CATEGORY_END; CATEGORY_BEGIN("Wavetable","chips which use user-specified waveforms to generate sound."); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 207c8838b..7edaeb0fa 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -1954,6 +1954,7 @@ void FurnaceGUI::drawSettings() { UI_COLOR_CONFIG(GUI_COLOR_INSTR_POKEMINI,"Pokémon Mini"); UI_COLOR_CONFIG(GUI_COLOR_INSTR_SM8521,"SM8521"); UI_COLOR_CONFIG(GUI_COLOR_INSTR_PV1000,"PV-1000"); + UI_COLOR_CONFIG(GUI_COLOR_INSTR_K053260,"K053260"); UI_COLOR_CONFIG(GUI_COLOR_INSTR_UNKNOWN,"Other/Unknown"); ImGui::TreePop(); } diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 77bc6c726..31f66e0a7 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -1784,6 +1784,26 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo } break; }*/ + case DIV_SYSTEM_K053260: { + int clockSel=flags.getInt("clockSel",0); + + ImGui::Text("Clock rate:"); + if (ImGui::RadioButton("3.58MHz (NTSC)",clockSel==0)) { + clockSel=0; + altered=true; + } + if (ImGui::RadioButton("4MHz",clockSel==1)) { + clockSel=1; + altered=true; + } + + if (altered) { + e->lockSave([&]() { + flags.set("clockSel",clockSel); + }); + } + break; + } case DIV_SYSTEM_SWAN: case DIV_SYSTEM_BUBSYS_WSG: case DIV_SYSTEM_PET: From 09726e6290a4ccdbd5360dcb80339e6472dd3d00 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 2 Apr 2023 14:34:10 +0900 Subject: [PATCH 02/20] Fix pitch --- extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp index 2ee4efac3..9c8d9434b 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp @@ -80,7 +80,7 @@ void k053260_core::voice_t::tick(u32 cycle) { m_bitpos -= 8; } - m_counter = 0x1000 - bitfield(m_pitch, 0, 12); + m_counter = (m_counter - 0x1000) + bitfield(m_pitch, 0, 12); } // calculate output From dee28d218e302fabede1282aefae0634e8612f7e Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 2 Apr 2023 14:55:10 +0900 Subject: [PATCH 03/20] Implement sample playback Fix register viewer Minor optimize --- .../vgsound_emu/src/k053260/k053260.cpp | 10 ++-- .../vgsound_emu/src/k053260/k053260.hpp | 22 ++++----- src/engine/platform/k053260.cpp | 49 +++++++++++++------ src/engine/platform/k053260.h | 1 + 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp index 9c8d9434b..990c1fc36 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp @@ -244,7 +244,7 @@ void k053260_core::voice_t::keyon() m_bitpos = 4; m_data = 0; m_output = 0; - std::fill(m_out.begin(), m_out.end(), 0); + std::fill_n(m_out, 2, 0); } // key off trigger @@ -260,13 +260,13 @@ void k053260_core::reset() //m_intf.write_int(0); - std::fill(m_host2snd.begin(), m_host2snd.end(), 0); - std::fill(m_snd2host.begin(), m_snd2host.end(), 0); + std::fill_n(m_host2snd, 2, 0); + std::fill_n(m_snd2host, 2, 0); m_ctrl.reset(); //m_dac.reset(); - std::fill(m_reg.begin(), m_reg.end(), 0); - std::fill(m_out.begin(), m_out.end(), 0); + std::fill_n(m_reg, 64, 0); + std::fill_n(m_out, 2, 0); } // reset voice diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp index feaffeac5..bfb7ea002 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp @@ -70,7 +70,7 @@ class k053260_core : public vgsound_emu_core , m_data(0) , m_output(0) { - m_out.fill(0); + std::fill_n(m_out, 2, 0); } // internal state @@ -124,7 +124,7 @@ class k053260_core : public vgsound_emu_core u8 m_bitpos = 4; // bit position for ADPCM decoding u8 m_data = 0; // current data s8 m_output = 0; // ADPCM buffer - std::array m_out; // current output + s32 m_out[2]; // current output }; class ctrl_t @@ -232,10 +232,10 @@ class k053260_core : public vgsound_emu_core //, m_ym3012(ym3012_t()) //, m_dac(dac_t()) { - m_host2snd.fill(0); - m_snd2host.fill(0); - m_reg.fill(0); - m_out.fill(0); + std::fill_n(m_host2snd, 2, 0); + std::fill_n(m_snd2host, 2, 0); + std::fill_n(m_reg, 64, 0); + std::fill_n(m_out, 2, 0); } // communications @@ -267,19 +267,19 @@ class k053260_core : public vgsound_emu_core inline s32 adpcm_lut(const u8 nibble) { return m_adpcm_lut[nibble]; } private: - std::array m_voice; + voice_t m_voice[4]; k053260_intf &m_intf; // common memory interface - std::array m_host2snd; - std::array m_snd2host; + u8 m_host2snd[2]; + u8 m_snd2host[2]; ctrl_t m_ctrl; // chip control //ym3012_t m_ym3012; // YM3012 output //dac_t m_dac; // YM3012 interface - std::array m_reg; // register pool - std::array m_out; // stereo output + u8 m_reg[64]; // register pool + s32 m_out[2]; // stereo output }; #endif diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 47e7636d1..f42a532dc 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -22,20 +22,32 @@ #include "../../ta-log.h" #include -#define rWrite(a,v) {if(!skipRegisterWrites) {k053260.write(a,v); regPool[a]=v; if(dumpWrites) addWrite(a,v);}} +#define rWrite(a,v) {if(!skipRegisterWrites && a<0x30) {k053260.write(a,v); regPool[a]=v; if(dumpWrites) addWrite(a,v);}} -#define CHIP_DIVIDER 64 -#define TICK_DIVIDER 4 +#define CHIP_DIVIDER 16 +#define TICK_DIVIDER 64 // for match to YM3012 output rate const char* regCheatSheetK053260[]={ - "FreqL", "0", - "FreqH", "1", - "LengthL", "2", - "LengthH", "3", - "StartL", "4", - "StartM", "5", - "StartH", "6", - "Volume", "7", + "MainToSub0", "00", + "MainToSub1", "01", + "SubToMain0", "02", + "SubToMain1", "03", + "CHx_FreqL", "08+x*8", + "CHx_FreqH", "09+x*8", + "CHx_LengthL", "0A+x*8", + "CHx_LengthH", "0B+x*8", + "CHx_StartL", "0C+x*8", + "CHx_StartM", "0D+x*8", + "CHx_StartH", "0E+x*8", + "CHx_Volume", "0F+x*8", + "KeyOn", "28", + "Status", "29", + "LoopFormat", "2A", + "Test", "2B", + "CH01_Pan", "2C", + "CH23_Pan", "2D", + "ROMReadback", "2E", + "Control", "2F", NULL }; @@ -49,8 +61,14 @@ inline void DivPlatformK053260::chWrite(unsigned char ch, unsigned int addr, uns } } -// TODO: this code is weird -// make sure newDispatch didn't break it up +u8 DivPlatformK053260::read_sample(u32 address) { + if ((sampleMem!=NULL) && (address& wlist) { - for (DivRegWrite& i: wlist) rWrite(i.addr&0x0f,i.val); + for (DivRegWrite& i: wlist) rWrite(i.addr&0x3f,i.val); } unsigned char* DivPlatformK053260::getRegisterPool() { + regPool[0x29]=k053260.read(0x29); // dynamically updated return regPool; } diff --git a/src/engine/platform/k053260.h b/src/engine/platform/k053260.h index c449206f6..3b21cb4dc 100644 --- a/src/engine/platform/k053260.h +++ b/src/engine/platform/k053260.h @@ -58,6 +58,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { friend void putDispatchChan(void*,int,int); public: + virtual u8 read_sample(u32 address) override; void acquire(short** buf, size_t len); int dispatch(DivCommand c); void* getChanState(int chan); From 8f783e604a4cd2c0bd2ae870b90a9e462a8490a1 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 2 Apr 2023 15:48:30 +0900 Subject: [PATCH 04/20] Minor fix --- src/engine/platform/k053260.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index f42a532dc..801325f86 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -159,6 +159,7 @@ void DivPlatformK053260::tick(bool sysTick) { } if (chan[i].audPos>0) { start=start+MIN(chan[i].audPos,s->length8); + length=MAX(1,length-chan[i].audPos); } start=MIN(start,getSampleMemCapacity()-31); length=MIN(length,getSampleMemCapacity()-31); From f56e09606a741ab0408bf892c390c8202f026dc6 Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 2 Apr 2023 15:49:12 +0900 Subject: [PATCH 05/20] More fixes --- src/engine/platform/k053260.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 801325f86..dd8364fa1 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -161,8 +161,8 @@ void DivPlatformK053260::tick(bool sysTick) { start=start+MIN(chan[i].audPos,s->length8); length=MAX(1,length-chan[i].audPos); } - start=MIN(start,getSampleMemCapacity()-31); - length=MIN(length,getSampleMemCapacity()-31); + start=MIN(start,getSampleMemCapacity()); + length=MIN(65535,MIN(length,getSampleMemCapacity())); rWrite(0x28,keyoff); // force keyoff first rWrite(0x2a,loopoff); chWrite(i,2,length&0xff); From f7768dafe3937dc0b95829cb2659959502ff0cbb Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 2 Apr 2023 23:01:57 +0900 Subject: [PATCH 06/20] Fix K053260 VGM output --- src/engine/vgmOps.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 4445ef93b..d68302b5d 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -1627,12 +1627,12 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p case DIV_SYSTEM_K053260: if (!hasK053260) { hasK053260=disCont[i].dispatch->chipClock; - CHIP_VOL(40,0.4); + CHIP_VOL(29,0.4); willExport[i]=true; writeK053260[0]=disCont[i].dispatch; } else if (!(hasK053260&0x40000000)) { isSecond[i]=true; - CHIP_VOL_SECOND(40,0.4); + CHIP_VOL_SECOND(29,0.4); willExport[i]=true; writeK053260[1]=disCont[i].dispatch; hasK053260|=0x40000000; From 9b877764c41db500bb05cf7f0c40a1b80d1a1d8a Mon Sep 17 00:00:00 2001 From: cam900 Date: Sun, 2 Apr 2023 23:33:34 +0900 Subject: [PATCH 07/20] Fix build --- extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp index 990c1fc36..b1c56a8d7 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp @@ -42,7 +42,6 @@ void k053260_core::voice_t::tick(u32 cycle) { if (m_enable && m_busy) { - bool update = false; // update counter m_counter += cycle; if (m_counter >= 0x1000) From 048728b496017cdf344e675e55d6514e549efe00 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 3 Apr 2023 00:34:09 +0900 Subject: [PATCH 08/20] Add reverse playback support --- .../vgsound_emu/src/k053260/k053260.cpp | 6 ++++-- .../vgsound_emu/src/k053260/k053260.hpp | 9 +++++++- src/engine/platform/k053260.cpp | 21 ++++++++++++++++--- src/engine/platform/k053260.h | 3 ++- src/engine/sysDef.cpp | 5 ++++- src/gui/debug.cpp | 1 + 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp index b1c56a8d7..59d8af8f7 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.cpp @@ -49,7 +49,7 @@ void k053260_core::voice_t::tick(u32 cycle) if (m_bitpos < 8) { m_bitpos += 8; - m_addr = bitfield(m_addr + 1, 0, 21); + m_addr = m_reverse ? bitfield(m_addr - 1, 0, 21) : bitfield(m_addr + 1, 0, 21); m_remain--; if (m_remain < 0) // check end flag { @@ -69,7 +69,7 @@ void k053260_core::voice_t::tick(u32 cycle) if (m_adpcm) { m_bitpos -= 4; - const u8 nibble = bitfield(m_data, m_bitpos & 4, 4); // get nibble from ROM + const u8 nibble = bitfield(m_data, m_reverse ? (~m_bitpos & 4) : (m_bitpos & 4), 4); // get nibble from ROM if (nibble) { m_output += m_host.adpcm_lut(nibble); @@ -169,6 +169,7 @@ void k053260_core::write(u8 address, u8 data) case 0x28: // keyon/off toggle for (int i = 0; i < 4; i++) { + m_voice[i].set_reverse(bitfield(data, 4 + i)); if (bitfield(data, i) && (!m_voice[i].enable())) { // rising edge (keyon) m_voice[i].keyon(); @@ -276,6 +277,7 @@ void k053260_core::voice_t::reset() m_loop = 0; m_adpcm = 0; m_pitch = 0; + m_reverse = 0; m_start = 0; m_length = 0; m_volume = 0; diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp index bfb7ea002..9eb81363d 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k053260/k053260.hpp @@ -59,6 +59,7 @@ class k053260_core : public vgsound_emu_core , m_loop(0) , m_adpcm(0) , m_pitch(0) + , m_reverse(0) , m_start(0) , m_length(0) , m_volume(0) @@ -91,6 +92,11 @@ class k053260_core : public vgsound_emu_core inline void set_adpcm(bool adpcm) { m_adpcm = adpcm ? 1 : 0; } + inline void set_reverse(const bool reverse) + { + m_reverse = reverse ? 1 : 0; + } + inline void length_inc() { m_length = (m_length + 1) & 0xffff; } inline void set_pan(u8 pan) { m_pan = pan & 7; } @@ -114,10 +120,11 @@ class k053260_core : public vgsound_emu_core u16 m_loop : 1; // loop flag u16 m_adpcm : 1; // ADPCM flag u16 m_pitch : 12; // pitch + u8 m_reverse : 1; // reverse playback u32 m_start = 0; // start position u16 m_length = 0; // source length u8 m_volume = 0; // master volume - int m_pan = -1; // master pan + s32 m_pan = 4; // master pan u16 m_counter = 0; // frequency counter u32 m_addr = 0; // current address s32 m_remain = 0; // remain for end sample diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index dd8364fa1..b35bc5a27 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -133,7 +133,7 @@ void DivPlatformK053260::tick(bool sysTick) { } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { unsigned char keyon=regPool[0x28]|(1<=0 && chan[i].samplesong.sampleLen) { start=sampleOffK053260[chan[i].sample]; - length=start+s->length8; + length=s->length8; + if (chan[i].reverse) { + start+=length; + keyon|=(16<0) { - start=start+MIN(chan[i].audPos,s->length8); + if (chan[i].reverse) { + start=start-MIN(chan[i].audPos,s->length8); + } + else { + start=start+MIN(chan[i].audPos,s->length8); + } length=MAX(1,length-chan[i].audPos); } start=MIN(start,getSampleMemCapacity()); @@ -314,6 +323,12 @@ int DivPlatformK053260::dispatch(DivCommand c) { chan[c.chan].audPos=c.value; chan[c.chan].setPos=true; break; + case DIV_CMD_SAMPLE_DIR: { + if (chan[c.chan].reverse!=(bool)(c.value&1)) { + chan[c.chan].reverse=c.value&1; + } + break; + } case DIV_CMD_GET_VOLMAX: return 127; break; diff --git a/src/engine/platform/k053260.h b/src/engine/platform/k053260.h index 3b21cb4dc..42ae0565a 100644 --- a/src/engine/platform/k053260.h +++ b/src/engine/platform/k053260.h @@ -29,7 +29,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { unsigned int audPos; int sample, wave; int panning; - bool setPos; + bool setPos, reverse; int macroVolMul; Channel(): SharedChannel(127), @@ -38,6 +38,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { wave(-1), panning(4), setPos(false), + reverse(false), macroVolMul(64) {} }; Channel chan[4]; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index f236fcd2c..0ce88965e 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1862,7 +1862,10 @@ void DivEngine::registerSystems() { {"CH1", "CH2", "CH3", "CH4"}, {DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM}, {DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260, DIV_INS_K053260}, - {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA} + {DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA}, + { + {0xdf, {DIV_CMD_SAMPLE_DIR, "DFxx: Set sample playback direction (0: normal; 1: reverse)"}} + } ); sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef( diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index 7a01edf8e..b1cdb2920 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -1101,6 +1101,7 @@ void putDispatchChan(void* data, int chanNum, int type) { ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); COMMON_CHAN_DEBUG_BOOL; ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + ImGui::TextColored(ch->reverse?colorOn:colorOff,">> Reverse"); break; } default: From 40f3455357fc9f8c2e4f7fd45a41559752a97e3a Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 3 Apr 2023 00:35:02 +0900 Subject: [PATCH 09/20] Fix build --- src/engine/platform/k053260.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index b35bc5a27..1705f1568 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -22,7 +22,7 @@ #include "../../ta-log.h" #include -#define rWrite(a,v) {if(!skipRegisterWrites && a<0x30) {k053260.write(a,v); regPool[a]=v; if(dumpWrites) addWrite(a,v);}} +#define rWrite(a,v) {if((!skipRegisterWrites) && (a<0x30)) {k053260.write(a,v); regPool[a]=v; if(dumpWrites) addWrite(a,v);}} #define CHIP_DIVIDER 16 #define TICK_DIVIDER 64 // for match to YM3012 output rate From 04f208c535677985d203b3301cad9c2a0767b580 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 3 Apr 2023 06:34:05 +0900 Subject: [PATCH 10/20] Fix build again --- src/engine/platform/k053260.cpp | 6 +++--- src/engine/platform/k053260.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 1705f1568..04cec849d 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -22,7 +22,7 @@ #include "../../ta-log.h" #include -#define rWrite(a,v) {if((!skipRegisterWrites) && (a<0x30)) {k053260.write(a,v); regPool[a]=v; if(dumpWrites) addWrite(a,v);}} +#define rWrite(a,v) {if(!skipRegisterWrites) {k053260.write(a,v); regPool[a]=v; if(dumpWrites) addWrite(a,v);}} #define CHIP_DIVIDER 16 #define TICK_DIVIDER 64 // for match to YM3012 output rate @@ -374,7 +374,7 @@ DivDispatchOscBuffer* DivPlatformK053260::getOscBuffer(int ch) { } void DivPlatformK053260::reset() { - memset(regPool,0,48); + memset(regPool,0,64); k053260.reset(); rWrite(0x28,0); // keyoff all channels for (int i=0; i<4; i++) { @@ -434,7 +434,7 @@ unsigned char* DivPlatformK053260::getRegisterPool() { } int DivPlatformK053260::getRegisterPoolSize() { - return 48; + return 64; } const void* DivPlatformK053260::getSampleMem(int index) { diff --git a/src/engine/platform/k053260.h b/src/engine/platform/k053260.h index 42ae0565a..c0c3f5a97 100644 --- a/src/engine/platform/k053260.h +++ b/src/engine/platform/k053260.h @@ -52,7 +52,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { unsigned char* sampleMem; size_t sampleMemLen; k053260_core k053260; - unsigned char regPool[48]; + unsigned char regPool[64]; void updatePanning(unsigned char mask); friend void putDispatchChip(void*,int); From d9c64e7c8c0e9db253f8f6f6b38cd9a357bbfcf1 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 3 Apr 2023 06:42:37 +0900 Subject: [PATCH 11/20] Fix typecasting --- src/engine/platform/k053260.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 04cec849d..a082be6d1 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -70,7 +70,7 @@ u8 DivPlatformK053260::read_sample(u32 address) { } void DivPlatformK053260::acquire(short** buf, size_t len) { - for (int i=0; i Date: Mon, 3 Apr 2023 06:44:00 +0900 Subject: [PATCH 12/20] Minor optimize --- src/engine/platform/k053260.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index a082be6d1..7005f18d3 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -63,8 +63,7 @@ inline void DivPlatformK053260::chWrite(unsigned char ch, unsigned int addr, uns u8 DivPlatformK053260::read_sample(u32 address) { if ((sampleMem!=NULL) && (address Date: Mon, 3 Apr 2023 07:02:56 +0900 Subject: [PATCH 13/20] Fix Mac compile --- src/engine/platform/k053260.h | 53 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/engine/platform/k053260.h b/src/engine/platform/k053260.h index c0c3f5a97..ce531f3d5 100644 --- a/src/engine/platform/k053260.h +++ b/src/engine/platform/k053260.h @@ -60,33 +60,32 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { public: virtual u8 read_sample(u32 address) override; - void acquire(short** buf, size_t len); - int dispatch(DivCommand c); - void* getChanState(int chan); - DivMacroInt* getChanMacroInt(int ch); - DivDispatchOscBuffer* getOscBuffer(int chan); - unsigned char* getRegisterPool(); - int getRegisterPoolSize(); - void reset(); - void forceIns(); - void tick(bool sysTick=true); - void muteChannel(int ch, bool mute); - int getOutputCount(); - void setChipModel(int type); - void notifyInsChange(int ins); - void notifyWaveChange(int wave); - void notifyInsDeletion(void* ins); - void setFlags(const DivConfig& flags); - void poke(unsigned int addr, unsigned short val); - void poke(std::vector& wlist); - const char** getRegisterSheet(); - const void* getSampleMem(int index = 0); - size_t getSampleMemCapacity(int index = 0); - size_t getSampleMemUsage(int index = 0); - bool isSampleLoaded(int index, int sample); - void renderSamples(int chipID); - int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); - void quit(); + virtual void acquire(short** buf, size_t len) override; + virtual int dispatch(DivCommand c) override; + virtual void* getChanState(int chan) override; + virtual DivMacroInt* getChanMacroInt(int ch) override; + virtual DivDispatchOscBuffer* getOscBuffer(int chan) override; + virtual unsigned char* getRegisterPool() override; + virtual int getRegisterPoolSize() override; + virtual void reset() override; + virtual void forceIns() override; + virtual void tick(bool sysTick=true) override; + virtual void muteChannel(int ch, bool mute) override; + virtual int getOutputCount() override; + virtual void notifyInsChange(int ins) override; + virtual void notifyWaveChange(int wave) override; + virtual void notifyInsDeletion(void* ins) override; + virtual void setFlags(const DivConfig& flags) override; + virtual void poke(unsigned int addr, unsigned short val) override; + virtual void poke(std::vector& wlist) override; + virtual const char** getRegisterSheet() override; + virtual const void* getSampleMem(int index = 0) override; + virtual size_t getSampleMemCapacity(int index = 0) override; + virtual size_t getSampleMemUsage(int index = 0) override; + virtual bool isSampleLoaded(int index, int sample) override; + virtual void renderSamples(int chipID) override; + virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override; + virtual void quit() override; DivPlatformK053260(): DivDispatch(), k053260_intf(), From 74958c59fa2368e2c8f078807745a9a147d1469d Mon Sep 17 00:00:00 2001 From: cam900 Date: Sat, 8 Apr 2023 08:52:16 +0900 Subject: [PATCH 14/20] Sync with master --- src/engine/platform/k053260.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 7005f18d3..ec5f26cd5 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -223,7 +223,10 @@ int DivPlatformK053260::dispatch(DivCommand c) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA); chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:127; - if (c.value!=DIV_NOTE_NULL) chan[c.chan].sample=ins->amiga.getSample(c.value); + if (c.value!=DIV_NOTE_NULL) { + chan[c.chan].sample=ins->amiga.getSample(c.value); + c.value=ins->amiga.getFreq(c.value); + } if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); } From 0e072b62b3cc883785be966a2ff7e4e0caf7ea79 Mon Sep 17 00:00:00 2001 From: cam900 Date: Tue, 2 May 2023 15:14:46 +0900 Subject: [PATCH 15/20] Fix sample cutoff with looping --- src/engine/platform/k053260.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index ec5f26cd5..396316d62 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -470,7 +470,7 @@ void DivPlatformK053260::renderSamples(int sysID) { continue; } - int length=MIN(65535,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)); + int length=MIN(65535,s->getEndPosition(DIV_SAMPLE_DEPTH_8BIT)); int actualLength=MIN((int)(getSampleMemCapacity()-memPos),length); if (actualLength>0) { sampleOffK053260[i]=memPos-1; From 4efd3591d2eb6ee4520fe01a7031ab02deba49a2 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 26 Jun 2023 19:59:57 +0900 Subject: [PATCH 16/20] Add silence to avoid popping noise --- src/engine/platform/k053260.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index edd9400b9..da7b58f29 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -477,6 +477,7 @@ void DivPlatformK053260::renderSamples(int sysID) { for (int j=0; jdata8[j]; } + sampleMem[memPos++]=0; // Silence for avoid popping noise } if (actualLength Date: Mon, 26 Jun 2023 20:00:29 +0900 Subject: [PATCH 17/20] Fix offset --- src/engine/platform/k053260.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index da7b58f29..7ba1cc2ca 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -471,7 +471,7 @@ void DivPlatformK053260::renderSamples(int sysID) { } int length=MIN(65535,s->getEndPosition(DIV_SAMPLE_DEPTH_8BIT)); - int actualLength=MIN((int)(getSampleMemCapacity()-memPos),length); + int actualLength=MIN((int)(getSampleMemCapacity()-memPos-1),length); if (actualLength>0) { sampleOffK053260[i]=memPos-1; for (int j=0; j Date: Wed, 28 Jun 2023 20:05:53 +0900 Subject: [PATCH 18/20] Loop point ignored in K053260 --- src/gui/sampleEdit.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index f68fd7a88..28ce24d2f 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -246,6 +246,13 @@ void FurnaceGUI::drawSampleEdit() { } } break; + case DIV_SYSTEM_K053260: + if (sample->loop) { + if (sample->loopStart!=0 || sample->loopEnd!=(int)(sample->samples)) { + SAMPLE_WARN(warnLoopPos,"K053260: loop point ignored (may only loop entire sample)"); + } + } + break; default: break; } From d33d487ab9c90a512dcfd811e6aca2925607cf37 Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 29 Jun 2023 21:35:53 +0900 Subject: [PATCH 19/20] Add warning --- src/gui/sampleEdit.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index 16eecfc8d..0c470177e 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -273,6 +273,9 @@ void FurnaceGUI::drawSampleEdit() { SAMPLE_WARN(warnLoopPos,"K053260: loop point ignored (may only loop entire sample)"); } } + if (sample->samples>65535) { + SAMPLE_WARN(warnLength,"K053260: maximum sample length is 65535"); + } break; default: break; From 5e0fb78a90eae211cceffb8bdbc4d300d10dfa87 Mon Sep 17 00:00:00 2001 From: cam900 Date: Mon, 10 Jul 2023 19:57:45 +0900 Subject: [PATCH 20/20] Use allocated ID --- src/engine/sysDef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 2cc3ccf1c..6d8a308e6 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1865,7 +1865,7 @@ void DivEngine::registerSystems() { ); sysDefs[DIV_SYSTEM_K053260]=new DivSysDef( - "Konami K053260", NULL, 0xfe/*placeholder*/, 0, 4, false, true, 0x161, false, 1U<