[Coco] DEFUSRn parameters vs. Color Extended BASIC manual
William Astle
lost at l-w.ca
Mon Apr 22 14:04:05 EDT 2019
The ECB implementation of USRn() parses the argument which may be either
string or numeric. If it is string, it removes it from the string stack
(if required) and returns the length in B and the data address in X. If
it's numeric, it leaves the value in FPA0 in which case INTCNV would be
relevant if you want an integer value.
The value type will be in A regardless, and also in VALTYP. Nonzero
means string, zero means numeric. The flags will already be set based on
the value in A.
On return, your return value needs to be in FPA0 with VALTYP set
appropriately. For a numeric return, you leave a floating point value in
FPA0 in which case GIVABF might be relevant unless you want to return an
actual floating point value.
For a string return, you leave a pointer to the string descriptor in the
low two bytes of the FPA0 mantissa. If returning an anonymous string
that you just created, or just returning the original string you were
passed, you have to push it onto the string stack (there's a routine
somewhere in the Color Basic ROM to do that). Regardless, you have to
make sure have a proper string descriptor.
If you want to return strings, you should probably take a look at some
of the stuff in the ROM that returns a string to see how to do it
correctly. Don't worry about the stuff in Color Basic that pops the
return address and jumps directly back to the interpretation loop -
that's not needed with USRn(). The whole reason for that is some
overcomplicated nonsense that insists on a numeric return type for
functions implemented in the Color Basic ROM.
Obviously, whatever variable you assign the result of USRn() to has to
match whatever it is returning.
If you don't change VALTYP, then the destination of the assignment will
have to match the argument. Thus, you should probably set VALTYP
correctly (0 for numeric, $FF for string). GIVABF will set it for numeric.
VARPTR returns a pointer to the string descriptor, not the string data.
At offset 0 you'll have the length and at offset 2 you'll have the
actual data pointer, which is only valid if the length is nonzero. Note
that it will also return a pointer to a numeric variable if that's what
you give it in which case it points to the 5 byte packed floating point
value. This should also work for an array element.
On 2019-04-22 11:26 a.m., Joel Rees wrote:
> Thanks, Arthur and William, for the confirmation about the conversion
> routines INTCNV and GIVABF.
>
> I'm playing with the USRn interface and I think it is clear that the Color
> Extended BASIC manual, in addition to containing typos, contains errors in
> the descriptions.
>
> When passing a string in, if you pass it with VARPTR giving the address, if
> the return value is stored in a string varable, it says TM error (type
> mismatch). But if you store it in a numeric, it doesn't complain. But the
> value in X is not the address of the string.
>
> If you pass it without VARPTR, if the return value is stored in a numeric,
> it gives type mismatch. But if you store it in a string, it doesn't
> complain, and the address in X is the address of the string, as described.
>
> Since the VARPTR is an integer, I'm guessing that the address passed that
> way gets passed as a numeric, requiring conversion by INTCNV to recover,
> which would require the BASIC interpreter to do less magic interpretation
> of user intent. I suppose I should test that after I get some sleep.
>
> Typical Microsoft misspecification, really.
>
> And it leaves me inclined to pass integers as hexadecimal numbers stored to
> strings, rather than depend on INTCNV and GIVABF.
>
More information about the Coco
mailing list