TIP: Click on subject to list as thread! ANSI
echo: locsysop
to: Frank Malcolm
from: Bob Lawrence
date: 1994-12-06 07:43:24
subject: Blaise de Pascal

Hi Frank,
          I'm looking at pkt2qwk and the qwk format, and I've come up
against the .ndx files.

  These have a message pointer in BasicReal. It continues to amaze me
how stupid programmers can be. For a pointer with a maximum value of
4096 (for a 500Kb pkt), firstly, they use a 4-byte number when an
plain integer would have done nicely, and then they use a code they
call the BASIC MKS$ format. Loonies!

  To top it all, it isn't even BASIC MKS$. When I try MKS$ and its
friend CVS in VB, I get the wrong answer.

  The QWK spec has a program written in Pascal to do the conversion,
but it leaves me gasping, in particular $007FFFFF, $00800000, and $ff.
WTF does this mean? Are they hex numbers like 0x in C? Or octal? Or
what? My Pascal books don't mention it. My guess is that it is so
basic that they assume everyone knows it. Not me...

  Invalue shr 24 worries me too. That's a hell of a shift right.

  Here is the .ndx QWK spec and the Pascal program: 


                           Format of Index files

      Index files are named XXX.NDX (where XXX is the conference
      number padded with leading zeros to make it three characters
      long.  There is one *.NDX file for each conference chosen that
      contains messages in the MESSAGES.DAT file.

      The *.NDX file contain records five characters long that point
      to each message in that conference.


      NdxRecord = Record
        MsgPointer: BasicReal
        Conference: Byte;
        End;

      The BasicReal is a four byte number in BASIC MKS$ format.


      The following is a sample program unit for TurboPascal that
      converts between BasicReal format and LongInt format.

...        -------------------------------------------------

Unit BasicConvert;

Interface
  Function BasicReal2Long(InValue: LongInt): LongInt;
                {Convert Basic Short Reals to LongInts}

  Function Long2BasicReal(InValue: LongInt): LongInt;
                {Convert LongInts to Basic Short Reals}

Implementation

Function BasicReal2Long(InValue: LongInt): LongInt;

  Var
  Temp: LongInt;
  Negative: Boolean;
  Expon: Integer;

  Begin
    If InValue And $00800000  0 Then
      Negative := True
    Else
      Negative := False;
    Expon := InValue shr 24;
    Expon := Expon and $ff;
    Temp := InValue and $007FFFFF;
    Temp := Temp or $00800000;
    Expon := Expon - 152;
    If Expon < 0 Then Temp := Temp shr Abs(Expon)
      Else Temp := Temp shl Expon;
    If Negative Then
      BasicReal2Long := -Temp
    Else
      BasicReal2Long := Temp;
    If Expon = 0 Then
      BasicReal2Long := 0;
  End;


Function Long2BasicReal(InValue: LongInt): LongInt;
  Var
  Negative: Boolean;
  Expon: LongInt;

  Begin
  If InValue = 0 Then
    Long2BasicReal := 0
  Else
    Begin
    If InValue < 0 Then
      Begin
      Negative := True;
      InValue := Abs(InValue);
      End
    Else
      Negative := False;
    Expon := 152;
    If InValue < $007FFFFF Then
      While ((InValue and $00800000) = 0) Do
        Begin
        InValue := InValue shl 1;
        Dec(Expon);
        End
    Else
      While ((InValue And $FF000000)  0) Do
        Begin
        InValue := InValue shr 1;
        Inc(Expon);
        End;
    InValue := InValue And $007FFFFF;
    If Negative Then
      InValue := InValue Or $00800000;
    Long2BasicReal := InValue + (Expon shl 24);
    End;
  End;

End.

...         --------------------------------------------

A quick and dirty conversion (handles positive numbers only) is possible
with the following expression:

MKSToNum := ((x AND NOT $ff000000) OR $00800000)
             SHR (24 - ((x SHR 24) AND $7f));

...         ----------------------------------------------

      The number contained in the MsgPointer is the record number
      (128 byte records - starting numbering from record 1 not 0)
      of the message header.  Note that since the 1st record contains
      packet header, the lowest MsgPointer that can exist is 2.

      Some message readers will reformat the *.NDX files so that the
      MsgPointer becomes a LongInt fileseek position (using a record
      size of 1).  To determine which type of index you are reading
      you should look at the size of the number.  Any BasicReal will
      appear as a huge number that would unlikely ever be a byte
      seek positon.

___ Blue Wave/QWK v2.12
@EOT:

---
* Origin: Precision Nonsense, Sydney (3:711/934.12)
SEEN-BY: 711/934
@PATH: 711/934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.