feat: emulator now sucessfully runs boot rom
This commit is contained in:
parent
9143286e9c
commit
1da01a318d
|
@ -112,6 +112,7 @@ impl Bus {
|
|||
0xFF0F => self.interrupt.flag.into(),
|
||||
0xFF11 => self.sound.ch1.sound_duty.into(),
|
||||
0xFF12 => self.sound.ch1.vol_envelope.into(),
|
||||
0xFF14 => self.sound.ch1.freq.get_hi(),
|
||||
0xFF24 => self.sound.control.channel.into(),
|
||||
0xFF25 => self.sound.control.select.into(),
|
||||
0xFF26 => self.sound.control.status.into(),
|
||||
|
@ -180,6 +181,8 @@ impl Bus {
|
|||
0xFF0F => self.interrupt.flag = byte.into(),
|
||||
0xFF11 => self.sound.ch1.sound_duty = byte.into(),
|
||||
0xFF12 => self.sound.ch1.vol_envelope = byte.into(),
|
||||
0xFF13 => self.sound.ch1.freq.set_lo(byte),
|
||||
0xFF14 => self.sound.ch1.freq.set_hi(byte),
|
||||
0xFF24 => self.sound.control.channel = byte.into(),
|
||||
0xFF25 => self.sound.control.select = byte.into(),
|
||||
0xFF26 => self.sound.control.status = byte.into(), // FIXME: Should we control which bytes are written to here?
|
||||
|
@ -189,6 +192,12 @@ impl Bus {
|
|||
0xFF43 => self.ppu.pos.scroll_x = byte,
|
||||
0xFF44 => self.ppu.pos.line_y = byte,
|
||||
0xFF47 => self.ppu.monochrome.bg_palette = byte.into(),
|
||||
0xFF50 => {
|
||||
// Disable Boot ROM
|
||||
if byte != 0 {
|
||||
self.boot = None;
|
||||
}
|
||||
}
|
||||
_ => unimplemented!("Unable to write to {:#06X} in I/O Registers", addr),
|
||||
};
|
||||
}
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -54,17 +54,6 @@ fn main() -> Result<()> {
|
|||
// window.request_redraw();
|
||||
}
|
||||
});
|
||||
|
||||
// loop {
|
||||
// let pc = game_boy.register_pair(gb::cpu::RegisterPair::PC);
|
||||
// let opcode = game_boy.fetch();
|
||||
// let instruction = game_boy.decode(opcode);
|
||||
|
||||
// let _cycles = game_boy.execute(instruction);
|
||||
|
||||
// let ppu = game_boy.get_ppu();
|
||||
// ppu.step();
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn create_window(event_loop: &EventLoop<()>) -> Result<Window> {
|
||||
|
|
55
src/ppu.rs
55
src/ppu.rs
|
@ -1,5 +1,7 @@
|
|||
use crate::instruction::Cycles;
|
||||
|
||||
const GB_WIDTH: usize = 160;
|
||||
const GB_HEIGHT: usize = 144;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PPU {
|
||||
pub lcd_control: LCDControl,
|
||||
|
@ -7,32 +9,60 @@ pub struct PPU {
|
|||
pub pos: ScreenPosition,
|
||||
pub vram: Box<[u8]>,
|
||||
pub oam: Box<[u8]>,
|
||||
frame_buf: [u8; GB_WIDTH * GB_HEIGHT * 4],
|
||||
pub stat: LCDStatus,
|
||||
cycles: Cycles,
|
||||
mode: PPUMode,
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
impl PPU {
|
||||
pub fn step(&mut self, cycles: Cycles) {
|
||||
self.cycles += cycles;
|
||||
|
||||
// let smth: u32 = self.cycles.into();
|
||||
// println!("Mode: {:?} | Cycles: {}", self.mode, smth);
|
||||
|
||||
match self.mode {
|
||||
PPUMode::OAMScan => {
|
||||
Mode::OAMScan => {
|
||||
if self.cycles >= 80.into() {
|
||||
self.cycles = cycles % 80;
|
||||
self.cycles %= 80;
|
||||
self.mode = Mode::Draw;
|
||||
}
|
||||
}
|
||||
Mode::Draw => {
|
||||
if self.cycles >= 172.into() {
|
||||
// 172 -> 129 Cycles
|
||||
// self.cycles %= 172;
|
||||
self.mode = Mode::HBlank;
|
||||
}
|
||||
}
|
||||
Mode::HBlank => {
|
||||
// The 80 comes from the 80 cycles we made disappear in OAMScan above.
|
||||
if self.cycles >= (456 - 80).into() {
|
||||
self.cycles %= 456 - 80;
|
||||
self.pos.line_y += 1;
|
||||
|
||||
if self.pos.line_y >= 144 {
|
||||
self.mode = Mode::VBlank;
|
||||
}
|
||||
}
|
||||
}
|
||||
Mode::VBlank => {
|
||||
if self.cycles >= 456.into() {
|
||||
self.cycles %= 456;
|
||||
self.pos.line_y += 1;
|
||||
|
||||
if self.pos.line_y == 154 {
|
||||
self.mode = Mode::OAMScan;
|
||||
self.pos.line_y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
PPUMode::Draw => {}
|
||||
PPUMode::HBlank => {}
|
||||
PPUMode::VBlank => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&self, frame: &mut [u8]) {
|
||||
for (_i, pixel) in frame.chunks_exact_mut(4).enumerate() {
|
||||
let rgba: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];
|
||||
pixel.copy_from_slice(&rgba);
|
||||
}
|
||||
frame.copy_from_slice(&self.frame_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,13 +76,14 @@ impl Default for PPU {
|
|||
vram: vec![0; 8192].into_boxed_slice(),
|
||||
oam: vec![0; 160].into_boxed_slice(),
|
||||
cycles: 0.into(),
|
||||
mode: PPUMode::OAMScan,
|
||||
frame_buf: [0; GB_WIDTH * GB_HEIGHT * 4],
|
||||
mode: Mode::OAMScan,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum PPUMode {
|
||||
enum Mode {
|
||||
OAMScan,
|
||||
Draw,
|
||||
HBlank,
|
||||
|
|
67
src/sound.rs
67
src/sound.rs
|
@ -19,6 +19,72 @@ pub struct SoundControl {
|
|||
pub status: SoundStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct Frequency {
|
||||
initial: bool,
|
||||
freq_type: FrequencyType,
|
||||
lo: u8, // Bottom 8 bits
|
||||
hi: u8, // Top 3 bits (11 bits total)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum FrequencyType {
|
||||
Counter,
|
||||
Consequtive,
|
||||
}
|
||||
|
||||
impl From<u8> for FrequencyType {
|
||||
fn from(byte: u8) -> Self {
|
||||
match byte {
|
||||
0b00 => Self::Counter,
|
||||
0b01 => Self::Consequtive,
|
||||
_ => unreachable!("{} is not a valid number for FreuquencyType"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FrequencyType> for u8 {
|
||||
fn from(freq_type: FrequencyType) -> Self {
|
||||
match freq_type {
|
||||
FrequencyType::Counter => 0b00,
|
||||
FrequencyType::Consequtive => 0b01,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FrequencyType {
|
||||
fn default() -> Self {
|
||||
Self::Counter
|
||||
}
|
||||
}
|
||||
|
||||
impl Frequency {
|
||||
fn get_11bit_freq(&self) -> u16 {
|
||||
(self.hi as u16) << 8 | self.lo as u16
|
||||
}
|
||||
|
||||
pub fn set_lo(&mut self, byte: u8) {
|
||||
self.lo = byte;
|
||||
}
|
||||
|
||||
pub fn get_lo(&self) -> u8 {
|
||||
self.lo
|
||||
}
|
||||
|
||||
pub fn set_hi(&mut self, byte: u8) {
|
||||
*self = Self {
|
||||
initial: byte >> 7 == 0x01,
|
||||
freq_type: ((byte >> 6) & 0x01).into(),
|
||||
lo: self.lo,
|
||||
hi: byte & 0x07,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_hi(&self) -> u8 {
|
||||
(self.initial as u8) << 7 | (self.freq_type as u8) << 6 | self.hi
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct SoundStatus {
|
||||
pub all_enabled: bool, // You can actually write to this one.
|
||||
|
@ -54,6 +120,7 @@ impl From<SoundStatus> for u8 {
|
|||
pub struct Channel1 {
|
||||
pub sound_duty: SoundDuty,
|
||||
pub vol_envelope: VolumeEnvelope,
|
||||
pub freq: Frequency,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
|
|
Loading…
Reference in New Issue