Skip to content

Commit

Permalink
More work on getting Java to run. Still not there.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Nov 2, 2016
1 parent 2ee12b6 commit 4e64524
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lx_loader.h
Expand Up @@ -13,10 +13,12 @@
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;

typedef int8_t sint8;
typedef int16_t sint16;
typedef int32_t sint32;
typedef int64_t sint64;

typedef unsigned int uint;

Expand Down
136 changes: 135 additions & 1 deletion native/doscalls.c
@@ -1,4 +1,4 @@
#include "os2native.h"
#include "os2native16.h"
#include "doscalls.h"

#include <unistd.h>
Expand Down Expand Up @@ -36,6 +36,17 @@ APIRET OS2API DosQuerySysState(ULONG func, ULONG arg1, ULONG pid, ULONG _res_, P
// This is also undocumented (no idea about this at all, including function params). Of course, Java uses it.
APIRET DosR3ExitAddr(void);

// These are 16-bit APIs that aren't in the 4.5 toolkit headers. Yeah, Java uses them! Winging it.
typedef int HSEM16, *PHSEM16;
static APIRET16 DosSemRequest(PHSEM16 sem, LONG ms);
static APIRET16 DosSemClear(PHSEM16 sem);
static APIRET16 DosSemWait(PHSEM16 sem, LONG ms);
static APIRET16 DosSemSet(PHSEM16 sem);
static APIRET16 bridge16to32_DosSemRequest(uint8 *args);
static APIRET16 bridge16to32_DosSemClear(uint8 *args);
static APIRET16 bridge16to32_DosSemWait(uint8 *args);
static APIRET16 bridge16to32_DosSemSet(uint8 *args);


static pthread_mutex_t GMutexDosCalls;

Expand Down Expand Up @@ -117,6 +128,13 @@ typedef struct
static DirFinder GHDir1;


LX_NATIVE_MODULE_16BIT_SUPPORT()
LX_NATIVE_MODULE_16BIT_API(DosSemRequest)
LX_NATIVE_MODULE_16BIT_API(DosSemClear)
LX_NATIVE_MODULE_16BIT_API(DosSemWait)
LX_NATIVE_MODULE_16BIT_API(DosSemSet)
LX_NATIVE_MODULE_16BIT_SUPPORT_END()

LX_NATIVE_MODULE_DEINIT({
GLoaderState->dosExit = NULL;

Expand All @@ -137,10 +155,19 @@ LX_NATIVE_MODULE_DEINIT({
MaxHFiles = 0;

pthread_mutex_destroy(&GMutexDosCalls);

LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT();
})

static int initDoscalls(void)
{
LX_NATIVE_MODULE_INIT_16BIT_SUPPORT()
LX_NATIVE_INIT_16BIT_BRIDGE(DosSemRequest, 8)
LX_NATIVE_INIT_16BIT_BRIDGE(DosSemClear, 4)
LX_NATIVE_INIT_16BIT_BRIDGE(DosSemWait, 8)
LX_NATIVE_INIT_16BIT_BRIDGE(DosSemSet, 4)
LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END()

GLoaderState->dosExit = DosExit;

if (pthread_mutex_init(&GMutexDosCalls, NULL) == -1) {
Expand Down Expand Up @@ -183,6 +210,10 @@ static int initDoscalls(void)
} // initDoscalls

LX_NATIVE_MODULE_INIT({ if (!initDoscalls()) return NULL; })
LX_NATIVE_EXPORT16(DosSemRequest, 140),
LX_NATIVE_EXPORT16(DosSemClear, 141),
LX_NATIVE_EXPORT16(DosSemWait, 142),
LX_NATIVE_EXPORT16(DosSemSet, 143),
LX_NATIVE_EXPORT(DosSetMaxFH, 209),
LX_NATIVE_EXPORT(DosSetPathInfo, 219),
LX_NATIVE_EXPORT(DosQueryPathInfo, 223),
Expand Down Expand Up @@ -2861,5 +2892,108 @@ __asm__ (
".size _DosSelToFlat, .-_DosSelToFlat \n\t"
);

static inline int trySpinLock(int *lock)
{
return (__sync_lock_test_and_set(lock, 1) == 0);
} // trySpinLock

static APIRET16 DosSemRequest(PHSEM16 sem, LONG ms)
{
TRACE_NATIVE("DosSemRequest(%p, %u)", sem, (uint) ms);
if (ms == 0) {
return !trySpinLock(sem) ? ERROR_TIMEOUT : NO_ERROR;
} else if (ms < 0) {
while (!trySpinLock(sem))
usleep(1000);
return NO_ERROR;
}

struct timespec ts;

clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
const uint64 end = (((uint64) ts.tv_sec) * 1000) + (((uint64) ts.tv_nsec) / 1000000) + ms;

while (1) {
if (trySpinLock(sem))
return NO_ERROR;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
const uint64 now = (((uint64) ts.tv_sec) * 1000) + (((uint64) ts.tv_nsec) / 1000000);
if (now >= end)
return ERROR_TIMEOUT;
usleep(1000);
} // while

return NO_ERROR;
} // DosSemRequest

static APIRET16 DosSemClear(PHSEM16 sem)
{
TRACE_NATIVE("DosSemClear(%p)", sem);
__sync_lock_release(sem);
return NO_ERROR;
} // DosSemClear

static APIRET16 DosSemWait(PHSEM16 sem, LONG ms)
{
TRACE_NATIVE("DosSemWait(%p, %u)", sem, (uint) ms);
if (ms == 0) {
return __sync_bool_compare_and_swap(sem, 0, 1) ? NO_ERROR : ERROR_TIMEOUT;
} else if (ms < 0) {
while (!__sync_bool_compare_and_swap(sem, 0, 1))
usleep(1000);
return NO_ERROR;
}

struct timespec ts;

clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
const uint64 end = (((uint64) ts.tv_sec) * 1000) + (((uint64) ts.tv_nsec) / 1000000) + ms;

while (1) {
if (__sync_bool_compare_and_swap(sem, 0, 1))
return NO_ERROR;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
const uint64 now = (((uint64) ts.tv_sec) * 1000) + (((uint64) ts.tv_nsec) / 1000000);
if (now >= end)
return ERROR_TIMEOUT;
usleep(1000);
} // while

return NO_ERROR;
} // DosSemWait

static APIRET16 DosSemSet(PHSEM16 sem)
{
TRACE_NATIVE("DosSemSet(%p)", sem);
__sync_bool_compare_and_swap(sem, 1, 0);
return NO_ERROR;
} // DosSemSet

static APIRET16 bridge16to32_DosSemRequest(uint8 *args)
{
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, ms);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
return DosSemRequest(sem, ms);
} // bridge16to32_DosSemRequest

static APIRET16 bridge16to32_DosSemClear(uint8 *args)
{
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
return DosSemClear(sem);
} // bridge16to32_DosSemClear

static APIRET16 bridge16to32_DosSemWait(uint8 *args)
{
LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, ms);
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
return DosSemWait(sem, ms);
} // bridge16to32_DosSemWait

static APIRET16 bridge16to32_DosSemSet(uint8 *args)
{
LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PHSEM16, sem);
return DosSemSet(sem);
} // bridge16to32_DosSemSet

// end of doscalls.c ...

41 changes: 41 additions & 0 deletions native/nls.c
Expand Up @@ -26,8 +26,49 @@ APIRET DosMapCase(ULONG cb, PCOUNTRYCODE pcc, PCHAR pch)
return NO_ERROR;
} // DosMapCase

APIRET DosQueryCtryInfo(ULONG cb, PCOUNTRYCODE pcc, PCOUNTRYINFO pci, PULONG pcbActual)
{
// From the 4.5 toolkit docs: "If this area is too small to hold all of
// the available information, then as much information as possible is
// provided in the available space (in the order in which the data would
// appear)." ...so we fill in a local struct and memcpy it at the end.
COUNTRYINFO ci;
memset(&ci, '\0', sizeof (ci));

// From the 4.5 toolkit docs: "If the amount of data returned is not
// enough to fill the memory area provided by the caller, then the memory
// that is unaltered by the available data is zeroed out." ...so blank
// it all out now.
memset(pci, '\0', cb);

if ((pcc->country != 0) || (pcc->codepage != 0))
return ERROR_CODE_PAGE_NOT_FOUND;

// !!! FIXME: this is just what OS/2 Warp 4.52 returns by default for my USA system.
ci.country = 1;
ci.codepage = 437;
ci.fsDateFmt = 0;
ci.szCurrency[0] = '$';
ci.szThousandsSeparator[0] = ',';
ci.szDecimal[0] = '.';
ci.szDateSeparator[0] = '-';
ci.szTimeSeparator[0] = ':';
ci.fsCurrencyFmt = 0;;
ci.cDecimalPlace = 2;
ci.fsTimeFmt = 0;
//USHORT abReserved1[2];
ci.szDataSeparator[0] = ',';
//USHORT abReserved2[5];

if (pcbActual)
*pcbActual = 38; // OS/2 Warp 4.52 doesn't count the abReserved[5] at the end.

return NO_ERROR;
} // DosQueryCtryInfo

LX_NATIVE_MODULE_INIT()
LX_NATIVE_EXPORT(DosQueryDBCSEnv, 6),
LX_NATIVE_EXPORT(DosQueryCtryInfo, 5),
LX_NATIVE_EXPORT(DosMapCase, 7)
LX_NATIVE_MODULE_INIT_END()

Expand Down
21 changes: 20 additions & 1 deletion native/nls.h
Expand Up @@ -7,14 +7,33 @@
extern "C" {
#endif

typedef struct COUNTRYCODE
typedef struct
{
ULONG country;
ULONG codepage;
} COUNTRYCODE, *PCOUNTRYCODE;

typedef struct
{
ULONG country;
ULONG codepage;
ULONG fsDateFmt;
CHAR szCurrency[5];
CHAR szThousandsSeparator[2];
CHAR szDecimal[2];
CHAR szDateSeparator[2];
CHAR szTimeSeparator[2];
UCHAR fsCurrencyFmt;
UCHAR cDecimalPlace;
UCHAR fsTimeFmt;
USHORT abReserved1[2];
CHAR szDataSeparator[2];
USHORT abReserved2[5];
} COUNTRYINFO, *PCOUNTRYINFO;

APIRET OS2API DosQueryDBCSEnv(ULONG cb, PCOUNTRYCODE pcc, PCHAR pBuf);
APIRET OS2API DosMapCase(ULONG cb, PCOUNTRYCODE pcc, PCHAR pch);
APIRET OS2API DosQueryCtryInfo(ULONG cb, PCOUNTRYCODE pcc, PCOUNTRYINFO pci, PULONG pcbActual);

#ifdef __cplusplus
}
Expand Down
8 changes: 8 additions & 0 deletions native/sesmgr.c
Expand Up @@ -2,7 +2,15 @@
#include "sesmgr.h"

LX_NATIVE_MODULE_INIT()
LX_NATIVE_EXPORT(DosStartSession, 37)
LX_NATIVE_MODULE_INIT_END()

APIRET DosStartSession(PSTARTDATA psd, PULONG pidSession, PPID ppid)
{
TRACE_NATIVE("DosStartSession(%p, %p, %p)", psd, pidSession, ppid);
printf("'%s', '%s', '%s'\n", psd->PgmTitle, psd->PgmName, psd->IconFile);
return ERROR_NOT_ENOUGH_MEMORY;
} // DosStartSession

// end of sesmgr.c ...

27 changes: 27 additions & 0 deletions native/sesmgr.h
Expand Up @@ -7,6 +7,33 @@
extern "C" {
#endif

typedef struct
{
USHORT Length;
USHORT Related;
USHORT FgBg;
USHORT TraceOpt;
PSZ PgmTitle;
PSZ PgmName;
PBYTE PgmInputs;
PBYTE TermQ;
PBYTE Environment;
USHORT InheritOpt;
USHORT SessionType;
PSZ IconFile;
ULONG PgmHandle;
USHORT PgmControl;
USHORT InitXPos;
USHORT InitYPos;
USHORT InitXSize;
USHORT InitYSize;
USHORT Reserved;
PSZ ObjectBuffer;
ULONG ObjectBuffLen;
} STARTDATA, *PSTARTDATA;

APIRET OS2API DosStartSession(PSTARTDATA psd, PULONG pidSession, PPID ppid);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 4e64524

Please sign in to comment.