diff options
| author | John "Lameguy" Wilbert Villamor <lameguy64@gmail.com> | 2022-01-18 08:31:14 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-18 08:31:14 +0800 |
| commit | 05d44488bd5587786f4bd0286fc0f555c79aa46a (patch) | |
| tree | 5740f396d10a9580c3a39ca536544436898ff1b6 /libpsn00b | |
| parent | 08de895e8582dbc70b639ae5f511ab9ebfb4d68a (diff) | |
| parent | e9475e283a82665fe6c19bebc3318b5084f15a2e (diff) | |
| download | psn00bsdk-05d44488bd5587786f4bd0286fc0f555c79aa46a.tar.gz | |
Merge pull request #44 from spicyjpeg/actions
GitHub Actions CI, psxcd and libc fixes, new examples
Diffstat (limited to 'libpsn00b')
| -rw-r--r-- | libpsn00b/CMakeLists.txt | 20 | ||||
| -rw-r--r-- | libpsn00b/build.json.template | 8 | ||||
| -rw-r--r-- | libpsn00b/cmake/flags.cmake | 151 | ||||
| -rw-r--r-- | libpsn00b/cmake/internal_setup.cmake | 23 | ||||
| -rw-r--r-- | libpsn00b/cmake/sdk.cmake | 10 | ||||
| -rw-r--r-- | libpsn00b/cmake/virtual_targets.cmake | 109 | ||||
| -rw-r--r-- | libpsn00b/include/dlfcn.h | 101 | ||||
| -rw-r--r-- | libpsn00b/include/psxcd.h | 6 | ||||
| -rw-r--r-- | libpsn00b/include/psxgpu.h | 2 | ||||
| -rw-r--r-- | libpsn00b/include/psxpad.h | 328 | ||||
| -rw-r--r-- | libpsn00b/include/psxspu.h | 4 | ||||
| -rw-r--r-- | libpsn00b/ldscripts/dll.ld | 4 | ||||
| -rw-r--r-- | libpsn00b/ldscripts/exe.ld | 2 | ||||
| -rw-r--r-- | libpsn00b/libc/scanf.c | 7 | ||||
| -rw-r--r-- | libpsn00b/libc/string.c | 14 | ||||
| -rw-r--r-- | libpsn00b/libc/vsprintf.c | 11 | ||||
| -rw-r--r-- | libpsn00b/psxcd/cdgetsector.s | 3 | ||||
| -rw-r--r-- | libpsn00b/psxcd/isofs.c | 30 | ||||
| -rw-r--r-- | libpsn00b/psxcd/psxcd.c | 16 | ||||
| -rw-r--r-- | libpsn00b/psxetc/_dl_resolve_wrapper.s | 14 | ||||
| -rw-r--r-- | libpsn00b/psxetc/dl.c | 51 | ||||
| -rw-r--r-- | libpsn00b/psxgpu/gettimimage.c | 2 |
22 files changed, 537 insertions, 379 deletions
diff --git a/libpsn00b/CMakeLists.txt b/libpsn00b/CMakeLists.txt index 7b5f7a5..829a2f7 100644 --- a/libpsn00b/CMakeLists.txt +++ b/libpsn00b/CMakeLists.txt @@ -58,12 +58,28 @@ add_custom_command( ## Installation install( - TARGETS ${PSN00BSDK_LIBRARIES} ${PSN00BSDK_VIRTUAL_TARGETS} + TARGETS ${PSN00BSDK_LIBRARIES} DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b EXPORT libpsn00b ) install( - DIRECTORY cmake include ldscripts + DIRECTORY cmake ldscripts + DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b +) +install( + DIRECTORY include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libpsn00b +) + +# Generate build.json. This file is used to determine the SDK version after +# installation and may contain additional metadata about the build. +configure_file( + build.json.template build.json + ESCAPE_QUOTES + NEWLINE_STYLE LF +) +install( + FILES ${PROJECT_BINARY_DIR}/build.json DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpsn00b ) diff --git a/libpsn00b/build.json.template b/libpsn00b/build.json.template new file mode 100644 index 0000000..374b22a --- /dev/null +++ b/libpsn00b/build.json.template @@ -0,0 +1,8 @@ +{ + "version": "${PSN00BSDK_VERSION}", + "build_date": "${PSN00BSDK_BUILD_DATE}", + "git_tag": "${PSN00BSDK_GIT_TAG}", + "git_commit": "${PSN00BSDK_GIT_COMMIT}", + "cmake_version": "${CMAKE_VERSION}", + "host_system": "${CMAKE_HOST_SYSTEM_NAME}" +} diff --git a/libpsn00b/cmake/flags.cmake b/libpsn00b/cmake/flags.cmake new file mode 100644 index 0000000..249c5b4 --- /dev/null +++ b/libpsn00b/cmake/flags.cmake @@ -0,0 +1,151 @@ +# libpsn00b interface targets +# (C) 2021 spicyjpeg - MPL licensed + +# This script creates several "virtual" targets (psn00bsdk_*) that set include +# directories and compiler flags when a target is linked against them. The +# following targets are currently defined: +# - psn00bsdk_common +# - psn00bsdk_object_lib (same as psn00bsdk_common) +# - psn00bsdk_static_exe +# - psn00bsdk_dynamic_exe +# - psn00bsdk_static_lib +# - psn00bsdk_shared_lib +# - psn00bsdk_module_lib (same as psn00bsdk_shared_lib) +# +# NOTE: building a static library and linking it as part of a DLL is currently +# *not* supported. + +if(NOT TARGET psn00bsdk_common) # Include guard + +add_library(psn00bsdk_common INTERFACE) + +foreach( + _target IN ITEMS + object_lib + static_exe + dynamic_exe + static_lib + shared_lib + module_lib +) + add_library (psn00bsdk_${_target} INTERFACE) + target_link_libraries(psn00bsdk_${_target} INTERFACE psn00bsdk_common) +endforeach() + +# Options common to all target types: +# - Define PLAYSTATION=1 +# - Optimize for MIPS R3000 +# - Inject zero checks into division operations (will throw breaks) +# - All standard libraries (including libgcc) disabled +# - Put all symbols into separate sections when building +# - C++ features that require runtime support disabled +# - Unused section stripping enabled +target_compile_options( + psn00bsdk_common INTERFACE + # CPU options + -msoft-float + -march=r3000 + -mtune=r3000 + -mabi=32 + -mdivide-breaks + -O2 + # Standard library options + -ffreestanding + -fno-builtin + -nostdlib + # Other options + -fdata-sections + -ffunction-sections + -fsigned-char + -fno-strict-overflow + -fdiagnostics-color=always + $<$<COMPILE_LANGUAGE:CXX>: + # C++ options + -fno-exceptions + -fno-rtti + -fno-unwind-tables + -fno-threadsafe-statics + -fno-use-cxa-atexit + > +) +target_link_options( + psn00bsdk_common INTERFACE + -nostdlib + -Wl,-gc-sections +) +target_compile_definitions( + psn00bsdk_common INTERFACE + PLAYSTATION=1 + $<$<CONFIG:DEBUG>:DEBUG=1> +) + +# Options for executables without support for dynamic linking: +# - Position-independent code disabled +# - GP-relative addressing enabled only for local symbols +# - ABI-compatible calls disabled (incompatible with GP-relative addr) +target_compile_options( + psn00bsdk_static_exe INTERFACE + -G8 + -fno-pic + -mno-abicalls + -mgpopt + -mno-extern-sdata +) +target_link_options( + psn00bsdk_static_exe INTERFACE + -G8 + -static +) + +# Options for executables with support for dynamic linking: +# - Position-independent code disabled +# - GP-relative addressing disabled +# - ABI-compatible calls disabled (must be performed manually) +target_compile_options( + psn00bsdk_dynamic_exe INTERFACE + -G0 + -fno-pic + -mno-abicalls + -mno-gpopt +) +target_link_options( + psn00bsdk_dynamic_exe INTERFACE + -G0 + -static +) + +# Options for static libraries: +# - Position-independent code disabled +# - GP-relative addressing disabled +# - ABI-compatible calls disabled +# - Local stripping enabled +target_compile_options( + psn00bsdk_static_lib INTERFACE + -G0 + -fno-pic + -mno-abicalls + -mno-gpopt + -Wa,--strip-local-absolute +) + +# Options for dynamically-loaded libraries: +# - Position-independent code enabled +# - GP-relative addressing disabled (incompatible with ABI calls) +# - ABI-compatible calls enabled +target_compile_options( + psn00bsdk_shared_lib INTERFACE + -G0 + -fPIC + -mabicalls + -mno-gpopt + -mshared +) +target_link_options( + psn00bsdk_shared_lib INTERFACE + -G0 + -shared +) + +target_link_libraries(psn00bsdk_module_lib INTERFACE psn00bsdk_shared_lib) + +endif() diff --git a/libpsn00b/cmake/internal_setup.cmake b/libpsn00b/cmake/internal_setup.cmake index b0c4591..7d6bfdd 100644 --- a/libpsn00b/cmake/internal_setup.cmake +++ b/libpsn00b/cmake/internal_setup.cmake @@ -7,8 +7,15 @@ cmake_minimum_required(VERSION 3.20) include(GNUInstallDirs) -# IMPORTANT TODO: set a version number -set(PSN00BSDK_VERSION 0.1.0) +# Fetch SDK version information from build.json. +if(NOT DEFINED PSN00BSDK_VERSION) + file(READ ${CMAKE_CURRENT_LIST_DIR}/../build.json _json) + + string(JSON PSN00BSDK_VERSION GET ${_json} version) + string(JSON PSN00BSDK_BUILD_DATE GET ${_json} build_date) + string(JSON PSN00BSDK_GIT_TAG GET ${_json} git_tag) + string(JSON PSN00BSDK_GIT_COMMIT GET ${_json} git_commit) +endif() ## Settings (can be overridden by projects) @@ -22,9 +29,7 @@ set(PSN00BSDK_SYMBOL_MAP_SUFFIX ".map") set(PSN00BSDK_LIBRARIES psxgpu psxgte psxspu psxcd psxsio psxetc psxapi lzp c) include(${CMAKE_CURRENT_LIST_DIR}/libpsn00b.cmake OPTIONAL) -if(NOT TARGET psn00bsdk_common) - include(${CMAKE_CURRENT_LIST_DIR}/virtual_targets.cmake) -endif() +include(${CMAKE_CURRENT_LIST_DIR}/flags.cmake) # Use the toolchain path to find libgcc (used to build libpsn00b). Of course # different installers, packages and distros have different opinions when it @@ -59,14 +64,18 @@ set( find_program(ELF2X elf2x HINTS ${PSN00BSDK_TOOLS}) find_program(ELF2CPE elf2cpe HINTS ${PSN00BSDK_TOOLS}) -find_program(SMXLINK elf2x HINTS ${PSN00BSDK_TOOLS}) +find_program(SMXLINK smxlink HINTS ${PSN00BSDK_TOOLS}) find_program(LZPACK lzpack HINTS ${PSN00BSDK_TOOLS}) find_program(MKPSXISO mkpsxiso HINTS ${PSN00BSDK_TOOLS}) ## Helper functions for executables -set(PSN00BSDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/../include) set(PSN00BSDK_LDSCRIPTS ${CMAKE_CURRENT_LIST_DIR}/../ldscripts) +if(IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../include) + set(PSN00BSDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/../include) +else() + set(PSN00BSDK_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/../../../include/libpsn00b) +endif() # psn00bsdk_add_executable( # <target name> <STATIC|DYNAMIC> diff --git a/libpsn00b/cmake/sdk.cmake b/libpsn00b/cmake/sdk.cmake index ae23a06..d6d9bcd 100644 --- a/libpsn00b/cmake/sdk.cmake +++ b/libpsn00b/cmake/sdk.cmake @@ -4,11 +4,11 @@ cmake_minimum_required(VERSION 3.20) set( - PSN00BSDK_TC $ENV{PSN00BSDK_TC} - CACHE PATH "Path to the GCC toolchain's installation directory" + PSN00BSDK_TC "" + CACHE PATH "Path to the GCC toolchain's installation directory (if not in PATH)" ) set( - PSN00BSDK_TARGET mipsel-unknown-elf + PSN00BSDK_TARGET mipsel-none-elf CACHE STRING "GCC toolchain target triplet" ) @@ -26,7 +26,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # toolchain settings to the generated test projects. This dodges missing C++ # standard library errors. set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) -set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PSN00BSDK_TC PSN00BSDK_TARGET) +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PSN00BSDK_TC PSN00BSDK_TARGET PSN00BSDK_VERSION) ## Toolchain path setup @@ -56,7 +56,7 @@ cmake_path(GET _bin PARENT_PATH _toolchain) if(NOT IS_DIRECTORY PSN00BSDK_TC) set( PSN00BSDK_TC ${_toolchain} - CACHE PATH "Path to the GCC toolchain's installation directory" + CACHE PATH "Path to the GCC toolchain's installation directory (if not in PATH)" FORCE ) endif() diff --git a/libpsn00b/cmake/virtual_targets.cmake b/libpsn00b/cmake/virtual_targets.cmake deleted file mode 100644 index 9afcebd..0000000 --- a/libpsn00b/cmake/virtual_targets.cmake +++ /dev/null @@ -1,109 +0,0 @@ -# libpsn00b interface targets -# (C) 2021 spicyjpeg - MPL licensed - -# This script creates several "virtual" targets (psn00bsdk_*) that set include -# directories and compiler flags when a target is linked against them. These -# all end up in the autogenerated libpsn00b setup script after installation, -# so this file is only included when building libpsn00b. - -# The following targets are currently defined: -# - psn00bsdk_common -# - psn00bsdk_object_lib (same as psn00bsdk_common) -# - psn00bsdk_static_exe -# - psn00bsdk_dynamic_exe -# - psn00bsdk_static_lib -# - psn00bsdk_shared_lib -# - psn00bsdk_module_lib (same as psn00bsdk_shared_lib) - -include(GNUInstallDirs) - -set(PSN00BSDK_VIRTUAL_TARGETS "") - -macro(_add_interface_target name) - add_library(${name} INTERFACE) - list(APPEND PSN00BSDK_VIRTUAL_TARGETS ${name}) - - target_compile_options( - ${name} INTERFACE - ${_aflags} - $<$<COMPILE_LANGUAGE:C,CXX>:${_cflags}> - $<$<COMPILE_LANGUAGE:CXX>:${_cxxflags}> - ) - target_link_options (${name} INTERFACE ${_ldflags}) - target_link_libraries(${name} INTERFACE ${ARGN}) -endmacro() - -macro(_add_alias_target name) - #add_library(${name} ALIAS ${ARGN}) - add_library(${name} INTERFACE) - list(APPEND PSN00BSDK_VIRTUAL_TARGETS ${name}) - - target_link_libraries(${name} INTERFACE ${ARGN}) -endmacro() - -# Options common to all target types: -# - Define PLAYSTATION=1 and set include directories -# - Optimize for MIPS R3000 -# - Inject zero checks into division operations (will throw breaks) -# - All standard libraries (including libgcc) disabled -# - Put all symbols into separate sections when building -# - C++ features that require runtime support disabled -# - Unused section stripping enabled -set(_aflags -msoft-float -march=r3000 -mtune=r3000 -mabi=32) -set(_cflags -mdivide-breaks -O2 -ffreestanding -fno-builtin -nostdlib -fdata-sections -ffunction-sections -fsigned-char -fno-strict-overflow -fdiagnostics-color=always) -set(_cxxflags -fno-exceptions -fno-rtti -fno-unwind-tables -fno-threadsafe-statics -fno-use-cxa-atexit) -set(_ldflags -nostdlib -Wl,-gc-sections) - -_add_interface_target(psn00bsdk_common) -_add_alias_target (psn00bsdk_object_lib psn00bsdk_common) - -target_compile_definitions( - psn00bsdk_common INTERFACE - PLAYSTATION=1 - $<$<CONFIG:DEBUG>:DEBUG=1> -) - -# Options for executables without support for dynamic linking: -# - Position-independent code disabled -# - GP-relative addressing enabled only for local symbols -# - ABI-compatible calls disabled (incompatible with GP-relative addr) -set(_aflags -G8) -set(_cflags -mno-abicalls -mgpopt -mno-extern-sdata) -set(_cxxflags) -set(_ldflags -G8 -static) - -_add_interface_target(psn00bsdk_static_exe psn00bsdk_common) - -# Options for executables with support for dynamic linking: -# - Position-independent code disabled -# - GP-relative addressing disabled -# - ABI-compatible calls disabled (must be performed manually) -set(_aflags -G0) -set(_cflags -mno-abicalls -mno-gpopt) -set(_cxxflags) -set(_ldflags -G0 -static) - -_add_interface_target(psn00bsdk_dynamic_exe psn00bsdk_common) - -# Options for static libraries: -# - GP-relative addressing disabled -# - ABI-compatible calls disabled -# - Local stripping enabled -set(_aflags -G0 -Wa,--strip-local-absolute) -set(_cflags -mno-abicalls -mno-gpopt) -set(_cxxflags) -set(_ldflags) - -_add_interface_target(psn00bsdk_static_lib psn00bsdk_common) - -# Options for dynamically-loaded libraries: -# - Position-independent code enabled -# - GP-relative addressing disabled (incompatible with ABI calls) -# - ABI-compatible calls enabled -set(_aflags -G0) -set(_cflags -mabicalls -mshared -mno-gpopt -fPIC) -set(_cxxflags) -set(_ldflags -G0 -shared) - -_add_interface_target(psn00bsdk_shared_lib psn00bsdk_common) -_add_alias_target (psn00bsdk_module_lib psn00bsdk_shared_lib) diff --git a/libpsn00b/include/dlfcn.h b/libpsn00b/include/dlfcn.h index b3a5cec..6874d06 100644 --- a/libpsn00b/include/dlfcn.h +++ b/libpsn00b/include/dlfcn.h @@ -21,39 +21,39 @@ #define RTLD_DEFAULT ((DLL *) 0) typedef enum _DL_Error { - RTLD_E_NONE = 0, // No error - RTLD_E_FILE_OPEN = 1, // Unable to find or open file - RTLD_E_FILE_ALLOC = 2, // Unable to allocate buffer to load file into - RTLD_E_FILE_READ = 3, // Failed to read file - RTLD_E_NO_MAP = 4, // No symbol map has been loaded yet - RTLD_E_MAP_ALLOC = 5, // Unable to allocate symbol map structures - RTLD_E_NO_SYMBOLS = 6, // No symbols found in symbol map - RTLD_E_DLL_NULL = 7, // Unable to initialize DLL from null pointer - RTLD_E_DLL_ALLOC = 8, // Unable to allocate DLL metadata structures - RTLD_E_DLL_FORMAT = 9, // Unsupported DLL type or format - RTLD_E_NO_FILE_API = 10, // psxetc has been built without file support - RTLD_E_MAP_SYMBOL = 11, // Symbol not found in symbol map - RTLD_E_DLL_SYMBOL = 12, // Symbol not found in DLL - RTLD_E_HASH_LOOKUP = 13 // Hash table lookup failed due to internal error + RTLD_E_NONE = 0, // No error + RTLD_E_FILE_OPEN = 1, // Unable to find or open file + RTLD_E_FILE_ALLOC = 2, // Unable to allocate buffer to load file into + RTLD_E_FILE_READ = 3, // Failed to read file + RTLD_E_NO_MAP = 4, // No symbol map has been loaded yet + RTLD_E_MAP_ALLOC = 5, // Unable to allocate symbol map structures + RTLD_E_NO_SYMBOLS = 6, // No symbols found in symbol map + RTLD_E_DLL_NULL = 7, // Unable to initialize DLL from null pointer + RTLD_E_DLL_ALLOC = 8, // Unable to allocate DLL metadata structures + RTLD_E_DLL_FORMAT = 9, // Unsupported DLL type or format + RTLD_E_MAP_SYMBOL = 10, // Symbol not found in symbol map + RTLD_E_DLL_SYMBOL = 11, // Symbol not found in DLL + RTLD_E_HASH_LOOKUP = 12 // Hash table lookup failed due to internal error } DL_Error; typedef enum _DL_ResolveMode { - RTLD_LAZY = 1, // Resolve functions when they are first called (default) - RTLD_NOW = 2 // Resolve all symbols immediately on load + RTLD_LAZY = 1, // Resolve functions when they are first called (default) + RTLD_NOW = 2, // Resolve all symbols immediately on load + RTLD_FREE_ON_DESTROY = 4 // Automatically free DLL buffer when closing DLL } DL_ResolveMode; // Members of this struct should not be accessed directly in most cases, but // they are intentionally exposed for easier expandability. typedef struct _DLL { - void *ptr; - void *malloc_ptr; - size_t size; - const uint32_t *hash; - uint32_t *got; - Elf32_Sym *symtab; - const char *strtab; - uint16_t symbol_count; - uint16_t got_length; + void *ptr; + void *malloc_ptr; + size_t size; + const uint32_t *hash; + uint32_t *got; + Elf32_Sym *symtab; + const char *strtab; + uint16_t symbol_count; + uint16_t got_length; } DLL; /* API */ @@ -62,8 +62,6 @@ typedef struct _DLL { extern "C" { #endif -// TODO: rewrite these javadoc comments into proper documentation - /** * @brief Reads the symbol table from the provided string buffer (which may or * may not be null-terminated), parses it and stores the parsed entries into a @@ -80,13 +78,14 @@ extern "C" { * file in the appropriate format after building the executable, by using this * command: * - * mipsel-unknown-elf-nm -f posix -l -n executable.elf >executable.map + * mipsel-none-elf-nm -f posix -l -n executable.elf >executable.map * * @param ptr * @param size * @return -1 or number of entries parsed */ int32_t DL_ParseSymbolMap(const char *ptr, size_t size); + /** * @brief File wrapper around DL_ParseSymbolMap(). Allocates a temporary buffer * then loads the specified map file into it (using BIOS APIs) and calls @@ -96,14 +95,16 @@ int32_t DL_ParseSymbolMap(const char *ptr, size_t size); * @param filename Must always contain device name, e.g. "cdrom:MODULE.DLL;1" * @return -1 or number of entries parsed */ -int32_t DL_LoadSymbolMap(const char *filename); +//int32_t DL_LoadSymbolMapFromFile(const char *filename); + /** * @brief Frees internal buffers containing the currently loaded symbol map. * This is automatically done before loading a new symbol map so there is no * need to call this function in most cases, however it can still be useful to * free up space on the heap once the symbol map is no longer needed. */ -void DL_UnloadSymbolMap(void); +void DL_UnloadSymbolMap(void); + /** * @brief Queries the currently loaded symbol map for the symbol with the given * name and returns a pointer to it, which can then be used to directly access @@ -112,7 +113,8 @@ void DL_UnloadSymbolMap(void); * @param name * @return NULL or pointer to symbol (any type) */ -void *DL_GetSymbolByName(const char *name); +void *DL_GetSymbolByName(const char *name); + /** * @brief Sets a custom function to be called for resolving symbols in DLLs. * The function will be given a pointer to the current DLL and the unresolved @@ -123,7 +125,7 @@ void *DL_GetSymbolByName(const char *name); * * @param callback NULL or pointer to callback function */ -void DL_SetResolveCallback(void *(*callback)(DLL *, const char *)); +void DL_SetResolveCallback(void *(*callback)(DLL *, const char *)); /** * @brief Initializes a buffer holding the contents of a dynamically-loaded @@ -131,8 +133,8 @@ void DL_SetResolveCallback(void *(*callback)(DLL *, const char *)); * binary) *in-place*. A new DLL struct is allocated to store metadata but, * unlike DL_ParseSymbolMap(), the DLL's actual code, data and tables are * referenced directly from the provided buffer. The buffer must not be moved - * or deallocated, at least not before calling dlclose() on the DLL struct - * returned by this function. + * or deallocated, at least not before calling DL_DestroyDLL() on the DLL + * struct returned by this function. * * The third argument specifies when symbols in the DLL should be resolved. * Setting it to RTLD_LAZY defers resolution of undefined functions to when @@ -145,7 +147,8 @@ void DL_SetResolveCallback(void *(*callback)(DLL *, const char *)); * @param mode RTLD_LAZY or RTLD_NOW * @return NULL or pointer to a new DLL struct */ -DLL *dlinit(void *ptr, size_t size, DL_ResolveMode mode); +DLL *DL_CreateDLL(void *ptr, size_t size, DL_ResolveMode mode); + /** * @brief File wrapper around dlinit(). Allocates a new buffer, loads the * specified file into it (using BIOS APIs) and calls dlinit() on that. When @@ -153,19 +156,22 @@ DLL *dlinit(void *ptr, size_t size, DL_ResolveMode mode); * automatically destroyed. * * @param filename Must always contain device name, e.g. "cdrom:MODULE.DLL;1" - * @param mode RTLD_LAZY or RTLD_NOW + * @param mode RTLD_LAZY or RTLD_NOW + optionally RTLD_FREE_ON_DESTROY * @return NULL or pointer to a new DLL struct */ -DLL *dlopen(const char *filename, DL_ResolveMode mode); +//DLL *DL_LoadDLLFromFile(const char *filename, DL_ResolveMode mode); + /** * @brief Destroys a loaded DLL by calling its global destructors and freeing - * the buffer it's loaded in. Any pointer passed to dlclose() should no longer - * be used after the call. If the DLL was initialized in-place using dlinit(), - * dlclose() will *NOT* free the buffer initially passed to dlinit(). + * the buffer it's loaded in. Any pointer passed to DL_DestroyDLL() should no + * longer be used after the call. If the DLL was initialized in-place using + * DL_CreateDLL(), DL_DestroyDLL() will only free the buffer initially passed + * to DL_CreateDLL() if RTLD_FREE_ON_DESTROY was used. * * @param dll */ -void dlclose(DLL *dll); +void DL_DestroyDLL(DLL *dll); + /** * @brief Returns a pointer to the DLL symbol with the given name, or null if * it can't be found. If null or RTLD_DEFAULT is passed as first argument, the @@ -176,7 +182,8 @@ void dlclose(DLL *dll); * @param name * @return NULL or pointer to symbol (any type) */ -void *dlsym(DLL *dll, const char *name); +void *DL_GetDLLSymbol(const DLL *dll, const char *name); + /** * @brief Returns a code describing the last error that occurred, or DL_E_NONE * if no error has occurred since the last call to dlerror() (i.e. calling this @@ -184,7 +191,15 @@ void *dlsym(DLL *dll, const char *name); * * @return NULL or member of DL_Error enum */ -DL_Error dlerror(void); +DL_Error DL_GetLastError(void); + +/* POSIX "compatibility" macros */ + +#define dlinit(ptr, size, mode) DL_CreateDLL(ptr, size, mode) +//#define dlopen(filename, mode) DL_LoadDLLFromFile(filename, mode) +#define dlsym(dll, name) DL_GetDLLSymbol(dll, name) +#define dlclose(dll) DL_DestroyDLL(dll) +#define dlerror() DL_GetLastError() #ifdef __cplusplus } diff --git a/libpsn00b/include/psxcd.h b/libpsn00b/include/psxcd.h index ffbe86b..3336963 100644 --- a/libpsn00b/include/psxcd.h +++ b/libpsn00b/include/psxcd.h @@ -132,9 +132,9 @@ CdlLOC* CdIntToPos(int i, CdlLOC *p); int CdPosToInt(CdlLOC *p); int CdGetToc(CdlLOC *toc); -int CdControl(u_char com, u_char *param, u_char *result); -int CdControlB(u_char com, u_char *param, u_char *result); -int CdControlF(u_char com, u_char *param); +int CdControl(u_char com, const void *param, u_char *result); +int CdControlB(u_char com, const void *param, u_char *result); +int CdControlF(u_char com, const void *param); int CdSync(int mode, u_char *result); u_long CdSyncCallback(CdlCB func); diff --git a/libpsn00b/include/psxgpu.h b/libpsn00b/include/psxgpu.h index f50b841..f061219 100644 --- a/libpsn00b/include/psxgpu.h +++ b/libpsn00b/include/psxgpu.h @@ -609,7 +609,7 @@ void AddPrim(u_long* ot, void* pri); // Function definitions (C) -int GetTimInfo(u_long *tim, TIM_IMAGE *timimg); /* ORIGINAL */ +int GetTimInfo(const u_long *tim, TIM_IMAGE *timimg); /* ORIGINAL */ DISPENV *SetDefDispEnv(DISPENV *disp, int x, int y, int w, int h); DRAWENV *SetDefDrawEnv(DRAWENV *draw, int x, int y, int w, int h); diff --git a/libpsn00b/include/psxpad.h b/libpsn00b/include/psxpad.h index d152896..9638ec1 100644 --- a/libpsn00b/include/psxpad.h +++ b/libpsn00b/include/psxpad.h @@ -14,43 +14,48 @@ #ifndef _PSXPAD_H #define _PSXPAD_H -// Pad button definitions for digital pad, joystick, dual analog, -// Dualshock and Jogcon -#define PAD_SELECT 1 -#define PAD_L3 2 -#define PAD_R3 4 -#define PAD_START 8 -#define PAD_UP 16 -#define PAD_RIGHT 32 -#define PAD_DOWN 64 -#define PAD_LEFT 128 -#define PAD_L2 256 -#define PAD_R2 512 -#define PAD_L1 1024 -#define PAD_R1 2048 -#define PAD_TRIANGLE 4096 -#define PAD_CIRCLE 8192 -#define PAD_CROSS 16384 -#define PAD_SQUARE 32768 - -// Mouse button definitions -#define MOUSE_RIGHT 1024 -#define MOUSE_LEFT 2048 - -// neGcon button definitions -#define NCON_START 8 -#define NCON_UP 16 -#define NCON_RIGHT 32 -#define NCON_DOWN 64 -#define NCON_LEFT 128 -#define NCON_R 256 -#define NCON_B 512 -#define NCON_A 1024 - -// Guncon button definitions -#define GCON_A 8 -#define GCON_TRIGGER 8192 -#define GCON_B 16384 +#include <stdint.h> + +/* Controller type and button definitions */ + +typedef enum { + // Standard pads, analog joystick, Jogcon + PAD_SELECT = 1 << 0, + PAD_L3 = 1 << 1, + PAD_R3 = 1 << 2, + PAD_START = 1 << 3, + PAD_UP = 1 << 4, + PAD_RIGHT = 1 << 5, + PAD_DOWN = 1 << 6, + PAD_LEFT = 1 << 7, + PAD_L2 = 1 << 8, + PAD_R2 = 1 << 9, + PAD_L1 = 1 << 10, + PAD_R1 = 1 << 11, + PAD_TRIANGLE = 1 << 12, + PAD_CIRCLE = 1 << 13, + PAD_CROSS = 1 << 14, + PAD_SQUARE = 1 << 15, + + // Mouse + MOUSE_LEFT = 1 << 10, + MOUSE_RIGHT = 1 << 11, + + // neGcon + NCON_START = 1 << 3, + NCON_UP = 1 << 4, + NCON_RIGHT = 1 << 5, + NCON_DOWN = 1 << 6, + NCON_LEFT = 1 << 7, + NCON_R = 1 << 8, + NCON_B = 1 << 9, + NCON_A = 1 << 10, + + // Guncon + GCON_A = 1 << 3, + GCON_TRIGGER = 1 << 13, + GCON_B = 1 << 14 +} PadButton; typedef enum { PAD_ID_MOUSE = 0x1, // Sony PS1 mouse @@ -64,9 +69,10 @@ typedef enum { PAD_ID_JOGCON = 0xe, // Namco Jogcon PAD_ID_CONFIG_MODE = 0xf, // Dual Analog/DualShock in config mode (if len == 0x3) PAD_ID_NONE = 0xf // No pad connected (if len == 0xf) -} PAD_TYPEID; +} PadTypeID; + +/* Pad and memory card commands */ -// Controller command definitions typedef enum { PAD_CMD_INIT_PRESSURE = '@', // Initialize DS2 button pressure sensors (in config mode) PAD_CMD_READ = 'B', // Read pad state and set rumble @@ -74,131 +80,155 @@ typedef enum { PAD_CMD_SET_ANALOG = 'D', // Set analog mode/LED state (in config mode) PAD_CMD_GET_ANALOG = 'E', // Get analog mode/LED state (in config mode) PAD_CMD_REQUEST_CONFIG = 'M', // Configure request/unlock vibration (in config mode) - PAD_CMD_RESPONSE_CONFIG = 'O' // Configure response/unlock DS2 pressure (in config mode) -} PAD_COMMAND; + PAD_CMD_RESPONSE_CONFIG = 'O', // Configure response/unlock DS2 pressure (in config mode) -// Memory card command/response definitions -typedef enum { - MCD_CMD_READ = 'R', // Read sector - MCD_CMD_IDENTIFY = 'S', // Retrieve ID and card size information - MCD_CMD_WRITE = 'W' // Write sector -} MCD_COMMAND; + MCD_CMD_READ_SECTOR = 'R', // Read 128-byte sector + MCD_CMD_IDENTIFY = 'S', // Retrieve ID and card size information (Sony cards only) + MCD_CMD_WRITE_SECTOR = 'W' // Erase and write 128-byte sector +} PadCommand; typedef enum { MCD_STAT_OK = 'G', MCD_STAT_BAD_CHECKSUM = 'N', MCD_STAT_BAD_SECTOR = 0xff -} MCD_STATUS; - -#define MCD_CMD_READ_LEN 139 -#define MCD_CMD_IDENTIFY_LEN 9 -#define MCD_CMD_WRITE_LEN 137 - -// Memory card status flags -#define MCD_FLAG_WRITE_ERROR 4 // Last write command failed -#define MCD_FLAG_NOT_WRITTEN 8 // No writes have been issued yet -#define MCD_FLAG_UNKNOWN 16 // Might be set on third-party cards - -// Struct for data returned by controllers -typedef struct _PADTYPE { - union { // Header: - struct __attribute__((packed)) { // When parsing data returned by BIOS: - unsigned char stat; // Status - unsigned char len:4; // Payload length / 2, 0 for multitap - unsigned char type:4; // Device type (PAD_TYPEID) +} MemCardStatus; + +typedef enum { + MCD_FLAG_WRITE_ERROR = 1 << 2, // Last write command failed + MCD_FLAG_NOT_WRITTEN = 1 << 3, // No writes have been issued yet + MCD_FLAG_UNKNOWN = 1 << 4 // Might be set on third-party cards +} MemCardStatusFlag; + +#define MEMCARD_CMD_READ_LEN 139 +#define MEMCARD_CMD_IDENTIFY_LEN 9 +#define MEMCARD_CMD_WRITE_LEN 137 + +/* Controller response as returned by BIOS driver */ + +typedef struct __attribute__((packed)) _PADTYPE { + uint8_t stat; // Status + uint8_t len:4; // Payload length / 2, 0 for multitap + uint8_t type:4; // Device type (PadTypeID) + + uint16_t btn; // Button states + union { + struct { // Analog controller: + uint8_t rs_x,rs_y; // - Right stick coordinates + uint8_t ls_x,ls_y; // - Left stick coordinates + uint8_t press[12]; // - Button pressure (DualShock 2 only) }; - struct __attribute__((packed)) { // When parsing raw controller response: - unsigned char len:4; // Payload length / 2, 0 for multitap - unsigned char type:4; // Device type (PAD_TYPEID) - unsigned char prefix; // Must be 0x5a - } raw; - }; - struct { // Payload: - unsigned short btn; // Button states - union { - struct { // Analog controller: - unsigned char rs_x,rs_y; // Right stick coordinates - unsigned char ls_x,ls_y; // Left stick coordinates - unsigned char press[12]; // Button pressure (DualShock 2 only) - }; - struct { // Mouse: - char x_mov; // X movement of mouse - char y_mov; // Y movement of mouse - }; - struct { // neGcon: - unsigned char twist; // Controller twist - unsigned char btn_i; // I button value - unsigned char btn_ii; // II button value - unsigned char trg_l; // L trigger value - }; - struct { // Jogcon: - unsigned short jog_rot; // Jog rotation - }; - struct { // Guncon: - unsigned short gun_x; // Gun X position in dotclocks - unsigned short gun_y; // Gun Y position in scanlines - }; + struct { // Mouse: + int8_t x_mov; // - X movement of mouse + int8_t y_mov; // - Y movement of mouse + }; + struct { // neGcon: + uint8_t twist; // - Controller twist + uint8_t btn_i; // - I button value + uint8_t btn_ii; // - II button value + uint8_t trg_l; // - L trigger value + }; + struct { // Jogcon: + uint16_t jog_rot; // - Jog rotation + }; + struct { // Guncon: + uint16_t gun_x; // - Gun X position in dotclocks + uint16_t gun_y; // - Gun Y position in scanlines }; }; } PADTYPE; -typedef struct _MCDRESPONSE { - unsigned char flags; // Status flags - unsigned char type1; // Must be 0x5a - unsigned char type2; // Must be 0x5d +//typedef struct _PADTYPE MOUSETYPE; +//typedef struct _PADTYPE NCONTYPE; +//typedef struct _PADTYPE JCONTYPE; +//typedef struct _PADTYPE GCONTYPE; + +/* Raw responses */ + +typedef struct __attribute__((packed)) _PadResponse { + uint8_t len:4; // Payload length / 2, 0 for multitap + uint8_t type:4; // Device type (PadTypeID) + uint8_t prefix; // Must be 0x5a + + uint16_t btn; // Button states + union { + struct { // Analog controller: + uint8_t rs_x,rs_y; // - Right stick coordinates + uint8_t ls_x,ls_y; // - Left stick coordinates + uint8_t press[12]; // - Button pressure (DualShock 2 only) + }; + struct { // Mouse: + int8_t x_mov; // - X movement of mouse + int8_t y_mov; // - Y movement of mouse + }; + struct { // neGcon: + uint8_t twist; // - Controller twist + uint8_t btn_i; // - I button value + uint8_t btn_ii; // - II button value + uint8_t trg_l; // - L trigger value + }; + struct { // Jogcon: + uint16_t jog_rot; // - Jog rotation + }; + struct { // Guncon: + uint16_t gun_x; // - Gun X position in dotclocks + uint16_t gun_y; // - Gun Y position in scanlines + }; + }; +} PadResponse; + +typedef struct __attribute__((packed)) _MemCardResponse { + uint8_t flags; // Status flags (MemCardStatusFlag) + uint8_t type1; // Must be 0x5a + uint8_t type2; // Must be 0x5d + union { - struct { // MCD_CMD_READ response: - unsigned char dummy[2]; - unsigned char ack1; // Must be 0x5c - unsigned char ack2; // Must be 0x5d - unsigned char lba_h; - unsigned char lba_l; - unsigned char data[128]; - unsigned char checksum; // = lba_h ^ lba_l ^ data - unsigned char stat; // Status (MCD_STATUS) + struct { // CMD_READ response: + uint8_t dummy[2]; + uint8_t ack1; // Must be 0x5c + uint8_t ack2; // Must be 0x5d + uint8_t lba_h; + uint8_t lba_l; + uint8_t data[128]; + uint8_t checksum; // = lba_h ^ lba_l ^ data + uint8_t stat; // Status (MemCardStatus) } read; - struct { // MCD_CMD_IDENTIFY response: - unsigned char ack1; // Must be 0x5c - unsigned char ack2; // Must be 0x5d - unsigned char size_h; // Card capacity bits 8-15 (0x04 = 128KB) - unsigned char size_l; // Card capacity bits 0-7 (0x00 = 128KB) - unsigned char blksize_h; // Sector size bits 8-15 (must be 0x00) - unsigned char blksize_l; // Sector size bits 0-7 (must be 0x80) + struct { // CMD_IDENTIFY response: + uint8_t ack1; // Must be 0x5c + uint8_t ack2; // Must be 0x5d + uint8_t size_h; // Card capacity bits 8-15 (0x04 = 128KB) + uint8_t size_l; // Card capacity bits 0-7 (0x00 = 128KB) + uint8_t blksize_h; // Sector size bits 8-15 (must be 0x00) + uint8_t blksize_l; // Sector size bits 0-7 (must be 0x80) } identify; - struct { // MCD_CMD_WRITE response: - unsigned char dummy[131]; - unsigned char ack1; // Must be 0x5c - unsigned char ack2; // Must be 0x5d - unsigned char stat; // Status (MCD_STATUS) + struct { // CMD_WRITE response: + uint8_t dummy[131]; + uint8_t ack1; // Must be 0x5c + uint8_t ack2; // Must be 0x5d + uint8_t stat; // Status (MemCardStatus) } write; }; -} MCDRESPONSE; - -//typedef PADTYPE MOUSETYPE; -//typedef PADTYPE NCONTYPE; -//typedef PADTYPE JCONTYPE; -//typedef PADTYPE GCONTYPE; - -// Structs for raw controller request -typedef struct _PADREQUEST { - unsigned char addr; // Must be 0x01 (or 02/03/04 for multitap pads) - unsigned char cmd; // Command (PAD_COMMAND) - unsigned char tap_mode; // 0x01 to enable multitap response - unsigned char motor_r; // Right motor control (on/off) - unsigned char motor_l; // Left motor control (PWM) - unsigned char dummy[4]; -} PADREQUEST; - -// Structs for raw memory card request -typedef struct _MCDREQUEST { - unsigned char addr; // Must be 0x81 (or 02/03/04 for multitap cards) - unsigned char cmd; // Command (MCD_COMMAND) - unsigned char dummy[2]; - unsigned char lba_h; // Sector address bits 8-15 (dummy for CMD_IDENTIFY) - unsigned char lba_l; // Sector address bits 0-7 (dummy for CMD_IDENTIFY) - unsigned char data[128]; // Sector payload (dummy for CMD_READ/CMD_IDENTIFY) - unsigned char checksum; // = lba_h ^ lba_l ^ data (CMD_WRITE only) - unsigned char dummy2[3]; -} MCDREQUEST; +} MemCardResponse; + +/* Raw requests */ + +typedef struct __attribute__((packed)) _PadRequest { + uint8_t addr; // Must be 0x01 (or 02/03/04 for multitap pads) + uint8_t cmd; // Command (PadCommand) + uint8_t tap_mode; // 0x01 to enable multitap response + uint8_t motor_r; // Right motor control (on/off) + uint8_t motor_l; // Left motor control (PWM) + uint8_t dummy[4]; +} PadRequest; + +typedef struct __attribute__((packed)) _MemCardRequest { + uint8_t addr; // Must be 0x81 (or 02/03/04 for multitap cards) + uint8_t cmd; // Command (MemCardCommand) + uint8_t dummy[2]; + uint8_t lba_h; // Sector address bits 8-15 (dummy for CMD_IDENTIFY) + uint8_t lba_l; // Sector address bits 0-7 (dummy for CMD_IDENTIFY) + uint8_t data[128]; // Sector payload (dummy for CMD_READ/CMD_IDENTIFY) + uint8_t checksum; // = lba_h ^ lba_l ^ data (CMD_WRITE only) + uint8_t dummy2[3]; +} MemCardRequest; #endif
\ No newline at end of file diff --git a/libpsn00b/include/psxspu.h b/libpsn00b/include/psxspu.h index a87e347..da000e3 100644 --- a/libpsn00b/include/psxspu.h +++ b/libpsn00b/include/psxspu.h @@ -115,7 +115,7 @@ extern "C" { void SpuInit(); -void SpuSetVoiceRaw( int voice, SpuVoiceRaw* param ); +void SpuSetVoiceRaw( int voice, const SpuVoiceRaw* param ); void SpuReverbOn( int voice ); void SpuSetReverb(); @@ -128,7 +128,7 @@ void SpuSetKey(int on_off, u_int voice_bit); // SPU transfer functions int SpuSetTransferMode(int mode); int SpuSetTransferStartAddr(int addr); -int SpuWrite(unsigned char* addr, int size); +int SpuWrite(const unsigned char* addr, int size); void SpuWait(); #ifdef __cplusplus diff --git a/libpsn00b/ldscripts/dll.ld b/libpsn00b/ldscripts/dll.ld index 59cbb53..a03a504 100644 --- a/libpsn00b/ldscripts/dll.ld +++ b/libpsn00b/ldscripts/dll.ld @@ -7,8 +7,8 @@ * replaced by the global offset table (GOT) and .bss being merged with .data. */ -OUTPUT_FORMAT(elf32-littlemips) -/*ENTRY(_start) +/*OUTPUT_FORMAT(elf32-littlemips) +ENTRY(_start) STARTUP(start.o)*/ MEMORY { diff --git a/libpsn00b/ldscripts/exe.ld b/libpsn00b/ldscripts/exe.ld index 3033636..c6b9f29 100644 --- a/libpsn00b/ldscripts/exe.ld +++ b/libpsn00b/ldscripts/exe.ld @@ -8,7 +8,7 @@ * compatible with dynamic linking, as DLLs require GP to be unused. */ -OUTPUT_FORMAT(elf32-littlemips) +/*OUTPUT_FORMAT(elf32-littlemips)*/ ENTRY(_start) /*STARTUP(start.o)*/ diff --git a/libpsn00b/libc/scanf.c b/libpsn00b/libc/scanf.c index b6d4510..ae3c714 100644 --- a/libpsn00b/libc/scanf.c +++ b/libpsn00b/libc/scanf.c @@ -8,6 +8,9 @@ #include <string.h> #include <strings.h> +// Uncomment to enable support for %f. +//#define ALLOW_FLOAT + char libc_vsscanf_buf[512]; char libc_vsscanf_allow[256]; @@ -354,7 +357,8 @@ int vsscanf(const char *str, const char *format, va_list ap) r++; } break; - + +#ifdef ALLOW_FLOAT case 'f': // Floating point number libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); fbuf = strtod(libc_vsscanf_buf, &ep); @@ -380,6 +384,7 @@ int vsscanf(const char *str, const char *format, va_list ap) conv = 0; break; +#endif } } diff --git a/libpsn00b/libc/string.c b/libpsn00b/libc/string.c index 445b227..a1a9a05 100644 --- a/libpsn00b/libc/string.c +++ b/libpsn00b/libc/string.c @@ -8,6 +8,10 @@ #include <string.h> #include <stdlib.h> +// Uncomment to enable strtod(), strtold() and strtof(). Note that these +// functions use extremely slow software floats. +//#define ALLOW_FLOAT + int tolower(int chr) { return (chr >='A' && chr<='Z') ? (chr + 32) : (chr); @@ -252,6 +256,8 @@ long strtol(const char *nptr, char **endptr, int base) return (long)strtoll(nptr, endptr, base); } +#ifdef ALLOW_FLOAT + double strtod(const char *nptr, char **endptr) { char strbuf[64]; @@ -302,6 +308,8 @@ double strtod(const char *nptr, char **endptr) return (i + d)*s; } +#endif + /* implementation by Lameguy64, behaves like OpenWatcom's strtok() */ /* BIOS strtok seemed either bugged, or designed for wide chars */ @@ -344,6 +352,8 @@ char *strtok( char *s1, char *s2 ) } /* strtok */ +#ifdef ALLOW_FLOAT + long double strtold(const char *nptr, char **endptr) { return (long double)strtod(nptr, endptr); @@ -352,4 +362,6 @@ long double strtold(const char *nptr, char **endptr) float strtof(const char *nptr, char **endptr) { return (float)strtod(nptr, endptr); -}
\ No newline at end of file +} + +#endif diff --git a/libpsn00b/libc/vsprintf.c b/libpsn00b/libc/vsprintf.c index 0a99dcc..9ca4cc5 100644 --- a/libpsn00b/libc/vsprintf.c +++ b/libpsn00b/libc/vsprintf.c @@ -6,6 +6,10 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdarg.h> + +// Uncomment to enable support for %f. +//#define ALLOW_FLOAT #define SPRINTF_ALT_FLAG (1<<0) #define SPRINTF_ZERO_FLAG (1<<1) @@ -208,6 +212,8 @@ int libc_ulltoa(unsigned long i, char *dst, int n) return n2; } +#ifdef ALLOW_FLOAT + void libc_float_to_string(float fl, char *dst, int n) { unsigned int *p = (unsigned int*)&fl; @@ -365,6 +371,8 @@ void libc_double_to_string(double fl, char *dst, int n) char libc_sprintf_floatbuf[64]; +#endif + int vsnprintf(char *string, unsigned int size, const char *fmt, va_list ap) { int string_pos,fmt_pos; @@ -732,6 +740,7 @@ int vsnprintf(char *string, unsigned int size, const char *fmt, va_list ap) directive_coming = 0; break; +#ifdef ALLOW_FLOAT case 'f': libc_double_to_string(va_arg(ap, double), libc_sprintf_floatbuf, 64); @@ -740,6 +749,8 @@ int vsnprintf(char *string, unsigned int size, const char *fmt, va_list ap) directive_coming = 0; break; +#endif + case 'n': // Number of characters written *(va_arg(ap,unsigned int*)) = string_pos; diff --git a/libpsn00b/psxcd/cdgetsector.s b/libpsn00b/psxcd/cdgetsector.s index 9af3543..dbe95cb 100644 --- a/libpsn00b/psxcd/cdgetsector.s +++ b/libpsn00b/psxcd/cdgetsector.s @@ -18,7 +18,8 @@ CdGetSector: # nop lui $v0, 0x1 - srl $a1, 2 +# srl $a1, 2 # (the official implementation expects $a1/size + # to be in 32-bit words rather than bytes) or $v0, $a1 sw $a0, D3_MADR($a2) # Set DMA base address and transfer length sw $v0, D3_BCR($a2) diff --git a/libpsn00b/psxcd/isofs.c b/libpsn00b/psxcd/isofs.c index 40a40af..d1c1b18 100644 --- a/libpsn00b/psxcd/isofs.c +++ b/libpsn00b/psxcd/isofs.c @@ -10,6 +10,9 @@ // Uncommend to enable debug output //#define DEBUG +#define DEFAULT_PATH_SEP '\\' +#define IS_PATH_SEP(ch) (((ch) == '/') || ((ch) == '\\')) + typedef struct _CdlDIR_INT { u_long _pos; @@ -374,7 +377,7 @@ static char* resolve_pathtable_path(int entry, char *rbuff) rbuff -= tbl_entry.nameLength; memcpy(rbuff, namebuff, tbl_entry.nameLength); rbuff--; - *rbuff = '\\'; + *rbuff = DEFAULT_PATH_SEP; // Parse to the parent entry = tbl_entry.dirLevel; @@ -431,12 +434,15 @@ static int find_dir_entry(const char *name, ISO_DIR_ENTRY *dirent) static char* get_pathname(char *path, const char *filename) { - char *c; - c = strrchr(filename, '\\'); + char *c = 0; + for (char *i = filename; *i; i++) { + if (IS_PATH_SEP(*i)) + c = i; + } if(( c == filename ) || ( !c )) { - path[0] = '\\'; + path[0] = DEFAULT_PATH_SEP; path[1] = 0; return NULL; } @@ -447,11 +453,17 @@ static char* get_pathname(char *path, const char *filename) static char* get_filename(char *name, const char *filename) { - char *c; - c = strrchr(filename, '\\'); + char *c = 0; + for (char *i = filename; *i; i++) { + if (IS_PATH_SEP(*i)) + c = i; + } - if(( c == filename ) || ( !c )) - { + if (!c) { + strcpy(name, filename); + return name; + } + if (c == filename) { strcpy(name, filename+1); return name; } @@ -783,7 +795,7 @@ static void _scan_callback(int status, unsigned char *result) { if( status == CdlDataReady ) { - CdGetSector((void*)_ses_scanbuff, 2048); + CdGetSector((void*)_ses_scanbuff, 512); if( _ses_scanbuff[0] == 0x1 ) { diff --git a/libpsn00b/psxcd/psxcd.c b/libpsn00b/psxcd/psxcd.c index 74c6c1c..8f19c8d 100644 --- a/libpsn00b/psxcd/psxcd.c +++ b/libpsn00b/psxcd/psxcd.c @@ -21,7 +21,7 @@ volatile int _cd_last_sector_count; int _cd_media_changed; void _cd_init(void); -void _cd_control(unsigned char com, unsigned char *param, int plen); +void _cd_control(unsigned char com, const void *param, int plen); void _cd_wait_ack(void); void _cd_wait(void); @@ -50,7 +50,7 @@ int CdInit(void) return 1; } -int CdControl(unsigned char com, unsigned char *param, unsigned char *result) +int CdControl(unsigned char com, const void *param, unsigned char *result) { // Don't issue command if ack is not received yet if( _cd_ack_wait ) @@ -72,7 +72,7 @@ int CdControl(unsigned char com, unsigned char *param, unsigned char *result) return 1; } -int CdControlB(unsigned char com, unsigned char *param, unsigned char *result) +int CdControlB(unsigned char com, const void *param, unsigned char *result) { if( !CdControl(com, param, result) ) { @@ -83,7 +83,7 @@ int CdControlB(unsigned char com, unsigned char *param, unsigned char *result) return 1; } -int CdControlF(unsigned char com, unsigned char *param) +int CdControlF(unsigned char com, const void *param) { int param_len=0; @@ -255,7 +255,7 @@ static void _CdReadReadyCallback(int status, unsigned char *result) CdGetSector((void*)_cd_read_addr, _cd_read_sector_sz); // Increment destination address - _cd_read_addr += _cd_read_sector_sz>>2; + _cd_read_addr += _cd_read_sector_sz; // Subtract sector count _cd_sector_count--; @@ -290,15 +290,15 @@ int CdRead(int sectors, u_long *buf, int mode) // Determine sector based on mode flags if( mode & CdlModeSize0 ) { - _cd_read_sector_sz = 2328; + _cd_read_sector_sz = 2328 / 4; } else if( mode & CdlModeSize1 ) { - _cd_read_sector_sz = 2340; + _cd_read_sector_sz = 2340 / 4; } else { - _cd_read_sector_sz = 2048; + _cd_read_sector_sz = 2048 / 4; } _cd_read_counter = VSync(-1); diff --git a/libpsn00b/psxetc/_dl_resolve_wrapper.s b/libpsn00b/psxetc/_dl_resolve_wrapper.s index 069ee84..01ebf3a 100644 --- a/libpsn00b/psxetc/_dl_resolve_wrapper.s +++ b/libpsn00b/psxetc/_dl_resolve_wrapper.s @@ -4,7 +4,7 @@ # This function is called by the lazy loader stubs generated by GCC in the # .plt/.MIPS.stubs section when attempting to call a GOT entry whose address # hasn't yet been resolved. The generated stubs conform to the MIPS ABI and -# uses the following registers to pass the following parameters: +# uses the following registers: # - $t7 = address the resolved function should return to (i.e. $ra of the # caller that triggered the stub) # - $t8 = index of the function in the .dynsym symbol table @@ -25,13 +25,13 @@ _dl_resolve_wrapper: # Figure out where the DLL's struct is. dlinit() places a pointer to the # struct in the second GOT entry, so it's just a matter of indexing the GOT - # using GP. Then call _dl_resolve_helper with the struct and $t8 as + # using $gp. Then call _dl_resolve_helper with the struct and $t8 as # arguments, and store the return value into $t0. - lw $a0, -0x7fec($gp) # sizeof(uint32_t) - 0x7ff0 (see dll.ld) + lw $a0, -0x7fec($gp) # (DLL *) sizeof(uint32_t) - 0x7ff0 [see dll.ld] move $a1, $t8 jal _dl_resolve_helper - addiu $sp, -8 # (branch delay) + addiu $sp, -8 addiu $sp, 8 move $t0, $v0 @@ -48,7 +48,9 @@ _dl_resolve_wrapper: jr $t0 nop -.global _dl_credits -.type _dl_credits, @object +.section .data + +.global _dl_credits +.type _dl_credits, @object _dl_credits: .asciiz "psxetc runtime dynamic linker by spicyjpeg\n" diff --git a/libpsn00b/psxetc/dl.c b/libpsn00b/psxetc/dl.c index e43374f..cbdcb66 100644 --- a/libpsn00b/psxetc/dl.c +++ b/libpsn00b/psxetc/dl.c @@ -38,8 +38,9 @@ //#define DEBUG // Comment before building to disable functions that rely on BIOS file APIs, -// i.e. DL_LoadSymbolMap() and dlopen(). -#define USE_FILE_API +// i.e. DL_LoadSymbolMapFromFile() and DL_LoadDLLFromFile(). +// FIXME: those seem to be broken currently, and shouldn't be used anyway +//#define USE_FILE_API /* Private types */ @@ -132,7 +133,7 @@ static uint32_t _elf_hash(const char *str) { } #ifdef USE_FILE_API -static uint8_t *_load_file(const char *filename, size_t *size_output) { +static uint8_t *_dl_load_file(const char *filename, size_t *size_output) { int32_t fd = open(filename, 1); if (fd < 0) { _LOG("psxetc: Can't open %s, error = %d\n", filename, fd); @@ -286,10 +287,10 @@ int32_t DL_ParseSymbolMap(const char *ptr, size_t size) { return entries; } -int32_t DL_LoadSymbolMap(const char *filename) { #ifdef USE_FILE_API +int32_t DL_LoadSymbolMapFromFile(const char *filename) { size_t size; - char *ptr = _load_file(filename, &size); + char *ptr = _dl_load_file(filename, &size); if (!ptr) return -1; @@ -297,10 +298,8 @@ int32_t DL_LoadSymbolMap(const char *filename) { free(ptr); return entries; -#else - _ERROR(RTLD_E_NO_FILE_API, -1); -#endif } +#endif void DL_UnloadSymbolMap(void) { if (!_symbol_map.entries) @@ -354,7 +353,7 @@ void DL_SetResolveCallback(void *(*callback)(DLL *, const char *)) { /* Library loading and linking API */ -DLL *dlinit(void *ptr, size_t size, DL_ResolveMode mode) { +DLL *DL_CreateDLL(void *ptr, size_t size, DL_ResolveMode mode) { if (!ptr) _ERROR(RTLD_E_DLL_NULL, 0); @@ -365,7 +364,7 @@ DLL *dlinit(void *ptr, size_t size, DL_ResolveMode mode) { } dll->ptr = ptr; - dll->malloc_ptr = 0; + dll->malloc_ptr = (mode & RTLD_FREE_ON_DESTROY) ? ptr : 0; dll->size = size; _LOG("psxetc: Initializing DLL at %08x\n", ptr); @@ -548,7 +547,7 @@ DLL *dlinit(void *ptr, size_t size, DL_ResolveMode mode) { // If RTLD_NOW was passed, resolve GOT entries ahead of time by // cross-referencing them with the symbol table. - if (mode != RTLD_NOW) + if (!(mode & RTLD_NOW)) continue; for (uint32_t j = got_offset; j < dll->got_length; j++) { @@ -584,7 +583,7 @@ DLL *dlinit(void *ptr, size_t size, DL_ResolveMode mode) { // _start() for regular executables, but we have to do it outside of the // DLL as there's no _start() or even a defined entry point within the // DLL itself. - const uint32_t *ctor_list = dlsym(dll, "__CTOR_LIST__"); + const uint32_t *ctor_list = DL_GetDLLSymbol(dll, "__CTOR_LIST__"); if (ctor_list) { for (uint32_t i = ((uint32_t) ctor_list[0]); i >= 1; i--) { void (*ctor)(void) = (void (*)(void)) ctor_list[i]; @@ -595,32 +594,28 @@ DLL *dlinit(void *ptr, size_t size, DL_ResolveMode mode) { return dll; } -DLL *dlopen(const char *filename, DL_ResolveMode mode) { #ifdef USE_FILE_API +DLL *DL_LoadDLLFromFile(const char *filename, DL_ResolveMode mode) { size_t size; - char *ptr = _load_file(filename, &size); + char *ptr = _dl_load_file(filename, &size); if (!ptr) return 0; - DLL *dll = dlinit(ptr, size, mode); - if (dll) - dll->malloc_ptr = dll->ptr; - else + DLL *dll = DL_CreateDLL(ptr, size, mode | RTLD_FREE_ON_DESTROY); + if (!dll) free(ptr); return dll; -#else - _ERROR(RTLD_E_NO_FILE_API, 0); -#endif } +#endif -void dlclose(DLL *dll) { +void DL_DestroyDLL(DLL *dll) { if (dll == RTLD_DEFAULT) return; if (dll->ptr) { // Call the DLL's global destructors. - const uint32_t *dtor_list = dlsym(dll, "__DTOR_LIST__"); + const uint32_t *dtor_list = DL_GetDLLSymbol(dll, "__DTOR_LIST__"); if (dtor_list) { for (uint32_t i = 0; i < ((uint32_t) dtor_list[0]); i++) { void (*dtor)(void) = (void (*)(void)) dtor_list[i + 1]; @@ -629,15 +624,15 @@ void dlclose(DLL *dll) { } } - // If the DLL is associated to a buffer allocated by dlopen(), free that - // buffer. + // If the DLL is associated to a buffer allocated by DL_LoadDLLFromFile(), + // free that buffer. if (dll->malloc_ptr) free(dll->malloc_ptr); free(dll); } -void *dlsym(DLL *dll, const char *name) { +void *DL_GetDLLSymbol(const DLL *dll, const char *name) { if (dll == RTLD_DEFAULT) return DL_GetSymbolByName(name); //return _dl_resolve_callback(RTLD_DEFAULT, name); @@ -654,7 +649,7 @@ void *dlsym(DLL *dll, const char *name) { // provided. for (uint32_t i = bucket[hash_mod]; i != 0xffffffff;) { if (i >= nchain) { - _LOG("psxetc: dlsym() index out of bounds (i = %d, n = %d)\n", i, nchain); + _LOG("psxetc: DL_GetDLLSymbol() index out of bounds (i = %d, n = %d)\n", i, nchain); _ERROR(RTLD_E_HASH_LOOKUP, 0); } @@ -673,7 +668,7 @@ void *dlsym(DLL *dll, const char *name) { _ERROR(RTLD_E_DLL_SYMBOL, 0); } -DL_Error dlerror(void) { +DL_Error DL_GetLastError(void) { DL_Error last = _error_code; _error_code = RTLD_E_NONE; diff --git a/libpsn00b/psxgpu/gettimimage.c b/libpsn00b/psxgpu/gettimimage.c index d9cf1bf..5598e07 100644 --- a/libpsn00b/psxgpu/gettimimage.c +++ b/libpsn00b/psxgpu/gettimimage.c @@ -1,7 +1,7 @@ #include <sys/types.h> #include <psxgpu.h> -int GetTimInfo(u_long *tim, TIM_IMAGE *timimg) { +int GetTimInfo(const u_long *tim, TIM_IMAGE *timimg) { u_long *rtim; |
