; General Post Processor
; Machine           :
; Type              :
; SubRoutines       :
; Comp Type         : 
; Customer          : 
; Rev 1.0 :10.23.2012 : Configured post for evaluation version software.
; ---Things to do-----
;

@init_post

	global string sUS_date sUS_time sUsrmsg sHomestr sHomestrbegin sHomestrtc sHomestrend sHomestrstpdiff sHomestrstpsame sHomeline
	global string sCamfilepath sSubspath cWo cPb cPe cG84 cG84p cCycs cHomep cTCcodep cTCcodes fG84spin cDr cCb cCe cDrZp cDrZs
	global string cDrCys cDrPts cG84endl cPn cHoffset sPostRevOutput
	global logical bStartFile bTlchg bSkipxyrapid bWorkoffsettc bfirst_rapid
	global logical bSubs bTlseperation bTcseperation bDateTimeOutput bStopM00difftool bToolPreselect bToolChangeAtEnd
	global logical bFromendprogram bFrombeginchangetool bFromendchangetool bFromendoffile bMultiplefixtures
	global logical bSafetyprep bSyncdrapid bFeedoutput bNnumtc
	global logical bOptstpbegin bOptstptc bOptstpend bUseprognum bUseprogname bCoolspinaftertc bCoolAfterHeightComp
	global logical bCoolExist bCoolofftc bSpinofftc bCooloffend bSpinoffend bG84spin bTest bHeightComp bHeightCompOffset
	global logical bHeightComponToolCh bHeightCompZsameLine bTCSplit bSpinOnlyUseS bDiameterCompOutputD bCompTypeOutput bPostRevOutput bUseFileName
	global logical bOutputToolList bOutputToolMessage bOutputUserMessages bSimpleformat
	global integer iMplane iAbsincmode iWorkoffset iHeightcomp iStopmode iMotionmode
	global integer iDiametercomp iDrillmode iTcnumber iNumpecks iPworkoffset iSpindleDir
	global integer iSlength_g_file_name iSlength_full_g_file_name iSlengthcampartpath iDiameteroffset iArcmode iG84feed
	global integer iHomingmode iWorkOffsetmode iProgendmode iG187_P_gpp iSplit_ProgName_Num iNumSeparationLines iOperationMessage ihome_number iLhome_number ippart_home_number
	global integer iCoolantM1 iCoolantM2 iCoolantM3 iCoolantM4 iCoolantM5 iCoolantM6 iCoolantM7 iCoolantM8
	global integer iCoolantM1ON iCoolantM2ON iCoolantM3ON iCoolantM4ON iCoolantM5ON iCoolantM6ON iCoolantM7ON iCoolantM8ON
	global integer iCoolantM1OFF iCoolantM2OFF iCoolantM3OFF iCoolantM4OFF iCoolantM5OFF iCoolantM6OFF iCoolantM7OFF iCoolantM8OFF
	global numeric nTcXnext nTcYnext nTcZnext nTcCnext nCorrectedpeck nRapidfeed nG187_E_gpp nHeightCompcode nG84feed
	global numeric mltfixxpos mltfixypos mltfixzpos
	global numeric  nR1pos5x nR1pos nR1postmatrix nR1postransform nR1poscpos nPtool_z_level nPR1pos nR1posadj nR1postemp
	global numeric  nR2pos5x nR2pos nR2postmatrix nR2postransform nR2poscpos nPR2pos nR2posadj nR2postemp
	global numeric nPtool_start_plane prevFeed iR1dir nPtool_z_level iR2dir nLlabel  pxmpos pympos pzmpos
	global string cR1 cR2 sHomestrrot nR1pos_f nR2pos_f bpos_f  ;apos_f
	global integer iFeedType iR1posControl i4xIndexMode i4xIndexClearanceMode i4xFeedMode
	; Non GPPL variables
	num_user_procs =    1
	remove_blanks = FALSE
	line_labels    = FALSE     ; Jump to N...
	clear_change_after_gen = 1

	; GPPL variables
	numeric_def_f   = '5.4'
	integer_def_f   = '5.0(p)'
	gcode_f         = '2/2.0(p)'
	mcode_f         = '2/2.0(p)'
	xpos_f          = '5.4'
	ypos_f          = '5.4'
	zpos_f          = '5.4'
	nR1pos_f        = '5.3'
	nR2pos_f        = '5.4'
	apos_f          = '5.3'
	bpos_f          = '5.4'
	feed_f          = '4.4'
	blknum_f        = '5.0(p)'
	blknum_gen      = true
	call @usr_ip_useroptions
	call @usr_ip_postwriteroptions
endp

@usr_ip_useroptions
	; Handle setting of options -- For end users & post writers

	;--------- Tool Change ---------
	bToolPreselect        = false      ;True = Next tool is Preselected after tool change
	bTCSplit              = false      ;True = Outputs M06 and T1 on separate lines (set 'M06' in cTCcodes, not cTCcodep)
	cTCcodep              = ''     ;Sets the Prefix Code(s) used for Tool Change (i.e. 'M06')
	cTCcodes              = 'M03'         ;Sets the Suffix Code(s) used for Tool Change (i.e. 'M06')
	bHeightComp           = true       ;True = Outputs Height Compensation (i.e. G43)
	bHeightCompOffset     = false       ;True = Outputs Height Offset (i.e. H1)
	nHeightCompcode       = 47         ;Sets the code for activating Hieght Compensation (i.e. 43,56)
	cHoffset              = 'H'        ;Sets the Character(s) for Height Offset (i.e. H)
	bHeightCompZsameLine  = false       ;True = Z outputs on same line with Height Compensation (i.e. G43 H1 Z1.0)
	bHeightComponToolCh   = false       ;True = Z outputs on same line with Height Compensation (i.e. G43 H1 Z1.0)
	bToolChangeAtEnd      = false       ;True = Tool Change for First Tool at end of program
	bOutputToolMessage    = false       ;True = Outputs Tool Message at Tool Change

	;--------- Program Header & End ---------
	bUseprognum           = false       ;True = Outputs Program Number
	bUseprogname          = false       ;True = Outputs Program Name
	iSplit_ProgName_Num   = 0          ;Sets if Program Name and Number are on separate lines (0=No, 1=Name->Number, 2=Number->Name)
	bUseFileName          = false      ;True = Outputs Gcode file name at beginning of file
	cPn                   = ''        ;Sets the Character(s) before program number (i.e. 'O', ':', or nothing)
	iProgendmode          = 2          ;Sets the code for ending a program (1=M30,2=M2)
	cPb                   = ''        ;Sets the Character(s) used for the beginning of file (i.e %)
	cPe                   = ''        ;Sets the Character(s) used for the beginning of file (i.e %)
	bCompTypeOutput       = false       ;True = Outputs the Cutter Compensation type as a message (i.e. (COMPENSATION-WEAR) )
	bPostRevOutput        = false       ;True = Outputs the Post Revision as a message (i.e. (REV-0.61) )
	sPostRevOutput        = 'Post Rev 0.2'  ;0.71: Sets Rev number of post to be output
	bDateTimeOutput       = false       ;True = Outputs Date & Time
	cCb                   = '('        ;Sets the begginning Character(s) for comments
	cCe                   = ')'        ;Sets the ending Character(s) for comments
	bOutputToolList       = true       ;True = Outputs Tool List at the beginning of program

	;--------- Motion (Lines, Arc, etc) ---------
	bSyncdrapid           = true      ;True = Machine Sync's Rapid Motion (Non-Box Move)
	nRapidfeed            = 1500.       ;Set your value for Max Feed in G1 (Used with Non-Sync'd Rapid Moves)
	iArcmode              = 2          ;Sets Arc Output Mode (1=AbsIJK, 2=IncIJK, 3=R 360AbsIJK, 4=R 360IncIJK)

	;--------- Work Offset ---------
	cWo                   = 'G52L'     ;Sets the Character(s) used for Work Offset (i.e. G, E, G54.1 P)
	iWorkOffsetmode       = 3          ;Sets the Mode used for Work Offset (1=G54, 2=E1, 3=G54.1 P1)
	bWorkoffsettc         = true       ;True = Forces output of Work Offset at each Tool Change

	;--------- Drilling ---------
	cDr                   = 'G98 '     ;Sets the Character(s) used at the begging of a drill cycle (i.e. G98,G98,or nothing '')
	cG84                  = 'G84'      ;Sets the Drill Cycle Character(s) used tapping (i.e. G84, G84.1)
	cG84p                 = ''         ;Sets the Preperation Line used for G84 Tapping (i.e. G84.2)**FADAL setting
	bG84spin              = false      ;True = RPM is output during G84 Tapping Cycles
	fG84spin              = '5.1'      ;Sets Formatting for RPM used for G84 Tapping Cycles ('5.1' = Decimal point 1 place)
	iG84feed              = 1          ;Sets the Mode for Feed when for G84 Tapping (1=Feed rate 2=Pitch)
	cG84endl              = ''         ;Sets the Line after G80 for G84 Tapping (i.e. G94, or nothing)
	cCycs                 = 'L0 '      ;Sets the Suppression Code to ignore Drill Cycles (i.e. L0)
	cDrZp                 = ''         ;Sets the Prefix Code(s) used to set retract position for drilling (i.e. G71, or nothing)
	cDrZs                 = ''         ;Sets the Suffix Code(s) used to set retract position for drilling (i.e. G71, or nothing)
	cDrCys                = ''         ;Sets the Suffix Code(s) used on Drill Cycle line (i.e. M53, or nothing)
	cDrPts                = ''         ;Sets the Suffix Code(s) used on Drill Point line (i.e. M53, or nothing)

	;--------- Coolant and Spindle ---------
	bCoolExist            = true       ;True = Outputs Coolant codes (Coolant,Air,Mist,etc)
	bCoolofftc            = true       ;True = Outputs Coolant off between Tool Changes
	bSpinofftc            = true       ;True = Outputs Spindle off between Tool Changes
	bCooloffend           = true       ;True = Outputs Coolant off at end of program
	bSpinoffend           = true       ;True = Outputs Spindle off at end of program
	bCoolspinaftertc      = true      ;True = Outputs Coolant&Spindle directly after Tool Change
	bCoolAfterHeightComp  = false      ;True = Outputs Coolant on a separate line, after G43 H1 Z1.0.
	iCoolantM1ON          = 8          ;Code: Flood Coolant ON
	iCoolantM1OFF         = 9          ;Code: Flood Coolant OFF
	iCoolantM2ON          = 7          ;Code: Flood Coolant ON
	iCoolantM2OFF         = 9          ;Code: Flood Coolant OFF
	iCoolantM5ON          = 88         ;Code: High Pressure Coolant Through Tool ON
	iCoolantM5OFF         = 89         ;Code: High Pressure Coolant Through Tool OFF
	iCoolantM7ON          = 83         ;Code: Air Blast ON
	iCoolantM7OFF         = 84         ;Code: Air Blast OFF
	bSpinOnlyUseS         = true      ;True = Disables outputting M3/M4, only used S (ie. "S1000" instead of "S1000 M3")

	;--------- Block/Line Numbering ---------
	bNnumtc               = false       ;True = Outputs N Numbers at Tool Changes (i.e. N1,N2,N3)
	blknum_exist          = false       ;True = Outputs Line Numbers
	blknum                = 2        ;Sets Starting Line Number
	blknum_delta          = 2          ;Sets the delta for Line Numbers
	blknum_max            = 999999    ;Sets the maximum value for Line Numbers

	;--------- Cutter Compensation ---------
	bDiameterCompOutputD  = true       ;True = Outputs D number when turning on Cutter Compensation (i.e. G41 D1)

	;--------- Optional Stops (M01) ---------
	bOptstpbegin          = false      ;True = Outputs Optional Stop at beginning of program
	bOptstptc             = false       ;True = Outputs Optional Stop between Tool Changes
	bOptstpend            = false      ;True = Outputs Optional Stop at end of program

	;--------- Gcode Separation (Visual setting) ---------
	bTlseperation         = false       ;True = Seperates Tool List by blank line(s)
	bTcseperation         = false       ;True = Seperates Tool List by blank line(s)
	iNumSeparationLines   = 2          ;Sets the amount of Blank lines when using Tool List Separation

	;--------- Misc. Options ---------
	iOperationMessage     = 2          ;Controls output of Operation messge (0=off, 1=long style, 2=short style)
	bOutputUserMessages   = true       ;true = outputs user messages (message field found in Operation - Misc parameters tab)
	bSimpleformat         = true      ;true = Simple G/M code format for special controllers (WinCNC, Millpwr, etc)

	;---------          Homing & Zero Returning axis             ---------
	;--------- Instructions and explaination of definition below ---------

	;  Format: [x][integer:][Prepstr :][AxisStr1 ;][AxisStrN]
	;  x       = Putting 'x' as the first character means "Homing Mode" must be set for each line (i.e. 'x2:G00 :Z0 ;3:G00 :X-15.0 ' )
	;  integer = Homing Output Mode (1=G28, 2=G28 G91, 3=G53 Non-Modal, 4=G53 Modal, 5=G30, 6=G30 G91, 7= any string)
	;  PrepStr = Sets the code(s) for the begging of line used for Homing Axis (i.e. 'G00')
	;  AxisStr = Homing Axis Definition (i.e. 'Z0.0', 'H0.0 W0.')
	;  Note: You can define up to 49 "Homing Lines" seperated by ";"
	;  Note: Only use ";" if using more then 1 "Homing Line"
	;  Note: Define string as empty '' to ignore Specific Homing Definition
	sHomestrbegin         = ''                           ; Program Begin Homing Definition
	sHomestrtc            = '7::G00 X0 Y0 V0 C0 B0 '                           ; Tool Change Homing Definition
	sHomestrend           = '7::G00 X0 Y0 V0 C0 B0 '     ; Program End Homing Definition
	sHomestrstpsame       = ''                 ; M00 Same Tool Homing Definition
	sHomestrstpdiff       = ''                 ; M00 Different Tool Homing Definition
	sHomestrrot           = '7::G00 X0 Y0 V0 C0 B0 '                     ;Between Rotations

	; ---- 4x
	iR1dir                = 1         ;1=+CCW -1=+CW
	iR2dir                = 1         ;1=+CCW -1=+CW for Rotary 2 Axis
	cR1                   = 'A'       ;Rotary 1 Axis
	cR2                   = 'B'       ;Rotary 2 Axis
	iR1posControl         = 0         ;Rotary Position Control (0=SolidCAM Direct, 1=Positive, 2=Negative, 3=Shortest Distance)
	i4xIndexMode          = 2         ;4x-Indexing control (0=Simple Rotation, 1=New WorkOffset, 2=Trig Macro)
	i4xIndexClearanceMode = 0         ;4x-Index Clearance control (0=Z-Homing, 1=Z-Tool_Z_Level, 2=Z-Tool_start_plane 3 = none)
	i4xFeedMode           = 0         ;4x-Simultanious control (0=Programed feedRate, 1=Inverse Time FeedRate, 2=Deg. per Minute)
	; ---- 4x

endp

@usr_ip_postwriteroptions
	; Handle setting of options -- For Post Writers
	bSubs = false          ;True = Using sub routines, False = Not using sub routines
; ------ Tracing functions -----
;	trace "all":5                                                         ; Mode 1 (standard)
; trace "all":1                                                         ; Mode 2 (standard)
; trace "@rapid_move, @move_4x, @move_5x":5                             ; Mode 3
; trace "@line, @arc, @line_4X, @line_5x, @compensation":5              ; Mode 4
; trace "@drill, @drill_point, @drill4x_pnt, @end_drill":5              ; Mode 5
; trace "@tool_path_info":5                                             ; Mode 6
; trace "@start_of_job, @end_of_job, @tmatrix, @rotate_to_plane":5           ; Mode 7
; trace "@change_tool, @turn_change_tool, @def_tool, @def_turn_tool":5  ; Mode 8
; trace "@feed_spin, @m_feed_spin":5                                    ; Mode 9
; trace "@rotate, @rotary_info":5                                       ; Mode 10
endp

;-------------------

@start_of_file
	; Handle what is output at the start of the file
	; This is the first procedure called (lie...@init_post is actually first)
	if iNumber_of_Fixtures > 1
		bMultiplefixtures = true
		blknum_exist    = false
	endif
	call @usr_campart_path
	call @usr_init_gmstates
	call @usr_sof_character
	call @usr_sof_progname
	call @usr_sof_commentsbeforecodes
	call @usr_sof_gmcodes
	call @usr_sof_commentsaftercodes
	bStartFile = true
	iLhome_number = home_number
	if message1 ne ''
		{NL,'(',message1,')'}
	endif
	if message2 ne ''
		{NL,'(',message2,')'}
	endif
	if message3 ne ''
		{NL,'(',message3,')'}
	endif
	if message4 ne ''
		{NL,'(',message4,')'}
	endif
	if message5 ne ''
		{NL,'(',message5,')'}
	endif
	if message6 ne ''
		{NL,'(',message6,')'}
	endif
	if message7 ne ''
		{NL,'(',message7,')'}
	endif
	if message8 ne ''
		{NL,'(',message8,')'}
	endif
	if message9 ne ''
		{NL,'(',message9,')'}
	endif
	if message10 ne ''
		{NL,'(',message10,')'}
	endif
	{NL,'M48 '}
	{NL,' '}
	if bOutputToolList
		{nb, '( Tools And Operations List )'}
	endif
endp

@usr_sof_character
	; Handle start of file character
	{,cPb}
endp

@usr_sof_progname
	; Handle Program Number and/or Name
	if iSplit_ProgName_Num and bUseprognum and bUseprogname
		if iSplit_ProgName_Num == 1
			{nl, cCb, part_name,cCe}
			{nl, cPn, program_number}
		else
			{nl, cPn, program_number}
			{nl, cCb, part_name,cCe}
		endif
	else
		if bUseprognum
			{nl, cPn,program_number}
			if bUseprogname
				{' 'cCb, part_name,cCe}
			endif
		else
			if bUseprogname
				{nl, cCb, part_name,cCe}
			endif
		endif
	endif
	if bUseFileName
		{nl, cCb, g_file_name,cCe}
	endif

endp

@usr_sof_commentsbeforecodes
	; Handle HardCoded or PartControlled comments  (Before G/M codes)
	if bCompTypeOutput
		{nb,cCb'COMPENSATION-WEAR'cCe}
	endif
	if bPostRevOutput
		{nb,cCb,sPostRevOutput,cCe}
	endif
	call @usr_US_date
	call @usr_US_time
	if bDateTimeOutput
		{nb,cCb,sUS_date'-'sUS_time,cCe}
	endif
endp

@usr_sof_gmcodes
	; Handle HardCoded or PartControlled G/M codes
endp

@usr_sof_commentsaftercodes
	; Handle HardCoded or UserDefined comments (After G/M codes)
	if bTlseperation and bOutputToolList
		local integer i ii
		i = 0
		if iNumSeparationLines == 0
			ii = 1
		else
			ii = iNumSeparationLines
		endif
		while i < ii
			{nl}
			i = i + 1
		endw
	endif
endp

@usr_US_date
	; Converts Europe Date format to US format
	Local Integer iInt1
	iInt1 = instr(date,'-')
	sUS_date = substr(date,(iInt1+1),3) + '-' + substr(date,1,(iInt1-1)) + '-' + right(date,4)
endp

@usr_US_time
	; Converts Military time to 12hr format
	Local Integer iInt1 iHr_Mil_int iHour
	Local String iHr_Mil iTm_of_day
	iInt1 = instr(time,':')
	iHr_Mil = left(time,(iInt1-1))
	iHr_Mil_int = tonum(iHr_Mil)
	if iHr_Mil_int < 12
		if iHr_Mil_int < 1
			iHour = 12
		else
			iHour = iHr_Mil_int
		endif
		iTm_of_day = 'AM'
	else
		if iHr_Mil_int < 13
			iHour = 12
		else
			iHour = iHr_Mil_int - 12
		endif
		iTm_of_day = 'PM'
	endif
	sUS_time = tostr(iHour:'5.0(p)') + substr(time,iInt1,8) + iTm_of_day
endp

@usr_init_gmstates
	; Handle initializing G/M codes for correct modality from beginning of file
	iMplane         = 17
	iAbsincmode     = 9999
	iWorkoffset     = 9999
	iHeightcomp     = 9999
	iMotionmode     = 9999
	iDiametercomp   = 9999
	iDiameteroffset = 9999
	iDrillmode      = 9999
	iTcnumber       = 1
	iCoolantM1      = iCoolantM1OFF
	iCoolantM2      = iCoolantM2OFF
	iCoolantM3      = iCoolantM3OFF
	iCoolantM4      = iCoolantM4OFF
	iCoolantM5      = iCoolantM5OFF
	iCoolantM6      = iCoolantM6OFF
	iCoolantM7      = iCoolantM7OFF
	iCoolantM8      = iCoolantM8OFF
	iG187_P_gpp     = 2
	nG187_E_gpp     = 0
	; ---- 4x
	nR1pos          = 9999
	nR2pos          = 9999
	change(cR1)     = false
	change(cR2)     = false
	change(cWo)     = false
	iFeedType       = 94
	change(iFeedType)     = false
	; ---- 4x
endp

;-------------------

@def_tool
	; Handle Tool List Output at top of program
	; Use bTlchg to use different message for tool_change
	if bOutputToolList
		if tool_message == '' then
			{nb, cCb'TOOL 'tool_number, ' - DIA '(tool_offset*2),cCe }
		else
			{nb,cCb'T'tool_number,'-' tool_message,cCe}
			if msg_mill_tool1 ne ''
				{nb,cCb'---' msg_mill_tool1,cCe}
			endif
			if msg_mill_tool2 ne ''
				{nb,cCb'---' msg_mill_tool2,cCe}
			endif
			if msg_mill_tool3 ne ''
				{nb,cCb'---' msg_mill_tool3,cCe}
			endif
			if msg_mill_tool4 ne ''
				{nb,cCb'---' msg_mill_tool4,cCe}
			endif
			if msg_mill_tool5 ne ''
				{nb,cCb'---' msg_mill_tool5,cCe}
			endif
		endif
	endif
	if next_command ne '@def_tool' and bTlchg eq false
		if bTlseperation and bOutputToolList
			local integer i ii
			i = 0
			if iNumSeparationLines == 0
				ii = 1
			else
				ii = iNumSeparationLines
			endif
			while i < ii
				{nl}
				i = i + 1
			endw
		endif
		if bOptstpbegin
			call @usr_optionalstop
		endif
		if bNnumtc
			{nl,'N'iTcnumber' '}
		else
			{nb}
		endif

	endif
endp

;-------------------

@start_program
	; Handle any safety G/M codes for top of program
	if !bSimpleformat
		call @usr_abs_inc_output
		call @usr_mp_output
		side = COMP_OFF
		call @compensation
		call @usr_compensation_output
		skipline = false
		call @end_drill
		{'G00 G20 G50 G94 G64'}
	else
		{'G90 G70 G40'}
		{nl,'G96'}
		{nl,'G46  (Tool Length Comp. Off)'}
		{nl,'G990    (Reset Machine)'}
		{nl,'M999    (Load Machine Variables)'}
		{nl,' '}
	endif
	if sHomestrbegin ne ''
		sHomestr = sHomestrbegin
		call @usr_prep_home_axis
	endif

endp

;-------------------

@end_program
	; Handle output for end of program
	if bMultiplefixtures eq True
		bFromendprogram = True
		call @Multiple_Fixtures
	endif
	{nb,'G46 '}
	{nb,'G990 (Partial Reset) '}
	{nb,'G90     (ABS MODE) '}
	{nb,'G00 Z0 (Rapid to Z0 - ABS) '}
	if bCooloffend and bCoolExist
		iCoolantM1      = iCoolantM1OFF
		iCoolantM2      = iCoolantM2OFF
		iCoolantM3      = iCoolantM3OFF
		iCoolantM4      = iCoolantM4OFF
		iCoolantM5      = iCoolantM5OFF
		iCoolantM6      = iCoolantM6OFF
		iCoolantM7      = iCoolantM7OFF
		call @usr_coolant_output
	endif
	if bSpinoffend
		iSpindleDir = 5
		{nb}
		call @usr_spindle_mcode_output
	endif
	if sHomestrend ne ''
		sHomestr = sHomestrend
		call @usr_prep_home_axis
	endif
	if change(iAbsincmode)
		{nb}
		call @usr_abs_inc_output
	endif
	if change(iWorkoffset)
		{nb}
		call @usr_homenumber_output
	endif
	if bOptstpend
		call @usr_optionalstop
	endif
	if bToolChangeAtEnd
		{nb,cTCcodep'T'next_tool_number' 'cTCcodes}
	endif
	if iProgendmode eq 1
		{nb, 'M30 '}
	endif
	if iProgendmode eq 2
		{nb, 'M2 '}
	endif

endp

;-------------------

@end_of_file
	; Handle end of file character
	if cPe ne ''
		{nl,cPe}
	endif
	if bMultiplefixtures eq True
		bFromendoffile = True
		call @Multiple_Fixtures
	endif
endp

;-------------------

@relative_mode
	; Handle setting of IncrementalMode Gcode
	iAbsincmode = 91
	if bSimpleformat
		if change(iAbsincmode)
			{nb}
;			call @usr_abs_inc_output
		endif
		change(iAbsincmode) = false
	endif
endp

@absolute_mode
	; Handle setting of AbsoluteMode Gcode
	iAbsincmode = 90
	if bSimpleformat
		if change(iAbsincmode)
			{nb}
;			call @usr_abs_inc_output
		endif
		change(iAbsincmode) = false
	endif
endp

@usr_abs_inc_output
	; Handle output of Absolute/Incremental Mode Gcode
	{['G'iAbsincmode, ' ']}
endp

;-------------------

@machine_plane
	; Handle setting of MachinePlane Gcode
	; We not use this procedure to output code
	; We create our own procedure for this so that we may Sync with arc_zx_yz
	if machine_plane eq XY
		iMplane = 17
	endif
	if machine_plane eq ZX
		iMplane = 18
	endif
	if machine_plane eq YZ
		iMplane = 19
	endif
	if bSimpleformat
		if change(iMplane)
			{nb}
;			call @usr_mp_output
		endif
		change(iMplane) = false
	endif
endp

@usr_mp_output
	; Handle output of MachinePlane Gcode
	; Use bStartFile variable to ignore this output at beginning of file
	{['G'iMplane' ']}
endp

;-------------------

@home_number
	; Handle setting WorkOffset Gcode
	if home_number eq 20
		ihome_number = iLhome_number
	else
		iLhome_number = home_number
		if i4xIndexMode eq 1
			ihome_number = (mac_number + position) - 1
		else
			ihome_number = home_number
		endif
	endif
	if iWorkOffset_Method eq 0
		if iWorkOffsetmode eq 1
			if home_number <= 6
				iWorkoffset = 53 + ihome_number
			else
				iWorkoffset = 53 + ihome_number
			endif
		endif
		if iWorkOffsetmode eq 2 or iWorkOffsetmode eq 3
			iWorkoffset = ihome_number
		endif
	else
		iWorkoffset = tonum(home_user_name)
	endif
	if bSimpleformat
		if bWorkoffsettc and btlchg
			change(iWorkoffset) = true
		endif
		if change(iWorkoffset)
			{nb}
			call @usr_homenumber_output
		endif
	endif
	if i4xIndexMode eq 1
		change(iWorkoffset) = true
	endif
endp

@usr_homenumber_output
	; Handle output WorkOffset Gcode
	{[cWo,iWorkoffset' ']}
	{'(Fixture Offset, Table ' iWorkoffset ') '}
	change(cWo) = FALSE ;!@#$%AC Fix for ChangeBit Intermittent problem
endp

;-------------------

@change_tool
	; Delayed Tool Change handling to @start_of_job to have access to Operation(Job) data
	nTcXnext = xnext
	nTcYnext = ynext
	nTcZnext = znext
	nTcCnext = cnext
	bTlchg = true
endp

@usr_ct
	; Handle all aspects of Tool Change
	if bMultiplefixtures eq True
		bFrombeginchangetool = True
		call @Multiple_Fixtures
	endif
	if !first_tool
		iTcnumber = iTcnumber + 1
	endif
	bStartFile = false
	call @usr_tc_init_gmstates
	if !first_tool
		call @usr_ct_before_notfirsttool
	endif
	if first_tool
		call @usr_ct_before_firsttool
	endif
	call @usr_ct_toolchange
	call @usr_ct_after
;	if !bMultiplefixtures
;		bSkipxyrapid = true
;	endif
endp

@usr_ct_before_notfirsttool
	; Handle output before the next tool change
	; This is not called before the first tool change
	{nb,'G46 '}
	{nb,'G990 (Partial Reset) '}
	{nb,'G90     (ABS MODE) '}
	{nb,'G00 Z0 (Rapid to Z0 - ABS) '}
	if !bStopM00difftool
		if bCoolofftc and bCoolExist
			iCoolantM1      = iCoolantM1OFF
			iCoolantM2      = iCoolantM2OFF
			iCoolantM3      = iCoolantM3OFF
			iCoolantM4      = iCoolantM4OFF
			iCoolantM5      = iCoolantM5OFF
			iCoolantM6      = iCoolantM6OFF
			iCoolantM7      = iCoolantM7OFF
			call @usr_coolant_output
		endif
		if bSpinofftc
			iSpindleDir = 5
			{nb}
			call @usr_spindle_mcode_output
		endif
		if sHomestrtc ne ''
			sHomestr = sHomestrtc
			call @usr_prep_home_axis
		endif
		if bOptstptc
			call @usr_optionalstop
		endif
	endif
	if bTcseperation
		{nl}
	endif
	if !bSimpleformat
		bSafetyprep = true
		call @usr_tc_init_gmstates
	endif
	if bNnumtc
		{nl,'N'iTcnumber' '}
	else
;		{nb}
	endif
	{nl,' '}
	call @home_number
	{nl,' '}
endp

@usr_ct_before_firsttool
	; Handle output before the first tool change
	{nb}
	if bSpinofftc
		iSpindleDir = 5
		{nb}
		call @usr_spindle_mcode_output
	endif
endp

@usr_ct_toolchange
	; Handle G/M code output to make tool change
	if bCoolspinaftertc and bTlchg
		skipline = true
		call @start_tool
		if bCoolExist
			skipline = true
			call @usr_coolant
		endif
	endif
	if bTCSplit
		{nb,cTCcodep'T'tool_number}
		if bOutputToolMessage
			{' 'cCb,tool_message,cCe}
		endif
		{nb,cTCcodes}
	else
		{nb,cTCcodep'T'tool_number' 'cTCcodes}
		if bOutputToolMessage
			{cCb,tool_message,cCe}
		endif
	endif
	if bHeightComponToolCh
		skipline = false
		call @usr_heightcomp_on
		skipline = true
	endif
	if bToolPreselect
		if !last_tool
			{nb,'T'next_tool_number}
		else
			if !bToolChangeAtEnd
				{nb,'T'next_tool_number}
			endif
		endif
	endif
endp

@usr_ct_after
	; Handle output after tool change
	; *Note: Coolant & job Options need handling
	local integer i poz1 l1b pr1
	local string msg1 msg1a msg1b
	if first_tool
		{nb,'G802 (Acceleration Macro) '}
		{nb,'G09F12 (Tangency Factor) '}
	endif
	if iOperationMessage eq 2
		{nb, cCb,job_name,cCe}
	endif
	if msg ne '' and bOutputUserMessages
		i = 1
		while i < 50
			i = i + 1
			poz1=instr(msg,'\n')
			if poz1 eq 0
				poz1=strlen(msg)
				msg1=msg
			else
				poz1 = poz1-2
				msg1=left(msg,poz1)
			endif
			{nb, cCb,msg1,cCe}
			poz1=instr(msg,'\n')
			if poz1 eq 0
				i = 51
			else
				l1b=strlen(msg)-strlen(msg1)
				pr1=poz1+1
				msg1b=substr(msg,pr1,l1b)
				msg=msg1b
			endif
		endw
	endif
endp

@usr_tc_init_gmstates
	; Handle initializing G/M codes for correct modality after tool change
	if first_tool
		iMotionmode = 9999
		iDiametercomp = 40
		if !bSimpleformat
			change(iAbsincmode) = true
			change(iWorkoffset) = true
		endif
		change(iDiameteroffset) = false
		iHeightcomp = 9999
		iDrillmode = 9999
		iCoolantM1      = iCoolantM1OFF
		iCoolantM2      = iCoolantM2OFF
		iCoolantM3      = iCoolantM3OFF
		iCoolantM4      = iCoolantM4OFF
		iCoolantM5      = iCoolantM5OFF
		iCoolantM6      = iCoolantM6OFF
		iCoolantM7      = iCoolantM7OFF
		iCoolantM8 = iCoolantM8OFF
	else
		if bSafetyprep
			call @job_plane
			change(iMplane) = true
			change(iAbsincmode) = true
			change(iDiametercomp) = true
			iDrillmode = 9999
			bSafetyprep = false
		else
			iMotionmode = 9999
			if bWorkoffsettc
				change(iWorkoffset) = true
			endif
			if !bSimpleformat
				change(iAbsincmode) = true
			endif
			iDiametercomp = 40
			change(iDiameteroffset) = false
			iHeightcomp = 9999
			iDrillmode = 9999
			iCoolantM1      = iCoolantM1OFF
			iCoolantM2      = iCoolantM2OFF
			iCoolantM3      = iCoolantM3OFF
			iCoolantM4      = iCoolantM4OFF
			iCoolantM5      = iCoolantM5OFF
			iCoolantM6      = iCoolantM6OFF
			iCoolantM7      = iCoolantM7OFF
			iCoolantM8 = iCoolantM8OFF
			change(nRapidfeed) = true
			; ---- 4x
			nR1pos = 9999
			nR2pos = 9999
			; ---- 4x
		endif
	endif
endp

@usr_heightcomp_on
	; Handle line to turn on Height Compensation (Typically after tool change)
	iHeightcomp = nHeightCompcode
	if bHeightComp or bHeightCompOffset
		{nb}
	endif
	if bHeightComp
		{'M31 '}
		{nb,'G'iHeightcomp' '}
	endif
	if bHeightCompOffset
		{cHoffset,tool_number' '}
	endif
	if (bHeightComp or bHeightCompOffset) and bHeightCompZsameLine
		skipline = false
	else
		skipline = true
	endif
endp

@usr_heightcomp_off
	; Handle line to turn off Height Compensation (Typically don't use)
	iHeightcomp = 49
	if change(iHeightcomp)
		{nb, 'G'iHeightcomp' '}
	endif
endp

@usr_coolant
	; Handle setting of coolant variable
	; When GlobalCode = 0, we use UserOption for thier default CoolantCode
	;  *Note: PartOptions default to 0 in SolidCAM
	;  *Note: Some customers default with M8(coolant), but some use M7(air) or M9(nothing)
	; We use GlobalCode for coolant unless
	;  the user inputs a number for LocalCode (Misc Params--Operation)
	if flood_coolant eq 1
		iCoolantM1 = iCoolantM1ON
	endif
	if flood_coolant eq 0 or flood_coolant eq 2
		iCoolantM1 = iCoolantM1OFF
	endif
	if Mist_coolant eq 1
		iCoolantM2 = iCoolantM2ON
	endif
	if Mist_coolant eq 0 or Mist_coolant eq 2
		iCoolantM2 = iCoolantM2OFF
	endif
	if HP_Flood_coolant eq 1
		iCoolantM3 = iCoolantM3ON
	endif
	if HP_Flood_coolant eq 0 or HP_Flood_coolant eq 2
		iCoolantM3 = iCoolantM3OFF
	endif
	if LP_Flood_coolant eq 1
		iCoolantM4 = iCoolantM4ON
	endif
	if LP_Flood_coolant eq 0 or LP_Flood_coolant eq 2
		iCoolantM4 = iCoolantM4OFF
	endif
	if HP_Through_coolant eq 1
		iCoolantM5 = iCoolantM5ON
	endif
	if HP_Through_coolant eq 0 or HP_Through_coolant eq 2
		iCoolantM5 = iCoolantM5OFF
	endif
	if LP_Through_coolant eq 1
		iCoolantM6 = iCoolantM6ON
	endif
	if LP_Through_coolant eq 0 or LP_Through_coolant eq 2
		iCoolantM6 = iCoolantM6OFF
	endif
	if Air_Blast_coolant eq 1
		iCoolantM7 = iCoolantM7ON
	endif
	if Air_Blast_coolant eq 0 or Air_Blast_coolant eq 2
		iCoolantM7 = iCoolantM7OFF
	endif
	call @usr_coolant_output
endp

@usr_coolant_output
	; Handle output of coolant variable
	if change(iCoolantM1)
		{nb,['M'iCoolantM1:mcode_f' ']}
	endif
	if change(iCoolantM2)
		{nb,['M'iCoolantM2:mcode_f' ']}
	endif
	if change(iCoolantM3)
		{nb,['M'iCoolantM3:mcode_f' ']}
	endif
	if change(iCoolantM4)
		{nb,['M'iCoolantM4:mcode_f' ']}
	endif
	if change(iCoolantM5)
		{nb,['M'iCoolantM5:mcode_f' ']}
	endif
	if change(iCoolantM6)
		{nb,['M'iCoolantM6:mcode_f' ']}
	endif
	if change(iCoolantM7)
		{nb,['M'iCoolantM7:mcode_f' ']}
	endif
	if  !change(iCoolantM1) or  !change(iCoolantM2) or !change(iCoolantM3) or  !change(iCoolantM4) or !change(iCoolantM5) or  !change(iCoolantM6) or !change(iCoolantM7)
		skipline = TRUE
	endif
endp

@usr_HSM_mode
	; Handle output of HSM code
	if iG187_P eq 0
		iG187_P = 2 ;Default = 2
	endif
	iG187_P_gpp = iG187_P
	nG187_E_gpp = nG187_E
	if change(iG187_P_gpp) or change (nG187_E_gpp)
		if change(nG187_E_gpp) and nG187_E_gpp eq 0
			{nb,'G187 '}
			change(nG187_E_gpp) = false
			change(iG187_P_gpp) = false
			if (iG187_P_gpp) ne 2
				change(iG187_P_gpp) = true
			endif
		endif
		if change(iG187_P_gpp) or change (nG187_E_gpp)
			{nb,'G187 '['P'iG187_P_gpp' ']['E'nG187_E_gpp' ']}
		endif
		change(iG187_P_gpp) = false
		change(nG187_E_gpp) = false
	endif
endp

;--------------------

@start_of_job
	; Handle what happens at start of operation(job)
	; If using Subs we do not make tool change in @start_of_job
	if bSubs
		{nb, cCb,job_name,cCe}
	else
		if bTlchg
			call @usr_ct
		else
			call @home_number
			if ippart_home_number ne part_home_number
				call @usr_4x_index
				if iPworkoffset ne iWorkoffset
					change(iWorkoffset) = true
				else
					change(iWorkoffset) = false
				endif
			endif
			{nb, cCb,job_name,cCe}
		endif
	endif
	if job_type eq 'drill_hr'
		bSkipxyrapid = false
	endif
	if bCoolExist and !bTlchg
		call @usr_coolant
	endif
	call @usr_HSM_mode
	bfirst_rapid = true
	ippart_home_number = part_home_number
	iPworkoffset = iWorkoffset
endp

;--------------------

@end_of_job
	; Handle what happens at end of operation(job)
	; If using Subs we do not make tool change in @start_of_job
	if bStopM00
		if tool_number eq next_job_tool_number
			call @usr_StopM00_sametool
		else
			call @usr_StopM00_difftool
		endif
	endif
	bSkipxyrapid = false
	bStopM00difftool = false
	; ---- 4x
	;if tool_z_level < tool_start_plane
	;    Print 'WARNING!! Tool Z Level is below Tool Start Plane in CoordSys'
	;    {nl,'WARNING!! Tool Z Level is below Tool Start Plane in CoordSys'}
	;endif
	nPtool_z_level = tool_z_level
	nPtool_start_plane = tool_start_plane
	bpos = 0
	apos = 0
	cpos = 0
	nPR1pos = 9999
	; ---- 4x
endp

;-------------------

@rapid_move
	; Handle GPP direct call to Rapid Move (G00)
	; We not use this procedure to output code
	; We create our own procedure for this so that we may...
	;   Sync with @rapid_move, @move_5x, @move_4x, @move4x_polar, @move4x_cartesian
	call @usr_rapid
endp

@usr_rapid
	; Handle output for Rapid Move (G00)
	; Note: XYZ not allowed together on a single line
	call @usr_r1pos_calc
	if !bSkipxyrapid
;		if bfirst_rapid
;			skipline = false
;		endif
		if !bSyncdrapid
			if job_type eq '3-d model'
				iMotionmode = 1
			else
				iMotionmode = 0
			endif
		else
			iMotionmode = 0
		endif
		if bfirst_rapid
			bTest = true
			{nb,['G'iMotionmode:mcode_f ' '],['G'iMplane' '],[cWo,iWorkoffset' '],['G'iAbsincmode ' '],['X'xpos ' '],['Y'ypos ' '],[cR2,nR2pos ' '],[cR1,nR1pos ' ']}
		else
			{nb,['G'iMotionmode:mcode_f ' '],['G'iMplane' '],[cWo,iWorkoffset' '],['G'iAbsincmode ' '],['X'xpos ' '],['Y'ypos ' '],['Z'zpos ' '],[cR2,nR2pos ' '],[cR1,nR1pos ' ']}
		endif
		if change(zpos)
			;if change(xpos) eq true or change(ypos) eq true
			if bTlchg
				if !bCoolspinaftertc
					skipline = false
					call @start_tool
					if !bHeightComponToolCh
						call @usr_heightcomp_on
					endif
					if bCoolExist
						if !bCoolAfterHeightComp
							skipline = false
						endif
						call @usr_coolant
						skipline = true          ;!@#$%AC Incase no coolant output, need to override 'skipline = false' 3 lines above
					endif
				else
					if !bHeightComponToolCh
						call @usr_heightcomp_on
;						skipline = false
					endif
				endif
			endif
			if bTest  ;!@#$% clear change
				{nb,['Z'zpos ' ']}
				bTest = false
			else
				{['Z'zpos ' ']}
			endif
		endif
		if !bSyncdrapid
			if job_type eq '3-d model'
				{['F'nRapidfeed' ']}
			endif
		endif
		bSkipxyrapid = false
	else
		{nb,['Z'zpos ' ']}
		if !bSyncdrapid
			if job_type eq '3-d model'
				{['F'nRapidfeed' ']}
			endif
		endif
		bSkipxyrapid = false
	endif
	if change(iMotionmode)
		change(iMotionmode) = false
	endif
	if change(iMplane)
		change(iMplane) = false
	endif
	if change(iWorkoffset)
		change(iWorkoffset) = false
	endif
	if change(iAbsincmode)
		change(iAbsincmode) = false
	endif
	if change(nRapidfeed)
		change(nRapidfeed) = false
	endif
	if !bSyncdrapid
		bFeedoutput        = true
	endif
	change(cWo) = FALSE ;!@#$%AC Fix for ChangeBit Intermittent problem
	if bMultiplefixtures and bTlchg
		mltfixxpos = xpos
		mltfixypos = ypos
		mltfixzpos = zpos
		bFromendchangetool = True
		call @Multiple_Fixtures
	endif
	bTlchg = false
	bfirst_rapid = false
endp

;-------------------

@line
	; Handle GPP direct call to Line Movement (G01)
	; We not use this procedure to output code
	; We create our own procedure for this so that we may...
	;   Sync with @line, @line_5x, @line_4x, @line4x_polar, @line4x_cartesian
	call @usr_line
endp

@usr_line
	; Handle output for line movement (G01)
	; ---- 4x
	;   - Set Rotary Position
	call @usr_r1pos_calc
	if  i4xFeedMode eq 0
		feed = feed
		if feed ne prevFeed
			change(feed) = true
		else
			change(feed) = false
		endif
	else
		if i4xFeedMode eq 1
			if rot_axis_type ne axis4_none or X5_job
				iFeedType = 93  ;Inverse Feed
				feed = inverse_feed
				change(feed) = true
			else
				iFeedType = 94
				if change(iFeedType)
					change(feed) = true
				endif
			endif
		endif
	endif
	; ---- 4x
	if bFeedoutput
		change(feed) = true
		bFeedoutput  = false
	endif
	iMotionmode = 1
	{nb,['G'iMotionmode:mcode_f ' '],['G'iMplane' '],['G'iDiametercomp' '],[cWo,iWorkoffset' '],['G'iAbsincmode ' ']}
	{['G'iFeedType' '],['D'iDiameteroffset' '],['X'xpos ' '],['Y'ypos ' '],['Z'zpos ' '],[cR2,nR2pos ' '],[cR1,nR1pos ' '],['F'feed ' ']}
	prevFeed = feed
	if change(iMotionmode)
		change(iMotionmode)     = false
	endif
	if change(iMplane)
		change(iMplane)         = false
	endif
	if change(iDiametercomp)
		change(iDiametercomp)   = false
	endif
	if change(iWorkoffset)
		change(iWorkoffset)     = false
	endif
	if change(iAbsincmode)
		change(iAbsincmode)     = false
	endif
	if change(iDiameteroffset)
		change(iDiameteroffset) = false
	endif
	change(nRapidfeed)          = true
endp

; -----------
@arc
	; SolidCAM call to normal arc movement
	; We do not use this procedure to output code
	; We create our own procedure for this so that we have one arc formatting section
	call @usr_arc
endp

@arc_yz
	; SolidCAM call to YZ arc movement
	; We not use this procedure to output code
	; We create our own procedure for this so that we have one arc formatting section
	call @usr_arc
endp

@arc_zx
	; SolidCAM call to ZX arc movement
	; We not use this procedure to output code
	; We create our own procedure for this so that we have one arc formatting section
	call @usr_arc
endp

@usr_arc
	; Handle output for arc movement (G02/G03)
	call @usr_r1pos_calc
	if bFeedoutput
		change(feed) = true
		bFeedoutput  = false
	endif
	if arc_direction eq CCW then
		iMotionmode = 3
	else
		iMotionmode = 2
	endif
	if arc_plane eq XY
		iMplane = 17
	endif
	if arc_plane eq ZX
		iMplane = 18
	endif
	if arc_plane eq YZ
		iMplane = 19
	endif
	{nb,['G'iMotionmode:mcode_f ' '],['G'iMplane' '],['G'iDiametercomp' '],[cWo,iWorkoffset' '],['G'iAbsincmode ' ']}
	{['D'iDiameteroffset' '] 'X'xpos ' ' 'Y'ypos ' ' ['Z'zpos ' ']}
	if arc_plane eq XY then
		if iArcmode eq 1 or (arc_size eq 360 and iArcmode eq 3)
			{'I'xmcenter ' ', 'J'ymcenter ' '}
		endif
		if iArcmode eq 2 or (arc_size eq 360 and iArcmode eq 4)
			{'I'xmcenter_rel ' ', 'J'ymcenter_rel ' '}
		endif
		if (iArcmode eq 3 or iArcmode eq 4) and arc_size ne 360
			if arc_size >= 180 then
				radius = -radius
			endif
			{'R'radius' '}
		endif
	endif
	if arc_plane eq ZX then
		if iArcmode eq 1 or (arc_size eq 360 and iArcmode eq 3)
			{'I'xmcenter ' ', 'K'zmcenter ' '}
		endif
		if iArcmode eq 2 or (arc_size eq 360 and iArcmode eq 4)
			{'I'xmcenter_rel ' ', 'K'zmcenter_rel ' '}
		endif
		if (iArcmode eq 3 or iArcmode eq 4) and arc_size ne 360
			if arc_size >= 180 then
				radius = -radius
			endif
			{'R'radius' '}
		endif
	endif
	if arc_plane eq YZ then
		if iArcmode eq 1 or (arc_size eq 360 and iArcmode eq 3)
			{'J'ymcenter ' ', 'K'zmcenter ' '}
		endif
		if iArcmode eq 2 or (arc_size eq 360 and iArcmode eq 4)
			{'J'ymcenter_rel ' ', 'K'zmcenter_rel ' '}
		endif
		if (iArcmode eq 3 or iArcmode eq 4) and arc_size ne 360
			if arc_size >= 180 then
				radius = -radius
			endif
			{'R'radius' '}
		endif
	endif
	{['F'feed ' ']}
	if change(iMotionmode)
		change(iMotionmode)     = false
	endif
	if change(iMplane)
		change(iMplane)         = false
	endif
	if change(iDiametercomp)
		change(iDiametercomp)   = false
	endif
	if change(iWorkoffset)
		change(iWorkoffset)     = false
	endif
	if change(iAbsincmode)
		change(iAbsincmode)     = false
	endif
	if change(iDiameteroffset)
		change(iDiameteroffset) = false
	endif
	change(nRapidfeed)          = true
	change(cWo) = FALSE ;!@#$%AC Fix for ChangeBit Intermittent problem
	prevFeed = feed
endp

;-------------------

@compensation
	; Handle setting of Diameter Compensation Gcode
	; We not use this procedure to output code
	; We create our own procedure for this so that we..
	;   have can control placement during @line,@arc
	if side eq COMP_LEFT then
		iDiametercomp = 41
		if bDiameterCompOutputD
			change(iDiameteroffset) = true
		endif
	endif
	if side eq COMP_RIGHT then
		iDiametercomp = 42
		if bDiameterCompOutputD
			change(iDiameteroffset) = true
		endif
	endif
	if side eq COMP_OFF then
		iDiametercomp = 40
		change(iDiameteroffset) = false
	endif
endp

@usr_compensation_output
	; Handle output of Diameter Compensation Gcode
	if change(iDiametercomp)
		if iDiametercomp eq 40 or !bDiameterCompOutputD
			{'G'iDiametercomp' '}
		else
			{'G'iDiametercomp, ' D'tool_number' '}
		endif
	endif
endp

;-------------------

@usr_optionalstop
	; Handle line for Optional Stop G/M code
	iStopmode = 1
	{nb, 'M'iStopmode:mcode_f' '}
endp

@usr_forcedstop
	; Handle line for forced Stop gmcode
	iStopmode = 0
	{nb, 'M'iStopmode:mcode_f' '}
endp

@usr_StopM00_sametool
	; Handle output for forced stopM00 between operations using the same tool
	if bCoolExist
		iCoolantM1      = iCoolantM1OFF
		iCoolantM2      = iCoolantM2OFF
		iCoolantM3      = iCoolantM3OFF
		iCoolantM4      = iCoolantM4OFF
		iCoolantM5      = iCoolantM5OFF
		iCoolantM6      = iCoolantM6OFF
		iCoolantM7      = iCoolantM7OFF
		call @usr_coolant_output
	endif
	iSpindleDir = 5
	{nb}
	call @usr_spindle_mcode_output
	if sHomestrstpsame ne ''
		sHomestr = sHomestrstpsame
		call @usr_prep_home_axis
	endif
	call @usr_forcedstop
	sUsrmsg = sStopMessage
	call @usr_message
	{nb}
	call @usr_abs_inc_output
	call @m_feed_spin
	call @usr_spindle_mcode_output
	change(xpos) = true
	change(ypos) = true
	change(zpos) = false
	call @rapid_move
	call @usr_heightcomp_on
endp

@usr_StopM00_difftool
	; Handle output for forced stopM00 between operations using different tools
	if bCoolExist
		iCoolantM1      = iCoolantM1OFF
		iCoolantM2      = iCoolantM2OFF
		iCoolantM3      = iCoolantM3OFF
		iCoolantM4      = iCoolantM4OFF
		iCoolantM5      = iCoolantM5OFF
		iCoolantM6      = iCoolantM6OFF
		iCoolantM7      = iCoolantM7OFF
		call @usr_coolant_output
	endif
	iSpindleDir = 5
	{nb}
	call @usr_spindle_mcode_output
	if sHomestrstpdiff ne ''
		sHomestr = sHomestrstpdiff
		call @usr_prep_home_axis
	endif
	call @usr_forcedstop
	sUsrmsg = sStopMessage
	call @usr_message
	bStopM00difftool = true
endp

;-------------------

@change_ref_point
	; @change_ref_point Not Supported in this template

endp

;-------------------

@rotate
	; @rotate Not Supported in this template
endp

;-------------------

@mirror
	; @mirror Not Supported in this template
endp

;-------------------

@fourth_axis
	; @fourth_axis Not Supported in this template
endp
;-------------------

@message
	; We don't always use messages directly from SolidCAM
	if iOperationMessage eq 1
		{nb, cCb,message,cCe}
	endif
endp

@usr_message
	; Handle output for messages
	; We don't use messages directly from SolidCAM
	{nb, cCb,sUsrmsg,cCe}
endp

;-------------------

@drill
	; Handle output for drill cycles
	if rot_axis_coord eq 1 or rot_axis_coord eq 2
		xpos = 0
		xnext = 0
		nTcxnext = 0
		Xpos = Xnext
		Ypos = Ynext
		Zpos = Znext
	endif
	if 	bfirst_rapid
		call @Rapid_move
	else
		call @usr_r1pos_calc
		{nb,cDrZp'Z'zpos' 'cDrZs}
	endif
	if drill_type eq G81
		iDrillmode = 81
		{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' F'feed ' 'cDrCys}
	endif
	if drill_type eq G82
		iDrillmode = 82
		{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' P'P_Dwell' F'feed' 'cDrCys}
	endif
	if drill_type eq G83
		iDrillmode = 83
		if P_Dwell eq 0
			change(P_Dwell) = false
		endif
		if Q_Peck eq 0
			Q_Peck = down_step
		endif
		if I_FirstPeck eq 0
			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' Q'Q_Peck,[' P'P_Dwell],' F'feed' 'cDrCys}
		else
			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' I'I_FirstPeck' J'J_ReduceAmount' K'K_MinimumDepth,[' P'P_Dwell],' F'feed' 'cDrCys}
		endif
	endif
;	if drill_type eq G73
;		iDrillmode = 73
;		if P_Dwell eq 0
;			change(P_Dwell) = false
;		endif
;		if Q_Peck eq 0
;			Q_Peck = down_step
;		endif
;		if I_FirstPeck eq 0
;			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' Q'Q_Peck' K'K_MinimumDepth,[' P'P_Dwell],' F'feed' 'cDrCys}
;		else
;			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' I'I_FirstPeck' J'J_ReduceAmount' K'K_MinimumDepth,[' P'P_Dwell],' F'feed' 'cDrCys}
;		endif
;	endif
	if drill_type eq G84
		iDrillmode = 84
		if cG84p ne ''
			{nb,cG84p}
		endif
		if bG84spin
			change(spin) = true
		else
			change(spin) = false
		endif
		if iG84feed eq 1
			nG84feed = tool_drill_lead*spin
		endif
		if iG84feed eq 2
			nG84feed = tool_drill_lead
		endif
		{nb, cDr,cG84 ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z,[' S'spin:fG84spin],' F'nG84feed ' 'cDrCys}
	endif
;	if drill_type eq G84_Peck
;		iDrillmode = 84
;		if cG84p ne ''
;			{nb,cG84p}
;		endif
;		if bG84spin
;			change(spin) = true
;		else
;			change(spin) = false
;		endif
;		if iG84feed eq 1
;			nG84feed = tool_drill_lead*spin
;		endif
;		if iG84feed eq 2
;			nG84feed = tool_drill_lead
;		endif
;		{nb, cDr,cG84 ' Z'drill_lower_z' R'drill_upper_z' 'cCycs,['S'spin:fG84spin' '],'F'nG84feed ' 'cDrCys}
;	endif
	if drill_type eq G85
		if P_Dwell eq 0
			iDrillmode = 85
			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' F'feed ' 'cDrCys}
		else
			iDrillmode = 89
			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' P'P_Dwell' F'feed' 'cDrCys}
		endif
	endif
	if drill_type eq G86
		iDrillmode = 86
		{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' F'feed ' 'cDrCys}
	endif
	if drill_type eq G87
		if P_Dwell eq 0
			iDrillmode = 87
			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' F'feed ' 'cDrCys}
		else
			iDrillmode = 88
			{nb, cDr'G'iDrillmode ' X'xpos' Y'ypos' Z'drill_lower_z' R'drill_upper_z' P'P_Dwell' F'feed' 'cDrCys}
		endif
	endif
	if job_type eq '3-d drill'
		call @end_drill
	endif
endp

;-------------------

@drill_point
	; Handle output for drill positions
;	local integer i
;	if drill_type eq G84_Peck
;		iNumpecks = (drill_depth/Q_Peck)+1.
;		nCorrectedpeck = drill_depth/iNumpecks
;		i = 1
;		while i <= iNumpecks
;			{nb,'X'xpos ' ', 'Y'ypos ' ', 'Z'(drill_upper_z-(nCorrectedpeck*i))' 'cDrPts}
;			i = i + 1
;		endw
;	else
	call @usr_r1pos_calc
	if !first_drill then
		{nb,'X'xpos ' ', 'Y'ypos ' ', ['Z'zpos ' ']cDrPts}
	endif
;	endif
endp

@drill4x_pnt
	; Handle output for drill positions
	local integer i
	call @usr_r1pos_calc
	if change(xpos)
		xpos = 0
	endif
;	if drill_type eq G84_Peck
;		iNumpecks = (drill_depth/Q_Peck)+1.
;		nCorrectedpeck = drill_depth/iNumpecks
;		i = 1
;		while i <= iNumpecks
;			{nb,'X'xpos ' ', 'Y'ypos ' ', 'Z'(drill_upper_z-(nCorrectedpeck*i))' 'cDrPts}
;			i = i + 1
;		endw
;	else
	if !first_drill then
		{nb,['X'xpos ' '], ['Y'ypos ' '], ['Z'zpos ' '],[cR2,nR2pos ' '],[cR1,nR1pos ' ']cDrPts}
	endif
;	endif
endp

;-------------------

@end_drill
	; Handle output to cancel drill cycles
	iDrillmode = 80
	if change(iDrillmode)
		{nb, 'G'iDrillmode' '}
	endif
;	if (cG84endl ne '') and (drill_type eq G84_Peck or drill_type eq G84)
;		{nb,cG84endl}
;	endif
endp

;-------------------

@m_feed_spin
	; Handle output for spindle change
	if tool_direction eq CW then
		iSpindleDir = 3
	else
		iSpindleDir = 4
	endif
	if change(spin) and !bTlchg
		call @usr_spindle_output
	endif
endp

@start_tool
	; Handle setting and output for spindle start
	if tool_direction eq CW then
		iSpindleDir = 3
	else
		iSpindleDir = 4
	endif
	call @usr_spindle_output
	if !bSpinOnlyUseS
		if bSimpleformat
			{nb}
		endif
		call @usr_spindle_mcode_output
	endif
endp

@usr_spindle_output
	; Handle output for spindle
	{nb,'S'spin:integer_def_f ' '}
endp

@usr_spindle_mcode_output
	; Handle output for spindle
	{'M'iSpindleDir:mcode_f ' '}
endp

;-------------------

@offset_change
	; Handle setting of Diameter offset
	iDiameteroffset = d_offset
endp

;-------------------

@job_plane
	; @job_plane Not Supported in this template
	if machine_plane eq XY
		iMplane = 17
	endif
	if machine_plane eq ZX
		iMplane = 18
	endif
	if machine_plane eq YZ
		iMplane = 19
	endif
	if bSimpleformat
		if change(iMplane)
			{nb}
			call @usr_mp_output
		endif
		change(iMplane) = false
	endif
endp

;-------------------

@call_proc
	; Handle call to subroutine
	if bTlchg
		call @usr_ct
		bTlchg = false
	endif
	{nb, 'M98 P'label}
	{[' ('message, ')']}
endp

;-------------------

@proc
	; Handle beggining of subroutine
	{nl, 'O'label}
endp

;-------------------

@end_proc
	; Handle end of subroutine
	{nb, 'M99'}
endp

;----------------

@loop_matrix_info
	bSkipxyrapid = false
endp

@loop
	; Loops Not Supported in this template

endp

;----------------

@end_loop
	; Loops Not Supported in this template

endp

;-------------------

@usr_prep_home_axis
	; Handle parsing of homing string and preping of output for homing
	local integer i line l mode p1 xMode
	local string s s1 s2 l1 pstr
	s = sHomestr                               ;Original String
	s1 = s                                     ;Temp String
	l = strlen(s1)                             ;Get string length of Temp String
	s2 = substr(s1,1,1)                   ;*Check for 'x' in first character to flag separate iHomingmode for each line
	if s2 eq 'x'
		xMode = 1
		s1 = substr(s1,2,l)                        ;Remove 'x' from Temp String
		l = strlen(s1)                             ;Get string length of Temp String
	else
		xMode = 0
	endif
	if !xMode                                    ;*Pull out Homing mode (when not using xMode)
		p1 = instr(s1,':')                         ;Find the position of first ":"
		l1 = left(s1,p1-1)                         ;Pull out the left of first ":"
		mode = tonum(l1)                           ;Convert string into Integer for "Mode" variable
		s1 = substr(s1,p1+1,l)                     ;Remove Homing mode from Temp String
		l = strlen(s1)                             ;Get string length of Temp String
		;*Pull out Preperation String
		p1 = instr(s1,':')                         ;Find the position of second ":"
		if p1 ne 0                                 ;Check if PrepStr is defined
			pstr = left(s1,p1-1)                   ;Pull out the left of second ":"
			s1 = substr(s1,p1+1,l)                 ;Remove PrepString from Temp String
			l = strlen(s1)                         ;Get string length of Temp String
		endif
	endif                                         ;*Pull out homing lines and send to output procedure
	i = 1
	while i < 50
		i = i + 1
		if xMode                                     ;*Pull out Homing mode (when using xMode)
			p1 = instr(s1,':')                         ;Find the position of first ":"
			l1 = left(s1,p1-1)                         ;Pull out the left of first ":"
			mode = tonum(l1)                           ;Convert string into Integer for "Mode" variable
			s1 = substr(s1,p1+1,l)                     ;Remove Homing mode from Temp String
			l = strlen(s1)                             ;Get string length of Temp String
			;*Pull out Preperation String
			p1 = instr(s1,':')                         ;Find the position of second ":"
			if p1 ne 0                                 ;Check if PrepStr is defined
				pstr = left(s1,p1-1)                   ;Pull out the left of second ":"
				s1 = substr(s1,p1+1,l)                 ;Remove PrepString from Temp String
				l = strlen(s1)                         ;Get string length of Temp String
			endif
		endif
		p1 = instr(s1,';')                      ;Find the position of ";"
		if p1 ne 0
			line = line + 1                     ;Keep track of lines. Not Used!!
			l1 = left(s1,p1-1)                  ;Pull out the left of ";"
			iHomingmode = mode                  ;Send Homing Mode
			cHomep = pstr                       ;Send Preperation String
			sHomeline = l1                      ;Send Homing Line
			call @usr_home_axis
		else
			line = line + 1                     ;Keep track of lines. Not Used!!
			iHomingmode = mode                  ;Send Homing Mode
			cHomep = pstr                       ;Send Preperation String
			sHomeline = s1                      ;Send Homing Line
			call @usr_home_axis
			i = 50                              ;Force end of While-Loop
		endif
		if i ne 50
			s1 = substr(s1,p1+1,l)              ;Remove Homing mode from Temp String
			l = strlen(s1)                      ;Get string length of Temp String
		endif
	endw
endp

@usr_home_axis
	; Handle output for homing the X-axis
	local integer sav_iWorkOffset
	sav_iWorkOffset = iWorkOffset
	if iHomingmode eq 1
		{nb,cHomep'G28 'sHomeline}
	endif
	if iHomingmode eq 2
		{nb,cHomep'G28 '}
		iAbsincmode = 91
		change(iAbsincmode) = true
		call @usr_abs_inc_output
		{ sHomeline}
		iAbsincmode = 90
		change(iAbsincmode) = true
	endif
	if iHomingmode eq 3 or iHomingmode eq 4
		if iWorkOffsetmode eq 1 or iWorkOffsetmode eq 3
			iWorkOffset = 53
			{nb,cHomep,[cWo,iWorkoffset' ']}
		endif
		if iWorkOffsetmode eq 2
			iWorkOffset = 0
			{nb,cHomep,[cWo,iWorkoffset' ']}
		endif
		call @usr_abs_inc_output
		{ sHomeline}
		iWorkOffset = sav_iWorkOffset
		if iHomingmode eq 3
			change(iWorkOffset) = false
		endif
		change(cWo) = FALSE ;!@#$%AC Fix for ChangeBit Intermittent problem
	endif
	if iHomingmode eq 5
		{nb,cHomep'G30 'sHomeline}
	endif
	if iHomingmode eq 6
		{nb,cHomep'G30 '}
		iAbsincmode = 91
		change(iAbsincmode) = true
		call @usr_abs_inc_output
		{ sHomeline}
		iAbsincmode = 90
		change(iAbsincmode) = true
	endif
	if iHomingmode eq 7
		{nb, sHomeline}
	endif
endp

;-------------------

@usr_campart_path
	; Uses String Functions to get the Windows Folder Path to the CAM-Part
	iSlength_g_file_name = strlen( g_file_name)
	iSlength_full_g_file_name = strlen(full_g_file_name)
	iSlengthcampartpath = iSlength_full_g_file_name - iSlength_g_file_name
	sCamfilepath = left(full_g_file_name,iSlengthcampartpath)
endp

;-------------------

@Multiple_Fixtures
	; Handle multiple fixture support
	local integer i
;----From tools 2 and up
;----Closes the sSubspath(tempfile) for the previous tool change
;----Runs loop to print G5x and copy in the tempfile
;----Sets the tempfile to new name for next tool
	if bFrombeginchangetool eq True
		if !first_tool
			{nl,'!!close file=' sSubspath '!!'}
			i = 1
			while i <= iNumber_of_Fixtures
				{nl,cCb'-----LOOPING CODE-----'cCe}
				if i ne 1
					{nb,'G'iMotionmode:mcode_f ' ',['G'iMplane' '],cWo,((iWorkoffset-1)+i)' ','G'iAbsincmode ' ','X'mltfixxpos ' ','Y'mltfixypos ' '}
				endif
				{nl,'!!copy file=' sSubspath '!!'}
				i = i + 1
			endw
			sSubspath = sCamfilepath + 'TEMPFILE' + tostr(iTcnumber:'5.0(n)')
		endif
		bFrombeginchangetool = False
	endif

;----At end of tool_change
;----Opens tempfile to print out gcode
	if bFromendchangetool eq True
		sSubspath = sCamfilepath + 'TEMPFILE' + tostr(iTcnumber:'5.0(n)')
		{nl,'!!open file=' sSubspath '!!'}
		bFromendchangetool = False
	endif

;----At end_program
;----Closes the sSubspath(tempfile) for the current tool change
;----Runs loop to print G5x and copy in the tempfile
	if bFromendprogram eq True
		{nl,'!!close file=' sSubspath '!!'}
		i = 1
		while i <= iNumber_of_Fixtures
			{nl,cCb'-----LOOPING LAST TOOL CHANGE CODE-----'cCe}
			if i ne 1
				{nb,'G'iMotionmode:mcode_f ' ',['G'iMplane' '],cWo,((iWorkoffset-1)+i)' ','G'iAbsincmode ' ','X'mltfixxpos ' ','Y'mltfixypos ' '}
			endif
			{nl,'!!copy file=' sSubspath '!!'}
			i = i + 1
		endw
		bFromendprogram = False
	endif

;----At eng_of_file
;----Delete all tempfiles
	if bFromendoffile eq True
		i = 1
		while i <= iTcnumber
			sSubspath = sCamfilepath + 'TEMPFILE' + tostr(i:'5.0(n)')
			{nl,'!!delete file=' sSubspath '!!'}
			i = i + 1
		endw
		bFromendoffile = false
	endif

endp

;-------------------

@usr_r1pos_calc
	; Calculate Rotary 1 Position (Main Spindle)
	; tmatrix + 4th Transform + cpos + 5xapos
	; Note: Angular Feed Formula fc = f*(180/(pi*r))
	; Note: fc=deg/min, f=linear feed
	nR1postmatrix = (rotate_angle_z) * iR1dir                        ;Rotary from CoordSys (tmatrix)
	nR1postransform = (angle) * iR1dir
	nR1poscpos = (cpos) * iR1dir                                     ;Rotary from C-axis cutting
	nR1pos5x = (apos) * iR1dir                                       ;Rotary from 4/5x Simulatenous
	nR1postemp = nR1postmatrix + nR1postransform + nR1poscpos
	if iR1posControl eq 0 ;SolidCAM Angles
		nR1posadj = 0
	endif
	if iR1posControl eq 1 ;Positive Angles only: Works up to 360deg
		if nR1postemp < 0 and nR1postemp > -360
			nR1posadj = 360
		else
			nR1posadj = 0
		endif
	endif
	if iR1posControl eq 2 ;Negative Angles only: Works up to 360deg
		if nR1postemp > 0 and nR1postemp < 360
			nR1posadj = -360
		else
			nR1posadj = 0
		endif
	endif
	if iR1posControl eq 3 ;Shortest Distance: Not Working yet
		nR1posadj = 0
	endif
	nR1pos = nR1postmatrix + nR1postransform + nR1poscpos + nR1pos5x + nR1posadj

	nR2postmatrix = (-rotate_angle_y) * iR2dir                        ;Rotary from CoordSys (tmatrix)
	nR2pos5x = (bpos) * iR2dir                                       ;Rotary from 4/5x Simulatenous
	nR2pos = nR2postmatrix + nR2pos5x
	if bLimit_3axis
		change(nR1pos) = false
	endif
	if nPR1pos ne nR1pos
		change(nR1pos) = TRUE
	endif
	if nPR2pos ne nR2pos
		change(nR2pos) = TRUE
	endif
	nPR1pos = nR1pos
	nPR2pos = nR2pos
	if (nR1pos ne 0 or nR2pos ne 0) and !X5_job
		xpos = xmpos
		ypos = ympos
		zpos = zmpos
		if pxmpos ne xmpos
			change(xpos) = true
		else
			change(xpos) = false
		endif
		if pympos ne ympos
			change(ypos) = true
		else
			change(ypos) = false
		endif
		if pzmpos ne zmpos
			change(zpos) = true
		else
			change(zpos) = false
		endif
		if abs(normal_to_plane_x eq 1)
			arc_plane = YZ
		endif
		if abs(normal_to_plane_y eq 1)
			arc_plane = ZX
		endif
		if abs(normal_to_plane_z eq 1)
			arc_plane = XY
		endif
	endif
	pxmpos = xmpos
	pympos = ympos
	pzmpos = zmpos
; {nb}
; {nb,'apos = ' apos}
; {nb,'bpos = ' bpos}
; {nb,'cpos = ' cpos}
; {nb,'nR1postmatrix = ' nR1postmatrix}
; {nb,'nR1postransform = ' nR1postransform}
; {nb,'nR1poscpos = ' nR1poscpos}
; {nb,'nR1pos5x = ' nR1pos5x}
; {nb,'nR1postemp = ' nR1postemp}
; {nb,'nR1pos = ' nR1pos' changebit = '(change(nR1pos))}
; {nb}
; {nb,'Updated Position =' cpos}
; {nb,'Updated Position =' nR1pos}
endp

@usr_4x_index
	; Handle 4x indexing (Rotary moves between operations)
	;4x-Indexing control (0=Simple Rotation, 1=New WorkOffset, 2=Trig Macro)
	;4x-Index Clearance control (0=Z-Homing, 1=Z-Tool_Z_Level, 2=Z-Tool_start_plane)

	if i4xIndexMode ne 2 ;Simple Rotation
		if i4xIndexClearanceMode eq 0
			if sHomestrrot ne ''
				{nb,'G46 '}
				{nb,'G990 (Partial Reset) '}
				{nb,'G90     (ABS MODE) '}
				{nb,'G00 Z0 (Rapid to Z0 - ABS) '}
				sHomestr = sHomestrrot
				call @usr_prep_home_axis
				{nl, ' ' }
				change(iWorkoffset) = true
				{nb}
				call @usr_homenumber_output
				{nl, ' ' }
			endif
			bTlchg = true
		endif
		if i4xIndexClearanceMode eq 1
			if tool_z_level < tool_start_plane
				Print 'WARNING!! Tool Z Level is below Tool Start Plane in CoordSys'
				{nl,'WARNING!! Tool Z Level is below Tool Start Plane in CoordSys'}
			endif
			iMotionmode = 0
			{nb,['G'iMotionmode:mcode_f ' '],['G'iAbsincmode ' '],'Z'nPtool_z_level ' '}
		endif
		if i4xIndexClearanceMode eq 2
			iMotionmode = 0
			{nb,['G'iMotionmode:mcode_f ' '],['G'iAbsincmode ' '],'Z'nPtool_start_plane ' '}
		endif
	endif
	if i4xIndexMode eq 2 ;Trig Macro
		if sHomestrrot ne ''
			sHomestr = sHomestrrot
			call @usr_prep_home_axis
		endif
		call @usr_trig_macro_call
		iMotionmode = 0
		iWorkoffset = 112
	endif
endp

@move_4x ; !@#$%
	; Handle GPP direct call to Rapid Move (G00)
	; We not use this procedure to output code
	; We create our own procedure for this so that we may...
	;   Sync with @rapid_move, @move_5x, @move_4x, @move4x_polar, @move4x_cartesian
	if change(xpos)
		xpos = 0
	endif
	call @usr_rapid
endp

@line_4x ; !@#$%
	; Handle GPP direct call to Line Movement (G01)
	; We not use this procedure to output code
	; We create our own procedure for this so that we may...
	;   Sync with @line, @line_5x, @line_4x, @line4x_polar, @line4x_cartesian
	call @usr_line
endp

@chng_tool_cnext
endp

@rotary_info
endp

@tmatrix
endp

@move_5x ; !@#$%
	; Handle GPP direct call to Rapid Move (G00)
	; We not use this procedure to output code
	; We create our own procedure for this so that we may...
	;   Sync with @rapid_move, @move_5x, @move_4x, @move4x_polar, @move4x_cartesian
	call @usr_rapid
endp

@line_5x ; !@#$%
	; Handle GPP direct call to Line Movement (G01)
	; We not use this procedure to output code
	; We create our own procedure for this so that we may...
	;   Sync with @line, @line_5x, @line_4x, @line4x_polar, @line4x_cartesian
	call @usr_line
endp

@tool_path_info
endp

@transform_info
endp

@usr_trig_macro_call
	; Handle SubProgram call to Trig_Macro

	{nb, 'G65P777 X'shift_x ' Y'shift_y ' Z'shift_z ' C'home_number:'5.3' ' A'bpos:'5.3'  ' I0 J0 K0 '}
	;{nl,'G65P777 X'shift_x ' Y'shift_y ' Z'shift_z ' C'home_number '. A'nT1pos:'5.3' ' B'bpos:'5.3'  ' I0 J0 K0'}

endp

@usr_trig_macro_output
	; Handle Trig_Macro output (Subprogram)
	{nl}
	{nl, 'O777'}
	;Copies Work Offset(i.e. G54) to G112 to use for Calculations
	{nb,'G103 P1'}
	{nb,'#7041= [#[5201 + 20 * #3] + #24]'} ; G112 x
	{nb,'M01'}
	{nb,'#7042= [#[5202 + 20 * #3]+ #25]'} ; G112 y
	{nb,'M01'}
	{nb,'#7043= [#[5203 + 20 * #3] + #26]'} ; G112 z
	{nb,'M01'}
	{nb,'#7044= [#[5204 + 20 * #3]]'} ; G112 A
	{nb,'M01'}
	{nb,'#7045= [#[5205 + 20 * #3]]'} ; G112 B
	{nb,'M01'} ;Stop added For HS-1RP to not read ahead

	;Variables 7xxx are G1xx additional work offsets. Puts work offsets in a variable
	;#7001 through #7005 = G110 X, Y, Z, A, B   (this will be the A axis Zero) X=#7001 Z=#7003
	;#7021 through #7025 = G111 X, Y, Z, A, B   (this will be the B axis Zero) X=#7021 Z=#7022

	;x1 = #7021
	;y  = #7022
	;Y2 = #7002  PICKED UP CENTER OF Y-AXIS  G110#
	;z  = #7003  PICKED UP CENTER OF Z-AXIS  G110#

	;Delta Changes In Y & Z- Leg of triangle used to calculate new Y & Z
	{nb,'#141= [#7042 - #7002]'} ; delta y
	{nb,'M01'}
	{nb,'#142= [#7043 - #7003]'} ; delta z
	{nb,'M01'}

	;Trig. Formula on how to calculate offcenter parts when they rotate around the 4th axis
	;z = z*cos(dev_angle) - y*sin(dev_angle)
	;y = z*sin(dev_angle)  + y*cos(dev_angle)

	;Actual Trig. Formula to Calulate the change in Z & Y in the machine
	{nb,'#148 = [[#142*COS[-#1]] - [#141*SIN[-#1]]](NEW Y B)'}  ; z
	{nb,'M01'}
	{nb,'#149 = [[#142*SIN[-#1]] + [#141*COS[-#1]]](NEW Z B)'}  ; y
	{nb,'M01'}
	{nb}

	;New Calculated Home Position- Uses shifts from SolidCAM, Centers of machine, and calculated change in Z & Y
	{nb,'#7041 = #7041 + #4'} ; X + user shift  = new X in g112
	{nb,'M01'}
	{nb,'#7042 = #7002 + #149 + #5'} ; center Y2 + new Y calculated point + user shift  = new Y in g112
	{nb,'M01'}
	{nb,'#7043 = #7003 + #148 + #6'} ; center z  + new z calculated point + user shift  = new z in g112
	{nb,'M01'}
	{nb,'G103'}
	;{nb,'G112'}
	;{nb,' G0 A#1'}
	;Used to end subprogram
	{nb,'M99'}
	{nl}
endp

@rotate_to_plane
;
endp




