Sync vgsound_emu with master

This commit is contained in:
cam900 2022-10-21 17:45:15 +09:00
parent 8e2f3199b5
commit eab12892f5
18 changed files with 339 additions and 253 deletions

View file

@ -2,6 +2,13 @@
## Important changes
### V 2.1.2 (2022-10-21)
Split utilities and core framework header
Use static constexprs for global constants
Fix initialization
Fix CMake
### V 2.1.1 (2022-10-20)
Add C++11 detection for CMake

View file

@ -97,8 +97,8 @@ set(EMU_SOURCE "")
# Core functions
list(APPEND CORE_SOURCE
vgsound_emu/src/core/core.hpp
vgsound_emu/src/core/util.hpp
vgsound_emu/src/core/util/clock_pulse.hpp
vgsound_emu/src/core/util/fifo.hpp
vgsound_emu/src/core/util/mem_intf.hpp
)

View file

@ -0,0 +1,34 @@
/*
License: Zlib
see https://gitlab.com/cam900/vgsound_emu/-/blob/main/LICENSE for more details
Copyright holder(s): cam900
Core framework for vgsound_emu
*/
#ifndef _VGSOUND_EMU_SRC_CORE_CORE_HPP
#define _VGSOUND_EMU_SRC_CORE_CORE_HPP
#pragma once
#include "util.hpp"
namespace vgsound_emu
{
class vgsound_emu_core
{
public:
// constructors
vgsound_emu_core(std::string tag)
: m_tag(tag)
{
}
// getters
std::string tag() { return m_tag; }
private:
std::string m_tag = ""; // core tags
};
}; // namespace vgsound_emu
#endif

View file

