Compare commits

..

2 Commits

Author SHA1 Message Date
2fc82faef6 Add resources to readme 2021-11-09 19:52:14 -05:00
4bab81cbfa Fix MBC1 bug. Mario Land is now playable 2021-11-09 19:42:21 -05:00
3 changed files with 26 additions and 13 deletions

View File

@ -1,7 +1,7 @@
# RMG-001 # RMG-001
Rust Matrix Game - 001: Yet Another Rust Gameboy Emulator. Rust Matrix Game - 001: Yet Another Rust Gameboy Emulator.
This is just a fun project I'm making for learning and practice purposes. If you want a fully-featured Gameboy emulator, this is not probably the best one :P This is just a fun project I'm making for learning and practice purposes. If you want a fully-featured Gameboy emulator, this is probably not the best one :P
Any help or suggestion is welcome! Any help or suggestion is welcome!
@ -27,3 +27,12 @@ Any help or suggestion is welcome!
- [ ] Gameboy Color compatibility - [ ] Gameboy Color compatibility
- [ ] Sound - [ ] Sound
- [ ] Many code refactors and optimizations are needed - [ ] Many code refactors and optimizations are needed
# Resources
This project would have been completely impossible without all the documentation and help that exists online for the Nintendo Gameboy:
- The EmuDev community
- Pandocs: https://gbdev.io/pandocs/
- Gameboy emulation guide: https://hacktixme.ga/GBEDG/
- CPU opcodes table: https://izik1.github.io/gbops/
- Opcodes behaviour: https://rgbds.gbdev.io/docs/v0.5.1/gbz80.7
- The Ultimate Gameboy talk: https://youtu.be/HyzD8pNlpwI

View File

@ -57,7 +57,7 @@ pub struct Bus {
impl Bus { impl Bus {
pub fn new() -> Self { pub fn new() -> Self {
let game_rom = match ROM::load_file("ignore/dmg-acid2.gb".to_string()) { let game_rom = match ROM::load_file("ignore/metroid-2.gb".to_string()) {
// let game_rom = match ROM::load_file("ignore/mooneye/emulator-only/mbc1/bits_bank1.gb".to_string()) { // let game_rom = match ROM::load_file("ignore/mooneye/emulator-only/mbc1/bits_bank1.gb".to_string()) {
// let game_rom = match ROM::load_file("roms/cpu_instrs.gb".to_string()) { // let game_rom = match ROM::load_file("roms/cpu_instrs.gb".to_string()) {
// let game_rom = match ROM::load_file("roms/cpu_instrs_individual/01-special.gb".to_string()) { // let game_rom = match ROM::load_file("roms/cpu_instrs_individual/01-special.gb".to_string()) {

View File

@ -2,6 +2,7 @@ use std::fs::File;
use std::io::Read; use std::io::Read;
use crate::bus::{ use crate::bus::{
BANK_ZERO,
BANK_SWITCHABLE, BANK_SWITCHABLE,
EXTERNAL_RAM, EXTERNAL_RAM,
}; };
@ -137,8 +138,8 @@ impl ROMInfo {
} }
} }
pub fn ram_size(&self) -> u16 { pub fn ram_size(&self) -> usize {
0x4000 * self.ram_banks as u16 0x4000 * self.ram_banks as usize
} }
} }
@ -177,8 +178,11 @@ impl ROM {
pub fn read(&self, address: u16) -> u8 { pub fn read(&self, address: u16) -> u8 {
match self.info.mbc { match self.info.mbc {
MBC::MBC1 => { MBC::MBC1 => {
if BANK_SWITCHABLE.in_range(address) { if BANK_ZERO.in_range(address) {
return self.data[(address + (BANK_SWITCHABLE.begin() * (self.rom_bank - 1))) as usize]; return self.data[address as usize];
} else if BANK_SWITCHABLE.in_range(address) {
return self.data[((self.rom_bank as usize * 0x4000) + (address as usize & 0x3FFF)) as usize];
// return self.data[(address + (BANK_SWITCHABLE.begin() * (self.rom_bank - 1))) as usize];
} else if EXTERNAL_RAM.in_range(address) { } else if EXTERNAL_RAM.in_range(address) {
println!("RAM read"); println!("RAM read");
if !self.info.has_ram { if !self.info.has_ram {
@ -196,20 +200,20 @@ impl ROM {
match self.info.mbc { match self.info.mbc {
MBC::MBC1 => { MBC::MBC1 => {
if address >= 0x0000 || address <= 0x1FFF { // RAM enable register if address >= 0x0000 && address <= 0x1FFF { // RAM enable register
self.ram_enable = match data & 0x0F { self.ram_enable = match data & 0x0F {
0x0A => true, 0x0A => true,
_ => false, _ => false,
}; };
return; return;
} else if address >= 0x2000 || address <= 0x3FFF { // ROM bank number register } else if address >= 0x2000 && address <= 0x3FFF { // ROM bank number register
println!("Switch bank to {:02X}", data); // println!("Switch bank to {:02X}", data);
self.switch_rom_bank(data as u16 & 0b00011111); self.switch_rom_bank(data as u16 & 0b00011111);
} else if address >= 0x4000 || address <= 0x5FFF { // ROM and RAM bank number register } else if address >= 0x4000 && address <= 0x5FFF { // ROM and RAM bank number register
println!("RAM bank {:02X}", data); // println!("RAM bank {:02X}", data);
self.ram_bank = data & 0b11; self.ram_bank = data & 0b11;
} else if address >= 0x6000 || address <= 0x7FFF { // Banking mode select } else if address >= 0x6000 && address <= 0x7FFF { // Banking mode select
println!("Change banking mode"); // println!("Change banking mode");
} else if EXTERNAL_RAM.in_range(address) { } else if EXTERNAL_RAM.in_range(address) {
if !self.ram_enable || !self.info.has_ram { if !self.ram_enable || !self.info.has_ram {
return; return;