MakeWord in C++ to PB

Just starting out? Need help? Post your questions and find answers here.
oliv
User
User
Posts: 42
Joined: Sun Aug 24, 2003 10:11 am
Location: France

MakeWord in C++ to PB

Post 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
HASO
User
User
Posts: 14
Joined: Tue Jun 10, 2003 12:29 am
Location: Netherlands

Post 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.
oliv
User
User
Posts: 42
Joined: Sun Aug 24, 2003 10:11 am
Location: France

Post by oliv »

8O 8O 8O
GOOD, i have read this but I haven't think it's i want THANKS
User avatar
Inner
PureBasic Expert
PureBasic Expert
Posts: 714
Joined: Fri Apr 25, 2003 4:47 pm
Location: New Zealand

Post 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.
HASO
User
User
Posts: 14
Joined: Tue Jun 10, 2003 12:29 am
Location: Netherlands

Post 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.
User avatar
Inner
PureBasic Expert
PureBasic Expert
Posts: 714
Joined: Fri Apr 25, 2003 4:47 pm
Location: New Zealand

Post by Inner »

haso: show me your function, so I can compare the 2 of them please.
HASO
User
User
Posts: 14
Joined: Tue Jun 10, 2003 12:29 am
Location: Netherlands

Post 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
User avatar
Inner
PureBasic Expert
PureBasic Expert
Posts: 714
Joined: Fri Apr 25, 2003 4:47 pm
Location: New Zealand

Post 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.
HASO
User
User
Posts: 14
Joined: Tue Jun 10, 2003 12:29 am
Location: Netherlands

Post 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.
User avatar
Inner
PureBasic Expert
PureBasic Expert
Posts: 714
Joined: Fri Apr 25, 2003 4:47 pm
Location: New Zealand

Post 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.
oliv
User
User
Posts: 42
Joined: Sun Aug 24, 2003 10:11 am
Location: France

Post by oliv »

Thanks for your answers. The Haso answer works perfectly :D :D :D :D
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post 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 :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
Inner
PureBasic Expert
PureBasic Expert
Posts: 714
Joined: Fri Apr 25, 2003 4:47 pm
Location: New Zealand

Post by Inner »

thanks HASO for the detailed explinations. ;)
HASO
User
User
Posts: 14
Joined: Tue Jun 10, 2003 12:29 am
Location: Netherlands

Post 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.
Post Reply