chore: stub vram, start work on ppu, fix set_register bug
This commit is contained in:
parent
2a234f4d14
commit
677a584ba7
66
src/bus.rs
66
src/bus.rs
|
@ -2,8 +2,9 @@ use super::cartridge::Cartridge;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Bus {
|
pub struct Bus {
|
||||||
boot: Option<[u8; 256]>,
|
boot: Option<[u8; 256]>, // Boot ROM is 256b long
|
||||||
cartridge: Option<Cartridge>,
|
cartridge: Option<Cartridge>,
|
||||||
|
vram: [u8; 8192], // 8KB of VRAM
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Bus {
|
impl Default for Bus {
|
||||||
|
@ -11,6 +12,7 @@ impl Default for Bus {
|
||||||
Self {
|
Self {
|
||||||
boot: Some(include_bytes!("../bin/DMG_ROM.bin").to_owned()),
|
boot: Some(include_bytes!("../bin/DMG_ROM.bin").to_owned()),
|
||||||
cartridge: None,
|
cartridge: None,
|
||||||
|
vram: [0; 8192],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +25,7 @@ impl Bus {
|
||||||
pub fn without_boot() -> Self {
|
pub fn without_boot() -> Self {
|
||||||
Self {
|
Self {
|
||||||
boot: None,
|
boot: None,
|
||||||
cartridge: None,
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +56,7 @@ impl Bus {
|
||||||
},
|
},
|
||||||
0x8000..=0x9FFF => {
|
0x8000..=0x9FFF => {
|
||||||
// 8KB Video RAM
|
// 8KB Video RAM
|
||||||
unimplemented!("Unable to read {:#06X} in Video RAM", addr);
|
self.vram[(addr - 0x8000) as usize]
|
||||||
}
|
}
|
||||||
0xA000..=0xBFFF => {
|
0xA000..=0xBFFF => {
|
||||||
// 8KB External RAM
|
// 8KB External RAM
|
||||||
|
@ -87,13 +89,62 @@ impl Bus {
|
||||||
}
|
}
|
||||||
0xFFFF => {
|
0xFFFF => {
|
||||||
// Interupts Enable Register
|
// Interupts Enable Register
|
||||||
unimplemented!("Unable to read Interrupt Enable Register {:#06X} ", addr);
|
unimplemented!("Unable to read IE Register {:#06X} ", addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
unimplemented!("Can't write {:#04x} to {:#06X}", byte, addr)
|
match addr {
|
||||||
|
0x0000..=0x3FFF => {
|
||||||
|
// 16KB ROM bank 00
|
||||||
|
panic!("Tried to write to {:#06X} in ROM Bank 00", addr);
|
||||||
|
}
|
||||||
|
0x4000..=0x7FFF => {
|
||||||
|
// 16KB ROM Bank 01 -> NN (switchable via MB)
|
||||||
|
panic!("Tried to write to {:#06X} in ROM Bank 01 -> NN", addr);
|
||||||
|
}
|
||||||
|
0x8000..=0x9FFF => {
|
||||||
|
// 8KB Video RAM
|
||||||
|
self.vram[(addr - 0x8000) as usize] = byte;
|
||||||
|
}
|
||||||
|
0xA000..=0xBFFF => {
|
||||||
|
// 8KB External RAM
|
||||||
|
unimplemented!("Unable to write to {:#06X} in Extermal RAM", addr);
|
||||||
|
}
|
||||||
|
0xC000..=0xCFFF => {
|
||||||
|
// 4KB Work RAM Bank 0
|
||||||
|
unimplemented!("Unable to write to {:#06X} in Work RAM Bank 0", addr);
|
||||||
|
}
|
||||||
|
0xD000..=0xDFFF => {
|
||||||
|
// 4KB Work RAM Bank 1 -> N
|
||||||
|
unimplemented!("Unable to write to {:#06X} in Work RAM Bank N", addr);
|
||||||
|
}
|
||||||
|
0xE000..=0xFDFF => {
|
||||||
|
// Mirror of 0xC000 to 0xDDFF
|
||||||
|
unimplemented!("Unable to write to {:#06X} in Restricted Mirror", addr);
|
||||||
|
}
|
||||||
|
0xFE00..=0xFE9F => {
|
||||||
|
// Sprite Attrbute Table
|
||||||
|
unimplemented!(
|
||||||
|
"Unable to write to {:#06X} in the Sprite Attribute Table",
|
||||||
|
addr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
0xFEA0..=0xFEFF => unimplemented!("{:#06X} is not allowed to be used", addr),
|
||||||
|
0xFF00..=0xFF7F => {
|
||||||
|
// IO Registers
|
||||||
|
unimplemented!("Unable to write to {:#06X} in I/O Registers", addr);
|
||||||
|
}
|
||||||
|
0xFF80..=0xFFFE => {
|
||||||
|
// High RAM
|
||||||
|
unimplemented!("Unable to write to {:#06X} in High RAM", addr);
|
||||||
|
}
|
||||||
|
0xFFFF => {
|
||||||
|
// Interupts Enable Register
|
||||||
|
unimplemented!("Unable to write to IE Register {:#06X} ", addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word(&self, addr: u16) -> u16 {
|
pub fn read_word(&self, addr: u16) -> u16 {
|
||||||
|
@ -117,7 +168,8 @@ impl Bus {
|
||||||
},
|
},
|
||||||
0x8000..=0x9FFF => {
|
0x8000..=0x9FFF => {
|
||||||
// 8KB Video RAM
|
// 8KB Video RAM
|
||||||
unimplemented!("Unable to read {:#06X} in Video RAM", addr);
|
(self.vram[((addr + 1) - 0x8000) as usize] as u16) << 8
|
||||||
|
| self.vram[(addr - 0x8000) as usize] as u16
|
||||||
}
|
}
|
||||||
0xA000..=0xBFFF => {
|
0xA000..=0xBFFF => {
|
||||||
// 8KB External RAM
|
// 8KB External RAM
|
||||||
|
@ -150,7 +202,7 @@ impl Bus {
|
||||||
}
|
}
|
||||||
0xFFFF => {
|
0xFFFF => {
|
||||||
// Interupts Enable Register
|
// Interupts Enable Register
|
||||||
unimplemented!("Unable to read Interrupt Enable Register {:#06X} ", addr);
|
unimplemented!("Unable to read IE Register {:#06X} ", addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
pub fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
self.bus.write_byte(addr, byte)
|
self.bus.write_byte(addr, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_word(&mut self, addr: u16) -> u16 {
|
pub fn read_word(&mut self, addr: u16) -> u16 {
|
||||||
|
@ -116,7 +116,7 @@ impl Cpu {
|
||||||
Register::E => self.reg.e = value,
|
Register::E => self.reg.e = value,
|
||||||
Register::H => self.reg.h = value,
|
Register::H => self.reg.h = value,
|
||||||
Register::L => self.reg.l = value,
|
Register::L => self.reg.l = value,
|
||||||
Register::Flag => self.reg.a = value,
|
Register::Flag => self.flags = value.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,4 @@ mod bus;
|
||||||
mod cartridge;
|
mod cartridge;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
mod instruction;
|
mod instruction;
|
||||||
|
mod ppu;
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
struct PPU {
|
||||||
|
lcdc: LCDControl,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LCDControl {
|
||||||
|
lcd_enable: bool, // Bit 7
|
||||||
|
window_tile_map_select: bool,
|
||||||
|
window_enable: bool,
|
||||||
|
tile_data_select: bool,
|
||||||
|
bg_tile_map_select: bool,
|
||||||
|
sprite_size: bool,
|
||||||
|
sprite_enable: bool,
|
||||||
|
display_priority: bool, // Bit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for LCDControl {
|
||||||
|
fn from(byte: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
lcd_enable: (byte >> 7) == 0x01,
|
||||||
|
window_tile_map_select: ((byte >> 6) & 0x01) == 0x01,
|
||||||
|
window_enable: ((byte >> 5) & 0x01) == 0x01,
|
||||||
|
tile_data_select: ((byte >> 4) & 0x01) == 0x01,
|
||||||
|
bg_tile_map_select: ((byte >> 3) & 0x01) == 0x01,
|
||||||
|
sprite_size: ((byte >> 2) & 0x01) == 0x01,
|
||||||
|
sprite_enable: ((byte >> 1) & 0x01) == 0x01,
|
||||||
|
display_priority: (byte & 0x01) == 0x01,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LCDControl> for u8 {
|
||||||
|
fn from(lcdc: LCDControl) -> Self {
|
||||||
|
(lcdc.lcd_enable as u8) << 7
|
||||||
|
| (lcdc.window_tile_map_select as u8) << 6
|
||||||
|
| (lcdc.window_enable as u8) << 5
|
||||||
|
| (lcdc.tile_data_select as u8) << 4
|
||||||
|
| (lcdc.bg_tile_map_select as u8) << 3
|
||||||
|
| (lcdc.sprite_size as u8) << 2
|
||||||
|
| (lcdc.sprite_enable as u8) << 1
|
||||||
|
| lcdc.display_priority as u8
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue