@@ -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
681667impl 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 ) ]
690711enum 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