[Coco] Surprising find when calling USRn(X)
Sean Conner
sean at conman.org
Tue Nov 5 21:22:13 EST 2024
I'm still working on writing assembly to interface with BASIC. It's neve
rmentioned what registers need to be saved when calling USR() or USRn(), but
I thought I would be safe to double check with the Unravelled books. It
seems like you can use any register, but reading the code for USRn()
revealed something interesting:
L892C BSR L891C GET STORAGE LOC OF EXEC ADDRESS FOR USRn
LDX ,X * GET EXEC ADDRESS AND
PSHS X * PUSH IT ONTO THE STACK
JSR LB262 SYNTAX CHECK FOR ( & EVALUATE EXPR
LDX #FP0EXP POINT X TO FPA0
LDA VALTYP GET VARIABLE TYPE
BEQ L8943 BRANCH IF NUMERIC, STRING IF <> 0
JSR LB657 GET POINTER TO STRING DESCRIPTOR
LDX FPA0+2 GET VARIABLE POINTER
LDA VALTYP GET VARIABLE TYPE
L8943 RTS JUMP TO USR ROUTINE (PSHS X ABOVE)
The called assembly language routine gets X pointing either to FPA0, or
the address of the string descriptor; A is 0 if number, or <>0 ($FF
actually) if a string. So there's no need to call INTCVT in the assembly
code, nor to use VARPTR() when calling USRn(). I found that the the
following program works:
10 DATA166,132,174,2,95,235,128,74,38,251,83,126,180,243
20 CLEAR200,32511:FORA=32512TO32525:READB:POKEA,B:NEXT:DEFUSR0=32512
30 X$="HELLO, WORLD!":C=USR0(X$):PRINTX$,C
40 X$=X$+CHR$(C):C=USR0(X$):PRINTX$,C
The assembly subroutine:
GIVBF equ $B4F3
org $7F00
lda ,x ; length
ldx 2,x ; actual string
clrb
chksum addb ,x+
deca
bne chksum
comb
jmp GIVBF
end
I checked _Getting Started With Extended Color BASIC_ and this is not
mentioned at all. In fact, I seem to have found an error in the book. It
states:
A$=(USR1(VARPTR(B$))
You can have your ML subroutine modify B$'s value and then end the
routine with an RTS instruction. This causes USR to return with
B$'s modified value.
So, I tried with the following code:
INTCVT equ $B3ED
org $7F00
lower1 jsr INVCVT ; this becomes USR0 below
tfr d,x
lower2 lda ,x ; this becomes USR1 below
ldx 2,x
loop ldb ,x
cmpb #'A'
blo store
cmpb #'Z'
bhi store
orb #$20
store stb ,x+
deca
bne loop
rts
end
And the following BASIC program:
10 DATA189,179,237,31,1,166,132,174,2,230,132,193,65,37,6,193,90,34,2,202,32,231,128,74,38,239,57
20 CLEAR200,32511:FORA=32512TO32538:READB:POKEA,B:NEXT:DEFUSR0=32512:DEFUSR1=32517
100 X$="HELLO, WORLD!"
110 X=USR0(VARPTR(X$)):PRINT X$
120 X$="NICE TO MEET YOU"
130 Y$=USR1(X$):PRINT Y$
If I change line 110 to basically match the documentation:
110 Y$=USR0(VARPTR(X$)):PRINT Y$
I get
?TM ERROR in 110
Line 130 works as is. Go figure.
-spc
More information about the Coco
mailing list