273 lines
5.4 KiB
C++
273 lines
5.4 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// 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 );
|
|
|
|
// 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 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__
|