Independent CNC repair and technical reference Contact

FANUC G65 and M98: why a subprogram change to #1 may be invisible to its caller

Published Updated

A motion-free variable trace based on the 0i-D common operator’s manual compares G65 with M98. It explains argument A mapping to #1, restoration of local-variable levels, and why common variables are not isolated by those levels.

Contents
  1. Distinguish program reuse from variable scope
  2. Trace the result without moving an axis
  3. Restoring locals does not restore every state
  4. Validate the call chain, not just variable numbers

A program segment assigns a variable, but after changing its call to G65, the main program's #1 seems unchanged on return. With M98, the assigned value remains. This often reflects different call semantics, not a lost assignment in the CNC.

Distinguish program reuse from variable scope

This article applies to 0i-D / 0i Mate-D systems with the relevant custom-macro capability. The public mirror of the original B-64304EN/02 manual, §14.7, page 206 distinguishes the calls: G65 passes macro arguments and changes the local-variable level. An M98 subprogram call provides neither that argument-passing mechanism nor a change of local-variable level. Reaching the same O program does not make the two calls equivalent.

Trace the result without moving an axis

The following is an original logic trace, assuming no interrupts, resets or other assignments. Before the call, #1 at the current level is 20.0. The called program only assigns 9.0 to the #1 it sees, then returns normally.

Observation pointG65 passing A4.0Ordinary M98 subprogram call
#1 when the called program begins4.0 at the new level20.0 at the original level
#1 after assignment9.0 at the new level9.0 at the original level
#1 after returning to the callerOriginal-level value 20.0 is restoredRemains 9.0

Section 14.7.1, pages 207–208, maps A to #1. Page 211 explains that a macro call preserves the previous local-variable level and an M99 return restores it. The table uses an argument with a decimal point to avoid mixing the least-input-increment rules for addresses without decimal points into this example. It illustrates variable scope, not a complete program ready for machine execution.

Restoring locals does not restore every state

Page 211 of the same chapter identifies common variables as readable and writable across macro levels. Consequently, if a calculation must return a result to its caller, the interface must explicitly define where to store that output. A submacro's #1 is not an automatically returned value, and common variables already reserved by the machine builder must not be appropriated casually.

For example, separating inputs, temporary values and outputs can keep an outer-level #1 used to calculate hole spacing unaffected by an inner-level temporary calculation. Conversely, an older program that relies on M98 to share local variables may leave the caller reading an old value if only the call instruction is changed without reviewing the data interface.

Validate the call chain, not just variable numbers

For each call, mark its type, the local-variable level on entry and the expected value after return. Compare these in a logic model with no motion or I/O writes. Treat the same variable number at different levels as different storage locations. Custom-macro functionality and a macro compiler are also distinct; see the OPTION section for function scope.

Related technical articles

FANUC optional rotary-axis control: how the sign of an absolute command selects directionFANUC direction-dependent high-speed position switches: why one coordinate can give different outputsFANUC flexible synchronization: matching speed and aligning phase are separate conditions