Discussion:
yet another new approach
(too old to reply)
muta...@gmail.com
2021-04-02 13:19:56 UTC
Permalink
I think I should provide a C90 library (using the osfunc()
generic OS interface) and PDOS-generic (using the osfunc()
generic BIOS interface) for every CPU listed in GCC 3.2.3.
PDOS-generic is most likely to be an ELF module for
each of those platforms, built using binutils.

Then provide a bios.c that runs under some existing
C compiler/runtime and just uses a 1 GiB or 2 GiB
flat file containing a FAT-16 file system.

Noting that bios.c can be replaced by pretty much
anything as an independent exercise.

Using that approach, and switching from GCC to
Smaller C, I could have bios.c as a fairly normal
MSDOS application (MSDOS doesn't know the
difference, anyway), and PDOS-generic is also
Smaller C, and has to exist within 640k (all that
bios.c can get from MSDOS) and from there it
starts loading ELF modules, that all outwardly
appear to be 8086 modules (internally they can
be Smaller C, that is undetectable).

Because I can write everything in Smaller C, I no
longer have difficulty finding a C compiler that
supports 8086. Other people can take their
chances whether Watcom C allows them to write
commercial programs or not, or try to get GCC
IA16 to do so.

Obviously I would run under Freedos instead of
MSDOS. It's a bit rude having two operating
systems running, but Freedos can probably be
loaded high. Since applications will be required
to use the osfunc() interface instead of INT 21H,
they will not have to double-up with a large C
runtime library, although there will be one C
runtime library for bios.c (which could be a
normal PDPCLIB, using INT 21H) and one provided
by PDOS-generic (which does all the FAT-16
handling itself). This would be the situation for all
the GCC targets too, at least initially.

BFN. Paul.
muta...@gmail.com
2021-04-02 15:20:04 UTC
Permalink
It's unclear to me what Smaller C will do under the
covers, but for a traditional large memory model
program, the executable will presumably be packed
so that functions start on 16-byte boundaries, but
other than that, there won't be any hardcoding
anywhere of 4-bit segment shifts, at least not for
the C-generated code. And other than setjmp/
longjmp, executables I produce will all be C code,
including the startup code.

Assuming PDOS-generic is loading the 8086 ELF
module on a 64k boundary, and we have:

funca = 30k
funcb = 20k
funcc = 60k

and funca calls both funcb and funcc, and we're on an
8086+ instead of an 8086, with 16-bit segment shifts,
then funcc needs to be shifted up to the next 64k
boundary.

In order for me to do that, the ELF format needs to let
me know how big each function is. Is it flexible enough
to do that?

That means I will have beautiful 8086 ELF executables.
Capable of running on both an 8086 and an 8086+,
without any hardcoding of segment shift amount in the
executable itself. And it could be any other shift value
too, e.g. 15-bit segment shifts to address 2 GiB. The
executable doesn't know or care if the granularity is
16-bytes, 32k or 64k.

But those flexible 8086 executables are limited to a
size_t of 64k. When I introduce magical huge pointers
into the equation, either via 8086 instructions or with
Smaller C's 80386 instructions, the executable needs
to know how much to adjust the segment register
whenever the offset wraps. It can do this via a global
variable, but the startup code still needs to set that
global variable.

And with no INT 21H calls available, there is no choice
but to provide a callback function via osfunc() to retrieve
the segment adjustment value. PDOS-generic will know
that value necessarily because it needs to know how to
load the flexible 8086 properly.

I think it's going to be quite messy loading a flexible
8086 executable. It's basically doing the job of the
linker.

Maybe we should just assume that source code is
available and recompile everything for either an 8086
or an 8086+, with a lot of padding x'00' between
certain functions in an 8086+. Or virtual padding
perhaps. ie keep it packed, but with all the segments
and offsets set so that after alignment on expected
boundaries, it is simple to adjust with the load point.
Although then it becomes impractical to adjust offsets.

And if we revert to loading executables on 64k boundaries
and never adjusting offsets, then we don't need ELF after
all, a traditional MSDOS executable will do the trick. And
we don't need an osfunc() call to get the segment shift
value, that will be done via compile option depending on
whether you are targeting an 8086 or an 8086+. And
special linker too.

Noting though that although it will look like a normal
MSDOS executable, the startup code will still be
osfunc-based and no INT 21H.

BFN. Paul.
Alexei A. Frounze
2021-04-03 06:26:19 UTC
Permalink
Post by ***@gmail.com
It's unclear to me what Smaller C will do under the
covers, but for a traditional large memory model
program, the executable will presumably be packed
so that functions start on 16-byte boundaries, but
other than that, there won't be any hardcoding
anywhere of 4-bit segment shifts, at least not for
the C-generated code. And other than setjmp/
longjmp, executables I produce will all be C code,
including the startup code.
Assuming PDOS-generic is loading the 8086 ELF
funca = 30k
funcb = 20k
funcc = 60k
and funca calls both funcb and funcc, and we're on an
8086+ instead of an 8086, with 16-bit segment shifts,
then funcc needs to be shifted up to the next 64k
boundary.
In Smaller C's huge memory model, pointers are 32-bit in size
and are physical addresses. Only 20 bits of those 32 are usable,
if we're talking real address mode of the 80x86.
Those get converted into segment:offset pairs at run time.
The offset after this conversion is minimal, 0 to 15.
IOW, this gives you the impression of having a flat 1MB address
space at the extra expense of speed and size (address
conversions happen "under the covers").

