The PBClone Windows Library --------------------------- Version 2.0 PBCwin Copyright (c) 1993-1994 Thomas G. Hanlin III This is PBCwin, a collection of tools in DLL format for Windows programming. It is written primarily with Visual Basic in mind, although much of it will work with any language that supports DLL libraries. The PBCwin collection is copyrighted and may be distributed only according to the following conditions: All PBCwin files must be distributed together as a unit. No files may be added or removed from PBCwin. No PBCwin file may be altered in any way. YOU USE THIS LIBRARY AT YOUR OWN RISK. I have tested it on my own computer, but I will not assume responsibility for any problems which PBCwin may cause you. It is expected that if you find PBCwin useful, you will register your copy. You may not use PBCwin routines in programs intended for distribution unless you have registered. See the ORDER.TXT file for more details. The PBCwin tools can be used with any language that supports DLL libraries. PBCwin is documented only for use with Visual Basic, however. In order to use the PBCWIN.DLL routines in a Visual Basic program, you must place the appropriate routine declarations in the globals section of the program. These declarations can be taken individually or en masse from the PBCWIN.BI text file. It is more efficient to use only the declarations you actually need, but that is up to you. You can use the PBCwinVer function to make sure that the installed version of PBCWIN.DLL is sufficiently current as to support the PBCwin routines required by your program. The PBCwin DLL routines are currently documented in the PBCWIN.TXT text file and in the PBCWIN.HLP online help. In order to use the online help, place PBCWIN.HLP in your VB directory. When you use VB, you can access the PBCwin help by selecting Help, then using the Help "File Open" option to open PBCWIN.HLP as the current help document. Name : BinI (Binary Integer) This function converts a binary value, passed to it as a string, to an integer. It stops the conversion on reaching the end of the string or at the first character that is not a valid binary digit ("0" or "1"). See also BinL, which returns a long integer value. Result% = BinI(St$) St$ binary number, in string form ------- Result% integer equivalent of binary number Name : BinL (Binary Long) This function converts a binary value, passed to it as a string, to a long integer. It stops the conversion on reaching the end of the string or at the first character that is not a valid binary digit ("0" or "1"). See also BinI, which returns an integer value. Result& = BinL(St$) St$ binary number, in string form ------- Result& long integer equivalent of binary number Name : Bytes2Int (Bytes to Integer) This function combines two bytes, contained in separate integers, into a single integer value. See also HiByte and LoByte, which may be used to reverse the process, splitting an integer into two bytes. Result% = Bytes2Int(Lo%, Hi%) Lo% low, or least significant, byte Hi% high, or most significant, byte ------- Result% result of combining bytes into an integer Name : Checksum (Checksum) This function calculates an 8-bit checksum for a string. The result is compatible with Xmodem and Ymodem file transfer protocols, and can be used as a fast and simple check of data validity. For more rigorous testing, see CRC16. Result% = Checksum(St$, Bytes%) St$ string for which to calculate checksum Bytes% number of characters for which to calculate checksum ------- Result% checksum of specified part of string Name : ComPorts (Comm Ports) This function returns the number of communications (serial) ports installed. Result% = ComPorts() ------- Result% comm ports (0-3) Name : CRC16 (CRC, 16-bit) This function calculates a 16-bit "cyclical redundancy check" checksum, or CRC, for a string. The result is compatible with Xmodem and Ymodem file transfer protocols, and can be used as a check of data validity. Note that the Xmodem and Ymodem file transfer protocols use a different byte ordering method than typical of Intel machines. If you intend to use this function in writing file transfer protocols, you will need to reverse the byte order to MSB first, LSB second. This can be accomplished with either LRotateI or RRotateI with a shift count of 8 (eight), or by splitting the integer into bytes with LoByte and HiByte, and swapping the results. Result% = CRC16(St$, Bytes%) St$ string for which to calculate CRC Bytes% number of characters for which to calculate CRC ------- Result% CRC of specified part of string Name : DateSq (Date Squeeze) This function compresses a date into a single integer. This provides a very efficient storage format for dates ranging from January 1, 1900 to December 31, 2028. Uncompression is done with DayUnsq, MonthUnsq, and YearUnsq. See also TimeSq, which allows you to compress a time value similarly. Note that compressed dates are not in a format that may be readily used for comparison or date math purposes. If you need such capabilities, convert the date to a BASIC time/date serial number first-- see your BASIC manual for details. If you pass a year of 0-99, it will be translated to 1900-1999 before the compression is done. Depending on your application, you may wish to assume 0-28 is the same as 2000-2028 instead. If so, make sure you do an explicit conversion before this function is called. Result% = DateSq(MonthNr%, DayNr%, YearNr%) MonthNr% month number (1-12) DayNr% day number (1-31) YearNr% year number (1900-2028) ------- Result% compressed date Name : DayUnsq (Day Unsqueeze) This function returns the day from a compressed date. It works in conjunction with the DateSq date compression function. DayNr% = DayUnsq(Number%) Number% compressed date ------- DayNr% day number Name : Floppies (Floppies) This function returns the number of floppy disk drives installed, up to two. Although it is possible to have up to four floppy drives, the PC was designed to expect a maximum of two, and this routine can't tell if there are more than that. Result% = Floppies() ------- Result% floppy drives (0-2) Name : GetComAddr (Get Comm Address) This function returns the I/O base port address for a specified communications (serial) port. If there is no such serial port, or if the port is in use, a zero will be returned. Address% = GetComAddr(PortNr%) PortNr% communications port number (0-3) ------- Address% I/O base port address for comm port Name : GetPrtAddr (Get Prt Address) This function returns the I/O base port address for a specified printer (parallel) port. If there is no such parallel port, a zero will be returned. Address% = GetPrtAddr(PortNr%) PortNr% printer port number (0-3) ------- Address% I/O base port address for printer port Name : GetTick (Get clock Tick) This function returns the current system time count. The count is the amount of time after midnight, in (approximately) 1/18th seconds. This can be used as a fairly high-resolution timer. DO NOT use this function to write a delay routine! That would eat precious system time that could be more profitably used by other programs while your program is idle-- remember, Windows is a multitasking environment. If you need a delay, use the SLEEP statement provided by BASIC. Result& = GetTick() ------- Result& system timer tick Name : HiByte (High Byte) This function returns the high, or most significant, byte of an integer. See also Bytes2Int, which can be used to reverse the process. Byte% = HiByte(Number%) Number% number from which to pick high byte ------- Byte% high byte of number Name : HiNybble (High Nybble) This function returns the high, or most significant, nybble of a byte. See also Nybs2Byte, which can be used to reverse the process. Nybble% = HiNybble(Number%) Number% byte from which to pick high nybble ------- Nybble% high nybble of byte Name : HiWord (High Word) This function returns the high, or most significant, word of a long integer. See also Ints2Long, which can be used to reverse the process. Word% = HiWord(Number&) Number& long integer from which to pick high word ------- Word% high word of long integer Name : HourUnsq (Hour Unsqueeze) This function returns the hour from a compressed time. It works in conjunction with the TimeSq time compression function. HourNr% = HourUnsq(Number%) Number% compressed time ------- HourNr% hour number Name : Ints2Long (Integers to Long) This function combines two integers into a single long integer value. See also HiWord and LoWord, which may be used to reverse the process, splitting a long integer into two integers. Result& = Ints2Long(Lo%, Hi%) Lo% low, or least significant, word Hi% high, or most significant, word ------- Result& result of combining integers into a long Name : IsAlNum (Is AlphaNumeric) This function tells you whether a character is alphanumeric, that is, either a letter of the alphabet or a digit. It operates on the first character of a string you pass it. Result% = IsAlNum(St$) St$ character to test ------- Result% whether char is alphanumeric (-1 yes, 0 no) Name : IsAlpha (Is Alphabetic) This function tells you whether a character is alphabetic. It operates on the first character of a string you pass it. Result% = IsAlpha(St$) St$ character to test ------- Result% whether char is alphabetic (-1 yes, 0 no) Name : IsASCII (Is ASCII) This function tells you whether a character is a member of the ASCII character set. It operates on the first character of a string you pass it. Result% = IsASCII(St$) St$ character to test ------- Result% whether char is ASCII (-1 yes, 0 no) Name : IsControl (Is Control) This function tells you whether a character is a control code. Control codes are considered to be ASCII 0-31 and 127. This function operates on the first character of a string you pass it. Result% = IsControl(St$) St$ character to test ------- Result% whether char is a control code (-1 yes, 0 no) Name : IsDigit (Is Digit) This function tells you whether a character is a digit. It operates on the first character of a string you pass it. Result% = IsDigit(St$) St$ character to test ------- Result% whether char is a digit (-1 yes, 0 no) Name : IsLower (Is Lowercase) This function tells you whether a character is a lowercase letter ("a" through "z"). It operates on the first character of a string you pass it. Result% = IsLower(St$) St$ character to test ------- Result% whether char is lowercase (-1 yes, 0 no) Name : IsPunct (Is Punctuation) This function tells you whether a character may be construed as punctuation. This includes the space and most symbols. This function operates on the first character of a string you pass it. Result% = IsPunct(St$) St$ character to test ------- Result% whether char is punctuation (-1 yes, 0 no) Name : IsSpace (Is Space) This function tells you whether a character is "white space" (ASCII 9-13 and 32, including tab, linefeed, formfeed, carriage return, and space). It operates on the first character of a string you pass it. Result% = IsSpace(St$) St$ character to test ------- Result% whether char is white space (-1 yes, 0 no) Name : IsUpper (Is Uppercase) This function tells you whether a character is an uppercase letter ("A" through "Z"). It operates on the first character of a string you pass it. Result% = IsUpper(St$) St$ character to test ------- Result% whether char is uppercase (-1 yes, 0 no) Name : IsXDigit (Is heX Digit) This function tells you whether a character is a hexadecimal digit. This includes 0-9, a-z, and A-Z. This function operates on the first character of a string you pass it. Result% = IsXDigit(St$) St$ character to test ------- Result% whether char is a hex digit (-1 yes, 0 no) Name : LoByte (Low Byte) This function returns the low, or least significant, byte of an integer. See also Bytes2Int, which can be used to reverse the process. Byte% = LoByte(Number%) Number% number from which to pick low byte ------- Byte% low byte of number Name : LoNybble (Low Nybble) This function returns the low, or least significant, nybble of a byte. See also Nybs2Byte, which can be used to reverse the process. Nybble% = LoNybble(Number%) Number% byte from which to pick low nybble ------- Nybble% low nybble of byte Name : LoWord (Low Word) This function returns the low, or least significant, word of a long integer. See also Ints2Long, which can be used to reverse the process. Word% = LoWord(Number&) Number& long integer from which to pick low word ------- Word% low word of long integer Name : LRotateI (Left Rotate Integer) This function returns the result of rotating an integer left by a specified number of bits. Result% = LRotateI(Number%, Count%) Number% number to rotate Count% number of bits by which to rotate ------- Result% rotated number Name : LRotateL (Left Rotate Long) This function returns the result of rotating a long integer left by a specified number of bits. Result& = LRotateL(Number&, Count%) Number& number to rotate Count% number of bits by which to rotate ------- Result& rotated number Name : LShiftI (Left Shift Integer) This function returns the result of shifting an integer left by a specified number of bits. Result% = LShiftI(Number%, Count%) Number% number to shift Count% number of bits by which to shift ------- Result% shifted number Name : LShiftL (Left Shift Long) This function returns the result of shifting a long integer left by a specified number of bits. Result& = LShiftL(Number&, Count%) Number& number to shift Count% number of bits by which to shift ------- Result& shifted number Name : MaxD (Maximum Double-precision) This function returns the larger of two double-precision numbers. Result# = MaxD(Nr1#, Nr2#) Nr1# first number Nr2# second number ------- Result# larger of the two numbers Name : MaxI (Maximum Integer) This function returns the larger of two integers. Result% = MaxI(Nr1%, Nr2%) Nr1% first number Nr2% second number ------- Result% larger of the two numbers Name : MaxL (Maximum Long) This function returns the larger of two long integers. Result& = MaxL(Nr1&, Nr2&) Nr1& first number Nr2& second number ------- Result& larger of the two numbers Name : MaxS (Maximum Single-precision) This function returns the larger of two single-precision numbers. Result! = MaxS(Nr1!, Nr2!) Nr1! first number Nr2! second number ------- Result! larger of the two numbers Name : MinD (Minimum Double-precision) This function returns the smaller of two double-precision numbers. Result# = MinD(Nr1#, Nr2#) Nr1# first number Nr2# second number ------- Result# smaller of the two numbers Name : MinI (Minimum Integer) This function returns the smaller of two integers. Result% = MinI(Nr1%, Nr2%) Nr1% first number Nr2% second number ------- Result% smaller of the two numbers Name : MinL (Minimum Long) This function returns the smaller of two long integers. Result& = MinL(Nr1&, Nr2&) Nr1& first number Nr2& second number ------- Result& smaller of the two numbers Name : MinS (Minimum Single-precision) This function returns the smaller of two single-precision numbers. Result! = MinS(Nr1!, Nr2!) Nr1! first number Nr2! second number ------- Result! smaller of the two numbers Name : MinuteUnsq (Minute Unsqueeze) This function returns the minute from a compressed time. It works in conjunction with the TimeSq time compression function. MinuteNr% = MinuteUnsq(Number%) Number% compressed time ------- MinuteNr% minute number Name : MonthUnsq (Month Unsqueeze) This function returns the month from a compressed date. It works in conjunction with the DateSq date compression function. MonthNr% = MonthUnsq(Number%) Number% compressed date ------- MonthNr% month number Name : Nybs2Byte (Nybbles to Byte) This function combines two nybbles into a single byte value. Since BASIC supports neither byte nor nybble data types, the values are all kept in integers. See also HiNybble and LoNybble, which may be used to reverse the process, splitting a byte into two nybbles. Result% = Nybs2Byte(Lo%, Hi%) Lo% low, or least significant, nybble Hi% high, or most significant, nybble ------- Result% result of combining nybbles into a byte Name : Odd (Odd) This function tells you whether an integer is an odd number. Result% = Odd(Number%) Number% number to test ------- Result% whether number is odd (-1 yes, 0 no) Name : OddL (Odd Long) This function tells you whether a long integer is an odd number. Result% = OddL(Number&) Number& number to test ------- Result% whether number is odd (-1 yes, 0 no) Name : PBCwinVer (PBCwin Version) This function returns the version of PBCwin available. You can use this to make sure the PBCWIN.DLL being used is sufficiently current to handle the routines you need. Don't check the exact version number, since it should be ok for the user to have a newer version of PBCwin than your program expects. Instead, make sure that the returned version number is greater than or equal to the version you expect. The version number is multiplied by 100 so it can be returned as an integer. For example, PBCwin v1.0 returns a result of 100 here. PBCwin v1.1 will return 110, and so on. Version% = PBCwinVer() ------- Version% PBCWIN.DLL version times 100 Name : PeekB (Peek Byte) This routine gets a byte from a specified memory location. The memory location is specified as a pointer, which is a combined segment and offset value. The VarPtr function can be used to get a pointer to a variable. If you want to create a pointer to an address for which you know the segment and offset, you can use the Ints2Long function to do so, by loading the segment into the high word and offset into the low word. Nr% = PeekB(Ptr&) Ptr& far pointer ------- Nr% byte retrieved from memory Name : PeekI (Peek Integer) This routine gets an integer from a specified memory location. The memory location is specified as a pointer, which is a combined segment and offset value. The VarPtr function can be used to get a pointer to a variable. If you want to create a pointer to an address for which you know the segment and offset, you can use the Ints2Long function to do so, by loading the segment into the high word and offset into the low word. Nr% = PeekI(Ptr&) Ptr& far pointer ------- Nr% integer retrieved from memory Name : PeekL (Peek Long) This routine gets a long integer from a specified memory location. The memory location is specified as a pointer, which is a combined segment and offset value. The VarPtr function can be used to get a pointer to a variable. If you want to create a pointer to an address for which you know the segment and offset, you can use the Ints2Long function to do so, by loading the segment into the high word and offset into the low word. Nr& = PeekL(Ptr&) Ptr& far pointer ------- Nr& long integer retrieved from memory Name : PokeB (Poke Byte) This routine pokes a byte into a specified memory location. The memory location is specified as a pointer, which is a combined segment and offset value. The VarPtr function can be used to get a pointer to a variable. If you want to create a pointer to an address for which you know the segment and offset, you can use the Ints2Long function to do so, by loading the segment into the high word and offset into the low word. PokeB Ptr&, Nr% Ptr& far pointer Nr% byte to place in memory at the pointer location ------- Name : PokeI (Poke Integer) This routine pokes an integer into a specified memory location. The memory location is specified as a pointer, which is a combined segment and offset value. The VarPtr function can be used to get a pointer to a variable. If you want to create a pointer to an address for which you know the segment and offset, you can use the Ints2Long function to do so, by loading the segment into the high word and offset into the low word. PokeI Ptr&, Nr% Ptr& far pointer Nr% integer to place in memory at the pointer location ------- Name : PokeL (Poke Long) This routine pokes a long integer into a specified memory location. The memory location is specified as a pointer, which is a combined segment and offset value. The VarPtr function can be used to get a pointer to a variable. If you want to create a pointer to an address for which you know the segment and offset, you can use the Ints2Long function to do so, by loading the segment into the high word and offset into the low word. PokeL Ptr&, Nr& Ptr& far pointer Nr% long integer to place in memory at the pointer posn ------- Name : Power2I (Power of 2, Integer) This function returns the result of raising 2 (two) to the specified power. It's much faster than using the floating-point raise-to-power operator in BASIC, and is especially handy for bit twiddling. Result% = Power2I(Power%) Power% power to which to raise two ------- Result% two to the specified power Name : Power2L (Power of 2, Long) This function returns the result of raising 2 (two) to the specified power. It's much faster than using the floating-point raise-to-power operator in BASIC, and is especially handy for bit twiddling. Result& = Power2L(Power%) Power% power to which to raise two ------- Result& two to the specified power Name : PrtPorts (Printer Ports) This function returns the number of printer (parallel) ports installed. Result% = PrtPorts() ------- Result% printer ports (0-3) Name : PtrMatD (Pointer Matrix Double-precision) This routine initializes each element of a double-precision array to an increasingly large value. The value starts at a specified beginning and is incremented by one for each subsequent element. PtrMatD VarPtr(Array#(FirstElem)), Elements%, InitValue# Array#(FirstElem) first element of array to initialize Elements% number of elements to initialize InitValue# value to which to init first array element ------- Array#(FirstElem thru FirstElem + Elements% - 1) initialized Name : PtrMatI (Pointer Matrix Integer) This routine initializes each element of an integer array to an increasingly large value. The value starts at a specified beginning and is incremented by one for each subsequent element. PtrMatI VarPtr(Array%(FirstElem)), Elements%, InitValue% Array%(FirstElem) first element of array to initialize Elements% number of elements to initialize InitValue% value to which to init first array element ------- Array%(FirstElem thru FirstElem + Elements% - 1) initialized Name : PtrMatL (Pointer Matrix Long) This routine initializes each element of a long integer array to an increasingly large value. The value starts at a specified beginning and is incremented by one for each subsequent element. PtrMatL VarPtr(Array&(FirstElem)), Elements%, InitValue& Array&(FirstElem) first element of array to initialize Elements% number of elements to initialize InitValue& value to which to init first array element ------- Array&(FirstElem thru FirstElem + Elements% - 1) initialized Name : PtrMatS (Pointer Matrix Single-precision) This routine initializes each element of a single-precision array to an increasingly large value. The value starts at a specified beginning and is incremented by one for each subsequent element. PtrMatS VarPtr(Array!(FirstElem)), Elements%, InitValue! Array!(FirstElem) first element of array to initialize Elements% number of elements to initialize InitValue! value to which to init first array element ------- Array!(FirstElem thru FirstElem + Elements% - 1) initialized Name : RRotateI (Right Rotate Integer) This function returns the result of rotating an integer right by a specified number of bits. Result% = RRotateI(Number%, Count%) Number% number to rotate Count% number of bits by which to rotate ------- Result% rotated number Name : RRotateL (Right Rotate Long) This function returns the result of rotating a long integer right by a specified number of bits. Result& = RRotateL(Number&, Count%) Number& number to rotate Count% number of bits by which to rotate ------- Result& rotated number Name : RShiftI (Right Shift Integer) This function returns the result of shifting an integer right by a specified number of bits. Result% = RShiftI(Number%, Count%) Number% number to shift Count% number of bits by which to shift ------- Result% shifted number Name : RShiftL (Right Shift Long) This function returns the result of shifting a long integer right by a specified number of bits. Result& = RShiftL(Number&, Count%) Number& number to shift Count% number of bits by which to shift ------- Result& shifted number Name : SecondUnsq (Second Unsqueeze) This function returns the second from a compressed time. It works in conjunction with the TimeSq time compression function. Note that the second value will always be even, due to the limited amount of information that can be squeezed into an integer. SecondNr% = SecondUnsq(Number%) Number% compressed time ------- SecondNr% second number Name : SetMatC (Set Matrix Currency) This routine initializes each element of a currency array to a specified value. SetMatC VarPtr(Array@(FirstElem)), Elements%, Value@ Array@(FirstElem) first element of array to initialize Elements% number of elements to initialize Value@ value to which to initialize array ------- Array@(FirstElem thru FirstElem + Elements% - 1) initialized Name : SetMatD (Set Matrix Double-precision) This routine initializes each element of a double-precision array to a specified value. SetMatD VarPtr(Array#(FirstElem)), Elements%, Value# Array#(FirstElem) first element of array to initialize Elements% number of elements to initialize Value# value to which to initialize array ------- Array#(FirstElem thru FirstElem + Elements% - 1) initialized Name : SetMatI (Set Matrix Integer) This routine initializes each element of an integer array to a specified value. SetMatI VarPtr(Array%(FirstElem)), Elements%, Value% Array%(FirstElem) first element of array to initialize Elements% number of elements to initialize Value% value to which to initialize array ------- Array%(FirstElem thru FirstElem + Elements% - 1) initialized Name : SetMatL (Set Matrix Long) This routine initializes each element of a long integer array to a specified value. SetMatL VarPtr(Array&(FirstElem)), Elements%, Value& Array&(FirstElem) first element of array to initialize Elements% number of elements to initialize Value& value to which to initialize array ------- Array&(FirstElem thru FirstElem + Elements% - 1) initialized Name : SetMatS (Set Matrix Single-precision) This routine initializes each element of a single-precision array to a specified value. SetMatS VarPtr(Array!(FirstElem)), Elements%, Value! Array!(FirstElem) first element of array to initialize Elements% number of elements to initialize Value! value to which to initialize array ------- Array!(FirstElem thru FirstElem + Elements% - 1) initialized Name : SwapC (Swap Currency) This routine swaps two currency values. SwapC Number1@, Number2@ Number1@ first number Number2@ second number ------- Number1@ former second number Number2@ former first number Name : SwapD (Swap Double-precision) This routine swaps two double-precision numbers. SwapD Number1#, Number2# Number1# first number Number2# second number ------- Number1# former second number Number2# former first number Name : SwapI (Swap Integer) This routine swaps two integers. SwapI Number1%, Number2% Number1% first number Number2% second number ------- Number1% former second number Number2% former first number Name : SwapL (Swap Long) This routine swaps two long integers. SwapL Number1&, Number2& Number1& first number Number2& second number ------- Number1& former second number Number2& former first number Name : SwapS (Swap Single-precision) This routine swaps two single-precision numbers. SwapS Number1!, Number2! Number1! first number Number2! second number ------- Number1! former second number Number2! former first number Name : TimeSq (Time Squeeze) This function compresses a time into a single integer. This provides a very efficient storage format. Note, however, that an integer is not quite large enough to store an exact time-- the seconds value, if odd, will be rounded down to the next closest even number. Uncompression is done with HourUnsq, MinuteUnsq, and SecondUnsq. See also DateSq, which allows you to compress a date value similarly. Note that compressed times are not in a format that may be readily used for comparison or time math purposes. If you need such capabilities, convert the time to a BASIC time/date serial number first-- see your BASIC manual for details. Result% = TimeSq(HourNr%, MinuteNr%, SecondNr%) HourNr% hour number (0-23) MinuteNr% minute number (0-59) SecondNr% second number (0-59; see note on truncation) ------- Result% compressed time Name : VarPtr (Variable Pointer) This function returns a far pointer to a variable. It works with any variable type except BASIC strings, which are stored in an unusual format. This function is required for passing arrays to the PBCwin routines which take arrays as parameters. It has not been tested with VB/Win 2.0 arrays, and is likely not to work with such arrays if they're over 64k bytes. Since BASIC arrays may move in memory, it is advised that you get the pointer to an array just before using it, to minimize the risk of accessing the wrong area of memory. This function can also be used to provide a pointer for use with the various Peek_ and Poke_ routines in PBCwin. Note that the PBCwin function, VarPtr, is not identical to the DOS BASIC function, VARPTR. It returns an absolute address consisting of both segment and offset, rather than merely an offset value. Ptr& = VarPtr(Vbl) Vbl variable for which to get a pointer ------- Ptr& far pointer to variable Name : YearUnsq (Year Unsqueeze) This function returns the year from a compressed date. It works in conjunction with the DateSq date compression function. YearNr% = YearUnsq(Number%) Number% compressed date ------- YearNr% year number