////////////////////////////////////////////////////////////////////////// // // // 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__