home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rxrtctrl.zip
/
RXRTCTRL.INF
(
.txt
)
< prev
Wrap
OS/2 Help File
|
1998-12-21
|
40KB
|
1,289 lines
ΓòÉΓòÉΓòÉ 1. Description ΓòÉΓòÉΓòÉ
rxRTCtrl ver. 2.0 - is a REXX-callable DLL providing access to the AIMS
RadioTrack FM radio card for OS/2 Warp 3 and later REXX programs. RxRTCtrl is
copyrighted freeware by N. Morrow and A. Schwarz.
ΓòÉΓòÉΓòÉ 2. Introduction ΓòÉΓòÉΓòÉ
RxRTCtrl.DLL allows access to the AIMS RadioTrack FM radio card through a set
of APIs. A sample REXX script is included to show how the card is controlled.
You can modify this script to your own liking or you can use a visual REXX
application generator like Vispro/REXX and create a cool-looking radio program
of your own. If you do, return the favor and consider making it available to
the OS/2 community as freeware or shareware.
RxRTCtrl.DLL is a REXX-callable DLL and I'm quite sure C/C++ can access the
functions too, so you could create a cool-looking C/C++ radio program with skin
capabilities (user changeable look), scanning for stations, preset stations,
clock functions, you name it. RxRTCtrl.DLL may be distributed royalty free with
your programs.
To use this DLL, you need the inexpensive AIMS RadioTrack FM radio card widely
available at computer stores or at www.aimslab.com. There are two versions of
this card. The older model has a built-in amplifier and connects directly to a
set of speakers. This card also has a programmable volume setting supported by
the rxRTCtrl API. The newer card does not have an amplifier or volume setting
and must be connected to your sound cards Line-In connector. Currently, the
rxRTCtrl API does not have a volume setting for this new card. You must use
your own mixer that supports your sound card to set the volume of the Line-In
connector. If all goes well, future upgrades to this DLL will include an API to
set the volume for most sound cards supported by OS/2.
Because the older and newer RadioTrack cards have a different command protocol,
rxRTCtrl distinguishes between them by using the letters RT2 in the function
call. For example, RT1Freq is used to set the frequency for the older card,
RT2Freq will set the frequency for the newer cards.
You need to know that rxRTCtrl uses TESTCFG.SYS, a generic device driver
standard to every OS/2 Warp 3.0 and 4.0 system. Installing and using rxRTCtrl
does in most cases not require to reboot the computer as TESTCFG.SYS is
installed by default on every Warp system.
If you have any suggestions about rxRTCtrl, please let us know.
ΓòÉΓòÉΓòÉ 3. Performance Considerations ΓòÉΓòÉΓòÉ
Bit Manipulation Functions:
Note: The bit manipulation functions are not needed for radio card
manipulation. They are only included for convenience.
Using the supplied bit manipulation functions makes it convenient to do bit
operations in REXX and from looking at the code below, it appears that it will
execute much faster as well. Not so. The call to the DLL puts quite an overhead
on to the program and can take up to 20 times longer than using several of the
built-in REXX functions to do the same operation. The native REXX function
example below will execute much faster than the call to rxRTCtrl using
RTBitClear. Both samples achieve the same result.
/* Native REXX Functions D2C and BITAND - MUCH FASTER */
BitVal = D2C('255')
BitResult = BITAND(BitVal, '1'x)
/* Call to rxRTCtrl - SLOWER */
BitVal = '255'
BitResult = RTBitClear(BitVal, '0')
If your program executes the bit manipulation routines many times in a loop,
you may consider using native REXX functions to perform this operation.
Time Delay RTDelay:
The RTDelay function is included for convenience and provides delays for a
fraction of a second, something the SysSleep function of REXXUTIL.DLL is not
able to do. If you are using Vispro/REXX to write your program, I suggest to
use the Timer events of these programs whenever possible. This will make your
programs more responsive, especially if time delays are fairly long. RTDelay
will essentially wait for the delay to time-out and your program will not
respond during that time. Using the Timer events of the visual REXX programs
will consume less CPU cycles and it will allow you to terminate the delay
through a dedicated button for example.
ΓòÉΓòÉΓòÉ 4. rxRTCtrl Function Description ΓòÉΓòÉΓòÉ
Describes all functions available in rxRTCtrl.DLL and how to use them.
RTLoadFuncs
RTDropFuncs
RTRead
RTWrite
RTDelay
RTBitPick
RTBitSet
RTBitClear
RT1VolUp
RT1VolDn
RT1On
RT1Off
RT1Tuned
RT1Freq
RT2Freq
RT2On
RT2Off
RT2Tuned
RT2Present
RTIniOpen
RTIniClose
RTDLLVersion
ΓòÉΓòÉΓòÉ 4.1. RTLoadFuncs ΓòÉΓòÉΓòÉ
This function loads rxRTCtrl.DLL to be used within your REXX program. A REXX
program using rxRTCtrl must contain the following two lines to access other
functions inside rxRTCtrl:
CALL RXFuncAdd 'RTLoadFuncs', 'RXRTCTRL', 'RTLoadFuncs'
CALL RTLoadFuncs
Standard REXX errors are returned for this function, for example: Error 43 -
Routine not found if rxRTCtrl.DLL can't be found.
This function also opens TESTCFG.SYS for read and write access. No errors are
returned by this function if opening TESTCFG.SYS fails. For errors returned see
each of the other functions.
ΓòÉΓòÉΓòÉ 4.2. RTDropFuncs ΓòÉΓòÉΓòÉ
This function drops rxRTCtrl.DLL from your REXX program and also closes access
to TESTCFG.SYS. Use it in your REXX program as shown below.
CALL RTDropFuncs
ΓòÉΓòÉΓòÉ 4.3. RTRead ΓòÉΓòÉΓòÉ
Note: This function is not required to control the RadioTrack cards and is only
included for completeness.
This function reads port_Address and returns the data in return_data. The
function format is as follows:
return_data = RTRead( port_Address )
The value of port_Address must be a decimal number in the range of 256 to 65535
which corresponds to the I/O range of the IBM Personal Computer.
If the RTRead was successful, the return_data contains the following string:
Addr: xxx Data: yyy
where xxx is the port_Address and yyy is the data of the port read. All values
are in decimal form. The range of the data read is 0 to 255.
If the RTRead was unsuccessful, the following errors are returned:
Addr: xx Data: yy
xx = 10 TESTCFG.SYS could not be opened during RTLoadFuncs.
yy = rc Return code of DOSOpen.
xx = 11 Unsuccessful read.
yy = rc Return code of DosDevIOCtl.
For error codes of DosOpen and DosDevIOCtl see the section on Error Codes.
Examples:
The code below reads the port at location 768 (300 hex) and results in the
following output:
port_Address = X2D('300')
return_data = RTRead( port_Address )
SAY 'Data read is ' || return_data
Output:
Data read is Addr: 768 Data: 255
The code below reads the port at location 888 (378 hex) which is reserved for
LPT1 and tied up by PRINT01.SYS. It results in the following read error output:
port_Address = X2D('378')
return_data = RTRead( port_Address )
SAY 'Data read is ' || return_data
Output:
Data read is Addr: 11 Data: 19
The error (19) given here is not listed under the return codes of DosDevIOCtl
of the Control Programming documentation. Error 19 is listed as
ERROR_WRITE_PROTECT under the disk access functions. Go figure.
The port_Address range is not directly checked by this function, however,
TESTCFG.SYS does not allow to read or write to ranges below 256 (100 hex) as
these contain critical system parameters. Also, it does not allow to read or
write to ports that are controlled by other drivers, like the printer (LPT1) or
serial ports (COM1, COM2).
ΓòÉΓòÉΓòÉ 4.4. RTWrite ΓòÉΓòÉΓòÉ
Note: This function is not required to control the RadioTrack cards and is only
included for completeness.
If you find that RTWrite is not working in a Vispro/REXX program, please read
the section Important Notes for details.
This function writes data_Value to port_Address. The function format is as
follows:
return_data = RTWrite( port_Address, data_Value )
The value of port_Address must be a decimal number in the range of 256 to 65535
which corresponds to the I/O range of the IBM Personal Computer. The value of
data_Value must be in decimal and have a range of 0 to 255.
If the RTWrite was successful, the return_data contains the following string:
Addr: xxx Data: yyy
where xxx is the port_Address and yyy is the data just written to the port. All
values are in decimal form.
If the RTWrite was unsuccessful, the following errors are returned:
Addr: xx Data: yy
xx = 10 TESTCFG.SYS could not be opened during RTLoadFuncs.
yy = rc Return code of DOSOpen.
xx = 12 Unsuccessful write.
yy = rc Return code of DosDevIOCtl.
For error codes of DosOpen and DosDevIOCtl see the section on Error Codes.
Example:
The code below writes to the port at location 768 (300 hex) and results in the
following output:
port_Address = X2D('300')
data_Value = 255
return_data = RTWrite( port_Address, data_Value )
SAY 'Data written is ' || return_data
Output:
Data written is Addr: 768 Data: 255
The port_Address range is not directly checked by this function, however,
TESTCFG.SYS does not allow to read or write to ranges below 256 (100 hex) as
these contain critical system parameters. Also, it does not allow to read or
write to ports that are controlled by other drivers, like the printer (LPT1) or
serial ports (COM1, COM2).
ΓòÉΓòÉΓòÉ 4.5. RTDelay ΓòÉΓòÉΓòÉ
This function provides time delay services to your REXX application. It does
not read or write to any I/O. REXX provides time delay in one second increments
only with the function SysSleep in REXXUTIL.DLL. The RTDelay function provides
time delay in the range of 1 to 1000 milliseconds and is useful if some I/O
hardware needs this short delay for proper operation. Note: This time delay is
rounded up to the next system clock tick and is therefore not accurate to the
millisecond. The format of the function is:
return_data = RTDelay( delay_value )
The delay_value is in the range of 1 to 1000 milliseconds. Any value outside
this range will cause an error.
return_data returns the following values:
0 No errors.
1 Invalid time delay range.
322 ERROR_TS_WAKEUP (Error given by DosSleep API function).
Example:
The code below illustrates the time delay function and shows how to verify the
delay using the REXX function TIME(). Note that TIME() has a resolution of only
10 milliseconds.
delay_value = 500
SAY 'Start delay of ' || delay_value || ' msec...'
verify_delay = TIME('R')
return_data = RTDelay( delay_value )
verify_delay = TIME('E')
SAY "... End Delay. rc = " || return_data
SAY 'elapsed time = ' || verify_delay
Output:
Start delay of 500 msec...
┬╖┬╖┬╖ End Delay. rc = 0
elapsed time = 0.520000
ΓòÉΓòÉΓòÉ 4.6. RTBitPick ΓòÉΓòÉΓòÉ
This function provides an easy way to pick a certain bit from a value. It does
not access any I/O, but rather provides a much easier way to pick a bit than
standard REXX functions do. The format of the function is:
return_bit_value = RTBitPick( value, bit_position )
The value is in decimal with a range of 0 to 65535.
bit_position is the position of the bit which value is to be extracted. The
right-most position (and therefore the least significant bit) is 0, the
left-most (or most significant bit) position is 15.
return_bit_value is the value returned and can only be 0 or 1.
There is no variable range checking, so you must insure that the right values
are passed along in the function.
Example:
The code below illustrates the RTBitPick function.
SAY 'The bit position 0 of the value 254 is ' || RTBitPick( '254', '0' )
SAY 'The bit position 1 of the value 254 is ' || RTBitPick( '254', '1' )
Output:
The bit position 0 of the value 254 is 0
The bit position 1 of the value 254 is 1
ΓòÉΓòÉΓòÉ 4.7. RTBitSet ΓòÉΓòÉΓòÉ
This function provides an easy way to set a certain bit in a value. It does not
access any I/O, but rather provides a much easier way to set a bit than
standard REXX functions do. The format of the function is:
return_value = RTBitSet( value, bit_position )
The value is in decimal with a range of 0 to 65535.
bit_position is the position of the bit which value is to be set. The
right-most position (and therefore the least significant bit) is 0, the
left-most (or most significant bit) position is 15.
return_value is the value returned after the bit has been set. Range is 1 to
65535.
There is no variable range checking, so you must insure that the right values
are passed along in the function.
Example:
The code below illustrates the RTBitSet function.
SAY 'Setting bit position 0 of the value 254 results in ' || RTBitSet( '254', '0' )
SAY 'Setting bit position 1 of the value 0 results in ' || RTBitSet( '0', '1' )
Output:
Setting bit position 0 of the value 254 results in 255
Setting bit position 1 of the value 0 results in 2
ΓòÉΓòÉΓòÉ 4.8. RTBitClear ΓòÉΓòÉΓòÉ
This function provides an easy way to clear a certain bit in a value. It does
not access any I/O, but rather provides a much easier way to clear a bit than
standard REXX functions do. The format of the function is:
return_value = RTBitClear( value, bit_position )
The value is in decimal with a range of 0 to 65535.
bit_position is the position of the bit which value is to be cleared. The
right-most position (and therefore the least significant bit) is 0, the
left-most (or most significant bit) position is 15.
return_value is the value returned after the bit has been cleared. Range is 0
to 65535.
There is no variable range checking, so you must insure that the right values
are passed along in the function.
Example:
The code below illustrates the RTBitClear function.
SAY 'Clearing bit position 0 of the value 255 results in ' || RTBitClear( '255', '0' )
SAY 'Clearing bit position 1 of the value 65535 results in ' || RTBitClear( '65535', '1' )
Output:
Clearing bit position 0 of the value 255 results in 254
Clearing bit position 1 of the value 65535 results in 65533
ΓòÉΓòÉΓòÉ 4.9. RT1VolUp ΓòÉΓòÉΓòÉ
For older style RadioTrack cards only.
This function increases the volume on the old-style RadioTrack cards with a
speaker output jack. This card has 16 discrete volume levels. You must keep
track of the volume setting in your own program. To establish a known level at
initial program start, you can decrease the volume 16 times and then increase
it to a preset level. The format of the function is:
return_data = RT1VolUp( rt_address )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
return_data returns the following values:
0 No errors.
1 Volume can't be set.
10 TESTCFG.SYS could not be opened.
ΓòÉΓòÉΓòÉ 4.10. RT1VolDn ΓòÉΓòÉΓòÉ
For older style RadioTrack cards only.
This function decreases the volume on the old-style RadioTrack cards with a
speaker output jack. This card has 16 discrete volume levels. You must keep
track of the volume setting in your own program. To establish a known level at
initial program start, you can decrease the volume 16 times and then increase
it to a preset level. The format of the function is:
return_data = RT1VolDn( rt_address )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
return_data returns the following values:
0 No errors.
1 Volume can't be set.
10 TESTCFG.SYS could not be opened.
ΓòÉΓòÉΓòÉ 4.11. RT1On ΓòÉΓòÉΓòÉ
For older style RadioTrack cards only.
This function turns on the old-style RadioTrack cards. The format of the
function is:
return_data = RT1On( rt_address )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
return_data returns the following values:
0 No errors.
1 Radio card can't be turned on.
10 TESTCFG.SYS could not be opened.
ΓòÉΓòÉΓòÉ 4.12. RT1Off ΓòÉΓòÉΓòÉ
For older style RadioTrack cards only.
This function turns off the old-style RadioTrack cards. The format of the
function is:
return_data = RT1Off( rt_address )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
return_data returns the following values:
0 No errors.
1 Radio card can't be turned off.
10 TESTCFG.SYS could not be opened.
ΓòÉΓòÉΓòÉ 4.13. RT1Tuned ΓòÉΓòÉΓòÉ
For older style RadioTrack cards only.
This function checks if the old-style RadioTrack card is tuned to a station. It
can be used to check for a valid station when doing station scans. The format
of the function is:
return_data = RT1Tuned( rt_address, delay1, delay2 )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
The delay1 and delay2 deal with getting the tuned status from the radio card.
Depending on your system and/or programming language used, these values may be
variable. Use delay1 = 150 and delay2 = 100 to try for starters. The units of
the delays are in milliseconds and they may not be less than 1 or greater than
1000. The same rules for these delays apply as the RTDelay function of this
library.
return_data returns the following values:
0 No station tuned.
1 Station tuned.
10 TESTCFG.SYS could not be opened.
11 Invalid time delay range.
28 Error reading radio card.
ΓòÉΓòÉΓòÉ 4.14. RT1Freq ΓòÉΓòÉΓòÉ
For older style RadioTrack cards only.
This function tunes the old-style RadioTrack cards to the given frequency. The
format of the function is:
return_data = RT1Freq( rt_address, freq, fine_tune )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
freq is the frequency in MHz x 10. Tuning to 90.1MHz would mean freq must be
set to the decimal integer 901. Note: Valid frequency range is 87.0MHz to
109.0MHz. No range check is performed in rxRTCtrl.DLL.
fine_tune allows to fine tune the set frequency freq in steps of 0.025MHz.
fine_tune has possible values of 0, 1, 2, 3, 4, -1, -2, -3 and -4. A value of 0
means there is no fine tuning requested and the set frequency would be as given
by freq. A value of 1 would add 0.025 MHz to freq before the frequency is
actually set in the card. A value of -1 would subtract 0.025 MHz from freq
before the frequency is actually set in the card. Similarly, 2 corresponds to
adding/subtracting 0.05MHz, 3 to 0.075MHz and 4 to 0.1MHz. There is not value
check of the fine_tune parameter, so you must assure it stays within the range
given.
return_data returns the following values:
0 No errors.
1 Frequency can't be tuned.
10 TESTCFG.SYS could not be opened.
Note: Scanning for stations can be implemented by setting the frequency to a
certain value then wait for a few seconds, increment to the next frequency and
so on. When a station is found, you can either use the function RT2Tuned (newer
RadioTrack only) or provide a way to manually stop scanning.
ΓòÉΓòÉΓòÉ 4.15. RT2Freq ΓòÉΓòÉΓòÉ
For newer style RadioTrack cards only.
This function tunes the new-style RadioTrack cards to the given frequency. The
format of the function is:
return_data = RT2Freq( rt_address, freq, fine_tune )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
freq is the frequency in MHz x 10. Tuning to 90.1MHz would mean freq must be
set to the decimal integer 901. Note: Valid frequency range is 87.0MHz to
109.0MHz. No range check is performed in rxRTCtrl.DLL.
fine_tune allows to fine tune the set frequency freq in steps of 0.025MHz.
fine_tune has possible values of 0, 2, 4, 6, 8, -2, -4, -6 and -8. A value of 0
means there is no fine tuning requested and the set frequency would be as given
by freq. A value of 2 would add 0.025 MHz to freq before the frequency is
actually set in the card. A value of -2 would subtract 0.025 MHz from freq
before the frequency is actually set in the card. Similarly, 4 corresponds to
adding/subtracting 0.05MHz, 6 to 0.075MHz and 8 to 0.1MHz. There is not value
check of the fine_tune parameter, so you must assure it stays within the range
given.
return_data returns the following values:
0 No errors.
1 Frequency can't be tuned.
10 TESTCFG.SYS could not be opened.
Note: Scanning for stations can be implemented by setting the frequency to a
certain value then wait for a few seconds, increment to the next frequency and
so on. When a station is found, you can either use the function RT2Tuned (newer
RadioTrack only) or provide a way to manually stop scanning.
ΓòÉΓòÉΓòÉ 4.16. RT2On ΓòÉΓòÉΓòÉ
For newer style RadioTrack cards only.
This function turns on the new-style RadioTrack cards. This function can also
be used to unmute the radio. The format of the function is:
return_data = RT2On( rt_address )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
return_data returns the following values:
0 No errors.
1 Radio card can't be turned on.
10 TESTCFG.SYS could not be opened.
ΓòÉΓòÉΓòÉ 4.17. RT2Off ΓòÉΓòÉΓòÉ
For new style RadioTrack cards only.
This function turns off the new-style RadioTrack cards. This function can also
be used to mute the radio. The format of the function is:
return_data = RT2Off( rt_address )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
return_data returns the following values:
0 No errors.
1 Radio card can't be turned off.
10 TESTCFG.SYS could not be opened.
ΓòÉΓòÉΓòÉ 4.18. RT2Tuned ΓòÉΓòÉΓòÉ
For new style RadioTrack cards only.
This function checks if the new-style RadioTrack card is tuned to a station. It
can be used to check for a valid station when doing station scans. The format
of the function is:
return_data = RT2Tuned( rt_address, delay1 )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
The delay1 deals with getting the tuned status from the radio card. Depending
on your system and/or program language used, this value may be variable. Use
delay1 = 250 to try for starters. The units of the delay is in milliseconds and
it may not be less than 1 or greater than 1000. The same rules for this delay
applies as the RTDelay function of this library.
Note: If RT2Tuned is not working reliably in your Vispro/REXX program even if a
station is playing properly, then issue a return_data = RTDelay( 250 ) before
calling RT2Tuned. We have found that this will make RT2Tuned work every time.
The source of this problem may be in the multithreading of Vispro/REXX code,
but we were not able to pinpoint it exactly. Classical REXX programs do not
reflect this problem. If you have any insight into this problem, let us know.
return_data returns the following values:
0 No station tuned.
1 Station tuned.
10 TESTCFG.SYS could not be opened.
11 Invalid time delay range.
28 Error reading radio card.
ΓòÉΓòÉΓòÉ 4.19. RT2Present ΓòÉΓòÉΓòÉ
For new style RadioTrack cards only.
This function checks if the new-style RadioTrack card is present in the system
at the particular I/O location. It is not a fool-proof way of detecting the
radio card, but in most cases it will work. The format of the function is:
return_data = RT2Present( rt_address )
The rt_address is the decimal value of the card's I/O location 780 (30C hex) or
524 (20C hex).
return_data returns the following values:
0 Not present.
1 Present.
10 TESTCFG.SYS could not be opened.
27 Error reading radio card.
ΓòÉΓòÉΓòÉ 4.20. RTIniOpen ΓòÉΓòÉΓòÉ
This call is not needed to control the RadioTrack cards. If you want to save
settings to an OS/2-style ini file using SysIni, this call will considerably
increase speed to access the ini file. This function uses the API call
PrfOpenProfile. The format of the function is:
iniHandle = RTIniOpen( iniFile )
The iniFile is the filename of the ini file. It can contain drive and directory
information, i.e. C:\MyDir\MyApp.ini
iniHandle returns the file handle as follows:
0 Error occurred
other File handle of opened ini file.
Sample code to use RTIniOpen and RTIniClose to save the variable port_Address
in an Ini file. Note that in this example, if the RTIniOpen fails, the variable
is still saved to the ini file.
inifile = 'APP.INI'
AppKey = 'myApp'
port_Address = X2D( '300' )
IniHandle = RTIniOpen( inifile )
iniRC = SysIni( inifile, AppKey, 'port_Address', port_Address )
IF IniHandle <> 0 THEN
rc = RTIniClose( IniHandle )
ΓòÉΓòÉΓòÉ 4.21. RTIniClose ΓòÉΓòÉΓòÉ
This call is not needed to control the RadioTrack cards. If you want to save
settings to an OS/2-style ini file using SysIni, this call will considerably
increase speed to access the ini file. This function uses the API call
PrfCloseProfile. The format of the function is:
rc = RTIniClose( iniHandle )
The iniHandle is the file handle of the ini file as returned by RTIniOpen.
rc returns errors as follows:
0 Error occurred
1 Success
Sample code to use RTIniOpen and RTIniClose to save the variable port_Address
in an Ini file. Note that in this example, if the RTIniOpen fails, the variable
is still saved to the ini file.
inifile = 'APP.INI'
AppKey = 'myApp'
port_Address = X2D( '300' )
IniHandle = RTIniOpen( inifile )
iniRC = SysIni( inifile, AppKey, 'port_Address', port_Address )
IF IniHandle <> 0 THEN
rc = RTIniClose( IniHandle )
ΓòÉΓòÉΓòÉ 4.22. RTDLLVersion ΓòÉΓòÉΓòÉ
This call is not needed to control the RadioTrack cards. It returns the name of
the DLL along with the version. The format of the function is:
version = RTDLLVersion()
version returns the following string: rxRTCtrl vx.yy where x is the major
revision and yy the minor revision number.
ΓòÉΓòÉΓòÉ 5. Error Codes ΓòÉΓòÉΓòÉ
Error Codes Returned:
If the port address is not returned by the RTRead and RTWrite functions, then
the data portion of the returned value indicates the type of error that
occurred.
DosOpen returns one of the following values as rc:
0 NO_ERROR
2 ERROR_FILE_NOT_FOUND
3 ERROR_PATH_NOT_FOUND
4 ERROR_TOO_MANY_OPEN_FILES
5 ERROR_ACCESS_DENIED
12 ERROR_INVALID_ACCESS
26 ERROR_NOT_DOS_DISK
32 ERROR_SHARING_VIOLATION
36 ERROR_SHARING_BUFFER_EXCEEDED
82 ERROR_CANNOT_MAKE
87 ERROR_INVALID_PARAMETER
99 ERROR_DEVICE_IN_USE
108 ERROR_DRIVE_LOCKED
110 ERROR_OPEN_FAILED
112 ERROR_DISK_FULL
206 ERROR_FILENAME_EXCED_RANGE
231 ERROR_PIPE_BUSY
DosDevIOCtl returns one of the following values as rc:
0 NO_ERROR
1 ERROR_INVALID_FUNCTION
6 ERROR_INVALID_HANDLE
15 ERROR_INVALID_DRIVE
31 ERROR_GEN_FAILURE
87 ERROR_INVALID_PARAMETER
111 ERROR_BUFFER_OVERFLOW
115 ERROR_PROTECTION_VIOLATION
117 ERROR_INVALID_CATEGORY
119 ERROR_BAD_DRIVER_LEVEL
163 ERROR_UNCERTAIN_MEDIA
165 ERROR_MONITORS_NOT_SUPPORTED
Note: If you get an error 10 - TESTCFG.SYS could not be opened, then
TESTCFG.SYS is not on your system.
If any of the API calls do not work and return errors, then most likely your
radio card I/O setting conflicts with another adapter in your system. If you
have a network card at 300 hex and your radio card is set to 30C hex, you will
not be able to access the radio card as TESTCFG.SYS prevents that. Set the
radio card to 20C hex in this case.
ΓòÉΓòÉΓòÉ 6. Important Notes ΓòÉΓòÉΓòÉ
It has been reported that the RTWrite function will sometimes not write to the
selected port when using Vispro/REXX based programs. This especially is the
case when the RTWrite function is the last statement in an event. To fix this
problem, simply add any other statement after the RTWrite function call. A
simple NOP (no operation) right after the RTWrite call will fix the problem.
This problem does not occur with classical REXX scripts.
I have observed this behaviour in the past but can not duplicate it anymore. I
have tested this on a relay card, by actually checking if the correct outputs
are turned on and I also have tested it with my FM radio card by changing
frequency and volume. It appears to work fine.
I would suspect that the reason could be in how Vispro/REXX poll keyboard and
mouse events. If anyone has any suggestions why this happens and how to fix it,
please let me know.
ΓòÉΓòÉΓòÉ 7. Example REXX Program ΓòÉΓòÉΓòÉ
The program below shows how to use rxRTCtrl with the older-style RadioTrack
card.
/* RTrack1.CMD */
/* Sample REXX Program to control the older RadioTrack FM Radio card */
/* Load RXRTCTRL.DLL */
CALL RXFuncAdd 'RTLoadFuncs', 'RXRTCTRL', 'RTLoadFuncs'
CALL RTLoadFuncs
SAY ''
SAY '--- Sample REXX Program to access RadioTrack FM card (older version).---'
SAY ''
SAY 'CAUTION: This program is capable of writing to I/O directly.'
SAY ' Make sure the rt_Address is set to the same value'
SAY ' as your RadioTrack card.'
SAY ' rt_Address is set to 20C hex by default.'
SAY ''
rt_Address = X2D('20C') /* enter radio address in hex. rt_address variable is converted from hex to decimal */
keyhit = ""
DO FOREVER
SAY "---------------------------------------------------"
SAY "Type 'x' to eXit..."
SAY "Commands below are for older RadioTrack only"
SAY "(type commands without the quotes):"
SAY "Type 'on' for radio on; 'off' for radio off;"
SAY "'f' to set radio to 90.1 MHz;"
SAY "'tu' fine tune 90.1 MHz up; 'td' to fine tune 90.1 MHz down;"
SAY "'vu' for volume up; 'vd' for volume down;"
SAY "'t' to check if station is tuned; 'v' for DLL version."
SAY ""
SAY "--------------------------------------------------"
SAY 'Enter selection: '
PARSE PULL keyhit
keyhit = Translate(keyhit)
SELECT
when keyhit = "F" then /* set frequency */
do
freq_value = 901 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901; 101.1 MHz = 1011 */
/* valid range is 87.0MHz to 109MHz. There is no range check, so that must be done in the REXX program */
return_data = RT1Freq( rt_Address, freq_value, '0' )
SAY "Set freq to 90.1 MHz: " || return_data
keyhit = ""
end
when keyhit = "OFF" then /* Radio off */
do
return_data = RT1Off( rt_Address ) /* rt_address must be decimal */
SAY "Set Radio off: " || return_data
keyhit = ""
end
when keyhit = "ON" then /* Radio on */
do
return_data = RT1On( rt_Address ) /* rt_address must be decimal */
SAY "Set Radio on: " || return_data
keyhit = ""
end
when keyhit = "VU" then /* volume up */
do
return_data = RT1Volup( rt_Address ) /* rt_address must be decimal */
SAY "Set volume up: " || return_data
keyhit = ""
end
when keyhit = "VD" then /* volume down */
do
return_data = RT1VolDn( rt_Address ) /* rt_address must be decimal */
SAY "Set volume down: " || return_data
keyhit = ""
end
when keyhit = "TU" then /* tune frequency */
do
freq_value = 901 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901 */
/* there is no range check, so that must be done in the REXX program */
fine_tune = fine_tune + 1 /* use this to fine tune the frequency to a resolution of 0.025MHz */
/* No range check takes place and fine_tune should be kept inside this range: */
/* -4, -3, -2, -1, 0, 1, 2, 3, 4 since this corresponds to +/-0.1MHz */
IF fine_tune > 4 THEN
fine_tune = 0
return_data = RT1Freq( rt_Address, freq_value, fine_tune )
SAY "Tune freq (90.1 MHz+) up: " || return_data
keyhit = ""
end
when keyhit = "TD" then /* tune frequency */
do
freq_value = 901 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901 */
/* there is no range check, so that must be done in the REXX program */
fine_tune = fine_tune - 1 /* use this to fine tune the frequency to a resolution of 0.025MHz */
/* No range check takes place and fine_tune should be kept inside this range: */
/* -4, -3, -2, -1, 0, 1, 2, 3, 4 since this corresponds to +/-0.1MHz */
IF fine_tune < -4 THEN
fine_tune = 0
return_data = RT1Freq( rt_Address, freq_value, fine_tune )
SAY "Tune freq (90.1 MHz-) down: " || return_data
keyhit = ""
end
when keyhit = "T" then /* Radio tuned */
do
return_data = RT1Tuned( rt_Address, '150', '100' ) /* rt_address must be decimal */
SAY "Radio is (1=tuned, 0=not tuned): " || return_data
keyhit = ""
end
when keyhit = "V" then /* rxRTCtrl.DLL version */
do
return_data = RTDLLVersion() /* no parameters passed on */
SAY "DLL version is: " || return_data
keyhit = ""
end
otherwise
DO
IF keyhit = "X" THEN
DO
CALL RTDropFuncs
SAY 'RXRTCTRL dropped.'
EXIT
END
ELSE
SAY "Invalid Input."
END
end /* select */
end /* do */
EXIT
The program below shows how to use rxRTCtrl with the newer-style RadioTrack
card.
/* Load RXRTCTRL.DLL */
CALL RXFuncAdd 'RTLoadFuncs', 'RXRTCTRL', 'RTLoadFuncs'
CALL RTLoadFuncs
SAY ''
SAY '--- Sample REXX Program to access newer RadioTrack FM card.---'
SAY ''
SAY 'CAUTION: This program is capable of writing to I/O directly.'
SAY ' Make sure the rt_Address is set to the same'
SAY ' address as your RadioTrack card.'
SAY ' rt_Address is set to 20C hex by default.'
SAY ''
rt_Address = X2D('20C') /* enter rt_address in hex. rt_address variable is converted from hex to decimal */
keyhit = ""
DO FOREVER
SAY "---------------------------------------------------"
SAY "Type 'x' to eXit..."
SAY "Commands below are for newer RadioTrack only"
SAY "(type commands without the quotes):"
SAY "Type 'on' for radio On; 'off' for radio Off;"
SAY "'90' to set radio to 90.1 MHz;"
SAY "'99' to set radio to 99.5 MHz; "
SAY "'101' to set radio to 101.1 MHz; "
SAY "'tu' fine tune 90.1 MHz up; 'td' to fine tune 90.1 MHz down;"
SAY "'t' to check if station is tuned; 'p' to check if radio card is present;"
SAY "'v' for DLL version."
SAY "--------------------------------------------------"
SAY 'Enter selection: '
PARSE PULL keyhit
keyhit = Translate(keyhit)
SELECT
when keyhit = "90" then /* set frequency */
do
freq_value = 901 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901 */
/* there is no range check, so that must be done in the REXX program */
fine_tune = 0 /* use this to fine tune the frequency to a resolution of 0.025MHz */
/* No range check takes place and fine_tune should be kept inside this range: */
/* -8, -6, -4, -2, 0, 2, 4, 6, 8 since this corresponds to +/-0.1MHz */
return_data = RT2Freq( rt_Address, freq_value, fine_tune )
SAY "Set Freq, to 90.1 MHz: " || return_data
keyhit = ""
end
when keyhit = "99" then /* set frequency */
do
freq_value = 995 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901 */
/* there is no range check, so that must be done in the REXX program */
fine_tune = 0 /* use this to fine tune the frequency to a resolution of 0.025MHz */
/* No range check takes place and fine_tune should be kept inside this range: */
/* -8, -6, -4, -2, 0, 2, 4, 6, 8 since this corresponds to +/-0.1MHz */
return_data = RT2Freq( rt_Address, freq_value, fine_tune )
SAY "Set Freq. to 99.5 MHz: " || return_data
keyhit = ""
end
when keyhit = "101" then /* set frequency */
do
freq_value = 1011 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901 */
/* there is no range check, so that must be done in the REXX program */
fine_tune = 0 /* use this to fine tune the frequency to a resolution of 0.025MHz */
/* No range check takes place and fine_tune should be kept inside this range: */
/* -8, -6, -4, -2, 0, 2, 4, 6, 8 since this corresponds to +/-0.1MHz */
return_data = RT2Freq( rt_Address, freq_value, fine_tune )
SAY "Set Freq. 101.1 MHz: " || return_data
keyhit = ""
end
when keyhit = "TU" then /* tune frequency */
do
freq_value = 901 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901 */
/* there is no range check, so that must be done in the REXX program */
fine_tune = fine_tune + 2 /* use this to fine tune the frequency to a resolution of 0.025MHz */
/* No range check takes place and fine_tune should be kept inside this range: */
/* -8, -6, -4, -2, 0, 2, 4, 6, 8 since this corresponds to +/-0.1MHz */
IF fine_tune > 8 THEN
fine_tune = 0
return_data = RT2Freq( rt_Address, freq_value, fine_tune )
SAY "Tune freq (90.1 MHz+) up: " || return_data
keyhit = ""
end
when keyhit = "TD" then /* tune frequency */
do
freq_value = 901 /* frequency is MHZ x 10, must be integer!!!! So 90.1 MHz = 901 */
/* there is no range check, so that must be done in the REXX program */
fine_tune = fine_tune - 2 /* use this to fine tune the frequency to a resolution of 0.025MHz */
/* No range check takes place and fine_tune should be kept inside this range: */
/* -8, -6, -4, -2, 0, 2, 4, 6, 8 since this corresponds to +/-0.1MHz */
IF fine_tune < -8 THEN
fine_tune = 0
return_data = RT2Freq( rt_Address, freq_value, fine_tune )
SAY "Tune freq (90.1 MHz-) down: " || return_data
keyhit = ""
end
when keyhit = "OFF" then /* Radio Off / mute */
do
return_data = RT2Off( rt_Address ) /* rt_address must be decimal */
SAY "Turn radio off or mute: " || return_data
keyhit = ""
end
when keyhit = "ON" then /* Radio On / unmute */
do
return_data = RT2On( rt_Address ) /* rt_address must be decimal */
SAY "Turn radio on or unmute: " || return_data
keyhit = ""
end
when keyhit = "T" then /* Radio tuned */
do
return_data = RT2Tuned( rt_Address, '250' ) /* rt_address must be decimal */
SAY "Radio is (1=tuned, 0=not tuned): " || return_data
keyhit = ""
end
when keyhit = "P" then /* New RadioTrack card present */
do
return_data = RT2Present( rt_Address ) /* rt_address must be decimal */
SAY "New RadioTrack is (1=present, 0=not present): " || return_data
keyhit = ""
end
when keyhit = "V" then /* rxRTCtrl.DLL version */
do
return_data = RTDLLVersion() /* no parameters passed on */
SAY "DLL version is: " || return_data
keyhit = ""
end
otherwise
DO
IF keyhit = "X" THEN
DO
CALL RTDropFuncs
SAY 'RXRTCTRL dropped.'
EXIT
END
ELSE
SAY "Invalid Input."
END
end /* select */
end /* do */
EXIT
ΓòÉΓòÉΓòÉ 8. Installation ΓòÉΓòÉΓòÉ
Note: REXX must be installed on your system for this program to work. REXX is
installed by default, but if you did not install it, then run Warp installation
again and selectively install REXX support.
rxRTCtrl.DLL requires the presence of the following statements in the
CONFIG.SYS:
IOPL=YES,FXPRINT
DEVICE=D:\OS2\BOOT\TESTCFG.SYS
These statements are present by default on any OS/2 Warp 3.0 or Warp 4.0
systems.
If you write your own REXX programs, only rxRTCtrl.DLL is required to access
the I/O. I suggest to keep rxRTCtrl.DLL in the same directory as your REXX
program so it will be able to find it when rxRTCtrl.DLL is loaded.
As an alternative, put rxRTCtrl.DLL into a directory called out by the LIBPATH
in the CONFIG.SYS. A reboot is required for this. Any program loading
rxRTCtrl.DLL will then automatically find it.
The following files belong to this program:
rxRTCtrl.DLL REXX-callable Dynamic Link Library for the RadioTrack
card.
rxRTCtrl.INF Documentation for rxRTCtrl in INF format.
HTMLDoc.ZIP Documentation for rxRTCtrl in HTML format, frame
based. HTML documentation must be installed on HPFS
drives because of long filenames.
RT2.CMD Sample REXX program to show how to use rxRTCtrl.DLL.
README.TXT Short program description.
ΓòÉΓòÉΓòÉ 9. References ΓòÉΓòÉΓòÉ
To get more information on programming for OS/2, especially for hardware I/O,
visit the sites listed below:
www.edm2.com
Look through back issues of articles published on hardware I/O and device drivers.
Also offers online classes for programming for OS/2.
http://avenger.mri.psu.edu/os2page.html
Information and source code on how to access I/O ports in OS/2.
http://femto.ssp.ameslab.gov
Contains OS/2 Warp Programming information for digital I/O
and GPIB devices.
To get information on interfacing to a PC or to get information on digital I/O
products, visit the sites listed below:
http://shell.rmi.net/~hisys/parport.html
IBM Parallel Port FAQ/Tutorial.
http://www.senet.com.au/~cpeacock/
Craig Peacock's Interfacing the PC. Online tutorial to interface any
device to the parallel or serial ports.
Many additional links to other sites about interfacing to computers.
http://www.industry.net/indcompsrc
Industrial Computer Source. Industrial computers and data acquisition products.
http://www.acces-usa.com
Acces I/O Products. Carries low-cost digital I/O products.
To get more information on programming for OS/2 using REXX visit the sites
listed below:
http://rexx.hursley.ibm.com/rexx/
Main REXX site.
http://www.vispro.com/
Visual programming for OS/2 using REXX. Hockware's Vispro/REXX site.
Helpful books about programming for OS/2 using REXX:
Teach Yourself REXX in 21 Days. Schindler&Schindler, SAMS, ISBN 0-672-30529-1
REXX Reference Summary Handbook, Dick Goran, CFS Nevada, ISBN 0-9639854-3-4
http://www.cfsrexx.com
OS/2 REXX, From Bark to Byte, Document Number GG24-4199-00, read online at:
http://publib.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/GG244199/contents
ΓòÉΓòÉΓòÉ 10. The Legal Stuff ΓòÉΓòÉΓòÉ
RxRTCtrl.DLL is free, however the authors retain the copyright to the source
code. It may be distributed electronically at no fee or a minimum fee to cover
media and distribution costs as long as all files are kept together.
RxRTCtrl.DLL may be distributed royalty free with any freeware or shareware
program controlling the RadioTrack cards. Please give credit to the authors and
include information where RxRTCtrl.DLL can be found.
RxRTCtrl.DLL is based on rxPortIO which you can also find at
http://home.att.net/~ASchw
DISCLAIMER
rxRTCtrl has been successfully tested on a variety of systems with the AIMS
RadioTrack cards. Use this software at your own risk. The authors of rxRTCtrl
are in no way responsible for any damage this program may cause to computer
equipment or other property by running this software on it.
CREDIT
Many thanks to Dennis Bareis for making the RTIniOpen and RTIniClose routines
possible. They are based on his FASTINI.DLL and you can find more information
at http://www.labyrinth.net.au/~dbareis/index.html
ΓòÉΓòÉΓòÉ 11. Contact ΓòÉΓòÉΓòÉ
For comments and questions on this program, you can contact the authors
directly via e-mail.
Our e-mail addresses are:
Armin Schwarz at ASchw@worldnet.att.net
or
Nicky Morrow at nrmorrow@cybertron.com
Visit "The Warped Code Cellar" at http://home.att.net/~ASchw for other
information and applications for OS/2 like HOUSE/2, a home automation program
using X10 devices, UPS Monitor for most APC UPS models, Memory Game and Leave
One, two speech-navigation-enabled games.