summaryrefslogtreecommitdiff
path: root/agbx
diff options
context:
space:
mode:
Diffstat (limited to 'agbx')
-rw-r--r--agbx/GNUmakefile30
-rw-r--r--agbx/include-private/ax/priv.h19
-rw-r--r--agbx/include/ax/bs.h17
-rw-r--r--agbx/include/ax/gfx.h40
-rw-r--r--agbx/source/bs/done.c22
-rw-r--r--agbx/source/gfx/clrscrn.c24
-rw-r--r--agbx/source/gfx/clrscrn.cc23
-rw-r--r--agbx/source/gfx/plot.c29
-rw-r--r--agbx/source/gfx/plottex.c36
-rw-r--r--agbx/source/gfx/plottex.cc29
-rw-r--r--agbx/source/gfx/rd.c24
-rw-r--r--agbx/source/gfx/rd.s (renamed from agbx/source/gfx/getpx.s)8
-rw-r--r--agbx/source/gfx/setpx.c31
13 files changed, 153 insertions, 179 deletions
diff --git a/agbx/GNUmakefile b/agbx/GNUmakefile
index c2e1ae7..33db079 100644
--- a/agbx/GNUmakefile
+++ b/agbx/GNUmakefile
@@ -5,13 +5,34 @@
# TOOLS
AS := arm-none-eabi-as
+#CC := arm-none-eabi-gcc -Dbool="_Bool" -Dfalse="((_Bool)+0x0u)" -Dfalse="((_Bool)+0x0u)"
CC := clang --target=arm-none-eabi
-#CC := arm-none-eabi-gcc
+#CXX := arm-none-eabi-g++
+CXX := clang++ --target=arm-none-eabi
OBJCOPY := arm-none-eabi-objcopy
# TOOL FLAGS
-CFLAGS := \
+CFLAGS := \
+ -Iinclude \
+ -Iinclude-private \
+ -Ofast \
+ -Wall \
+ -Wextra \
+ -Wpedantic \
+ -Wno-gnu-binary-literal \
+ -Wno-gnu-empty-initializer \
+ -ffreestanding \
+ -fno-builtin \
+ -fno-strict-aliasing \
+ -fshort-enums \
+ -mcpu=arm7tdmi \
+ -mthumb \
+ -mtune=arm7tdmi \
+ -nostdlib \
+ -std=c2x
+
+CXXFLAGS := \
-Iinclude \
-Iinclude-private \
-Ofast \
@@ -20,13 +41,14 @@ CFLAGS := \
-Wpedantic \
-ffreestanding \
-fno-builtin \
+ -fno-exceptions \
-fno-strict-aliasing \
-fshort-enums \
-mcpu=arm7tdmi \
-mthumb \
-mtune=arm7tdmi \
-nostdlib \
- -std=c2x
+ -std=c++2b
# HEADERS
@@ -46,12 +68,10 @@ OBJS := \
source/bs/set.o \
source/gfx/clrscrn.o \
source/gfx/flip.o \
- source/gfx/getpx.o \
source/gfx/getvbnk.o \
source/gfx/plot.o \
source/gfx/plottex.o \
source/gfx/rd.o \
- source/gfx/setpx.o \
source/gfx/vsync.o \
source/key/getkeymap.o \
source/priv/init.o
diff --git a/agbx/include-private/ax/priv.h b/agbx/include-private/ax/priv.h
index 382a7ee..677d77f 100644
--- a/agbx/include-private/ax/priv.h
+++ b/agbx/include-private/ax/priv.h
@@ -9,6 +9,10 @@
#include <ax/bs.h>
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
#define __ax_get10(_addr) (*(ax_i01 volatile *)_addr)
#define __ax_get20(_addr) (*(ax_i02 volatile *)_addr)
@@ -21,9 +25,22 @@
#define __ax_set8(_addr,_val) ((void)(*(ax_i8 volatile *)_addr = _val))
-#define __ax_setpx2(_vaddr,_px,_col) { \
+#define __ax_plot2(_vaddr,_px,_col) { \
ax_i02 const addr = _vaddr + _px * 0x2u; /* We multiply it by two as each pixel takes up two bytes. */ \
__ax_set10(addr,_col); \
}
+#if defined(__cplusplus)
+}
+#endif
+
+#if defined(__cplusplus)
+
+template<typename _ltyp,typename _rtyp> struct __ax_typeqimpl {constexpr static bool eq = false;};
+template<typename _typ> struct __ax_typeqimpl<_typ,_typ> {constexpr static bool eq = true;};
+
+template<typename _ltyp,typename _rtyp> constexpr bool __ax_typeq = ::__ax_typeqimpl<_ltyp,_rtyp>::eq;
+
+#endif
+
#endif
diff --git a/agbx/include/ax/bs.h b/agbx/include/ax/bs.h
index 9f27d8f..88c632a 100644
--- a/agbx/include/ax/bs.h
+++ b/agbx/include/ax/bs.h
@@ -7,8 +7,14 @@
#if !defined(__ax_hdr_bs)
#define __ax_hdr_bs
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if !defined(__cplusplus)
/* C23 compatibility: */
#define constexpr static const
+#endif
typedef unsigned short ax_i01;
typedef unsigned int ax_i02;
@@ -26,7 +32,12 @@ typedef enum {
ax_err_max = 0xFFu,
} ax_err;
-constexpr ax_i04 ax_ver = 0x7u;
+constexpr ax_i04 ax_ver = 0x8u;
+
+constexpr ax_i8 ax_scrnw3 = 0xF0u;
+constexpr ax_i8 ax_scrnw5 = 0xA0u;
+constexpr ax_i8 ax_scrnh3 = 0xA0u;
+constexpr ax_i8 ax_scrnh5 = 0x80u;
[[noreturn]] void ax_done(ax_err err);
@@ -38,4 +49,8 @@ void ax_set10(ax_i02 addr,ax_i01 val);
void ax_set20(ax_i02 addr,ax_i02 val);
void ax_set8( ax_i02 addr,ax_i8 val);
+#if defined(__cplusplus)
+}
+#endif
+
#endif
diff --git a/agbx/include/ax/gfx.h b/agbx/include/ax/gfx.h
index b3830d6..d9fa1b7 100644
--- a/agbx/include/ax/gfx.h
+++ b/agbx/include/ax/gfx.h
@@ -9,34 +9,34 @@
#include <ax/bs.h>
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define ax_coord3(_x,_y) ((ax_i01)_y * ax_scrnw3 + (ax_i01)_x)
+#define ax_coord5(_x,_y) ((ax_i01)_y * ax_scrnw5 + (ax_i01)_x)
+
ax_i02 ax_flip( void);
ax_i02 ax_getvbnk(void);
void ax_vsync( void);
-void ax_setpx1(ax_i02 vaddr,ax_i01 px,ax_i8 col);
-void ax_setpx2(ax_i02 vaddr,ax_i01 px,ax_i01 col);
+void ax_clrscrn1(ax_i02 vaddr,ax_i8 col);
+void ax_clrscrn2(ax_i02 vaddr,ax_i01 col);
-ax_i8 ax_getpx1(ax_i02 vaddr,ax_i01 px);
-ax_i01 ax_getpx2(ax_i02 vaddr,ax_i01 px);
+void ax_plot1(ax_i02 vaddr,ax_i01 px, ax_i8 col);
+void ax_plot2(ax_i02 vaddr,ax_i01 px, ax_i01 col);
-void ax_clrscrn3(ax_i01 col);
-void ax_clrscrn4(ax_i02 vaddr,ax_i8 col);
-void ax_clrscrn5(ax_i02 vaddr,ax_i01 col);
+void ax_plottex1(ax_i02 vaddr,ax_i8 scrnw,ax_i8 const * tex,ax_i01 px,ax_i8 w,ax_i8 h);
+void ax_plottex2(ax_i02 vaddr,ax_i8 scrnw,ax_i01 const * tex,ax_i01 px,ax_i8 w,ax_i8 h);
-void ax_plot3(ax_i8 x, ax_i8 y,ax_i01 col);
-void ax_plot4(ax_i02 vaddr,ax_i8 x,ax_i8 y, ax_i8 col);
-void ax_plot5(ax_i02 vaddr,ax_i8 x,ax_i8 y, ax_i01 col);
+ax_i8 ax_rd1(ax_i02 vaddr,ax_i01 px);
+ax_i01 ax_rd2(ax_i02 vaddr,ax_i01 px);
-void ax_plottex3(ax_i01 const * tex, ax_i8 x, ax_i8 y,ax_i8 w,ax_i8 h);
-void ax_plottex4(ax_i02 vaddr,ax_i8 const * tex,ax_i8 x,ax_i8 y,ax_i8 w,ax_i8 h);
-void ax_plottex5(ax_i02 vaddr,ax_i01 const * tex,ax_i8 x,ax_i8 y,ax_i8 w,ax_i8 h);
+void ax_cir1(ax_i02 vaddr,ax_i8 scrnw,ax_i01 px,ax_i8 r,ax_i8 col);
+void ax_cir2(ax_i02 vaddr,ax_i8 scrnw,ax_i01 px,ax_i8 r,ax_i01 col);
-ax_i01 ax_rd3(ax_i8 x, ax_i8 y);
-ax_i8 ax_rd4(ax_i02 vaddr,ax_i8 x,ax_i8 y);
-ax_i01 ax_rd5(ax_i02 vaddr,ax_i8 x,ax_i8 y);
-
-void ax_cir3(ax_i8 x, ax_i8 y,ax_i8 r);
-void ax_cir4(ax_i02 vaddr,ax_i8 x,ax_i8 y,ax_i8 r);
-void ax_cir5(ax_i02 vaddr,ax_i8 x,ax_i8 y,ax_i8 r);
+#if defined(__cplusplus)
+}
+#endif
#endif
diff --git a/agbx/source/bs/done.c b/agbx/source/bs/done.c
index 0bb0a3c..17b55c6 100644
--- a/agbx/source/bs/done.c
+++ b/agbx/source/bs/done.c
@@ -15,28 +15,6 @@ void ax_done(ax_err const _err) {
);
__builtin_unreachable();
}
- /* Display the barcode-like error message: */
- ax_set10(0x400'0000u,0x404u);
- ax_set10(0x500'0000u,0x0u);
- ax_set10(0x500'0002u,0b11111u);
- ax_i8 err[0xBu];
- for (ax_i8 pos = 0x0u;pos != 0x8u;++pos) {err[pos] = (ax_i8)_err >> pos & 0x1u;}
- err[0x8u] = 0x0u;
- err[0x9u] = 0x1u;
- err[0xAu] = 0x0u;
- for (ax_i01 pos = 0x0u;pos != 0x9600u;pos += 0xF0u) {
- ax_setpx1(0x600'0000u,pos, err[0x0u]);
- ax_setpx1(0x600'0000u,pos + 0x1u,err[0x1u]);
- ax_setpx1(0x600'0000u,pos + 0x2u,err[0x2u]);
- ax_setpx1(0x600'0000u,pos + 0x3u,err[0x3u]);
- ax_setpx1(0x600'0000u,pos + 0x4u,err[0x4u]);
- ax_setpx1(0x600'0000u,pos + 0x5u,err[0x5u]);
- ax_setpx1(0x600'0000u,pos + 0x6u,err[0x6u]);
- ax_setpx1(0x600'0000u,pos + 0x7u,err[0x7u]);
- ax_setpx1(0x600'0000u,pos + 0x8u,err[0x8u]);
- ax_setpx1(0x600'0000u,pos + 0x9u,err[0x9u]);
- ax_setpx1(0x600'0000u,pos + 0xAu,err[0xAu]);
- }
__asm__ (
"svc 0x2\n"
);
diff --git a/agbx/source/gfx/clrscrn.c b/agbx/source/gfx/clrscrn.c
deleted file mode 100644
index cd9a7b3..0000000
--- a/agbx/source/gfx/clrscrn.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- Copyright 2022 Gabriel Jensen.
- This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>.
-*/
-
-#include <ax/priv.h>
-
-#include <ax/gfx.h>
-
-void ax_clrscrn3(ax_i01 const _col) {
- ax_i02 const val = (ax_i02)_col | (ax_i02)_col << 0x10u;
- for (ax_i02 addr = 0x600'0000u;addr != 0x601'2C00u;addr += 0x4u) {__ax_set20(addr,val);}
-}
-
-void ax_clrscrn4(ax_i02 const _vaddr,ax_i8 const _col) {
- ax_i02 const val = (ax_i02)_col | (ax_i02)_col << 0x8u | (ax_i02)_col << 0x10u | (ax_i02)_col << 0x18u;
- for (ax_i02 addr = _vaddr;addr != _vaddr + 0x9600u;addr += 0x4u) {__ax_set20(addr,val);}
-}
-
-void ax_clrscrn5(ax_i02 const _vaddr,ax_i01 const _col) {
- ax_i02 const val = (ax_i02)_col | (ax_i02)_col << 0x10u;
- for (ax_i02 addr = _vaddr;addr != _vaddr + 0xA000u;addr += 0x4u) {__ax_set20(addr,val);}
-}
diff --git a/agbx/source/gfx/clrscrn.cc b/agbx/source/gfx/clrscrn.cc
new file mode 100644
index 0000000..8f27268
--- /dev/null
+++ b/agbx/source/gfx/clrscrn.cc
@@ -0,0 +1,23 @@
+/*
+ Copyright 2022 Gabriel Jensen.
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>.
+*/
+
+#include <ax/priv.h>
+
+#include <ax/gfx.h>
+
+template<typename _pxtyp> [[gnu::always_inline]] inline static auto __ax_clrscrn(::ax_i02 const _vaddr,_pxtyp const _col) noexcept -> void {
+ static_assert(::__ax_typeq<_pxtyp,::ax_i8> || ::__ax_typeq<_pxtyp,::ax_i01>);
+ ::ax_i02 const val = [&_col] {
+ if constexpr (::__ax_typeq<_pxtyp,::ax_i01>) {
+ return (ax_i02)_col | (ax_i02)_col << 0x10u;
+ }
+ return (ax_i02)_col | (ax_i02)_col << 0x8u | (ax_i02)_col << 0x10u | (ax_i02)_col << 0x18u;
+ }();
+ for (::ax_i02 addr = _vaddr;addr != _vaddr + 0x9600u;addr += 0x4u) {__ax_set20(addr,val);}
+}
+
+extern "C" auto ax_clrscrn1(::ax_i02 const _vaddr,::ax_i8 const _col) -> void {::__ax_clrscrn(_vaddr,_col);}
+extern "C" auto ax_clrscrn2(::ax_i02 const _vaddr,::ax_i01 const _col) -> void {::__ax_clrscrn(_vaddr,_col);}
diff --git a/agbx/source/gfx/plot.c b/agbx/source/gfx/plot.c
index a100208..066b97e 100644
--- a/agbx/source/gfx/plot.c
+++ b/agbx/source/gfx/plot.c
@@ -8,17 +8,24 @@
#include <ax/gfx.h>
-void ax_plot3(ax_i8 const _x,ax_i8 const _y,ax_i01 const _col) {
- ax_i01 const px = _y * 0xF0u + _x;
- __ax_setpx2(0x600'0000u,px,_col)
+void ax_plot1(ax_i02 const _vaddr,ax_i01 const _px,ax_i8 const _col) {
+ /* We can only write halfwords to VRAM, so we need to load the adjacent pixel value and combine it into a halfword. */
+ bool const odd = _px & 0x1u;
+ ax_i02 addr = _vaddr + _px - odd;
+ ax_i01 precol = __ax_get10(addr);
+ ax_i01 col = _col;
+ if (odd) {
+ precol &= 0b11111111u;
+ col <<= 0x8u;
+ }
+ else {
+ precol &= 0b1111111100000000u;
+ }
+ ax_i01 const newcol = precol | col;
+ __ax_set10(addr,newcol);
}
-void ax_plot4(ax_i02 const _vaddr,ax_i8 const _x,ax_i8 const _y,ax_i8 const _col) {
- ax_i01 const px = _y * 0xF0u + _x;
- ax_setpx1(_vaddr,px,_col);
-}
-
-void ax_plot5(ax_i02 const _vaddr,ax_i8 const _x,ax_i8 const _y,ax_i01 const _col) {
- ax_i01 const px = _y * 0xA0u + _x;
- __ax_setpx2(_vaddr,px,_col)
+void ax_plot2(ax_i02 const _vaddr,ax_i01 const _px,ax_i01 const _col) {
+ ax_i02 const addr = _vaddr + _px;
+ __ax_set10(addr,_col);
}
diff --git a/agbx/source/gfx/plottex.c b/agbx/source/gfx/plottex.c
deleted file mode 100644
index 2165c52..0000000
--- a/agbx/source/gfx/plottex.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- Copyright 2022 Gabriel Jensen.
- This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>.
-*/
-
-#include <ax/priv.h>
-
-#include <ax/gfx.h>
-
-void ax_plottex3(ax_i01 const * const _tex,ax_i8 const _x,ax_i8 const _y,ax_i8 const _w,ax_i8 const _h) {
- ax_i01 const * texpos = _tex;
- for (ax_i8 y = _y;y != _y + _h;++y) {
- for (ax_i8 x = _x;x != _x + _w;++x) {
- ax_plot3(x,y,*(texpos++));
- }
- }
-}
-
-void ax_plottex4(ax_i02 const _vaddr,ax_i8 const * const _tex,ax_i8 const _x,ax_i8 const _y,ax_i8 const _w,ax_i8 const _h) {
- ax_i8 const * texpos = _tex;
- for (ax_i8 y = _y;y != _y + _h;++y) {
- for (ax_i8 x = _x;x != _x + _w;++x) {
- ax_plot4(_vaddr,x,y,*(texpos++));
- }
- }
-}
-
-void ax_plottex5(ax_i02 const _vaddr,ax_i01 const * const _tex,ax_i8 const _x,ax_i8 const _y,ax_i8 const _w,ax_i8 const _h) {
- ax_i01 const * texpos = _tex;
- for (ax_i8 y = _y;y != _y + _h;++y) {
- for (ax_i8 x = _x;x != _x + _w;++x) {
- ax_plot5(_vaddr,x,y,*(texpos++));
- }
- }
-}
diff --git a/agbx/source/gfx/plottex.cc b/agbx/source/gfx/plottex.cc
new file mode 100644
index 0000000..836a6ff
--- /dev/null
+++ b/agbx/source/gfx/plottex.cc
@@ -0,0 +1,29 @@
+/*
+ Copyright 2022 Gabriel Jensen.
+ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>.
+*/
+
+#include <ax/priv.h>
+
+#include <ax/gfx.h>
+
+template<typename _pxtyp> [[gnu::always_inline]] inline static auto __ax_plottex(::ax_i02 const _vaddr,::ax_i8 const _scrnw,_pxtyp const * const _tex,::ax_i01 const _px,::ax_i8 const _w,::ax_i8 const _h) noexcept -> void {
+ static_assert(::__ax_typeq<_pxtyp,::ax_i8> || ::__ax_typeq<_pxtyp,::ax_i01>);
+ _pxtyp const * texpos = _tex;
+ for (::ax_i01 px = _px;px != _px + _h * _scrnw;) {
+ ::ax_i01 const rowstart = px;
+ for (;px != rowstart + _w;++px) {
+ if constexpr (::__ax_typeq<_pxtyp,::ax_i01>) {
+ ax_plot2(_vaddr,px,*(texpos++));
+ }
+ else {
+ ax_plot1(_vaddr,px,*(texpos++));
+ }
+ }
+ px = rowstart + _scrnw;
+ }
+}
+
+extern "C" auto ax_plottex1(::ax_i02 const _vaddr,::ax_i8 const _scrnw,::ax_i8 const * const _tex,::ax_i01 const _px,::ax_i8 const _w,::ax_i8 const _h) -> void {::__ax_plottex(_vaddr,_scrnw,_tex,_px,_w,_h);}
+extern "C" auto ax_plottex2(::ax_i02 const _vaddr,::ax_i8 const _scrnw,::ax_i01 const * const _tex,::ax_i01 const _px,::ax_i8 const _w,::ax_i8 const _h) -> void {::__ax_plottex(_vaddr,_scrnw,_tex,_px,_w,_h);}
diff --git a/agbx/source/gfx/rd.c b/agbx/source/gfx/rd.c
deleted file mode 100644
index aba36b1..0000000
--- a/agbx/source/gfx/rd.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- Copyright 2022 Gabriel Jensen.
- This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>.
-*/
-
-#include <ax/priv.h>
-
-#include <ax/gfx.h>
-
-ax_i01 ax_rd3(ax_i8 const _x,ax_i8 const _y) {
- ax_i01 const px = _y * 0xF0u + _x;
- return ax_getpx2(0x600'0000u,px);
-}
-
-ax_i8 ax_rd4(ax_i02 const _vaddr,ax_i8 const _x,ax_i8 const _y) {
- ax_i01 const px = _y * 0xF0u + _x;
- return ax_getpx1(_vaddr,px);
-}
-
-ax_i01 ax_rd5(ax_i02 const _vaddr,ax_i8 const _x,ax_i8 const _y) {
- ax_i01 const px = _y * 0xA0u + _x;
- return ax_getpx2(_vaddr,px);
-}
diff --git a/agbx/source/gfx/getpx.s b/agbx/source/gfx/rd.s
index 1db82a8..6662848 100644
--- a/agbx/source/gfx/getpx.s
+++ b/agbx/source/gfx/rd.s
@@ -7,13 +7,13 @@
.cpu arm7tdmi
.thumb
-.globl ax_getpx1
-.globl ax_getpx2
+.globl ax_rd1
+.globl ax_rd2
.func
.thumb_func
-ax_getpx1:
+ax_rd1:
adds r0,r1 @ Get the address of the pixel by adding the offset to the video address.
ldrh r0,[r0]
bx lr
@@ -23,7 +23,7 @@ ax_getpx1:
.func
.thumb_func
-ax_getpx2:
+ax_rd2:
adds r0,r1 @ Get the address of the pixel by adding the offset to the video address.
adds r0,r1 @ Add the offset twice as each pixel takes up two bytes.
ldrh r0,[r0]
diff --git a/agbx/source/gfx/setpx.c b/agbx/source/gfx/setpx.c
deleted file mode 100644
index 7110d02..0000000
--- a/agbx/source/gfx/setpx.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- Copyright 2022 Gabriel Jensen.
- This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>.
-*/
-
-#include <ax/priv.h>
-
-#include <ax/gfx.h>
-
-void ax_setpx1(ax_i02 const _vaddr,ax_i01 const _px,ax_i8 const _col) {
- /* We can only write halfwords to VRAM, so we need to load the adjacent pixel value and combine it into a halfword. */
- bool const odd = _px & 0x1u;
- ax_i02 addr = _vaddr + _px - odd;
- ax_i01 precol = __ax_get10(addr);
- ax_i01 col = _col;
- if (odd) {
- precol &= 0b11111111u;
- col <<= 0x8u;
- }
- else {
- precol &= 0b1111111100000000u;
- }
- ax_i01 const newcol = precol | col;
- __ax_set10(addr,newcol);
-}
-
-void ax_setpx2(ax_i02 const _vaddr,ax_i01 const _px,ax_i01 const _col) {
- ax_i02 const addr = _vaddr + _px;
- __ax_set10(addr,_col);
-}