diff src/divemode.asm @ 604:ca4556fb60b9

bump to 2.99beta, work on 3.00 stable
author heinrichsweikamp
date Thu, 22 Nov 2018 19:47:26 +0100
parents 08a0162d3ca1
children 5ce603c29750
line wrap: on
line diff
--- a/src/divemode.asm	Thu Oct 11 21:06:29 2018 +0200
+++ b/src/divemode.asm	Thu Nov 22 19:47:26 2018 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemode.asm								REFACTORED VERSION V2.98
+;   File divemode.asm								REFACTORED VERSION V2.99e
 ;
 ;   Divemode
 ;
@@ -9,8 +9,8 @@
 ; HISTORY
 ;  2011-08-15 : [mH] moving from OSTC code
 
-#include "hwos.inc"						; Mandatory header
-#include "shared_definitions.h"			; Mailbox from/to p2_deco.c
+#include "hwos.inc"						; mandatory header
+#include "shared_definitions.h"			; mailbox from/to p2_deco.c
 #include "tft_outputs.inc"
 #include "strings.inc"
 #include "tft.inc"
@@ -26,6 +26,10 @@
 #include "calibrate.inc"
 #include "convert.inc"
 
+ IFDEF _rx_functions
+#include "rx_ops.inc"
+ ENDIF
+
 
 	extern	TFT_dive_compass_heading
 	extern	do_line_menu
@@ -38,37 +42,50 @@
 
 	CBLOCK	local1						; max size is 16 Byte !!!
 		apnoe_timeout_counter			; timeout counter for apnoe mode
-		average_depth_hold:4			; used in calculation of the average depth
 		sensor_setpoint					; sensor ppo2 in 0.01bar for deco routine
-		active_diluent					; backup of diluent gas for when switching back from bailout to CCR/pSCR loop
-		average_depth_hold_total:4		; used to calculate the average depth
-	ENDC								; used: 11 byte, remaining: 5 byte
-
-gui		CODE
+		check_gas_num					; used in search for best gas/dil: current gas/dil number (1-5)
+		check_gas_depth					; used in search for best gas/dil: current gas/dil change depth
+		check_gas_type					; used in search for best gas/dil: current gas/dil type
+		check_gas_O2_ratio				; used in search for best gas/dil: current gas/dil O2 ratio
+		best_gas_num					; used in search for best gas/dil: best    gas/dil number (1-5)  CAUTION: there is also a variable named best_gas_number !
+		best_gas_depth					; used in search for best gas/dil: best    gas/dil change depth
+		ppO2_min						; used in search for best gas/dil: minimum ppO2 required
+		ppO2_max						; used in search for best gas/dil: maximum ppO2 allowed
+	ENDC								; used: 10 byte, remaining: 6 byte
+
+	CBLOCK	local2						; max size is 16 Byte !!!
+		average_depth_hold:4			; used to calculate the resettable average depth
+		average_depth_hold_total:4		; used to calculate the absolute   average depth
+	ENDC								; used: 8 byte, remaining: 8 byte
+
+dmode		CODE
 
 ;=============================================================================
 
 	global	diveloop
 diveloop:
-	banksel common
+	banksel	common
 	call	speed_normal
-	call	diveloop_boot				; Boot tasks for all modes
-
-	; Startup Tasks for all modes
-	call	TFT_boot					; Initialize TFT (includes clear screen)
-	bsf		FLAG_TFT_divemode_mask		; Display mask
-	movff	customview_divemode,menupos3; Reload last customview
-	call	customview_mask				; Redraw last custom view
+	call	diveloop_boot				; boot tasks for all modes
+
+	; startup tasks for all modes
+	call	TFT_boot					; initialize TFT (includes clear screen)
+	bsf		FLAG_TFT_divemode_mask		; request display of dive mode mask
+
+	movff	customview_divemode,menupos3; reload last custom view
+	bsf		redraw_custview_mask		; request redraw of last custom view
 
 	btfsc	FLAG_apnoe_mode
-	bsf		realdive					; Set Realdive flag in Apnoe mode
-
-	btfsc	FLAG_apnoe_mode				; Done for Apnoe or Gauge mode
+	bsf		realdive					; set realdive flag in apnoe mode
+
+	btfsc	FLAG_apnoe_mode				; done for apnoe or gauge mode
 	bra		diveloop_loop_start
-	btfsc	FLAG_gauge_mode				; Done for Apnoe or Gauge mode
+	btfsc	FLAG_gauge_mode				; done for apnoe or gauge mode
 	bra		diveloop_loop_start
 
-	bsf		FLAG_TFT_display_ndl_mask	; display "NDL"
+	; Deco modes
+	bsf		FLAG_TFT_active_gas_divemode; request display of gas and setpoint
+	bsf		FLAG_TFT_display_ndl_mask	; request display of "NDL"
 
 	; +@5 init
 	clrf	WREG						; WAIT marker: display "---"
@@ -79,37 +96,53 @@
 	movff	WREG,int_O_alternate_ascenttime+1
 
 diveloop_loop_start:
+	btfsc	FLAG_TFT_divemode_mask
+	call	TFT_divemode_mask
 	btfsc	FLAG_TFT_display_ndl_mask
 	call	TFT_display_ndl_mask
 
-
-diveloop_loop:							; The diveloop starts here
+diveloop_loop:							; the dive loop starts here
 	btfss	quarter_second_update
 	bra		diveloop_loop1
 
 	; tasks any 1/4 second, any mode
 	bcf		quarter_second_update		; clear flag
 
-	movlw	.6
-	cpfseq	menupos3					; in compass view?
-	bra		diveloop_loop1				; No, done.
-
-	btfsc	alternative_divelayout		; In alternative layout mode?
-	bra		diveloop_loop1				; Yes, done. No Compass.
-
-; TFT Output routines
-	call	TFT_dive_compass_heading	; Yes, update compass heading value
-	bsf		FLAG_TFT_temp_divemode		; Redraw temperature (is slightly affected from compass heading arrow)
-; TFT Output routines
+	btfsc	alternative_divelayout		; in alternative layout?
+	bra		diveloop_loop1				; YES - no compass in alternative layout mode
+	movlw	index_compass_dm			; NO  - index of compass view
+	cpfseq	menupos3					;     - in compass view?
+	bra		diveloop_loop1				;       NO  - done
+	call	TFT_dive_compass_heading	;       YES - update compass heading value
+	bsf		FLAG_TFT_temp_divemode		;           - redraw temperature (is slightly affected from compass heading arrow)
 
 diveloop_loop1:
-	btfss	onesecupdate
-	bra		diveloop_loop3
+	btfss	onesecupdate				; next second begun?
+	bra		diveloop_loop3				; NO
 
 ; tasks any new second...
 	bcf		onesecupdate				; one seconds update, clear flag here in case it's set again in ISR before all tasks are done.
 
-	;bsf	LEDg	; ### USE FOR DEBUG ONLY - RESETS RX CIRCUITRY ###
+;	###-- USE FOR DEBUG ONLY - RESETS RX CIRCUITRY --###
+;	bsf		LEDg
+;	###----------------------------------------------###
+
+	; compute current depth in meters
+	SAFE_2BYTE_COPY rel_pressure,xA
+	movlw	.100
+	movwf	xB+0
+	clrf	xB+1
+	call	div16x16						; xC = xA / xB, xC+0 now holds depth in full meters
+	movff	xC+0,curr_depth					; store result in curr_depth
+
+	; compute ambient pressure / 10, will be needed later
+	SAFE_2BYTE_COPY amb_pressure,xA
+	movlw	.10
+	movwf	xB+0
+	clrf	xB+1
+	call	div16x16						; xC = xA / xB = p_amb / 10
+	movff	xC+0,amb_press_10+0				; store result for later use
+	movff	xC+1,amb_press_10+1				; ...
 
 	; display depth based on full seconds interval (nicer blinking)
 	btfss	alternative_divelayout
@@ -117,22 +150,29 @@
 	btfsc	alternative_divelayout
 	rcall	TFT_output4_alternative
 
-	btfsc	FLAG_apnoe_mode				; Only in apnoe mode
-	bra		diveloop_loop1_nonedeco		; One Second Tasks in Apnoe mode
+	btfsc	FLAG_apnoe_mode				; in Apnoe mode?
+	bra		diveloop_loop1_nonedeco		; YES - do Apnoe mode every second tasks
 
 ; tasks any new second - only for deco modes
-diveloop_loop1_decomodes:
-	bsf		FLAG_TFT_divemins			; Display (new) divetime!
-	btfsc	show_safety_stop			; Show the safety stop?
-	bsf		FLAG_TFT_show_safety_stop	; Yes, show/delete if done.
+diveloop_loop1_deco:
+	bsf		FLAG_TFT_divemins			; display (new) dive time!
+	btfsc	show_safety_stop			; show the safety stop?
+	bsf		FLAG_TFT_show_safety_stop	; YES - show/delete if done
 
 	btfss	alternative_divelayout
 	rcall	TFT_output1_normal
 	btfsc	alternative_divelayout
 	rcall	TFT_output1_alternative
 
-	btfsc	FLAG_ccr_mode				; in CCR mode...
-	call	check_dive_autosp			; ...check for Auto-SP
+	call	divemode_check_for_warnings	; check for warnings
+
+ IFDEF _rx_functions
+	btfss	FLAG_tr_enabled				; TR functions enabled?
+	bra		diveloop_loop1_deco1		; NO  - skip pressure readings part
+	call	get_pressure_readings		; YES - get  pressure readings
+	call	configure_sac_calculation	;     - set up SAC calculation
+diveloop_loop1_deco1:
+ ENDIF
 
 	call	calc_deko_divemode			; calculate decompression and set resulting display flags
 
@@ -140,124 +180,108 @@
 	rcall	TFT_output2_normal
 	btfsc	alternative_divelayout
 	rcall	TFT_output2_alternative
-
-	call	divemode_check_for_warnings	; Check for any warnings
-
-	bra		diveloop_loop2				; Common Tasks
-
+	bra		diveloop_loop2				; continue with common tasks
 
 ; tasks any new second - only for apnoe mode
 diveloop_loop1_nonedeco:
-	rcall	divemode_apnoe_tasks		; 1 sec. Apnoe tasks
-	call	customview_second			; Do every-second tasks for the custom view area
-	;bra	diveloop_loop2				; Common Tasks
+	rcall	divemode_apnoe_tasks		; 1 sec. apnoe tasks
+	call	customview_second			; do every-second tasks for the custom view area
+	;bra	diveloop_loop2				; common tasks
 
 ; continue tasks any new second, any mode
 diveloop_loop2:
-	rcall	timeout_divemode			; ** menu timeout? ** This routine sets the required flags
+	btfsc	redraw_custview_mask		; shall we redraw the custom view mask?
+	call	customview_mask				; YES - redraw custom view mask
+
+	rcall	timeout_divemode			; ** menu timeout? ** - this routine sets the required flags
 	rcall	set_dive_modes				; tests if depth > threshold
-	rcall	set_min_temp				; store min. temp if required (Future hardware will need this to be checked 1/second...)
+	rcall	set_min_temp				; store min. temp if required (future hardware will need this to be checked 1/second...)
 
 	btfsc	oneminupdate				; one minute tasks
-	rcall	update_divemode60			; Update clock, etc.
+	rcall	update_divemode60			; update clock, etc.
+
+	btfss	FLAG_oc_mode				; are we in OC mode?
+	bsf		FLAG_TFT_active_gas_divemode; NO - have the gas and setpoint redrawn on every second to update setpoint display, animate the blinking, etc.
 
 	btfss	alternative_divelayout
 	rcall	TFT_output3_normal
 	btfsc	alternative_divelayout
 	rcall	TFT_output3_alternative
 
-	;bcf	LEDg	; ### USE FOR DEBUG ONLY - RESETS RX CIRCUITRY ###
+;	###-- USE FOR DEBUG ONLY - RESETS RX CIRCUITRY --###
+;	bcf		LEDg
+;	###----------------------------------------------###
 
 ; tasks any round, any mode
 diveloop_loop3:
-	call	test_switches_divemode		; Check switches in divemode
+	call	test_switches_divemode		; check switches in dive mode
 
 	global	diveloop_loop4
-diveloop_loop4:							; Menu-Exit returns here...
-	btfsc	divemode_menu				; in the big divemode menu?
-	bra		diveloop_loop4b				; YES - no space for CCR/pSCR info
-	btfsc	menuview					; NO  - in the small yellow menu?
-	bra		diveloop_loop4b				;       YES - no space for CCR/pSCR info
-	btfsc	alternative_divelayout		;       NO  - in the alternative layout?
-	bra		diveloop_loop4b				;             YES - no space for CCR/pSCR info
-	call	TFT_show_mode_divemode		;             NO  - (re)write CCR/pSCR mode info to display
-diveloop_loop4b:
-	btfsc	toggle_customview			; Next view?
-	call	customview_toggle			; Yes, show next customview (and delete this flag)
-
-	btfsc	divemode_gaschange			; Gas switch flag set?
+diveloop_loop4:							; menu-exit returns here...
+	btfsc	toggle_customview			; next view?
+	call	customview_toggle			; YES - show next custom view (and delete this flag)
+
+	btfsc	divemode_gaschange			; gas switch flag set?
 	call	gas_switched_common			; YES
 
-	btfsc	toggle_gf					; Toggle GF/aGF?
+	btfsc	toggle_gf					; toggle GF/aGF?
 	rcall	divemodemode_togglegf		; YES
 
-	btfsc	FLAG_set_marker				; shall a marker be set?
+ IFDEF _cave_mode
+	btfsc	toggle_turn_dive			; toggle dive turned?
+	rcall	divemodemode_toggleturn		; YES
+ ENDIF
+
+	btfsc	FLAG_set_marker				; shall set a marker?
 	call	set_logbook_marker			; YES
 
-	btfsc	store_sample				; store new sample?
-	call	store_dive_data				; Store profile data
-
-	btfss	divemode					; Dive finished?
-	goto	ghostwriter_end_dive		; Dive finished!
+	btfsc	store_sample				; shall store new sample?
+	call	store_dive_data				; YES - store profile data
+
+	btfss	divemode					; dive finished?
+	goto	ghostwriter_end_dive		; YES - dive finished!
 
 	btfsc	pressure_refresh			; new pressure available?
-	rcall	set_max_depth				; update max. depth if required
+	rcall	set_max_depth				; YES - update max. depth if required
 	btfsc	pressure_refresh			; new pressure available?
-	bsf		FLAG_TFT_depth				; Yes, update depth
+	bsf		FLAG_TFT_depth				; YES - update depth
 	bcf		pressure_refresh			; clear flag
 
-	btfsc	temp_changed
-	bsf		FLAG_TFT_temp_divemode		; Displays temperature
-
-	; display depth based on as-fast-as-possible (no nice blinking)
-	;btfss	alternative_divelayout
-	;rcall	TFT_output4_normal
-	;btfsc	alternative_divelayout
-	;rcall	TFT_output4_alternative
-
-	btfsc	enable_screen_dumps			; =1: Ignore vin_usb, wait for "l" command (Screen dump)
-	bra		diveloop_loop5
-	bra		diveloop_loop6
-
-diveloop_loop5:
-	btfss	vusb_in						; USB (still) plugged in?
-	bcf		enable_screen_dumps			; No, clear flag
-	call	rs232_get_byte
-	btfsc	rs232_receive_overflow
-	bra		diveloop_loop6
-	movlw	"l"
-	cpfseq	RCREG1
-	bra		diveloop_loop6
-	call	TFT_dump_screen				; Dump the screen contents
-
-diveloop_loop6:
-	bra		diveloop_loop				; Loop the divemode
+	btfsc	temp_changed				; temperature changed?
+	bsf		FLAG_TFT_temp_divemode		; YES - display temperature
+
+ IFDEF _screendump
+	btfsc	enable_screen_dumps			; screen dump function enabled?
+	call	TFT_dump_screen_check		; YES - check if requested and do it
+ ENDIF
+
+	bra		diveloop_loop				; loop the dive mode
 
 ;--------------------------------------------------------------------------------------------------------	
 
-TFT_output1_normal:						; beginning of any new second - only for deco modes
+TFT_output1_normal:							; beginning of any new second - only for deco modes
 	btfsc	FLAG_TFT_divemode_mask
 	call	TFT_divemode_mask
 	btfsc	FLAG_TFT_divemins
-	call	TFT_divemins				; Display (new) divetime!
-	call	customview_second			; Do every-second tasks for the custom view area (In sync with the divetime) mH
+	call	TFT_divemins					; display (new) dive time!
+	call	customview_second				; do every-second tasks for the custom view area (in sync with the dive time) mH
 	btfsc	FLAG_TFT_show_safety_stop
-	call	TFT_show_safety_stop		; Show safety stop
+	call	TFT_show_safety_stop			; show safety stop
 	btfsc	FLAG_TFT_clear_safety_stop
-	call	TFT_clear_safety_stop		; Clear safety stop
+	call	TFT_clear_safety_stop			; clear safety stop
 	return
 
-TFT_output1_alternative:				; beginning of any new second - only for deco modes
+TFT_output1_alternative:					; beginning of any new second - only for deco modes
+	btfsc	FLAG_TFT_divemode_mask_alt
+	call	TFT_divemode_mask_alternative	; alternative mask
 	btfsc	FLAG_TFT_divemins
-	call	TFT_divemins_alternative	; Display (new) divetime!
-	btfsc	FLAG_TFT_divemode_mask_alt
-	call	TFT_divemode_mask_alternative ; Alt. mask
-	call	customview_alternative_second ; Do every-second tasks for the custom view area (In sync with the divetime) mH
+	call	TFT_divemins_alternative		; display (new) divetime!
+	call	customview_alternative_second	; do every-second tasks for the custom view area (in sync with the dive time) mH
 	btfsc	FLAG_TFT_big_deco_alt
-	call	TFT_big_deco_alt			; Big deco and safety stop
+	call	TFT_big_deco_alt				; big deco, also manages alternative safety stop thus moved to first wave of outputs [rl]
 	return
 
-TFT_output2_normal:						; any new second - only for deco modes
+TFT_output2_normal:							; any new second - only for deco modes
 	btfsc	FLAG_TFT_display_ndl_mask
 	call	TFT_display_ndl_mask
 	btfsc	FLAG_TFT_display_ndl
@@ -270,56 +294,56 @@
 	call	TFT_display_tts
 	return
 
-TFT_output2_alternative:				; any new second - only for deco modes
+TFT_output2_alternative:					; any new second - only for deco modes
 	return
 
-TFT_output3_normal:						; tasks any new second, any mode
+TFT_output3_normal:							; tasks any new second, any mode, after deco calculations
 	btfsc	FLAG_TFT_max_depth
-	call	TFT_max_depth				; use normal max. depth
+	call	TFT_max_depth					; use normal max. depth
 	btfsc	FLAG_TFT_divemode_warning
 	call	TFT_divemode_warning
 	btfsc	FLAG_TFT_divemode_warning_clear
 	call	TFT_divemode_warning_clear
-	btfsc	FLAG_TFT_active_gas_divemode
-	call	TFT_active_gas_divemode		; Display gas/Setpoint
 	btfsc	FLAG_TFT_dive_warning_text_clear
-	call	TFT_clear_warning_text		; clear complete warnings area
+	call	TFT_clear_warning_text			; clear complete warnings area
 	btfsc	FLAG_TFT_dive_warning_text_clr2
-	call	TFT_clear_warning_text_2nd_row; clear 2nd row of warnings
+	call	TFT_clear_warning_text_2nd_row	; clear 2nd row of warnings
 	return
 
-TFT_output3_alternative:				; tasks any new second, any mode
-	btfsc	FLAG_TFT_max_depth_alt
-	call	TFT_max_depth_alternative	; big max. depth
+TFT_output3_alternative:					; tasks any new second
+	btfsc	FLAG_TFT_max_depth
+	call	TFT_max_depth_alternative		; big max. depth
 	btfsc	FLAG_TFT_dive_warning_text_clear
-	call	TFT_clear_warning_text		; clear complete warnings area (In alt mode only 2nd. row...)
+	call	TFT_clear_warning_text			; clear complete warnings area (in alt mode only 2nd row...)
 	return
 
-TFT_output4_normal:						; tasks any round, any mode
+TFT_output4_normal:							; tasks any round, any mode, before deco calculations (stable timebase)
 	btfsc	FLAG_TFT_depth
-	call	TFT_depth					; Displays new depth
+	call	TFT_depth						; display depth
+	btfsc	FLAG_TFT_active_gas_divemode
+	call	TFT_active_gas_divemode			; display gas/setpoint
 	btfsc	FLAG_TFT_temp_divemode
-	call	TFT_temp_divemode			; Update temperature
+	call	TFT_temp_divemode				; update temperature
 	return
 
-TFT_output4_alternative:				; tasks any round, any mode
+TFT_output4_alternative:					; tasks any round, any mode
 	btfsc	FLAG_TFT_depth
-	call	TFT_depth					; Displays new depth
+	call	TFT_depth						; display new depth
 	return
 
 
 ;--------------------------------------------------------------------------------------------------------
 
-divemode_apnoe_tasks:					; 1 sec. Apnoe tasks
-	call	TFT_display_apnoe_descent	; Yes, Show descent timer
+divemode_apnoe_tasks:					; 1 sec. apnoe tasks
+	call	TFT_display_apnoe_descent	; show descent timer
 	call	TFT_max_depth				; use normal max. depth
 
-	btfsc	divemode2					; Time running?
-	bra		divemode_apnoe_tasks2		; New descent, reset data if flag is set
+	btfsc	divemode2					; time running?
+	bra		divemode_apnoe_tasks2		; YES - new descent, reset data if flag is set
 
 	rcall	apnoe_calc_maxdepth
 	call	TFT_display_apnoe_surface
-	call	TFT_display_apnoe_last_max	; Show last max. depth
+	call	TFT_display_apnoe_last_max	; show last max. depth
 	incf	apnoe_surface_secs,F
 	movlw	d'60'
 	cpfseq	apnoe_surface_secs
@@ -328,26 +352,26 @@
 	incf	apnoe_surface_mins,F
 
 divemode_apnoe_tasks1:
-	bcf		FLAG_active_descent			; Clear flag
-	btfsc	divemode2					; Time running?
-	return								; Yes, return
-	bsf		FLAG_active_descent			; Set Flag
+	bcf		FLAG_active_descent			; clear flag
+	btfsc	divemode2					; time running?
+	return								; YES - return
+	bsf		FLAG_active_descent			; set flag
 	return
 
 divemode_apnoe_tasks2:
-	btfss	FLAG_active_descent			; Are we descending?
-	return								; No, We are at the surface
-	rcall	apnoe_calc_maxdepth			; Yes!
-	call	TFT_apnoe_clear_surface		; Clear Surface timer
-	clrf	apnoe_timeout_counter		; Delete timeout
+	btfss	FLAG_active_descent			; are we descending?
+	return								; NO - we are at the surface
+	rcall	apnoe_calc_maxdepth			; YES
+	call	TFT_apnoe_clear_surface		; clear surface timer
+	clrf	apnoe_timeout_counter		; delete timeout
 	clrf	apnoe_surface_secs
 	clrf	apnoe_surface_mins
 	clrf	apnoe_secs
-	clrf	apnoe_mins					; Reset Descent time
+	clrf	apnoe_mins					; reset descent time
 	movlw	.0
 	movff	WREG,max_pressure+0
-	movff	WREG,max_pressure+1			; Reset Max. Depth
-	bcf		FLAG_active_descent			; Clear flag
+	movff	WREG,max_pressure+1			; reset max. depth
+	bcf		FLAG_active_descent			; clear flag
 	return
 
 	global	apnoe_calc_maxdepth
@@ -357,8 +381,8 @@
 	movff	max_pressure+0,sub_b+0
 	movff	max_pressure+1,sub_b+1
 	call	subU16						; sub_c = sub_a - sub_b
-										; apnoe_max_pressure<max_pressure -> neg_flag=1
-										; max_pressure<=apnoe_max_pressure -> neg_flag=0
+										; apnoe_max_pressure <  max_pressure       -> neg_flag=1
+										; max_pressure       <= apnoe_max_pressure -> neg_flag=0
 	btfss	neg_flag
 	return
 										;apnoe_max_pressure<max_pressure
@@ -369,148 +393,193 @@
 	; --------------------------------------------------------------------------------------
 
 calc_deko_divemode:
-	rcall	calc_deko_divemode2			; all deco relevant code is now invoked every second
-	btfsc	twosecupdate
-	bra		calc_deko_divemode1
-	bsf		twosecupdate
-	return
-
-calc_deko_divemode1:					; the following code is invoked every 2 seconds
-	bcf		twosecupdate
-
+	btfss	FLAG_gauge_mode				; in gauge mode?
+	rcall	calc_deko_engine			; NO - do deco calculations
+
+	; Increment the time accumulators used for calculating the average depths.
+	; This done here and not in the ISR to guarantee synchronism between time
+	; and depth accumulator incrementing.
+	infsnz	average_divesecs+0,F
+	incf	average_divesecs+1,F
+	infsnz	average_divesecs_total+0,F
+	incf	average_divesecs_total+1,F
+
+	btg		onesectoggle				; toggle the one-second toggle bit
+	btfss	onesectoggle				; toggle bit set?
+	bra		calc_deko_divemode2			; NO
+	;bra	calc_deko_divemode1			; YES
+
+calc_deko_divemode1:					; every-2-seconds tasks, 1st phase
+;	call	TFT_debug_output			; optional debug output
+	btfsc	FLAG_gauge_mode				; in gauge mode?
+	return								; YES - done
+	goto	check_gas_best			; NO  - checks if a better gas should be selected (by user) and return
+
+calc_deko_divemode2:					; every-2-seconds tasks, 2nd phase
 	call	calc_average_depth			; calculate average depth
 	call	calc_velocity				; calculate vertical velocity and display if > threshold (every two seconds)
-	call	set_reset_safety_stop		; Set flags for safety stop and/or reset safety stop
-	call	TFT_debug_output
-
-	btfsc	FLAG_apnoe_mode				; Done for Apnoe or Gauge mode
-	return
-	btfsc	FLAG_gauge_mode				; Done for Apnoe or Gauge mode
-	return
-
-; Check for a gas change
-	goto	check_gas_change			; Checks if a better gas should be selected (by user) and return...
-
-
-calc_deko_divemode2:
-	btfsc	FLAG_gauge_mode				; Done for Apnoe or Gauge mode
-	return
-
-	btfsc	FLAG_ccr_mode				; In CCR mode?
-	rcall	calc_deko_divemode_sensor	; do sensor data acquisition if applicable by OSTC model
-
-	btfsc	FLAG_pscr_mode				; In PSCR mode?
-	rcall	calc_deko_divemode_sensor	; do sensor data acquisition if applicable by OSTC model
-
-	SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; transfer ambient pressure to deco engine
+	goto	set_reset_safety_stop		; set/reset flags for safety stop and return
+
+
+calc_deko_engine:
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	call	check_dive_autosp			; YES - check for Auto-SP
+
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	rcall	calc_deko_divemode_sensor	; YES - do sensor data acquisition if applicable by OSTC model
+
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	rcall	calc_deko_divemode_sensor	; YES - do sensor data acquisition if applicable by OSTC model
 
 
 	; check deco engine state and switch between normal and alternative plan calculations
 	;
 	; Remark: Any reconfigurations done here do only affect the ascent & deco calculation settings,
-	;		not the settings for the calculations done on the real tissues. The later ones are only
-	;		altered in case of a gas change, or in case of a real bailout or switchback to setpoint
-	;		or sensor, respectively.
-	;		In case of a gas change or real bailout/switchback, the settings for the deco calculations
-	;		are also changed to match the settings for the real tissues. This is done on signal through
-	;		'divemode_gaschange' and will also leave the deco engine status in state as if having done
-	;		the alternative plan last.
-
-	; check state of ascent/deco calculations
-	movff	char_O_deco_status,lo		; get a working copy of char_O_deco_status into bank common
-	movlw	DECO_STATUS_MASK			; load bit mask covering the deco status bits
-	andwf	lo,W						; mask out bits showing deco engine computations state
-	tstfsz	WREG						; check if the last compute cycle has finished (bits 1 and 0 cleared)
-	bra		calc_deko_divemode2e		; NO  - computations still in progress, needs more computation cycles
-	btfss	lo,DECO_PLAN_FLAG			; YES - computation cycle finished, so check what has been computed
-	bra		calc_deko_divemode2b		; PLAN bit is cleared i.e. normal plan was done, may do alternative next
-
-	; The PLAN bit is set, i.e. an alternative plan was computed in the last cycle, or the deco engine has
-	; been restarted because of a gas change etc. --> Reconfigure to normal plan for next computation cycle.
-
-	; reset flags for special calculations
+	;         not the settings for the calculations done on the real tissues. The later ones are only
+	;         altered in case of a gas change, or in case of a real bailout or switchback to setpoint
+	;         or sensor, respectively.
+	;         In case of a gas change or real bailout/switchback, the settings for the deco calculations
+	;         are also changed to match the settings for the real tissues. This is done on signal through
+	;         'divemode_gaschange' and will also leave the deco engine status in state as if having done
+	;         the alternative plan last.
+
+	; get working copies of char_O_main_status and char_O_deco_status
+	movff	char_O_main_status,hi		; get char_O_main_status into hi
+	movff	char_O_deco_status,lo		; get char_O_deco_status into lo
+
+	; check state of deco calculations
+	btfsc	hi,DECO_COMPLETED_NORM		; finished calculations for normal plan?
+	bra		calc_deko_engine_alt		; YES - do an alternative plan next (or a normal one with more features enabled)
+	btfsc	hi,DECO_COMPLETED_ALT		; finished calculations for alternative plan?
+	bra		calc_deko_engine_norm		; YES - do a normal plan next
+	bra		calc_deko_engine_cont		; NO to both - continue calculations / do first invocation in INIT mode
+
+calc_deko_engine_norm:
+	; Last cycle did an alternative plan, or the deco engine has been restarted because of a gas change etc.
+	; --> Reconfigure to normal plan for next computation cycle.
+	bcf		lo,DECO_PLAN_FLAG			; clear flag for alternative plan to do a normal plan next
+	bcf		lo,DECO_ASCENT_FLAG			; clear flag for delayed ascent calculation
+	bcf		lo,DECO_VOLUME_FLAG			; clear flag for gas needs calculation
+	bcf		lo,DECO_BAILOUT_FLAG		; clear flag for bailout mode
+ IFDEF _cave_mode
+	bcf		hi,DECO_CAVE_MODE			; clear flag for cave mode
+ ENDIF
+
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	bra		calc_deko_engine_norm_loop	; YES - reload diluents and reconfigure CCR mode if not in bailout
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	bra		calc_deko_engine_norm_loop	; YES - reload diluents and reconfigure pSCR mode if not in bailout
+	;bra	calc_deko_engine_norm_OC	; neither in CCR nor pSCR mode, so reload OC gases and reconfigure OC mode
+										; (first cycle omits gas needs calculation for faster first deco results)
+calc_deko_engine_norm_OC:
+	movff	active_gas,WREG				; get current OC gas
+	call	deco_setup_oc_gases_pre		; set up deco calculations in OC mode with OC gases
+	bra		calc_deko_engine_start		; start deco engine
+
+calc_deko_engine_norm_loop:				; switch to loop calculation if not in a real bailout situation
+	btfsc	FLAG_bailout_mode			; check if a real bailout situation is present
+	bra		calc_deko_engine_norm_OC	; YES - revert to OC mode
+										; NO  - switch to loop calculation:
+	movff	active_dil,WREG				;     - get current diluent
+	call	deco_setup_cc_diluents_pre	;     - set up deco calculations in CCR/pSCR mode with diluents
+	bra		calc_deko_engine_start		;     - start deco engine
+
+calc_deko_engine_alt:
+	; A normal plan was computed in the last cycle. For the next calculation cycle the mode may be switched
+	; to alternative plan, or stay in normal plan but with certain features enabled...
+	bcf		lo,DECO_ASCENT_FLAG			; clear flag for delayed ascent calculation
+	bcf		lo,DECO_VOLUME_FLAG			; clear flag for gas needs calculation
+	bcf		lo,DECO_BAILOUT_FLAG		; clear flag for bailout mode
+ IFDEF _cave_mode
+	bcf		hi,DECO_CAVE_MODE			; clear flag for cave mode
+ ENDIF
+
+	btfsc	FLAG_bailout_mode			; check if a real bailout situation is present
+	bra		calc_deko_engine_alt_1		; YES - stay in normal plan mode and preclude delayed ascent calculation
+	TSTOSS	char_I_extra_time			; NO  - check if a delayed ascent is enabled
+	bra		calc_deko_engine_alt_1		;       NO  - stay in normal plan mode and preclude delayed ascent calculation
+	bsf		lo,DECO_PLAN_FLAG			;       YES - set flag for alternative plan
+	bsf		lo,DECO_ASCENT_FLAG			;           - set flag for delayed ascent
+
+calc_deko_engine_alt_1:
+	TSTOSS	opt_calc_asc_gasvolume		; check if gas volume calculation is enabled
+	bra		calc_deko_engine_start		; NO  - no volume calculation, no simulated bailout plan in this case
+	bsf		lo,DECO_VOLUME_FLAG			; YES - set gas needs calculation flag
+
+	btfsc	FLAG_bailout_mode			; check if a real bailout situation is present
+	bra		calc_deko_engine_start		; YES - normal plan already does bailout (OC) calculation "for real"
+
+ IFDEF _cave_mode
+	bsf		hi,DECO_CAVE_MODE			; activate cave mode by default
+	btfss	FLAG_cave_mode				; cave mode switched on?
+	bcf		hi,DECO_CAVE_MODE			; NO  - deactivate p2deco cave mode again
+	btfsc	FLAG_dive_turned			; dive turned?
+	bcf		hi,DECO_CAVE_MODE			; YES - deactivate p2deco cave mode again
+	btfsc	FLAG_cave_mode_shutdown		; cave mode function shut down?
+	bcf		hi,DECO_CAVE_MODE			; YES - deactivate p2deco cave mode again
+ ENDIF
+
+	btfss	lo,DECO_MODE_LOOP_FLAG		; NO  - has a loop mode calculation been done during the normal plan?
+	bra		calc_deko_engine_start		;       NO  - when not in loop mode, no simulated bailout to be done
+	decf	best_gas_number,W			;       YES - get best gas number -1 into WREG. If not available, WREG will be 255 now. If not computed yet, WREG will be 254 now.
+	btfsc	WREG,7						;           - WREG < 128 (a bailout gas is available)?
+	bra		calc_deko_engine_alt_2		;             NO  - no simulated bailout possible because no bailout gas available to switch to
+	bsf		lo,DECO_PLAN_FLAG			;             YES - set flag for alternative plan
+	bsf		lo,DECO_BAILOUT_FLAG		;                 - set bailout mode flag (enables gas changes before 1st stop)
+	movf	best_gas_number,W			;                 - put number of best gas into WREG
+	call	deco_setup_oc_gases_pre		;                 - set up deco calculations in OC mode with OC gases
+	bra		calc_deko_engine_start		;                 - start in alternative plan mode
+
+calc_deko_engine_alt_2:
 	bcf		lo,DECO_PLAN_FLAG			; clear flag for alternative plan
 	bcf		lo,DECO_ASCENT_FLAG			; clear flag for delayed ascent calculation
 	bcf		lo,DECO_VOLUME_FLAG			; clear flag for gas needs calculation
+ IFDEF _cave_mode
+	bcf		hi,DECO_CAVE_MODE			; clear flag for cave mode
+ ENDIF
+	call	inval_alternative_plan_data	; invalidate all alternative (bailout) plan data because they are not applicable any more
+
+calc_deko_engine_start:
+ IFDEF _cave_mode
+	movff	hi,char_O_main_status		; write-back char_O_main_status to deco engine interface
+ ENDIF
 	movff	lo,char_O_deco_status		; write-back char_O_deco_status to deco engine interface
 
-	; check if a switchback from CCR or pSCR bailout calculation is to be done
-	btfsc	FLAG_ccr_mode				; may a switchback from a CCR bailout calculation be needed?
-	bra		calc_deko_divemode2a		; in CCR  mode, so may need to switch back from bailout calculation
-	btfsc	FLAG_pscr_mode				; may a switchback from a pSCR bailout calculation be needed?
-	bra		calc_deko_divemode2a		; in pSCR mode, so may need to switch back from bailout calculation
-	bra		calc_deko_divemode2e		; not in CCR nor pSCR, so no switchback needed, start normal plan now
-										; (first cycle omits gas needs calculation in OC without delayed ascent)
-
-	; switch back to loop calculation if last cycle was doing a bailout calculation
-calc_deko_divemode2a:					
-	movff	opt_calc_asc_gasvolume,hi	; get the gas volume needs calculation setting
-	movf	hi,W						; are gas volume calculations turned on?
-	bz		calc_deko_divemode2e		; NO  - can't have done a bailout calculation then, start normal plan
-	btfsc	is_bailout					; YES - check if a real bailout situation is present
-	bra		calc_deko_divemode2e		; YES - OC gases have been set by bailout action then, start normal plan
-	movff	active_gas,WREG				; NO  - switch back to loop calculation: get current (diluent) gas, ...
-	call	deco_setup_cc_diluents		;     ... set up deco calculations in CCR/pSCR mode with diluents,
-	bra		calc_deko_divemode2e		;     ... and start in normal plan mode
-
-	; The PLAN bit was cleared, i.e. a normal plan was computed in the last cycle. For the next
-	; computation cycle the mode may be switched to alternative plan, or stay in normal mode...
-
-calc_deko_divemode2b:
-	bcf		lo,DECO_ASCENT_FLAG			; clear flag for delayed ascent calculation (for safety only)
-	btfsc	is_bailout					; check if a real bailout situation is present
-	bra		calc_deko_divemode2c		; YES - stay in normal plan mode and preclude delayed ascent calculation
-	movff	char_I_extra_time,hi		; NO  -	get the delayed ascent setting
-	tstfsz	hi							;       check if delayed ascent calculation is enabled
-	bsf		lo,DECO_ASCENT_FLAG			;       YES - set flag for delayed ascent calculation
-	tstfsz	hi							;       check if delayed ascent calculation is enabled (again)
-	bsf		lo,DECO_PLAN_FLAG			;       YES - set flag for alternative plan
-
-	; check if a gas needs calculation shall be done
-calc_deko_divemode2c:					
-	bsf		lo,DECO_VOLUME_FLAG			; set gas needs calculation flag (may be cleared again next)
-	TSTOSS	opt_calc_asc_gasvolume		; check if gas needs calculation is enabled
-	bcf		lo,DECO_VOLUME_FLAG			; NO  - reset flag again
-	movff	lo,char_O_deco_status		; write-back char_O_deco_status to deco engine interface
-	TSTOSS	opt_calc_asc_gasvolume		; check if gas volume calculation is enabled (again)
-	bra		calc_deko_divemode2e		; NO  - no volume calculation, no simulated bailout plan in no case
-
-	; check if conditions are met to calculate a bailout plan
-	btfsc	is_bailout					; check if a real bailout situation is present
-	bra		calc_deko_divemode2e		; YES - normal plan already does bailout (OC) calculation "for real"
-	btfss	lo,DECO_MODE_LOOP_FLAG		; NO  - have loop mode calculation been done during the normal plan?
-	bra		calc_deko_divemode2e		; NO  - when not in loop mode, no simulated bailout to be done
-	bsf		lo,DECO_PLAN_FLAG			; YES - set flag for alternative plan
-	movff	lo,char_O_deco_status		;       write-back char_O_deco_status to deco engine interface
-	call	get_first_gas_to_WREG		;       get first OC gas, ...
-	call	deco_setup_oc_gases			;       ... set up deco calculations in OC mode with OC gases,
-	;bra	calc_deko_divemode2e		;       ... and start in alternative plan mode
-
-
-calc_deko_divemode2e:
-	clrf	TMR5L
-	clrf	TMR5H						; 30,51757813µs/bit in TMR5L:TMR5H
-	call	deco_calc_hauptroutine		; calc_tissue
+calc_deko_engine_cont:
+	SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; transfer ambient pressure to deco engine
+	clrf	TMR5L						; restart timer used to preempt stops calculation
+	clrf	TMR5H						;
+	call	deco_calc_hauptroutine		; invoke the deco engine (p2_deco.c)
 	banksel	common
 
-	; Check if deco stops are necessary
-	movff	char_O_first_deco_depth,WREG; get ceiling
-	tstfsz	WREG						; ceiling < 0m (aka in deco) ?
-	bra		calc_deko_divemode3			; YES
-	; NO - within NDL
-	btfsc	decostop_active				; already in no deco mode ?
-	bsf		FLAG_TFT_display_ndl_mask	; NO - clear deco data, display NDL time
+	; check if display shall be updated due to deco engine restart
+	btfsc	FLAG_TFT_display_ndl_or_deko; shall update immediately?
+	bra		calc_deko_engine_update		; YES
+
+	; check if new calculation results for normal plan mode are available
+	movff	char_O_main_status,WREG		; get deco status of deco engine
+	btfss	WREG,DECO_COMPLETED_NORM	; new calculation results for normal plan available?
+	return								; NO  - done
+calc_deko_engine_update:
+	bcf		FLAG_TFT_display_ndl_or_deko; YES - reset flag for immediate update
+	movff	char_O_deco_info,WREG		;     - get deco info vector
+	btfsc	WREG,deco_ceiling			;     - ceiling depth > 0 ?
+	bra		calc_deko_engine_update_deco;       YES - in deco
+	;bra	calc_deko_engine_update_NDL	;       NO  - within NDL
+
+calc_deko_engine_update_NDL:			; within NDL
+	btfsc	decostop_active				; been in deco mode before?
+	bsf		FLAG_TFT_display_ndl_mask	; YES - clear deco data, display NDL time
 	bsf		FLAG_TFT_display_ndl		; display NDL time
-	bcf		decostop_active				; clear flag (again)
+	bcf		decostop_active				; clear flag for been in deco mode before
 	return
 
-calc_deko_divemode3:
-	; YES - in deco
-	btfss	decostop_active				; already in deco mode ?
+calc_deko_engine_update_deco:			; in deco
+	btfss	decostop_active				; already been in deco mode before?
 	bsf		FLAG_TFT_display_deko_mask	; NO - clear NDL time, display deco data
 	bsf		FLAG_TFT_display_deko		; display deco data
 	bsf		FLAG_TFT_display_tts		; display TTS
-	bsf		decostop_active				; set flag (again)
+	bsf		decostop_active				; set flag for being in deco mode
 	return
 
 	; --------------------------------------------------------------------------------------
@@ -521,71 +590,57 @@
 	btfss	s8_digital						 ; check if we have a digital interface to the sensors
 	bra		calc_deko_divemode_sensor_analog ; NO  - check if we have an analog interface
 	btfss	new_s8_data_available			 ; YES - check if a new data frame was received
-	bra		calc_deko_divemode_sensor_common ; NO  - use old values -- TODO: add timeout for no new data
+	bra		calc_deko_divemode_sensor_common ; NO  - use old values
 	call	compute_mvolts_for_all_sensors	 ; YES - compute mV values from digital data
 	bra		calc_deko_divemode_sensor_common
-
+calc_deko_divemode_sensor_analog:
+	btfss	analog_o2_input					; do we have an analog input?
+	bra		calc_deko_divemode_sensor_opt	; NO  - check if we have an optical interface
+	call	get_analog_inputs				; YES - get the analog voltages and continue with the common part
+	bra		calc_deko_divemode_sensor_common
 calc_deko_divemode_sensor_opt:
-	btfss	optical_input				; do we have an optical input?
-	return						; No, return (We have no sensors at all. Not analog, not S8 and not optical)
-	;o2_ppo2_sensor1, o2_ppo2_sensor2 and o2_ppo2_sensor3 are already filled in ISR
-	;clear use_O2_sensorX for timeout case
-	btfss	sensor1_active
-	bcf	use_O2_sensor1
-    	btfss	sensor2_active
-	bcf	use_O2_sensor2
+	btfss	optical_input					; do we have an optical input?
+	return									; NO  - return (we have no sensors at all: not analog, not S8 and not optical)
+	btfss	sensor1_active					; YES - o2_ppo2_sensor1, o2_ppo2_sensor2 and o2_ppo2_sensor3 are already filled in ISR
+	bcf		use_O2_sensor1					;       check HUD status data and eventually clear use_O2_sensorX
+	btfss	sensor2_active
+	bcf		use_O2_sensor2
 	btfss	sensor3_active
-	bcf	use_O2_sensor3
-	bra	calc_deko_divemode_sensor1
-	
-calc_deko_divemode_sensor_analog:
-	btfss	analog_o2_input				; do we have an analog input?
-	bra	calc_deko_divemode_sensor_opt		; NO  - check if we have an optical interface
-	call	get_analog_inputs			; YES - get the analog voltages and continue with the common part
+	bcf		use_O2_sensor3
+	bra		calc_deko_divemode_sensor_A		; continue with calculating sensor average
 
 calc_deko_divemode_sensor_common:
-	; Check for each sensor if it is calibrated and if its mv value is within min_mv and max_mv limits.
-	; If     ok: compute o2_ppo2_sensorX := o2_mv_sensorX * opt_x_sX / 1000
+	; Check each sensor if it is calibrated and if its mV value is within min_mv and max_mv limits.
+	; If     ok: compute o2_ppo2_sensorX = o2_mv_sensorX * opt_x_sX / 1000
 	; If not ok: reset   o2_ppo2_sensorX, reset use_O2_sensorX and show the customview 1 in case the sensor was ok before
 
-	; Check min_mv of sensor 1
+	; check sensor 1
 	btfss	sensor1_calibrated_ok		; check if sensor is usable at all
 	bra		check_sensor_1_fail			; NO  - handle it as failed
-	movff	o2_mv_sensor1+0, sub_a+0	; load sensor mV value
-	movff	o2_mv_sensor1+1, sub_a+1
-	movlw	LOW  min_mv					; load minimum mV value
-	movwf	sub_b+0
-	movlw	HIGH min_mv
-	movwf	sub_b+1
-	call	sub16						; sub_c = sensor_mv - min_mv
+	; check min threshold
+	movff	o2_mv_sensor1+0,sub_a+0		; load sensor mV value
+	movff	o2_mv_sensor1+1,sub_a+1
+	rcall	check_min_threshold
 	btfsc	neg_flag					; check if result is negative, i.e. sensor_mv < min_mv
 	bra		check_sensor_1_fail			; YES - declare sensor as failed
-	; Check max_mv of sensor 1			; NO  - continue with next check
-	movff	o2_mv_sensor1+0, sub_a+0
-	movff	o2_mv_sensor1+1, sub_a+1
-	movlw	LOW  max_mv
-	movwf	sub_b+0
-	movlw	HIGH max_mv
-	movwf	sub_b+1
-	call	sub16						; sub_c = sensor_mv - max_mv
+	; check max_threshold
+	rcall	check_max_threshold
 	btfss	neg_flag					; check if result is negative, i.e. sensor_mv < max_mv
 	bra		check_sensor_1_fail			; NO  - declare sensor as failed
-	; Check HUD data, if available		; YES - continue with next check
+	; check HUD data, if available
 	btfss	hud_connection_ok			; check if there is a HUD connected
 	bra		check_sensor_1_ok			; NO  - all checks done then and positive
-	btfss	sensor1_active				; YES - check HUD report on sensor
-	bra		check_sensor_1_fail			; HUD reports a fail
-
+	btfss	sensor1_active				; YES - HUD status ok?
+	bra		check_sensor_1_fail			;       NO - HUD reports a fail
 check_sensor_1_ok:
-	; o2_ppo2_sensor1 := o2_mv_sensor1:2 * opt_x_s1:2 / 1000
+	; o2_ppo2_sensor1 = o2_mv_sensor1:2 * opt_x_s1:2 / 1000
 	movff	o2_mv_sensor1+0,xA+0
 	movff	o2_mv_sensor1+1,xA+1
 	movff	opt_x_s1+0,xB+0
 	movff	opt_x_s1+1,xB+1
 	rcall	compute_ppo2_helper
-	movff	xC+0,o2_ppo2_sensor1		; result in 0.01bar
+	movff	xC+0,o2_ppo2_sensor1		; result in 0.01 bar
 	bra		check_sensor_2				; continue with next sensor
-
 check_sensor_1_fail:
 	clrf	WREG
 	movff	WREG,o2_ppo2_sensor1		; set ppO2 reading to zero
@@ -594,46 +649,34 @@
 	call	check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met
 check_sensor_1_fail_1:
 	bcf		use_O2_sensor1				; revoke sensor from usage
-	;bra	check_sensor_2				; continue with next sensor
-
-check_sensor_2:							; Check min_mv of sensor 2
+
+check_sensor_2:							; check min_mv of sensor 2
 	btfss	sensor2_calibrated_ok		; check if sensor is usable at all
 	bra		check_sensor_2_fail			; NO  - handle it as failed
-	movff	o2_mv_sensor2+0, sub_a+0	; load sensor mV value
-	movff	o2_mv_sensor2+1, sub_a+1
-	movlw	LOW  min_mv					; load minimum mV value
-	movwf	sub_b+0
-	movlw	HIGH min_mv
-	movwf	sub_b+1
-	call	sub16						; sub_c = sensor_mv - min_mv
+	; check min threshold
+	movff	o2_mv_sensor2+0,sub_a+0		; load sensor mV value
+	movff	o2_mv_sensor2+1,sub_a+1
+	rcall	check_min_threshold
 	btfsc	neg_flag					; check if result is negative, i.e. sensor_mv < min_mv
 	bra		check_sensor_2_fail			; YES - declare sensor as failed
-	; Check max_mv of sensor 2			; NO  - continue with next check
-	movff	o2_mv_sensor2+0, sub_a+0
-	movff	o2_mv_sensor2+1, sub_a+1
-	movlw	LOW  max_mv
-	movwf	sub_b+0
-	movlw	HIGH max_mv
-	movwf	sub_b+1
-	call	sub16						; sub_c = sensor_mv - max_mv
+	; check max_threshold
+	rcall	check_max_threshold
 	btfss	neg_flag					; check if result is nagative, i.e. sensor_mv < max_mv
 	bra		check_sensor_2_fail			; NO  - declare sensor as failed
-	; Check HUD data, if available		; YES - continue with next check
+	; check HUD data, if available
 	btfss	hud_connection_ok			; check if there is a HUD connected
 	bra		check_sensor_2_ok			; NO  - all checks done then and positive
-	btfss	sensor2_active				; YES - check HUD report on sensor
-	bra		check_sensor_2_fail			; HUD reports a fail
-
+	btfss	sensor2_active				; YES - HUD status ok?
+	bra		check_sensor_2_fail			;       NO - HUD reports a fail
 check_sensor_2_ok:
-	; o2_ppo2_sensor2 := o2_mv_sensor2:2 * opt_x_s2:2 / 1000
+	; o2_ppo2_sensor2 = o2_mv_sensor2:2 * opt_x_s2:2 / 1000
 	movff	o2_mv_sensor2+0,xA+0
 	movff	o2_mv_sensor2+1,xA+1
 	movff	opt_x_s2+0,xB+0
 	movff	opt_x_s2+1,xB+1
 	rcall	compute_ppo2_helper
-	movff	xC+0,o2_ppo2_sensor2		; result in 0.01bar
+	movff	xC+0,o2_ppo2_sensor2		; result in 0.01 bar
 	bra		check_sensor_3				; continue with next sensor
-
 check_sensor_2_fail:
 	clrf	WREG
 	movff	WREG,o2_ppo2_sensor2		; set ppO2 reading to zero
@@ -642,186 +685,191 @@
 	call	check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met
 check_sensor_2_fail_1:
 	bcf		use_O2_sensor2				; revoke sensor from usage
-	;bra	check_sensor_3				; continue with next sensor	
-
-check_sensor_3:							; Check min_mv of sensor 2
+
+check_sensor_3:							; check min_mv of sensor 2
 	btfss	sensor3_calibrated_ok		; check if sensor is usable at all
 	bra		check_sensor_3_fail			; NO  - handle it as failed
-	movff	o2_mv_sensor3+0, sub_a+0	; load sensor mV value
-	movff	o2_mv_sensor3+1, sub_a+1
-	movlw	LOW  min_mv					; load minimum mV value
-	movwf	sub_b+0
-	movlw	HIGH min_mv
-	movwf	sub_b+1
-	call	sub16						; sub_c = sensor_mv - min_mv
+	; check min threshold
+	movff	o2_mv_sensor3+0,sub_a+0		; load sensor mV value
+	movff	o2_mv_sensor3+1,sub_a+1
+	rcall	check_min_threshold
 	btfsc	neg_flag					; check if result is negative, i.e. sensor_mv < min_mv
 	bra		check_sensor_3_fail			; YES - declare sensor as failed
-	; Check max_mv of sensor 2			; NO  - continue with next check
-	movff	o2_mv_sensor3+0, sub_a+0
-	movff	o2_mv_sensor3+1, sub_a+1
-	movlw	LOW  max_mv
-	movwf	sub_b+0
-	movlw	HIGH max_mv
-	movwf	sub_b+1
-	call	sub16						; sub_c = sensor_mv - max_mv
+	; check max threshold
+	rcall	check_max_threshold
 	btfss	neg_flag					; check if result is negative, i.e. sensor_mv < max_mv
 	bra		check_sensor_3_fail			; NO  - declare sensor as failed
-	; Check HUD data, if available		; YES - continue with next check
+	; check HUD data, if available
 	btfss	hud_connection_ok			; check if there is a HUD connected
 	bra		check_sensor_3_ok			; NO  - all checks done then and positive
-	btfss	sensor3_active				; YES - check HUD report on sensor
-	bra		check_sensor_3_fail			; HUD reports a fail
-
+	btfss	sensor3_active				; YES - HUD status ok?
+	bra		check_sensor_3_fail			;       NO - HUD reports a fail
 check_sensor_3_ok:
-	; o2_ppo2_sensor3 := o2_mv_sensor3:2 * opt_x_s1:2 / 1000
+	; o2_ppo2_sensor3 = o2_mv_sensor3:2 * opt_x_s1:2 / 1000
 	movff	o2_mv_sensor3+0,xA+0
 	movff	o2_mv_sensor3+1,xA+1
 	movff	opt_x_s3+0,xB+0
 	movff	opt_x_s3+1,xB+1
 	rcall	compute_ppo2_helper
-	movff	xC+0,o2_ppo2_sensor3		; result in 0.01bar
-	bra		calc_deko_divemode_sensor1	; continue with calculating sensor average
-
+	movff	xC+0,o2_ppo2_sensor3		; result in 0.01 bar
+	bra		calc_deko_divemode_sensor_A	; continue with calculating sensor average
 check_sensor_3_fail:
 	clrf	WREG
 	movff	WREG,o2_ppo2_sensor3		; set ppO2 reading to zero
 	btfss	use_O2_sensor3				; check if sensor was in use before
 	bra		check_sensor_3_fail_1		; NO  - no new news then
-	call	check_sensor_custview_helper; YES - show customview 1 (sensor values) on further conditions met
+	call	check_sensor_custview_helper; YES - show custom view 1 (sensor values) on further conditions met
 check_sensor_3_fail_1:
 	bcf		use_O2_sensor3				; revoke sensor from usage
-	;bra	calc_deko_divemode_sensor1	; continue with calculating sensor average
-
-calc_deko_divemode_sensor1:				; calculate sensor average
-	; exit here if not in divemode
+
+calc_deko_divemode_sensor_A:			; calculate sensor average
+	; exit here if not in dive mode
 	btfss	divemode
 	return
 
-	; compute sensor_setpoint := average of all o2_ppo2_sensorX of those sensors that have use_O2_sensorX == true
+	; compute sensor_setpoint = average of all o2_ppo2_sensorX of those sensors that have use_O2_sensorX == true
 	; sum up sensor values (in xA:2) and active sensors in (xB:2)
 	clrf	xB+0
 	clrf	xB+1
 	clrf	xA+0
 	clrf	xA+1
-	btfss	use_O2_sensor1				; Sensor1 active?
-	bra		divemode_setup_sensor_values2 ; No
+divemode_setup_sensor_1_value:
+	btfss	use_O2_sensor1					; sensor1 active?
+	bra		divemode_setup_sensor_2_value	; NO
 	movf	o2_ppo2_sensor1,W
-	addwf	xA+0
+	addwf	xA+0,F
 	movlw	.0
-	addwfc	xA+1						; Add into xA:2
-	incf	xB+0,F						; Add a sensor
-divemode_setup_sensor_values2:
-	btfss	use_O2_sensor2				; Sensor2 active?
-	bra		divemode_setup_sensor_values3 ; No
+	addwfc	xA+1,F							; add into xA:2
+	incf	xB+0,F							; add a sensor
+divemode_setup_sensor_2_value:
+	btfss	use_O2_sensor2					; sensor2 active?
+	bra		divemode_setup_sensor_3_value	; NO
 	movf	o2_ppo2_sensor2,W
-	addwf	xA+0
+	addwf	xA+0,F
 	movlw	.0
-	addwfc	xA+1						; Add into xA:2
-	incf	xB+0,F						; Add a sensor
-divemode_setup_sensor_values3:
-	btfss	use_O2_sensor3				; Sensor3 active?
-	bra		divemode_setup_sensor_values4 ; No
+	addwfc	xA+1,F							; add into xA:2
+	incf	xB+0,F							; add a sensor
+divemode_setup_sensor_3_value:
+	btfss	use_O2_sensor3					; sensor3 active?
+	bra		divemode_setup_sensor_mean		; NO
 	movf	o2_ppo2_sensor3,W
-	addwf	xA+0
+	addwf	xA+0,F
 	movlw	.0
-	addwfc	xA+1						; Add into xA:2
-	incf	xB+0,F						; Add a sensor
-
-	; Divide sum of sensor values by number of active sensors found.
-divemode_setup_sensor_values4:
-	call	div16x16					; xA/xB=xC with xA+0 as remainder
-	movff	xC+0,sensor_setpoint		; copy result
-
-	; set default value for pSCR mode: 0 = let p2_deco.c compute the ppO2 based on current dil gas and depth
+	addwfc	xA+1,F							; add into xA:2
+	incf	xB+0,F							; add a sensor
+
+	; divide sum of sensor values by number of active sensors found
+divemode_setup_sensor_mean:
+	clrf	xC+0							; set zero as default result
+	tstfsz	xB+0							; pending div/0 ?
+	call	div16x16						; NO - execute xC = xA / xB = summed ppO2 / number of sensors
+	movff	xC+0,sensor_setpoint			; copy result (or its default)
+
+	; set default value for pSCR mode: 0 => let p2_deco.c compute the ppO2 based on current dil gas and depth
 	; will be overwritten later in case we are in sensor mode and have at least one usable sensor
-	clrf	WREG						; preload a zero
-	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
-	movff	WREG,char_I_const_ppO2		; YES - write 0 to char_I_const_ppo2,
-										;		it will be overwritten if we have a usable sensor reading
-
-	btfsc	is_bailout					; check if we are in bailout
-	bra		calc_deko_divemode_sensor2	; YES - no sensor data transfer to char_I_const_ppO2 in this case
-	movff	opt_ccr_mode,WREG			; =0: Fixed SP, =1: Sensor, =2: Auto SP
-	sublw	.1							; opt_ccr_mode = 1 (Sensor)?
-	bnz		calc_deko_divemode_sensor2	; not in sensor mode - no transfer of sensor data to char_I_const_ppO2
-	tstfsz	xB+0						; check if we have found at least one usable sensor
-	bra		calc_deko_divemode_sensor1a	; YES - we have at least one usable sensor
-	bsf		setpoint_fallback			; NO  - we have NO usable sensors -> initiate fallback
-	btfss	FLAG_ccr_mode				; check if we are in CCR mode
-	bra		calc_deko_divemode_sensor2	; NO  - continue with voting logic flags
-	movff	char_I_setpoint_cbar+0,char_I_const_ppO2	; YES - select fixed setpoint no. 1 for fallback
-	bra		calc_deko_divemode_sensor2	; done - continue with voting logic flags
-calc_deko_divemode_sensor1a:			; we have at least one usable sensor with a value > 0
-	bcf		setpoint_fallback			; clear fallback condition
+	clrf	WREG								; preload a zero
+	btfsc	FLAG_pscr_mode						; check if we are in pSCR mode
+	movff	WREG,char_I_const_ppO2				; YES - write 0 to char_I_const_ppo2,
+												;       it will be overwritten if we have a usable sensor reading
+	btfsc	FLAG_bailout_mode					; check if we are in bailout
+	bra		calc_deko_divemode_sensor_V			; YES - no sensor data transfer to char_I_const_ppO2 in this case
+	movff	opt_ccr_mode,WREG					; NO  - get mode (0: Fixed SP, 1: Sensor, 2: Auto SP)
+	sublw	.1									;     - in sensor mode?
+	bnz		calc_deko_divemode_sensor_V			;       NO  - not in sensor mode - no transfer of sensor data to char_I_const_ppO2
+	tstfsz	xB+0								;       YES - check if we have found at least one usable sensor
+	bra		divemode_setup_sensor_mean1			;             YES - we have at least one usable sensor
+	bsf		setpoint_fallback					;             NO  - we have NO usable sensors -> initiate fallback
+	btfss	FLAG_ccr_mode						;                 - check if we are in CCR mode
+	bra		calc_deko_divemode_sensor_V			;                   NO  - continue with voting logic flags
+	movff	char_I_setpoint_cbar+0,char_I_const_ppO2;               YES - select fixed setpoint no. 1 for fallback
+	bra		calc_deko_divemode_sensor_V			;                       - continue with voting logic flags
+	; we have at least one usable sensor with a ppO2 value > 0
+divemode_setup_sensor_mean1:
+	bcf		setpoint_fallback					; clear fallback condition
 	movff	sensor_setpoint,char_I_const_ppO2	; transfer average sensor value to p2_deco.c code
-	;bra	calc_deko_divemode_sensor2
-
-calc_deko_divemode_sensor2:
+	; vote sensors
+calc_deko_divemode_sensor_V:
 	bsf		voting_logic_sensor1
 	movff	o2_ppo2_sensor1,lo
 	rcall	check_sensor_voting_helper
-	incfsz	WREG						; Was WREG = 255?
-	bcf		voting_logic_sensor1		; No, ignore this sensor
+	tstfsz	WREG						; sensor within range (WREG = 0)?
+	bcf		voting_logic_sensor1		; NO - vote out this sensor
 
 	bsf		voting_logic_sensor2
 	movff	o2_ppo2_sensor2,lo
 	rcall	check_sensor_voting_helper
-	incfsz	WREG						; Was WREG=255?
-	bcf		voting_logic_sensor2		; No, ignore this sensor
+	tstfsz	WREG						; sensor within range (WREG = 0)?
+	bcf		voting_logic_sensor2		; NO - vote out this sensor
 
 	bsf		voting_logic_sensor3
 	movff	o2_ppo2_sensor3,lo
 	rcall	check_sensor_voting_helper
-	incfsz	WREG						; Was WREG=255?
-	bcf		voting_logic_sensor3		; No, ignore this sensor
+	tstfsz	WREG						; sensor within range (WREG = 0)?
+	bcf		voting_logic_sensor3		; NO - vote out this sensor
 
 	; check if a warning shall be issued on sensor disagreement
-
 	btfsc	FLAG_ccr_mode				; check if we are in CCR mode
-	bra		check_warn_sensor_1			; YES - continue with further checks
+	bra		check_warn_sensor_0			; YES - continue with further checks
 	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
-	bra		check_warn_sensor_1			; YES - continue with further checks
-	bra		check_warn_sensor_agree		; not in CCR and not in pSCR, so no warning
-check_warn_sensor_1:					; we are in CCR or pSCR mode
-	btfsc	is_bailout					; check if we are in bailout
-	bra		check_warn_sensor_agree		; YES - no warning in this case
-	movff	opt_ccr_mode,WREG			; =0: Fixed SP, =1: Sensor, =2: Auto SP
-	sublw	.1							; opt_ccr_mode = 1 (Sensor)?
-	bnz		check_warn_sensor_agree		; not in sensor mode - no warning in this case
-										; check sensor 1
+	bra		check_warn_sensor_0			; YES - continue with further checks
+	bra		check_warn_sensor_done		; not in CCR and not in pSCR, so no warning
+check_warn_sensor_0:					; we are in CCR or pSCR mode
+	btfsc	FLAG_bailout_mode			; check if we are in bailout
+	bra		check_warn_sensor_done		; YES - no warning in this case
+	movff	opt_ccr_mode,WREG			; get mode (0: Fixed SP, 1: Sensor, 2: Auto SP)
+	sublw	.1							; in sensor mode?
+	bnz		check_warn_sensor_done		; NO - not in sensor mode - no warning in this case
+	; check sensor 1
+check_warn_sensor_1:
 	btfss	sensor1_calibrated_ok		; check if sensor has a valid calibration
 	bra		check_warn_sensor_2			; NO  - sensor can not cause a warning then
 	btfss	use_O2_sensor1				; YES - check if sensor is in use
-	bra		check_warn_sensor_2			; NO  - sensor can not cause a warning then
-	btfsc	voting_logic_sensor1		; YES - check if sensor value is within agreement range
-	bra		check_warn_sensor_2			; YES - continue with next sensor
-	bcf		sensors_agree				; NO  - issue a warning
+	bra		check_warn_sensor_2			;       NO  - sensor can not cause a warning then
+	btfsc	voting_logic_sensor1		;       YES - check if sensor value is within agreement range
+	bra		check_warn_sensor_2			;             YES - continue with next sensor
+	bcf		sensors_agree				;             NO  - issue a warning
 	return
-
-check_warn_sensor_2:					; check sensor 2
+	; check sensor 2
+check_warn_sensor_2:
 	btfss	sensor2_calibrated_ok		; check if sensor has a valid calibration
 	bra		check_warn_sensor_3			; NO  - sensor can not cause a warning then
 	btfss	use_O2_sensor2				; YES - check if sensor is in use
-	bra		check_warn_sensor_3			; NO  - sensor can not cause a warning then
-	btfsc	voting_logic_sensor2		; YES - check if sensor value is within agreement range
-	bra		check_warn_sensor_3			; YES - continue with next sensor
-	bcf		sensors_agree				; NO  - issue a warning
+	bra		check_warn_sensor_3			;       NO  - sensor can not cause a warning then
+	btfsc	voting_logic_sensor2		;       YES - check if sensor value is within agreement range
+	bra		check_warn_sensor_3			;             YES - continue with next sensor
+	bcf		sensors_agree				;             NO  - issue a warning
 	return
-
-check_warn_sensor_3:					; check sensor 2
+	; check sensor 3
+check_warn_sensor_3:
 	btfss	sensor3_calibrated_ok		; check if sensor has a valid calibration
 	bra		check_warn_sensor_agree		; NO  - sensor can not cause a warning then
 	btfss	use_O2_sensor3				; YES - check if sensor is in use
-	bra		check_warn_sensor_agree		; NO  - sensor can not cause a warning then
-	btfsc	voting_logic_sensor3		; YES - check if sensor value is within agreement range
-	bra		check_warn_sensor_agree		; YES - continue with next sensor
-	bcf		sensors_agree				; NO  - issue a warning
+	bra		check_warn_sensor_agree		;       NO  - sensor can not cause a warning then
+	btfsc	voting_logic_sensor3		;       YES - check if sensor value is within agreement range
+	bra		check_warn_sensor_agree		;             YES - continue with next sensor
+	bcf		sensors_agree				;             NO  - issue a warning
 	return
-
+	; no need for a warning
+check_warn_sensor_done:
 check_warn_sensor_agree:
 	bsf		sensors_agree
 	return
 
+
+check_min_threshold:
+	movlw	LOW  min_mv					; load minimum mV value
+	movwf	sub_b+0
+	movlw	HIGH min_mv
+	movwf	sub_b+1
+	goto	sub16						; sub_c = sensor_mv - min_mv (and return)
+
+check_max_threshold:
+	movlw	LOW  max_mv
+	movwf	sub_b+0
+	movlw	HIGH max_mv
+	movwf	sub_b+1
+	goto	sub16						; sub_c = sensor_mv - max_mv (and return)
+
 compute_ppo2_helper:
 	call	mult16x16					; xA:2*xB:2=xC:4
 	movlw	LOW  .1000
@@ -834,75 +882,83 @@
 	movlw	d'0'
 	addwfc	xC+1,W						; we are still just interested in the carry flag
 	tstfsz	WREG						; ppO2 is higher than 2.55bar?
-	setf	xC+0						; Yes.
+	setf	xC+0						; YES
 	return
 
 check_sensor_custview_helper:
-	btfss	divemode					; check if we are in divemode
+	btfss	divemode					; check if we are in dive mode
 	return								; NO  - not in dive mode, return
-	movff	opt_ccr_mode,WREG			; =0: Fixed SP, =1: Sensor, =2: Auto SP
-	sublw	.1							; opt_ccr_mode = 1 (Sensors)?
-	bnz		check_sensor_helper_1		; NO  - not using the sensors in the moment
-	clrf	menupos3					; YES - arm customview 1 (sensor values)
-	bsf		toggle_customview			;       and request a customview toggle
-check_sensor_helper_1:
+	movff	opt_ccr_mode,WREG			; YES - =0: Fixed SP, =1: Sensor, =2: Auto SP
+	decfsz	WREG,W						;     - opt_ccr_mode = 1 (sensors)?
+	return								;       NO  - not using the sensors in the moment
+	btfsc	alternative_divelayout		;       YES - in alternative layout?
+	call	switch_layout_to_normal		;             YES - switch to normal layout
+	movlw	index_ppo2_sensors-1		;             custom view number one below ppO2 sensors
+	movwf	menupos3					;             set custom view number
+	bsf		toggle_customview			;             initiate toggle to desired custom view -> ppO2 sensors
 	return
 
-
 check_sensor_voting_helper:
 	movf	lo,W
 	cpfsgt	sensor_setpoint
-	bra		check_sensor_voting_common2	; lo < sensor_setpoint
+	bra		check_sensor_voting_helper2		; lo < sensor_setpoint
 	; lo > sensor_setpoint
 	movf	lo,W
 	subwf	sensor_setpoint,W
 	movwf	lo
-check_sensor_voting_common1:
-	movlw	sensor_voting_logic_threshold ; Threshold in 0.01 bar
+check_sensor_voting_helper1:
+	movlw	sensor_voting_logic_threshold	; threshold in 0.01 bar
 	cpfsgt	lo
-	retlw	.255						; Within range
-	retlw	.0							; Out of range
-check_sensor_voting_common2:
-	; lo<sensor_setpoint
+	retlw	.0								; within range
+	retlw	.1								; out of range
+check_sensor_voting_helper2:
+	; lo < sensor_setpoint
 	movf	sensor_setpoint,W
 	subwf	lo,F
-	bra		check_sensor_voting_common1
+	bra		check_sensor_voting_helper1
 
 ;-----------------------------------------------------------------------------
 
-divemodemode_togglegf:								; Toggle aGF/GF
-	bcf		toggle_gf								; clear flag
-	btg		use_agf									; toggle GF
-
-	btfsc	use_agf									; switch to aGF?
+divemodemode_togglegf:								; toggle aGF/GF
+	bcf		toggle_gf								; clear command flag
+	btg		use_agf									; toggle status flag for GF
+
+	btfsc	use_agf									; aGF activated?
 	bra		divemodemode_togglegf_1					; YES - branch to using aGF
 	movff	opt_GF_low,char_I_GF_Low_percentage		; NO  - use normal GF factors
-	movff	opt_GF_high,char_I_GF_High_percentage	;
-	bra		divemodemode_togglegf_2					;       continue with common part
-
-divemodemode_togglegf_1:							; use alternative GF factors
-	movff	opt_aGF_low,char_I_GF_Low_percentage
-	movff	opt_aGF_high,char_I_GF_High_percentage
-
+	movff	opt_GF_high,char_I_GF_High_percentage	;     -
+	bra		divemodemode_togglegf_2					;     - continue with common part
+divemodemode_togglegf_1:
+	movff	opt_aGF_low,char_I_GF_Low_percentage	; YES - use alternative GF factors
+	movff	opt_aGF_high,char_I_GF_High_percentage	;     -
 divemodemode_togglegf_2:
-	call	TFT_gf_mask								; update customview mask to show which one is in use
-													; the customview itself has been called from divemenu_tree before
+	call	TFT_gf_factors_mask						; update custom view mask to show which one is in use
+													; the custom view itself has been called from divemenu_tree before
 	goto	restart_deco_engine						; ...and return
 
 
-calc_velocity:									; called every two seconds
+ IFDEF _cave_mode
+divemodemode_toggleturn:
+	bcf		toggle_turn_dive						; clear command flag
+	btg		FLAG_dive_turned						; toggle dive turned state
+	btfsc	FLAG_cave_mode_shutdown					; cave mode function shut down?
+	bsf		FLAG_dive_turned						; YES - allow only activating turned state
+	goto	set_logbook_marker						; set a logbook marker (and return)
+ ENDIF
+
+calc_velocity:										; called every two seconds
 	btfsc	display_velocity
-	bra		calc_velocity1						; Always update if already displayed
+	bra		calc_velocity1							; always update if already displayed
 	btfss	divemode2
-	return										; display velocity only if deeper then 1m (Not at the surface after the dive)
+	return											; display velocity only if deeper then 1m (Not at the surface after the dive)
 calc_velocity1:
 	SAFE_2BYTE_COPY amb_pressure, sub_a
 	movff	last_pressure_velocity+0,sub_b+0
 	movff	last_pressure_velocity+1,sub_b+1
-	movff	sub_a+0,last_pressure_velocity+0	; store old value for velocity
+	movff	sub_a+0,last_pressure_velocity+0		; store old value for velocity
 	movff	sub_a+1,last_pressure_velocity+1
 
-	call	subU16								; sub_c = amb_pressure - last_pressure
+	call	subU16									; sub_c = amb_pressure - last_pressure
 
 	bcf		neg_flag_velocity
 	btfsc	neg_flag
@@ -917,13 +973,12 @@
 	movff	xC+0,divA+0
 	movff	xC+1,divA+1
 	movlw	d'7'
-	movwf	divB+0
-	call	div16						; divided by 2^7 equals velocity in m/min
+	call	div16						; divA = divA / 2^WREG, divide by 2^7 equals velocity in m/min
 
 	movlw	d'99'
-	cpfsgt	divA+0						; limit to 99m/min
-	bra		calc_velocity3
-	movwf	divA+0						; divA=99
+	cpfsgt	divA+0						; velocity > 99 m/min ?
+	bra		calc_velocity3				; NO
+	movwf	divA+0						; YES - set divA = 99
 
 calc_velocity3:
 	; Copy old speeds
@@ -948,19 +1003,19 @@
 ;	addwf	divA+0,F					; add old speed
 ;	bcf		STATUS,C
 ;	rrcf	divA+0,F					; /2
-	goto	TFT_display_velocity		; With divA+0 = m/min..., and return...
+	goto	TFT_display_velocity		; with divA+0 = m/min..., and return...
 
 
 ;=============================================================================
 
-set_reset_safety_stop:					; Set flags for safety stop and/or reset safety stop
-	TSTOSS	opt_enable_safetystop		; =1: A safety stop is shown
-	bra		delete_safety_stop			; No, don't show safety stop
-
-	btfsc	decostop_active				; Is a deco stop displayed?
-	bra		delete_safety_stop			; Yes, don't show safety stop
-
-	; Below "opt_safety_stop_reset"? Set flag and reset count-down timer
+set_reset_safety_stop:					; set flags for safety stop and/or reset safety stop
+	TSTOSS	opt_enable_safetystop		; safety stop enabled? (=1: show safety stop)
+	bra		delete_safety_stop			; NO - don't show safety stop
+
+	btfsc	decostop_active				; is a deco stop displayed?
+	bra		delete_safety_stop			; YES - don't show safety stop
+
+	; Below "opt_safety_stop_reset"? if yes, set flag and reset count-down timer
 	SAFE_2BYTE_COPY rel_pressure, lo
 	call	adjust_depth_with_salinity	; computes salinity setting into lo:hi [mbar]
 	movff	lo,sub_a+0
@@ -971,51 +1026,43 @@
 	movff	PRODH,sub_b+1
 	call	subU16						; sub_c = sub_a - sub_b
 	btfss	neg_flag
-	bra		reset_safety_stop			; Below 10m, reset safety stop
-
-	; Above "opt_safety_stop_end"? Clear flag.
-	SAFE_2BYTE_COPY rel_pressure, lo
-	call	adjust_depth_with_salinity	; computes salinity setting into lo:hi [mbar]
-	movff	lo,sub_a+0
-	movff	hi,sub_a+1
+	bra		reset_safety_stop			; below 10m, reset safety stop
+
+	; Above "opt_safety_stop_end"? if yes ,clear flag
 	movff	opt_safety_stop_end,WREG	; [cbar]
 	mullw	.10							; mbar in PRODL:H
-	movff	PRODL,sub_b+0
+	movff	PRODL,sub_b+0				; sub_a is still loaded with adjusted rel_pressure
 	movff	PRODH,sub_b+1
 	call	subU16						; sub_c = sub_a - sub_b
 	btfsc	neg_flag
-	bra		delete_safety_stop			; Above 3m, remove safety stop
-
-	; Above "opt_safety_stop_start"? Activate safety stop
-	SAFE_2BYTE_COPY rel_pressure, lo
-	call	adjust_depth_with_salinity	; computes salinity setting into lo:hi [mbar]
-	movff	lo,sub_a+0
-	movff	hi,sub_a+1
+	bra		delete_safety_stop			; above 3m, remove safety stop
+
+	; Above "opt_safety_stop_start"? if yes, activate safety stop
 	movff	opt_safety_stop_start,WREG	; [cbar]
 	mullw	.10							; mbar in PRODL:H
-	movff	PRODL,sub_b+0
+	movff	PRODL,sub_b+0				; sub_a is still loaded with adjusted rel_pressure
 	movff	PRODH,sub_b+1
 	call	subU16						; sub_c = sub_a - sub_b
 	btfsc	neg_flag
-	bra		acivate_safety_stop			; Above 5m, activate safety stop
-	bra		reset_safety_stop2			; Pause safety stop
+	bra		acivate_safety_stop			; above 5m, activate safety stop
+	bra		reset_safety_stop2			; pause safety stop
 
 acivate_safety_stop:
-	tstfsz	safety_stop_countdown		; Countdown at zero?
-	bsf		show_safety_stop			; No, Set flag!
+	tstfsz	safety_stop_countdown		; countdown at zero?
+	bsf		show_safety_stop			; NO - set flag
 	return
 
 delete_safety_stop:
 	clrf	safety_stop_countdown		; reset timer
-	bra		reset_safety_stop2			; Remove safety stop from display
+	bra		reset_safety_stop2			; remove safety stop from display
 
 reset_safety_stop:
 	movff	opt_safety_stop_length,safety_stop_countdown ; reset timer
 reset_safety_stop2:
-	bcf		show_safety_stop			; Clear flag
-	btfss	safety_stop_active			; Safety stop shown
-	return								; No, don't delete it
-	bcf		safety_stop_active			; Clear flag
+	bcf		show_safety_stop			; clear flag
+	btfss	safety_stop_active			; safety stop shown?
+	return								; NO - don't delete it
+	bcf		safety_stop_active			; clear flag
 	bsf		FLAG_TFT_clear_safety_stop	; Clear safety stop
 	return
 
@@ -1023,27 +1070,28 @@
 ;=============================================================================
 
 timeout_menuview:
-	decfsz	timeout_counter2,F			; timeout for menuview
-	return								; No timeout, return
+	decfsz	timeout_counter2,F			; timeout for menu view?
+	return								; NO - done
 	; Timeout, clear e.g. "Menu?"
-	goto	menuview_toggle_reset		; "returns"
+	goto	menuview_toggle_reset		; ...and return
 
 timeout_divemode_menu:
 	decfsz	timeout_counter2,F			; timeout for divemode menu
 	return
 
 	global	timeout_divemode_menu2
-timeout_divemode_menu2:					; Called from divemenu_tree.asm
-	bcf		divemode_menu				; Timeout! Clear flag
-	call	TFT_clear_divemode_menu		; Clear menu
-	bsf		FLAG_TFT_active_gas_divemode; Redraw gas/setpoint/diluent
-	bcf		blinking_better_gas			; Clear flag to have temperature updated once
-	bsf		FLAG_TFT_temp_divemode		; Displays temperature
-	call	TFT_draw_gassep_line		; Gas separator grid in spec mode only
-
-	btfss	decostop_active				; In deco mode ?
-	bra		timeout_divemode_menu_ndl	; No, show NDL again
-	; Show deco
+timeout_divemode_menu2:					; called from divemenu_tree.asm
+	bcf		divemode_menu				; timeout, clear flag
+	call	TFT_clear_divemode_menu		; clear menu
+	bsf		FLAG_TFT_active_gas_divemode; redraw gas/setpoint/diluent
+	bcf		blinking_better_gas			; clear flag to have temperature updated once
+	bcf		blinking_better_dil			; clear flag to have temperature updated once
+	bsf		FLAG_TFT_temp_divemode		; display temperature
+	call	TFT_draw_gassep_line		; gas separator grid in spec mode only
+
+	btfss	decostop_active				; in deco mode ?
+	bra		timeout_divemode_menu_ndl	; NO - show NDL again
+	; Show deco data
 	bsf		FLAG_TFT_display_deko_mask
 	bsf		FLAG_TFT_display_deko
 	bsf		FLAG_TFT_display_tts
@@ -1056,37 +1104,37 @@
 	return
 
 timeout_divemode:
-	btfsc	divemode_menu				; Divemode menu active?
-	rcall	timeout_divemode_menu		; Yes, check the timeout for it...
-
-	btfsc	menuview					; is a menuview shown?
-	rcall	timeout_menuview			; Yes, check the timeout for it...
-
-	btfss	realdive					; Dive longer then one minute
-	return
-
-	btfsc	FLAG_apnoe_mode				; In Apnoe mode?
-	bra		timeout_divemode2			; Yes, use apnoe_timeout [min] for timeout
-
-	ifndef __DEBUG
-		btfsc	simulatormode_active	; In Simulator mode?
-		bra		timeout_divemode3		; Yes, use simulator timeout
-	endif
-
-	bcf		divemode
-	infsnz	timeout_counter1+0,F
+	btfsc	divemode_menu				; divemode menu active?
+	rcall	timeout_divemode_menu		; YES - check the timeout for it...
+
+	btfsc	menuview					; is a menu view shown?
+	rcall	timeout_menuview			; YES - check the timeout for it...
+
+	btfss	realdive					; dive longer than one minute?
+	return								; NO  - done
+
+	btfsc	FLAG_apnoe_mode				; in apnoe mode?
+	bra		timeout_divemode2			; YES - use apnoe_timeout [min] for timeout
+
+ IFNDEF __DEBUG
+	btfsc	simulatormode_active		; in simulator mode?
+	bra		timeout_divemode3			; YES - use simulator timeout
+ ENDIF
+
+	bcf		divemode					; terminate divemode my default
+	infsnz	timeout_counter1+0,F		; increment timeout counter
 	incf	timeout_counter1+1,F		; timeout is 16 bit counter
 
-	movff	opt_diveTimeout,WREG		; in [min]
-	mullw	.60
+	movff	opt_diveTimeout,WREG		; get timeout in minutes
+	mullw	.60							; convert into seconds
 	movff	PRODL,sub_a+0
-	movff	PRODH,sub_a+1				; in [s]
+	movff	PRODH,sub_a+1
 
 	movff	timeout_counter1+0,sub_b+0
 	movff	timeout_counter1+1,sub_b+1
 	call	subU16						; sub_c = sub_a - sub_b
-	btfss	neg_flag					; Result negative?
-	bsf		divemode					; No, set flag
+	btfss	neg_flag					; result negative, i.e. timeout?
+	bsf		divemode					; NO - set divemode flag again
 	return
 
 timeout_divemode2:
@@ -1113,36 +1161,59 @@
 
 update_divemode60:						; update any minute
 	call	get_battery_voltage			; gets battery voltage
-	rcall	set_powersafe				; Battery low?
-	call	customview_minute			; Do every-minute tasks for the custom view area
+	rcall	set_powersafe				; check if battery low
+	;call	customview_minute			; do every-minute tasks for the custom view area
 	bcf		oneminupdate
-
+ IFDEF _cave_mode
+	movlw	.1							; prepare to add backtrack data for 1 minute
+	btfsc	FLAG_cave_mode				; cave mode enabled?
+	rcall	update_backtrack			; YES - make it so
+ ENDIF
 	btfss	simulatormode_active		; in simulator mode?
-	return								; No
-	; Yes, quite dive mode simulation after 21*256s=89min:36s
-	movlw	.20
-	cpfsgt	total_divetime_seconds+1	; Timeout?
-	return								; No
-
-	ifdef __DEBUG
-		return							; No simulator timeout in debug mode
-	endif
-
-	bra		divemode_option1			; Yes, set to 0m and "return"
+	return								; NO  - done
+	movlw	.20							; YES - quite dive mode simulation after 21 * 256 sec = 89 min : 36 sec
+	cpfsgt	total_divetime_seconds+1	; timeout?
+	return								; NO  - done
+ IFDEF __DEBUG
+	return								; YES -  but no timeout in debug mode
+ ENDIF
+	bra		divemode_option1			; YES - set depth to 0 m and "return"
+
+ IFDEF _cave_mode
+update_backtrack:
+	btfsc	FLAG_dive_turned			; dive turned?
+	return								; YES - done
+	movwf	lo							; store minutes to add in lo
+	lfsr	FSR1,char_I_backtrack_depth ; load FSR1 with base address of backtrack storage
+	movff	char_I_backtrack_time,FSR1L	; adjust FSR1 to last index
+update_backtrack_loop:
+	btfsc	FLAG_cave_mode_shutdown		; backtrack storage full?
+	return								; YES - done
+	movff	curr_depth,PREINC1			; NO  - increment index and write current depth to backtrack storage
+	incfsz	FSR1L,W						;     - did a wrap-around of the index occur (backtrack storage full)?
+	bra		update_backtrack_loop_1		;       NO  - continue loop
+	bsf		FLAG_cave_mode_shutdown		;       YES - flag backtrack storage as being full
+	return
+update_backtrack_loop_1:
+	decfsz	lo,F						; decrement loop counter, did it became zero?
+	bra		update_backtrack_loop		; NO  - loop
+	movff	FSR1L,char_I_backtrack_time	; YES - read-back index
+	return								;     - done
+ ENDIF
 
 set_max_depth:
 	movff	max_pressure+0,sub_a+0
 	movff	max_pressure+1,sub_a+1
 	SAFE_2BYTE_COPY rel_pressure, sub_b
 	call	subU16						; sub_c = sub_a - sub_b
-										; max_pressure<rel_pressure -> neg_flag=1
-										; rel_pressure<=max_pressure -> neg_flag=0
+										; max_pressure <  rel_pressure -> neg_flag=1
+										; rel_pressure <= max_pressure -> neg_flag=0
 	btfss	neg_flag
 	return
-										; max_pressure<rel_pressure
+										; max_pressure < rel_pressure
 	movff	sub_b+0,max_pressure+0
 	movff	sub_b+1,max_pressure+1
-	bsf		FLAG_TFT_max_depth			; Set flag
+	bsf		FLAG_TFT_max_depth			; set flag
 	return
 
 set_min_temp:
@@ -1150,8 +1221,8 @@
 	movff	minimum_temperature+1,sub_a+1
 	SAFE_2BYTE_COPY temperature,sub_b
 	call	sub16						; sub_c = sub_a - sub_b
-										; minimum_temperature<T -> neg_flag=1
-										; T<=minimum_temperature -> neg_flag=0
+										; minimum_temperature < T  -> neg_flag=1
+										; T <= minimum_temperature -> neg_flag=0
 	btfsc	neg_flag
 	return
 	; minimum_temperature >= T
@@ -1161,8 +1232,8 @@
 
 	global	set_dive_modes
 set_dive_modes:
-	btfsc	high_altitude_mode			; In high altitude (Fly) mode?
-	bra		set_dive_modes3				; Yes!
+	btfsc	high_altitude_mode			; in high altitude (fly) mode?
+	bra		set_dive_modes3				; YES
 
 set_dive_modes0:
 	movlw	LOW  start_dive_threshold
@@ -1177,23 +1248,22 @@
 	btfss	neg_flag
 	bra		set_dive_modes2				; too shallow (rel_pressure < dive_threshold)
 
-	btfsc	realdive					; Dive longer than one minute?
-	clrf	timeout_counter1+0			; Yes, reset timeout counter +++
-
-	bsf		divemode					; (Re-)Set divemode flag
+	btfsc	realdive					; dive longer than one minute?
+	clrf	timeout_counter1+0			; YES - reset timeout counter
+
+	bsf		divemode					; (re-)set divemode flag
 	bsf		divemode2					; displayed divetime is running
 	return
 
 set_dive_modes2:
-	bcf		divemode2					; Stop time
+	bcf		divemode2					; stop time
 	btfss	realdive					; dive longer then one minute?
-	bcf		divemode					; no -> this was no real dive
-	return								; No, return
-
-
-set_dive_modes3:						; High-altitude mode
+	bcf		divemode					; NO  - this was no real dive
+	return								; YES - return
+
+set_dive_modes3:						; high-altitude mode
 	btfsc	realdive					; dive longer then one minute?
-	bra		set_dive_modes0				; Yes -> this is a real dive -> Use start_dive_threshold or ascend
+	bra		set_dive_modes0				; YES - this is a real dive -> Use start_dive_threshold or ascend
 
 	movlw	LOW  high_altitude_dive_threshold
 	movwf	sub_a+0
@@ -1206,181 +1276,181 @@
 	cpfslt	batt_percent
 	return
 
-	movlw	d'7'						; Type of Alarm (Battery Low)
-	movwf	AlarmType					; Copy to Alarm Register
+	movlw	d'7'						; type of alarm (battery Low)
+	movwf	AlarmType					; copy to alarm register
 	bsf		event_occured				; set event flag
 	movlw	.0
-	movff	WREG,opt_brightness			; Set Brightness to ECO
+	movff	WREG,opt_brightness			; set brightness to ECO
 	return								; return
 
+
+reset_average:
+	bcf		reset_average_depth			; clear reset-average flag
+	clrf	average_depth_hold+0		; clear the depth accumulator
+	clrf	average_depth_hold+1		; ...
+	clrf	average_depth_hold+2		; ...
+	clrf	average_depth_hold+3		; ...
+	clrf	average_divesecs+0			; clear the time accumulator
+	clrf	average_divesecs+1			; ...
+	SAFE_2BYTE_COPY rel_pressure,avg_rel_pressure ; prime result with current rel.pressure/depth
+	return
+
+
 calc_average_depth:
-	btfsc	reset_average_depth			; Reset the Average depth?
-	rcall	reset_average1				; Reset the resettable average depth
-
-	; 1. Add new 2xdepth to the Sum of depths registers
-	SAFE_2BYTE_COPY rel_pressure,xB		; Buffer...
+	; 1. compute rel_pressure x 2, because this routine is called every 2nd second only
+	SAFE_2BYTE_COPY rel_pressure,xB		; copy current rel pressure to xB
 	bcf		STATUS,C
-	rlcf	xB+0,F
-	rlcf	xB+1,F						; x2
-
-	movf	xB+0,w
+	rlcf	xB+0,F						; multiply rel pressure x 2 (via shift left)
+	rlcf	xB+1,F						; ...
+
+	; 2a add (rel_pressure x 2) to the resettable depth accumulator
+	movf	xB+0,W
 	addwf	average_depth_hold+0,F
-	movf	xB+1,w
+	movf	xB+1,W
 	addwfc	average_depth_hold+1,F
-	movlw	d'0'
+	movlw	.0
 	addwfc	average_depth_hold+2,F
-	addwfc	average_depth_hold+3,F		; Will work up to 9999mbar*60*60*24=863913600mbar
-
-	; Do the same for the _total registers (Non-Resettable)
-	movf	xB+0,w
+	addwfc	average_depth_hold+3,F			; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth)
+
+	; 2b add (rel_pressure x 2) to the total depth accumulator
+	movf	xB+0,W
 	addwf	average_depth_hold_total+0,F
-	movf	xB+1,w
+	movf	xB+1,W
 	addwfc	average_depth_hold_total+1,F
-	movlw	d'0'
+	movlw	.0
 	addwfc	average_depth_hold_total+2,F
-	addwfc	average_depth_hold_total+3,F; Will work up to 9999mbar*60*60*24=863913600mbar
-
-	; 2. Compute Average Depth on base of average_divesecs:2
-	movff	average_divesecs+0,xB+0
-	movff	average_divesecs+1,xB+1		; Copy
+	addwfc	average_depth_hold_total+3,F	; will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth)
+
+	; 3a compute avg_rel_pressure on base of average_divesecs:2
 	movff	average_depth_hold+0,xC+0
 	movff	average_depth_hold+1,xC+1
 	movff	average_depth_hold+2,xC+2
-	movff	average_depth_hold+3,xC+3
-
-	call	div32x16					; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
+	movff	average_depth_hold+3,xC+3		; copy accumulated depth
+	movff	average_divesecs+0,xB+0
+	movff	average_divesecs+1,xB+1			; copy accumulated time
+	call	div32x16						; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
 	movff	xC+0,avg_rel_pressure+0
-	movff	xC+1,avg_rel_pressure+1
-
-	btfss	divemode2					; displayed divetime is running?
-	return								; No (e.g. too shallow)
-
-	; 3. Compute Total Average Depth on base of total_divetime_seconds:2
-	movff	total_divetime_seconds+0,xB+0
-	movff	total_divetime_seconds+1,xB+1	; Copy
+	movff	xC+1,avg_rel_pressure+1			; store result
+
+	btfss	divemode2						; displayed divetime is running?
+	return									; NO (e.g. too shallow)
+
+	; 3b compute avg_rel_pressure_total on base of average_divesecs_total:2
 	movff	average_depth_hold_total+0,xC+0
 	movff	average_depth_hold_total+1,xC+1
 	movff	average_depth_hold_total+2,xC+2
-	movff	average_depth_hold_total+3,xC+3
-	call	div32x16					; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
+	movff	average_depth_hold_total+3,xC+3	; copy accumulated depth
+	movff	average_divesecs_total+0,xB+0
+	movff	average_divesecs_total+1,xB+1	; copy accumulated time
+	call	div32x16						; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
 	movff	xC+0,avg_rel_pressure_total+0
-	movff	xC+1,avg_rel_pressure_total+1
+	movff	xC+1,avg_rel_pressure_total+1	; store result
+
+	btfsc	reset_average_depth				; reset the resettable average depth?
+	rcall	reset_average					; YES - reset the resettable average depth
+
+	TSTOSS	opt_2ndDepthDisp				; drawing avg depth instead of max depth?
+	return									; NO  - done
+	bsf		FLAG_TFT_max_depth				; YES - flag to update display
 	return
 
-reset_average1:
-	clrf	average_depth_hold+0
-	clrf	average_depth_hold+1
-	clrf	average_depth_hold+2
-	clrf	average_depth_hold+3		; Clear average depth register
-	movlw	d'2'
-	movwf	average_divesecs+0
-	clrf	average_divesecs+1
-	bcf		reset_average_depth			; Clear flag
-	return
-
-test_switches_divemode:					; checks switches in divemode
-	btfsc	divemode_menu				; Divemode menu shown?
-	bra		test_switches_divemode_menu	; Yes, use menu processor
-	btfsc	switch_left
-	;bra	test_switches_divemode2		; Enter button pressed, check if we need to do something
-	goto	menuview_toggle				; Menu or Simulator tasks; and return...
-	btfss	switch_right
-	return								; No button press
-	tstfsz	menupos2					; any option shown?
-	bra		test_switches_divemode1		; Yes, do option tasks
-	bsf		toggle_customview			; No, toggle custom view
-	return
+
+test_switches_divemode:						; checks switches in divemode
+	btfsc	divemode_menu					; divemode menu shown?
+	bra		test_switches_divemode_menu		; YES - use menu processor
+	btfsc	switch_left						; NO  - left button pressed?
+	goto	menuview_toggle					;       YES - menu or simulator tasks; and return...
+	btfss	switch_right					;       NO  - right button pressed?
+	return									;             NO  - done
+	tstfsz	menupos2						;             YES - any option shown?
+	bra		test_switches_divemode1			;                   YES - do option tasks
+	bsf		toggle_customview				;                   NO  - toggle custom view
+	return									;                       - done
 
 test_switches_divemode_menu:
 	btfsc	switch_left
-	bra		test_switches_divemode_menu2; Move cursor
-	btfsc	switch_right
-	bra		test_switches_divemode_menu3; Enter submenu or do something
-	return								; No button press
+	bra		test_switches_divemode_menu2	; move cursor
+	btfsc	switch_right					; left button pressed?
+	bra		test_switches_divemode_menu3	; YES - enter submenu or do something
+	return									; NO  - done
 
 test_switches_divemode_menu1:
 	clrf	menupos1
 test_switches_divemode_menu2:
 	incf	menupos1,F
-	incf	menupos4,W					; menupos4+1 -> WREG
-	cpfslt	menupos1					; > menupos4 (Set in menu_processor.asm)?
-	bra		test_switches_divemode_menu1; > Yes, set to 1
-	call	TFT_divemode_menu_cursor	; Update the cursor
+	incf	menupos4,W						; menupos4 + 1 -> WREG
+	cpfslt	menupos1						; > menupos4 (set in menu_processor.asm)?
+	bra		test_switches_divemode_menu1	; YES - set to 1
+	call	TFT_divemode_menu_cursor		; update the cursor
 	bcf		switch_left
-	movlw	divemode_menu_timeout		; Reload timeout
-	movwf	timeout_counter2			; timeout for divemode menu
+	movlw	divemode_menu_timeout			; reload timeout
+	movwf	timeout_counter2				; timeout for divemode menu
 	return
 
-test_switches_divemode_menu3:			; Enter submenu or do something
+test_switches_divemode_menu3:			; enter submenu or do something
 	bcf		switch_right
 ;	decf	menupos1,F					; menu_processor needs 0-5...
-	goto	do_line_menu				; Warning! Trashes STKPTR and returns to diveloop_loop4:
+	goto	do_line_menu				; Warning! trashes STKPTR and returns to diveloop_loop4:
 
 test_switches_divemode1:
 	bcf		switch_right
 	movlw	divemode_menuview_timeout
-	movwf	timeout_counter2			; Reload timeout
+	movwf	timeout_counter2			; reload timeout
 	movff	menupos2,WREG				; menupos2 holds number of customview/divemode menu function
 	dcfsnz	WREG,F
-	bra		divemode_option_gaschange	; Switch to the indicated "better gas"
+	bra		divemode_option_gaschange	; switch to the the "better gas" / "better diluent"
 	dcfsnz	WREG,F
-	bra		divemode_option0			; Start/Setup Divemode menu
+	bra		divemode_option0			; start/setup Divemode menu
 	dcfsnz	WREG,F
-	bra		divemode_option1			; Quit Simulation?
+	bra		divemode_option1			; quit simulation?
 	dcfsnz	WREG,F
-	bra		divemode_option2			; Descent 1m
+	bra		divemode_option2			; descent 1m
 	dcfsnz	WREG,F
-	bra		divemode_option3			; Ascend 1m
+	bra		divemode_option3			; ascend 1m
 	dcfsnz	WREG,F
-	bra		divemode_option4			; Quit Apnoe mode
+	bra		divemode_option4			; quit Apnoe mode
 	dcfsnz	WREG,F
-	bra		divemode_option5			; Reset Stopwatch (In Gauge mode)
+	bra		divemode_option5			; reset stopwatch (gauge mode only)
 	dcfsnz	WREG,F
 	bra		divemode_option6			; +5mins simulation
 	dcfsnz	WREG,F
-	bra		divemode_option7			; Store heading
+	bra		divemode_option7			; store heading
 	dcfsnz	WREG,F
-	bra		divemode_option8			; Switch to alt. layout
+	bra		divemode_option8			; switch to alternative layout
 	return
 
 gas_switched_common:
-	bcf		divemode_gaschange			; Clear flag
+	bcf		divemode_gaschange			; clear flag
 	btfss	FLAG_back_to_loop			; check if it is a switchback from OC bailout to loop
 	bra		gas_switched_common0		; NO  - continue with checking if selected gas is valid
 	bcf		FLAG_back_to_loop			; YES - clear flag
-	movff	active_diluent,menupos1		;       reload last diluent
+	movff	active_dil,menupos1			;       reload last diluent
 	bra		gas_switched_common1		;       continue with common part
 gas_switched_common0:
-	tstfsz	menupos1					; menupos1=0?
+	tstfsz	menupos1					; menupos1 = 0 ?
 	bra		gas_switched_common1		; NO  - valid gas
 	return								; YES - something went wrong, invalid gas, abort
 gas_switched_common1:
 	movf	menupos1,W					; get selected gas into WREG (1-6)
-
-	btfsc	FLAG_ccr_mode				; in CCR mode?
-	bra		gas_switched_common2		; YES - configure diluent or bailout
-	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	bra		gas_switched_common2		; YES - configure diluent or bailout
-
-	; OC
-	rcall	setup_gas_registers			; With WREG = Gas 1-6
-	rcall	deco_setup_oc_gases			; With WREG = Gas 1-6
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		gas_switched_common_OC		; YES
+	btfsc	FLAG_bailout_mode			; in bailout?
+	bra		gas_switched_common_OC		; YES
+gas_switched_common_loop:				; NO to both - must be loop mode then
+	rcall	setup_dil_registers			; with WREG = diluent 1-6
+	rcall	deco_setup_cc_diluents		; with WREG = diluent 1-6
 	bra		gas_switched_common3
-
-	; loop or bailout
-gas_switched_common2:
-	rcall	setup_dil_registers			; With WREG = diluent 1-6, in case of is_bailout reverts to OC gases
-	rcall	deco_setup_cc_diluents		; With WREG = diluent 1-6, in case of is_bailout reverts to OC gases
-
+gas_switched_common_OC:
+	rcall	setup_gas_registers			; with WREG = Gas 1-6
+	rcall	deco_setup_oc_gases			; with WREG = Gas 1-6
 gas_switched_common3:
-	bsf		FLAG_TFT_active_gas_divemode	; Redraw gas/setpoint/diluent
+	bsf		FLAG_TFT_active_gas_divemode	; redraw gas/setpoint/diluent
 	call	restart_deco_engine_wo_ceiling	; abort any running deco calculations and restart the deco engine
-
-	; Set flags for profile recording
+	; set flags for profile recording
 	bsf		event_occured				; set event flag
-	btfsc	is_bailout					; Choose OC Bailouts (OC Gases)
-	bsf		bailoutgas_event			; Bailout gas change
-	btfss	is_bailout					; Choose OC Bailouts (OC Gases)
+	btfsc	FLAG_bailout_mode			; choose OC Bailouts (OC Gases)
+	bsf		bailoutgas_event			; bailout gas change
+	btfss	FLAG_bailout_mode			; choose OC Bailouts (OC Gases)
 	bsf		stored_gas_changed			; OC gas change
 	return
 
@@ -1388,165 +1458,130 @@
 ; Code to pass all parameters to the C code
 
 	global	get_first_gas_to_WREG
-get_first_gas_to_WREG:					; Gets first gas (1-5) into WREG
-	lfsr	FSR1,opt_gas_type			; Point to gas types
-	clrf	lo							; start with Gas0
+get_first_gas_to_WREG:					; gets first gas (1-5) into WREG
+	lfsr	FSR1,opt_gas_type			; point to gas types
+	clrf	lo							; start with gas 0
 get_first_gas_to_WREG2:
 	movf	lo,W
-	movf	PLUSW1,W					; Get Type of Gas #lo
+	movf	PLUSW1,W					; get type of gas #lo
 	sublw	.1							; it is = 1 (First Gas)
-	bz		get_first_gas_to_WREG3		; Found the first gas!
+	bz		get_first_gas_to_WREG3		; found the first gas!
 	incf	lo,F						; ++
 	movlw	NUM_GAS+1
-	cpfseq	lo							; All done?
-	bra		get_first_gas_to_WREG2		; Not yet
-	; No first gas found, use #1
+	cpfseq	lo							; all done?
+	bra		get_first_gas_to_WREG2		; NO - not yet
+	; no first gas found, use #1
 	movlw	.0
-	movff	WREG,opt_gas_type+0			; Set Gas1 to First
+	movff	WREG,opt_gas_type+0			; set gas 1 to First
 	incf	WREG,W						; 0 -> 1
 	return
 get_first_gas_to_WREG3:
-	movf	lo,W						; Put into Wreg
+	movf	lo,W						; put into WREG
 	incf	WREG,W						; 0-4 -> 1-5
-	return								; Done
+	return								; done
 
 	global	get_first_dil_to_WREG
-get_first_dil_to_WREG:					; Gets first dil (1-5) into WREG
-	lfsr	FSR1,opt_dil_type			; Point to dil types
-	clrf	lo							; start with Gas0
+get_first_dil_to_WREG:					; gets first dil (1-5) into WREG
+	lfsr	FSR1,opt_dil_type			; point to dil types
+	clrf	lo							; start with dil 0
 get_first_dil_to_WREG2:
 	movf	lo,W
-	movf	PLUSW1,W					; Get Type of Dil #lo
+	movf	PLUSW1,W					; get type of Dil #lo
 	sublw	.1							; it is = 1 (First Dil)
-	bz		get_first_dil_to_WREG3		; Found the first dil!
+	bz		get_first_dil_to_WREG3		; found the first dil!
 	incf	lo,F						; ++
 	movlw	NUM_GAS+1
-	cpfseq	lo							; All done?
-	bra		get_first_dil_to_WREG2		; Not yet
-	; No first dil found, use #1
+	cpfseq	lo							; all done?
+	bra		get_first_dil_to_WREG2		; NO - not yet
+	; no first dil found, use #1
 	movlw	.0
-	movff	WREG,opt_dil_type+0			; Set Dil1 to First
+	movff	WREG,opt_dil_type+0			; set dil 1 to First
 	incf	WREG,W						; 0 -> 1
 	return
 get_first_dil_to_WREG3:
-	movf	lo,W						; Put into Wreg
+	movf	lo,W						; Put into WREG
 	incf	WREG,W						; 0-4 -> 1-5
-	return								; Done
-
-	global	deco_setup_oc_gases
+	return								; done
+
+
 deco_setup_oc_gases:					; with currently breathed gas in WREG (1-5 or 6)
-	movff	WREG,char_I_current_gas		; gas to start with when doing the deco calculations
-
-	banksel	opt_gas_type				; opt_gas_type[] and opt_OC_bail_gas_change[] are together in bank common2
-
-	movff	opt_gas_He_ratio+0,char_I_deco_He_ratio+0
-	movff	opt_gas_O2_ratio+0,char_I_deco_O2_ratio+0
-
-	movlw	.3							; 3=Deco
-	cpfseq	opt_gas_type+0				; Gas is deco type?
-	clrf	opt_OC_bail_gas_change+0	; No, clear depth for 0=Disabled, 1=First and 2=Travel
-
-	movff	opt_gas_He_ratio+1,char_I_deco_He_ratio+1
-	movff	opt_gas_O2_ratio+1,char_I_deco_O2_ratio+1
-	movlw	.3							; 3=Deco
-	cpfseq	opt_gas_type+1				; Gas is deco type?
-	clrf	opt_OC_bail_gas_change+1	; No, clear depth for 0=Disabled, 1=First and 2=Travel
-
-	movff	opt_gas_He_ratio+2,char_I_deco_He_ratio+2
-	movff	opt_gas_O2_ratio+2,char_I_deco_O2_ratio+2
-	movlw	.3							; 3=Deco
-	cpfseq	opt_gas_type+2				; Gas is deco type?
-	clrf	opt_OC_bail_gas_change+2	; No, clear depth for 0=Disabled, 1=First and 2=Travel
-
-	movff	opt_gas_He_ratio+3,char_I_deco_He_ratio+3
-	movff	opt_gas_O2_ratio+3,char_I_deco_O2_ratio+3
-	movlw	.3							; 3=Deco
-	cpfseq	opt_gas_type+3				; Gas is deco type?
-	clrf	opt_OC_bail_gas_change+3	; No, clear depth for 0=Disabled, 1=First and 2=Travel
-
-	movff	opt_gas_He_ratio+4,char_I_deco_He_ratio+4
-	movff	opt_gas_O2_ratio+4,char_I_deco_O2_ratio+4
-	movlw	.3							; 3=Deco
-	cpfseq	opt_gas_type+4				; Gas is deco type?
-	clrf	opt_OC_bail_gas_change+4	; No, clear depth for 0=Disabled, 1=First and 2=Travel
-
-	banksel common
-
-	; Setup char_I_deco_gas_change array
-	movff	opt_OC_bail_gas_change+0, char_I_deco_gas_change+0
-	movff	opt_OC_bail_gas_change+1, char_I_deco_gas_change+1
-	movff	opt_OC_bail_gas_change+2, char_I_deco_gas_change+2
-	movff	opt_OC_bail_gas_change+3, char_I_deco_gas_change+3
-	movff	opt_OC_bail_gas_change+4, char_I_deco_gas_change+4
-
-	; switch to oc mode
 	movff	char_O_deco_status,lo		; working copy of char_O_deco_status in bank common
+deco_setup_oc_gases_pre:				; entry point with lo preloaded
+	movff	WREG,char_I_current_gas		; set gas to start with when doing the deco calculations
+	;
+	; Memory Map:
+	; ---------------------------------------------------------------------------------
+	; opt_gas_O2_ratio		res NUM_GAS		|	char_I_deco_O2_ratio		res NUM_GAS
+	; opt_dil_O2_ratio		res NUM_GAS		|
+	; opt_gas_He_ratio		res NUM_GAS		|	char_I_deco_He_ratio		res NUM_GAS
+	; opt_dil_He_ratio		res NUM_GAS		|
+	; opt_gas_type			res NUM_GAS		|	char_I_deco_gas_type		res NUM_GAS
+	; opt_dil_type			res NUM_GAS		|
+	; opt_gas_change		res NUM_GAS		|	char_I_deco_gas_change		res NUM_GAS
+	; opt_dil_change		res NUM_GAS		|
+	;
+	lfsr	FSR2,char_I_deco_O2_ratio	; Load FSR2 with base address of char_I_deco_O2_ratio.
+										; FSR2 will step through all char_I_deco_... vars.
+	lfsr	FSR1,opt_gas_O2_ratio		; load FSR1 with base address of opt_gas_O2_ratio
+	rcall	deco_setup_copy				; copy all OC O2 ratios
+	lfsr	FSR1,opt_gas_He_ratio		; load FSR1 with base address of opt_gas_He_ratio
+	rcall	deco_setup_copy				; copy all OC He ratios
+	lfsr	FSR1,opt_gas_type			; load FSR1 with base address of opt_gas_type
+	rcall	deco_setup_copy				; copy all gas types
+	lfsr	FSR1,opt_gas_change			; load FSR1 with base address of opt_gas_change
+	rcall	deco_setup_copy				; copy all gas change depths
+										; switch to oc mode
 	bcf		lo,DECO_MODE_PSCR_FLAG		; clear the pSCR-mode flag (may not be set, but never mind)
 	bcf		lo,DECO_MODE_LOOP_FLAG		; clear the loop/CCR-mode flag
 	movff	lo,char_O_deco_status		; bank safe write-back of char_O_deco_status
-
 	return
 
 
-	global	deco_setup_cc_diluents
-deco_setup_cc_diluents:					; with currently breathed gas in WREG (1-5 or 6)
-	btfsc	is_bailout					; check if in bailout condition
-	bra		deco_setup_oc_gases			; revert to setting up OC gases in bailout condition
-
-	movff	WREG,char_I_current_gas		; gas to start with when doing the deco calculations
-
-	movff	opt_dil_He_ratio+0,char_I_deco_He_ratio+0
-	movff	opt_dil_O2_ratio+0,char_I_deco_O2_ratio+0
-	movff	opt_dil_type+0,WREG			; 0=Disabled, 1=First, 2=Normal
-	tstfsz	WREG						; Disabled?
-	bra		$+4							; No
-	movff	WREG,char_I_dil_change+0	; Yes, clear char_I_deco_gas_change (Bank safe)
-
-	movff	opt_dil_He_ratio+1,char_I_deco_He_ratio+1
-	movff	opt_dil_O2_ratio+1,char_I_deco_O2_ratio+1
-	movff	opt_dil_type+1,WREG			; 0=Disabled, 1=First, 2=Normal
-	tstfsz	WREG						; Disabled?
-	bra		$+4							; No
-	movff	WREG,char_I_dil_change+1	; Yes, clear char_I_dil_change
-
-	movff	opt_dil_He_ratio+2,char_I_deco_He_ratio+2
-	movff	opt_dil_O2_ratio+2,char_I_deco_O2_ratio+2
-	movff	opt_dil_type+2,WREG			; 0=Disabled, 1=First, 2=Normal
-	tstfsz	WREG						; Disabled?
-	bra		$+4							; No
-	movff	WREG,char_I_dil_change+2	; Yes, clear char_I_dil_change
-
-	movff	opt_dil_He_ratio+3,char_I_deco_He_ratio+3
-	movff	opt_dil_O2_ratio+3,char_I_deco_O2_ratio+3
-	movff	opt_dil_type+3,WREG			; 0=Disabled, 1=First, 2=Normal
-	tstfsz	WREG						; Disabled?
-	bra		$+4							; No
-	movff	WREG,char_I_dil_change+3	; Yes, clear char_I_dil_change
-
-	movff	opt_dil_He_ratio+4,char_I_deco_He_ratio+4
-	movff	opt_dil_O2_ratio+4,char_I_deco_O2_ratio+4
-	movff	opt_dil_type+4,WREG			; 0=Disabled, 1=First, 2=Normal
-	tstfsz	WREG						; Disabled?
-	bra		$+4							; No
-	movff	WREG,char_I_dil_change+4	; Yes, clear char_I_dil_change
-
-	; Setup char_I_deco_gas_change array
-	movff	char_I_dil_change+0, char_I_deco_gas_change+0
-	movff	char_I_dil_change+1, char_I_deco_gas_change+1
-	movff	char_I_dil_change+2, char_I_deco_gas_change+2
-	movff	char_I_dil_change+3, char_I_deco_gas_change+3
-	movff	char_I_dil_change+4, char_I_deco_gas_change+4
-
-	; switch to CCR / pSCR mode
+deco_setup_cc_diluents:					; with currently breathed diluent in WREG (1-5 or 6)
 	movff	char_O_deco_status,lo		; working copy of char_O_deco_status in bank common
+deco_setup_cc_diluents_pre:				; entry point with lo preloaded
+	btfsc	FLAG_bailout_mode			; check if in bailout condition       | --------------- FOR SAFETY ONLY --------------
+	bra		deco_setup_oc_gases_pre		; YES - revert to setting up OC gases | This branch should never happen to be taken...
+	movff	WREG,char_I_current_gas		; NO  - set diluent to start with when doing the deco calculations
+	;
+	; Memory Map:
+	; ---------------------------------------------------------------------------------
+	; opt_gas_O2_ratio		res NUM_GAS		|
+	; opt_dil_O2_ratio		res NUM_GAS		|	char_I_deco_O2_ratio		res NUM_GAS
+	; opt_gas_He_ratio		res NUM_GAS		|
+	; opt_dil_He_ratio		res NUM_GAS		|	char_I_deco_He_ratio		res NUM_GAS
+	; opt_gas_type			res NUM_GAS		|
+	; opt_dil_type			res NUM_GAS		|	char_I_deco_gas_type		res NUM_GAS
+	; opt_gas_change		res NUM_GAS		|
+	; opt_dil_change		res NUM_GAS		|	char_I_deco_gas_change		res NUM_GAS
+	;
+	lfsr	FSR2,char_I_deco_O2_ratio	; Load FSR2 with base address of char_I_deco_O2_ratio.
+										; FSR2 will step through all char_I_deco_... vars.
+	lfsr	FSR1,opt_dil_O2_ratio		; load FSR1 with base address of opt_dil_O2_ratio
+	rcall	deco_setup_copy				; copy all dil O2 ratios
+	lfsr	FSR1,opt_dil_He_ratio		; load FSR1 with base address of opt_dil_He_ratio
+	rcall	deco_setup_copy				; copy all dil He ratios
+	lfsr	FSR1,opt_dil_type			; load FSR1 with base address of opt_dil_type
+	rcall	deco_setup_copy				; copy all dil types
+	lfsr	FSR1,opt_dil_change			; load FSR1 with base address of opt_dil_change
+	rcall	deco_setup_copy				; copy all dil change depths
+										; switch to CCR / pSCR mode
 	bsf		lo,DECO_MODE_LOOP_FLAG		; loop flag is set in both, CCR and pSCR mode
 	bcf		lo,DECO_MODE_PSCR_FLAG		; clear pSCR mode flag by default
 	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
 	bsf		lo,DECO_MODE_PSCR_FLAG		; YES - set additional flag for pSCR mode
-	movff	lo,char_O_deco_status		; bank safe write-back of char_O_deco_status	
-
+	movff	lo,char_O_deco_status		; bank safe write-back of char_O_deco_status
 	return
 
+deco_setup_copy:
+	movlw	NUM_GAS						; load loop counter with number of gases (5)
+deco_setup_copy_loop:
+	movff	POSTINC1,POSTINC2			; copy from (FSR1) to (FSR2)
+	decfsz	WREG						; decrement loop counter and check if it became 0
+	bra		deco_setup_copy_loop		; NO  - not yet, loop
+	return								; YES - done
+
+
 	global	setup_gas_registers
 setup_gas_registers:					; with currently breathed gas in WREG (1-5 or 6)
 	movwf	active_gas					; set as current gas
@@ -1554,76 +1589,92 @@
 	cpfseq	active_gas					; gas = gas6 ?
 	bra		setup_gas_registers_15		; NO - load gas 1-5
 	movff	gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine
-	movff	gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine	
+	movff	gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine
+	movlw	.3							; declare gas6 as a deco gas
+	movff	WREG,char_I_current_gas_type; copy gas type to deco engine
+	movff	curr_depth,char_I_gas6_depth; set current depth as change depth
 	bra		setup_gas_registers_com		; continue with common part
 setup_gas_registers_15:
 	decf	active_gas,W				; 1-5 -> 0-4
-	lfsr	FSR1,opt_gas_O2_ratio+0
+	lfsr	FSR1,opt_gas_O2_ratio
 	movff	PLUSW1,char_I_O2_ratio		; copy gas 1-5 O2 ratio to deco engine
-	lfsr	FSR1,opt_gas_He_ratio+0
+	lfsr	FSR1,opt_gas_He_ratio
 	movff	PLUSW1,char_I_He_ratio		; copy gas 1-5 He ratio to deco engine
-setup_gas_registers_com:	
-	;lfsr	FSR1,opt_gas_type			; commented out - currently not used anywhere
-	;movff	PLUSW1,active_gas_type		; 0=Disabled, 1=First, 2=Travel, 3=Deco
+	lfsr	FSR1,opt_gas_type			;
+	movff	PLUSW1,char_I_current_gas_type ; copy gas 1-5 type (0=Disabled, 1=First, 2=Travel, 3=Deco)
+setup_gas_registers_com:
 	movff	char_O_main_status,lo		; working copy of char_O_main_status in bank common
 	bcf		lo,DECO_MODE_PSCR_FLAG		; clear the pSCR-mode flag (may not be set, but never mind)
 	bcf		lo,DECO_MODE_LOOP_FLAG		; clear the loop/CCR-mode flag
 	movff	lo,char_O_main_status		; bank safe write-back of char_O_main_status
-	movf	active_gas,W				; reload WREG with diluent 1-5 or 6 (important!)
+	movf	active_gas,W				; reload WREG with gas 1-5 or 6 (important!)
 	return
 
 	global	setup_dil_registers
 setup_dil_registers:					; with currently breathed gas in WREG (1-5 or 6)
-	btfsc	is_bailout					; check if in bailout condition
-	bra		setup_gas_registers			; revert to setting up OC gases in bailout condition
-	movwf	active_gas					; set as current gas
-	movff	WREG,active_diluent			; remember for when switching back from bailout to loop
+	btfsc	FLAG_bailout_mode			; check if in bailout condition                      | --------------- FOR SAFETY ONLY --------------
+	bra		setup_gas_registers			; revert to setting up OC gases in bailout condition | This branch should never happen to be taken...
+	movwf	active_dil					; set as current diluent
 	movlw	.6
-	cpfseq	active_gas					; diluent = gas6 ?
+	cpfseq	active_dil					; diluent = gas6 ?
 	bra		setup_dil_registers_15		; NO - load diluent 1-5
 	movff	gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine
 	movff	gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine
+	movlw	.2							; declare gas6 as a normal diluent
+	movff	WREG,char_I_current_gas_type; copy gas type to deco engine
+	movff	curr_depth,char_I_gas6_depth; set current depth as change depth
 	bra		setup_dil_registers_com		; continue with common part
 setup_dil_registers_15:
-	decf	active_gas,W				; 1-5 -> 0-4
-	lfsr	FSR1,opt_dil_O2_ratio+0
+	decf	active_dil,W				; 1-5 -> 0-4
+	lfsr	FSR1,opt_dil_O2_ratio
 	movff	PLUSW1,char_I_O2_ratio		; copy diluent 1-5 O2 ratio to deco engine
-	lfsr	FSR1,opt_dil_He_ratio+0
+	lfsr	FSR1,opt_dil_He_ratio
 	movff	PLUSW1,char_I_He_ratio		; copy diluent 1-5 He ratio to deco engine
+	lfsr	FSR1,opt_dil_type			;
+	movff	PLUSW1,char_I_current_gas_type ; copy dil type (0=Disabled, 1=First, 2=Normal)
 setup_dil_registers_com:
-	;lfsr	FSR1,opt_dil_type			; commented out - currently not used anywhere
-	;movff	PLUSW1,active_gas_type		; 0=Disabled, 1=First, 2=Normal (there is no type 3 for diluents)
 	movff	char_O_main_status,lo		; working copy of char_O_main_status in bank common
 	bsf		lo,DECO_MODE_LOOP_FLAG		; loop flag is set in both, CCR and pSCR mode
 	bcf		lo,DECO_MODE_PSCR_FLAG		; clear pSCR mode flag by default
 	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
 	bsf		lo,DECO_MODE_PSCR_FLAG		; YES - set additional flag for pSCR mode
 	movff	lo,char_O_main_status		; bank safe write-back of char_O_main_status
-	movf	active_gas,W				; reload WREG with diluent 1-5 or 6 (important!)
+	movf	active_dil,W				; reload WREG with diluent 1-5 or 6 (important!)
 	return
 
-divemode_option_gaschange:				; Switch to the better gas
-	movff	better_gas_number,menupos1	; 1-5
-	bsf		divemode_gaschange			; Change the gas in the dive mode loop...
-	call	menuview_toggle_reset		; Reset to zero (Zero=no menuview)
-	bcf		better_gas_available		; Clear flag immediately
+
+divemode_option_gaschange:				; switch to the "better gas" / "better diluent"
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		divemode_option_gaschange_oc; YES
+	btfsc	FLAG_bailout_mode			; in bailout?
+	bra		divemode_option_gaschange_oc; YES
+divemode_option_gaschange_loop:			; in CCR/pSCR mode and not in bailout
+	movff	best_dil_number,menupos1	; NO  - select best diluent
+	bcf		better_dil_available		;     - clear flag immediately
+	bra		divemode_option_gaschange3	;     - continue with common part
+divemode_option_gaschange_oc:			; in OC or bailout
+	movff	best_gas_number,menupos1	; select best gas
+	bcf		better_gas_available		; clear flag immediately
+divemode_option_gaschange3				; common part
+	bsf		divemode_gaschange			; command a gas/diluent change
+	call	menuview_toggle_reset		; terminate the options menu
 	return
 
-divemode_option0:						; Start/Setup Divemode menu
-	call	TFT_clear_divemode_menu		; Clear menu area
+divemode_option0:						; start/setup dive mode menu
+	call	TFT_clear_divemode_menu		; clear menu area
 	bcf		menuview
 	call	do_main_divemenu
 
 	global	divemode_option0_return
 divemode_option0_return:
 ;	movlw	.1
-;	movwf	menupos1					; Set to first option in divemode menu
-	call	TFT_divemode_menu_cursor	; Show the cursor
+;	movwf	menupos1					; set to first option in dive mode menu
+	call	TFT_divemode_menu_cursor	; show the cursor
 	movlw	divemode_menu_timeout
-	movwf	timeout_counter2			; timeout for divemode menu
-	bsf		divemode_menu				; Set flag
-	clrf	menupos2					; Clear option counter
-	goto	diveloop_loop4				; Goto back to diveloop (menu processor trashes STKPTR!)
+	movwf	timeout_counter2			; timeout for dive mode menu
+	bsf		divemode_menu				; set flag
+	clrf	menupos2					; clear option counter
+	goto	diveloop_loop4				; go back to dive loop (menu processor trashes STKPTR!)
 
 divemode_option4:
 	movlw	d'58'						; two seconds left
@@ -1631,18 +1682,20 @@
 	movlw	apnoe_timeout-1				; apnoe timeout [min]
 	movwf	apnoe_timeout_counter
 	btfss	simulatormode_active		; in simulator mode?
-	return								; No
-divemode_option1:						; Quit simulation mode
+	return								; NO
+	;bra	divemode_option1			; YES
+
+divemode_option1:						; quit simulation mode
 	banksel	isr_backup
 	movlw	LOW  .1000
 	movwf	sim_pressure+0
 	movlw	HIGH .1000
-	movwf	sim_pressure+1				; Set to 0m -> End of Dive
+	movwf	sim_pressure+1				; set to 0m -> end of dive
 	banksel	common
-	call	menuview_toggle_reset		; Reset to zero (Zero=no menuview)
-
-	btfss	FLAG_apnoe_mode				; In Apnoe mode?
-	return								; No
+	call	menuview_toggle_reset		; reset to zero (zero = no menu view)
+
+	btfss	FLAG_apnoe_mode				; in apnoe mode?
+	return								; NO - done
 	movlw	d'58'						; two seconds left
 	movwf	timeout_counter1+0
 	movlw	apnoe_timeout-1				; apnoe timeout [min]
@@ -1662,51 +1715,74 @@
 divemode_option2:						; plus 1m
 	banksel	isr_backup
 	movlw	d'100'
-	addwf	sim_pressure+0
+	addwf	sim_pressure+0,F
 	movlw	.0
-	addwfc	sim_pressure+1
+	addwfc	sim_pressure+1,F
 	rcall	divemode_simulator_check_limits
 	banksel	common
 	return
 
 divemode_option5:
-	call	menuview_toggle_reset		; Reset to zero (Zero=no menuview)
-	bsf		reset_average_depth			; Set Flag
+	call	menuview_toggle_reset		; reset to zero (zero = no menu view)
+	bsf		reset_average_depth			; set flag
 	return
 
 divemode_option6:
-	bcf		divemode2					; Stop divetime
+	; advance tissues and deco by 5 minutes
+	movlw	.5							; + 5 minutes
+	movff	WREG,char_I_sim_advance_time; copy to mailbox
+	call	restart_deco_engine
+
+	; stop divetime incrementing in ISR
+	bcf		divemode2
+
+	; add 5 minutes to divemins
 	movlw	.5
 	addwf	divemins+0,F
 	movlw	.0
-	addwfc	divemins+1,F				; Add 5 mins
+	addwfc	divemins+1,F
+
+	; add 5 minutes (5 * 60 seconds) to total_divetime_seconds
+	movlw	LOW  (.5*.60)
+	addwf	total_divetime_seconds+0,F
+	movlw	HIGH (.5*.60)
+	addwfc	total_divetime_seconds+1,F
+
+	; continue dive time incrementing in ISR
+	bsf		divemode2
+
+	; add 5 minutes (5 * 60 seconds) to resettable time accumulator
 	movlw	LOW  (.5*.60)
 	addwf	average_divesecs+0,F
 	movlw	HIGH (.5*.60)
-	addwfc	average_divesecs+1,F		; Add 5*60 seconds
+	addwfc	average_divesecs+1,F
+
+	; add 5 minutes (5 * 60 seconds) to total time accumulator
 	movlw	LOW  (.5*.60)
-	addwf	total_divetime_seconds+0,F
+	addwf	average_divesecs_total+0,F
 	movlw	HIGH (.5*.60)
-	addwfc	total_divetime_seconds+1,F	; Add 5*60 seconds
-
-	; 1. Add 300xdepth to the sum of depths registers
-	SAFE_2BYTE_COPY rel_pressure, xB	; Buffer...
+	addwfc	average_divesecs_total+1,F
+
+
+	; calculate 300 x depth in mbar (300 = 5 min * 60 sec/min)
+	SAFE_2BYTE_COPY rel_pressure, xB
 	movlw	LOW  (.5*.60)
 	movwf	xA+0
 	movlw	HIGH (.5*.60)
 	movwf	xA+1
 	call	mult16x16					; xA*xB=xC
 
-	movf	xC+0,w
+	; add to the resettable depth accumulator
+	movf	xC+0,W
 	addwf	average_depth_hold+0,F
-	movf	xC+1,w
+	movf	xC+1,W
 	addwfc	average_depth_hold+1,F
-	movf	xC+2,w
+	movf	xC+2,W
 	addwfc	average_depth_hold+2,F
-	movf	xC+3,w
-	addwfc	average_depth_hold+3,F		; Will work up to 9999mbar*60*60*24=863913600mbar
-
-	; Do the same for the _total registers (Non-Resettable)
+	movf	xC+3,W
+	addwfc	average_depth_hold+3,F
+
+	; add to the total depth accumulator
 	movf	xC+0,w
 	addwf	average_depth_hold_total+0,F
 	movf	xC+1,w
@@ -1714,12 +1790,14 @@
 	movf	xC+2,w
 	addwfc	average_depth_hold_total+2,F
 	movf	xC+3,w
-	addwfc	average_depth_hold_total+3,F; Will work up to 9999mbar*60*60*24=863913600mbar
-
-	movlw	.5							; + 5 minutes
-	movff	WREG,char_I_sim_advance_time; copy to mailbox
-	bsf		divemode2					; continue divetime
-	call	restart_deco_engine
+	addwfc	average_depth_hold_total+3,F
+
+ IFDEF _cave_mode
+	; update backtracking data
+	movlw	.5							; add backtrack data for 5 minutes
+	call	update_backtrack			; make it so
+ ENDIF
+
 	goto	menuview_toggle_reset		; and return...
 
 divemode_option7:
@@ -1727,38 +1805,42 @@
 	movff	compass_heading_shown+0,compass_bearing+0
 	movff	compass_heading_shown+1,compass_bearing+1
 	bsf		compass_bearing_set			; set flag
-	goto	menuview_toggle_reset		; Done and return...
-	
+	goto	menuview_toggle_reset		; and return...
+
 divemode_option8:
-	bsf		alternative_divelayout		; Set flag for mode
-	bsf		FLAG_TFT_divemode_mask_alt	; Set flag for mask
-	movlw	.1
-	movwf	menupos3					; For the customviews...
-	call	TFT_ClearScreen				; Clear screen
-	goto	menuview_toggle_reset		; Done and return...
+	bsf		alternative_divelayout		; set flag for alternative layout mode
+	call	menuview_toggle_reset		; terminate the pre-menu
+	call	TFT_ClearScreen				; clear the whole screen
+	bsf		FLAG_TFT_divemode_mask_alt	; set flag to draw the alternative mask
+	movff	menupos3,customview_divemode; back-up the custom view shown in normal layout
+	clrf	menupos3					; select the default alternative layout
+	call	customview_mask_alternative ; draw   the default alternative layout
+	return								; done
+
 
 divemode_simulator_check_limits:
-	; Check limits (150m and 0m)
-	movlw	LOW  d'16000'			; Compare to 16bar=16000mbar (150m).
+	; check limits (150m and 0m)
+	movlw	LOW  d'16000'				; compare to 16 bar = 16000 mbar (150m)
 	subwf	sim_pressure+0,W
 	movlw	HIGH d'16000'
 	subwfb	sim_pressure+1,W
-	bnc		divemode_simulator_check_limits2 ; No-carry = borrow = not deeper
-
-	; Too deep, limit to 150m
+	bnc		divemode_simulator_check_limits2 ; no carry = borrow = not deeper
+
+	; too deep, limit to 150m
 	movlw	LOW  d'16000'
 	movwf	sim_pressure+0
 	movlw	HIGH d'16000'
 	movwf	sim_pressure+1
 	return
+
 divemode_simulator_check_limits2:
-	movlw	LOW  d'1000'				; Compare to 1bar == 0m == 1000 mbar.
+	movlw	LOW  d'1000'				; compare to 1 bar == 0m == 1000 mbar
 	subwf	sim_pressure+0,W
 	movlw	HIGH d'1000'
 	subwfb	sim_pressure+1,W
-	btfsc	STATUS,C					; No-carry = borrow = not deeper.
-	return								; Deeper than 0m == Ok.
-	; Too shallow, limit to 0m
+	btfsc	STATUS,C					; no carry = borrow = not deeper
+	return								; deeper than 0 m == ok
+	; too shallow, limit to 0m
 	movlw	LOW  d'1000'
 	movwf	sim_pressure+0
 	movlw	HIGH d'1000'
@@ -1766,291 +1848,383 @@
 	return
 
 ;=============================================================================
-; Compare all enabled gas in list, to see if a better one is available.
+; Find the best gas and diluent for the current depth
+; and check if a gas/diluent change is to be advised.
+;
+; Output: best_gas_number      : number of best gas, 0= none avail, 255= not computed
+;         best_dil_number      : number of best dil, 0= none avail, 255= not computed
+;         better_gas_available : flag indicating if a change is advised
+;         better_dil_available : flag indicating if a change is advised
+;
+;
+; in CCR and pSCR mode: - checks both, gases and diluents for respective best gas / best diluent
+;                       - if not in bailout, sets better_dil_available on diluents
+;                       - if     in bailout, sets better_gas_available on OC gases
+;
+; in OC mode          : - checks only gases for best gas
+;                       - sets better_gas_available on OC gases
 ;
-; Output: better_gas_available, better_gas_number
+check_gas_best:
+	movff	amb_press_10+0,xA+0				; copy ambient pressure / 10 into xA:2, will be used by ppO2 min/max checks later
+	movff	amb_press_10+1,xA+1				; ...
+	; set maximum ppO2 allowed
+	movff	char_I_ppO2_max,ppO2_max		; max ppO2 for working phase (default)
+	movff	char_O_deco_info,lo				; bank-safe copy of deco info vector
+	btfsc	lo,deco_flag					; is the ppo2 deco limit enabled?
+	movff	char_I_ppO2_max_deco,ppO2_max	; YES - replace by max ppO2 for deco phase
+	; check dive mode
+	btfsc	FLAG_oc_mode					; in OC mode?
+	bra		check_gas_best_gas				; YES - skip diluents, check for best gas only
+
+check_gas_best_dil:
+	; set minimum ppO2 required
+	movff	char_I_ppO2_min,WREG			; min ppO2 for pure diluent in CCR mode (default)
+	btfsc	FLAG_pscr_mode					; in pSCR mode?
+	movff	char_I_ppO2_min_loop,ppO2_min	; YES - replace by min ppO2 for pure diluent in pSCR mode
+	; preset results to nothing found
+	clrf	best_gas_num					; initialize best diluent as 0 = nothing found yet
+	bcf		better_dil_available			; =1: a better diluent is available and a gas change is advised in divemode
+;	; current diluent = 'gas6' ?
+;	movlw	.6								;
+;	cpfseq	active_dil						; using 'gas6' as current diluent?
+;	bra		check_gas_best_dil0				; NO  - continue
+;	bra		check_gas_best_dil3				; YES - suppress better diluent search in this case
+;check_gas_best_dil0:
+	; check all diluents
+	lfsr	FSR1,opt_dil_O2_ratio			; set base address for diluent arrays
+	movff	active_dil,lo					; number of currently used diluent
+	setf	best_gas_depth					; initialize change depth of best dil found so far to 255 meter
+; original code
+	clrf	check_gas_num
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check diluent 1
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check diluent 2
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check diluent 3
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check diluent 4
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check diluent 5
+; alternative code
+;	movlw	.5
+;	movwf	check_gas_num
+;check_gas_best_dil_loop:
+;	rcall	check_gas_best_common
+;	decfsz	check_gas_num
+;	bra		check_gas_best_dil_loop
 ;
-check_gas_change:						; Checks if a better gas should be selected (by user)
-	bcf		better_gas_available		; =1: A better gas is available and a gas change is advised in divemode
-	clrf	WREG
-	movff	WREG,better_gas_number		; clear better gas register
-
-	SAFE_2BYTE_COPY rel_pressure,xA
-	movlw	d'100'
-	movwf	xB+0
-	clrf	xB+1
-	call	div16x16					; compute depth in full m -> result in xC+0
-
-	btfsc	FLAG_pscr_mode				; in PSCR mode?
-	bra		check_gas_change2			; YES - check for diluents
-	btfss	FLAG_ccr_mode				; in CCR mode?
-	bra		check_gas_change_OC_bail	; NO - check for OC
-check_gas_change2:
-	btfsc	is_bailout					; in bailout?
-	bra		check_gas_change_OC_bail	; YES - check for OC
-
-	; Check Diluents
-	movlw	.0
-	rcall	check_dil_common			; With Gas 0-4 in WREG
-	movlw	.1
-	rcall	check_dil_common			; With Gas 0-4 in WREG
-	movlw	.2
-	rcall	check_dil_common			; With Gas 0-4 in WREG
-	movlw	.3
-	rcall	check_dil_common			; With Gas 0-4 in WREG
-	movlw	.4
-	rcall	check_dil_common			; With Gas 0-4 in WREG
-	bra		check_gas_change_exit
-
-check_gas_change_OC_bail:
-	movlw	.0
-	rcall	check_gas_common			; With Gas 0-4 in WREG
-	movlw	.1
-	rcall	check_gas_common			; With Gas 0-4 in WREG
-	movlw	.2
-	rcall	check_gas_common			; With Gas 0-4 in WREG
-	movlw	.3
-	rcall	check_gas_common			; With Gas 0-4 in WREG
-	movlw	.4
-	rcall	check_gas_common			; With Gas 0-4 in WREG
-	;bra	check_gas_change_exit
-
-check_gas_change_exit:
-	bsf		FLAG_TFT_active_gas_divemode; redraw gas/setpoint/diluent
-	btfss	better_gas_available		; is a better gas available?
-	bcf		blinking_better_gas			; NO - clear blinking flag
-	btfsc	better_gas_available		; is a better gas available?
-	return								; YES
-	clrf	WREG						; NO  - clear better_gas_number (for gaslist display)
-	movff	WREG,better_gas_number
+	; store result
+	movff	best_gas_num,best_dil_number	; store new best diluent found (1-5 or 0 of no usable diluent available)
+	; check if change advices shall be given in general
+	btfsc	FLAG_bailout_mode				; in bailout?
+	bra		check_gas_best_gas				; YES - no better diluent advice when in bailout
+check_gas_best_dil1:
+	; check if a change advice shall be given right now
+	movf	best_dil_number,W				; load number of best diluent into WREG (1-5)
+	bz		check_gas_best_dil3				; has a best diluent been found at all?  NO - nothing to signal for
+	cpfseq	active_dil						; is this the currently used diluent?
+	bra		check_gas_best_dil2				; NO
+	bra		check_gas_best_dil3				; YES - no need to signal a better diluent if this diluent is already in use
+check_gas_best_dil2:
+	btfsc	setpoint_fallback				; is a fallback warning active?
+	bra		check_gas_best_dil3				; YES - suppress better diluent prompt in this case
+	; not using the best gas - show better diluent hint whenever a better diluent is available
+	bsf		better_dil_available			; signal that a better diluent is available
+	bsf		FLAG_TFT_active_gas_divemode	; redraw gas/setpoint/diluent
+check_gas_best_dil3:
+	btfss	better_dil_available			; shall a better diluent be signaled for?
+	bcf		blinking_better_dil				; NO  - clear blinking flag
+	; continue with checking for best bailout gas
+
+check_gas_best_gas:
+	; set minimum ppO2 required
+	movff	char_I_ppO2_min,ppO2_min		; min ppO2 for OC/Bailout
+	; preset results to nothing found
+	clrf	best_gas_num					; initialize best gas as 0 = nothing found yet
+	bcf		better_gas_available			; =1: a better gas is available and a gas change is advised in divemode
+;	; current gas = 'gas6' ?
+;	movlw	.6								;
+;	cpfseq	active_gas						; using 'gas6' as current gas?
+;	bra		check_gas_best_gas0				; NO  - continue
+;	bra		check_gas_best_gas3				; YES - suppress better gas search in this case
+;check_gas_best_gas0:
+	; check all gases
+	lfsr	FSR1,opt_gas_O2_ratio			; set base address for gas arrays
+	movff	active_gas,lo					; number of currently used gas
+	setf	best_gas_depth					; initialize change depth of best gas found so far to 255 meter
+; original code
+	clrf	check_gas_num
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check gas 1
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check gas 2
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check gas 3
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check gas 4
+	incf	check_gas_num,F
+	rcall	check_gas_best_common			; check gas 5
+; alternative code
+;	movlw	.5
+;	movwf	check_gas_num
+;check_gas_best_gas_loop:
+;	rcall	check_gas_best_common
+;	decfsz	check_gas_num
+;	bra		check_gas_best_gas_loop
+;
+	; store result
+	movff	best_gas_num,best_gas_number	; store new best gas found (1-5 or 0 of no usable gas available)
+	; check if change advices shall be given in general
+	btfsc	FLAG_oc_mode					; in OC mode?
+	bra		check_gas_best_gas1				; YES
+	btfsc	FLAG_bailout_mode				; in bailout?
+	bra		check_gas_best_gas1				; YES
+	return									; NO  - no better (OC) gas advice when not in OC or bailout mode
+check_gas_best_gas1:						; check if we are already on the best gas
+	; check if a change advice shall be given right now
+	movf	best_gas_number,W				; load number of best gas into WREG (1-5)
+	bz		check_gas_best_gas3				; has a best gas been found at all?  NO - nothing to signal for
+	cpfseq	active_gas						; is this the currently used gas?
+	bra		check_gas_best_gas2				; NO
+	bra		check_gas_best_gas3				; YES - no need to signal a better gas if this gas is already in use
+check_gas_best_gas2:
+	; not using the best gas - show better gas hint whenever a better gas is available
+	bsf		better_gas_available			; YES - signal that a better gas is available
+	bsf		FLAG_TFT_active_gas_divemode	; YES - redraw gas/setpoint/diluent
+check_gas_best_gas3:
+	btfss	better_gas_available			; shall a better gas be signaled for?
+	bcf		blinking_better_gas				; NO - clear blinking flag
 	return
 
-check_gas_common:						; With Gas 0-4 in WREG
-	btfsc	better_gas_available		; Better Gas already found?
-	return								; Yes, return
-	lfsr	FSR1,opt_gas_type			; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	btfss	PLUSW1,0					; Test for Bit0 and 1 -> type=3 -> Deco
-	return								; No
-	btfss	PLUSW1,1					; Test for Bit0 and 1 -> type=3 -> Deco
-	return								; No
-	incf	WREG,W						; 1-5
-	cpfseq	active_gas					; is this gas current gas?
-	bra		check_gas_common2			; No
-	return								; Yes, skip test for active gas
-check_gas_common2:
-	decf	WREG,W						; 0-4
-	movwf	hi							; Save tested gas 0-4
-	lfsr	FSR1,opt_OC_bail_gas_change
-	movff	PLUSW1,lo					; Change depth into lo
-	movlw	minimum_change_depth
-	cpfsgt	lo							; Change depth>minimum_change_depth?
-	return								; No, Change depth not deep enough, skip!
-	movf	xC+0,W						; load depth in m into WREG
-	cpfsgt	lo							; gas_change_depth < current depth?
-	bra		check_gas_common3			; No, check if we are within the better_gas_window_pos window
-	incf	hi,W						; 1-5
-	movff	WREG,better_gas_number		; number (1-5) of the "better gas" in divemode, =0: no better gas available
-	movlw	better_gas_window_neg
-	subwf	lo,W						; Change depth-better_gas_window_neg
-	cpfslt	xC+0						; current depth<Change depth-better_gas_window_neg?
-	bra		check_gas_common4			; Ok, now check the better gas ppO2<char_I_ppO2_max
-	return
-check_gas_common3:
-	incf	hi,W						; 1-5
-	movff	WREG,better_gas_number		; number (1-5) of the "better gas" in divemode, =0: no better gas available
-	movlw	better_gas_window_pos
-	addwf	lo,W						; Change depth+better_gas_window_pos
-	cpfsgt	xC+0						; current depth>Change depth+better_gas_window_pos?
-	bra		check_gas_common4			; Ok, now check the better gas ppO2<char_I_ppO2_max
-	return
-check_gas_common4:
-	movf	hi,W						; gas 0-4 into WREG
-	lfsr	FSR1,char_I_deco_O2_ratio	; load base address char_I_deco_O2_ratio array
-	movff	PLUSW1,lo					; read O2 ratio from array into lo
-
-	SAFE_2BYTE_COPY amb_pressure, xA
-	movlw	d'10'
-	movwf	xB+0
+check_gas_best_common:						; with gas to be checked in check_gas_num (1-5)
+;											; and  current gas       in lo            (1-5)
+	;
+	; Memory Map:
+	; ---------------------------------------------------------------------------------------
+	; opt_gas_O2_ratio		res 5	; base address for gases
+	; opt_dil_O2_ratio		res 5	; base address for diluents
+	; opt_gas_He_ratio		res 5	; (not needed here)
+	; opt_dil_He_ratio		res 5	; (not needed here)
+	; opt_gas_type			res 5	; has offset of 20 bytes from base address for gases
+	; opt_dil_type			res 5	; has offset of 20 bytes from base address for diluents
+	; opt_gas_change		res 5	; has offset of 10 bytes from opt_gas_type
+	; opt_dil_change		res 5	; has offset of 10 bytes from opt_dil_type
+
+	; get gas data
+	decf	check_gas_num,W					; (1-5) -> (0-4) into WREG to be used as index
+	movff	PLUSW1,check_gas_O2_ratio		; load O2 ratio (%) of current gas/dil into check_gas_O2_ratio
+	addlw	.20								; add offset of 20 bytes to index type in opt_gas_type/opt_dil_type
+	movff	PLUSW1,check_gas_type			; load type of current gas/dil into check_gas_type (0=disabled, 1=first, 2=travel/normal, 3=deco/-)
+	addlw	.10								; add offset of 10 bytes to index change depth in opt_gas_change/opt_dil_change
+	movff	PLUSW1,check_gas_depth			; load change depth of current gas/dil into check_gas_depth
+	; check if gas is usable (i.e. not disabled)
+	tstfsz	check_gas_type					; type = disabled (0)?
+	bra		check_gas_best_common0			; NO  - continue checks
+	movf	check_gas_num,W					; YES - get the number of the gas to be checked (1-5)
+	cpfseq	lo								;     - is this the currently used gas?
+	return									;       NO  - skip disabled gases which are not the current gas
+	bra		check_gas_best_common1			;       YES - a gas in use overrides it's disabled status, therefore treat it as available
+check_gas_best_common0:
+	; skip deco gases (type=3) if not in deco mode, but search among all enabled gases when in loop or bailout mode
+	movlw	.3
+	cpfseq	check_gas_type					; type = deco (3)?
+	bra		check_gas_best_common1			; NO  - proceed
+	btfsc	FLAG_bailout_mode				; YES - in bailout?
+	bra		check_gas_best_common1			;       YES - proceed, include deco gases
+	movff	char_O_main_status,WREG			;       NO  - get main deco mode
+	btfsc	WREG,DECO_MODE_LOOP_FLAG		;           - in loop mode?
+	bra		check_gas_best_common1			;             YES - proceed, include deco gases
+	movff	char_O_deco_info,WREG			;             NO  - get deco info vector
+	btfss	WREG,deco_flag					;                 - in deco mode (deco_flag set), i.e. use of deco gases allowed?
+	return									;                   NO  - skip deco gas while not in deco mode
+check_gas_best_common1:						;                   YES - proceed
+;	; check if gas change depth is below minimum change depth
+;	movlw	minimum_change_depth			; for value see definition in hwos.inc
+;	cpfsgt	check_gas_depth					; change depth of checked gas > minimum_change_depth?
+;	return									; NO - change depth not deep enough, skip and check next gas
+	; check if gas is usable, i.e. its change depth is below or equal to the current depth
+	movf	curr_depth,W					; load current depth (in m) into WREG
+	cpfslt	check_gas_depth					; change depth of checked gas < (shallower than) current depth?
+	bra		check_gas_best_common2			; NO  - gas is usable
+	return									; YES - gas is not usable
+check_gas_best_common2:
+	; check if this gas is the first best gas candidate
+	movf	best_gas_num,W					; get best gas found so far (1-5) or 0 if none found yet
+	tstfsz	WREG							; has a best gas candidate been found yet?
+	bra		check_gas_best_common3			; YES - check if the new one is better than the one we have so far
+	bra		check_gas_best_common4			; NO  - no need to do the above mentioned check
+check_gas_best_common3:
+	; check if the change depth of the checked gas is < (shallower) than the change depth of the best gas found so far
+	movf	best_gas_depth,W				; load change depth of best gas so far into WREG
+	cpfslt	check_gas_depth					; change depth of checked gas < (shallower than) change depth of best gas so far?
+	return									; NO - this gas is not better than the best already found
+check_gas_best_common4:
+	; check if the gas fits into the ppO2 limits
+	movff	check_gas_O2_ratio,xB+0			; xB = O2 ratio, xA is still loaded with (p_amb / 10)
 	clrf	xB+1
-	call	div16x16					; xC=p_amb/10
-	movff	xC+0,xA+0
-	movff	xC+1,xA+1
-	movff	lo,xB+0						; =O2 ratio
-	clrf	xB+1
-	call	mult16x16					; lo * p_amb/10
-
-	; Check very high ppO2 manually
-	tstfsz	xC+2						; char_I_O2_ratio * p_amb/10 > 65536, ppO2>6,55bar?
-	return								; Done.
-	; Check if ppO2>3,30bar
-	btfsc	xC+1,7
-	return								; Done.
-
-	; Check for low ppo2
-	movff	xC+0,sub_b+0
-	movff	xC+1,sub_b+1
-	movff	char_I_ppO2_min,WREG
-	mullw	d'100'						; char_I_ppO2_min*100
-	movff	PRODL,sub_a+0
-	movff	PRODH,sub_a+1
-	call	subU16						; sub_c = sub_a - sub_b
-	btfss	neg_flag
-	return								; Done (Too low).
-
-	;check if we are within our warning thresholds!
+	call	mult16x16						; xC = O2 ratio * (p_amb / 10)
+	; check for very high ppO2
+	tstfsz	xC+2							; O2_ratio * p_amb / 10 > 65536, i.e. ppO2 > 6.55 bar ?
+	return									; YES - gas is not usable
+	btfsc	xC+1,7							; check if ppO2 > 3.30 bar
+	return									; YES - gas is not usable
+	; check for low ppO2
 	movff	xC+0,sub_a+0
 	movff	xC+1,sub_a+1
-	movff	char_I_ppO2_max_deco,WREG	; ppO2 max for MOD calculation and color coding in divemode
-	addlw	.1							; e.g. >1.60
-	mullw	d'100'						; char_I_ppO2_max*100
+	movf	ppO2_min,W
+	mullw	.100							; char_I_ppO2_min * 100
 	movff	PRODL,sub_b+0
 	movff	PRODH,sub_b+1
-	call	subU16						; sub_c = sub_a - sub_b
-	btfsc	neg_flag
-	bsf		better_gas_available		;=1: A better gas is available and a gas change is advised in divemode
-	return								; Done.
-
-
-check_dil_common:						; With Dil 0-4 in WREG
-	btfsc	better_gas_available		; Better Diluent already found?
-	return								; Yes, return
-	lfsr	FSR1,opt_dil_type			; 0=Disabled, 1=First, 2=Normal
-	tstfsz	PLUSW1						; =0?
-	bra		check_dil_common1			; No
-	return								; Yes, skip inactive diluents for test
-check_dil_common1:
-	incf	WREG,W						; 1-5
-	cpfseq	active_gas					; is this the current diluent?
-	bra		check_dil_common2			; No
-	return								; Yes, skip test for active diluent
-check_dil_common2:
-	decf	WREG,W						; 0-4
-	movwf	hi							; Save tested diluent 0-4
-	lfsr	FSR1,char_I_dil_change
-	movff	PLUSW1,lo					; Change depth into lo
-	movlw	minimum_change_depth
-	cpfsgt	lo							; Change depth>minimum_change_depth?
-	return								; No, Change depth not deep enough, skip!
-	movf	xC+0,W						; load depth in m into WREG
-	cpfsgt	lo							; gas_change_depth < current depth?
-	return								; No, check next gas
-	incf	hi,W						; 1-5
-	movff	WREG,better_gas_number		; number (1-5) of the "better gas" in divemode, =0: no better gas available
-	movlw	better_gas_window_neg
-	subwf	lo,W						; Change depth-better_gas_window_neg
-	cpfslt	xC+0						; current depth<Change depth-better_gas_window_neg?
-	bsf		better_gas_available		;=1: A better gas is available and a gas change is advised in divemode
+	call	subU16							; sub_c = sub_a - sub_b
+	btfsc	neg_flag						; within limit?
+	return									; NO - too low, gas is not usable
+	; check for high ppO2
+	movf	ppO2_max,W
+	mullw	.100							; ppO2_max * 100
+	movff	PRODL,sub_b+0
+	movff	PRODH,sub_b+1
+	infsnz	sub_b+0,F						; add 1 mbar to allowance to avoid exclusion on equal
+	incf	sub_b+1,F
+	call	subU16							; sub_c = sub_a - sub_b
+	btfss	neg_flag						; within limit?
+	return									; NO - too high, gas is not usable
+	; we have a (new) best gas
+	movff	check_gas_num,  best_gas_num	; set checked gas (1-5) as best gas
+	movff	check_gas_depth,best_gas_depth	; memorize its change depth
 	return
 
 
 ;=============================================================================
 ; Check for Auto-SP
 ;
-check_dive_autosp:						; Check for Auto-SP
+check_dive_autosp:						; check for Auto-SP
 	movff	opt_ccr_mode,WREG			; =0: Fixed SP, =1: Sensor, =2: Auto SP
 	sublw	.2							; opt_ccr_mode = 2 (Auto SP)?
-	bz		check_dive_autosp2			; Yes, check
-	return								; No, return for Sensor or Fixed mode
+	bz		check_dive_autosp2			; YES - check
+	return								; NO  - return for sensor or fixed mode
 check_dive_autosp2:
-	SAFE_2BYTE_COPY rel_pressure,xA
-	movlw	d'100'
-	movwf	xB+0
-	clrf	xB+1
-	call	div16x16					; compute depth in full m -> result in xC+0
 	; Check SP2
-	btfsc	sp2_switched				; =1: This setpoint has been autoselected already
-	bra		check_dive_autosp3			; Skip check
-	movff	char_I_setpoint_change+1,lo	; Get depth in m
-	tstfsz	lo							; =0?
-	bra		check_dive_autosp2a			; No, continue
-	bra		check_dive_autosp3			; Skip check
+	btfsc	sp2_switched				; SP 2 used so far?
+	bra		check_dive_autosp3			; YES - continue with SP 3
+	movff	char_I_setpoint_change+1,lo	; NO  - get depth in m
+	tstfsz	lo							;     - SP change depth = 0 ?
+	bra		check_dive_autosp2a			;       NO  - continue
+	bra		check_dive_autosp3			;       YES - continue with SP 3
 check_dive_autosp2a:
-	decf	lo,W						; -1 -> WREG
-	cpfsgt	xC+0						; Compare with depth
-	bra		check_dive_autosp3			; lower depth, do not switch
+	decf	lo,W						; SP change depth -1 -> WREG
+	cpfsgt	curr_depth					; current depth > change depth - 1 ?
+	bra		check_dive_autosp3			; NO  - continue with SP 3
 	; auto switch to SP2
-	movff	char_I_setpoint_cbar+1,char_I_const_ppO2	; Use SetPoint
-	rcall	xmit_sp_set_flag
-	bsf		sp2_switched				; Set flag
+	movff	char_I_setpoint_cbar+1,char_I_const_ppO2 ; YES - use SP
+	rcall	xmit_sp_set_flag			;     - send SP to external devices
+	bsf		sp2_switched				;     - set SP 2 used flag
 check_dive_autosp3:
 	; Check SP3
-	btfsc	sp3_switched				;=1: This setpoint has been autoselected already
-	bra		check_dive_autosp4			; Skip check
-	movff	char_I_setpoint_change+2,lo	; Get depth in m
-	tstfsz	lo							; =0?
-	bra		check_dive_autosp3a			; No, continue
-	bra		check_dive_autosp4			; Skip check
+	btfsc	sp3_switched				; SP 3 used so far?
+	bra		check_dive_autosp4			; YES - continue with SP 4
+	movff	char_I_setpoint_change+2,lo	; NO  - get depth in m
+	tstfsz	lo							;     - SP change depth = 0 ?
+	bra		check_dive_autosp3a			;       NO  - continue
+	bra		check_dive_autosp4			;       YES - continue with SP 4
 check_dive_autosp3a:
-	decf	lo,W						; -1 -> WREG
-	cpfsgt	xC+0						; Compare with depth
-	bra		check_dive_autosp4			; lower depth, do not switch
+	decf	lo,W						; SP change depth -1 -> WREG
+	cpfsgt	curr_depth					; current depth > change depth - 1 ?
+	bra		check_dive_autosp4			; NO  - continue with SP 4
 	; auto switch to SP3
-	movff	char_I_setpoint_cbar+2,char_I_const_ppO2	; Use SetPoint
-	rcall	xmit_sp_set_flag
-	bsf		sp3_switched				; Set flag
+	movff	char_I_setpoint_cbar+2,char_I_const_ppO2 ; YES - use SP
+	rcall	xmit_sp_set_flag			;     - send SP to external devices
+	bsf		sp3_switched				;     - set SP 3 used flag
 check_dive_autosp4:
 	; Check SP4
-	btfsc	sp4_switched				;=1: This setpoint has been autoselected already
-	bra		check_dive_autosp5			; Skip check
-	movff	char_I_setpoint_change+3,lo ; Get depth in m
-	tstfsz	lo							; =0?
-	bra		check_dive_autosp4a			; No, continue
-	bra		check_dive_autosp5			; Skip check
+	btfsc	sp4_switched				; SP 4 used so far?
+	bra		check_dive_autosp5			; YES - continue with SP 5
+	movff	char_I_setpoint_change+3,lo ; NO  - get depth in m
+	tstfsz	lo							;     - SP change depth = 0 ?
+	bra		check_dive_autosp4a			;       NO  - continue
+	bra		check_dive_autosp5			;        YES - continue with SP 5
 check_dive_autosp4a:
-	decf	lo,W						; -1 -> WREG
-	cpfsgt	xC+0						; Compare with depth
-	bra		check_dive_autosp5			; lower depth, do not switch
+	decf	lo,W						; SP change depth -1 -> WREG
+	cpfsgt	curr_depth					; current depth > change depth - 1 ?
+	bra		check_dive_autosp5			; NO  - continue with SP 5
 	; auto switch to SP4
-	movff	char_I_setpoint_cbar+3,char_I_const_ppO2 ; Use SetPoint
-	rcall	xmit_sp_set_flag
-	bsf		sp4_switched				; Set flag
+	movff	char_I_setpoint_cbar+3,char_I_const_ppO2 ; YES - use SP
+	rcall	xmit_sp_set_flag			;     - send SP to external devices
+	bsf		sp4_switched				;     - set SP 4 used flag
 check_dive_autosp5:
 	; Check SP5
-	btfsc	sp5_switched				;=1: This setpoint has been autoselected already
-	bra		check_dive_autosp6			; Skip check
-	movff	char_I_setpoint_change+4,lo	; Get depth in m
-	tstfsz	lo							; =0?
-	bra		check_dive_autosp5a			; No, continue
-	bra		check_dive_autosp6			; Skip check
+	btfsc	sp5_switched				; SP 5 used so far?
+	bra		check_dive_autosp6			; YES - done
+	movff	char_I_setpoint_change+4,lo	; NO  - get depth in m
+	tstfsz	lo							;     - SP change depth = 0 ?
+	bra		check_dive_autosp5a			;       NO  - continue
+	bra		check_dive_autosp6			;       YES - done
 check_dive_autosp5a:
-	decf	lo,W						; -1 -> WREG
-	cpfsgt	xC+0						; Compare with depth
-	bra		check_dive_autosp6			; lower depth, do not switch
+	decf	lo,W						; SP change depth -1 -> WREG
+	cpfsgt	curr_depth					; current depth > change depth - 1 ?
+	bra		check_dive_autosp6			; NO  - done
 	; auto switch to SP5
-	movff	char_I_setpoint_cbar+4,char_I_const_ppO2 ; Use SetPoint
-	rcall	xmit_sp_set_flag
-	bsf		sp5_switched				; Set flag
+	movff	char_I_setpoint_cbar+4,char_I_const_ppO2 ; YES - use SP
+	rcall	xmit_sp_set_flag			;     - send SP to external devices
+	bsf		sp5_switched				;     - set SP 5 used flag
 check_dive_autosp6:
 	return
 
 xmit_sp_set_flag:
 	movff	char_I_const_ppO2,WREG
-	call	transmit_setpoint			; Transmit current setpoint from WREG (in cbar) to external electronics
-	bsf		setpoint_changed			; Set flag (for profile)
-	bsf		event_occured				; Set event flag
+	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
+	bsf		setpoint_changed			; set flag (for profile)
+	bsf		event_occured				; set event flag
 	return
 
 set_logbook_marker:
 	bcf		FLAG_set_marker				; clear flag
-	movlw	d'6'						; set type of Alarm (manual marker)
-	movwf	AlarmType					; copy to Alarm Register
-	bsf		event_occured				; Set event flag
+	movlw	d'6'						; set type of alarm (manual marker)
+	movwf	AlarmType					; copy to alarm register
+	bsf		event_occured				; set event flag
 	return
 
 ;=============================================================================
-; Setup everything to enter divemode.
+; Setup everything to enter dive mode
 ;
+	global	dive_boot_oc_bail
+dive_boot_oc_bail:
+	; copy opt_gas_types into backup (for "lost gas" feature)
+	movff	opt_gas_type+0,opt_gas_type_backup+0		; 0=Disabled, 1=First, 2=Travel, 3=Deco
+	movff	opt_gas_type+1,opt_gas_type_backup+1		; 0=Disabled, 1=First, 2=Travel, 3=Deco
+	movff	opt_gas_type+2,opt_gas_type_backup+2		; 0=Disabled, 1=First, 2=Travel, 3=Deco
+	movff	opt_gas_type+3,opt_gas_type_backup+3		; 0=Disabled, 1=First, 2=Travel, 3=Deco
+	movff	opt_gas_type+4,opt_gas_type_backup+4		; 0=Disabled, 1=First, 2=Travel, 3=Deco
+	; done
+	return
+
+	global	dive_boot_oc
 dive_boot_oc:
-	rcall	get_first_gas_to_WREG		; Gets first gas (1-5) into WREG
+	; set-up registers
+	rcall	get_first_gas_to_WREG		; get first gas (1-5) into WREG
 	rcall	setup_gas_registers			; set-up of gas parameters of currently breathed gas (with WREG = gas 1-5)
 	rcall	deco_setup_oc_gases			; set-up of gas list for deco calculations (with WREG = gas 1-5)
 	return
 
+	global	dive_boot_cc
 dive_boot_cc:
-	bcf		is_bailout					; =1: Bailout
-	bcf		setpoint_fallback			; =1: Fallback to SP1 due to external O2 sensor failure
-	bcf		blinking_setpoint			; Reset blinking SP flag
-
+	; copy opt_dil_types into backup (for "lost diluent" feature)
+	movff	opt_dil_type+0,opt_dil_type_backup+0		; 0=Disabled, 1=First, 2=Normal
+	movff	opt_dil_type+1,opt_dil_type_backup+1		; 0=Disabled, 1=First, 2=Normal
+	movff	opt_dil_type+2,opt_dil_type_backup+2		; 0=Disabled, 1=First, 2=Normal
+	movff	opt_dil_type+3,opt_dil_type_backup+3		; 0=Disabled, 1=First, 2=Normal
+	movff	opt_dil_type+4,opt_dil_type_backup+4		; 0=Disabled, 1=First, 2=Normal
+	; clear flags
+	bcf		FLAG_bailout_mode			; =1: bailout
+	bcf		setpoint_fallback			; =1: fallback to SP1 due to external O2 sensor failure
+	; set-up registers
+	rcall	get_first_dil_to_WREG		; get first diluent (1-5) into WREG
+	rcall	setup_dil_registers			; set-up of diluent parameters for currently breathed diluent (with WREG = current diluent 1-5)
+	rcall	deco_setup_cc_diluents		; set-up of diluent list for deco calculations (with WREG = current diluent 1-5)
+	; done
+	return
+
+dive_boot_cc_part2:
 	; revoke sensors from usage if they do not have a valid calibration
 	bsf		use_O2_sensor1
 	bsf		use_O2_sensor2
@@ -2061,108 +2235,120 @@
 	bcf		use_O2_sensor2
 	btfss	sensor3_calibrated_ok
 	bcf		use_O2_sensor3
-
+	; check for external HUD/ppO2 Monitor
 	btfss	optical_input				; do we have an optical input?
-	bra	dive_boot_cc_0				; No
-	; Copy (initial) valid flags from HUD/ppO2 Monitor
+	bra		dive_boot_cc_part2_1		; NO
+	; copy (initial) valid flags from HUD/ppO2 Monitor
 	btfsc	sensor1_active
-	bsf	use_O2_sensor1
-    	btfsc	sensor2_active
-	bsf	use_O2_sensor2
+	bsf		use_O2_sensor1
+	btfsc	sensor2_active
+	bsf		use_O2_sensor2
 	btfsc	sensor3_active
-	bsf	use_O2_sensor3
-
-dive_boot_cc_0:
+	bsf		use_O2_sensor3
+dive_boot_cc_part2_1:
 	; In pSCR mode, only settings 0 (calculated ppO2) and 1 (ppO2 from sensors) are defined.
-	; In case we still have 3 (auto SP) selected out of previous ccr mode, we reset to 0.
+	; In case we still have 3 (auto SP) selected out of previous CCR mode, we reset to 0.
 	btfss	FLAG_pscr_mode
-	bra		dive_boot_cc_1
+	bra		dive_boot_cc_part2_2
 	movff	opt_ccr_mode,WREG			; =0: Fixed SP (CCR) / calculated SP (pSCR), =1: Sensor, =2: Auto SP
 	sublw	.2							; opt_ccr_mode = 1 (Auto SP)?
-	bnz		dive_boot_cc_1
+	bnz		dive_boot_cc_part2_2
 	movlw	.0
 	movff	WREG,opt_ccr_mode
-
-dive_boot_cc_1:
+dive_boot_cc_part2_2:
 	bsf		setpoint_changed			; set flag (for profile)
-	bcf		sp2_switched				; =1: This setpoint has been auto-selected already
-	bcf		sp3_switched				; =1: This setpoint has been auto-selected already
-	bcf		sp4_switched				; =1: This setpoint has been auto-selected already
-	bcf		sp5_switched				; =1: This setpoint has been auto-selected already
-
-	rcall	get_first_dil_to_WREG		; get first gas (1-5) into WREG
-	rcall	setup_dil_registers			; set-up of gas parameters for currently breathed gas (with WREG = current gas 1-5)
-	rcall	deco_setup_cc_diluents		; set-up of gas list for deco calculations (with WREG = current gas 1-5)
-
+	bcf		sp2_switched				; =1: this setpoint has been auto-selected already
+	bcf		sp3_switched				; =1: this setpoint has been auto-selected already
+	bcf		sp4_switched				; =1: this setpoint has been auto-selected already
+	bcf		sp5_switched				; =1: this setpoint has been auto-selected already
 	; Start with SP1 (CCR) or 0 (pSCR) as default.
 	; If in sensor mode, this value will be overwritten by calc_deko_divemode_sensor
 	clrf	WREG						; preload WREG with setpoint value 0 for pSCR calculated
-	btfss	FLAG_ccr_mode				; are we in CCR mode?
-	bra		dive_boot_cc_2				; NO  - keep preloaded value
+	btfsc	FLAG_ccr_mode				; are we in CCR mode?
 	movff	char_I_setpoint_cbar+0,WREG	; YES - get value of setpoint 1
-dive_boot_cc_2:
 	movff	WREG,char_I_const_ppO2		; write setpoint to deco engine
 	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
 	goto	calc_deko_divemode_sensor	; read & process sensor data (and return)
 
+
 diveloop_boot:
+
+	; do the basic initialization
 	call	restart_set_modes_and_flags
 
-	call	I2C_sleep_accelerometer		; stop accelerometer
-	call	I2C_sleep_compass			; stop compass
+	; stop accelerometer and compass
+	call	I2C_sleep_accelerometer
+	call	I2C_sleep_compass
+
+	; reset max pressure aka max depth
+	clrf	WREG
+	movff	WREG,max_pressure+0	
+	movff	WREG,max_pressure+1
+
+	; initialize press needs to zero and invalid (not yet computed) state
+	clrf	WREG						; set WREG to 0
+ IFDEF _cave_mode
+	movff	WREG,char_I_backtrack_time	; clear backtracking time (index to char_I_backtrack_depth)
+	movff	WREG,char_I_backtrack_depth	; prime first entry with depth 0
+ ENDIF
+	bsf		WREG,int_is_zero			; set zero flag
+	bsf		WREG,int_invalid_flag		; set invalid flag (additionally)
+	banksel	int_O_ascent_pres_need		; select bank with shared output vars
+	movwf	int_O_ascent_pres_need+1	; Set flags for tank pressure needs = 0 before p2_deco.c
+	movwf	int_O_ascent_pres_need+3	; can do it. If this is not done here and the gas needs
+	movwf	int_O_ascent_pres_need+5	; custom view is shown before p2_deco.c completes the first
+	movwf	int_O_ascent_pres_need+7	; deco calculation, some rubbish numbers from last dive or
+	movwf	int_O_ascent_pres_need+9	; simulation may be shown
+	banksel	common						; back to bank common
+
+	; configure the deco engine
+	clrf	hi
+	bsf		hi,DECO_Z_FACTOR_FLAG		; enable Z factor mode by default
+	TSTOSS	opt_ZfactorUse				; shall use Z factor mode?
+	bcf		hi,DECO_Z_FACTOR_FLAG		; NO - disable again
+ IFDEF _rx_functions
+	bsf		hi,DECO_TR_FUNCTIONS		; enable TR mode by default
+	btfss	FLAG_tr_enabled				; shall use TR mode?
+	bcf		hi,DECO_TR_FUNCTIONS		; NO - disable again
+ ENDIF
+	movff	hi,char_O_main_status		; bank-safe copy to deco engine
+
+	movff	char_O_deco_status,lo		; bank-safe read
+	bsf		lo,DECO_STATUS_0_FLAG		; set init-  | ATTENTION: The deco engine must be started in init state! If omitted, it may
+	bsf		lo,DECO_STATUS_1_FLAG		;     state, |            enter an infinite loop at some point in time and brick the OSTC!
+	bcf		lo,DECO_PLAN_FLAG			; normal plan mode,
+	bcf		lo,DECO_VOLUME_FLAG			; disable gas volume calculation, and
+	bcf		lo,DECO_ASCENT_FLAG			; disable delayed ascent calculation
+	movff	lo,char_O_deco_status		; bank-safe copy back to deco engine
 
 	clrf	WREG
-	movff	WREG,max_pressure+0			; clear some variables
-	movff	WREG,max_pressure+1
-
-	; init in invalid data state
-	clrf	WREG						; set WREG to 0
-	bsf		WREG,int_invalid_flag		; set invalid flag
-	bsf		WREG,int_is_zero			; set zero flag
-	movff	WREG,int_O_tank_pres_need+1	; Set flags for tank pressure needs = 0 before p2_deco.c
-	movff	WREG,int_O_tank_pres_need+3	; can do it. If this is not done here and the gas needs
-	movff	WREG,int_O_tank_pres_need+5	; custom view is shown before p2_deco.c completes the first
-	movff	WREG,int_O_tank_pres_need+7	; deco calculation, some rubbish numbers from last dive of
-	movff	WREG,int_O_tank_pres_need+9	; simulation may be shown
-
-	; configure the deco engine:
-	movff	char_O_deco_status,WREG		; bank-safe copy
-	bsf		WREG,DECO_STATUS_0_FLAG		; configure init ...
-	bsf		WREG,DECO_STATUS_1_FLAG		; ... state,
-	bcf		WREG,DECO_PLAN_FLAG			; normal plan mode,
-	bsf		WREG,DECO_CNS_FLAG			; enable CNS calculation (CNS at end of dive),
-	bcf		WREG,DECO_VOLUME_FLAG		; disable gas volume calculation, and
-	bcf		WREG,DECO_ASCENT_FLAG		; disable delayed ascent calculation
-	movff	WREG,char_O_deco_status		; bank-safe copy back
-
-	clrf	WREG
-	movff	WREG,char_O_main_status		; reset char_O_main_status
-
-	movlw	deco_distance
-	movff	WREG,char_I_deco_distance
-	movff	opt_last_stop,char_I_depth_last_deco
-	movff	opt_GF_low,char_I_GF_Low_percentage
-	movff	opt_GF_high,char_I_GF_High_percentage
-
-	bcf		use_agf						; Start with normal GF set
-	bcf		divemode_menu				; clear divemode menu flag
-
-	bcf		alternative_divelayout		; Start with default layout
-
+	movff	WREG,char_O_deco_warnings	; clear any deco warnings remaining from last dive
+	movff	WREG,char_O_deco_info		; clear any deco infos    remaining from last dive
+
+	movlw	deco_distance				; load distance between actual depth and depth used for deco calculation
+	movff	WREG,char_I_deco_distance	; write distance to the deco engine
+
+	movff	opt_last_stop,char_I_depth_last_deco	; write last stop depth to deco engine
+	movff	opt_GF_low,char_I_GF_Low_percentage		; write GF low  to deco engine
+	movff	opt_GF_high,char_I_GF_High_percentage	; write GF high to deco engine
+
+	bcf		onesectoggle				; clear toggle bit for calculation phasing
+	bcf		use_agf						; start with normal GF set
+	bcf		divemode_menu				; clear dive mode menu flag
+	bcf		alternative_divelayout		; start with default layout
 	bcf		blinking_depth_prev			; clear flag for blinking depth
-	bcf		blinking_depth_warning		; clear flag for blinking depth
 	bcf		blinking_depth_toggle		; clear flag for blinking depth
+	bcf		blinking_depth_warning		; clear flag for blinking depth as warning
+	bcf		blinking_depth_attention	; clear flag for blinking depth as attention
+	bcf		max_depth_greater_100m		; clear flag for last max/avg depth was > 100 m
 
 	movlw	d'1'
 	movwf	apnoe_max_pressure+0
 	clrf	apnoe_max_pressure+1
 ;	clrf	apnoe_surface_mins
 ;	clrf	apnoe_surface_secs
-	clrf	apnoe_mins
-	clrf	divemins+0
-	clrf	divemins+1
-
-	; Copy date and time for logbook
+
+	; copy date and time for logbook
 	movff	year,start_year
 	movff	month,start_month
 	movff	day,start_day
@@ -2171,146 +2357,187 @@
 
 	movff	int_O_CNS_fraction+0,CNS_start+0 ; save CNS value at beginning of dive
 	movff	int_O_CNS_fraction+1,WREG		 ; get high byte to WREG
-	bcf	WREG,int_warning_flag			 ; clear warning   flag
-	bcf	WREG,int_attention_flag			 ; clear attention flag
+	bcf		WREG,int_warning_flag			 ; clear warning   flag
+	bcf		WREG,int_attention_flag			 ; clear attention flag
 	movff	WREG,CNS_start+1				 ; move high byte on
 	movff	int_O_gradient_factor+0,GF_start ; save GF value at beginning of dive (only lower byte used for value)
 
-	bcf		no_more_divesecs				 ; =1: do no longer show seconds in divemode
+	bcf		no_more_divesecs			 ; =1: do no longer show seconds in dive mode
 	bcf		divemode_menu_active
 	clrf	menupos1
-	clrf	menupos2						 ; Reset to zero (Zero=no premenu or simulator task)
-	bsf		sensors_agree					 ; init of sensors disagree warning system
-
-	btfsc	FLAG_ccr_mode
-	bra		diveloop_boot_cc
-	btfsc	FLAG_pscr_mode
-	bra		diveloop_boot_cc
-	rcall	dive_boot_oc
-	bra		diveloop_boot_cont
-
-diveloop_boot_cc:
-	rcall	dive_boot_cc
-
-diveloop_boot_cont:
-	; Copy opt_dil_types into backup (For "lost gas" feature)
-	movff	opt_dil_type+0,opt_dil_type_backup+0					; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+1,opt_dil_type_backup+1					; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+2,opt_dil_type_backup+2					; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+3,opt_dil_type_backup+3					; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+4,opt_dil_type_backup+4					; 0=Disabled, 1=First, 2=Normal
-	; Copy opt_gas_types into backup (For "lost gas" feature)
-	movff	opt_gas_type+0,opt_gas_type_backup+0					; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+1,opt_gas_type_backup+1					; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+2,opt_gas_type_backup+2					; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+3,opt_gas_type_backup+3					; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+4,opt_gas_type_backup+4						; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	; Also copy change depths into backup (For "lost gas" feature)
-	movff	char_I_dil_change+0,opt_dil_change_backup+0				; Gas change depths Diluents
-	movff	char_I_dil_change+1,opt_dil_change_backup+1				; Gas change depths Diluents
-	movff	char_I_dil_change+2,opt_dil_change_backup+2				; Gas change depths Diluents
-	movff	char_I_dil_change+3,opt_dil_change_backup+3				; Gas change depths Diluents
-	movff	char_I_dil_change+4,opt_dil_change_backup+4				; Gas change depths Diluents
-	; Also copy change depths into backup (For "lost gas" feature)
-	movff	opt_OC_bail_gas_change+0,opt_OC_bail_gas_change_backup+0; Gas change depths OC/Bailout
-	movff	opt_OC_bail_gas_change+1,opt_OC_bail_gas_change_backup+1; Gas change depths OC/Bailout
-	movff	opt_OC_bail_gas_change+2,opt_OC_bail_gas_change_backup+2; Gas change depths OC/Bailout
-	movff	opt_OC_bail_gas_change+3,opt_OC_bail_gas_change_backup+3; Gas change depths OC/Bailout
-	movff	opt_OC_bail_gas_change+4,opt_OC_bail_gas_change_backup+4; Gas change depths OC/Bailout
-
-	clrf	WREG
-	movff	WREG,better_gas_number		; clear better gas register
-
-	bcf		show_safety_stop			; =1: Show the safety stop
-	clrf	safety_stop_countdown		; Clear count-down
-
-	clrf	samplesecs
+	clrf	menupos2					 ; reset to zero (Zero=no pre-menu or simulator task)
+	bsf		sensors_agree				 ; init of sensors disagree warning system
+
+	bcf		show_safety_stop			; =1: show the safety stop
+	clrf	safety_stop_countdown		; clear count-down
+
+	clrf	samplesecs					; timer for data logging
 	clrf	apnoe_timeout_counter		; timeout in minutes
 	clrf	timeout_counter1+0			; takes care of the timeout (low  byte)
 	clrf	timeout_counter1+1			; takes care of the timeout (high byte)
 	clrf	AlarmType					; Clear all alarms
 	bcf		event_occured				; clear flag
-	clrf	average_depth_hold_total+0
+	clrf	average_divesecs_total+0	; clear non-resettable time accumulator
+	clrf	average_divesecs_total+1
+	clrf	average_depth_hold_total+0	; clear non-resettable average depth
 	clrf	average_depth_hold_total+1
 	clrf	average_depth_hold_total+2
-	clrf	average_depth_hold_total+3	; Clear Non-Resettable Average
-	rcall	reset_average1				; Reset the resettable average depth
-	bcf		decostop_active
-	bcf		better_gas_available		; =1: A better gas is available and a gas change is advised in divemode
-	call	ghostwriter_short_header	; Write short header with divenumber into profile memory
+	clrf	average_depth_hold_total+3
+	call	reset_average				; reset the resettable average depth
+
+ IFDEF _rx_functions
+	btfss	FLAG_tr_enabled				; TR functions enabled?
+	bra		diveloop_boot_0				; NO  - skip TR function initialization
+										; YES - initialize TR function variables
+	banksel	int_O_sac_rate
+	clrf	int_O_sac_rate+0			; clear low byte      of SAC rate
+	clrf	int_O_pressure_need+0		; clear low byte      of 1st pressure need    value
+	clrf	int_O_pressure_need+2		; clear low byte      of 2nd pressure need    value
+	banksel	int_IO_pressure_value
+	clrf	int_IO_pressure_value+0		; clear low byte      of 1st pressure reading value
+	clrf	int_IO_pressure_value+2		; clear low byte      of 2nd pressure reading value
+	clrf	int_I_pressure_drop+0		; clear low byte      of 1st pressure drop    value
+	clrf	int_I_pressure_drop+2		; clear low byte      of 2nd pressure drop    value
+	clrf	char_I_pressure_gas+0		; clear gas selection of 1st pressure reading
+	clrf	char_I_pressure_gas+1		; clear gas selection of 2nd pressure reading
+	clrf	char_I_pressure_age+0		; clear age           of 1st pressure reading
+	clrf	char_I_pressure_age+1		; clear age           of 2nd pressure reading
+	clrf	char_I_pressure_stat+0		; clear status        of 1st pressure reading
+	clrf	char_I_pressure_stat+1		; clear status        of 2nd pressure reading
+	clrf	WREG						; clear WREG
+	bsf		WREG,int_not_avail_flag		; set   WREG to coding for integer numbers -> data not available
+	banksel	int_O_sac_rate
+	movwf	int_O_sac_rate+1			; copy to high byte     of SAC rate
+	movwf	int_O_pressure_need+1		; copy to high byte     of 1st pressure need    value
+	movwf	int_O_pressure_need+3		; copy to high byte     of 1st pressure need    value
+	banksel	int_IO_pressure_value
+	movwf	int_IO_pressure_value+1		; copy to high byte     of 1st pressure reading value
+	movwf	int_IO_pressure_value+3		; copy to high byte     of 2nd pressure reading value
+	movwf	int_I_pressure_drop+1		; copy to high byte     of 1st pressure drop    value
+	movwf	int_I_pressure_drop+3		; copy to high byte     of 1st pressure drop    value
+	banksel	gas__last_1st				; select bank with vars for pressure drop calculation
+	setf	gas__last_1st				; invalidate last gas of 1st reading
+	setf	gas__last_2nd				; invalidate last gas of  2nd reading
+	banksel	common						; back to bank common
+ ENDIF
+
+diveloop_boot_0:
+	bcf		decostop_active				; clear flag for being in deco
+	setf	best_gas_number				; initialize best gas     as not computed yet (255)
+	setf	best_dil_number				; initialize best diluent as not computed yet (255)
+	bcf		better_gas_available		; =1: a better gas     is available and a gas change is advised
+	bcf		better_dil_available		; =1: a better diluent is available and a gas change is advised
+
+	rcall	dive_boot_oc_bail			; basic settings required for all modes
+
+	btfsc	FLAG_oc_mode				; in OC mode?
+	rcall	dive_boot_oc				; YES - add OC mode settings
+
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	rcall	dive_boot_cc				; YES - add CC mode settings
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	rcall	dive_boot_cc_part2			; YES - add CC sensor and SP settings
+
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	rcall	dive_boot_cc				; YES - add CC mode settings
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	rcall	dive_boot_cc_part2			; YES - add CC sensor and SP settings
+
+	call	ghostwriter_short_header	; write short header with dive number into profile memory
 
 	btfsc	simulatormode_active
 	bra		diveloop_boot_1
-	; Normal mode = Surface pressure is the pressure 30mn before dive.
-	SAFE_2BYTE_COPY last_surfpressure_30min, int_I_pres_surface	;copy surfacepressure to deco routine
-	SAFE_2BYTE_COPY last_surfpressure_30min, last_surfpressure	;copy surfacepressure to last_surfpressure for correct depth
+
+	; normal mode = surface pressure is the pressure 30 minutes before dive
+	SAFE_2BYTE_COPY last_surfpressure_30min, int_I_pres_surface	;copy surface pressure to deco routine
+	SAFE_2BYTE_COPY last_surfpressure_30min, last_surfpressure	;copy surface pressure to last_surfpressure for correct depth
 	bra		diveloop_boot_2
 
 diveloop_boot_1:
-	; Simulator mode: Surface pressure is 1bar.
-	movlw	LOW .1000
-	movff	WREG,int_I_pres_surface+0	; LOW copy surface pressure to deco routine
+	; simulator mode: set surface pressure to 1 bar because simulated depths are also based on 1 bar surface pressure
+	movlw	LOW  .1000
+	movff	WREG,int_I_pres_surface+0	; LOW  copy surface pressure to deco routine
 	movlw	HIGH .1000
 	movff	WREG,int_I_pres_surface+1	; HIGH copy surface pressure to deco routine
 
 diveloop_boot_2:
-	SAFE_2BYTE_COPY temperature,minimum_temperature ; Reset Min-Temp registers
+	SAFE_2BYTE_COPY temperature,minimum_temperature ; reset minimum temperature registers
 
 	call	init_recording_params		; set up all the divisors
 
-	bsf		ccr_diluent_setup			; For CCR mode (Required to have better gas working)
-	btfsc	FLAG_ccr_mode				; =1: CCR mode (Fixed ppO2 or Sensor) active
-	bra		divemode_boot2
+	bsf		FLAG_diluent_setup			; for CCR mode (required to have better gas working)
+	btfsc	FLAG_ccr_mode				; =1: CCR mode (fixed ppO2 or Sensor) active
+	bra		diveloop_boot_3
 	btfsc	FLAG_pscr_mode
-	bra		divemode_boot2
-	bcf		ccr_diluent_setup			; For OC mode (Required to have better gas working)
-
-divemode_boot2:
+	bra		diveloop_boot_3
+	bcf		FLAG_diluent_setup			; for OC mode (required to have better gas working)
+
+diveloop_boot_3:
 	bcf		LEDg						; switch off green LED / release reset to RX circuitry
-	bcf		LEDr						; switch off red LED
+	bcf		LEDr						; switch off red   LED
 	bcf		realdive
-	btfss	simulatormode_active		; do not disable in simulator mode!					
-	call	disable_rs232				; Disable RS232
-	btfsc	enable_screen_dumps			; =1: Ignore vin_usb, wait for "l" command (Screen dump)
-	call	enable_rs232				; Also sets to speed_normal ...
-	; Reset divetime seconds
-	movlw	.2							; Start at 2seconds
-	movwf	total_divetime_seconds+0
+	btfss	simulatormode_active		; in simulator mode?
+	call	disable_rs232				; NO - disable RS232
+
+ IFDEF _screendump
+	btfsc	enable_screen_dumps			; =1: ignore vin_usb, wait for "l" command (screen dump)
+	call	enable_rs232				; also sets to speed_normal
+ ENDIF
+
+	; reset dive time seconds
+;	movlw	.2							; start at 2 seconds
+;	movwf	total_divetime_seconds+0
+;	clrf	total_divetime_seconds+1
+;	movwf	divesecs
+;	movwf	apnoe_secs
+;	bsf		divemode2					; displayed dive time is running (dive time starts HERE)
+
+	; clear the timers (start dive times at zero)
+	clrf	total_divetime_seconds+0
 	clrf	total_divetime_seconds+1
-	movwf	divesecs
-	movwf	apnoe_secs
-	bsf		divemode2					; displayed divetime is running (Divetime starts HERE)
-	return								; Done with divemode boot
-
+	clrf	divesecs
+	clrf	divemins+0
+	clrf	divemins+1
+	clrf	apnoe_secs
+	clrf	apnoe_mins
+
+	; divemode2 flag will be set by pressure & timeout evaluation in function set_dive_modes
+
+	return								; done with dive mode boot
+
+
+;=============================================================================
 
 divemode_check_for_warnings:
-	movlw	.1							; One warning at a time in alt. layout mode
+	movlw	.1							; one message at a time in alternative layout
 	btfss	alternative_divelayout
-	movlw	.2							; Two warnings at a time in default layout mode
-	cpfsgt	warning_counter				; only one (or two) warnings active?
-	bra		divemode_check_for_warnings1 ; Yes, update every second
-
-	btfss	secs,0						; Every two seconds...
+	movlw	.2							; two messages at a time in default layout
+	cpfsgt	message_counter				; only one (or two) messages active?
+	bra		divemode_check_for_warnings1; YES - update every second
+
+	btfss	secs,0						; every two seconds...
 	return
-	btfss	secs,1						; Every four seconds...
+	btfss	secs,1						; every four seconds...
 	return
 
 divemode_check_for_warnings1:
-	bcf		warning_active				; Clear flag
-	clrf	warning_counter				; Clear counter
-
-	; warnings sorted by severity, highest severity first
-
-	; Warnings for all modes
-	call	check_warn_battery			; Check if the battery level should be displayed/warned
-	call	check_divetimeout			; Not actually a warning. Check and show the divemode timeout
-
-	btfsc	FLAG_apnoe_mode				; Done for Apnoe or Gauge mode
-	bra		divemode_check_for_warnings2
-	btfsc	FLAG_gauge_mode				; Done for Apnoe or Gauge mode
-	bra		divemode_check_for_warnings2
-
-	; Warnings only in deco modes
+	bcf		message_advice				; clear flag for messages of level advice
+	bcf		message_attention			; clear flag for messages of level attention
+	bcf		message_warning				; clear flag for messages of level warning
+	clrf	message_counter				; clear message counter
+
+	; messages sorted by severity: highest severity warnings first, then attentions, advices and last info
+
+	; warnings for all modes
+	call	check_warn_battery			; check if the battery level should be displayed/warned
+	call	check_divetimeout			; check and show the dive mode timeout (not actually a warning)
+
+	btfsc	FLAG_apnoe_mode				; in Apnoe mode?
+	bra		divemode_check_for_warnings2; YES
+	btfsc	FLAG_gauge_mode				; in gauge mode?
+	bra		divemode_check_for_warnings2; YES
+
+	; warnings applicable only in deco modes
 	rcall	check_ppO2					; check ppO2 and displays warning, if required
 
 	btfss	sensors_agree				; are the sensor values within the threshold range?
@@ -2318,118 +2545,133 @@
 	btfsc	sensors_agree				; are the sensor values within the threshold range?
 	bcf		sensor_warning				; YES - revoke memorized sensor warning
 
-	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
-	btfsc	WREG,outside_warning_lock	; are we outside of the ZH-L16 model?
-	rcall	warn_outside				; YES
+	rcall	check_outside				; check of ZHL16 model violation
 
 	rcall	check_IBCD					; check for IBCD attention or warning
 
-	btfsc	decostop_active				; In deco mode?
-	rcall	check_and_store_gf_violation; Yes, sets warnings, if required
-
-	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
-	btfsc	WREG,mbubble_warning_lock	; do we have a microbubbles warning?
-	rcall	warn_mbubbles				; YES
+	rcall	check_OC_gas_avail			; check if a breathable OC gas is available
+
+	btfsc	decostop_active				; in deco mode?
+	rcall	check_and_store_gf_violation; YES - sets warnings, if required
+
+	rcall	check_mbubbles				; check for micro bubbles
 
 	rcall	check_cns_violation			; Check CNS value and display it, if required
 
-	;btfsc	decostop_active				; In deco mode?
-	rcall	check_gas_needs				; show gas needs warning if any gas need is > threshold
-
-	rcall	check_eod_cns_violation		; Check CNS values for end-of-dive and display warning, if required
-
-	call	TFT_display_ftts			; Show @+x time
-
-	btfsc	use_agf						; In aGF mode?
-	rcall	warn_agf					; Yes, show a warning for it
-
-	btfsc	setpoint_fallback			; =1: Fallback to SP1 due to external O2 sensor failure
-	rcall	warn_fallback				; Show the warning
+	rcall	check_gas_needs_ascent		; show gas needs warning if any gas need for ascent is > threshold
+
+	rcall	check_eod_cns_violation		; check CNS values for end-of-dive and display warning, if required
+
+	rcall	check_display_ftts			; show @+x time
+
+ IFDEF _cave_mode
+	btfsc	FLAG_cave_mode				; cave mode enabled?
+	rcall	check_cavemode				; YES - check cave mode status
+ ENDIF
+
+	btfsc	use_agf						; in aGF mode?
+	rcall	warn_agf					; YES - show memo
+
+	btfsc	setpoint_fallback			; fallback to SP1 due to external O2 sensor failure?
+	rcall	warn_fallback				; YES - show a warning
+
+	btfsc	better_dil_available		; is a better diluent available?
+	rcall	advice_gas_change			; YES - display an advice
+	btfsc	better_gas_available		; is a better gas     available?
+	rcall	advice_gas_change			; YES - display an advice
 
 divemode_check_for_warnings2:
-; Display the warning icon?
-	btfsc	warning_active				; Any warning active?
-	bsf		FLAG_TFT_divemode_warning	; Yes
-	btfss	warning_active				; Any warning active?
-	bsf		FLAG_TFT_divemode_warning_clear ; No, clear warning icon
-
-; Setup warning_page number
-	incf	warning_page,F
-	movf	warning_page,W
+ IFDEF _rx_functions
+	btfss	FLAG_tr_enabled					; TR functions enabled?
+	bra		divemode_check_for_warnings3	; NO  - skip
+	call	check_tr_functions				; YES - check transmitter functions
+	call	check_tr_messages				;     - check SAC attention and switch advice
+ ENDIF
+
+divemode_check_for_warnings3:
+	; Display the attention or warning icon?
+	btfsc	message_advice					; any message of level advice?
+	bsf		FLAG_TFT_divemode_warning		; YES
+	btfsc	message_attention				; any message of level attention?
+	bsf		FLAG_TFT_divemode_warning		; YES
+	btfsc	message_warning					; any message of level warning?
+	bsf		FLAG_TFT_divemode_warning		; YES
+	btfss	FLAG_TFT_divemode_warning		; any message of above levels?
+	bsf		FLAG_TFT_divemode_warning_clear ; NO - clear warning icon
+
+	; Setup message page number
+	incf	message_page,F
+	movf	message_page,W
 	bcf		STATUS,C
-	btfss	alternative_divelayout
-	rlcf	warning_page,W				; *2 (But only in standard layout mode)
-	cpfsgt	warning_counter				; > warning_counter
-	clrf	warning_page				; No, clear
-
-; Clear both rows of warnings if there is nothing to show at all
-	tstfsz	warning_counter				; any warnings?
-	bra		divemode_check_for_warnings3 ; YES - look if second row needs to be cleared
-	bsf		FLAG_TFT_dive_warning_text_clear ; Set flag
+	btfss	alternative_divelayout			; in alternative layout?
+	rlcf	message_page,W					; NO - *2
+	cpfsgt	message_counter					; > message_counter?
+	clrf	message_page					; NO - clear
+
+	; Clear both rows of messages if there is nothing to show at all
+	tstfsz	message_counter					; any messages?
+	bra		divemode_check_for_warnings4	; YES - look if second row needs to be cleared
+	bsf		FLAG_TFT_dive_warning_text_clear; set flag
 	return
-divemode_check_for_warnings3:
-
-
-; Clear 2nd row of warnings if there is nothing to show (on this page)
-	btfss	second_row_warning			; =1: The second row contains a warning
-	bsf		FLAG_TFT_dive_warning_text_clr2	; Set flag for 2nd row
-	return								; Done.
+
+divemode_check_for_warnings4:
+	; Clear 2nd row of messages if there is nothing to show (on this page)
+	btfss	second_row_warning				; =1: the second row contains a warning
+	bsf		FLAG_TFT_dive_warning_text_clr2	; set flag for 2nd row
+	return									; done
 
 	global	check_warn_battery
 check_warn_battery:
 	movff	batt_percent,lo
 	movlw	battery_show_level+1
-	cpfslt	lo
-	return								; No Display, no warning
+	cpfslt	lo							; battery percentage ok?
+	return								; YES - no display, no warning
 	; Display Battery, but warn?
 	movff	batt_percent,lo
 	movlw	color_code_battery_low+1
-	cpfsgt	lo
-	bsf		warning_active				; Set Warning flag
-
-	movlw	.4
-	cpfseq	menupos3					; battery shown in Custom View 4?
-	bra		check_warn_battery2			; No
-	return								; Yes, do not show twice (in custom view and in warning area)
+	cpfsgt	lo							; battery percent below warning threshold?
+	bsf		message_warning				; YES - set warning flag
+	btfsc	alternative_divelayout		; in alternative layout?
+	bra		check_warn_battery2			; YES - show warning
+	movlw	index_clock_batt_surfpress	; NO  - index of custom view clock, battery and surface pressure
+	cpfseq	menupos3					;     - battery shown in custom view?
+	bra		check_warn_battery2			;       NO  - show warning
+	return								;       YES - do not show twice (in custom view and in message area)
 check_warn_battery2:
-	incf	warning_counter,F			; increase counter
-	goto	TFT_update_batt_percent_divemode ; Show percent (And return)
+	incf	message_counter,F			;       increase counter
+	goto	TFT_update_batt_percent_divemode ;  show percent (and return)
 
 check_divetimeout:
-	btfsc	divemode2
-	return								; displayed divetime is not running
-	incf	warning_counter,F			; increase counter
-	goto	TFT_divetimeout				; Show timeout counter (and return)
-
+	btfsc	divemode2					; dive time running?
+	return								; YES - do nothing
+	incf	message_counter,F			; increase counter
+	goto	TFT_divetimeout				; show timeout counter (and return)
 
 check_ppO2:
-	btfsc	FLAG_ccr_mode				; are we in CCR mode?
-	bra		check_ppO2_loop				; YES
-	btfsc	FLAG_pscr_mode				; are we in pSCR mode?
-	bra		check_ppO2_loop				; YES
-	bra		check_ppO2_oc_1				; NO  - neither CCR nor pSCR
-check_ppO2_loop:
-	btfsc	is_bailout					; in bailout?
-	bra		check_ppO2_oc_1				; YES - continue with OC
-	movff	int_O_pure_ppO2+1,hi		; NO  - get upper part of int_O_pure_ppO2
-	btfsc	hi,int_warning_flag			;       ppO2 of the pure diluent to low or high?
-	rcall	check_ppo2_display				;       YES - show warning and return on next line
-	btfsc	hi,int_attention_flag		;       ppO2 of the pure diluent close to setpoint?
-	rcall	check_ppo2_display				;       YES - show warning and return on next line
-	bra		check_ppO2_oc_2				;             skip attention threshold test on breathed ppO2
-check_ppO2_oc_1:
-	movff	int_O_breathed_ppO2+1,WREG	; get upper part of int_O_breathed_ppO2
-	btfsc	WREG,int_attention_flag		; breathed ppO2 just above attention threshold?
-	bra		check_ppo2_display			; YES - show ppO2
-check_ppO2_oc_2:
-	movff	int_O_breathed_ppO2+1,WREG	; get upper part of int_O_breathed_ppO2 (perhaps again)
-	btfsc	WREG,int_low_flag			; breathed ppO2 to low?
+	btfsc	FLAG_oc_mode				; are we in OC mode?
+	bra		check_ppO2_1				; YES - continue with breathed gas
+	btfsc	FLAG_bailout_mode			; NO  - in bailout?
+	bra		check_ppO2_1				;       YES - continue with breathed gas
+	; CCR / pSCR mode - checks on pure diluent
+	movff	int_O_pure_ppO2+0,lo		; get value and attention/warning flags for the pure diluent
+	movff	int_O_pure_ppO2+1,hi		;
+	btfsc	hi,int_warning_flag			; ppO2 of the pure diluent to low or high?
+	rcall	check_ppO2_dw				; YES - show warning and return on next line
+	btfsc	hi,int_attention_flag		; ppO2 of the pure diluent in attention state?
+	rcall	check_ppO2_da				; YES - show attention and return on next line
+	; all modes - checks on breathed gas (OC or from loop)
+check_ppO2_1:
+	movff	int_O_breathed_ppO2+0,lo	; get value and attention/warning flags for the breathed gas
+	movff	int_O_breathed_ppO2+1,hi	; get warnings for breathed gas
+	btfsc	hi,int_attention_flag		; breathed ppO2 in attention state (when in loop mode, no attention will be generated)?
+	bra		check_ppo2_display_a		; YES - set attention flag and show ppO2
+	btfsc	hi,int_low_flag				; breathed ppO2 to low?
 	bra		check_ppO2_low				; YES - record the warning and show ppO2
-	btfsc	WREG,int_high_flag			; breathed ppO2 to high?
+	btfsc	hi,int_high_flag			; breathed ppO2 to high?
 	bra		check_ppO2_high				; YES - record the warning and show ppO2
 	TSTOSS	opt_showppo2				; show ppO2 anyhow? (0 = no, 1 = show always)
-	return								; NO  - no warnings, no show
-	bra		check_ppo2_display			; YES - just show ppO2
+	return								; NO  - no warnings, no show - done
+	bra		check_ppO2_common_2			; YES - but only when in OC or bailout...
 check_ppO2_low:
 	movlw	d'4'						; set type of alarm (ppO2 low)
 	bra		check_ppO2_common			; continue with common part
@@ -2437,37 +2679,47 @@
 	movlw	d'5'						; set type of alarm (ppO2 high)
 check_ppO2_common:
 	movwf	AlarmType					; copy alarm type to alarm register
-	bsf		event_occured				; set event flag
-	bsf		warning_active				; set warning flag
-	btfsc	is_bailout					; are we in bailout?
-	bra		check_ppo2_display			; YES - skip CCR/pSCR checks
-	btfsc	FLAG_ccr_mode				; are we in CCR mode?
-	return								; YES - no extra warning required
-	btfsc	FLAG_pscr_mode				; are we in pSCR mode?
-	return								; YES - no extra warning required
-check_ppo2_display:						; display warning if ppO2 is not already shown in custom view
-	movlw	.9
-	cpfseq	menupos3					; ppO2 shown in Custom View 9?
-	bra		check_ppO2_a				; No
-	return								; Yes, do not show twice (in custom view and in warning area)
-check_ppO2_a:
-	movlw	.11
-	cpfseq	menupos3					; ppO2 shown in Custom View 11?
-	bra		check_ppO2_b				; No
-	return								; Yes, do not show twice (in custom view and in warning area)
+	bsf		event_occured				; set event   flag
+	bsf		message_warning				; show warning sign
+check_ppO2_common_2:
+	btfsc	FLAG_oc_mode				; are we in OC mode?
+	bra		check_ppo2_display			; YES
+	btfsc	FLAG_bailout_mode			; are we in bailout mode?
+	bra		check_ppo2_display			; YES
+	return								; NO  - in loop mode, ppO2 is already shown via setpoint display
+check_ppo2_display_a:
+	bsf		message_attention			; show attention sign
+check_ppo2_display:
+	btfsc	alternative_divelayout		; in alternative layout?
+	bra		check_ppO2_d				; YES - show warning
+	movlw	index_ppo2_ead_end_cns		; NO  - index of custom view ppO2, EAD/END and CNS)
+	cpfseq	menupos3					;       ppO2 shown?
+	bra		check_ppO2_b				;       NO
+	return								;       YES - do not show twice (in custom view and in warning area)
 check_ppO2_b:
-	movlw	.12
-	cpfseq	menupos3					; ppO2 shown in Custom View 12?
-	bra		check_ppO2_c				; No
-	return								; Yes, do not show twice (in custom view and in warning area)
-check_ppO2_c:
-	movlw	.10
-	cpfseq	menupos3					; ppO2 shown in Custom View 10?
-	bra		check_ppO2_d				; No
-	return								; Yes, do not show twice (in custom view and in warning area)
+	movlw	index_pscr_info				; index of custom view with pSCR data
+	cpfseq	menupos3					; ppO2 shown?
+	bra		check_ppO2_d				; NO  - show warning
+	return								; YES - do not show twice (in custom view and in warning area)
+check_ppO2_dw:
+	bsf		message_warning				; show warning sign
+check_ppO2_da:
+	bsf		message_attention			; show attention sign (no problem if a warning sign is set as well, as it will take priority)
 check_ppO2_d:
-	incf	warning_counter,F			; increase counter
-	goto	TFT_display_ppo2			; show breathed gas or diluent ppO2 warning (and return)
+	incf	message_counter,F			; increase counter
+	goto	TFT_display_ppo2_warning	; show breathed gas or diluent ppO2 warning (and return)
+
+
+check_display_ftts:
+	movff	char_I_extra_time,lo		; get extra time
+	tstfsz	lo							; extra time > 0 ?
+	bra		check_display_ftts_1		; YES - continue checking bailout condition
+	return								; NO  - done
+check_display_ftts_1:
+	btfsc	FLAG_bailout_mode			; in bailout mode?
+	return								; YES - in bailout no fTTS will be computed, so nothing to display
+	incf	message_counter,F			; NO  - increase counter
+	goto	TFT_display_ftts			;     - show @+x time
 
 
 	global	check_cns_violation
@@ -2475,32 +2727,35 @@
 	; Check if CNS should be displayed
 	movff	int_O_CNS_fraction+1,WREG	; get high byte
 	btfsc	WREG,int_warning_flag		; warning flag set?
-	bra		check_cns_violation2		; Yes - issue warning
-	btfsc	WREG,int_attention_flag		; attention flag set?
-	bra		display_cns_violation		; YES - just display CNS
-	return								; No  - no display, no warning
-check_cns_violation2:
-	bsf		warning_active				; Set Warning flag
-display_cns_violation:					; Show CNS if not shown in the custom view
-	movlw	.11
-	cpfseq	menupos3					; CNS shown in Custom View?
-	bra		display_cns_violation2		; No
-	return								; Yes, do not show twice (in custom view and in warning area)
-display_cns_violation2:
-	movlw	.8
-	cpfseq	menupos3					; CNS shown through Custom View 8 right now?
-	bra		display_cns_violation3		; No
-	return								; Yes, do not show twice (in custom view and in warning area)
-display_cns_violation3:
-	incf	warning_counter,F			; increase counter
-	goto	TFT_display_cns				; Show CNS (and return)
+	bra		check_cns_violation_1		; YES - issue warning
+	btfsc	WREG,int_attention_flag		; NO  - attention flag set?
+	bra		check_cns_violation_2		;       YES - issue attention
+	return								;       NO  - done
+check_cns_violation_1:
+	bsf		message_warning				; show warning sign
+check_cns_violation_2:
+	bsf		message_attention			; show attention sign
+	btfsc	alternative_divelayout		; in alternative layout?
+	bra		check_cns_violation_4		; YES - show attention
+	movlw	index_ppo2_ead_end_cns		; NO  - index of custom view ppO2, EAD/END and CNS
+	cpfseq	menupos3					;     - CNS shown?
+	bra		check_cns_violation_3		;       NO
+	return								;       YES - do not show twice (in custom view and in warning area)
+check_cns_violation_3:
+	movlw	index_CNS					; index of custom view with CNS values
+	cpfseq	menupos3					; CNS shown?
+	bra		check_cns_violation_4		; NO
+	return								; YES - do not show twice (in custom view and in warning area)
+check_cns_violation_4:
+	incf	message_counter,F			; increase counter
+	goto	TFT_display_cns				; show CNS (and return)
 
 
 	global	check_eod_cns_violation		; check end-of-dive CNS values
 check_eod_cns_violation:
 	movff	int_O_CNS_fraction+1,WREG	; get high-byte of current CNS value
 	btfsc	WREG,int_warning_flag		; current CNS value in warning state?
-	return								; YES - inhibit eod warning if current CNS is already in warning
+	return								; YES - inhibit end-of-dive warning if current CNS is already in warning
 	movff	int_O_normal_CNS_fraction+1,WREG
 	btfsc	WREG,int_invalid_flag		; flag for invalid value set?
 	bra		check_eod_cns_violation1	; YES - continue with checking the other CNS value
@@ -2511,16 +2766,18 @@
 	btfsc	WREG,int_invalid_flag		; flag for invalid value set?
 	return								; YES - done with CNS checking
 	btfsc	WREG,int_warning_flag		; NO  - flag for warning set?
-	bra		check_eod_cns_violation2	;       Yes - issue warning
+	bra		check_eod_cns_violation2	;       YES - issue warning
 	return								;       NO  - done with CNS checking
-check_eod_cns_violation2:				; YES - issue warning
-	bsf		warning_active				; set Warning flag
-	movlw	.8							; issue textual warning if CNS values are not shown in the custom view right now
-	cpfseq	menupos3					; CNS values shown through Custom View 8 right now?
-	bra		display_eod_cns_violation	; NO  - issue textual warning
-	return								; YES - do not show twice (in custom view and in warning area)
+check_eod_cns_violation2:				; issue warning (actually only on attention level)
+	bsf		message_attention			; show attention sign
+	btfsc	alternative_divelayout		; in alternative layout?
+	bra		display_eod_cns_violation	; YES - show warning
+	movlw	index_CNS					; NO  - index of custom view with CNS values
+	cpfseq	menupos3					;     - CNS values shown?
+	bra		display_eod_cns_violation	;       NO  - issue textual warning
+	return								;       YES - do not show twice (in custom view and in warning area)
 display_eod_cns_violation:
-	incf	warning_counter,F			; increase counter
+	incf	message_counter,F			; increase counter
 	goto	TFT_display_eod_cns			; issue CNS at end-of-dive warning (and return)
 
 
@@ -2532,7 +2789,7 @@
 	movlw	d'2'							; YES - set type of alarm
 	movwf	AlarmType						;		copy to alarm register
 	bsf		event_occured					;		set event   flag
-	bsf		warning_active					;		set warning flag
+	bsf		message_warning					;		set warning flag
 	bra		check_and_store_gf_violation3	;		show gf warning
 check_and_store_gf_violation2:
 	btfsc	WREG,int_attention_flag			; check if the attention flag is set
@@ -2543,56 +2800,268 @@
 	btfss	WREG,IBCD_warning				;			 is the IBCD warning flag set?
 	bra		check_and_store_gf_violation4	;			 NO  - continue checking for deco info
 check_and_store_gf_violation3:				;			 YES - show gf
-	bsf		warning_active					; set Warning flag
-	incf	warning_counter,F				; increase counter
+	bsf		message_attention				; show attention sign
+	incf	message_counter,F				; increase counter
 	goto	TFT_warning_gf					; show GF (and return)
 check_and_store_gf_violation4:				; check for deco info
-	btfss	divemode						; in divemode?
+	btfss	divemode						; in dive mode?
 	return									; NO  - done, return
-	movff	char_O_deco_warnings,WREG		; YES - get the deco warnings vector
-	btfss	WREG,deco_flag					;       check if the deco flag is set
-	return									;       NO  - all done, return
-	incf	warning_counter,F				;       YES - increase counter
-	goto	TFT_info_deco					;             show deco info
-
-
-warn_outside:
-	incf	warning_counter,F			; increase counter
-	bsf		warning_active				; Set Warning flag
-	goto	TFT_warning_outside			; show outside warning (and return)
-
-
-	global	warn_mbubbles
-warn_mbubbles:
-	incf	warning_counter,F			; increase counter
-	bsf		warning_active				; Set Warning flag
-	goto	TFT_warning_mbubbles		; show microbubbles warning (and return)
-	
+	btfsc	FLAG_bailout_mode				; YES - in bailout mode?
+	return									;       YES - done, return (deco_decreasing flag is not updated when in bailout mode)
+	movff	char_O_deco_info,WREG			;       NO  - get the deco info vector
+	btfss	WREG,deco_decreasing			;             check if the deco_decreasing flag is set
+	return									;             NO  - done, return
+	incf	message_counter,F				;             YES - increase counter
+	goto	TFT_info_deco					;                 - show deco info
+
+
+check_outside:
+	movff	char_O_deco_warnings,WREG	; bank-safe copy of deco warnings
+	btfss	WREG,outside_warning_lock	; are we outside of the ZH-L16 model?
+	return								; NO  - done
+	incf	message_counter,F			; YES - increase counter
+	bsf		message_attention			;     - show attention sign
+	btfsc	WREG,outside_warning		;     - are we outside the ZH-L16 model right now (-> warning)?
+	bsf		message_warning				;     - set warning flag
+	goto	TFT_warning_outside			;     - show outside-ZHL-model warning/attention (and return)
+
+
+	global	check_mbubbles
+check_mbubbles:
+	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
+	btfsc	WREG,mbubble_warning		; are we in micro bubbling zone right now?
+	bra		check_mbubbles_warn			; YES
+	btfss	WREG,mbubble_warning_lock	; were we in micro bubbling zone?
+	return								; NO  - done
+check_mbubble_att						; YES - attention level
+	incf	message_counter,F			; increase counter
+	bsf		message_attention			; show attention sign
+	goto	TFT_warning_mbubbles		; show micro bubble attention (and return) - TFT_warning_mbubbles switches by itself between attention and warning
+check_mbubbles_warn:					; locked micro bubbles - warning level if at issue, attention level if locked
+	incf	message_counter,F			; increase counter
+	bsf		message_warning				; set warning flag
+	goto	TFT_warning_mbubbles		; show micro bubbles warning (and return)
+
+ IFDEF _cave_mode
+check_cavemode:
+	incf	message_counter,F			; increase counter
+	btfsc	FLAG_dive_turned			; dive turned?
+	goto	TFT_info_dive_turned		; YES - show info that dive is turned
+	btfsc	FLAG_cave_mode_shutdown		; NO  - has cave mode shut down?
+	goto	TFT_warn_cave_shutdown		;       YES - show that cave mode has shut down
+	goto	TFT_info_cave_mode			;       NO  - show that cave mode is active
+ ENDIF
+
 warn_agf:
-	incf	warning_counter,F			; increase counter
-	goto	TFT_warning_agf				; Show aGF warning (and return)
+	incf	message_counter,F			; increase counter
+	goto	TFT_warning_agf				; show aGF warning (and return)
 
 warn_fallback:
-	incf	warning_counter,F			; increase counter
-	bsf		warning_active				; Set Warning flag
-	goto	TFT_warning_fallback		; Show fallback warning (and return)
-
-
-check_gas_needs:
-	banksel	int_O_tank_pres_need
-	movf	int_O_tank_pres_need+1,w	; get               HIGH(pres need of 1st tank)
-	iorwf	int_O_tank_pres_need+3,w	; inclusive or with HIGH(pres need of 2nd tank)
-	iorwf	int_O_tank_pres_need+5,w	; inclusive or with HIGH(pres need of 3rd tank)
-	iorwf	int_O_tank_pres_need+7,w	; inclusive or with HIGH(pres need of 4th tank)
-	iorwf	int_O_tank_pres_need+9,w	; inclusive or with HIGH(pres need of 5th tank)
+	incf	message_counter,F			; increase counter
+	bsf		message_warning				; set warning flag
+	goto	TFT_warning_fallback		; show fallback warning (and return)
+
+
+ IFDEF _rx_functions
+
+check_tr_messages:
+	movff	int_O_sac_rate+1,WREG		; bank-safe copy of current SAC rate
+	btfss	WREG,int_attention_flag		; attention flag set?
+	bra		check_tr_messages2			; NO  - skip
+	btfsc	WREG,int_not_avail_flag		; SAC rate available?
+	bra		check_tr_messages2			; NO  - continue with swap advice
+	bsf		message_attention			; YES - show attention sign
+	btfsc	alternative_divelayout		;     - in alternative layout?
+	bra		check_tr_messages1			;       YES - show attention message
+	movlw	index_pressures_SAC			;       NO  - index of custom view with SAC rate
+	cpfseq	menupos3					;           - SAC rate shown right now?
+	bra		check_tr_messages1			;             NO  - show attention message
+	bra		check_tr_messages2			;             YES - do not show twice, continue with swap advice
+check_tr_messages1:
+	incf	message_counter,F			; increase counter
+	call	TFT_attention_sac			; show SAC attention
+check_tr_messages2:
+	movff	char_O_deco_info,WREG		; bank-safe copy of deco info vector
+	btfss	WREG,ind_double_switch		; swap tank flag set?
+	return								; NO
+	incf	message_counter,F			; YES - increase counter
+	bsf		message_advice				;     - show advice sign
+	goto	TFT_advice_switch			;     - show swap advice
+
+
+#DEFINE show_custview			ul,0		; show pressure readings custom view
+#DEFINE show_transmitter		ul,1		; show transmitter attention
+#DEFINE show_pres_warning		ul,2		; show transmitter pressure warning
+#DEFINE show_pres_attention		ul,3		; show transmitter pressure attention
+
+check_tr_functions:
+	clrf	ul								; set all messages as not shown yet
+	btfsc	alternative_divelayout			; in alternative layout?
+	bra		check_tr_functions_tr1			; YES - continue with checking transmitter 1
+	movlw	index_pressures_SAC				; NO  - index of custom view pressure readings
+	cpfseq	menupos3						;     - pressure readings shown?
+	bra		check_tr_functions_tr1			;       NO  - continue with checking transmitter 1
+	bsf		show_custview					;       YES - suppress redraw by faking it has already been redrawn
+check_tr_functions_tr1:
+	movff	char_I_pressure_stat+0,WREG		; get status of 1st pressure reading
+	rcall	check_tr_functions_helper1		; check for transmitter 1 lost
+	rcall	check_tr_functions_helper2		; check for transmitter 1 low battery
+	movff	int_IO_pressure_value+1,WREG	; get high byte of 1st pressure reading
+	rcall	check_tr_functions_helper3		; check for transmitter 1 pressure warning
+	rcall	check_tr_functions_helper4		; check for transmitter 1 pressure attention
+check_tr_functions_tr2:
+	movff	char_I_pressure_stat+1,WREG		; get status of 2nd pressure reading
+	rcall	check_tr_functions_helper5		; check for transmitter 2 lost
+	rcall	check_tr_functions_helper6		; check for transmitter 2 low battery
+	movff	int_IO_pressure_value+3,WREG	; get high byte of 2nd pressure reading
+	rcall	check_tr_functions_helper7		; check for transmitter 2 pressure warning
+	rcall	check_tr_functions_helper8		; check for transmitter 2 pressure attention
+check_tr_functions_show_xmtr:
+	btfss	show_transmitter				; shall show transmitter message?
+	bra		check_tr_functions_show_warn	; NO  - continue with pressure warning
+	bsf		message_attention				; YES - set flag for attention
+	incf	message_counter,F				;     - increase counter
+	call	TFT_attention_transmitter		;     - show transmitter attention message
+check_tr_functions_show_warn:
+	btfss	show_pres_warning				; shall show pressure warning?
+	bra		check_tr_functions_show_att		; NO  - continue with pressure attention
+	bsf		message_warning					; YES - set flag for warning
+	incf	message_counter,F				;     - increase counter
+	goto	TFT_warning_pres_reading		;     - pressure reading warning message and done then
+check_tr_functions_show_att:
+	btfss	show_pres_attention				; shall show pressure attention?
+	return									; NO  - done
+	bsf		message_attention				; YES - set flag for attention
+	incf	message_counter,F				;     - increase counter
+	goto	TFT_attention_pres_reading		;     - pressure reading warning message and done then
+
+check_tr_functions_helper1:
+	btfsc	WREG,char_transmitter_lost		; transmitter 1 lost?
+	bra		check_tr_functions_helper1a		; YES - show transmitter attention message
+	bcf		transmitter1_lost				; NO  - clear flag for old lost attention
+	return									;     - done
+check_tr_functions_helper1a:
+	bsf		show_transmitter				; show transmitter attention
+	btfsc	transmitter1_lost				; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter1_lost				; YES - memorize it's an old message now
+	bra		check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_helper2:
+	btfsc	WREG,char_transmitter_low_bat	; transmitter 1 low battery?
+	bra		check_tr_functions_helper2a		; YES - show transmitter attention message
+	bcf		transmitter1_battery			; NO  - clear flag for old battery attention
+	return									;     - done
+check_tr_functions_helper2a:
+	bsf		show_transmitter				; show transmitter attention
+	btfsc	transmitter1_battery			; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter1_battery			; YES - memorize it's an old message now
+	bra		check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_helper3:
+	btfsc	WREG,int_warning_flag			; transmitter 1 pressure warning?
+	bra		check_tr_functions_helper3a		; YES - show pressure reading message as warning
+	bcf		transmitter1_pres_warn			; NO  - clear flag for old warning
+	return									;     - done
+check_tr_functions_helper3a:
+	bsf		show_pres_warning				; show pressure warning
+	btfsc	transmitter1_pres_warn			; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter1_pres_warn			; YES - memorize it's an old message now
+	bra		check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_helper4:
+	btfsc	WREG,int_attention_flag			; transmitter 1 pressure attention?
+	bra		check_tr_functions_helper4a		; YES - show pressure reading message as attention
+	bcf		transmitter1_pres_att			; NO  - clear flag for old attention
+	return									;     - done
+check_tr_functions_helper4a
+	bsf		show_pres_attention				; show pressure attention
+	btfsc	transmitter1_pres_att			; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter1_pres_att			; YES - memorize it's an old message now
+	bra		check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_helper5:
+	btfsc	WREG,char_transmitter_lost		; transmitter 2 lost?
+	bra		check_tr_functions_helper5a		; YES - show transmitter attention message
+	bcf		transmitter2_lost				; NO  - clear flag for old lost attention
+	return									;     - done
+check_tr_functions_helper5a:
+	bsf		show_transmitter				; show transmitter attention
+	btfsc	transmitter2_lost				; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter2_lost				; YES - memorize it's an old message now
+	bra		check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_helper6:
+	btfsc	WREG,char_transmitter_low_bat	; transmitter 2 low battery?
+	bra		check_tr_functions_helper6a		; YES - show transmitter attention message
+	bcf		transmitter2_battery			; NO  - clear flag for old battery attention
+	return									;     - done
+check_tr_functions_helper6a:
+	bsf		show_transmitter				; show transmitter attention
+	btfsc	transmitter2_battery			; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter2_battery			; YES - memorize it's an old message now
+	bra		check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_helper7:
+	btfsc	WREG,int_warning_flag			; transmitter 2 pressure warning?
+	bra		check_tr_functions_helper7a		; YES - show pressure reading message as warning
+	bcf		transmitter2_pres_warn			; NO  - clear flag for old warning
+	return									;     - done
+check_tr_functions_helper7a:
+	bsf		show_pres_warning				; show pressure warning
+	btfsc	transmitter2_pres_warn			; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter2_pres_warn			; YES - memorize it's an old message now
+	bra		check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_helper8:
+	btfsc	WREG,int_attention_flag			; transmitter 2 pressure attention?
+	bra		check_tr_functions_helper8a		; YES - show pressure reading message as attention
+	bcf		transmitter2_pres_att			; NO  - clear flag for old attention
+	return									;     - done
+check_tr_functions_helper8a
+	bsf		show_pres_attention				; show pressure attention
+	btfsc	transmitter2_pres_att			; is it a new message?
+	return									; NO  - do not show the pressure readings custom view again
+	bsf		transmitter2_pres_att			; YES - memorize it's an old message now
+	;bra	check_tr_functions_show_cv		;     - show custom view
+
+check_tr_functions_show_cv:
+	btfsc	show_custview					; is the pressure readings custom view not shown yet shown?
+	return									; NO  - already shown, done
+	bsf		show_custview					; YES - mark as shown
+	btfsc	alternative_divelayout			;     - in alternative layout?
+	call	switch_layout_to_normal			;       YES - switch to normal layout
+	movlw	index_pressures_SAC-1			;       custom view number one below pressure readings
+	movwf	menupos3						;       set custom view number
+	bsf		toggle_customview				;       initiate toggle to desired custom view ->  pressure readings view will be shown
+	return									;       done
+
+ ENDIF
+
+
+check_gas_needs_ascent:
+	banksel	int_O_ascent_pres_need
+	movf	int_O_ascent_pres_need+1,w	; get               high byte from pres need of 1st tank
+	iorwf	int_O_ascent_pres_need+3,w	; inclusive or with high byte from pres need of 2nd tank
+	iorwf	int_O_ascent_pres_need+5,w	; inclusive or with high byte from pres need of 3rd tank
+	iorwf	int_O_ascent_pres_need+7,w	; inclusive or with high byte from pres need of 4th tank
+	iorwf	int_O_ascent_pres_need+9,w	; inclusive or with high byte from pres need of 5th tank
 	banksel	common
 	btfsc	WREG,int_invalid_flag		; check if invalid flag is set
 	return								; YES - no further checking required
-	btfsc	WREG,int_warning_flag		; NO  - check if any gas has a pres_need >= pres_fill
-	bsf		warning_active				; YES - set warning flag
-	btfsc	WREG,int_warning_flag		; NO  - check if any gas has a pres_need >= pres_fill
+	btfsc	WREG,int_warning_flag		; check if any gas has a pres_need >= pres_fill
+	bsf		message_warning				; YES - set warning flag
+	btfsc	WREG,int_warning_flag		; check if any gas has a pres_need >= pres_fill
 	goto	TFT_warning_gas_needs_warn	; Yes - show a warning
-	btfsc	WREG,int_attention_flag		; NO  - check if any gas has a pres_need >= pres_fill * threshold
+	btfsc	WREG,int_attention_flag		; check if any gas has a pres_need >= pres_fill * threshold
+	bsf		message_attention			; YES - set attention flag
+	btfsc	WREG,int_attention_flag		; check if any gas has a pres_need >= pres_fill * threshold
 	goto	TFT_warning_gas_needs_att	; YES - show an attention
 	bcf		gas_needs_attention			; NO  - clear flag for a new attention
 	bcf		gas_needs_warning			;       clear flag for a new warning
@@ -2600,8 +3069,8 @@
 
 
 check_warn_sensors_disagree:
-	incf	warning_counter,F			; increase counter
-	bsf		warning_active				; YES - set Warning flag
+	incf	message_counter,F			; increase counter
+	bsf		message_warning				; YES - set warning flag
 	goto	TFT_warning_sensor_disagree	;       show sensor disagree warning (and return)
 
 
@@ -2611,75 +3080,119 @@
 	movff	char_O_deco_warnings,WREG	; YES - get deco warnings vector
 	btfss	WREG,IBCD_warning			;       IBCD warning flag set?
 	return								;       NO  - return
-	incf	warning_counter,F			;       YES - increase counter
+	incf	message_counter,F			;       YES - increase counter
 	goto	TFT_warning_IBCD			;             write warning to display
 
 
+check_OC_gas_avail:
+	tstfsz	best_gas_number				; is a breathable gas available?
+	return								; > 0 : a breathable gas is available
+	btfsc	FLAG_ccr_mode				; = 0 : problem - in CCR mode?
+	bra		check_OC_gas_avail_1		; YES - real problem
+	btfsc	FLAG_pscr_mode				; NO  - in PSCR mode?
+	bra		check_OC_gas_avail_1		;       YES - real problem
+	return								;       NO  - neither CCR nor pSCR mode, suppress warning
+check_OC_gas_avail_1:
+	btfsc	FLAG_bailout_mode			; in bailout?
+	return								; YES - suppress warning
+	incf	message_counter,F			; NO  - increase counter
+	bsf		message_attention			;       set attention flag
+	goto	TFT_warning_no_BO_gas		;       show message (and return)
+
+
+advice_gas_change:
+	bsf		message_advice				; show advice sign
+	incf	message_counter,F			; increase counter
+	goto	TFT_advice_gas_change
+
+
 	global	restart_deco_engine
 	global	restart_deco_engine_wo_ceiling
 restart_deco_engine:
-	; make bank save copies and set flags for invalid data
+	; invalidate ceiling
 	movff	int_O_ceiling+1,WREG
 	bsf		WREG,char_invalid_flag		; int_O_ceiling has its invalid flag on a char's position!
 	movff	WREG,int_O_ceiling+1
 
 restart_deco_engine_wo_ceiling:
-	; make more bank save copies and set more flags for invalid data
+	; invalidate deco data (stop table data)
 	movff	char_O_deco_gas+0,WREG
 	bsf		WREG,char_invalid_flag
 	movff	WREG,char_O_deco_gas+0
 
+	; invalidate ascent time (normal plan)
 	movff	int_O_ascenttime+1,WREG
 	bsf		WREG,int_invalid_flag
 	movff	WREG,int_O_ascenttime+1
 
-	movff	int_O_alternate_ascenttime+1,WREG
-	bsf		WREG,int_invalid_flag
-	movff	WREG,int_O_alternate_ascenttime+1
-
+	; invalidate CNS at end of dive in normal plan
 	movff	int_O_normal_CNS_fraction+1,WREG
 	bsf		WREG,int_invalid_flag
 	movff	WREG,int_O_normal_CNS_fraction+1
 
+	; restart deco engine
+	movff	char_O_main_status,WREG		; get current main engine configuration
+	bcf		WREG,DECO_COMPLETED_NORM	; eventually clear flag stating completion of normal plan
+	bsf		WREG,DECO_COMPLETED_ALT		; fake we came from alternative plan to force normal plan to be done next
+	movff	WREG,char_O_main_status		; write back new configuration
+	movff	char_O_deco_status,WREG		; get current deco engine status
+	bcf		WREG,DECO_STATUS_0_FLAG		; set status flags to...
+	bcf		WREG,DECO_STATUS_1_FLAG		; ... DECO_STATUS_START
+	movff	WREG,char_O_deco_status		; write back new configuration to restart deco computations
+
+inval_alternative_plan_data:
+	; invalidate ascent time (alternative plan)
+	movff	int_O_alternate_ascenttime+1,WREG
+	bsf		WREG,int_invalid_flag
+	movff	WREG,int_O_alternate_ascenttime+1
+
+	; invalidate CNS at end of dive in alternative plan
 	movff	int_O_alternate_CNS_fraction+1,WREG
 	bsf		WREG,int_invalid_flag
 	movff	WREG,int_O_alternate_CNS_fraction+1
 
-	movff	int_O_tank_pres_need+1,WREG
+	; invalidate ascent gas needs
+	movff	int_O_ascent_pres_need+1,WREG
 	bsf		WREG,int_invalid_flag
-	movff	WREG,int_O_tank_pres_need+1
-
-	; restart deco engine
-	movff	char_O_deco_status,WREG		; get current deco engine configuration
-	bcf		WREG,DECO_STATUS_0_FLAG		; set status flags to...
-	bcf		WREG,DECO_STATUS_1_FLAG		; ... DECO_STATUS_START
-	bsf		WREG,DECO_PLAN_FLAG			; fake we came from alternative plan to force normal plan to be done next
-	movff	WREG,char_O_deco_status		; write back new configuration to restart deco computations
+	movff	WREG,int_O_ascent_pres_need+1
+
+ IFDEF _rx_functions
+	; invalidate pressure needs (TR functions)
+	movff	int_O_pressure_need+1,WREG
+	bsf		WREG,int_not_avail_flag
+	movff	WREG,int_O_pressure_need+1
+	movff	int_O_pressure_need+3,WREG
+	bsf		WREG,int_not_avail_flag
+	movff	WREG,int_O_pressure_need+3
+ ENDIF
+
+	; update display depended on NDL or deco mode
+	bsf		FLAG_TFT_display_ndl_or_deko
 
 	return
 
 ;=============================================================================
-; simulator mode
+; Simulator Mode
 ;
 
 	global	do_demo_divemode
 do_demo_divemode:
-	call	option_save_all					; Save all settings into EEPROM before starting simulation
+	call	TFT_ClearScreen					; blank screen
+	call	option_save_all					; save all settings into EEPROM before starting simulation
 	call	deco_push_tissues_to_vault		; C-code: back-up status of the real tissues
-	banksel	common							; Bank1
-
-	; +++ COMMENTED OUT FOR TESTING PURPOSE ONLY !!! +++
-	; +++ DO NOT COMMENT OUT IN OPERATIONAL USE  !!! +++
-	;
-	bsf		restore_deco_data			; Restore tissue and CNS after simulator use
+	banksel	common							; bank 1
+
+	; +++ COMMENT OUT FOR TESTING PURPOSE ONLY  !!! +++
+	bsf		restore_deco_data				; restore tissue and CNS after simulator use
+	; +++ DO NOT COMMENT OUT IN OPERATIONAL USE !!! +++
 
 	bcf		pressure_refresh
-	btfss	pressure_refresh				; Wait for sensor
+	btfss	pressure_refresh				; wait for sensor
 	bra		$-2
 
-	bsf		simulatormode_active			; Set Flag
-	; Compute dive ambient conditions
-	banksel	char_I_bottom_depth
+	bsf		simulatormode_active			; set flag
+
+	banksel	char_I_bottom_depth				; compute dive ambient conditions
 	movf	char_I_bottom_depth,W
 	mullw	.100
 	movff	PRODL,rel_pressure+0
@@ -2690,9 +3203,9 @@
 	movlw	HIGH (.1000)
 	addwfc	PRODH,W
 	movff	WREG,sim_pressure+1
-	banksel common							; Bank1
+	banksel	common							; bank 1
 
 	bsf		divemode
-	goto	diveloop						; Switch into Divemode!
+	goto	diveloop						; switch into dive mode
 
 	END
\ No newline at end of file