delorie.com/archives/browse.cgi   search  
Mail Archives: opendos/1997/03/21/02:39:11

Comments: Authenticated sender is <alaric+abwillms AT sdps DOT demon DOT co DOT uk>
From: "Alaric B. Williams" <alaric AT abwillms DOT demon DOT co DOT uk>
To: "Mike A. Harris" <mharris AT blackwidow DOT saultc DOT on DOT ca>
Date: Fri, 21 Mar 1997 07:09:16 +0000
MIME-Version: 1.0
Subject: Re: [opendos] FSSTND
Reply-to: alaric AT abwillms DOT demon DOT co DOT uk
CC: OpenDOS Mailing List <opendos AT mail DOT tacoma DOT net>
References: <199703150101 DOT CAA04384 AT magigimmix DOT xs4all DOT nl>
In-reply-to: <Pine.LNX.3.95.970320070753.12128G-100000@capslock.com>
Message-ID: <858928000.1021765.0@abwillms.demon.co.uk>

On 20 Mar 97 at 7:12, Mike A. Harris wrote:

> So basically if there is going to be a OPENDOS.STD file, it
> should come installed with certain defaults.  If you want to
> change them then you have to edit the file.  Sounds reasonable to
> me.  Personally I'd prefer a "worded standard", but this seems a
> comfortable comprimise.  I'm going to wait and see what everyone
> else thinks first.  Whatever seems to be the most popular I will
> add to the wishlist.  Otherwise I'll add them all as
> possibilities to the wishlist.

Ya know, I've had a thought; some people might like to paint their visions of what
OpenDOS should be like and post them. Not wishlists (I want IFS, I want...); actual
descriptions of how this can be implemented - so that legacy DOS apps will work, so
apps using these APIs can still work on DOS, how modules will be dealt with, how much
of the system runs in protected mode, etc.

I'll put mine together, we'll see what we get. Much better than idle posturing!

