Here's the rundown Joe, some you know, some might be new...
All of it is done with different variations of M98. The full break down is like this...
M98 Pxxx Hxxx Lxxx (P = program, H = "N" number, L = repeats)
So, you can code like the following:
M98 P2000 (regular sub call)
Sub call to program number 2000.
M98 H1550 (internal sub call)
Sub call "jump" to N1550 in the main (or same program you're calling from)
M98 P2000 H1550(external sub call with a jump)
Sub call to program #2000, jump to line N1550
You can also jump with a M99:
M99P600 (return to N600)
With the above (M99), if you're in a sub program, it will go back to calling program to line N600. If you do this within its own program, it will look in reverse to find N600.
On a Fusion and newer control, I usually put internal subs after the main program M30 like this....
(code)
(code)
(code)
G0G91G28Z0M5
G30X0Y0
M30 (end of main program)
(*)
N1550(internal sub 1)
(code)
(code)
M99
(*)
N1600(internal sub 2)
(code)
(code)
M99
.
.
.
etc, etc.
On a M+ and older control, you need to put the internal subs before the M30 unless you write it into the program at the control. Some Plus controls have a hard time dealing with info after the M30. In which case, I'll have a jump (GOTO) statement to hit the M30 at the end of the run. This is just what I do. You can place the subs and commands anywhere in the program body. And, you can nest them within subs as well. Much like macro statements, you can nest sub commands 8 levels deep on Mazatrol controls. This includes if you're using G65, G66, G66.1 mixed together. It's 8 levels total from a single jump point.