diff src/divemode.asm @ 560:b7eb98dbd800

bump to 2.96beta (REFACTORED VERSION)
author heinrichsweikamp
date Wed, 31 Jan 2018 19:39:37 +0100
parents 98c564a2d6cc
children 54346c651b6a
line wrap: on
line diff
--- a/src/divemode.asm	Wed Dec 27 14:34:11 2017 +0100
+++ b/src/divemode.asm	Wed Jan 31 19:39:37 2018 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemode.asm
+;   File divemode.asm								REFACTORED VERSION V2.96a
 ;
 ;   Divemode
 ;
@@ -9,19 +9,19 @@
 ; 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	"tft_outputs.inc"
-#include 	"strings.inc"
-#include 	"tft.inc"
-#include	"eeprom_rs232.inc"
-#include	"isr.inc"
-#include	"math.inc"
-#include	"wait.inc"
-#include	"customview.inc"
-#include	"start.inc"
-#include	"adc_lightsensor.inc"
-#include	"ghostwriter.inc"
+#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"
+#include    "eeprom_rs232.inc"
+#include    "isr.inc"
+#include    "math.inc"
+#include    "wait.inc"
+#include    "customview.inc"
+#include    "start.inc"
+#include    "adc_lightsensor.inc"
+#include    "ghostwriter.inc"
 #include    "i2c.inc"
 #include    "calibrate.inc"
 #include    "convert.inc"
@@ -31,136 +31,273 @@
 	global	diveloop
 diveloop:
     banksel common
-	call	speed_normal
-	call	diveloop_boot			; Boot tasks for all modes
+    call    speed_normal
+    call    diveloop_boot				; Boot tasks for all modes
 
-; Startup Tasks for all modes
-    call	TFT_boot                ; Initialize TFT (includes clear screen)
-	call	TFT_divemode_mask		; Display mask
-	call	TFT_temp_divemode		; Displays temperature
-    movff   customview_divemode,menupos3    ; Reload last customview
-    call    customview_mask         ; Redraw last custom view
+    ; 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
 
-	btfsc	FLAG_apnoe_mode
-	bsf		realdive					; Set Realdive flag in Apnoe mode
+    btfsc   FLAG_apnoe_mode
+    bsf	    realdive					; Set Realdive flag in Apnoe mode
 
-	btfsc	FLAG_apnoe_mode             ; Done for Apnoe or Gauge mode
-    bra     diveloop_loop
-	btfsc	FLAG_gauge_mode             ; Done for Apnoe or Gauge mode
-	bra     diveloop_loop
+    btfsc   FLAG_apnoe_mode             ; Done for Apnoe or Gauge mode
+    bra     diveloop_loop_start
+    btfsc   FLAG_gauge_mode             ; Done for Apnoe or Gauge mode
+    bra     diveloop_loop_start
 
-	call	TFT_active_gas_divemode     ; Display gas/Setpoint
-	call	TFT_display_ndl_mask		; display "NDL"
+    bsf	    FLAG_TFT_display_ndl_mask	; display "NDL"
 
 	; +@5 init
-    setf        WREG                    ; WAIT marker: display "---"
-    movff       WREG,int_O_extra_ascenttime+0
-    movff       WREG,int_O_extra_ascenttime+1
-	movlw       1
-    movwf       apnoe_mins              ; Start compute after next cycle.
+    clrf    WREG                    	; WAIT marker: display "---"
+    movff   WREG,char_I_sim_advance_time; bank safe clrf
+    movff   WREG,int_O_alternate_ascenttime+0
+	bsf		WREG,int_not_yet_computed
+	bsf		WREG,int_invalid_flag
+    movff   WREG,int_O_alternate_ascenttime+1
+
+diveloop_loop_start:
+    btfsc   FLAG_TFT_display_ndl_mask
+    call    TFT_display_ndl_mask
+
+
+diveloop_loop:							; The diveloop starts here
+    btfss   quarter_second_update
+    bra     diveloop_loop4a
 
-;--------------------------------------------------------------------------------------------------------
-diveloop_loop:		; The diveloop starts here
+    ; tasks any 1/4 second, any mode
+    bcf     quarter_second_update		; clear flag
+    
+    movlw   .6
+    cpfseq  menupos3                    ; in compass view?
+    bra     diveloop_loop4a				; No, done.
+
+    btfsc   alternative_divelayout		; In alternative layout mode?
+    bra	    diveloop_loop4a				; Yes, done. No Compass.
+
+; TFT Output routines	
+    extern  TFT_dive_compass_heading
+    call    TFT_dive_compass_heading    ; Yes, update compass heading value
+    bsf	    FLAG_TFT_temp_divemode		; Redraw temperature (Is slighty affected from compass heading arrow)
+; TFT Output routines	
+
+diveloop_loop4a:
 	btfss	onesecupdate					
 	bra		diveloop_loop3
-
+	
 ; 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.
+    bcf     onesecupdate				; one seconds update, clear flag here in case it's set again in ISR before all tasks are done.
 
-	btfsc	FLAG_apnoe_mode					; Only in apnoe mode
-	bra		diveloop_loop1b					; One Second Tasks in Apnoe mode
+	;bsf	LEDg	; ### DEBUG - used to measure the time used by all deco code to see if there is enough margin each second ###	
 
-	call	TFT_divemins					; Display (new) divetime!
-	call	customview_second				; Do every-second tasks for the custom view area
-    call	divemode_check_for_warnings     ; Check for any warnings
+	; display depth based on full seconds interval (nicer blinking)
+    btfss   alternative_divelayout
+    rcall   TFT_output4_normal
+    btfsc   alternative_divelayout
+    rcall   TFT_output4_alternative
+	
+	btfsc	FLAG_apnoe_mode				; Only in apnoe mode
+	bra		diveloop_loop1b				; One Second Tasks in Apnoe mode
+	
+; tasks any new second - only for deco modes
+	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.
 
-; Tasks only for deco modes
-	btfsc	show_safety_stop				; Show the safety stop?
-	call	TFT_show_safety_stop			; Yes, show/delete if done.
-	call	calc_deko_divemode				; calculate decompression and display result (any two seconds)
-	bra		diveloop_loop1x					; Common Tasks
+	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	calc_deko_divemode			; calculate decompression and set resulting display flags
+
+	btfss	alternative_divelayout
+	rcall	TFT_output2_normal
+	btfsc	alternative_divelayout
+	rcall	TFT_output2_alternative
+
+	call	divemode_check_for_warnings	; Check for any warnings
+
+	bra		diveloop_loop1x				; Common Tasks
+
+	
+; tasks any new second - only for apnoe mode
 diveloop_loop1b:
-; Tasks only for Apnoe mode
-	rcall	divemode_apnoe_tasks			; 1 sec. Apnoe tasks
-    call	customview_second				; Do every-second tasks for the custom view area
- ;	bra		diveloop_loop1x					; Common Tasks
+	rcall	divemode_apnoe_tasks		; 1 sec. Apnoe tasks
+	call	customview_second			; Do every-second tasks for the custom view area
 
+	;bra	diveloop_loop1x				; Common Tasks
+
+; continue tasks any new second, any mode
 diveloop_loop1x:
-; Common 1sec. tasks for all modes
-	rcall	timeout_divemode				; dive finished? 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...)
-
-	btfsc	store_sample					; store new sample?
-	call	store_dive_data					; Store profile data
-
-	btfss	divemode						; Dive finished?
-	goto	ghostwriter_end_dive    		; Dive finished!
+	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...)
 
-    btfsc   divemode_gaschange              ; Gas switch flag set?
-    rcall   gas_switched_common             ; Yes
+	btfsc	oneminupdate				; one minute tasks
+	rcall	update_divemode60			; Update clock, etc.
 
-    btfsc   toggle_gf                       ; =1: Toggle GF/aGF
-    rcall   divemodemode_togglegf           ; Toggle aGF/GF
+	btfss	alternative_divelayout
+	rcall	TFT_output3_normal
+	btfsc	alternative_divelayout
+	rcall	TFT_output3_alternative
+
+	;bcf	LEDg	; ### DEBUG - used to measure the time used by all deco code to see if there is enough margin each second ###
 
-    btfsc   FLAG_ccr_mode                   ; In CCR mode...
-    call    check_dive_autosp               ; ...check for Auto-SP
-
+; tasks any round, any mode
 diveloop_loop3:
-	rcall	test_switches_divemode			; Check switches in divemode
-
+    call	test_switches_divemode		; Check switches in divemode
+	
     global  diveloop_loop4
-diveloop_loop4:                             ; Menu-Exit returns here...
-	btfsc	toggle_customview				; Next view?
-	call	customview_toggle				; Yes, show next customview (and delete this flag)
+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	pressure_refresh				; new pressure available?
-	rcall	update_temp_and_or_depth        ; Yes, display new depth and clear 	"pressure_refresh" flag
+    btfsc   store_sample				; store new sample?
+    call    store_dive_data				; Store profile data
 
-	btfsc	oneminupdate					; one minute tasks
-	rcall	update_divemode60				; Update clock, etc.
+    btfss   divemode					; Dive finished?
+    goto    ghostwriter_end_dive    	; Dive finished!
 
-;    btfss   quarter_second_update
-;    bra     diveloop_loop4a
+    btfsc   divemode_gaschange			; Gas switch flag set?
+    call    gas_switched_common			; Yes
 
-    bcf     quarter_second_update
-    movlw   .6
-    cpfseq  menupos3                    ; in compass view?
-    bra     diveloop_loop4a             ; No
-    extern  TFT_dive_compass_heading
-    call    TFT_dive_compass_heading    ; Yes, update compass heading value
-    call    TFT_temp_divemode		; Redraw temperature (Is slighty affected from compass heading arrow)
-diveloop_loop4a:
-    btfsc   enable_screen_dumps         ; =1: Ignore vin_usb, wait for "l" command (Screen dump)
+    btfsc   toggle_gf					; =1: Toggle GF/aGF
+    rcall   divemodemode_togglegf		; Toggle aGF/GF
+    
+    btfsc   pressure_refresh			; new pressure available?	
+    rcall   set_max_depth				; update max. depth if required
+    btfsc   pressure_refresh			; new pressure available?	
+    bsf	    FLAG_TFT_depth				; Yes, update depth asap
+    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
+    btfss   vusb_in						; USB (still) plugged in?
+    bcf     enable_screen_dumps			; No, clear flag
     call    rs232_get_byte
     btfsc   rs232_recieve_overflow
     bra     diveloop_loop6
     movlw   "l"
     cpfseq	RCREG1
     bra     diveloop_loop6
-    call    TFT_dump_screen             ; Dump the screen contents
+    call    TFT_dump_screen				; Dump the screen contents
+	
 diveloop_loop6:
+	bra		diveloop_loop				; Loop the divemode
+	
+;--------------------------------------------------------------------------------------------------------	
+	
+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
+	btfsc	FLAG_TFT_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
+	return
+	
+TFT_output1_alternative:				; beginning of any new second - only for deco modes
+	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
+	return
+	
+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
+	call    TFT_display_ndl
+	btfsc	FLAG_TFT_display_deko_mask
+	call	TFT_display_deko_mask
+	btfsc	FLAG_TFT_display_deko
+	call	TFT_display_deko
+	btfsc	FLAG_TFT_display_tts
+	call	TFT_display_tts
+	return
 
-	bra		diveloop_loop					; Loop the divemode
+TFT_output2_alternative:    			; any new second - only for deco modes
+	return
+	
+TFT_output3_normal:	    				; tasks any new second, any mode
+	btfsc	FLAG_TFT_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
+	btfsc   FLAG_TFT_dive_warning_text_clr2
+	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
+	btfsc	FLAG_TFT_dive_warning_text_clear
+	call	TFT_clear_warning_text		; clear complete warnings area (In alt mode only 2nd. row...)
+	btfsc	FLAG_TFT_big_deco_alt
+	call	TFT_big_deco_alt			; Big deco
+	return
+
+TFT_output4_normal:						; tasks any round, any mode
+	btfsc	FLAG_TFT_depth
+	call	TFT_depth					; Displays new depth
+	btfsc	FLAG_TFT_temp_divemode		
+	call	TFT_temp_divemode			; Update temperature
+	return
+	
+TFT_output4_alternative:    			; tasks any round, any mode
+    btfsc	FLAG_TFT_depth
+	call	TFT_depth					; Displays new depth
+	return
+	
+	
 ;--------------------------------------------------------------------------------------------------------
 
+divemode_apnoe_tasks:					; 1 sec. Apnoe tasks
+	call	TFT_display_apnoe_descent	; Yes, Show descent timer
+	call	TFT_max_depth				; use normal max. depth
 
-divemode_apnoe_tasks:                       ; 1 sec. Apnoe tasks
-	call	TFT_display_apnoe_descent		; Yes, Show descent timer
-	call	TFT_max_pressure				; 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		; 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
@@ -169,26 +306,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
@@ -197,259 +334,341 @@
 	movff	apnoe_max_pressure+1,sub_a+1
 	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
+	call	subU16						; sub_c = sub_a - sub_b
+										; 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
+										;apnoe_max_pressure<max_pressure
 	movff	max_pressure+0,apnoe_max_pressure+0
 	movff	max_pressure+1,apnoe_max_pressure+1
 	return
 
+	; --------------------------------------------------------------------------------------
 
 calc_deko_divemode:
-	btfsc	twosecupdate			; two seconds after the last call
-	bra		calc_deko_divemode2		; Yes, calculate and display deco data ("first second")
-
-	bsf		twosecupdate			; No, but next second!
-	; Routines used in the "other second"
-	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
+	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
+	
+	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
+	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
 
-; Calculate CNS
-    btfss   FLAG_pscr_mode		; in PSCR mode?
-    rcall   set_actual_ppo2             ; No, set char_I_actual_ppO2
-    btfsc   is_bailout			; Always in bailout...
-    rcall   set_actual_ppo2             ; ...set char_I_actual_ppO2
-    
-    clrf    WREG
-    movff   WREG,char_I_step_is_1min    ; Make sure to be in 2sec mode.
-	call	deco_calc_CNS_fraction		; calculate CNS
-	movlb	b'00000001'					; rambank 1 selected
-; Check for a gas change
-	bra	check_gas_change			; Checks if a better gas should be selected (by user) and return...
+	btfsc	FLAG_ccr_mode				; In CCR mode?
+	rcall	calc_deko_divemode_sensor	; do sensor data acquisition if applicable by OSTC model
 
-    global  set_actual_ppo2
-set_actual_ppo2:                        ; calculate ppO2 in 0.01bar (e.g. 150 = 1.50 bar ppO2)
-    btfsc   divemode                    ; in divemode
-    bra     set_actual_ppo2_dive        ; Yes
-    ; No, use simulated ambient pressure for char_I_actual_ppO2
-    movff   char_I_bottom_depth,WREG
-    mullw   .100
-    movlw   LOW(.1000)
-    addwf   PRODL,W
-    movwf   xA+0
-    movlw   HIGH(.1000)
-    addwfc  PRODH,W
-    movwf   xA+1                        ; P_amb in millibar (1000 = 1.00 bar).
-    bra     set_actual_ppo2_common
-set_actual_ppo2_dive:
-    SAFE_2BYTE_COPY amb_pressure, xA    ; P_amb in millibar (1000 = 1.00 bar).
-set_actual_ppo2_common:
- 	movlw		d'10'
-	movwf		xB+0
-	clrf		xB+1
-	call		div16x16				; xC=p_amb/10 (100 = 1.00 bar).
-	movff		xC+0,xA+0
-	movff		xC+1,xA+1
-	movff		char_I_O2_ratio,xB+0
-	clrf		xB+1
-	call		mult16x16				; char_I_O2_ratio * (p_amb/10)
-	movff		xC+0,xA+0
-	movff		xC+1,xA+1
-	movlw		d'100'
-	movwf		xB+0
-	clrf		xB+1
-	call		div16x16				; xC=(char_I_O2_ratio * p_amb/10)/100
-
-; Copy ppO2 for CNS calculation
-    tstfsz      xC+1                    ; Is ppO2 > 2.55bar ?
-    setf        xC+0                    ; yes: bound to 2.55... better than wrap around.
-
-    movff		xC+0, char_I_actual_ppO2	; copy last ppO2 to buffer register
-    btfsc       is_bailout                  ; In Bailout?
-    return                                  ; Yes, done.
-    ; No Bailout, check for ccr mode
-    btfsc		FLAG_ccr_mode               ; If FLAG_ccr_mode=1...
-    movff		char_I_const_ppO2, char_I_actual_ppO2	; ...copy last ppO2 to buffer register
-    return
-
-check_fallback_clear:
-    call    check_sensors                   ; Setups "use_O2_sensorX" flags
-    ; Copy use flags to voting logic flags in case we are no longer in fallback
-    btfsc   use_O2_sensor1
-    bsf     voting_logic_sensor1
-    btfsc   use_O2_sensor2
-    bsf     voting_logic_sensor2
-    btfsc   use_O2_sensor3
-    bsf     voting_logic_sensor3
-    rcall   divemode_setup_sensor_values    ; Setup sensor values
-    goto    check_sensors                   ; Check O2 sensor thresholds for fallback customview_minute
-
-calc_deko_divemode2:
-	bcf	twosecupdate
-
-	btfsc	FLAG_gauge_mode             ; Done for Apnoe or Gauge mode
-	return
-
-	extern	deco_setup_dive
-	call	deco_setup_dive				;  Pass all parameters to the C code
+    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
 
 
-    btfsc   setpoint_fallback               ; Are we in Fallback?
-    rcall   check_fallback_clear            ; Yes, check if we still have fallback condition
-
-    bcf     setpoint_fallback               ; =1: Fallback to SP1 due to external O2 sensor failure
-
-    btfsc   FLAG_ccr_mode                   ; In CCR mode?
-    rcall    calc_deko_divemode_sensor      ; External sensor stuff
-
-;    btfsc   FLAG_pscr_mode                   ; In PSCR mode?
-;    rcall    calc_deko_divemode_sensor      ; External sensor stuff
+	; 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
 
-    
-	SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; C-code needs the ambient pressure
-	clrf	WREG
-	movff	WREG,char_I_step_is_1min    ; Force 2 second deco mode
+	; 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
+	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
+	movff	lo,char_O_deco_status		; write-back char_O_deco_status to deco engine interface
 
-	movff	char_I_O2_ratio,lo_temp		; Backup original value for everything
-	movff	char_I_N2_ratio,hi_temp		; Backup original value for everything
-	
-	btfss	FLAG_pscr_mode
-	bra	calc_deko_divemode2a	    ; Non-PSCR modes...
+	; 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)
 
-	btfsc	is_bailout
-	bra	calc_deko_divemode2a	    ; Skip in bailout
+	; 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...
 	
-	; in PSCR mode, compute fO2 into char_I_O2_ratio
-	call		compute_pscr_ppo2	; pSCR ppO2 into sub_c:2
-	movff		sub_c+0,xA+0
-	movff		sub_c+1,xA+1
-	movlw		LOW		.10
-	movwf		xB+0
-	movlw		HIGH	.10
-	movwf		xB+1
-	call		mult16x16		;xA*xB=xC	-> xC:4 = ppO2*10
-	SAFE_2BYTE_COPY amb_pressure, xB
-	call		div32x16	 	; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
-	; xC+0 has O2 in percent
-	movff	xC+0,char_I_O2_ratio
+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
 
-	movff	char_I_He_ratio, wait_temp	; copy into bank1 register
-	bsf	STATUS,C			; Borrow bit
-	movlw	d'100'				; 100%
-	subfwb	wait_temp,W			; minus He
-	bsf	STATUS,C			; Borrow bit
-	subfwb	xC+0,W				; minus O2
-	movff	WREG, char_I_N2_ratio		; = N2!
+	; 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
 	
-calc_deko_divemode2a:
+	; 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
-    movlb   .1
-    
-  	movff	lo_temp,char_I_O2_ratio		; Restore original value for everything
-	movff	hi_temp,char_I_N2_ratio		; Restore original value for everything
-
-
-    movff   char_O_deco_status,WREG     ; Is a compute cycle finished ?
-    iorwf   WREG,F
-    btfss   STATUS,Z
-    return                              ; Return is status <> 0
+	banksel common
 
     ; Check if deco stops are necessary ?
 	movff	char_O_first_deco_depth,wait_temp	; copy ceiling to temp register
 	tstfsz	wait_temp							; Ceiling<0m?
 	bra		calc_deko_divemode3					; Yes!
 
-	btfsc	decostop_active             ; Already in nodeco mode ?
-	call	TFT_display_ndl_mask       	; No, Clear deco data, display nostop time
-	bcf		decostop_active             ; clear flag (again)
+	btfsc	decostop_active             		; Already in nodeco mode ?
+	bsf		FLAG_TFT_display_ndl_mask       	; No, Clear deco data, display nostop time
+	bcf		decostop_active						; clear flag (again)
 
 	; Copy for profile recording
 	clrf	decodata+0
-	movff	char_O_nullzeit,decodata+1  ; NDL
+	movff	char_O_nullzeit,decodata+1 			; NDL
 	
-	goto	TFT_display_ndl            ; display no deco limit, and return...
+	bsf		FLAG_TFT_display_ndl				; display no deco limit
+	return
 
 calc_deko_divemode3:
-	btfss	decostop_active            ; Already in deco mode ?
-	call	TFT_display_deko_mask      ; No, clear nostop time, display decodata
-	bsf		decostop_active            ; Set flag (again)
+	btfss	decostop_active						; Already in deco mode ?
+	bsf		FLAG_TFT_display_deko_mask			; No, clear nostop time, display decodata
+	bsf		decostop_active						; Set flag (again)
 
 	; Copy for profile recording
 	movff	char_O_first_deco_depth,decodata+0	; ceiling
-	movff	char_O_first_deco_time,decodata+1	; length of first stop in minues
-	call	TFT_display_deko            ; display decodata
-	call	TFT_show_TTS_divemode       ; display TTS
+	movff	char_O_first_deco_time,decodata+1	; length of first stop in minutes
+	bsf		FLAG_TFT_display_deko				; display decodata
+	bsf		FLAG_TFT_display_tts				; display TTS
+	return
+
+	; --------------------------------------------------------------------------------------
 
-    movff   char_I_extra_time,WREG
-    tstfsz  WREG                    ; extra time = 0?
-    bra     calc_deko_divemode4     ; No, compute it
-    return
+	global	calc_deko_divemode_sensor
+calc_deko_divemode_sensor:
+	; sensor acquisition code
+	btfss   s8_digital							; check if we have digital interface to the sensors
+	bra     calc_deko_divemode_sensor_analog	; NO  - use 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
+	call	compute_mvolts_for_all_sensors		; YES - compute mV values from digital data
+	bra		calc_deko_divemode_sensor_common
+
+calc_deko_divemode_sensor_analog:
+	call    get_analog_inputs					; TODO: abort when OSTC model does not have analog inputs
+
+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.
+	; If not ok: reset o2_ppo2_sensorX, reset use_O2_sensorX and show the customview 1 in case the sensor was ok before.
 
-calc_deko_divemode4:
-    ; Check if extra cycles are needed to compute @5 variant:
-	decfsz  apnoe_mins,F                ; Reached count-down ?
-	return                              ; No: don't compute yet.
-	
-	movlw   .6
-	movff   WREG,char_O_deco_status     ; Stole next cycles for @5 variant.
-    
-    movlw   .2                          ; Restart countdown.
-    movwf   apnoe_mins
- 	return                              ; done.
+	; Check min_mv of 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
+    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
+	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
+	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
+
+check_sensor_1_ok:
+	; 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
+	bra	check_sensor_2						; continue with next sensor
+
+check_sensor_1_fail:
+	clrf	WREG
+	movff	WREG,o2_ppo2_sensor1			; set ppO2 reading to zero
+	btfss	use_O2_sensor1					; check if sensor was in use before
+	bra		check_sensor_1_fail_1			; NO  - no new news then
+	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
 
-calc_deko_divemode_sensor:                  ; External sensor stuff
-    call    compute_ppo2		    ; computes o2_ppo2_sensorX from mV-Readings
-    call    check_sensors		    ; analyses mv-Readings to set up use- and voting-Flags
-    call    divemode_setup_sensor_values    ; computes sensor_setpoint from o2_pp02_sensorX and Flags
-    
-    movff   opt_ccr_mode,WREG               ; =0: Fixed SP, =1: Sensor,  =2: Auto SP
-    sublw   .1                              ; opt_ccr_mode = 1 (Sensor)?
-    bnz     calc_deko_divemode_sensor_done  ; No, return
-    
-    movff   sensor_setpoint,char_I_const_ppO2; Copy sensor result to C-code
+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
+    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
+	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
+	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
 
-    TSTOSS  opt_sensor_fallback             ; =1: Fallback to SP1 when sensor is lost
-    return                                  ; Never fallback
+check_sensor_2_ok:
+	; 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
+	bra	check_sensor_3						; continue with next sensor
+
+check_sensor_2_fail:
+	clrf	WREG
+	movff	WREG,o2_ppo2_sensor2			; set ppO2 reading to zero
+	btfss	use_O2_sensor2					; check if sensor was in use before
+	bra		check_sensor_2_fail_1			; NO  - no new news then
+	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	
 
-    btfsc   is_bailout                      ; In bailout?
-    return                                  ; Never fallback in bailout
-    ; Check if we should fallback to SP1
-  	btfsc	use_O2_sensor1
-    return                                  ; At least one sensor is active, no fallback
-	btfsc	use_O2_sensor2
-	return                                  ; At least one sensor is active, no fallback
-	btfsc	use_O2_sensor3
-	return                                  ; At least one sensor is active, no fallback
-    ; No sensor in use -> fallback
-    movff   char_I_setpoint_cbar+0,char_I_const_ppO2    ; Setup fixed Setpoint (Always fallback to SP1), overwrite sensor result
-    bsf     setpoint_fallback               ; =1: Fallback to SP1 due to external O2 sensor failure
-calc_deko_divemode_sensor_done:
-    return
-   
-;-----------------------------------------------------------------------------
+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
+    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
+	btfss	neg_flag						; check if result is nagative, 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
+	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
 
-divemodemode_togglegf:                  ; Toggle aGF/GF
-    bcf     toggle_gf                   ; clear flag    
-    btg     use_agf                     ; Toggle GF
-    call    TFT_gf_mask                 ; Setup Mask
-    clrf    WREG
-    movff   WREG,char_O_deco_status     ; Restart decoplan computation
-    return
+check_sensor_3_ok:
+	; 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
 
-    global  divemode_setup_sensor_values
-divemode_setup_sensor_values:
+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
+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
+	btfss	divemode
+	return
+
+	; 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
@@ -457,8 +676,6 @@
     clrf    xA+1
     btfss   use_O2_sensor1                  ; Sensor1 active?
     bra     divemode_setup_sensor_values2   ; No
-;    btfss   voting_logic_sensor1            ; Sensor within voting logic?
-;    bra     divemode_setup_sensor_values2   ; No
     movf    o2_ppo2_sensor1,W
     addwf   xA+0
     movlw   .0
@@ -467,8 +684,6 @@
 divemode_setup_sensor_values2:
     btfss   use_O2_sensor2                  ; Sensor2 active?
     bra     divemode_setup_sensor_values3   ; No
-;    btfss   voting_logic_sensor2            ; Sensor within voting logic?
-;    bra     divemode_setup_sensor_values3   ; No
     movf    o2_ppo2_sensor2,W
     addwf   xA+0
     movlw   .0
@@ -477,18 +692,172 @@
 divemode_setup_sensor_values3:
     btfss   use_O2_sensor3                  ; Sensor3 active?
     bra     divemode_setup_sensor_values4   ; No
-;    btfss   voting_logic_sensor3            ; Sensor within voting logic?
-;    bra     divemode_setup_sensor_values4   ; No
     movf    o2_ppo2_sensor3,W
     addwf   xA+0
     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
+    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
+	; 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
+	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:
+    bsf     voting_logic_sensor1
+    movff   o2_ppo2_sensor1,temp1
+    rcall   check_sensor_voting_helper
+    incfsz  WREG                    		; Was Wreg=255?
+    bcf     voting_logic_sensor1    		; No, ignore this sensor
+
+    bsf     voting_logic_sensor2
+    movff   o2_ppo2_sensor2,temp1
+    rcall   check_sensor_voting_helper
+    incfsz  WREG                    		; Was Wreg=255?
+    bcf     voting_logic_sensor2    		; No, ignore this sensor
+
+    bsf     voting_logic_sensor3
+    movff   o2_ppo2_sensor3,temp1
+    rcall   check_sensor_voting_helper
+    incfsz  WREG                    		; Was Wreg=255?
+    bcf     voting_logic_sensor3    		; No, ignore 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
+	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
+	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
+	return
+
+check_warn_sensor_2:						; check 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
+	return
+	
+check_warn_sensor_3:						; check sensor 2
+	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
+	return
+					
+check_warn_sensor_agree:
+	bsf		sensors_agree
+	return
+
+compute_ppo2_helper:
+	call	mult16x16						;xA:2*xB:2=xC:4
+	movlw	LOW		.1000
+	movwf	xB+0
+	movlw	HIGH	.1000
+	movwf	xB+1
+	call	div32x16						; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
+	movlw	d'1'
+	addwf	xC+0,W							; we are just interessed in the carry flag
+	movlw	d'0'
+	addwfc	xC+1,W							; we are still just interessed in the carry flag
+    tstfsz  WREG							; ppO2 is higher than 2.55bar?
+    setf    xC+0							; Yes.
     return
 
+check_sensor_custview_helper:
+	btfss	divemode						; check if we are in divemode
+	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:
+	return
+
+	
+check_sensor_voting_helper:
+    movf    temp1,W
+    cpfsgt  sensor_setpoint
+    bra     check_sensor_voting_common2		; temp1<sensor_setpoint
+    ; temp1>sensor_setpoint
+    movf    temp1,W
+    subwf   sensor_setpoint,W
+    movwf   temp1
+check_sensor_voting_common1:
+    movlw	sensor_voting_logic_threshold	; Threshold in 0.01 bar
+    cpfsgt  temp1
+    retlw   .255							; Within range
+    retlw   .0								; Out of range
+check_sensor_voting_common2:
+    ; temp1<sensor_setpoint
+    movf    sensor_setpoint,W
+    subwf   temp1,F
+    bra     check_sensor_voting_common1
+		
+;-----------------------------------------------------------------------------
+
+divemodemode_togglegf:						; Toggle aGF/GF
+    bcf     toggle_gf						; clear flag    
+    btg     use_agf							; toggle GF
+
+	movff	opt_GF_low,char_I_GF_Low_percentage
+	movff	opt_GF_high,char_I_GF_High_percentage
+
+	; Overwrite GF if aGF is wanted
+	btfsc	use_agf							; =1: Use aGF
+	movff	opt_aGF_low,char_I_GF_Low_percentage
+	btfsc	use_agf							; =1: Use aGF
+	movff	opt_aGF_high,char_I_GF_High_percentage
+
+    call    TFT_gf_mask						; Setup Mask
+	goto	restart_deco_engine				; ...and return
+
+
 calc_velocity:								; called every two seconds
     btfsc   display_velocity                
     bra     calc_velocity1                  ; Always update if already displayed
@@ -501,7 +870,7 @@
 	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
@@ -509,20 +878,20 @@
 
 	movff	sub_c+0,xA+0
 	movff	sub_c+1,xA+1
-	movlw	d'39'						; 77 when called every second....
+	movlw	d'39'							; 77 when called every second....
 	movwf	xB+0
 	clrf	xB+1
-	call	mult16x16					; differential pressure in mbar*77...
+	call	mult16x16						; differential pressure in mbar*77...
 	movff	xC+0,divA+0
 	movff	xC+1,divA+1
 	movlw	d'7'
 	movwf	divB+0
-	call	div16						; devided by 2^7 equals velocity in m/min
+	call	div16							; devided by 2^7 equals velocity in m/min
 
 	movlw	d'99'
-	cpfsgt	divA+0                      ; limit to 99m/min
+	cpfsgt	divA+0                      	; limit to 99m/min
 	bra		calc_velocity3
-	movwf	divA+0						; divA=99
+	movwf	divA+0							; divA=99
 
 calc_velocity3:
     ; Copy old speeds
@@ -532,22 +901,22 @@
     movff   divA+0,old_velocity+0
     
 ;    movff   old_velocity+3,WREG
-;    addwf   divA+0,F                    ; add old speed
+;    addwf   divA+0,F                    	; add old speed
 ;    bcf     STATUS,C
-;    rrcf    divA+0,F                    ; /2
+;    rrcf    divA+0,F                    	; /2
 ;    movff   old_velocity+2,WREG
-;    addwf   divA+0,F                    ; add old speed
+;    addwf   divA+0,F                    	; add old speed
 ;    bcf     STATUS,C
-;    rrcf    divA+0,F                    ; /2
+;    rrcf    divA+0,F                    	; /2
 ;    movff   old_velocity+1,WREG
-;    addwf   divA+0,F                    ; add old speed
+;    addwf   divA+0,F                    	; add old speed
 ;    bcf     STATUS,C
-;    rrcf    divA+0,F                    ; /2
+;    rrcf    divA+0,F                    	; /2
 ;    movff   old_velocity+0,WREG
-;    addwf   divA+0,F                    ; add old speed
+;    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...
+;    rrcf    divA+0,F                    	; /2
+	goto	TFT_display_velocity			; With divA+0 = m/min..., and return...
 
 
 ;=============================================================================
@@ -558,6 +927,7 @@
 
 	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
     SAFE_2BYTE_COPY rel_pressure, lo
 	call	adjust_depth_with_salinity		; computes salinity setting into lo:hi [mbar]
@@ -567,7 +937,7 @@
     mullw   .10                             ; mbar in PRODL:H
     movff   PRODL,sub_b+0
     movff   PRODH,sub_b+1
-	call	subU16							;  sub_c = sub_a - sub_b
+	call	subU16							; sub_c = sub_a - sub_b
 	btfss	neg_flag
 	bra		reset_safety_stop				; Below 10m, reset safety stop
 
@@ -576,11 +946,11 @@
 	call	adjust_depth_with_salinity		; computes salinity setting into lo:hi [mbar]
 	movff	lo,sub_a+0
 	movff	hi,sub_a+1
-    movff   opt_safety_stop_end,WREG      ; [cbar]
+    movff   opt_safety_stop_end,WREG      	; [cbar]
     mullw   .10                             ; mbar in PRODL:H
     movff   PRODL,sub_b+0
     movff   PRODH,sub_b+1
-	call	subU16							;  sub_c = sub_a - sub_b
+	call	subU16							; sub_c = sub_a - sub_b
 	btfsc	neg_flag
 	bra		delete_safety_stop				; Above 3m, remove safety stop
 
@@ -614,7 +984,8 @@
 	btfss	safety_stop_active				; Safety stop shown
 	return									; No, don't delete it
 	bcf		safety_stop_active				; Clear flag
-    goto    TFT_clear_safety_stop           ; Clear safety stop, and return...
+    bsf	    FLAG_TFT_clear_safety_stop		; Clear safety stop
+    return
 
 
 ;=============================================================================
@@ -633,21 +1004,24 @@
 timeout_divemode_menu2:                 ; Called from divemenu_tree.asm
     bcf     divemode_menu               ; Timeout! Clear flag
     call    TFT_clear_divemode_menu     ; Clear menu
-    call    TFT_active_gas_divemode     ; Redraw gas/setpoint/diluent
+    bsf	    FLAG_TFT_active_gas_divemode; Redraw gas/setpoint/diluent
     bcf     blinking_better_gas         ; Clear flag to have temperature updated once
-    call	TFT_temp_divemode           ; Displays temperature
+    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
-	call	TFT_display_deko_mask      ; clear nostop time, display decodata
-    call    TFT_display_deko
-    goto    TFT_show_TTS_divemode; and return...
-
-timeout_divemode_menu_ndl:              ; Show NDL
-	call	TFT_display_ndl_mask       	; Clear deco data, display nostop time
-    goto    TFT_display_ndl; and return...
+    bsf	    FLAG_TFT_display_deko_mask
+    bsf	    FLAG_TFT_display_deko
+    bsf	    FLAG_TFT_display_tts
+    return
+    
+timeout_divemode_menu_ndl:              
+    ; Show NDL
+    bsf	    FLAG_TFT_display_ndl_mask
+    bsf	    FLAG_TFT_display_ndl
+    return
 
 timeout_divemode:
     btfsc   divemode_menu               ; Divemode menu active?
@@ -674,7 +1048,7 @@
 	movff	opt_diveTimeout,WREG	    ; in [min]
 	mullw	.60
 	movff	PRODL,sub_a+0
-	movff	PRODH,sub_a+1		    ; in [s]
+	movff	PRODH,sub_a+1		    	; in [s]
 
 	movff	timeout_counter, sub_b+0
 	movff	timeout_counter2, sub_b+1
@@ -705,17 +1079,6 @@
 	bsf		divemode
 	return
 
-update_temp_and_or_depth:			    ; New sensor data arrived...
-	btfsc	temp_changed	
-	call	TFT_temp_divemode		    ; Displays temperature
-
-;	btfsc	pressure_refresh
-	call	TFT_depth			    ; Displays new depth
-
-	rcall	set_max_depth			    ; update max. depth if required
-	bcf	pressure_refresh		    ; until new pressure is available
-	return
-
 update_divemode60:                      ; update any minute
 	call	get_battery_voltage			; gets battery voltage
 	rcall	set_powersafe				; Battery low?
@@ -745,7 +1108,8 @@
                                         ; max_pressure<rel_pressure
 	movff	sub_b+0,max_pressure+0
 	movff	sub_b+1,max_pressure+1
-	goto	TFT_max_pressure			; No, use normal max. depth; and return...
+	bsf	FLAG_TFT_max_depth				; Set flag
+	return
 
 set_min_temp:
 	movff	minimum_temperature+0,sub_a+0
@@ -763,39 +1127,39 @@
 
 	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
-	movwf	sub_a+0					; dive_treshold is in cm
+	movwf	sub_a+0						; dive_treshold is in cm
 	movlw	HIGH	start_dive_threshold
-	movwf	sub_a+1					; dive_treshold is in cm
+	movwf	sub_a+1						; dive_treshold is in cm
 
 set_dive_modes1:
     SAFE_2BYTE_COPY rel_pressure, sub_b
-	call	subU16					; sub_c = sub_a - sub_b
+	call	subU16						; sub_c = sub_a - sub_b
 
 	btfss	neg_flag	
-	bra		set_dive_modes2			; too shallow (rel_pressure<dive_threshold)
+	bra		set_dive_modes2				; too shallow (rel_pressure<dive_threshold)
 
-	btfsc	realdive				; Dive longer than one minute?
-	clrf 	timeout_counter			; Yes, reset timout counter
+	btfsc	realdive					; Dive longer than one minute?
+	clrf 	timeout_counter				; Yes, reset timout counter
 
-	bsf		divemode				; (Re-)Set divemode flag
-	bsf		divemode2				; displayed divetime is running
+	bsf		divemode					; (Re-)Set divemode flag
+	bsf		divemode2					; displayed divetime is running
 	return
 
 set_dive_modes2:
-	bcf		divemode2				; Stop time
-	btfss	realdive				; dive longer then one minute?
-	bcf		divemode				; no -> this was no real dive
-	return							; No, return
+	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
-	btfsc	realdive				; dive longer then one minute?
-	bra		set_dive_modes0			; Yes -> this is a real dive -> Use start_dive_threshold or ascend
+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
 
 	movlw	HIGH	high_altitude_dive_threshold
 	movwf	sub_a+1
@@ -808,22 +1172,22 @@
     cpfslt  batt_percent
 	return
 
-	movlw	d'7'					; Type of Alarm (Battery Low)
-	movwf	AlarmType				; Copy to Alarm Register
-	bsf		event_occured			; Set Event Flag
+	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
-	return							; return
+    movff   WREG,opt_brightness     	; Set Brightness to ECO
+	return								; return
 
 calc_average_depth:
-	btfsc	reset_average_depth		; Reset the Average depth?
-	rcall	reset_average1			; Reset the resettable 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...
     bcf     STATUS,C
     rlcf    xB+0,F
-    rlcf    xB+1,F                  ; x2
+    rlcf    xB+1,F                  	; x2
 
 	movf	xB+0,w
 	addwf	average_depth_hold+0,F
@@ -831,9 +1195,9 @@
 	addwfc	average_depth_hold+1,F
 	movlw	d'0'
 	addwfc	average_depth_hold+2,F
-	addwfc	average_depth_hold+3,F ; Will work up to 9999mbar*60*60*24=863913600mbar
+	addwfc	average_depth_hold+3,F 		; Will work up to 9999mbar*60*60*24=863913600mbar
 
-; Do the same for the _total registers (Non-Resettable)
+	; Do the same for the _total registers (Non-Resettable)
 	movf	xB+0,w
 	addwf	average_depth_hold_total+0,F
 	movf	xB+1,w
@@ -850,7 +1214,7 @@
 	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
+	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
 
@@ -864,7 +1228,7 @@
 	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
+	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
 	return
@@ -880,11 +1244,12 @@
 	bcf		reset_average_depth			; Clear flag
 	return
 
-test_switches_divemode:		; checks switches in divemode
+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
-	goto    menuview_toggle         ; Menu or Simulator tasks; and return...; bra		test_switches_divemode2		; Enter button pressed, check if we need to do something
+	; 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?
@@ -914,7 +1279,7 @@
 
 test_switches_divemode_menu3:           ; Enter submenu or do something
     bcf     switch_right
-;    decf    menupos,F                   ; menu_processor needs 0-5...
+;    decf    menupos,F					; menu_processor needs 0-5...
     extern  do_line_menu
     goto    do_line_menu                ; Warning! Trashes STKPTR and returns to diveloop_loop4:
 
@@ -941,103 +1306,281 @@
 	bra		divemode_option6			; +5mins simulation
 	dcfsnz	WREG,F
 	bra		divemode_option7			; Store heading
+	dcfsnz	WREG,F
+	bra		divemode_option8			; Switch to alt. layout
     return
 
 gas_switched_common:
-    bcf     divemode_gaschange      ; Clear flag
-
-    tstfsz  menupos                 ; menupos=0?
-    bra     $+4                     ; No
-    return                          ; Yes, do not switch gas (There is no Gas #0 !)
+    bcf     divemode_gaschange			; Clear flag
+    tstfsz  menupos						; menupos=0?
+    bra     gas_switched_common1		; No
+    return								; Yes, do not switch gas (there is no Gas #0 !)
+gas_switched_common1:
+	movf	menupos,W					; get selected gas into WREG (1-6)
 
-    decf    menupos,W               ; 1-5 -> 0-4
-    btfsc   FLAG_ccr_mode           ; Choose CC Diluents
-    rcall   setup_dil_registers     ; With WREG=Gas 0-4
-    decf    menupos,W               ; 1-5 -> 0-4
-    btfsc   FLAG_pscr_mode          ; Choose CC Diluents
-    rcall   setup_dil_registers     ; With WREG=Gas 0-4
-    ; OC mode?
-    btfsc   FLAG_ccr_mode           ; CCR?
-    bra	    gas_switched_common2    ; Yes
-    btfsc   FLAG_pscr_mode          ; PSCR?
-    bra	    gas_switched_common2    ; Yes
-    ; -> OC
-    decf    menupos,W               ; 1-5 -> 0-4
-    rcall   setup_gas_registers     ; With WREG=Gas 0-4
+    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
+	bra		gas_switched_common3
+
+	; Loop or Bailout
 gas_switched_common2:
-    decf    menupos,W               ; 1-5 -> 0-4
-    btfsc   is_bailout              ; Choose OC Bailouts (OC Gases)
-    rcall   setup_gas_registers     ; With WREG=Gas 0-4
-    
-    movlw   .0
-    btfsc   is_bailout
-    movff   WREG,char_I_const_ppO2  ; deactivate CCR-mode deco calc
-
-    call	TFT_active_gas_divemode	; Display gas/Setpoint
-    clrf    WREG
-    movff   WREG,char_O_deco_status ; Restart decoplan computation
+    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_common3:
+    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
-	bsf		event_occured			; Set global event byte
-    btfsc   is_bailout              ; Choose OC Bailouts (OC Gases)
-    bsf     bailoutgas_event        ; Bailout gas change
-    btfss   is_bailout              ; Choose OC Bailouts (OC Gases)
-	bsf		stored_gas_changed		; OC gas change
+	bsf		event_occured				; Set global event byte
+    btfsc   is_bailout					; Choose OC Bailouts (OC Gases)
+    bsf     bailoutgas_event			; Bailout gas change
+    btfss   is_bailout					; Choose OC Bailouts (OC Gases)
+	bsf		stored_gas_changed			; OC gas change
 	return
 
-    global  setup_gas_registers
-setup_gas_registers:                ; With WREG=Gas 0-4
-    lfsr    FSR1,opt_gas_O2_ratio+0
-    movff   PLUSW1,char_I_O2_ratio  ; O2 (For ppO2 calculations)
-    lfsr    FSR1,opt_gas_He_ratio+0
-    movff   PLUSW1,char_I_He_ratio  ; He
-    lfsr    FSR1,opt_gas_type
-    movff   PLUSW1,active_gas_type  ; 0=Disabled, 1=First, 2=Travel, 3=Deco for OC gases and 0=Disabled, 1=First, 2=Normal for diluents
-    incf    WREG,W                  ; Gas# 1-5
-	movff	WREG,char_I_current_gas	; Set gas
-	movff	WREG,active_gas			; Set for logbook and display
-    banksel char_I_O2_ratio
-	movf    char_I_O2_ratio,W       ; Add O2...
-    addwf   char_I_He_ratio,W       ; ...and He...
-	sublw   .100                    ; ...subtract both from 100
-	movwf   char_I_N2_ratio         ; -> N2!
-    banksel common
-    return
+
+; 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_WREG2:
+	movf    lo,W
+	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!
+	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
+	movlw   .0
+	movff   WREG,opt_gas_type+0			; Set Gas1 to First
+	incf	WREG,W						; 0 -> 1
+	return
+get_first_gas_to_WREG3:
+	movf    lo,W						; Put into Wreg
+	incf	WREG,W						; 0-4 -> 1-5
+	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_WREG2:
+	movf    lo,W
+	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!
+	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
+	movlw   .0
+	movff   WREG,opt_dil_type+0			; Set Dil1 to First
+	incf	WREG,W						; 0 -> 1
+	return
+get_first_dil_to_WREG3:
+	movf    lo,W						; Put into Wreg
+	incf	WREG,W						; 0-4 -> 1-5
+	return								; Done
+
+	global	deco_setup_oc_gases
+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
+
+	movff   opt_gas_He_ratio+0,char_I_deco_He_ratio+0
+	movff   opt_gas_O2_ratio+0,char_I_deco_O2_ratio+0
+	banksel opt_gas_type+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
+	banksel common
+
+	movff   opt_gas_He_ratio+1,char_I_deco_He_ratio+1
+	movff   opt_gas_O2_ratio+1,char_I_deco_O2_ratio+1
+	banksel opt_gas_type+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
+	banksel common
+
+	movff   opt_gas_He_ratio+2,char_I_deco_He_ratio+2
+	movff   opt_gas_O2_ratio+2,char_I_deco_O2_ratio+2
+	banksel opt_gas_type+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
+	banksel common
+
+	movff   opt_gas_He_ratio+3,char_I_deco_He_ratio+3
+	movff   opt_gas_O2_ratio+3,char_I_deco_O2_ratio+3
+	banksel opt_gas_type+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
+	banksel common
+
+	movff   opt_gas_He_ratio+4,char_I_deco_He_ratio+4
+	movff   opt_gas_O2_ratio+4,char_I_deco_O2_ratio+4
+	banksel opt_gas_type+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
+	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
 
-    global  setup_dil_registers
-setup_dil_registers:                ; With WREG=dil 0-4
-    btfsc   is_bailout
-    return                          ; Ignore in bailout
-    lfsr    FSR1,opt_dil_O2_ratio+0
-    movff   PLUSW1,char_I_O2_ratio  ; O2 (For ppO2 calculations)
-    lfsr    FSR1,opt_dil_He_ratio+0
-    movff   PLUSW1,char_I_He_ratio  ; He
-    lfsr    FSR1,opt_dil_type
-    movff   PLUSW1,active_gas_type  ; 0=Disabled, 1=First, 2=Travel, 3=Deco for OC gases and 0=Disabled, 1=First, 2=Normal for diluents
-    incf    WREG,W                  ; Gas# 1-5
-	movff	WREG,char_I_current_gas	; Set gas
-	movff	WREG,active_gas			; Set for logbook and display
-    movff   WREG,active_diluent     ; As a backup when switching back from Bailout to CCR
-    banksel char_I_O2_ratio
-	movf    char_I_O2_ratio,W       ; Add O2...
-    addwf   char_I_He_ratio,W       ; ...and He...
-	sublw   .100                    ; ...subtract both from 100
-	movwf   char_I_N2_ratio         ; -> N2!
-    banksel common
-    return
+	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
+	movff	char_O_deco_status,lo		; working copy of char_O_deco_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_deco_status		; bank safe write-back of char_O_deco_status	
+		
+	return
 
-divemode_option_gaschange:          ; Switch to the better gas
-    movff   better_gas_number,menupos; 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
-    return
+	global  setup_gas_registers
+setup_gas_registers:						; with currently breathed gas in WREG (1-5 or 6)
+	movwf	active_gas						; set as current gas
+	movlw	.6
+	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	
+	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
+	movff	PLUSW1,char_I_O2_ratio			; copy gas 1-5 O2 ratio to deco engine
+	lfsr	FSR1,opt_gas_He_ratio+0
+	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
+	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!)
+	return
 
-divemode_option0:                   ; Start/Setup Divemode menu
-    call    TFT_clear_divemode_menu ; Clear menu area
-    bcf     menuview
-    extern  do_main_divemenu
-    call    do_main_divemenu
+	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
+	movlw	.6
+	cpfseq	active_gas						; 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
+	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
+	movff	PLUSW1,char_I_O2_ratio			; copy diluent 1-5 O2 ratio to deco engine
+	lfsr	FSR1,opt_dil_He_ratio+0
+	movff	PLUSW1,char_I_He_ratio			; copy diluent 1-5 He ratio to deco engine
+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!)
+	return
+
+divemode_option_gaschange:					; Switch to the better gas
+	movff	better_gas_number,menupos		; 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
+	return
+
+divemode_option0:							; Start/Setup Divemode menu
+	call	TFT_clear_divemode_menu			; Clear menu area
+	bcf	menuview
+	extern	do_main_divemenu
+	call	do_main_divemenu
+
     global  divemode_option0_return
 divemode_option0_return:
 ;    movlw   .1
@@ -1047,7 +1590,7 @@
 	movwf	timeout_counter3        ; timeout for divemode menu
     bsf     divemode_menu           ; Set flag
     clrf    menupos2                ; Clear option counter
-    bra     diveloop_loop4          ; Goto back to diveloop (Menuprocessor trashes STKPTR!)
+    goto	diveloop_loop4          ; Goto back to diveloop (Menuprocessor trashes STKPTR!)
 
 divemode_option4:
 	movlw	d'58'					; two seconds left
@@ -1056,7 +1599,7 @@
 	movwf	apnoe_timeout_counter
     btfss   simulatormode_active	; in simulator mode?
 	return							; No
-divemode_option1:						; Quit simulation mode
+divemode_option1:					; Quit simulation mode
 	banksel	isr_backup
     movlw   low     .1000
     movwf	sim_pressure+0
@@ -1073,7 +1616,7 @@
 	movwf	apnoe_timeout_counter
 	return
 
-divemode_option3:			; minus 1m
+divemode_option3:					; minus 1m
 	banksel	isr_backup
 	movlw	d'100'
 	subwf	sim_pressure+0
@@ -1083,7 +1626,7 @@
 	banksel common
 	return
 
-divemode_option2:			; plus 1m
+divemode_option2:					; plus 1m
 	banksel	isr_backup
 	movlw	d'100'
 	addwf	sim_pressure+0
@@ -1112,13 +1655,14 @@
     addwf   total_divetime_seconds+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
+
+	; 1. Add 300xdepth to the Sum of depths registers
     SAFE_2BYTE_COPY rel_pressure, xB	; Buffer...
     movlw   LOW     (.5*.60)
     movwf   xA+0
     movlw   HIGH    (.5*.60)
     movwf   xA+1
-    call    mult16x16           		;xA*xB=xC
+    call    mult16x16           		; xA*xB=xC
 
 	movf	xC+0,w
 	addwf	average_depth_hold+0,F
@@ -1127,32 +1671,23 @@
 	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
+	addwfc	average_depth_hold+3,F		; Will work up to 9999mbar*60*60*24=863913600mbar
 
-; Do the same for the _total registers (Non-Resettable)
+	; Do the same for the _total registers (Non-Resettable)
 	movf	xC+0,w
 	addwf	average_depth_hold_total+0,F
 	movf	xC+1,w
 	addwfc	average_depth_hold_total+1,F
 	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
+	movf	xC+3,w
+	addwfc	average_depth_hold_total+3,F; Will work up to 9999mbar*60*60*24=863913600mbar
 
-    movlw   .5
-    movwf   up                          ; counter
-; 1min mode
-divemode_option6_2:
-	movlw   .1
-	movff	WREG,char_I_step_is_1min    ; Force 1min mode
-    clrf    TMR5L
-    clrf    TMR5H                       ; 30,51757813µs/bit in TMR5L:TMR5H
-	call	deco_calc_hauptroutine		; calc_tissue
-    movlb   .1
-    decfsz  up,F                        ; Done?
-    bra     divemode_option6_2          ; Not yet
-    bsf     divemode2                   ; continue divetime
-    goto    menuview_toggle_reset	; and return...
+	movlw	.5							; + 5 minutes
+	movff	WREG,char_I_sim_advance_time; copy to mailbox
+	bsf     divemode2                   ; continue divetime
+	call	restart_deco_engine
+    goto    menuview_toggle_reset		; and return...
 
 divemode_option7:
     ; Store heading for compass view
@@ -1160,6 +1695,14 @@
     movff   compass_heading_shown+1,compass_bearing+1
     bsf     compass_bearing_set         ; set flag
     goto    menuview_toggle_reset       ; Done 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...
 
 divemode_simulator_check_limits:
 	; Check limits (150m and 0m)
@@ -1237,12 +1780,14 @@
     movlw   .4
     rcall   check_gas_common        ; With Gas 0-4 in WREG
 ;    bra     check_gas_change_exit
+
 check_gas_change_exit:
-    btfss	better_gas_available	; Is a better gas available
-    bcf     blinking_better_gas     ; No, Clear blinking flag
-    btfss	better_gas_available	; Is a better gas available
+    btfss   better_gas_available	; Is a better gas available
+    bcf     blinking_better_gas		; No, Clear blinking flag
+    btfss   better_gas_available	; Is a better gas available
     clrf    better_gas_number		; No, Clear better_gas_number (For gaslist display)
-    goto    TFT_active_gas_divemode ; Display gas/Setpoint and return...
+    bsf	    FLAG_TFT_active_gas_divemode; Redraw gas/setpoint/diluent
+    return
 
 check_gas_common:                   ; With Gas 0-4 in WREG
     btfsc   better_gas_available	; Better Gas already found?
@@ -1253,7 +1798,7 @@
     btfss   PLUSW1,1                ; Test for Bit0 and 1 -> type=3 -> Deco
     return                          ; No
     incf    WREG,W                  ; 1-5
-    cpfseq  active_gas				; is this gas currently selected?
+    cpfseq  active_gas				; is this gas current gas?
     bra     check_gas_common2       ; No
     return                          ; Yes, skip test for active gas
 check_gas_common2:
@@ -1272,7 +1817,7 @@
 	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<opt_ppO2_max
+    bra     check_gas_common4       ; Ok, now check the better gas ppO2<char_I_ppO2_max
     return
 
 check_gas_common3:
@@ -1281,20 +1826,13 @@
 	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<opt_ppO2_max
+    bra     check_gas_common4       ; Ok, now check the better gas ppO2<char_I_ppO2_max
     return
 
 check_gas_common4:
-    movf    hi,W                    ; 0-4
-    lfsr    FSR1,char_I_deco_N2_ratio
-    movff   PLUSW1,lo               ; N2 ratio into lo
-    lfsr    FSR1,char_I_deco_He_ratio
-    movff   PLUSW1,xB+0             ; He ratio into xB+0
-    movf    xB+0,W
-    addwf   lo,F
-    movlw   .101
-    bcf     STATUS,C
-    subfwb  lo,F                    ; O2 ratio in lo
+    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'
@@ -1308,35 +1846,35 @@
 	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.
+	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.
+	return                      	; Done.
 
     ; Check for low ppo2
 	movff	xC+0,sub_b+0
 	movff	xC+1,sub_b+1
-	movff   opt_ppO2_min,WREG
-	mullw	d'100'		    ; opt_ppO2_min*100
+	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
+	call	subU16		    		; sub_c = sub_a - sub_b
 	btfss	neg_flag
-	return                      ; Done (Too low).
+	return                      	; Done (Too low).
 
-;check if we are within our warning thresholds!
+	;check if we are within our warning thresholds!
 	movff	xC+0,sub_a+0
 	movff	xC+1,sub_a+1
-	movff	opt_ppO2_max_deco,WREG	; PPO2 Max for MOD calculation and color coding in divemode
-	addlw   .1                  ; e.g. >1.60
-	mullw	d'100'		    ; opt_ppO2_max*100
+	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
 	movff	PRODL,sub_b+0
 	movff	PRODH,sub_b+1
-	call	subU16		    ; sub_c = sub_a - sub_b
+	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.
+	return                      	; Done.
 
 check_dil_common:                   ; With Dil 0-4 in WREG
     btfsc   better_gas_available	; Better Diluent already found?
@@ -1347,7 +1885,7 @@
     return                          ; Yes, skip inactive diluents for test
 check_dil_common1:
     incf    WREG,W                  ; 1-5
-    cpfseq  active_gas				; is this diluent currently selected?
+    cpfseq  active_gas				; is this the current diluent?
     bra     check_dil_common2       ; No
     return                          ; Yes, skip test for active diluent
 check_dil_common2:
@@ -1373,11 +1911,11 @@
 ;=============================================================================
 ; 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
+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
 check_dive_autosp2:
     SAFE_2BYTE_COPY rel_pressure,xA
 	movlw	d'100'
@@ -1385,17 +1923,18 @@
 	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
+    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     $+4                     ; No, continue
+    bra     check_dive_autosp2a     ; No, continue
     bra     check_dive_autosp3      ; Skip check
+check_dive_autosp2a:
     decf    lo,W                    ; -1 -> WREG
     cpfsgt  xC+0                    ; Compare with depth
     bra     check_dive_autosp3      ; lower depth, do not switch
     ; auto switch to SP2
-	movff	char_I_setpoint_cbar+1, char_I_const_ppO2	; Use SetPoint
+	movff	char_I_setpoint_cbar+1,char_I_const_ppO2	; Use SetPoint
     rcall   xmit_sp_set_flag
     bsf     sp2_switched            ; Set flag
 check_dive_autosp3:
@@ -1404,13 +1943,14 @@
     bra     check_dive_autosp4      ; Skip check
     movff   char_I_setpoint_change+2,lo ; Get depth in m
     tstfsz  lo                      ; =0?
-    bra     $+4                     ; No, continue
+    bra     check_dive_autosp3a      ; No, continue
     bra     check_dive_autosp4      ; Skip check
+check_dive_autosp3a:
     decf    lo,W                    ; -1 -> WREG
     cpfsgt  xC+0                    ; Compare with depth
     bra     check_dive_autosp4      ; lower depth, do not switch
     ; auto switch to SP3
-	movff	char_I_setpoint_cbar+2, char_I_const_ppO2	; Use SetPoint
+	movff	char_I_setpoint_cbar+2,char_I_const_ppO2	; Use SetPoint
     rcall   xmit_sp_set_flag
     bsf     sp3_switched            ; Set flag
 check_dive_autosp4:
@@ -1419,13 +1959,14 @@
     bra     check_dive_autosp5      ; Skip check
     movff   char_I_setpoint_change+3,lo ; Get depth in m
     tstfsz  lo                      ; =0?
-    bra     $+4                     ; No, continue
+    bra     check_dive_autosp4a     ; No, continue
     bra     check_dive_autosp5      ; Skip check
+check_dive_autosp4a:
     decf    lo,W                    ; -1 -> WREG
     cpfsgt  xC+0                    ; Compare with depth
     bra     check_dive_autosp5      ; lower depth, do not switch
     ; auto switch to SP4
-	movff	char_I_setpoint_cbar+3, char_I_const_ppO2	; Use SetPoint
+	movff	char_I_setpoint_cbar+3,char_I_const_ppO2	; Use SetPoint
     rcall   xmit_sp_set_flag
     bsf     sp4_switched            ; Set flag
 check_dive_autosp5:
@@ -1434,13 +1975,14 @@
     bra     check_dive_autosp6      ; Skip check
     movff   char_I_setpoint_change+4,lo ; Get depth in m
     tstfsz  lo                      ; =0?
-    bra     $+4                     ; No, continue
+    bra     check_dive_autosp5a     ; No, continue
     bra     check_dive_autosp6      ; Skip check
+check_dive_autosp5a:
     decf    lo,W                    ; -1 -> WREG
     cpfsgt  xC+0                    ; Compare with depth
     bra     check_dive_autosp6      ; lower depth, do not switch
     ; auto switch to SP5
-	movff	char_I_setpoint_cbar+4, char_I_const_ppO2	; Use SetPoint
+	movff	char_I_setpoint_cbar+4,char_I_const_ppO2	; Use SetPoint
     rcall   xmit_sp_set_flag
     bsf     sp5_switched            ; Set flag
 check_dive_autosp6:
@@ -1448,7 +1990,7 @@
 
 xmit_sp_set_flag:
     movff   char_I_const_ppO2,WREG
-    call    transmit_setpoint           ; Transmit current setpoint from WREG (in cbar) to external electronics
+    call    transmit_setpoint       ; Transmit current setpoint from WREG (in cbar) to external electronics
     bsf     setpoint_changed        ; Set flag (For profile)
     bsf		event_occured			; Set global event byte
     return
@@ -1457,54 +1999,58 @@
 ; Setup everything to enter divemode.
 ;
 dive_boot_oc:
-    extern  get_first_gas_to_WREG
-    call    get_first_gas_to_WREG           ; Gets first gas (0-4) into WREG
-    incf    WREG
-    movff   WREG,char_I_first_gas           ; Copy for compatibility (1-5)
-    decf    WREG,W			    ; decrement WREG to old value again
-    rcall    setup_gas_registers            ; With WREG=Gas 0-4
-    movlw   .0
-    movff   WREG,char_I_const_ppO2	    ; deactivate CCR-mode deco calc
+    rcall   get_first_gas_to_WREG			; Gets 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
 
 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
-    ; load default setpoint
-    movff   char_I_setpoint_cbar+0,char_I_const_ppO2    ; Always start with SP1
-    movff   char_I_const_ppO2,WREG
+    bcf		blinking_setpoint               ; Reset blinking SP flag
 
-    call    transmit_setpoint           ; Transmit current setpoint from WREG (in cbar) to external electronics
+	; revoke sensors from usage if they do not have a valid calibration
+	bsf		use_O2_sensor1
+	bsf		use_O2_sensor2
+	bsf		use_O2_sensor3
+	btfss	sensor1_calibrated_ok
+	bcf		use_O2_sensor1
+	btfss	sensor2_calibrated_ok
+	bcf		use_O2_sensor2
+	btfss	sensor3_calibrated_ok
+	bcf		use_O2_sensor3
 	
-    ; check if in sensor mode
-    movff   opt_ccr_mode,WREG               ; =0: Fixed SP, =1: Sensor,  =2: Auto SP
-    sublw   .1                              ; opt_ccr_mode = 1 (Sensor)?
-    bnz     dive_boot_cc2                   ; No, Skip
+	; 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.
+	btfss	FLAG_pscr_mode
+	bra		dive_boot_cc_1
+	movff   opt_ccr_mode,WREG				; =0: Fixed SP, =1: Sensor,  =2: Auto SP
+    sublw   .2								; opt_ccr_mode = 1 (Auto SP)?
+    bnz     dive_boot_cc_1
+	movlw	.0
+	movff	WREG,opt_ccr_mode
 
-    ; get initial setpoint from all sensors in use
-    call   compute_ppo2                    ; compute mv_sensorX and ppo2_sensorX arrays
-    bsf    voting_logic_sensor1            ; voting logic not used while computing initial setpoint	
-    bsf    voting_logic_sensor2
-    bsf    voting_logic_sensor3
-    call   divemode_setup_sensor_values     ; setup sensor values
-    tstfsz sensor_setpoint		    ; if no sensor is in use, sensor_setpoint will be zero
-    movff  sensor_setpoint,char_I_const_ppO2; overwrite default only if we have a valid sensor_setpoint 
-
-dive_boot_cc2:
+dive_boot_cc_1:
     bsf     setpoint_changed                ; Set flag (For profile)
     bcf     sp2_switched                    ; =1: This setpoint has been autoselected already
     bcf     sp3_switched                    ; =1: This setpoint has been autoselected already
     bcf     sp4_switched                    ; =1: This setpoint has been autoselected already
     bcf     sp5_switched                    ; =1: This setpoint has been autoselected already
 
-    extern  get_first_dil_to_WREG
-    call    get_first_dil_to_WREG           ; Gets first gas (0-4) into WREG
-    incf    WREG
-    movff   WREG,char_I_first_gas           ; Copy for compatibility
-    decf    WREG,W
-    rcall   setup_dil_registers             ; With WREG=Gas 0-4
-    goto  calc_deko_divemode_sensor        ; External sensor stuff (and return!)
+    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)
+
+	; 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
+	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:
 	call	restart_set_modes_and_flags
@@ -1515,9 +2061,45 @@
 	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
+	
+	bcf		blinking_depth_prev				; clear flag for blinking depth	## NEW BUGFIX
+	bcf		blinking_depth_warning			; clear flag for blinking depth	## NEW BUGFIX
+	bcf		blinking_depth_toggle			; clear flag for blinking depth	## NEW BUGFIX
+	
 	movlw	d'1'
 	movwf	apnoe_max_pressure+0
 	clrf	apnoe_max_pressure+1
@@ -1526,66 +2108,65 @@
 	clrf	apnoe_mins
 	clrf	divemins+0
 	clrf	divemins+1
-
-	bcf        blinking_depth_prev                ; clear flag for blinking depth    ## NEW BUGFIX
-	bcf        blinking_depth_warning         ; clear flag for blinking depth    ## NEW BUGFIX
-	bcf        blinking_depth_toggle            ; clear flag for blinking depth    ## NEW BUGFIX
     
-; Copy date and time for logbook
+	; Copy date and time for logbook
     movff   year,start_year
     movff   month,start_month
     movff   day,start_day
     movff   hours,start_hours
     movff   mins,start_mins
     
-    movff   int_O_CNS_fraction+0,CNS_start+0
-    movff   int_O_CNS_fraction+1,CNS_start+1   ; Save CNS value at beginning of dive
-    movff   char_O_gradient_factor,GF_start    ; Save GF value at  beginning of dive
+    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 bit
+	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 divemode
 	bcf		divemode_menu_active
     clrf    menupos
-    clrf    menupos2                    ; Reset to zero (Zero=no premenu or simulator task)
-
+    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
+    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
+    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
+    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
+    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
+    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	better_gas_number           ; Clear better gas register
 
-	bcf		show_safety_stop			;=1: Show the safety stop
+	bcf		show_safety_stop			; =1: Show the safety stop
 	clrf	safety_stop_countdown		; Clear count-down
 
  	clrf	samplesecs
@@ -1598,9 +2179,9 @@
 	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
+    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
 
     btfsc   simulatormode_active
@@ -1613,17 +2194,17 @@
 diveloop_boot_1:
     ; Simulator mode: Surface pressure is 1bar.
     movlw   LOW .1000
-	movff	WREG,int_I_pres_surface+0   ; LOW copy surfacepressure to deco routine
+	movff	WREG,int_I_pres_surface+0   	; LOW copy surfacepressure to deco routine
     movlw   HIGH .1000
-	movff	WREG,int_I_pres_surface+1   ; HIGH copy surfacepressure to deco routine
+	movff	WREG,int_I_pres_surface+1   	; HIGH copy surfacepressure to deco routine
 
 diveloop_boot_2:
 	SAFE_2BYTE_COPY	temperature,minimum_temperature ; Reset Min-Temp registers
 
 ; Init profile recording parameters	
-	movff	samplingrate,samplesecs_value            ; to avoid EEPROM access in the ISR
+	movff	samplingrate,samplesecs_value	; to avoid EEPROM access in the ISR
 	movlw	div_temperature
-	movwf	divisor_temperature         ; load divisors for profile storage
+	movwf	divisor_temperature         	; load divisors for profile storage
 	movlw	div_deco
 	movwf	divisor_deco				
 	movlw	div_gf
@@ -1637,14 +2218,16 @@
 	movlw	div_tank
 	movwf	divisor_tank
 
-	btfss	FLAG_apnoe_mode				; In Apnoe mode?
+	btfss	FLAG_apnoe_mode					; In Apnoe mode?
 	bra		divemode_boot1
-; Overwrite some parameters in Apnoe mode....
+
+	; Overwrite some parameters in Apnoe mode....
 	movlw	samplingrate_apnoe
-	movwf	samplesecs_value			; to avoid EEPROM access in the ISR
+	movwf	samplesecs_value				; to avoid EEPROM access in the ISR
+
 divemode_boot1:
-    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
+    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
     btfsc   FLAG_pscr_mode
     bra     divemode_boot2
@@ -1653,84 +2236,115 @@
     movlw   .0
     movwf   divisor_ppo2_sensors
     
-    bcf     ccr_diluent_setup		; For OC mode (Required to have better gas working)
+    bcf     ccr_diluent_setup				; For OC mode (Required to have better gas working)
+
 divemode_boot2:
-
 	bcf		LEDg
 	bcf		LEDr
 	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 ...
+	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
+    movlw   .2                          	; Start at 2seconds
     movwf   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
+    bsf	    divemode2                   	; displayed divetime is running (Divetime starts HERE)
+    return									; Done with divemode boot
 
 divemode_check_for_warnings:
-    movlw   .2
-    cpfsgt  warning_counter						; only two warnings active?
-    bra     divemode_check_for_warnings1        ; Yes, update every second
+    movlw   .1				    			; One warning at a time in alt. layout mode
+    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...
+    btfss   secs,0                      	; Every two seconds...
     return
-    btfss   secs,1                      ; Every four seconds...
+    btfss   secs,1                      	; Every four seconds...
     return
 
 divemode_check_for_warnings1:
-	movf	warning_counter_backup,W
-	cpfseq	warning_counter						; warning_counter_backup = warning_counter?
-	call	TFT_clear_warning_text              ; No, clear all warnings
-	movff	warning_counter,warning_counter_backup	; copy warning_counter
-
-	bcf		warning_active				; Clear flag
+	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
+	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
+	btfsc	FLAG_gauge_mode             		; Done for Apnoe or Gauge mode
 	bra     divemode_check_for_warnings2
 
     ; Warnings only in deco modes
-    	rcall	check_ppO2							; check ppO2 and displays warning, if required
+    rcall	check_ppO2							; check ppO2 and displays warning, if required
 	
-	rcall	check_cns_violation					; Check CNS value and display it, if required
+	btfss	sensors_agree						; are the sensor values within the threshold range?
+	rcall	check_warn_sensors_disagree			; NO  - further evaluate
+	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_IBCD							; check for IBCD attention or warning
+	
 	btfsc	decostop_active						; In deco mode?
-	rcall	check_and_store_gf_violation		; Yes, Sets warnings, if required
-	btfsc	decostop_active						; In deco mode?
-    call    TFT_ftts                            ; Show @+x time
+	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_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
-
+	
 divemode_check_for_warnings2:
 ; Display the warning icon?
-	btfsc	warning_active				; Any warning active?
-	call	TFT_divemode_warning				; Yes
-	btfss	warning_active				; Any warning active?
-	call	TFT_divemode_warning_clear			; No, clear 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
     bcf     STATUS,C
-    rlcf    warning_page,W                      ; *2
+    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
+	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
-    call    TFT_clear_warning_text_2nd_row      ; No, clear this row
+    bsf	    FLAG_TFT_dive_warning_text_clr2	; Set flag for 2nd row
     return                                      ; Done.
 
     global  check_warn_battery
@@ -1738,210 +2352,192 @@
     movff   batt_percent,lo
     movlw	battery_show_level+1
     cpfslt	lo
-    return                              ; No Display, no warning
+    return                              		; 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
+    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)
+    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)
 check_warn_battery2:
-    incf	warning_counter,F		    ; increase counter
-    goto	TFT_update_batt_percent_divemode    ; Show percent (And return)
+    incf	warning_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)
+    return										; displayed divetime is not running
+	incf	warning_counter,F					; increase counter
+    goto    TFT_divetimeout						; Show timeout counter  (and return)
 
 
-check_ppO2:							    ; check current ppO2 and display warning if required
-    btfss	FLAG_pscr_mode
-    bra		check_ppO2_non_pscr		; Non-PSCR modes...
-    	; in PSCR mode
-    btfsc	is_bailout
-    bra		check_ppO2_non_pscr		; Non-PSCR modes...
-	
-    call		compute_pscr_ppo2		; pSCR ppO2 into sub_c:2
-    movff		sub_c+0,xA+0
-    movff		sub_c+1,xA+1
-    movlw		d'100'
-    movwf		xB+0
-    clrf		xB+1
-    call		div16x16				; /100
-    tstfsz      xC+1                    ; Is ppO2 > 2.55bar ?
-    setf        xC+0                    ; yes: bound to 2.55... better than wrap around.
-    movff		xC+0,char_I_actual_ppO2	; copy last ppO2 to buffer register (for pSCR CNS)
-    clrf		xC+2
-    clrf		xC+3
-    movff		sub_c+0,xC+0
-    movff		sub_c+1,xC+1			; copy for comptibility
-    bra			check_ppO2_check
-
-check_ppO2_non_pscr:    
-    SAFE_2BYTE_COPY amb_pressure, xA
-    movlw	d'10'
-    movwf	xB+0
-    clrf	xB+1
-    call	div16x16				; xC=p_amb/10
-
-    movff	xC+0,xA+0
-    movff	xC+1,xA+1
-    movff   char_I_O2_ratio,xB+0    ; =O2 ratio
-    clrf	xB+1
-    call	mult16x16               ; char_I_O2_ratio * p_amb/10
-
-check_ppO2_check:
-    ; Check very high ppO2 manually
-	tstfsz	xC+2				; char_I_O2_ratio * p_amb/10 > 65536, ppO2>6,55bar?
-	bra		check_ppO2_1		; Yes, display Value!
-    ; Check if ppO2>3,30bar
-	btfsc   xC+1,7
-	bra     check_ppO2_1		; Yes!
-
-    ; Check for low ppo2
-    movff	xC+0,sub_b+0
-	movff	xC+1,sub_b+1
-    movff   opt_ppO2_min,WREG
-	mullw	d'100'				; opt_ppO2_min*100
-	movff	PRODL,sub_a+0
-	movff	PRODH,sub_a+1
-	call	subU16
-	btfsc	neg_flag
-	bra     check_ppO2_0        ; Not too low
-    ; ppO2 low
-    rcall   check_ppo2_display  ; display if not already shown in custom view
-	movlw	d'4'				; Type of Alarm (ppO2 low)
-	movwf	AlarmType			; Copy to Alarm Register
-	bsf		event_occured		; Set Event Flag
-	bsf		warning_active		; Set Warning flag
-	return						; Done.
-
-check_ppO2_0:
-    ; Check if ppO2 should be displayed
-    movlw   .0
-    TSTOSS  opt_showppo2		; 0=no, 1=always show
-    movlw   ppo2_display_high
-	mullw	d'100'				; ppo2_display_high*100
-	movff	PRODL,sub_a+0
-	movff	PRODH,sub_a+1
-	call	subU16
-	btfss	neg_flag
-	return						; No Display, no warning
-    ; Display ppO2, but warn?
-    rcall   check_ppo2_display  ; display if not already shown in custom view
-
-;check if we are within our warning thresholds!
-	movff	xC+0,sub_b+0
-	movff	xC+1,sub_b+1
-		;active_gas_type -> 0=Disabled, 1=First, 2=Travel, 3=Deco for OC gases and 0=Disabled, 1=First, 2=Normal for diluents	
-	movff   active_gas_type,xA+0	; xA+0 used as temp here -> holds type
-	movff   opt_ppO2_max_deco,xB+1	; xB+1 used as temp here
-	movlw	.3			
-	cpfseq	xA+0			; Deco?
-	movff   opt_ppO2_max,xB+1	; No, overwrite with travel/bottom max
-	movf	xB+1,W			; Result in WREG
-	mullw	d'100'				; opt_ppO2_max*100
-	movff	PRODL,sub_a+0
-	movff	PRODH,sub_a+1
-	infsnz	sub_a+0,F		
-	incf	sub_b+1,F		
-	call	subU16					
-	btfss	neg_flag
-	return						; Done. Not too high
-	movlw	d'5'				; Type of Alarm (ppO2 high)
-	movwf	AlarmType			; Copy to Alarm Register
-	bsf		event_occured		; Set Event Flag
-	bsf		warning_active		; Set Warning flag
-	return						; Done.
-
-check_ppO2_1:                   ; ppO2 very high
-    rcall   check_ppo2_display  ; display if not already shown in custom view
-	movlw	d'5'				; Type of Alarm
-	movwf	AlarmType			; Copy to Alarm Register
-	bsf		event_occured		; Set Event Flag
-	bsf		warning_active		; Set Warning flag
-	return						; Done.
-
-check_ppo2_display:
+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_d				; 		YES - show warning and return on next line
+	bra		check_ppO2_oc_2				;		      skip pre-warning 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_prewarning_flag	; breathed ppO2 just above pre-warning 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?
+	bra		check_ppO2_low				; YES - record the warning and show ppO2
+	btfsc	WREG,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
+check_ppO2_low:
+    movlw	d'4'						; set type of alarm (ppO2 low)
+	bra		check_ppO2_common  			; continue with common part
+check_ppO2_high:
+	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)
+    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)
+    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)
 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)
+    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)
+    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)
 check_ppO2_d:    
-    incf	warning_counter,F	; increase counter
-    goto    TFT_display_ppo2	; Show ppO2  (and return)
+    incf	warning_counter,F			; increase counter
+    goto    TFT_display_ppo2			; show breathed gas or diluent ppO2 warning (and return)
+	
 
     global  check_cns_violation
 check_cns_violation:
     ; Check if CNS should be displayed
-    movff   int_O_CNS_fraction+1,lo		; copy into bank1
-    tstfsz  lo                          ; >255% ?
-    bra     check_cns_violation2        ; Yes
-	movff	int_O_CNS_fraction+0,lo		; copy into bank1
-
-	movlw	cns_warning_high			; cns_warning_high
-	subwf	lo,W
-	btfsc	STATUS,C
-	bsf		warning_active              ; Set Warning flag
+    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_prewarning_flag	; pre-warning 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)
 
-	movlw	cns_display_high			; cns_display_high
-	subwf	lo,W
-	btfss	STATUS,C
-	return                              ; No Display, no warning
-    ; Display CNS
-	bra	display_cns_violation
-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:
-	incf	warning_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
+    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
+    btfsc	WREG,int_warning_flag		; NO  - flag for warning set?
+    bra     check_eod_cns_violation2	; 		YES - issue warning
+check_eod_cns_violation1:				; 		NO  - continue with checking the other CNS value
+    movff   int_O_alternate_CNS_fraction+1,WREG
+	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
+	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)
+display_eod_cns_violation:
+	incf	warning_counter,F	    	; increase counter
+    goto	TFT_display_eod_cns			; issue CNS at end-of-dive warning (and return)
+
+
     global  check_and_store_gf_violation
 check_and_store_gf_violation:
-	movff	char_O_gradient_factor,lo			; gradient factor absolute (Non-GF model)
-
-	movlw	gf_warning_high
-	cpfsgt	lo
-	bra     check_and_store_gf_violation2   ; No warning
-	movlw	d'2'                        ; Type of Alarm
-	movwf	AlarmType                   ; Copy to Alarm Register
-	bsf		event_occured               ; Set Event Flag
+	movff	int_O_gradient_factor+1,WREG	; get upper byte of gradient factor
+	btfss	WREG,int_warning_flag			; check if the warning flag is set
+	bra     check_and_store_gf_violation2   ; NO  - continue with checking for pre-warning
+	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
+	bra		check_and_store_gf_violation3	;		show gf warning
+check_and_store_gf_violation2:
+	btfsc	WREG,int_prewarning_flag		; check if the pre-warning flag is set
+    bra		check_and_store_gf_violation3	; YES - show gf
+	TSTOSS	opt_enable_IBCD					; NO  - IBCD warning activated?
+	bra		check_and_store_gf_violation4	; 		NO  - continue checking of deco info
+	movff	char_O_deco_warnings,WREG		; 		YES - get the deco warnings vector
+	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
+    goto    TFT_warning_gf              	; show GF (and return)
+check_and_store_gf_violation4:				; check for deco info
+	btfss	divemode						; in divemode?
+	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
-check_and_store_gf_violation2:
-	movlw	gf_display_high
-	cpfsgt	lo
-    return                              ; No Display, no warning
-    ; Display GF
+    goto    TFT_warning_outside			; show microbubbles warning (and return)
+
+	
+	global	warn_mbubbles
+warn_mbubbles:
 	incf	warning_counter,F			; increase counter
-    goto    TFT_warning_gf              ; Show GF Warning (and return)
-
+	bsf		warning_active              ; Set Warning flag
+    goto    TFT_warning_mbubbles		; show microbubbles warning (and return)
+	
 warn_agf:
 	incf	warning_counter,F			; increase counter
 	goto    TFT_warning_agf             ; Show aGF warning  (and return)
@@ -1951,5 +2547,87 @@
     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)
+	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
+	goto	TFT_warning_gas_needs_warn	; Yes - show a warning
+	btfsc	WREG,int_prewarning_flag	; NO  - 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
+	return
 
+	
+check_warn_sensors_disagree:
+    incf	warning_counter,F			; increase counter
+	bsf		warning_active				; YES - set Warning flag
+	goto	TFT_warning_sensor_disagree	; 		show sensor disagree warning (and return)
+
+
+check_IBCD:
+	TSTOSS	opt_enable_IBCD				; IBCD warning activated?
+	return								; NO  - done
+	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
+	goto	TFT_warning_IBCD			;			  write warning to display
+	
+
+
+	global	restart_deco_engine
+	global	restart_deco_engine_wo_ceiling
+restart_deco_engine:
+	; make bank save copies and set flags for invalid data
+	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
+	movff	char_O_deco_gas+0,WREG
+	bsf		WREG,char_invalid_flag
+	movff	WREG,char_O_deco_gas+0
+
+	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
+
+	movff	int_O_normal_CNS_fraction+1,WREG
+	bsf		WREG,int_invalid_flag
+	movff	WREG,int_O_normal_CNS_fraction+1
+
+	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
+	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
+
+    return
+	
+	
  END
\ No newline at end of file