AxibugEmuOnline/References/virtuanessrc097-master/NES/ApuEX/APU_INTERNAL.h
2024-08-05 17:58:53 +08:00

275 lines
12 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//////////////////////////////////////////////////////////////////////////
// //
// APU Internal //
// Norix //
// written 2002/06/27 //
// last modify ----/--/-- //
//////////////////////////////////////////////////////////////////////////
#ifndef __APU_INTERNAL_INCLUDED__
#define __APU_INTERNAL_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#include "math.h"
#include "typedef.h"
#include "macro.h"
#include "APU_INTERFACE.h"
#include "nes.h"
#include "cpu.h"
class APU_INTERNAL : public APU_INTERFACE
{
public:
APU_INTERNAL();
~APU_INTERNAL();
void SetParent( NES* parent ) { nes = parent; }
void Reset( FLOAT fClock, INT nRate );
void Setup( FLOAT fClock, INT nRate );
void ToneTableLoad();
INT Process( INT channel );
void Write( WORD addr, BYTE data );
BYTE Read ( WORD addr );
void SyncWrite( WORD addr, BYTE data );
BYTE SyncRead ( WORD addr );
BOOL Sync( INT cycles );
INT GetFreq( INT channel );
void GetFrameIRQ( INT& Cycle, BYTE& Count, BYTE& Type, BYTE& IRQ, BYTE& Occur ) {
Cycle = FrameCycle;
Count = (BYTE)FrameCount;
Type = (BYTE)FrameType;
IRQ = FrameIRQ;
Occur = FrameIRQoccur;
}
void SetFrameIRQ( INT Cycle, BYTE Count, BYTE Type, BYTE IRQ, BYTE Occur ) {
FrameCycle = Cycle;
FrameCount = (INT)Count;
FrameType = (INT)Type;
FrameIRQ = IRQ;
FrameIRQoccur = Occur;
}
INT GetStateSize();
void SaveState( LPBYTE p );
void LoadState( LPBYTE p );
protected:
typedef struct {
BYTE reg[4]; // register
BYTE enable; // enable
BYTE holdnote; // holdnote
BYTE volume; // volume
BYTE complement;
// For Render
INT phaseacc;
INT freq;
INT freqlimit;
INT adder;
INT duty;
INT len_count;
INT nowvolume;
// For Envelope
BYTE env_fixed;
BYTE env_decay;
BYTE env_count;
BYTE dummy0;
INT env_vol;
// For Sweep
BYTE swp_on;
BYTE swp_inc;
BYTE swp_shift;
BYTE swp_decay;
BYTE swp_count;
BYTE dummy1[3];
// For sync;
BYTE sync_reg[4];
BYTE sync_output_enable;
BYTE sync_enable;
BYTE sync_holdnote;
BYTE dummy2;
INT sync_len_count;
} RECTANGLE, *LPRECTANGLE;
typedef struct {
BYTE reg[4];
BYTE enable;
BYTE holdnote;
BYTE counter_start;
BYTE dummy0;
INT phaseacc;
INT freq;
INT len_count;
INT lin_count;
INT adder;
INT nowvolume;
// For sync;
BYTE sync_reg[4];
BYTE sync_enable;
BYTE sync_holdnote;
BYTE sync_counter_start;
// BYTE dummy1;
INT sync_len_count;
INT sync_lin_count;
} TRIANGLE, *LPTRIANGLE;
typedef struct {
BYTE reg[4]; // register
BYTE enable; // enable
BYTE holdnote; // holdnote
BYTE volume; // volume
BYTE xor_tap;
INT shift_reg;
// For Render
INT phaseacc;
INT freq;
INT len_count;
INT nowvolume;
INT output;
// For Envelope
BYTE env_fixed;
BYTE env_decay;
BYTE env_count;
BYTE dummy0;
INT env_vol;
// For sync;
BYTE sync_reg[4];
BYTE sync_output_enable;
BYTE sync_enable;
BYTE sync_holdnote;
BYTE dummy1;
INT sync_len_count;
} NOISE, *LPNOISE;
typedef struct {
BYTE reg[4];
BYTE enable;
BYTE looping;
BYTE cur_byte;
BYTE dpcm_value;
INT freq;
INT phaseacc;
INT output;
WORD address, cache_addr;
INT dmalength, cache_dmalength;
INT dpcm_output_real, dpcm_output_fake, dpcm_output_old, dpcm_output_offset;
// For sync
BYTE sync_reg[4];
BYTE sync_enable;
BYTE sync_looping;
BYTE sync_irq_gen;
BYTE sync_irq_enable;
INT sync_cycles, sync_cache_cycles;
INT sync_dmalength, sync_cache_dmalength;
} DPCM, *LPDPCM;
void SyncWrite4017( BYTE data );
void UpdateFrame();
// Rectangle
void WriteRectangle ( INT no, WORD addr, BYTE data );
void UpdateRectangle( RECTANGLE& ch, INT type );
INT RenderRectangle( RECTANGLE& ch );
// For Sync
void SyncWriteRectangle ( INT no, WORD addr, BYTE data );
void SyncUpdateRectangle( RECTANGLE& ch, INT type );
// Triangle
void WriteTriangle ( WORD addr, BYTE data );
void UpdateTriangle( INT type );
INT RenderTriangle();
// For Sync
void SyncWriteTriangle ( WORD addr, BYTE data );
void SyncUpdateTriangle( INT type );
// Noise
void WriteNoise ( WORD addr, BYTE data );
void UpdateNoise( INT type );
BYTE NoiseShiftreg( BYTE xor_tap );
INT RenderNoise();
// For Sync
void SyncWriteNoise ( WORD addr, BYTE data );
void SyncUpdateNoise( INT type );
// DPCM
void WriteDPCM ( WORD addr, BYTE data );
// void UpdateDPCM();
INT RenderDPCM();
// For Sync
void SyncWriteDPCM ( WORD addr, BYTE data );
BOOL SyncUpdateDPCM( INT cycles );
// Frame Counter
INT FrameCycle;
INT FrameCount;
INT FrameType;
BYTE FrameIRQ;
BYTE FrameIRQoccur;
// Channels
RECTANGLE ch0;
RECTANGLE ch1;
TRIANGLE ch2;
NOISE ch3;
DPCM ch4;
// $4015 Reg
BYTE reg4015, sync_reg4015;
// NES object(ref)
NES* nes;
// Sound
FLOAT cpu_clock;
INT sampling_rate;
INT cycle_rate;
// Tables
static INT vbl_length[32];
static INT freq_limit[8];
static INT duty_lut[4];
static INT noise_freq[16];
static INT dpcm_cycles[16];
static INT dpcm_cycles_pal[16];
// static INT vol_effect[16];
// WaveTables
enum { TONEDATA_MAX = 16, TONEDATA_LEN = 32 };
enum { CHANNEL_MAX = 3, TONE_MAX = 4 };
BOOL bToneTableEnable[TONEDATA_MAX];
INT ToneTable[TONEDATA_MAX][TONEDATA_LEN];
INT ChannelTone[CHANNEL_MAX][TONE_MAX];
private:
};
#endif // !__APU_INTERNAL_INCLUDED__