Skip to content

Commit

Permalink
Upgrade to latest chirp8-engine
Browse files Browse the repository at this point in the history
  • Loading branch information
gergoerdi committed Dec 26, 2022
1 parent f6a477d commit 1098b31
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 48 deletions.
2 changes: 1 addition & 1 deletion chirp8-engine
62 changes: 62 additions & 0 deletions src/framebuffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use pcd8544;
use chirp8::prelude::*;

const FB_X_START: u8 = (pcd8544::SCREEN_WIDTH - SCREEN_WIDTH) / 2;
const FB_X_END: u8 = FB_X_START + SCREEN_WIDTH;
const FB_Y_START: u8 = (pcd8544::SCREEN_HEIGHT - SCREEN_HEIGHT) / 2;
const FB_Y_END: u8 = FB_Y_START + SCREEN_HEIGHT;

pub struct FBIter<'a> {
data: &'a [u64; SCREEN_HEIGHT as usize],
x: u8,
y: u8
}

impl<'a> FBIter<'a> {
pub fn new(data: &'a [u64; SCREEN_HEIGHT as usize]) -> FBIter<'a> {
FBIter {
data: data,
x: 0,
y: 0
}
}

fn stripe(&self) -> u8 {
if self.x < FB_X_START || self.x >= FB_X_END { return 0x00 };
let x = self.x - FB_X_START;
if self.y < FB_Y_START || self.y >= FB_Y_END { return 0x00 };
let y = self.y - FB_Y_START;

let mut stripe = 0x00;
let mask = 1 << (63 - x);

for i in (y..y+8).rev() {
let row: u64 = self.data[i as usize];
let pixel = if row & mask == 0 { 0 } else { 1 };

stripe = (stripe << 1) | pixel;
}

stripe
}
}

impl<'a> Iterator for FBIter<'a> {
type Item = u8;

fn next(&mut self) -> Option<Self::Item> {
if self.x >= pcd8544::SCREEN_WIDTH {
return None
}

let result = self.stripe();

self.y += 8;
if self.y >= pcd8544::SCREEN_HEIGHT {
self.y = 0;
self.x += 1;
}

Some(result)
}
}
62 changes: 20 additions & 42 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ mod timer;
mod keypad;
mod serial_ram;
mod rom;
mod framebuffer;

use rom::*;
use timer::sleep_ms;
use framebuffer::FBIter;

use chirp8::prelude::*;
use chirp8::peripherals::*;

struct Board {
fb_dirty: bool,
fb_pixels: [[u8; (pcd8544::SCREEN_HEIGHT / 8) as usize]; pcd8544::SCREEN_WIDTH as usize],
fb_rows: [u64; SCREEN_HEIGHT as usize],
countdown: u8,
prng_state: u16,
}
Expand All @@ -39,54 +41,26 @@ impl Board {
pub const fn new() -> Board {
Board {
fb_dirty: false,
fb_pixels: [[0; (pcd8544::SCREEN_HEIGHT / 8) as usize]; pcd8544::SCREEN_WIDTH as usize],
fb_rows: [0; SCREEN_HEIGHT as usize],
countdown: 0,
prng_state: 0x0001
}
}
}
static mut BOARD: Board = Board::new();

fn xy_from_chirp8(x: u8, y: u8) -> (u8, u8) {
let dx = (pcd8544::SCREEN_WIDTH - SCREEN_WIDTH) / 2;
let dy = (pcd8544::SCREEN_HEIGHT - SCREEN_HEIGHT) / 2;
(x + dx, y + dy)
}

impl Peripherals for Board {
fn keep_running(&self) -> bool { true }

fn clear_pixels(&mut self) {
for col in self.fb_pixels.iter_mut() {
for pixel in col.iter_mut() {
*pixel = 0;
}
}
self.fb_dirty = true
fn get_pixel_row(&self, y: u8) -> u64 {
self.fb_rows[y as usize]
}

fn set_pixel(&mut self, x: Byte, y: Byte, v: bool) {
let (x, y) = xy_from_chirp8(x, y);

let row = y >> 3;
let offset = y - (row << 3);
let mask = 1 << offset;
let bit = (if v {1} else {0}) << offset;

self.fb_pixels[x as usize][row as usize] = (self.fb_pixels[x as usize][row as usize] & !mask) | bit;
fn set_pixel_row(&mut self, y: u8, row: u64) {
self.fb_rows[y as usize] = row;
self.fb_dirty = true;
}

fn get_pixel(&self, x: Byte, y: Byte) -> bool {
let (x, y) = xy_from_chirp8(x, y);

let row = y >> 3;
let offset = y - (row << 3);
let mask = 1 << offset;

self.fb_pixels[x as usize][row as usize] & mask != 0
}

fn redraw(&mut self) {
// Not really needed? timer will take care of it?
}
Expand Down Expand Up @@ -147,7 +121,7 @@ impl Peripherals for Board {

fn redraw(board: &mut Board) {
if board.fb_dirty {
pcd8544::send(&board.fb_pixels);
pcd8544::send(FBIter::new(&board.fb_rows));
board.fb_dirty = false;
}
}
Expand All @@ -162,19 +136,23 @@ pub fn tick() {
fn draw_test_pattern(board: &mut Board) {
let dx = (SCREEN_WIDTH - SCREEN_HEIGHT) / 2;

for i in 0..SCREEN_HEIGHT {
board.set_pixel(i + dx, SCREEN_HEIGHT - (i + 1), false);
board.set_pixel(i + dx, i, true);
let mut row: u64 = 1 << 47;
for i in 0..32 {
board.set_pixel_row(i, row);
row >>= 1;
}
sleep_ms(500);

let mut row: u64 = 1 << 47;
for i in (0..32).rev() {
board.set_pixel_row(i, row);
row >>= 1;
}
sleep_ms(500);

for i in 0..SCREEN_HEIGHT {
board.set_pixel(i + dx, SCREEN_HEIGHT - (i + 1), true);
board.set_pixel(i + dx, i, false);
board.set_pixel_row(i, 0)
}
sleep_ms(500);
board.clear_pixels();
}

#[no_mangle]
Expand Down
8 changes: 3 additions & 5 deletions src/pcd8544.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn setup() {
port::D3::set_high(); // Unselect LCD
}

pub fn send(pixels: &[[u8; (SCREEN_HEIGHT / 8) as usize]; SCREEN_WIDTH as usize]) {
pub fn send<I>(pixels: I) where I: IntoIterator<Item = u8> {
port::D3::set_low(); // Chip select LCD
port::D5::set_low(); // Set Command mode

Expand All @@ -41,10 +41,8 @@ pub fn send(pixels: &[[u8; (SCREEN_HEIGHT / 8) as usize]; SCREEN_WIDTH as usize]
spi::sync(0x40 | 0); // Set Y address

port::D5::set_high(); // Set Data mode
for col in pixels.iter() {
for &pixel in col.iter() {
spi::sync(pixel);
}
for stripe in pixels.into_iter() {
spi::sync(stripe);
}

port::D3::set_high(); // Unselect LCD
Expand Down

0 comments on commit 1098b31

Please sign in to comment.