Skip to content

Commit a1f5d57

Browse files
committed
Remove the static mut from the video.
1 parent ab1f620 commit a1f5d57

File tree

1 file changed

+53
-40
lines changed

1 file changed

+53
-40
lines changed

src/vga/mod.rs

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,10 @@ impl RenderEngine {
201201
// Pick a buffer to render into based on the line number we are drawing.
202202
// It's safe to write to this buffer because it's the the other one that
203203
// is currently being DMA'd out to the Pixel SM.
204-
let scan_line_buffer = unsafe {
205-
if (current_line_num & 1) == 0 {
206-
&mut PIXEL_DATA_BUFFER_EVEN
207-
} else {
208-
&mut PIXEL_DATA_BUFFER_ODD
209-
}
204+
let scan_line_buffer = if (current_line_num & 1) == 0 {
205+
&PIXEL_DATA_BUFFER_EVEN
206+
} else {
207+
&PIXEL_DATA_BUFFER_ODD
210208
};
211209

212210
match self.current_video_mode.format() {
@@ -243,18 +241,14 @@ impl RenderEngine {
243241
///
244242
/// The `current_line_num` goes from `0..NUM_LINES`.
245243
#[link_section = ".data"]
246-
pub fn draw_next_line_chunky1(
247-
&mut self,
248-
scan_line_buffer: &mut LineBuffer,
249-
current_line_num: u16,
250-
) {
244+
pub fn draw_next_line_chunky1(&mut self, scan_line_buffer: &LineBuffer, current_line_num: u16) {
251245
let base_ptr = self.current_video_ptr as *const u8;
252246
let line_len_bytes = self.current_video_mode.line_size_bytes();
253247
let is_double = self.current_video_mode.is_horiz_2x();
254248
let offset = usize::from(current_line_num) * line_len_bytes;
255249
let line_start = unsafe { base_ptr.add(offset) };
256250
// Get a pointer into our scan-line buffer
257-
let mut scan_line_buffer_ptr = scan_line_buffer.pixels.as_mut_ptr();
251+
let mut scan_line_buffer_ptr = scan_line_buffer.pixel_ptr();
258252
let black_pixel = RGBColour(VIDEO_PALETTE[0].load(Ordering::Relaxed));
259253
let white_pixel = RGBColour(VIDEO_PALETTE[15].load(Ordering::Relaxed));
260254
if is_double {
@@ -361,18 +355,14 @@ impl RenderEngine {
361355
///
362356
/// The `current_line_num` goes from `0..NUM_LINES`.
363357
#[link_section = ".data"]
364-
pub fn draw_next_line_chunky2(
365-
&mut self,
366-
scan_line_buffer: &mut LineBuffer,
367-
current_line_num: u16,
368-
) {
358+
pub fn draw_next_line_chunky2(&mut self, scan_line_buffer: &LineBuffer, current_line_num: u16) {
369359
let is_double = self.current_video_mode.is_horiz_2x();
370360
let base_ptr = self.current_video_ptr as *const u8;
371361
let line_len_bytes = self.current_video_mode.line_size_bytes();
372362
let offset = usize::from(current_line_num) * line_len_bytes;
373363
let line_start = unsafe { base_ptr.add(offset) };
374364
// Get a pointer into our scan-line buffer
375-
let mut scan_line_buffer_ptr = scan_line_buffer.pixels.as_mut_ptr();
365+
let mut scan_line_buffer_ptr = scan_line_buffer.pixel_ptr();
376366
let pixel_colours = [
377367
RGBColour(VIDEO_PALETTE[0].load(Ordering::Relaxed)),
378368
RGBColour(VIDEO_PALETTE[1].load(Ordering::Relaxed)),
@@ -446,18 +436,14 @@ impl RenderEngine {
446436
///
447437
/// The `current_line_num` goes from `0..NUM_LINES`.
448438
#[link_section = ".data"]
449-
pub fn draw_next_line_chunky4(
450-
&mut self,
451-
scan_line_buffer: &mut LineBuffer,
452-
current_line_num: u16,
453-
) {
439+
pub fn draw_next_line_chunky4(&mut self, scan_line_buffer: &LineBuffer, current_line_num: u16) {
454440
let is_double = self.current_video_mode.is_horiz_2x();
455441
let base_ptr = self.current_video_ptr as *const u8;
456442
let line_len_bytes = self.current_video_mode.line_size_bytes();
457443
let line_start_offset_bytes = usize::from(current_line_num) * line_len_bytes;
458444
let line_start_bytes = unsafe { base_ptr.add(line_start_offset_bytes) };
459445
// Get a pointer into our scan-line buffer
460-
let mut scan_line_buffer_ptr = scan_line_buffer.pixels.as_mut_ptr();
446+
let mut scan_line_buffer_ptr = scan_line_buffer.pixel_ptr();
461447
let palette_ptr = VIDEO_PALETTE.as_ptr() as *const RGBColour;
462448
if is_double {
463449
// Double-width mode.
@@ -466,7 +452,7 @@ impl RenderEngine {
466452
unsafe {
467453
let chunky_pixels = line_start_bytes.add(col).read() as usize;
468454
let left = palette_ptr.add((chunky_pixels >> 4) & 0x0F).read();
469-
let right = palette_ptr.add((chunky_pixels >> 0) & 0x0F).read();
455+
let right = palette_ptr.add(chunky_pixels & 0x0F).read();
470456
scan_line_buffer_ptr.write(RGBPair::from_pixels(left, left));
471457
scan_line_buffer_ptr
472458
.add(1)
@@ -604,7 +590,7 @@ impl RenderEngine {
604590
pub fn draw_next_line_text<const GLYPH_HEIGHT: usize>(
605591
&mut self,
606592
font: &Font,
607-
scan_line_buffer: &mut LineBuffer,
593+
scan_line_buffer: &LineBuffer,
608594
current_line_num: u16,
609595
) {
610596
// Convert our position in scan-lines to a text row, and a line within each glyph on that row
@@ -630,7 +616,7 @@ impl RenderEngine {
630616
let font_ptr = unsafe { font.data.as_ptr().add(font_row) };
631617

632618
// Get a pointer into our scan-line buffer
633-
let mut scan_line_buffer_ptr = scan_line_buffer.pixels.as_mut_ptr();
619+
let mut scan_line_buffer_ptr = scan_line_buffer.pixel_ptr();
634620

635621
// Convert from characters to coloured pixels, using the font as a look-up table.
636622
for col in 0..self.num_text_cols {
@@ -675,16 +661,51 @@ struct LineBuffer {
675661
/// Must be one less than the number of pixel-pairs in `pixels`
676662
length: u32,
677663
/// Pixels to be displayed, grouped into pairs (to save FIFO space and reduce DMA bandwidth)
678-
pixels: [RGBPair; MAX_NUM_PIXEL_PAIRS_PER_LINE],
664+
pixels: UnsafeCell<[RGBPair; MAX_NUM_PIXEL_PAIRS_PER_LINE]>,
679665
}
680666

681667
impl LineBuffer {
682-
/// Convert the line buffer to a 32-bit address that the DMA engine understands.
668+
/// Make a new LineBuffer
669+
///
670+
/// Use this for the even lines, so you get a checkerboard
671+
const fn new_even() -> LineBuffer {
672+
LineBuffer {
673+
length: (MAX_NUM_PIXEL_PAIRS_PER_LINE as u32) - 1,
674+
pixels: UnsafeCell::new(
675+
[RGBPair::from_pixels(RGBColour::WHITE, RGBColour::BLACK);
676+
MAX_NUM_PIXEL_PAIRS_PER_LINE],
677+
),
678+
}
679+
}
680+
681+
/// Make a new LineBuffer
682+
///
683+
/// Use this for the odd lines, so you get a checkerboard
684+
const fn new_odd() -> LineBuffer {
685+
LineBuffer {
686+
length: (MAX_NUM_PIXEL_PAIRS_PER_LINE as u32) - 1,
687+
pixels: UnsafeCell::new(
688+
[RGBPair::from_pixels(RGBColour::BLACK, RGBColour::WHITE);
689+
MAX_NUM_PIXEL_PAIRS_PER_LINE],
690+
),
691+
}
692+
}
693+
694+
/// Get a pointer to the entire linebuffer.
695+
///
696+
/// This produces a 32-bit address that the DMA engine understands.
683697
fn as_ptr(&self) -> u32 {
684698
self as *const _ as usize as u32
685699
}
700+
701+
/// Get a pointer to the pixel data
702+
fn pixel_ptr(&self) -> *mut RGBPair {
703+
self.pixels.get() as *mut RGBPair
704+
}
686705
}
687706

707+
unsafe impl Sync for LineBuffer {}
708+
688709
/// The kind of IRQ we want to raise
689710
#[derive(Debug, Copy, Clone)]
690711
enum RaiseIrq {
@@ -1682,22 +1703,14 @@ const PIXEL_DMA_CHAN: usize = 1;
16821703
/// Gets read by DMA, which pushes them into the pixel state machine's FIFO.
16831704
///
16841705
/// Gets written to by `RenderEngine` running on Core 1.
1685-
static mut PIXEL_DATA_BUFFER_EVEN: LineBuffer = LineBuffer {
1686-
length: (MAX_NUM_PIXEL_PAIRS_PER_LINE as u32) - 1,
1687-
pixels: [RGBPair::from_pixels(RGBColour::WHITE, RGBColour::BLACK);
1688-
MAX_NUM_PIXEL_PAIRS_PER_LINE],
1689-
};
1706+
static PIXEL_DATA_BUFFER_EVEN: LineBuffer = LineBuffer::new_even();
16901707

16911708
/// One scan-line's worth of 12-bit pixels, used for the odd scan-lines (1, 3, 5 ... NUM_LINES-1).
16921709
///
16931710
/// Gets read by DMA, which pushes them into the pixel state machine's FIFO.
16941711
///
16951712
/// Gets written to by `RenderEngine` running on Core 1.
1696-
static mut PIXEL_DATA_BUFFER_ODD: LineBuffer = LineBuffer {
1697-
length: (MAX_NUM_PIXEL_PAIRS_PER_LINE as u32) - 1,
1698-
pixels: [RGBPair::from_pixels(RGBColour::BLACK, RGBColour::WHITE);
1699-
MAX_NUM_PIXEL_PAIRS_PER_LINE],
1700-
};
1713+
static PIXEL_DATA_BUFFER_ODD: LineBuffer = LineBuffer::new_odd();
17011714

17021715
/// Holds the colour look-up table for text mode.
17031716
///
@@ -1896,7 +1909,7 @@ pub fn init(
18961909
.write(|w| unsafe { w.bits(pixel_fifo.fifo_address() as usize as u32) });
18971910
dma.ch(PIXEL_DMA_CHAN)
18981911
.ch_trans_count()
1899-
.write(|w| unsafe { w.bits(PIXEL_DATA_BUFFER_EVEN.pixels.len() as u32 + 1) });
1912+
.write(|w| unsafe { w.bits(MAX_NUM_PIXEL_PAIRS_PER_LINE as u32 + 1) });
19001913

19011914
// Enable the DMA
19021915
dma.multi_chan_trigger()

0 commit comments

Comments
 (0)