SCC: acquireDirect()

This commit is contained in:
tildearrow 2025-03-06 19:06:45 -05:00
parent 7a6f6a6745
commit c2228cd74b
7 changed files with 94 additions and 105 deletions

View file

@ -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()

View file

@ -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