Page 1 of 1

MakeWord in C++ to PB

Posted: Fri Jan 30, 2004 5:09 pm
by oliv
Anyone can help me for convert MakeWord macro for Pb ? Or I just want the result of

Code: Select all

MakeWord(2,2)
Thanks

Posted: Fri Jan 30, 2004 5:38 pm
by HASO
Oliv,

From C++ windef.h:

Code: Select all

MAKEWORD(a, b) ((WORD)(((BYTE)((DWORD_PTR)(a) & 0xff)) | WORD)((BYTE)((DWORD_PTR)(b) & 0xff))) << 8))
This means: result = (b & 255) * 256 + (a & 255)
In your example: 2 * 256 + 2 = 514

Hope this helps,
Hans.

Posted: Fri Jan 30, 2004 7:10 pm
by oliv
8O 8O 8O
GOOD, i have read this but I haven't think it's i want THANKS

Posted: Fri Jan 30, 2004 11:17 pm
by Inner
actually that's not quite right;

this should work thou..

Code: Select all

Procedure.w MakeWord(a.b,b.b)

    c.w=(b & $ff)|((a & $ff)<<8)

    ProcedureReturn c
EndProcedure

Debug(Hex(MakeWord(1,1)))
side note: this isn't a C++ thing, it's C/C++/C# thing, and it's a macro.

Posted: Sat Jan 31, 2004 4:39 am
by HASO
Inner,

Actually that is not quite quite right.

Quoted from some deleted web page (found with GOOGLE): WinDoc/msdn/sdk/platforms/doc/sdk/win32/mac/src
The MAKEWORD macro creates an unsigned 16-bit integer by concatenating two given unsigned character values.

WORD MAKEWORD(
BYTE bLow, // low-order byte of short value
BYTE bHigh // high-order byte of short value
);

Parameters
bLow Specifies the low-order byte of the new short value.
bHigh Specifies the high-order byte of the new short value.

Return Values:
The return value is an unsigned 16-bit integer value.

Remarks
The MAKEWORD macro is defined as follows:

#define MAKEWORD(a, b) \

((WORD) (((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8))
The current definition is a little more elaborated, but the meaning is still the same.

So in human terms: take the value of the first (low byte) parameter and OR the value of the second (high byte) parameter * 256

Note: Adding parms was wrong, must use OR instead. Thanks.

Side side note: From c++ windef.h just means that I have quoted this particular definition. It does NOT mean it is not defined millions of times in other places...

Special note: as usual the MS documentation is completely unclear what in the macro definition is meant by (a,b). All the examples I have been able to find VERY carefully use MAKEWORD(2,2)...

Hope I have been a little clearer now.
Hans.

Posted: Sat Jan 31, 2004 7:42 am
by Inner
haso: show me your function, so I can compare the 2 of them please.

Posted: Sat Jan 31, 2004 1:56 pm
by HASO
Inner,

Your function:

Code: Select all

Procedure.w MakeWord(a.b,b.b) 

    c.w=(b & $ff)|((a & $ff)<<8) 

    ProcedureReturn c 
EndProcedure 

Debug(Hex(MakeWord(1,2))) 
My function:

Code: Select all

Procedure.w MakeWord(a.b,b.b) 

    c.w=(a & $ff)|((b & $ff)<<8) 

    ProcedureReturn c 
EndProcedure 

Debug(Hex(MakeWord(1,2))) 
The difference between these two is line c.w=...
I have also changed the debug call. With identical parameters it is impossible to see if the function works as expected.

Hope this helps, :)
Hans

Posted: Sat Jan 31, 2004 2:52 pm
by Inner
okay, the reason I switch a<>b around was this;

MAKEWORD(1,9)

Code: Select all

c.w=(a & $ff)|((b & $ff)<<8)=0901 
* Which isn't what we want here, when I use MAKEWORD() it's normally in conduction with a WSAStartup(), which requires a requested version for winsock, in this case I would be requesting v9.1 this doesn't exist at all.

Code: Select all

c.w=(b & $ff)|((a & $ff)<<8)=0109 
* Which does exist because we're requesting version v1.9, there is defintant importants in how those bytes are ordered, as you can imagine asking for winsock v9.1 would be insane.

However that is the reason why I switched the a & b around.

Posted: Sat Jan 31, 2004 3:42 pm
by HASO
Inner,

I completely agree with you that your method makes sense in human readability. However, it is NOT the MAKEWORD implementation of MSDN.

I've run a few tests with TurboC++ and the PSDK definition of MAKEWORD.
Result: MAKEWORD (1,2) returns &0201 and MAKEWORD(2,1) returns &0102

This seems to be wrong, until you consider the way an integer is stored in memory: first low byte, then high byte.
That way high and low are reversed again...

So, if you store a string "version " in memory and after that store result as word, the result from MAKEWORD (1,2) reads: version &1&2.

I know this looks completely insane, but this is the way MS has defined it in their unmeasurable wisdom.

p.s.
I have made a quick search for MAKEWORD on internet. It seems there are MakeWord (not MAKEWORD) versions that work the way you coded it.
I guess the confusion is now complete :!: :?: :!:

Hans.

Posted: Sat Jan 31, 2004 5:14 pm
by Inner
Utterly, now I'll have to change mine :x .. but it does make sence I don't think that it is a M$ thing now that futher light has been shed, it's to do with little iden vs big iden, which is actually I suppose, a pc hardware thing, this of course is utterly stuppid, and it's not suprising I coded it that way, since my roots are from Amiga days, where you put $1122 into memory and it went to memory as $1122 and stayed there as $1122, and you read it back as $1122.. however it seams that the pc likes to fondel your bytes, and turn it into $2211 .. only _GOD_ knows why they ever felt that this was a better way.

Posted: Sat Jan 31, 2004 7:16 pm
by oliv
Thanks for your answers. The Haso answer works perfectly :D :D :D :D

Posted: Sat Jan 31, 2004 7:56 pm
by blueznl
inner, call me what you like :-) but there were actually some reasons...

memory (4 bytes): lo hi higher highest

you can read the same var in four different ways from the same location

as a byte
as a word
as a doubleword

... while the mem location stays the same

all the registers inside the cpu are built in the same way, indexed adressing modes (what the hell they are called on an intel anyway) can access the registers all starting 'from the same base', this was deemed an advantage by intel in the early days (8080 / 8086)

another way to look at it, is to put the lsb IN FRONT, so memory would look like 0 1 2 4 8 16 32 64 128 256 etc. etc. in which case it makes perfect sense, that it's not that way on the hardware side (ie. D0 to D7 are not D7 to D0 on the databus) is... intel? :-)

again, it's an arbitrary choice, and *i* don't like it much either, but then again i started with a 6502 so i shouldn't complain at all i guess...

there might be other / more compelling reasons, but this is the little i know :-)

Posted: Sat Jan 31, 2004 11:41 pm
by Inner
thanks HASO for the detailed explinations. ;)

Posted: Sun Feb 01, 2004 4:43 pm
by HASO
Inner,

You're welcome!

Blueznl wrote:
you can read the same var in four different ways from the same location

as a byte
as a word
as a doubleword
Whatever happened to method 4 :?:
Maybe as a book...

Hans.