# Post Name           : LINUXCNC
# Product             : LATHE
# Machine Name        : STANDARD MODERN
# Control Name        : LINUXCNC 2.9
# Description         : MODIFIED LATHE POST FOR LINUXCNC AND MASTERCAM V9
# Associated Post     : MPLFAN
# Mill/Turn           : YES
# 4-axis/Axis subs.   : YES
# 5-axis              : NO
# Subprograms         : YES
# Canned Cycles       : YES
# Executable          : MPL v9.0
#
# WARNING: THIS POST IS GENERIC AND IS INTENDED FOR MODIFICATION TO
# THE MACHINE TOOL REQUIREMENTS AND PERSONAL PREFERENCE.
#
# --------------------------------------------------------------------------
# Revision log:
# --------------------------------------------------------------------------
# Programmers Note:
#
# TRAVIS 11/07/2023  - Lots of things are modified for use with linuxcnc , this post uses controller offsets only
#                    g33 for spindle sync motion , g33.1 as a canned ridged tap cycle , outputs g43 with every tool change.
#
# CNC 01/12/01  -  Initial post update for V8.1, grt
# CNC 05/17/01  -  Changed parameter that groove 'directcc' was read from, rjm
# CNC 06/01/01  -  Added 'foundcc = zero' in postblock 'psub_call_s', rjm
# CNC 06/19/01  -  Altered thread taper calc. for G92 & G76 threading, rjm
#                  Now takes Acceleration Clearance in account when
#                  calculating the taper parameter for these cycles.
#               -  Altered G92 box threading cycle output, rjm
#                  Force X axis output in 'pthrg92_3' (for spring passes).
#                  No longer restates 'R' taper value on each 'X' block.
# CNC 06/25/01  -  Altered to force output of initial G-code on canned cycles.
# CNC 07/02/01  -  Add cantext to cancel drill and tool retract, jph
# CNC 07/03/01  -  Changed parameter that groove 'directcc' was read from, rjm
# CNC 09/05/01  -  In postblock 'pnullspindle' the additional logic of ->, rjm
#                  'prv_css_actv <> css_actv' was added in 2 if statements. 
#                  This takes care of the unusual (but possible) situation 
#                  were the spindle transitions from CSS -> RPM or RPM -> CSS 
#                  with the SAME speed value at a NULL tlchg.
#                  Ex: (Going from 400RPM -> 400CSS at a NULL Toolchange)
#                - Added 'css_start_rpm' switch to allow disabling the
#                  usual G97S???? RPM initial spindle startup when CSS mode
#                  is programmed.
# CNC 09/21/01  -  Modified logic in pmsicint to address bug with MI2 not being read, jce
# CNC 01/08/02  -  Initial post update for V9.0, rjm
# CNC 02/12/02  -  Added skeleton code for MiscOps example, grt
#
# --------------------------------------------------------------------------
# Features:
# --------------------------------------------------------------------------
#######          MILL/TURN FUNCTIONS SUPPORTED BY THIS POST          #######
#
# This post supports Generic Fanuc code output for mill/turn lathes.
# It is designed to support the features of Mastercam Mill V8.
#
# Following Misc. Integers are used:
#
# mi1 - Work coordinate system: (home_type)
#       -1 = Reference return / Tool offset positioning.
#       0 = G50 with the X and Z home positions.
#       1 = X and Z home positions.
#       2 = WCS of G54, G55.... based on Mastercam settings.
#
# mi2 - Absolute or Incremental positioning at top level
#       0 = absolute
#       1 = incremental
#
# mi3 = Select G28 or G30 reference point return:
#       0 = G28, 1 = G30
#
#mi4 = Canned conversion cycle type selection:
#       Mill-
#       Activates milling axis conversation canned cycles (G107 or G112).
#       1 or -1 activates the cycle, the path continues until next entry is
#       zero, sign switches (1 to -1) forces g113 at null toolchnge, the
#       cycle changes or the tool changes.
#
#Canned text:
#  Entering cantext within Mastercam allows the following functions to
#  enable/disable.
#  cantext value:
#  1 = Stop =  output the "M00" stop code
#  2 = Ostop = output the "M01" optional stop code
#  3 = Bld on = turn on block delete codes in NC lines
#  4 = bLd off = turn off block delete codes in NC lines
#  5 = Ret. tlstk =  output the code to retract the tail stock
#  6 = Adv. tlstk =  output the code to advance the tail stock
#  7 = Ret. chute =  output the code to retract the chute
#  8 = Adv. chute =  output the code to advance the chute
#  9 = Exstp = turn on the exact stop code in the NC line
#  10 = Exstp = turn off the exact stop code in the NC line
#  11 to 99 output the value selected
#
#TURN TOOLPATHS:
#Lathe canned cycles:
# V8 supports lathe canned turning cycles through Mastercam.  This post
# is configured to process them.
#
#MILL TOOLPATHS:
#Mill Layout:
# The term "Reference View" refers to the coordinate system associated
# with the Mill Top view (Alt-F9, the upper gnomon of the three displayed).
# Create the part drawing with the the axis of rotation along the X axis
# of the "Mill Reference View" with the face of the part toward the side
# view (Mill Reference View X plus direction).  The Y plus axis of the
# Mill Reference View indicates the position on the part of C zero
# (View number 3).  The right or left side view are the only legal views
# for face milling.  The view number 3 rotated about the X axis as a
# "single axis rotation" are the only legal views for cross milling
# except for axis substitution where the top view is required.
# Rotation around the part is positive in the CCW direction when viewed
# from the side view.
# (The Chook 'CVIEW' should be used for creating milling tool plane and
# construction plane selections, C axis toolpaths in lathe perform
# this function automatically).
#NOTICE: View number 3 always indicates the location for C zero.  Milling
#        with a turret below the centerline indicates C at 180 degrees.
#
#Mill canned cycles:
#Cylindrical interpolation, G107 canned cycle:
# Cylindrical interpolation is created with axis substitution only.
# Use the Caxis/C_axis Contour toolpath.  Create the geometry from
# view number 4 if the rotation of C axis is CCW.  This prevents producing
# a mirror image.  Wrapped and unwrapped geometry are broken and arcs are
# lost so it is better to create flattened geometry.  Set the parameters
# in Rotary Axis not to 'unroll' and set the correct diameter.
# Use View number 3 as the C0 location.  Set mi4 to activate!
#
#Polar interpolation, G112 canned cycle:
# Polar interpolation is active only for face cutting (Right or Left).
# Use the Caxis/Face Contour toolpath.  Create geometry for the lead in
# and lead out with the start and end position on the View number 3 tool
# axis.  All paths must start and end at the 'C0'location for output to
# be correct.  Chain the entire geometry without using Mastercam leads.
# Set mi4 to activate!
#
#Axis substitution:
# View number 3 is the C zero location on the part and corresponds to the
# Y zero position of the "Mill Reference View".  Positions are wrapped
# from and to the diameter of the part as CCW for the Y positive direction.
# If geometry is drawn from View number 4 (Bottom), it is correct for the
# wrap/unwrap on the diameter.  The radius of the specified diameter is
# added to the Z position in the post.  The Y axis is the only axis to
# be converted with mill/turn.
#
#Simultaneous 4 Axis (11 gcode):
# Full 4 axis toolpaths can be generated from various toolpaths under the
# 'multi-axis' selection (i.e. Rotary 4 axis). All 5 axis paths are
# converted to 4 axis paths where only the angle about the rotation axis
# is resolved. Use View number 3 for the toolplane with all 'multi-axis'.
# 4 and 5 axis toolpaths are converted assuming cross machining only!
#
#Y axis output and machining over part center:
# Output Y axis motion by setting 'Rotary axis/Y axis' in the NC
# parameter page and setting y_axis_mch in the post to one.
# Set 'Rotary axis/Y axis' in a machine with no Y axis (y_axis_mch = 0)
# to force linear/circular position moves in the XZ plane (g18).
# This allows machining over the part center.
#Caution: The machining must stay in the XZ plane at a Y fixed value
# when y_axis_mch = zero because no C (other than the Tplane) or
# Y positions are output!!!  This occurs when selecting C_axis/Cross
# Contour without 'y_axis_mch'.  Use Mill toolpaths for cross profiling.
#
#NOTICE: Milling through the part center with a linear move requires the
#        geometry be broken at the centerline.  Milling through the part
#        center with an arc move in the G18 plane, no Y axis and on the
#        negative side of X, reverses only the arc direction and I sign.
#
#Additional Notes:
# 1) G54 calls are generated where the work offset entry of 0 = G54,
#    1 = G55, etc.
# 2) Metric is applied from the NCI met_tool variable.
# 3) The Tplane angle is added to polar conversion and rotary paths.
# 4) The variable 'absinc' is now pre-defined, set mi2 (Misc. Integer) for
#    the 'top level' absolute/incremental program output.  Subprograms are
#    updated through the Mastercam dialog settings for sub-programs.
# 5) Lathe disables coordinate mirror and rotate subprograms.
# 6) When creating tools the diameter/radius should end as even numbers
#    relative to the machine precision. EX. Enter 1.0002 dia. and not
#    1.0001 dia. with a machine accuracy of .0001.
# 7) Transform subprograms are intended for use with G54... workshifts.
# 8) Incremental motion at a toolchange is calculated from the values
#    entered for home position.
#
# --------------------------------------------------------------------------
# Debugging and program switches
# --------------------------------------------------------------------------
m_one       : -1    #Define constant
zero        : 0     #Define constant
one         : 1     #Define constant
two         : 2     #Define constant
three       : 3     #Define constant
four        : 4     #Define constant
five        : 5     #Define constant
c9k         : 9999  #Define constant


fastmode    : yes   #Enable Quick Post Processing, (set to no for debug)
fastmode    : 1     #Posting speed optimizition
bug1        : 2     #0=No display, 1=Generic list box, 2=Editor
bug2        : 30    #Append postline labels, non-zero is column position?
bug3        : 0     #Append whatline no. to each NC line?
bug4        : 1     #Append NCI line no. to each NC line?
whatno      : yes   #Do not perform whatline branches? (leave as yes)

get_1004    : 0     #Find gcode 1004 with getnextop?
rpd_typ_v7  : 0     #Use Version 7 style contour flags/processing?
strtool_v7  : 2     #Use Version 7+ toolname?
tlchng_aft  : 2     #Delay call to toolchange until move line
cant_tlchng : 1     #Ignore cantext entry on move with tlchng_aft
newglobal   : 1     #Error checking for global variables
getnextop   : 1     #Build the next variable table
cc_1013     : 1     #Read cc_pos on the 1013 line, lathe
#uselstation: 1     #Use Version 7 mill tool reference

# --------------------------------------------------------------------------
# General Output Settings
# --------------------------------------------------------------------------
sub_level   : 1     #Enable automatic subprogram support
breakarcs   : 1     #Break arcs, 0 = no, 1 = quadrants, 2 = 180deg. max arcs
arcoutput   : 0     #0 = IJK, 1 = R no sign, 2 = R signed neg. over 180
arctype     : 2     #Arc center 1=abs, 2=St-Ctr, 3=Ctr-St, 4=unsigned inc.
do_full_arc : 0     #Allow full circle output? 0=no, 1=yes
helix_arc   : 0     #Support helix arc output, 0=no, 1=all planes, 2=XY plane only
arccheck    : 1     #Convert small arcs to linear, 1=ltol, 2=atol,ltol
atol        : .01   #Angularity tolerance for arccheck = 2
ltol        : .002  #Length tolerance for arccheck = 1
vtol        : .0001 #System tolerance
maxfeedpm   : 140   #Limit for feed in inch/min
lcc_move    : .05   #Enter the move in X, Z for lathe canned cycle comp.
ltol_m      : .05   #Length tolerance for arccheck = 1, metric
vtol_m      : .0025 #System tolerance, metric
maxfeedpm_m : 10000 #Limit for feed in mm/min
lcc_move_m  : 1.25  #Enter the move in X, Z for lathe canned cycle comp.,mm

force_wcs   : yes   #Force WCS output at every toolchange?
spaces      : 2     #No. of spaces to add between fields
omitseq     : yes   #Omit sequence no. (use -1 to enable sequence for LCC)
seqmax      : 9999  #Max. sequence no.
nobrk       : no    #Omit breakup of x, y & z rapid moves
progname    : 1     #Use uppercase for program name
rotaxtyp    : 3     #Rotary axis type for toolplane
tooltable   : 3     #Read for tool table and pwrtt (3 recalls pwrtt at sof)
ref_ret     : 0     #G29 / G30 return variable from Mi3
css_start_rpm : yes #Do direct RPM spindle start prior to CSS ?


# --------------------------------------------------------------------------
# Enable Canned Drill Cycle Postblocks, set for mill and lathe
# --------------------------------------------------------------------------
pcuttypldrl   #Change cut parameters for lathe drill
      usecandrill = 0
      usecanpeck = 0
      usecanchip = 0
      usecantap = 1
      usecanbore1 = 0
      usecanbore2 = 0
      usecanmisc1 = 0
      usecanmisc2 = 0

pcuttypmdrl   #Change cut parameters for mill drill
      usecandrill = 1
      usecanpeck = 1
      usecanchip = 1
      usecantap = 1
      usecanbore1 = 1
      usecanbore2 = 1
      usecanmisc1 = 1
      usecanmisc2 = 0

# --------------------------------------------------------------------------
# Machine Specific Settings
# --------------------------------------------------------------------------
#Machine axis switches, initial
y_axis_mch  : no    #Machine has Y axis, 0=no, 1=yes
old_new_sw  : 1     #Switch old (6T), new (0T+) cycle formats, 0=old, 1=new
wcs_origin  : 0     #Always use the WCS origin for coordinates
dia_mult    : -1     #Multiplier for output on X axis (Neg. switches sign of X)
y_mult      : 1     #Multiplier for output on Y axis (Neg. switches sign of Y)
z_mult      : 1     #Multiplier for output on Z axis (Neg. switches sign of Z)
dia_shift   : 0     #Shift for output on X axis, radial entry
y_shift     : 0     #Shift for output on Y axis
z_shift     : 0     #Shift for output on Z axis
map_home    : yes   #Use home positions as enterd or map to machine axis

#C axis and Index switches
str_cax_abs "C"     #String address for absolute rotary axis
str_cax_inc "H"     #String address for incremental rotary axis
str_index   "B"     #String address for indexer
frc_cinit   : 1     #Force C axis reset at toolchange
c_shift     : 0     #Shift for output on bottom turrets with C axis
ctol        : 270   #Tolerance in deg. of inc. move before 'rev' flag changes
ctable      : 15    #Degrees for each index step with indexing spindle
ixtol       : .01   #Tolerance in deg. for index error
maxfrdeg    : 2000  #Limit for feed in deg/min
frdegstp    : 10    #Step limit for rotary feed in deg/min

#Spindle switches and values
use_gear    : 1      #Output gear selection code, 0=no, 1=yes
cool_w_spd  : 0      #Output coolant with spindle code, 0=no, 1=yes
max_speedl0 : 2250   #Maximum spindle speed (lathe), Bottom turret/Left spindle
min_speedl0 : 20     #Minimum spindle speed
max_speedm0 : 2500   #Maximum spindle speed (mill)
min_speedm0 : 50     #Minimum spindle speed
max_speedl1 : 3600   #Maximum spindle speed (lathe), Top turret/Left spindle
min_speedl1 : 20     #Minimum spindle speed
max_speedm1 : 2500   #Maximum spindle speed (mill)
min_speedm1 : 50     #Minimum spindle speed
max_speedl2 : 3600   #Maximum spindle speed (lathe), Bottom turret/Right spindle
min_speedl2 : 20     #Minimum spindle speed
max_speedm2 : 2500   #Maximum spindle speed (mill)
min_speedm2 : 50     #Minimum spindle speed
max_speedl3 : 3600   #Maximum spindle speed (lathe), Top turret/Right spindle
min_speedl3 : 20     #Minimum spindle speed
max_speedm3 : 2500   #Maximum spindle speed (mill)
min_speedm3 : 50     #Minimum switchesspindle speed

#Machining position turret/spindle settings
# Switch strings based on turret position top/bottom-left/right and cut type.
# Turret position is based on the Mastercam settings (see lathtype).
# Strings are re-assigned for output in the routine psw_str_mult.
# The string variable sw_string holds the place position value to determine
# how to assign the strings.  Planes are relative to the view from Mastercam.
# Assign the 17 digit string following the alpha columns below:
# A - C axis, 1 = axis winds, 2 = axis signed, 3 = indexer
# B - Spindle direction, 0 = normal, 1 = reverse
# C - Plane 0 arc/comp, 0 = normal, 1 = switch
# D - Plane 1 arc/comp, 0 = normal, 1 = switch
# E - Plane 2 arc/comp, 0 = normal, 1 = switch
# F - Plane 0, 0 = G17, 1 = G19, 2 = G18
# G - Plane 1, 0 = G17, 1 = G19, 2 = G18
# H - Plane 2, 0 = G17, 1 = G19, 2 = G18
# Decimal (required)
# I - Plane 0, X axis, 0 = normal, 1 = switch sign from basic
# J - Plane 0, Y axis, 0 = normal, 1 = switch sign from basic
# K - Plane 0, Z axis, 0 = normal, 1 = switch sign from basic
# L - Plane 1, X axis, 0 = normal, 1 = switch sign from basic
# M - Plane 1, Y axis, 0 = normal, 1 = switch sign from basic
# N - Plane 1, Z axis, 0 = normal, 1 = switch sign from basic
# O - Plane 2, X axis, 0 = normal, 1 = switch sign from basic
# P - Plane 2, Y axis, 0 = normal, 1 = switch sign from basic
# Q - Plane 2, Z axis, 0 = normal, 1 = switch sign from basic
use_only_tl : 1     #Use only Top turret/Left spindle settings (below) for
                    #all Mastercam turret/spindle selections
                    #When configuring for multi-spindle/turret set to 0

#Columns-    ABCDEFGH.IJKLMNOPQ #Turret/Spindle            #Path Type
scase_tl_c1  10000222.000000000 #Top turret/Left spindle, Turning cut
scase_tl_c2  11000012.000000000 #Top turret/Left spindle, Right Face cut
scase_tl_c_2 11110012.000000000 #Top turret/Left spindle, Left Face cut
scase_tl_c3  10010102.000000000 #Top turret/Left spindle, Cross cut
scase_tl_c4c 10000111.000000000 #Top turret/Left spindle, Y axis subs. Cycle
scase_tl_c4  10000222.000000000 #Top turret/Left spindle, Y axis subs.
scase_tl_c5  10000222.000000000 #Top turret/Left spindle, Multisurf Rotary

#Columns-    ABCDEFGH.IJKLMNOPQ
scase_bl_c1  10000222.000000000 #Bottom turret/Left spindle, Turning cut
scase_bl_c2  11000012.000000000 #Bottom turret/Left spindle, Right Face cut
scase_bl_c_2 11110012.000000000 #Bottom turret/Left spindle, Left Face cut
scase_bl_c3  10010102.000000000 #Bottom turret/Left spindle, Cross cut
scase_bl_c4c 10000111.000000000 #Bottom turret/Left spindle, Y axis subs. Cycle
scase_bl_c4  10000222.000000000 #Bottom turret/Left spindle, Y axis subs.
scase_bl_c5  10000222.000000000 #Bottom turret/Left spindle, Multisurf Rotary

#Columns-    ABCDEFGH.IJKLMNOPQ
scase_tr_c1  10000222.000000000 #Top turret/Right spindle, Turning cut
scase_tr_c2  11000012.000000000 #Top turret/Right spindle, Right Face cut
scase_tr_c_2 11110012.000000000 #Top turret/Right spindle, Left Face cut
scase_tr_c3  10010102.000000000 #Top turret/Right spindle, Cross cut
scase_tr_c4c 10000111.000000000 #Top turret/Right spindle, Y axis subs. Cycle
scase_tr_c4  10000222.000000000 #Top turret/Right spindle, Y axis subs.
scase_tr_c5  10000222.000000000 #Top turret/Right spindle, Multisurf Rotary

#Columns-    ABCDEFGH.IJKLMNOPQ
scase_br_c1  10000222.000000000 #Bottom turret/Right spindle, Turning cut
scase_br_c2  11000012.000000000 #Bottom turret/Right spindle, Right Face cut
scase_br_c_2 11110012.000000000 #Bottom turret/Right spindle, Right Face cut
scase_br_c3  10010102.000000000 #Bottom turret/Right spindle, Cross cut
scase_br_c4c 10000111.000000000 #Bottom turret/Right spindle, Y axis subs. Cycle
scase_br_c4  10000222.000000000 #Bottom turret/Right spindle, Y axis subs.
scase_br_c5  10000222.000000000 #Bottom turret/Right spindle, Multisurf Rotary

# --------------------------------------------------------------------------
# Common User-defined Variable Initializations (not switches!)
# --------------------------------------------------------------------------
cuttype     : 0     #Flag for cut type
                    #1 = Lathe
                    #2 = Right face cut (a = 90)
                    #-2 = Left face cut  (a = -90)
                    #3 = Cross cut      (a = 0)
                    #4 = Y axis substitution
                    #5 = Multisurf Rotary 4 axis or 11 gcode
lathtype    : 0     #Lathe turret and spindle selection
                    #0 = Bottom turret/Left spindle
                    #1 = Top turret/Left spindle
                    #2 = Bottom turret/Right spindle
                    #3 = Top turret/Right spindle
lathecc     : 0     #Flag for canned turning cycle type
                    #1 = G71/G72 rough cycle
                    #2 = G73 pattern repeating cycle
                    #3 = G74/G75 groove cycle
                    #4 = Finish pass for types 1 and 2
                    #Neg.=rough and finish, Pos.=rough only
millcc      : 0     #Flag for mill conversion cycle type

#Cantext activated flags
bld         : 0     #Block delete active
exact       : 0     #Exact stop active
chute       : 0     #Toggle for part catcher operation
tlstk       : 0     #Toggle for tailstock operation

#General user variables
xia         : 0     #Formated absolute value for X
yia         : 0     #Formated absolute value for Y
zia         : 0     #Formated absolute value for Z
cia         : 0     #Formated absolute value for C
copy_x      : 0     #X value copy, prevent compound operations
copy_y      : 0     #Y value copy, prevent compound operations
copy_z      : 0     #Z value copy, prevent compound operations
xa          : 0     #Absolute coordinate mapped value for X
ya          : 0     #Absolute coordinate mapped value for Y
za          : 0     #Absolute coordinate mapped value for Z
cfeed_x     : 0     #Absolute mapped/rotated unshifted value for X
cfeed_y     : 0     #Absolute mapped/rotated unshifted value for Y
cfeed_z     : 0     #Absolute mapped/rotated unshifted value for Z
xca         : 0     #Absolute unshifted value for XC
yca         : 0     #Absolute unshifted value for YC
zca         : 0     #Absolute unshifted value for ZC
sav_xa      : 0     #X saved value
sav_ya      : 0     #Z saved value
sav_za      : 0     #Z saved value
sav_xh      : 0     #X saved value
sav_yh      : 0     #Z saved value
sav_zh      : 0     #Z saved value

conversion  : 12    #Unit conversion value, do not change
result      : 0     #Return value for functions
compok      : 1     #Flag to output cutter compensation
toolchng    : 1     #On a toolchange flag
plane       : -1    #Initialize plane
ipr_actv    : -1    #Initialize active feed type
mach_plane  : 0     #Plane mapped to machine
sav_arcout  : arcoutput #Arc output type saved
breakarcss   : breakarcs #Break arcs, 0 = no, 1 = quadrants, 2 = 180deg. max arcs

sav_absinc  : 0     #Saved absolute/Incremental
spd_rev     : 0     #Flag to reverse spindle direction
sav_gcode   : 0     #Gcode saved
sav_feed    : 0     #Feed saved
sav_ipr     : 0     #IPR saved
sav_feedcc  : 0     #Feed saved, canned cycle
sav_iprcc   : 0     #IPR saved, canned cycle
sav_spdir   : 0     #Spindle direction saved
sav_omitsq  : 0     #Omitseq saved
sav_subout  : 0     #Saved subout
sav_frc_wcs : 0     #Force work offset flag saved
sav_bug2    : bug2  #Saved setting for bug2
sav_cutpos2 : 0     #Patch to handle cutpos2 flag through null toolchnages
cir_at_zero : 0     #Arc center at centerline in XY plane, -1 if not plane 0
pnt_at_zero : 0     #Position at centerline with milling
c_ax_flp    : 0     #G18 plane with C axis arcs in neg. range
home_type   : 0     #Flag for type of home location, read from misc. int.
rslt_plc    : 0     #Return value from plcval
rslt_upd    : 0     #Return value from updstr

#Drilling variables
drlgsel     : -1    #Drill Select Initialize
drillref    : -1    #Select drill reference
peckacel    : 0     #Fractional percent to reduce peck2 when usecan.. : no
mdrl_dir    : 0     #Mill drill direction for boolean, 0 = face, 1 = cross
zdrl_x      : 0     #Drill point, mapped X
zdrl_y      : 0     #Drill point, mapped Y
zdrl_z      : 0     #Drill point, mapped Z

#Threading variables
nstart_cnt  : 0     #Counter for multiple threads
thd_vlen    : 0     #Incremental X move for G76 mult starts
xmaj_thd    : 0     #X major dia. from parameters
zstrt_thd   : 0     #Z start from parameters
zend_thd    : 0     #Z end from parameters
face_thd    : 0     #Face thread from parameters

#Spindle variables
max_speed   : 0     #Maximum spindle speed (set by turret definition)
min_speed   : 0     #Minimum spindle speed (set by turret definition)
speedrpm    : 0     #Spindle calculation RPM
g_speed     : 0     #Generic positive spindle speed (rpm or css)
g_spdir     : 0     #Generic spindle direction
speedx      : 0     #Test spindle calculation X position
gear_spd    : 0     #Absolute value of gear speed

# Lathe canned cycle variables
gcodecc     : 0     #Canned turning cycle gcode
y_axis      : 0     #Flag for Y axis machining (implies over center)
directcc    : 0     #Direction from parameters
dopeckcc    : 0     #Do peck from groove parameters
foundcc     : 0     #Return found from G70 read
cc_stop_fcc : 0     #Stop output with rough only
lcc_cc_pos  : 0     #Position for lathe canned cycle cutter comp. enable
lccdirx     : 0     #Canned cycle X vector direction
lccdirz     : 0     #Canned cycle Z vector direction
lcc_xcst    : 0     #Lathe canned cycle contour start position
lcc_ycst    : 0     #Lathe canned cycle contour start position
lcc_zcst    : 0     #Lathe canned cycle contour start position
lcc_xcend   : 0     #Lathe canned cycle contour end position
lcc_ycend   : 0     #Lathe canned cycle contour end position
lcc_zcend   : 0     #Lathe canned cycle contour end position

#Vector Varibles for Mapp ing and Rotatary Calculations
#Lathe - Uses top matrix - initialize here
m1          : 1
m5          : 1
m9          : 1

#C rotation vector
caxisx      : 0
caxisy      : 0
caxisz      : 1

#Mapping matrix
#Home position mapping matrix
hmtx1       : 1
hmtx2       : 0
hmtx3       : 0
hmtx4       : 0
hmtx5       : 1
hmtx6       : 0
hmtx7       : 0
hmtx8       : 0
hmtx9       : 1

#Cut type mapping matrix
mmtx1       : 1
mmtx2       : 0
mmtx3       : 0
mmtx4       : 0
mmtx5       : 1
mmtx6       : 0
mmtx7       : 0
mmtx8       : 0
mmtx9       : 1

#Side matrix
smtx1       : 0
smtx2       : 1
smtx3       : 0
smtx4       : 0
smtx5       : 0
smtx6       : 1
smtx7       : 1
smtx8       : 0
smtx9       : 0

#Cross matrix
cmtx1       : -1
cmtx2       : 0
cmtx3       : 0
cmtx4       : 0
cmtx5       : 0
cmtx6       : 1
cmtx7       : 0
cmtx8       : 1
cmtx9       : 0

#Back matrix
bmtx1       : 0
bmtx2       : -1
bmtx3       : 0
bmtx4       : 0
bmtx5       : 0
bmtx6       : 1
bmtx7       : -1
bmtx8       : 0
bmtx9       : 0

#Axis Subs matrix
amtx1       : 1
amtx2       : 0
amtx3       : 0
amtx4       : 0
amtx5       : 0
amtx6       : 1
amtx7       : 0
amtx8       : 1
amtx9       : 0

#C-axis variables for calculations
c_axistype  : 0     #1 = C axis winds-up, 2 = C axis signed absolute
                    #3 = index positioning (do not set here, use string)
ipr_type    : 0     #Feedrate for Rotary, 0 = UPM, 1 = DPM
csav        : 0     #Initial c axis result from pxyzcout call
czero_csav  : 0     #Save csav when circle at zero detected
c_wnd       : 0     #Calculation for c axis position tracking (abs-wind)
prvc_wnd    : 0     #Saved cout calculation from deg., this is cabs in mpfan
rev         : 0     #C axis wind-up multiplier
prvfrdeg    : 0     #Feedrate deg/min actual
circum      : 0     #Circumference
ldelta      : 0     #Linear distance for deg/min, linear
cdelta      : 0     #Total linear and angular motion for deg/min
cldelta     : 0     #Calculation for deg/min, linear and rotary
sav_rev     : 0     #Saved revolution counter
indx_out    : c9k   #Rotation direction calculation
fmt     17  frdeg   #Feedrate deg/min actual
fmt     20  indx_mc #Rotation direction calculation

#Plane/axis sign modifier (always 1 or -1)
pl_ax_m0x   : 1
pl_ax_m0y   : 1
pl_ax_m0z   : 1
pl_ax_m1x   : 1
pl_ax_m1y   : 1
pl_ax_m1z   : 1
pl_ax_m2x   : 1
pl_ax_m2y   : 1
pl_ax_m2z   : 1

# --------------------------------------------------------------------------
# Buffer definitions
# --------------------------------------------------------------------------
#Buffer 1, toolchange information
wc1           : 1       #Initial count for write buffer 1
rc1           : 1       #Initial count for read buffer 1
nc1           : 2       #Initial count for read buffer 1 into next record
size1         : 0       #Buffer 1 size

# Current tool information
c1_gcode      : 0       #Buffer 1
c1_xh         : 0       #Buffer 1
c1_yh         : 0       #Buffer 1
c1_zh         : 0       #Buffer 1
c1_tox        : 0       #Buffer 1
c1_toy        : 0       #Buffer 1
c1_toz        : 0       #Buffer 1
c1_cc_pos     : 0       #Buffer 1
c1_tool       : 0       #Buffer 1
c1_tloffno    : 0       #Buffer 1
c1_maxss      : 0       #Buffer 1
c1_ss         : 0       #Buffer 1
c1_spdir      : 0       #Buffer 1
c1_css_actv   : 0       #Buffer 1
c1_fr_pos     : 0       #Buffer 1
c1_ipr_actv   : 0       #Buffer 1
c1_coolant    : 0       #Buffer 1
c1_nextdc     : 0       #Buffer 1
c1_posttype   : 0       #Buffer 1
c1_cuttype    : 0       #Buffer 1
c1_lathtype   : 0       #Buffer 1
c1_gcodecc    : 0       #Buffer 1
c1_lathecc    : 0       #Buffer 1
c1_millcc     : 0       #Buffer 1
c1_y_axis     : 0       #Buffer 1
c1_x_min      : 0       #Buffer 1
c1_x_max      : 0       #Buffer 1

# Next tool information
n1_gcode      : 0       #Buffer 1
n1_xh         : 0       #Buffer 1
n1_yh         : 0       #Buffer 1
n1_zh         : 0       #Buffer 1
n1_tox        : 0       #Buffer 1
n1_toy        : 0       #Buffer 1
n1_toz        : 0       #Buffer 1
n1_cc_pos     : 0       #Buffer 1
n1_tool       : 0       #Buffer 1
n1_tloffno    : 0       #Buffer 1
n1_maxss      : 0       #Buffer 1
n1_ss         : 0       #Buffer 1
n1_spdir      : 0       #Buffer 1
n1_css_actv   : 0       #Buffer 1
n1_fr_pos     : 0       #Buffer 1
n1_ipr_actv   : 0       #Buffer 1
n1_coolant    : 0       #Buffer 1
n1_nextdc     : 0       #Buffer 1
n1_posttype   : 0       #Buffer 1
n1_cuttype    : 0       #Buffer 1
n1_lathtype   : 0       #Buffer 1
n1_gcodecc    : 0       #Buffer 1
n1_lathecc    : 0       #Buffer 1
n1_millcc     : 0       #Buffer 1
n1_y_axis     : 0       #Buffer 1
n1_x_min      : 0       #Buffer 1
n1_x_max      : 0       #Buffer 1

fbuf 1 0 27 0           #Buffer 1
# --------------------------------------------------------------------------
#Buffer 2, recall lathe canned turning cycle line numbers
wc2           : 1       #Initial count for write buffer 2
rc2           : 1       #Initial count for read buffer 2
size2         : 0       #Buffer 2 size

fcc_subid     : 0       #Buffer 2
fcc_ng70s     : 0       #Buffer 2
fcc_ng70e     : 0       #Buffer 2

fbuf 2 0 3 0            #Buffer 3
# --------------------------------------------------------------------------
#Buffer 3, output strings for lathe canned turning cycles
wc3           : 1       #Initial count for write buffer 3
rc3           : 1       #Initial count for read buffer 3
size3         : 0       #Buffer 3 size

string3                 #Buffer 3

fbuf 3 0 80 1           #Buffer 3
# --------------------------------------------------------------------------
# Format statements - n=nonmodal, l=leading, t=trailing, i=inc, d=delta
# --------------------------------------------------------------------------
#Default english/metric position format statements
fs2 1   0.7 0.6     #Decimal, absolute, 7 place, default for initialize (:)
fs2 2   0.4 0.3     #Decimal, absolute, 4/3 place
fs2 3   0.4 0.3d    #Decimal, delta, 4/3 place
#Common format statements
fs2 4   1 0 1 0     #Integer, not leading
fs2 5   2 0 2 0l    #Integer, force two leading
fs2 6   3 0 3 0l    #Integer, force three leading
fs2 7   4 0 4 0l    #Integer, force four leading
fs2 9   0.1 0.1     #Decimal, absolute, 1 place
fs2 10  0.2 0.2     #Decimal, absolute, 2 place
fs2 11  0.3 0.3     #Decimal, absolute, 3 place
fs2 12  0.4 0.4     #Decimal, absolute, 4 place
fs2 13  0.5 0.5     #Decimal, absolute, 5 place
fs2 14  0.3 0.3d    #Decimal, delta, 3 place
fs2 15  0.2 0.1     #Decimal, absolute, 2/1 place
fs2 16  0 4 0 4t    #No decimal, absolute, 4 trailing
#Default english/metric feed format statements
fs2 17  0.2 0.1     #Decimal, absolute, 2/1 place
fs2 18  0.4 0.3     #Decimal, absolute, 4/3 place
fs2 19  0.5 0.4     #Decimal, absolute, 5/4 place
fs2 20  1 0 1 0n    #Integer, forced output

# --------------------------------------------------------------------------
#String and string selector definitions for NC output
# --------------------------------------------------------------------------
#Address string definitions
stra        "A"     #String for address A
strd        "D"     #String for address D
stre        "K"     #String for address E
strf        "F"     #String for address F
stri        "I"     #String for address I
strk        "K"     #String for address K
strm        "M"     #String for address M
stro        "O"     #String for address O
strp        "P"     #String for address P
strq        "Q"     #String for address Q
stru        "U"     #String for address U
strw        "W"     #String for address W
srad        "R"     #String for address R (radius)
srminus     "R-"    #String for address R- (minus radius)
sc_minus    "-"     #Manipulated string for signed rotary minus

#Tool note
stoper              #String for tool notes
stinsert    " INSERT - "#String for tool notes
stinsert2           #String for tool notes

#String definitions
sg50        "D"   #String for spindle clamp and work coordinate

#Cantext string definitions (spaces must be padded here)
sm00        "M00"   #String for stop
sm01        "M01"   #String for optional stop
strtextno           #String for cantext
strcantext          #String for cantext

sblank              #Empty string
sw_string           #String for lathe turret type settings
# --------------------------------------------------------------------------
# Error message strings
# --------------------------------------------------------------------------
saxiserror  "ERROR-WRONG AXIS OF ROTATION, ROTATE ON X AXIS OF WCS"
sindxerror  "WARNING-INDEX ANGLE DOES NOT MATCH POST SETTING ('ctable')"
ssignerror  "WARNING-SIGNED AXIS POSITIONING MOVE OVER 360 DEGREES"
swrkserror  "WARNING-WORK OFFSET IS CHANGED IN A SUBPROGRAM"
stoperror   "ERROR-AXIS SUBSTITUTION MUST USE THE TOP TOOLPLANE"
scutterror  "ERROR-A VALID CUT TYPE WAS NOT FOUND, CHECK ROTARY SETTINGS"
sfccerror   "ERROR-MATCHING G70 FINISH PROFILE WAS NOT FOUND"
s5drlerror  "ERROR-5 AXIS DRILLING REQUIRES LONG CYCLE ('usecan..')"
slthrmerror "ERROR-ROTATE/MIRROR SUBPROGRAM NOT ALLOWED WITH LATHE PATH"
smilrmerror "ERROR-ROTATE/MIRROR PROGRAM ROUTINE NOT ALLOWED"
smny50error "ERROR-G50 AND HOME ('mi1') DOES NOT SUPPORT MULTIPLE TOOL SUBPROGRAM"
shomeserror "ERROR-HOME ('mi1') DOES NOT SUPPORT TRANSFORM SUBPROGRAM"
symoterror  "WARNING-Y AXIS MOTION AND ('y_axis_mch') NOT SET"

# --------------------------------------------------------------------------
# General G and M Code String select tables
# --------------------------------------------------------------------------
# Strings for switch based on planes, see psw_str_mult
sxg02   G3      #Circular interpolation CW
sxg03   G2      #Circular interpolation CCW
# --------------------------------------------------------------------------
# Motion G code selection
sg00    G0      #Rapid
sg01    G1      #Linear feed
sg02    G3      #Circular interpolation CW
sg03    G2      #Circular interpolation CCW
sg04    G4      #Dwell
sgcode          #Target for string

fstrsel sg00 gcode sgcode
# --------------------------------------------------------------------------
# Motion G code selection, plane 1
sg00_1  G0      #Rapid
sg01_1  G1      #Linear feed
sg02_1  G2      #Circular interpolation CW
sg03_1  G3      #Circular interpolation CCW
sg04_1  G4      #Dwell
sgcode1         #Target for string

fstrsel sg00_1 gcode sgcode1
# --------------------------------------------------------------------------
# Motion G code selection, plane 2
sg00_2  G0      #Rapid
sg01_2  G1      #Linear feed
sg02_2  G2      #Circular interpolation CW
sg03_2  G3      #Circular interpolation CCW
sg04_2  G4      #Dwell
sgcode2         #Target for string

fstrsel sg00_2 gcode sgcode2
# --------------------------------------------------------------------------
# Strings for switch based on planes, see psw_str_mult
sxg17   G17     #XY plane code
sxg19   G19     #YZ plane code
sxg18   G18     #XZ plane code
swstr              #Target for string

fstrsel sxg17 rslt_plc swstr
# --------------------------------------------------------------------------
# Select work plane G code
sg17    G17     #XY plane code
sg19    G19     #YZ plane code
sg18    G18     #XZ plane code
sgplane            #Target string

fstrsel sg17 plane sgplane
# --------------------------------------------------------------------------
#Select english/metric code
sg20    G20     #Inch code
sg21    G21     #Metric code
smetric         #Target string

fstrsel sg20 met_tool smetric
# --------------------------------------------------------------------------
#Select reference return code
sg28    G28     #First reference point return
sg30    G30     #Second reference point return
sg28ref         #Target string

fstrsel sg28 ref_ret sg28ref
# --------------------------------------------------------------------------
# Strings for switch based on planes, see psw_str_mult
sxg41   G41     #Cutter compensation left
sxg42   G42     #Cutter compensation right
# --------------------------------------------------------------------------
# Cutter compensation G code selection, plane 0
sg40    G40     #Cancel cutter compensation
sg41    G41     #Cutter compensation left
sg42    G42     #Cutter compensation right
sccomp          #Target for string

fstrsel sg40 cc_pos sccomp
# --------------------------------------------------------------------------
# Cutter compensation G code selection, plane 1
sg40_1  G40     #Cancel cutter compensation
sg41_1  G41     #Cutter compensation left
sg42_1  G42     #Cutter compensation right
sccomp1         #Target for string

fstrsel sg40_1 cc_pos sccomp1
# --------------------------------------------------------------------------
# Cutter compensation G code selection, plane 2
sg40_2  G40     #Cancel cutter compensation
sg41_2  G41     #Cutter compensation left
sg42_2  G42     #Cutter compensation right
sccomp2         #Target for string

fstrsel sg40_2 cc_pos sccomp2
# --------------------------------------------------------------------------
# Select canned cycle type, profile is direction of finish profile vector
sthdg32 G33     #Cycle type G33
sthdg76 G76     #Cycle type G76
sthdg92 G92     #Cycle type G92
sthdg33 G33     #Cycle type G33 with alternating position
sthdgcode       #Target for string

fstrsel sthdg32 thdtype sthdgcode
# --------------------------------------------------------------------------
# Select canned cycle type
sg70    G70     #Cycle type G70
sg71    G71     #Cycle type G71
sg72    G72     #Cycle type G72
sg73    G73     #Cycle type G73
sg74    G74     #Cycle type G74
sg75    G75     #Cycle type G75
scclgcode       #Target for string

fstrsel sg70 gcodecc scclgcode
# --------------------------------------------------------------------------
# Canned drill cycle string select
sg80_f  G81     #drill face
sg80_fd G82     #drill face w/dwell
sg81_f  G83     #peck face
sg81_fd G83     #peck face w/dwell
sg82_f  G83     #chpbrk face
sg82_fd G83     #chpbrk face w/dwell
sg83_f  G84     #tap right face
sg83_fd G84     #tap left face
sg84_f  G85     #bore1 face
sg84_fd G85     #bore1 face w/dwell
sg85_f  G86     #bore2 face
sg85_fd G88     #bore2 face w/dwell
sg86_f  G87     #misc1 face
sg86_fd G87     #misc1 face w/dwell
sg87_f  G8?     #misc2 face
sg87_fd G8?     #misc2 face w/dwell
sgdrillf        #Target for string

fstrsel sg80_f drlgsel sgdrillf
# --------------------------------------------------------------------------
sg80_c  G81     #drill cross
sg80_cd G82     #drill cross w/dwell
sg81_c  G83     #peck cross
sg81_cd G83     #peck cross w/dwell
sg82_c  G87     #chpbrk cross
sg82_cd G87     #chpbrk cross w/dwell
sg83_c  G88     #tap right cross
sg83_cd G88     #tap left cross
sg84_c  G89     #bore1 cross
sg84_cd G89     #bore1 cross w/dwell
sg85_c  G86     #bore2 cross
sg85_cd G88     #bore2 cross w/dwell
sg86_c  G87     #misc1 cross
sg86_cd G87     #misc1 cross w/dwell
sg87_c  G8?     #misc2 cross
sg87_cd G8?     #misc2 cross w/dwell
sgdrillc        #Target for string

fstrsel sg80_c drlgsel sgdrillc
# --------------------------------------------------------------------------
# Select incremental or absolute G code
sg90    G90     #Absolute code
sg91    G91     #Incremental code
sgabsinc        #Target string

fstrsel sg90 absinc sgabsinc
# --------------------------------------------------------------------------
# RPM/CSS code selection
sg97    G97     #RPM
sg96    G96     #CSS
sg9697          #Target for string

fstrsel sg97 css_actv sg9697
# --------------------------------------------------------------------------
# Feed mode G code selection
sg98    G94     #UPM
sg99    G95     #UPR
sgfeed          #Target for string

fstrsel sg98 ipr_actv sgfeed
# --------------------------------------------------------------------------
# C axis cycles
sg107   G107    #C axis cylindrical interpolation enable
sg108   G107    #C axis cylindrical interpolation disable
sg112   G112    #C axis face polar interpolation enable
sg113   G113    #C axis face polar interpolation disable
# --------------------------------------------------------------------------
#Canned drill cycle reference height
sg198   #G198   #Reference at initht
sg199   #G199   #Reference at refht
sgdrlref        #Target for string

fstrsel sg198 drillref sgdrlref
# --------------------------------------------------------------------------
# Generate string for spindle, lathe
sm04    M04     # Spindle reverse - no coolant
sm05    M05     # Spindle off     - no coolant
sm03    M03     # Spindle forward - no coolant
sm14    M14     # Spindle reverse - coolant
sm05c   M15     # Spindle off     - coolant
sm13    M13     # Spindle forward - coolant
spindle_l       #Target for string

fstrsel sm04 g_spdir spindle_l
# --------------------------------------------------------------------------
# Coolant M code selection
sm09    M9      #Coolant Off
sm08    M8      #Coolant Flood
sm08_1  M8      #Coolant Mist
sm08_2  M8      #Coolant Tool
scoolant        #Target for string

# --------------------------------------------------------------------------
#linuxcnc tool change
sm06    M06     #change tool
sm43    G43     #length offset
sg07    G07     #diameter mode
sg08    G08     #radius mode
sg91_1  G91.1   #incremental arcs
sg90_1  G90.1   #absolute arcs
sthdg33_1 G33.1 #ridgid tap

fstrsel sm09 coolant scoolant
# --------------------------------------------------------------------------
# Table rotation direction, index
sindx_cw   M22   #Rotate CW code
sindx_ccw  M21   #Rotate CCW code
sindx_mc        #Target for string

fstrsel sindx_cw indx_mc sindx_mc
# --------------------------------------------------------------------------
# C axis mode
sm23    M23     #C axis enable
sm24    M24     #C axis disable

# --------------------------------------------------------------------------
# Tailstock M code selection
sm26    M26     #Tailstock retracted
sm25    M25     #Tailstock engaged
stlstk          #Target for string

fstrsel sm26 tlstk stlstk
# --------------------------------------------------------------------------
# Generate string for spindle, mill
sm52    M52     # Spindle reverse - no coolant
sm55    M55     # Spindle off     - no coolant
sm51    M51     # Spindle forward - no coolant
sm54    M54     # Spindle reverse - coolant
sm55c   M55     # Spindle off     - coolant
sm53    M53     # Spindle forward - coolant
spindle_m       #Target for string

fstrsel sm52 g_spdir spindle_m
# --------------------------------------------------------------------------
# Chute M code selection
sm73    M73     #Chute retracted
sm74    M74     #Chute engaged
schute          #Target for string

fstrsel sm73 chute schute
# --------------------------------------------------------------------------
# Define the gear selection code
flktbl  1       3       #Lookup table definition - table no. - no. entries
        101      0       #Low gear range
        102      650     #Med gear range
        103      1200    #Hi gear range

# --------------------------------------------------------------------------
# Toolchange / NC output Variable Formats
# --------------------------------------------------------------------------
fmt  T  7   toolno      #Tool number
fmt  G  4   g_wcs       #WCS G address
fmt  P  4   p_wcs       #WCS P address
fmt  S  4   speed       #Spindle Speed
fmt  M  4   gear        #Gear range
fmt    4   maxss       #RPM spindle speed
# --------------------------------------------------------------------------
fmt  N  4   n           #Sequence number
fmt  X  2   xabs        #X position output
fmt  Y  2   yabs        #Y position output
fmt  Z  2   zabs        #Z position output
fmt  U  3   xinc        #X position output
fmt  V  3   yinc        #Y position output
fmt  W  3   zinc        #Z position output
fmt  C  11  cabs        #C axis position
fmt  H  14  cinc        #C axis position
fmt  B  4   indx_out    #Index position
fmt  I  3   iout        #Arc center description in X
fmt  J  3   jout        #Arc center description in Y
fmt  K  3   kout        #Arc center description in Z
fmt  R  2   arcrad      #Arc Radius
fmt  F  18  feed        #Feedrate
fmt  P  11  dwell       #Dwell
fmt  M  5   cantext     #Default cantext
fmt  C  2   crad        #C axis start radius, G107
fmt  H  2   tlrad       #C axis cancel, G112, currently using C position
# --------------------------------------------------------------------------
#Move comment (pound) to output colon with program numbers
fmt  O  7   progno      #Program number
#fmt ":" 7   progno      #Program number
fmt  O  7   main_prg_no #Program number
#fmt ":" 7   main_prg_no #Program number
fmt  O  7   sub_prg_no  #Program number
#fmt ":" 7   sub_prg_no  #Program number
fmt  U  2   sub_trnsx   #Rotation point
fmt  V  2   sub_trnsy   #Rotation point
fmt  W  2   sub_trnsz   #Rotation point
# --------------------------------------------------------------------------
# Drill output
# --------------------------------------------------------------------------
fmt  R  2   refht_a     #Reference height
fmt  R  2   refht_i     #Reference height
fmt  X  2   initht_x    #Initial height, mapped X
fmt     2   initht_y    #Initial height, mapped Y
fmt  Z  2   initht_z    #Initial height, mapped Z
fmt  X  2   refht_x     #Reference height, mapped X
fmt     2   refht_y     #Reference height, mapped Y
fmt  Z  2   refht_z     #Reference height, mapped Z
fmt  X  2   depth_x     #Depth, mapped X
fmt     2   depth_y     #Depth, mapped Y
fmt  Z  2   depth_z     #Depth, mapped Z
fmt  Q  2   peck1       #First peck increment (positive)
fmt     2   peck2       #Second or last peck (positive)
fmt  R  2   peckclr     #Safety distance
fmt     2   retr        #Retract height
fmt  Q  2   shftdrl     #Fine bore tool shift
# --------------------------------------------------------------------------
# Thread output
# --------------------------------------------------------------------------
fmt  P  2   thddepth    #Thread height absolute
fmt  J  2   thdfirst    #First depth cut in thread
fmt  Q  2   thdlast     #Last depth cut in thread
fmt  R  2   thdfinish   #G76 thread finish allowance
fmt  R  3   thdrdlt     #Thread R delta G92 and G76
fmt  U  3   thd_dirx    #Incremental X move for G76 mult starts
fmt  W  3   thd_dirz    #Incremental Z move for G76 mult starts
fmt  H  5   nspring     #Number of spring cuts
fmt     5   thdpull     #G76 thread pull off
fmt  Q  5   thdang      #G76 threading angle
# --------------------------------------------------------------------------
# Canned cycle output format (do not change order, used by buffer 2)
# --------------------------------------------------------------------------
fmt  U  2   depthcc
fmt  R  2   clearcc
fmt  U  2   xstckcc
fmt  W  2   zstckcc
fmt  R  4   ncutscc
fmt     2   stepcc
fmt  P  4   ng70s       #P line number in canned cycle
fmt  Q  4   ng70e       #Q line number in canned cycle
fmt  U  2   g73x        #Stored offset of canned cycle rough cut G73
fmt  V  2   g73y        #Stored offset of canned cycle rough cut G73
fmt  W  2   g73z        #Stored offset of canned cycle rough cut G73
fmt  P  2   grvspcc
fmt  Q  2   grvdpcc
# --------------------------------------------------------------------------
fmt "TOOL - "       4   tnote       # Note format
fmt " OFFSET - "    4   toffnote    # Note format

# --------------------------------------------------------------------------
# Parameter information lookup tables, see pparameter
# --------------------------------------------------------------------------
fprmtbl 1 5 #Rough cut parameters
        10200 depthcc
        10201 clearcc
        10202 xstckcc
        10203 zstckcc
        10214 directcc

fprmtbl 2 4 #Finish cut parameters
        10100 ncutscc
        10101 depthcc
        10102 xstckcc
        10103 zstckcc

fprmtbl 3 5 #Groove cut parameters
        10301 stepcc
        10306 directcc
        10312 dopeckcc
        10316 depthcc
        10320 clearcc

fprmtbl 104 4 #Thread cut parameters
        10411 xmaj_thd
        10413 zstrt_thd
        10414 zend_thd
        10419 face_thd

# --------------------------------------------------------------------------
# Tool Comment / Manual Entry Section
# --------------------------------------------------------------------------
pparameter      #Information from parameters
      if prmcode = 10000, stoper = sparameter
      if prmcode = 20103, stinsert2 = sparameter
      result = fprm (abs(lathecc))

ptoolcomment    #Comment for tool
      tnote = abs(t)
      toffnote = tloffno
      strtool = ucase(strtool)
      stoper = ucase(stoper)
      stinsert2 = ucase(stinsert2)
      "(", *tnote, ")", e
      if posttype = two,
        "(", *stoper, " ", *strtool, " ", *stinsert, *stinsert2, ")", e
      else,
        "(", *stoper, " ", *strtool, ")", e

pcomment        #Comment from manual entry (must call pcomment2 if booleans)
      pcomment2

pcomment2       #Comment from manual entry
      scomm = ucase(scomm)
      if gcode = 1007, "(", scomm, ")"
      else, "(", scomm, ")", e

# --------------------------------------------------------------------------
# Start of File and Toolchange Setup
# --------------------------------------------------------------------------
pheader         #Start of file
      "%", e
      pbld, n, *smetric, sg90, sg18, sg08, sg91_1, e
      "(", progname, "  ", date, "  ", time, ")", e


lsof0           #Start of file for tool zero, lathe
      lsof

lsof            #Start of file for non-zero tool number, lathe
      ltlchg

msof0           #Start of file for tool zero, mill
      msof

msof            #Start of file for non-zero tool number, mill
      mtlchg

ltlchg          #Toolchange, lathe
      toolchng = one
      gcode = zero
      copy_x = vequ(x)
      pcc_capture   #Capture LCC ends, stop output RLCC
      c_rcc_setup   #Save original in sav_xa and shift copy_x for LCC comp.
      pcom_moveb    #Get machine position, set inc. from c1_xh
      c_mmlt        #Position multi-tool sub, sets inc. current if G54...
      ptoolcomment
      comment
      if home_type < two, #Toolchange G50/home/reference position
        [
        sav_xh = vequ(copy_x)
        sav_absinc = absinc
        absinc = zero
        pmap_home   #Get home position, xabs
        ps_inc_calc #Set start position, not incremental
        #Toolchange home position
        if home_type = one,
          pbld, n, *sgcode, pfxout, pfyout, pfzout, e
        else,
          [
          #Toolchange g50 position
          pbld, n, *sg28ref, e
          toolno = t * 1
          if home_type = m_one, pbld, n, *sgcode, *toolno, sm06, sm43, e
          else, pbld, n, *sg50, pfxout, pfzout, e
          ]
        pe_inc_calc #Update previous
        absinc = sav_absinc
        copy_x = vequ(sav_xh)
        ]
      toolno = t * 1
      pbld, n, *sgcode, *toolno, sm06, sm43, e
      pbld, n, pfsgplane, e
      pcaxis_off_l  #Postblock for lathe transition
      pcom_moveb    #Reset machine position, set inc. from last position
      pcan
      pspindle
      #Added for 'css_start_rpm' logic (09/05/01)
      if css_actv,
        [
        if css_start_rpm,
          prpm # Direct RPM startup for programmed CSS
        else,
          pbld, pcssg50, pcss # NO RPM start - just output the CSS
        ]
      else, # Direct RPM was programmed
        [
        prpm # Output programmed RPM
        ]
      sav_absinc = absinc
      if home_type > one, absinc = zero
      pcan1, pbld, n, psccomp, *sgcode, pwcs, pfxout, pfzout,
        pfscool, strcantext, e
      if lcc_cc_pos, plcc_cc_pos  #Use sav_xa to position with comp. LCC
      pcom_movea    #Update previous, pcan2
      ps_inc_calc   #Reset current
      absinc = sav_absinc
      #Added for 'css_start_rpm' logic (09/05/01)
      if css_start_rpm,
        pbld, pcssg50, pcss # CSS output AFTER a G97S???? RPM spindle startup
      c_msng        #Position single-tool sub, sets inc. current if G54...
      toolchng = zero

mtlchg          #Toolchange, mill
      toolchng = one
      gcode = zero
      copy_x = vequ(x)
      pcom_moveb    #Get machine position, set inc. from c1_xh
      c_mmlt        #Position multi-tool sub, sets inc. current if G54...
      ptoolcomment
      comment


      if home_type < two, #Toolchange G50/home/reference position
        [
        sav_xh = vequ(copy_x)
        sav_absinc = absinc
        absinc = zero
        pmap_home   #Get home position, xabs
        ps_inc_calc #Set start position, not incremental
        #Toolchange home position
        if home_type = one,
          pbld, n, *sgcode, pfxout, pfyout, pfzout, e
        else,
          [
          #Toolchange g50 position/reference
          pbld, n, *sg28ref, "U0.", [if y_axis_mch, "V0."], "W0.", e
          toolno = t * 1
          if home_type = m_one, pbld, n, *sgcode, *toolno, sm43, e
          else, pbld, n, *sg50, pfxout, pfyout, pfzout, e
          ]
        pe_inc_calc #Update previous
        absinc = sav_absinc
        copy_x = vequ(sav_xh)
        ]
      toolno = t * 1
      pbld, n, *sgcode, *toolno, sm43, e
      pbld, n, pfsgplane, e
      pcom_moveb    #Reset machine position, set inc. from last position
      pcaxis_on_m   #Postblock for mill transition
      pcan
      sav_absinc = absinc
      if home_type > one, absinc = zero
      pcan1, pbld, n, *sgcode, pwcs, pfxout, pyout, pfzout, strcantext, e
      pbld, n, pfcout, e
      pindex
      pbld, n, pfscool, e
      pspindle
      prpm
      pcom_movea    #Update previous, pcan2
      ps_inc_calc   #Reset current
      absinc = sav_absinc
      c_msng        #Position single-tool sub, sets inc. current if G54...
      toolchng = zero
      if millcc,
        [
        pmillccb #Set mill conversion
        pmillcca #End mill conversion
        ]

ltlchg0         #Call from NCI null tool change, lathe
      copy_x = vequ(x)
      c_rcc_setup   #Save original in sav_xa and shift copy_x for LCC comp.
      pcom_moveb    #Get machine position, set inc. from last position
      c_mmlt        #Position multi-tool sub, sets inc. current if G54...
      comment
      pcan
      toolno = t * 1
      pbld, n, toolno, sm43, e
      pbld, n, psgplane, e
      pcaxis_off_l  #Postblock for lathe transition
      pspindle
      pnullspindle
      pbld, n, pscool,e
      if home_type > one & workofs <> prv_workofs,
        [
        sav_absinc = absinc
        absinc = zero
        pbld, n, psgcode, pwcs, pfxout, pfyout, pfzout, e
        pe_inc_calc #Update previous
        ps_inc_calc #Set current inc.
        absinc = sav_absinc
        ]
      if gcode = one, plinout
      else, prapidout
      if lcc_cc_pos, plcc_cc_pos  #Use sav_xa to position with comp. LCC
      pcom_movea
      c_msng #Single tool subprogram call

mtlchg0         #Call from NCI null tool change, mill
      copy_x = vequ(x)
      pcom_moveb    #Get machine position, set inc. from last position
      c_mmlt        #Position multi-tool sub, sets inc. current if G54...
      comment
      pcan
      pbld, n, toolno, sm43, e
      pbld, n, psgplane, e
      pspindle
      pcaxis_on_m   #Postblock for mill transition
      pnullspindle
      pbld, n, pscool,e
      if home_type > one & workofs <> prv_workofs,
        [
        sav_absinc = absinc
        absinc = zero
        pbld, n, psgcode, pwcs, pfxout, pfyout, pfzout, pfcout, e
        pe_inc_calc #Update previous
        ps_inc_calc #Set current inc.
        absinc = sav_absinc
        ]
      pindex
      ppos_cax_lin  #Position C axis, toolplane or CL
      if millcc, pmillccb #Set mill conversion
      if gcode = one, plinout
      else, prapidout
      if millcc, pmillcca #End mill conversion
      pcom_movea    #Update previous, pcan2
      c_msng #Single tool subprogram call

ptoolend        #Read from buffer 1 for prv_, current and next tool info
                #end tool here, current and next valid
      sav_rev = rev #Axis Sub does not update to rev
      pcan
      if n1_gcode <> 1000,
        [
        toolno = t * 1
        sav_gcode = gcode
        gcode = zero
        coolant = zero
        pbld, n, pfscool, e
        if posttype = two, pl_retract
        else, pm_retract
        if n1_gcode <> 1003, pbld, n, "M01", e
        gcode = sav_gcode
        ]
      else, #Null toolchange
        [
        if n1_posttype <> posttype, pcan1, pbld, n, pnullstop, strcantext, e
        ]
      pcan2
      #Update current variables to prv_ needed in comparisons
      !posttype
      if rc1 < size1, preadcur_nxt

pl_retract      #Retract tool based on next tool gcode, lathe (see ptoolend)
      cc_pos = zero
      if home_type = one,
        [
        pmap_home   #Get home position, xabs
        ps_inc_calc #Set inc.
        pbld, n, psccomp, e
        pcan1, pbld, n, *sgcode, pfxout, pfzout, *toolno, sm43, strcantext, e
        pbld, n, pnullstop, e
        ]
      else,
        [
        #Retract to reference return
        pbld, n, `sgcode, psccomp, e
        if home_type = m_one, pbld, n, *toolno, sm43, e
        pcan1, pbld, n, *sg28ref
          pnullstop, strcantext, e
        if home_type > m_one, pbld, n, *toolno, sm43, e
        ]

pm_retract      #Retract tool based on next tool gcode, mill (see ptoolend)
      if home_type = one,
        [
        pmap_home   #Get home position, xabs
        if frc_cinit, cabs = zero
        ps_inc_calc #Set inc.
        pbld, n, psccomp, e
        pcan1, pbld, n, *sgcode, pfxout, pfyout, pfzout, protretinc,
          *toolno, sm43, strcantext, e
        pbld, n, pnullstop, e
        ]
      else,
        [
        #Retract to reference return
        pbld, n, `sgcode, psccomp, e
        if home_type = m_one, pbld, n, *toolno, sm43, e
        pcan1, pbld, n, *sg28ref, "U0.", [if y_axis_mch, "V0."], "W0.",
          protretinc, pnullstop, strcantext, e
        if home_type > m_one, pbld, n, *toolno, sm43, e
        ]

protretinc      #Reset the C axis revolution counter
      if frc_cinit,
        [
        rev = zero
        sav_rev = zero
        cabs = zero
        csav = zero
        c_wnd = zero
        prvc_wnd = zero
        indx_out = zero
        if c_axistype = one,
          [
          if home_type = one, pfcout
          else,
            [
            cinc = zero
            *cinc
            ]
          ]
        else,
          [
          pindxcalc
          if c_axistype = three,
            [
            indx_out = cabs
            e, pbld, n, pindex
            ]
          else, pfcout
          ]
        !csav, !cabs, !c_wnd
        ]

peof0           #End of file for tool zero
      peof

peof            #End of file for non-zero tool
      ptoolend
      comment
      n, "M30", e
      mergesub
      clearsub
      mergeaux
      clearaux
      "%", e

pwcs            #G54+ coordinate setting at toolchange
      if home_type > one,
        [
        sav_frc_wcs = force_wcs
        if sub_level, force_wcs = zero
        if workofs <> prv_workofs | (force_wcs & toolchng),
          [
          if sub_level, result = mprint(swrkserror)
          if workofs < 6,
            [
            g_wcs = workofs + 54
            *g_wcs
            ]
          else,
            [
            p_wcs = workofs - five
            "G54.1", *p_wcs
            ]
          ]
        force_wcs = sav_frc_wcs
        !workofs
        ]

#Rc1 is used to flag the SOF, rc1 = two at SOF
pcaxis_off_l    #Toolchange C axis disable, lathe, check prv_ to current
      if rc1 > two & prv_posttype <> two, pbld, n, *sm24, e

pcaxis_on_m     #Toolchange C axis enable, mill, check prv_ to current
      if (rc1 = two | prv_posttype = two),
        [
        pbld, n, *sm23, e
        if nextdc = three, pbld, n, "M49", e  #Disable tap
        ]

plcc_cc_pos     #Position for lathe canned cycle cutter comp. enable
                #Position saved in prcc_setup
      pe_inc_calc   #Update previous
      copy_x = vequ(sav_xa)
      pcom_moveb    #Get machine position, set inc. from previous
      #Force comp from the finish profile
      compok = one
      cc_pos = n1_cc_pos
      if gcode = zero, prapidout
      else, plinout
      lcc_cc_pos = zero

pgear           #Use spindle gear range, find gear from RPM at X min.
      if use_gear = one,
        [
        if lathtype = zero | lathtype = two, x_min = c1_x_max
        else, x_min = c1_x_min
        x_min = x_min + c1_tox  #Correction for workshift
        if x_min = zero, x_min = .001
        if css_actv = zero, gear_spd = speedrpm
        else, gear_spd = (conversion * g_speed) / (pi * abs(x_min) * two)
        gear = frange(one, gear_spd)
        *gear
        ]

prpm            #Output for start spindle
      speed = speedrpm
      pbld, n, *sg97, pgear, *speed, *spindle_l, e

prpmnull       #Output for RPM at NULL tlchg (don't force spindle 'M' code)
      speed = speedrpm
      if posttype = two, pbld, n, *sg97, pgear, *speed, spindle_l, e
      else, pbld, n, *sg97, *speed, spindle_m, e

pcssg50         #Output Constant surface speed clamp
      #if css_actv, pbld, n, *sg50, *maxss, e  

pcss            #Output Constant surface speed
      speed = g_speed
      if css_actv, pbld, n, *sg9697, *sg50, *maxss, *speed, spindle_l, e                
      !speed

#Toolchange setup, spindle output, pspindle must be called first
pnullspindle  #Null toolchange and dwell spindle change, g_speed is input
      if prv_css_actv<>css_actv | prv_g_spdir<>g_spdir
         | prv_speed<>g_speed,
        [
        #Switch G97/G96 or direction at null or dwell
        #Stop the spindle if direction changes
        if prv_g_spdir <> g_spdir, pbld, n, pnullstop, e
        if css_actv,
          [
          speed = g_speed
          pnullg50
          if prv_speed <> speed | prv_css_actv<>css_actv, pcss #(09/05/01)
          ]
        else,
          [
          if (prv_speed<>g_speed | prv_g_spdir<>g_spdir | prv_css_actv<>css_actv)
             & g_speed, prpmnull #(09/05/01)
          ]
        ]
      else, pnullg50

pnullg50      #Change G50 clamp speed at null or dwell
      if prv_maxss <> maxss & css_actv, pcssg50

pnullstop     #Stop spindle at null, dwell or tool end
      sav_spdir = g_spdir
      if cool_w_spd = zero, g_spdir = one
      else, g_spdir = one + (fsg2(coolant) * three)
      if posttype = two, spindle_l
      else, spindle_m
      g_spdir = sav_spdir

pspindle        #Spindle speed calculations for RPM
      if maxss = zero | maxss > max_speed, maxss = max_speed
      if css_actv,
        [
        #Spindle speed calculations for strt_spd w/CSS
        speedx = abs(xa)
        if opcode = 104, speedx = abs(c1_x_min)
        if opcode = 105, speedx = abs(tcr)
        if speedx < .001, speedx = .001
        speedrpm = (conversion * g_speed) / (pi * speedx * two)
        ]
      else, speedrpm = g_speed
      #zero indicates spindle off (not a mistake)
      if speedrpm,
        [
        if speedrpm > maxss, speedrpm = maxss
        if speedrpm < min_speed, speedrpm = min_speed
        ]
      #Spindle speed for RPM with lathe drill, thread
      if opcode = 104 | opcode = 105, css_actv = zero
      if css_actv = zero, g_speed = speedrpm

pset_g_speed    #Set the spindle control variables from the read variables
      g_speed = abs(ss)
      if cool_w_spd, g_spdir = fsg3(spdir) + (fsg2(coolant) * 3)
      else, g_spdir = fsg3(spdir)
      if spd_rev, pswtchspin

pswtchspin      #Reverse spindle direction
      if g_spdir > two, g_spdir = abs (g_spdir - five) + three
      else, g_spdir = abs (g_spdir - two)

preadcur_nxt    #Read current and next tool record
      c1_gcode = rbuf (one, rc1)     #Current tool record
      #Place buffered variables in post global variables
      cuttype = c1_cuttype
      lathtype = c1_lathtype
      lathecc = c1_lathecc
      gcodecc = c1_gcodecc
      y_axis = c1_y_axis
	  millcc = c1_millcc
      n1_gcode = rbuf (one, nc1)     #Next tool record
      if cuttype = one, cc_1013 = one
      else, cc_1013 = zero
      if lathecc<>zero & lathecc<>4, compok = zero
      else, compok = one

ptlchg1002      #Call at actual toolchange with tlchng_aft
      whatline = four #Required for vector toolpaths
      pmatrix_su
      pmap_plane
      pset_turret
      pset_g_speed
      if gcode = 1000,
        [
        #Null toolchange
        if millcc, cutpos2 = sav_cutpos2
        ]
      else,
        [
        #Toolchange and Start of file
        if gcode = 1002,
          [
          #Actual toolchange
          preset_mod
          ]
        prv_xia = vequ (c1_xh)
        prv_feed = c9k
        pnt_at_zero = zero
        ]
      #Mill canned cycle initialze at toolchange
      arcoutput = sav_arcout
      if millcc,
        [
        #R arc output
        arcoutput = one
        if cuttype = four,
          [
          crad = rotdia/two
          ]
        else,
          [
          breakarcs = zero
          ]
        ]
      iout = zero
      kout = zero

preset_mod    #Reset the mode flags and map during motion blocks
      breakarcs = breakarcss
      cir_at_zero = zero
      linarc = zero
      brklinestype = zero

# --------------------------------------------------------------------------
# Motion NC output
# --------------------------------------------------------------------------
prapidout       #Output to NC, linear movement - rapid
      pcan1, pbld, n, psgplane, pexct, psgcode, psccomp, pxout, pyout,
        pzout, pcout, pscool, strcantext, e

plinout         #Output to NC, linear movement - feed
      pcan1, pbld, n, psgplane, sgfeed, pexct, psgcode, psccomp, pxout,
        pyout, pzout, pcout, pfr, pscool, strcantext, e

pcirout         #Output to NC, circular interpolation
      pcan1, pbld, n, psgplane, sgfeed, pexct, psgcode, psccomp, pxout,
        pyout, pzout, pcout, parc, pfr, pscool, strcantext, e

pl_ncoutput     #Movement output
      pcc_capture   #Capture LCC ends, stop output RLCC
      pcom_moveb    #Get machine position, set inc. from last position
      pcan
      c_rcc_setup   #Save original in sav_xa and shift copy_x for LCC comp.
      if gcode = zero, prapidout
      if gcode = one, plinout
      if gcode > one & gcode < four, pcirout
      if lcc_cc_pos, plcc_cc_pos  #Use sav_xa to position with comp. LCC
      pcom_movea    #Update previous, pcan2

pm_ncoutput     #Movement output
      pcom_moveb    #Get machine position, set inc. from last position
      pcan
      pindex
      ppos_cax_lin  #Position C axis, toolplane or CL
      if millcc, pmillccb #Set mill conversion
      if gcode = zero, prapidout
      if gcode = one, plinout
      if gcode > one & gcode < four, pcirout
      if millcc, pmillcca #End mill conversion
      pcom_movea    #Update previous, pcan2
      ppos_pnt_zero #Update to detect point at zero

pdwl_spd        #Output to NC, spindle, dwell changes
      pset_g_speed
      pspindle
      comment
      pnullspindle
      pcan
      if fmtrnd(dwell), pdwell1
      else, pcan1, pbld, n, strcantext, e
      pcan2

mrapid          #Output to NC of linear movement - rapid, mill
      copy_x = vequ(x)
      pm_ncoutput

pzrapid         #Linear movement in Z axis only - rapid, mill
      copy_x = vequ(x)
      pm_ncoutput

pz              #Linear movement in Z axis only - at feedrate, mill
      copy_x = vequ(x)
      pm_ncoutput

mlin            #Output to NC of linear movement - feed, mill
      copy_x = vequ(x)
      pm_ncoutput

mcir            #Output to NC of circular interpolation, mill
      pshft_map_ijk
      copy_x = vequ(x)
      pm_ncoutput

lrapid          #Rapid linear movement, lathe
      copy_x = vequ(x)
      pl_ncoutput

llin            #Linear line movement - at feedrate, lathe
      copy_x = vequ(x)
      pl_ncoutput

lcir            #Circular interpolation, lathe
      pshft_map_ijk
      copy_x = vequ(x)
      pl_ncoutput

pmx             #Output to NC of Multisurf Rotary, mill
      copy_x = vequ(x)
      pm_ncoutput

#Pre-process rotary motion control flags, mill
pmx0            #5 ax Drill
      if cuttype = five,
        [
        if drill5 = one, z = initht * z_mult
        else,
          [
          if fr = -2, gcode = zero
          else, gcode = one
          ]
        ]
plin0           #Pre-linear movement postblock
      if posttype <> two,
        [
        preset_mod
        if y_axis = zero & millcc = zero & c_axistype <> three,
          [
          #Set brklinestype
          if abs(cuttype) = two, brklinestype = 6
          if cuttype = three, brklinestype = four
          ]
        ]

pcir0           #Pre-circular interpolation postblock
      pmap_plane
      if posttype <> two,
        [
        preset_mod
        pshft_map_xc
        if y_axis = zero & millcc = zero,
          [
          #Set linarc, breakarcs and cir_at_zero
          if fmtrnd(xca) = zero & fmtrnd(yca) = zero,
            [
            #Set breakarcs and cir_at_zero
            breakarcs = zero
            #C axis move
            if mach_plane = zero,
              [
              cir_at_zero = one
              czero_csav = csav
              ]
            #Arc output
            if mach_plane = two, cir_at_zero = m_one
            ]
          if cir_at_zero = zero, linarc = one
          ]
        ]
      !ynci

# --------------------------------------------------------------------------
# Motion output components
# --------------------------------------------------------------------------
pdwell1         #Dwell output
      gcode = four  #for implied dwells
      pcan1, pbld, n, *sgcode, *dwell, strcantext, e

pbld            #Canned text - block delete
      if bld, '/'

pfbld           #Force block delete
      "/"

psgplane        #Machining plane
      if y_axis_mch, sgplane
      !plane

pfsgplane       #Force machining plane
      if y_axis_mch, *sgplane
      !plane

pexct           #Canned text - exact stop
      if exact, 'G9'

psgcode         #Output the Gcode based on the current plane
      if c_ax_flp,
        [
        #Reverse arc direction for c_axis flip
        if gcode = two | gcode = three,
          [
          sav_gcode = gcode
          gcode = abs (gcode - five)
          ]
        ]
      if plane = zero, `sgcode
      if plane = one, `sgcode1
      if plane = two, `sgcode2
      if c_ax_flp, gcode = sav_gcode

psccomp         #Output the cutter compensation based on the current plane
      if compok,
        [
        if plane = zero, sccomp
        if plane = one, sccomp1
        if plane = two, sccomp2
        ]

pfxout          #Force X axis output
      if absinc = zero, *xabs, !xinc
      else, *xinc, !xabs

pxout           #X output
      if absinc = zero, xabs, !xinc
      else, xinc, !xabs

pfyout          #Force Y axis output
      if y_axis_mch,
        [
        if absinc = zero, *yabs
        else, *yinc
        ]
      else, pchecky
      !yabs, !yinc

pyout           #Y output
      if y_axis_mch,
        [
        if absinc = zero, yabs
        else, yinc
        ]
      else, pchecky
      !yabs, !yinc

pchecky         #Y output should not happen on a c-axis lathe
      if not(toolchng) & yinc, result = mprint(symoterror)

pfzout          #Force Z axis output
      if absinc = zero, *zabs, !zinc
      else, *zinc, !zabs

pzout           #Z output
      if absinc = zero, zabs, !zinc
      else, zinc, !zabs

pfcout          #Force C axis output
      if posttype <> two & c_axistype < three,
        [
        if c_axistype = one,
          [
          if absinc = zero, *cabs, !cinc
          else, *cinc, !cabs
          ]
        else, #Signed direction, no incremental
          [
          if indx_mc = zero, result = nwadrs(sc_minus, cabs)
          else, result = nwadrs(str_cax_abs, cabs)
          *cabs
          !c_wnd, !cabs, !cinc
          ]
        ]

pcout           #C axis output
      if posttype <> two & c_axistype < three,
        [
        if c_axistype = one,
          [
          if absinc = zero, cabs, !cinc
          else, cinc, !cabs
          ]
        else, #Signed direction, modality on c_wnd, no incremental
          [
          if prv_c_wnd <> c_wnd,
            [
            if indx_mc = zero, result = nwadrs(sc_minus, cabs)
            else, result = nwadrs(str_cax_abs, cabs)
            *cabs
            ]
          !c_wnd, !cabs, !cinc
          ]
        ]

pindex          #Index output
      if c_axistype = three,
        [
        pbld, n, `sindx_mc, indx_out, e
        !cabs, !cinc
        ]

parc            #Select the arc output
      if arcoutput = zero,
        [
        #Arc output for IJK
        if arctype = one,
          [
          #Arc output for IJK, absolute
          iout = (iout + dia_shift) * dia_mult
          jout = (jout + y_shift) * y_mult
          kout = (kout + z_shift) * z_mult
          if c_ax_flp, iout = -iout
          ]
        else,
          [
          #Arc output for IJK, start/center
          iout = iout * dia_mult
          jout = jout * y_mult
          kout = kout * z_mult
          if c_ax_flp, iout = -iout
          ]
        iout, kout, jout
        ]
      else,
        [
        #Arc output for R
        if abs(sweep)<=180 | arcoutput=one, result = nwadrs(srad, arcrad)
        else, result = nwadrs(srminus, arcrad)
        *arcrad
        ]

pffr            #Output feedrate, force
      if ipr_actv = zero, pfr_m
      else, pfr_l
      *feed

pfr             #Output feedrate
      if ipr_actv = zero, pfr_m
      else, pfr_l
      `feed

pfr_m           #Format feedrate for mill
      result = nwadrs(strf, feed)
      result = newfs (17, feed)

pfr_l           #Format feedrate for lathe
      if opcode = 104,
        [
        #Format feedrate for lathe thread
        result = nwadrs(stre, feed)
        result = newfs (19, feed)
        ]
      else,
        [
        result = nwadrs(strf, feed)
        result = newfs (18, feed)
        ]

pscool          #Coolant is seperate code
      if cool_w_spd = zero, scoolant
      !coolant

pfscool         #Coolant is seperate code, force
      if cool_w_spd = zero, *scoolant
      !coolant

pcc_capture     #Capture ends of canned turning path, stop output w/rough
      #Stop output in rough only lathe canned cycles
      #between rough and finish paths
      if cc_stop_fcc & rcc_flg = 6, no_nc_out = one
      #Capture vector for G73 cycle
      if rpd_typ = 6 & abs(lathecc) = two,
        [
        if rcc_flg = one, lcc_xcst = vequ (copy_x)
        if rcc_flg = three, lcc_xcend = vequ (copy_x)
        ]

pcom_moveb      #Common motion preparation routines, before
      pshft_map_xa
      pxyzcout
      ps_inc_calc

ppos_cax_lin    #Position C if from CL
      if (prv_pnt_at_zero) & c_axistype < three,
        [
        #Output to NC, C axis movement only - rapid deg/min
        sav_gcode = gcode
        sav_feed = feed
        gcode = one
        if millcc = zero,
          [
          feed = maxfrdeg
          pbld, n, psgcode, pfcout, pffr, e
          ]
        else, pbld, n, psgcode, pfcout, pfr, e
        gcode = sav_gcode
        feed = sav_feed
        ]

pcom_movea      #Common motion preparation routines, after
      pcan2
      pe_inc_calc

ppos_pnt_zero   #Position C if from CL
      !pnt_at_zero
      pnt_at_zero = zero

#Mill canned cycle output
pmillccb        #Cross/Face canned cycle code, before
      if c1_millcc = n1_millcc & n1_millcc & n1_gcode = 1000
      & cutpos2 = three,
        [
        sav_cutpos2 = two
        cutpos2 = two
        ]
      if cutpos2 = one,
        [
        result = newfs(two, cabs)
        result = newfs(two, cinc)
        #Cross/Face canned cycle start code
        if abs(cuttype) = two,
          [
          #Face canned cycle start code, G112 (break ramp)
          pbld, n, *sgfeed, *sgcode, *sg112, e
          prv_xabs = c9k
          prv_xinc = c9k
          prv_cabs = c9k
          prv_cinc = c9k
          compok = one
          ]
        else,
          [
          #Cross canned cycle start code, G107
          pbld, n, *sgcode, *sgfeed, *sg107, *crad, e
          ]
        ]
      if cutpos2 > zero & cutpos2 < four,
        [
        #Change rapid to highest possible feedrate
        if gcode = zero,
          [
          gcode = one
          feed = maxfeedpm
          ]
        ]

pmillcca        #Cross/Face canned cycle code, after
      if cutpos2 = three,
        [
        #Cross/Face canned cycle end code
        if abs(cuttype) = two, pbld, n, *sg113, e  #Face
        else, pbld, n, *sg108, "C0.", e #Cross
        result = newfs(11, cabs)
        result = newfs(14, cinc)
        ]

# --------------------------------------------------------------------------
# Drilling
# --------------------------------------------------------------------------
pdrill0         #Pre-drill postblock call
      if cuttype = five, #Don't allow 5 axis, rests at toolchange
        [
        usecandrill = zero
        usecanpeck = zero
        usecanchip = zero
        usecantap = one
        usecanbore1 = zero
        usecanbore2 = zero
        usecanmisc1 = zero
        usecanmisc2 = zero
        ]
      else,
        [
        if abs(cuttype) < three, mdrl_dir = zero
        else, mdrl_dir = one
        x = xnci
        y = ynci
        z = refht
        copy_x = vequ(x)
        pshft_map_xa
        pxyzcout
        refht_x = vequ(xabs)
        z = depth
        copy_x = vequ(x)
        pshft_map_xa
        pxyzcout
        depth_x = vequ(xabs)
        z = zdrl
        copy_x = vequ(x)
        pshft_map_xa
        pxyzcout
        zdrl_x = vequ(xabs)
        z = initht  #Initial is last
        copy_x = vequ(x)
        pshft_map_xa
        pxyzcout
        initht_x = vequ(xabs)
        znci = initht
        ps_inc_calc
        ]

pdrlcommonb     #Canned Drill Cycle common call, before
      if gcode = 81,
        [
        if drillcyc = three, drlgsel = fsg1 (-g_speed) + drillcyc * two #Tap
        else, drlgsel = fsg2 (dwell) + drillcyc * two
        if initht <> refht, drillref = zero
        else, drillref = one
        prv_refht_a = c9k
        prv_refht_i = c9k
        prv_dwell = zero
        ]
      if mdrl_dir = zero, #Set Z to depth
        [
        zia = fmtrnd(depth_z)
        zinc = zia - prv_zia
        ]
      else,               #Set X to depth
        [
        xia = fmtrnd(depth_x)
        xinc = xia - prv_xia
        ]
      xabs = vequ (depth_x)
      comment
      pcan

pgdrlout        #Drill Gcode output
      if mdrl_dir = zero, *sgdrillf
      else, *sgdrillc

prdrlout        #R drill position
      if mdrl_dir = zero, refht_a = refht_z
      else, refht_a = refht_x
      refht_i = refht - initht
      if absinc = zero, refht_a, !refht_i
      else, refht_i, !refht_a

ldrill          #Canned drill cycle, lathe
      #Use this postblock to customize lathe drilling cycles 0 - 7
      pdrlcommonb
      "CUSTOMIZABLE DRILL CYCLE ", pfxout, pfyout, pfzout, e
      pcom_movea

lpeck           #Canned peck drill cycle, lathe
      ldrill

lchpbrk         #Canned chip break cycle, lathe
      gcode = zero
      prv_dwell = zero
      @dwell
      comment
      pcan
      pe_inc_calc
      xabs = vequ(refht_x)
      ps_inc_calc
      pcan1, pbld, n, sgcode, pzout, strcantext
      pe_inc_calc
      xabs = vequ(depth_x)
      ps_inc_calc
      if old_new_sw = one,
        [
        pbld, n, *sg74, *peckclr, e
        result = nwadrs (strq, peck1)
        ]
      else, result = nwadrs (strk, peck1)
      pcan1, pbld, n, *sg74, pfzout, *peck1, pffr, strcantext, e
      prv_gcode = -1
      if refht <> initht,
        [
        gcode = zero
        xabs = vequ(refht_x)
        ps_inc_calc
        pe_inc_calc
        xabs = vequ(initht_x)
        ps_inc_calc
        pbld, n, sgcode, pfzout, e
        ]
      pcom_movea

ltap            #Canned tap cycle, lathe
      gcode = zero
      prv_dwell = zero
      @dwell
      comment
      pcan
      pe_inc_calc
      xabs = vequ(refht_x)
      ps_inc_calc
      pcan1, pbld, n, sgcode, pzout, strcantext, e
      pe_inc_calc
      xabs = vequ(depth_x)
      ps_inc_calc
      opcode = 104 #thread address from feedrate
      pbld, n, *sthdg33_1, pfzout, pffr, e
      if dwell, pdwell1
      pe_inc_calc
      xabs = vequ(refht_x)
      ps_inc_calc
      pswtchspin
     # pbld, n, *sthdg33_1, pfzout, *spindle_l, e
      if dwell, pdwell1
      prv_gcode = -1
     # pbld, n, pnullstop
      pswtchspin
      if refht <> initht,
        [
        gcode = zero
        pe_inc_calc
        xabs = vequ(initht_x)
        ps_inc_calc
        #pbld, n, sgcode, pfzout, *spindle_l, e
        ]
      pbld, n, spindle_l, e
      opcode = 81 #Restore opcode
      pcom_movea

lbore1          #Canned bore #1 cycle, lathe
      ldrill

lbore2          #Canned bore #2 cycle, lathe
      ldrill

lmisc1          #Canned misc #1 cycle, lathe
      ldrill

lmisc2          #Canned misc #2 cycle, lathe
      ldrill

mdrill          #Canned drill cycle, mill
      pdrlcommonb
      pcan1, pbld, n, *sgdrlref, pgdrlout, pxout, pyout, pzout,
        pcout, prdrlout, dwell, pffr, strcantext, e
      pcom_movea

mpeck         #Canned peck drill cycle, mill
      pdrlcommonb
      pcan1, pbld, n, *sgdrlref, pgdrlout, pxout, pyout, pzout,
        pcout, prdrlout, *peck1, dwell, pffr, strcantext, e
      pcom_movea

mchpbrk       #Canned chip break cycle, mill
      mpeck

mtap          #Canned tap cycle, mill
      pdrlcommonb
      pcan1, pbld, n, *sgdrlref, pgdrlout, pxout, pyout, pzout,
        pcout, prdrlout, pffr, strcantext, e
      pcom_movea

mbore1        #Canned bore #1 cycle, mill
      mdrill

mbore2        #Canned bore #2 cycle, mill
      mdrill

mmisc1        #Canned misc #1 cycle, mill
      pdrlcommonb
      pcan1, pbld, n, *sgdrlref, pgdrlout, pxout, pyout, pzout,
        pcout, prdrlout, *shftdrl, dwell, pffr, strcantext, e
      pcom_movea

mmisc2        #Canned misc #2 cycle, mill

mdrill_2      #Canned drill cycle repeat, mill
      pdrlcommonb
      pcan1, pbld, n, pxout, pyout, pzout, pcout, prdrlout,
      dwell, pfr, strcantext, e
      pcom_movea

mpeck_2       #Canned peck drill cycle repeat, mill
      mdrill_2

mchpbrk_2     #Canned chip break cycle repeat, mill
      mdrill_2

mtap_2        #Canned tap cycle repeat, mill
      mdrill_2

mbore1_2      #Canned bore #1 cycle repeat, mill
      mdrill_2

mbore2_2      #Canned bore #2 cycle repeat, mill
      mdrill_2

mmisc1_2      #Canned misc #1 cycle repeat, mill
      mdrill_2

mmisc2_2      #Canned misc #2 cycle repeat, mill
      mdrill_2

pdrlcst         #Custom drill cycles 8 - 19 (user option)
      #Use this postblock to customize drilling cycles 8 - 19
      pdrlcommonb
      "CUSTOMIZABLE DRILL CYCLE ", pfxout, pfyout, pfzout, pfcout, e
      pcom_movea

pdrlcst_2       #Custom drill cycles 8 - 19 (user option)
      #Use this postblock to customize drilling cycles 8 - 19
      pdrlcommonb
      "CUSTOMIZABLE DRILL CYCLE ", pfxout, pfyout, pfzout, pfcout, e
      pcom_movea

pcanceldc     #Cancel drill cycle
      xabs = vequ (initht_x) #Position to return
      ps_inc_calc
      pe_inc_calc #Update to current location
      gcode = zero
      pcan
      pcan1, pbld, n, sgcode, "G80", strcantext, e
      pcan2

# --------------------------------------------------------------------------
# Version 9+ MiscOps Section  
# --------------------------------------------------------------------------
#Miscellaneous Variables Common to all Miscops operations 
#Format as needed

#Integers
#miscops_mi1, miscops_mi2, miscops_mi3, 
#miscops_mi4,  miscops_mi5, miscops_mi6, 
#miscops_mi7, miscops_mi8, miscops_mi9, 
#miscops_mi10 

#Reals
#miscops_mr1, miscops_mr2, miscops_mr3, 
#miscops_mr4, miscops_mr5, miscops_mr6, 
#miscops_mr7, miscops_mr8, miscops_mr9, 
#miscops_mr10
#
# --------------------------------------------------------------------------
#Format Assignments and Initializations
# --------------------------------------------------------------------------
fmt Z 2 stck_init_z             #Initial Z position of the stock (900-902,904,905)
fmt Z 2 stck_final_z            #Final Z position of the stock (900-902,904,905)
fmt Z 2 stck_chuk_st_z          #Initial Z axis Chuck Position (900-903)
fmt X 2 stck_chuk_st_x          #Initial X axis Chuck Position (900-903)
fmt Z 2 stck_chuk_end_z         #Final Z axis Chuck Position (900-903)
fmt X 2 stck_chuk_end_x         #Final X axis Chuck Position (900-903)
fmt W 3 stck_chuk_st_dz         #Destination chuck Z axis reference position before transfer (900)
fmt U 3 stck_chuk_st_dx         #Destination chuck X axis reference position before transfer (900)
fmt W 3 stck_chuk_end_dz        #Destination chuck Z axis reference position after transfer (900)
fmt U 3 stck_chuk_end_dx        #Destination chuck X axis reference position after transfer (900)
fmt Z 2 stck_clear              #Stock clearance value for stock pull operation (902)
fmt X 2 stck_tool_x             #Tool X axis position for bar stop / puller (902)
fmt Z 2 stck_grip               #Grip length value for stock pull operation(902)

fmt F 18 stk_adv_fr             #Used with Lathe Stock Advance (Bar-Feed/Pull) function (NCI 902).
fmt F 18 stck_appr_fr           #Used with Lathe Stock Advance (Bar-Feed/Pull) function (NCI 902)

#Flags
stck_op         : 0             #Stock advance operation method (902)
                                #(0=Push stock,1=Push stock with Use Tool Stop option,2=Pull stock)
stck_spindle    : 0             #Active spindle with stock to transfer (900-902)
                                #0=Left Spindle,1=Right Spindle
clmp_op         : 0             #The selected Operation mode: 0=Clamp,1=Un-clamp,2=Re-position (903)
clmp_spindle    : 0             #Active spindle for clamp/unclamp 0=Left Spindle,1=Right Spindle (903)
tlstck_on       : 0             #Retract or engage the tailstock (0=Retract,1=Engage) (904)

# --------------------------------------------------------------------------
#Postblock Section -comments only!
# --------------------------------------------------------------------------
pstck_trans     #NCI code = 900 available variables:
                #stck_spindle, stck_init_z, stck_final_z, 
                #stck_chuk_st_z, stck_chuk_st_x, 
                #stck_chuk_end_z, stck_chuk_end_x, 
                #stck_chuk_st_dz, stck_chuk_st_dx, 
                #stck_chuk_end_dz, stck_chuk_end_dx
                if stck_spindle = 0, "(Xfer Part from Left Spindle)", e
                if stck_spindle = 1, "(Xfer Part from Right Spindle)", e

pstck_flip      #NCI code = 901 available variables:
                #stck_spindle, stck_init_z, stck_final_z, 
                #stck_chuk_st_z, stck_chuk_st_x, 
                #stck_chuk_end_z, stck_chuk_end_x
                "(Flip Stock)", e


pstck_bar_fd	#NCI code = 902 available variables:
                #stck_spindle, stck_op, stck_clear, 
                #stck_grip, stck_init_z, stck_final_z, 
                #stck_chuk_st_z, stck_chuk_st_x, 
                #stck_chuk_end_z, stck_chuk_end_x
                [
                  if stck_op = 0, "(Push stock -"
                  if stck_op = 1, "(Push stock with Use Tool Stop option -"
                  if stck_op = 2, "(Pull stock -"
                  if stck_spindle = 0, "from Left Spindle)", e
                  if stck_spindle = 1, "from Right Spindle)", e
                ]
                
pchuck	        #NCI code = 903 available variables:
                #clmp_spindle, clmp_op,  stck_chuk_st_z, 
                #stck_chuk_st_x, stck_chuk_end_z, stck_chuk_end_x
                [
                  if clmp_op = 0, "(Clamp -"
                  if clmp_op = 1, "(Un-clamp -"
                  if clmp_op = 2, "(Re-position -"
                  if clmp_spindle = 0, "Left Spindle)", e
                  if clmp_spindle = 1, "Right Spindle)", e
                ]
                
ptailstock	    #NCI code = 904 available variables:
                #tlstck_on, stck_init_z, stck_final_z
                if tlstck_on = 0, "(Retract Tailstock)", e
                if tlstck_on = 1, "(Engage Tailstock)", e

psteadyrest	    #NCI code = 905 available variables:
                #stck_init_z, stck_final_z
                "(Position Steadyrest)", e
               
# --------------------------------------------------------------------------
# Threading output
# --------------------------------------------------------------------------
pthread0        #Pre-thread calculations
      # Calculate taper delta 'X' on Acceleration Clearance distance
      thdrdlt = (((thdx2 - thdx3) / (thdz1 - thdz2)) * thdzclr)
      # Add to the original thread 'X' difference calculation
      thdrdlt = (thdrdlt + (thdx2 - thdx3)) * pl_ax_m0x
      thdang = rad2deg * thdangle
      thd_dirx = (thdx2 - thdx3) * pl_ax_m0x
      thd_dirz = (thdz1 - thdz2) * pl_ax_m0z
      thd_vlen = thdlead/ nstarts
      thd_dirx = vsa (thd_vlen, thd_dirx)
      if fr_pos, pthreadpull
      else, thdpull = zero

pthreadpull     #Pre-thread calculations
      if thdpulloff/(fr_pos*10) > .99, thdpull = 99
      else, thdpull = (thdpulloff/(fr_pos*10))*100

pthdext         #Calculation override for external thread
      #thddepth = thdlead * .61343         #Calc. thread depth
      #thdflat  = thdlead * .1667          #Calc. thread flat

pthdint         #Calculation override for internal thread
      #thddepth = thdlead * .54127         #Calc. thread depth
      #thdflat  = thdlead * .125           #Calc. thread flat

pthdface        #Calculation override for face thread
      #thddepth = thdlead * .61343         #Calc. thread depth
      #thdflat  = thdlead * .1667          #Calc. thread flat

pthrg32_1       #G33 threading first
      comment
      gcode = zero
      lrapid

pthrg32_2       #G33 threading second
      gcode = zero
      lrapid

pthrg32_3       #G33 threading third
      copy_x = vequ(x)
      pcom_moveb
      pcan1, pbld, n, sgfeed, *sthdgcode, pxout, pyout, pzout, pcout, pffr,
      strcantext, e
      pcom_movea
      prv_gcode = m_one

pthrg32_4       #G33 threading fourth
      gcode = zero
      lrapid

pthrg92_1       #G92 threading
      if thdpass = one, pthrg92_11

pthrg92_11      #G92 threading
      comment
      gcode = zero
      lrapid
      prv_feed = m_one
      prv_zabs = c9k
      prv_thdtype = m_one

pthrg92_2       #G92 threading

pthrg92_3       #G92 threading
      copy_x = vequ (x)
      pcom_moveb
      pcan1, pbld, n, sgfeed, sthdgcode, pxout, pyout, pzout, pcout,
        [if thdrdlt & thdpass = one, *thdrdlt], pfr, strcantext, e
      pcom_movea
      prv_gcode = m_one

pthrg92_4       #G92 threading

pg32e           #G33/G92 threading end
      gcode = zero
      lrapid

pthrg76_1       #G76 threading start point
      gcode = zero
      lrapid

pg76            #G76 threading
      comment
      gcode = zero
      lrapid
      sav_xa = vequ(copy_x)
      if thdface = zero, copy_x = thdx2
      else, copy_z = thdx2
      if thdface = zero, copy_z = thdz2
      else, copy_x = thdz2
      pcom_moveb
      nstart_cnt = zero
      while nstart_cnt < nstarts, pg76nstart
      pcom_movea
      prv_gcode = -1
      copy_x = vequ(sav_xa)
      copy_x = copy_x + (thd_dirx * (nstarts - one))
      copy_z = copy_z + (thd_dirz * (nstarts - one))
      pcom_moveb
      pe_inc_calc
      !gcode, !xabs, !yabs, !zabs, !xinc, !yinc, !zinc

pg76nstart      #G76 threading, for multiple starts
      if old_new_sw = zero, pg76old
      else, pg76new
      nstart_cnt = nstart_cnt + one
      if nstarts <> one & nstart_cnt <> nstarts,
      pbld, n, *sgcode, thd_dirx, thd_dirz, e

pg76old         #G76 threading old style
      pbld, n, *sthdgcode, pfxout, pfzout, *thdrdlt, *thddepth,
        *thdfirst, *thdang, pffr, e

pg76new         #G76 threading new style
      pbld, n, *sthdgcode, *nspring, *thdpull, *thdang, *thdlast,
        *thdfinish, e
      pbld, n, *sthdgcode, pfxout, pfzout, *thddepth, *thdfirst,
        *thdrdlt, pffr, e

# --------------------------------------------------------------------------
# Lathe canned cycle output
# --------------------------------------------------------------------------
pg71old         #Output G71-G72 canned cycle routines, old style
      pbld, n, *scclgcode, *ng70s, *ng70e, *xstckcc, *zstckcc,
        *depthcc, pffr, e

pg71new         #Output G71-G72 canned cycle routines, new style, first
      if gcodecc = 1, result = nwadrs (stru, depthcc)
      else, result = nwadrs (strw, depthcc)
      pbld, n, *scclgcode, *depthcc, *clearcc, e
      pbld, n, *scclgcode, *ng70s, *ng70e, *xstckcc, *zstckcc, pffr, e

pg73old         #Output G73 canned cycle routines, old style
      pbld, n, *scclgcode, *ng70s, *ng70e, *g73x, *g73z,
        *xstckcc, *zstckcc, *ncutscc, pffr, e

pg73new       #Output G73 canned cycle routines, new style, first
      pbld, n, *scclgcode, *g73x, *g73z, *ncutscc, e
      pbld, n, *scclgcode, *ng70s, *ng70e, *xstckcc, *zstckcc, pffr, e

pg74old         #Output G74-G75 canned cycle routines, old style
      pbld, n, *scclgcode, pfxout, pfzout, *grvspcc, *grvdpcc,
        *clearcc, pffr, e

pg74new         #Output G74-G75 canned cycle routines, new style, first
      pbld, n, *scclgcode, *clearcc, e
      pbld, n, *sgfeed, *scclgcode, pfxout, pfzout, *grvspcc,
        *grvdpcc, pffr, e

prcc_setup      #Lathe canned cycle setup
                #Capture values from rough
      sav_iprcc = c1_ipr_actv
      sav_feedcc = c1_fr_pos
      if orient = one|orient = two|orient = five|orient = 6, lccdirx = one
      else, lccdirx = m_one
      if orient = one|orient = four|orient = five|orient = 8, lccdirz = one
      else, lccdirz = m_one
      if lathecc > zero, cc_stop_fcc = one
      else, cc_stop_fcc = zero
      #G74/G75
      if lathecc = three,
        [
        lcc_xcst = vequ (copy_x)
        if dopeckcc = zero,
          [
          depthcc = zero
          clearcc = zero
          ]
        if directcc > one,
          [
          gcodecc = four
          grvspcc = stepcc
          grvdpcc = depthcc
          ]
        else,
          [
          gcodecc = five
          grvspcc = depthcc
          grvdpcc = stepcc
          ]
        ]
      else,
        [
        if n1_cc_pos,
          [
          sav_xa = vequ(copy_x)
          #Shift for cutter comp. start position
          copy_x = copy_x + (lcc_move * lccdirx)
          copy_z = copy_z + (lcc_move * lccdirz)
          pcom_moveb
          compok = zero
          lcc_cc_pos = one
          ]
        else, lcc_cc_pos = zero
        ]

prcc_call_st    #Rough canned cycle start
      if tool_op <> 208,
        [
        sav_subout = subout
        sav_omitsq = omitseq
        omitseq = one
        extprg = one
        subout = three
        prv_gcode = m_one #Added (06/25/01)
        ]

prcc_call_end   #Rough canned cycle end
      if tool_op <> 208,
        [
        omitseq = sav_omitsq
        #Close the ext file
        result = fclose (sbufname3)
        #Open the ext file as a buffer
        #Use the size to determine the start and end sequence
        subout = sav_subout
        size3 = rbuf(three, zero)
        if omitseq = one,
          [
          ng70s = n
          ng70e = n + seqinc
          ]
        else,
          [
          if old_new_sw = zero, ng70s = n + seqinc
          else, ng70s = n + (seqinc * two)
          ng70e = ng70s + (seqinc * (size3 - one))
          ]
        pwrite_g70
        ]
      #Setup the stock and clearance directions
      g73x = vsub (lcc_xcst,lcc_xcend)
      if old_new_sw = zero, g73x = g73x * pl_ax_m0x
      else, g73x = g73x * dia_mult
      g73z = g73z * pl_ax_m0z
      xstckcc =  xstckcc * dia_mult * lccdirx
      zstckcc =  zstckcc * lccdirz * pl_ax_m0z
      clearcc =  clearcc * lccdirz * pl_ax_m0z
      #Write the cycle definition
      sav_feed = feed
      sav_ipr = ipr_actv
      feed = sav_feedcc
      ipr_actv = sav_iprcc
      if lathecc = three,
        [
        #Setup the previous position for inc. in G74/G75 cycle
        sav_xa = vequ(xabs) #Save the cycle end
        copy_x = vequ(lcc_xcst) #The cycle start raw
        pshft_map_xa
        pxyzcout  ##The cycle start in machine terms
        ps_inc_calc #Recalculate incremental
        pe_inc_calc #Update previous at start
        xabs = vequ(sav_xa) #Restore the cycle end
        ps_inc_calc #Recalculate incremental
        ]
      if old_new_sw = zero,
        [
        if gcodecc < three, pg71old
        if gcodecc = three, pg73old
        if gcodecc > three, pg74old
        ]
      else,
        [
        if gcodecc < three, pg71new
        if gcodecc = three, pg73new
        if gcodecc > three, pg74new
        ]
      if lathecc = three,
        [
        #Set the cycle end position at the original start
        copy_x = vequ(lcc_xcst) #The cycle start raw
        pshft_map_xa
        pxyzcout  ##The cycle start in machine terms
        ps_inc_calc #Position at start
        pe_inc_calc #Update previous
        ps_inc_calc #Recalculate incremental
        ]
      feed = sav_feed
      ipr_actv = sav_ipr
      if tool_op <> 208,
        [
        #Bug2 is off to prevent execution crashes with long strings
        bug2 = zero
        #Write the cycle profile, sequence are written now
        rc3 = one
        while rc3 <= size3,
          [
          #Write the lathe canned cycle profile
          string3 = rbuf (three, rc3)
          if rc3 = two,
            [
            #Add the finish spindle speed to the first move
            speed = n1_ss
            pbld, *n, *string3, *speed, e
            ]
          else,
            [
            if omitseq = one & rc3 = size3 + one, pbld, *n, *string3, e
            else, pbld, n, *string3, e
            ]
          ]
        #Close the buffer
        result = fclose (three)
        #Remove the ext file
        result = remove (sbufname3)
        bug2 = sav_bug2
        ]

pfcc_call       #G70 recall output postblock
      if cc_stop_fcc = zero,
        [
        pread_g70
        if foundcc = zero, result = mprint(sfccerror)
        ]
      no_nc_out = zero
      cc_stop_fcc = zero

pread_g70       #Read G70 recall buffer
      foundcc = zero
      size2 = rbuf (two, zero)
      wc2 = one
      while wc2 <= size2 & foundcc = zero,
        [
        fcc_subid = rbuf (two, wc2)
        if fcc_subid = sub_op_id,
          [
          gcodecc = zero
          ng70s = fcc_ng70s
          ng70e = fcc_ng70e
          pbld, n, *scclgcode, *ng70s, *ng70e, e
          foundcc = one
          ]
        ]

pwrite_g70      #Write G70 recall buffer
      fcc_subid = sub_op_id
      fcc_ng70s = ng70s
      fcc_ng70e = ng70e
      fcc_subid = wbuf (two, rc2)

# --------------------------------------------------------------------------
#Subprogram output
#sub_trnstyp - 0=mirror, 1=rotate, 2=scale, 3=translate
#sub_trnmthd (mirror) - 0=X axis, 1=Y axis, 2=line
#sub_trnmthd (rotate) - 0=tplane, 1=tplane origin only, 2=coordinates
# --------------------------------------------------------------------------
pmiscint        #Capture the top level absinc for subprograms
      if sub_level <= zero, absinc = mi2
      ref_ret = mi3

psub_call_m     #Call to main level, single tool
      psub_call_trans

psub_call_mm    #Call to main level, multiple tools
      psub_call_trans

psub_call_trans #Translate level calls from toolchange, user
      #Mirror and coordinate rotate subs not allowed with lathe
      if sub_trnstyp <> three & posttype = two, result = mprint(slthrmerror)
      if (sub_trnstyp = one & sub_trnmthd = two)
      | sub_trnstyp = zero, result = mprint(smilrmerror)
      sav_absinc = absinc
      pindex
      if home_type > one,
        [
        if sub_mny_t,
          [
          absinc = zero
          pbld, n, *sgcode, pwcs, pfxout, pfyout, pfzout, pfcout, e
          pe_inc_calc
          ps_inc_calc
          ]
        ]
      else,
        [
        if home_type = one, result = mprint(shomeserror)
        else,
          [
          if sub_mny_t, result = mprint(smny50error)
          ]
        #Apply G50 shift and correct incremental position
        if sub_sec_no & sub_trnstyp = three,
          [
          sub_trnsx = vmap(sub_trnsx, hmtx1)
          sub_trnsx = vscl(m_one, sub_trnsx)
          sub_trnsx = sub_trnsx * dia_mult
          sub_trnsy = sub_trnsy * y_mult
          sub_trnsz = sub_trnsz * z_mult
          pbld, n, *sg50, *sub_trnsx, [if y_axis_mch, *sub_trnsy],
            *sub_trnsz, e
          prv_xia = vadd(prv_xia, sub_trnsx)
          ps_inc_calc
          ]
        if toolchng = zero | home_type < two,
          [
          pbld, n, *sgcode, pfxout, pfyout, pfzout, pfcout, e
          pe_inc_calc
          ps_inc_calc
          ]
        ]
      absinc = sav_absinc
      result = nwadrs(strp, main_prg_no)
      pbld, n, "M98", *main_prg_no, e
      prv_feed = c9k #Force feed in sub

psub_st_m       #Header in main level
      result = nwadrs(stro, main_prg_no)
      " ", e
      *main_prg_no, e

psub_end_m      #End in main level
      n, "M99", e

psub_call_s     #Call to sub level
      if tool_op = 201,  pread_g70
      else, foundcc = zero

      if foundcc = zero,
        [
        if sub_trnstyp <> 3, sub_level = -1
        else,
          [
          result = nwadrs(strp, sub_prg_no)
          sub_prg_no = sub_prg_no + 1000 #Add sub number offset
          pbld, n, "M98", *sub_prg_no, e
          ]
        ]

psub_st_s       #Header in sub leveln
      result = nwadrs(stro, sub_prg_no)
      " ", e
      *sub_prg_no, e

psub_end_s      #End in sub level
      n, "M99", e

# --------------------------------------------------------------------------
# Canned Text
# --------------------------------------------------------------------------
pcan          #Canned text - before output call
      strcantext = sblank
      if cant_no > zero,
        [
        if cant_pos1 = zero, pcant_1
        if cant_pos2 = zero, pcant_2
        if cant_pos3 = zero, pcant_3
        if cant_pos4 = zero, pcant_4
        if cant_pos5 = zero, pcant_5
        if cant_pos6 = zero, pcant_6
        if cant_pos7 = zero, pcant_7
        if cant_pos8 = zero, pcant_8
        if cant_pos9 = zero, pcant_9
        if cant_pos10 = zero, pcant_10
        pbld, n, strcantext, e
        strcantext = sblank
        ]

pcan1         #Canned text - with move
      strcantext = sblank
      if cant_no > zero,
        [
        if cant_pos1 = one, pcant_1
        if cant_pos2 = one, pcant_2
        if cant_pos3 = one, pcant_3
        if cant_pos4 = one, pcant_4
        if cant_pos5 = one, pcant_5
        if cant_pos6 = one, pcant_6
        if cant_pos7 = one, pcant_7
        if cant_pos8 = one, pcant_8
        if cant_pos9 = one, pcant_9
        if cant_pos10 = one, pcant_10
        ]
      if cstop, strcantext = strcantext + sm00
      if cgstop, strcantext = strcantext + sm01
      #Output of strcantext occurs at the end of the output line

pcan2         #Canned text - after output call
      strcantext = sblank
      if cant_no > zero,
        [
        if cant_pos1 = two, pcant_1
        if cant_pos2 = two, pcant_2
        if cant_pos3 = two, pcant_3
        if cant_pos4 = two, pcant_4
        if cant_pos5 = two, pcant_5
        if cant_pos6 = two, pcant_6
        if cant_pos7 = two, pcant_7
        if cant_pos8 = two, pcant_8
        if cant_pos9 = two, pcant_9
        if cant_pos10 = two, pcant_10, e
        pbld, n, strcantext, e
        strcantext = sblank
        ]

pcant_1       #Canned text - output call
      cantext = cant_val1
      pcant_out

pcant_2       #Canned text - output call
      cantext = cant_val2
      pcant_out

pcant_3       #Canned text - output call
      cantext = cant_val3
      pcant_out

pcant_4       #Canned text - output call
      cantext = cant_val4
      pcant_out

pcant_5       #Canned text - output call
      cantext = cant_val5
      pcant_out

pcant_6       #Canned text - output call
      cantext = cant_val6
      pcant_out

pcant_7       #Canned text - output call
      cantext = cant_val7
      pcant_out

pcant_8       #Canned text - output call
      cantext = cant_val8
      pcant_out

pcant_9       #Canned text - output call
      cantext = cant_val9
      pcant_out

pcant_10      #Canned text - output call
      cantext = cant_val10
      pcant_out

pcant_out     #Canned text - final output call
      #Assign string select global variables
      if cantext = 3, bld = one
      if cantext = 4, bld = zero
      if cantext = 9, exact = one
      if cantext = 10, exact = zero
      #Build the cantext string from strings
      if cantext = 1, strcantext = strcantext + sm00
      if cantext = 2, strcantext = strcantext + sm01
      #Build the cantext string from string selects
      if cantext = 5 | cantext = 6,
        [
        if cantext = 5, tlstk = zero
        else, tlstk = one
        rslt_upd = updstr (stlstk)
        strcantext = strcantext + stlstk
        ]
      if cantext = 7 | cantext = 8,
        [
        if cantext = 7, chute = zero
        else, chute = one
        rslt_upd = updstr (schute)
        strcantext = strcantext + schute
        ]
      #Build the cantext string from cantext number
      if cantext > 10,
        [
        strtextno = no2str(cantext)
        strcantext = strcantext + strm + strtextno
        ]

# --------------------------------------------------------------------------
# Position calculations, generally these do not need to be modified
# --------------------------------------------------------------------------
#The variables for absolute output are xabs, yabs, zabs.
#The variables for incremental output are xinc, yinc, zinc.
#They are found from the input variables x, y, z (typically) which are
#copied to copy_x, copy_y, copy_z.  These are passed to the mapping routine
#to get raw machine coordinates xa, ya, za.  These are used in pxyxcout to
#get the output xabs, yabs, zabs.  ps_inc_calc is called to get xinc, yinc,
#zinc.  cfeed_x, cfedd_y, cfeed_z are the unshifted positions for feed
#calculations.
# --------------------------------------------------------------------------
pxyzcout      #Perform calls for mapping coordinates and shifts
      pplane_mod
      if cuttype = one, pxyzcout0                   #Turning
      if abs(cuttype) = two                         #Right/Left Face cut
      | cuttype = three, pxyzcout2                  #Cross cut
      if cuttype = four, pxyzcout4                  #Y axis substitution
      if cuttype = five, pxyzcout5                  #Multisurf Rotary
      #C axis control modifications
      if posttype <> two,
        [
        pcoutrev
        cabs = c_wnd
        if c_axistype > one | millcc,
          [
          pindxcalc
          if c_axistype = three,
            [
            #Check if in tolerance
            cdelta = frac(abs(cabs)/ctable)
            if cdelta > ixtol & cdelta < 1-ixtol,
              result = mprint(sindxerror)
            indx_out = cabs
            ]
          if c_axistype = two, #Signed direction calculation
            [
            #Warn if a move greater than 360
            if abs(prvc_wnd - c_wnd) > 360, result = mprint(ssignerror)
            ]
          ]
        if y_axis = zero,
          [
          if cir_at_zero = one, gcode = one #only C is moving
          if cir_at_zero = m_one & (xa < zero | prv_xa < zero), c_ax_flp = one
          else, c_ax_flp = zero
          ]
        if millcc,
          [
          if fmtrnd(cabs) = 360, cabs = zero  #Always try to start at zero
          if cutpos2 > zero &  cutpos2 < four,
            [
            if abs(cuttype) = two, ppolar_fcyc
            ]
          ]
        ]
      pfcalc

pxyzcout0       #Lathe and machine coordinates
      cfeed_x = vequ(xa)
      csav = c
      pax_shift
      ipr_type = zero

pxyzcout4       #Calculations for Y axis substitution (mapped)
      cfeed_x = xa + (rotdia/two)
      cfeed_y = zero
      cfeed_z = za
      csav = ya * (360 / (pi * rotdia))
      pax_shift
      if millcc, ipr_type = zero
      else, ipr_type = one

pxyzcout2       #Polar conversion, Cross cut, Right/Left Face cut
      #Drill polar is toolplane drilling toward center
      #if not a coincident axis (Face cut)
      if (y_axis | (opcode = three & abs(cuttype) <> two)), pxyzcout0
      else,
        [
        cfeed_x = sqrt(xa^2 + ya^2)
        cfeed_y = zero
        cfeed_z = za
        if opcode = three & cuttype = three, csav = c
        else, csav = atan2(ya, xa) + c
        pax_shift
        ipr_type = one
        if not(millcc & abs(cuttype) = two),
          [
          if fmtrnd(xa) = zero & fmtrnd(ya) = zero & opcode <> three,
            pnt_at_zero = one
          ]
        ]

pxyzcout5       #Multisurf rotary axis motion
      csav = atan2(vtooly, vtoolz)
      axisx = vequ(caxisx)
      xa = rotp (-csav, xa)
      cfeed_x = vequ(xa)
      pax_shift
      csav = csav + c
      ipr_type = one

ppolar_fcyc     #Output values for face, polar conversion cycle
      xabs = (xa + dia_shift) * dia_mult
      yabs = zero
      zabs = (za + z_shift) * z_mult
      cabs = (ya + y_shift) * y_mult
      ipr_type = zero

pax_shift       #Apply multiplier and shift positions, csav was recalculated
      xabs = (cfeed_x + dia_shift) * dia_mult
      yabs = (cfeed_y + y_shift) * y_mult
      zabs = (cfeed_z + z_shift) * z_mult
      #Apply axis shift for lower turrets
      if posttype <> two & (lathtype = zero | lathtype = two),
        csav = csav + c_shift
      if posttype = two,
        [
        yabs = zero
        csav = zero
        ]

pplane_mod    #Modify the multiplier based on plane, see psw_str_mult
      if plane = zero,
        [
        dia_mult = prv_dia_mult * pl_ax_m0x
        y_mult = prv_y_mult * pl_ax_m0y
        z_mult = prv_z_mult * pl_ax_m0z
        ]
      else,
        [
        if plane = one,
          [
          dia_mult = prv_dia_mult * pl_ax_m1x
          y_mult = prv_y_mult * pl_ax_m1y
          z_mult = prv_z_mult * pl_ax_m1z
          ]
        else, #plane = two
          [
          dia_mult = prv_dia_mult * pl_ax_m2x
          y_mult = prv_y_mult * pl_ax_m2y
          z_mult = prv_z_mult * pl_ax_m2z
          ]
        ]

pcoutrev        #Rotary axis revolution calculation (Modify for wind-up)
      if cir_at_zero = one,
        [
        #Arcs at center position the c axis
        if cuttype = -2 | cuttype = three,
        csav = czero_csav - sweep
        else, csav = czero_csav + sweep
        ]
      #C does not move going to CL
      if pnt_at_zero, csav = prv_csav
      cdelta = fmtrnd(csav) - prv_csav  #This calculates once, for rev
      while abs(cdelta) > ctol, #If motion exceeds ctol, add wind-up
        [
        if cdelta > zero,
          [
          rev = rev - one
          cdelta = cdelta - 360
          ]
        else,
          [
          rev = rev + one
          cdelta = cdelta + 360
          ]
        ]
      if cuttype <> four, c_wnd = rev * 360 + csav
      else, c_wnd = sav_rev * 360 + csav
      !csav
      @c_wnd
      #Now switch to c_wnd which is the absolute winding C calculation
      #Modify for shortest direction if toolchange or toolplane
      #but not with axis subs
      if c_axistype <> three,
        [
        if abs(prvc_wnd - c_wnd) > 180
          & (toolchng | (y_axis & cuttype < four)),
          [
          while abs(prvc_wnd - c_wnd) > 180,
            [
            if prvc_wnd > c_wnd, rev = rev + one
            else, rev = rev - one
            c_wnd = rev * 360 + csav
            ]
          @c_wnd
          ]
        ]

pindxcalc       #Index move calculations, direction is shortest exc. Asub
      if pnt_at_zero | cdelta = zero, indx_mc = prv_indx_mc
      else,
        [
        cdelta = fmtrnd(c_wnd) - prvc_wnd
        if cuttype = four, #Just look at the direction
          [
          if cdelta >= zero, indx_mc = one
          else, indx_mc = zero
          ]
        else,
          [
          #Phase shift delta 10 revolutions, check odd/even for direction
          if frac(int((cdelta + 3600)/180)/two), indx_mc = zero
          else, indx_mc = one
          ]
        ]
      #Set range 0-360
      while cabs < zero, cabs = cabs + 360
      while cabs > 360, cabs = cabs - 360

pfcalc          #Feedrate calculations, gcode 0 does not evaluate
      if abs(c_wnd-prvc_wnd)<vtol | c_axistype=three | drillcur
      | ipr_type=zero | prv_pnt_at_zero | gcode = zero, pfcalc_u_min
      else, pfclc_deg_inv

pfcalc_u_min    #Feedrate unit/min
      feed = fr_pos
      if feed > maxfeedpm, feed = maxfeedpm
      prvfrdeg = feed

pfclc_deg_inv   #Feedrate deg/min, xa and ya are assumed relative to origin
      #Average last radius to current radius
      ldelta = ((cfeed_x+prv_cfeed_x)/two)^two+((cfeed_y+prv_cfeed_y)/two)^two
      circum = sqrt(ldelta) * two * pi
      if circum = zero, circum = c9k          #Don't allow Zero
      ldelta = (cfeed_x-prv_cfeed_x)^two+(cfeed_y-prv_cfeed_y)^two
      ldelta = sqrt(ldelta+(cfeed_z-prv_cfeed_z)^two)
      cdelta = ((abs(c_wnd - prvc_wnd))/360)*circum
      if ldelta = zero, cldelta = cdelta
      else, cldelta = sqrt(cdelta^two + ldelta^two)
      if cldelta = zero, cldelta = c9k
      #Feedrate deg/min control and calculation
      frdeg = abs(cdelta/cldelta) * abs(fr_pos * (360/circum))
      if abs(frdeg - prvfrdeg) > frdegstp | ipr_type <> prv_ipr_type,
        [
        #Control output of frdeg
        prvfrdeg = frdeg
        feed = frdeg
        ]
      if fmtrnd(frdeg) = zero, feed = fr_pos
      if frdeg > maxfrdeg, feed = maxfrdeg

#Incremental calculations
ps_inc_calc     #Incremental calculations, start
      xia = fmtrnd(xabs)
      yia = fmtrnd(yabs)
      zia = fmtrnd(zabs)
      xinc = vsub (xia, prv_xia)
      if posttype <> two, ps_cinc_calc

ps_cinc_calc    #Incremental calculations, start rotary
      cia = fmtrnd(cabs)
      cinc = cia - prv_cia

pe_inc_calc     #Incremental calculations, end
      prvc_wnd = fmtrnd(c_wnd)      #Avoid updating until called explicitly
      !cfeed_x, !cfeed_y, !cfeed_z, !ipr_type  #These are used in pxyzcout
      !x, !y, !z, !xa, !ya, !za
      !xia, !yia, !zia, !cia

# --------------------------------------------------------------------------
# Mapping routines, maps input to basic machine coordinates (side view)
# --------------------------------------------------------------------------
pmatrix_su      #Setup mapping matrix
      hmtx1 = matt(m1)
      if cuttype <> one, hmtx1 = mmul(hmtx1, smtx1)
      if cuttype = one, mmtx1 = matt(m1)
      if cuttype = two, mmtx1 = matt(smtx1)
      if cuttype = -2, mmtx1 = matt(bmtx1)
      if cuttype = three | cuttype = five, mmtx1 = matt(cmtx1)
      if cuttype = four, mmtx1 = matt(amtx1)
      if cuttype <> one, mmtx1 = mmul(mmtx1, smtx1)

pshft_map_xc    #Remove workshift and map to lathe coordinates, center
      xca = vadd (xc, tox)  #Always shift to origin
      if plane = one,
        [
        result = xca
        xca = zca
        zca = yca
        yca = result
        ]
      if plane = two,
        [
        result = yca
        yca = zca
        zca = result
        ]
      xca = vmap (xca, mmtx1)

pshft_map_ijk    #Remove workshift and map to lathe coordinates, ijk
      if arctype = one, #Absolute is shifted
        [
        if wcs_origin, iout = vadd (i, tox)
        else, iout = vequ (i)
        ]
      else, iout = vequ (i)
      iout = vmap (iout, mmtx1)

pshft_map_xa     #Remove workshift and map to lathe coordinates, xyz
      if wcs_origin, xa = vadd (copy_x, tox)
      else, xa = vequ (copy_x)
      xa = vmap (xa, mmtx1)

pmap_home     #Set the location for home position
      xa = vequ(xh)
      if map_home,
        [
        if wcs_origin, xa = vadd(xa, tox)
        xa = vmap(xa, hmtx1)
        ]
      pplane_mod
      pxyzcout0 #basic toolplane positioning

pmap_plane    #Map NCI plane to machine plane
      mach_plane = plane
      #Cross
      if cuttype=3 & plane<two, mach_plane = abs(plane - one)
      #Top
      if (abs(cuttype)<=one | abs(cuttype)>=4),
      mach_plane = plane - one
      if mach_plane = m_one, mach_plane = two

# --------------------------------------------------------------------------
# NCI file pre-read look ahead routines
# Build the toolchange buffer, sets cycle and turret flags
# --------------------------------------------------------------------------
pwrttparam      #Information from parameters
      if opcode = 104, result = fprm (opcode)

pwrtt           #Buffer toolchange information, tooltable = 3 calls on 1003
      if gcode = 1001, psetup
      pcut_cctyp
      if opcode=104 | opcode=105 | opcode=three | opcode=16, cc_pos = zero
      if gcode <> 1001, plast_recd
      pcur_recd
      if gcode <> 1003, cc_pos = zero
      !opcode, !tool_op
      if gcode = 1003,
        [
        size1 = rbuf (one, zero)
        rc1 = one
        if rc1 < size1, preadcur_nxt
        if cc_1013 = zero, cc_pos = zero
        ]

pcur_recd       #Write to the current tool record
      c1_gcode = gcode
      pmatrix_su
      pset_turret
      pmap_home
      c1_xh = vequ(xabs)
      c1_tox = vmap (tox, mmtx1)
      c1_cc_pos = cc_pos
      if gcode <> 1003, c1_tool = abs(t)
      else, c1_tool = zero
      c1_tloffno = tloffno
      c1_maxss = maxss
      c1_ss = abs(ss)
      if cool_w_spd = zero, c1_spdir = spdir + one
      else, c1_spdir = (spdir + one) + (fsg2(coolant) * three)
      c1_css_actv = css_actv
      c1_fr_pos = fr_pos
      c1_ipr_actv = ipr_actv
      c1_coolant = coolant
      c1_nextdc = nextdc
      c1_posttype = posttype
      c1_cuttype = cuttype
      c1_lathtype = lathtype
      c1_gcodecc = gcodecc
      c1_lathecc = lathecc
      c1_millcc = millcc
      c1_y_axis = y_axis
      if opcode = 104,
        [
        if face_thd <> two, x_min = abs(xmaj_thd)
        else,
          [
          if abs(zstrt_thd) > abs(zend_thd), x_min = abs(zstrt_thd)
          else, x_min = abs(zend_thd)
          ]
        x_max = x_min
        ]
      c1_gcode = wbuf (one, wc1)

plast_recd      #Update the last record(s) for min-max and point
      rc1 = wc1 - one
      c1_gcode = rbuf (one, rc1)
      if prv_opcode <> 104,
        [
        c1_x_min = x_min
        c1_x_max = x_max
        ]
      rc1 = wc1 - one               #rc1 is used to write also
      c1_gcode = wbuf (one, rc1)

pcut_cctyp      #Find the type of cut for the tool buffer
                #y_axis
                #posttype
                #cuttype
                #lathtype
      y_axis = zero
      cuttype = zero
      if posttype = two, cuttype = one
      else,
        [
        if mill5, cuttype = five
        else,
          [
          if rotary_type = one, cuttype = four
          else,
            [
            @m1, @m2, @m3, @m7, @m8, @m9
            if m7 = m_one & m8 = zero & m9 = zero, cuttype = -2
            if m7 = one & m8 = zero & m9 = zero, cuttype = two
            if m1 = m_one & m2 = zero & m3 = zero, cuttype = three
            if rotary_type = three, y_axis = one
            ]
          ]
        ]
      lathtype = lturret + spindle_no * two
      #Check for errors
      if rotary_type,
        [
        if (abs(cuttype) = two & rotary_axis <> three)
        | (cuttype = three & rotary_axis <> one),
          result = mprint(saxiserror)
        if cuttype = four & tlplnno <> one, result = mprint(stoperror)
        ]
      else,
        [
        if cuttype = zero, result = mprint(scutterror)
        ]
      #gcodecc, determine G74/G75 direction during processing
      #lathecc
      #millcc
      gcodecc = zero
      lathecc = zero
      if tool_op > 201,
        [
        if tool_op = 202 | tool_op = 203,
          [
          gcodecc = one
          lathecc = one
          if tool_op = 203, lathecc = m_one
          ]
        else,
          [
          if tool_op = 204 | tool_op = 205,
            [
            gcodecc = two
            lathecc = one
            if tool_op = 205, lathecc = m_one
            ]
          else,
            [
            if tool_op = 206 | tool_op = 207,
              [
              gcodecc = three
              lathecc = two
              if tool_op = 207, lathecc = -2
              ]
            else,
              [
              if tool_op = 208,
                [
                gcodecc = four
                lathecc = three
                ]
              ]
            ]
          ]
        ]
      if mi4<>zero & opcode <> three & (cuttype=four | abs(cuttype)=two),
         millcc = mi4
      else, millcc = zero

psetup          #Setup post based on NCI settings
      home_type = mi1
      sbufname3 = spathnci + snamenci + sextext
      spathext = spathnci
      snameext = snamenci
      #Set metric defaults
      if met_tool = one,
        [
        conversion = 1000
        ltol = ltol_m
        vtol = vtol_m
        maxfeedpm = maxfeedpm_m
        lcc_move = lcc_move_m
        ]

      #Setup for old or new style canned cycles
      if old_new_sw = one,
        [
        result = newfs (16, thddepth)
        result = newfs (16, thdfirst)
        ]
      else,
        [
        result = nwadrs (stra, thdang)
        result = nwadrs (stri, thdrdlt)
        result = nwadrs (strk, thddepth)
        result = nwadrs (strd, thdfirst)
        #Lathe canned cycle old style conversion
        result = nwadrs (strd, depthcc)
        result = nwadrs (strd, ncutscc)
        result = nwadrs (stri, g73x)
        result = nwadrs (strk, g73z)
        result = nwadrs (stri, grvspcc)
        result = nwadrs (strk, grvdpcc)
        ]
      #Setup for arctype setting
      if arctype = one | arctype = four,
        [
        result = newfs(two, i)
        result = newfs(two, j)
        result = newfs(two, k)
        result = newfs(two, iout)
        result = newfs(two, jout)
        result = newfs(two, kout)
        ]
      else,
        [
        result = newfs(three, i)
        result = newfs(three, j)
        result = newfs(three, k)
        result = newfs(three, iout)
        result = newfs(three, jout)
        result = newfs(three, kout)
        ]
      result = nwadrs(str_cax_abs, cabs)
      result = nwadrs(str_cax_inc, cinc)
      result = nwadrs(str_index, indx_out)
      sc_minus = str_cax_abs + sc_minus

# --------------------------------------------------------------------------
# Turret and cut type change setup, do not edit
# --------------------------------------------------------------------------
pset_turret     #Set the machine conditions and mapping based on the turret
      if lathtype = one | use_only_tl, pltype1
      else,
        [
        if lathtype = zero, pltype0
        else,
          [
          if lathtype = two, pltype2
          else, pltype3
          ]
        ]
      psw_str_mult

pltype0         #Bottom turret/Left spindle
      if cuttype = one,
        [
        #Lathe
        pcuttypldrl
        max_speed = max_speedl0
        min_speed = min_speedl0
        sw_string = scase_bl_c1
        ]
      else,
        [
        #Mill
        pcuttypmdrl
        max_speed = max_speedm0
        min_speed = min_speedm0
        sw_string = scase_bl_c2 #case two is the default
        if cuttype = -2, sw_string = scase_bl_c_2
        if cuttype = three, sw_string = scase_bl_c3
        if cuttype = four & abs(c1_millcc) = one, sw_string = scase_bl_c4c
        if cuttype = four & c1_millcc = zero, sw_string = scase_bl_c4
        if cuttype = five, sw_string = scase_bl_c5
        ]

pltype1         #Top turret/Left spindle
      if cuttype = one,
        [
        #Lathe
        pcuttypldrl
        max_speed = max_speedl1
        min_speed = min_speedl1
        sw_string = scase_tl_c1
        ]
      else,
        [
        #Mill
        pcuttypmdrl
        max_speed = max_speedm1
        min_speed = min_speedm1
        sw_string = scase_tl_c2 #case two is the default
        if cuttype = -2, sw_string = scase_tl_c_2
        if cuttype = three, sw_string = scase_tl_c3
        if cuttype = four & abs(c1_millcc) = one, sw_string = scase_tl_c4c
        if cuttype = four & c1_millcc = zero, sw_string = scase_tl_c4
        if cuttype = five, sw_string = scase_tl_c5
        ]

pltype2         #Bottom turret/Right spindle
      if cuttype = one,
        [
        #Lathe
        pcuttypldrl
        max_speed = max_speedl2
        min_speed = min_speedl2
        sw_string = scase_br_c1
        ]
      else,
        [
        #Mill
        pcuttypmdrl
        max_speed = max_speedm2
        min_speed = min_speedm2
        sw_string = scase_br_c2 #case two is the default
        if cuttype = -2, sw_string = scase_br_c_2
        if cuttype = three, sw_string = scase_br_c3
        if cuttype = four & abs(c1_millcc) = one, sw_string = scase_br_c4c
        if cuttype = four & c1_millcc = zero, sw_string = scase_br_c4
        if cuttype = five, sw_string = scase_br_c5
        ]

pltype3         #Top turret/Right spindle
      if cuttype = one,
        [
        #Lathe
        pcuttypldrl
        max_speed = max_speedl3
        min_speed = min_speedl3
        sw_string = scase_tr_c1
        ]
      else,
        [
        #Mill
        pcuttypmdrl
        max_speed = max_speedm3
        min_speed = min_speedm3
        sw_string = scase_tr_c2 #case two is the default
        if cuttype = -2, sw_string = scase_tr_c_2
        if cuttype = three, sw_string = scase_tr_c3
        if cuttype = four & abs(c1_millcc) = one, sw_string = scase_tr_c4c
        if cuttype = four & c1_millcc = zero, sw_string = scase_tr_c4
        if cuttype = five, sw_string = scase_tr_c5
        ]

psw_str_mult    #Apply sw_string to variables and strings
      #c axis type
      c_axistype = plcval (sw_string, 8)
      #reverse spindle
      spd_rev = plcval (sw_string, 7)
      #plane 0
      rslt_plc = plcval (sw_string, 6)
       if rslt_plc = zero,
        [
        sg02 = sxg02
        sg03 = sxg03
        sg41 = sxg41
        sg42 = sxg42
        ]
      else,
        [
        sg02 = sxg03
        sg03 = sxg02
        sg41 = sxg42
        sg42 = sxg41
        ]
      #plane 1
      rslt_plc = plcval (sw_string, five)
      if rslt_plc = zero,
        [
        sg02_1 = sxg02
        sg03_1 = sxg03
        sg41_1 = sxg41
        sg42_1 = sxg42
        ]
      else,
        [
        sg02_1 = sxg03
        sg03_1 = sxg02
        sg41_1 = sxg42
        sg42_1 = sxg41
        ]
      #plane 2
      rslt_plc = plcval (sw_string, four)
      if rslt_plc = zero,
        [
        sg02_2 = sxg02
        sg03_2 = sxg03
        sg41_2 = sxg41
        sg42_2 = sxg42
        ]
      else,
        [
        sg02_2 = sxg03
        sg03_2 = sxg02
        sg41_2 = sxg42
        sg42_2 = sxg41
        ]
      #plane 0
      rslt_plc = plcval (sw_string, three)
      rslt_upd = updstr (swstr)
      sg17 = swstr
      #plane 1
      rslt_plc = plcval (sw_string, two)
      rslt_upd = updstr (swstr)
      sg19 = swstr
      #plane 2
      rslt_plc = plcval (sw_string, one)
      rslt_upd = updstr (swstr)
      sg18 = swstr
      #plane 0, x axis
      rslt_plc = plcval (sw_string, m_one)
      pl_ax_m0x = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -2)
      pl_ax_m0y = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -3)
      pl_ax_m0z = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -4)
      pl_ax_m1x = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -5)
      pl_ax_m1y = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -6)
      pl_ax_m1z = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -7)
      pl_ax_m2x = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -8)
      pl_ax_m2y = -((rslt_plc * two) - one)
      rslt_plc = plcval (sw_string, -9)
      pl_ax_m2z = -((rslt_plc * two) - one)

# --------------------------------------------------------------------------
# Numbered questions for Mastercam --  Used by Lathe 9
# --------------------------------------------------------------------------
38. Rapid feedrate? 250
1538. Rapid feedrate (metric)? 10000.0

80. Communications port number for receive and transmit (1 or 2) ? 2
81. Data rate (110,150,300,600,1200,2400,4800,9600,14400,19200,38400)? 1200
82. Parity (E/O/N)? E
83. Data bits (7 or 8)? 7
84. Stop bits (1 or 2)? 2
85. Strip line feeds? N
86. Delay after end of line (seconds)? 0
87. Ascii, Eia, or Binary (A/E/B)? A
88. Echo keyboard to screen in terminal emulation? N
89. Strip carriage returns? N

90. Drive and subdirectory for NC files?
91. Name of executable post processor? MPL
92. Name of reverse post processor? RPL
93. Reverse post PST file name? RPL_GEN

100. Number of places BEFORE the decimal point for sequence numbers? -1
101. Number of places AFTER the decimal point for sequence numbers? -1
103. Maximum spindle speed? 3600
108. Name of associated Mill post? MPLFAN

161. Enable Home Position button? y
162. Enable Reference Point button? y
163. Enable Misc. Values button? y
164. Enable Rotary Axis button? y
165. Enable Tool Plane button? y
166. Enable Construction Plane button? y
167. Enable Tool Display button? y
168. Check tplane during automatic work origin creation? y

# --------------------------------------------------------------------------
# Default Miscellaneous Real Values, see lathe defaults below
# --------------------------------------------------------------------------
201. Default miscellaneous real variable 1 (mr1)? 0.0
202. Default miscellaneous real variable 2 (mr2)? 0.0
203. Default miscellaneous real variable 3 (mr3)? 0.0
204. Default miscellaneous real variable 4 (mr4)? 0.0
205. Default miscellaneous real variable 5 (mr5)? 0.0
206. Default miscellaneous real variable 6 (mr6)? 0.0
207. Default miscellaneous real variable 7 (mr7)? 0.0
208. Default miscellaneous real variable 8 (mr8)? 0.0
209. Default miscellaneous real variable 9 (mr9)? 0.0
210. Default miscellaneous real variable 10 (mr10)? 0.0

# --------------------------------------------------------------------------
# Default Miscellaneous Real Values (METRIC)
# --------------------------------------------------------------------------
1601. Default miscellaneous real variable 1 (mr1) (metric)? 0.0
1602. Default miscellaneous real variable 2 (mr2) (metric)? 0.0
1603. Default miscellaneous real variable 3 (mr3) (metric)? 0.0
1604. Default miscellaneous real variable 4 (mr4) (metric)? 0.0
1605. Default miscellaneous real variable 5 (mr5) (metric)? 0.0
1606. Default miscellaneous real variable 6 (mr6) (metric)? 0.0
1607. Default miscellaneous real variable 7 (mr7) (metric)? 0.0
1608. Default miscellaneous real variable 8 (mr8) (metric)? 0.0
1609. Default miscellaneous real variable 9 (mr9) (metric)? 0.0
1610. Default miscellaneous real variable 10 (mr10) (metric)? 0.0

# --------------------------------------------------------------------------
# Enable/Disable Miscellaneous Real Variable switches
# --------------------------------------------------------------------------
1611. Enable miscellaneous real variable 1? y
1612. Enable miscellaneous real variable 2? y
1613. Enable miscellaneous real variable 3? y
1614. Enable miscellaneous real variable 4? y
1615. Enable miscellaneous real variable 5? y
1616. Enable miscellaneous real variable 6? y
1617. Enable miscellaneous real variable 7? y
1618. Enable miscellaneous real variable 8? y
1619. Enable miscellaneous real variable 9? y
1620. Enable miscellaneous real variable 10? y

# --------------------------------------------------------------------------
# Default Miscellaneous Integer Values, see lathe defaults below
# --------------------------------------------------------------------------
301. Work coordinate (-1=REF, 0=G50, 1=HOME, 2=G54's)? 2
302. Top Level absolute/incremental (0=ABS, 1=INC)? 0
303. G28 or G30 return (0=G28, 1=G30)? 0
304. Can Conversion Cycles (Mill 1 or -1)? 0
305. Default miscellaneous integer variable 5 (mi5)? 0
306. Default miscellaneous integer variable 6 (mi6)? 0
307. Default miscellaneous integer variable 7 (mi7)? 0
308. Default miscellaneous integer variable 8 (mi8)? 0
309. Default miscellaneous integer variable 9 (mi9)? 0
310. Default miscellaneous integer variable 10 (mi10)? 0

# --------------------------------------------------------------------------
# Enable/Disable Miscellaneous Integer Variable switches
# --------------------------------------------------------------------------
1621. Enable miscellaneous integer variable 1? y
1622. Enable miscellaneous integer variable 2? y
1623. Enable miscellaneous integer variable 3? y
1624. Enable miscellaneous integer variable 4? y
1625. Enable miscellaneous integer variable 5? y
1626. Enable miscellaneous integer variable 6? y
1627. Enable miscellaneous integer variable 7? y
1628. Enable miscellaneous integer variable 8? y
1629. Enable miscellaneous integer variable 9? y
1630. Enable miscellaneous integer variable 10? y

# --------------------------------------------------------------------------
# Configuration File association parameters (default is "y")
# --------------------------------------------------------------------------
#400. Name of associated cfg file?
401. Read SYSTEM COLORS section? y
402. Read ALLOCATIONS section? y
403. Read TOLERANCES section? y
404. Read DATA PATHS section? y
405. Read COMMUNICATIONS section? y
406. Read DRAFT SETTINGS section? y
407. Read MISCELLANEOUS section? y
408. Read NC SETTINGS section? y
409. Read DIALOG SCRIPTS section? y
410. Read DESIGN SETTINGS section? y
411. Read PLOTTER SETTINGS section? y
412. Read ALT-KEY ASSIGNMENTS section? y
413. Read CAD section? y
414. Read START/EXIT section? y
415. Read SCREEN section? y
416. Read FILE NAMES section? y

1501. Insert parameter information in the ascii NCI? y
1502. Write operation information to binary file (.ops)? n

1520. Display a warning when cutter compensation in control simulation finds an error? n

# Do NOT manually change the answer for Q.1999 !
1999. Product major version number that post supports? 9
 
3001. Machine acceleration? 2
3002. Timing size? .1

3010. Minimum inch/revolution feedrate? .002
3011. Minimum mm/revolution feedrate? .05

3020. Enable canned roughing turning (Post must support these operations)? y
3021. Enable canned roughing pattern repeat? y
3022. Enable canned grooving? y
3023. Enable canned threading? y
3024. Enable canned finish? y

3040. Enable canned groove wall taper? n
3041. Enable canned groove radius on corners? n
3042. Enable canned groove radius on chamfer? n
3043. Enable canned groove rough pecking? y
3044. Enable canned groove rough depth cuts?y
3045. Enable canned groove dwell? n
3046. Enable canned groove chamfer on corners? n

3050. Enable canned thread equal depths? y
3051. Enable canned thread equal area? y
3052. Enable canned thread multiple starts? y
3053. Enable canned thread anticipated pulloff? y

# --------------------------------------------------------------------------
# Lathe misc reals
# --------------------------------------------------------------------------
#3201. Default lathe miscellaneous real variable 1 (mr1)? 0.0
#3202. Default lathe miscellaneous real variable 2 (mr2)? 0.0
#3203. Default lathe miscellaneous real variable 3 (mr3)? 0.0 
#3204. Default lathe miscellaneous real variable 4 (mr4)? 0.0 
#3205. Default lathe miscellaneous real variable 5 (mr5)? 0.0
#3206. Default lathe miscellaneous real variable 6 (mr6)? 0.0
#3207. Default lathe miscellaneous real variable 7 (mr7)? 0.0
#3208. Default lathe miscellaneous real variable 8 (mr8)? 0.0
#3209. Default lathe miscellaneous real variable 9 (mr9)? 0.0
#3210. Default lathe miscellaneous real variable 10 (mr10)? 0.0

# --------------------------------------------------------------------------
# Enable/Disable LATHE Miscellaneous Real Variable switches
# --------------------------------------------------------------------------
1631. Enable lathe miscellaneous real variable 1? y
1632. Enable lathe miscellaneous real variable 2? y
1633. Enable lathe miscellaneous real variable 3? y
1634. Enable lathe miscellaneous real variable 4? y
1635. Enable lathe miscellaneous real variable 5? y
1636. Enable lathe miscellaneous real variable 6? y
1637. Enable lathe miscellaneous real variable 7? y
1638. Enable lathe miscellaneous real variable 8? y
1639. Enable lathe miscellaneous real variable 9? y
1640. Enable lathe miscellaneous real variable 10? y

# --------------------------------------------------------------------------
# Lathe misc integers
# --------------------------------------------------------------------------
#3301. Default lathe miscellaneous integer variable 1 (mi1)? 0
#3302. Default lathe miscellaneous integer variable 2 (mi2)? 0
#3303. Default lathe miscellaneous integer variable 3 (mi3)? 0
#3304. Default lathe miscellaneous integer variable 4 (mi4)? 0
#3305. Default lathe miscellaneous integer variable 5 (mi5)? 0
#3306. Default lathe miscellaneous integer variable 6 (mi6)? 0
#3307. Default lathe miscellaneous integer variable 7 (mi7)? 0
#3308. Default lathe miscellaneous integer variable 8 (mi8)? 0
#3309. Default lathe miscellaneous integer variable 9 (mi9)? 0
#3310. Default lathe miscellaneous integer variable 10 (mi10)? 0

# --------------------------------------------------------------------------
# LATHE Default Miscellaneous Real Values  (METRIC)
# --------------------------------------------------------------------------
#3601. Default lathe miscellaneous real variable 1 (mr1) (metric)? 0.0
#3602. Default lathe miscellaneous real variable 2 (mr2) (metric)? 0.0
#3603. Default lathe miscellaneous real variable 3 (mr3) (metric)? 0.0
#3604. Default lathe miscellaneous real variable 4 (mr4) (metric)? 0.0
#3605. Default lathe miscellaneous real variable 5 (mr5) (metric)? 0.0
#3606. Default lathe miscellaneous real variable 6 (mr6) (metric)? 0.0
#3607. Default lathe miscellaneous real variable 7 (mr7) (metric)? 0.0
#3608. Default lathe miscellaneous real variable 8 (mr8) (metric)? 0.0
#3609. Default lathe miscellaneous real variable 9 (mr9) (metric)? 0.0
#3610. Default lathe miscellaneous real variable 10 (mr10) (metric)? 0.0

# --------------------------------------------------------------------------
# Enable/Disable LATHE Miscellaneous Integer Variable switches
# --------------------------------------------------------------------------
1641. Enable lathe miscellaneous integer variable 1? y
1642. Enable lathe miscellaneous integer variable 2? y
1643. Enable lathe miscellaneous integer variable 3? y
1644. Enable lathe miscellaneous integer variable 4? y
1645. Enable lathe miscellaneous integer variable 5? y
1646. Enable lathe miscellaneous integer variable 6? y
1647. Enable lathe miscellaneous integer variable 7? y
1648. Enable lathe miscellaneous integer variable 8? y
1649. Enable lathe miscellaneous integer variable 9? y
1650. Enable lathe miscellaneous integer variable 10? y