Recent

Author Topic: Far pointer versus Pointer in 16-bit DOS  (Read 3111 times)

aitorsm

  • New member
  • *
  • Posts: 7
Far pointer versus Pointer in 16-bit DOS
« on: October 21, 2022, 12:34:34 am »
Hello,

I used to code with TP for 16-bit and FPC for 32-bit DOS, so I was very happy to know that finally there's a 16-bit flavour of FPC, so I can use an actively supported compiler.

I am trying to re-compile FD-KEYB under FPC 16-bit (under a Win32 host OS). It compiles fine under TP, but I get a bunch of errors when trying to compile for FPC 16-bit, so trying to see how to overcome them.
FD-KEYB is a complex stuff to recompile, it has a lot of pointer and memory mangling, and most of the resident code is inlined assembler. For compatibility, I hope that the inlined assembler is taken as TASM-compatible and not NASM-compatible.

So here I go with the first question: most of the errors I get are about incompatibility between Pointers and Far pointers:
Incompatible types: got "FarPointer" expected "Pointer"
Incompatible types: got "Pointer" expected "FarPointer"
Illegal type conversion: "FarPointer" to "pword"

So how does FPC handle FarPointers? In TP I never had to care because all pointers were by default Far, but for FPC I see I have to care.

Thanks in advance,
Aitor

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #1 on: October 21, 2022, 09:17:34 am »
I believe it's highly dependent on the chosen memory model. You might need compact, large or huge to make Pointer = FarPointer.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #2 on: October 21, 2022, 04:11:56 pm »
In addition to what Leledumbo wrote (which is correct) you also need to compile the RTL with the correct memory model assuming you did compile FPC yourself and didn't use the installer provided with FPC 3.2.2 (which contains all memory models precompiled; then just specifying the memory model should be enough to pick the correct units).

aitorsm

  • New member
  • *
  • Posts: 7
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #3 on: October 21, 2022, 11:42:00 pm »
Hello,
As the program is less than 50K (before UPX-ing), I chose the Tiny memory model:

ppcross8086 -WmTiny -WtEXE -Sg  KEYB.PAS

Wouldn't that make ALL pointers near?

I haven't precompiled the compiler, I am using the 3.2.2 distribution.
I have to use -Sg, because I am using LABEL/GOTO at some points.

To add more context information:
I don't get cross incompatibilities between my code and the standar units, but between my code itself:

Var   
       MultiHand   : Pointer;
...
   MultiHand := ptr (ResCS,ofs(Int2Fh));

gives me a:
KEYB.PAS(2656,17) Error: Incompatible types: got "FarPointer" expected "Pointer"

That suggests that the ptr construct returns a FAR pointer, whereas Pointer is NEAR pointer.
I need it to be far to be able to check the installed handler;

Var    IntVec      : Array[Byte] of Pointer absolute 0:0;
...
if not (  (IntVec[$2F]=MultiHand)...

as I wanted to bypass DOS. I'll try and see if using GetIntVec and passing MultiHand would make it any better, but I'd need that both SEG:OFS of the interrupt vector table coincides (not just the OFS).
Or alternatively, treating all them as double words instead of pointers.

Aitor


marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11452
  • FPC developer.
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #4 on: October 21, 2022, 11:56:22 pm »
Anything CS:Offset is per definition a far pointer, as a near pointer is only the 16-bit offset within the segment.

IOW you are using FAR pointer constructors like ptr() and FAR variables like IntVec (outside the datasegment, probably), but define a NEAR pointer (multihand) to work with it.   

That does not make sense. Maybe declaring multihand FAR will fix this.

aitorsm

  • New member
  • *
  • Posts: 7
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #5 on: October 22, 2022, 12:07:40 am »
Thanks, I think this would work, this is what I am looking for.

But how do I declare a pointer to be FAR?
These two won't work:

var
  MultiHand : FAR;

var
   MultiHand:  FAR pointer;

AlexTP

  • Hero Member
  • *****
  • Posts: 2402
    • UVviewsoft
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #6 on: October 22, 2022, 12:08:47 am »
https://wiki.freepascal.org/Far
IMO this page needs the improving to show how to use far pointers.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11452
  • FPC developer.
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #7 on: October 22, 2022, 12:12:41 am »
16-bit is a quarter century ago for me, but wasn't there also a {$F+}  ?

Or simply a predefined farpointer?

aitorsm

  • New member
  • *
  • Posts: 7
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #8 on: October 22, 2022, 12:15:52 am »
Thanks!

Var
  MultiHand: FarPointer;

seems to remove the error. I didn't know type "FarPointer" ever existed (I've found it in the RTL sources).
I'll keep debugging!

Thanks for your help!
Aitor

aitorsm

  • New member
  • *
  • Posts: 7
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #9 on: November 06, 2022, 12:46:02 am »
Hello again!!

Switching to COMPACT mode instead of TINY solved many pointer/far pointer programs.

I have come across a problem that I don't know how to solve, and so I am requesting if someone does.

The relevant code bits are the following:


ppcross8086.exe -WmCompact -Wtexe -Sg   KEYB.PAS
===
TYPE
        SimpleProc     = procedure;     { parameter-less callable function }
...

CONST
...
       BIOSStoreKey: SimpleProc   = NIL;    { procedure EXCLUSIVE to StoreKey }
...

Procedure EfStoreKey0; far; assembler;
asm
...
end;

...
   BIOSStorekey  := EfStoreKey0;
===

This last line gives the error:

KEYB.PAS(2960,21) Error: Incompatible types: got "untyped" expected "<procedure variable type of procedure;Pascal>"

I assume that, whereas TPC is assuming that EfStoreKey0 is a procedure-type variable, FPC assumes that I want to assign the result of executing the procedure, which I assume is "untyped" (as in C would be void).

I don't know how to solve it. According to FPC documentation, this should make it work:

   BIOSStorekey  := @EfStoreKey0;

but it gives

KEYB.PAS(2960,21) Error: Incompatible types: got "<address of procedure;far;Pascal>" expected "<procedure variable type of procedure;Pascal>"

and

   BIOSStorekey  := SimpleProc(@EfStoreKey0);

KEYB.PAS(2960,21) Error: Illegal type conversion: "<address of procedure;far;Pascal>" to "<procedure variable type of procedure;Pascal>"

and

   BIOSStorekey  := @EfStoreKey0^;

KEYB.PAS(2960,34) Error: Illegal qualifier

(Also not using the TYPE or replacing VAR for CONST does not make a difference)

What is wrong here?


The -MTP option does NOT help, it produces a bunch new errors, that are corrected if I use:
TYPE
        SimpleProc     = procedure; far;     { parameter-less callable function }
...

which is NOT TPC compatible.

And the "old" problem is not corrected anyway, it is changed to:

KEYB.PAS(2960,21) Error: Illegal type conversion: "<address of procedure;far;Pascal>" to "NearCsPointer"


Thanks in advance for your help,
Aitor

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #10 on: November 08, 2022, 10:27:24 pm »
For mode TP you should not use @ to retrieve function pointers. For the default mode (FPC) you must however. The following code works for me when compiled with ppcross8086.exe -Wmcompact -CX -XX tfar.pp:

Default mode:

Code: Pascal  [Select][+][-]
  1. program tfar;
  2.  
  3. type
  4.   SimpleProc = procedure;
  5.  
  6. const
  7.   BIOSStoreKey: SimpleProc = Nil;
  8.  
  9. procedure EFStoreKey0; assembler;
  10. asm
  11. end;
  12.  
  13. begin
  14.   BIOSStoreKey := @EFStoreKey0;
  15. end.

TP mode:

Code: Pascal  [Select][+][-]
  1. program tfar;
  2.  
  3. {$mode tp}
  4.  
  5. type
  6.   SimpleProc = procedure;
  7.  
  8. const
  9.   BIOSStoreKey: SimpleProc = Nil;
  10.  
  11. procedure EFStoreKey0; assembler;
  12. asm
  13. end;
  14.  
  15. begin
  16.   BIOSStoreKey := EFStoreKey0;
  17. end.

If that doesn't work for you then please provide a complete example that shows the problem and not only snippets.

aitorsm

  • New member
  • *
  • Posts: 7
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #11 on: November 17, 2022, 12:56:20 am »
Thanks, I'll check that.

Instead of using {$mode tp} I was using -MTP in commandline, assuming it was equivalent.
Nevertheless, I'll try using the inlined compiled directive and report.

Thanks for replying.
Aitor

ccrause

  • Hero Member
  • *****
  • Posts: 856
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #12 on: November 17, 2022, 06:13:12 am »
Instead of using {$mode tp} I was using -MTP in commandline, assuming it was equivalent.
Nevertheless, I'll try using the inlined compiled directive and report.
The two versions are basically the same, refer to the documentation for the details.

aitorsm

  • New member
  • *
  • Posts: 7
Re: Far pointer versus Pointer in 16-bit DOS
« Reply #13 on: January 30, 2023, 08:52:45 pm »
Hello!

Sorry for being late in replying. {$MODE TP} does not make any better, as expected.

You can see the code here:

https://gitlab.com/FreeDOS/base/keyb/-/blob/master/SOURCE/KEYB/KEYB.PAS

Actually, with this commandline:

ppcross8086.exe -WmCompact -Wtexe -Sg  KEYB.PAS

I get less errors, so I prefer to stay in the default mode, and use conditional compilation directives for dual-compiling.

Notice somehow the error in line 2960. If I set:

   BIOSStorekey  := EfStoreKey0;

as it is default mode, I get this error as expected:

KEYB.PAS(2960,21) Error: Incompatible types: got "untyped" expected "<procedure variable type of procedure;Pascal>"

However, with this:

   BIOSStorekey  := @EfStoreKey0;

KEYB.PAS(2960,21) Error: Incompatible types: got "<address of procedure;far;Pascal>" expected "<procedure variable type of procedure;Pascal>"

Which in my understanding, shouldn't happen.

What is wrong there? How can I circumvent this error?

Thanks in advance,
Aitor








 

TinyPortal © 2005-2018