Skip to content

Commit

Permalink
core: Handle 8bit writes to video memory
Browse files Browse the repository at this point in the history
fixes #96
  • Loading branch information
michelhe committed May 18, 2020
1 parent 4677465 commit 44082a3
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 20 deletions.
67 changes: 65 additions & 2 deletions rustboyadvance-core/src/gpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use std::rc::Rc;
use serde::{Deserialize, Serialize};

use super::interrupt::IrqBitmask;
pub use super::sysbus::consts::*;
use super::sysbus::{BoxedMemory, SysBus};
use super::Bus;
use super::VideoInterface;
use super::{Addr, Bus};

use crate::bitfield::Bit;
use crate::num::FromPrimitive;
Expand All @@ -30,11 +31,11 @@ pub use regs::*;

#[allow(unused)]
pub mod consts {
pub use super::VRAM_ADDR;
pub const VIDEO_RAM_SIZE: usize = 128 * 1024;
pub const PALETTE_RAM_SIZE: usize = 1 * 1024;
pub const OAM_SIZE: usize = 1 * 1024;

pub const VRAM_ADDR: u32 = 0x0600_0000;
pub const DISPLAY_WIDTH: usize = 240;
pub const DISPLAY_HEIGHT: usize = 160;
pub const VBLANK_LINES: usize = 68;
Expand Down Expand Up @@ -203,6 +204,68 @@ pub struct Gpu {
pub(super) frame_buffer: Vec<u32>,
}

impl Bus for Gpu {
fn read_8(&self, addr: Addr) -> u8 {
let page = (addr >> 24) as usize;
match page {
PAGE_PALRAM => self.palette_ram.read_8(addr & 0x3ff),
PAGE_VRAM => {
// complicated
let mut ofs = addr & ((VIDEO_RAM_SIZE as u32) - 1);
if ofs > 0x18000 {
ofs -= 0x8000;
}
self.vram.read_8(ofs)
}
PAGE_OAM => self.oam.read_8(addr & 0x3ff),
_ => unreachable!(),
}
}

fn write_16(&mut self, addr: Addr, value: u16) {
let page = (addr >> 24) as usize;
match page {
PAGE_PALRAM => self.palette_ram.write_16(addr & 0x3fe, value),
PAGE_VRAM => {
let mut ofs = addr & ((VIDEO_RAM_SIZE as u32) - 1);
if ofs > 0x18000 {
ofs -= 0x8000;
}
self.vram.write_16(ofs, value)
}
PAGE_OAM => self.oam.write_16(addr & 0x3fe, value),
_ => unreachable!(),
}
}

fn write_8(&mut self, addr: Addr, value: u8) {
fn expand_value(value: u8) -> u16 {
(value as u16) * 0x101
}

let page = (addr >> 24) as usize;
match page {
PAGE_PALRAM => self.oam.write_16(addr & 0x3fe, expand_value(value)),

This comment has been minimized.

Copy link
@xTibor

xTibor May 18, 2020

Contributor

Copy-paste bug here (OAM / PAL)

This comment has been minimized.

Copy link
@michelhe

michelhe May 19, 2020

Author Owner

Now that would have taken forever to discover.
Thank you for noticing!

PAGE_VRAM => {
let mut ofs = addr & ((VIDEO_RAM_SIZE as u32) - 1);
if ofs > 0x18000 {
ofs -= 0x8000;
}
let obj_offset = if self.dispcnt.mode() >= 3 {
0x14000
} else {
0x10000
};
if ofs < obj_offset {
self.vram.write_16(ofs & !1, expand_value(value));
}
}
PAGE_OAM => { /* OAM can't be written with 8bit store */ }
_ => unreachable!(),
};
}
}

impl Gpu {
pub fn new() -> Gpu {
Gpu {
Expand Down
20 changes: 2 additions & 18 deletions rustboyadvance-core/src/sysbus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,7 @@ macro_rules! memory_map {
};
$sb.io.$read_fn(addr)
}
PALRAM_ADDR => $sb.io.gpu.palette_ram.$read_fn($addr & 0x3ff),
VRAM_ADDR => {
let mut ofs = $addr & ((VIDEO_RAM_SIZE as u32) - 1);
if ofs > 0x18000 {
ofs -= 0x8000;
}
$sb.io.gpu.vram.$read_fn(ofs)
}
OAM_ADDR => $sb.io.gpu.oam.$read_fn($addr & 0x3ff),
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => $sb.io.gpu.$read_fn($addr),
GAMEPAK_WS0_LO | GAMEPAK_WS0_HI | GAMEPAK_WS1_LO | GAMEPAK_WS1_HI | GAMEPAK_WS2_LO => {
$sb.cartridge.$read_fn($addr)
}
Expand All @@ -289,15 +281,7 @@ macro_rules! memory_map {
};
$sb.io.$write_fn(addr, $value)
}
PALRAM_ADDR => $sb.io.gpu.palette_ram.$write_fn($addr & 0x3ff, $value),
VRAM_ADDR => {
let mut ofs = $addr & ((VIDEO_RAM_SIZE as u32) - 1);
if ofs > 0x18000 {
ofs -= 0x8000;
}
$sb.io.gpu.vram.$write_fn(ofs, $value)
}
OAM_ADDR => $sb.io.gpu.oam.$write_fn($addr & 0x3ff, $value),
PALRAM_ADDR | VRAM_ADDR | OAM_ADDR => $sb.io.gpu.$write_fn($addr, $value),
GAMEPAK_WS0_LO | GAMEPAK_WS0_HI => {}
GAMEPAK_WS2_HI => $sb.cartridge.$write_fn($addr, $value),
SRAM_LO | SRAM_HI => $sb.cartridge.$write_fn($addr, $value),
Expand Down

0 comments on commit 44082a3

Please sign in to comment.