Skip to main content Scroll Top
Subprogram and Macro Call Errors
How wrong call numbers, missing M99 returns, and carried modal states cause program flow crashes. Verify nested M98/M99 call structures on a digital twin

The main program looks clean — because the mistake is off in a call you didn't follow

Subprograms are how a real program stays readable: a main that calls a drilling routine by number, repeated across a fixture of parts; a macro called with arguments; nested calls a few levels deep. It’s good structure — and it’s structure that hides its own failures. When something goes wrong in the flow — a wrong call number, a missing return, a nesting level too deep, a modal state that carried across a call — the main program still reads perfectly. The mistake isn’t on the page you’re looking at. It’s in where the flow actually went, three calls deep, on a path you didn’t trace.

That’s the specific trap of subprogram and macro calls: correctness isn’t a property of any one file. It’s a property of the whole call-and-return flow, executed in order, with the right state at each boundary — and that flow is exactly what a linear read of the main program doesn’t reveal.

The call-flow mistakes

  • Wrong subprogram number. M98 P1200 when the routine is O1210 calls the wrong subprogram — valid code that runs the wrong operations, or errors out mid-program.
  • Missing M99 (no return). A subprogram that never returns runs off its end into whatever follows in memory, or faults. The main looks fine; the return that isn’t there is invisible in it.
  • Nesting too deep. Calls within calls beyond the control’s allowed nesting level fault at runtime — and which call tips it over isn’t obvious from any single file.
  • Wrong repeat count. A subprogram called to repeat a different number of times than intended machines too many or too few positions.
  • Modal state carried across the call. A units mode, plane, work offset, or an active cycle set in the main (or a prior call) governs the subprogram, which assumed a different state. The subprogram is correct in isolation and wrong in context.
  • Argument-passing errors in macro calls. A macro called with the wrong argument mapped to the wrong local variable drives the logic — and the tool — off its intended path.

Every one runs as valid code. The flow simply goes somewhere the main program doesn’t show.

Why a listing and CAM simulation miss it

You can’t read the flow. Following a program built from nested calls means expanding every M98/M99, tracking the repeat counts, and carrying the modal state across each boundary — by hand, in your head. A wrong call number or a missing return doesn’t announce itself; it changes where the flow goes, which the main program’s text doesn’t contain.

CAM knows only what it generated. If the CAM produced the operations, it can simulate those — but a hand-built main that calls subprograms by number, with hand-written macros in the mix, is a call structure the CAM never created and can’t follow. It has no way to expand a call it didn’t write or evaluate a modal state that carried across it.

Catching it needs the real program’s call structure expanded and executed the way the control runs it — every call, every return, with the real state at each boundary.

Where Eureka G-Code fits

Eureka G-Code reads and executes the true ISO, expanding and running the real subprogram and macro call structure — M98/M99, repeats, nesting, argument passing — the way the control will. So the flow on the twin follows exactly the calls and returns the control will follow, carrying the real modal state across each boundary. A wrong call number, a missing return, a nesting level too deep, a repeat count off, a modal state that shouldn’t have carried: each shows up as the program going somewhere it shouldn’t — a collision, near-miss, overtravel, or a machined result that doesn’t match the model.

Because it reads the real ISO regardless of origin, the hand-built mains and hand-written macros a CAM never generated — the programs where call-flow errors are most common — are exactly what it verifies. On complex machines, where a main calls subprograms across positions and channels, following the real flow is the only way to know the program does what its structure implies.

> Take a program built from nested subprograms — the main that calls routines by number across a fixture, with a macro or two in the mix — and run the real ISO on a twin of your machine in Eureka G-Code. Watching the flow follow every call and return the way the control will, before the machine does, is how a wrong call number gets caught at a desk.

FAQ

What are the most common subprogram errors?

 A wrong subprogram number (M98 P pointing at the wrong routine), a missing M99 return, nesting too deep for the control, a wrong repeat count, a modal state carried across the call, and argument-passing errors in macro calls. All run as valid code while sending the flow somewhere unintended.

Why can't I see a call-flow error in the main program?

Because correctness is a property of the whole call-and-return flow, not any one file. Following it means expanding every call, tracking repeats, and carrying modal state across each boundary — which the main program’s linear text doesn’t show.

Why doesn't CAM simulation follow my subprograms?

A CAM can simulate the operations it generated, but a hand-built main that calls subprograms by number — with hand-written macros — is a call structure the CAM never created and can’t expand or evaluate.

How does Eureka G-Code verify the call structure?

 It expands and executes the real M98/M99 structure — repeats, nesting, argument passing — the way the control will, carrying the real modal state across each boundary, so a wrong call, missing return, or bad nesting shows up as a collision, near-miss, overtravel, or a part that doesn’t match the model.

Does it handle modal state carried across calls?

 Yes. It executes the program the way the control does, so a units mode, plane, offset, or active cycle that carries into a subprogram is reflected — catching the subprogram that’s correct alone but wrong in context.

Next step

Eureka G-Code — request a demonstration on a digital twin of your own machine and controller.

Expand and run the real call structure on a twin — and follow the flow the control will actually take.

Related Articles