From 12647140d11cba36ffff6f782059232fa186e9fe Mon Sep 17 00:00:00 2001 From: claudiol Date: Sun, 14 Feb 2021 12:46:51 -0500 Subject: [PATCH] Added color graphics library (breaks build of Desktop). A few USB driver fixes - still not working. --- firmware/ggl/cgl/cgl_bitblt.c | 67 +++++++ firmware/ggl/cgl/cgl_bitbltoper.c | 54 ++++++ firmware/ggl/cgl/cgl_filter.c | 28 +++ firmware/ggl/cgl/cgl_fltdarken.c | 24 +++ firmware/ggl/cgl/cgl_fltinvert.c | 23 +++ firmware/ggl/cgl/cgl_fltlighten.c | 22 +++ firmware/ggl/cgl/cgl_fltreplace.c | 25 +++ firmware/ggl/cgl/cgl_getnib.c | 23 +++ firmware/ggl/cgl/cgl_hblitoper.c | 244 +++++++++++++++++++++++++ firmware/ggl/cgl/cgl_hblt.c | 93 ++++++++++ firmware/ggl/cgl/cgl_hbltfilter.c | 46 +++++ firmware/ggl/cgl/cgl_hline.c | 94 ++++++++++ firmware/ggl/cgl/cgl_initscr.c | 18 ++ firmware/ggl/cgl/cgl_mkcolor.c | 19 ++ firmware/ggl/cgl/cgl_mkcolor32.c | 24 +++ firmware/ggl/cgl/cgl_opmask.c | 45 +++++ firmware/ggl/cgl/cgl_optransp.c | 23 +++ firmware/ggl/cgl/cgl_ovlblt.c | 39 ++++ firmware/ggl/cgl/cgl_pltnib.c | 17 ++ firmware/ggl/cgl/cgl_rect.c | 70 +++++++ firmware/ggl/cgl/cgl_rectp.c | 23 +++ firmware/ggl/cgl/cgl_revblt.c | 34 ++++ firmware/ggl/cgl/cgl_scrolldn.c | 28 +++ firmware/ggl/cgl/cgl_scrolllf.c | 28 +++ firmware/ggl/cgl/cgl_scrollrt.c | 28 +++ firmware/ggl/cgl/cgl_scrollup.c | 28 +++ firmware/ggl/cgl/cgl_vline.c | 56 ++++++ firmware/include/hal_api.h | 2 +- firmware/include/target_pc.h | 6 +- firmware/include/target_prime1.h | 4 + firmware/include/xgl.h | 28 +++ firmware/sys/target_pc/lcd.c | 4 +- firmware/sys/target_prime1/usbdriver.c | 73 ++++++-- newrpl-ui-prime.pro | 57 +++--- 34 files changed, 1343 insertions(+), 54 deletions(-) create mode 100644 firmware/ggl/cgl/cgl_bitblt.c create mode 100644 firmware/ggl/cgl/cgl_bitbltoper.c create mode 100644 firmware/ggl/cgl/cgl_filter.c create mode 100644 firmware/ggl/cgl/cgl_fltdarken.c create mode 100644 firmware/ggl/cgl/cgl_fltinvert.c create mode 100644 firmware/ggl/cgl/cgl_fltlighten.c create mode 100644 firmware/ggl/cgl/cgl_fltreplace.c create mode 100644 firmware/ggl/cgl/cgl_getnib.c create mode 100644 firmware/ggl/cgl/cgl_hblitoper.c create mode 100644 firmware/ggl/cgl/cgl_hblt.c create mode 100644 firmware/ggl/cgl/cgl_hbltfilter.c create mode 100644 firmware/ggl/cgl/cgl_hline.c create mode 100644 firmware/ggl/cgl/cgl_initscr.c create mode 100644 firmware/ggl/cgl/cgl_mkcolor.c create mode 100644 firmware/ggl/cgl/cgl_mkcolor32.c create mode 100644 firmware/ggl/cgl/cgl_opmask.c create mode 100644 firmware/ggl/cgl/cgl_optransp.c create mode 100644 firmware/ggl/cgl/cgl_ovlblt.c create mode 100644 firmware/ggl/cgl/cgl_pltnib.c create mode 100644 firmware/ggl/cgl/cgl_rect.c create mode 100644 firmware/ggl/cgl/cgl_rectp.c create mode 100644 firmware/ggl/cgl/cgl_revblt.c create mode 100644 firmware/ggl/cgl/cgl_scrolldn.c create mode 100644 firmware/ggl/cgl/cgl_scrolllf.c create mode 100644 firmware/ggl/cgl/cgl_scrollrt.c create mode 100644 firmware/ggl/cgl/cgl_scrollup.c create mode 100644 firmware/ggl/cgl/cgl_vline.c create mode 100644 firmware/include/xgl.h diff --git a/firmware/ggl/cgl/cgl_bitblt.c b/firmware/ggl/cgl/cgl_bitblt.c new file mode 100644 index 0000000..87cbee8 --- /dev/null +++ b/firmware/ggl/cgl/cgl_bitblt.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_bitblt(gglsurface * dest, gglsurface * src, int width, int height) +{ + +// COPIES A RECTANGULAR REGION FROM src TO dest +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + int doff, soff, line; + + doff = dest->y * dest->width + dest->x; + soff = src->y * src->width + src->x; + + for(line = 0; line < height; ++line) { + ggl_hblt(dest->addr, doff, src->addr, soff, width); + doff += dest->width; + soff += src->width; + } +} + +void ggl_bitbltclip(gglsurface * dest, gglsurface * src, int width, int height) +{ + // SOURCE CLIPPING FIRST - REDUNDANT + /* + if(src->x+width<0) return; + if(src->x>=src->width) return; + if(src->y+height<0) return; + if(src->y>=src->height) return; + if(src->x<0) { dest->x-=src->x; width+=src->x; src->x=0; } + if(src->y<0) { dest->y-=src->y; height+=src->y; src->y=0; } + if(src->x+width>src->width) { width=src->width-src->x; } + */ + + // DESTINATION CLIPPING ONLY + if(dest->x > dest->clipx2) + return; + if(dest->y > dest->clipy2) + return; + if(dest->x + width < dest->clipx) + return; + if(dest->y + height < dest->clipy) + return; + if(dest->x < dest->clipx) + dest->x = dest->clipx; + if(dest->x + width > dest->clipx2) + width = dest->clipx2 - dest->x + 1; + if(dest->y < dest->clipy) { + src->y += dest->clipy - dest->y; + height -= dest->clipy - dest->y; + dest->y = dest->clipy; + } + if(dest->y + height > dest->clipy2) + height = dest->clipy2 - dest->y + 1; + + ggl_bitblt(dest, src, width, height); + +} diff --git a/firmware/ggl/cgl/cgl_bitbltoper.c b/firmware/ggl/cgl/cgl_bitbltoper.c new file mode 100644 index 0000000..645e356 --- /dev/null +++ b/firmware/ggl/cgl/cgl_bitbltoper.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_bitbltoper(gglsurface * dest, gglsurface * src, int width, int height, + int param, ggloperator fop) +{ + +// COPIES A RECTANGULAR REGION FROM src TO dest AND APPLIES THE GIVEN OPERATOR +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + int doff, soff, line; + + doff = dest->y * dest->width + dest->x; + soff = src->y * src->width + src->x; + + for(line = 0; line < height; ++line) { + ggl_hbltoper(dest->addr, doff, src->addr, soff, width, param, fop); + doff += dest->width; + soff += src->width; + } +} + +void ggl_monobitbltoper(gglsurface * dest, gglsurface * src, int width, + int height, int param, ggloperator fop) +{ + +// COPIES A RECTANGULAR REGION FROM src TO dest AND APPLIES THE GIVEN OPERATOR +// src POINTS TO A MONOCHROME BITMAP, NOT GRAYSCALE +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + int doff, soff, line; + + doff = dest->y * dest->width + dest->x; + soff = src->y * src->width + src->x; + + for(line = 0; line < height; ++line) { + ggl_monohbltoper(dest->addr, doff, (unsigned char *)(src->addr), soff, + width, param, fop); + doff += dest->width; + soff += src->width; + } +} diff --git a/firmware/ggl/cgl/cgl_filter.c b/firmware/ggl/cgl/cgl_filter.c new file mode 100644 index 0000000..b137d23 --- /dev/null +++ b/firmware/ggl/cgl/cgl_filter.c @@ -0,0 +1,28 @@ + +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ +#include + +void ggl_filter(gglsurface * dest, int width, int height, int param, + gglfilter filterfunc) +{ + +// FILTERS A RECTANGULAR REGION FROM src TO dest +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + int doff, line; + + doff = dest->y * dest->width + dest->x; + + for(line = 0; line < height; ++line) { + ggl_hbltfilter(dest->addr, doff, width, param, filterfunc); + doff += dest->width; + } +} diff --git a/firmware/ggl/cgl/cgl_fltdarken.c b/firmware/ggl/cgl/cgl_fltdarken.c new file mode 100644 index 0000000..2959468 --- /dev/null +++ b/firmware/ggl/cgl/cgl_fltdarken.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ +#include + +unsigned ggl_fltdarken(unsigned word, int param) +{ + register int f; + register unsigned int res = 0; + for(f = 0; f < 8; ++f, word >>= 4) { + // filter the pixel here + if(((word & 0xf) + param) >= 0xf) + res |= 0xf; + else + res |= (word & 0xf) + param; + + res = (res >> 4) | (res << 28); + + } + return res; +} diff --git a/firmware/ggl/cgl/cgl_fltinvert.c b/firmware/ggl/cgl/cgl_fltinvert.c new file mode 100644 index 0000000..f3f1806 --- /dev/null +++ b/firmware/ggl/cgl/cgl_fltinvert.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +unsigned int ggl_fltinvert(unsigned word, int param) +{ + (void)param; // THIS IS JUST TO SILENCE THE UNUSED ARGUMENT WARNING + + register int f; + register unsigned int res = 0; + for(f = 0; f < 8; ++f, word >>= 4) { + // filter the pixel here + res |= 0xf - (word & 0xf); + + res = (res >> 4) | (res << 28); + } + return res; +} diff --git a/firmware/ggl/cgl/cgl_fltlighten.c b/firmware/ggl/cgl/cgl_fltlighten.c new file mode 100644 index 0000000..d28b9e8 --- /dev/null +++ b/firmware/ggl/cgl/cgl_fltlighten.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +unsigned int ggl_fltlighten(unsigned word, int param) +{ + register int f; + register unsigned int res = 0; + for(f = 0; f < 8; ++f, word >>= 4) { + // filter the pixel here + if((word & 0xf) > (unsigned)param) + res |= (word & 0xf) - param; + + res = (res >> 4) | (res << 28); + } + return res; +} diff --git a/firmware/ggl/cgl/cgl_fltreplace.c b/firmware/ggl/cgl/cgl_fltreplace.c new file mode 100644 index 0000000..133a3e6 --- /dev/null +++ b/firmware/ggl/cgl/cgl_fltreplace.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ +#include + +// param = 0xMN where M is the color to replace, N is the color to replace with. +unsigned ggl_fltreplace(unsigned word, int param) +{ + register int f; + register unsigned int res = 0; + for(f = 0; f < 8; ++f, word >>= 4) { + // filter the pixel here + if(((word & 0xf) == ((param >> 4) & 0xf))) + res |= (param & 0xf); + else + res |= (word & 0xf); + + res = (res >> 4) | (res << 28); + + } + return res; +} diff --git a/firmware/ggl/cgl/cgl_getnib.c b/firmware/ggl/cgl/cgl_getnib.c new file mode 100644 index 0000000..1c32b2f --- /dev/null +++ b/firmware/ggl/cgl/cgl_getnib.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +int ggl_getnib(int *buf, int addr) +{ + register char *ptr = ((char *)buf) + (addr >> 1); + register int a = (int)(*ptr); + if(addr & 1) + a >>= 4; + return a & 0xf; +} + +int ggl_getmonopix(char *buf, int addr) +{ + register char *ptr = ((char *)buf) + (addr >> 3); + return (*ptr & (1 << (addr & 7))) ? 1 : 0; +} diff --git a/firmware/ggl/cgl/cgl_hblitoper.c b/firmware/ggl/cgl/cgl_hblitoper.c new file mode 100644 index 0000000..c1074ec --- /dev/null +++ b/firmware/ggl/cgl/cgl_hblitoper.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_hbltoper(int *dest, int destoff, int *src, int srcoff, int npixels, + int param, ggloperator foperator) +{ + +// SAME AS hblt BUT THIS ONE APPLIES AN ARBITRARY OPERATOR BETWEEN 2 SURFACES +// COPIES npixels NIBBLES FROM src TO dest +// dest AND src ARE WORD ALIGNED ADDRESSES +// destoff AND srcoff ARE OFFSETS IN NIBBLES (PIXELS) FROM dest AND src +// tcolor INDICATES WHICH OF THE 16 COLORS IS TRANSPARENT +// RESTRICTIONS: +// npixels<=512 (NO CHECKS MADE HERE) + + while(npixels > 504) { + ggl_hbltoper(dest, destoff, src, srcoff, 504, param, foperator); + npixels -= 504; + destoff += 504; + srcoff += 504; + } + + int tempmem[HBLT_BUFFER]; + + // CALCULATE ROTATION + int rot = ((srcoff & 7) - (destoff & 7)) * 4; + unsigned a, b = 0; + int *ptr = tempmem, *start = src + (srcoff >> 3), *end = + src + ((srcoff + npixels - 1) >> 3); + + // FIRST STAGE: COPY AND ROTATION + + ++end; + if(rot < 0) { + // ROTATION RIGHT + rot = -rot; + while(start <= end) { + a = *start; + *ptr = (a << rot) | (b >> (32 - rot)); + b = a; + ++ptr; + ++start; + } + } + else if(rot > 0) { + // ROTATION LEFT + b = *start; + ++start; + while(start <= end) { + a = *start; + *ptr = (b >> rot) | (a << (32 - rot)); + b = a; + ++ptr; + ++start; + } + } + else { + // ROTATION IS ZERO, JUST COPY + while(start <= end) { + *ptr = *start; + ++ptr; + ++start; + } + } + + // SECOND STAGE: MASK AND UPDATE + + int ml = ggl_leftmask(destoff), mr = ggl_rightmask(destoff + npixels - 1); + ptr = tempmem; + start = dest + (destoff >> 3); + end = dest + ((destoff + npixels - 1) >> 3); + + if(start == end) { + // single word operation + ml |= mr; + *start = (*start & ml) | (((*foperator) (*start, *ptr, param)) & (~ml)); + return; + } + + *start = (*start & ml) | (((*foperator) (*start, *ptr, param)) & (~ml)); + ++start; + ++ptr; + + while(start != end) { + *start = (*foperator) (*start, *ptr, param); + ++start; + ++ptr; + } + + *start = (*start & mr) | (((*foperator) (*start, *ptr, param)) & (~mr)); + +} + +// TABLE TO EXPAND MONOCHROME BITMAP TO 16-GRAYS + +const unsigned int const ggl_mono2gray[256] = { + 0x0, + 0xF, 0xF0, 0xFF, 0xF00, 0xF0F, 0xFF0, 0xFFF, 0xF000, 0xF00F, 0xF0F0, 0xF0FF, + 0xFF00, 0xFF0F, 0xFFF0, 0xFFFF, 0xF0000, + 0xF000F, 0xF00F0, 0xF00FF, 0xF0F00, 0xF0F0F, 0xF0FF0, 0xF0FFF, 0xFF000, + 0xFF00F, 0xFF0F0, 0xFF0FF, 0xFFF00, 0xFFF0F, 0xFFFF0, 0xFFFFF, + 0xF00000, + 0xF0000F, 0xF000F0, 0xF000FF, 0xF00F00, 0xF00F0F, 0xF00FF0, 0xF00FFF, + 0xF0F000, 0xF0F00F, 0xF0F0F0, 0xF0F0FF, 0xF0FF00, 0xF0FF0F, + 0xF0FFF0, 0xF0FFFF, 0xFF0000, + 0xFF000F, 0xFF00F0, 0xFF00FF, 0xFF0F00, 0xFF0F0F, 0xFF0FF0, 0xFF0FFF, + 0xFFF000, 0xFFF00F, 0xFFF0F0, 0xFFF0FF, 0xFFFF00, 0xFFFF0F, + 0xFFFFF0, 0xFFFFFF, 0xF000000, + 0xF00000F, 0xF0000F0, 0xF0000FF, 0xF000F00, 0xF000F0F, 0xF000FF0, 0xF000FFF, + 0xF00F000, 0xF00F00F, 0xF00F0F0, 0xF00F0FF, 0xF00FF00, 0xF00FF0F, + 0xF00FFF0, 0xF00FFFF, 0xF0F0000, + 0xF0F000F, 0xF0F00F0, 0xF0F00FF, 0xF0F0F00, 0xF0F0F0F, 0xF0F0FF0, 0xF0F0FFF, + 0xF0FF000, 0xF0FF00F, 0xF0FF0F0, 0xF0FF0FF, 0xF0FFF00, 0xF0FFF0F, + 0xF0FFFF0, 0xF0FFFFF, 0xFF00000, + 0xFF0000F, 0xFF000F0, 0xFF000FF, 0xFF00F00, 0xFF00F0F, 0xFF00FF0, 0xFF00FFF, + 0xFF0F000, 0xFF0F00F, 0xFF0F0F0, 0xFF0F0FF, 0xFF0FF00, 0xFF0FF0F, + 0xFF0FFF0, 0xFF0FFFF, 0xFFF0000, + 0xFFF000F, 0xFFF00F0, 0xFFF00FF, 0xFFF0F00, 0xFFF0F0F, 0xFFF0FF0, 0xFFF0FFF, + 0xFFFF000, 0xFFFF00F, 0xFFFF0F0, 0xFFFF0FF, 0xFFFFF00, 0xFFFFF0F, + 0xFFFFFF0, 0xFFFFFFF, 0xF0000000, + 0xF000000F, 0xF00000F0, 0xF00000FF, 0xF0000F00, 0xF0000F0F, 0xF0000FF0, + 0xF0000FFF, 0xF000F000, 0xF000F00F, 0xF000F0F0, 0xF000F0FF, + 0xF000FF00, 0xF000FF0F, 0xF000FFF0, 0xF000FFFF, 0xF00F0000, + 0xF00F000F, 0xF00F00F0, 0xF00F00FF, 0xF00F0F00, 0xF00F0F0F, 0xF00F0FF0, + 0xF00F0FFF, 0xF00FF000, 0xF00FF00F, 0xF00FF0F0, 0xF00FF0FF, + 0xF00FFF00, 0xF00FFF0F, 0xF00FFFF0, 0xF00FFFFF, 0xF0F00000, + 0xF0F0000F, 0xF0F000F0, 0xF0F000FF, 0xF0F00F00, 0xF0F00F0F, 0xF0F00FF0, + 0xF0F00FFF, 0xF0F0F000, 0xF0F0F00F, 0xF0F0F0F0, 0xF0F0F0FF, + 0xF0F0FF00, 0xF0F0FF0F, 0xF0F0FFF0, 0xF0F0FFFF, 0xF0FF0000, + 0xF0FF000F, 0xF0FF00F0, 0xF0FF00FF, 0xF0FF0F00, 0xF0FF0F0F, 0xF0FF0FF0, + 0xF0FF0FFF, 0xF0FFF000, 0xF0FFF00F, 0xF0FFF0F0, 0xF0FFF0FF, + 0xF0FFFF00, 0xF0FFFF0F, 0xF0FFFFF0, 0xF0FFFFFF, 0xFF000000, + 0xFF00000F, 0xFF0000F0, 0xFF0000FF, 0xFF000F00, 0xFF000F0F, 0xFF000FF0, + 0xFF000FFF, 0xFF00F000, 0xFF00F00F, 0xFF00F0F0, 0xFF00F0FF, + 0xFF00FF00, 0xFF00FF0F, 0xFF00FFF0, 0xFF00FFFF, 0xFF0F0000, + 0xFF0F000F, 0xFF0F00F0, 0xFF0F00FF, 0xFF0F0F00, 0xFF0F0F0F, 0xFF0F0FF0, + 0xFF0F0FFF, 0xFF0FF000, 0xFF0FF00F, 0xFF0FF0F0, 0xFF0FF0FF, + 0xFF0FFF00, 0xFF0FFF0F, 0xFF0FFFF0, 0xFF0FFFFF, 0xFFF00000, + 0xFFF0000F, 0xFFF000F0, 0xFFF000FF, 0xFFF00F00, 0xFFF00F0F, 0xFFF00FF0, + 0xFFF00FFF, 0xFFF0F000, 0xFFF0F00F, 0xFFF0F0F0, 0xFFF0F0FF, + 0xFFF0FF00, 0xFFF0FF0F, 0xFFF0FFF0, 0xFFF0FFFF, 0xFFFF0000, + 0xFFFF000F, 0xFFFF00F0, 0xFFFF00FF, 0xFFFF0F00, 0xFFFF0F0F, 0xFFFF0FF0, + 0xFFFF0FFF, 0xFFFFF000, 0xFFFFF00F, 0xFFFFF0F0, 0xFFFFF0FF, + 0xFFFFFF00, 0xFFFFFF0F, 0xFFFFFFF0, 0xFFFFFFFF +}; + +void ggl_monohbltoper(int *dest, int destoff, unsigned char *src, int srcoff, + int npixels, int param, ggloperator foperator) +{ + +// SAME AS hbltoper BUT SOURCE BITMAP IS MONOCHROME, AND CONVERTED TO 16-GRAYS ON-THE-FLY +// COPIES npixels NIBBLES FROM src TO dest +// dest IS WORD ALIGNED ADDRESSES, src IS BYTE ALIGNED +// destoff AND srcoff ARE OFFSETS IN NIBBLES (PIXELS) FROM dest AND src +// tcolor INDICATES WHICH OF THE 16 COLORS IS TRANSPARENT +// RESTRICTIONS: +// npixels<=512 (NO CHECKS MADE HERE) + + while(npixels > 504) { + ggl_monohbltoper(dest, destoff, src, srcoff, 504, param, foperator); + npixels -= 504; + destoff += 504; + srcoff += 504; + } + + int tempmem[HBLT_BUFFER]; + + // CALCULATE ROTATION + int rot = ((srcoff & 7) - (destoff & 7)) * 4; + unsigned a, b = 0; + int *ptr = tempmem, *dstart, *dend; + unsigned char *start = src + (srcoff >> 3), *end = + src + ((srcoff + npixels - 1) >> 3); + + // FIRST STAGE: COPY AND ROTATION + + ++end; + if(rot < 0) { + // ROTATION RIGHT + rot = -rot; + while(start <= end) { + a = ggl_mono2gray[*start]; + *ptr = (a << rot) | (b >> (32 - rot)); + b = a; + ++ptr; + ++start; + } + } + else if(rot > 0) { + // ROTATION LEFT + b = ggl_mono2gray[*start]; + ++start; + while(start <= end) { + a = ggl_mono2gray[*start]; + *ptr = (b >> rot) | (a << (32 - rot)); + b = a; + ++ptr; + ++start; + } + } + else { + // ROTATION IS ZERO, JUST COPY + while(start <= end) { + *ptr = ggl_mono2gray[*start]; + ++ptr; + ++start; + } + } + + // SECOND STAGE: MASK AND UPDATE + + int ml = ggl_leftmask(destoff), mr = ggl_rightmask(destoff + npixels - 1); + ptr = tempmem; + dstart = dest + (destoff >> 3); + dend = dest + ((destoff + npixels - 1) >> 3); + + if(dstart == dend) { + // single word operation + ml |= mr; + *dstart = + (*dstart & ml) | (((*foperator) (*dstart, *ptr, + param)) & (~ml)); + return; + } + + *dstart = (*dstart & ml) | (((*foperator) (*dstart, *ptr, param)) & (~ml)); + ++dstart; + ++ptr; + + while(dstart != dend) { + *dstart = (*foperator) (*dstart, *ptr, param); + ++dstart; + ++ptr; + } + + *dstart = (*dstart & mr) | (((*foperator) (*dstart, *ptr, param)) & (~mr)); + +} diff --git a/firmware/ggl/cgl/cgl_hblt.c b/firmware/ggl/cgl/cgl_hblt.c new file mode 100644 index 0000000..5269164 --- /dev/null +++ b/firmware/ggl/cgl/cgl_hblt.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_hblt(int *dest, int destoff, int *src, int srcoff, int npixels) +{ + +// COPIES npixels NIBBLES FROM src TO dest +// dest AND src ARE WORD ALIGNED ADDRESSES +// destoff AND srcoff ARE OFFSETS IN NIBBLES (PIXELS) FROM dest AND src + + while(npixels > 504) { + ggl_hblt(dest, destoff, src, srcoff, 504); + npixels -= 504; + destoff += 504; + srcoff += 504; + } + + int tempmem[HBLT_BUFFER]; + + // CALCULATE ROTATION + int rot = ((srcoff & 7) - (destoff & 7)) * 4; + unsigned a, b = 0; + int *ptr = tempmem, *start = src + (srcoff >> 3), *end = + src + ((srcoff + npixels - 1) >> 3); + + // FIRST STAGE: COPY AND ROTATION + + ++end; + if(rot < 0) { + // ROTATION RIGHT + rot = -rot; + while(start <= end) { + a = *start; + *ptr = (a << rot) | (b >> (32 - rot)); + b = a; + ++ptr; + ++start; + } + } + else if(rot > 0) { + // ROTATION LEFT + b = *start; + ++start; + while(start <= end) { + a = *start; + *ptr = (b >> rot) | (a << (32 - rot)); + b = a; + ++ptr; + ++start; + } + } + else { + // ROTATION IS ZERO, JUST COPY + while(start <= end) { + *ptr = *start; + ++ptr; + ++start; + } + } + + // SECOND STAGE: MASK AND UPDATE + + int ml = ggl_leftmask(destoff), mr = ggl_rightmask(destoff + npixels - 1); + ptr = tempmem; + start = dest + (destoff >> 3); + end = dest + ((destoff + npixels - 1) >> 3); + + if(start == end) { + // single word operation + ml |= mr; + *start = (*start & ml) | (*ptr & (~ml)); + return; + } + + *start = (*start & ml) | (*ptr & (~ml)); + ++start; + ++ptr; + + while(start != end) { + *start = *ptr; + ++start; + ++ptr; + } + + *start = (*start & mr) | (*ptr & (~mr)); + +} diff --git a/firmware/ggl/cgl/cgl_hbltfilter.c b/firmware/ggl/cgl/cgl_hbltfilter.c new file mode 100644 index 0000000..052a2a4 --- /dev/null +++ b/firmware/ggl/cgl/cgl_hbltfilter.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_hbltfilter(int *dest, int destoff, int npixels, int param, + gglfilter filterfunc) +{ + +// APPLIES A UNARY OPERATOR (A FILTER) TO A SERIES OF NIBBLES +// THE OPERATOR SHOULD ACT WORD BY WORD +// dest IS A WORD ALIGNED ADDRESSES +// destoff OFFSET IN NIBBLES (PIXELS) FROM dest +// param IS AN ARBITRARY PARAMETER PASSED TO THE FILTER FUNCTION +// filterfunc IS THE CUSTOM FILTER FUNCTION + + int *start, *end; + + // MASK AND UPDATE + + int ml = ggl_leftmask(destoff), mr = ggl_rightmask(destoff + npixels - 1); + start = dest + (destoff >> 3); + end = dest + ((destoff + npixels - 1) >> 3); + + if(start == end) { + // single word operation + ml |= mr; + *start = (*start & ml) | (((*filterfunc) (*start, param)) & (~ml)); + return; + } + + *start = (*start & ml) | (((*filterfunc) (*start, param)) & (~ml)); + ++start; + + while(start != end) { + *start = (*filterfunc) (*start, param); + ++start; + } + + *start = (*start & mr) | (((*filterfunc) (*start, param)) & (~mr)); + +} diff --git a/firmware/ggl/cgl/cgl_hline.c b/firmware/ggl/cgl/cgl_hline.c new file mode 100644 index 0000000..0ae7686 --- /dev/null +++ b/firmware/ggl/cgl/cgl_hline.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +// VERSION DRAWS HORIZONTAL LINES IN A COLOR BITMAP +// Supports 16-bit per pixel RGB555 +// Color is a single color, no pattern supported + +void ggl_hline(gglsurface * srf, int y, int xl, int xr, int color) +{ + // PAINTS A HORIZONTAL LINE FROM xl TO xr BOTH INCLUSIVE + // color=COLORED PATTERN TO USE, 8 PIXELS - 1 NIBBLE PER PIXEL + // PATTERN IS ALWAYS WORD ALIGNED + + // RESTRICTIONS: xr>=xl + // y MUST BE VALID + + int loff = (y * srf->width + xl); + int roff = (y * srf->width + xr); + register int *left = (int *)srf->addr + (loff >> 3); + register int *right = (int *)srf->addr + (roff >> 3); + int ml = ggl_leftmask(loff), mr = ggl_rightmask(roff); + + + + if(left == right) { + // single word operation + ml |= mr; + *left = (*left & ml) | (color & (~ml)); + return; + } + + *left = (*left & ml) | (color & (~ml)); + ++left; + while(left != right) { + *left = color; + ++left; + } + + *right = (*right & mr) | (color & (~mr)); + +} + +void ggl_cliphline(gglsurface * srf, int y, int xl, int xr, int color) +{ + // PAINTS A HORIZONTAL LINE FROM xl TO xr BOTH INCLUSIVE + // color=COLORED PATTERN TO USE, 8 PIXELS - 1 NIBBLE PER PIXEL + // PATTERN IS ALWAYS WORD ALIGNED + + // RESTRICTIONS: xr>=xl + // y MUST BE VALID + + if(y < srf->clipy) + return; + if(y > srf->clipy2) + return; + if(xr < srf->clipx) + return; + if(xl > srf->clipx2) + return; + + if(xl < srf->clipx) + xl = srf->clipx; + if(xr > srf->clipx2) + xr = srf->clipx2; + + int loff = (y * srf->width + xl); + int roff = (y * srf->width + xr); + register int *left = (int *)srf->addr + (loff >> 3); + register int *right = (int *)srf->addr + (roff >> 3); + int ml = ggl_leftmask(loff), mr = ggl_rightmask(roff); + + if(left == right) { + // single word operation + ml |= mr; + *left = (*left & ml) | (color & (~ml)); + return; + } + + *left = (*left & ml) | (color & (~ml)); + ++left; + while(left != right) { + *left = color; + ++left; + } + + *right = (*right & mr) | (color & (~mr)); + +} diff --git a/firmware/ggl/cgl/cgl_initscr.c b/firmware/ggl/cgl/cgl_initscr.c new file mode 100644 index 0000000..bee115c --- /dev/null +++ b/firmware/ggl/cgl/cgl_initscr.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_initscr(gglsurface * srf) +{ + srf->addr = (int *)MEM_PHYS_SCREEN; + srf->width = LCD_W; + srf->x = srf->y = 0; + srf->clipx = srf->clipy = 0; + srf->clipx2 = SCREEN_WIDTH - 1; + srf->clipy2 = SCREEN_HEIGHT - 1; +} diff --git a/firmware/ggl/cgl/cgl_mkcolor.c b/firmware/ggl/cgl/cgl_mkcolor.c new file mode 100644 index 0000000..2f5ace7 --- /dev/null +++ b/firmware/ggl/cgl/cgl_mkcolor.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +int ggl_mkcolor(int color) +{ + // RETURNS A SOLID PATTERN WITH ALL 8 PIXELS SET TO color + color &= 0xf; + color |= color << 4; + color |= color << 8; + color |= color << 16; + + return color; +} diff --git a/firmware/ggl/cgl/cgl_mkcolor32.c b/firmware/ggl/cgl/cgl_mkcolor32.c new file mode 100644 index 0000000..12de554 --- /dev/null +++ b/firmware/ggl/cgl/cgl_mkcolor32.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_mkcolor32(int col, int *pattern) +{ + // RETURNS A DITHERED PATTERN FOR 32 COLORS + // color= from 0 to 30 --> 30 and 31 = both black + int color = col >> 1, mask = (col & 1) ? 0x01010101 : 0; + int c; + color &= 0xf; + color |= color << 4; + color |= color << 8; + color |= color << 16; + + for(c = 0; c < 8; ++c) { + pattern[c] = color + ((c & 1) ? (mask << 4) : mask); + } +} diff --git a/firmware/ggl/cgl/cgl_opmask.c b/firmware/ggl/cgl/cgl_opmask.c new file mode 100644 index 0000000..a8e4511 --- /dev/null +++ b/firmware/ggl/cgl/cgl_opmask.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +unsigned int ggl_opmask(unsigned int dest, unsigned int src, int tcol) +{ + // APPLY 100% TRANSPARENCY MASK + // tcol = TRANSPARENT COLOR IN src + register int f; + register unsigned int res = 0; + for(f = 0; f < 8; ++f, src >>= 4, dest >>= 4) { + if((src & 0xf) == (unsigned int)tcol) + res |= dest & 0xf; + else + res |= src & 0xf; + res = (res >> 4) | (res << 28); + + } + return res; +} + +// COPY src INTO dest, WITH tcol=TRANSPARENT COLOR IN src, AND THEN REPLACE BLACK COLOR IN src +// WITH THE COLOR GIVEN IN newcolor + +unsigned int ggl_opmaskcol(unsigned int dest, unsigned int src, int tcol, + int newcolor) +{ + // APPLY 100% TRANSPARENCY MASK + // tcol = TRANSPARENT COLOR IN src + register int f; + register unsigned int res = 0; + for(f = 0; f < 8; ++f, src >>= 4, dest >>= 4) { + if((src & 0xf) == (unsigned int)tcol) + res |= dest & 0xf; + else + res |= src & newcolor; + res = (res >> 4) | (res << 28); + } + return res; +} diff --git a/firmware/ggl/cgl/cgl_optransp.c b/firmware/ggl/cgl/cgl_optransp.c new file mode 100644 index 0000000..4ac26b4 --- /dev/null +++ b/firmware/ggl/cgl/cgl_optransp.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +unsigned int ggl_optransp(unsigned int dest, unsigned int src, int weight) +{ + // APPLY 100% TRANSPARENCY MASK + // tcol = TRANSPARENT COLOR IN src + register int f; + register unsigned int res = 0; + for(f = 0; f < 8; ++f, src >>= 4, dest >>= 4) { + + res |= ((src & 0xf) * (16 - weight) + (dest & 0xf) * weight) >> 4; + res = (res >> 4) | (res << 28); + + } + return res; +} diff --git a/firmware/ggl/cgl/cgl_ovlblt.c b/firmware/ggl/cgl/cgl_ovlblt.c new file mode 100644 index 0000000..2e23867 --- /dev/null +++ b/firmware/ggl/cgl/cgl_ovlblt.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_ovlblt(gglsurface * dest, gglsurface * src, int width, int height) +{ + +// SAME AS ggl_bitblt BUT WITH OVERLAPPING CHECK +// IT COPIES CORRECTLY WHEN dest AND src ZONES OVERLAP + +// COPIES A RECTANGULAR REGION FROM src TO dest +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + int doff, soff; + int *dst, *dend, *st; //,*send; + +// CHECK FOR OVERLAPPING ZONES + + doff = dest->y * dest->width + dest->x; + soff = src->y * src->width + src->x; + + dst = dest->addr + (doff >> 3); + st = src->addr + (soff >> 3); + dend = dst + ((height * dest->width) >> 3); + //send=st+((height*src->width)>>3); + + if(dst >= st && dst <= dend) + ggl_revblt(dest, src, width, height); + else + ggl_bitblt(dest, src, width, height); +} diff --git a/firmware/ggl/cgl/cgl_pltnib.c b/firmware/ggl/cgl/cgl_pltnib.c new file mode 100644 index 0000000..5d18b66 --- /dev/null +++ b/firmware/ggl/cgl/cgl_pltnib.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_pltnib(int *buf, int addr, int color) +{ + register char *ptr = ((char *)buf) + (addr >> 1); + if(addr & 1) + *ptr = (*ptr & 0xf) | ((color << 4) & 0xf0); + else + *ptr = (*ptr & 0xf0) | (color & 0xf); +} diff --git a/firmware/ggl/cgl/cgl_rect.c b/firmware/ggl/cgl/cgl_rect.c new file mode 100644 index 0000000..92ee981 --- /dev/null +++ b/firmware/ggl/cgl/cgl_rect.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_rect(gglsurface * srf, int x1, int y1, int x2, int y2, int color) +{ +// DRAWS A RECTANGLE BETWEEN x1,y1 and x2,y2 ALL INCLUSIVE +// color CAN BE AN 8-BIT PATTERN THAT REPEATS VERTICALLY +// RESTRICTIONS: +// NO BOUNDARY CHECKS +// y2>=y1 && x2>=x1 + + while(y1 <= y2) { + ggl_hline(srf, y1, x1, x2, color); + ++y1; + } + +} + +void ggl_cliprect(gglsurface * srf, int x1, int y1, int x2, int y2, int color) +{ + // SAME AS ggl_rect BUT WITH CLIPPING + + if(x1 > x2) { + int tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + } + if(y1 > y2) { + int tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + } + + if(x1 > srf->clipx2) + return; + if(y1 > srf->clipy2) + return; + if(y2 < srf->clipy) + return; + if(x2 < srf->clipx) + return; + + if(x1 < srf->clipx) + x1 = srf->clipx; + if(y1 < srf->clipy) + y1 = srf->clipy; + if(x2 > srf->clipx2) + x2 = srf->clipx2; + if(y2 > srf->clipy2) + y2 = srf->clipy2; + + // DRAWS A RECTANGLE BETWEEN x1,y1 and x2,y2 ALL INCLUSIVE + // color CAN BE AN 8-BIT PATTERN THAT REPEATS VERTICALLY + // RESTRICTIONS: + // NO BOUNDARY CHECKS + // y2>=y1 && x2>=x1 + + while(y1 <= y2) { + ggl_hline(srf, y1, x1, x2, color); + ++y1; + } +} diff --git a/firmware/ggl/cgl/cgl_rectp.c b/firmware/ggl/cgl/cgl_rectp.c new file mode 100644 index 0000000..cccd31b --- /dev/null +++ b/firmware/ggl/cgl/cgl_rectp.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_rectp(gglsurface * srf, int x1, int y1, int x2, int y2, int *color) +{ +// DRAWS A RECTANGLE BETWEEN x1,y1 and x2,y2 ALL INCLUSIVE +// color IS AN 8x8-BIT PATTERN (int color[8]) +// RESTRICTIONS: +// NO BOUNDARY CHECKS +// y2>=y1 && x2>=x1 + + while(y1 <= y2) { + ggl_hline(srf, y1, x1, x2, color[y1 & 7]); + ++y1; + } + +} diff --git a/firmware/ggl/cgl/cgl_revblt.c b/firmware/ggl/cgl/cgl_revblt.c new file mode 100644 index 0000000..af0ef6d --- /dev/null +++ b/firmware/ggl/cgl/cgl_revblt.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_revblt(gglsurface * dest, gglsurface * src, int width, int height) +{ +// REVERSE bitblt +// COPIES A RECTANGULAR REGION FROM src TO dest +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + int doff, soff, line; + + doff = dest->y * dest->width + dest->x; + soff = src->y * src->width + src->x; + + // REVERSE LOOP NEEDED + doff += dest->width * height; + soff += src->width * height; + + for(line = 0; line < height; ++line) { + doff -= dest->width; + soff -= src->width; + ggl_hblt(dest->addr, doff, src->addr, soff, width); + } + +} diff --git a/firmware/ggl/cgl/cgl_scrolldn.c b/firmware/ggl/cgl/cgl_scrolldn.c new file mode 100644 index 0000000..60a957c --- /dev/null +++ b/firmware/ggl/cgl/cgl_scrolldn.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_scrolldn(gglsurface * dest, int width, int height, int npixels) +{ + +// SCROLLS A RECTANGULAR REGION DOWN npixels +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + gglsurface srf; + + srf.addr = dest->addr; + srf.width = dest->width; + srf.x = dest->x; + srf.y = dest->y + npixels; + + ggl_revblt(&srf, dest, width, height - npixels); + +} diff --git a/firmware/ggl/cgl/cgl_scrolllf.c b/firmware/ggl/cgl/cgl_scrolllf.c new file mode 100644 index 0000000..0179f57 --- /dev/null +++ b/firmware/ggl/cgl/cgl_scrolllf.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_scrolllf(gglsurface * dest, int width, int height, int npixels) +{ + +// SCROLLS A RECTANGULAR REGION LEFT npixelsup +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + gglsurface srf; + + srf.addr = dest->addr; + srf.width = dest->width; + srf.x = dest->x + npixels; + srf.y = dest->y; + + ggl_bitblt(dest, &srf, width - npixels, height); + +} diff --git a/firmware/ggl/cgl/cgl_scrollrt.c b/firmware/ggl/cgl/cgl_scrollrt.c new file mode 100644 index 0000000..ef7d11b --- /dev/null +++ b/firmware/ggl/cgl/cgl_scrollrt.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_scrollrt(gglsurface * dest, int width, int height, int npixels) +{ + +// SCROLLS A RECTANGULAR REGION RIGHT npixelsup +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + gglsurface srf; + + srf.addr = dest->addr; + srf.width = dest->width; + srf.x = dest->x + npixels; + srf.y = dest->y; + + ggl_bitblt(&srf, dest, width - npixels, height); + +} diff --git a/firmware/ggl/cgl/cgl_scrollup.c b/firmware/ggl/cgl/cgl_scrollup.c new file mode 100644 index 0000000..be8c3f7 --- /dev/null +++ b/firmware/ggl/cgl/cgl_scrollup.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_scrollup(gglsurface * dest, int width, int height, int npixelsup) +{ + +// SCROLLS A RECTANGULAR REGION UP npixelsup +// gglsurface CONTAINS THE BUFFER AND OFFSETS +// width AND height ARE THE SIZE OF THE BLOCK TO MOVE + +// RESTRICTIONS: NO SAFETY CHECKS REGARDING MEMORY MOVEMENTS + + gglsurface srf; + + srf.addr = dest->addr; + srf.width = dest->width; + srf.x = dest->x; + srf.y = dest->y + npixelsup; + + ggl_bitblt(dest, &srf, width, height - npixelsup); + +} diff --git a/firmware/ggl/cgl/cgl_vline.c b/firmware/ggl/cgl/cgl_vline.c new file mode 100644 index 0000000..8c533e6 --- /dev/null +++ b/firmware/ggl/cgl/cgl_vline.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team + * All rights reserved. + * This file is released under the 3-clause BSD license. + * See the file LICENSE.txt that shipped with this distribution. + */ + +#include + +void ggl_vline(gglsurface * srf, int x, int yt, int yb, int color) +{ + // PAINTS A VERTICAL LINE FROM yt TO yb BOTH INCLUSIVE + // color=number from 0 to 15 + // RESTRICTIONS: yb>=yt + + int offset = srf->width * yt + x; + + while(yt <= yb) { + ggl_pltnib(srf->addr, offset, color >> ((yt & 7) << 2)); + offset += srf->width; + ++yt; + } + +} + +// SAME AS VLINE BU WITH CLIPPING +void ggl_clipvline(gglsurface * srf, int x, int yt, int yb, int color) +{ + // PAINTS A VERTICAL LINE FROM yt TO yb BOTH INCLUSIVE + // color=number from 0 to 15 + // RESTRICTIONS: yb>=yt + + if(yt > srf->clipy2) + return; + if(yb < srf->clipy) + return; + + if(yt < srf->clipy) + yt = srf->clipy; + if(yb > srf->clipy2) + yb = srf->clipy2; + + if(x < srf->clipx) + return; + if(x > srf->clipx2) + return; + + int offset = srf->width * yt + x; + + while(yt <= yb) { + ggl_pltnib(srf->addr, offset, color >> ((yt & 7) << 2)); + offset += srf->width; + ++yt; + } + +} diff --git a/firmware/include/hal_api.h b/firmware/include/hal_api.h index 994b045..60667cb 100644 --- a/firmware/include/hal_api.h +++ b/firmware/include/hal_api.h @@ -9,7 +9,7 @@ #define _HAL_API_H #include "newrpl.h" -#include "ggl.h" +#include "xgl.h" #include "usb.h" #ifndef EXTERN diff --git a/firmware/include/target_pc.h b/firmware/include/target_pc.h index b0af46e..9113c67 100644 --- a/firmware/include/target_pc.h +++ b/firmware/include/target_pc.h @@ -71,7 +71,7 @@ extern int __usb_timeout; // USABLE SCREEN WINDOW SIZE #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 -#define PIXELS_PER_WORD 8 +#define PIXELS_PER_WORD 2 // PHYSICAL SCREEN SIZE // WIDTH MUST BE AT LEAST ONE MORE THAN THE WINDOW SIZE @@ -100,8 +100,8 @@ extern int __usb_timeout; #define HAL_USBCLOCK 48000000 #define HAL_FASTCLOCK 192000000 -extern char PhysicalScreen[(SCREEN_W*SCREEN_H)/(PIXELS_PER_WORD/4)]; -extern char ExceptionScreen[(SCREEN_W*SCREEN_H)/(PIXELS_PER_WORD/4)]; +extern char PhysicalScreen[(SCREEN_W*SCREEN_H)*4/PIXELS_PER_WORD]; +extern char ExceptionScreen[(SCREEN_W*SCREEN_H)*4/PIXELS_PER_WORD]; typedef unsigned int INTERRUPT_TYPE; diff --git a/firmware/include/target_prime1.h b/firmware/include/target_prime1.h index 283eeb0..7f18194 100644 --- a/firmware/include/target_prime1.h +++ b/firmware/include/target_prime1.h @@ -770,6 +770,10 @@ #define EP0_TZLS 1 // SHT = STALL HANDHAKE TRANSMITTED BIT #define EP0_SHT 0x10 +// LWO = LAST WORD ODD +#define EP0_LWO 0x40 + + // ESS = ENDPOINT STALL SET #define EP_ESS 2 // FLUSH FIFO diff --git a/firmware/include/xgl.h b/firmware/include/xgl.h new file mode 100644 index 0000000..6df9680 --- /dev/null +++ b/firmware/include/xgl.h @@ -0,0 +1,28 @@ +#ifndef XGL_H +#define XGL_H + +// Select the proper library according to the target (4-bit grayscale or full color) + + +#ifdef TARGET_PC_PRIMEG1 +#include "cgl.h" +#endif + +#ifdef TARGET_PRIME1 +//#include "cgl.h" +#include "ggl.h" +#endif + +#ifdef TARGET_50G +#include "ggl.h" +#endif + +#ifdef TARGET_39GS +#include "ggl.h" +#endif + +#ifdef TARGET_40GS +#include "ggl.h" +#endif + +#endif // XGL_H diff --git a/firmware/sys/target_pc/lcd.c b/firmware/sys/target_pc/lcd.c index 0fea642..b5ec1f0 100644 --- a/firmware/sys/target_pc/lcd.c +++ b/firmware/sys/target_pc/lcd.c @@ -16,8 +16,8 @@ int __lcd_mode = -1; int __lcd_needsupdate = 0; unsigned int *__lcd_buffer; // SIMULATED SCREEN MEMORY -char PhysicalScreen[(SCREEN_W*SCREEN_H)/(PIXELS_PER_WORD/4)]; -char ExceptionScreen[(SCREEN_W*SCREEN_H)/(PIXELS_PER_WORD/4)]; +char PhysicalScreen[(SCREEN_W*SCREEN_H)*4/PIXELS_PER_WORD]; +char ExceptionScreen[(SCREEN_W*SCREEN_H)*4/PIXELS_PER_WORD]; int __lcd_contrast __SYSTEM_GLOBAL__; diff --git a/firmware/sys/target_prime1/usbdriver.c b/firmware/sys/target_prime1/usbdriver.c index 805ca06..661eea9 100644 --- a/firmware/sys/target_prime1/usbdriver.c +++ b/firmware/sys/target_prime1/usbdriver.c @@ -451,6 +451,8 @@ void usb_init(int force) if(!force) return; } + red_led_off(); + green_led_on(); //__usb_intcount=0; @@ -511,7 +513,8 @@ void usb_shutdown() if(!(__usb_drvstatus & USB_STATUS_INIT)) return; - + red_led_on(); + green_led_off(); // MASK INTERRUPT AND REMOVE HANDLER __irq_mask(25); @@ -587,31 +590,42 @@ void usb_ep0_transmit(int newtransmission) *EP0CR&= ~EP0_TZLS; // CLEAR TRANSMIT ZERO PACKET BIT - *BWCR = __usb_ctlcount + __usb_ctlpadding ; // TOTAL BYTES TO TRANSMIT + int total = __usb_ctlcount + __usb_ctlpadding ; + *BWCR = (total>EP0_FIFO_SIZE)? EP0_FIFO_SIZE : total ; // BWCR = WRITE COUNT - IN BYTES DESPITE THE FIFO USING HALF-WORDS *EP0SR= EP_TPS; // CLEAR TRANSMIT PACKET SUCCESS BIT (READY FOR NEXT PACKET) - int cnt = 0; - while(__usb_ctlcount && (cnt < EP0_FIFO_SIZE)) { - *EP0BR = (WORD) * __usb_ctlbufptr; - ++__usb_ctlbufptr; - ++cnt; - --__usb_ctlcount; + int halfword; + while((__usb_ctlcount>1) && (cnt < EP0_FIFO_SIZE)) { + halfword = __usb_ctlbufptr[0] | (__usb_ctlbufptr[1]<<8); + *EP0BR = (WORD) halfword; + __usb_ctlbufptr+=2; + cnt+=2; + __usb_ctlcount-=2; + } + + if(__usb_ctlcount == 1) { + halfword = __usb_ctlbufptr[0] ; // UPPER BYTE IS ZERO + *EP0BR = (WORD) halfword; + __usb_ctlbufptr++; + cnt+=2; + __usb_ctlcount--; + __usb_ctlpadding--; } if(__usb_ctlcount == 0) { // SEND ANY PADDING - while((__usb_ctlpadding != 0) && (cnt < EP0_FIFO_SIZE)) { + while((__usb_ctlpadding > 0) && (cnt < EP0_FIFO_SIZE)) { *EP0BR = 0; - ++cnt; - --__usb_ctlpadding; + cnt+=2; + __usb_ctlpadding-=2; } } if((__usb_ctlcount == 0) && (__usb_ctlpadding == 0)) { - // SEND A 0-LENGTH PACKET + // SEND A 0-LENGTH PACKET TO INDICATE END OF TRANSMISSION *EP0CR |= EP0_TZLS; // SEND A ZERO-LENGTH PACKET @@ -649,13 +663,29 @@ void usb_ep0_receive(int newtransmission) } int cnt = 0; + int halfword; + int lwo = *EP0SR & EP0_LWO; // GET THE LAST WORD ODD BIT BEFORE IT'S AUTOMATICALLY CLEARED + while(__usb_ctlcount && (cnt < EP0_FIFO_SIZE) && (*BRCR&0x1ff)) { - *__usb_ctlbufptr = (BYTE) * EP0BR; - ++__usb_ctlbufptr; - --__usb_ctlcount; - ++cnt; + halfword=*EP0BR; + *__usb_ctlbufptr++ = (BYTE) halfword; + *__usb_ctlbufptr++ = (BYTE) (halfword>>8); + __usb_ctlcount-=2; + cnt+=2; } + if(lwo && (cnt>0) && !(*BRCR&0x1ff)) { + // DISCARD THE LAST BYTE IF THE LAST WORD WAS ODD + __usb_ctlcount++; + __usb_ctlbufptr--; + cnt--; + } + + // THERE WAS EXTRA DATA IN THE PACKET?? + // JUST IN CASE CLEAN THE FIFO + while(*BRCR) halfword=*EP0BR; + + *EP0SR = EP0_RSR; // CLEAR PACKET RECEIVED @@ -726,13 +756,13 @@ void ep0_irqservice() // READ ALL 8 BYTES FROM THE FIFO reqtype = *EP0BR; - request = *EP0BR; + + request = reqtype >> 8; + reqtype &= 0xff; + value = *EP0BR; - value |= (*EP0BR) << 8; index = *EP0BR; - index |= (*EP0BR) << 8; length = *EP0BR; - length |= (*EP0BR) << 8; if((reqtype & 0x60) == 0) // STANDARD REQUESTS { @@ -1486,6 +1516,7 @@ void usb_irqservice() return; __usb_drvstatus |= USB_STATUS_INSIDEIRQ; + blue_led_on(); *IR = 0; @@ -1495,10 +1526,12 @@ void usb_irqservice() if(__usb_drvstatus & (USB_STATUS_EP0TX | USB_STATUS_EP0RX)) ep0_irqservice(); __usb_drvstatus &= ~USB_STATUS_INSIDEIRQ; + *EIR = *EIR; return; } if(*EIR & 1) { + ep0_irqservice(); *EIR = 1; diff --git a/newrpl-ui-prime.pro b/newrpl-ui-prime.pro index 4377e35..0d1c3bf 100644 --- a/newrpl-ui-prime.pro +++ b/newrpl-ui-prime.pro @@ -12,6 +12,33 @@ TEMPLATE = app DEFINES += TARGET_PC TARGET_PC_PRIMEG1 "NEWRPL_BUILDNUM=$$system(git rev-list --count HEAD)" SOURCES += main.cpp\ + firmware/ggl/cgl/cgl_bitblt.c \ + firmware/ggl/cgl/cgl_bitbltoper.c \ + firmware/ggl/cgl/cgl_filter.c \ + firmware/ggl/cgl/cgl_fltdarken.c \ + firmware/ggl/cgl/cgl_fltinvert.c \ + firmware/ggl/cgl/cgl_fltlighten.c \ + firmware/ggl/cgl/cgl_fltreplace.c \ + firmware/ggl/cgl/cgl_getnib.c \ + firmware/ggl/cgl/cgl_hblitoper.c \ + firmware/ggl/cgl/cgl_hblt.c \ + firmware/ggl/cgl/cgl_hbltfilter.c \ + firmware/ggl/cgl/cgl_hline.c \ + firmware/ggl/cgl/cgl_initscr.c \ + firmware/ggl/cgl/cgl_mkcolor.c \ + firmware/ggl/cgl/cgl_mkcolor32.c \ + firmware/ggl/cgl/cgl_opmask.c \ + firmware/ggl/cgl/cgl_optransp.c \ + firmware/ggl/cgl/cgl_ovlblt.c \ + firmware/ggl/cgl/cgl_pltnib.c \ + firmware/ggl/cgl/cgl_rect.c \ + firmware/ggl/cgl/cgl_rectp.c \ + firmware/ggl/cgl/cgl_revblt.c \ + firmware/ggl/cgl/cgl_scrolldn.c \ + firmware/ggl/cgl/cgl_scrolllf.c \ + firmware/ggl/cgl/cgl_scrollrt.c \ + firmware/ggl/cgl/cgl_scrollup.c \ + firmware/ggl/cgl/cgl_vline.c \ firmware/hal_battery_primeg1.c \ firmware/sys/Font18.c \ firmware/sys/Font24.c \ @@ -20,31 +47,6 @@ SOURCES += main.cpp\ newrpl/lib-112-asm.c \ newrpl/lib-4081-tags.c \ qemuscreen.cpp \ - firmware/ggl/ggl/ggl_bitblt.c \ - firmware/ggl/ggl/ggl_bitbltoper.c \ - firmware/ggl/ggl/ggl_filter.c \ - firmware/ggl/ggl/ggl_fltdarken.c \ - firmware/ggl/ggl/ggl_fltlighten.c \ - firmware/ggl/ggl/ggl_getnib.c \ - firmware/ggl/ggl/ggl_hblt.c \ - firmware/ggl/ggl/ggl_hbltfilter.c \ - firmware/ggl/ggl/ggl_hbltoper.c \ - firmware/ggl/ggl/ggl_hline.c \ - firmware/ggl/ggl/ggl_initscr.c \ - firmware/ggl/ggl/ggl_mkcolor.c \ - firmware/ggl/ggl/ggl_mkcolor32.c \ - firmware/ggl/ggl/ggl_opmask.c \ - firmware/ggl/ggl/ggl_optransp.c \ - firmware/ggl/ggl/ggl_ovlblt.c \ - firmware/ggl/ggl/ggl_pltnib.c \ - firmware/ggl/ggl/ggl_rect.c \ - firmware/ggl/ggl/ggl_rectp.c \ - firmware/ggl/ggl/ggl_revblt.c \ - firmware/ggl/ggl/ggl_scrolldn.c \ - firmware/ggl/ggl/ggl_scrolllf.c \ - firmware/ggl/ggl/ggl_scrollrt.c \ - firmware/ggl/ggl/ggl_scrollup.c \ - firmware/ggl/ggl/ggl_vline.c \ firmware/hal_keyboard_primeg1.c \ firmware/hal_screen_primeg1.c \ firmware/sys/graphics.c \ @@ -195,13 +197,11 @@ SOURCES += main.cpp\ newrpl/lib-20-comments.c \ firmware/sys/target_pc/flash.c \ firmware/ui_softmenu.c \ - firmware/ggl/ggl/ggl_fltinvert.c \ newrpl/lib-48-angles.c \ newrpl/lib-74-sdcard.c \ firmware/sys/target_pc/rtc.c \ firmware/hal_clock.c \ firmware/hal_alarm.c \ - firmware/ggl/ggl/ggl_fltreplace.c \ newrpl/lib-76-ui.c \ newrpl/lib-zero-messages.c \ firmware/ui_forms.c \ @@ -234,9 +234,10 @@ SOURCES += main.cpp\ HEADERS += mainwindow.h \ + firmware/include/cgl.h \ firmware/include/usb.h \ + firmware/include/xgl.h \ qemuscreen.h \ - firmware/include/ggl.h \ firmware/include/ui.h \ firmware/include/hal_api.h \ newrpl/libraries.h \