[futurebasic] Re: [FB] Sound Manager code

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : September 2001 : Group Archive : Group : All Groups

From: Robert Purves <robert.purves@...>
Date: Sat, 1 Sep 2001 15:05:28 +1200
>Along the way, I have found a strange thing, that I failed to
>explain to myself. I probably need an explanation à la Robert Purves
>once again. It is about the SndSoundManagerVersion Toolbox call
>which was in 68K assembly in the original file. I finally came up
>with the following to get a correct(?) result:
>
>TOOLBOX FN SndSoundManagerVersion() = LONG `0x203C, 0x000C, 0x0008, 0xA800
>
>BEGIN RECORD NumVersion
>  DIM majorRev       AS UNSIGNED CHAR
>  DIM minorAndBugRev AS UNSIGNED CHAR
>  DIM stage          AS UNSIGNED CHAR
>  DIM nonRelRev      AS UNSIGNED CHAR
>END RECORD
>
>LOCAL MODE
>LOCAL FN GetSMVersion$
>  DIM @ vers      AS LONG
>  DIM   version   AS NumVersion
>  DIM   SMVersion AS STR15
>
>  vers      = FN SndSoundManagerVersion
>  version   = vers
>  SMVersion = STR$(VAL&(HEX$( version.majorRev ))) ¬
>            + STR$(VAL&(HEX$( version.minorAndBugRev ))) ¬
>            + STR$(VAL&(HEX$( version.stage )))
>END FN = SMVersion
>
>// test
>PRINT FN GetSMVersion$
>
>I don't understand exactly why I have to store first the result of
>the call in a long int variable (that must be in RAM) then to copy
>the result in another variable.


SndSoundManagerVersion returns a 32-bit value, which later is to be
interpreted as four 1-byte fields in a record structure.  Owing to its weak
variable-typing, FB^3 does not complain if you attempt this the wrong way,
but you are liable to get an incorrect result or even a crash, by assigning
a register var to a record.

The right way is to define NumVersionVariant, as shown below, which allows
us to write the unambiguously correct statement:
  vers.whole = fn SndSoundManagerVersion

Then decoding the BCD information in vers.parts is far from straighforward.
I believe the decoding below, although incomplete, is accurate.
It would be an interesting challenge to decode 0x04214003 as "4.2.1a3",
which Apple claims is the correct interpretation.

Robert P.


'---Run in Console mode-------
// NumVersion  Packed BCD version representation
//  (e.g. "4.2.1a3" is 0x04214003)
begin record NumVersion
dim majorRev       as unsigned char
dim minorAndBugRev as unsigned char
dim stage          as unsigned char
dim nonRelRev      as unsigned char
end record

// NumVersionVariant is a wrapper so NumVersion
//  can be accessed as a 32-bit value
begin record NumVersionVariant
begin union
dim parts as NumVersion
dim whole as unsigned long
end union
end record

toolbox fn SndSoundManagerVersion = long `0x203C, 0x000C, 0x0008, 0xA800

local fn GetSndMGrVersion$
dim vers as NumVersionVariant
dim as str15  majorTens, majorUnits, minor, bugFix, SMVersion
vers.whole = fn SndSoundManagerVersion
// decode majorRev and minorAndBugRev fields:
majorTens  = str$( vers.parts.majorRev >> 4 )
if ( majorTens == " 0" ) then majorTens = ""
majorUnits = str$( vers.parts.majorRev and 15 )
minor      = str$( vers.parts.minorAndBugRev >> 4 )
bugFix     = str$( vers.parts.minorAndBugRev and 15 )
SMVersion  = right$( majorTens, 1 ) + right$( majorUnits, 1 ) ¬
 + "." + right$( minor, 1 ) ¬
 + "." + right$( bugFix, 1 )
end fn = SMVersion

// test
print fn GetSndMGrVersion$
'---------------------------