From 68f873784b54fc5c53a5e329f24e12abc8d41ec2 Mon Sep 17 00:00:00 2001 From: "opencode.energia.arti.ee" Date: Sat, 31 Oct 2026 20:50:11 +0000 Subject: [PATCH] tms34010: run TI TMS34010 OS/2 tools (gspa/gsplnk/gsprom) under 2ine Fixes needed to run the 1990 TI 'TMS340 Family Code Generation Tools r5.01' (16-bit OS/2 1.x NE, DOSCALLS-only) on 2ine: * CMake: fall back to the system SDL2 headers when /usr/local/include/SDL2 is absent; the hard-coded path broke the build on stock distros. * doscalls16: implement the entry points these tools import - Dos16GetDateTime (33) with the OS/2 1.x *hours-first* 10-byte layout (the year-first 8-byte layout crashes gspa in asctime/localtime) - Dos16NewSize (68) - Dos16GetHugeShift (135) / Dos16HugeIncr (136) - Dos16CreateCSAlias (43), Dos16DevConfig (52), Dos16Move (67) * lx_loader: walk NE fixup chains to the segment's 64K virtual size instead of its file size, so fixups pointing into the BSS tail are applied. gspa segfaulted in a lcall to its CRT exit handler because of this. * doscalls: do not assert that the host PID fits in 16 bits (pid_max is 4194304 on current kernels); the 16-bit API truncates anyway. Verified: gspa assembles a 2,412-line TMS34010 source with 'No Errors, No Warnings', gsplnk links it with rts.lib, gsprom converts to Tek-hex. The C compiler child (gspac via gspcl) still hits the lxConvert1616to32 selector assertion; see TMS34010.md. --- .gitignore | 3 +- CMakeLists.txt | 7 +++- TMS34010.md | 94 ++++++++++++++++++++++++++++++++++++++++++++ lx_loader.c | 6 ++- native/doscalls-lx.h | 61 ++++++++++++++++++++++++++++ native/doscalls.c | 74 ++++++++++++++++++++++++++++++++-- native/doscalls.h | 12 ++++++ 7 files changed, 251 insertions(+), 6 deletions(-) create mode 100644 TMS34010.md diff --git a/.gitignore b/.gitignore index 95d4610..24911e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ cmake-* - +build/ +seg*.bin diff --git a/CMakeLists.txt b/CMakeLists.txt index 467f42e..7254ef3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,12 @@ elseif(CURSES_HAVE_NCURSES_CURSES_H) endif() # !!! FIXME -include_directories("/usr/local/include/SDL2") +# Local patch: prefer system SDL2 headers if the hardcoded path is missing. +if(EXISTS "/usr/local/include/SDL2/SDL.h") + include_directories("/usr/local/include/SDL2") +else() + include_directories("/usr/include/SDL2") +endif() add_library(2ine SHARED "lib2ine.c") if(LX_LEGACY) diff --git a/TMS34010.md b/TMS34010.md new file mode 100644 index 0000000..8f9e92d --- /dev/null +++ b/TMS34010.md @@ -0,0 +1,94 @@ +# 2ine fork: TI TMS34010 OS/2 toolchain support + +This is a fork of [`icculus/2ine`](https://github.com/icculus/2ine) at commit +`1ca194f` ("viocalls: Actually, VioGetMode() needs to initialize ncurses", +2022-01-31) plus a small patch series that makes **TI's 1990 "TMS340 Family +Code Generation Tools r5.01"** usable on Linux. + +Those tools (`gspa`, `gsplnk`, `gsprom`, `gspcg`, `gspopt`, `gspcl`, …) are +16-bit OS/2 1.x `NE` executables that import **only `DOSCALLS`** — exactly the +shape 2ine's 16-bit bridge targets. + +## Status (verified 2026-10-31) + +| tool | result | +|---|---| +| `gspa` (TMS340 COFF assembler) | **works** — assembles a 2,400-line source, "No Errors, No Warnings", valid COFF | +| `gsplnk` (linker) | **works** — links `.obj` + `rts.lib` into an absolute image | +| `gsprom` (COFF → Tek-hex) | **works** — "Translation complete" | +| `gspcl` → `gspac` (C compiler) | **blocked** — the compiler child starts, then 2ine asserts in `lxConvert1616to32` | + +Example session (from the repo root): + +```sh +cd build # lx_loader dlopen()s ./lib.so, so cwd matters +./lx_loader /path/to/gspa.exe test.asm +./lx_loader /path/to/gsplnk.exe test.obj rts.lib -o test.out +./lx_loader /path/to/gsprom.exe test.out test.hex +``` + +``` +TMS340 COFF Assembler Version 5.01 +(c) Copyright 1985, 1990 Texas Instruments Incorporated + PASS 1 + PASS 2 + + No Errors, No Warnings +``` + +`lx_dump` also parses the NE headers (segments, fixups, DOSCALLS imports). + +## Build + +Dependencies (Debian/Ubuntu names): + +```sh +sudo apt install build-essential cmake libncurses-dev libncurses-dev:i386 \ + libc6-dev-i386 gcc-multilib +``` + +2ine builds **32-bit** (`-m32`) and links the 32-bit `libSDL2-2.0.so.0` that is +checked into the repo root. `cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug && +cmake --build build -j2` produces `build/lx_loader` (32-bit), `build/lx_dump` +and the `lib*.so` modules. + +## Patches + +1. **`CMakeLists.txt`** — the hard-coded `include_directories("/usr/local/include/SDL2")` + is used only if it exists; otherwise fall back to `/usr/include/SDL2`. + Without this, `lib2ine.c` cannot find `SDL.h` on a stock distro. +2. **`native/doscalls*.c/.h`** — 16-bit entry points these tools import: + * `Dos16GetDateTime` (ordinal 33). The OS/2 1.x 16-bit `DATETIME` is the + *hours-first* 10-byte layout (same shape as the 32-bit struct), not the + year-first 8-byte one. Proven against the tool's own `asctime`/`localtime` + wrapper; getting this wrong crashes `gspa` at startup. + * `Dos16NewSize` (68) — validate selector, no-op (2ine maps full 64 KB). + * `Dos16GetHugeShift` (135) → 3, `Dos16HugeIncr` (136) — huge-segment + selector arithmetic. + * `Dos16CreateCSAlias` (43), `Dos16DevConfig` (52), `Dos16Move` (67) — for + the C compiler child. +3. **`lx_loader.c`** — NE fixup chains were walked only up to the segment's + *file* size, so fixups whose target lies in the BSS tail were skipped, + leaving the `0xFFFF:0000` placeholder in memory (`gspa` then segfaulted in a + `lcall` to its CRT exit handler). Chains now run to the 64 KB virtual size + or the end-of-chain marker. +4. **`native/doscalls.c`** — `Dos16GetPID` asserted that the host PID fits in + 16 bits. On modern kernels (`pid_max` = 4194304) it does not, so the process + aborted before the tool ran. The 16-bit API already truncates; the asserts + are disabled. + +## Known issues / next steps + +* `gspcl` (C compiler driver) spawns `gspac` successfully, but the child dies on + `lx_loader.c:546: lxConvert1616to32: Assertion 'GLoaderState.ldt[selector] != 0'` + — a 16:16 far pointer whose selector is not one of 2ine's mapped segments + (likely selector arithmetic around `Dos16CreateCSAlias`/`Dos16AllocSeg`). + The assembler/linker/converter path is unaffected. +* Huge-segment selector arithmetic is stubbed; nothing in the assembler path + needs more than 64 KB of data. + +## Provenance + +Upstream: . The patch series was written while +bringing up the TI toolchain for the VT1200 project and is published here so the +fixes are not lost; it has not been sent upstream. diff --git a/lx_loader.c b/lx_loader.c index b16bb47..ae6f973 100644 --- a/lx_loader.c +++ b/lx_loader.c @@ -2109,7 +2109,11 @@ static int fixupNeSegment(const NeSegmentTableEntry *seg, LxModule *lxmod, uint8 default: fprintf(stderr, "unknown fixup type %u\n", (uint) (srctype & 0xF)); break; } // switch } else { - while (srcchain_offset < seg->size) { // strictly, this should end with 0xFFFF, but we drop out for any out-of-bounds index. + // Local patch: fixup chains can point anywhere in the segment's + // 64k virtual address space (e.g. into BSS, past the file data + // size), not just within seg->size. 0xFFFF is the end-of-chain + // marker. + while ((srcchain_offset < 0x10000) && (srcchain_offset != 0xFFFF)) { uint16 *source = (uint16 *) (dst + srcchain_offset); srcchain_offset = *source; switch (srctype & 0xF) { diff --git a/native/doscalls-lx.h b/native/doscalls-lx.h index 13934ad..61ff335 100644 --- a/native/doscalls-lx.h +++ b/native/doscalls-lx.h @@ -44,6 +44,11 @@ static APIRET16 bridge16to32_Dos16SetSigHandler(uint8 *args) { return Dos16SetSigHandler(routine, prevaddress, prevaction, action, signumber); } +static APIRET16 bridge16to32_Dos16GetDateTime(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PDATETIME16, pdt); + return Dos16GetDateTime(pdt); +} + static APIRET16 bridge16to32_Dos16AllocSeg(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, flags); LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, psel); @@ -67,6 +72,12 @@ static APIRET16 bridge16to32_Dos16GetHugeShift(uint8 *args) { return Dos16GetHugeShift(pcount); } +static APIRET16 bridge16to32_Dos16CreateCSAlias(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pnewsel); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, sel); + return Dos16CreateCSAlias(sel, pnewsel); +} + static APIRET16 bridge16to32_Dos16GetMachineMode(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pmode); return Dos16GetMachineMode(pmode); @@ -78,6 +89,12 @@ static APIRET16 bridge16to32_Dos16Beep(uint8 *args) { return Dos16Beep(freq, dur); } +static APIRET16 bridge16to32_Dos16DevConfig(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, pb); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcb); + return Dos16DevConfig(pcb, pb); +} + static APIRET16 bridge16to32_Dos16ChDir(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(ULONG, res); LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pszDir); @@ -139,6 +156,19 @@ static APIRET16 bridge16to32_Dos16MkDir(uint8 *args) { return Dos16MkDir(pszDirName, peaop2); } +static APIRET16 bridge16to32_Dos16Move(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cb); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, psrc); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, pdst); + return Dos16Move(pdst, psrc, cb); +} + +static APIRET16 bridge16to32_Dos16NewSize(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, newsize); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, sel); + return Dos16NewSize(sel, newsize); +} + static APIRET16 bridge16to32_Dos16Open(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PEAOP2, peaop2); LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, fsOpenMode); @@ -216,6 +246,16 @@ static APIRET16 bridge16to32_Dos16GetCp(uint8 *args) { return Dos16GetCp(cb, arCP, pcCP); } +static USHORT bridge16to32_Dos16HugeShift(uint8 *args) { + return Dos16HugeShift(); +} + +static USHORT bridge16to32_Dos16HugeIncr(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, incr); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, sel); + return Dos16HugeIncr(sel, incr); +} + static APIRET16 bridge16to32_Dos16Read(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcbActual); LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbRead); @@ -277,12 +317,15 @@ LX_NATIVE_MODULE_16BIT_SUPPORT() LX_NATIVE_MODULE_16BIT_API(Dos16GetInfoSeg) LX_NATIVE_MODULE_16BIT_API(Dos16HoldSignal) LX_NATIVE_MODULE_16BIT_API(Dos16SetSigHandler) + LX_NATIVE_MODULE_16BIT_API(Dos16GetDateTime) LX_NATIVE_MODULE_16BIT_API(Dos16AllocSeg) LX_NATIVE_MODULE_16BIT_API(Dos16ReallocSeg) LX_NATIVE_MODULE_16BIT_API(Dos16FreeSeg) LX_NATIVE_MODULE_16BIT_API(Dos16GetHugeShift) + LX_NATIVE_MODULE_16BIT_API(Dos16CreateCSAlias) LX_NATIVE_MODULE_16BIT_API(Dos16GetMachineMode) LX_NATIVE_MODULE_16BIT_API(Dos16Beep) + LX_NATIVE_MODULE_16BIT_API(Dos16DevConfig) LX_NATIVE_MODULE_16BIT_API(Dos16ChDir) LX_NATIVE_MODULE_16BIT_API(Dos16ChgFilePtr) LX_NATIVE_MODULE_16BIT_API(Dos16Close) @@ -292,6 +335,8 @@ LX_NATIVE_MODULE_16BIT_SUPPORT() LX_NATIVE_MODULE_16BIT_API(Dos16FindFirst) LX_NATIVE_MODULE_16BIT_API(Dos16FindNext) LX_NATIVE_MODULE_16BIT_API(Dos16MkDir) + LX_NATIVE_MODULE_16BIT_API(Dos16Move) + LX_NATIVE_MODULE_16BIT_API(Dos16NewSize) LX_NATIVE_MODULE_16BIT_API(Dos16Open) LX_NATIVE_MODULE_16BIT_API(Dos16QCurDir) LX_NATIVE_MODULE_16BIT_API(Dos16QCurDisk) @@ -303,6 +348,8 @@ LX_NATIVE_MODULE_16BIT_SUPPORT() LX_NATIVE_MODULE_16BIT_API(Dos16GetVersion) LX_NATIVE_MODULE_16BIT_API(Dos16GetPID) LX_NATIVE_MODULE_16BIT_API(Dos16GetCp) + LX_NATIVE_MODULE_16BIT_API(Dos16HugeShift) + LX_NATIVE_MODULE_16BIT_API(Dos16HugeIncr) LX_NATIVE_MODULE_16BIT_API(Dos16Read) LX_NATIVE_MODULE_16BIT_API(Dos16Write) LX_NATIVE_MODULE_16BIT_API(DosSemRequest) @@ -324,12 +371,15 @@ static int init16_doscalls(void) { LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetInfoSeg, 8) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16HoldSignal, 2) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16SetSigHandler, 16) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetDateTime, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16AllocSeg, 8) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ReallocSeg, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FreeSeg, 2) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetHugeShift, 4) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16CreateCSAlias, 6) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetMachineMode, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Beep, 4) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16DevConfig, 8) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ChDir, 8) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ChgFilePtr, 12) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Close, 2) @@ -339,6 +389,8 @@ static int init16_doscalls(void) { LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FindFirst, 24) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FindNext, 12) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16MkDir, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Move, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16NewSize, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Open, 26) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QCurDir, 10) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QCurDisk, 8) @@ -350,6 +402,8 @@ static int init16_doscalls(void) { LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetVersion, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetPID, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetCp, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16HugeShift, 0) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16HugeIncr, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Read, 12) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Write, 12) LX_NATIVE_INIT_16BIT_BRIDGE(DosSemRequest, 8) @@ -368,12 +422,15 @@ LX_NATIVE_MODULE_INIT({ if (!init16_doscalls()) return 0; }) LX_NATIVE_EXPORT16(Dos16GetInfoSeg, 8), LX_NATIVE_EXPORT16(Dos16HoldSignal, 13), LX_NATIVE_EXPORT16(Dos16SetSigHandler, 14), + LX_NATIVE_EXPORT16(Dos16GetDateTime, 33), LX_NATIVE_EXPORT16(Dos16AllocSeg, 34), LX_NATIVE_EXPORT16(Dos16ReallocSeg, 38), LX_NATIVE_EXPORT16(Dos16FreeSeg, 39), LX_NATIVE_EXPORT16(Dos16GetHugeShift, 41), + LX_NATIVE_EXPORT16(Dos16CreateCSAlias, 43), LX_NATIVE_EXPORT16(Dos16GetMachineMode, 49), LX_NATIVE_EXPORT16(Dos16Beep, 50), + LX_NATIVE_EXPORT16(Dos16DevConfig, 52), LX_NATIVE_EXPORT16(Dos16ChDir, 57), LX_NATIVE_EXPORT16(Dos16ChgFilePtr, 58), LX_NATIVE_EXPORT16(Dos16Close, 59), @@ -383,6 +440,8 @@ LX_NATIVE_MODULE_INIT({ if (!init16_doscalls()) return 0; }) LX_NATIVE_EXPORT16(Dos16FindFirst, 64), LX_NATIVE_EXPORT16(Dos16FindNext, 65), LX_NATIVE_EXPORT16(Dos16MkDir, 66), + LX_NATIVE_EXPORT16(Dos16Move, 67), + LX_NATIVE_EXPORT16(Dos16NewSize, 68), LX_NATIVE_EXPORT16(Dos16Open, 70), LX_NATIVE_EXPORT16(Dos16QCurDir, 71), LX_NATIVE_EXPORT16(Dos16QCurDisk, 72), @@ -394,6 +453,8 @@ LX_NATIVE_MODULE_INIT({ if (!init16_doscalls()) return 0; }) LX_NATIVE_EXPORT16(Dos16GetVersion, 92), LX_NATIVE_EXPORT16(Dos16GetPID, 94), LX_NATIVE_EXPORT16(Dos16GetCp, 130), + LX_NATIVE_EXPORT16(Dos16HugeShift, 135), + LX_NATIVE_EXPORT16(Dos16HugeIncr, 136), LX_NATIVE_EXPORT16(Dos16Read, 137), LX_NATIVE_EXPORT16(Dos16Write, 138), LX_NATIVE_EXPORT16(DosSemRequest, 140), diff --git a/native/doscalls.c b/native/doscalls.c index c601870..97ac8f9 100644 --- a/native/doscalls.c +++ b/native/doscalls.c @@ -3321,6 +3321,72 @@ APIRET16 Dos16GetVersion(PUSHORT pver) return NO_ERROR; } // Dos16GetVersion +APIRET16 Dos16CreateCSAlias(USHORT sel, PUSHORT pnewsel) +{ + TRACE_NATIVE("Dos16CreateCSAlias(%u, %p)", (uint) sel, pnewsel); + // We hand back a selector for the same linear memory (our 16-bit segments + // are already mapped read/write/execute, so this is writable in practice). + const uint32 addr32 = GLoaderState.ldt[sel >> 3]; + if (!addr32) + return ERROR_INVALID_SELECTOR; + uint16 newsel = 0xFFFF; + uint16 offset = 0; + if (!GLoaderState.findSelector(addr32, &newsel, &offset, 1)) + return ERROR_NOT_ENOUGH_MEMORY; + if (pnewsel) *pnewsel = (USHORT) ((newsel << 3) | 7); + return NO_ERROR; +} // Dos16CreateCSAlias + +APIRET16 Dos16DevConfig(PUSHORT pcb, PBYTE pb) +{ + TRACE_NATIVE("Dos16DevConfig(%p, %p)", pcb, pb); + FIXME("returning an empty device config"); + if (pcb) *pcb = 0; + return NO_ERROR; +} // Dos16DevConfig + +APIRET16 Dos16Move(PVOID pdst, PVOID psrc, USHORT cb) +{ + TRACE_NATIVE("Dos16Move(%p, %p, %u)", pdst, psrc, (uint) cb); + memmove(pdst, psrc, cb); + return NO_ERROR; +} // Dos16Move + +APIRET16 Dos16GetDateTime(PDATETIME16 pdt) +{ + TRACE_NATIVE("Dos16GetDateTime(%p)", pdt); + // the 1.x 16-bit DATETIME layout is identical to the 32-bit one. + return (APIRET16) DosGetDateTime((PDATETIME) pdt); +} // Dos16GetDateTime + +APIRET16 Dos16NewSize(USHORT sel, USHORT newsize) +{ + TRACE_NATIVE("Dos16NewSize(%u, %u)", (uint) sel, (uint) newsize); + // we always map a full 64k segment and never discard, so resizing is a + // no-op. Just make sure the selector is one of ours. + if (!GLoaderState.ldt[sel >> 3]) + return ERROR_INVALID_SELECTOR; + FIXME("this implementation is severely lacking"); // sharing concerns, etc. + return NO_ERROR; +} // Dos16NewSize + +USHORT Dos16HugeShift(void) +{ + // Huge segments are made of consecutive 64k selectors, so each one is 8 + // higher than the last (1 << 3). + TRACE_NATIVE("Dos16HugeShift()"); + return 3; +} // Dos16HugeShift + +USHORT Dos16HugeIncr(USHORT sel, USHORT incr) +{ + TRACE_NATIVE("Dos16HugeIncr(%u, %u)", (uint) sel, (uint) incr); + // !!! FIXME: this assumes the same selector math as DOS16HugeShift, and + // !!! FIXME: that we actually made a huge allocation with consecutive + // !!! FIXME: selectors (we don't, currently). + return (USHORT) (sel + (incr << 3)); +} // Dos16HugeIncr + APIRET16 Dos16GetMachineMode(PBYTE pmode) { TRACE_NATIVE("Dos16GetMachineMode(%p)", pmode); @@ -3343,9 +3409,11 @@ APIRET16 Dos16GetPID(PPIDINFO16 ppidinfo) // note that these happen to fit Linux default PID ranges in 2018, which // tend to be 32768, but can be much higher by writing to // /proc/sys/kernel/pid_max - assert(GLoaderState.pib.pib_ulpid <= 0xFFFF); - assert(GLoaderState.pib.pib_ulppid <= 0xFFFF); - assert(tib2->tib2_ultid <= 0xFFFF); + // NOTE: host PIDs routinely exceed 16 bits (pid_max is 4194304 here), so + // these asserts fire on any modern Linux; the 16-bit API truncates below. + // assert(GLoaderState.pib.pib_ulpid <= 0xFFFF); + // assert(GLoaderState.pib.pib_ulppid <= 0xFFFF); + // assert(tib2->tib2_ultid <= 0xFFFF); ppidinfo->pid = (USHORT) GLoaderState.pib.pib_ulpid; ppidinfo->tid = (USHORT) tib2->tib2_ultid; diff --git a/native/doscalls.h b/native/doscalls.h index 583c643..758fde4 100644 --- a/native/doscalls.h +++ b/native/doscalls.h @@ -119,6 +119,11 @@ typedef struct UCHAR weekday; } DATETIME, *PDATETIME; +// OS/2 1.x's 16-bit DATETIME is the same layout as the 32-bit one above, just +// with different field names in the 16-bit headers (hours/minutes/... vs +// hour/minute/...). We reuse DATETIME for it. +typedef DATETIME DATETIME16, *PDATETIME16; + typedef void *PEAOP2; // !!! FIXME @@ -505,6 +510,13 @@ OS2EXPORT APIRET16 OS2API16 DosSemSet(PHSEM16 sem) OS2APIINFO(143); // These are only meant to be available to 16-bit binaries, some were removed in OS/2 2.0's SDK. +OS2EXPORT APIRET16 OS2API16 Dos16CreateCSAlias(USHORT sel, PUSHORT pnewsel) OS2APIINFO(43); +OS2EXPORT APIRET16 OS2API16 Dos16DevConfig(PUSHORT pcb, PBYTE pb) OS2APIINFO(52); +OS2EXPORT APIRET16 OS2API16 Dos16Move(PVOID pdst, PVOID psrc, USHORT cb) OS2APIINFO(67); +OS2EXPORT APIRET16 OS2API16 Dos16GetDateTime(PDATETIME16 pdt) OS2APIINFO(33); +OS2EXPORT APIRET16 OS2API16 Dos16NewSize(USHORT sel, USHORT newsize) OS2APIINFO(68); +OS2EXPORT USHORT OS2API16 Dos16HugeShift(void) OS2APIINFO(135); +OS2EXPORT USHORT OS2API16 Dos16HugeIncr(USHORT sel, USHORT incr) OS2APIINFO(136); OS2EXPORT APIRET16 OS2API16 Dos16GetVersion(PUSHORT pver) OS2APIINFO(92); OS2EXPORT APIRET16 OS2API16 Dos16GetMachineMode(PBYTE pmode) OS2APIINFO(49); OS2EXPORT APIRET16 OS2API16 Dos16GetHugeShift(PUSHORT pcount) OS2APIINFO(41);