1 // 2 // Copyright (C) 2007 by sinamas <sinamas at users.sourceforge.net> 3 // 4 // This program is free software; you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License version 2 as 6 // published by the Free Software Foundation. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License version 2 for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // version 2 along with this program; if not, write to the 15 // Free Software Foundation, Inc., 16 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 // 18 19 #ifndef SOUND_CHANNEL3_H 20 #define SOUND_CHANNEL3_H 21 22 #include "gbint.h" 23 #include "length_counter.h" 24 #include "master_disabler.h" 25 26 namespace gambatte { 27 28 struct SaveState; 29 30 class Channel3 { 31 public: 32 Channel3(); isActive()33 bool isActive() const { return master_; } 34 void reset(); 35 void init(bool cgb); 36 void setStatePtrs(SaveState &state); 37 void saveState(SaveState &state) const; 38 void loadState(const SaveState &state); 39 void setNr0(unsigned data); setNr1(unsigned data)40 void setNr1(unsigned data) { lengthCounter_.nr1Change(data, nr4_, cycleCounter_); } 41 void setNr2(unsigned data); setNr3(unsigned data)42 void setNr3(unsigned data) { nr3_ = data; } 43 void setNr4(unsigned data); 44 void setSo(unsigned long soMask); 45 void update(uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); 46 waveRamRead(unsigned index)47 unsigned waveRamRead(unsigned index) const { 48 if (master_) { 49 if (!cgb_ && cycleCounter_ != lastReadTime_) 50 return 0xFF; 51 52 index = wavePos_ >> 1; 53 } 54 55 return waveRam_[index]; 56 } 57 waveRamWrite(unsigned index,unsigned data)58 void waveRamWrite(unsigned index, unsigned data) { 59 if (master_) { 60 if (!cgb_ && cycleCounter_ != lastReadTime_) 61 return; 62 63 index = wavePos_ >> 1; 64 } 65 66 waveRam_[index] = data; 67 } 68 69 private: 70 class Ch3MasterDisabler : public MasterDisabler { 71 public: Ch3MasterDisabler(bool & m,unsigned long & wC)72 Ch3MasterDisabler(bool &m, unsigned long &wC) : MasterDisabler(m), waveCounter_(wC) {} 73 operator()74 virtual void operator()() { 75 MasterDisabler::operator()(); 76 waveCounter_ = SoundUnit::counter_disabled; 77 } 78 79 private: 80 unsigned long &waveCounter_; 81 }; 82 83 unsigned char waveRam_[0x10]; 84 Ch3MasterDisabler disableMaster_; 85 LengthCounter lengthCounter_; 86 unsigned long cycleCounter_; 87 unsigned long soMask_; 88 unsigned long prevOut_; 89 unsigned long waveCounter_; 90 unsigned long lastReadTime_; 91 unsigned char nr0_; 92 unsigned char nr3_; 93 unsigned char nr4_; 94 unsigned char wavePos_; 95 unsigned char rshift_; 96 unsigned char sampleBuf_; 97 bool master_; 98 bool cgb_; 99 100 void updateWaveCounter(unsigned long cc); 101 }; 102 103 } 104 105 #endif 106