From 1c3c9727a5fd8b5536dd743fe12017a78177f8d2 Mon Sep 17 00:00:00 2001 From: Lephe Date: Sat, 16 Jul 2022 22:30:59 +0100 Subject: [PATCH] r61524: add a r61524_display_rect() function for small regions --- include/gint/drivers/r61524.h | 25 +++++++++++++++++++++---- src/r61524/r61524.c | 21 ++++++++++++++++++--- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/include/gint/drivers/r61524.h b/include/gint/drivers/r61524.h index 5988e44..9ffc25c 100644 --- a/include/gint/drivers/r61524.h +++ b/include/gint/drivers/r61524.h @@ -35,16 +35,33 @@ enum { @method Transfer method, see above */ void r61524_display(uint16_t *vram, int start, int height, int method); +/* r61524_display_rect(): Send a rectangular section of VRAM to the display + + This function updates the rectangle going from (xmin,ymin) to (xmax,ymax) in + the VRAM to the display (both ends included). This can be faster than a full + dupdate() or a striped r61524_display() depending on the situation. However, + because the source VRAM is not contiguous, the transfer is only possible by + CPU, so this is only interesting for small regions. + + @vram Source VRAM with a stride of 396*2 bytes + @xmin @xmax Horizontal range to be updated (both included) + @ymin @ymax Vertical range to be updated (both included) */ +void r61524_display_rect(uint16_t *vram, int xmin, int xmax, int ymin, + int ymax); + /* r61524_start_frame(): Prepare the display for a region update This function sets up the display driver to receive graphics data to update - liens [start] to [start+height-1] (both included) of the current window. - This is the initial step of r61524_display(), which is normally followed by - writing all the data to 0xb4000000. + the rectangle going from (xmin,ymin) to (xmax,ymax) (both included). This is + the initial step of r61524_display(), which is normally followed by writing + all the data to 0xb4000000. + + In order to write with the DMA, it is necessary to write the full horizontal + range and select ymin and ymax to be congruent to 0 and 3 modulo 4. This function can be used to implement additional display driver update methods or alternate rendering pipelines. */ -void r61524_start_frame(int start, int height); +void r61524_start_frame(int xmin, int xmax, int ymin, int ymax); /* r162524_win_get() and r61524_win_set(): Manipulate the display window diff --git a/src/r61524/r61524.c b/src/r61524/r61524.c index 708608f..446f1fa 100644 --- a/src/r61524/r61524.c +++ b/src/r61524/r61524.c @@ -134,10 +134,10 @@ void r61524_win_set(uint16_t HSA, uint16_t HEA, uint16_t VSA, uint16_t VEA) /* TODO: r61524: update, backlight, brightness, gamma */ -void r61524_start_frame(int start, int height) +void r61524_start_frame(int xmin, int xmax, int ymin, int ymax) { /* Move the window to the desired region, then select address 0 */ - r61524_win_set(0, 395, start, start + height - 1); + r61524_win_set(xmin, xmax, ymin, ymax); select(ram_address_horizontal); write(0); select(ram_address_vertical); @@ -153,7 +153,7 @@ void r61524_display(uint16_t *vram, int start, int height, int method) the DMA might write data *while* we're sending commands! */ dma_transfer_wait(0); - r61524_start_frame(start, height); + r61524_start_frame(0, 395, start, start + height - 1); if(method == R61524_CPU) { @@ -181,6 +181,21 @@ void r61524_display(uint16_t *vram, int start, int height, int method) } } +void r61524_display_rect(uint16_t *vram, int xmin, int xmax, int ymin, + int ymax) +{ + dma_transfer_wait(0); + r61524_start_frame(xmin, xmax, ymin, xmax); + + vram += 396 * ymin + xmin; + + for(int y = 0; y < ymax - ymin + 1; y++) { + for(int x = 0; x < xmax - xmin + 1; x++) + write(vram[x]); + vram += 396; + } +} + //--- // State and driver metadata //---