Discussion:
DOS extenders
(too old to reply)
T. Ment
2019-10-24 17:08:22 UTC
Permalink
Next to survey is Pharlap 286. With a 286 extender, 16-bit compilers
like Microsoft C 6.0 work, because 64k segments are still used. But the
total memory allowed is 16MB, a big increase from 640k real mode.

I have two books on extended DOS, Williams' DOS and Windows Protected
Mode, and Duncan's Extending DOS. Both cover Pharlap 286, with sample
code to learn from. The 286 era lasted long enough to matter, and you
had to get started then, or miss out. It was several years before 386
systems became prevalent. And your 286 code still worked.

Vetusware has Pharlap 286 Lite, and the commercial 3.1 sdk. Lite has a
2MB memory limit (so they claim). Lite includes an abbreviated 50 page
manual. The 3.1 sdk only had printed documentation, which is not found
in the download. So I got both. It would be better to have the printed
docs, but that would be a rare find now.

https://vetusware.com/download/286%20Dos%20Extender%20Lite%202.5/?id=6123

https://vetusware.com/download/286%7CDOS-Extender%203.1/?id=10425


There's also a patch from 3.10 to 3.12.

https://vetusware.com/download/286%7CDOS%20Extender%203.12/?id=6832

Some files in the patch archive are corrupt with Windows zip. 7z didn't
complain. I'll try and see if the patch works.
T. Ment
2019-10-24 17:35:21 UTC
Permalink
Post by T. Ment
There's also a patch from 3.10 to 3.12.
https://vetusware.com/download/286%7CDOS%20Extender%203.12/?id=6832
Some files in the patch archive are corrupt with Windows zip. 7z didn't
complain. I'll try and see if the patch works.
I compared the two expansions with diff. The 7z has 3 extra batch files,
each with a comment that says

@echo Sorry -- no Borland version of this example program

Must be some kind of archive quirk Windows zip complains about, but 7z
can handle.

I've still not tried the patch yet, but there are some .TXT files in a
DOCS directory, not present in the 3.10 sdk. I may need to inspect whole
thing, one file at a time.
T. Ment
2019-10-25 16:40:21 UTC
Permalink
Post by T. Ment
Next to survey is Pharlap 286.
There's also a patch from 3.10 to 3.12.
https://vetusware.com/download/286%7CDOS%20Extender%203.12/?id=6832
Some files in the patch archive are corrupt with Windows zip. 7z didn't
complain. I'll try and see if the patch works.
The patch works. Not sure how important it is.

What is important in the archive, is the RTK directory. You need its
executables and dlls to bind the extender to your app. That directory is
missing from the 3.10 archive.

You can run an app without binding the extender in, but then its stub
must find the Pharlap extender binary somewhere in the path. That's no
good for users who don't have Pharlap installed.

To test things, I compiled their hello.c example with Microsoft C 6.0a.

cl -AL -Lp hello.c
bind286 hello

That gives you an executable with a small stub. As noted above, it must
search the path for the extender binary. To avoid that, I used:

bind286 \p2\bin\run286b.exe hello -dll \p2\bin\doscalls.dll

