HP3000-L Archives

September 2001, Week 1

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Stan Sieler <[log in to unmask]>
Reply To:
Stan Sieler <[log in to unmask]>
Date:
Tue, 4 Sep 2001 18:04:07 -0700
Content-Type:
text/plain
Parts/Attachments:
text/plain (115 lines)
Re:
> yes. the manual has been revised. about 20 years ago :-).
>
> here's some of our sample code from almost that long ago:

oops:

>    47     PROCEDURE ZDBFIND(DBASE,DSET,MODE,STATUS,ITEM,ARGUMENT);
>    48     BYTE ARRAY DBASE;
>    49     INTEGER DSET;
>    50     INTEGER MODE;
>    51     INTEGER ARRAY STATUS;
>    52     INTEGER ITEM;
>    53     BYTE ARRAY ARGUMENT;
>    54     BEGIN
>    55       BYTE ARRAY ARGUMENT'(0:127);
>    56       ARRAY DB(*)=DBASE;
>    57       ARRAY ST(*)=STATUS;
>    58       ARRAY ARG(*)=ARGUMENT'(0);
>    59       INTRINSIC DBFIND;
>    60       MOVE ARGUMENT'(0):=ARGUMENT(0),(ARGUMENT(-1));
>    61       DBFIND(DB,DSET,MODE,ST,ITEM,ARG);
>    62     END;

The above has a classic problem, which will cause it to
not work correctly for large stacks.  (Remember, for SPL "large"
isn't very big by modern standards :)

The basic fix is:
   Never equate "word" arrays to byte arrays.

Why? because SPL emits an ASR (Arithmetic Shift Right)
instruction to convert the byte array's address into
a "word" address.  And, that's wrong if the byte array
is more than 32 KB above DB.  (Why?  Because positive byte
addresses in the range 32768..65535 "look" negative if you
look at the upper bit of their 16-bit values.)

If you're forced to have a byte address for "ZDBFIND" (as I
suspect you are), there are two correct approaches to fix
the problem:

   1) convert correctly:

      convert from byte to word address yourself, using LSR instead
      or ASR.  (Or, even better, by comparing the byte address
      to 0..(logical (S)*2) to see if it's positive, 0, or
      DB-negative, and then using LSR or ASR as appropriate)

and:

   2) avoid converting the input address:

      copy the data into correctly declared local byte/word array
      combo.

The following code fragment uses both techniques:

     procedure zdbfind (dbase', dset, mode, status, item, argument');
         ...
         begin

         logical array
            copy'argument (0 : 63);       ! 128 bytes

         logical pointer
            dbase;             ! will point to data in dbase'

         byte array
            copy'argument' (*) = copy'argument;


         move copy'argument := argument (0), (argument (-1));

            ! assuming dbase' is not a DB-negative address..
         @dbase := @dbase' & lsr (1);    ! convert byte->word address

         dbfind (dbase, ..., copy'argument);

   (you can see, BTW, that I use a suffix of "'" to indicate "byte",
    and a lack of it to indicate "non-byte")

   Note that for local variables, I also declare the word array first,
   and then equate the byte array to it.  This always generates
   the correct code, but the opposite doesn't, as this warning
   from SPL (for the original code) shows:

         00000 2     BYTE ARRAY ARGUMENT'(0:127);
         00000 2     ARRAY DB(*)=DBASE;
                                       ^
***** WARNING #001 *****  ARITHMETIC RIGHT SHIFT EMITTED

         00000 2     ARRAY ST(*)=STATUS;
         00000 2     ARRAY ARG(*)=ARGUMENT'(0);
                                               ^
***** WARNING #002 *****  ARITHMETIC RIGHT SHIFT EMITTED           SEE    10

One thing you almost never want to use in SPL:  $CONTROL NOWARN

I'd add two other things:

   1) check that dbase' address is not odd.  If it is, you'll
      have a problem.   (Or, document that you assume it's even
      (i.e., word aligned)

   2) check the value of argument' (-1), to make sure it's in the
      range 0..127 before using it as a move length.
      (Or, document the assumption)

Stan Sieler                                           [log in to unmask]
www.allegro.com/sieler/wanted/index.html          www.allegro.com/sieler

* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *

ATOM RSS1 RSS2