CNC Path Analyzer

M98/M99 subprograms: write a repeated shape once and call it many times

Explains with an example the structure of calling a subprogram with M98 and returning with M99, the P number and repeat count L, how to machine the same slot at several positions with an incremental subprogram, and the types of call errors.

Why use subprograms?

Cutting the same slot in five places, or machining the same contour several times at different depths, is common. Copying and pasting the same blocks each time makes the program long, and correcting one dimension means correcting all five places. Missing even one produces a reject where one of the five has a different size.

A subprogram separates the repeated part into its own program, which the main program calls when needed. The shape is maintained in one place only, and the main program just has to say "where, and how many times".

Calling and returning

CommandMeaningExample
M98 P_Calls the program with P number (O number)M98 P3100
L_ or leading digits of PRepeat countL3 → 3 times
M99Returns to the line after the calling blockLast line of O3100
M99 P_Returns, but jumps to the specified sequence numberUsed for branching and loop structures

Example: three slots with an incremental subprogram

Subprogram O3100 is written in G91 incremental mode. From the current position it goes down 6 mm, cuts a 30 mm slot in X, comes up 6 mm and moves 10 mm in Y while returning to the start X. The end position becomes the start of the next repetition, so simply repeating the same call three times produces three slots 10 mm apart.

Calling subprogram O3100 three times with L3 to cut three slots 10 mm apart

O3007
T1 M6
G21 G90 G17 G94
G54
S3000 M03
G00 X0. Y0. Z5.
M98 P3100 L3
G90 G00 Z50.
M30
O3100
G91 G01 Z-6. F100
X30. F300
G00 Z6.
X-30. Y10.
M99
Calling subprogram O3100 three times with L3 to cut three slots 10 mm apart — XY pathXY
Dashed light blue is G00 rapid traverse; solid orange is cutting motion. Arcs are expanded into calculated static curves.

The figure above is the CNC Path Analyzer result for this program (rapid 8 segments, linear cutting 6 segments).

Rules for the main program

  • Restore the mode: the subprogram ends in G91, so command G90 again in the main program right after the return. The example's G90 G00 Z50. does this. Writing just Z50. without G90 is interpreted as "50 mm above the current position" instead of "height 50". Here it is an upward move, so there is little harm, but in the approach block of the next tool it could lead to a collision.
  • Start position: an incremental subprogram gives different results depending on the position at the time of the call. Command the start position clearly in absolute coordinates just before the call.
  • Compensation and cycle state: calling with cutter radius compensation or a canned cycle active can make the moves inside the subprogram behave unexpectedly. Deliberately tidy up the modal state before and after the call.
  • Position of M30: when the subprogram is placed in the same file, put it after the main program's M30. The main program ends at M30, so the subprogram is not run by mistake.

Repeat count and cycle time calculation

One run of the subprogram cuts Z 6 mm (F100) and X 30 mm (F300): 3.6 seconds and 6 seconds, so 9.6 seconds per run and about 29 seconds of pure cutting for three runs. Changing the repeat count to L5 edits a single character of the main program and gives five slots and about 48 seconds of cutting. This shows how a repeat structure simplifies both program changes and time estimates. The calculation method is covered in more detail in Machining time calculation.

Types of call errors

In the tool, called programs in separate files can be loaded together with the main program, and the P number is linked to the O number inside the file, not to the file name.

ErrorCauseWhat CNC Path Analyzer shows
Called program not foundNo program with the O number matching PThe call line and the number not found
Duplicate O numberTwo or more programs with the same numberA warning that it cannot decide which to use
Missing M99The subprogram does not end and runs into the next programA missing-return warning
Endless callsPrograms keep calling each other, or a program calls itselfCalculation stops on recursion or execution limit

Frequently asked questions

Can a subprogram call another subprogram?
Yes. This is called nesting, and the number of levels allowed (usually four or more) differs by controller. The deeper the nesting, the harder it is to track the modal state, so we recommend staying within two levels.
How does M98 differ from a G65 macro call?
G65 is a macro call that passes arguments (A, B, C…) as variables. It is used to call the same shape with different dimensions, whereas M98 repeats the same operation without arguments.

Next steps

Check the path in CNC Path Analyzer