Alex
muta...@gmail.com
2021-04-04 10:03:47 UTC
Permalink
Post by ***@gmail.com
I think it's going to be quite messy loading a flexible
8086 executable. It's basically doing the job of the
linker.
Maybe we should just assume that source code is
available and recompile everything for either an 8086
or an 8086+, with a lot of padding x'00' between
certain functions in an 8086+.
Actually, we just need to relink it, not recompile it.
So long as the ELF (or whatever) executable has
all the base information of what the program is
trying to do, it should be possible to convert an
8086 ELF into an 8086+ ELF.
Post by ***@gmail.com
Or virtual padding
perhaps. ie keep it packed, but with all the segments
and offsets set so that after alignment on expected
boundaries, it is simple to adjust with the load point.
Note that Windows PE appears to have virtual padding.

We could choose to have the OS do a dynamic relink
of 8086 to 8086+ or do it once-off, externally to the OS.

And 80386 can be grafted on top of an 8086+. I think
real mode currently has flat addressing, but only to
the 1 MiB mark. To go above that you need to switch
to protected mode. But maybe with an upgrade to an
8086+, this would no longer need to be the case, and
the entire 4 GiB is addressable without needing to
leave real mode.

I think I'd like to see all this in Bochs. There's probably
not a lot of changes required to implement that.

Unless I'm missing something of course.

BFN. Paul.

Rod Pemberton
2021-04-03 04:30:38 UTC
Permalink
On Fri, 2 Apr 2021 06:19:56 -0700 (PDT)
Post by ***@gmail.com
just uses a 1 GiB or 2 GiB
flat file containing a FAT-16 file system.
FAT-16? You really need long file names. For M$ file systems, you'd
need MS-DOS version 7.0 (Windows 95) or later, or the DOSLFN utility, or
ODI's LFN Tools. I'm not sure what you'd do about implementing LFN's
for your OS, as they're probably still patented by M$.
Post by ***@gmail.com
Because I can write everything in Smaller C, I no
longer have difficulty finding a C compiler that
supports 8086.
Being in control of the tool chain is a good decision. You stated that
you took that approach previously. If you're not going to code your own
tools anymore, may I suggest that you use "dead" projects, projects that
haven't updated their code base in decades. This means you won't be
forced to update the tools.
Post by ***@gmail.com
Obviously I would run under Freedos instead of
MSDOS. It's a bit rude having two operating
systems running, but Freedos can probably be
loaded high.
Why Freedos? Wasn't DR-DOS open sourced? Apparently, even M$ has
opened sourced various versions of MS-DOS, at various times.

--
muta...@gmail.com
2021-04-03 06:07:10 UTC
Permalink
Post by ***@gmail.com
just uses a 1 GiB or 2 GiB
flat file containing a FAT-16 file system.
FAT-16? You really need long file names. For M$ file systems, you'd
need MS-DOS version 7.0 (Windows 95) or later, or the DOSLFN utility, or
ODI's LFN Tools. I'm not sure what you'd do about implementing LFN's
for your OS, as they're probably still patented by M$.
Alica already added LFN to all FAT types.

Patents only last 20 years, and LFN was available
before 2000.
Post by ***@gmail.com
Because I can write everything in Smaller C, I no
longer have difficulty finding a C compiler that
supports 8086.
Being in control of the tool chain is a good decision. You stated that
you took that approach previously. If you're not going to code your own
tools anymore,
I'm not sure what you're referring to here. I don't
remember what I said and what changed.
may I suggest that you use "dead" projects, projects that
haven't updated their code base in decades. This means you won't be
forced to update the tools.
One of my primary focuses is IBM mainframes. I have
made a couple of previous attempts to get GCC's
existing i370 target to build an MVS executable, but
although I got as far as a clean link, I didn't get a
viable execution, and wasn't prepared to spend the
rest of my life debugging it.

It was only after someone else got it working on
EBCDIC that I was finally able to marry it up with
PDPCLIB. And that happened around GCC 3.2.3
and that is where I stopped, to consolidate.

GCC 3.2.3 is dead, as you say. It's perfectly fine for
C90 which is what I want. I don't know anyone else
working on this release.
Post by ***@gmail.com
Obviously I would run under Freedos instead of
MSDOS. It's a bit rude having two operating
systems running, but Freedos can probably be
loaded high.
Why Freedos? Wasn't DR-DOS open sourced? Apparently, even M$ has
opened sourced various versions of MS-DOS, at various times.
Well, actually, I've now gone full circle and I'm back to
a traditional PDOS/86, just upgraded to use magical
huge pointers with a freeware license. The IA16 target
may prove useful in the future too.

There's no need to bother with PDOS-generic running
under PDOS/86, but PDOS/86 provides another
MSDOS rival, this time public domain.

BFN. Paul.
Loading...