diff options
-rw-r--r-- | CHANGELOG.txt | 11 | ||||
-rw-r--r-- | ax/GNUmakefile | 5 | ||||
-rw-r--r-- | ax/include-private/ax/priv.h | 2 | ||||
-rw-r--r-- | ax/include/ax/algo.h | 10 | ||||
-rw-r--r-- | ax/include/ax/bs.h | 6 | ||||
-rw-r--r-- | ax/include/ax/gfx.h | 2 | ||||
-rw-r--r-- | ax/include/ax/key.h | 2 | ||||
-rw-r--r-- | ax/include/stdarg.h | 12 | ||||
-rw-r--r-- | ax/include/stddef.h | 2 | ||||
-rw-r--r-- | ax/include/string.h | 10 | ||||
-rw-r--r-- | ax/source/algo/cp.c | 16 | ||||
-rw-r--r-- | ax/source/algo/cp.s | 51 | ||||
-rw-r--r-- | ax/source/algo/cp8.s | 36 | ||||
-rw-r--r-- | ax/source/algo/divmod.c | 18 | ||||
-rw-r--r-- | ax/source/gfx/flip.s | 10 | ||||
-rw-r--r-- | ax/source/gfx/getvbnk.s | 6 | ||||
-rw-r--r-- | ax/source/gfx/setcol.s | 6 | ||||
-rw-r--r-- | ax/source/string/memcpy.c | 15 | ||||
-rw-r--r-- | ax/source/string/memcpy.s | 30 | ||||
-rw-r--r-- | ax/source/string/memmove.s | 30 | ||||
-rw-r--r-- | ax/source/string/memset.c | 16 | ||||
-rw-r--r-- | ax/source/string/memset.s | 29 | ||||
-rw-r--r-- | ax/source/string/strlen.c | 16 | ||||
-rw-r--r-- | ax/source/string/strlen.s | 38 | ||||
-rw-r--r-- | demo/hdr.s | 2 | ||||
-rw-r--r-- | demo/script.ld | 4 | ||||
-rw-r--r-- | demo/source/start.c | 7 |
27 files changed, 299 insertions, 93 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5bb896a..15927a3 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,14 @@ +# C.0 + +* Implement cp in assembly; +* Implement stdarg header; +* Implement memcpy in assembly; +* Implement strlen in assembly; +* Add old-style <string.h> search functions; +* Implement memmove; +* Add function for copying in byte chunks; +* Add function for division and modulo; + # B.0 * Add error screen; diff --git a/ax/GNUmakefile b/ax/GNUmakefile index 1e37bab..070e273 100644 --- a/ax/GNUmakefile +++ b/ax/GNUmakefile @@ -7,7 +7,7 @@ AS := arm-none-eabi-as CC := arm-none-eabi-gcc #CC := clang --target=arm-none-eabi -CXX := arm-none-eabi-g++ +CXX := arm-none-eabi-g++ #CXX := clang++ --target=arm-none-eabi OBJCOPY := arm-none-eabi-objcopy @@ -76,6 +76,8 @@ HDRS := \ OBJS := \ source/algo/cp.o \ + source/algo/cp8.o \ + source/algo/divmod.o \ source/algo/fill.o \ source/bs/done.o \ source/bs/get.o \ @@ -97,6 +99,7 @@ OBJS := \ source/setjmp/setjmp.o \ source/stdlib/memalignement.o \ source/string/memcpy.o \ + source/string/memmove.o \ source/string/memset.o \ source/string/memset_explicit.o \ source/string/strlen.o diff --git a/ax/include-private/ax/priv.h b/ax/include-private/ax/priv.h index 4d4791f..ea06890 100644 --- a/ax/include-private/ax/priv.h +++ b/ax/include-private/ax/priv.h @@ -9,8 +9,6 @@ #include <ax/bs.h> -#include <ax/bs.h> - #if defined(__cplusplus) extern "C" { #endif diff --git a/ax/include/ax/algo.h b/ax/include/ax/algo.h index f9cff8b..4458933 100644 --- a/ax/include/ax/algo.h +++ b/ax/include/ax/algo.h @@ -9,15 +9,21 @@ #include <ax/bs.h> -#include <ax/bs.h> - #if defined(__cplusplus) extern "C" { #endif +typedef struct { + ax_i02 quot; + ax_i02 rem; +} ax_quotrem; + void ax_cp( void const * in, ax_i02 num,void * out); +void ax_cp8( void const * in, ax_i02 num,void * out); void ax_fill(void * ptr,ax_i02 num,ax_i8 byte); +ax_quotrem ax_divmod(ax_i02 num,ax_i02 den) [[unsequenced]]; + #if defined(__cplusplus) } #endif diff --git a/ax/include/ax/bs.h b/ax/include/ax/bs.h index 4e6de79..69f5621 100644 --- a/ax/include/ax/bs.h +++ b/ax/include/ax/bs.h @@ -82,7 +82,7 @@ typedef enum { ax_err_max = 0xFFu, } ax_err; -constexpr ax_i04 ax_ver = 0xBu; +constexpr ax_i04 ax_ver = 0xCu; ax_i01 ax_get01(ax_i02 addr); ax_i02 ax_get02(ax_i02 addr); @@ -92,8 +92,8 @@ void ax_set01(ax_i02 addr,ax_i01 val); void ax_set02(ax_i02 addr,ax_i02 val); void ax_set8( ax_i02 addr,ax_i8 val); -[[noreturn]] void ax_done(ax_err err); -[[noreturn]] void ax_trap(void); +void ax_done(ax_err err) [[noreturn]]; +void ax_trap(void) [[noreturn]]; #if defined(__cplusplus) } diff --git a/ax/include/ax/gfx.h b/ax/include/ax/gfx.h index 3e413a7..9b39831 100644 --- a/ax/include/ax/gfx.h +++ b/ax/include/ax/gfx.h @@ -9,8 +9,6 @@ #include <ax/bs.h> -#include <ax/bs.h> - #if defined(__cplusplus) extern "C" { #endif diff --git a/ax/include/ax/key.h b/ax/include/ax/key.h index f7a1799..dc582d2 100644 --- a/ax/include/ax/key.h +++ b/ax/include/ax/key.h @@ -26,7 +26,7 @@ typedef struct { ax_i01 _keys; } ax_keymap; -#define ax_chkkey(_map,_key) ((bool)(((_map)._keys & (ax_i01)(_key)) ^ (ax_i01)(_key))) +#define ax_chkkey(_map,_key) ((bool)(((_map)._keys ^ 0b11111111'11111111u) & (ax_i01)(_key))) ax_keymap ax_getkeymap(void); diff --git a/ax/include/stdarg.h b/ax/include/stdarg.h index 476691e..3364fa7 100644 --- a/ax/include/stdarg.h +++ b/ax/include/stdarg.h @@ -9,6 +9,16 @@ #include <ax/bs.h> -/* This is gonna be complicated. */ +#define __STDC_VERSION_STDARG_H__ (202311l) + +#define va_arg(_ap,_type) ((_type)0x0u) + +#define va_copy(_dest,_src) ((void)0x0u) + +#define va_end(_ap) ((void)0x0u) + +#define va_start(_ap,...) ((void)0x0u) + +typedef void * va_list; #endif diff --git a/ax/include/stddef.h b/ax/include/stddef.h index ea5a04e..ee45593 100644 --- a/ax/include/stddef.h +++ b/ax/include/stddef.h @@ -28,7 +28,7 @@ typedef ax_i02s ptrdiff_t; typedef ax_i02 size_t; -typedef long double max_align_t; +typedef unsigned long long max_align_t; typedef ax_i02 wchar_t; typedef typeof_unqual (nullptr) nullptr_t; diff --git a/ax/include/string.h b/ax/include/string.h index 4365228..4d31874 100644 --- a/ax/include/string.h +++ b/ax/include/string.h @@ -32,6 +32,16 @@ int strcmp( char const * s1,char const * s2); int strncmp(char const * s1,char const * s2); /* strxfrm not required. */ +/* We're missing the generic variations of the following functions: */ +void * memchr( void const * s, int c, size_t n); +char * strchr( char const * s, int c); +size_t strcspn(char const * s1,char const * s2); +char * strpbrk(char const * s1,char const * s2); +char * strrchr(char const * s1,int c); +size_t strspn( char const * s1,char const * s2); +char * strstr( char const * s1,char const * s2); +char * strtok( char * restrict s1,char * restrict s2); + void * memset( void * s,int c,size_t n); void * memset_explicit(void * s,int c,size_t n); /* strerror is not required. */ diff --git a/ax/source/algo/cp.c b/ax/source/algo/cp.c deleted file mode 100644 index 4f9ae7a..0000000 --- a/ax/source/algo/cp.c +++ /dev/null @@ -1,16 +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/algo.h> - -void ax_cp(void const * const _in,ax_i02 const _num,void * const _out) { - unsigned char const * in = _in; - unsigned char * out = _out; - unsigned char const * const afterbuf = in + _num; - for (;in != afterbuf;++in,++out) {*out = *in;} -} diff --git a/ax/source/algo/cp.s b/ax/source/algo/cp.s new file mode 100644 index 0000000..bcb6a6f --- /dev/null +++ b/ax/source/algo/cp.s @@ -0,0 +1,51 @@ +@ 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>. + +.syntax unified + +.cpu arm7tdmi +.thumb + +.globl ax_cp + +.func +.thumb_func + +ax_cp: + @ ax_i02 tmp4; + @ ax_i8 tmp1; + +.wrdcp: @ wrdcp:; + @ Check if there are at least four bytes remaining: + cmp r1,0x4 + blt .bytecp @ if (num < 0x4u) goto bytecp; + + @ Copy one word: + ldm r0!,{r3} @ tmp4 = *(ax_i02 *)in; /* We use ldm/stm with an exclamation mark after the source/destination as this version saves the incremented address into the register, meaning we don't have to icrement it ourselves. */ + stm r2!,{r3} @ *(ax_i02 *)out = tmp4; + + @ Continue to the next word: + subs r1,0x4 @ num -= 0x4u; + b .wrdcp @ goto wrdcp; + +.bytecp: @ bytecp:; + @ Check if we have any bytes remaining: + cmp r1,0x0 + beq .done @ if (num == 0x0u) goto done; + + @ Copy one byte: + ldrb r3,[r0] @ tmp1 = *(ax_i8 *)in; + strb r3,[r2] @ *(ax_i8 *)out = tmp1; + + @ Continue to the next byte: + adds r0,0x1 @ ++in; + adds r2,0x1 @ ++out; + subs r1,0x1 @ --num; + b .bytecp @ goto bytecp; + +.done: @ done:; + @ Return: + bx lr @ return; + +.endfunc diff --git a/ax/source/algo/cp8.s b/ax/source/algo/cp8.s new file mode 100644 index 0000000..94456ba --- /dev/null +++ b/ax/source/algo/cp8.s @@ -0,0 +1,36 @@ +@ 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>. + +.syntax unified + +.cpu arm7tdmi +.thumb + +.globl ax_cp8 + +.func +.thumb_func + +ax_cp8: + @ ax_i8 tmp; + adds r1,r0 @ void * end = in + num; +.cp: @ cp:; + @ Check if we have any bytes remaining: + cmp r0,r1 + beq .done @ if (num == end) goto done; + + @ Copy one byte: + ldrb r3,[r0] @ tmp = *(ax_i8 *)in; + strb r3,[r2] @ *(ax_i8 *)out = tmp; + + @ Continue to the next byte: + adds r0,0x1 @ ++in; + adds r2,0x1 @ ++out; + b .cp @ goto cp; + +.done: @ done:; + @ Return: + bx lr @ return; + +.endfunc diff --git a/ax/source/algo/divmod.c b/ax/source/algo/divmod.c new file mode 100644 index 0000000..0576ea3 --- /dev/null +++ b/ax/source/algo/divmod.c @@ -0,0 +1,18 @@ +/* + 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/algo.h> + +ax_quotrem ax_divmod(ax_i02 const _num,ax_i02 const _den) { + if (__builtin_expect(_den == 0x0,0x0)) { + ax_done(ax_err_divzero); + } + ax_quotrem quotrem; + for (quotrem = (ax_quotrem){.quot = 0x0u,.rem = _num};quotrem.rem >= _den;++quotrem.quot,quotrem.rem -= _den) {} + return quotrem; +} diff --git a/ax/source/gfx/flip.s b/ax/source/gfx/flip.s index 2676d95..57cb589 100644 --- a/ax/source/gfx/flip.s +++ b/ax/source/gfx/flip.s @@ -17,20 +17,20 @@ ax_flip: @ Get the current value of dispcntrl: ldr r0,.dispcntrladdr @ ax_i02 dispcntrladdr = 0x4000000u; - ldrh r1,[r0] @ ax_i01 dispcntrl = *(ax_i01 *)dispcntrladdr; + ldrh r1,[r0] @ ax_i01 dispcntrl = *(ax_i01 *)dispcntrladdr; @ XOR bit four: movs r2,0b10000 - eors r1,r2 @ dispcntrl ^= 0b10000u; + eors r1,r2 @ dispcntrl ^= 0b10000u; @ Save dispcntrl: - strh r1,[r0] @ *(ax_i01 *)dispcntrladdr = dispcntrl; + strh r1,[r0] @ *(ax_i01 *)dispcntrladdr = dispcntrl; @ Get the address of the video bank: - b __ax_getvbnk @ ax_i02 vaddr = __ax_getvbnk(); + b __ax_getvbnk @ ax_i02 vaddr = __ax_getvbnk(); @ Return: - bx lr @ return vaddr; + bx lr @ return vaddr; .endfunc diff --git a/ax/source/gfx/getvbnk.s b/ax/source/gfx/getvbnk.s index da4c30a..d526e47 100644 --- a/ax/source/gfx/getvbnk.s +++ b/ax/source/gfx/getvbnk.s @@ -16,12 +16,12 @@ ax_getvbnk: @ Get the current value of dispcntrl: ldr r0,.dispcntrladdr @ ax_i02 dispcntrladdr = 0x4000000u; - ldrh r1,[r0] @ ax_i01 dispcntrl = *(ax_i01 *)dispcntrladdr; + ldrh r1,[r0] @ ax_i01 dispcntrl = *(ax_i01 *)dispcntrladdr; @ Get the address: - b __ax_getvbnk @ ax_i02 vaddr = __ax_getvbnk(); + b __ax_getvbnk @ ax_i02 vaddr = __ax_getvbnk(); - bx lr @ return vaddr; + bx lr @ return vaddr; .endfunc diff --git a/ax/source/gfx/setcol.s b/ax/source/gfx/setcol.s index 4738099..5276df4 100644 --- a/ax/source/gfx/setcol.s +++ b/ax/source/gfx/setcol.s @@ -15,11 +15,11 @@ ax_setcol: @ Get the address of the colour: ldr r2,.paladdr @ ax_i02 paladdr = 0x5000000u; - adds r2,r0 @ paladdr += _n; - adds r2,r0 @ paladdr += _n; /* Add the colour number twice as each colour value takes up two bytes. */ + adds r2,r0 @ paladdr += n; + adds r2,r0 @ paladdr += n; /* Add the index number twice as each colour value takes up two bytes. This is also simpler than multiplying by two. */ @ Set the colour value: - strh r1,[r2] @ *(ax_i01 *)paladdr = _col; + strh r1,[r2] @ *(ax_i01 *)paladdr = col; @ Return: bx lr @ return; diff --git a/ax/source/string/memcpy.c b/ax/source/string/memcpy.c deleted file mode 100644 index c38ca09..0000000 --- a/ax/source/string/memcpy.c +++ /dev/null @@ -1,15 +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/algo.h> -#include <string.h> - -void * memcpy(void * const restrict _dest,void const * const restrict _src,size_t const _count) { - ax_cp(_src,_count,_dest); - return _dest; -} diff --git a/ax/source/string/memcpy.s b/ax/source/string/memcpy.s new file mode 100644 index 0000000..c5efaa3 --- /dev/null +++ b/ax/source/string/memcpy.s @@ -0,0 +1,30 @@ +@ 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>. + +.syntax unified + +.cpu arm7tdmi +.thumb + +.extern ax_cp + +.globl memcpy + +.func +.thumb_func + +memcpy: + push {r0,lr} @ Save the value of s1 (r0) as we need to return it later. + + @ Order the parameters correctly: + movs r3,r2 + movs r2,r0 + movs r0,r1 + movs r1,r3 + + bl ax_cp + pop {r0,r1} @ We cannot pop into lr. + bx r1 + +.endfunc diff --git a/ax/source/string/memmove.s b/ax/source/string/memmove.s new file mode 100644 index 0000000..8a2ec88 --- /dev/null +++ b/ax/source/string/memmove.s @@ -0,0 +1,30 @@ +@ 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>. + +.syntax unified + +.cpu arm7tdmi +.thumb + +.extern ax_cp + +.globl memmove + +.func +.thumb_func + +memmove: + push {r0,lr} @ Save the value of s1 (r0) as we need to return it later. + + @ Order the parameters correctly: + movs r3,r2 + movs r2,r0 + movs r0,r1 + movs r1,r3 + + bl ax_cp8 + pop {r0,r1} @ We cannot pop into lr. + bx r1 + +.endfunc diff --git a/ax/source/string/memset.c b/ax/source/string/memset.c deleted file mode 100644 index 3bf5545..0000000 --- a/ax/source/string/memset.c +++ /dev/null @@ -1,16 +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/algo.h> -#include <string.h> - -void * memset(void * const _dest,int const _ch,size_t const _count) { - unsigned char const byte = (unsigned char)_ch; - ax_fill(_dest,_count,byte); - return _dest; -} diff --git a/ax/source/string/memset.s b/ax/source/string/memset.s new file mode 100644 index 0000000..8f419dc --- /dev/null +++ b/ax/source/string/memset.s @@ -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>. + +.syntax unified + +.cpu arm7tdmi +.thumb + +.extern ax_fill + +.globl memset + +.func +.thumb_func + +memset: + push {r0,lr} + + @ Order the parameters correctly: + movs r3,r1 + movs r1,r2 + movs r2,r3 + + bl ax_fill + pop {r0,r1} + bx r1 + +.endfunc diff --git a/ax/source/string/strlen.c b/ax/source/string/strlen.c deleted file mode 100644 index 401a8a4..0000000 --- a/ax/source/string/strlen.c +++ /dev/null @@ -1,16 +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/algo.h> -#include <string.h> - -size_t strlen(char const * const _s) { - char const * pos = _s; - while (*pos++) {} - return (size_t)(pos - _s); -} diff --git a/ax/source/string/strlen.s b/ax/source/string/strlen.s new file mode 100644 index 0000000..e9daab8 --- /dev/null +++ b/ax/source/string/strlen.s @@ -0,0 +1,38 @@ +@ 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>. + +.syntax unified + +.cpu arm7tdmi +.thumb + +.globl strlen + +.func +.thumb_func + +strlen: + @ char chr; + + movs r1,r0 @ char const * start = s; + +.loop: @ loop:; + @ Move the character into a register: + ldrb r2,[r0] @ chr = *s; + + @ Check if we have reached the null-terminator: + cmp r2,0x0 + beq .done @ if (chr == '\x0') goto done; + + @ Continue to the next character: + adds r0,0x1 @ ++s; + b .loop @ goto loop; + +.done: + @ Calculate the length: + subs r0,r1 @ s -= start; + + bx lr @ return (size_t)s; + +.endfunc @@ -41,7 +41,7 @@ _start: @ We define this label to stop the linker from complaining @ "J": Japan @ "P": Elsewhere @ "S": Spain -.ascii "CXXE" +.ascii "CAXE" @ Maker code (2) @ Two character ASCII string. Identifies the (commerical) developer. diff --git a/demo/script.ld b/demo/script.ld index 6eb58e4..8f61176 100644 --- a/demo/script.ld +++ b/demo/script.ld @@ -13,8 +13,8 @@ MEMORY { } SECTIONS { - .bss : {*(.bss*)} > iwram - .data : {*(.data*)} > iwram + .bss : {*(.bss*)} > ewram + .data : {*(.data*)} > ewram .text : {*(.text*)} > rom .rodata : {*(.rodata*)} > rom } diff --git a/demo/source/start.c b/demo/source/start.c index eb4bb9d..e6c9a45 100644 --- a/demo/source/start.c +++ b/demo/source/start.c @@ -1,7 +1,8 @@ #include <ax-demo.h> -#include <ax/key.h> +#include <ax/algo.h> #include <ax/gfx.h> +#include <ax/key.h> #include <float.h> #include <iso646.h> @@ -42,7 +43,7 @@ 0x04u, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x04u, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x04u, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x04u, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x04u, };*/ -static ax_i8 const axd_logo[] = { +constexpr ax_i8 axd_logo[] = { 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x03u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x03u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x03u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x03u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x03u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x03u, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x03u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x01u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x01u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x03u,0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x02u,0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u,0x02u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x01u,0x04u,0x04u,0x03u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x03u,0x04u,0x03u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x03u,0x04u,0x03u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x02u,0x04u,0x04u,0x01u,0x0Eu, @@ -90,7 +91,7 @@ static ax_i8 const axd_logo[] = { static_assert(sizeof (axd_logo) == axd_logow * axd_logoh); -static ax_i8 const axd_startmsg[] = { +constexpr ax_i8 axd_startmsg[] = { 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x0Eu, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x0Eu, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x0Eu,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x0Eu,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x0Eu,0x04u,0x04u,0x04u,0x04u,0x04u,0x0Eu, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x0Eu, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x0Eu,0x04u,0x04u,0x04u,0x04u,0x04u,0x0Eu, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x0Eu,0x04u,0x04u,0x04u, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x04u,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x0Eu,0x0Eu,0x04u,0x04u, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x04u, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x04u, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x0Eu,0x04u,0x04u, 0x0Eu, 0x0Eu,0x04u,0x04u,0x04u,0x04u,0x04u,0x0Eu, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x0Eu,0x04u, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x04u,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x0Eu,0x0Eu,0x0Eu,0x04u,0x0Eu,0x0Eu,0x0Eu, 0x0Eu, 0x04u,0x04u,0x0Eu,0x0Eu,0x0Eu,0x04u,0x04u, 0x0Eu, 0x04u,0x04u,0x04u,0x04u,0x0Eu,0x04u,0x04u, |