@ -32,24 +32,11 @@ namespace vgsound_emu
typedef float f32;
typedef double f64;
class vgsound_emu_core
{
public:
// constructors
vgsound_emu_core(std::string tag)
: m_tag(tag)
{
}
// getters
std::string tag() { return m_tag; }
protected:
const f64 PI = 3.1415926535897932384626433832795;
static constexpr f64 PI = 3.1415926535897932384626433832795;
// std::clamp is only for C++17 or later; I use my own code
template<typename T>
T clamp(T in, T min, T max)
static inline T clamp(T in, T min, T max)
{
#if defined(_HAS_CXX17) && _HAS_CXX17
// just use std::clamp if C++17 or above
@ -62,202 +49,22 @@ namespace vgsound_emu
// get bitfield, bitfield(input, position, len)
template<typename T>
T bitfield(T in, u8 pos, u8 len = 1)
static inline T bitfield(T in, u8 pos, u8 len = 1)
{
return (in >> pos) & (len ? (T(1 << len) - 1) : 1);
}
// get sign extended value, sign_ext<type>(input, len)
template<typename T>
T sign_ext(T in, u8 len)
static inline T sign_ext(T in, u8 len)
{
len = std::max<u8>(0, (8 * sizeof(T)) - len);
return T(T(in) << len) >> len;
}
// convert attenuation decibel value to gain
inline f32 dB_to_gain(f32 attenuation) { return std::pow(10.0f, attenuation / 20.0f); }
static inline f32 dB_to_gain(f32 attenuation) { return std::pow(10.0f, attenuation / 20.0f); }
private:
std::string m_tag = ""; // core tags
};
class vgsound_emu_mem_intf : public vgsound_emu_core
{
public:
// constructor
vgsound_emu_mem_intf()
: vgsound_emu_core("mem_intf")
{
}
virtual u8 read_byte(u32 address) { return 0; }
virtual u16 read_word(u32 address) { return 0; }
virtual u32 read_dword(u32 address) { return 0; }
virtual u64 read_qword(u32 address) { return 0; }
virtual void write_byte(u32 address, u8 data) {}
virtual void write_word(u32 address, u16 data) {}
virtual void write_dword(u32 address, u32 data) {}
virtual void write_qword(u32 address, u64 data) {}
};
template<typename T>
class clock_pulse_t : public vgsound_emu_core
{
private:
const T m_init_width = 1;
class edge_t : public vgsound_emu_core
{
private:
const u8 m_init_edge = 1;
public:
edge_t(u8 init_edge = 0)
: vgsound_emu_core("clock_pulse_edge")
, m_init_edge(init_edge)
, m_current(init_edge ^ 1)
, m_previous(init_edge)
, m_rising(0)
, m_falling(0)
, m_changed(0)
{
set(init_edge);
}
// internal states
void reset()
{
m_previous = m_init_edge;
m_current = m_init_edge ^ 1;
set(m_init_edge);
}
void tick(bool toggle)
{
u8 current = m_current;
if (toggle)
{
current ^= 1;
}
set(current);
}
void set(u8 edge)
{
edge &= 1;
m_rising = m_falling = m_changed = 0;
if (m_current != edge)
{
m_changed = 1;
if (m_current && (!edge))
{
m_falling = 1;
}
else if ((!m_current) && edge)
{
m_rising = 1;
}
m_current = edge;
}
m_previous = m_current;
}
// getters
inline bool current() { return m_current; }
inline bool rising() { return m_rising; }
inline bool falling() { return m_falling; }
inline bool changed() { return m_changed; }
private:
u8 m_current : 1; // current edge
u8 m_previous : 1; // previous edge
u8 m_rising : 1; // rising edge
u8 m_falling : 1; // falling edge
u8 m_changed : 1; // changed flag
};
public:
clock_pulse_t(T init_width, u8 init_edge = 0)
: vgsound_emu_core("clock_pulse")
, m_init_width(init_width)
, m_edge(edge_t(init_edge & 1))
, m_width(init_width)
, m_width_latch(init_width)
, m_counter(init_width)
, m_cycle(0)
{
}
void reset(T init)
{
m_edge.reset();
m_width = m_width_latch = m_counter = init;
m_cycle = 0;
}
inline void reset() { reset(m_init_width); }
bool tick(T width = 0)
{
bool carry = ((--m_counter) <= 0);
if (carry)
{
if (!width)
{
m_width = m_width_latch;
}
else
{
m_width = width; // reset width
}
m_counter = m_width;
m_cycle = 0;
}
else
{
m_cycle++;
}
m_edge.tick(carry);
return carry;
}
inline void set_width(T width) { m_width = width; }
inline void set_width_latch(T width) { m_width_latch = width; }
// Accessors
inline bool current_edge() { return m_edge.current(); }
inline bool rising_edge() { return m_edge.rising(); }
inline bool falling_edge() { return m_edge.falling(); }
// getters
edge_t &edge() { return m_edge; }
inline T cycle() { return m_cycle; }
private:
edge_t m_edge;
T m_width = 1; // clock pulse width
T m_width_latch = 1; // clock pulse width latch
T m_counter = 1; // clock counter
T m_cycle = 0; // clock cycle
};
}; // namespace vgsound_emu
using namespace vgsound_emu;
#endif

View file

