mirror of
https://github.com/FranLMSP/snes.git
synced 2026-10-03 16:05:18 -04:00
WIP Bus implementation
This commit is contained in:
@@ -0,0 +1,120 @@
|
|||||||
|
pub struct Bus {
|
||||||
|
wram: [u8; 0x10000],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum MemoryMap {
|
||||||
|
WRAM,
|
||||||
|
PPU,
|
||||||
|
CPU,
|
||||||
|
Joypad,
|
||||||
|
Cartridge,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bus {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
wram: [0; 0x10000],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_wram(&self, address: u32) -> u8 {
|
||||||
|
return self.wram[(address & 0xFFFF) as usize];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_wram(&mut self, address: u32, value: u8) {
|
||||||
|
self.wram[(address & 0xFFFF) as usize] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_address(address: u32) -> MemoryMap {
|
||||||
|
let (bank, sub_address) = {
|
||||||
|
let bank = (address >> 16) as u8;
|
||||||
|
let sub_address = address as u16;
|
||||||
|
(bank, sub_address)
|
||||||
|
};
|
||||||
|
match bank {
|
||||||
|
0x7E..=0x7F => MemoryMap::WRAM,
|
||||||
|
0x80..=0xBF | 0x00..=0x3F => match sub_address {
|
||||||
|
0x0000..=0x1FFF => MemoryMap::WRAM,
|
||||||
|
0x2100..=0x21FF => MemoryMap::PPU,
|
||||||
|
0x4016..=0x4017 => MemoryMap::Joypad,
|
||||||
|
0x4200..=0x43FF => MemoryMap::CPU,
|
||||||
|
_ => MemoryMap::Cartridge,
|
||||||
|
},
|
||||||
|
_ => MemoryMap::Cartridge,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(&self, address: u32) -> u8 {
|
||||||
|
let section = Bus::map_address(address);
|
||||||
|
match section {
|
||||||
|
MemoryMap::WRAM => self.read_wram(address),
|
||||||
|
_ => todo!("Implement other memory sections"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(&mut self, address: u32, value: u8) {
|
||||||
|
let section = Bus::map_address(address);
|
||||||
|
match section {
|
||||||
|
MemoryMap::WRAM => self.write_wram(address, value),
|
||||||
|
_ => todo!("Implement other memory sections"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod bus_tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn memory_map() {
|
||||||
|
assert_eq!(Bus::map_address(0x7E0000), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x7F0000), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x7E0500), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x000000), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x3F0000), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x3F1FFF), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x3F0000), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x800000), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0xBF0000), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0xBF1FFF), MemoryMap::WRAM);
|
||||||
|
assert_eq!(Bus::map_address(0x3F0000), MemoryMap::WRAM);
|
||||||
|
|
||||||
|
assert_eq!(Bus::map_address(0x002100), MemoryMap::PPU);
|
||||||
|
assert_eq!(Bus::map_address(0x0021FF), MemoryMap::PPU);
|
||||||
|
assert_eq!(Bus::map_address(0x3F2100), MemoryMap::PPU);
|
||||||
|
assert_eq!(Bus::map_address(0x3F21FF), MemoryMap::PPU);
|
||||||
|
assert_eq!(Bus::map_address(0x802100), MemoryMap::PPU);
|
||||||
|
assert_eq!(Bus::map_address(0x8021FF), MemoryMap::PPU);
|
||||||
|
assert_eq!(Bus::map_address(0xBF2100), MemoryMap::PPU);
|
||||||
|
assert_eq!(Bus::map_address(0xBF21FF), MemoryMap::PPU);
|
||||||
|
|
||||||
|
assert_eq!(Bus::map_address(0x004200), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x0042FF), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x3F4200), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x3F42FF), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x804200), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x8042FF), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0xBF4200), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0xBF42FF), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x004300), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x0043FF), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x3F4300), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x3F43FF), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x804300), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0x8043FF), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0xBF4300), MemoryMap::CPU);
|
||||||
|
assert_eq!(Bus::map_address(0xBF43FF), MemoryMap::CPU);
|
||||||
|
|
||||||
|
assert_eq!(Bus::map_address(0x004016), MemoryMap::Joypad);
|
||||||
|
assert_eq!(Bus::map_address(0x004017), MemoryMap::Joypad);
|
||||||
|
assert_eq!(Bus::map_address(0x3F4016), MemoryMap::Joypad);
|
||||||
|
assert_eq!(Bus::map_address(0x3F4017), MemoryMap::Joypad);
|
||||||
|
assert_eq!(Bus::map_address(0x804016), MemoryMap::Joypad);
|
||||||
|
assert_eq!(Bus::map_address(0x804017), MemoryMap::Joypad);
|
||||||
|
assert_eq!(Bus::map_address(0xBF4016), MemoryMap::Joypad);
|
||||||
|
assert_eq!(Bus::map_address(0xBF4017), MemoryMap::Joypad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,10 +129,10 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn adc_const(&mut self, value: u16) {
|
pub fn adc_const(&mut self, value: u16) {
|
||||||
self.registers.pc.wrapping_add(2);
|
self.registers.pc = self.registers.pc.wrapping_add(2);
|
||||||
self.cycles += 2;
|
self.cycles += 2;
|
||||||
if self.registers.get_memory_select_flag() {
|
if self.registers.get_memory_select_flag() {
|
||||||
self.registers.pc.wrapping_add(1);
|
self.registers.pc = self.registers.pc.wrapping_add(1);
|
||||||
self.cycles += 1;
|
self.cycles += 1;
|
||||||
}
|
}
|
||||||
if self.registers.get_decimal_mode_flag() {
|
if self.registers.get_decimal_mode_flag() {
|
||||||
@@ -144,7 +144,7 @@ impl CPU {
|
|||||||
pub fn decode_instruction(&mut self, opcode: u8) {
|
pub fn decode_instruction(&mut self, opcode: u8) {
|
||||||
match opcode {
|
match opcode {
|
||||||
0x69 => self.adc_const(0x00), // TODO: read value from Bus
|
0x69 => self.adc_const(0x00), // TODO: read value from Bus
|
||||||
_ => (),
|
_ => todo!("Opcode missing!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
|
pub mod bus;
|
||||||
|
|||||||
Reference in New Issue
Block a user