[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: