Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/armdsp/armdsp.cpp
2 views
1
#include <snes/snes.hpp>
2
3
#define ARMDSP_CPP
4
namespace SNES {
5
6
//zero 01-sep-2014 - dont clobber these when reconstructing!
7
uint8 *ArmDSP::firmware;
8
uint8 *ArmDSP::programROM;
9
uint8 *ArmDSP::dataROM;
10
11
static bool trace = 0;
12
13
#include "opcodes.cpp"
14
#include "memory.cpp"
15
#include "disassembler.cpp"
16
#include "serialization.cpp"
17
ArmDSP armdsp;
18
19
void ArmDSP::Enter() { armdsp.enter(); }
20
21
void ArmDSP::enter() {
22
//reset hold delay
23
while(bridge.reset) {
24
tick();
25
continue;
26
}
27
28
//reset sequence delay
29
if(bridge.ready == false) {
30
tick(65536);
31
bridge.ready = true;
32
}
33
34
while(true) {
35
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
36
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
37
}
38
39
if(exception) {
40
print("* ARM unknown instruction\n");
41
print("\n", disassemble_registers());
42
print("\n", disassemble_opcode(pipeline.instruction.address), "\n");
43
while(true) tick(frequency);
44
}
45
46
if(pipeline.reload) {
47
pipeline.reload = false;
48
pipeline.prefetch.address = r[15];
49
pipeline.prefetch.opcode = bus_readword(r[15]);
50
r[15].step();
51
}
52
53
pipeline.instruction = pipeline.prefetch;
54
pipeline.prefetch.address = r[15];
55
pipeline.prefetch.opcode = bus_readword(r[15]);
56
r[15].step();
57
58
//todo: bus_readword() calls tick(); so we need to prefetch this as well
59
//pipeline.mdr.address = r[15];
60
//pipeline.mdr.opcode = bus_readword(r[15]);
61
62
//if(pipeline.instruction.address == 0x00000208) trace = 1;
63
if(trace) {
64
print("\n", disassemble_registers(), "\n");
65
print(disassemble_opcode(pipeline.instruction.address), "\n");
66
usleep(200000);
67
}
68
//trace = 0;
69
70
instruction = pipeline.instruction.opcode;
71
if(!condition()) continue;
72
if((instruction & 0x0fc000f0) == 0x00000090) { op_multiply(); continue; }
73
if((instruction & 0x0fb000f0) == 0x01000000) { op_move_to_register_from_status_register(); continue; }
74
if((instruction & 0x0fb000f0) == 0x01200000) { op_move_to_status_register_from_register(); continue; }
75
if((instruction & 0x0e000010) == 0x00000000) { op_data_immediate_shift(); continue; }
76
if((instruction & 0x0e000090) == 0x00000010) { op_data_register_shift(); continue; }
77
if((instruction & 0x0e000000) == 0x02000000) { op_data_immediate(); continue; }
78
if((instruction & 0x0e000000) == 0x04000000) { op_move_immediate_offset(); continue; }
79
if((instruction & 0x0e000010) == 0x06000000) { op_move_register_offset(); continue; }
80
if((instruction & 0x0e000000) == 0x08000000) { op_move_multiple(); continue; }
81
if((instruction & 0x0e000000) == 0x0a000000) { op_branch(); continue; }
82
83
exception = true;
84
}
85
}
86
87
void ArmDSP::tick(unsigned clocks) {
88
if(bridge.timer && --bridge.timer == 0) bridge.busy = false;
89
90
step(clocks);
91
synchronize_cpu();
92
}
93
94
//MMIO: $00-3f|80-bf:3800-38ff
95
//3800-3807 mirrored throughout
96
//a0 ignored
97
98
uint8 ArmDSP::mmio_read(unsigned addr) {
99
cpu.synchronize_coprocessors();
100
101
uint8 data = 0x00;
102
addr &= 0xff06;
103
104
if(addr == 0x3800) {
105
if(bridge.armtocpu.ready) {
106
bridge.armtocpu.ready = false;
107
data = bridge.armtocpu.data;
108
}
109
}
110
111
if(addr == 0x3802) {
112
bridge.timer = 0;
113
bridge.busy = false;
114
}
115
116
if(addr == 0x3804) {
117
data = bridge.status();
118
}
119
120
return data;
121
}
122
123
void ArmDSP::mmio_write(unsigned addr, uint8 data) {
124
cpu.synchronize_coprocessors();
125
126
addr &= 0xff06;
127
128
if(addr == 0x3802) {
129
bridge.cputoarm.ready = true;
130
bridge.cputoarm.data = data;
131
}
132
133
if(addr == 0x3804) {
134
data &= 1;
135
if(!bridge.reset && data) arm_reset();
136
bridge.reset = data;
137
}
138
}
139
140
void ArmDSP::init() {
141
}
142
143
void ArmDSP::load() {
144
}
145
146
void ArmDSP::unload() {
147
}
148
149
void ArmDSP::power() {
150
for(unsigned n = 0; n < 16 * 1024; n++) programRAM[n] = random(0x00);
151
}
152
153
void ArmDSP::reset() {
154
bridge.reset = false;
155
arm_reset();
156
}
157
158
void ArmDSP::arm_reset() {
159
create(ArmDSP::Enter, 21477272);
160
161
bridge.ready = false;
162
bridge.timer = 0;
163
bridge.timerlatch = 0;
164
bridge.busy = false;
165
bridge.cputoarm.ready = false;
166
bridge.armtocpu.ready = false;
167
168
for(auto &rd : r) rd = 0;
169
shiftercarry = 0;
170
exception = 0;
171
pipeline.reload = true;
172
r[15].write = [&] { pipeline.reload = true; };
173
}
174
175
ArmDSP::ArmDSP() {
176
firmware = new uint8[160 * 1024]();
177
programRAM = new uint8[16 * 1024]();
178
179
programROM = &firmware[0];
180
dataROM = &firmware[128 * 1024];
181
}
182
183
ArmDSP::~ArmDSP() {
184
delete[] firmware;
185
delete[] programRAM;
186
}
187
188
}
189
190