SCC: acquireDirect()
This commit is contained in:
parent
7a6f6a6745
commit
c2228cd74b
|
@ -5,61 +5,88 @@
|
|||
Copyright holder(s): cam900
|
||||
Contributor(s): Natt Akuma, James Alan Nguyen, Laurens Holst
|
||||
Konami SCC emulation core
|
||||
|
||||
modified by tildearrow...
|
||||
*/
|
||||
|
||||
#include "scc.hpp"
|
||||
#include "../../../../../src/engine/dispatch.h"
|
||||
|
||||
// shared SCC features
|
||||
void scc_core::tick(const int cycles)
|
||||
void scc_core::tick(const int cycles, blip_buffer_t* bb, DivDispatchOscBuffer** oscBuf)
|
||||
{
|
||||
m_out = 0;
|
||||
for (int elem=0; elem<5; elem++)
|
||||
{
|
||||
m_voice[elem].tick(cycles);
|
||||
m_out += m_voice[elem].out();
|
||||
m_voice[elem].tick(cycles,bb,oscBuf[elem]);
|
||||
}
|
||||
}
|
||||
|
||||
void scc_core::voice_t::tick(const int cycles)
|
||||
{
|
||||
if (m_pitch >= 9) // or voice is halted
|
||||
{
|
||||
// update counter - Post decrement
|
||||
const u16 temp = m_counter;
|
||||
if (m_host.m_test.freq_4bit()) // 4 bit frequency mode
|
||||
{
|
||||
m_counter = (m_counter & ~0x0ff) | (bitfield(bitfield(m_counter, 0, 8) - cycles, 0, 8) << 0);
|
||||
m_counter = (m_counter & ~0xf00) | (bitfield(bitfield(m_counter, 8, 4) - cycles, 0, 4) << 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_counter = bitfield(m_counter - cycles, 0, 12);
|
||||
}
|
||||
void scc_core::voice_t::updateOut(const int pos) {
|
||||
int out=0;
|
||||
// get output
|
||||
if (m_enable)
|
||||
{
|
||||
out = (m_wave[m_addr] * m_volume) >> 4; // scale to 11 bit digital output
|
||||
}
|
||||
else
|
||||
{
|
||||
out = 0;
|
||||
}
|
||||
|
||||
// handle counter carry
|
||||
const bool carry = (temp<cycles) || (m_host.m_test.freq_8bit()
|
||||
? (bitfield(temp, 0, 8) == 0)
|
||||
: (m_host.m_test.freq_4bit() ? (bitfield(temp, 8, 4) == 0)
|
||||
: (bitfield(temp, 0, 12) == 0)));
|
||||
if (carry)
|
||||
{
|
||||
m_addr = bitfield(m_addr + 1, 0, 5);
|
||||
m_counter = m_pitch - ((temp<cycles)?(cycles-temp-1):0);
|
||||
while (m_counter>m_pitch) {
|
||||
m_addr = bitfield(m_addr + 1, 0, 5);
|
||||
m_counter+=m_pitch-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// get output
|
||||
if (m_enable)
|
||||
{
|
||||
m_out = (m_wave[m_addr] * m_volume) >> 4; // scale to 11 bit digital output
|
||||
}
|
||||
else
|
||||
{
|
||||
m_out = 0;
|
||||
}
|
||||
m_oscBuf->putSample(pos,out<<7);
|
||||
|
||||
if (out!=m_out) {
|
||||
blip_add_delta(m_bb,pos,(out-m_out)<<5);
|
||||
m_out=out;
|
||||
}
|
||||
}
|
||||
|
||||
void scc_core::voice_t::tick(const int amt, blip_buffer_t* bb, DivDispatchOscBuffer* oscBuf)
|
||||
{
|
||||
m_bb=bb;
|
||||
m_oscBuf=oscBuf;
|
||||
|
||||
if (m_pitch >= 9) // or voice is halted
|
||||
{
|
||||
int rem=amt;
|
||||
for (int pos=0; pos<amt; pos++) {
|
||||
int cycles=m_host.m_test.freq_4bit()?(m_counter&15):(m_host.m_test.freq_8bit()?(m_counter&0xff):(m_counter&0xfff));
|
||||
if (cycles>rem) cycles=rem;
|
||||
if (cycles<1) cycles=1;
|
||||
|
||||
// update counter - Post decrement
|
||||
const u16 temp = m_counter;
|
||||
if (m_host.m_test.freq_4bit()) // 4 bit frequency mode
|
||||
{
|
||||
m_counter = (m_counter & ~0x0ff) | (bitfield(bitfield(m_counter, 0, 8) - cycles, 0, 8) << 0);
|
||||
m_counter = (m_counter & ~0xf00) | (bitfield(bitfield(m_counter, 8, 4) - cycles, 0, 4) << 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_counter = bitfield(m_counter - cycles, 0, 12);
|
||||
}
|
||||
|
||||
// handle counter carry
|
||||
const bool carry = (temp<cycles) || (m_host.m_test.freq_8bit()
|
||||
? (bitfield(temp, 0, 8) == 0)
|
||||
: (m_host.m_test.freq_4bit() ? (bitfield(temp, 8, 4) == 0)
|
||||
: (bitfield(temp, 0, 12) == 0)));
|
||||
if (carry)
|
||||
{
|
||||
m_addr = bitfield(m_addr + 1, 0, 5);
|
||||
m_counter = m_pitch - ((temp<cycles)?(cycles-temp-1):0);
|
||||
while (m_counter>m_pitch) {
|
||||
m_addr = bitfield(m_addr + 1, 0, 5);
|
||||
m_counter+=m_pitch-1;
|
||||
}
|
||||
}
|
||||
pos+=cycles-1;
|
||||
rem-=cycles;
|
||||
updateOut(pos);
|
||||
}
|
||||
} else {
|
||||
updateOut(0);
|
||||
}
|
||||
}
|
||||
|
||||
void scc_core::reset()
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
Copyright holder(s): cam900
|
||||
Contributor(s): Natt Akuma, James Alan Nguyen, Laurens Holst
|
||||
Konami SCC emulation core
|
||||
|
||||
modified by tildearrow...
|
||||
*/
|
||||
|
||||
#ifndef _VGSOUND_EMU_SRC_SCC_HPP
|
||||
|
@ -12,10 +14,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "blip_buf.h"
|
||||
#include "../core/core.hpp"
|
||||
#include "../core/util/mem_intf.hpp"
|
||||
#include <string.h>
|
||||
|
||||
struct DivDispatchOscBuffer;
|
||||
|
||||
using namespace vgsound_emu;
|
||||
|
||||
// shared for SCCs
|
||||
|
@ -42,7 +47,8 @@ class scc_core : public vgsound_emu_core
|
|||
|
||||
// internal state
|
||||
void reset();
|
||||
void tick(const int cycles=1);
|
||||
void tick(const int cycles, blip_buffer_t* bb, DivDispatchOscBuffer* oscBuf);
|
||||
void updateOut(const int pos);
|
||||
|
||||
// accessors
|
||||
inline void reset_addr() { m_addr = 0; }
|
||||
|
@ -70,6 +76,8 @@ class scc_core : public vgsound_emu_core
|
|||
private:
|
||||
// registers
|
||||
scc_core &m_host;
|
||||
blip_buffer_t* m_bb;
|
||||
DivDispatchOscBuffer* m_oscBuf;
|
||||
s8 m_wave[32]; // internal waveform
|
||||
bool m_enable = false; // output enable flag
|
||||
u16 m_pitch : 12; // pitch
|
||||
|
@ -152,7 +160,7 @@ class scc_core : public vgsound_emu_core
|
|||
|
||||
// internal state
|
||||
virtual void reset();
|
||||
void tick(const int cycles=1);
|
||||
void tick(const int cycles, blip_buffer_t* bb, DivDispatchOscBuffer** oscBuf);
|
||||
|
||||
// getters
|
||||
inline s32 out() { return m_out; } // output to DA0...DA10 pin
|
||||
|
|
|
@ -672,20 +672,10 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
case DIV_SYSTEM_SCC:
|
||||
dispatch=new DivPlatformSCC;
|
||||
((DivPlatformSCC*)dispatch)->setChipModel(false);
|
||||
if (isRender) {
|
||||
((DivPlatformSCC*)dispatch)->setCoreQuality(eng->getConfInt("sccQualityRender",3));
|
||||
} else {
|
||||
((DivPlatformSCC*)dispatch)->setCoreQuality(eng->getConfInt("sccQuality",3));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_SCC_PLUS:
|
||||
dispatch=new DivPlatformSCC;
|
||||
((DivPlatformSCC*)dispatch)->setChipModel(true);
|
||||
if (isRender) {
|
||||
((DivPlatformSCC*)dispatch)->setCoreQuality(eng->getConfInt("sccQualityRender",3));
|
||||
} else {
|
||||
((DivPlatformSCC*)dispatch)->setCoreQuality(eng->getConfInt("sccQuality",3));
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_YMZ280B:
|
||||
dispatch=new DivPlatformYMZ280B;
|
||||
|
|
|
@ -81,19 +81,17 @@ const char** DivPlatformSCC::getRegisterSheet() {
|
|||
}
|
||||
|
||||
void DivPlatformSCC::acquire(short** buf, size_t len) {
|
||||
}
|
||||
|
||||
void DivPlatformSCC::acquireDirect(blip_buffer_t** bb, size_t len) {
|
||||
for (int i=0; i<5; i++) {
|
||||
oscBuf[i]->begin(len);
|
||||
}
|
||||
|
||||
for (size_t h=0; h<len; h++) {
|
||||
scc->tick(coreQuality);
|
||||
short out=(short)scc->out()<<5;
|
||||
buf[0][h]=out;
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
oscBuf[i]->putSample(h,scc->voice_out(i)<<7);
|
||||
}
|
||||
}
|
||||
scc->tick(len,bb[0],oscBuf);
|
||||
//for (int i=0; i<5; i++) {
|
||||
// oscBuf[i]->putSample(h,scc->voice_out(i)<<7);
|
||||
//}
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
oscBuf[i]->end(len);
|
||||
|
@ -346,6 +344,10 @@ int DivPlatformSCC::getOutputCount() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool DivPlatformSCC::hasAcquireDirect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DivPlatformSCC::notifyWaveChange(int wave) {
|
||||
for (int i=0; i<5; i++) {
|
||||
if (chan[i].wave==wave) {
|
||||
|
@ -391,38 +393,12 @@ void DivPlatformSCC::setFlags(const DivConfig& flags) {
|
|||
break;
|
||||
}
|
||||
CHECK_CUSTOM_CLOCK;
|
||||
rate=chipClock/(coreQuality>>1);
|
||||
rate=chipClock*2;
|
||||
for (int i=0; i<5; i++) {
|
||||
oscBuf[i]->setRate(rate);
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformSCC::setCoreQuality(unsigned char q) {
|
||||
switch (q) {
|
||||
case 0:
|
||||
coreQuality=128;
|
||||
break;
|
||||
case 1:
|
||||
coreQuality=64;
|
||||
break;
|
||||
case 2:
|
||||
coreQuality=32;
|
||||
break;
|
||||
case 3:
|
||||
coreQuality=16;
|
||||
break;
|
||||
case 4:
|
||||
coreQuality=8;
|
||||
break;
|
||||
case 5:
|
||||
coreQuality=2;
|
||||
break;
|
||||
default:
|
||||
coreQuality=16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int DivPlatformSCC::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
|
|
|
@ -41,7 +41,6 @@ class DivPlatformSCC: public DivDispatch {
|
|||
unsigned char writeOscBuf;
|
||||
int lastUpdated34;
|
||||
|
||||
int coreQuality;
|
||||
scc_core* scc;
|
||||
bool isPlus;
|
||||
unsigned char regBase;
|
||||
|
@ -51,6 +50,7 @@ class DivPlatformSCC: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short** buf, size_t len);
|
||||
void acquireDirect(blip_buffer_t** bb, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -62,6 +62,7 @@ class DivPlatformSCC: public DivDispatch {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
int getOutputCount();
|
||||
bool hasAcquireDirect();
|
||||
void notifyWaveChange(int wave);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
|
@ -69,7 +70,6 @@ class DivPlatformSCC: public DivDispatch {
|
|||
const char** getRegisterSheet();
|
||||
void setFlags(const DivConfig& flags);
|
||||
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
|
||||
void setCoreQuality(unsigned char q);
|
||||
void setChipModel(bool isPlus);
|
||||
void quit();
|
||||
~DivPlatformSCC();
|
||||
|
|
|
@ -1801,7 +1801,6 @@ class FurnaceGUI {
|
|||
int ndsQuality;
|
||||
int pnQuality;
|
||||
int saaQuality;
|
||||
int sccQuality;
|
||||
int smQuality;
|
||||
int swanQuality;
|
||||
int vbQuality;
|
||||
|
@ -1827,7 +1826,6 @@ class FurnaceGUI {
|
|||
int ndsQualityRender;
|
||||
int pnQualityRender;
|
||||
int saaQualityRender;
|
||||
int sccQualityRender;
|
||||
int smQualityRender;
|
||||
int swanQualityRender;
|
||||
int vbQualityRender;
|
||||
|
@ -2064,7 +2062,6 @@ class FurnaceGUI {
|
|||
ndsQuality(3),
|
||||
pnQuality(3),
|
||||
saaQuality(3),
|
||||
sccQuality(3),
|
||||
smQuality(3),
|
||||
swanQuality(3),
|
||||
vbQuality(3),
|
||||
|
@ -2090,7 +2087,6 @@ class FurnaceGUI {
|
|||
ndsQualityRender(3),
|
||||
pnQualityRender(3),
|
||||
saaQualityRender(3),
|
||||
sccQualityRender(3),
|
||||
smQualityRender(3),
|
||||
swanQualityRender(3),
|
||||
vbQualityRender(3),
|
||||
|
|
|
@ -2125,7 +2125,6 @@ void FurnaceGUI::drawSettings() {
|
|||
CORE_QUALITY("Nintendo DS",ndsQuality,ndsQualityRender);
|
||||
CORE_QUALITY("PowerNoise",pnQuality,pnQualityRender);
|
||||
CORE_QUALITY("SAA1099",saaQuality,saaQualityRender);
|
||||
CORE_QUALITY("SCC",sccQuality,sccQualityRender);
|
||||
CORE_QUALITY("SID (dSID)",dsidQuality,dsidQualityRender);
|
||||
CORE_QUALITY("SM8521",smQuality,smQualityRender);
|
||||
CORE_QUALITY("Virtual Boy",vbQuality,vbQualityRender);
|
||||
|
@ -5136,7 +5135,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.ndsQuality=conf.getInt("ndsQuality",3);
|
||||
settings.pnQuality=conf.getInt("pnQuality",3);
|
||||
settings.saaQuality=conf.getInt("saaQuality",3);
|
||||
settings.sccQuality=conf.getInt("sccQuality",3);
|
||||
settings.smQuality=conf.getInt("smQuality",3);
|
||||
settings.swanQuality=conf.getInt("swanQuality",3);
|
||||
settings.vbQuality=conf.getInt("vbQuality",3);
|
||||
|
@ -5164,7 +5162,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
settings.ndsQualityRender=conf.getInt("ndsQualityRender",3);
|
||||
settings.pnQualityRender=conf.getInt("pnQualityRender",3);
|
||||
settings.saaQualityRender=conf.getInt("saaQualityRender",3);
|
||||
settings.sccQualityRender=conf.getInt("sccQualityRender",3);
|
||||
settings.smQualityRender=conf.getInt("smQualityRender",3);
|
||||
settings.swanQualityRender=conf.getInt("swanQualityRender",3);
|
||||
settings.vbQualityRender=conf.getInt("vbQualityRender",3);
|
||||
|
@ -5208,7 +5205,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.ndsQuality,0,5);
|
||||
clampSetting(settings.pnQuality,0,5);
|
||||
clampSetting(settings.saaQuality,0,5);
|
||||
clampSetting(settings.sccQuality,0,5);
|
||||
clampSetting(settings.smQuality,0,5);
|
||||
clampSetting(settings.swanQuality,0,5);
|
||||
clampSetting(settings.vbQuality,0,5);
|
||||
|
@ -5234,7 +5230,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
clampSetting(settings.ndsQualityRender,0,5);
|
||||
clampSetting(settings.pnQualityRender,0,5);
|
||||
clampSetting(settings.saaQualityRender,0,5);
|
||||
clampSetting(settings.sccQualityRender,0,5);
|
||||
clampSetting(settings.smQualityRender,0,5);
|
||||
clampSetting(settings.swanQualityRender,0,5);
|
||||
clampSetting(settings.vbQualityRender,0,5);
|
||||
|
@ -5734,7 +5729,6 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("ndsQuality",settings.ndsQuality);
|
||||
conf.set("pnQuality",settings.pnQuality);
|
||||
conf.set("saaQuality",settings.saaQuality);
|
||||
conf.set("sccQuality",settings.sccQuality);
|
||||
conf.set("smQuality",settings.smQuality);
|
||||
conf.set("swanQuality",settings.swanQuality);
|
||||
conf.set("vbQuality",settings.vbQuality);
|
||||
|
@ -5762,7 +5756,6 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
|
|||
conf.set("ndsQualityRender",settings.ndsQualityRender);
|
||||
conf.set("pnQualityRender",settings.pnQualityRender);
|
||||
conf.set("saaQualityRender",settings.saaQualityRender);
|
||||
conf.set("sccQualityRender",settings.sccQualityRender);
|
||||
conf.set("smQualityRender",settings.smQualityRender);
|
||||
conf.set("swanQualityRender",settings.swanQualityRender);
|
||||
conf.set("vbQualityRender",settings.vbQualityRender);
|
||||
|
@ -5824,7 +5817,6 @@ void FurnaceGUI::commitSettings() {
|
|||
settings.ndsQuality!=e->getConfInt("ndsQuality",3) ||
|
||||
settings.pnQuality!=e->getConfInt("pnQuality",3) ||
|
||||
settings.saaQuality!=e->getConfInt("saaQuality",3) ||
|
||||
settings.sccQuality!=e->getConfInt("sccQuality",3) ||
|
||||
settings.smQuality!=e->getConfInt("smQuality",3) ||
|
||||
settings.swanQuality!=e->getConfInt("swanQuality",3) ||
|
||||
settings.vbQuality!=e->getConfInt("vbQuality",3) ||
|
||||
|
|
Loading…
Reference in a new issue