Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libgambatte/src/sound/length_counter.cpp
2 views
1
/***************************************************************************
2
* Copyright (C) 2007 by Sindre Aamås *
3
* [email protected] *
4
* *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License version 2 as *
7
* published by the Free Software Foundation. *
8
* *
9
* This program is distributed in the hope that it will be useful, *
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
* GNU General Public License version 2 for more details. *
13
* *
14
* You should have received a copy of the GNU General Public License *
15
* version 2 along with this program; if not, write to the *
16
* Free Software Foundation, Inc., *
17
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18
***************************************************************************/
19
#include "length_counter.h"
20
#include "master_disabler.h"
21
#include <algorithm>
22
23
namespace gambatte {
24
25
LengthCounter::LengthCounter(MasterDisabler &disabler, const unsigned mask) :
26
disableMaster(disabler),
27
lengthMask(mask)
28
{
29
init(false);
30
nr1Change(0, 0, 0);
31
}
32
33
void LengthCounter::event() {
34
counter = COUNTER_DISABLED;
35
lengthCounter = 0;
36
disableMaster();
37
}
38
39
void LengthCounter::nr1Change(const unsigned newNr1, const unsigned nr4, const unsigned long cycleCounter) {
40
lengthCounter = (~newNr1 & lengthMask) + 1;
41
counter = (nr4 & 0x40) ?( (cycleCounter >> 13) + lengthCounter) << 13 : static_cast<unsigned long>(COUNTER_DISABLED);
42
}
43
44
void LengthCounter::nr4Change(const unsigned oldNr4, const unsigned newNr4, const unsigned long cycleCounter) {
45
if (counter != COUNTER_DISABLED)
46
lengthCounter = (counter >> 13) - (cycleCounter >> 13);
47
48
{
49
unsigned dec = 0;
50
51
if (newNr4 & 0x40) {
52
dec = ~cycleCounter >> 12 & 1;
53
54
if (!(oldNr4 & 0x40) && lengthCounter) {
55
if (!(lengthCounter -= dec))
56
disableMaster();
57
}
58
}
59
60
if ((newNr4 & 0x80) && !lengthCounter)
61
lengthCounter = lengthMask + 1 - dec;
62
}
63
64
if ((newNr4 & 0x40) && lengthCounter)
65
counter = ((cycleCounter >> 13) + lengthCounter) << 13;
66
else
67
counter = COUNTER_DISABLED;
68
}
69
70
/*void LengthCounter::reset() {
71
counter = COUNTER_DISABLED;
72
73
if (cgb)
74
lengthCounter = lengthMask + 1;
75
}*/
76
77
void LengthCounter::init(const bool cgb) {
78
this->cgb = cgb;
79
}
80
81
void LengthCounter::loadState(const SaveState::SPU::LCounter &lstate, const unsigned long cc) {
82
counter = std::max(lstate.counter, cc);
83
lengthCounter = lstate.lengthCounter;
84
}
85
86
SYNCFUNC(LengthCounter)
87
{
88
NSS(counter);
89
NSS(lengthCounter);
90
NSS(cgb);
91
}
92
93
}
94
95