# HG changeset patch # User Paul Boddie # Date 1540329947 -7200 # Node ID 4a67e90a0e1a4dd583958d1432e72900782bf467 # Parent 424c116cadb1a7ee128dd8910c32384feb44da6b Introduced a display configuration structure to be included in an application, encapsulating the display parameters in a form that can be provided to library routines, thus eliminating the library code dependency on specific application configuration details. diff -r 424c116cadb1 -r 4a67e90a0e1a examples/vga-dual/main.c --- a/examples/vga-dual/main.c Tue Oct 23 22:14:20 2018 +0200 +++ b/examples/vga-dual/main.c Tue Oct 23 23:25:47 2018 +0200 @@ -28,6 +28,7 @@ #include "devconfig.h" #include "vga.h" #include "display.h" +#include "display_config.h" @@ -38,12 +39,11 @@ /* Pointers to pixel lines. */ -static uint8_t *linedata, *linedatalimit, *screenstart; +static uint8_t *linedata; /* Pixel data. */ static const uint8_t zerodata[ZERO_LENGTH] = {0}; -static uint8_t framebuffer[SCREEN_SIZE]; @@ -77,12 +77,7 @@ { line = 0; state_handler = vbp_active; - test_linedata(framebuffer); - - /* Initialise the current display line pointer and display limit. */ - - linedatalimit = framebuffer + SCREEN_SIZE; - screenstart = framebuffer; + test_linedata(&display_config); init_memory(); init_pins(); @@ -105,14 +100,17 @@ dma_init(0, 3); dma_set_auto_enable(0, 1); dma_set_interrupt(0, T2, 1); - dma_set_transfer(0, PHYSICAL((uint32_t) screenstart), LINE_LENGTH / 2, + dma_set_transfer(0, PHYSICAL((uint32_t) display_config.screen_start), + display_config.line_length / 2, HW_PHYSICAL(PORTB), 1, TRANSFER_CELL_SIZE); dma_init(1, 3); dma_set_auto_enable(1, 1); dma_set_interrupt(1, T2, 1); - dma_set_transfer(1, PHYSICAL((uint32_t) screenstart + LINE_LENGTH / 2), LINE_LENGTH / 2, + dma_set_transfer(1, PHYSICAL((uint32_t) display_config.screen_start + + display_config.line_length / 2), + display_config.line_length / 2, HW_PHYSICAL(PORTB), 1, TRANSFER_CELL_SIZE); @@ -202,9 +200,10 @@ /* Set the line address. */ - linedata = screenstart; - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2); - dma_set_source(1, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2); + linedata = display_config.screen_start; + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2); + dma_set_source(1, PHYSICAL((uint32_t) linedata + display_config.line_length / 2), + display_config.line_length / 2); /* Enable the channels for the next line. */ @@ -222,15 +221,16 @@ { /* Update the line address and handle wraparound. */ - if (!(line % LINE_MULTIPLIER)) + if (!(line % display_config.line_multiplier)) { - linedata += LINE_LENGTH; - if (linedata >= linedatalimit) - linedata -= SCREEN_SIZE; + linedata += display_config.line_length; + if (linedata >= display_config.screen_limit) + linedata -= display_config.screen_size; } - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2); - dma_set_source(1, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2); + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2); + dma_set_source(1, PHYSICAL((uint32_t) linedata + display_config.line_length / 2), + display_config.line_length / 2); return; } diff -r 424c116cadb1 -r 4a67e90a0e1a examples/vga-pmp/Makefile --- a/examples/vga-pmp/Makefile Tue Oct 23 22:14:20 2018 +0200 +++ b/examples/vga-pmp/Makefile Tue Oct 23 23:25:47 2018 +0200 @@ -27,7 +27,7 @@ # Ordering of objects is important and cannot be left to replacement rules. -SRC = $(START_SRC) main.c $(COMMON_SRC) -OBJ = $(START_OBJ) main.o $(COMMON_OBJ) +SRC = $(START_SRC) main.c $(COMMON_SRC) $(DISPLAY_SRC) +OBJ = $(START_OBJ) main.o $(COMMON_OBJ) $(DISPLAY_OBJ) include ../../mk/rules.mk diff -r 424c116cadb1 -r 4a67e90a0e1a examples/vga-pmp/main.c --- a/examples/vga-pmp/main.c Tue Oct 23 22:14:20 2018 +0200 +++ b/examples/vga-pmp/main.c Tue Oct 23 23:25:47 2018 +0200 @@ -28,6 +28,7 @@ #include "devconfig.h" #include "vga.h" #include "display.h" +#include "display_config.h" @@ -38,12 +39,11 @@ /* Pointers to pixel lines. */ -static uint8_t *linedata, *linedatalimit, *screenstart; +static uint8_t *linedata; /* Pixel data. */ static const uint8_t zerodata[ZERO_LENGTH] = {0}; -static uint8_t framebuffer[SCREEN_SIZE]; @@ -77,12 +77,7 @@ { line = 0; state_handler = vbp_active; - test_linedata(framebuffer); - - /* Initialise the current display line pointer and display limit. */ - - linedatalimit = framebuffer + SCREEN_SIZE; - screenstart = framebuffer; + test_linedata(&display_config); init_memory(); init_pins(); @@ -109,7 +104,7 @@ dma_init(0, 3); dma_set_auto_enable(0, 1); dma_set_interrupt(0, T2, 1); - dma_set_transfer(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH, + dma_set_transfer(0, PHYSICAL((uint32_t) linedata), display_config.line_length, HW_PHYSICAL(PM_REG(0, PMxDIN)), 1, TRANSFER_CELL_SIZE); @@ -201,8 +196,8 @@ /* Set the line address. */ - linedata = screenstart; - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH); + linedata = display_config.screen_start; + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length); /* Enable the channel for the next line. */ @@ -217,14 +212,14 @@ { /* Update the line address and handle wraparound. */ - if (!(line % LINE_MULTIPLIER)) + if (!(line % display_config.line_multiplier)) { - linedata += LINE_LENGTH; - if (linedata >= linedatalimit) - linedata -= SCREEN_SIZE; + linedata += display_config.line_length; + if (linedata >= display_config.screen_limit) + linedata -= display_config.screen_size; } - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH); + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length); return; } diff -r 424c116cadb1 -r 4a67e90a0e1a examples/vga-timer/main.c --- a/examples/vga-timer/main.c Tue Oct 23 22:14:20 2018 +0200 +++ b/examples/vga-timer/main.c Tue Oct 23 23:25:47 2018 +0200 @@ -28,6 +28,7 @@ #include "devconfig.h" #include "vga.h" #include "display.h" +#include "display_config.h" @@ -38,12 +39,11 @@ /* Pointers to pixel lines. */ -static uint8_t *linedata, *linedatalimit, *screenstart; +static uint8_t *linedata; /* Pixel data. */ static const uint8_t zerodata[ZERO_LENGTH] = {0}; -static uint8_t framebuffer[SCREEN_SIZE]; @@ -77,12 +77,7 @@ { line = 0; state_handler = vbp_active; - test_linedata(framebuffer); - - /* Initialise the current display line pointer and display limit. */ - - linedatalimit = framebuffer + SCREEN_SIZE; - screenstart = framebuffer; + test_linedata(&display_config); init_memory(); init_pins(); @@ -124,7 +119,8 @@ dma_init(0, 3); dma_set_chaining(0, dma_chain_next); dma_set_interrupt(0, T3, 1); - dma_set_transfer(0, PHYSICAL((uint32_t) screenstart), LINE_LENGTH / 2, + dma_set_transfer(0, PHYSICAL((uint32_t) display_config.screen_start), + display_config.line_length / 2, HW_PHYSICAL(PORTB), 1, TRANSFER_CELL_SIZE); @@ -134,7 +130,9 @@ dma_init(2, 3); dma_set_chaining(2, dma_chain_previous); dma_set_interrupt(2, T3, 1); - dma_set_transfer(2, PHYSICAL((uint32_t) screenstart + LINE_LENGTH / 2), LINE_LENGTH / 2, + dma_set_transfer(2, PHYSICAL((uint32_t) display_config.screen_start + + display_config.line_length / 2), + display_config.line_length / 2, HW_PHYSICAL(PORTB), 1, TRANSFER_CELL_SIZE); @@ -229,9 +227,10 @@ /* Set the line address. */ - linedata = screenstart; - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2); - dma_set_source(2, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2); + linedata = display_config.screen_start; + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2); + dma_set_source(2, PHYSICAL((uint32_t) linedata + display_config.line_length / 2), + display_config.line_length / 2); /* Enable the channels for the next line. */ @@ -248,15 +247,16 @@ { /* Update the line address and handle wraparound. */ - if (!(line % LINE_MULTIPLIER)) + if (!(line % display_config.line_multiplier)) { - linedata += LINE_LENGTH; - if (linedata >= linedatalimit) - linedata -= SCREEN_SIZE; + linedata += display_config.line_length; + if (linedata >= display_config.screen_limit) + linedata -= display_config.screen_size; } - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2); - dma_set_source(2, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2); + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2); + dma_set_source(2, PHYSICAL((uint32_t) linedata + display_config.line_length / 2), + display_config.line_length / 2); return; } diff -r 424c116cadb1 -r 4a67e90a0e1a examples/vga/main.c --- a/examples/vga/main.c Tue Oct 23 22:14:20 2018 +0200 +++ b/examples/vga/main.c Tue Oct 23 23:25:47 2018 +0200 @@ -28,6 +28,7 @@ #include "devconfig.h" #include "vga.h" #include "display.h" +#include "display_config.h" @@ -38,12 +39,11 @@ /* Pointers to pixel lines. */ -static uint8_t *linedata, *linedatalimit, *screenstart; +static uint8_t *linedata; /* Pixel data. */ static const uint8_t zerodata[ZERO_LENGTH] = {0}; -static uint8_t framebuffer[SCREEN_SIZE]; @@ -77,12 +77,8 @@ { line = 0; state_handler = vbp_active; - test_linedata(framebuffer); - /* Initialise the current display line pointer and display limit. */ - - linedatalimit = framebuffer + SCREEN_SIZE; - screenstart = framebuffer; + test_linedata(&display_config); init_memory(); init_pins(); @@ -102,7 +98,8 @@ dma_init(0, 3); dma_set_auto_enable(0, 1); dma_set_interrupt(0, T2, 1); - dma_set_transfer(0, PHYSICAL((uint32_t) screenstart), LINE_LENGTH, + dma_set_transfer(0, PHYSICAL((uint32_t) display_config.screen_start), + display_config.line_length, HW_PHYSICAL(PORTB), 1, TRANSFER_CELL_SIZE); @@ -192,8 +189,8 @@ /* Set the line address. */ - linedata = screenstart; - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH); + linedata = display_config.screen_start; + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length); /* Enable the channel for the next line. */ @@ -210,14 +207,14 @@ { /* Update the line address and handle wraparound. */ - if (!(line % LINE_MULTIPLIER)) + if (!(line % display_config.line_multiplier)) { - linedata += LINE_LENGTH; - if (linedata >= linedatalimit) - linedata -= SCREEN_SIZE; + linedata += display_config.line_length; + if (linedata >= display_config.screen_limit) + linedata -= display_config.screen_size; } - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH); + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length); return; } diff -r 424c116cadb1 -r 4a67e90a0e1a include/display.h --- a/include/display.h Tue Oct 23 22:14:20 2018 +0200 +++ b/include/display.h Tue Oct 23 23:25:47 2018 +0200 @@ -22,7 +22,37 @@ #include -int get_position(int x); -void test_linedata(uint8_t *framebuffer); + + +/* Display configuration type. */ + +typedef struct +{ + /* Framebuffer pointer and size. */ + + uint8_t *framebuffer; + uint32_t screen_size; + uint32_t line_length, line_count; /* width, height */ + + /* Screen start/top and limit pointers. */ + + uint8_t *screen_start, *screen_limit; + + /* Number of scanlines per display line. */ + + int line_multiplier; + + /* Number of consecutive pixels provided by a framebuffer region. */ + + int cell_size; + +} display_config_t; + + + +/* Access functions. */ + +int get_position(display_config_t *cfg, int x); +void test_linedata(display_config_t *cfg); #endif /* __DISPLAY_H__ */ diff -r 424c116cadb1 -r 4a67e90a0e1a include/display_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/display_config.h Tue Oct 23 23:25:47 2018 +0200 @@ -0,0 +1,38 @@ +/* + * VGA-specific display-related functions. + * + * Copyright (C) 2018 Paul Boddie + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DISPLAY_VGA_H__ +#define __DISPLAY_VGA_H__ + +#include "display.h" + +uint8_t framebuffer[SCREEN_SIZE]; + +display_config_t display_config = { + .framebuffer = framebuffer, + .screen_size = SCREEN_SIZE, + .line_length = LINE_LENGTH, + .line_count = LINE_COUNT, + .line_multiplier = LINE_MULTIPLIER, + .cell_size = CELL_SIZE, + .screen_start = framebuffer, + .screen_limit = framebuffer + SCREEN_SIZE, + }; + +#endif /* __DISPLAY_VGA_H__ */ diff -r 424c116cadb1 -r 4a67e90a0e1a lib/display.c --- a/lib/display.c Tue Oct 23 22:14:20 2018 +0200 +++ b/lib/display.c Tue Oct 23 23:25:47 2018 +0200 @@ -19,42 +19,38 @@ #include "display.h" -/* Provided by the application. */ - -#include "vga.h" - /* Return the line data position for the given pixel. */ -int get_position(int x) +int get_position(display_config_t *cfg, int x) { - int cell = x / CELL_SIZE, offset = x % CELL_SIZE; - int pos = (cell / 2) * CELL_SIZE + offset; + int cell = x / cfg->cell_size, offset = x % cfg->cell_size; + int pos = (cell / 2) * cfg->cell_size + offset; - return cell % 2 ? pos + LINE_LENGTH / 2 : pos; + return cell % 2 ? pos + cfg->line_length / 2 : pos; } /* Provide a pattern to test the line data. */ -void test_linedata(uint8_t *framebuffer) +void test_linedata(display_config_t *cfg) { int x, y; - uint8_t *linedata = framebuffer; + uint8_t *linedata = cfg->framebuffer; - for (y = 0; y < LINE_COUNT; y++) + for (y = 0; y < cfg->line_count; y++) { - for (x = 0; x < LINE_LENGTH; x++) + for (x = 0; x < cfg->line_length; x++) { /* Pixel: I0RRGGBB = Y0YYYYXX */ - linedata[get_position(x)] = (x % 2) ? - (((y / (LINE_COUNT / 32)) & 0b1) << 7) | - (((y / (LINE_COUNT / 16)) & 0b1111) << 2) | - ((x / (LINE_LENGTH / 4)) & 0b11) : + linedata[get_position(cfg, x)] = (x % 2) ? + (((y / (cfg->line_count / 32)) & 0b1) << 7) | + (((y / (cfg->line_count / 16)) & 0b1111) << 2) | + ((x / (cfg->line_length / 4)) & 0b11) : 0x00; } - linedata += LINE_LENGTH; + linedata += cfg->line_length; } }