1 // Namco 106 sound chip emulator 2 3 // Nes_Snd_Emu $vers 4 #ifndef NES_NAMCO_APU_H 5 #define NES_NAMCO_APU_H 6 7 #include "blargg_common.h" 8 #include "Blip_Buffer.h" 9 10 struct namco_state_t; 11 12 class Nes_Namco_Apu { 13 public: 14 // See Nes_Apu.h for reference. 15 void volume( double ); 16 void treble_eq( const blip_eq_t& ); 17 void set_output( Blip_Buffer* ); 18 enum { osc_count = 8 }; 19 void set_output( int index, Blip_Buffer* ); 20 void reset(); 21 void end_frame( blip_time_t ); 22 23 // Read/write data register is at 0x4800 24 enum { data_reg_addr = 0x4800 }; 25 void write_data( blip_time_t, int ); 26 int read_data(); 27 28 // Write-only address register is at 0xF800 29 enum { addr_reg_addr = 0xF800 }; 30 void write_addr( int ); 31 32 // to do: implement save/restore 33 void save_state( namco_state_t* out ) const; 34 void load_state( namco_state_t const& ); 35 36 public: 37 Nes_Namco_Apu(); 38 BLARGG_DISABLE_NOTHROW 39 private: 40 // noncopyable 41 Nes_Namco_Apu( const Nes_Namco_Apu& ); 42 Nes_Namco_Apu& operator = ( const Nes_Namco_Apu& ); 43 44 struct Namco_Osc { 45 int delay; 46 Blip_Buffer* output; 47 short last_amp; 48 short wave_pos; 49 }; 50 51 Namco_Osc oscs [osc_count]; 52 53 blip_time_t last_time; 54 int addr_reg; 55 56 enum { reg_count = 0x80 }; 57 BOOST::uint8_t reg [reg_count]; 58 Blip_Synth_Norm synth; 59 60 BOOST::uint8_t& access(); 61 void run_until( blip_time_t ); 62 }; 63 /* 64 struct namco_state_t 65 { 66 BOOST::uint8_t regs [0x80]; 67 BOOST::uint8_t addr; 68 BOOST::uint8_t unused; 69 BOOST::uint8_t positions [8]; 70 BOOST::uint32_t delays [8]; 71 }; 72 */ 73 access()74inline BOOST::uint8_t& Nes_Namco_Apu::access() 75 { 76 int addr = addr_reg & 0x7F; 77 if ( addr_reg & 0x80 ) 78 addr_reg = (addr + 1) | 0x80; 79 return reg [addr]; 80 } 81 volume(double v)82inline void Nes_Namco_Apu::volume( double v ) { synth.volume( 0.10 / osc_count / 15 * v ); } 83 treble_eq(const blip_eq_t & eq)84inline void Nes_Namco_Apu::treble_eq( const blip_eq_t& eq ) { synth.treble_eq( eq ); } 85 write_addr(int v)86inline void Nes_Namco_Apu::write_addr( int v ) { addr_reg = v; } 87 read_data()88inline int Nes_Namco_Apu::read_data() { return access(); } 89 set_output(int i,Blip_Buffer * buf)90inline void Nes_Namco_Apu::set_output( int i, Blip_Buffer* buf ) 91 { 92 assert( (unsigned) i < osc_count ); 93 oscs [i].output = buf; 94 } 95 write_data(blip_time_t time,int data)96inline void Nes_Namco_Apu::write_data( blip_time_t time, int data ) 97 { 98 run_until( time ); 99 access() = data; 100 } 101 102 #endif 103