Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/msu1/msu1.cpp
2 views
1
#include <snes/snes.hpp>
2
3
#define MSU1_CPP
4
namespace SNES {
5
6
MSU1 msu1;
7
8
#include "serialization.cpp"
9
10
void MSU1::Enter() { msu1.enter(); }
11
12
void MSU1::enter() {
13
while(true) {
14
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
15
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
16
}
17
18
int16 left = 0, right = 0;
19
20
if(mmio.audio_play) {
21
if(audiofile.open()) {
22
if(audiofile.end()) {
23
if(!mmio.audio_repeat) {
24
mmio.audio_play = false;
25
audiofile.seek(mmio.audio_offset = 8);
26
} else {
27
audiofile.seek(mmio.audio_offset = mmio.audio_loop_offset);
28
}
29
} else {
30
mmio.audio_offset += 4;
31
left = audiofile.readl(2);
32
right = audiofile.readl(2);
33
}
34
} else {
35
mmio.audio_play = false;
36
}
37
}
38
39
signed lchannel = (double)left * (double)mmio.audio_volume / 255.0;
40
signed rchannel = (double)right * (double)mmio.audio_volume / 255.0;
41
left = sclamp<16>(lchannel);
42
right = sclamp<16>(rchannel);
43
44
audio.coprocessor_sample(left, right);
45
step(1);
46
synchronize_cpu();
47
}
48
}
49
50
void MSU1::init() {
51
}
52
53
void MSU1::load() {
54
if(datafile.open()) datafile.close();
55
datafile.open(interface()->path(Cartridge::Slot::Base, "msu1.rom"), file::mode::read);
56
}
57
58
void MSU1::unload() {
59
if(datafile.open()) datafile.close();
60
}
61
62
void MSU1::power() {
63
audio.coprocessor_enable(true);
64
audio.coprocessor_frequency(44100.0);
65
}
66
67
void MSU1::reset() {
68
create(MSU1::Enter, 44100);
69
70
mmio.data_offset = 0;
71
mmio.audio_offset = 0;
72
mmio.audio_track = 0;
73
mmio.audio_volume = 255;
74
mmio.data_busy = true;
75
mmio.audio_busy = true;
76
mmio.audio_repeat = false;
77
mmio.audio_play = false;
78
}
79
80
uint8 MSU1::mmio_read(unsigned addr) {
81
switch(addr & 7) {
82
case 0:
83
return (mmio.data_busy << 7)
84
| (mmio.audio_busy << 6)
85
| (mmio.audio_repeat << 5)
86
| (mmio.audio_play << 4)
87
| (Revision << 0);
88
case 1:
89
if(mmio.data_busy) return 0x00;
90
mmio.data_offset++;
91
if(datafile.open()) return datafile.read();
92
return 0x00;
93
case 2: return 'S';
94
case 3: return '-';
95
case 4: return 'M';
96
case 5: return 'S';
97
case 6: return 'U';
98
case 7: return '0' + Revision;
99
}
100
throw;
101
}
102
103
void MSU1::mmio_write(unsigned addr, uint8 data) {
104
switch(addr & 7) {
105
case 0: mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0); break;
106
case 1: mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8); break;
107
case 2: mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16); break;
108
case 3: mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24);
109
if(datafile.open()) datafile.seek(mmio.data_offset);
110
mmio.data_busy = false;
111
break;
112
case 4: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0);
113
case 5: mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8);
114
if(audiofile.open()) audiofile.close();
115
if(audiofile.open(interface()->path(Cartridge::Slot::Base, { "track-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) {
116
uint32 header = audiofile.readm(4);
117
if(header != 0x4d535531) { //verify 'MSU1' header
118
audiofile.close();
119
} else {
120
mmio.audio_offset = 8;
121
mmio.audio_loop_offset = 8 + audiofile.readl(4) * 4;
122
}
123
}
124
mmio.audio_busy = false;
125
mmio.audio_repeat = false;
126
mmio.audio_play = false;
127
break;
128
case 6:
129
mmio.audio_volume = data;
130
break;
131
case 7:
132
mmio.audio_repeat = data & 2;
133
mmio.audio_play = data & 1;
134
break;
135
}
136
}
137
138
}
139
140