Xojo does in fact have a goto instruction and labels. I used this to advantage when I coded a PIC microcontroller emulator. Similar to what you have done, all of the PIC instruction codes were coded as Xojo methods. This allowed the writing of PIC assembly language code directly in the Xojo code editor and then running it. There’s a short description of the project, which I submitted in the summer 2018 Just Code Challenge. Here’s a link, and it has a link for downloading the project.
Here is example assembly code that makes use of Xojo’s goto instruction and labels:
'Volder's CORDIC rectangular to polar routine in PIC assembly language.
'It is assumed that inputs are 12 bit positive integers 0..4095.
'Hence the vector is in the first quadrant.
'The following XOJO housekeeping code sets up the various PIC registers.
dim xH,xL,yH,yL,angleH,angleL,index,count,tL,tH,vL,vH,kScale As UInt8
'dim deltaSum As Double
'Lookup table values with angles in degrees. Tables probably have more entries than necessary for 16 bit resolution
dim LU_AngleInt() As Integer = array(26,14,7,3,1,0,0,0,0,0,0,0,0,0)
dim LU_AngleFrac() As Integer = Array(144,9,32,147,202,229,114,57,28,14,7,4,2,1)
dim nTable As UInt8 = UBound(LU_AngleFrac)
'Initialize x and y variables
xH=x\256 'High byte of x coordinate
xL=x mod 256 'Low byte of x coordinate
yH=y\256 'High byte of y coordinate
yL=y mod 256 'Low byte of y coordinate
'*************************************
'Start of ASM code
'CORDIC ATAN2 function
'
'On entry, the 12 bit (0..4095) values of x and y should be in xL,xH,yL,yH
'The upper 4 bits of xH and yH must be Zero.
'On completion, the angle (in degrees) is in AngleH and AngleL
'The integer part is in AngleH, and the fractional part is in AngleL
'The radius (magnitude) is in yH,yL (integer), and xH (fraction).
clrf angleH
clrf angleL
'Check for all Zero input combinations
movf xL,w
iorwf xH,w
iorwf yL,w
iorwf yH,w
btfsc status,z
if noSkip then Return 999 'This is an error code indicating that both x an y are zero
'check if y=0
movf yH,w
iorwf yL,w
btfsc status,z
if noSkip then Return 0 'Angle is zero if y=0
'check for x=0
movlw 90
movwf angleH
movf xH,w
iorwf xL,w
btfsc status,z
if noSkip then Return 90 'Angle is 90 degrees if x=0
movlw 45
movwf angleH
' Scale up x and y to improve resolution
movlw 15
movwf kScale
ScaleXY:
decf kScale,f
clc
rlf xL,f 'shift xH and yH left
rlf xH,f
clc
rlf yL,f
rlf yH,f
movf xH,w
iorwf yH,w
andlw &hF0
btfsc status,z
if noSkip then goto ScaleXY
'xH and yH are now normalized
'initialize calc loop
'calc x and y initial values
'save old x, as it will be overwritten
movf xH,w
movwf vH
movf xL,w
movwf vL
'calc x=x+y
addwf yL,w
movwf xL
btfsc status,c
incf xH,f
movf yH,w
addwf xH,f
'calc y=y-x
movf vL,w
subwf yL,f
btfss status,c
decf yH,f
movf vH,w
subwf yH,f
clrf index 'Loop counter and lookup table index
MainLoop:
'shift x and y values
movf index,w
movwf count
'calc x y shift
movf yH,w
movwf tH
movf yL,w
movwf tL
movf xH,w
movwf vH
movf xL,w
movwf vL
btfss yH,7 'check for negative y
if noSkip then goto ShiftLoop
comf tH,f
comf tL,f
incf tL,f
btfsc status,z
incf tH,f
ShiftLoop:
clc
rrf vH,f
rrf vL,f
clc
rrf tH,f
rrf tL,f
clc
decfsz count,f
if noSkip then goto ShiftLoop
'calc new xH and yH
btfsc yH,7
if noSkip then goto NewXYcalc
'y=y+/-yH>>index
comf vH,f
comf vL,f
incf vL,f
btfsc status,z
incf vH,f
NewXYcalc:
movf vL,w
addwf yL,f
btfsc status,c
incf yH,f
movf vH,w
addwf yH,f
'x=x+y>>index
movf tL,w
addwf xL,f
btfsc status,c
incf xH,f
movf tH,w
addwf xH,f
' Sum Angle from lookup table
movf index,w
call_Lkp LU_AngleFrac
movwf tL
movf index,w
call_Lkp LU_AngleInt
movwf tH
btfss yH,7
if noSkip then goto AddSum
comf tH,f
comf tL,f
incf tL,f
btfsc status,z
incf tH,f
AddSum:
movf tL,w
addwf angleL,f
btfsc status,c
incf angleH,f
movf tH,w
addwf angleH,f
'if result is Zero, then we are done
incf index,f
movlw nTable+1
subwf index,w
btfss status,z
if noSkip then goto MainLoop
'
'The result of the preceding steps is to rotate the vector to the x axis. The rotated angle
'is the required polar angle, and the final x value is proportional to the required magnitude.
'The magnitude will be high by a factor of 1.6467743... which is the product of the cosine values
'in the lookup table. to get the true magnitude value we must scale it back by multiplying by
'1/1.6467743 or 0.607247753539552. Since we only need 16 bit precision, we can pick the simplest
'fixed shift and add routine that gives a sufficiently precise result. Multiplying by 17/28
'gives 0.6071428571 which is in error by 0.0172% which is probably good enough. However, we can
'improve the accuracy by truncating the summation after 4 terms and adding the final term twice.
'This gives a correction of 0.60725402832 for an error of 0.001%
'We use a repeating fraction multiply algorithm with parameters m=17, n=5, p=3 (for 17/28 factor)
'First multiply by m, then shift right n bits, then repeatedly shift right p bits and add to the
'n shifted value.
'start by multiplying by 17 (actually 17/4, in order to scale values to a safe range;
'the factor 4 will be removed later)
clc
rrf xH,w
movwf tH
rrf xL,w
movwf tL
movlw 3
movwf count
MpyLoop1:
clc 'bcf status,c
rrf tH,f
rrf tL,f
decfsz count,f
if noSkip then goto MpyLoop1
movf xL,w
addwf tL,f
btfsc status,c
incf tH,f
movf xH,w
addwf tH,f
movf tH,w 'copy back from t to x
movwf xH
movf tL,w
movwf xL
'end of 17/4 scale
'repeating shift/add loop
movlw 4
movwf index
MpyLoop2:
movlw 3
movwf count
MpyLoop3:
clc 'bcf status,c
rrf tH,f
rrf tL,f
decfsz count,f
if noSkip then goto MpyLoop3
movf tL,w
addwf xL,f
btfsc status,c
incf xH,f
movf tH,w
addwf xH,f
decfsz index,f
if noSkip then goto MpyLoop2
movf tL,w
addwf xL,f
btfsc status,c
incf xH,f
movf tH,w
addwf xH,f
'Finally shift x into y regs
clrf yH
clrf yL
ScaleLoop:
clc
rlf xL,f
rlf xH,f
rlf yL,f
rlf yH,f
decfsz kScale,f
if noSkip then goto ScaleLoop
nop
AllDone:
nop
'End of asm code.
'****************************************
'The magnitude value is converted to a type double, and stored as a property.
magnitudeCORDIC=(yH*256+yL+xH/255)
'The angle is converted to a type double, and stored as a property.
angleCORDIC = angleL/256+angleH
return 1 'Error code Indicates valid result
This worked well in my situation, because these PIC processors have no conditional jump instructions, just conditional skips. So all I had to do for compatibility is have the skip instruction set or clear a flag bit, and then the following line that has the goto instruction is simply prefixed with “If noskip then”