To bind the full extender and docalls in. That makes it large, but it
works standalone. Only downside is the startup banner it prints on the
screen. Maybe there is a way to silence it. Don't know yet. But that's
only a brief cosmetic distraction. The app can clear it away.
r***@gmail.com
2019-10-26 15:04:12 UTC
Permalink
Hi,
Post by T. Ment
Next to survey is Pharlap 286. With a 286 extender, 16-bit compilers
like Microsoft C 6.0 work, because 64k segments are still used. But the
total memory allowed is 16MB, a big increase from 640k real mode.
Borland Pascal already supported that way back in the day (early '90s).
But it allowed higher amounts on 386+ machines (128 MB??). Dunno more.
Post by T. Ment
The 286 era lasted long enough to matter, and you had to get started
then, or miss out. It was several years before 386 systems became
prevalent. And your 286 code still worked.
FYI, I've heard AVX won't work in real mode or V86, only 16-bit pmode.
(I know we don't care, just found it curious!)
Post by T. Ment
Vetusware has Pharlap 286 Lite, and the commercial 3.1 sdk. Lite has a
2MB memory limit (so they claim).
Not sure which country's laws you abide by, but I doubt that's
widely recommended. I'm pretty sure the U.S. doesn't buy into the
concept of abandonware.

An alternative would be Japheth's HX (HXDEV* or HXD16*) with OpenWatcom.
I think you can reuse most of the 16-bit OS/2 support to then target
16-bit pmode with HDPMI16. (Actually, I think HDPMI16.EXE proper
required 386, but DPMILD16.EXE only needed 286.)

* http://www.bttr-software.de/forum/board_entry.php?id=15450
* https://github.com/Baron-von-Riedesel/HX/tree/master/bin
* https://sourceforge.net/projects/hx-dos/files/2.17/

I haven't developed with it much, so I'm not much help, but it's
fairly promising, obviously. But I'm sure you can figure out
what you need.
T. Ment
2019-10-26 16:45:07 UTC
Permalink
Post by r***@gmail.com
Post by T. Ment
Vetusware has Pharlap 286 Lite, and the commercial 3.1 sdk.
Not sure which country's laws you abide by
Exodus 20:17.
Post by r***@gmail.com
the U.S. doesn't buy into the concept of abandonware.
God said don't covet your neighbor's house, wife, ox, donkey, "nor
anything that is your neighbor's."

Intellectual property is not real. Jesus was a carpenter, not a priest.
T. Ment
2019-10-28 19:14:48 UTC
Permalink
Post by T. Ment
Next to survey is Pharlap 286
The 3.1 SDK supports Borland and Microsoft compilers. The setup for
Borland and Microsoft C 7.0 is simple. Run mklib.bat to convert the
compiler runtime library and make it Pharlap compatible. You get a new
library (in a separate directory) that supersedes the compiler's
version.

Microsoft C 7.0 needs Windows 3.1 to run. Microsoft C 5.1 and 6.0 do
not. So for plain DOS you need one of those. Both have OS/2 1.x support
and Pharlap's mklib.bat takes a different approach. Instead of building
an entire replacement library, they only build a small adjunct library.

That works because Microsoft C 5.1 and 6.0 provide OS/2 (protected mode)
libraries directly usable by Pharlap. So they only need a small extra
library to make everything Pharlap compatible. You add that library to
your command line and it works. It should be searched first though, in
case of duplicate function names between the two libraries. You always
want the Pharlap version.

Microsoft C 5.1 won't install the OS/2 libraries unless you also install
the OS/2 runtime. Version 6.0 does not have that problem. Both versions
ask which libraries you want to be default, DOS or OS/2. What that does
is determine how the libraries are named. The default name will have no
suffix, while DOS suffix = r and OS/2 suffix = p.

Pharlap setup is easier when no default library names are present. With
a default library name present, I had to hack Pharlap's mklib.bat to get
the extra Pharlap library set up.

When compiling, you select DOS library names with /Lr and Pharlap (OS/2)
names with /Lp.

Without any /L switch, the linker will search the default library name
automatically. That makes it a little easier for people only interested
in real mode DOS.
T. Ment
2019-10-30 04:32:51 UTC
Permalink
Post by T. Ment
Next to survey is Pharlap 286
With setup hurdles cleared, I wondered if HLT would work. It did not,
and I could not find a -priv flag like the Pharlap 386 extender has.

I dug into the API and found DosRealFarCall(). It won't work with a
function linked into your app, because they all run in protected mode.
Try it, if you like crashing. To use DosRealFarCall(), you need some
code already present in real mode before your app started up. But that
would mean writing a small TSR. Too much trouble.

I looked around the API some more, and found DosAllocRealSeg(). It gives
you a block of memory below 1 meg. The API says:

As this function returns both a real mode paragraph address and
a protected mode pointer the allocated block can be addressed in
either mode, and can therefore be useful in mixed-mode programming.

So I thought why not create a RealSeg block and write my opcode bytes
(STI, HLT, RETF) into it. Then create a far pointer to it in protected
mode and call it with DosRealFarCall(). With no other ideas, it seemed
worth a try.

Why not. Sometimes you get lucky. And what do you know, it works.

Protection still works, you can change the segment length from 3 to 2
and watch it fault. But HLT is no longer trapped. That's the way I like
it.




# include <stdio.h>
# include <stdlib.h>
# include <bios.h>
# include <dos.h>
# include <memory.h>
# include <phapi.h>

# define MK_FP(seg,off) ((void _far *) (((ULONG) (seg) << 16) | ((USHORT) (off))))

static int idle;
static USHORT key;
static ULONG next, wait;
static PUSHORT head, tail;

static SEL selector;
static USHORT paragraph;
static PUCHAR data;
static PVOID code;
static REGS16 regs;

void
main ()
{
setbuf (stdout, NULL);

if (DosAllocRealSeg (3L, &paragraph, &selector) != 0) {
fprintf (stderr, "failure allocating halt space\n");
exit (1);
}

data = MAKEP (selector, 0);

data[0] = 0xfb; /* (sti) There must be nothing */
data[1] = 0xf4; /* (cli) else between these two */
data[2] = 0xcb; /* (retf) */

code = MK_FP (paragraph, 0);

head = (unsigned short _far *) MK_FP (0x40, 0x1a);
tail = (unsigned short _far *) MK_FP (0x40, 0x1c);

printf ("int = %d, short = %d\n", sizeof (int), sizeof (short));
printf ("head @ %Fp\ntail @ %Fp\n", head, tail);
printf ("head = %u, tail = %u\n", *head, *tail);
printf ("\n");

goto next;

wait:

memset (&regs, 0, sizeof regs);
DosRealFarCall ((REALPTR) code, &regs, 0L, 0);

wait++;

next:

idle = 1;

_asm cli;

if (*head != *tail)
idle = 0;

if (idle)
goto wait;

_asm sti; /* Do not factor out, see above */

next++;

key = _bios_keybrd (_KEYBRD_READ);
key &= 0xff;
putchar (key);

if (key != 'X')
goto next;

printf ("\n\n");
printf ("head = %u, tail = %u\n", *head, *tail);
printf ("wait = %lu, next = %lu\n", wait, next);

if (DosFreeSeg (selector) != 0) {
fprintf (stderr, "failure releasing halt space\n");
exit (1);
}

exit (0);
}
T. Ment
2019-10-31 20:56:07 UTC
Permalink
Post by T. Ment
data[0] = 0xfb; /* (sti) There must be nothing */
data[1] = 0xf4; /* (cli) else between these two */
data[2] = 0xcb; /* (retf) */
I see a comment error. (cli) should read (hlt).

Poking opcodes into a buffer is OK for that short sequence, but a real
mode dll is more flexible. You can write C code as usual. Williams' book
covers them, but some details were lacking. Fortunately, the Pharlap SDK
has a working example. The compile and link steps are easy with Borland,
the example makefile shows how. So I'll only post my code.



--- rmode.def

LIBRARY RMODE
; EXETYPE DOS4
DESCRIPTION 'RMODE'
EXPORTS
_RM_halt


--- rmode.c (dll source)

RM_halt (void)
{
_asm sti; /* There must be nothing */
_asm hlt; /* else between these two */
}


--------- ht.c (Phar Lap 286 HLT test)

# include <stdio.h>
# include <stdlib.h>
# include <bios.h>
# include <memory.h>
# include <phapi.h>

# undef MK_FP
# define MK_FP(seg,off) ((void _far *) (((ULONG) (seg) << 16) | ((USHORT) (off))))

static int idle;
static USHORT key;
static ULONG next, wait;
static PUSHORT head, tail;
static REGS16 regs;
static REALPTR halt;

void _far RM_halt (void);

void
main ()
{
setbuf (stdout, NULL);

halt = DosProtToReal ((PVOID) RM_halt);

head = (unsigned short _far *) MK_FP (0x40, 0x1a);
tail = (unsigned short _far *) MK_FP (0x40, 0x1c);

printf ("int = %d, short = %d\n", sizeof (int), sizeof (short));
printf ("head @ %Fp\ntail @ %Fp\n", head, tail);
printf ("head = %u, tail = %u\n", *head, *tail);
printf ("\n");

goto next;

wait:

memset (&regs, 0, sizeof regs);
DosRealFarCall (halt, &regs, 0L, 0);

wait++;

next:

idle = 1;

_asm cli;

if (*head != *tail)
idle = 0;

if (idle)
goto wait;

_asm sti; /* Do not factor out, see RM_halt */

next++;

key = _bios_keybrd (_KEYBRD_READ);
key &= 0xff;
putchar (key);

if (key != 'X')
goto next;

printf ("\n\n");
printf ("head = %u, tail = %u\n", *head, *tail);
printf ("wait = %lu, next = %lu\n", wait, next);

exit (0);
}

Loading...