[Coco] Surprising find when calling USRn(X)
Sean Conner
sean at conman.org
Wed Nov 6 15:48:36 EST 2024
It was thus said that the Great Johann Klasek once stated:
> On Tue, Nov 05, 2024 at 09:22:13PM -0500, Sean Conner via Coco wrote:
>
> > The assembly subroutine:
> >
> > GIVBF equ $B4F3
>
> Here you should check in A if the expected type is given otherwise
> X won't contain a descriptor address at all ...
Yes, of course. It was just a quick test.
> The current type is derived from the last expression evaluated. The
> expression of the argument is this last expression and determines the
> type of the whole expression USRx() which has to match the variable type
> of the assignement. The reported "Type Mismatch" is telling this.
>
> For
>
> > 110 Y$=USR0(VARPTR(X$)):PRINT Y$
>
> to work the code above has to put a discriptor pointer (maybe a temporary
> descriptor on the string descriptor stack) with a string allocated on the
> string heap (containing the result) into the ACC0 and set the type to
> "string".
> Otherwise, the rule applies that the assignment type and argument type are
> identical.
But none of that was documented in either _Getting Started with Color
BASIC_or _Getting Started with Extended Color BASIC_. And it's _Getting
Started with Extended Color BASIC_ that says to:
Y$=USR0(VARPTR(X$))
Anyway, I finished adding a new output format for my 6809 assembler [1],
which is to output a BASIC program to poke the machine code into memory,
which is why I was playing around with this stuff. Given this program:
include "basic.i"
include "basic-int.i"
include "dp.i"
.opt basic strspace 300
.opt basic defusr0 both
.opt basic defusr1 decstr
.opt basic defusr2 addone
.opt basic defusr3 identity
.opt basic defusr4 maskstr
org $7F00
;***************************************************************************
both beq .number ; handle number
ldx _STRPTR,x ; point to string data
.text lda ,x ; just increment each character
inca ; B already has length
sta ,x+
decb
bne .text
rts ; return
.number ldx #.pi ; FP0 = FP0 * pi
jmp CB.FMULx
.pi .float 3.1415926
;***************************************************************************
decstr jsr CB.strchk ; looking for a string
ldx _STRPTR,x ; get string pointer
.text lda ,x ; decrement each character
deca
sta ,x+
decb
bne .text
rts
;***************************************************************************
addone jsr CB.numchk ; check for number
ldx #.one ; add one to FP0
jmp CB.FADDx
.one .float 1.0
;***************************************************************************
identity rts ; identity function
;***************************************************************************
maskstr jsr CB.strchk ; check for string
stb CB.strdes + _STRLEN ; save length of new string
jsr CB.rsvpstr ; reserve string space
ldb CB.strdes + _STRLEN ; get length
lda #'*' ; masking character
.mask sta ,x+
decb
bne .mask
ldx CB.frespc ; point to new string
stx CB.strdes + _STRPTR
jmp CB.putstrdes ; add to string pool
;***************************************************************************
end
And selecting the BASIC format, you get the following output:
10 DATA39,11,174,2,166,132,76,167,128,90,38,248,57,142,127,19,126,186,202,130,73,15,218,104,189,177,70,174,2,166,132,74,167,128,90,38,248,57,189,177,67,142,127,47,126,185,194,129,0,0,0,0,57,189,177,70,215,86,189,181,109,214,86,134,42,167,128,90,38
20 DATA251,158,37,159,88,126,181,76
30 CLEAR300,32511:FORA=32512TO32588:READB:POKEA,B:NEXT:DEFUSR0=32512:DEFUSR1=32536:DEFUSR2=32550:DEFUSR3=32564:DEFUSR4=32565
ready to be MERGEed into an existing BASIC program. And there are options
to change the line numbering if so desired.
The example program I have to drive this code is:
100 X=USR0(2):PRINT X:X$=USR0("HELLO"):PRINT X$
105 X=USR1(5):REM WILL ERROR OUT
110 X$=USR1("THERE"):PRINT X$
115 X$=USR2("HELLO"):REM WILL ERROR OUT
120 X=USR2(1):PRINT X
130 X=USR3(3.1415926):PRINT X:X$=USR3("IDENTITY"):PRINT X$
135 X=USR4(4):REM WILL ERROR OUT
140 P$="PASSWORD":H$=USR4(P$):PRINT P$,H$
What I've found is that on entry to a DEFUSRn routine:
X - points to either FP0 ($4F), or a string descriptor, depending
upon type (not documented?)
A - 0 if number, 255 if string (not documented?)
B - length of string if A = 255 (not documented?)
INTCVT ($B3ED) - converts contents of FP0 to D
GIVBF ($B4F3) - converts B to FP0 (unsigned)
GIVABF ($B4F4) - convertd D to FP0
VARPTR(var) - set FP0 to address of numberic variable, or string
descriptor of string variable
-spc
[1] https://github.com/spc476/a09
More information about the Coco
mailing list