[fpc-pascal] FPC in DOS environment

Tomas Hajny XHajT03 at mbox.vol.cz
Fri Jan 12 13:47:32 CET 2007


Daniel Franzini wrote:
> On 1/11/07, Tomas Hajny <XHajT03 at mbox.vol.cz> wrote:
 .
 .
>> GO32v2 is a protected mode application, indeed - specifically, it's
>> using
>> DPMI (DOS Protected Mode Interface). No special extender is needed if
>> you
>> already have DPMI host available (up and running). Some DOS
>> implementations already include this such DPMI host, similarly DPMI host
>> is provided for DOS applications running under Win 3.x, Win32 platforms,
>> OS/2, etc. If you run GO32v2 applications and no DPMI host is running,
>> the
>> loader/stub (linked into the compiled executable) tries to locate (using
>> standard search rules - current directory and then using %PATH%) and
>> launch CWSDPMI.EXE first (thus starting a DPMI host itself).
>
>
> this is something still obscure to me....when i target the compiler to
> go32v2, the compiler generates my code and links it with some magic code
> in
> order to work correctly with the funtions provided by the host (which in
> the
> general case is a standalone exe)???

In general case when using plain DOS (when using virtual DOS machines
provided by some other platforms like WinXX or OS/2, DPMI is provided
directly by the platform and interface to it is part of the VDM kernel).
The only "magic" is detection of DPMI (int 31h support) availability,
potentially launching CWSDPMI.EXE host and switching into 32-bit protected
mode. Interfacing to functions provided by the host is part of GO32v2 RTL
(using int 31h services), or some host services just overlay the usual DOS
services (overridden int 21h calls).


 .
 .
>> Surely, this inline stuff needs to be disassembled and ported to a
>> 32-bit
>> protected mode environment in order to make it to work properly with
>> FPC.
>
>
> the code that generates is here:
>  ------------------code start-----------------------------
>
>         {diskwrite}
>         asm
>                 push    bp
>                 mov     bp, sp
>                 add     bp, 8
>                 push    ds
>                 mov     bx, [bp]
>                 mov     ax, [bp+2]
>                 mov     ds, ax
>                 mov     cx, [bp+4]
>                 mov     dx, [bp+6]
>                 mov     al, [bp+8]
>                 push    bp
>                 int     26h
>                 jnc     ok
>                 popf
>                 pop     bp
>                 mov     [bp+10], ax
>                 jmp     cont
>         ok:     popf
>                 pop     bp
>                 xor     ax, ax
>                 mov     [bp+10], ax
>         cont:   pop     ds
>                 pop     bp
>                 mov     ax, 13h
>                 int     21h
>                 ret
> ------------------code end-----------------------------
>
>
>> Rewrite it in proper 32-bit assembler targetted for a protected mode
>> environment. I guess you should be able to find some information
>> available
>> on Internet regarding what needs to be changed and how, but it isn't
>> that
>> simple to be described here (especially with functions requiring a
>> memory
>> buffer shared between real mode and protected mode code like with your
>> disk read/write functions).
>
>
> like i said to Daniel Mantionne, the plans are to rewrite it in pure
> pascal...but it should work first in 32bit assembly...what would be the
> main
> differences between the two asm sources??

Just very briefly:

1) Read what our manual, wiki and mailing lists contributions state on FPC
calling conventions (i.e. how parameters are passed to
functions/procedures and how the stack organization and processing look
like) - this is certainly different from TP/BP. This implies changes of
code using [bp].

2) In general, you should use 32-bit registers rather than 16-bit
registers (I believe there's even some speed penalty on some CPUs when
using 16-bit registers, but more importantly, the overridden functions may
even _require_ providing parameters in 32-bit registers as opposed to e.g.
standard DOS functions) - i.e. eax instead of ax, etc.

3) If you need to exchange data with the underlying 16-bit code like BIOS
functions (yes, this includes your read/write sectore functions), the used
memory buffer must be placed in a memory area where the 16-bit code can
access it (= within the first MB of RAM) if it's your code allocating the
buffer and you need to make sure that you can access it too. This is
achieved using DPMI functions (read DPMI specification to find out more,
or at least have a look at some FPC RTL code using these int 31h
functions).

4) In general, you don't touch any segment registers - all your data are
available in flat memory model, where everything is available using 32-bit
addressing and ds=es=ss (i.e. no instructions like lds/les needed, no mov
es:[xx],yy, etc.). There's one exception directly related to the previous
point related to sharing data with 16-bit code - if you pass parameters
to/receive results from 16-bit code/functions, you need to translate the
16:16 16-bit addresses to 0:32 addresses used in 32-bit code and vice
versa (as described above) and then you obviously might need to change
some segment registers too immediately before/after the 16-bit function
call (however, these cases are normally solved using helper functions like
the DPMI support function for calling 16-bit interrupts, i.e. your code
wouldn't be directly messing with segment registers anyway).

Tomas




More information about the fpc-pascal mailing list