1.1 --- a/examples/vga-dual/main.c Tue Oct 23 22:14:20 2018 +0200
1.2 +++ b/examples/vga-dual/main.c Tue Oct 23 23:25:47 2018 +0200
1.3 @@ -28,6 +28,7 @@
1.4 #include "devconfig.h"
1.5 #include "vga.h"
1.6 #include "display.h"
1.7 +#include "display_config.h"
1.8
1.9
1.10
1.11 @@ -38,12 +39,11 @@
1.12
1.13 /* Pointers to pixel lines. */
1.14
1.15 -static uint8_t *linedata, *linedatalimit, *screenstart;
1.16 +static uint8_t *linedata;
1.17
1.18 /* Pixel data. */
1.19
1.20 static const uint8_t zerodata[ZERO_LENGTH] = {0};
1.21 -static uint8_t framebuffer[SCREEN_SIZE];
1.22
1.23
1.24
1.25 @@ -77,12 +77,7 @@
1.26 {
1.27 line = 0;
1.28 state_handler = vbp_active;
1.29 - test_linedata(framebuffer);
1.30 -
1.31 - /* Initialise the current display line pointer and display limit. */
1.32 -
1.33 - linedatalimit = framebuffer + SCREEN_SIZE;
1.34 - screenstart = framebuffer;
1.35 + test_linedata(&display_config);
1.36
1.37 init_memory();
1.38 init_pins();
1.39 @@ -105,14 +100,17 @@
1.40 dma_init(0, 3);
1.41 dma_set_auto_enable(0, 1);
1.42 dma_set_interrupt(0, T2, 1);
1.43 - dma_set_transfer(0, PHYSICAL((uint32_t) screenstart), LINE_LENGTH / 2,
1.44 + dma_set_transfer(0, PHYSICAL((uint32_t) display_config.screen_start),
1.45 + display_config.line_length / 2,
1.46 HW_PHYSICAL(PORTB), 1,
1.47 TRANSFER_CELL_SIZE);
1.48
1.49 dma_init(1, 3);
1.50 dma_set_auto_enable(1, 1);
1.51 dma_set_interrupt(1, T2, 1);
1.52 - dma_set_transfer(1, PHYSICAL((uint32_t) screenstart + LINE_LENGTH / 2), LINE_LENGTH / 2,
1.53 + dma_set_transfer(1, PHYSICAL((uint32_t) display_config.screen_start +
1.54 + display_config.line_length / 2),
1.55 + display_config.line_length / 2,
1.56 HW_PHYSICAL(PORTB), 1,
1.57 TRANSFER_CELL_SIZE);
1.58
1.59 @@ -202,9 +200,10 @@
1.60
1.61 /* Set the line address. */
1.62
1.63 - linedata = screenstart;
1.64 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2);
1.65 - dma_set_source(1, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2);
1.66 + linedata = display_config.screen_start;
1.67 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
1.68 + dma_set_source(1, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
1.69 + display_config.line_length / 2);
1.70
1.71 /* Enable the channels for the next line. */
1.72
1.73 @@ -222,15 +221,16 @@
1.74 {
1.75 /* Update the line address and handle wraparound. */
1.76
1.77 - if (!(line % LINE_MULTIPLIER))
1.78 + if (!(line % display_config.line_multiplier))
1.79 {
1.80 - linedata += LINE_LENGTH;
1.81 - if (linedata >= linedatalimit)
1.82 - linedata -= SCREEN_SIZE;
1.83 + linedata += display_config.line_length;
1.84 + if (linedata >= display_config.screen_limit)
1.85 + linedata -= display_config.screen_size;
1.86 }
1.87
1.88 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2);
1.89 - dma_set_source(1, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2);
1.90 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
1.91 + dma_set_source(1, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
1.92 + display_config.line_length / 2);
1.93 return;
1.94 }
1.95
2.1 --- a/examples/vga-pmp/Makefile Tue Oct 23 22:14:20 2018 +0200
2.2 +++ b/examples/vga-pmp/Makefile Tue Oct 23 23:25:47 2018 +0200
2.3 @@ -27,7 +27,7 @@
2.4
2.5 # Ordering of objects is important and cannot be left to replacement rules.
2.6
2.7 -SRC = $(START_SRC) main.c $(COMMON_SRC)
2.8 -OBJ = $(START_OBJ) main.o $(COMMON_OBJ)
2.9 +SRC = $(START_SRC) main.c $(COMMON_SRC) $(DISPLAY_SRC)
2.10 +OBJ = $(START_OBJ) main.o $(COMMON_OBJ) $(DISPLAY_OBJ)
2.11
2.12 include ../../mk/rules.mk
3.1 --- a/examples/vga-pmp/main.c Tue Oct 23 22:14:20 2018 +0200
3.2 +++ b/examples/vga-pmp/main.c Tue Oct 23 23:25:47 2018 +0200
3.3 @@ -28,6 +28,7 @@
3.4 #include "devconfig.h"
3.5 #include "vga.h"
3.6 #include "display.h"
3.7 +#include "display_config.h"
3.8
3.9
3.10
3.11 @@ -38,12 +39,11 @@
3.12
3.13 /* Pointers to pixel lines. */
3.14
3.15 -static uint8_t *linedata, *linedatalimit, *screenstart;
3.16 +static uint8_t *linedata;
3.17
3.18 /* Pixel data. */
3.19
3.20 static const uint8_t zerodata[ZERO_LENGTH] = {0};
3.21 -static uint8_t framebuffer[SCREEN_SIZE];
3.22
3.23
3.24
3.25 @@ -77,12 +77,7 @@
3.26 {
3.27 line = 0;
3.28 state_handler = vbp_active;
3.29 - test_linedata(framebuffer);
3.30 -
3.31 - /* Initialise the current display line pointer and display limit. */
3.32 -
3.33 - linedatalimit = framebuffer + SCREEN_SIZE;
3.34 - screenstart = framebuffer;
3.35 + test_linedata(&display_config);
3.36
3.37 init_memory();
3.38 init_pins();
3.39 @@ -109,7 +104,7 @@
3.40 dma_init(0, 3);
3.41 dma_set_auto_enable(0, 1);
3.42 dma_set_interrupt(0, T2, 1);
3.43 - dma_set_transfer(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH,
3.44 + dma_set_transfer(0, PHYSICAL((uint32_t) linedata), display_config.line_length,
3.45 HW_PHYSICAL(PM_REG(0, PMxDIN)), 1,
3.46 TRANSFER_CELL_SIZE);
3.47
3.48 @@ -201,8 +196,8 @@
3.49
3.50 /* Set the line address. */
3.51
3.52 - linedata = screenstart;
3.53 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH);
3.54 + linedata = display_config.screen_start;
3.55 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
3.56
3.57 /* Enable the channel for the next line. */
3.58
3.59 @@ -217,14 +212,14 @@
3.60 {
3.61 /* Update the line address and handle wraparound. */
3.62
3.63 - if (!(line % LINE_MULTIPLIER))
3.64 + if (!(line % display_config.line_multiplier))
3.65 {
3.66 - linedata += LINE_LENGTH;
3.67 - if (linedata >= linedatalimit)
3.68 - linedata -= SCREEN_SIZE;
3.69 + linedata += display_config.line_length;
3.70 + if (linedata >= display_config.screen_limit)
3.71 + linedata -= display_config.screen_size;
3.72 }
3.73
3.74 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH);
3.75 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
3.76 return;
3.77 }
3.78
4.1 --- a/examples/vga-timer/main.c Tue Oct 23 22:14:20 2018 +0200
4.2 +++ b/examples/vga-timer/main.c Tue Oct 23 23:25:47 2018 +0200
4.3 @@ -28,6 +28,7 @@
4.4 #include "devconfig.h"
4.5 #include "vga.h"
4.6 #include "display.h"
4.7 +#include "display_config.h"
4.8
4.9
4.10
4.11 @@ -38,12 +39,11 @@
4.12
4.13 /* Pointers to pixel lines. */
4.14
4.15 -static uint8_t *linedata, *linedatalimit, *screenstart;
4.16 +static uint8_t *linedata;
4.17
4.18 /* Pixel data. */
4.19
4.20 static const uint8_t zerodata[ZERO_LENGTH] = {0};
4.21 -static uint8_t framebuffer[SCREEN_SIZE];
4.22
4.23
4.24
4.25 @@ -77,12 +77,7 @@
4.26 {
4.27 line = 0;
4.28 state_handler = vbp_active;
4.29 - test_linedata(framebuffer);
4.30 -
4.31 - /* Initialise the current display line pointer and display limit. */
4.32 -
4.33 - linedatalimit = framebuffer + SCREEN_SIZE;
4.34 - screenstart = framebuffer;
4.35 + test_linedata(&display_config);
4.36
4.37 init_memory();
4.38 init_pins();
4.39 @@ -124,7 +119,8 @@
4.40 dma_init(0, 3);
4.41 dma_set_chaining(0, dma_chain_next);
4.42 dma_set_interrupt(0, T3, 1);
4.43 - dma_set_transfer(0, PHYSICAL((uint32_t) screenstart), LINE_LENGTH / 2,
4.44 + dma_set_transfer(0, PHYSICAL((uint32_t) display_config.screen_start),
4.45 + display_config.line_length / 2,
4.46 HW_PHYSICAL(PORTB), 1,
4.47 TRANSFER_CELL_SIZE);
4.48
4.49 @@ -134,7 +130,9 @@
4.50 dma_init(2, 3);
4.51 dma_set_chaining(2, dma_chain_previous);
4.52 dma_set_interrupt(2, T3, 1);
4.53 - dma_set_transfer(2, PHYSICAL((uint32_t) screenstart + LINE_LENGTH / 2), LINE_LENGTH / 2,
4.54 + dma_set_transfer(2, PHYSICAL((uint32_t) display_config.screen_start +
4.55 + display_config.line_length / 2),
4.56 + display_config.line_length / 2,
4.57 HW_PHYSICAL(PORTB), 1,
4.58 TRANSFER_CELL_SIZE);
4.59
4.60 @@ -229,9 +227,10 @@
4.61
4.62 /* Set the line address. */
4.63
4.64 - linedata = screenstart;
4.65 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2);
4.66 - dma_set_source(2, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2);
4.67 + linedata = display_config.screen_start;
4.68 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
4.69 + dma_set_source(2, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
4.70 + display_config.line_length / 2);
4.71
4.72 /* Enable the channels for the next line. */
4.73
4.74 @@ -248,15 +247,16 @@
4.75 {
4.76 /* Update the line address and handle wraparound. */
4.77
4.78 - if (!(line % LINE_MULTIPLIER))
4.79 + if (!(line % display_config.line_multiplier))
4.80 {
4.81 - linedata += LINE_LENGTH;
4.82 - if (linedata >= linedatalimit)
4.83 - linedata -= SCREEN_SIZE;
4.84 + linedata += display_config.line_length;
4.85 + if (linedata >= display_config.screen_limit)
4.86 + linedata -= display_config.screen_size;
4.87 }
4.88
4.89 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH / 2);
4.90 - dma_set_source(2, PHYSICAL((uint32_t) linedata + LINE_LENGTH / 2), LINE_LENGTH / 2);
4.91 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
4.92 + dma_set_source(2, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
4.93 + display_config.line_length / 2);
4.94 return;
4.95 }
4.96
5.1 --- a/examples/vga/main.c Tue Oct 23 22:14:20 2018 +0200
5.2 +++ b/examples/vga/main.c Tue Oct 23 23:25:47 2018 +0200
5.3 @@ -28,6 +28,7 @@
5.4 #include "devconfig.h"
5.5 #include "vga.h"
5.6 #include "display.h"
5.7 +#include "display_config.h"
5.8
5.9
5.10
5.11 @@ -38,12 +39,11 @@
5.12
5.13 /* Pointers to pixel lines. */
5.14
5.15 -static uint8_t *linedata, *linedatalimit, *screenstart;
5.16 +static uint8_t *linedata;
5.17
5.18 /* Pixel data. */
5.19
5.20 static const uint8_t zerodata[ZERO_LENGTH] = {0};
5.21 -static uint8_t framebuffer[SCREEN_SIZE];
5.22
5.23
5.24
5.25 @@ -77,12 +77,8 @@
5.26 {
5.27 line = 0;
5.28 state_handler = vbp_active;
5.29 - test_linedata(framebuffer);
5.30
5.31 - /* Initialise the current display line pointer and display limit. */
5.32 -
5.33 - linedatalimit = framebuffer + SCREEN_SIZE;
5.34 - screenstart = framebuffer;
5.35 + test_linedata(&display_config);
5.36
5.37 init_memory();
5.38 init_pins();
5.39 @@ -102,7 +98,8 @@
5.40 dma_init(0, 3);
5.41 dma_set_auto_enable(0, 1);
5.42 dma_set_interrupt(0, T2, 1);
5.43 - dma_set_transfer(0, PHYSICAL((uint32_t) screenstart), LINE_LENGTH,
5.44 + dma_set_transfer(0, PHYSICAL((uint32_t) display_config.screen_start),
5.45 + display_config.line_length,
5.46 HW_PHYSICAL(PORTB), 1,
5.47 TRANSFER_CELL_SIZE);
5.48
5.49 @@ -192,8 +189,8 @@
5.50
5.51 /* Set the line address. */
5.52
5.53 - linedata = screenstart;
5.54 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH);
5.55 + linedata = display_config.screen_start;
5.56 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
5.57
5.58 /* Enable the channel for the next line. */
5.59
5.60 @@ -210,14 +207,14 @@
5.61 {
5.62 /* Update the line address and handle wraparound. */
5.63
5.64 - if (!(line % LINE_MULTIPLIER))
5.65 + if (!(line % display_config.line_multiplier))
5.66 {
5.67 - linedata += LINE_LENGTH;
5.68 - if (linedata >= linedatalimit)
5.69 - linedata -= SCREEN_SIZE;
5.70 + linedata += display_config.line_length;
5.71 + if (linedata >= display_config.screen_limit)
5.72 + linedata -= display_config.screen_size;
5.73 }
5.74
5.75 - dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH);
5.76 + dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
5.77 return;
5.78 }
5.79
6.1 --- a/include/display.h Tue Oct 23 22:14:20 2018 +0200
6.2 +++ b/include/display.h Tue Oct 23 23:25:47 2018 +0200
6.3 @@ -22,7 +22,37 @@
6.4
6.5 #include <stdint.h>
6.6
6.7 -int get_position(int x);
6.8 -void test_linedata(uint8_t *framebuffer);
6.9 +
6.10 +
6.11 +/* Display configuration type. */
6.12 +
6.13 +typedef struct
6.14 +{
6.15 + /* Framebuffer pointer and size. */
6.16 +
6.17 + uint8_t *framebuffer;
6.18 + uint32_t screen_size;
6.19 + uint32_t line_length, line_count; /* width, height */
6.20 +
6.21 + /* Screen start/top and limit pointers. */
6.22 +
6.23 + uint8_t *screen_start, *screen_limit;
6.24 +
6.25 + /* Number of scanlines per display line. */
6.26 +
6.27 + int line_multiplier;
6.28 +
6.29 + /* Number of consecutive pixels provided by a framebuffer region. */
6.30 +
6.31 + int cell_size;
6.32 +
6.33 +} display_config_t;
6.34 +
6.35 +
6.36 +
6.37 +/* Access functions. */
6.38 +
6.39 +int get_position(display_config_t *cfg, int x);
6.40 +void test_linedata(display_config_t *cfg);
6.41
6.42 #endif /* __DISPLAY_H__ */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/include/display_config.h Tue Oct 23 23:25:47 2018 +0200
7.3 @@ -0,0 +1,38 @@
7.4 +/*
7.5 + * VGA-specific display-related functions.
7.6 + *
7.7 + * Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
7.8 + *
7.9 + * This program is free software: you can redistribute it and/or modify
7.10 + * it under the terms of the GNU General Public License as published by
7.11 + * the Free Software Foundation, either version 3 of the License, or
7.12 + * (at your option) any later version.
7.13 + *
7.14 + * This program is distributed in the hope that it will be useful,
7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.17 + * GNU General Public License for more details.
7.18 + *
7.19 + * You should have received a copy of the GNU General Public License
7.20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
7.21 + */
7.22 +
7.23 +#ifndef __DISPLAY_VGA_H__
7.24 +#define __DISPLAY_VGA_H__
7.25 +
7.26 +#include "display.h"
7.27 +
7.28 +uint8_t framebuffer[SCREEN_SIZE];
7.29 +
7.30 +display_config_t display_config = {
7.31 + .framebuffer = framebuffer,
7.32 + .screen_size = SCREEN_SIZE,
7.33 + .line_length = LINE_LENGTH,
7.34 + .line_count = LINE_COUNT,
7.35 + .line_multiplier = LINE_MULTIPLIER,
7.36 + .cell_size = CELL_SIZE,
7.37 + .screen_start = framebuffer,
7.38 + .screen_limit = framebuffer + SCREEN_SIZE,
7.39 + };
7.40 +
7.41 +#endif /* __DISPLAY_VGA_H__ */
8.1 --- a/lib/display.c Tue Oct 23 22:14:20 2018 +0200
8.2 +++ b/lib/display.c Tue Oct 23 23:25:47 2018 +0200
8.3 @@ -19,42 +19,38 @@
8.4
8.5 #include "display.h"
8.6
8.7 -/* Provided by the application. */
8.8 -
8.9 -#include "vga.h"
8.10 -
8.11
8.12
8.13 /* Return the line data position for the given pixel. */
8.14
8.15 -int get_position(int x)
8.16 +int get_position(display_config_t *cfg, int x)
8.17 {
8.18 - int cell = x / CELL_SIZE, offset = x % CELL_SIZE;
8.19 - int pos = (cell / 2) * CELL_SIZE + offset;
8.20 + int cell = x / cfg->cell_size, offset = x % cfg->cell_size;
8.21 + int pos = (cell / 2) * cfg->cell_size + offset;
8.22
8.23 - return cell % 2 ? pos + LINE_LENGTH / 2 : pos;
8.24 + return cell % 2 ? pos + cfg->line_length / 2 : pos;
8.25 }
8.26
8.27 /* Provide a pattern to test the line data. */
8.28
8.29 -void test_linedata(uint8_t *framebuffer)
8.30 +void test_linedata(display_config_t *cfg)
8.31 {
8.32 int x, y;
8.33 - uint8_t *linedata = framebuffer;
8.34 + uint8_t *linedata = cfg->framebuffer;
8.35
8.36 - for (y = 0; y < LINE_COUNT; y++)
8.37 + for (y = 0; y < cfg->line_count; y++)
8.38 {
8.39 - for (x = 0; x < LINE_LENGTH; x++)
8.40 + for (x = 0; x < cfg->line_length; x++)
8.41 {
8.42 /* Pixel: I0RRGGBB = Y0YYYYXX */
8.43
8.44 - linedata[get_position(x)] = (x % 2) ?
8.45 - (((y / (LINE_COUNT / 32)) & 0b1) << 7) |
8.46 - (((y / (LINE_COUNT / 16)) & 0b1111) << 2) |
8.47 - ((x / (LINE_LENGTH / 4)) & 0b11) :
8.48 + linedata[get_position(cfg, x)] = (x % 2) ?
8.49 + (((y / (cfg->line_count / 32)) & 0b1) << 7) |
8.50 + (((y / (cfg->line_count / 16)) & 0b1111) << 2) |
8.51 + ((x / (cfg->line_length / 4)) & 0b11) :
8.52 0x00;
8.53 }
8.54
8.55 - linedata += LINE_LENGTH;
8.56 + linedata += cfg->line_length;
8.57 }
8.58 }