changeset 657:c2e97f94c55f default tip

bump to 10.93 / 3.32
author heinrichsweikamp
date Tue, 27 Jan 2026 11:01:04 +0100
parents 8af5aefbcdaf
children
files src/configuration.inc src/convert.asm src/customview.asm src/divemode.asm src/hwos.inc src/i2c.asm src/menu_tree.asm src/option_table.asm src/p2_deco.c src/start.asm src/surfmode.asm src/text_english.inc src/text_french.inc src/text_german.inc src/text_italian.inc src/text_multilang.asm src/tft_outputs.asm src/tft_outputs.inc
diffstat 18 files changed, 367 insertions(+), 128 deletions(-) [+]
line wrap: on
line diff
--- a/src/configuration.inc	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/configuration.inc	Tue Jan 27 11:01:04 2026 +0100
@@ -23,9 +23,9 @@
 ;
 #endif
 
-#define fw_version_major		.3
-#define fw_version_minor		.31
-#define fw_version_beta			0x01
+#define fw_version_major		.10
+#define fw_version_minor		.93
+#define fw_version_beta			0x00
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -42,11 +42,11 @@
 ;
 #endif
 
-#define firmware_creation_year	.25;0x18
-#define firmware_creation_month	.11;0x09
-#define firmware_creation_day	.24;0x06
+#define firmware_creation_year	.26;0x18
+#define firmware_creation_month	.01;0x09
+#define firmware_creation_day	.10;0x06
 
-#define firmware_expire_year	.28;0x18
+#define firmware_expire_year	.29;0x18
 #define firmware_expire_month	.08;0x08
 #define firmware_expire_day	.29;0x1C
 
@@ -64,7 +64,7 @@
 ;                                                                                    122.880 max. available
 #endif
 
-#define _hwos_tech_2_TR_cave
+#define _hwos_sport
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -80,7 +80,7 @@
 #endif
 
 #define _language_1		en
-#define _language_2		none
+#define _language_2		de
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -207,7 +207,7 @@
 #define _gas_contingency
 #define _cave_mode
 #define _big_divemenu
-#define _firmware_recovery
+#define NOT_INCLUDED_firmware_recovery
 #define NOT_INCLUDED_min_depth_option
 #define NOT_INCLUDED_screendump
 
--- a/src/convert.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/convert.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -588,8 +588,8 @@
 	call	output99x_call			; ...
 	PUTC	'.'						; print spacing dot
 	movff	up,lo					; print up (00-99)
-	call	output99x_call			; ...
-	return							; done
+	goto	output99x_call			; ... (And return)
+	;return							; done
 
 
 ;=============================================================================
--- a/src/customview.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/customview.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -127,9 +127,9 @@
 	incf	active_customview,F			; set number of the next custom view to show
 
  IFDEF _compass
-	movlw	.6							; load index of surface custom view compass
-	cpfseq	active_customview			; will the compass be shown in custom view?
-	call	I2C_sleep_compass			; NO - can stop the compass to save on energy
+;	movlw	.6							; load index of surface custom view compass
+;	cpfseq	active_customview			; will the compass be shown in custom view?
+;	call	I2C_sleep_compass			; NO - can stop the compass to save on energy
  ENDIF
 
 	movlw	num_surface_cv				; load number of custom views available
@@ -258,7 +258,7 @@
 	;
 surf_customview_init_view6:
  IFDEF _compass
-	call	I2C_init_compass			; start compass
+;	call	I2C_init_compass			; start compass
 	btfss	compass_present
 	bra		surf_customview_toggle		; not available without compass compiled in, goto next view
 	call	TFT_surface_compass_mask	; show compass mask
@@ -602,9 +602,9 @@
 ;
 	global	dive_customview_callup
 dive_customview_callup:
-	movlw	index_compass_dm			; get index of compass custom view
-	cpfseq	active_customview			; will compass be shown?
-	call	I2C_sleep_compass			; NO - stop compass to save on energy
+;	movlw	index_compass_dm			; get index of compass custom view
+;	cpfseq	active_customview			; will compass be shown?
+;	call	I2C_sleep_compass			; NO - stop compass to save on energy
 
 	; clear custom view area in dive mode
 	WIN_BOX_BLACK dm_customview_row, dm_customview_bot-.2, dm_customview_column, dm_customview_rgt ; top, bottom, left, right
@@ -614,7 +614,7 @@
 	dcfsnz	WREG,F						;
 	bra		init_avr_stopwatch			;  1: average depth and stopwatch
 	dcfsnz	WREG,F						;
-	bra		init_TFT_dive_compass		;  2: compass
+	bra		init_TFT_dive_compass			;  2: compass
 	dcfsnz	WREG,F						;
 	bra		init_ppo2_sensors			;  3: ppO2 sensors
 	dcfsnz	WREG,F						;
@@ -624,21 +624,21 @@
 	dcfsnz	WREG,F						;
 	bra		init_pressures_SAC			;  6: tank pressure and SAC rate
 	dcfsnz	WREG,F						;
-	bra		init_gas_needs_ascent		;  7: gas needs for ascent / cave return
+	bra		init_gas_needs_ascent			;  7: gas needs for ascent / cave return
 	dcfsnz	WREG,F						;
 	bra		init_cave_tts				;  8: cave mode TTS
 	dcfsnz	WREG,F						;
 	bra		init_decoplan				;  9: deco plan (next stops)
 	dcfsnz	WREG,F						;
-	bra		init_ceiling_GF_tissue		; 10: ceiling, current GF and tissues
+	bra		init_ceiling_GF_tissue			; 10: ceiling, current GF and tissues
 	dcfsnz	WREG,F						;
-	bra		init_ceiling_GF_surfGF		; 11: ceiling, current GF and surfGF
+	bra		init_ceiling_GF_surfGF			; 11: ceiling, current GF and surfGF
 	dcfsnz	WREG,F						;
-	bra		init_CNS					; 12: CNS values
+	bra		init_CNS				; 12: CNS values
 	dcfsnz	WREG,F						;
-	bra		init_ppo2_ead_end_cns		; 13: ppO2, END/EAD and CNS/gas density
+	bra		init_ppo2_ead_end_cns			; 13: ppO2, END/EAD and CNS/gas density
 	dcfsnz	WREG,F						;
-	bra		init_clock_batt_surfpress	; 14: clock, battery and surface pressure
+	bra		init_clock_batt_surfpress		; 14: clock, battery and surface pressure
 	dcfsnz	WREG,F						;
 	bra		init_gf_factors				; 15: GF factors
 	dcfsnz	WREG,F						;
@@ -664,7 +664,7 @@
 	;
 init_TFT_dive_compass:
  IFDEF _compass
-	call	I2C_init_compass			; start compass
+;	call	I2C_init_compass			; start compass
 	btfss	compass_present
 	bra		dive_customview_toggle		; not available without compass compiled in, goto next view
 	call	TFT_dive_compass_mask		; mask for compass
@@ -853,6 +853,8 @@
 	;
 init_cave_waypoints:
  IFDEF _cave_mode
+ 	btfss	cave_mode					; cave mode switched on?
+	bra		dive_customview_toggle		;       NO - goto next view
 	call	TFT_cave_waypoints			; show waypoint graphics
 	bra		dive_cv_toggle_exit			; done
  ELSE
--- a/src/divemode.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/divemode.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -562,6 +562,39 @@
 	movff	WREG,opt_brightness_divemode			;     - set brightness to ECO
 
 update_divemode60_1:
+ IFDEF _ccr_pscr
+	TSTOSS	opt_ScrubTmrEnable			; Scrubber Timer Enabled?	   
+	bra	update_divemode60_3			; NO  - skip next
+
+	btfsc	sensor_override_active			; in simulator mode?
+	bra	update_divemode60_3	    		; YES  - skip next
+	
+	btfsc	FLAG_ccr_mode				; check if we are in CCR mode
+	bra	update_divemode60_1_2			; YES - continue with further checks
+	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
+	bra	update_divemode60_1_2			; YES - continue with further checks
+	bra	update_divemode60_3			; NO  - skip next
+update_divemode60_1_2:
+	btfsc	bailout_mode				; =1: in bailout mode
+	bra	update_divemode60_3			; YES  - skip next
+	MOVII	opt_scrubber_timer_mins,mpr			; Get the minutes into lo:hi
+	btfss	hi,7					; already negative?
+	bra	update_divemode60_1_3			; No, count-down
+	; count up
+	INCI	mpr					; ++1
+	bra	update_divemode60_2			; done
+update_divemode60_1_3:
+	; count down
+	DECI	mpr					; --1
+	btfss	hi,7					; already negative?
+	bra	update_divemode60_2			; No, done
+	clrf	lo
+	movlw	b'10000000'
+	movwf	hi					; clear and set negative bit
+update_divemode60_2:
+	MOVII	mpr,opt_scrubber_timer_mins			; Copy result back into opt_scrubber_timer_mins:2
+update_divemode60_3:	
+ ENDIF	
 	; max allowed runtime in simulator is 254 minutes in
 	; order for the tissue calculation catch-up to work!
 
@@ -3194,7 +3227,7 @@
 	call	restart_set_modes_and_flags	; basic settings depending on deco mode
 
 	; save on energy
-	call	I2C_sleep_compass			; stop accelerometer and compass
+;	call	I2C_sleep_compass			; stop accelerometer and compass
 
 	; do an early initialization of all deco engine output variables to
 	; avoid glitches in the display outputs during deco engine start-up
@@ -3481,6 +3514,12 @@
 	rcall	check_gas_density			; YES - check gas density
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
 	rcall	check_gas_density			; YES - check gas density
+
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	rcall	check_scrubber_timer			; YES - check the scrubber (If it's enabled)
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	rcall	check_scrubber_timer			; YES - check the scrubber (If it's enabled)
+
  ENDIF
 
 	btfsc	use_aGF						; using alternative GF factors?
@@ -4002,6 +4041,41 @@
 	incf	message_counter,F			;           - increase message counter
 	goto	TFT_message_no_BO_gas		;           - show message and return
 
+	
+;-----------------------------------------------------------------------------
+; Check the scrubber timer
+;
+check_scrubber_timer:	
+	bcf	attn_scrubber_timer		; clear warning by default
+	TSTOSS	opt_ScrubTmrEnable		; Scrubber Timer Enabled?	   
+	return					; NO  - Done.
+	MOVII	opt_scrubber_timer_mins,mpr	; Get the minutes into lo:hi
+	btfsc	hi,7				; Negative timer?
+	bra	check_scrubber_timer4		; YES, Show the warning
+check_scrubber_timer2:				; NO
+	movff	lo,sub_a+0
+	movff	hi,sub_a+1
+	movlw	low_scrubber_threshold+0
+	movwf	sub_b+0
+	movlw	low_scrubber_threshold+1
+	movwf	sub_b+1
+	call	cmpU16				; sub_a - sub_b
+	btfss	neg_flag			; theshold triggered?
+	bra	check_scrubber_timer4		; YES, Show the warning
+check_scrubber_timer3:				; NO
+    	movff	char_O_deco_info,WREG		; get the deco info vector
+	btfss	WREG,deco_stops_norm		; deco stops found?
+	return					; NO  - within NDL - Done.
+    	MOVII	int_O_TTS_norm,sub_b	    	; YES - use TTS as the threshold
+	call	cmpU16				; sub_a - sub_b
+	btfss	neg_flag			; theshold triggered?
+	return					; NO  - Done.
+check_scrubber_timer4:				; Show the warning
+	incf	message_counter,F		; YES - increase message counter
+	bsf	attn_scrubber_timer		; Set warning for scrubber timer
+	goto	TFT_message_scrubber		; - show message and return
+	
+	
  ENDIF	; _ccr_pscr
 
 
--- a/src/hwos.inc	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/hwos.inc	Tue Jan 27 11:01:04 2026 +0100
@@ -75,23 +75,24 @@
 #DEFINE	i2c_speed_value	    0x27		;0x9C = 100kHz @ 64MHz Fosc, 0x27 = 100kHz @ 16MHz Fosc 
 
 ; ---- Divemode Custom View Indexes - Attention: these numbers need to be in line with the jump tables in customview.asm!
-#DEFINE index_blank						 .0			; blank view
+#DEFINE index_blank					 .0			; blank view
 #DEFINE index_avr_stopwatch				 .1			; average depth and stopwatch
 #DEFINE index_compass_dm				 .2			; compass
 #DEFINE index_ppo2_sensors				 .3			; ppO2 sensors
 #DEFINE index_sensor_check				 .4			; sensor check
 #DEFINE index_pscr_info					 .5			; pSCR data
 #DEFINE index_pressures_SAC				 .6			; tank pressure and SAC rate
-#DEFINE index_gas_needs_ascent			 .7			; gas needs for ascent / cave return
+#DEFINE index_gas_needs_ascent				 .7			; gas needs for ascent / cave return
 #DEFINE index_cave_tts					 .8			; cave mode TTS
 #DEFINE index_decoplan					 .9			; deco plan
-#DEFINE index_ceiling_GF_tissue			.10			; ceiling, current GF and tissues
-#DEFINE index_CNS						.11			; CNS values
-#DEFINE index_ppo2_ead_end_cns			.12			; ppO2, END/EAD and CNS or gas density
-#DEFINE index_clock_batt_surfpress		.13			; clock, battery and surface pressure
-#DEFINE index_gf_factors				.14			; GF factors
-#DEFINE index_cave_waypoints			.15			; cave waypoints
-#DEFINE index_cv_dm_max					.13			; highest index used in normal custom view rotation
+#DEFINE index_ceiling_GF_tissue				.10			; ceiling, current GF and tissues
+#DEFINE	index_ceiling_GF_surfGF				.11			; ceiling, current GF and surface GF
+#DEFINE index_CNS					.12			; CNS values
+#DEFINE index_ppo2_ead_end_cns				.13			; ppO2, END/EAD and CNS or gas density
+#DEFINE index_clock_batt_surfpress			.14			; clock, battery and surface pressure
+#DEFINE index_gf_factors				.15			; GF factors
+#DEFINE index_cave_waypoints				.16			; cave waypoints
+#DEFINE index_cv_dm_max					.16			; highest index used in normal custom view rotation
 
 
 ; ---- Timing for button hold-down flags
@@ -378,6 +379,8 @@
 #DEFINE compass_fast_treshold			.9			; show new heading instantly if angular difference > compass_fast_treshold, else show animated turning of compass rose
 #DEFINE compass_averaging				.10			; number of averaging cycles
 
+; ---- Scrubber timer 
+#DEFINE	low_scrubber_threshold			.30			; [min] Scrubber low threshold (16bit value)
 
 ;-----------------------------------------------------------------------------
 ; Bit Flags
@@ -511,7 +514,7 @@
 
  ;---- Hardware - OSTC Model Variants3 (stored in access RAM, NOT cleared in restart)
 #DEFINE dual_comm			HW_variants3,0		; =1: dual comm hardware (USB and BLE-only)
- 
+#DEFINE	adjustable_buttons		HW_variants3,1		; =1: The buttons have adjustable sensitivity
  
 ;---- Hardware - States 1 (stored in access RAM, cleared on restart)
 #DEFINE analog_sw1_pressed		HW_flags_state1,0	; =1: analog switch 1 pressed
@@ -739,7 +742,7 @@
 #DEFINE attn_det_xmit1_bat		DM_flags_att3_det,0	; =1: xmitter 1 low batt attention issued
 #DEFINE attn_det_xmit2_bat		DM_flags_att3_det,1	; =1: xmitter 2 low batt attention issued
 #DEFINE attn_det_cns_eod		DM_flags_att3_det,2	; =1: end-of-dive CNS    attention threshold reached
-;								DM_flags_att3_det,3	; --- unused
+#DEFINE	attn_scrubber_timer		DM_flags_att3_det,3	; =1: Scrubber timer runs out or is negative
 ;								DM_flags_att3_det,4	; --- unused
 ;								DM_flags_att3_det,5	; --- unused
 ;								DM_flags_att3_det,6	; --- unused
@@ -920,7 +923,7 @@
 	endm							;
 
 
-; ---- arithetics
+; ---- arithmetics
 
 INCI	macro address				; INCrement Integer (version of incf for 2 byte integers)
 	infsnz	address+0,F				; Attention: must be in bank where target variable resides!
@@ -1625,7 +1628,7 @@
 ;---- IR/S8-Link
 ir_s8_buffer					res .64		; buffer for data received on IR/S8 interface,
 
-; 224 byte used, 25 byte free
+; 226 byte used, 23 byte free
 
 
 ;-----------------------------------------------------------------------------
@@ -1770,7 +1773,14 @@
 opt_TR_2nd_pres					res 1		; TR functions - 2nd pressure assignment
 opt_TR_Bail_pres				res 1		; TR functions - bailout pressure assignment
 
-; ==> 194 bytes used - 50 bytes free (244 usable bytes only in bank 14 as the upper 12
+;---- Scrubber timer				
+opt_ScrubberTime			res 1		; Scrubber timer time in 10min
+opt_ScrubTmrEnable			res 1		; =1: Use the Scrubber Timer, =0: Ignore the Scrubber Timer			
+opt_scrubber_timer_mins			res 2		; The Scrubber timer in mins
+opt_scrubber_timer_day			res 1		; Date when then Scrubber was restarted
+opt_scrubber_timer_month		res 1		; Date when then Scrubber was restarted
+opt_scrubber_timer_year			res 1		; Date when then Scrubber was restarted
+; ==> 201 bytes used - 43 bytes free (244 usable bytes only in bank 14 as the upper 12
 ;                                     bytes are reserved for special function registers)
 
 ;-----------------------------------------------------------------------------
--- a/src/i2c.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/i2c.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -998,29 +998,29 @@
 	clrf	SSP1CON1					; reset entire module
 	clrf	SSP1CON2					; ...
 	clrf	SSP1STAT					; ...
-	bcf		TRISC,3						; SCL as OUTPUT
-	bsf		TRISC,4						; SDA as input
-	bcf		PORTC,3						; SCL = 0
+	bcf	TRISC,3						; SCL as OUTPUT
+	bsf	TRISC,4						; SDA as input
+	bcf	PORTC,3						; SCL = 0
 	movlw	d'9'						; clock-out 9 clock cycles manually
 	movwf	i2c_temp1					; ...
 I2CReset_1:
-	bsf		PORTC,3						; SCL = 1
-	nop									; pause for 4 CPU cycles
-	nop									; ...
-	nop									; ...
-	nop									; ...
+	bsf	PORTC,3						; SCL = 1
+	nop							; pause for 4 CPU cycles
+	nop							; ...
+	nop							; ...
+	nop							; ...
 	btfsc	PORTC,4						; SDA = 1 ?
-	bra		I2CReset_2					; YES - SDA has been released from slave
-	bcf		PORTC,3						; NO  - set SCL = 0
-	nop									;     - pause for 2 CPU cycles
-	nop									;     - ...
-	bcf		PORTC,3						;     - SCL = 0
-	nop									;     - pause for 2 CPU cycles
-	nop									;     - ...
+	bra	I2CReset_2					; YES - SDA has been released from slave
+	bcf	PORTC,3						; NO  - set SCL = 0
+	nop							;     - pause for 2 CPU cycles
+	nop							;     - ...
+	bcf	PORTC,3						;     - SCL = 0
+	nop							;     - pause for 2 CPU cycles
+	nop							;     - ...
 	decfsz	i2c_temp1,F					;     - clock counter, all cycles done?
-	bra		I2CReset_1					;       NO - loop
+	bra	I2CReset_1					;       NO - loop
 I2CReset_2:
-	bsf		TRISC,3						; SCL as input
+	bsf	TRISC,3						; SCL as input
 	clrf	SSP1CON1					; setup I2C mode
 	rcall	I2C_WAIT_100US					; ISR-Safe 100µs wait
 	movlw	b'00000000'					; enable slew rate control
@@ -1032,12 +1032,16 @@
 	movlw	i2c_speed_value
 	movwf	SSP1ADD						; ...
 	rcall	I2C_WAIT_100US					; ISR-Safe 100µs wait
+	banksel	i2c_error_counter
 	movlw	.1
-	addwf	i2c_error_counter+0
+	addwf	i2c_error_counter+0,F
 	movlw	.0
-	addwfc	i2c_error_counter+1				; +1 on the error counter
+	addwfc	i2c_error_counter+1,F				; +1 on the error counter
+	banksel	common
 	btfss	press_sensor_type				; =1: pressure sensor MS5837, =0: Pressure sensor MS5541
 	return							; MS5541, Done.
+	btfss	i2c_reinit_sensor2				; Sensor ok?
+	return							; Yes, Done.
 	; reset the sensor
 	rcall	I2C_SEN						; start condition
 	movlw	0xEC						; address byte + write bit
@@ -1045,7 +1049,13 @@
 	movlw	0x1E
 	rcall	I2C_TX						; send byte
 	rcall	I2C_PEN						; stop condition
-	WAITMS	.5						; 2.8ms according to datasheet
+	movlw	.50
+	movwf	i2c_temp1
+I2CReset_3:	
+	rcall	I2C_WAIT_100US					; ISR-Safe 100µs wait
+	decfsz	i2c_temp1,F
+	bra	I2CReset_3					; ~5ms delay
+;	WAITMS	.5						; 2.8ms according to datasheet
 	return							; done
 
 
--- a/src/menu_tree.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/menu_tree.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -168,15 +168,16 @@
 
 	bcf		imprint_sensor_mv			; stop imprinting of live O2 sensor mV data
 	btfss	ext_input_s8_ana			; S8/analog sensor input available?
-	bra		do_menu_ccr_2				; NO  - do OSTC 2  menu
-	;bra	do_menu_ccr_cR				; YES - do OSTC cR menu
+	bra		do_menu_ccr_2				; NO  - Non-Bulkhead OSTC  menu
+	;bra	do_menu_ccr_cR				; YES - do Bulkhead OSTC menu
 
-do_menu_ccr_cR:							; OSTC cR menu
-	MENU_BEGIN	tCCRSetup, .6
+do_menu_ccr_cR:							; Bulkhead OSTC menu
+	MENU_BEGIN	tCCRSetup, .7
 		MENU_OPT_INC	tCCRMode,					oCCRMode
 		MENU_CALL		tCalibrateMenu,				do_menu_calibrate
 		MENU_CALL		tDiluentSetup,				do_menu_diluent
 		MENU_CALL		tFixedSetpoints,			do_menu_setpoints
+		MENU_CALL		tScrubberTimer,				do_menu_scrubbertimer
 		MENU_CALL		tMore,						do_menu_ccr_more
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
@@ -184,10 +185,11 @@
  ENDIF	; _external_sensor_eccr
 
 do_menu_ccr_2:
-	MENU_BEGIN	tCCRSetup, .5			; OSTC 2 menu
+	MENU_BEGIN	tCCRSetup, .6			; Non-Bulkhead OSTC menu
 		MENU_OPT_INC	tCCRMode,					oCCRMode
 		MENU_CALL		tDiluentSetup,				do_menu_diluent
 		MENU_CALL		tFixedSetpoints,			do_menu_setpoints
+		MENU_CALL		tScrubberTimer,				do_menu_scrubbertimer
 		MENU_CALL		tMore,						do_menu_ccr_more
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
@@ -198,26 +200,75 @@
 ;
 do_menu_ccr_more:
  IFDEF _external_sensor_eccr
-	MENU_BEGIN	tCCRSetup, .7			; CCR/pSCR more menu
+	MENU_BEGIN	tCCRSetup, .7				; CCR/pSCR more menu
 		MENU_OPT_INC	tS8Mode,					oS8Mode
 		MENU_OPT_INC	tCCmaxFracO2,				oCCmaxFracO2
 		MENU_OPT_INC	tDilppO2Check,				oDilppO2Check
 		MENU_OPT_INC	tGasDensityCheck,			oGasDensityCheck
 		MENU_OPT_INC	tPSCR_O2_drop,				oPSCR_drop
 		MENU_OPT_INC	tPSCR_lungratio,			oPSCR_lungratio
-		MENU_CALL		tBack,						do_return_menu_ccr
+		MENU_CALL	tBack,					do_return_menu_ccr
 	MENU_END
  ELSE
-	MENU_BEGIN	tCCRSetup, .6			; CCR/pSCR more menu
+	MENU_BEGIN	tCCRSetup, .6				; CCR/pSCR more menu
 		MENU_OPT_INC	tCCmaxFracO2,				oCCmaxFracO2
 		MENU_OPT_INC	tDilppO2Check,				oDilppO2Check
 		MENU_OPT_INC	tGasDensityCheck,			oGasDensityCheck
 		MENU_OPT_INC	tPSCR_O2_drop,				oPSCR_drop
 		MENU_OPT_INC	tPSCR_lungratio,			oPSCR_lungratio
-		MENU_CALL		tBack,						do_return_menu_ccr
+		MENU_CALL	tBack,					do_return_menu_ccr
 	MENU_END
  ENDIF	; _external_sensor_eccr
 
+do_menu_scrubbertimer:
+	MENU_BEGIN	tScrubberTimer, .6			; The scrubber timer menu
+		MENU_DYNAMIC	dyn_Scrubber_Timer,			0			; Show current value
+		MENU_DYNAMIC	dyn_Scrubber_Date,			0			; Show last restart date
+		MENU_CALL	tScrubTmrReset,				do_resetScrubberTimer	; Reset to Scrubber Timer Time
+		MENU_OPT_INC	tScrubTmrEnable,			oEnable_ScrubTmr	; Scrubber Timer enable
+		MENU_OPT_INC	tScrubTmrTime,				oScrubTmrTime		; Increase Scrubber Timer Time
+		MENU_CALL	tBack,					do_return_menu_ccr
+	MENU_END
+    
+do_resetScrubberTimer:
+	movff	opt_ScrubberTime,WREG
+	mullw	.10
+	MOVII	PRODL,opt_scrubber_timer_mins			; opt_ScrubberTime is in 10 minutes increments
+	SMOVSS	rtc_year,rtc_latched_year			; ISR-safe 6 byte copy of date and time
+	movff	rtc_latched_day,opt_scrubber_timer_day
+	movff	rtc_latched_month,opt_scrubber_timer_month
+	movff	rtc_latched_year,opt_scrubber_timer_year		; Store scrubber restart date
+	return
+	
+;-----------------------------------------------------------------------------
+; dynamic Title - show current scrubber time
+;
+dyn_Scrubber_Timer:
+	STRCAT_TEXT tScrubTmrRemain			    ; "Remaining:"
+	MOVII	opt_scrubber_timer_mins,mpr			    ; Get the minutes into lo:hi
+	btfss	hi,7					    ; Negative timer?
+	bra	dyn_Scrubber_Timer2			    ; NO
+	FONT_COLOR_WARNING				    ; YES - print in Red (If enabled)
+	STRCAT	"-"					    ; And add a -
+dyn_Scrubber_Timer2:
+	TSTOSS	opt_ScrubTmrEnable			    ; Scrubber Timer Enabled?	   
+	FONT_COLOR_DISABLED				    ; NO - print in disabled color
+	bcf	hi,7					    ; Clear sign bit
+	output_999
+	STRCAT_TEXT tMinutes
+	return						    ; done
+
+	;-----------------------------------------------------------------------------
+; dynamic Title - show last restart date
+;
+dyn_Scrubber_Date:
+	STRCAT_TEXT tScrubTmrLast		; "Last restart:"
+    	movff	opt_scrubber_timer_year, lo		; copy year  to lo
+	movff	opt_scrubber_timer_month,hi		; copy month to hi
+	movff	opt_scrubber_timer_day,  up		; copy day   to up
+	call	output_date					; print date
+	return
+	
  ENDIF	; _ccr_pscr
 
 
@@ -1364,7 +1415,7 @@
 ;
 dyn_show_config:
 	STRCAT_TEXT tHardware				; print  text
-	call	I2C_init_compass			; start compass to get compass configuration
+;	call	I2C_init_compass			; start compass to get compass configuration
 	movf	HW_descriptor,W				; copy hardware descriptor to WREG
 	output_hex					; print as hex
 	movf	HW_variants,W				; copy hardware variants   to WREG
@@ -1718,7 +1769,7 @@
 	bra	do_menu_syssets_dn		; YES
 	btfsc	dual_comm			; Dual comm hardware?
 	bra	do_menu_syssets_dual_comm	; YES
-	btfsc	battery_gauge_available		; piezo buttons available?
+	btfsc	adjustable_buttons		; piezo buttons available?
 	bra	do_menu_syssets_piezo		; YES
 
 do_menu_syssets_dual_comm:	
--- a/src/option_table.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/option_table.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -99,7 +99,7 @@
 
 ;=============================================================================
 
-	extern	tPercent, tMeters, tMinutes, tGasDisabled, tbar, tNo, tTrModeOff, tTrPresNone, tDefName, tblank, tLogTunitC, tTissuePresSat
+	extern	tPercent, tMeters, tMinutes, t10Minutes, tGasDisabled, tbar, tNo, tTrModeOff, tTrPresNone, tDefName, tblank, tLogTunitC, tTissuePresSat
 	extern	char_I_bottom_time, char_I_bottom_depth
 	extern	char_I_model
 	extern	char_I_extra_time
@@ -330,12 +330,19 @@
 	OPTION_BOOL     oGasDensityCheck,                                              .1,                       0x107,    0x92,  opt_gas_density_check			; gas density is checked (effective in CCR / pSCR modes only)
 	OPTION_ENUM8	oWarningLevel,	     .2,                                       .0,      tLess,           0x108,    0x93,  opt_warning_level_divemode		; =0: Less, =1: All
 	OPTION_ENUM8    oTimeFormat,         .2,                                       .0,      tTimeformat,     0x109,    0x94,  opt_timeformat			; =0:24h, =1:12h
+	OPTION_UINT8    oScrubTmrTime,	     .6,		    .36,	       .12,     t10Minutes,      0x10A,    0x95,  opt_ScrubberTime			; Scrubber timer Time (in 10min increments)
+	OPTION_BOOL     oEnable_ScrubTmr,						.0,			 0x10B,	   0x96,  opt_ScrubTmrEnable			; =1: Use the Scrubber Timer, =0: Ignore the Scrubber Timer
+	OPTION_UINT8    oScubTmrCounter_LOW, .0,                 .255,                 .0,      nounit,          0x10C,    0x97,  opt_scrubber_timer_mins+0		; Actual scrubber time (LOW)
+	OPTION_UINT8    oScubTmrCounter_HIGH,.0,                 .255,                 .0,      nounit,          0x10D,    0x98,  opt_scrubber_timer_mins+1		; Actual scrubber time (HIGH)
+	OPTION_UINT8    oscrubber_timer_day, .0,                 .255,                 .0,      nounit,          0x10E,    0x99,  opt_scrubber_timer_day		; Last restart date
+	OPTION_UINT8    oscrubber_timer_month,.0,                .255,                 .0,      nounit,          0x10F,    0x9A,  opt_scrubber_timer_month		; Last restart date
+	OPTION_UINT8    oscrubber_timer_year, .0,                .255,                 .0,      nounit,          0x110,    0x9B,  opt_scrubber_timer_year		; Last restart date
 	;	+---------------------------------------------------------------------------------------------------------------------------------------------+
 	;	|  .                                                                                                                                          |
 	;	| /|\                                                                                                                                         |
 	;	|  |  add new options here!                                                                                                                   |
-	;	|  |  EEPROM address  min: 0x012, max: 0x1FF, last used: 0x109, spare: 0x0B7-0x0B9, 0x0F5-0x0F6, disused: 0x0A8, 0x0CE                        |
-	;	|  |  serial address  min:  0x20, max:  0xF9, last used:  0x94, spare: 0x84 (0xFA - 0xFE are reserved for internal use)			      |
+	;	|  |  EEPROM address  min: 0x012, max: 0x1FF, last used: 0x110, spare: 0x0B7-0x0B9, 0x0F5-0x0F6, disused: 0x0A8, 0x0CE                        |
+	;	|  |  serial address  min:  0x20, max:  0xF9, last used:  0x9B, spare: 0x84 (0xFA - 0xFE are reserved for internal use)			      |
 	;	+---------------------------------------------------------------------------------------------------------------------------------------------+
 
 	; ppO2 warnings, sorted by ppO2 levels
--- a/src/p2_deco.c	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/p2_deco.c	Tue Jan 27 11:01:04 2026 +0100
@@ -2052,43 +2052,14 @@
 	char_I_sim_advance_time = 0;
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// calc_GF_surface
-//
-// Calculates the instantaneous surface GF (GF_surf) for the leading compartment.
-//
-// Definition:
-//   GF_surf = (P_tissue - pres_surface) / (M_surf - pres_surface)
-//
-// - P_tissue  : current inert gas tissue pressure (N2 + He) in bar
-// - pres_surface : pres_surface (Ambient pressure at the surface, in bar)
-// - M_surf    : M-value on the surface (per calc_M_value_at_pressure)
-//
-// The maximum across all compartments is taken as GF_surf.
-// The result is written in percent (0..250) in int_O_GF_surface.
-//
-static float calc_M_value_at_pressure(float pres_surface)
-{
-    float a, b;
-    read_Buhlmann_coefficients();
-#ifdef _helium
-    adopt_Buhlmann_coefficients();
-    a = var_a;
-    b = var_b;
-#else    
-    a = var_N2_a;
-    b = var_N2_b;
-#endif
-    return a + b * pres_surface;
-}
-
 static void calc_GF_surface(void)
 {
     overlay float P_tissue;
     overlay float M_surf;
     overlay float gf_surf;
     overlay float gf_surf_max = 0.0f;
-
+    float a, b;
+    
     // Pass through all compartments
     for (ci = 0; ci < NUM_COMP; ci++)
     {
@@ -2097,10 +2068,21 @@
 #else
         P_tissue = real_pres_tissue_N2[ci];
 #endif
-
+      
+        read_Buhlmann_coefficients();
+
+#ifdef _helium
+        adopt_Buhlmann_coefficients();
+        a = var_a;
+        b = var_b;
+#else    
+        a = var_N2_a;
+        b = var_N2_b;
+#endif
+        
         // M-value on the surface for this compartment
-        M_surf = calc_M_value_at_pressure(pres_surface);
-
+        M_surf = pres_surface / b + a;
+        
         // Filtering out unnecessary cases
         if (M_surf <= pres_surface)
             continue;
@@ -2120,14 +2102,11 @@
     }
     else
     {
-        unsigned int tmp;
-
-        tmp = (unsigned int)(gf_surf_max * 100.0f + 0.5f);
-
-        if (tmp > 999)
-            tmp = 999;
-
-        int_O_GF_surface = tmp;
+        int_O_GF_surface = (unsigned int)(gf_surf_max * 100.0f + 0.5f);
+
+        if (int_O_GF_surface > 999)
+            int_O_GF_surface = 999;
+
     }
 }
 
--- a/src/start.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/start.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -128,6 +128,7 @@
 	bsf		cold_start
 
 	; get button type from bootloader info
+	bcf	adjustable_buttons					; assume non-adjustable by default
 	bsf		analog_switches					; assume analog buttons by default
 	movlw	0x7C							; set up read from 0x01F77C
 	movwf	TBLPTRL							; ...
@@ -139,6 +140,8 @@
 	movlw	0x07							; coding for analog buttons
 	cpfseq	TABLAT							; equal?
 	bcf		analog_switches					; NO - no analog buttons
+	btfsc	analog_switches						; analog buttons?
+	bsf	adjustable_buttons					; Yes! analog are always adjustable
 
 	; get screen type (2) from bootloader info
 	bsf		screen_type2					; set flags for later clear of the false one
@@ -237,11 +240,21 @@
 	call	lt2942_get_status				; check for gauge IC
 	btfss	battery_gauge_available			; cR or 2 hardware?
 	bra		start_check_new_firmware		; NO  - skip next
+	
+	call    eeprom_serial_number_read		    ; read OSTC serial number
+	movff	lo,sub_a+0
+	movff	hi,sub_a+1
+	MOVLI	.15000,sub_b
+	call	cmpU16
+	btfss	neg_flag					; serial >14999
+	bra	    start_check_new_firmware		; YES  - skip next
+	
 	movlw	.30								; YES - load default button sensitivity
 	movff	WREG,opt_cR_button_right		;     - set default for left  button
 	movff	WREG,opt_cR_button_left			;     - set default for right button
 	call	piezo_config					;     - configure buttons, 1st pass
 	call	piezo_config					;     - configure buttons, 2nd pass
+	bsf	adjustable_buttons				; 2015-style adjustable digital
 
 start_check_new_firmware:
 	call	TFT_boot						; initialize TFT (includes clear screen & backlight switch-off)
--- a/src/surfmode.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/surfmode.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -114,7 +114,8 @@
 	bsf		trigger_pres_cur_changed	; set flag to have pressure    written to display on first round of surface loop
 	bsf		trigger_temp_changed		; set flag to have temperature written to display on first round of surface loop
 
-	call	I2C_sleep_compass			; shut down compass
+;	call	I2C_sleep_compass			; shut down compass
+	call	I2C_init_compass				; start compass
 
  IFDEF _ccr_pscr
 	movlw	surface_sp					; load default surface setpoint (in cbar)
--- a/src/text_english.inc	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/text_english.inc	Tue Jan 27 11:01:04 2026 +0100
@@ -354,6 +354,7 @@
 	TCODE	tFeets,				"ft"
 	TCODE	tFeets1,			"f"
 	TCODE	tMinutes,			"'"
+	TCODE	t10Minutes,			"0'"
 	TCODE	tPercent,			"%"
 	TCODE	tLitersMinute,		"l/min"
 	TCODE	tbar,				" bar"					; bar
@@ -617,7 +618,17 @@
 	TCODE	tColorSetName2,		"Green"					; Green
 	TCODE	tColorSetName3,		"Blue"					; Blue
 
-
+ IFDEF _ccr_pscr	
+; Scrubber Timer menu
+	TCODE	tScrubberTimer,		"Scrubber timer"			; Scrubber Timer
+	TCODE	tScrubTmrReset,		"Restart scrubber"			; Reset Scrubber
+	TCODE	tScrubTmrEnable,	"Timer enabled:"			; Timer Enabled:
+	TCODE	tScrubTmrTime,		"Scrubber Time:"			; Scubber Time:
+	TCODE	tScrubTmrRemain,	"Remaining:"				; Remaining:
+	TCODE	tScrubTmrLast,		"Last set:"				; Last set:
+	TCODE	tScrubTmrWarn,		"Scrubber!"				; Scrubber!
+ ENDIF
+ 
 ; Debug Stuff
  IFDEF _comm_debug
 	TCODE	tCommTimeout,		"RX Timeout: "
--- a/src/text_french.inc	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/text_french.inc	Tue Jan 27 11:01:04 2026 +0100
@@ -354,6 +354,7 @@
 	TCODE	tFeets,				"ft"
 	TCODE	tFeets1,			"f"
 	TCODE	tMinutes,			"'"
+	TCODE	t10Minutes,			"0'"
 	TCODE	tPercent,			"%"
 	TCODE	tLitersMinute,		"l/min"
 	TCODE	tbar,				"bar"					; bar
@@ -619,6 +620,17 @@
 	TCODE	tColorSetName2,		"Vert"					; Green
 	TCODE	tColorSetName3,		"Bleu"					; Blue
 
+ IFDEF _ccr_pscr	
+; Scrubber Timer menu
+	TCODE	tScrubberTimer,		"Scrubber timer"			; Scrubber Timer
+	TCODE	tScrubTmrReset,		"Restart scrubber"			; Reset Scrubber
+	TCODE	tScrubTmrEnable,	"Timer enabled:"			; Timer Enabled:
+	TCODE	tScrubTmrTime,		"Scrubber Time:"			; Scubber Time:
+	TCODE	tScrubTmrRemain,	"Remaining:"				; Remaining:
+	TCODE	tScrubTmrLast,		"Last set:"				; Last set:
+	TCODE	tScrubTmrWarn,		"Scrubber!"				; Scrubber!
+ ENDIF
+
 
 ; Debug Stuff
  IFDEF _comm_debug
--- a/src/text_german.inc	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/text_german.inc	Tue Jan 27 11:01:04 2026 +0100
@@ -354,6 +354,7 @@
 	TCODE	tFeets,				"ft"
 	TCODE	tFeets1,			"f"
 	TCODE	tMinutes,			"'"
+	TCODE	t10Minutes,			"0'"
 	TCODE	tPercent,			"%"
 	TCODE	tLitersMinute,		"l/min"
 	TCODE	tbar,				" bar"					; bar
@@ -618,6 +619,17 @@
 	TCODE	tColorSetName2,		"Grün"					; Green
 	TCODE	tColorSetName3,		"Blau"					; Blue
 
+ IFDEF _ccr_pscr	
+; Scrubber Timer menu
+	TCODE	tScrubberTimer,		"Scrubber Timer"			; Scrubber Timer
+	TCODE	tScrubTmrReset,		"Zurücksetzen"				; Reset Scrubber
+	TCODE	tScrubTmrEnable,	"Timer aktiv:"				; Timer Enabled:
+	TCODE	tScrubTmrTime,		"Kalkstandzeit:"			; Scubber Time:
+	TCODE	tScrubTmrRemain,	"Restzeit:"				; Remaining:
+	TCODE	tScrubTmrLast,		"Befüllt am:"				; Last set:
+	TCODE	tScrubTmrWarn,		"Kalkzeit!"				; Scrubber!
+ ENDIF
+
 
 ; Debug Stuff
  IFDEF _comm_debug
--- a/src/text_italian.inc	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/text_italian.inc	Tue Jan 27 11:01:04 2026 +0100
@@ -354,6 +354,7 @@
 	TCODE	tFeets,				"ft"
 	TCODE	tFeets1,			"f"
 	TCODE	tMinutes,			"'"
+	TCODE	t10Minutes,			"0'"
 	TCODE	tPercent,			"%"
 	TCODE	tLitersMinute,		"l/min"
 	TCODE	tbar,				"bar"					; bar
@@ -618,6 +619,17 @@
 	TCODE	tColorSetName2,		"Verde"					; Green
 	TCODE	tColorSetName3,		"Blu"					; Blue
 
+ IFDEF _ccr_pscr	
+; Scrubber Timer menu
+	TCODE	tScrubberTimer,		"Scrubber timer"			; Scrubber Timer
+	TCODE	tScrubTmrReset,		"Restart scrubber"			; Reset Scrubber
+	TCODE	tScrubTmrEnable,	"Timer enabled:"			; Timer Enabled:
+	TCODE	tScrubTmrTime,		"Scrubber Time:"			; Scubber Time:
+	TCODE	tScrubTmrRemain,	"Remaining:"				; Remaining:
+	TCODE	tScrubTmrLast,		"Last set:"				; Last set:
+	TCODE	tScrubTmrWarn,		"Scrubber!"				; Scrubber!
+ ENDIF
+
 
 ; Debug Stuff
  IFDEF _comm_debug
--- a/src/text_multilang.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/text_multilang.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -22,7 +22,7 @@
 ; fast hack **ONLY** for **CHANGING** languages ( en / de / fr / it )
 
 ;#undefine _language_1
-;#define   _language_1 fr 
+;#define   _language_1 fr
 
 ;#undefine _language_2
 ;#define   _language_2 it
--- a/src/tft_outputs.asm	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/tft_outputs.asm	Tue Jan 27 11:01:04 2026 +0100
@@ -3313,6 +3313,20 @@
 	STRCPY_TEXT tnoBOgas				; print "-B/O-Gas-"
 	bra		TFT_message_close			; finalize message output
 
+ IFDEF _ccr_pscr	
+;-----------------------------------------------------------------------------
+; Dive Mode - Scrubber timer
+;
+	global	TFT_message_scrubber
+TFT_message_scrubber:	
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_WARNING					; set warning color
+	STRCPY_TEXT tScrubTmrWarn				; print "Scrubber!"
+	bra		TFT_message_close			; finalize message output
+ ENDIF	
 
 ;-----------------------------------------------------------------------------
 ; Message - open Message
@@ -3727,7 +3741,7 @@
 	STRCAT_TEXT_PRINT	tAvgDepth		; "Average"
 
 	FONT_COLOR_MEMO						; set color
-	WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row
+	WIN_SMALL surf_gaslist_column+.53,surf_gaslist_row
 	SMOVII	int_O_desaturation_time,mpr	; ISR-safe copy of the desaturation time
 	movf	mpr+0,W						; get low byte into WREG
 	iorwf	mpr+1,W						; inclusive-or with high byte, check if desaturation time is zero
@@ -3756,7 +3770,7 @@
 
 TFT_surface_lastdive_com:
 	; last dive duration
-	WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.1)
+	WIN_SMALL surf_gaslist_column+.53,surf_gaslist_row+(surf_gaslist_spacing*.1)
 	MOVII	lastdive_duration,mpr		; get duration of last dive, minutes
 	output_999							; print minutes
 	PUTC	":"							; print ":"
@@ -3765,15 +3779,42 @@
 	PRINT								; dump to screen
 
 	; last dive max depth
-	WIN_SMALL	surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.2)
+	WIN_SMALL	surf_gaslist_column+.53,surf_gaslist_row+(surf_gaslist_spacing*.2)
 	MOVII	lastdive_maxdepth,mpr		; get max depth of last dive
 	rcall	TFT_surface_lastdive_depth	; print depth
 
 	; average depth
-	WIN_SMALL	surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.3)
+	WIN_SMALL	surf_gaslist_column+.53,surf_gaslist_row+(surf_gaslist_spacing*.3)
 	MOVII	lastdive_avgdepth,mpr		; get avg depth of last dive
-	;bra	TFT_surface_lastdive_depth	; print depth and return
-
+	rcall	TFT_surface_lastdive_depth	; print depth
+
+ IFDEF _ccr_pscr	
+	TSTOSS	opt_ScrubTmrEnable		; Scrubber Timer Enabled?	   
+	return					; NO  - Done.
+
+	FONT_COLOR color_green				; set menu title font color
+	; Scrubber timer
+	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)+.5
+	STRCAT_TEXT_PRINT	tScrubTmrTime		; "Scubber Time:"
+	FONT_COLOR_MEMO						; set color
+	WIN_SMALL	surf_gaslist_column+.65,surf_gaslist_row+(surf_gaslist_spacing*.4)
+	MOVII	opt_scrubber_timer_mins,mpr			    ; Get the minutes into lo:hi
+	btfss	hi,7					    ; Negative timer?
+	bra	TFT_surface_lastdive_scrubber1		    ; NO
+	FONT_COLOR_WARNING				    ; YES - print in Red (If enabled)
+	STRCAT	"-"					    ; And add a -
+	bra	TFT_surface_lastdive_scrubber2		    ; Skip Space
+TFT_surface_lastdive_scrubber1:
+	STRCAT	" "					    ; Add a Space when positive
+TFT_surface_lastdive_scrubber2:    
+	bcf	hi,7					    ; Clear sign bit
+;	bcf	leftbind
+	output_999
+	STRCAT_TEXT_PRINT tMinutes
+	ENDIF	; _ccr_pscr
+
+	return
+	
 	; Helper Function - print depth
 TFT_surface_lastdive_depth:
 	TSTOSS	opt_units					; 0=Meter, 1=Feet
@@ -5016,7 +5057,10 @@
 	bra		TFT_ceiling_GF_tissue0		; continue
 
 TFT_ceiling_GF_tissue0:
-	PUTC_PRINT " "						; append a space and dump to screen
+	PUTC " "						; append a space
+	clrf	WREG						; load string terminator
+	movff	WREG,buffer+.4					; limit string length to 4
+	PRINT
 	return	
 
 	; Helper Function - draw a bargraph
--- a/src/tft_outputs.inc	Thu Nov 27 18:32:58 2025 +0100
+++ b/src/tft_outputs.inc	Tue Jan 27 11:01:04 2026 +0100
@@ -141,6 +141,7 @@
 
  IFDEF _ccr_pscr
 	extern	TFT_message_gas_density				; gas density
+	extern	TFT_message_scrubber				; Scrubber warning
  ENDIF
 
  IFDEF _external_sensor_eccr