@ -0,0 +1,167 @@
/*
License: Zlib
see https://gitlab.com/cam900/vgsound_emu/-/blob/main/LICENSE for more details
Copyright holder(s): cam900
Common clock pulse emulation for vgsound_emu
*/
#ifndef _VGSOUND_EMU_SRC_CORE_UTIL_CLOCK_PULSE_HPP
#define _VGSOUND_EMU_SRC_CORE_UTIL_CLOCK_PULSE_HPP
#pragma once
#include "../core.hpp"
namespace vgsound_emu
{
template<typename T>
class clock_pulse_t : public vgsound_emu_core
{
private:
const T m_init_width = 1;
class edge_t : public vgsound_emu_core
{
private:
const u8 m_init_edge = 1;
public:
edge_t(u8 init_edge = 0)
: vgsound_emu_core("clock_pulse_edge")
, m_init_edge(init_edge)
, m_current(init_edge ^ 1)
, m_previous(init_edge)
, m_rising(0)
, m_falling(0)
, m_changed(0)
{
set(init_edge);
}
// internal states
void reset()
{
m_previous = m_init_edge;
m_current = m_init_edge ^ 1;
set(m_init_edge);
}
void tick(bool toggle)
{
u8 current = m_current;
if (toggle)
{
current ^= 1;
}
set(current);
}
void set(u8 edge)
{
edge &= 1;
m_rising = m_falling = m_changed = 0;
if (m_current != edge)
{
m_changed = 1;
if (m_current && (!edge))
{
m_falling = 1;
}
else if ((!m_current) && edge)
{
m_rising = 1;
}
m_current = edge;
}
m_previous = m_current;
}
// getters
inline bool current() { return m_current; }
inline bool rising() { return m_rising; }
inline bool falling() { return m_falling; }
inline bool changed() { return m_changed; }
private:
u8 m_current : 1; // current edge
u8 m_previous : 1; // previous edge
u8 m_rising : 1; // rising edge
u8 m_falling : 1; // falling edge
u8 m_changed : 1; // changed flag
};
public:
clock_pulse_t(T init_width, u8 init_edge = 0)
: vgsound_emu_core("clock_pulse")
, m_init_width(init_width)
, m_edge(edge_t(init_edge & 1))
, m_width(init_width)
, m_width_latch(init_width)
, m_counter(init_width)
, m_cycle(0)
{
}
void reset(T init)
{
m_edge.reset();
m_width = m_width_latch = m_counter = init;
m_cycle = 0;
}
inline void reset() { reset(m_init_width); }
bool tick(T width = 0)
{
bool carry = ((--m_counter) <= 0);
if (carry)
{
if (!width)
{
m_width = m_width_latch;
}
else
{
m_width = width; // reset width
}
m_counter = m_width;
m_cycle = 0;
}
else
{
m_cycle++;
}
m_edge.tick(carry);
return carry;
}
inline void set_width(T width) { m_width = width; }
inline void set_width_latch(T width) { m_width_latch = width; }
// Accessors
inline bool current_edge() { return m_edge.current(); }
inline bool rising_edge() { return m_edge.rising(); }
inline bool falling_edge() { return m_edge.falling(); }
// getters
edge_t &edge() { return m_edge; }
inline T cycle() { return m_cycle; }
private:
edge_t m_edge;
T m_width = 1; // clock pulse width
T m_width_latch = 1; // clock pulse width latch
T m_counter = 1; // clock counter
T m_cycle = 0; // clock cycle
};
}; // namespace vgsound_emu
#endif

View file

@ -0,0 +1,44 @@
/*
License: Zlib
see https://gitlab.com/cam900/vgsound_emu/-/blob/main/LICENSE for more details
Copyright holder(s): cam900
Common memory interface for vgsound_emu
*/
#ifndef _VGSOUND_EMU_SRC_CORE_UTIL_MEM_INTF_HPP
#define _VGSOUND_EMU_SRC_CORE_UTIL_MEM_INTF_HPP
#pragma once
#include "../core.hpp"
namespace vgsound_emu
{
class vgsound_emu_mem_intf : public vgsound_emu_core
{
public:
// constructor
vgsound_emu_mem_intf()
: vgsound_emu_core("mem_intf")
{
}
virtual u8 read_byte(u32 address) { return 0; }
virtual u16 read_word(u32 address) { return 0; }
virtual u32 read_dword(u32 address) { return 0; }
virtual u64 read_qword(u32 address) { return 0; }
virtual void write_byte(u32 address, u8 data) {}
virtual void write_word(u32 address, u16 data) {}
virtual void write_dword(u32 address, u32 data) {}
virtual void write_qword(u32 address, u64 data) {}
};
}; // namespace vgsound_emu
#endif

View file

