Skip to content

Commit c1fbdfc

Browse files
committed
Upgrade to latest chirp8-engine
1 parent 665ea0a commit c1fbdfc

File tree

4 files changed

+86
-48
lines changed

4 files changed

+86
-48
lines changed

src/framebuffer.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use pcd8544;
2+
use chirp8::prelude::*;
3+
4+
const FB_X_START: u8 = (pcd8544::SCREEN_WIDTH - SCREEN_WIDTH) / 2;
5+
const FB_X_END: u8 = FB_X_START + SCREEN_WIDTH;
6+
const FB_Y_START: u8 = (pcd8544::SCREEN_HEIGHT - SCREEN_HEIGHT) / 2;
7+
const FB_Y_END: u8 = FB_Y_START + SCREEN_HEIGHT;
8+
9+
pub struct FBIter<'a> {
10+
data: &'a [u64; SCREEN_HEIGHT as usize],
11+
x: u8,
12+
y: u8
13+
}
14+
15+
impl<'a> FBIter<'a> {
16+
pub fn new(data: &'a [u64; SCREEN_HEIGHT as usize]) -> FBIter<'a> {
17+
FBIter {
18+
data: data,
19+
x: 0,
20+
y: 0
21+
}
22+
}
23+
24+
fn stripe(&self) -> Option<u8> {
25+
if self.x < FB_X_START || self.x >= FB_X_END { return None };
26+
let x = self.x - FB_X_START;
27+
if self.y < FB_Y_START || self.y >= FB_Y_END { return None };
28+
let y = self.y - FB_Y_START;
29+
30+
let mut stripe = 0x00;
31+
let mask = 1 << (63 - x);
32+
33+
for i in (y..y+8).rev() {
34+
let row: u64 = self.data[i as usize];
35+
let pixel = if row & mask == 0 { 0 } else { 1 };
36+
37+
stripe = (stripe << 1) | pixel;
38+
}
39+
40+
Some(stripe)
41+
}
42+
}
43+
44+
impl<'a> Iterator for FBIter<'a> {
45+
type Item = u8;
46+
47+
fn next(&mut self) -> Option<Self::Item> {
48+
if self.x >= pcd8544::SCREEN_WIDTH {
49+
return None
50+
}
51+
52+
let result = self.stripe();
53+
54+
self.y += 8;
55+
if self.y >= pcd8544::SCREEN_HEIGHT {
56+
self.y = 0;
57+
self.x += 1;
58+
}
59+
60+
Some(result.unwrap_or(0x00))
61+
}
62+
}

src/main.rs

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,70 +20,44 @@ mod timer;
2020
mod keypad;
2121
mod serial_ram;
2222
mod rom;
23+
mod framebuffer;
2324

2425
use rom::*;
2526
use timer::sleep_ms;
27+
use framebuffer::FBIter;
2628

2729
use chirp8::prelude::*;
2830
use chirp8::peripherals::*;
2931

3032
struct Board {
3133
fb_dirty: bool,
32-
fb_pixels: [[u8; (pcd8544::SCREEN_HEIGHT / 8) as usize]; pcd8544::SCREEN_WIDTH as usize],
34+
fb_rows: [u64; SCREEN_HEIGHT as usize],
3335
countdown: u8
3436
}
3537

3638
impl Board {
3739
pub const fn new() -> Board {
3840
Board {
3941
fb_dirty: false,
40-
fb_pixels: [[0; (pcd8544::SCREEN_HEIGHT / 8) as usize]; pcd8544::SCREEN_WIDTH as usize],
42+
fb_rows: [0; SCREEN_HEIGHT as usize],
4143
countdown: 0
4244
}
4345
}
4446
}
4547
static mut BOARD: Board = Board::new();
4648

47-
fn xy_from_chirp8(x: u8, y: u8) -> (u8, u8) {
48-
let dx = (pcd8544::SCREEN_WIDTH - SCREEN_WIDTH) / 2;
49-
let dy = (pcd8544::SCREEN_HEIGHT - SCREEN_HEIGHT) / 2;
50-
(x + dx, y + dy)
51-
}
52-
5349
impl Peripherals for Board {
5450
fn keep_running(&self) -> bool { true }
5551

56-
fn clear_pixels(&mut self) {
57-
for col in self.fb_pixels.iter_mut() {
58-
for pixel in col.iter_mut() {
59-
*pixel = 0;
60-
}
61-
}
62-
self.fb_dirty = true
52+
fn get_pixel_row(&self, y: u8) -> u64 {
53+
self.fb_rows[y as usize]
6354
}
6455

65-
fn set_pixel(&mut self, x: Byte, y: Byte, v: bool) {
66-
let (x, y) = xy_from_chirp8(x, y);
67-
68-
let row = y >> 3;
69-
let offset = y - (row << 3);
70-
let mask = 1 << offset;
71-
let bit = (if v {1} else {0}) << offset;
72-
73-
self.fb_pixels[x as usize][row as usize] = (self.fb_pixels[x as usize][row as usize] & !mask) | bit;
56+
fn set_pixel_row(&mut self, y: u8, row: u64) {
57+
self.fb_rows[y as usize] = row;
7458
self.fb_dirty = true;
7559
}
7660

77-
fn get_pixel(&self, x: Byte, y: Byte) -> bool {
78-
let (x, y) = xy_from_chirp8(x, y);
79-
80-
let row = y >> 3;
81-
let offset = y - (row << 3);
82-
let mask = 1 << offset;
83-
84-
self.fb_pixels[x as usize][row as usize] & mask != 0
85-
}
86-
8761
fn redraw(&mut self) {
8862
// Not really needed? timer will take care of it?
8963
}
@@ -140,7 +114,7 @@ impl Peripherals for Board {
140114
pub fn redraw() {
141115
let board = unsafe{ &mut BOARD };
142116
if board.fb_dirty {
143-
pcd8544::send(&board.fb_pixels);
117+
pcd8544::send(FBIter::new(&board.fb_rows));
144118
board.fb_dirty = false;
145119
}
146120
}
@@ -153,19 +127,23 @@ pub fn tick() {
153127
fn draw_test_pattern(board: &mut Board) {
154128
let dx = (SCREEN_WIDTH - SCREEN_HEIGHT) / 2;
155129

156-
for i in 0..SCREEN_HEIGHT {
157-
board.set_pixel(i + dx, SCREEN_HEIGHT - (i + 1), false);
158-
board.set_pixel(i + dx, i, true);
130+
let mut row: u64 = 1 << 47;
131+
for i in 0..32 {
132+
board.set_pixel_row(i, row);
133+
row >>= 1;
159134
}
135+
sleep_ms(500);
160136

137+
let mut row: u64 = 1 << 47;
138+
for i in (0..32).rev() {
139+
board.set_pixel_row(i, row);
140+
row >>= 1;
141+
}
161142
sleep_ms(500);
162143

163144
for i in 0..SCREEN_HEIGHT {
164-
board.set_pixel(i + dx, SCREEN_HEIGHT - (i + 1), true);
165-
board.set_pixel(i + dx, i, false);
145+
board.set_pixel_row(i, 0)
166146
}
167-
sleep_ms(500);
168-
board.clear_pixels();
169147
}
170148

171149
#[no_mangle]

src/pcd8544.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn setup() {
3232
port::D3::set_high(); // Unselect LCD
3333
}
3434

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

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

4343
port::D5::set_high(); // Set Data mode
44-
for col in pixels.iter() {
45-
for &pixel in col.iter() {
46-
spi::sync(pixel);
47-
}
44+
for stripe in pixels.into_iter() {
45+
spi::sync(stripe);
4846
}
4947

5048
port::D3::set_high(); // Unselect LCD

0 commit comments

Comments
 (0)