/* License: BSD-3-Clause see https://github.com/cam900/vgsound_emu/LICENSE for more details Copyright holder(s): cam900 Konami SCC emulation core See scc.cpp for more info. */ #include #include #ifndef _VGSOUND_EMU_SCC_HPP #define _VGSOUND_EMU_SCC_HPP #pragma once namespace scc { typedef unsigned char u8; typedef signed char s8; typedef unsigned short u16; typedef signed short s16; typedef unsigned int u32; typedef signed int s32; // get bitfield, bitfield(input, position, len) template T bitfield(T in, u8 pos, u8 len = 1) { return (in >> pos) & (len ? (T(1 << len) - 1) : 1); } } using namespace scc; // shared for SCCs class scc_core { public: // constructor scc_core() : m_voice{*this,*this,*this,*this,*this} {}; // accessors virtual u8 scc_r(bool is_sccplus, u8 address) = 0; virtual void scc_w(bool is_sccplus, u8 address, u8 data) = 0; // internal state virtual void reset(); void tick(); // getters s32 out() { return m_out; } // output to DA0...DA10 pin s32 chan_out(u8 ch) { return m_voice[ch].out; } u8 reg(u8 address) { return m_reg[address]; } protected: // voice structs struct voice_t { // constructor voice_t(scc_core &host) : m_host(host) {}; // internal state void reset(); void tick(); // registers scc_core &m_host; s8 wave[32] = {0}; // internal waveform bool enable = false; // output enable flag u16 pitch = 0; // pitch u8 volume = 0; // volume u8 addr = 0; // waveform pointer u16 counter = 0; // frequency counter s32 out = 0; // current output }; voice_t m_voice[5]; // 5 voices // accessor u8 wave_r(bool is_sccplus, u8 address); void wave_w(bool is_sccplus, u8 address, u8 data); void freq_vol_enable_w(u8 address, u8 data); struct test_t { // constructor test_t() : freq_4bit(0) , freq_8bit(0) , resetpos(0) , rotate(0) , rotate4(0) { }; void reset() { freq_4bit = 0; freq_8bit = 0; resetpos = 0; rotate = 0; rotate4 = 0; } u8 freq_4bit : 1; // 4 bit frequency u8 freq_8bit : 1; // 8 bit frequency u8 resetpos : 1; // reset counter after pitch writes u8 rotate : 1; // rotate and write protect waveform for all channels u8 rotate4 : 1; // same as above but for channel 4 only }; test_t m_test; // test register s32 m_out = 0; // output to DA0...10 u8 m_reg[256] = {0}; // register pool }; // SCC core class k051649_scc_core : public scc_core { public: // accessors virtual u8 scc_r(bool is_sccplus, u8 address) override; virtual void scc_w(bool is_sccplus, u8 address, u8 data) override; }; class k052539_scc_core : public k051649_scc_core { public: // accessors virtual u8 scc_r(bool is_sccplus, u8 address) override; virtual void scc_w(bool is_sccplus, u8 address, u8 data) override; }; #endif