diff options
Diffstat (limited to 'src/osd/modules/lib/osdlib_macosx.cpp')
-rw-r--r-- | src/osd/modules/lib/osdlib_macosx.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp new file mode 100644 index 00000000000..0d89e6c3596 --- /dev/null +++ b/src/osd/modules/lib/osdlib_macosx.cpp @@ -0,0 +1,285 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// sdlos_*.c - OS specific low level code +// +// SDLMAME by Olivier Galibert and R. Belmont +// +//============================================================ + +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <signal.h> + +#include <mach/mach.h> +#include <mach/mach_time.h> +#include <mach/mach_traps.h> +#include <Carbon/Carbon.h> + +// MAME headers +#include "osdcore.h" +#include "osdlib.h" + +// FIXME: We shouldn't use SDL functions in here + +#include "sdlinc.h" + +//============================================================ +// osd_getenv +//============================================================ + +const char *osd_getenv(const char *name) +{ + return getenv(name); +} + +//============================================================ +// osd_setenv +//============================================================ + +int osd_setenv(const char *name, const char *value, int overwrite) +{ + return setenv(name, value, overwrite); +} + +//============================================================ +// osd_process_kill +//============================================================ + +void osd_process_kill(void) +{ + kill(getpid(), SIGKILL); +} + +//============================================================ +// osd_num_processors +//============================================================ + +int osd_get_num_processors(void) +{ + int processors = 1; + + struct host_basic_info host_basic_info; + unsigned int count; + kern_return_t r; + mach_port_t my_mach_host_self; + + count = HOST_BASIC_INFO_COUNT; + my_mach_host_self = mach_host_self(); + if ( ( r = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)(&host_basic_info), &count)) == KERN_SUCCESS ) + { + processors = host_basic_info.avail_cpus; + } + mach_port_deallocate(mach_task_self(), my_mach_host_self); + + return processors; +} + +//============================================================ +// osd_malloc +//============================================================ + +void *osd_malloc(size_t size) +{ +#ifndef MALLOC_DEBUG + return malloc(size); +#else +#error "MALLOC_DEBUG not yet supported" +#endif +} + + +//============================================================ +// osd_malloc_array +//============================================================ + +void *osd_malloc_array(size_t size) +{ +#ifndef MALLOC_DEBUG + return malloc(size); +#else +#error "MALLOC_DEBUG not yet supported" +#endif +} + + +//============================================================ +// osd_free +//============================================================ + +void osd_free(void *ptr) +{ +#ifndef MALLOC_DEBUG + free(ptr); +#else +#error "MALLOC_DEBUG not yet supported" +#endif +} + + +//============================================================ +// osd_alloc_executable +// +// allocates "size" bytes of executable memory. this must take +// things like NX support into account. +//============================================================ + +void *osd_alloc_executable(size_t size) +{ +#if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX) + return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); +#elif defined(SDLMAME_UNIX) + return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, 0, 0); +#endif +} + +//============================================================ +// osd_free_executable +// +// frees memory allocated with osd_alloc_executable +//============================================================ + +void osd_free_executable(void *ptr, size_t size) +{ +#ifdef SDLMAME_SOLARIS + munmap((char *)ptr, size); +#else + munmap(ptr, size); +#endif +} + +//============================================================ +// osd_break_into_debugger +//============================================================ + +void osd_break_into_debugger(const char *message) +{ + #ifdef MAME_DEBUG + printf("MAME exception: %s\n", message); + printf("Attempting to fall into debugger\n"); + kill(getpid(), SIGTRAP); + #else + printf("Ignoring MAME exception: %s\n", message); + #endif +} + + +//============================================================ +// PROTOTYPES +//============================================================ + +static osd_ticks_t init_cycle_counter(void); +static osd_ticks_t mach_cycle_counter(void); + +//============================================================ +// STATIC VARIABLES +//============================================================ + +static osd_ticks_t (*cycle_counter)(void) = init_cycle_counter; +static osd_ticks_t (*ticks_counter)(void) = init_cycle_counter; +static osd_ticks_t ticks_per_second; + +//============================================================ +// init_cycle_counter +// +// to avoid total grossness, this function is split by subarch +//============================================================ + +static osd_ticks_t init_cycle_counter(void) +{ + osd_ticks_t start, end; + osd_ticks_t a, b; + + cycle_counter = mach_cycle_counter; + ticks_counter = mach_cycle_counter; + + // wait for an edge on the timeGetTime call + a = SDL_GetTicks(); + do + { + b = SDL_GetTicks(); + } while (a == b); + + // get the starting cycle count + start = (*cycle_counter)(); + + // now wait for 1/4 second total + do + { + a = SDL_GetTicks(); + } while (a - b < 250); + + // get the ending cycle count + end = (*cycle_counter)(); + + // compute ticks_per_sec + ticks_per_second = (end - start) * 4; + + // return the current cycle count + return (*cycle_counter)(); +} + +//============================================================ +// performance_cycle_counter +//============================================================ + +//============================================================ +// mach_cycle_counter +//============================================================ +static osd_ticks_t mach_cycle_counter(void) +{ + return mach_absolute_time(); +} + +//============================================================ +// osd_ticks +//============================================================ + +osd_ticks_t osd_ticks(void) +{ + return (*cycle_counter)(); +} + + +//============================================================ +// osd_ticks_per_second +//============================================================ + +osd_ticks_t osd_ticks_per_second(void) +{ + if (ticks_per_second == 0) + { + // if we haven't computed the value yet, there's no time like the present + init_cycle_counter(); + } + return ticks_per_second; +} + + + +//============================================================ +// osd_sleep +//============================================================ + +void osd_sleep(osd_ticks_t duration) +{ + UINT32 msec; + + // make sure we've computed ticks_per_second + if (ticks_per_second == 0) + (void)osd_ticks(); + + // convert to milliseconds, rounding down + msec = (UINT32)(duration * 1000 / ticks_per_second); + + // only sleep if at least 2 full milliseconds + if (msec >= 2) + { + // take a couple of msecs off the top for good measure + msec -= 2; + usleep(msec*1000); + } +} |