@@ -470,6 +470,19 @@ impl RenderEngine {
470470 //
471471 // two RGB pixels (one pair) per byte eight RGB pixels (four pairs)
472472 // per word
473+ //
474+ // We give the interpolator `palette_ptr` and `chunky_pixels`.
475+ //
476+ // We want to know the corresponding palette addresses for each of
477+ // the eight 4-bit pixels in `chunky_pixels`. For each pixel `p` in
478+ // the 32-bit word `pppppppp` we want `palette_ptr.offset(p)`, which
479+ // is `palette_ptr + (p * 2)`.
480+ //
481+ // The interpolator calculates `palette_ptr + ((w >> 3) & 0b11110)`
482+ // for our left pixel and `palette_ptr + ((w << 1) & 0b11110)` for
483+ // our right pixel so we can pull out two pixels for each
484+ // interpolator write.
485+ let palette_ptr = VIDEO_PALETTE . as_ptr ( ) as * const RGBColour ;
473486
474487 // Set up the interpolator. This is safe because core1 has its own.
475488 let sio = unsafe { & * crate :: pac:: SIO :: ptr ( ) } ;
@@ -481,41 +494,40 @@ impl RenderEngine {
481494 unsafe { w. bits ( palette_ptr as u32 ) } ;
482495 w
483496 } ) ;
484- // lane0 will pull out the higher of the two 4-bit chunky pixels, but shifted
485- // by 2 bits to account for the 32-bit palette entry
497+ // lane0 will pull out the palette address of the higher of the two 4-bit chunky pixels in the bottom byte
486498 sio. interp0_ctrl_lane0 ( ) . write ( |w| {
487499 unsafe {
488- w. shift ( ) . bits ( 4 ) ;
489- w. mask_lsb ( ) . bits ( 2 ) ;
490- w. mask_msb ( ) . bits ( 5 ) ;
500+ w. shift ( ) . bits ( 3 ) ;
501+ w. mask_lsb ( ) . bits ( 1 ) ;
502+ w. mask_msb ( ) . bits ( 4 ) ;
491503 }
492504 w
493505 } ) ;
494- // lane1 will pull out the lower of the two 4-bit chunky pixels, but shifted
495- // by 2 bits to account for the 32-bit palette entry
506+ // lane1 will pull out the palette address of the higher of the two 4-bit chunky pixels in the bottom byte
496507 sio. interp0_ctrl_lane1 ( ) . write ( |w| {
497508 unsafe {
498- w. shift ( ) . bits ( 0 ) ;
499- w. mask_lsb ( ) . bits ( 2 ) ;
500- w. mask_msb ( ) . bits ( 5 ) ;
509+ w. shift ( ) . bits ( 31 ) ;
510+ w. mask_lsb ( ) . bits ( 1 ) ;
511+ w. mask_msb ( ) . bits ( 4 ) ;
501512 }
502513 w
503514 } ) ;
504515 let line_start_words = line_start_bytes as * const u32 ;
505516 let line_len_words = line_len_bytes / 4 ;
506517 for col in 0 ..line_len_words {
507518 unsafe {
508- let chunky_pixels = line_start_words. add ( col) . read ( ) ;
519+ let mut chunky_pixels = line_start_words. add ( col) . read ( ) ;
520+
521+ // ========================================================
522+ // First byte (containing two 4-bit pixels)
523+ // ========================================================
509524
510- // First two pixels
511- // Shift up by 2 bits before we load, to account for the 32
512- // bit size of each palette entry.
513525 sio. interp0_accum0 ( ) . write ( |w| {
514- w. bits ( chunky_pixels << 2 ) ;
526+ w. bits ( chunky_pixels) ;
515527 w
516528 } ) ;
517529 sio. interp0_accum1 ( ) . write ( |w| {
518- w. bits ( chunky_pixels << 2 ) ;
530+ w. bits ( chunky_pixels) ;
519531 w
520532 } ) ;
521533 // now we get the palette address for the left pixel
@@ -527,13 +539,17 @@ impl RenderEngine {
527539 scan_line_buffer_ptr. write ( pair) ;
528540 scan_line_buffer_ptr = scan_line_buffer_ptr. add ( 1 ) ;
529541
530- // Second two pixels
542+ // ========================================================
543+ // Second byte (containing two 4-bit pixels)
544+ // ========================================================
545+
546+ chunky_pixels >>= 8 ;
531547 sio. interp0_accum0 ( ) . write ( |w| {
532- w. bits ( chunky_pixels >> 6 ) ;
548+ w. bits ( chunky_pixels) ;
533549 w
534550 } ) ;
535551 sio. interp0_accum1 ( ) . write ( |w| {
536- w. bits ( chunky_pixels >> 6 ) ;
552+ w. bits ( chunky_pixels) ;
537553 w
538554 } ) ;
539555 // now we get the palette address for the left pixel
@@ -545,13 +561,17 @@ impl RenderEngine {
545561 scan_line_buffer_ptr. write ( pair) ;
546562 scan_line_buffer_ptr = scan_line_buffer_ptr. add ( 1 ) ;
547563
548- // Third two pixels
564+ // ========================================================
565+ // Third byte (containing two 4-bit pixels)
566+ // ========================================================
567+
568+ chunky_pixels >>= 8 ;
549569 sio. interp0_accum0 ( ) . write ( |w| {
550- w. bits ( chunky_pixels >> 14 ) ;
570+ w. bits ( chunky_pixels) ;
551571 w
552572 } ) ;
553573 sio. interp0_accum1 ( ) . write ( |w| {
554- w. bits ( chunky_pixels >> 14 ) ;
574+ w. bits ( chunky_pixels) ;
555575 w
556576 } ) ;
557577 // now we get the palette address for the left pixel
@@ -563,13 +583,17 @@ impl RenderEngine {
563583 scan_line_buffer_ptr. write ( pair) ;
564584 scan_line_buffer_ptr = scan_line_buffer_ptr. add ( 1 ) ;
565585
566- // Fourth two pixels
586+ // ========================================================
587+ // Fourth byte (containing two 4-bit pixels)
588+ // ========================================================
589+
590+ chunky_pixels >>= 8 ;
567591 sio. interp0_accum0 ( ) . write ( |w| {
568- w. bits ( chunky_pixels >> 22 ) ;
592+ w. bits ( chunky_pixels) ;
569593 w
570594 } ) ;
571595 sio. interp0_accum1 ( ) . write ( |w| {
572- w. bits ( chunky_pixels >> 22 ) ;
596+ w. bits ( chunky_pixels) ;
573597 w
574598 } ) ;
575599 // now we get the palette address for the left pixel
0 commit comments