Path: utzoo!utgpu!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!ukma!psuvm.bitnet!cunyvm!ndsuvm1!ndsuvax!ncsmith
From: ncsmith@ndsuvax.UUCP (Timothy Smith)
Newsgroups: comp.lang.pascal
Subject: Re: Pointers in TP4
Keywords: operations on them
Message-ID: <1868@ndsuvax.UUCP>
Date: 30 Nov 88 08:38:40 GMT
References: <340@lafcol.UUCP> <230@prles2.UUCP>
Reply-To: ncsmith@ndsuvax.UUCP (Timothy Smith)
Organization: North Dakota State University, Fargo
Lines: 73


In article <230@prles2.UUCP> vanpelt@nvpna1.UUCP (bart van pelt) writes:
>
>To increment pointers in TP4, use a type cast as follows
>
>longint( Ptr ) := longint( Ptr ) + Increment;

This is incorrect and will lead to possible large troubles.  TP4
depends on the offset of the pointer to be in the range of 0 to 15.
If your offsets do not conform to this rule then the results of any
conditional check between pointers is suspect.  Example: 0:16 and
1:0 will both point to the same location but if you use a conditional
operator such as '=' to compare them the test will fail even though both
pointers point to the same location.

The following equation should, I havn't tested it, work if you
want to do everything in one line.  It will only work when incrementing
a pointer.

longint(P) := (longint(P) and $FFFF0000) +
              ((longint(P) + inc) and $FFF0) shl 16 +
              ((longint(P) + inc) and $F)

The method that I prefer is as follows:

    type
        foo = record
            O: word;  { offset }
            S: word   { segment }
            end;

    procedure IncPtr( var Ptr: pointer;
                      N: word );
        var
            T: foo;
        begin
        T := foo(Ptr);
        inc(T.S, N div 16);
        inc(T.O, N mod 16);
        if T.O>15 then
            begin
            inc(T.S, T.O div 16);
            T.O := T.O mod 16
            end;
        Ptr := pointer(T)
        end;

    procedure DecPtr( var Ptr: pointer;
                      N: word );
        var
            T: foo;
        begin
        T := foo(Ptr);
        dec(T.S, N div 16);
        N := N mod 16;
        if N>T.O then
            begin
            dec(T.S);
            T.O := T.O + 16 - N
            end
        else
            dec(T.O, N mod 16);
        Ptr := pointer(T)
        end;

    I know that these procedures work as I implemented a K&R style
memory managment system with them.

    The reference to the offset range for pointers is on page 244
of the TP4 manual.

--
Tim Smith     North Dakota State University,  Fargo, ND  58105
UUCP:         ...!uunet!ndsuvax!ncsmith | 90% of the people on this planet
BITNET:       ncsmith@ndsuvax.bitnet    | are crazy and the rest of us are
INTERNET:     ncsmith@plains.NoDak.edu  | in grave danger of contamination