Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions aliusnes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
log = ["simplelog"]
trace = ["log"]

[dependencies]
log = "0.4.21"
Expand Down
10 changes: 5 additions & 5 deletions aliusnes/src/bus/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ impl Dma {
5 => vec![0, 1, 0, 1],
_ => unreachable!(),
};
// log::warn!("Channel {index} will transfer {count} Bytes");

for i in 0..count {
let bank = bus.dma.channels[index].a_bank_or_h_table_bank;
let offset = bus.dma.channels[index].a_addr_or_h_table_addr;
let a_addr = Address::new(offset, bank);
let byte = channel.b_addr.wrapping_add(pattern[i % pattern.len()]);

//WRAM to WRAM is invalid
// WRAM to WRAM is invalid
if byte == 0x80
&& ((u32::from(a_addr) & 0x00FE_0000) == 0x007E_0000
|| (u32::from(a_addr) & 0x0040_E000) == 0)
&& ((u32::from(a_addr) & 0xFE_0000) == 0x7E_0000
|| (u32::from(a_addr) & 0x40_E000) == 0)
{
continue;
}
Expand Down Expand Up @@ -110,7 +110,7 @@ impl Dma {
}

impl Access for Dma {
fn read(&mut self, addr: u16) -> Option<u8> {
fn read(&mut self, addr: u16, _: u64) -> Option<u8> {
let channel = self.channels[((addr >> 4) & 7) as usize];
match addr & 0xF {
0x0 => Some(channel.parameters.0),
Expand Down
2 changes: 1 addition & 1 deletion aliusnes/src/bus/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Math {
}

impl Access for Math {
fn read(&mut self, addr: u16) -> Option<u8> {
fn read(&mut self, addr: u16, _: u64) -> Option<u8> {
match addr {
0x4214 => Some(self.quotient.low_byte()),
0x4215 => Some(self.quotient.high_byte()),
Expand Down
6 changes: 3 additions & 3 deletions aliusnes/src/bus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ pub trait Bus {
fn read_and_tick(&mut self, addr: Address) -> u8;
fn write_and_tick(&mut self, addr: Address, data: u8);
fn add_io_cycles(&mut self, cycles: usize);
fn fired_nmi(&self) -> bool;
fn fired_irq(&self) -> bool;
fn fired_nmi(&mut self) -> bool;
fn fired_irq(&mut self) -> bool;
}

pub trait Access {
fn read(&mut self, addr: u16) -> Option<u8>;
fn read(&mut self, addr: u16, time: u64) -> Option<u8>;
fn write(&mut self, addr: u16, data: u8);
}
133 changes: 80 additions & 53 deletions aliusnes/src/bus/system_bus.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,114 @@
use crate::{cart::Cart, ppu::Ppu, utils::int_traits::ManipulateU16, w65c816::addressing::Address};
use crate::{
cart::Cart, ppu::Ppu, scheduler::Scheduler, utils::int_traits::ManipulateU16,
w65c816::addressing::Address,
};

use super::{dma::Dma, math::Math, wram::Wram, Access, Bus};

pub struct SystemBus {
mdr: u8,
fast_rom_enabled: bool,
cycles: usize,
cart: Cart,
pub dma: Dma,
math: Math,
pub ppu: Ppu,
pub scheduler: Scheduler,
wram: Wram,
dummy_apu: [u8; 4],
}

impl SystemBus {
pub fn new(cart: Cart) -> Self {
Self {
mdr: 0,
fast_rom_enabled: false,
cycles: 0,
ppu: Ppu::new(cart.model),
scheduler: Scheduler::new(),
cart,
dma: Dma::new(),
math: Math::new(),
wram: Wram::new(),
}
}

pub fn tick(&mut self) {
//todo apu, joypad, hdma

let ticks = self.cycles;
self.cycles = 0;

for _ in 0..ticks {
self.ppu.tick();
dummy_apu: [0xAA, 0, 0, 0],
}
}

pub fn add_cycles(&mut self, cycles: usize) {
self.cycles += cycles;
self.scheduler.tick(cycles as u64);
}

pub fn read_b(&mut self, addr: u16) -> u8 {
if let Some(val) = match addr.low_byte() {
0x34..=0x3F => self.ppu.read(addr),
0x40..=0x43 => todo!("apu area"),
0x80 => self.wram.read(addr),
0x34..=0x3F => self.ppu.read(addr, self.scheduler.cycles),
0x40..=0x43 => {
let ch = ((addr - 0x2140) % 4) as usize;

let value = self.dummy_apu[ch];
self.dummy_apu[ch] = match ch {
0 => 0xAA,
1 => 0xBB,
_ => 0,
};

Some(value)
}
0x80 => self.wram.read(addr, 0),
_ => None,
} {
self.mdr = val;
val
} else {
self.mdr = 0;
self.mdr
}
self.mdr
}

fn peek(&self, addr: Address) -> Option<u8> {
let bank = addr.bank;
let page = addr.offset;

match bank {
0x00..=0x3F | 0x80..=0xBF => {
if let 0x00..=0x1F = page.high_byte() {
return Some(self.wram.ram[page as usize & 0x1FFF]);
}
}
0x7E..=0x7F => return Some(self.wram.ram[u32::from(addr) as usize & 0x1_FFFF]),
_ => {}
}

self.cart.read(bank.into(), page.into())
}

pub fn read<const DMA: bool>(&mut self, addr: Address) -> u8 {
let bank = addr.bank;
let page = addr.offset;

if DMA && (bank & 0x40) == 0 && matches!(page.high_byte(), 0x21 | 0x40 | 0x42 | 0x43) {
self.mdr = 0;
return self.mdr;
}

if let Some(val) = match bank {
0x00..=0x3F | 0x80..=0xBF => match page.high_byte() {
0x00..=0x1F => Some(self.wram.ram[page as usize & 0x1FFF]),
0x21 => return self.read_b(page),
0x21 => Some(self.read_b(page)),
0x40..=0x43 => {
if DMA {
Some(0)
} else {
match page {
0x4210 => Some(self.ppu.read_nmi_flag() | (self.mdr & 0x70)),
0x4211 => Some(self.ppu.read_irq_flag() | (self.mdr & 0x7F)),
0x4212 => {
let joypad_autoread_status = false; // todo
Some(
self.ppu.read_hv_status()
| u8::from(joypad_autoread_status)
| (self.mdr & 0x3E),
)
}
0x4214..=0x4217 => self.math.read(page),
0x4300..=0x437F => self.dma.read(page),
_ => {
println!("Tried to read at {page:#0x}");
None
}
match page {
0x4210 => Some(self.ppu.read_nmi_flag() | (self.mdr & 0x70)),
0x4211 => Some(self.ppu.read_irq_flag() | (self.mdr & 0x7F)),
0x4212 => {
let joypad_autoread_status = false; // todo
Some(
self.ppu.read_hv_status()
| u8::from(joypad_autoread_status)
| (self.mdr & 0x3E),
)
}
0x4214..=0x4217 => self.math.read(page, 0),
// TODO joypad registers
0x4218..=0x421F => Some(0),
0x4300..=0x437F => self.dma.read(page, 0),
_ => {
println!("Tried to read at {page:#0x}");
None
}
}
}
Expand All @@ -98,7 +122,7 @@ impl SystemBus {
return self.mdr;
}

if let Some(val) = self.cart.read(bank, page) {
if let Some(val) = self.cart.read(bank.into(), page.into()) {
self.mdr = val;
}
self.mdr
Expand All @@ -107,7 +131,10 @@ impl SystemBus {
pub fn write_b(&mut self, addr: u16, data: u8) {
match addr.low_byte() {
0x00..=0x33 => self.ppu.write(addr, data),
0x40..=0x43 => todo!("apu area"),
0x40..=0x43 => {
let ch = ((addr - 0x2140) % 4) as usize;
self.dummy_apu[ch] = data;
}
0x80..=0x83 => self.wram.write(addr, data),
_ => println!("Tried to write at {addr:#0x} val: {data:#04x}"),
}
Expand Down Expand Up @@ -140,7 +167,7 @@ impl SystemBus {
0x7E..=0x7F => return self.wram.ram[u32::from(addr) as usize & 0x1_FFFF] = data,
_ => {}
}
self.cart.write(bank, page, data);
self.cart.write(bank.into(), page.into(), data);
}

pub fn memory_access_cycles(&self, addr: &Address) -> u32 {
Expand Down Expand Up @@ -174,29 +201,29 @@ impl SystemBus {
}

impl Bus for SystemBus {
fn peek_at(&self, _addr: Address) -> Option<u8> {
todo!()
fn peek_at(&self, addr: Address) -> Option<u8> {
self.peek(addr)
}

fn read_and_tick(&mut self, addr: Address) -> u8 {
self.cycles += self.memory_access_cycles(&addr) as usize;
self.scheduler.tick(self.memory_access_cycles(&addr) as u64);
self.read::<false>(addr)
}

fn write_and_tick(&mut self, addr: Address, data: u8) {
self.cycles += self.memory_access_cycles(&addr) as usize;
self.scheduler.tick(self.memory_access_cycles(&addr) as u64);
self.write::<false>(addr, data);
}

fn add_io_cycles(&mut self, cycles: usize) {
self.cycles += cycles * 6;
self.scheduler.tick((cycles * 6) as u64);
}

fn fired_nmi(&self) -> bool {
self.ppu.nmi_requested
fn fired_nmi(&mut self) -> bool {
self.ppu.nmi_requested()
}

fn fired_irq(&self) -> bool {
fn fired_irq(&mut self) -> bool {
self.ppu.is_in_irq()
}
}
2 changes: 1 addition & 1 deletion aliusnes/src/bus/wram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Wram {
}

impl Access for Wram {
fn read(&mut self, _addr: u16) -> Option<u8> {
fn read(&mut self, _addr: u16, _: u64) -> Option<u8> {
let data = self.ram[usize::from(self.wm_addr)];
let raw_addr = (u32::from(self.wm_addr) + 1) & 0x1_FFFF;
self.wm_addr = Address::from(raw_addr);
Expand Down
Loading
Loading