Fanuc
M98 P1000 L4P is the subprogram number without the O, and leading zeros are ignored: P1000 calls O1000 and P1 calls O0001. On old Fanuc controls, P takes eight digits where the first four are the repeats, so P00041000 is four passes of O1000.
We use technical and security cookies and, only if you accept, analytics with no cross-site tracking. More in the Cookie policy and Privacy policy.
We use first-party cookies and technical storage to make the site work, Google reCAPTCHA security technology and, only if you accept, Vercel analytics (no cookies, no cross-site tracking). You can accept or reject analytics; both options are equivalent and you can change your choice at any time. More info: Cookie policy, Privacy policy, Legal notice and Terms and conditions.
M98 calls a subprogram and M99 hands control back to the main program. With M98 P1000, the control jumps to program O1000, runs it until it finds the M99 and comes back to the block after the call. It is there so you write once what repeats: a pocket that appears in four places, the machining that has to be done in two setups or a pass given several times stepping down in Z. Repeats are given with L, or with the P itself on old Fanucs.
For reference only: syntax changes with the control, the post-processor and the machine parameters. Check the official manual and run a simulation before cutting. Legal notice.
Fanuc
M98 P1000 L4P is the subprogram number without the O, and leading zeros are ignored: P1000 calls O1000 and P1 calls O0001. On old Fanuc controls, P takes eight digits where the first four are the repeats, so P00041000 is four passes of O1000.
Haas
M98 P1000 L4Same syntax. Haas adds M97 P, which calls a local subprogram by N block number inside the same program: it saves managing two files and is very handy for short programs.
Mitsubishi and some Fanucs
M98 P1000 H50 L2H gives the N sequence number of the subprogram to start from, instead of starting at its first line. It does not exist on every control: check it before using it.
Siemens 840D / 828D
L1000 P4Siemens uses neither M98 nor M99: the subprogram is called by writing its name (L1000, or a name of your own such as TALADROS) and P gives the repeats. The subprogram ends with M17 or with RET. EXTCALL calls a program held in external memory.
Heidenhain TNC (Klartext)
CALL LBL 1 REP4Subprograms are labels inside the same program: LBL 1 marks the start, LBL 0 the end and CALL LBL 1 REP4 runs it four times. To call another complete program you use CALL PGM.
M99 in the main program
/M99An M99 written in the main program returns nowhere: it restarts the program from the beginning, creating an infinite loop. With the block delete slash in front, the operator can break it from the panel. It is the usual trick on machines with a bar feeder.
| Letter | What it sets | Unit |
|---|---|---|
| P (with M98) | Number of the subprogram being called, written without the O. On old Fanucs it can carry eight digits, with the repeats in the first four. | integer |
| L | Number of repeats of the call. M98 P1000 L4 runs the subprogram four times in a row. With no L, it runs once. | integer |
| H | N sequence number inside the subprogram to start from, on Mitsubishi controls and some Fanucs. It is not universal. | block number |
| P (with M99) | N block of the main program to return to, instead of returning to the block after the call. It lets you jump forward or backward on the way back. | block number |
| O number of the subprogram | Header of the subprogram in its own file or its own area of memory. It has to exist in the control: if it is not loaded, the call throws a program not found alarm. | integer (O1000) |
A 12 mm deep slot in steel that has to be taken down in four 3 mm passes. Instead of writing the same thing four times, the pass lives in a subprogram that drops 3 mm in incremental and runs the slot out and back, and the main program calls it four times with L4. Notice that the subprogram leaves the tool at the same point in the plane it started from: if it did not, every repeat would walk further along.
O0098 (RANURA EN CUATRO PASADAS) | ( Header of the main program. ) |
G21 G17 G40 G49 G80 | ( Millimeters, XY plane and a clean state. ) |
G91 G28 Z0. | ( Z to the reference point in incremental before the change. ) |
T4 M06 (FRESA D10) | ( 10 mm cutter. ) |
G90 G54 G00 X10. Y30. S2800 M03 | ( Absolute, work offset, positioning at the start of the slot and spindle on. ) |
G43 H04 Z50. | ( T4 length offset. ) |
G00 Z0.5 M08 | ( Sits half a millimeter above the face: that is the starting point of the first step down, and the subprogram counts on it. ) |
M98 P2001 L4 | ( Calls subprogram O2001 four times. Each call drops another 3 mm, so by the end the slot is 12 mm deep. ) |
G90 G00 Z50. M09 | ( Back to absolute in case the subprogram left something in incremental, retract in Z and coolant off. ) |
G91 G28 Z0. M05 | ( Z to the reference point and spindle stop. ) |
G90 M30 | ( End of the main program. This M30 is essential: without it, the control would keep reading and walk into the subprogram as if it were new code. ) |
O2001 (UNA PASADA DE LA RANURA) | ( Header of the subprogram. It lives in its own file or its own area of the control memory. ) |
G91 G01 Z-3. F150 | ( Drops 3 mm in incremental from wherever the tool is. That is the key to the repeats: in absolute, the four passes would all go to the same depth. ) |
G90 G01 X150. F700 | ( Runs the slot out, now in absolute. ) |
G01 X10. | ( Comes back along the same slot to the starting point, so the tool ends up where the next step down needs it. ) |
M99 | ( Hands control back to the main program. Since the call carried L4, the control comes back in until the four passes are done and only then carries on with the block after the M98. ) |
First, maintenance: if the pocket repeats in six positions and one dimension has to change, you change it in one place and not in six. Second, readability: the main program becomes a list of operations you can read at a glance. Third, memory, which on old controls is still a real limit. And fourth, production flexibility: the same subprogram is called from several work offsets to machine several setups, or repeated with L to take successive passes. The cost is that you have to manage two files and that a missing subprogram stops the machine.
A subprogram called with L4 runs four times exactly the same, so if everything inside is absolute, the four passes do the same thing in the same place. What gives the repeat any meaning is that something inside is incremental: dropping another 3 mm in Z, moving another 40 mm in X for the next hole, indexing the fourth axis another step. That is why G91 and G90 live together inside the subprogram and why the main program should write G90 the moment it comes back: whichever mode is active when the M99 runs is the one the rest of the program takes with it.
A subprogram can call another, but there is a limit on levels: Fanuc usually allows four and other controls allow more, so it pays not to build long chains. M99 P hands control back to a particular N block instead of the next one, which is useful for skipping part of the program when it suits, although it makes the code harder to follow. And an M99 written in the main program returns nowhere: it restarts from the first block. With the block delete slash in front, the operator decides from the panel whether the machine keeps producing or stops.
No. You write the number alone: to call O1000 you write M98 P1000. Leading zeros are ignored, so P1 calls O0001. On some old Fanucs the P takes eight digits because the first four are the repeats.
With L: M98 P1000 L4 runs it four times in a row. On the Fanucs that use the eight digit P, P00041000 does the same. For the repeat to be worth anything, there has to be some incremental move inside the subprogram; otherwise the four passes repeat the same path.
M98 calls another program stored separately in the control memory. M97 P calls an N block inside the same program, so everything lives in a single file. M97 is handier for short programs and avoids losing the subprogram when you copy the program to another machine; M98 is the standard and works on any control.
It depends on the control: Fanuc usually allows four levels of nesting and other controls allow more. It is a limit nobody remembers until the alarm goes off, so as a shop rule it pays not to go past two or three levels even if the machine takes more.
To make the program start over by itself, in a loop. It is used on machines with a bar feeder or with automation, where the next part comes in on its own. The normal thing is to write it with the block delete slash in front, so the operator can break the loop from the panel at the end of the part in progress.
CNC IDE: editing with G/M tooltips, line inspector, conversion between controls and 2D/3D toolpath.
CNC Alarms and Solutions Guide. Enter the error code or symptom to find the cause and how to repair it at the machine.
Estimate CNC turning and milling cycle time from G-code. Calculate parts per hour with a breakdown of cutting, rapids, canned cycles and tool changes.