summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib/osdlib_os2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/lib/osdlib_os2.cpp')
-rw-r--r--src/osd/modules/lib/osdlib_os2.cpp292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/osd/modules/lib/osdlib_os2.cpp b/src/osd/modules/lib/osdlib_os2.cpp
new file mode 100644
index 00000000000..c1aea62f489
--- /dev/null
+++ b/src/osd/modules/lib/osdlib_os2.cpp
@@ -0,0 +1,292 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont
+//============================================================
+//
+// sdlos_*.c - OS specific low level code
+//
+// SDLMAME by Olivier Galibert and R. Belmont
+//
+//============================================================
+
+// standard sdl header
+#include "sdlinc.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define INCL_DOS
+#include <os2.h>
+
+// MAME headers
+#include "osdcore.h"
+#include "osdlib.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)
+{
+ PPIB ppib;
+
+ DosGetInfoBlocks(NULL, &ppib);
+ DosKillProcess(DKP_PROCESSTREE, ppib->pib_ulpid);
+}
+
+//============================================================
+// osd_num_processors
+//============================================================
+
+int osd_get_num_processors(void)
+{
+ ULONG numprocs = 1;
+
+ DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numprocs, sizeof(numprocs));
+
+ return numprocs;
+}
+
+//============================================================
+// 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)
+{
+ void *p;
+
+ DosAllocMem( &p, size, fALLOC );
+ return p;
+}
+
+//============================================================
+// osd_free_executable
+//
+// frees memory allocated with osd_alloc_executable
+//============================================================
+
+void osd_free_executable(void *ptr, size_t size)
+{
+ DosFreeMem( ptr );
+}
+
+//============================================================
+// osd_break_into_debugger
+//============================================================
+
+void osd_break_into_debugger(const char *message)
+{
+ printf("Ignoring MAME exception: %s\n", message);
+}
+
+//============================================================
+// PROTOTYPES
+//============================================================
+
+
+static osd_ticks_t init_cycle_counter(void);
+static osd_ticks_t performance_cycle_counter(void);
+
+//============================================================
+// STATIC VARIABLES
+//============================================================
+
+// global cycle_counter function and divider
+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;
+
+ ULONG frequency;
+ PTIB ptib;
+ ULONG ulClass;
+ ULONG ulDelta;
+
+ DosGetInfoBlocks( &ptib, NULL );
+ ulClass = HIBYTE( ptib->tib_ptib2->tib2_ulpri );
+ ulDelta = LOBYTE( ptib->tib_ptib2->tib2_ulpri );
+
+ if ( DosTmrQueryFreq( &frequency ) == 0 )
+ {
+ // use performance counter if available as it is constant
+ cycle_counter = performance_cycle_counter;
+ ticks_counter = performance_cycle_counter;
+
+ ticks_per_second = frequency;
+
+ // return the current cycle count
+ return (*cycle_counter)();
+ }
+ else
+ {
+ fprintf(stderr, "No Timer available!\n");
+ exit(-1);
+ }
+
+ // temporarily set our priority higher
+ DosSetPriority( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 );
+
+ // 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;
+
+ // restore our priority
+ DosSetPriority( PRTYS_THREAD, ulClass, ulDelta, 0 );
+
+ // return the current cycle count
+ return (*cycle_counter)();
+}
+
+//============================================================
+// performance_cycle_counter
+//============================================================
+
+static osd_ticks_t performance_cycle_counter(void)
+{
+ QWORD qwTime;
+
+ DosTmrQueryTime( &qwTime );
+ return (osd_ticks_t)qwTime.ulLo;
+}
+
+//============================================================
+// 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);
+ }
+}