Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/gameboy/apu/apu.cpp
2 views
1
#include <gameboy/gameboy.hpp>
2
3
#define APU_CPP
4
namespace GameBoy {
5
6
#include "square1/square1.cpp"
7
#include "square2/square2.cpp"
8
#include "wave/wave.cpp"
9
#include "noise/noise.cpp"
10
#include "master/master.cpp"
11
#include "serialization.cpp"
12
APU apu;
13
14
void APU::Main() {
15
apu.main();
16
}
17
18
void APU::main() {
19
while(true) {
20
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
21
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
22
}
23
24
if(sequencer_base == 0) { //512hz
25
if(sequencer_step == 0 || sequencer_step == 2 || sequencer_step == 4 || sequencer_step == 6) { //256hz
26
square1.clock_length();
27
square2.clock_length();
28
wave.clock_length();
29
noise.clock_length();
30
}
31
if(sequencer_step == 2 || sequencer_step == 6) { //128hz
32
square1.clock_sweep();
33
}
34
if(sequencer_step == 7) { //64hz
35
square1.clock_envelope();
36
square2.clock_envelope();
37
noise.clock_envelope();
38
}
39
sequencer_step++;
40
}
41
sequencer_base++;
42
43
square1.run();
44
square2.run();
45
wave.run();
46
noise.run();
47
master.run();
48
49
interface->audioSample(master.center, master.left, master.right);
50
51
clock += 1 * cpu.frequency;
52
if(clock >= 0) co_switch(scheduler.active_thread = cpu.thread);
53
}
54
}
55
56
void APU::power() {
57
create(Main, 4 * 1024 * 1024);
58
for(unsigned n = 0xff10; n <= 0xff3f; n++) bus.mmio[n] = this;
59
60
for(auto &n : mmio_data) n = 0x00;
61
sequencer_base = 0;
62
sequencer_step = 0;
63
64
square1.power();
65
square2.power();
66
wave.power();
67
noise.power();
68
master.power();
69
}
70
71
uint8 APU::mmio_read(uint16 addr) {
72
static const uint8 table[48] = {
73
0x80, 0x3f, 0x00, 0xff, 0xbf, //square1
74
0xff, 0x3f, 0x00, 0xff, 0xbf, //square2
75
0x7f, 0xff, 0x9f, 0xff, 0xbf, //wave
76
0xff, 0xff, 0x00, 0x00, 0xbf, //noise
77
0x00, 0x00, 0x70, //master
78
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //unmapped
79
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //wave pattern
80
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //wave pattern
81
};
82
83
if(addr == 0xff26) {
84
uint8 data = master.enable << 7;
85
if(square1.enable) data |= 0x01;
86
if(square2.enable) data |= 0x02;
87
if( wave.enable) data |= 0x04;
88
if( noise.enable) data |= 0x08;
89
return data | table[addr - 0xff10];
90
}
91
92
if(addr >= 0xff10 && addr <= 0xff3f) return mmio_data[addr - 0xff10] | table[addr - 0xff10];
93
return 0xff;
94
}
95
96
void APU::mmio_write(uint16 addr, uint8 data) {
97
if(addr >= 0xff10 && addr <= 0xff3f) mmio_data[addr - 0xff10] = data;
98
99
if(addr >= 0xff10 && addr <= 0xff14) return square1.write (addr - 0xff10, data);
100
if(addr >= 0xff15 && addr <= 0xff19) return square2.write (addr - 0xff15, data);
101
if(addr >= 0xff1a && addr <= 0xff1e) return wave.write (addr - 0xff1a, data);
102
if(addr >= 0xff1f && addr <= 0xff23) return noise.write (addr - 0xff1f, data);
103
if(addr >= 0xff24 && addr <= 0xff26) return master.write (addr - 0xff24, data);
104
if(addr >= 0xff30 && addr <= 0xff3f) return wave.write_pattern(addr - 0xff30, data);
105
}
106
107
}
108
109