@ -3,7 +3,7 @@
see https://gitlab.com/cam900/vgsound_emu/-/blob/main/LICENSE for more details
Copyright holder(s): cam900
Dialogic ADPCM core
OKI/Dialogic ADPCM core
*/
#ifndef _VGSOUND_EMU_SRC_CORE_VOX_VOX_HPP
@ -11,7 +11,9 @@
#pragma once
#include "../util.hpp"
#include "../core.hpp"
using namespace vgsound_emu;
class vox_core : public vgsound_emu_core
{
@ -93,8 +95,8 @@ class vox_core : public vgsound_emu_core
bool m_loop_saved = false;
};
const s8 m_index_table[8] = {-1, -1, -1, -1, 2, 4, 6, 8};
const s32 m_step_table[49] = {
static constexpr s8 m_index_table[8] = {-1, -1, -1, -1, 2, 4, 6, 8};
static constexpr s32 m_step_table[49] = {
16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73,
80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371,
408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552};

View file

@ -11,7 +11,10 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
#include "../core/util/clock_pulse.hpp"
using namespace vgsound_emu;
// ES5504/ES5505/ES5506 interface
class es550x_intf : public vgsound_emu_core
@ -168,11 +171,11 @@ class es550x_shared_core : public vgsound_emu_core
}
// configurations
const u8 m_integer;
const u8 m_fraction;
const u8 m_total_bits;
const u32 m_accum_mask;
const bool m_transwave;
const u8 m_integer = 21;
const u8 m_fraction = 11;
const u8 m_total_bits = 32;
const u32 m_accum_mask = 0xffffffff;
const bool m_transwave = true;
// internal states
void reset();

View file

@ -11,7 +11,8 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
using namespace vgsound_emu;
class k005289_core : public vgsound_emu_core
{

View file

@ -11,7 +11,9 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
using namespace vgsound_emu;
class k007232_intf : public vgsound_emu_core
{

View file

@ -11,7 +11,9 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
using namespace vgsound_emu;
class k053260_intf : public vgsound_emu_core
{
@ -31,7 +33,7 @@ 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
static constexpr int pan_dir[8] = {-1, 0, 24, 35, 45, 55, 66, 90}; // pan direction
class voice_t : public vgsound_emu_core
{

View file

@ -11,16 +11,20 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
#include "../core/util/mem_intf.hpp"
#include "../core/vox/vox.hpp"
using namespace vgsound_emu;
class msm6295_core : public vox_core
{
friend class vgsound_emu_mem_intf; // common memory interface
private:
// Internal volume table, 9 step
const s32 m_volume_table[9] = {32 /* 0.0dB */,
static constexpr s32 m_volume_table[9] = {
32 /* 0.0dB */,
22 /* -3.2dB */,
16 /* -6.0dB */,
11 /* -9.2dB */,

View file

@ -11,7 +11,9 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
using namespace vgsound_emu;
class n163_core : public vgsound_emu_core
{

View file

@ -12,7 +12,10 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
#include "../core/util/mem_intf.hpp"
using namespace vgsound_emu;
// shared for SCCs
class scc_core : public vgsound_emu_core

View file

@ -11,7 +11,10 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
#include "../core/util/mem_intf.hpp"
using namespace vgsound_emu;
class template_core : public vgsound_emu_core
{

View file

@ -61,7 +61,7 @@ bool vrcvi_core::alu_t::tick()
}
// carry handling
bool carry = bitfield(m_host.m_control.shift(), 1)
const bool carry = bitfield(m_host.m_control.shift(), 1)
? (bitfield(temp, 8, 4) == 0)
: (bitfield(m_host.m_control.shift(), 0) ? (bitfield(temp, 4, 8) == 0)
: (bitfield(temp, 0, 12) == 0));

View file

@ -11,7 +11,9 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
using namespace vgsound_emu;
class vrcvi_intf : public vgsound_emu_core
{

View file

@ -11,7 +11,10 @@
#pragma once
#include "../core/util.hpp"
#include "../core/core.hpp"
#include "../core/util/mem_intf.hpp"
using namespace vgsound_emu;
class x1_010_core : public vgsound_emu_core
{