WolPSX
Loading...
Searching...
No Matches
bus.cpp
1#include <iostream>
2#include <sstream>
3
4#include "core/interconnect/bus.hpp"
5#include "core/bios/bios.hpp"
6#include "core/cpu/cpu.hpp"
7#include "core/memory/ram.hpp"
8
20Bus::Bus(std::string bios_path)
21{
22 cpu = new CPU();
23 bios = new BIOS(bios_path);
24 ram = new RAM(2 * 1024 * 1024);
25
26 cpu->connectBus(this);
27}
28
47uint32_t Bus::read32_cpu(uint32_t addr)
48{
49 //catch unaligned accesses
50 if (addr % 4 != 0)
51 {
52 //throw a runtime error with the unaligned address converted to hex
53 std::stringstream ss;
54 ss << "Unaligned read32_cpu: 0x" << std::hex << addr;
55 throw std::runtime_error(ss.str());
56 }
57
58 uint32_t addr_og = addr;
59 addr &= region_mask(addr);
60
61 if(bios_range.contains(addr))
62 {
63 return bios->read32_cpu(bios_range.offset(addr));
64 }
65 else if(ram_range.contains(addr))
66 {
67 return ram->read32_cpu(ram_range.offset(addr));
68 }
69 else if(interrupt_range.contains(addr))
70 {
71 std::cout << "Unhandled Interrupt Control Read: Just returning 0" << std::endl;
72 // TODO: Implement interrupts
73 return 0;
74 }
75
76 //throw a runtime error with the unmapped address converted to hex
77 std::stringstream ss;
78 ss << "Unmapped address for read32_cpu: 0x" << std::hex << addr_og;
79 throw std::runtime_error(ss.str());
80}
81
100void Bus::write32_cpu(uint32_t addr, uint32_t data)
101{
102 //catch unaligned accesses
103 if (addr % 4 != 0)
104 {
105 //throw a runtime error with the unaligned address converted to hex
106 std::stringstream ss;
107 ss << "Unaligned write32_cpu: 0x" << std::hex << addr;
108 throw std::runtime_error(ss.str());
109 }
110
111 uint32_t addr_og = addr;
112 addr &= region_mask(addr);
113
114 if(mem_ctrl_range.contains(addr))
115 {
116 switch(mem_ctrl_range.offset(addr))
117 {
118 case 0:
119 if(data != 0x1f000000)
120 {
121 std::stringstream ss;
122 ss << "Bad Expansion 1 Base Address write: 0x" << std::hex << data;
123 throw std::runtime_error(ss.str());
124 }
125 break;
126 case 4:
127 if(data != 0x1f802000)
128 {
129 std::stringstream ss;
130 ss << "Bad Expansion 2 Base Address write: 0x" << std::hex << data;
131 throw std::runtime_error(ss.str());
132 }
133 break;
134 default:
135 std::stringstream ss;
136 ss << "Unhandled write to MEM_CTRL register: " << addr;
137 // throw std::runtime_error(ss.str());
138 break;
139 }
140 return;
141 }
142 else if(ram_size_range.contains(addr))
143 {
144 //TODO: implement RAM size register
145 return;
146 }
147 else if(cache_ctrl_range.contains(addr))
148 {
149 //TODO: implement cache control register
150 return;
151 }
152 else if(ram_range.contains(addr))
153 {
154 ram->write32_cpu(ram_range.offset(addr), data);
155 return;
156 }
157 else if(interrupt_range.contains(addr))
158 {
159 //Implement peripherals and interrupts
160 std::cout << "Ignoring write32 to Interrupt Register" << std::endl;
161 return;
162 }
163
164 //throw a runtime error with the unmapped address converted to hex
165 std::stringstream ss;
166 ss << "Unmapped address for write32_cpu: 0x" << std::hex << addr_og;
167 throw std::runtime_error(ss.str());
168}
169
186uint16_t Bus::read16_cpu(uint32_t addr)
187{
188 //catch unaligned accesses
189 if (addr % 2 != 0)
190 {
191 //throw a runtime error with the unaligned address converted to hex
192 std::stringstream ss;
193 ss << "Unaligned read16_cpu: 0x" << std::hex << addr;
194 throw std::runtime_error(ss.str());
195 }
196
197 uint32_t addr_og = addr;
198 addr &= region_mask(addr);
199
200 //throw a runtime error with the unmapped address converted to hex
201 std::stringstream ss;
202 ss << "Unmapped address for read16_cpu: 0x" << std::hex << addr_og;
203 throw std::runtime_error(ss.str());
204}
205
222void Bus::write16_cpu(uint32_t addr, uint16_t data)
223{
224 //catch unaligned accesses
225 if (addr % 2 != 0)
226 {
227 //throw a runtime error with the unaligned address converted to hex
228 std::stringstream ss;
229 ss << "Unaligned write16_cpu: 0x" << std::hex << addr;
230 throw std::runtime_error(ss.str());
231 }
232
233 uint32_t addr_og = addr;
234 addr &= region_mask(addr);
235
236 if(spu_range.contains(addr))
237 {
238 //TODO: Implement SPU
239 switch(spu_range.offset(addr))
240 {
241 default:
242 std::stringstream ss;
243 ss << "Unhandled write16 (" << data << ") to SPU register: " << addr_og;
244 // throw std::runtime_error(ss.str());
245 break;
246 }
247
248 return;
249 }
250 else if(timer_range.contains(addr))
251 {
252 //TODO implement timer
253 std::cout << "Ignoring write16 to Timer Register" << std::endl;
254 return;
255 }
256
257 //throw a runtime error with the unmapped address converted to hex
258 std::stringstream ss;
259 ss << "Unmapped address for write16_cpu: 0x" << std::hex << addr;
260 throw std::runtime_error(ss.str());
261}
262
281uint8_t Bus::read8_cpu(uint32_t addr)
282{
283 uint32_t addr_og = addr;
284 addr &= region_mask(addr);
285
286 if(bios_range.contains(addr))
287 {
288 return bios->read32_cpu(bios_range.offset(addr));
289 }
290 else if(expansion1_range.contains(addr))
291 {
292 //TODO: Implement Expansion Region 1
293 return 0xff;
294 }
295 else if(ram_range.contains(addr))
296 {
297 return ram->read8_cpu(ram_range.offset(addr));
298 }
299
300 //throw a runtime error with the unmapped address converted to hex
301 std::stringstream ss;
302 ss << "Unmapped address for read8_cpu: 0x" << std::hex << addr_og;
303 throw std::runtime_error(ss.str());
304}
305
323void Bus::write8_cpu(uint32_t addr, uint8_t data)
324{
325 uint32_t addr_og = addr;
326 addr &= region_mask(addr);
327
328 if(expansion2_range.contains(addr))
329 {
330 std::cout << "Ignoring write8 to Expansion 2" << std::endl;
331 return;
332 }
333 else if(ram_range.contains(addr))
334 {
335 return ram->write8_cpu(ram_range.offset(addr), data);
336 }
337
338 //throw a runtime error with the unmapped address converted to hex
339 std::stringstream ss;
340 ss << "Unmapped address for write8_cpu: 0x" << std::hex << addr_og;
341 throw std::runtime_error(ss.str());
342}
Class to emulate the BIOS.
Definition bios.hpp:16
uint32_t read32_cpu(uint32_t offset)
Reads a 32-bit word from the BIOS.
Definition bios.cpp:40
Range mem_ctrl_range
Range of the Memory Control Registers.
Definition bus.hpp:125
RAM * ram
Pointer to the RAM object.
Definition bus.hpp:113
Range expansion1_range
Range of the Expansion 1.
Definition bus.hpp:161
Range ram_size_range
Range of the RAM Size Register.
Definition bus.hpp:131
CPU * cpu
Pointer to the CPU object.
Definition bus.hpp:101
uint16_t read16_cpu(uint32_t addr)
Reads a 16-bit word from the given address.
Definition bus.cpp:186
uint32_t read32_cpu(uint32_t addr)
Reads a 32-bit word from the given address.
Definition bus.cpp:47
Bus(std::string bios_path)
Construct a new Bus:: Bus object.
Definition bus.cpp:20
Range ram_range
Range of the RAM.
Definition bus.hpp:143
Range bios_range
Range of the BIOS.
Definition bus.hpp:119
Range timer_range
Range of the Timer Registers.
Definition bus.hpp:173
Range cache_ctrl_range
Range of the Cache Control Register.
Definition bus.hpp:137
BIOS * bios
Pointer to the BIOS object.
Definition bus.hpp:107
void write8_cpu(uint32_t addr, uint8_t data)
Writes a 8-bit word to the given address.
Definition bus.cpp:323
uint32_t region_mask(uint32_t addr)
Returns the region mask for a given address.
Definition bus_utils.cpp:15
Range expansion2_range
Range of the Expansion 2.
Definition bus.hpp:155
void write32_cpu(uint32_t addr, uint32_t data)
Writes a 32-bit word to the given address.
Definition bus.cpp:100
void write16_cpu(uint32_t addr, uint16_t data)
Writes a 16-bit word to the given address.
Definition bus.cpp:222
Range interrupt_range
Range of the Interrupt Registers.
Definition bus.hpp:167
Range spu_range
Range of the SPU (Sound Processing Unit) Registers.
Definition bus.hpp:149
uint8_t read8_cpu(uint32_t addr)
Reads a 8-bit word from the given address.
Definition bus.cpp:281
Class to emulate the CPU.
Definition cpu.hpp:145
void connectBus(Bus *bus)
Connects Bus to the CPU.
Definition cpu.hpp:155
Class to emulate the RAM.
Definition ram.hpp:13
void write8_cpu(uint32_t offset, uint8_t data)
Writes a byte to the RAM.
Definition ram.cpp:97
void write32_cpu(uint32_t offset, uint32_t data)
Writes a 32-bit word to the RAM.
Definition ram.cpp:53
uint32_t read32_cpu(uint32_t offset)
Reads a 32-bit word from the RAM.
Definition ram.cpp:27
uint8_t read8_cpu(uint32_t offset)
Reads a byte from the RAM.
Definition ram.cpp:78
bool contains(uint32_t addr)
Checks if the given address is in the range.
Definition bus.hpp:55
uint32_t offset(uint32_t addr)
Gets the offset of the given address from the start of the range.
Definition bus.hpp:66