diff --git a/AutomatedTests/CMakeLists.txt b/AutomatedTests/CMakeLists.txt index ed7afbbeab..f778367f4f 100644 --- a/AutomatedTests/CMakeLists.txt +++ b/AutomatedTests/CMakeLists.txt @@ -59,4 +59,7 @@ set_tests_properties(Log PROPERTIES PASS_REGULAR_EXPRESSION "One\nTwo\nThree") test(Init.cc) set_tests_properties(Init PROPERTIES PASS_REGULAR_EXPRESSION "constructor\nmain\ndestructor") +test(StdIO.c) +set_tests_properties(StdIO PROPERTIES PASS_REGULAR_EXPRESSION "OK") + endif() # RETRO68_LAUNCH_METHOD diff --git a/AutomatedTests/StdIO.c b/AutomatedTests/StdIO.c new file mode 100644 index 0000000000..27f8c65f46 --- /dev/null +++ b/AutomatedTests/StdIO.c @@ -0,0 +1,8 @@ +#include + +int main() +{ + FILE *f = fopen("out", "w"); + fprintf(f, "OK\n"); + fclose(f); +} diff --git a/gcc/gcc/config.gcc b/gcc/gcc/config.gcc index 4f011261b3..96bc8c97c9 100644 --- a/gcc/gcc/config.gcc +++ b/gcc/gcc/config.gcc @@ -1922,7 +1922,7 @@ m68k-*-elf* | fido-*-elf*) ;; esac ;; -m68k-*-macos* | fido-*-elf*) +m68k-*-macos*) default_m68k_cpu=68020 default_cf_cpu=5206 tm_file="${tm_file} m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h newlib-stdint.h m68k/m68kemb.h m68k/m68k-macos.h" diff --git a/gcc/gcc/config/m68k/m68k-macos.h b/gcc/gcc/config/m68k/m68k-macos.h index 5e8d528571..14220a2321 100644 --- a/gcc/gcc/config/m68k/m68k-macos.h +++ b/gcc/gcc/config/m68k/m68k-macos.h @@ -1,7 +1,12 @@ -#define LIBGCC_SPEC "-lretrocrt -lgcc" +#define LIBGCC_SPEC "--start-group -lretrocrt -lgcc --end-group" #define LINK_SPEC "-elf2mac -q -undefined=_consolewrite" +#undef LIB_SPEC +#define LIB_SPEC "--start-group -lc -lretrocrt --end-group" + +#define LINK_GCC_C_SEQUENCE_SPEC "--start-group -lgcc -lc -lretrocrt --end-group" + #undef STARTFILE_SPEC #define STARTFILE_SPEC "" diff --git a/gcc/gcc/config/rs6000/macos.h b/gcc/gcc/config/rs6000/macos.h index 315e56c6e4..c5dc931f88 100644 --- a/gcc/gcc/config/rs6000/macos.h +++ b/gcc/gcc/config/rs6000/macos.h @@ -66,10 +66,6 @@ #undef ASM_DEFAULT_SPEC #define ASM_DEFAULT_SPEC "" -/* Profiled library versions are used by linking with special directories. */ -#define LIB_SPEC "-lc" - -#define LIBGCC_SPEC "-lgcc -lretrocrt -lgcc %{carbon: -lCarbonLib} %{!carbon: -lInterfaceLib}" /* Static linking with shared libstdc++ requires libsupc++ as well. */ #define LIBSTDCXX_STATIC "supc++" @@ -171,6 +167,10 @@ --no-check-sections -undefined=_consolewrite \ %{shared:-bM:SRE}" +#define LIB_SPEC "-lc" +#define LIBGCC_SPEC "-lgcc -lretrocrt -lgcc %{carbon: -lCarbonLib} %{!carbon: -lInterfaceLib}" + +#define LINK_GCC_C_SEQUENCE_SPEC "--start-group -lgcc -lc -lretrocrt %{carbon: -lCarbonLib} %{!carbon: -lInterfaceLib} --end-group" #undef STARTFILE_SPEC #define STARTFILE_SPEC "" diff --git a/gcc/newlib/configure.host b/gcc/newlib/configure.host index 436bae2a4a..71d0d3b460 100644 --- a/gcc/newlib/configure.host +++ b/gcc/newlib/configure.host @@ -743,9 +743,9 @@ case "${host}" in syscall_dir= ;; m68k-apple-macos) - newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES -DMALLOC_PROVIDED" + newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED -DMALLOC_PROVIDED" newlib_cflags="${newlib_cflags} -ffunction-sections" - syscall_dir= + syscall_dir=syscalls ;; mcore-*-*) syscall_dir=syscalls @@ -812,8 +812,9 @@ case "${host}" in syscall_dir=syscalls ;; powerpc-*-macos) - newlib_cflags="${newlib_cflags} -DHAVE_RENAME -DHAVE_SYSTEM -DMISSING_SYSCALL_NAMES -DMALLOC_PROVIDED" - syscall_dir= + newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED -DMALLOC_PROVIDED" + newlib_cflags="${newlib_cflags} -ffunction-sections" + syscall_dir=syscalls ;; sh*-*-*) default_newlib_io_long_long="yes" diff --git a/libretro/malloc.c b/libretro/malloc.c index 1bb5df415b..e49141b294 100644 --- a/libretro/malloc.c +++ b/libretro/malloc.c @@ -36,7 +36,7 @@ void *_malloc_r(struct _reent *reent_ptr, size_t sz) Ptr p = NewPtr(sz); if(!p) - errno = ENOMEM; + reent_ptr->_errno = ENOMEM; return p; } @@ -45,7 +45,7 @@ void *_calloc_r(struct _reent *reent_ptr, size_t sz, size_t sz2) Ptr p = NewPtrClear(sz*sz2); if(!p) - errno = ENOMEM; + reent_ptr->_errno = ENOMEM; return p; } @@ -63,7 +63,7 @@ void *_realloc_r(struct _reent *reent_ptr, void *ptr, size_t sz) Ptr p = NewPtr(sz); if(!p) - errno = ENOMEM; + reent_ptr->_errno = ENOMEM; return p; } @@ -79,7 +79,7 @@ void *_realloc_r(struct _reent *reent_ptr, void *ptr, size_t sz) void *newPtr = NewPtr(sz); if(!newPtr) { - errno = ENOMEM; + reent_ptr->_errno = ENOMEM; return NULL; } memcpy(newPtr, ptr, oldSz); @@ -87,7 +87,7 @@ void *_realloc_r(struct _reent *reent_ptr, void *ptr, size_t sz) } else { - errno = ENOMEM; + reent_ptr->_errno = ENOMEM; return NULL; } } diff --git a/libretro/syscalls.c b/libretro/syscalls.c index 62a695af2a..fcb977595b 100644 --- a/libretro/syscalls.c +++ b/libretro/syscalls.c @@ -27,12 +27,16 @@ #include #include #include +#include +#include +#include #include #include +#include +#include -int isatty(int fd) { return fd >= 0 && fd <= 2; } -void *sbrk(long increment) +void *_sbrk_r(struct _reent *reent, ptrdiff_t increment) { Debugger(); return NewPtrClear(increment); @@ -50,37 +54,115 @@ void _exit(int status) ssize_t _consolewrite(int fd, const void *buf, size_t count); ssize_t _consoleread(int fd, void *buf, size_t count); -ssize_t write(int fd, const void *buf, size_t count) +const int kMacRefNumOffset = 10; + +ssize_t _write_r(struct _reent *reent, int fd, const void *buf, size_t count) { - return _consolewrite(fd,buf,count); + long cnt = count; + if(fd >= kMacRefNumOffset) + { + FSWrite(fd - kMacRefNumOffset, &cnt, buf); + return cnt; + } + else + return _consolewrite(fd,buf,count); } -ssize_t read(int fd, void *buf, size_t count) +ssize_t _read_r(struct _reent *reent, int fd, void *buf, size_t count) { - return _consoleread(fd,buf,count); + long cnt = count; + if(fd >= kMacRefNumOffset) + { + FSRead(fd - kMacRefNumOffset, &cnt, buf); + return cnt; + } + else + return _consoleread(fd,buf,count); } -int open(const char* name, int flags, mode_t mode) +int _open_r(struct _reent *reent, const char* name, int flags, int mode) +{ + Str255 pname; + c2pstrcpy(pname,name); + short ref; + + SInt8 permission; + switch(flags & O_ACCMODE) + { + case O_RDONLY: + permission = fsRdPerm; + break; + case O_WRONLY: + permission = fsWrPerm; + break; + case O_RDWR: + permission = fsRdWrPerm; + break; + } + + if(flags & O_CREAT) + { + HCreate(0,0,pname,'????','TEXT'); + } + + OSErr err = HOpenDF(0,0,pname,fsRdWrPerm,&ref); + + if(err) + return -1; // TODO: errno + + if(flags & O_TRUNC) + { + SetEOF(ref, 0); + } + + return ref + kMacRefNumOffset; +} + +int _close_r(struct _reent *reent, int fd) +{ + if(fd >= kMacRefNumOffset) + FSClose(fd - kMacRefNumOffset); + return 0; +} + +int _fstat_r(struct _reent *reent, int fd, struct stat *buf) { return -1; } -int close(int fd) +extern int _stat_r(struct _reent * reent, const char *fn, struct stat *buf) { return -1; } -int fstat(int fd, struct stat *buf) +off_t _lseek_r(struct _reent *reent, int fd, off_t offset, int whence) { - return -1; -} + if(fd >= kMacRefNumOffset) + { + short posMode; + switch(whence) + { + case SEEK_SET: + posMode = fsFromStart; + break; + case SEEK_CUR: + posMode = fsFromMark; + break; + case SEEK_END: + posMode = fsFromLEOF; + break; + } -off_t lseek(int fd, off_t offset, int whence) -{ + short ref = fd - kMacRefNumOffset; + SetFPos(ref, posMode, offset); + long finalPos; + GetFPos(ref, &finalPos); + return finalPos; + } return (off_t) -1; } -int kill(pid_t pid, int sig) +int _kill_r(struct _reent *reent, pid_t pid, int sig) { if(pid == 42) _exit(42); @@ -88,12 +170,67 @@ int kill(pid_t pid, int sig) return -1; } -pid_t getpid(void) +pid_t _getpid_r(struct _reent *reent) { return 42; } -int gettimeofday(struct timeval *tp, void *__tz) +int _fork_r(struct _reent *reent) +{ + return -1; +} + +int _execve_r(struct _reent *reent, const char *fn, char *const * argv, char *const *envp) +{ + return -1; +} + +int _fcntl_r(struct _reent *reent, int fd, int cmd, int arg) +{ + return -1; +} + +int _isatty_r(struct _reent *reent, int fd) +{ + return fd < kMacRefNumOffset; +} + +int _link_r(struct _reent *reent, const char *from, const char *to) +{ + reent->_errno = EPERM; + return -1; +} + +int _mkdir_r(struct _reent *reent, const char *fn, int mode) +{ + return -1; +} + +int _rename_r(struct _reent *reent, const char *from, const char *to) +{ + return -1; +} + +int _unlink_r(struct _reent *reent, const char *fn) +{ + return -1; +} + +_CLOCK_T_ _times_r(struct _reent *reent, struct tms *buf) +{ + reent->_errno = EACCES; + return -1; +} + +int _wait_r(struct _reent *reent, int *wstatus) +{ + reent->_errno = ECHILD; + return -1; /* Always fails */ +} + + + +int _gettimeofday_r(struct _reent *reent, struct timeval *tp, void *__tz) { /* Classic MacOS's GetDateTime function returns an integer. * TickCount() has a slightly higher resolution, but is independend of the real-time clock. @@ -127,4 +264,6 @@ int gettimeofday(struct timeval *tp, void *__tz) tp->tv_sec = secs - 86400 * (365 * 66 + 66/4); tp->tv_usec = (ticks - savedTicks) * 20000000 / 2003; } + + return 0; }