(There is now a slight pause while gears click within Alaric's head)

I still like the idea of a single TSR that provides the extended API and is licensed to
be freely copyable to MS-DOS so we can port our fancy apps there.

The TSR shall be a valid DPMI client, and will run under CWSDPMI, 
Windows DOS box, dosemu, etc.

It shall provide a real mode interface which does:

 - Access to realmode DLLs
 - Access to protmode DLLs in the way DPMI provides access to real mode ints; allocate
   a transfer buffer in PM memory, use calls to copy stuff there, use a call 
   to invoke the DLL
 - Register a DLL (real or prot mode) file with the system (it will be demand loaded)
 - Request/release memory map regions (screen mem etc), IO port ranges, IRQs.
 - Enter protected mode


The last one deserves some explanation. It is called with a filename for to a protected mode
image in our own format (probably just COFF, nice and easy to make with DJGPP). So a
real mode stub can contain the protected mode "payload" within the .EXE, 
after it's official end, and simply call "OD_pm_invoke(argv[0]);".

The protected mode environment is thus:

All apps/dlls live in the same address space under DPMI, along with 
the OD.EXE TSR. This has pros and cons. But it's backwards comptabile, so like
it or lump it or come up with a better way of doing this!

When they are invoked, they are given a pointer to the OD.EXE TSR protected mode
entry point, which provides:

 - Access to protmode DLLs
 - Access to realmode DLLs via transfer buffers
 - Register a DLL file
 - Request/release hardware
 - End execution

Now, the DLL thing is the core of the matter. There are two distinct type,
real mode modules (*.M16) and protmode modules (*.M32). I know 32/16 bit
isn't the distinction between real and protected mode, but if we keep it
that way, 16 bit stuff will always work on <386s and 32 bit stuff will
always have protected mode available.

Real and protected mode DLLs are very different.

Realmode ones must demand load to fit in 640k. They are relocatable, and
the header contains an ID string, version, and title. The ID string is
remembered by the system when a DLL is registered, and a program uses
the following type of interface:

void (*print)(char *text);
int (*status)();

OD_M16_handle printer = OD_M16_lock("Printer");

OD_M16_bind(printer,&print,"PrintAsciizString");
OD_M16_bind(printer,&status,"ReturnStatusWord");

if(status() == PRINTER_READY) print("Hello!");

OD_M16_release(printer);

...........

application locks the DLL, which loads it into RAM if necessary,
identifying it by the ID string in the .M16 header. Once
locked, it's stuck in memory. It then requests some pointers into
named entry points of the DLL, calls the entry points, and unlinks the DLL.

Reference counting is used to decide when to zap .M16s from memory. They get special
hook entry points:

_First_Loaded           (reset hardware, called once per session only)
_Unload                 (save state to file if necessary, remove 
                        ISRs, option of refusing to unload - ISR must be serviced, etc.)
_Loaded                 (pick up system state from file, install ISRs)

An OD-only version of the TSR would cooperate with the kernel over memory management, 
unloading DLLs when space got tight. The DOS version would have to dump modules as soon
as they are not in use.

The protected mode DLL interface is pretty similar, only the modules aren't swapped in and
out, since we have loads of virtual memory to play with!

Now, a set of standard modules is provided:

FILER.M16, FILER.M32: Replaces DOS filesystem interface. Special device modules may register
  with the filer to replace stdout, for example, with a fast direct version. Filers may
  install under here by "mounting" into the filer tree.

TASKS.M16, TASKS.M32: Multitasker interface, preemptive. This one never unloads. The two of them
  cooperate internally.

CONFIG.M16, CONFIG.M32: A nice configuration system (See below)

etc.

In the FILER case, FILER.M16 can just be a stub that passes on to the FILER.M32 interface.
Either way, they share the filer extension tables, so that 32 bit filers are visible from
real mode and vice versa. The tasker, being more intricate, will really need to be
one module that works in both modes - split into two halves. The 16 bit part deals with legacy
tasking and OD-compliant 16 bit tasking (which is nice since all device access is through
drivers, which know about multiple tasks and don't get screwed up by them), while the 32
bit part works with the clean world of protected mode tasking. A DLL can fork inside itself,
one fork returning to the caller, the other doing something useful. DLLs 
can use other DLLs as well.

The configuration system also specifies system paths. Ther is no standard on directory names,
only a standard on directory variables in the environment.

Configuration files are like so:

INCLUDE Dirs\OpenDOS + "CONFIG\HARDWARE.CFG"
INCLUDE Dirs\OpenDOS + "CONFIG\LANGUAGE.CFG"
INCLUDE Dirs\Drivers + "\SOUND\SOUND.CFG"

GROUP "User information"
STRING "UserName" "Alaric B. Williams"
INTEGER "UserHeadRadius/cm" 13
ENDGROUP

GROUP "Memory areas"
MEMORY "Cache" 64Mb
ENDGROUP

GROUP "Messages"
STRING "NoRam" "There isn't enough system RAM, sorry!"
ENDGROUP

So we might write:

puts(OD_env("Messages\NoRam"));

If a path is renamed, the OD kernel will change any PATH statements 
involved in a configuration file.

There are some standard configuration files - such as LANGUAGE.CFG, which defines the
"Messages" group. Different copies of LANGUAGE.CFG for different languages can be made.
Applications can use the standard ones, like NoRam, as well as ones that are added to 
the OpenDOS configuration via their own configuration file, which should include the standard
Dirs\OpenDOS + "OPENDOS.CFG" file.

Note that all config files automatically include the config file defining the directory 
structure by defining the "Dirs" group, so it can find others!

Erm...

...that's just about it for now.

ABW
--
Alaric B. Williams (alaric AT abwillms DOT demon DOT co DOT uk)

   ---<## OpenDOS FAQ ##>---
Plain HTML: http://www.delorie.com/opendos/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019