-
Notifications
You must be signed in to change notification settings - Fork 6
/
CookieboyLFSR.h
145 lines (121 loc) · 2.72 KB
/
CookieboyLFSR.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#ifndef COOKIEBOYLFSR_H
#define COOKIEBOYLFSR_H
#include "CookieboyDefs.h"
namespace Cookieboy
{
class LFSR
{
public:
LFSR()
{
LFSRPeriods[0] = 32768;
LFSRPeriods[1] = 128;
Reset();
}
void Step(DWORD clockDelta)
{
static BYTE LFSR7Table[127] =
{
#include "LFSR7.inc"
};
static BYTE LFSR15Table[32767] =
{
#include "LFSR15.inc"
};
static BYTE* LFSRTables[2] = {LFSR15Table, LFSR7Table};
//Using a noise channel clock shift of 14 or 15 results in the LFSR receiving no clocks
if (Period == 0 || NR43Clock == 14 + 4 || NR43Clock == 15 + 4)
{
return;
}
ClockCounter += clockDelta;
if (ClockCounter >= Period)
{
int passedPeriods = ClockCounter / Period;
ClockCounter %= Period;
SampleIndex += passedPeriods;
SampleIndex %= LFSRPeriods[NR43Step];
Output = LFSRTables[NR43Step][SampleIndex];
}
}
BYTE GetOutput() { return Output; }
void Reset()
{
NR43Changed(0);
ClockCounter = 0;
SampleIndex = 0;
Output = 0;
}
BYTE GetNR43() { return NR43; }
void NR43Changed(BYTE value)
{
NR43 = value;
NR43Clock = (NR43 >> 4) + 4;
NR43Step = (NR43 >> 3) & 0x1;
NR43Ratio = NR43 & 0x7;
if (!NR43Ratio)
{
NR43Ratio = 1;
NR43Clock--;
}
Period = NR43Ratio << NR43Clock;
//Using a noise channel clock shift of 14 or 15 results in the LFSR receiving no clocks
if (Period == 0 || NR43Clock == 14 + 4 || NR43Clock == 15 + 4)
{
ClockCounter = 0;
SampleIndex = 0;
}
else
{
ClockCounter %= Period;
}
}
void NR44Changed(BYTE value)
{
if (value & 0x80)
{
ClockCounter = 0;
SampleIndex = 0;
}
}
private:
BYTE NR43; //Polynomial counter (R/W)
//Bit 7-4 - Selection of the shift clock frequency of the polynomial counter
//Bit 3 - Selection of the polynomial counter's step
//Bit 2-0 - Selection of the dividing ratio of frequencies:
// 000: f * 1/2^3 * 2
// 001: f * 1/2^3 * 1
// 010: f * 1/2^3 * 1/2
// 011: f * 1/2^3 * 1/3
// 100: f * 1/2^3 * 1/4
// 101: f * 1/2^3 * 1/5
// 110: f * 1/2^3 * 1/6
// 111: f * 1/2^3 * 1/7
// f = 4.194304 Mhz
//
//Selection of the polynomial counter step:
// 0: 15 steps
// 1: 7 steps
//
//Selection of the shift clock frequency of the polynomial counter:
// 0000: dividing ratio of frequencies * 1/2
// 0001: dividing ratio of frequencies * 1/2^2
// 0010: dividing ratio of frequencies * 1/2^3
// 0011: dividing ratio of frequencies * 1/2^4
// : :
// : :
// : :
// 0101: dividing ratio of frequencies * 1/2^14
// 1110: prohibited code
// 1111: prohibited code
BYTE NR43Clock;
BYTE NR43Step;
BYTE NR43Ratio;
BYTE Output;
int ClockCounter;
int SampleIndex;
int Period;
int LFSRPeriods[2];
};
}
#endif