#Basic -> ARexx
11 messages in this thread
I'm trying to translate a Basic program to Arexx and I wanted to doublecheck
and see if I am using the right vocabulary…
I'm writing a series of bytes to the SER: port, so I start by opening the
port with
x = OPEN(test,'SER:','Write')
Now the basic line reads "Print #1, CHR$(255)"
I've assumed that the ARexx equivalent is:
WRITECH(d2c(255))
Anyone see anything I'm doing wrong?
Thanks – Joe
Joe …
A few small technical details get in the way. You're generally on the right
track:
WRITECH() is a function. So, just like SQR() in Basic, you must do something
with the result it returns. Some examples:
IF WRITECH(…) THEN SAY 'OK'
CALL WRITECH(…)
Function WRITECH returns the count of characters sent. But it's OK to use
it as a boolean as in example 1, or throw away the return value with CALL.
WRITECH() takes two arguments: the file handle, and THEN the data to be
sent. So try:
CALL WRITECH(test,d2c(255))
… and I think things will start working OK.
–Jim
Jim –
Forgive me for being a PITA nitpicker but — 🙂
> But it's OK to use it as a boolean as in example 1, . . .
I'm sure that you meant:
"But it's OK to use it in a boolean expression as in example 1 . . ."
^^ ^^^^^^^^^^
where example 1 looks something like:
if writech(…) > 0 then say 'OK' /* example 1 */
since in ARexx (and REXX) a boolean is only allowed one of two values TRUE (1)
or FALSE (0) (unlike C for example). Consequently, if more than one (1)
character is written, the original example would produce
+++ Error 46 in line xx: Boolean value not 0 or 1
——
Right you are!
I depend on the ARexx interpreter to straighten me out on these small
details, which big thinkers (like me) don't always pay attention to…
🙂
–Jim
Jim –
> I depend on the ARexx interpreter to . . .
Me too — I won't tell you how many times it has given me the
"+++ Error 46 . . ." message! And, of course, we have here a prime example of
the "things just JUMP out of someone else's code that are completely invisible
in my own" fundamental law of software. 🙂
——
Jim –
Thanks for the reply. I've been using "Call WriteCH(byte)" in my program,
so I'm covered there, but where I think I'm getting stuck is trying to find an
equivalent for the CHR$() function.
If I understand d2c()'s result, I'll won't get an ASCII character – which is
what CHR$() will do. So how do I get from binary (or decimal) to the ASCII?
The only clue I found in the ARexx manual was the CVi2a() function – which will
convert from integer (decimal?) to ASCII. Unfortunately, it doesn't seem to be
simple to use, i.e. (from the ARexx manual):
CVi2a() – convert from integer to ASCII
Usage: (length, pointer) = CVi2a(buffer, value, digits)
I don't know how to use a 'pointer' to access the converted value.
Perhaps there is another undocumented conversion function with one of the
other support libraries that I am unfamiliar with?
Thanks for your help.
Joe
… d2c() vs. CHR$() …
Yes, function d2c() does indeed give you ASCII characters based on the value
you supply in the parens. Try the following direct command:
RX "say d2c(65)" .. you'll get upper case A, similarly:
RX "chnum = 65 ; say d2c(chnum)" .. same thing. With a "typeless"
language such as ARexx, it sometimes takes a moment to realize that a numeric
variable can generally be assumed to be in decimal. Next step:
RX >RAM:TEST "say d2c(65)d2c(10)" followed by TYPE HEX RAM:TEST. You'll
see that three characters have been written (SAY automatically inserts a
NewLine at the end, making two of them). By the way, you might feed more
comfortable putting two vertical bars ahead of the second d2c(), but it works
either way.
If you use a value greater than 255, d2c() will generate more than one byte
(unless you force it with a second parameter) .. in fact, you could go up to
four bytes. This allows d2c() and c2d() to easily translate multi-byte
addresses to and from their decimal equivalents. I doubt that you would need
that feature for your telecomms coding, but it's there. You could try:
RX "say d2c(1248814369)" .. to see this work.
Where you want to code a fixed character (or string), you can bypass the
d2c() function by just defining the characters directly; a command such as:
RX "say '48 65 6C 6C 6F 21'x" .. will output the hex characters quite
neatly. And you can omit the spaces for greater compactness and lower
readability.
I don't know function CVi2a, and can't find any reference to it in my ARexx
guides. I speculate that it's from some library I haven't encountered or tried
using. From the above, you may decide that you don't need to fuss with it.
ARexx can use pointers if you really have to, typically with commands such as
IMPORT or EXPORT. But again, I suspect you won't need to worry about them
right now.
–Jim
Thanks Jim –
Well, I figured out the what the problem was. I was trying to control a
X10 home automation module and that has a much lower baud rate than I expected
– 600 baud. Once I set those parameters, using the ARexx Serial library, I got
the result I was expecting.
Thanks again for all your help.
Joe
Joe –
Just a few comments (that probably are superfluous :).
First, I'm sure that you are aware that ARexx (and REXX) functions always
return a value — for writech it is the number of characters written (of course
:). However, it is NOT always obvious that if you don't explicitly assign that
result to a variable:
nchars = writech(test, 'FF'X) /* for example */
or explicitly ignore the returned value by using the call statement:
call writech test, 'FF'X /* for another example */
then the returned value (in this case '1' — the number of characters written)
will be passed to the current host (use 'say address()' if you're curious what
it is) for processing. Unless that value ('1' in this case) has a meaning to
the current host (which is not likely), it will produce an (obsure, perhaps)
error message.
Second, if I remember Basic (haven't used any variety for quite a while),
a non-continued print statement (as shown) appends a NEWLINE (appropriate to
the environment – LF, CRLF, or whatever). Consequently, the same effect in
ARexx would be achieved by:
call writeln test, 'FF'X /* letting writeln append the NEWLINE */
or
call writech test, 'FF0A'X /* adding NEWLINE yourself */
Finally, although I've not had an occasion to use it myself, you might
want to look into Joseph M. Stivaletta's 'rexxserdev.library' which can be
found in the AmigaTech Forum libraries and is supposed to facilitate using the
serial device from ARexx.
> [72155,516] Joe Stivaletta Lib:13
> RXSER5.LHA
> Bin, Bytes: 7521, Count: 302, 28-Dec-92(26-Mar-93)
>
> Title : Rexxserdev.library Version 5.02
> Keywords: AREXX SERIAL DEVICE FUNCTION LIBRARY
>
> ARexx Serial Device Function Library Version 5.02. Corrects a very
> subtle bug. Requires AOS 2.04 or greater.
——
Bob –
I guess I didn't indicate that I was using the "Call WriteCH()" format – as
both you and Jim Butterfield caught the same syntax.
Really though, I'm trying to find an ARexx function that would convert a
binary or decimal number to ASCII, and so far have not been able to get the
CVi2a() to work correctly.
Do you know of any function that would be the equivalent of CHR$()?
Thanks – Joe
Joe –
> I guess I didn't indicate that . . .
Great – just wanted to be sure since it is a common oversight on
introduction to ARexx – at least I made it and I'm as common as can be 🙂
> . . . an ARexx function that would convert a binary or decimal number
> to ASCII, . . .
Guess that I'm not understanding what you are looking for, since B2C, X2C,
and D2C seem to do just that, as shown by the following 'inline' ARexx
programs:
> rx "say b2c('00110000 00100000 00110001 00110011')" ; binary->ascii
0 13
> rx "say c2b(01 3)" ; ascii->binary
00110000001100010010000000110011
> rx "say x2c('61 62 20 63')" ; hex->ascii
ab c
> rx "say c2x('ab c')" ; ascii->hex
61622063
> rx "say d2c('4276803')" ; decimal->ascii note: 4276803='414243'X
ABC
> rx "say d2x(c2d('ABC'))" ; ascii->dec->hex
414243
Of course these functions work for the single character case also. d2c(14889)
——