diff options
-rwxr-xr-x | port | 2 | ||||
-rw-r--r-- | ports/doom | 79 | ||||
-rw-r--r-- | src/shared/include/camellia/errno.h | 2 | ||||
-rw-r--r-- | src/shared/printf.c | 13 | ||||
-rw-r--r-- | src/user/lib/elfload.c | 1 | ||||
-rw-r--r-- | src/user/lib/include/fcntl.h | 0 | ||||
-rw-r--r-- | src/user/lib/include/inttypes.h | 1 | ||||
-rw-r--r-- | src/user/lib/include/math.h | 2 | ||||
-rw-r--r-- | src/user/lib/include/stdio.h | 2 | ||||
-rw-r--r-- | src/user/lib/include/stdlib.h | 5 | ||||
-rw-r--r-- | src/user/lib/include/string.h | 3 | ||||
-rw-r--r-- | src/user/lib/include/strings.h | 5 | ||||
-rw-r--r-- | src/user/lib/include/sys/stat.h | 8 | ||||
-rw-r--r-- | src/user/lib/include/sys/types.h | 1 | ||||
-rw-r--r-- | src/user/lib/math.c | 5 | ||||
-rw-r--r-- | src/user/lib/stdio/misc.c | 6 | ||||
-rw-r--r-- | src/user/lib/stdlib.c | 16 | ||||
-rw-r--r-- | src/user/lib/string.c | 46 |
18 files changed, 185 insertions, 12 deletions
@@ -9,6 +9,6 @@ if [ $1 = deepclean ]; then exit fi -mkdir -p ports/out/$1/ $PREFIX +mkdir -p ports/out/$1/ $PREFIX/bin cd ports/out/$1/ sh $REPO/ports/$1 $2 diff --git a/ports/doom b/ports/doom new file mode 100644 index 0000000..c230087 --- /dev/null +++ b/ports/doom @@ -0,0 +1,79 @@ +set -eu +camellia_path_check + +fetch() { + git clone https://github.com/ozkl/doomgeneric + cd doomgeneric + # TODO use a newer commit + git -c advice.detachedHead=false checkout ee3ee581912dacd38af06e81da2374c1267453e8 + + cd doomgeneric + rm doomgeneric # a leftover OS X binary + sed s/xlib/camellia/ -i Makefile + sed s/-lX11// -i Makefile + curl -A "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0" -LO https://assets.wad-archive.com/wadarchive/files/1437fc1ac25a17d5b3cef4c9d2f74e40cae3d231/DOOM1.WAD + + cat <<\EOF > doomgeneric_camellia.c +#include <string.h> +#include <camellia/syscalls.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <user/lib/draw/draw.h> + +#include "doomgeneric.h" + +struct framebuf fb; + +void DG_Init(void) { + if (fb_setup(&fb, "/kdev/video/") < 0) { + puts("DG_Init: fb_setup error"); + abort(); + } +} + +void DG_DrawFrame(void) { + size_t doomw = DOOMGENERIC_RESX; + size_t doomh = DOOMGENERIC_RESY; + size_t doompitch = doomw * 4; + for (int y = 0; y < DOOMGENERIC_RESY; y++) { + memcpy(fb.b + fb.pitch * y, ((char*)DG_ScreenBuffer) + doompitch * y, doompitch); + } + + struct rect d; + dirty_mark(&d, 0, 0); + dirty_mark(&d, doomw, doomh); + dirty_flush(&d, &fb); +} + +static uint32_t timer = 0; +void DG_SleepMs(uint32_t ms) { + timer += ms; + _syscall_sleep(ms); +} + +uint32_t DG_GetTicksMs(void) { + /* if it's stupid and it works... */ + return timer; +} + +int DG_GetKey(int *pressed, unsigned char *doomKey) { + return 0; +} + +void DG_SetWindowTitle(const char *title) { + (void)title; +} +EOF +} + +prep() { + [ -d doomgeneric ] || (fetch) + cd doomgeneric/doomgeneric +} + +case $1 in + install) (prep; make "CC=cc" && cp doomgeneric $PREFIX/bin/doom && cp DOOM1.WAD $PREFIX/) ;; + clean) (prep; make clean) ;; + *) echo "usage: $0 install|clean"; false ;; +esac
\ No newline at end of file diff --git a/src/shared/include/camellia/errno.h b/src/shared/include/camellia/errno.h index 2c5594b..1e4841c 100644 --- a/src/shared/include/camellia/errno.h +++ b/src/shared/include/camellia/errno.h @@ -11,3 +11,5 @@ #define EACCES 10 #define EMFILE 11 /* All file descriptors taken. */ #define ECONNRESET 12 + +#define EISDIR 200 diff --git a/src/shared/printf.c b/src/shared/printf.c index 9d8eb2d..d28f891 100644 --- a/src/shared/printf.c +++ b/src/shared/printf.c @@ -115,6 +115,18 @@ int __printf_internal(const char *fmt, va_list argp, c = *fmt++; } + if (c == '.') { + // TODO implement precision properly, this violates the spec and is stupid + c = *fmt++; + m.fill_char = '0'; + m.field_width = 0; + while ('0' <= c && c <= '9') { + m.field_width *= 10; + m.field_width += c - '0'; + c = *fmt++; + } + } + // TODO length modifiers enum lenmod lm; switch (c) { @@ -174,6 +186,7 @@ int __printf_internal(const char *fmt, va_list argp, break; case 'd': + case 'i': if (lm == LM_int) ns = va_arg(argp, int); else if (lm == LM_long) ns = va_arg(argp, long); else if (lm == LM_longlong) ns = va_arg(argp, long long); diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c index 6912239..777c8b8 100644 --- a/src/user/lib/elfload.c +++ b/src/user/lib/elfload.c @@ -160,6 +160,7 @@ void elf_exec(void *base, char **argv, char **envp) { void *exebase = elf_loadmem(ehdr); if (!exebase) return; + _klogf("exebase 0x%x", exebase); void *newstack = _syscall_memflag((void*)0x1000, 0x1000, MEMFLAG_FINDFREE | MEMFLAG_PRESENT); if (!newstack) return; diff --git a/src/user/lib/include/fcntl.h b/src/user/lib/include/fcntl.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/user/lib/include/fcntl.h diff --git a/src/user/lib/include/inttypes.h b/src/user/lib/include/inttypes.h new file mode 100644 index 0000000..9a6118b --- /dev/null +++ b/src/user/lib/include/inttypes.h @@ -0,0 +1 @@ +#include <stdint.h> diff --git a/src/user/lib/include/math.h b/src/user/lib/include/math.h index 07ff81d..1aec564 100644 --- a/src/user/lib/include/math.h +++ b/src/user/lib/include/math.h @@ -3,8 +3,6 @@ #define INFINITY __builtin_inff() #define HUGE_VAL ((double)INFINITY) -int abs(int i); - double acos(double x); double asin(double x); double atan2(double x, double y); diff --git a/src/user/lib/include/stdio.h b/src/user/lib/include/stdio.h index dd6a078..5ee0878 100644 --- a/src/user/lib/include/stdio.h +++ b/src/user/lib/include/stdio.h @@ -81,3 +81,5 @@ int rename(const char *old, const char *new); #define L_tmpnam (5 + 16 + 1) char *tmpnam(char *s); + +int sscanf(const char *restrict s, const char *restrict format, ...); diff --git a/src/user/lib/include/stdlib.h b/src/user/lib/include/stdlib.h index 8c827e3..2df0bf7 100644 --- a/src/user/lib/include/stdlib.h +++ b/src/user/lib/include/stdlib.h @@ -15,3 +15,8 @@ _Noreturn void exit(int); int mkstemp(char *template); char *getenv(const char *name); int system(const char *cmd); + +int abs(int i); + +int atoi(const char *s); +double atof(const char *s); diff --git a/src/user/lib/include/string.h b/src/user/lib/include/string.h index cf621d5..38fb0d2 100644 --- a/src/user/lib/include/string.h +++ b/src/user/lib/include/string.h @@ -4,6 +4,7 @@ long strtol(const char *restrict s, char **restrict end, int base); double strtod(const char *restrict s, char **restrict end); char *strchr(const char *s, int c); +char *strrchr(const char *s, int c); size_t strspn(const char *s, const char *accept); size_t strcspn(const char *s, const char *reject); @@ -18,5 +19,7 @@ int strcoll(const char *s1, const char *s2); char *strstr(const char *s1, const char *s2); char *strcpy(char *restrict s1, const char *restrict s2); +char *strncpy(char *restrict s1, const char *restrict s2, size_t n); +char *strdup(const char *s); char *strerror(int errnum); diff --git a/src/user/lib/include/strings.h b/src/user/lib/include/strings.h new file mode 100644 index 0000000..d0abc47 --- /dev/null +++ b/src/user/lib/include/strings.h @@ -0,0 +1,5 @@ +#pragma once +#include <stddef.h> + +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t n); diff --git a/src/user/lib/include/sys/stat.h b/src/user/lib/include/sys/stat.h index a954c9b..78a8fc1 100644 --- a/src/user/lib/include/sys/stat.h +++ b/src/user/lib/include/sys/stat.h @@ -1,4 +1,5 @@ #pragma once +#include <sys/types.h> #include <errno.h> // only for ENOSYS #define S_ISFIFO(x) 0 @@ -9,3 +10,10 @@ static inline int fstat(int fd, struct stat *sb) { errno = ENOSYS; return -1; } + +static inline int mkdir(const char *path, mode_t mode) { + // TODO + (void)path; (void)mode; + errno = ENOSYS; + return -1; +} diff --git a/src/user/lib/include/sys/types.h b/src/user/lib/include/sys/types.h index 3b1772b..9f6f8f8 100644 --- a/src/user/lib/include/sys/types.h +++ b/src/user/lib/include/sys/types.h @@ -5,3 +5,4 @@ typedef long long off_t; typedef int64_t time_t; typedef uint64_t clock_t; +typedef int mode_t; diff --git a/src/user/lib/math.c b/src/user/lib/math.c index db1f2ec..bf7c039 100644 --- a/src/user/lib/math.c +++ b/src/user/lib/math.c @@ -1,11 +1,6 @@ #include <math.h> #include <user/lib/panic.h> -int abs(int i) { - return i < 0 ? -i : i; -} - - // TODO port a libm #pragma GCC diagnostic ignored "-Wunused-parameter" double acos(double x) { __libc_panic("unimplemented"); } diff --git a/src/user/lib/stdio/misc.c b/src/user/lib/stdio/misc.c index d74c197..a140ee4 100644 --- a/src/user/lib/stdio/misc.c +++ b/src/user/lib/stdio/misc.c @@ -44,3 +44,9 @@ char *tmpnam(char *s) { strcpy(s, "/tmp/tmpnam"); return s; } + +// TODO sscanf +int sscanf(const char *restrict s, const char *restrict format, ...) { + (void)s; (void)format; + return 0; +} diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c index 6018d16..38e87ad 100644 --- a/src/user/lib/stdlib.c +++ b/src/user/lib/stdlib.c @@ -1,7 +1,8 @@ -#include <camellia/syscalls.h> #include <camellia/flags.h> +#include <camellia/syscalls.h> #include <errno.h> #include <string.h> +#include <user/lib/panic.h> _Noreturn void abort(void) { _syscall_exit(1); @@ -30,3 +31,16 @@ int system(const char *cmd) { errno = ENOSYS; return -1; } + +int abs(int i) { + return i < 0 ? -i : i; +} + +int atoi(const char *s) { + return strtol(s, NULL, 10); +} + +double atof(const char *s) { + (void)s; + __libc_panic("unimplemented"); +} diff --git a/src/user/lib/string.c b/src/user/lib/string.c index 386cffa..fa9c0ca 100644 --- a/src/user/lib/string.c +++ b/src/user/lib/string.c @@ -1,6 +1,7 @@ #include <ctype.h> #include <errno.h> #include <string.h> +#include <strings.h> long strtol(const char *restrict s, char **restrict end, int base) { long res = 0; @@ -55,7 +56,14 @@ double strtod(const char *restrict s, char **restrict end) { char *strchr(const char *s, int c) { for (; *s; s++) { - if (*s == c) return (char*)s; + if (*s == c) return (char *)s; + } + return NULL; +} + +char *strrchr(const char *s, int c) { + for (int i = strlen(s) + 1; i >= 0; i--) { + if (s[i] == c) return (char *)s + i; } return NULL; } @@ -123,9 +131,24 @@ char *strstr(const char *s1, const char *s2) { } char *strcpy(char *restrict s1, const char *restrict s2) { - char *ret = s1; while (*s2) *s1++ = *s2++; - return ret; + *s1 = *s2; + return s1; +} + +char *strncpy(char *restrict s1, const char *restrict s2, size_t n) { + for (size_t i = 0; i < n; i++) { + s1[i] = s2[i]; + if (s1[i] == '\0') return s1 + i; // TODO fill with null bytes + } + return s1 + n; +} + +char *strdup(const char *s) { + size_t len = strlen(s) + 1; + char *buf = malloc(len); + if (buf) memcpy(buf, s, len); + return buf; } // TODO strerror mapping @@ -133,3 +156,20 @@ char *strerror(int errnum) { (void)errnum; return "unknown error"; } + +/* strings.h */ +int strcasecmp(const char *s1, const char *s2) { + return strncasecmp(s1, s2, ~0); +} + +int strncasecmp(const char *s1, const char *s2, size_t n) { + for (size_t i = 0; i < n; i++) { + char c1 = tolower(s1[i]), c2 = tolower(s2[i]); + if (c1 == '\0' || c1 != c2) { + if (c1 < c2) return -1; + else if (c1 > c2) return 1; + else return 0; + } + } + return 0; +} |