[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