diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 8 | ||||
-rw-r--r-- | src/mos6502.rs | 4 | ||||
-rw-r--r-- | src/ppu.rs | 121 |
3 files changed, 65 insertions, 68 deletions
diff --git a/src/main.rs b/src/main.rs index 8327d1d..b5c45de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,7 +47,7 @@ impl SDLWindow { fn new() -> Self { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); - let window = video_subsystem.window("rust-sdl2 demo: Video", 256 * PIXEL_SIZE, 240 * PIXEL_SIZE) + let window = video_subsystem.window("RuNES", 256 * PIXEL_SIZE, 240 * PIXEL_SIZE) .position_centered() .opengl() .build() @@ -75,7 +75,7 @@ impl SDLWindow { } } -const PIXEL_SIZE: u32 = 4; +const PIXEL_SIZE: u32 = 2; const COLORS: [u32; 64] = [ 0x666666, 0x002A88, 0x1412A7, 0x3B00A4, 0x5C007E, 0x6E0040, 0x6C0600, 0x561D00, 0x333500, 0x0B4800, 0x005200, 0x004F08, 0x00404D, 0x000000, 0x000000, 0x000000, @@ -95,9 +95,9 @@ fn get_rgb(color: u8) -> Color { impl ppu::Screen for SDLWindow { fn put(&self, x: u8, y: u8, color: u8) { let mut canvas = self.canvas.borrow_mut(); - println!("put {} at {}, {}", color, x, y); + //println!("put {} at {}, {}", color, x, y); canvas.set_draw_color(get_rgb(color)); - canvas.draw_rect(Rect::new((x as u32 * PIXEL_SIZE) as i32, + canvas.fill_rect(Rect::new((x as u32 * PIXEL_SIZE) as i32, (y as u32 * PIXEL_SIZE) as i32, PIXEL_SIZE, PIXEL_SIZE)); } diff --git a/src/mos6502.rs b/src/mos6502.rs index c98b7cc..e960d32 100644 --- a/src/mos6502.rs +++ b/src/mos6502.rs @@ -762,8 +762,8 @@ impl<'a> CPU<'a> { for i in 0..len as u16 { code[i as usize] = self.mem.read(pc + i); } - println!("0x{:04x} {} a:{} x:{} y:{}", - pc, disasm::parse(opcode as u8, &code[1..]), self.a, self.x, self.y); + //println!("0x{:04x} {} a:{} x:{} y:{}", + // pc, disasm::parse(opcode as u8, &code[1..]), self.a, self.x, self.y); /* update opr pointing to operands of current inst */ self.opr = pc.wrapping_add(1); /* update program counter pointing to next inst */ @@ -299,13 +299,9 @@ impl<'a> PPU<'a> { 0 => 8, _ => 16 }; - self.sp_zero_insight = false; for (i, s) in self.oam.iter().enumerate() { let y = s.y as u16; if y <= scanline && scanline < y + h { - if nidx == 0 { - self.sp_zero_insight = true; - } self.oam2[nidx] = i; nidx += 1; if nidx == 8 { @@ -314,17 +310,19 @@ impl<'a> PPU<'a> { } } } - let mut m = 0; - unsafe { - let oam_raw = transmute::<&[Sprite; 64], &[[u8; 4]; 64]>(&self.oam); - while n < 64 { - let y = oam_raw[n][m] as u16; - if y <= scanline && scanline < y + h { - self.ppustatus |= PPU::FLAG_OVERFLOW; /* set overflow */ - } else { - m = (m + 1) & 3; /* emulates hardware bug */ + if nidx == 8 { + let mut m = 0; + unsafe { + let oam_raw = transmute::<&[Sprite; 64], &[[u8; 4]; 64]>(&self.oam); + while n < 64 { + let y = oam_raw[n][m] as u16; + if y <= scanline && scanline < y + h { + self.ppustatus |= PPU::FLAG_OVERFLOW; /* set overflow */ + } else { + m = (m + 1) & 3; /* emulates hardware bug */ + } + n += 1; } - n += 1; } } } @@ -352,7 +350,7 @@ impl<'a> PPU<'a> { ((self.ppuctl as u16 & 0x08) << 9, s.tile, y) }, _ => { - assert!(false); + //assert!(false); let y = if vflip {15 - y0 as u8} else {y0 as u8}; ((s.tile as u16 & 1) << 12, (s.tile & !1u8) | (y >> 3), @@ -403,7 +401,8 @@ impl<'a> PPU<'a> { match self.get_sp_pidx(i) { 0x0 => (), pidx => { - if self.sp_zero_insight && bg_pidx != 0 && i == 0 { + if bg_pidx != 0 && self.sp_idx[i] == 0 { + assert!(i == 0); self.ppustatus |= PPU::FLAG_SPRITE_ZERO; /* set sprite zero hit */ } sp_pidx = pidx; @@ -486,50 +485,48 @@ impl<'a> PPU<'a> { let visible = self.scanline < 240; let pre_render = self.scanline == 261; self.rendering = pre_render || visible; - if self.rendering && (self.get_show_bg() || self.get_show_sp()) { - if pre_render { - if cycle == 1 { - /* clear vblank, sprite zero hit & overflow */ - self.ppustatus &= !(PPU::FLAG_VBLANK | - PPU::FLAG_SPRITE_ZERO | PPU::FLAG_OVERFLOW); - } else if 279 < cycle && cycle < 305 { - self.reset_y(); - } - } - let shifting = 0 < cycle && cycle < 257; /* 1..256 */ - let fetch = shifting || (320 < cycle && cycle < 337); - if fetch { /* 1..256 and 321..336 */ - match cycle & 0x7 { - 1 => { - if shifting { - self.load_bgtile(); + if pre_render && cycle == 1 { + /* clear vblank, sprite zero hit & overflow */ + self.ppustatus &= !(PPU::FLAG_VBLANK | + PPU::FLAG_SPRITE_ZERO | PPU::FLAG_OVERFLOW); + + } else if self.rendering && (self.get_show_bg() || self.get_show_sp()) { + if pre_render && 279 < cycle && cycle < 305 { + self.reset_y(); + } else { + let shifting = 0 < cycle && cycle < 257; /* 1..256 */ + let fetch = shifting || (320 < cycle && cycle < 337); + if fetch { /* 1..256 and 321..336 */ + match cycle & 0x7 { + 1 => { + if shifting { + self.load_bgtile(); + } + self.fetch_nametable_byte(); + }, + 3 => self.fetch_attrtable_byte(), + 5 => self.fetch_low_bgtile_byte(), + 7 => self.fetch_high_bgtile_byte(), + 0 => self.wrapping_inc_cx(), + _ => () + } + if visible { + match cycle { + 1 => self.clear_sprite(), /* clear secondary OAM */ + 65 => self.eval_sprite(), /* sprite evaluation */ + _ => () } - self.fetch_nametable_byte(); - }, - 3 => self.fetch_attrtable_byte(), - 5 => self.fetch_low_bgtile_byte(), - 7 => self.fetch_high_bgtile_byte(), - 0 => self.wrapping_inc_cx(), - _ => () - } - if visible { + } match cycle { - 1 => self.clear_sprite(), /* clear secondary OAM */ - 65 => self.eval_sprite(), /* sprite evaluation */ + 256 => self.wrapping_inc_y(), + 328 => self.shift_bgtile(8), _ => () } - } - match cycle { - 256 => self.wrapping_inc_y(), - 328 => self.shift_bgtile(8), - _ => () - } - } else if cycle > 336 { /* 337..340 */ - if cycle & 1 == 1 { - self.fetch_nametable_byte(); - } - } else { /* 257..320 */ - if cycle == 257 { + } else if cycle > 336 { /* 337..340 */ + if cycle & 1 == 1 { + self.fetch_nametable_byte(); + } + } else if cycle == 257 { /* we don't emulate fetch to per cycle precision because all data are fetched * from the secondary OAM which is not subject to any change during this * scanline */ @@ -538,13 +535,13 @@ impl<'a> PPU<'a> { self.fetch_sprite(); } } - } - if shifting { - if visible { - self.render_pixel(); + if shifting { + if visible { + self.render_pixel(); + } + self.shift_bgtile(1); + self.shift_sprites(); } - self.shift_bgtile(1); - self.shift_sprites(); } } else if self.scanline == 241 && cycle == 1 { self.scr.render(); |