[Prev][Next][Index][Thread]

machine hacking



Hi,

I need to read a series of lonwords (32-bits) a byte at a time from a DSP
interface and hack these bytes into either longword integers or 32-bit
floats. I tried using an old Pascal trick of building a union type and
storing values into one field of the union, while reading out of another.
But I run into <integer> range limitations in FO Dylan.

Here's a simple example going the other way, storing a longword integer into
the struct and reading the bytes out (yes I realize this is machine endian
dependent, but it works well for me in Lisp).

define C-union <DOPPELGANGER>
  slot float-value :: <C-float>;
  slot long-value  :: <C-long>;
  array slot uchar-value  :: <C-unsigned-char>, length: 4;
  pointer-type-name: <DOPPELGANGER*>;
end C-union;

define method poke-word (buf :: <simple-vector>,
                         offset :: <integer>,
                         wrd :: <machine-word>)
                     => ()
  let off :: <integer> = 4 * offset;
  with-stack-structure (d :: <DOPPELGANGER*>)
    d.long-value := as(<integer>, wrd);
<--------------------------------------- trouble here!
    for(ix :: <integer> from 0 below 4)
      buf[off + ix] := uchar-value(d, ix);
    end;
  end;
end method;

define test () => ()
       let buf :: <simple-vector> = make(<simple-vector>, of: <byte>,
length: 4);
      poke-word(buf, 0, #xbadc0db4);
end method;

;;
The trouble arises because the value #xbadc0db4 can't be converted to
<integer> since integers are only 29 bits or so. And I have to coerce the
value to something acceptable to storing into a <c-long> value. Type
<abstract-integer> doesn't work here, since <c-long> still expects an
<integer>.

What to do? (Do I really need to dissassemble the bytes by hand using bit
shifting and masking?)

Thanks,

David McClain





Follow-Ups: