forked from Vhex-Kernel-Core/fxlibc
Compare commits
37 Commits
Author | SHA1 | Date |
---|---|---|
Lephenixnoir | ddec761f61 | |
Lephenixnoir | ca6c39bf56 | |
Lephenixnoir | 4b61daa602 | |
Lephenixnoir | 8231557ff5 | |
Lephenixnoir | 714e1cf605 | |
Lephenixnoir | ed52c1d7c2 | |
Lephenixnoir | 143029a837 | |
Lephenixnoir | 31ee6fdbee | |
Lephenixnoir | b38dd3f894 | |
Lephenixnoir | 89c6c39405 | |
Yann MAGNIN | e8779145c2 | |
Yann MAGNIN | ed77a97547 | |
Yann MAGNIN | bdf9566723 | |
Lephenixnoir | 26d5b5d9ab | |
Yann MAGNIN | 619afe25da | |
Yann MAGNIN | 996b2b8ded | |
Lephenixnoir | d50e44c563 | |
Lephenixnoir | 94faa6cbea | |
Alice Rozengarden | 3f5989ceab | |
Lephenixnoir | 3c29639988 | |
Lephenixnoir | 4d464bde01 | |
Lephenixnoir | 809238e5b8 | |
Yann MAGNIN | fa4adc5620 | |
Lephenixnoir | 71866ed769 | |
Lephenixnoir | ed873a652e | |
Lephenixnoir | 294fda9731 | |
Lephenixnoir | f1512125d0 | |
Lephenixnoir | 6ec0c24e2d | |
Lephenixnoir | 06b66252c9 | |
Lephenixnoir | 0c2f81e5bb | |
Lephenixnoir | 909c7df815 | |
Lephenixnoir | 4461bdb96a | |
Lephenixnoir | b6dbdf321d | |
Lephenixnoir | a12b84f1ef | |
Lephenixnoir | 51528170bb | |
Lephenixnoir | b53078776d | |
Lephenixnoir | 3046304497 |
370
CMakeLists.txt
370
CMakeLists.txt
|
@ -1,15 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
project(FxLibc VERSION 1.3.0 LANGUAGES C ASM)
|
||||
project(FxLibc VERSION 1.4.4 LANGUAGES C ASM)
|
||||
|
||||
set(CMAKE_INSTALL_MESSAGE LAZY)
|
||||
|
||||
# Options
|
||||
|
||||
# * -DFXLIBC_TARGET=<vhex-sh, vhex-x86, casiowin-fx, casiowin-cg, gint>
|
||||
# * -DFXLIBC_SHARED=1
|
||||
|
||||
option(SHARED "Build a shared library")
|
||||
option(STANDARD_NAMESPACE "Use libc.a and put headers in global include folder")
|
||||
|
||||
set(TARGET_FOLDERS ${FXLIBC_TARGET})
|
||||
# Install paths
|
||||
|
@ -17,31 +12,10 @@ set(LIBDIR "lib")
|
|||
set(INCDIR "include")
|
||||
|
||||
if(FXLIBC_TARGET STREQUAL vhex-sh)
|
||||
list(APPEND TARGET_FOLDERS vhex-generic sh-generic)
|
||||
list(APPEND TARGET_FOLDERS vhex sh-generic)
|
||||
set(FXLIBC_ARCH sh)
|
||||
add_definitions(-D__SUPPORT_VHEX_KERNEL)
|
||||
# set(FXLIBC_SHARED ON)
|
||||
endif()
|
||||
|
||||
if(FXLIBC_TARGET STREQUAL vhex-x86)
|
||||
list(APPEND TARGET_FOLDERS vhex-generic x86-generic)
|
||||
set(FXLIBC_ARCH x86)
|
||||
add_definitions(-D__SUPPORT_VHEX_KERNEL)
|
||||
# set(FXLIBC_SHARED ON)
|
||||
# TODO: Maybe add -nostdinc (but that removes compiler-provided headers like
|
||||
# <stddef.h>), or use another compiler than the system one?
|
||||
endif()
|
||||
|
||||
if(FXLIBC_TARGET STREQUAL casiowin-fx)
|
||||
list(APPEND TARGET_FOLDERS sh-generic)
|
||||
set(FXLIBC_ARCH sh)
|
||||
add_definitions(-D__SUPPORT_CASIOWIN_FX9860G)
|
||||
endif()
|
||||
|
||||
if(FXLIBC_TARGET STREQUAL casiowin-cg)
|
||||
list(APPEND TARGET_FOLDERS sh-generic)
|
||||
set(FXLIBC_ARCH sh)
|
||||
add_definitions(-D__SUPPORT_CASIOWIN_FXCG50)
|
||||
set(CMAKE_INSTALL_PREFIX "${FXSDK_COMPILER_INSTALL}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
if(FXLIBC_TARGET STREQUAL gint)
|
||||
|
@ -51,12 +25,21 @@ if(FXLIBC_TARGET STREQUAL gint)
|
|||
|
||||
# Default to fxSDK install path
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "${FXSDK_COMPILER_INSTALL}" CACHE PATH "..." FORCE)
|
||||
set(FXLIBC_PREFIX_IS_FXSDK 1 CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
if(CMAKE_INSTALL_PREFIX STREQUAL "${FXSDK_COMPILER_INSTALL}")
|
||||
set(LIBDIR ".")
|
||||
set(INCDIR "include")
|
||||
if(FXLIBC_PREFIX_IS_FXSDK)
|
||||
# Use the fxSDK paths; these variables are uncached so we are always up-to-
|
||||
# date, even if the compiler is upgraded without removing the fxlibc build
|
||||
# folder (which happens with GiteaPC)
|
||||
execute_process(
|
||||
COMMAND fxsdk path include
|
||||
OUTPUT_VARIABLE INCDIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(
|
||||
COMMAND fxsdk path lib
|
||||
OUTPUT_VARIABLE LIBDIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -64,16 +47,16 @@ if(sh-generic IN_LIST TARGET_FOLDERS)
|
|||
add_definitions(-D__SUPPORT_ARCH_SH)
|
||||
endif()
|
||||
|
||||
if(x86-generic IN_LIST TARGET_FOLDERS)
|
||||
add_definitions(-D__SUPPORT_ARCH_X86)
|
||||
endif()
|
||||
|
||||
# TODO: Preprocessor definitions for configuration
|
||||
# configure_file()
|
||||
|
||||
# libc.{a,so} libfxlibc.{a,so}
|
||||
|
||||
add_compile_options(-Wall -Wextra -std=c11 -ffreestanding -Os)
|
||||
if(FXLIBC_PIC)
|
||||
add_compile_options(-fpic)
|
||||
endif()
|
||||
|
||||
if(FXLIBC_ARCH STREQUAL sh)
|
||||
add_compile_options(
|
||||
"$<$<COMPILE_LANGUAGE:C>:-m3;-mb>"
|
||||
|
@ -88,177 +71,187 @@ set(SOURCES
|
|||
3rdparty/tinymt32/rand.c
|
||||
3rdparty/tinymt32/tinymt32.c
|
||||
# assert
|
||||
src/libc/assert/assert.c
|
||||
src/assert/assert.c
|
||||
# ctype
|
||||
src/libc/ctype/isalnum.c
|
||||
src/libc/ctype/isalpha.c
|
||||
src/libc/ctype/isblank.c
|
||||
src/libc/ctype/iscntrl.c
|
||||
src/libc/ctype/isdigit.c
|
||||
src/libc/ctype/isgraph.c
|
||||
src/libc/ctype/islower.c
|
||||
src/libc/ctype/isprint.c
|
||||
src/libc/ctype/ispunct.c
|
||||
src/libc/ctype/isspace.c
|
||||
src/libc/ctype/isupper.c
|
||||
src/libc/ctype/isxdigit.c
|
||||
src/libc/ctype/tolower.c
|
||||
src/libc/ctype/toupper.c
|
||||
src/ctype/isalnum.c
|
||||
src/ctype/isalpha.c
|
||||
src/ctype/isblank.c
|
||||
src/ctype/iscntrl.c
|
||||
src/ctype/isdigit.c
|
||||
src/ctype/isgraph.c
|
||||
src/ctype/islower.c
|
||||
src/ctype/isprint.c
|
||||
src/ctype/ispunct.c
|
||||
src/ctype/isspace.c
|
||||
src/ctype/isupper.c
|
||||
src/ctype/isxdigit.c
|
||||
src/ctype/tolower.c
|
||||
src/ctype/toupper.c
|
||||
# errno
|
||||
src/libc/errno/errno.c
|
||||
src/errno/errno.c
|
||||
# inttypes
|
||||
src/libc/inttypes/imaxabs.c
|
||||
src/libc/inttypes/imaxdiv.c
|
||||
src/libc/inttypes/strtoimax.c
|
||||
src/libc/inttypes/strtoumax.c
|
||||
src/inttypes/imaxabs.c
|
||||
src/inttypes/imaxdiv.c
|
||||
src/inttypes/strtoimax.c
|
||||
src/inttypes/strtoumax.c
|
||||
# locale
|
||||
src/libc/locale/setlocale.c
|
||||
src/libc/locale/localeconv.c
|
||||
src/locale/setlocale.c
|
||||
src/locale/localeconv.c
|
||||
# signal
|
||||
src/libc/signal/signal.c
|
||||
src/libc/signal/raise.c
|
||||
src/signal/signal.c
|
||||
src/signal/raise.c
|
||||
# stdio
|
||||
src/libc/stdio/asprintf.c
|
||||
src/libc/stdio/dprintf.c
|
||||
src/libc/stdio/fprintf.c
|
||||
src/libc/stdio/printf.c
|
||||
src/libc/stdio/printf/format_fixed.c
|
||||
src/libc/stdio/printf/format_fp.c
|
||||
src/libc/stdio/printf/format_usual.c
|
||||
src/libc/stdio/printf/print.c
|
||||
src/libc/stdio/printf/util.c
|
||||
src/libc/stdio/putc.c
|
||||
src/libc/stdio/puts.c
|
||||
src/libc/stdio/snprintf.c
|
||||
src/libc/stdio/sprintf.c
|
||||
src/libc/stdio/vasprintf.c
|
||||
src/libc/stdio/vdprintf.c
|
||||
src/libc/stdio/vfprintf.c
|
||||
src/libc/stdio/vprintf.c
|
||||
src/libc/stdio/vsnprintf.c
|
||||
src/libc/stdio/vsprintf.c
|
||||
src/stdio/asprintf.c
|
||||
src/stdio/clearerr.c
|
||||
src/stdio/dprintf.c
|
||||
src/stdio/fclose.c
|
||||
src/stdio/fdopen.c
|
||||
src/stdio/ferror.c
|
||||
src/stdio/feof.c
|
||||
src/stdio/fflush.c
|
||||
src/stdio/fgetc.c
|
||||
src/stdio/fgetpos.c
|
||||
src/stdio/fgets.c
|
||||
src/stdio/fileutil.c
|
||||
src/stdio/fopen.c
|
||||
src/stdio/fprintf.c
|
||||
src/stdio/fputc.c
|
||||
src/stdio/fputs.c
|
||||
src/stdio/fread.c
|
||||
src/stdio/freopen.c
|
||||
src/stdio/fseek.c
|
||||
src/stdio/fsetpos.c
|
||||
src/stdio/ftell.c
|
||||
src/stdio/fwrite.c
|
||||
src/stdio/getc.c
|
||||
src/stdio/getchar.c
|
||||
src/stdio/gets.c
|
||||
src/stdio/getline.c
|
||||
src/stdio/getdelim.c
|
||||
src/stdio/perror.c
|
||||
src/stdio/printf.c
|
||||
src/stdio/printf/format_fixed.c
|
||||
src/stdio/printf/format_fp.c
|
||||
src/stdio/printf/format_usual.c
|
||||
src/stdio/printf/print.c
|
||||
src/stdio/printf/util.c
|
||||
src/stdio/putc.c
|
||||
src/stdio/putchar.c
|
||||
src/stdio/puts.c
|
||||
src/stdio/remove.c
|
||||
src/stdio/rewind.c
|
||||
src/stdio/setbuf.c
|
||||
src/stdio/setvbuf.c
|
||||
src/stdio/snprintf.c
|
||||
src/stdio/sprintf.c
|
||||
src/stdio/streams.c
|
||||
src/stdio/ungetc.c
|
||||
src/stdio/vasprintf.c
|
||||
src/stdio/vdprintf.c
|
||||
src/stdio/vfprintf.c
|
||||
src/stdio/vprintf.c
|
||||
src/stdio/vsnprintf.c
|
||||
src/stdio/vsprintf.c
|
||||
# stdlib
|
||||
src/libc/stdlib/abort.c
|
||||
src/libc/stdlib/abs.c
|
||||
src/libc/stdlib/atof.c
|
||||
src/libc/stdlib/atoi.c
|
||||
src/libc/stdlib/atol.c
|
||||
src/libc/stdlib/atoll.c
|
||||
src/libc/stdlib/calloc.c
|
||||
src/libc/stdlib/div.c
|
||||
src/libc/stdlib/exit.c
|
||||
src/libc/stdlib/labs.c
|
||||
src/libc/stdlib/ldiv.c
|
||||
src/libc/stdlib/llabs.c
|
||||
src/libc/stdlib/lldiv.c
|
||||
src/libc/stdlib/qsort.c
|
||||
src/libc/stdlib/reallocarray.c
|
||||
src/libc/stdlib/strto_fp.c
|
||||
src/libc/stdlib/strto_int.c
|
||||
src/libc/stdlib/strtod.c
|
||||
src/libc/stdlib/strtof.c
|
||||
src/libc/stdlib/strtol.c
|
||||
src/libc/stdlib/strtold.c
|
||||
src/libc/stdlib/strtoll.c
|
||||
src/libc/stdlib/strtoul.c
|
||||
src/libc/stdlib/strtoull.c
|
||||
src/stdlib/abort.c
|
||||
src/stdlib/abs.c
|
||||
src/stdlib/atof.c
|
||||
src/stdlib/atoi.c
|
||||
src/stdlib/atol.c
|
||||
src/stdlib/atoll.c
|
||||
src/stdlib/calloc.c
|
||||
src/stdlib/div.c
|
||||
src/stdlib/exit.c
|
||||
src/stdlib/labs.c
|
||||
src/stdlib/ldiv.c
|
||||
src/stdlib/llabs.c
|
||||
src/stdlib/lldiv.c
|
||||
src/stdlib/qsort.c
|
||||
src/stdlib/reallocarray.c
|
||||
src/stdlib/strto_fp.c
|
||||
src/stdlib/strto_int.c
|
||||
src/stdlib/strtod.c
|
||||
src/stdlib/strtof.c
|
||||
src/stdlib/strtol.c
|
||||
src/stdlib/strtold.c
|
||||
src/stdlib/strtoll.c
|
||||
src/stdlib/strtoul.c
|
||||
src/stdlib/strtoull.c
|
||||
# string
|
||||
src/libc/string/memchr.c
|
||||
src/libc/string/memcmp.c
|
||||
src/libc/string/memcpy.c
|
||||
src/libc/string/memmove.c
|
||||
src/libc/string/memset.c
|
||||
src/libc/string/strcasecmp.c
|
||||
src/libc/string/strcasestr.c
|
||||
src/libc/string/strcat.c
|
||||
src/libc/string/strchr.c
|
||||
src/libc/string/strchrnul.c
|
||||
src/libc/string/strcmp.c
|
||||
src/libc/string/strcoll.c
|
||||
src/libc/string/strcpy.c
|
||||
src/libc/string/strcspn.c
|
||||
src/libc/string/strdup.c
|
||||
src/libc/string/strerror.c
|
||||
src/libc/string/strlen.c
|
||||
src/libc/string/strncasecmp.c
|
||||
src/libc/string/strncat.c
|
||||
src/libc/string/strncmp.c
|
||||
src/libc/string/strncpy.c
|
||||
src/libc/string/strndup.c
|
||||
src/libc/string/strnlen.c
|
||||
src/libc/string/strpbrk.c
|
||||
src/libc/string/strrchr.c
|
||||
src/libc/string/strspn.c
|
||||
src/libc/string/strstr.c
|
||||
src/libc/string/strstr_base.c
|
||||
src/libc/string/strtok.c
|
||||
src/libc/string/strxfrm.c
|
||||
src/string/memchr.c
|
||||
src/string/memcmp.c
|
||||
src/string/memcpy.c
|
||||
src/string/memmove.c
|
||||
src/string/memrchr.c
|
||||
src/string/memset.c
|
||||
src/string/strcasecmp.c
|
||||
src/string/strcasestr.c
|
||||
src/string/strcat.c
|
||||
src/string/strchr.c
|
||||
src/string/strchrnul.c
|
||||
src/string/strcmp.c
|
||||
src/string/strcoll.c
|
||||
src/string/strcpy.c
|
||||
src/string/strcspn.c
|
||||
src/string/strdup.c
|
||||
src/string/strerror.c
|
||||
src/string/strlen.c
|
||||
src/string/strncasecmp.c
|
||||
src/string/strncat.c
|
||||
src/string/strncmp.c
|
||||
src/string/strncpy.c
|
||||
src/string/strndup.c
|
||||
src/string/strnlen.c
|
||||
src/string/strpbrk.c
|
||||
src/string/strrchr.c
|
||||
src/string/strspn.c
|
||||
src/string/strstr.c
|
||||
src/string/strstr_base.c
|
||||
src/string/strtok.c
|
||||
src/string/strxfrm.c
|
||||
# time
|
||||
src/libc/time/asctime.c
|
||||
src/libc/time/ctime.c
|
||||
src/libc/time/difftime.c
|
||||
src/libc/time/gmtime.c
|
||||
src/libc/time/localtime.c
|
||||
src/libc/time/mktime.c
|
||||
src/libc/time/strftime.c)
|
||||
src/time/asctime.c
|
||||
src/time/ctime.c
|
||||
src/time/difftime.c
|
||||
src/time/gmtime.c
|
||||
src/time/localtime.c
|
||||
src/time/mktime.c
|
||||
src/time/strftime.c)
|
||||
|
||||
# Silence extended warnings on Grisu2b code
|
||||
set_source_files_properties(3rdparty/grisu2b_59_56/grisu2b_59_56.c PROPERTIES
|
||||
COMPILE_OPTIONS "-Wno-all;-Wno-extra")
|
||||
|
||||
if(vhex-generic IN_LIST TARGET_FOLDERS)
|
||||
# TODO
|
||||
endif()
|
||||
|
||||
if(vhex-sh IN_LIST TARGET_FOLDERS)
|
||||
list(APPEND SOURCES
|
||||
src/libc/signal/target/vhex-sh/kill.S
|
||||
src/libc/signal/target/vhex-sh/signal.S
|
||||
src/libc/stdlib/target/vhex-sh/_Exit.S
|
||||
src/libc/stdlib/target/vhex-sh/free.S
|
||||
src/libc/stdlib/target/vhex-sh/malloc.S
|
||||
src/libc/stdlib/target/vhex-sh/realloc.S
|
||||
src/posix/fcntl/target/vhex-sh/open.S
|
||||
src/posix/sys/wait/target/vhex-sh/wait.S
|
||||
src/posix/sys/wait/target/vhex-sh/waitpid.S
|
||||
src/posix/unistd/target/vhex-sh/read.S
|
||||
src/posix/unistd/target/vhex-sh/getppid.S
|
||||
src/posix/unistd/target/vhex-sh/close.S
|
||||
src/posix/unistd/target/vhex-sh/fork_execve.S
|
||||
src/posix/unistd/target/vhex-sh/lseek.S
|
||||
src/posix/unistd/target/vhex-sh/getpid.S
|
||||
src/posix/unistd/target/vhex-sh/getpgid.S
|
||||
src/posix/unistd/target/vhex-sh/setpgid.S
|
||||
src/posix/unistd/target/vhex-sh/write.S)
|
||||
src/stdlib/target/vhex-sh/free.c
|
||||
src/stdlib/target/vhex-sh/malloc.c
|
||||
src/stdlib/target/vhex-sh/realloc.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(sh-generic IN_LIST TARGET_FOLDERS)
|
||||
list(APPEND SOURCES
|
||||
src/libc/setjmp/target/sh-generic/setjmp.S
|
||||
src/libc/setjmp/target/sh-generic/longjmp.S
|
||||
src/libc/string/target/sh-generic/memchr.S
|
||||
src/libc/string/target/sh-generic/memcmp.S
|
||||
src/libc/string/target/sh-generic/memcpy.S
|
||||
src/libc/string/target/sh-generic/memmove.S
|
||||
src/libc/string/target/sh-generic/memset.S
|
||||
src/libc/string/target/sh-generic/strlen.S
|
||||
src/setjmp/target/sh-generic/setjmp.S
|
||||
src/setjmp/target/sh-generic/longjmp.S
|
||||
src/string/target/sh-generic/memchr.S
|
||||
src/string/target/sh-generic/memcmp.S
|
||||
src/string/target/sh-generic/memcpy.S
|
||||
src/string/target/sh-generic/memmove.S
|
||||
src/string/target/sh-generic/memset.S
|
||||
src/string/target/sh-generic/strlen.S
|
||||
src/target/sh-generic/cpucap.c)
|
||||
endif()
|
||||
|
||||
if(gint IN_LIST TARGET_FOLDERS)
|
||||
list(APPEND SOURCES
|
||||
# stdlib
|
||||
src/libc/stdlib/target/gint/free.c
|
||||
src/libc/stdlib/target/gint/malloc.c
|
||||
src/libc/stdlib/target/gint/realloc.c
|
||||
src/stdlib/target/gint/free.c
|
||||
src/stdlib/target/gint/malloc.c
|
||||
src/stdlib/target/gint/realloc.c
|
||||
# time
|
||||
src/libc/time/target/gint/clock.c
|
||||
src/libc/time/target/gint/time.c)
|
||||
endif()
|
||||
|
||||
if(casiowin-fx IN_LIST TARGET_FOLDERS)
|
||||
list(APPEND SOURCES
|
||||
src/posix/unistd/target/casiowin-fx/close.S)
|
||||
src/time/target/gint/clock.c
|
||||
src/time/target/gint/time.c)
|
||||
endif()
|
||||
|
||||
# TODO: All targets
|
||||
|
@ -266,21 +259,6 @@ endif()
|
|||
add_library(fxlibc ${SOURCES})
|
||||
|
||||
target_include_directories(fxlibc PRIVATE include/)
|
||||
if(sh-generic IN_LIST TARGET_FOLDERS)
|
||||
target_include_directories(fxlibc PRIVATE "${FXSDK_COMPILER_INSTALL}/include/openlibm")
|
||||
endif()
|
||||
|
||||
if(FXLIBC_SHARED)
|
||||
target_compile_options(fxlibc PRIVATE -fPIC)
|
||||
|
||||
if("${FXLIBC_ARCH}" STREQUAL "sh")
|
||||
# Original command: "ar qc <TARGET> <OBJECTS>; ranlib <TARGET>"
|
||||
set(CMAKE_C_CREATE_STATIC_LIBRARY
|
||||
"sh-elf-ld -shared <OBJECTS> -o <TARGET>")
|
||||
else()
|
||||
message(SEND_ERROR "TODO: Shared vhex on non-SuperH not available yet")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(FOLDER IN LISTS TARGET_FOLDERS)
|
||||
target_include_directories(fxlibc PRIVATE include/target/${FOLDER}/)
|
||||
|
|
60
README.md
60
README.md
|
@ -1,4 +1,4 @@
|
|||
# The FX C Library
|
||||
# fxlibc: The FX C Library
|
||||
|
||||
This directory contains the sources of the FxLibc Library. See `CMakeLists.txt`
|
||||
to see what release version you have.
|
||||
|
@ -13,65 +13,65 @@ system.
|
|||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
FxLibc requires a GCC compiler toolchain the PATH to build for any calculator.
|
||||
You cannot build with your system compiler! The tutorial on Planète Casio
|
||||
builds an `sh-elf` toolchain that supports all models using multilib.
|
||||
builds an `sh-elf` toolchain that supports all models using multilib. See also
|
||||
[Lephenixnoir/sh-elf-gcc](/Lephenixnoir/sh-elf-gcc).
|
||||
|
||||
For Vhex and gint targets, the headers of the kernel are also required.
|
||||
For Vhex targets, the headers of the kernel are also required (but not for gint; the fxlibc is installed before gint).
|
||||
|
||||
---
|
||||
|
||||
## Building and installing FxLibc
|
||||
|
||||
FxLibc supports several targets:
|
||||
* Vhex on SH targets (`vhex-sh`)
|
||||
* CASIOWIN for fx-9860G-like calculators (`casiowin-fx`)
|
||||
* CASIOWIN for fx-CG-series calculators (`casiowin-cg`)
|
||||
* gint for all targets (`gint`)
|
||||
* gint for all calculators (`gint`)
|
||||
|
||||
Each target supports different features depending on what the kernel/OS
|
||||
provides.
|
||||
|
||||
#### Configuration and support
|
||||
For automated gint/fxSDK setups using [GiteaPC](/Lephenixnoir/GiteaPC) is recommended. The instructions below are for manual installs.
|
||||
|
||||
#### Configuration
|
||||
|
||||
Configure with CMake; specify the target with `-DFXLIBC_TARGET`. For SH
|
||||
platforms, set the toolchain to `cmake/toolchain-sh.cmake`.
|
||||
|
||||
The FxLibc supports shared libraries when building with Vhex (TODO); set
|
||||
`-DSHARED=1` to enable this behavior.
|
||||
You can either install FxLibc in the compiler's `include` folder (for Vhex), or another folder of your choice (eg. the fxSDK sysroot). If you choose non-standard folders you might need `-I` and `-L` options to use the library.
|
||||
|
||||
You can either install FxLibc in the compiler's `include` folder, or installl
|
||||
in another location of your choice. In the second case, you will need a `-I`
|
||||
option when using the library.
|
||||
|
||||
To use the compiler, set `PREFIX` like this:
|
||||
|
||||
```
|
||||
% PREFIX=$(sh-elf-gcc -print-file-name=.)
|
||||
```
|
||||
|
||||
To use another location, set `PREFIX` manually (recommended):
|
||||
|
||||
```
|
||||
```bash
|
||||
# Install in the compiler's include folder
|
||||
% PREFIX="$(sh-elf-gcc -print-file-name=.)"
|
||||
# Install in the fxSDK sysroot
|
||||
% PREFIX="$(fxsdk path sysroot)"
|
||||
# Custom target
|
||||
% PREFIX="$HOME/.sh-prefix/"
|
||||
# For gint, do not specify anything, the fxSDK will be used dynamically
|
||||
```
|
||||
|
||||
Example for a static Vhex build:
|
||||
|
||||
```
|
||||
```bash
|
||||
% cmake -B build-vhex-sh -DFXLIBC_TARGET=vhex-sh -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sh.cmake -DCMAKE_INSTALL_PREFIX="$PREFIX"
|
||||
```
|
||||
|
||||
#### Building
|
||||
Or for a traditional gint/fxSDK build:
|
||||
|
||||
```bash
|
||||
% cmake -B build-gint -DFXLIBC_TARGET=gint -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sh.cmake
|
||||
```
|
||||
|
||||
#### Build and install
|
||||
|
||||
Build in the directory specified in `cmake -B`.
|
||||
|
||||
```
|
||||
% make -C build
|
||||
```
|
||||
|
||||
To install, run the `install` target.
|
||||
|
||||
```
|
||||
% make -C build install
|
||||
```bash
|
||||
% make -C build-X
|
||||
% make -C build-X install
|
||||
```
|
||||
|
||||
---
|
||||
|
|
242
STATUS
242
STATUS
|
@ -31,51 +31,49 @@ TODO: Function/symbol/macro is not implemented/defined
|
|||
BDEPS(...): Function/symbol/macro needs ... to build
|
||||
LDEPS(...): Function/symbol/macro needs ... to link
|
||||
TEST: Function/symbol/macro needs to be tested
|
||||
DONE: Function/symbol/macro is defined, builds, links, and is tested
|
||||
-: Function/symbol/macro is defined, builds, links, and is tested
|
||||
|
||||
7.2 <assert.h>
|
||||
! 7.2.1 assert: LDEPS(fprintf,stderr)
|
||||
7.2.1 assert LDEPS(fprintf,stderr)
|
||||
|
||||
7.3 <complex.h> => OpenLibm
|
||||
|
||||
7.4 <ctype.h>
|
||||
7.4.1 is*: DONE
|
||||
7.4.2 to*: DONE
|
||||
7.4.1 is* -
|
||||
7.4.2 to* -
|
||||
|
||||
7.5 <errno.h>
|
||||
7.5.2 EDOM EILSEQ ERANGE: DONE
|
||||
7.5.2 EDOM, EILSEQ, ERANGE -
|
||||
|
||||
7.6 <fenv.h> => OpenLibm
|
||||
|
||||
7.7 <float.h> => GCC
|
||||
|
||||
7.8 <inttypes.h>
|
||||
! 7.8.1 PRI* macros: LDEPS(*printf)
|
||||
! 7.8.1 SCN* macros: LDEPS(*scanf)
|
||||
7.8.2.1 imaxabs: DONE
|
||||
7.8.2.2 imaxdiv: DONE
|
||||
7.8.2.3 strtoimax strtoumax: DONE
|
||||
! 7.8.2.4 wcstoimax wcstoumax: TODO
|
||||
7.8.1 PRI* macros -
|
||||
7.8.1 SCN* macros -
|
||||
7.8.2.1 imaxabs -
|
||||
7.8.2.2 imaxdiv -
|
||||
7.8.2.3 strtoimax, strtoumax -
|
||||
7.8.2.4 wcstoimax, wcstoumax TODO
|
||||
|
||||
7.9 <iso646.h> => GCC
|
||||
|
||||
7.10 <limits.h> => GCC
|
||||
|
||||
7.11 <locale.h>
|
||||
! 7.11.1 setlocale: TEST
|
||||
! 7.11.2 localeconv: TEST
|
||||
7.11.1 setlocale TEST
|
||||
7.11.2 localeconv TEST
|
||||
|
||||
7.12 <math.h> => OpenLibm
|
||||
|
||||
7.13 <setjmp.h>
|
||||
7.13.1 setjmp: DONE
|
||||
7.13.2 longjmp: DONE
|
||||
7.13.1 setjmp -
|
||||
7.13.2 longjmp -
|
||||
|
||||
7.14 <signal.h>
|
||||
7.14 sig_atomic_t SIG_DFL SIG_ERR SIG_IGN: DONE
|
||||
7.14 SIGABRT SIGFPE SIGILL SIGINT SIGSEGV SIGTERM: DONE
|
||||
7.14.1.1 signal: DONE
|
||||
7.14.1.2 raise: DONE
|
||||
7.14.1.1 signal -
|
||||
7.14.1.2 raise -
|
||||
|
||||
7.15 <stdarg.h> => GCC
|
||||
|
||||
|
@ -86,93 +84,143 @@ DONE: Function/symbol/macro is defined, builds, links, and is tested
|
|||
7.18 <stdint.h> => GCC
|
||||
|
||||
7.19 <stdio.h>
|
||||
7.19.1 Introduction: TEST
|
||||
TODO: Handle wide-oriented streams? (see notes)
|
||||
! 7.19.4 Operations on files: TODO
|
||||
! 7.19.5 File access functions: TODO
|
||||
! 7.19.6 Formatted input/output functions: TODO
|
||||
! 7.19.7 Character input/output functions: TODO
|
||||
! 7.19.8 Direct input/output functions: TODO
|
||||
! 7.19.9 File positioning functions: TODO
|
||||
! 7.19.10 Error-handling functions: TODO
|
||||
7.19.1 Introduction - (no wide-oriented streams *)
|
||||
7.19.1 stdin, stdout, stderr -
|
||||
|
||||
7.19.4.1 remove TEST
|
||||
7.19.4.2 rename TODO
|
||||
7.19.4.3 tmpfile TODO
|
||||
7.19.4.4 tmpnam TODO
|
||||
|
||||
7.19.5.1 fclose -
|
||||
7.19.5.2 fflush - (fflush(NULL) not supported yet)
|
||||
7.19.5.3 fopen -
|
||||
(EXT) fdopen -
|
||||
7.19.5.4 freopen -
|
||||
7.19.5.5 setbuf -
|
||||
7.19.5.6 setvbuf -
|
||||
|
||||
7.19.6.1 fprintf -
|
||||
7.19.6.2 fscanf TODO
|
||||
7.19.6.3 printf -
|
||||
7.19.6.4 scanf TODO
|
||||
7.19.6.5 snprintf -
|
||||
7.19.6.6 sprintf -
|
||||
7.19.6.7 sscanf TODO
|
||||
7.19.6.8 vfprintf -
|
||||
7.19.6.9 vfscanf TODO
|
||||
7.19.6.10 vprintf -
|
||||
7.19.6.11 vscanf TODO
|
||||
7.19.6.12 vsnprintf -
|
||||
7.19.6.13 vsprintf -
|
||||
7.19.6.14 vsscanf TODO
|
||||
(EXT) asprintf -
|
||||
(EXT) vasprintf -
|
||||
(EXT) dprintf -
|
||||
(EXT) vdprintf -
|
||||
|
||||
7.19.7.1 fgetc -
|
||||
7.19.7.2 fgets -
|
||||
7.19.7.3 fputc -
|
||||
7.19.7.4 fputs -
|
||||
7.19.7.5 getc -
|
||||
7.19.7.6 getchar -
|
||||
7.19.7.7 gets -
|
||||
7.19.7.8 putc -
|
||||
7.19.7.9 putchar -
|
||||
7.19.7.10 puts -
|
||||
7.19.7.11 ungetc -
|
||||
(EXT) getline -
|
||||
(EXT) getdelim -
|
||||
|
||||
7.19.8.1 fread -
|
||||
7.19.8.2 fwrite -
|
||||
|
||||
7.19.9.1 fgetpos -
|
||||
7.19.9.2 fseek -
|
||||
7.19.9.3 fsetpos -
|
||||
7.19.9.4 ftell -
|
||||
7.19.9.5 rewind -
|
||||
|
||||
7.19.10.1 clearerr -
|
||||
7.19.10.2 feof -
|
||||
7.19.10.3 ferror -
|
||||
7.19.10.4 perror -
|
||||
|
||||
7.20 <stdlib.h>
|
||||
7.20 RAND_MAX: DONE
|
||||
! 7.20 MB_CUR_MAX: TODO
|
||||
7.20.1.1 atof: DONE
|
||||
7.20.1.2 atoi, atol, atoll: DONE
|
||||
7.20.1.3 strtod, strtof, strtold: DONE
|
||||
7.20.1.4 strtol, strtoul, strtoll, strtoull: DONE
|
||||
7.20.2.1 rand: DONE
|
||||
7.20.2.2 srand: DONE
|
||||
7.20.3.1 calloc: DONE
|
||||
7.20.3.2 free: DONE (at least gint)
|
||||
7.20.3.3 malloc: DONE (at least gint)
|
||||
7.20.3.4 realloc: DONE (at least gint)
|
||||
7.20.4.1 abort: DONE
|
||||
! 7.20.4.2 atexit: TODO
|
||||
7.20.4.3 exit: DONE (missing stream flushing/closing/etc)
|
||||
7.20.4.4 _Exit: DONE (gint only)
|
||||
! 7.20.4.5 getenv: TODO
|
||||
! 7.20.4.6 system: TODO
|
||||
! 7.20.5.1 bsearch: TODO
|
||||
! 7.20.5.2 qsort: TEST
|
||||
7.20.6.1 abs, labs, llabs: DONE
|
||||
7.20.6.2 div, ldiv, lldiv: DONE
|
||||
! 7.20.7 Multibyte/wide character conversion functions: TODO
|
||||
! 7.20.8 Multibyte/wide string conversion functions: TODO
|
||||
7.20 MB_CUR_MAX TODO
|
||||
7.20.1.1 atof -
|
||||
7.20.1.2 atoi, atol, atoll -
|
||||
7.20.1.3 strtod, strtof, strtold -
|
||||
7.20.1.4 strtol, strtoul -
|
||||
7.20.1.4 strtoll, strtoull -
|
||||
7.20.2.1 rand -
|
||||
7.20.2.2 srand -
|
||||
7.20.3.1 calloc -
|
||||
7.20.3.2 free - (gint)
|
||||
7.20.3.3 malloc - (gint)
|
||||
7.20.3.4 realloc - (gint)
|
||||
7.20.4.1 abort - (stream flushing/closing/etc?)
|
||||
7.20.4.2 atexit TODO
|
||||
7.20.4.3 exit - (stream flushing/closing/etc?)
|
||||
7.20.4.4 _Exit - (gint)
|
||||
7.20.4.5 getenv TODO
|
||||
7.20.4.6 system TODO
|
||||
7.20.5.1 bsearch TODO
|
||||
7.20.5.2 qsort TEST
|
||||
7.20.6.1 abs, labs, llabs -
|
||||
7.20.6.2 div, ldiv, lldiv -
|
||||
7.20.7 Multibyte/wide char conv TODO
|
||||
7.20.8 Multibyte/wide string conv TODO
|
||||
|
||||
7.21 <string.h>
|
||||
7.21.2.1 memcpy: DONE
|
||||
7.21.2.2 memmove: DONE (Unoptimized: byte-by-byte)
|
||||
7.21.2.3 strcpy: DONE
|
||||
7.21.2.4 strncpy: DONE
|
||||
7.21.3.1 strcat: DONE
|
||||
7.21.3.2 strncat: DONE
|
||||
7.21.4.1 memcmp: DONE
|
||||
7.21.4.2 strcmp: DONE
|
||||
7.21.4.3 strcoll: DONE
|
||||
7.21.4.4 strncmp: DONE
|
||||
7.21.4.5 strxfrm: DONE
|
||||
7.21.5.1 memchr: DONE
|
||||
7.21.5.2 strchr: DONE
|
||||
7.21.5.3 strcspn: DONE
|
||||
7.21.5.4 strpbrk: DONE
|
||||
7.21.5.5 strrchr: DONE
|
||||
7.21.5.6 strspn: DONE
|
||||
7.21.5.7 strstr: DONE
|
||||
7.21.5.8 strtok: DONE
|
||||
7.21.6.1 memset: DONE
|
||||
7.21.6.2 strerror: DONE
|
||||
7.21.6.3 strlen: DONE
|
||||
Extensions:
|
||||
- strnlen: DONE
|
||||
- strchrnul: DONE
|
||||
- strcasestr: DONE
|
||||
- strcasecmp: DONE
|
||||
- strncasecmp: DONE
|
||||
- strdup: DONE
|
||||
- strndup: DONE
|
||||
7.21.2.1 memcpy -
|
||||
7.21.2.2 memmove - (Unoptimized: byte-by-byte)
|
||||
7.21.2.3 strcpy -
|
||||
7.21.2.4 strncpy -
|
||||
7.21.3.1 strcat -
|
||||
7.21.3.2 strncat -
|
||||
7.21.4.1 memcmp -
|
||||
7.21.4.2 strcmp -
|
||||
7.21.4.3 strcoll -
|
||||
7.21.4.4 strncmp -
|
||||
7.21.4.5 strxfrm -
|
||||
7.21.5.1 memchr -
|
||||
7.21.5.2 strchr -
|
||||
7.21.5.3 strcspn -
|
||||
7.21.5.4 strpbrk -
|
||||
7.21.5.5 strrchr -
|
||||
7.21.5.6 strspn -
|
||||
7.21.5.7 strstr -
|
||||
7.21.5.8 strtok -
|
||||
7.21.6.1 memset -
|
||||
7.21.6.2 strerror -
|
||||
7.21.6.3 strlen -
|
||||
(EXT) strnlen -
|
||||
(EXT) strchrnul -
|
||||
(EXT) strcasestr -
|
||||
(EXT) strcasecmp -
|
||||
(EXT) strncasecmp -
|
||||
(EXT) strdup -
|
||||
(EXT) strndup -
|
||||
(EXT) memrchr - (Unoptimized: byte-by-byte)
|
||||
|
||||
7.22 <tgmath.h> => GCC
|
||||
|
||||
7.23 <time.h>
|
||||
7.23.1 Components of time: DONE
|
||||
7.23.2.1 clock: DONE
|
||||
7.23.2.2 difftime: DONE
|
||||
7.23.2.3 mktime: DONE (DST flag ignored)
|
||||
7.23.2.4 time: DONE
|
||||
7.23.3.1 asctime: DONE
|
||||
7.23.3.2 ctime: DONE
|
||||
7.23.3.3 gmtime: DONE
|
||||
7.23.3.4 localtime: DONE (No timezones; same as gmtime)
|
||||
7.23.3.5 strftime: DONE (No %g/%G/%U/%V/%W; timezones %z/%Z empty)
|
||||
7.23.2.1 clock -
|
||||
7.23.2.2 difftime -
|
||||
7.23.2.3 mktime - (DST flag ignored)
|
||||
7.23.2.4 time -
|
||||
7.23.3.1 asctime -
|
||||
7.23.3.2 ctime -
|
||||
7.23.3.3 gmtime -
|
||||
7.23.3.4 localtime - (No timezones; same as gmtime)
|
||||
7.23.3.5 strftime - (No %g, %G, %U, %V, %W, %z, %Z)
|
||||
|
||||
7.24 <wchar.h>
|
||||
TODO (not a priority)
|
||||
7.24 <wchar.h> TODO (not a priority)
|
||||
|
||||
7.25 <wctype.h>
|
||||
TODO (not a priority)
|
||||
7.25 <wctype.h> TODO (not a priority)
|
||||
|
||||
# Supporting locales
|
||||
|
||||
|
@ -188,7 +236,7 @@ What if we wanted to support more locales?
|
|||
|
||||
# Supporting text and binary files (newline translation)
|
||||
|
||||
Because of 7.19.2%1,223 we don't need to support newline translation.
|
||||
Because of 7.19.2§1.223 we don't need to support newline translation.
|
||||
|
||||
# Support wide-oriented streams
|
||||
|
||||
|
|
|
@ -26,6 +26,72 @@ extern int errno;
|
|||
#define EISDIR 15 /* File descriptor is a directory. */
|
||||
#define ENOTDIR 16 /* File descriptor is not a directory. */
|
||||
#define ENOTEMPTY 17 /* Directory is not empty. */
|
||||
#define EINTR 18 /* Interrupted system call. */
|
||||
#define EAGAIN 19 /* Resource temporarily unavailable. */
|
||||
#define EIO 20 /* Input/Output error */
|
||||
#define ENODEV 21 /* No such device */
|
||||
#define ENOMEDIUM 22 /* No medium found */
|
||||
#define EMEDIUMTYPE 23 /* Wrong medium type */
|
||||
|
||||
/* Error codes used by libstdc++. */
|
||||
#define EAFNOSUPPORT 24
|
||||
#define EADDRINUSE 25
|
||||
#define EADDRNOTAVAIL 26
|
||||
#define EISCONN 27
|
||||
#define E2BIG 28
|
||||
#define EFAULT 29
|
||||
#define EPIPE 30
|
||||
#define ECONNABORTED 31
|
||||
#define EALREADY 32
|
||||
#define ECONNREFUSED 33
|
||||
#define ECONNRESET 34
|
||||
#define EXDEV 35
|
||||
#define EDESTADDRREQ 36
|
||||
#define EBUSY 37
|
||||
#define ENOEXEC 38
|
||||
#define EFBIG 39
|
||||
#define ENAMETOOLONG 40
|
||||
#define ENOSYS 41
|
||||
#define EHOSTUNREACH 42
|
||||
#define ENOTTY 43
|
||||
#define EMSGSIZE 44
|
||||
#define ENETDOWN 45
|
||||
#define ENETRESET 46
|
||||
#define ENETUNREACH 47
|
||||
#define ENOBUFS 48
|
||||
#define ECHILD 49
|
||||
#define ENOLCK 50
|
||||
#define ENOMSG 51
|
||||
#define ENOPROTOOPT 52
|
||||
#define ENXIO 53
|
||||
#define ESRCH 54
|
||||
#define ENOTSOCK 55
|
||||
#define ENOTCONN 56
|
||||
#define EINPROGRESS 57
|
||||
#define EPERM 58
|
||||
#define EOPNOTSUPP 59
|
||||
#define EWOULDBLOCK 60
|
||||
#define EPROTONOSUPPORT 61
|
||||
#define EROFS 62
|
||||
#define EDEADLK 63
|
||||
#define ETIMEDOUT 64
|
||||
#define EMFILE 65
|
||||
#define EMLINK 66
|
||||
#define ELOOP 67
|
||||
#define EPROTOTYPE 68
|
||||
#define EBADMSG 69
|
||||
#define EIDRM 70
|
||||
#define ENOLINK 71
|
||||
#define ENODATA 72
|
||||
#define ENOSR 73
|
||||
#define ECANCELED 74
|
||||
#define EOWNERDEAD 75
|
||||
#define EPROTO 76
|
||||
#define ENOTRECOVERABLE 77
|
||||
#define ETIME 78
|
||||
#define ETXTBUSY 79
|
||||
#define EOVERFLOW 80
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ extern "C" {
|
|||
** parse options, lay out strings, and generate output.
|
||||
*/
|
||||
|
||||
#include <bits/types/FILE.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -85,12 +85,8 @@ struct __printf_format {
|
|||
int16_t precision;
|
||||
|
||||
/*
|
||||
** Size specifier for integers (%o, %x, %i, %d, %u), may be one of:
|
||||
** (0) char (8-bit)
|
||||
** (1) short (16-bit)
|
||||
** (2) int (32-bit)
|
||||
** (3) long (32-bit)
|
||||
** (4) long long (64-bit)
|
||||
** Size specifier for integers (%o, %x, %i, %d, %u), is equal to the
|
||||
** sizeof() of the targeted type. Also used for %lc.
|
||||
*/
|
||||
uint8_t size;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Hide by default in C++ (7.8.1§1.181) */
|
||||
/* Hide by default in C++ (7.8.1§1.182) */
|
||||
#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
|
||||
|
||||
/* Printing signed fixed-width types, decimal */
|
||||
|
|
|
@ -7,11 +7,10 @@ extern "C" {
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
/* C99 API. */
|
||||
|
||||
typedef volatile atomic_int sig_atomic_t;
|
||||
typedef int sig_atomic_t;
|
||||
|
||||
/* Type of a signal handler.*/
|
||||
typedef void (*__sighandler_t)(int);
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
/* We rely on GCC's default version. */
|
||||
#include "stdint-gcc.h"
|
270
include/stdio.h
270
include/stdio.h
|
@ -7,11 +7,99 @@ extern "C" {
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Type of FILE handlers. */
|
||||
#include <bits/types/FILE.h>
|
||||
#define __FILE_BUF_READ 0
|
||||
#define __FILE_BUF_WRITE 1
|
||||
|
||||
/* Type of positions within files. */
|
||||
/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the
|
||||
work is maintaining that buffer to provide the basic fgetc()/fputc()
|
||||
functions, then everything else is built on top of the abstracted stream.
|
||||
|
||||
The buffer of a FILE can either be in reading or writing mode. When in
|
||||
reading mode, the buffer contains pre-fetched data from a previous read that
|
||||
hasn't yet been requested by the user. When in writing mode, the buffer
|
||||
contains data written by the user which hasn't yet been sent to the kernel.
|
||||
|
||||
The buffer has the following structure:
|
||||
|
||||
0 bufpos bufread bufsize
|
||||
+--------+---------+---------+
|
||||
|xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading)
|
||||
+--------+---------+---------+
|
||||
|wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing)
|
||||
+--------+-------------------+
|
||||
|
||||
x: Data read from file descriptor and returned to user
|
||||
r: Data read from file descriptor not yet returned to user
|
||||
w: Data written by user not yet sent to file descriptor
|
||||
u: Undefined
|
||||
|
||||
In reading mode, the region [0..bufread) contains data obtained from the
|
||||
file. bufpos marks how much has been read, in the sense that [0..bufpos) has
|
||||
already been returned to the user while [bufpos..bufread) has not. The offset
|
||||
on the underlying file descriptor sits at bufread, so the position reported
|
||||
by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined.
|
||||
|
||||
In writing mode, the region [0..bufpos) contains data received through API
|
||||
but not yet written to the file descriptor. ftell() reports fdpos + bufpos.
|
||||
The rest of the buffer is undefined.
|
||||
|
||||
The ungetc() function pushes back characters into the buffer; if the FILE is
|
||||
unbuffered, then it's made buffered temporarily to hold the characters and
|
||||
cleared at the next fflush() or read. The buffer is put in reading mode. For
|
||||
this reason, reading functions should test [fp->buf] to check whether there
|
||||
is a buffer instead of [fp->bufmode != _IONBF].
|
||||
|
||||
Many fields in the FILE structure are abstracted away by API calls in layers:
|
||||
|
||||
1. [fd], [fdpos] and [error] are updated by the primitive functions of
|
||||
fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously).
|
||||
2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(),
|
||||
setvbuf() and fclose().
|
||||
3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions
|
||||
like fgets() or fwrite(), and cleared by fflush().
|
||||
4. [readable], [writable], [append] and [text] are set by fopen() and
|
||||
freopen(), and used as read-only by the primitive functions of 3. */
|
||||
typedef struct {
|
||||
/* File descriptor */
|
||||
int fd;
|
||||
/* Current position in file, as tracked by the file descriptor (ie. not
|
||||
accounting for buffer operations) */
|
||||
size_t fdpos;
|
||||
|
||||
/* Pointer to buffer (NULL if _IONBF) */
|
||||
char *buf;
|
||||
/* Current position in buffer, water mark of read data in buffer, and
|
||||
buffer size; see header comment for details */
|
||||
size_t bufpos;
|
||||
size_t bufread;
|
||||
size_t bufsize;
|
||||
/* Number of ungetc()'d characters at the start of buffer data */
|
||||
int bufungetc;
|
||||
/* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */
|
||||
uint8_t bufmode :2;
|
||||
/* We own the buffer and it needs to be freed */
|
||||
uint8_t bufowned :1;
|
||||
/* __FILE_BUF_READ if the buffer is in reading mode
|
||||
__FILE_BUF_WRITE if it's in writing mode
|
||||
This mode can only be changed immediately after fflush(). */
|
||||
uint8_t bufdir :1;
|
||||
|
||||
/* Opening flags */
|
||||
uint8_t readable :1;
|
||||
uint8_t writable :1;
|
||||
uint8_t append :1;
|
||||
/* Non-zero if text mode, zero if binary mode */
|
||||
uint8_t text :1;
|
||||
/* EOF indicator */
|
||||
uint8_t eof :1;
|
||||
/* Error indicator */
|
||||
uint8_t error :1;
|
||||
} FILE;
|
||||
|
||||
/* Type of positions within files. We don't have wide-oriented streams. */
|
||||
typedef size_t fpos_t;
|
||||
|
||||
/* Buffering modes. */
|
||||
|
@ -20,8 +108,7 @@ typedef size_t fpos_t;
|
|||
#define _IONBF 2
|
||||
|
||||
/* Some buffer size for file buffering. */
|
||||
/* TODO: We might want a larger BUFSIZ than 256 on fx-CG 50. */
|
||||
#define BUFSIZ 256
|
||||
#define BUFSIZ 512
|
||||
|
||||
/* End-of-file marker. */
|
||||
#define EOF ((int)(-1))
|
||||
|
@ -38,9 +125,9 @@ typedef size_t fpos_t;
|
|||
#define L_tmpnam FILENAME_MAX
|
||||
|
||||
/* Seeking positions. */
|
||||
#define SEEK_CUR 0
|
||||
#define SEEK_END 1
|
||||
#define SEEK_SET 2
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#define SEEK_SET 3
|
||||
|
||||
/* Maximum number of unique filenames that tmpnam can generate. */
|
||||
/* TODO: Set a useful value in TMP_MAX other than 16*16*16 */
|
||||
|
@ -55,6 +142,53 @@ extern FILE *stderr;
|
|||
#define stdout stdout
|
||||
#define stderr stderr
|
||||
|
||||
/*
|
||||
** Operations on files.
|
||||
*/
|
||||
|
||||
/* Remove a file from the filesystem.
|
||||
In gint, the file must not be open (open files' names are not tracked). */
|
||||
extern int remove(char const *__filename);
|
||||
|
||||
extern int rename(char const *__old, char const *__new);
|
||||
|
||||
extern FILE *tmpfile(void);
|
||||
|
||||
extern char *tmpnam(char *__s);
|
||||
|
||||
/*
|
||||
** File access functions.
|
||||
*/
|
||||
|
||||
/* Flush the stream and disassociate it from the underlying file. */
|
||||
extern int fclose(FILE *__fp);
|
||||
|
||||
/* Flush any written data in the FILE's internal buffer. */
|
||||
extern int fflush(FILE *__fp);
|
||||
|
||||
/* Open a file and associate a stream with it. */
|
||||
extern FILE *fopen(
|
||||
char const * __restrict__ __filename,
|
||||
char const * __restrict__ __mode);
|
||||
|
||||
/* Open a file descriptor and associate a stream with it. */
|
||||
extern FILE *fdopen(int __fd, char const *__mode);
|
||||
|
||||
/* Reopen a stream with another file, or change its mode. */
|
||||
extern FILE *freopen(
|
||||
char const * __restrict__ __filename,
|
||||
char const * __restrict__ __mode,
|
||||
FILE * __restrict__ __fp);
|
||||
|
||||
/* Use __buf as a buffer (of size BUFSIZ) for access to __fp. */
|
||||
extern void setbuf(FILE * __restrict__ __fp, char * __restrict__ __buf);
|
||||
|
||||
/* Changer the buffering mode and buffer address for __fp. */
|
||||
extern int setvbuf(FILE * __restrict__ __fp, char * __restrict__ __buf,
|
||||
int __mode, size_t __size);
|
||||
|
||||
extern int fileno(FILE *__fp);
|
||||
|
||||
/*
|
||||
** Formatted input/output functions.
|
||||
**
|
||||
|
@ -136,6 +270,126 @@ extern int asprintf(char ** __restrict__ __str,
|
|||
extern int vasprintf(char ** __restrict__ __str,
|
||||
char const * __restrict__ __format, va_list __args);
|
||||
|
||||
/* Formatted scan from file. */
|
||||
extern int fscanf(FILE * __restrict__ __fp,
|
||||
char const * __restrict__ __format, ...);
|
||||
|
||||
/* Formatted scan from stdin. */
|
||||
extern int scanf(
|
||||
char const * __restrict__ __format, ...);
|
||||
|
||||
/* Formatted scan from string. */
|
||||
extern int sscanf(const char * __restrict__ __s,
|
||||
char const * __restrict__ __format, ...);
|
||||
|
||||
/* Formatted scan from file (variable argument list). */
|
||||
extern int vfscanf(FILE * __restrict__ __fp,
|
||||
char const * __restrict__ __format, va_list __args);
|
||||
|
||||
/* Formatted scan from stdin (variable argument list). */
|
||||
extern int vscanf(
|
||||
char const * __restrict__ __format, va_list __args);
|
||||
|
||||
/* Formatted scan from string (variable argument list). */
|
||||
extern int vsscanf(char const * __restrict__ __s,
|
||||
char const * __restrict__ __format, va_list __args);
|
||||
|
||||
/*
|
||||
** Character input/output functions.
|
||||
*/
|
||||
|
||||
/* Read a character from a stream. */
|
||||
extern int fgetc(FILE *__fp);
|
||||
|
||||
/* Read at most n characters from a stream, stopping after a newline. */
|
||||
extern char *fgets(char * __restrict__ __s, int __n,
|
||||
FILE * __restrict__ __fp);
|
||||
|
||||
/* Write a character to a stream. */
|
||||
extern int fputc(int __c, FILE *__fp);
|
||||
|
||||
/* Write a string to a stream (excluding the NUL nyte). */
|
||||
extern int fputs(char const * __restrict__ __s, FILE * __restrict__ __fp);
|
||||
|
||||
extern int getc(FILE *__fp);
|
||||
#define getc fgetc
|
||||
|
||||
/* Get a character from stdin */
|
||||
extern int getchar(void);
|
||||
#define getchar() fgetc(stdin)
|
||||
|
||||
/* (DEPRECATED; use fgets() instead) Read a string from stdin. */
|
||||
extern char *gets(char *__s);
|
||||
|
||||
/* Get a line from stream, with dynamic allocation */
|
||||
extern ssize_t getline(char ** __restrict__ __lineptr,
|
||||
size_t * __restrict__ __n, FILE * __restrict__ __fp);
|
||||
|
||||
/* Like getline but with [delim] instead of '\n' */
|
||||
extern ssize_t getdelim(char ** __restrict__ __lineptr,
|
||||
size_t * __restrict__ __n, int __delim, FILE * __restrict__ __fp);
|
||||
|
||||
extern int putc(int __c, FILE *__fp);
|
||||
#define putc fputc
|
||||
|
||||
/* Write a character to stdout */
|
||||
extern int putchar(int __c);
|
||||
#define putchar(__c) fputc(__c, stdout)
|
||||
|
||||
/* Write a string to stdout, followed by a newline */
|
||||
extern int puts(char const *__s);
|
||||
|
||||
/* Un-read a character back to the stream; only one ungetc() is guaranteed, and
|
||||
the character is lost after reading, writing or flushing. */
|
||||
extern int ungetc(int __c, FILE *__fp);
|
||||
|
||||
/*
|
||||
** Direct input/output functions.
|
||||
*/
|
||||
|
||||
/* Read an array of items from a stream. */
|
||||
extern size_t fread(void * __restrict__ __ptr, size_t __size, size_t __nmemb,
|
||||
FILE * __restrict__ __fp);
|
||||
|
||||
/* Write an array of items to a stream. */
|
||||
extern size_t fwrite(void const * __restrict__ __ptr, size_t __size,
|
||||
size_t __nmemb, FILE * __restrict__ __fp);
|
||||
|
||||
/*
|
||||
** File positioning functions.
|
||||
*/
|
||||
|
||||
/* Get current position (same as ftell() unless wide-oriented). */
|
||||
extern int fgetpos(FILE * __restrict__ __fp, fpos_t * __restrict__ __pos);
|
||||
|
||||
/* Set the current position. */
|
||||
extern int fseek(FILE *__fp, long __offset, int __whence);
|
||||
|
||||
/* Restore the position to a value returned by fgetpos(). */
|
||||
extern int fsetpos(FILE *__fp, fpos_t const *__pos);
|
||||
|
||||
/* Get the current position. */
|
||||
extern long ftell(FILE *__fp);
|
||||
|
||||
/* Sets the file position to the start of the stream. */
|
||||
extern void rewind(FILE *__fp);
|
||||
|
||||
/*
|
||||
** Error-handling functions.
|
||||
*/
|
||||
|
||||
/* Clear EOF and error flags in the stream. */
|
||||
extern void clearerr(FILE *__fp);
|
||||
|
||||
/* Test the EOF flag. */
|
||||
extern int feof(FILE *__fp);
|
||||
|
||||
/* Test the error flag. */
|
||||
extern int ferror(FILE *__fp);
|
||||
|
||||
/* Print a message followed by strerror(errno) to stdout. */
|
||||
extern void perror(char const *__s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,8 @@ extern void free(void *__ptr);
|
|||
__attribute__((noreturn))
|
||||
extern void abort(void);
|
||||
|
||||
extern int atexit(void (*__func)(void));
|
||||
|
||||
/* Exit; calls handlers, flushes and closes streams and temporary files. */
|
||||
__attribute__((noreturn))
|
||||
extern void exit(int __status);
|
||||
|
@ -46,6 +48,10 @@ extern void exit(int __status);
|
|||
__attribute__((noreturn))
|
||||
extern void _Exit(int __status);
|
||||
|
||||
extern char *getenv(char const *__name);
|
||||
|
||||
extern int system(char const *__string);
|
||||
|
||||
/* Integer arithmetic functions. */
|
||||
|
||||
extern int abs(int __j);
|
||||
|
@ -142,15 +148,20 @@ extern long double strtold(
|
|||
#define RAND_MAX 0x7fffffff
|
||||
|
||||
/* Seed the PRNG. */
|
||||
extern void srand(unsigned int seed);
|
||||
extern void srand(unsigned int __seed);
|
||||
|
||||
/* Generate a pseudo-random number between 0 and RAND_MAX. */
|
||||
extern int rand(void);
|
||||
|
||||
/* Searching and sorting utilities. */
|
||||
|
||||
void qsort(void *base, size_t nmemb, size_t size,
|
||||
int (*compare)(void const *left, void const *right));
|
||||
extern void *bsearch(void const *__key,
|
||||
void const *__base, size_t __nmemb, size_t __size,
|
||||
int (*__compare)(void const *, void const *));
|
||||
|
||||
extern void qsort(
|
||||
void *__base, size_t __nmemb, size_t __size,
|
||||
int (*__compare)(void const *, void const *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -54,6 +54,9 @@ extern size_t strxfrm(char * __restrict__ __dest,
|
|||
/* Search __c within the first __n characters of __s. */
|
||||
extern void *memchr(void const *__s, int __c, size_t __n);
|
||||
|
||||
/* Search the last occurrence of __c withing the first __n bytes of __s. */
|
||||
extern void *memrchr(void const *__s, int __c, size_t __n);
|
||||
|
||||
/* Find the first occurrence of __c within __s. */
|
||||
extern char *strchr(char const *__s, int __c);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ extern "C" {
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef __KERNEL_MEMORY_H__
|
||||
// mapping flags
|
||||
|
|
|
@ -55,16 +55,16 @@ struct stat {
|
|||
|
||||
dev_t st_dev;
|
||||
ino_t st_ino;
|
||||
nlink_t st_link;
|
||||
nlink_t st_nlink;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
dev_t st_rdev;
|
||||
blksize_t st_blksize;
|
||||
blkcnt_t st_blocks;
|
||||
|
||||
// struct timespec st_atim;
|
||||
// struct timespec st_mtim;
|
||||
// struct timespec st_ctim;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
};
|
||||
|
||||
#define st_atime st_atim.tv_sec
|
||||
|
@ -72,8 +72,10 @@ struct stat {
|
|||
#define st_ctime st_ctim.tv_sec
|
||||
|
||||
/* Obtain information about an entry in the filesystem. */
|
||||
extern int stat(char const * restrict __pathname,
|
||||
struct stat * restrict __statbuf);
|
||||
extern int stat(char const * __restrict__ __pathname,
|
||||
struct stat * __restrict__ __statbuf);
|
||||
|
||||
extern int chmod(char const *__pathname, mode_t mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef __BITS_TRAPA_H__
|
||||
# define __BITS_TRAPA_H__
|
||||
|
||||
/*
|
||||
** Normally the SH3/SH4 processor provide a "trapa" instruction which allow
|
||||
** tipping between userland and kernel. But Casio's don't use this method
|
||||
** (this is why we are always in "privilegied mode" and we can do whatever
|
||||
** we whant) but use custom calling convention to access the syscall call.
|
||||
**
|
||||
** The convention whant that the user jump into the syscall trampoline code
|
||||
** located at 0x80010070 for fx9860g and 0x80020070 for fxcg20/50.
|
||||
*/
|
||||
# define casio_trapa(id) \
|
||||
mov.l syscall_table, r2 ;\
|
||||
mov.l syscall_id, r0 ;\
|
||||
jmp @r2 ;\
|
||||
nop ;\
|
||||
.align 4 ;\
|
||||
syscall_table: .long 0x80020070 ;\
|
||||
syscall_id: .long id
|
||||
|
||||
#endif /*__BITS_TRAPA_H__*/
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef __BITS_UNISTD_32_H__
|
||||
# define __BITS_UNISTD_32_H__
|
||||
|
||||
// File manipulation
|
||||
#define __NR_BFile_Remove 0x00001db4
|
||||
#define __NR_BFile_Create 0x00001dae
|
||||
#define __NR_BFile_Open 0x00001da3
|
||||
#define __NR_BFile_Close 0x00001da4
|
||||
#define __NR_BFile_Size 0x00001da6
|
||||
#define __NR_BFile_Write 0x00001daf
|
||||
#define __NR_BFile_Read 0x00001dac
|
||||
#define __NR_BFile_FindFirst 0x00001db7
|
||||
#define __NR_BFile_FindNext 0x00001db9
|
||||
#define __NR_BFile_FindClose 0x00001dba
|
||||
|
||||
// Keyboard interface
|
||||
#define __NR_PutKeyCode 0x000012c6
|
||||
#define __NR_GetKeyWait 0x000012bf
|
||||
#define __NR_ClearKeyBuffer 0x000012c7
|
||||
#define __NR_GetVRAMAddress 0x000001e6
|
||||
|
||||
// Memory management
|
||||
#define __NR_Bmem_malloc 0x00001f44
|
||||
#define __NR_Bmem_free 0x00001f42
|
||||
#define __NR_Bmem_calloc 0x00001f40
|
||||
#define __NR_Bmem_realloc 0x00001f46
|
||||
|
||||
// Timer interface
|
||||
#define __NR_Timer_Install 0x000008d9
|
||||
#define __NR_Timer_Deinstall 0x000008da
|
||||
#define __NR_Timer_Start 0x000008db
|
||||
#define __NR_Timer_Stop 0x000008dc
|
||||
|
||||
#endif /*__BITS_UNISTD_32_H__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
typedef struct {
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,57 +0,0 @@
|
|||
#ifndef __BITS_UNISTD_32_H__
|
||||
# define __BITS_UNISTD_32_H__
|
||||
|
||||
// File manipulation
|
||||
#define __NR_Bfile_CreateFile 0x00000434
|
||||
#define __NR_Bfile_OpenFile 0x0000042c
|
||||
#define __NR_Bfile_WriteFile 0x00000435
|
||||
#define __NR_Bfile_ReadFile 0x00000432
|
||||
#define __NR_Bfile_SeekFile 0x00000431
|
||||
#define __NR_Bfile_CloseFile 0x0000042d
|
||||
#define __NR_Bfile_FindFirst 0x0000043b
|
||||
#define __NR_Bfile_FindNext 0x0000043c
|
||||
#define __NR_Bfile_FindClose 0x0000043d
|
||||
#define __NR_Bfile_GetMediaFree 0x0000042e
|
||||
#define __NR_Bfile_RemoveFile 0x00000439
|
||||
|
||||
// Display syscalls
|
||||
#define __NR_Bdisp_GetVRAM 0x00000135
|
||||
#define __NR_Bdisp_DrawLine 0x00000030
|
||||
#define __NR_Bdisp_AllClr_VRAM 0x00000143
|
||||
#define __NR_Bdisp_Display 0x00000028
|
||||
#define __NR_Bdisp_PrintMini 0x00000c4f
|
||||
#define __NR_Bdisp_ClearArea 0x0000014b
|
||||
#define __NR_Bdisp_ReverseArea 0x0000014d
|
||||
#define __NR_Bdisp_RestoreDisp 0x00000814
|
||||
#define __NR_Bdisp_SaveDisp 0x00000813
|
||||
|
||||
// Keyboard primitives
|
||||
#define __NR_Bkey_GetKey 0x0000090f
|
||||
#define __NR_Bkey_PutKeycode 0x0000024f
|
||||
#define __NR_BKey_GetKeyWait 0x00000247
|
||||
|
||||
// Memory management
|
||||
#define __NR_Bmem_malloc 0x00000acd
|
||||
#define __NR_Bmem_realloc 0x00000e6d
|
||||
#define __NR_Bmem_called 0x00000e6b
|
||||
#define __NR_Bmem_free 0x00000acc
|
||||
|
||||
// USB primitive
|
||||
#define __NR_USB_Open 0x000002ac // not sure
|
||||
#define __NR_USB_Close 0x000004a4 // not sure
|
||||
|
||||
// SD Card primitives
|
||||
#define __NR_SDC_Init 0x0000017a // not sure
|
||||
#define __NR_SDC_Mount 0x0000044b // not sure
|
||||
#define __NR_SDC_Umount 0x0000044a
|
||||
|
||||
// Timer interface
|
||||
#define __NR_TimerInstall 0x00000118
|
||||
#define __NR_TimerDeinstall 0x00000119
|
||||
#define __NR_TimerStart 0x0000011a
|
||||
#define __NR_TimerStop 0x0000011b
|
||||
|
||||
// power management
|
||||
#define __NR_PowerOff 0x000003f4
|
||||
|
||||
#endif /*__BITS_UNISTD_32__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_CONFNAME_H__
|
||||
# define __BITS_CONFNAME_H__
|
||||
|
||||
#define _SC_PAGE_SIZE 0
|
||||
#define _SC_PAGESIZE _SC_PAGE_SIZE
|
||||
|
||||
#endif /*__BITS_CONFNAME_H__*/
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef __BITS_EXIT_H__
|
||||
# define __BITS_EXIT_H__
|
||||
|
||||
/* Exit codes for CASIOWIN add-ins. */
|
||||
#define EXIT_SUCCESS 1
|
||||
#define EXIT_FAILURE 0
|
||||
|
||||
#endif /*__BITS_EXIT_H__*/
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef __BITS_TRAPA_H__
|
||||
# define __BITS_TRAPA_H__
|
||||
|
||||
/*
|
||||
** Normally the SH3/SH4 processor provide a "trapa" instruction which allow
|
||||
** tipping between userland and kernel. But Casio's don't use this method
|
||||
** (this is why we are always in "privilegied mode" and we can do whatever
|
||||
** we whant) but use custom calling convention to access the syscall call.
|
||||
**
|
||||
** The convention whant that the user jump into the syscall trampoline code
|
||||
** located at 0x80010070 for fx9860g and 0x80020070 for fxcg20/50.
|
||||
*/
|
||||
# define casio_trapa(id) \
|
||||
mov.l syscall_table, r2 ;\
|
||||
mov.l syscall_id, r0 ;\
|
||||
jmp @r2 ;\
|
||||
nop ;\
|
||||
.align 4 ;\
|
||||
syscall_table: .long 0x80010070 ;\
|
||||
syscall_id: .long id
|
||||
|
||||
#endif /*__BITS_TRAPA_H__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
typedef struct {
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,17 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
/* BFile handler */
|
||||
int fd;
|
||||
/* Current position in file */
|
||||
size_t pos;
|
||||
/* Buffering mode */
|
||||
// TODO
|
||||
/* Opening mode */
|
||||
// TODO
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,45 +0,0 @@
|
|||
#ifndef __BITS_ASM_UNISTD_32_H__
|
||||
# define __BITS_ASM_UNISTD_32_H__
|
||||
|
||||
// Define the number of syscall
|
||||
#define __NR_MAX 21
|
||||
|
||||
// Kernel Test
|
||||
#define __NR_test_syscall 0
|
||||
|
||||
// Process
|
||||
#define __NR_exit 1
|
||||
#define __NR_fork_execve 2 // (custom)
|
||||
#define __NR_waitpid 3
|
||||
#define __NR_wait 4
|
||||
#define __NR_getpid 5
|
||||
#define __NR_getppid 6
|
||||
#define __NR_getpgid 7
|
||||
#define __NR_setpgid 8
|
||||
|
||||
// Signal
|
||||
#define __NR_signal 9
|
||||
#define __NR_sigreturn 10
|
||||
#define __NR_sigaction 11
|
||||
#define __NR_kill 12
|
||||
#define __NR_sigprogmask 13
|
||||
#define __NR_sigpending 14
|
||||
#define __NR_sigaltstack 15
|
||||
|
||||
// VFS
|
||||
#define __NR_read 16
|
||||
#define __NR_write 17
|
||||
#define __NR_open 18
|
||||
#define __NR_close 19
|
||||
#define __NR_lseek 20
|
||||
#define __NR_pread 21
|
||||
#define __NR_pwrite 22
|
||||
|
||||
// Memory
|
||||
#define __NR_mmap 23
|
||||
#define __NR_munmap 24
|
||||
#define __NR_proc_heap_alloc 25 // (custom)
|
||||
#define __NR_proc_heap_free 26 // (custom)
|
||||
#define __NR_proc_heap_realloc 27 // (custom)
|
||||
|
||||
#endif /*__BITS_ASM_UNISTD_32_H__*/
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef __BITS_CONFNAME_H__
|
||||
# define __BITS_CONFNAME_H__
|
||||
|
||||
//FIXME: this part is probably arch-specific(?)
|
||||
#define _SC_PAGE_SIZE 0
|
||||
#define _SC_PAGESIZE _SC_PAGE_SIZE
|
||||
|
||||
#endif /*__BITS_CONFNAME_H__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_EXIT_H__
|
||||
# define __BITS_EXIT_H__
|
||||
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
|
||||
#endif /*__BITS_EXIT_H__*/
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef __BITS_SIGACTION_H__
|
||||
# define __BITS_SIGACTION_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Values for the HOW argument to `sigprocmask'. */
|
||||
#define SIG_BLOCK 0 /* Block signals. */
|
||||
#define SIG_UNBLOCK 1 /* Unblock signals. */
|
||||
#define SIG_SETMASK 2 /* Set the set of blocked signals. */
|
||||
|
||||
#endif /*__BITS_SIGACTION_H__*/
|
|
@ -1,50 +0,0 @@
|
|||
#ifndef __BITS_SIGNUM_H__
|
||||
# define __BITS_SIGNUM_H__
|
||||
|
||||
// Define the number of signals
|
||||
#define _NSIG 32
|
||||
|
||||
// Vhex kernel internal define used to indicate
|
||||
// if the signal is implemented or not
|
||||
#define __SIGUNDEF ((__sighandler_t) -2) /* Not implemented */
|
||||
|
||||
/* Fake signal functions. */
|
||||
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
|
||||
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
|
||||
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
|
||||
|
||||
/* ISO C99 signals. */
|
||||
#define SIGINT 2 /* Interactive attention signal. */
|
||||
#define SIGILL 4 /* Illegal instruction. */
|
||||
#define SIGABRT 6 /* Abnormal termination. */
|
||||
#define SIGFPE 8 /* Erroneous arithmetic operation. */
|
||||
#define SIGSEGV 11 /* Invalid access to storage. */
|
||||
#define SIGTERM 15 /* Termination request. */
|
||||
|
||||
/* Historical signals specified by POSIX. */
|
||||
#define SIGHUP 1 /* Hangup. */
|
||||
#define SIGQUIT 3 /* Quit. */
|
||||
#define SIGTRAP 5 /* Trace/breakpoint trap. */
|
||||
#define SIGKILL 9 /* Killed. */
|
||||
#define SIGBUS 10 /* Bus error. */
|
||||
#define SIGSYS 12 /* Bad system call. */
|
||||
#define SIGPIPE 13 /* Broken pipe. */
|
||||
#define SIGALRM 14 /* Alarm clock. */
|
||||
|
||||
/* New(er) POSIX signals (1003.1-2008, 1003.1-2013). */
|
||||
#define SIGURG 16 /* Urgent data is available at a socket. */
|
||||
#define SIGSTOP 17 /* Stop, unblockable. */
|
||||
#define SIGTSTP 18 /* Keyboard stop. */
|
||||
#define SIGCONT 19 /* Continue. */
|
||||
#define SIGCHLD 20 /* Child terminated or stopped. */
|
||||
#define SIGTTIN 21 /* Background read from control terminal. */
|
||||
#define SIGTTOU 22 /* Background write to control terminal. */
|
||||
#define SIGPOLL 23 /* Pollable event occurred (System V). */
|
||||
#define SIGXCPU 24 /* CPU time limit exceeded. */
|
||||
#define SIGXFSZ 25 /* File size limit exceeded. */
|
||||
#define SIGVTALRM 26 /* Virtual timer expired. */
|
||||
#define SIGPROF 27 /* Profiling timer expired. */
|
||||
#define SIGUSR1 30 /* User-defined signal 1. */
|
||||
#define SIGUSR2 31 /* User-defined signal 2. */
|
||||
|
||||
#endif /*__BITS_SIGNUM_H__*/
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
// opaque definition of the _IO_FILE
|
||||
struct _IO_FILE;
|
||||
|
||||
/*
|
||||
** The opaque type of streams.
|
||||
** This is the definition used elsewhere.
|
||||
*/
|
||||
typedef struct _IO_FILE FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef __BITS_TYPES___FILE_H__
|
||||
# define ___BITS_TYPES___FILE_H__
|
||||
|
||||
// define opaque definition of the FILE type
|
||||
struct _IO_FILE;
|
||||
typedef struct _IO_FILE __FILE;
|
||||
|
||||
#endif /*__BITS_TYPES___FILE_H__*/
|
|
@ -1,26 +0,0 @@
|
|||
#ifndef __BITS_TYPES_STRUCT_FILE_H__
|
||||
# define __BITS_TYPES_STRUCT_FILE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
//---
|
||||
// TODO: VFS abstraction ? or ABI-spesific abstraction ?
|
||||
//---
|
||||
|
||||
|
||||
// Define _IO_FILE
|
||||
// TODO: add open flags
|
||||
// TODO: add file descriptor ?
|
||||
// TODO: update me !
|
||||
struct _IO_FILE
|
||||
{
|
||||
off_t cursor;
|
||||
int permission;
|
||||
void *file_op;
|
||||
void *private;
|
||||
};
|
||||
|
||||
#endif /*__BITS_TYPES_STRUCT_FILE_H__*/
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef __BITS_WAITFLAGS_H__
|
||||
# define __BITS_WAITFLAGS_H__
|
||||
|
||||
/* Bits in the third argument to `waitpid'. */
|
||||
#define WNOHANG 1 /* Don't block waiting. */
|
||||
#define WUNTRACED 2 /* Report status of stopped child. */
|
||||
#define WCONTINUED 3 /* Report continued child. */
|
||||
|
||||
#endif /*__BITS_WAITFLAGS_H__*/
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef __BITS_WAITSTATUS_H__
|
||||
# define __BITS_WAITSTATUS_H__
|
||||
|
||||
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
|
||||
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
|
||||
|
||||
/* If WIFSIGNALED(STATUS), the terminating signal. */
|
||||
#define __WTERMSIG(status) ((status) & 0x7f)
|
||||
|
||||
/* If WIFSTOPPED(STATUS), the signal that stopped the child. */
|
||||
#define __WSTOPSIG(status) __WEXITSTATUS(status)
|
||||
|
||||
/* Nonzero if STATUS indicates normal termination. */
|
||||
#define __WIFEXITED(status) (__WTERMSIG(status) == 0)
|
||||
|
||||
/* Nonzero if STATUS indicates termination by a signal. */
|
||||
#define __WIFSIGNALED(status) \
|
||||
(((signed char) (((status) & 0x7f) + 1) >> 1) > 0)
|
||||
|
||||
/* Nonzero if STATUS indicates the child is stopped. */
|
||||
#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
|
||||
|
||||
/* Nonzero if STATUS indicates the child continued after a stop. */
|
||||
# define __WIFCONTINUED(status) ((status) == __W_CONTINUED)
|
||||
|
||||
/* Nonzero if STATUS indicates the child dumped core. */
|
||||
#define __WCOREDUMP(status) ((status) & __WCOREFLAG)
|
||||
|
||||
/* Macros for constructing status values. */
|
||||
#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
|
||||
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
|
||||
#define __W_CONTINUED 0xffff
|
||||
#define __WCOREFLAG 0x80
|
||||
|
||||
#endif /*__BITS_WAITSTATUS_H__*/
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __BITS_SIGNUM_H__
|
||||
# define __BITS_SIGNUM_H__
|
||||
|
||||
// Define the number of signals
|
||||
#define _NSIG 16
|
||||
|
||||
/* Fake signal functions. */
|
||||
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
|
||||
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
|
||||
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
|
||||
|
||||
/* ISO C99 signals. */
|
||||
#define SIGINT 2 /* Interactive attention signal. */
|
||||
#define SIGILL 4 /* Illegal instruction. */
|
||||
#define SIGABRT 6 /* Abnormal termination. */
|
||||
#define SIGFPE 8 /* Erroneous arithmetic operation. */
|
||||
#define SIGSEGV 11 /* Invalid access to storage. */
|
||||
#define SIGTERM 15 /* Termination request. */
|
||||
|
||||
#endif /*__BITS_SIGNUM_H__*/
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef __BITS_TYPES_DIR_H__
|
||||
# define __BITS_TYPES_DIR_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
/* Associated directory descriptor */
|
||||
int fd;
|
||||
} DIR;
|
||||
|
||||
#endif /*__BITS_TYPES_DIR_H__*/
|
|
@ -1,85 +0,0 @@
|
|||
#ifndef __THREADS_H__
|
||||
# define __THREADS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//---
|
||||
// Warnig, this part is experimental and reserved for Vhex
|
||||
//---
|
||||
|
||||
// Define Mutex type
|
||||
enum {
|
||||
mtx_plain = 0,
|
||||
mtx_recursive = 1,
|
||||
mtx_timed = 2
|
||||
};
|
||||
|
||||
// Define mutex structure
|
||||
// @note: This is a custom implementation
|
||||
#define MTX_WATERMARK (0xdeadbeef)
|
||||
struct __mtx_s {
|
||||
uint32_t __watermark;
|
||||
uint16_t lock;
|
||||
uint8_t type;
|
||||
};
|
||||
typedef struct __mtx_s mtx_t;
|
||||
|
||||
|
||||
//---
|
||||
// Mutex functions
|
||||
//---
|
||||
|
||||
/*
|
||||
** Creates a new mutex object with type __TYPE.
|
||||
** @note: If successful the new object is pointed by __MUTEX.
|
||||
*/
|
||||
extern int mtx_init(mtx_t *__mutex, int __type);
|
||||
|
||||
/*
|
||||
** Block the current thread until the mutex pointed to by __MUTEX is unlocked.
|
||||
** In that case current thread will not be blocked.
|
||||
*/
|
||||
extern int mtx_lock(mtx_t *__mutex);
|
||||
|
||||
/*
|
||||
** Try to lock the mutex pointed by __MUTEX without blocking.
|
||||
** @note: If the mutex is free the current threads takes control of it,
|
||||
** otherwise it returns immediately.
|
||||
*/
|
||||
extern int mtx_trylock(mtx_t *__mutex);
|
||||
|
||||
/*
|
||||
** Unlock the mutex pointed by __MUTEX.
|
||||
** @note: It may potentially awake other threads waiting on this mutex.
|
||||
*/
|
||||
extern int mtx_unlock (mtx_t *__mutex);
|
||||
|
||||
/* Destroy the mutex object pointed by __MUTEX. */
|
||||
extern void mtx_destroy(mtx_t *__mutex);
|
||||
|
||||
|
||||
//---
|
||||
// Atomic operations
|
||||
//---
|
||||
/*
|
||||
** Save the current SR register and set the SR.BIT bit up (start atomic operations)
|
||||
** @note: return the saved SR register (if has been saved), 0xffffffff otherwise.
|
||||
*/
|
||||
extern uint32_t __thread_atomic_start(void);
|
||||
|
||||
/*
|
||||
** Restore the saved SR register
|
||||
** @note: return the restored SR register or -1 otherwise.
|
||||
*/
|
||||
extern uint32_t __thread_atomic_stop(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__THREADS_H__*/
|
|
@ -31,6 +31,12 @@ struct tm {
|
|||
int tm_isdst; /* Daylight Saving Time flag */
|
||||
};
|
||||
|
||||
/* Full time specification with second/nanosecond precision. */
|
||||
struct timespec {
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
|
||||
/* Returns CPU time used by the program (in number of CLOCKS_PER_SEC). */
|
||||
extern clock_t clock(void);
|
||||
|
||||
|
@ -61,8 +67,8 @@ extern struct tm *localtime(const time_t *time);
|
|||
/* Formats __time according to the specified format; similar to snprintf().
|
||||
TODO: %g, %G, %V (week-based year), and %U, %W (week number) are not
|
||||
supported and substituted by "??". %z and %Z output nothing. */
|
||||
size_t strftime(char * restrict __s, size_t __maxsize,
|
||||
const char * restrict __format, const struct tm * restrict __time);
|
||||
size_t strftime(char * __restrict__ __s, size_t __maxsize,
|
||||
const char * __restrict__ __format, const struct tm * __restrict__ __time);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@ extern int mkdir(const char *__path, mode_t __mode);
|
|||
/* Remove an empty directory. */
|
||||
extern int rmdir(const char *__path);
|
||||
|
||||
extern char *getcwd(char *__buf, size_t __size);
|
||||
|
||||
extern int chdir(char const *__path);
|
||||
|
||||
|
||||
/* Kernel-style functions supported only by Vhex. */
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _kill
|
||||
.type _kill, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern int kill(pid_t pid, int sig);
|
||||
** Send signal SIG to process number PID. If PID is zero, send SIG to all
|
||||
** processes in the current process's process group. If PID is < -1, send SIG to
|
||||
** all processes in process group - PID.
|
||||
*/
|
||||
_kill:
|
||||
trapa #__NR_kill
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,17 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _signal
|
||||
.type _signal, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void (*signal(int signum, void (*handler)(int)))(int);
|
||||
** Set the handler for the signal SIG to HANDLER, returning the old handler, or
|
||||
** SIG_ERR on error. By default `signal' has the BSD semantic.
|
||||
*/
|
||||
_signal:
|
||||
trapa #__NR_signal
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,11 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int putchar(int c)
|
||||
{
|
||||
char n;
|
||||
|
||||
n = (char)c;
|
||||
write(STDOUT_FILENO, &n, 1);
|
||||
return (n);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
** puts() writes the string s and a trailing newline to stdout.
|
||||
** FIXME: check last write error !
|
||||
*/
|
||||
int puts(const char *s)
|
||||
{
|
||||
size_t size;
|
||||
size_t n;
|
||||
|
||||
size = strlen(s);
|
||||
n = write(STDOUT_FILENO, s, size);
|
||||
write(STDOUT_FILENO, "\n", 1);
|
||||
return (-(n == size));
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global __Exit
|
||||
.type __Exit, @function
|
||||
|
||||
|
||||
.align 2
|
||||
__Exit:
|
||||
trapa #__NR_exit
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,21 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _free
|
||||
.type _free, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void free(void *ptr)
|
||||
** Custom syscall which free a block allocated by `malloc', `realloc' or `calloc'.
|
||||
**
|
||||
** @note:
|
||||
** The MMU is used by Casio so we cannot implement brk or skr for technical
|
||||
** reason (non-continius heap, no shared page, ...), so all memory management
|
||||
** is performed by the Vhex kernel.
|
||||
*/
|
||||
_free:
|
||||
trapa #__NR_proc_heap_free
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,21 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _malloc
|
||||
.type _malloc, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void *malloc(size_t size);
|
||||
** Allocate SIZE bytes of memory.
|
||||
**
|
||||
** @note:
|
||||
** The MMU is used by Casio so we cannot implement brk or skr for technical
|
||||
** reason (non-continius heap, no shared page, ...), so all memory management
|
||||
** is performed by the Vhex kernel.
|
||||
*/
|
||||
_malloc:
|
||||
trapa #__NR_proc_heap_alloc
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,41 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _realloc
|
||||
.type _realloc, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void *realloc(void ptr, size_t size)
|
||||
**
|
||||
** @note:
|
||||
** The MMU is used by Casio so we cannot implement brk or skr for technical
|
||||
** reason (non-continius heap, no shared page, ...), so all memory management
|
||||
** is performed by the Vhex kernel.
|
||||
*/
|
||||
_realloc:
|
||||
! Check if the PTR is NULL
|
||||
! In this case, realloc() work like malloc(), so lets call it
|
||||
tst r4, r4
|
||||
bf check_free
|
||||
mov r5, r4
|
||||
trapa #__NR_proc_heap_alloc
|
||||
rts
|
||||
nop
|
||||
|
||||
! Check is the size is NULL
|
||||
! In this case, realloc() work like free(), so lets call it
|
||||
! then return NULL pointer
|
||||
check_free:
|
||||
tst r5, r5
|
||||
bf call_realloc
|
||||
trapa #__NR_proc_heap_free
|
||||
rts
|
||||
xor r0, r0
|
||||
|
||||
! Call realloc
|
||||
call_realloc:
|
||||
trapa #__NR_proc_heap_realloc
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,95 +0,0 @@
|
|||
.text
|
||||
.global ___thread_atomic_start
|
||||
.global ___thread_atomic_stop
|
||||
|
||||
.type ___thread_atomic_start, @function
|
||||
.type ___thread_atomic_stop, @function
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern uint32_t __thread_atomic_start(void)
|
||||
** Save the current SR register and set the SR.BIT bit up to start an atomic
|
||||
** context (interrupt is blocked).
|
||||
** Return the saved SR register (only if the we enter into an atomic context),
|
||||
** 0xffffffff otherwise.
|
||||
*/
|
||||
___thread_atomic_start:
|
||||
! Check if the user is currently into an atomic operation
|
||||
! and update atomic counter.
|
||||
mov.l atomic_counter, r1
|
||||
mov.l @r1, r2
|
||||
tst r2, r2
|
||||
add #1, r2
|
||||
mov.l r2, @r1
|
||||
bf.s atomic_start_exit
|
||||
mov #-1, r0
|
||||
|
||||
! Block interrupt if needed.
|
||||
stc sr, r1
|
||||
mov r1, r0
|
||||
mov.l bl_mask, r2
|
||||
or r2, r1
|
||||
ldc r1, sr
|
||||
|
||||
! Save "old" SR register.
|
||||
mov.l sr_save, r1
|
||||
mov.l r0, @r1
|
||||
|
||||
atomic_start_exit:
|
||||
rts
|
||||
nop
|
||||
|
||||
/*
|
||||
** extern uint32_t __thread_atomic_stop(void)
|
||||
** Decreate the internal "atomic context counter" and if the counter is 0,
|
||||
** restore the saved SR register status.
|
||||
** Return the restored SR register (if restored) or -1 otherwise.
|
||||
*/
|
||||
___thread_atomic_stop:
|
||||
|
||||
! Check if the device is currently into an atomic operation
|
||||
! and update atomic counter and, if needed, restore the SR
|
||||
! regsiter
|
||||
mov.l atomic_counter, r1
|
||||
mov.l @r1, r0
|
||||
tst r0, r0
|
||||
bt atomic_end_error
|
||||
cmp/eq #1, r0
|
||||
add #-1, r0
|
||||
mov.l r0, @r1
|
||||
bf atomic_end_error
|
||||
|
||||
! Restore saved SR register data.
|
||||
mov.l sr_save, r1
|
||||
mov.l @r1, r0
|
||||
ldc r0, sr
|
||||
bra atomic_end_exit
|
||||
nop
|
||||
|
||||
atomic_end_error:
|
||||
mov #-1, r0
|
||||
|
||||
atomic_end_exit:
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 4
|
||||
bl_mask: .long 0x100000f0
|
||||
sr_save: .long ___thread_atomic_sr_save
|
||||
atomic_counter: .long ___thread_atomic_counter
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Global part.
|
||||
##---
|
||||
.data
|
||||
.global ___thread_atomic_sr_save
|
||||
.global ___thread_atomic_counter
|
||||
|
||||
.type ___thread_atomic_sr_save, @object
|
||||
.type ___thread_atomic_counter, @object
|
||||
|
||||
.align 4
|
||||
___thread_atomic_sr_save: .long 0x00000000
|
||||
___thread_atomic_counter: .long 0x00000000
|
|
@ -1,107 +0,0 @@
|
|||
#include <threads.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Creates a new mutex object with type __TYPE.
|
||||
// @note: If successful the new object is pointed by __MUTEX.
|
||||
int mtx_init (mtx_t *__mutex, int __type)
|
||||
{
|
||||
// Check if the mutext is already initialized
|
||||
if (__mutex->__watermark == MTX_WATERMARK)
|
||||
return (-1);
|
||||
|
||||
// Initialize mutex
|
||||
__mutex->__watermark = MTX_WATERMARK;
|
||||
__mutex->type = __type;
|
||||
__mutex->lock = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Block the current thread until the mutex pointed to by __MUTEX is unlocked.
|
||||
// In that case current thread will not be blocked.
|
||||
int mtx_lock(mtx_t *__mutex)
|
||||
{
|
||||
// Check mutex validity
|
||||
if (__mutex->__watermark != MTX_WATERMARK)
|
||||
return (-1);
|
||||
|
||||
// Wait util the mutex is unlocked
|
||||
while (1) {
|
||||
// Check if the mutex is unlock
|
||||
__thread_atomic_start();
|
||||
if (__mutex->lock == 0)
|
||||
break;
|
||||
__thread_atomic_stop();
|
||||
|
||||
// TODO: force kernel schedule
|
||||
__asm__ volatile ("sleep");
|
||||
}
|
||||
|
||||
//TODO: handle mutex type !!
|
||||
(void)__mutex->type;
|
||||
|
||||
// Lock the mutex
|
||||
__mutex->lock = 1;
|
||||
|
||||
// Stop atomic operations
|
||||
__thread_atomic_stop();
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Try to lock the mutex pointed by __MUTEX without blocking.
|
||||
// @note: If the mutex is free the current threads takes control of it,
|
||||
// otherwise it returns immediately.
|
||||
int mtx_trylock(mtx_t *__mutex)
|
||||
{
|
||||
// Check mutex validity
|
||||
if (__mutex->__watermark != MTX_WATERMARK)
|
||||
return (-1);
|
||||
|
||||
// Start atomic operations
|
||||
__thread_atomic_start();
|
||||
|
||||
// Check if the mutex is already free
|
||||
int ret = -1;
|
||||
if (__mutex->lock == 0) {
|
||||
//TODO: handle mutex type !!
|
||||
(void)__mutex->type;
|
||||
|
||||
// lock the mutex and change the return value
|
||||
__mutex->lock = 1;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
// Stop atomic operation and return
|
||||
__thread_atomic_stop();
|
||||
return (ret);
|
||||
}
|
||||
|
||||
// Unlock the mutex pointed by __MUTEX.
|
||||
// @note: It may potentially awake other threads waiting on this mutex.
|
||||
int mtx_unlock(mtx_t *__mutex)
|
||||
{
|
||||
// Check mutex validity
|
||||
if (__mutex->__watermark != MTX_WATERMARK)
|
||||
return (-1);
|
||||
|
||||
// Start atomic operation
|
||||
__thread_atomic_start();
|
||||
|
||||
// Check if the mutex is realy used and unluck if needed
|
||||
int ret = -1;
|
||||
if (__mutex->lock != 0) {
|
||||
__mutex->lock = 0;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
// Stop atomic operation and return
|
||||
__thread_atomic_stop();
|
||||
return (ret);
|
||||
}
|
||||
|
||||
// Destroy the mutex object pointed by __MUTEX.
|
||||
// TODO: check if the mutex is in use ?
|
||||
void mtx_destroy(mtx_t *__mutex)
|
||||
{
|
||||
__mutex->__watermark = 0x00000000;
|
||||
__mutex->type = -1;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _open
|
||||
.type _open, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern int open(const char *pathname, int flags, ...);
|
||||
** Open FILE and return a new file descriptor for it, or -1 on error.
|
||||
** OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set
|
||||
** in OFLAG, the third argument is taken as a `mode_t', the mode of the
|
||||
** created file.
|
||||
*/
|
||||
_open:
|
||||
trapa #__NR_open
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,17 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _wait
|
||||
.type _wait, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t wait(int *wstatus);
|
||||
** Wait for a child to die. When one does, put its status in *STAT_LOC
|
||||
** and return its process ID. For errors, return (pid_t) -1.
|
||||
*/
|
||||
_wait:
|
||||
trapa #__NR_wait
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,27 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _waitpid
|
||||
.type _waitpid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t waitpid(pid_t pid, int *wstatus, int options);
|
||||
** Wait for a child matching PID to die.
|
||||
** - If PID is greater than 0, match any process whose process ID is PID.
|
||||
** - If PID is (pid_t) -1, match any process.
|
||||
** - If PID is (pid_t) 0, match any process with the same process group as the
|
||||
** current process.
|
||||
** - If PID is less than -1, match any process whose process group is the absolute
|
||||
** value of PID.
|
||||
** - If the WNOHANG bit is set in OPTIONS, and that child is not already dead,
|
||||
** return (pid_t) 0. If successful, return PID and store the dead child's
|
||||
** status in STAT_LOC.
|
||||
** - Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS,
|
||||
** return status for stopped children; otherwise don't.
|
||||
*/
|
||||
_waitpid:
|
||||
trapa #__NR_waitpid
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,18 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
#include <bits/trapa.h>
|
||||
.text
|
||||
.global _close
|
||||
.type _close, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** int close(int fd)
|
||||
** close() closes a file descriptor, so that it no longer refers to any file
|
||||
** and may be reused.
|
||||
*/
|
||||
_close:
|
||||
casio_trapa(__NR_Bfile_CloseFile)
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,17 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _close
|
||||
.type _close, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** int close(int fd)
|
||||
** close() closes a file descriptor, so that it no longer refers to any file
|
||||
** and may be reused.
|
||||
*/
|
||||
_close:
|
||||
trapa #__NR_close
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,22 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _fork_execve
|
||||
.type _fork_execve, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** pid_t fork_execve(const char *pathname, char **argv, char **envp);
|
||||
** Custom syscall used to create a new process based on the new command passed
|
||||
** using the `argv` and `envp` parametter. This sycall is equivalent of fork()
|
||||
** and execve() combined.
|
||||
**
|
||||
** This custom syscall exist because the Vhex kernel doesn't have access to the
|
||||
** MMU, so we cannot ensure that the memory requested by the potential new
|
||||
** process is enough when execve() is involved by the user.
|
||||
*/
|
||||
_fork_execve:
|
||||
trapa #__NR_fork_execve
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,16 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _getpgid
|
||||
.type _getpgid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t getpgid(void);
|
||||
** Get the process group ID of the calling process.
|
||||
*/
|
||||
_getpgid:
|
||||
trapa #__NR_getpgid
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,16 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _getpid
|
||||
.type _getpid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t getpid(void);
|
||||
** Get the process ID of the calling process.
|
||||
*/
|
||||
_getpid:
|
||||
trapa #__NR_getpid
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,16 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _getppid
|
||||
.type _getppid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t getpgid(void);
|
||||
** Get the parent process ID of the calling process.
|
||||
*/
|
||||
_getppid:
|
||||
trapa #__NR_getppid
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,19 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _lseek
|
||||
.type _lseek, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern off_t lseek(int fd, off_t offset, int whence)
|
||||
** Move FD's file position to OFFSET bytes from the beginning of the file
|
||||
** (if WHENCE is SEEK_SET), the current position (if WHENCE is SEEK_CUR),
|
||||
** or the end of the file (if WHENCE is SEEK_END).
|
||||
** Return the new file position.
|
||||
*/
|
||||
_lseek:
|
||||
trapa #__NR_lseek
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,17 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _read
|
||||
.type _read, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern ssize_t write(int __fd, const void *__buf, size_t __nbytes);
|
||||
** Write N bytes of BUF to FD.
|
||||
** Return the number written, or -1.
|
||||
*/
|
||||
_read:
|
||||
trapa #__NR_read
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,18 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _setpgid
|
||||
.type _setpgid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern int setpgid(pid_t __pid, pid_t __pgid);
|
||||
** Set the process group ID of the process matching PID to PGID.
|
||||
** If PID is zero, the current process's process group ID is set.
|
||||
** If PGID is zero, the process ID of the process is used.
|
||||
*/
|
||||
_setpgid:
|
||||
trapa #__NR_setpgid
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,17 +0,0 @@
|
|||
#include <bits/asm/unistd_32.h>
|
||||
.text
|
||||
.global _write
|
||||
.type _write, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern ssize_t write(int __fd, const void *__buf, size_t __nbytes);
|
||||
** Write N bytes of BUF to FD.
|
||||
** Return the number written, or -1.
|
||||
*/
|
||||
_write:
|
||||
trapa #__NR_write
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void clearerr(FILE *fp)
|
||||
{
|
||||
fp->error = 0;
|
||||
fp->eof = 0;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "fileutil.h"
|
||||
|
||||
int fclose(FILE *fp)
|
||||
{
|
||||
__fp_close(fp, true);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "fileutil.h"
|
||||
|
||||
FILE *fdopen(int fd, char const *mode)
|
||||
{
|
||||
FILE *fp = calloc(1, sizeof *fp);
|
||||
if(!fp) goto err;
|
||||
fp->fd = -1;
|
||||
|
||||
int flags = __fp_parse_mode(mode, fp);
|
||||
if(flags < 0) goto err;
|
||||
|
||||
__fp_open(fp, fd, true);
|
||||
|
||||
/* TODO: fdopen(): Seek to the current file offset of the fd */
|
||||
|
||||
return fp;
|
||||
|
||||
err:
|
||||
__fp_close(fp, true);
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int feof(FILE *fp)
|
||||
{
|
||||
if(!fp->buf)
|
||||
return fp->eof;
|
||||
|
||||
/* If there is read data to be accessed, the flag doesn't count */
|
||||
if(fp->bufdir == __FILE_BUF_READ && fp->bufpos < fp->bufread)
|
||||
return 0;
|
||||
else
|
||||
return fp->eof;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int ferror(FILE *fp)
|
||||
{
|
||||
return fp->error;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "fileutil.h"
|
||||
|
||||
int fflush(FILE *fp)
|
||||
{
|
||||
/* TODO: fflush(NULL) should flush "all" files (do we track them?) */
|
||||
if(!fp) {
|
||||
errno = EINVAL;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if(!fp->buf)
|
||||
return 0;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
/* In reading mode, reset the file offset */
|
||||
if(__fp_hasbuf_read(fp)) {
|
||||
fp->fdpos = fp->fdpos - fp->bufread + fp->bufpos;
|
||||
lseek(fp->fd, fp->fdpos, SEEK_SET);
|
||||
}
|
||||
|
||||
/* In writing mode, write pending data */
|
||||
else if(__fp_hasbuf_write(fp)) {
|
||||
ssize_t written = __fp_write(fp, fp->buf, fp->bufpos);
|
||||
rc = (written == (ssize_t)fp->bufpos ? 0 : EOF);
|
||||
|
||||
/* TODO: fflush(): Keep data that couldn't be written */
|
||||
}
|
||||
|
||||
fp->bufpos = 0;
|
||||
fp->bufread = 0;
|
||||
fp->bufungetc = 0;
|
||||
|
||||
/* Clear buffering for unbuffered streams that used ungetc() */
|
||||
if(fp->bufmode == _IONBF)
|
||||
__fp_remove_buffer(fp);
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include <stdio.h>
|
||||
#include "fileutil.h"
|
||||
|
||||
int fgetc(FILE *fp)
|
||||
{
|
||||
if(!fp->readable) {
|
||||
fp->error = 1;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* For this function we inline __fp_fread2() and__fp_buffered_read() in
|
||||
order to maintain decent performance */
|
||||
unsigned char c;
|
||||
__fp_buffer_mode_read(fp);
|
||||
|
||||
/* No buffered data available, non-buffered mode */
|
||||
if(!fp->buf) {
|
||||
ssize_t rc = __fp_read(fp, &c, 1);
|
||||
return (rc == 1) ? c : EOF;
|
||||
}
|
||||
|
||||
/* If there is no data, get some */
|
||||
if(fp->bufpos >= fp->bufread) {
|
||||
ssize_t rc = __fp_read(fp, fp->buf, fp->bufsize);
|
||||
if(rc <= 0)
|
||||
return EOF;
|
||||
fp->bufread = rc;
|
||||
}
|
||||
|
||||
/* Get a byte from the buffer */
|
||||
c = fp->buf[fp->bufpos++];
|
||||
fp->bufungetc -= (fp->bufungetc > 0);
|
||||
|
||||
/* Rewind the buffer if at end, and clear _IONBF ungetc() buffers */
|
||||
if(fp->bufpos >= fp->bufread) {
|
||||
fp->bufread = 0;
|
||||
fp->bufpos = 0;
|
||||
if(fp->bufmode == _IONBF)
|
||||
__fp_remove_buffer(fp);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int fgetpos(FILE *fp, fpos_t *pos)
|
||||
{
|
||||
if(fp->buf && fp->bufdir == __FILE_BUF_WRITE) {
|
||||
*pos = fp->fdpos + fp->bufpos;
|
||||
}
|
||||
else if(fp->buf && fp->bufdir == __FILE_BUF_READ) {
|
||||
*pos = fp->fdpos - fp->bufread + fp->bufpos;
|
||||
}
|
||||
else {
|
||||
*pos = fp->fdpos;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include "fileutil.h"
|
||||
|
||||
char *fgets(char * restrict s, int n, FILE * restrict fp)
|
||||
{
|
||||
ssize_t read_size = __fp_fread2(fp, s, n - 1, '\n');
|
||||
if(read_size <= 0)
|
||||
return NULL;
|
||||
s[read_size] = 0;
|
||||
return s;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue