Skip to content
Snippets Groups Projects
Verified Commit 1c99b69a authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

feat: better MMu code structure

parent 0ca783bc
No related branches found
No related tags found
No related merge requests found
......@@ -75,6 +75,7 @@ fn main() {
let mut game_boy = GameBoy::new();
game_boy.load_boot_default();
game_boy.load_rom("C:/Users/joamag/Desktop/tetris.gb");
let mut counter = 0;
......
use crate::{cpu::Cpu, mmu::Mmu, ppu::{Ppu, FRAME_BUFFER_SIZE}, util::read_file};
use crate::{
cpu::Cpu,
mmu::Mmu,
ppu::{Ppu, FRAME_BUFFER_SIZE},
util::read_file,
};
pub struct GameBoy {
cpu: Cpu,
......@@ -42,6 +47,11 @@ impl GameBoy {
&(self.ppu().frame_buffer)
}
pub fn load_rom(&mut self, path: &str) {
let data = read_file(path);
self.cpu.mmu().write_rom(0x0000, &data);
}
pub fn load_boot(&mut self, path: &str) {
let data = read_file(path);
self.cpu.mmu().write_boot(0x0000, &data);
......
......@@ -32,7 +32,7 @@ impl Mmu {
pub fn read(&mut self, addr: u16) -> u8 {
match addr & 0xf000 {
// BIOS
// BOOT (256 B) + ROM0 (4 KB/16 KB)
0x0000 => {
// in case the boot mode is active and the
// address is withing boot memory reads from it
......@@ -47,21 +47,21 @@ impl Mmu {
}
self.rom[addr as usize]
}
// ROM0
// ROM0 (12 KB/16 KB)
0x1000 | 0x2000 | 0x3000 => self.rom[addr as usize],
// ROM1 (unbanked) (16k)
// ROM1 (unbanked) (16 KB)
0x4000 | 0x5000 | 0x6000 | 0x7000 => self.rom[addr as usize],
// Graphics: VRAM (8k)
// Graphics: VRAM (8 KB)
0x8000 | 0x9000 => {
println!("READING FROM VRAM");
self.ppu.vram[(addr & 0x1fff) as usize]
}
// External RAM (8k)
// External RAM (8 KB)
0xa000 | 0xb000 => {
println!("READING FROM ERAM");
self.eram[(addr & 0x1fff) as usize]
}
// Working RAM (8k)
// Working RAM (8 KB)
0xc000 | 0xd000 => self.ram[(addr & 0x1fff) as usize],
// Working RAM shadow
0xe000 => {
......@@ -97,30 +97,30 @@ impl Mmu {
pub fn write(&mut self, addr: u16, value: u8) {
match addr & 0xf000 {
// BOOT
// BOOT (256 B) + ROM0 (4 KB/16 KB)
0x0000 => {
println!("WRITING to BOOT")
}
// ROM0
// ROM0 (12 KB/16 KB)
0x1000 | 0x2000 | 0x3000 => {
println!("WRITING TO ROM 0");
}
// ROM1 (unbanked) (16k)
// ROM1 (unbanked) (16 KB)
0x4000 | 0x5000 | 0x6000 | 0x7000 => {
println!("WRITING TO ROM 1");
}
// Graphics: VRAM (8k)
// Graphics: VRAM (8 KB)
0x8000 | 0x9000 => {
self.ppu.vram[(addr & 0x1fff) as usize] = value;
if addr < 0x9800 {
self.ppu.update_tile(addr, value);
}
}
// External RAM (8k)
// External RAM (8 KB)
0xa000 | 0xb000 => {
println!("WRITING TO ERAM");
}
// Working RAM (8k)
// Working RAM (8 KB)
0xc000 | 0xd000 => {
println!("WRITING TO RAM");
self.ram[(addr & 0x1fff) as usize] = value;
......@@ -166,4 +166,8 @@ impl Mmu {
pub fn write_ram(&mut self, addr: u16, buffer: &[u8]) {
self.ram[addr as usize..addr as usize + buffer.len()].clone_from_slice(buffer);
}
pub fn write_rom(&mut self, addr: u16, buffer: &[u8]) {
self.rom[addr as usize..addr as usize + buffer.len()].clone_from_slice(buffer);
}
}
......@@ -163,7 +163,7 @@ impl Ppu {
match addr & 0x00ff {
0x0040 => {
self.switch_bg = value & 0x01 == 0x01;
self.bg_map = value & 0x08 == 0x08;
self.bg_map = value & 0x08 == 0x08; // @todo o buf pode estar aqui
self.bg_tile = value & 0x10 == 0x10;
self.switch_lcd = value & 0x80 == 0x80;
}
......@@ -196,12 +196,8 @@ impl Ppu {
for x in 0..8 {
mask = 1 << (7 - x);
self.tiles[tile_index][y][x] =
if self.vram[addr] & mask > 0 {
0x1
} else {
0x0
} | if self.vram[addr + 1] & mask > 0 {
self.tiles[tile_index][y][x] = if self.vram[addr] & mask > 0 { 0x1 } else { 0x0 }
| if self.vram[addr + 1] & mask > 0 {
0x2
} else {
0x0
......@@ -217,6 +213,7 @@ impl Ppu {
// shifted by 3 meaning as the tiles are 8x8
let mut line_offset: usize = (self.scx >> 3) as usize;
// calculates both the current Y and X positions within the tiles
let y = ((self.scy + self.line) & 0x07) as usize;
let mut x = (self.scx & 0x07) as usize;
......@@ -233,6 +230,23 @@ impl Ppu {
let mut frame_offset = self.line as usize * DISPLAY_WIDTH * RGB_SIZE;
for _index in 0..DISPLAY_WIDTH {
// obtains the current pixel data from the tile and
// re-maps it according to the current palette
let pixel = self.tiles[tile_index][y][x];
let color = self.palette[pixel as usize];
// set the color pixel in the frame buffer
self.frame_buffer[frame_offset] = color[0];
self.frame_buffer[frame_offset + 1] = color[1];
self.frame_buffer[frame_offset + 2] = color[2];
// increments the offset of the frame buffer by the
// size of an RGB pixel (which is 3 bytes)
frame_offset += RGB_SIZE;
// increments the current tile X position in drawing
x += 1;
// in case the end of tile width has been reached then
// a new tile must be retrieved for plotting
if x == 8 {
......@@ -251,21 +265,6 @@ impl Ppu {
tile_index += 256;
}
}
// obtains the current pixel data from the tile and
// re-maps it according to the current palette
let pixel = self.tiles[tile_index][y][x];
let color = self.palette[pixel as usize];
// set the color pixel in the frame buffer
self.frame_buffer[frame_offset] = color[0];
self.frame_buffer[frame_offset + 1] = color[1];
self.frame_buffer[frame_offset + 2] = color[2];
frame_offset += RGB_SIZE;
// increments the current tile X position in drawing
x += 1;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment