WIP commit
This commit is contained in:
parent
92855bf6b9
commit
67e2d7140b
13
src/cpu.rs
13
src/cpu.rs
@ -912,7 +912,10 @@ impl CPU {
|
||||
// cycle.
|
||||
let expected_cycles = start.elapsed().as_nanos() / (238 / 2);
|
||||
while cycles_executed < expected_cycles {
|
||||
if let CpuTickResult::Continue { cycles_executed: x, .. } = self.run_instruction() {
|
||||
if let CpuTickResult::Continue {
|
||||
cycles_executed: x, ..
|
||||
} = self.run_instruction()
|
||||
{
|
||||
cycles_executed += x as u128;
|
||||
} else {
|
||||
return;
|
||||
@ -1757,8 +1760,12 @@ impl CPU {
|
||||
}
|
||||
|
||||
if self.interconnect.tick(cycles) == TickResult::Shutdown {
|
||||
return CpuTickResult::Shutdown { cycles_executed: cycles as usize }
|
||||
return CpuTickResult::Shutdown {
|
||||
cycles_executed: cycles as usize,
|
||||
};
|
||||
}
|
||||
CpuTickResult::Continue {
|
||||
cycles_executed: cycles as usize,
|
||||
}
|
||||
CpuTickResult::Continue { cycles_executed: cycles as usize }
|
||||
}
|
||||
}
|
||||
|
||||
163
src/display.rs
163
src/display.rs
@ -60,6 +60,37 @@ const MONOCHROME_PALETTE: &'static [[u8; 3]; 4] = &[
|
||||
[50, 50, 50],
|
||||
];
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct CgbPalette([u8; 8]);
|
||||
impl CgbPalette {
|
||||
fn get_color(&self, n: usize) -> sdl2::pixels::Color {
|
||||
let v = ((self.0[2 * n + 1] as u16) << 8) | (self.0[2 * n] as u16);
|
||||
let r = (v & 0b1_1111) as u8;
|
||||
let g = ((v >> 5) & 0b1_1111) as u8;
|
||||
let b = ((v >> 10) & 0b1_1111) as u8;
|
||||
sdl2::pixels::Color::RGB(r << 3, g << 3, b << 3)
|
||||
}
|
||||
}
|
||||
|
||||
struct BgMapAttributes(u8);
|
||||
impl BgMapAttributes {
|
||||
fn palette_number(&self) -> usize {
|
||||
(self.0 & 0b111) as usize
|
||||
}
|
||||
|
||||
fn vram_bank_number(&self) -> usize {
|
||||
(((self.0 >> 3) & 1) as usize)
|
||||
}
|
||||
|
||||
fn horizontal_flip(&self) -> bool {
|
||||
(self.0 >> 5) != 0
|
||||
}
|
||||
|
||||
fn vertical_flip(&self) -> bool {
|
||||
(self.0 >> 6) != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum PixelOrigin {
|
||||
Empty,
|
||||
@ -180,7 +211,7 @@ pub struct Display {
|
||||
// GBC:
|
||||
background_palette_autoinc: bool,
|
||||
background_palette_index: u8,
|
||||
background_palette_c: [u8; 256], // 0x40],
|
||||
background_palette_cgb: [CgbPalette; 0x40 / 8],
|
||||
|
||||
object_palette_index: u8,
|
||||
}
|
||||
@ -228,7 +259,7 @@ impl Display {
|
||||
|
||||
background_palette_autoinc: false,
|
||||
background_palette_index: 0,
|
||||
background_palette_c: [0u8; 256], // 0x40],
|
||||
background_palette_cgb: [CgbPalette([0u8; 2 * 4]); 0x40 / 8],
|
||||
object_palette_index: 0,
|
||||
}
|
||||
}
|
||||
@ -321,13 +352,17 @@ impl Display {
|
||||
0xFF49 => self.object_palette[1] = val,
|
||||
// GBC
|
||||
0xFF68 => {
|
||||
self.background_palette_index = val;
|
||||
self.background_palette_index = val & 0b0111_1111;
|
||||
self.background_palette_autoinc = (val >> 7) != 0;
|
||||
}
|
||||
0xFF69 => {
|
||||
self.background_palette_c[self.background_palette_index as usize] = val;
|
||||
let idx = self.background_palette_index as usize;
|
||||
self.background_palette_cgb[idx / 8].0[idx % 8] = val;
|
||||
if self.background_palette_autoinc {
|
||||
self.background_palette_index += 1;
|
||||
if self.background_palette_index >= 8 {
|
||||
self.background_palette_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
0xFF6A => {
|
||||
@ -380,6 +415,26 @@ impl Display {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_background_attribute(
|
||||
&self,
|
||||
//tile_index_x: usize,
|
||||
//tile_index_y: usize,
|
||||
vram_offset: usize,
|
||||
) -> BgMapAttributes {
|
||||
/*
|
||||
let background_map = if self.control & CTRL_BG_TILE_MAP_SELECT != 0 {
|
||||
0x1C00
|
||||
} else {
|
||||
0x1800
|
||||
};
|
||||
|
||||
let vram_offset: usize =
|
||||
background_map + ((tile_index_y as usize) * 32) + tile_index_x as usize;
|
||||
*/
|
||||
|
||||
BgMapAttributes(self.vram1[vram_offset])
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tick(&mut self, ticks: u16) {
|
||||
self.status &= 0xFC;
|
||||
@ -594,18 +649,8 @@ impl Display {
|
||||
);
|
||||
*/
|
||||
let c = ((b1 as u8) * 2 + b2 as u8) as usize;
|
||||
let a = self.object_palette[sprite.palette() as usize * 8 + c * 2];
|
||||
let b = self.object_palette[sprite.palette() as usize * 8 + c * 2 + 1];
|
||||
let ab = ((b as u16) << 8) | a as u16;
|
||||
let r = (ab & 0b11111) as u8;
|
||||
let g = ((ab >> 5) & 0b11111) as u8;
|
||||
let b = ((ab >> 10) & 0b11111) as u8;
|
||||
self.set_pixel(
|
||||
x.wrapping_add(x_o),
|
||||
render_y,
|
||||
sdl2::pixels::Color::RGB(r, g, b),
|
||||
PixelOrigin::Sprite,
|
||||
);
|
||||
let c = self.background_palette_cgb[sprite.palette() as usize].get_color(c);
|
||||
self.set_pixel(x.wrapping_add(x_o), render_y, c, PixelOrigin::Sprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -681,9 +726,9 @@ impl Display {
|
||||
let render_abs_y = map_offset_y.wrapping_add(render_y);
|
||||
|
||||
let tile_index_x: u8 = render_abs_x >> 3;
|
||||
let tile_offset_x: u8 = render_abs_x & 7;
|
||||
|
||||
let tile_index_y: u8 = render_abs_y >> 3;
|
||||
|
||||
let tile_offset_x: u8 = render_abs_x & 7;
|
||||
let tile_offset_y: u8 = render_abs_y & 7;
|
||||
|
||||
let vram_offset: usize =
|
||||
@ -692,25 +737,53 @@ impl Display {
|
||||
// Obtain tile ID in this area
|
||||
let tile_id = self.vram0[vram_offset];
|
||||
|
||||
// Obtain tile information
|
||||
let tile_base_addr: usize = self.get_bg_window_tile_addr(tile_id);
|
||||
let addr = tile_base_addr + (tile_offset_y as usize) * 2;
|
||||
|
||||
// GBC stuff
|
||||
let vram = if (self.vram1[vram_offset] >> 3) == 1 {
|
||||
let bg_attribs = self.get_background_attribute(vram_offset);
|
||||
// Get BG map attributes
|
||||
let vram = if bg_attribs.vram_bank_number() == 0 {
|
||||
&*self.vram0
|
||||
} else {
|
||||
&*self.vram1
|
||||
};
|
||||
|
||||
// TODO: Priority
|
||||
let tile_offset_y = if bg_attribs.vertical_flip() {
|
||||
7 ^ tile_offset_y
|
||||
} else {
|
||||
tile_offset_y
|
||||
};
|
||||
|
||||
// Obtain tile information
|
||||
let tile_base_addr: usize = self.get_bg_window_tile_addr(tile_id);
|
||||
// TODO: Colored background
|
||||
let addr = tile_base_addr + (tile_offset_y as usize) * 2;
|
||||
|
||||
let tile_line_1 = vram[addr];
|
||||
let tile_line_2 = vram[addr + 1];
|
||||
|
||||
// Get the correct bit
|
||||
let b1: bool = (tile_line_1 & 1 << (7 - tile_offset_x)) != 0;
|
||||
let b2: bool = (tile_line_2 & 1 << (7 - tile_offset_x)) != 0;
|
||||
let b1 = if bg_attribs.horizontal_flip() {
|
||||
7 ^ (1 << (7 - tile_offset_x))
|
||||
} else {
|
||||
1 << (7 - tile_offset_x)
|
||||
};
|
||||
let b2 = if bg_attribs.horizontal_flip() {
|
||||
7 ^ (1 << (7 - tile_offset_x))
|
||||
} else {
|
||||
1 << (7 - tile_offset_x)
|
||||
};
|
||||
let b1: bool = (tile_line_1 & b1) != 0;
|
||||
let b2: bool = (tile_line_2 & b2) != 0;
|
||||
|
||||
// Lookup the color
|
||||
let c = ((b1 as u8) * 2 + b2 as u8) as usize;
|
||||
let origin = match c {
|
||||
0 => PixelOrigin::Empty, // Hack so that objects will be in front of it.
|
||||
_ => PixelOrigin::Background,
|
||||
};
|
||||
let c = self.background_palette_cgb[bg_attribs.palette_number()].get_color(c);
|
||||
self.set_pixel(render_x, render_y, c, origin);
|
||||
/*
|
||||
let c = (b1 as u8) * 2 + b2 as u8;
|
||||
let lookup: [u8; 4] = [
|
||||
self.background_palette & 3,
|
||||
@ -730,6 +803,7 @@ impl Display {
|
||||
sdl2::pixels::Color::RGB(entry[0], entry[1], entry[2]),
|
||||
origin,
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -744,8 +818,8 @@ impl Display {
|
||||
let render_x = r_x.wrapping_add(rx);
|
||||
// Absolute render coordinates
|
||||
let tile_index_x: u8 = render_x >> 3;
|
||||
let tile_offset_x: u8 = render_x & 7;
|
||||
let tile_index_y: u8 = ry >> 3;
|
||||
let tile_offset_x: u8 = render_x & 7;
|
||||
let tile_offset_y: u8 = ry & 7;
|
||||
|
||||
let vram_offset: usize =
|
||||
@ -754,17 +828,49 @@ impl Display {
|
||||
// Obtain tile ID in this area
|
||||
let tile_id = self.vram0[vram_offset];
|
||||
|
||||
let bg_attribs = self.get_background_attribute(
|
||||
//tile_index_x as usize, tile_index_y as usize
|
||||
vram_offset,
|
||||
);
|
||||
|
||||
// Get BG map attributes
|
||||
let vram = if bg_attribs.vram_bank_number() == 0 {
|
||||
&*self.vram0
|
||||
} else {
|
||||
&*self.vram1
|
||||
};
|
||||
|
||||
// TODO: Priority
|
||||
let tile_offset_x = if bg_attribs.vertical_flip() {
|
||||
7 ^ tile_offset_x
|
||||
} else {
|
||||
tile_offset_x
|
||||
};
|
||||
let tile_offset_y = if bg_attribs.horizontal_flip() {
|
||||
7 ^ tile_offset_y
|
||||
} else {
|
||||
tile_offset_y
|
||||
};
|
||||
|
||||
// Obtain tile information
|
||||
let tile_base_addr: usize = self.get_bg_window_tile_addr(tile_id);
|
||||
let tile_addr = tile_base_addr + (tile_offset_y as usize) * 2;
|
||||
let tile_line_1 = self.vram0[tile_addr];
|
||||
let tile_line_2 = self.vram0[tile_addr + 1];
|
||||
let tile_line_1 = vram[tile_addr];
|
||||
let tile_line_2 = vram[tile_addr + 1];
|
||||
|
||||
// Get the correct bit
|
||||
let b1: bool = (tile_line_1 & 1 << (7 - tile_offset_x)) > 0;
|
||||
let b2: bool = (tile_line_2 & 1 << (7 - tile_offset_x)) > 0;
|
||||
|
||||
let c = (b1 as u8) * 2 + b2 as u8;
|
||||
let origin = match c {
|
||||
0 => PixelOrigin::Empty, // Hack so that objects will be in front of it.
|
||||
_ => PixelOrigin::Window,
|
||||
};
|
||||
let c = self.background_palette_cgb[bg_attribs.palette_number()]
|
||||
.get_color(c as usize);
|
||||
self.set_pixel(render_x, render_y, c, origin);
|
||||
/*
|
||||
let lookup: [u8; 4] = [
|
||||
self.background_palette & 3,
|
||||
(self.background_palette >> 2) & 3,
|
||||
@ -784,6 +890,7 @@ impl Display {
|
||||
sdl2::pixels::Color::RGB(entry[0], entry[1], entry[2]),
|
||||
origin,
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user