diff code_part1/OSTC_code_asm_part1/divemode.asm @ 0:96a35aeda5f2

Initial setup
author heinrichsweikamp
date Tue, 12 Jan 2010 15:05:59 +0100
parents
children d11ef8dc4b2c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/code_part1/OSTC_code_asm_part1/divemode.asm	Tue Jan 12 15:05:59 2010 +0100
@@ -0,0 +1,1544 @@
+
+; OSTC - diving computer code
+; Copyright (C) 2008 HeinrichsWeikamp GbR
+
+;    This program is free software: you can redistribute it and/or modify
+;    it under the terms of the GNU General Public License as published by
+;    the Free Software Foundation, either version 3 of the License, or
+;    (at your option) any later version.
+
+;    This program is distributed in the hope that it will be useful,
+;    but WITHOUT ANY WARRANTY; without even the implied warranty of
+;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;    GNU General Public License for more details.
+
+;    You should have received a copy of the GNU General Public License
+;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+; Mainroutines for divemode
+; written by: Matthias Heinrichs, info@heinrichsweikamp.com
+; written: 10/01/05
+; last updated: 15/05/08
+; known bugs:
+; ToDo: 
+
+diveloop:
+	call	diveloop_boot			; Boot tasks for all modes
+
+; Startup Tasks for all modes
+	ostc_debug	'R'		; Sends debug-information to screen if debugmode active
+	call	PLED_ClearScreen			; clean up OLED
+	call	PLED_divemode_mask					; Display mask
+	call	PLED_active_gas_divemode	; Display gas, if required
+	call	PLED_temp_divemode			; Displays temperature
+
+	btfsc	FLAG_apnoe_mode
+	bsf		realdive					; Set Realdive flag in Apnoe mode
+
+	btfsc	gauge_mode
+	bra		diveloop_loop				; Skip in gauge mode
+	btfsc	FLAG_apnoe_mode
+	bra		diveloop_loop				; Skip in apnoe mode
+
+; Startup Tasks for deco modes
+	call	PLED_display_ndl_mask		; display "no stop" if not in gauge or apnoe mode
+
+diveloop_loop:		; The diveloop starts here
+	btfss	onesecupdate					; tasks any new second
+	bra		diveloop_loop2
+
+	btfsc	gauge_mode						; Only in gauge mode
+	bra		diveloop_loop1a					; One Second Tasks in Gauge mode
+	btfsc	FLAG_apnoe_mode					; Only in apnoe mode
+	bra		diveloop_loop1b					; One Second Tasks in Apnoe mode
+	btfsc	FLAG_const_ppO2_mode			; only in const_ppO2_mode
+	bra		diveloop_loop1c					; One Second Tasks in const_ppO2 mode
+
+; Tasks only for OC modes
+	call	check_ppO2						; check ppO2 and displays warning if required
+	call	calc_deko_divemode				; calculate decompression and display result (any two seconds)
+	bra		diveloop_loop1x					; Common Tasks
+
+; Tasks only for Gauge mode
+diveloop_loop1a:
+	btfss	premenu						; Is the divemode menu active?
+	call	PLED_divemins					; display (new) divetime!
+	call	timeout_divemode				; dive finished? This routine sets the required flags
+
+	btfsc	stopwatch_active				;  =1: Show Average Depth instead of Temperature
+	call	PLED_stopwatch_show			; Show stopwatch only in Average mode
+
+	btfsc	twosecupdate					; two seconds after the last call
+	bra		diveloop_loop1a2					; Common Tasks
+
+	bsf		twosecupdate				; Routines used in the "other second"
+	call	calc_average_depth			; calculate average depth
+	
+	bra		diveloop_loop1x					; Common Tasks
+
+diveloop_loop1a2:
+	bcf		twosecupdate		
+	bra		diveloop_loop1x					; Common Tasks
+
+; Tasks only for Apnoe mode
+diveloop_loop1b:
+	call	divemode_apnoe_tasks			; 1 sec. Apnoe tasks
+	bra		diveloop_loop1x					; Common Tasks
+
+; Tasks only for ppO2 mode
+diveloop_loop1c:
+	call	PLED_const_ppO2_value			; display const ppO2 setting in [Bar]
+	call	calc_deko_divemode				; calculate decompression and display result (any two seconds)
+	bra		diveloop_loop1x					; Common Tasks
+	
+; Common Tasks for all modes
+diveloop_loop1x:
+	call	timeout_divemode				; dive finished? This routine sets the required flags
+	btfsc	low_battery_state				; If battery is low, then...
+	call	update_batt_voltage_divemode	; Display Battery Symbol/Voltage!
+	btfsc	premenu							; is Menu? displayed?
+	call	timeout_premenu_divemode		; No, so check for timeout premenu
+	btfsc	menubit							; is the Dive mode menu displayed?
+	call	timeout_divemenu				; Yes, so check for timeout divemenu
+	call	set_leds_divemode				; Sets warnings, if required. Also Sets buzzer
+	btfsc	enter_error_sleep				; Enter Fatal Error Routine?
+	goto	fatal_error_sleep				; Yes (In Sleepmode_vxx.asm!)
+
+	btfsc	stopwatch_active				;  =1: Show Average Depth instead of Temperature
+	call	PLED_stopwatch_show				; Show stopwatch only in Average mode
+
+	bcf		onesecupdate					; one seconds update done
+
+	GETCUSTOM8	d'38'		; Show seconds (=1?)
+	movwf	lo
+	movlw	d'1'
+	cpfseq	lo					; =1?
+	bra		diveloop_loop2		; No, minutes only
+	bsf		update_divetime		; Set Update flag
+
+
+diveloop_loop2:	
+	btfss	update_divetime				; display new divetime?
+	bra		diveloop_loop3				; No
+	btfsc	premenu						; Is the divemode menu active?
+	bra		diveloop_loop2a				; Yes
+	call	PLED_divemins				; Display (new) divetime!
+	btfsc	FLAG_const_ppO2_mode		; only in const_ppO2_mode
+	call	PLED_const_ppO2_value		; display const ppO2 setting in [Bar]
+	btfsc	ppO2_show_value				; show ppO2?
+	call	check_ppO2					; check ppO2 and displays warning if required
+
+diveloop_loop2a:
+	bcf		update_divetime				; clear flag
+
+
+diveloop_loop3:
+	btfss	menubit							; Divemode menu active?
+	call	test_switches_divemode			; No, Check switches normal
+
+	btfsc	menubit							; Divemode menu active?
+	call	test_switches_divemode_menu		; Yes, check switches divemode menu
+
+	btfss	divemode						; Dive finished?
+	bra		end_dive						; Dive finished!
+
+	btfsc	pressure_refresh				; new pressure available?
+	call	update_divemode1				; Yes, display new depth
+	bcf		pressure_refresh				; until new pressure is available
+
+	btfsc	oneminupdate					; one minute tasks
+	call	update_divemode60				; Update clock, etc.
+
+	btfsc	store_sample					; store new sample?
+	call	store_dive_data					; Store profile data
+
+	btfss	menubit							; Sleep only with inactive menu...
+	sleep
+	
+	nop
+	bra		diveloop_loop					; Loop the divemode
+
+timeout_premenu_divemode:
+	incf	timeout_counter3,F		; Yes...
+
+	GETCUSTOM8	d'4'				; loads premenu_timeout into WREG
+	cpfsgt	timeout_counter3		; ... longer then premenu_timeout
+	return							; No!
+
+	bcf		premenu					; Yes, so clear "Menu?" and clear pre_menu bit
+	call	PLED_menu_clear			; Remove "Menu?"
+	return
+
+divemode_apnoe_tasks:						; 1 sec. Apnoe tasks
+	call	PLED_display_apnoe_descent		; Show descent timer
+
+	btfsc	divemode2						; Time running?
+	bra		divemode_apnoe_tasks2			; New descent, reset data if flag is set
+
+	call	PLED_display_apnoe_surface
+	incf	apnoe_surface_secs,F
+	movlw	d'60'
+	cpfseq	apnoe_surface_secs
+	bra		divemode_apnoe_tasks1
+	clrf	apnoe_surface_secs
+	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
+	return
+
+divemode_apnoe_tasks2:
+	btfss	FLAG_active_descent				; Are descending?			
+	return									; No, We are at the surface
+	rcall	apnoe_calc_maxdepth				; Yes!
+	
+divemode_apnoe_tasks3:
+	call	PLED_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	max_pressure+0
+	clrf	max_pressure+1					; Reset Max. Depth
+	bcf		FLAG_active_descent				; Clear flag
+	return
+
+apnoe_calc_maxdepth:
+	movff	apnoe_max_pressure+0,sub_a+0
+	movff	apnoe_max_pressure+1,sub_a+1
+	movff	max_pressure+0,sub_b+0
+	movff	max_pressure+1,sub_b+1
+	call	sub16				; 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
+	movff	max_pressure+0,apnoe_max_pressure+0
+	movff	max_pressure+1,apnoe_max_pressure+1
+	return
+
+set_leds_divemode:
+	call	clear_LEDy					; LEDy OFF
+	movff	char_O_gradient_factor,lo		; gradient factor absolute
+
+	GETCUSTOM8	d'14'		; threshold for LED warning
+	cpfslt	lo				; 
+	call	warn_gf1		; show warning, set flags
+
+	btfsc	ppO2_warn_value	; warn because of too high ppO2?
+	call	set_LEDy		; Yes
+
+	movff	char_I_deco_model,lo
+		decfsz	lo,W		; jump over return if char_I_deco_model == 1
+	return
+
+	movff	char_O_relative_gradient_GF,lo		; gradient factor relative (GF model)
+
+	GETCUSTOM8	d'14'		; threshold for LED warning
+	cpfslt	lo				; 
+	call	warn_gf1		; show warning, set flags
+
+	btfsc	ppO2_warn_value	; warn because of too high ppO2?
+	call	set_LEDy		; Yes
+
+	return
+
+warn_gf1:
+	call		set_LEDy		; LED Yellow on
+	movlw		d'2'			; Type of Alarm
+	movwf		AlarmType		; Copy to Alarm Register
+	bsf			event_occured	; Set Event Flag
+	return
+
+calc_deko_divemode:
+	btfsc	twosecupdate		; two seconds after the last call
+	bra		calc_deko_divemode2		; Yes, calculate and display deco data ("first second")
+
+	; Routines used in the "other second"
+
+	bsf		twosecupdate		; No, but next second!
+	call	calc_average_depth	; calculate average depth
+	call	calc_velocity		; calculate vertical velocity and display if > threshold (every two seconds)
+	
+	; calculate ppO2 in 0.1Bar (e.g. 150 = 1.50Bar ppO2)
+	movff		amb_pressure+0,xA+0
+	movff		amb_pressure+1,xA+1
+	movlw		LOW		d'10'
+	movwf		xB+0
+	movlw		HIGH 	d'10'
+	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
+	clrf		xB+1
+	call		mult16x16				; char_I_O2_ratio * p_amb/10
+	movff		xC+0,xA+0
+	movff		xC+1,xA+1
+	movlw		LOW		d'100'
+	movwf		xB+0
+	movlw		HIGH 	d'100'
+	clrf		xB+1
+	call		div16x16				; xC=(char_I_O2_ratio * p_amb/10)/100
+
+; Copy ppO2 for CNS calculation
+	movff		xC+0, char_I_actual_ppO2	; copy last ppO2 to buffer register
+	btfsc		FLAG_const_ppO2_mode		; do in const_ppO2_mode
+	movff		char_I_const_ppO2, char_I_actual_ppO2	; copy last ppO2 to buffer register
+
+; Calculate CNS	
+	call	main_calc_CNS_fraction		; calculate CNS
+	movlb	b'00000001'					; rambank 1 selected
+
+; Check if CNS should be displayed
+	movff	char_O_CNS_fraction,lo		; copy into bank1
+	GETCUSTOM8	d'27'					; cns_display_high
+	subwf	lo,W
+	btfsc	STATUS,C
+	call	PLED_display_cns			; Show CNS
+
+; Check for decompression gases if in decomode
+divemode_check_decogases:					; CALLed from Simulator
+	btfss	dekostop_active
+	bra		reset_decompression_gases	; While in NDL, do not set deompression gas
+; 1. Find active gas with deepest change depth < current depth
+; 2. Set Decogas
+
+	movff	rel_pressure+0,xA+0			
+	movff	rel_pressure+1,xA+1
+	movlw	d'100'
+	movwf	xB+0
+	clrf	xB+1
+	call	div16x16				; compute depth in full m -> result in xC+0
+	clrf	lo						; clear depth for comparison
+
+; check gas1 
+	read_int_eeprom		d'27'		; read flag register
+	btfss	EEDATA,0				; check active flag
+	bra		check_decogas2			; skip inactive gases!
+	read_int_eeprom		d'28'		; read gas_change_depth
+	movf	xC+0,W					; load depth in m into WREG
+	cpfslt	EEDATA					; gas_change_depth > current depth?
+	bra		check_decogas2			; W < EEDATA -> current depth lower then gas_change_depth
+	
+	movff	EEDATA,lo				; deepest gas_change_depth in lo
+	movlw	d'1'
+	movwf	hi						; Decogas # in hi (1-5)
+
+check_decogas2:
+	read_int_eeprom		d'27'		; read flag register
+	btfss	EEDATA,1				; check active flag
+	bra		check_decogas3			; skip inactive gases!
+	read_int_eeprom		d'29'		; read gas_change_depth
+	movf	xC+0,W					; load depth in m into WREG
+	cpfslt	EEDATA					; gas_change_depth > current depth?
+	bra		check_decogas3			; W < EEDATA -> current depth lower then gas_change_depth
+
+	read_int_eeprom		d'29'		; read gas_change_depth
+	movf	lo,W					; load current gas_change_depth into WREG
+	cpfsgt	EEDATA					; last gas_change_depth > current gas_change_depth ?
+	bra		check_decogas3			; W < lo -> last gas_change_depth > current gas_change_depth
+	movff	EEDATA,lo				; deepest gas_change_depth in lo
+	movlw	d'2'
+	movwf	hi						; Decogas # in hi (1-5)
+
+check_decogas3:
+	read_int_eeprom		d'27'		; read flag register
+	btfss	EEDATA,2				; check active flag
+	bra		check_decogas4			; skip inactive gases!
+	read_int_eeprom		d'30'		; read gas_change_depth
+	movf	xC+0,W					; load depth in m into WREG
+	cpfslt	EEDATA					; gas_change_depth > current depth?
+	bra		check_decogas4			; W < EEDATA -> current depth lower then gas_change_depth
+
+	read_int_eeprom		d'30'		; read gas_change_depth
+	movf	lo,W					; load current gas_change_depth into WREG
+	cpfsgt	EEDATA					; last gas_change_depth > current gas_change_depth ?
+	bra		check_decogas4			; W < lo -> last gas_change_depth > current gas_change_depth
+	movff	EEDATA,lo				; deepest gas_change_depth in lo
+	movlw	d'3'
+	movwf	hi						; Decogas # in hi (1-5)
+
+check_decogas4:
+	read_int_eeprom		d'27'		; read flag register
+	btfss	EEDATA,3				; check active flag
+	bra		check_decogas5			; skip inactive gases!
+	read_int_eeprom		d'31'		; read gas_change_depth
+	movf	xC+0,W					; load depth in m into WREG
+	cpfslt	EEDATA					; gas_change_depth > current depth?
+	bra		check_decogas5			; W < EEDATA -> current depth lower then gas_change_depth
+
+	read_int_eeprom		d'31'		; read gas_change_depth
+	movf	lo,W					; load current gas_change_depth into WREG
+	cpfsgt	EEDATA					; last gas_change_depth > current gas_change_depth ?
+	bra		check_decogas5			; W < lo -> last gas_change_depth > current gas_change_depth
+	movff	EEDATA,lo				; deepest gas_change_depth in lo
+	movlw	d'4'
+	movwf	hi						; Decogas # in hi (1-5)
+
+check_decogas5:
+	read_int_eeprom		d'27'		; read flag register
+	btfss	EEDATA,4				; check active flag
+	bra		check_decogas_done		; skip inactive gases!
+	read_int_eeprom		d'32'		; read gas_change_depth
+	movf	xC+0,W					; load depth in m into WREG
+	cpfslt	EEDATA					; gas_change_depth > current depth?
+	bra		check_decogas_done		; W < EEDATA -> current depth lower then gas_change_depth
+
+	read_int_eeprom		d'32'		; read gas_change_depth
+	movf	lo,W					; load current gas_change_depth into WREG
+	cpfsgt	EEDATA					; last gas_change_depth > current gas_change_depth ?
+	bra		check_decogas_done		; W < lo -> last gas_change_depth > current gas_change_depth
+	movff	EEDATA,lo				; deepest gas_change_depth in lo
+	movlw	d'5'
+	movwf	hi						; Decogas # in hi (1-5)
+
+check_decogas_done:
+	ostc_debug	'E'		; Sends debug-information to screen if debugmode active
+
+	decf	hi,F						; Gas 0-4
+	movff	lo, char_I_deco_gas_change	; copy change_depth
+
+	movf	hi,W						; Gas 0-4
+	mullw	d'4'
+	movf	PRODL,W			
+	addlw	d'7'						; = address for He ratio
+	movwf	EEADR
+	call	read_eeprom					; Read He ratio
+	movff	EEDATA,char_I_deco_He_ratio	; And copy into hold register
+
+
+	movf	hi,W						; Gas 0-4
+	mullw	d'4'
+	movf	PRODL,W			
+	addlw	d'6'						; = address for O2 ratio
+	movwf	EEADR
+	call	read_eeprom					; Read O2 ratio
+	
+	movff	char_I_deco_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	EEDATA,F					; minus O2
+	movff	EEDATA, char_I_deco_N2_ratio	; = N2!
+	bra		skip_decompression_gases
+
+reset_decompression_gases:				; reset the deco gas while in NDL
+	ostc_debug	'F'		; Sends debug-information to screen if debugmode active
+  	clrf	lo
+ 	movff	lo, char_I_deco_gas_change	; clear 
+ 	movff	lo, char_I_deco_N2_ratio	; clear
+ 	movff	lo, char_I_deco_He_ratio	; clear
+skip_decompression_gases:
+;call	PLED_gaschange_DEBUG
+	return
+
+calc_deko_divemode2:
+	bcf		twosecupdate		
+
+	btfsc	gauge_mode				; ignore decompression calculation in gauge mode
+	return
+	btfsc	FLAG_apnoe_mode			; ignore decompression calculation in apnoe mode
+	return
+
+ 	ostc_debug	'B'		; Sends debug-information to screen if debugmode active
+	call	divemode_prepare_flags_for_deco
+	call	deco_main_calc_hauptroutine		; calc_tissue
+	movlb	b'00000001'						; rambank 1 selected
+	ostc_debug	'C'		; Sends debug-information to screen if debugmode active
+
+	movff	char_O_deco_status,deco_status		; 
+	tstfsz	deco_status							; deco_status=0 if decompression calculation done
+	return										; calculation not yet finished!
+	
+	movff	char_O_array_decodepth+0,wait_temp	; copy ceiling to temp register
+	tstfsz	wait_temp							; Ceiling<0m?
+	bra		calc_deko_divemode3					; Yes!
+
+	btfsc	dekostop_active
+	call	PLED_display_ndl_mask			; Clear deco data, display nostop time
+	bcf		dekostop_active					; clear flag
+
+	clrf	decodata+0						; for profile memory
+	movff	char_O_nullzeit,decodata+1		; nostop time
+	
+	call	PLED_display_ndl				; display no deco limit
+	return
+
+divemode_prepare_flags_for_deco:	
+	movff	amb_pressure+0,int_I_pres_respiration+0		; lo  and copy result to deco routine
+	movff	amb_pressure+1,int_I_pres_respiration+1		; hi
+	GETCUSTOM8	d'11'				; Saturation multiplier %
+	movwf	wait_temp
+	movff	wait_temp,char_I_saturation_multiplier
+	GETCUSTOM8	d'12'				; Desaturation multiplier %
+	movwf	wait_temp
+	movff	wait_temp,char_I_desaturation_multiplier
+	GETCUSTOM8	d'16'				; Deco distance to decostop in 1/10 meter for simulation
+	movwf	wait_temp
+	movff	wait_temp,char_I_deco_distance
+	GETCUSTOM8	d'29'				; Depth Last Deco in meter for simulation
+	movwf	wait_temp
+	movff	wait_temp,char_I_depth_last_deco
+	call	restart_set_modes_and_flags			; Sets decomode (char_I_deco_model) and flags (again)
+	return
+
+calc_deko_divemode3:
+	btfss	dekostop_active
+	call	PLED_display_deko_mask				; clear nostop time, display decodata
+	bsf		dekostop_active						; Set flag
+
+	movff	char_O_array_decodepth+0,decodata+0	; ceiling
+	movff	char_O_array_decotime,decodata+1	; length of first stop in minues
+
+	call	PLED_display_deko					; display decodata
+	return						
+
+store_dive_data:						; CF20 seconds gone
+	bcf		store_sample				; update only any CF20 seconds
+	bsf		update_divetime				; update divemins every CF20 seconds
+
+	call	clear_LEDg					; LEDg off
+
+	btfsc	header_stored				; Header already stored?
+	bra	store_dive_data2				; Yes, store only profile data
+	bsf		header_stored				; Store header
+	
+	movff	eeprom_address+0, eeprom_header_address+0	; store startposition
+	movff	eeprom_address+1, eeprom_header_address+1	; store startposition
+
+; shift address for header
+; the header will be stored after the dive
+	incf_eeprom_address	d'47'				; Macro, that adds 8Bit to eeprom_address:2 with banking at 0x8000
+
+store_dive_data2:
+	movf	rel_pressure+0,W				; store depth with every sample
+	call	write_external_eeprom
+	movf	rel_pressure+1,W
+	call	write_external_eeprom
+
+;First, find out how many bytes will append to this sample....
+	clrf	ProfileFlagByte					; clear number of bytes to append
+
+; Check Extented informations
+	decfsz	divisor_temperature,W	; Check divisor
+	bra		check_extended1		
+	movlw	d'2'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+check_extended1:
+	decfsz	divisor_deco,W		; Check divisor
+	bra		check_extended2		
+	movlw	d'2'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+check_extended2:
+	decfsz	divisor_tank,W		; Check divisor
+	bra		check_extended3		
+	movlw	d'2'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+check_extended3:
+	decfsz	divisor_ppo2,W		; Check divisor
+	bra		check_extended4		
+	movlw	d'3'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+check_extended4:
+	decfsz	divisor_deco_debug,W; Check divisor
+	bra		check_extended5		
+	movlw	d'9'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+check_extended5:
+	decfsz	divisor_nuy2,W		; Check divisor
+	bra		check_extended6		
+	movlw	d'0'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+check_extended6:
+
+; Second, check global event flag
+	btfss	event_occured		; Check global event flag
+	bra		store_dive_data3	; No Event
+	movlw	d'1'
+	addwf	ProfileFlagByte,F	; add one byte (The EventByte)
+
+	clrf	EventByte			; reset EventByte
+
+	movf	AlarmType,W			; Type of Alarm Bit 0-3
+	addwf	EventByte,F			; Copy to EventByte Bit 0-3
+	clrf	AlarmType			; Reset AlarmType
+	
+; Third, check events and add aditional bytes
+	btfss	manual_gas_changed	; Check flag	
+	bra		check_event1
+	movlw	d'2'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+	bsf		EventByte,4			; Also set Flag in EventByte!
+check_event1:
+	btfss	stored_gas_changed	; Check flag	
+	bra		check_event2
+	movlw	d'1'				; Information length	
+	addwf	ProfileFlagByte,F	; add to ProfileFlagByte
+	bsf		EventByte,5			; Also set Flag in EventByte!
+check_event2:
+	bsf		ProfileFlagByte,7	; Set EventByte Flag in ProfileFlagByte
+
+store_dive_data3:
+	movf	ProfileFlagByte,W	; finally, write ProfileFlagByte!
+	call	write_external_eeprom
+
+	btfss	event_occured		; Check global event flag (again)
+	bra		store_dive_data4	; No Event
+
+; Store the EventByte + additional bytes now
+	movf	EventByte,W		
+	call	write_external_eeprom
+
+	btfss	manual_gas_changed	; Check flag	
+	bra		store_dive_data3a
+	read_int_eeprom	d'24'			; % O2 Gas6
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom	d'25'			; % He Gas6
+	movf	EEDATA,W
+	call	write_external_eeprom
+
+store_dive_data3a:
+	btfss	stored_gas_changed	; Check flag	
+	bra		store_dive_data3b			
+	movf	active_gas,W		; Store active gas
+	call	write_external_eeprom
+
+store_dive_data3b:
+
+store_dive_data4:
+	bcf		event_occured		; Clear the global event flag
+	bcf		manual_gas_changed	; Clear all events
+	bcf		stored_gas_changed	; Clear all events
+
+; Store extended informations
+	decfsz	divisor_temperature,F	; Check divisor
+	bra		store_extended1	
+	rcall	store_dive_temperature
+store_extended1:
+	decfsz	divisor_deco,F		; Check divisor
+	bra		store_extended2	
+	rcall	store_dive_decodata
+store_extended2:
+	decfsz	divisor_tank,F		; Check divisor
+	bra		store_extended3	
+	rcall	store_dive_tankdata
+store_extended3:
+	decfsz	divisor_ppo2,F		; Check divisor
+	bra		store_extended4	
+	rcall	store_dive_ppo2
+store_extended4:
+	decfsz	divisor_deco_debug,F; Check divisor
+	bra		store_extended5	
+	rcall	store_dive_decodebug
+store_extended5:
+	decfsz	divisor_nuy2,F		; Check divisor
+	bra		store_extended6	
+	rcall	store_dive_nuy2
+store_extended6:
+
+; The next block is required to take care of "store never"
+	btfsc	divisor_temperature,7	; Test highest Bit (Register must have been zero before the "decfsz" command!)
+	clrf	divisor_temperature		; And clear register again, so it will never reach zero...
+	btfsc	divisor_deco,7			; Test highest Bit (Register must have been zero before the "decfsz" command!)
+	clrf	divisor_deco			; And clear register again, so it will never reach zero...
+	btfsc	divisor_tank,7			; Test highest Bit (Register must have been zero before the "decfsz" command!)
+	clrf	divisor_tank			; And clear register again, so it will never reach zero...
+	btfsc	divisor_ppo2,7			; Test highest Bit (Register must have been zero before the "decfsz" command!)
+	clrf	divisor_ppo2			; And clear register again, so it will never reach zero...
+	btfsc	divisor_deco_debug,7	; Test highest Bit (Register must have been zero before the "decfsz" command!)
+	clrf	divisor_deco_debug		; And clear register again, so it will never reach zero...
+	btfsc	divisor_nuy2,7			; Test highest Bit (Register must have been zero before the "decfsz" command!)
+	clrf	divisor_nuy2			; And clear register again, so it will never reach zero...
+
+	ostc_debug	'D'		; Sends debug-information to screen if debugmode active
+	return				; Done.
+	
+store_dive_nuy2:
+	GETCUSTOM8	d'26'
+	movwf	divisor_nuy2			; Reload divisor from CF
+	return
+
+store_dive_decodebug:
+	movff	0x931,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x930,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x933,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x932,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x935,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x934,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x937,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x936,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	movff	0x938,divisor_deco_debug	; Used as temp
+	movf	divisor_deco_debug,W		; copy to WREG
+	call	write_external_eeprom		; Store in EEPROM
+	GETCUSTOM8	d'25'
+	movwf	divisor_deco_debug			; Reload divisor from CF
+	return
+
+store_dive_ppo2:
+	movlw	0x00			; Dummy
+	call	write_external_eeprom
+	movlw	0x00			; Dummy
+	call	write_external_eeprom
+	movlw	0x00			; Dummy
+	call	write_external_eeprom
+	GETCUSTOM8	d'24'
+	movwf	divisor_ppo2			; Reload divisor from CF
+	return
+
+store_dive_tankdata:
+	movlw	d'0'				; Dummy Tank1
+	call	write_external_eeprom
+	movlw	d'0'				; Dummy Tank2
+	call	write_external_eeprom
+	GETCUSTOM8	d'23'
+	movwf	divisor_tank			; Reload divisor from CF
+	return
+
+store_dive_decodata:
+	movf	decodata+0,W				; =0:no stop dive, if in deco mode: ceiling in m
+	call	write_external_eeprom
+	movf	decodata+1,W				; no stop time of length of first stop
+	call	write_external_eeprom
+	GETCUSTOM8	d'22'
+	movwf	divisor_deco			; Reload divisor from CF
+	return
+
+store_dive_temperature:
+	movf	temperature+0,W				; append temperature to current sample!
+	call	write_external_eeprom
+	movf	temperature+1,W
+	call	write_external_eeprom
+	GETCUSTOM8	d'21'
+	movwf	divisor_temperature			; Reload divisor from CF
+	return
+
+calc_velocity:								; called every two seconds
+	btfss	divemode						
+	bra		do_not_display_velocity			; display velocity only in divemode
+
+calc_velocity2:
+	movff	amb_pressure+0,sub_a+0
+	movff	amb_pressure+1,sub_a+1
+	movff	last_pressure+0,sub_b+0
+	movff	last_pressure+1,sub_b+1
+	movff	amb_pressure+0,last_pressure+0	; store old value for velocity
+	movff	amb_pressure+1,last_pressure+1
+
+	call	sub16						; sub_c = amb_pressure - last_pressure
+
+	movff	sub_c+0,xA+0
+	movff	sub_c+1,xA+1
+	movlw	d'39'			;77 when called every second....
+	movwf	xB+0
+	clrf	xB+1
+	call	mult16x16					; differential pressure in mBar*77...
+	movff	xC+0,divA+0
+	movff	xC+1,divA+1
+	movlw	d'7'
+	movwf	divB
+	call	div16						; devided by 2^7 equals velocity in m/min
+
+	movlw	d'99'
+	cpfsgt	divA
+	bra		calc_velocity3
+	movwf	divA						; divA=99
+
+calc_velocity3:
+
+	GETCUSTOM8	d'5'					; threshold for display vertical velocity
+	subwf	divA+0,W					; 
+
+	btfss	STATUS,C
+	bra		do_not_display_velocity
+
+update_velocity:
+	bsf		display_velocity
+	call	PLED_display_velocity
+	return
+
+do_not_display_velocity:
+	btfss	display_velocity			; Velocity was not displayed, do not delete
+	return
+		
+	bcf		display_velocity			; Velocity was displayed, delete velocity now
+	call	PLED_display_velocity_clear
+	return
+
+check_ppO2:								; check current ppO2 and display warning if required
+	btfsc		FLAG_const_ppO2_mode		; ignore in ppO2 mode....
+	return
+
+	movff		amb_pressure+0,xA+0
+	movff		amb_pressure+1,xA+1
+	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
+	clrf		xB+1
+	call		mult16x16				; char_I_O2_ratio * p_amb/10
+
+; Check if ppO2 should be displayed
+	movff		xC+0,sub_b+0
+	movff		xC+1,sub_b+1
+	GETCUSTOM8	d'19'					; ppo2_display_high
+	mullw		d'100'					; ppo2_display_high*100
+	movff		PRODL,sub_a+0
+	movff		PRODH,sub_a+1
+	call		sub16					
+	bcf			ppO2_show_value		; clear flag
+	btfsc		neg_flag
+	bsf			ppO2_show_value		; set flag if required
+
+;check if we are within our warning thresholds!
+	bcf			ppO2_warn_value		; clear flag
+	movff		xC+0,sub_b+0
+	movff		xC+1,sub_b+1
+	GETCUSTOM8	d'18'					; ppo2_warning_high
+	mullw		d'100'					; ppo2_warning_high*100
+	movff		PRODL,sub_a+0
+	movff		PRODH,sub_a+1
+	call		sub16					
+	btfss		neg_flag
+	bra			check_ppO2_0		; Not too high
+
+	bsf			ppO2_warn_value		; set flag 
+	movlw		d'5'				; Type of Alarm
+	movwf		AlarmType			; Copy to Alarm Register
+	bsf			event_occured		; Set Event Flag
+
+check_ppO2_0:
+	movff		xC+0,sub_b+0
+	movff		xC+1,sub_b+1
+	GETCUSTOM8	d'17'					; ppo2_warning_low
+	mullw		d'100'					; ppo2_warning_low*100
+	movff		PRODL,sub_a+0
+	movff		PRODH,sub_a+1
+	call		sub16					
+	btfsc		neg_flag
+	bra			check_ppO2_1		; Not too low
+
+	bsf			ppO2_warn_value		; set flag 
+	bsf			ppO2_show_value		; show ppO2 if below threshold!
+	movlw		d'4'				; Type of Alarm
+	movwf		AlarmType			; Copy to Alarm Register
+	bsf			event_occured		; Set Event Flag
+
+check_ppO2_1:
+	btfsc		ppO2_show_value		; show value?
+	bra			check_ppO2_2		; yes!
+
+	btfss		ppO2_display_active	; is the value displayed?
+	bra			check_ppO2_3		; No, so clear not required
+	
+	call		PLED_show_ppO2_clear; Clear ppO2 value
+	bcf			ppO2_display_active	; clear flag
+	bra			check_ppO2_3		; done
+
+check_ppO2_2:
+	call		PLED_show_ppO2		; Display ppO2 (stored in xC)
+	bsf			ppO2_display_active	; Set flag		
+
+check_ppO2_3:
+	return		; done
+
+
+calculate_noflytime:
+	; calculate nofly time
+	movff	int_O_desaturation_time+0,xA+0
+	movff	int_O_desaturation_time+1,xA+1
+	tstfsz	xA+0			; Desat=0?
+	bra		calculate_noflytime2
+	tstfsz	xA+1			; Desat=0?
+	bra		calculate_noflytime2
+	; Desaturation time = zero
+	movlw	d'1'
+	movwf	nofly_time+0			; Clear nofly time
+	clrf	nofly_time+1			; Clear nofly time
+	bcf		nofly_active			; Clear flag
+	return
+	
+calculate_noflytime2:	
+	movff	xA+0,int_I_temp+0
+	movff	xA+1,int_I_temp+1
+	GETCUSTOM8 	.13					; nofly_time_ratio
+	movwf	xB+0
+	movff	xB,char_I_temp
+	ostc_debug	'K'		; Sends debug-information to screen if debugmode active
+	call	main_calc_percentage
+	movlb	b'00000001'				; select ram bank 1
+	ostc_debug	'L'		; Sends debug-information to screen if debugmode active
+	movff	int_I_temp+0,xA+0
+	movff	int_I_temp+1,xA+1
+	tstfsz	xA+0			; Desat=0?
+	bra		calculate_noflytime_2_final
+	tstfsz	xA+1			; Desat=0?
+	bra		calculate_noflytime_2_final
+	; noflytime = zero
+	movlw	d'1'
+	movwf	nofly_time+0			; Clear nofly time
+	clrf	nofly_time+1			; Clear nofly time
+	bcf		nofly_active			; Clear flag
+	return
+calculate_noflytime_2_final:
+	movff	xA+0,nofly_time+0
+	movff	xA+1,nofly_time+1
+	bsf		nofly_active			; Set flag
+	return
+
+end_dive:
+	btfss	realdive					; dive longer then one minute
+	goto	end_dive_common				; No, discard everything
+
+	; Dive finished (and longer then one minute or Apnoe timeout occured)
+
+	btfsc	FLAG_apnoe_mode			; Calc max. depth (again) for very short apnoe dives
+	rcall	apnoe_calc_maxdepth
+
+	; calculate desaturation time
+	movff	last_surfpressure_30min+0,int_I_pres_respiration+0		; copy surface air pressure to deco routine
+	movff	last_surfpressure_30min+1,int_I_pres_respiration+1		; 30min old values 
+
+	GETCUSTOM8	d'12'				; Desaturation multiplier %
+	movwf	wait_temp
+	movff	wait_temp,char_I_desaturation_multiplier
+
+	ostc_debug	'G'		; Sends debug-information to screen if debugmode active
+	call	deco_main_calc_desaturation_time	; calculate desaturation time
+	movlb	b'00000001'						; select ram bank 1
+	rcall	calculate_noflytime				; Calc NoFly time
+	ostc_debug	'H'		; Sends debug-information to screen if debugmode active
+										; store header and ...
+	movlw	0xFD						; .... End-of-Profile Bytes
+	call	write_external_eeprom
+	movlw	0xFD
+	call	write_external_eeprom
+	movlw	0xFE						; This positon will be overwritten for the next profile
+	call	write_external_eeprom			; and is required to find the newest dive after a firmware reset
+
+	movff	eeprom_header_address+0, eeprom_address+0	; set header adress
+	movff	eeprom_header_address+1, eeprom_address+1	; write header
+
+	movlw	0xFA						; Header start
+	call	write_external_eeprom
+	movlw	0xFA
+	call	write_external_eeprom
+	movlw	logbook_profile_version			; Defined in definitions_vxyy.asm
+	call	write_external_eeprom
+	movf	month,W					; Date
+	call	write_external_eeprom
+	movf	day,W
+	call	write_external_eeprom
+	movf	year,W
+	call	write_external_eeprom
+	movf	hours,W					; End of dive time
+	call	write_external_eeprom
+	movf	mins,W
+	call	write_external_eeprom
+
+	btfss	FLAG_apnoe_mode				; Store apnoe max or normal max (Which is only max from the last descent)
+	bra		end_dive1					; Store normal depth
+
+	movff	apnoe_max_pressure+0,lo
+	movff	apnoe_max_pressure+1,hi
+	call	adjust_depth_with_salinity			; computes salinity setting into lo:hi [mBar]
+	movff	lo,apnoe_max_pressure+0
+	movff	hi,apnoe_max_pressure+1
+	
+	movf	apnoe_max_pressure+0,W		; Max. depth
+	call	write_external_eeprom
+	movf	apnoe_max_pressure+1,W
+	call	write_external_eeprom
+	bra		end_dive2					; skip
+		
+end_dive1:
+	movff	max_pressure+0,lo
+	movff	max_pressure+1,hi
+	call	adjust_depth_with_salinity			; computes salinity setting into lo:hi [mBar]
+	movff	lo,max_pressure+0
+	movff	hi,max_pressure+1
+	
+	movf	max_pressure+0,W			; Max. depth
+	call	write_external_eeprom
+	movf	max_pressure+1,W
+	call	write_external_eeprom
+
+end_dive2:
+	movf	divemins+0,W				; divetime minutes
+	call	write_external_eeprom
+	movf	divemins+1,W
+	call	write_external_eeprom
+	movf	divesecs,W					; divetime seconds
+	call	write_external_eeprom
+	movf	mintemp+0,W					; minimum temperature
+	call	write_external_eeprom
+	movf	mintemp+1,W		
+	call	write_external_eeprom
+	movf	last_surfpressure_30min+0,W		; airpressure before dive
+	call	write_external_eeprom
+	movf	last_surfpressure_30min+1,W		
+	call	write_external_eeprom
+	movff	int_O_desaturation_time+0,lo			; 
+	movff	int_O_desaturation_time+1,hi
+	movf	lo,W						; desaturation time in minutes
+	call	write_external_eeprom
+	movf	hi,W						; 
+	call	write_external_eeprom
+
+	; Gases....
+	read_int_eeprom 	d'6'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom 	d'7'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+
+	read_int_eeprom 	d'10'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom 	d'11'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+
+	read_int_eeprom 	d'14'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom 	d'15'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+
+	read_int_eeprom 	d'18'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom 	d'19'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+
+	read_int_eeprom 	d'22'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom 	d'23'		; Read byte (stored in EEDATA)
+	movf	EEDATA,W
+	call	write_external_eeprom
+
+	read_int_eeprom	d'24'			; % O2 Gas6
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom	d'25'			; % He Gas6
+	movf	EEDATA,W
+	call	write_external_eeprom
+	read_int_eeprom	d'33'			; start gas
+	movf	EEDATA,W
+	call	write_external_eeprom
+
+	movlw	softwareversion_x			; Firmware version
+	call	write_external_eeprom
+	movlw	softwareversion_y
+	call	write_external_eeprom
+	movf	batt_voltage+0,W			; Battery voltage 
+	call	write_external_eeprom
+	movf	batt_voltage+1,W
+	call	write_external_eeprom
+
+	GETCUSTOM8	d'20'					; sampling rate in WREG
+	btfsc	FLAG_apnoe_mode				; Apnoe mode?
+	movlw	d'1'						; Apnoe sampling rate
+	call	write_external_eeprom
+
+	movlw	d'2'		; information size temperature
+	movwf	temp1		; copy to bits 0-3
+	swapf	temp1,F		; swap nibbels 0-3 with 4-7
+	GETCUSTOM8	d'21'	; Divisor temperature
+	addwf	temp1,W		; copy to bits 0-3, result in WREG
+	call	write_external_eeprom
+
+	movlw	d'2'		; information size deco
+	movwf	temp1		; copy to bits 0-3
+	swapf	temp1,F		; swap nibbels 0-3 with 4-7
+	GETCUSTOM8	d'22'	; Divisor deco
+	addwf	temp1,W		; copy to bits 0-3, result in WREG
+	call	write_external_eeprom
+
+	movlw	d'2'		; information size tank
+	movwf	temp1		; copy to bits 0-3
+	swapf	temp1,F		; swap nibbels 0-3 with 4-7
+	GETCUSTOM8	d'23'					; Divisor Tank
+	addwf	temp1,W		; copy to bits 0-3, result in WREG
+	call	write_external_eeprom
+
+	movlw	d'3'		; information size pp02
+	movwf	temp1		; copy to bits 0-3
+	swapf	temp1,F		; swap nibbels 0-3 with 4-7
+	GETCUSTOM8	d'24'	; Divisor pp02
+	addwf	temp1,W		; copy to bits 0-3, result in WREG
+	call	write_external_eeprom
+
+	movlw	d'9'		; information size Decodebug
+	movwf	temp1		; copy to bits 0-3
+	swapf	temp1,F		; swap nibbels 0-3 with 4-7
+	GETCUSTOM8	d'25'	; Divisor Decodebug
+	addwf	temp1,W		; copy to bits 0-3, result in WREG
+	call	write_external_eeprom
+
+	movlw	d'0'		; information size nuy2
+	movwf	temp1		; copy to bits 0-3
+	swapf	temp1,F		; swap nibbels 0-3 with 4-7
+	GETCUSTOM8	d'26'	; Divisor nuy2
+	addwf	temp1,W		; copy to bits 0-3, result in WREG
+	call	write_external_eeprom
+
+	read_int_eeprom	d'26'			; Read Salinity from EEPROM
+	movf	EEDATA,W
+	call	write_external_eeprom	; Store Salinity to Dive
+	
+	movlw	d'0'		; Spare
+	call	write_external_eeprom
+
+	movlw	0xFB						; Header stop
+	call	write_external_eeprom
+	movlw	0xFB
+	call	write_external_eeprom
+	
+	; Increase total dive counter
+	read_int_eeprom 	d'2'		; Read byte (stored in EEDATA)
+	movff	EEDATA,temp1			; Low byte
+	read_int_eeprom 	d'3'		; Read byte (stored in EEDATA)
+	movff	EEDATA,temp2			; high byte
+	bcf		STATUS,C
+	movlw	d'1'
+	addwf	temp1
+	movlw	d'0'
+	addwfc	temp2				
+	movff	temp1,EEDATA
+	write_int_eeprom	d'2'			; write byte stored in EEDATA
+	movff	temp2,EEDATA
+	write_int_eeprom	d'3'			; write byte stored in EEDATA
+
+	GETCUSTOM15	.28							; Logbook Offset -> lo, hi
+	tstfsz		lo							; lo=0?
+	bra		change_logbook_offset1		; No, adjust offset	
+	tstfsz		hi						; hi=0?
+	bra		change_logbook_offset1		; No, adjust offset
+	bra		change_logbook_offset2		; lo=0 and hi=0 -> skip Offset routine
+change_logbook_offset1:
+	movlw	d'1'
+	addwf	lo
+	movlw	d'0'
+	addwfc	hi
+	movlw	d'112'					; CF28 *4 Bytes...
+	addlw	0x82
+	movwf	EEADR
+	movff	lo,EEDATA
+	call	write_eeprom			; Lowbyte
+	movlw	d'112'					; CF28 *4 Bytes...
+	addlw	0x83
+	movwf	EEADR
+	movff	hi,EEDATA
+	call	write_eeprom			; Highbyte 
+
+change_logbook_offset2:
+	bcf		simulatormode_active		; if we were in simulator mode
+	call	clear_LEDusb
+
+end_dive_common:
+	btfsc	restore_deco_data			; Restore decodata?
+	call	simulator_restore_tissue_data		; Yes!
+
+	call	deco_main_gradient_array
+	movlb	b'00000001'					; select ram bank 1
+
+	clrf	surface_interval+0
+	clrf	surface_interval+1		; Clear surface interval timer
+
+	goto	surfloop					; and return to surfaceloop
+
+timeout_divemode:
+	btfss	realdive					; Dive longer then one minute
+	return
+	
+	btfsc	FLAG_apnoe_mode				; In Apnoe mode?
+	bra		timeout_divemode2			; Yes, use CF30 [min] for timeout
+
+	btfsc	simulatormode_active		; In Simulator mode?
+	bra		timeout_divemode3			; Yes, use fixed 5 seconds timeout			
+	
+	bcf		divemode
+	incf	timeout_counter,F
+	GETCUSTOM8	d'2'					; diveloop_timeout
+	addlw	d'2'						; adds two seconds in case timout=zero!
+	btfsc	STATUS,C					; > 255?
+	movlw	d'255'						; Set to 255...
+	decf	WREG,F						; Limit to 254
+	cpfsgt	timeout_counter
+	bsf		divemode
+	return
+
+timeout_divemode2:
+	incf	timeout_counter,F			; seconds...
+	movlw	d'60'
+	cpfseq	timeout_counter				; timeout_counter=60?
+	return								; No.
+
+	clrf	timeout_counter
+	bcf		divemode
+	incf	apnoe_timeout_counter,F
+	GETCUSTOM8	d'30'					; apnoe timeout [min]
+	cpfseq	apnoe_timeout_counter
+	bsf		divemode
+	return
+
+timeout_divemode3:
+	bcf		divemode
+	incf	timeout_counter,F
+	movlw	d'5'						; Fixed timeout of 5 seconds
+	cpfsgt	timeout_counter
+	bsf		divemode
+	return
+
+update_divemode1:						; update any second
+	call	set_dive_modes				; tests if depth>threshold
+	
+	btfsc	divemode
+	call	set_max_depth				; update max. depth if required
+
+	btfsc	divemode
+	call	set_min_temp				; store min. temp if required
+
+	bcf		temp_changed			; Display temperature?
+	movf	temperature+0,W
+	cpfseq	last_temperature+0
+	bsf		temp_changed			; Yes
+	movf	temperature+1,W
+	cpfseq	last_temperature+1
+	bsf		temp_changed			; Yes
+	btfsc	temp_changed	
+	call	PLED_temp_divemode		; Displays temperature
+
+	bcf		pres_changed			; Display new depth?
+	movf	amb_pressure+0,W
+	cpfseq	last_pressure+0
+	bsf		pres_changed			; Yes
+	movf	amb_pressure+1,W
+	cpfseq	last_pressure+1
+	bsf		pres_changed			; Yes
+
+	btfsc	simulatormode_active	; always update depth when in simulator mode
+	bsf		pres_changed				
+
+	btfsc	pres_changed	
+	call	PLED_depth					; Displays new depth
+	return
+
+update_divemode60:					; update any minute
+	call	get_battery_voltage			; gets battery voltage
+	call	set_powersafe				; red LED blinking if battery is low
+	call	PLED_max_pressure			; No, use normal max. depth
+	call	check_temp_extrema			; check for new temperature extremas
+	bcf		oneminupdate
+	return
+
+set_max_depth:
+	movff	max_pressure+0,sub_a+0
+	movff	max_pressure+1,sub_a+1
+	movff	rel_pressure+0,sub_b+0
+	movff	rel_pressure+1,sub_b+1
+	call	sub16						; sub_c = sub_a - sub_b
+								; max_pressure<rel_pressure -> neg_flag=1
+								; rel_pressure<=max_pressure -> neg_flag=0
+	btfss	neg_flag	
+	return
+								;max_pressure<rel_pressure
+	movff	rel_pressure+0,max_pressure+0
+	movff	rel_pressure+1,max_pressure+1
+	call	PLED_max_pressure			; No, use normal max. depth
+	return
+
+set_min_temp:
+	movff	mintemp+0,sub_a+0
+	movff	mintemp+1,sub_a+1
+	movff	temperature+0,sub_b+0
+	movff	temperature+1,sub_b+1
+	call	sub16						; sub_c = sub_a - sub_b
+								; mintemp<T -> neg_flag=1
+								; T<=mintemp -> neg_flag=0
+	btfsc	neg_flag	
+	return
+								;mintemp>=T
+	movff	temperature+0,mintemp+0
+	movff	temperature+1,mintemp+1
+	return
+
+set_dive_modes:
+	bcf		divemode2				; Stop time
+
+	GETCUSTOM8	.0					; loads dive_threshold in WREG
+	movwf	sub_a+0					; dive_treshold is in cm
+	clrf	sub_a+1
+
+	movff	rel_pressure+0,sub_b+0
+	movff	rel_pressure+1,sub_b+1
+		
+	call	sub16						; sub_c = sub_a - sub_b
+	
+	btfss	neg_flag	
+	bra		set_dive_modes2				; too shallow (rel_pressure<dive_threshold)
+
+	btfsc	realdive					; Dive longer than one minute?
+	clrf 	timeout_counter
+
+	bsf		divemode
+	bsf		divemode2				; displayed divetime is running
+	return
+
+set_dive_modes2:
+	btfss	realdive					; dive longer then one minute?
+	bcf		divemode					; no -> this was no real dive
+	return
+
+set_powersafe:
+	btfsc	low_battery_state		; battery warning alread active?
+	bra		set_powersafe2			; Yes, but is it still required?
+									; battery voltage in mV (value*256+Lowbyte=actual treshold)
+	movlw	d'12'					; 3,328V
+	cpfsgt	batt_voltage+1
+	bra		set_powersafe1
+	return
+
+set_powersafe1:
+	movlw	d'7'					; Type of Alarm (Battery Low)
+	movwf	AlarmType				; Copy to Alarm Register
+	bsf		event_occured			; Set Event Flag
+	bsf		low_battery_state		; set flag for battery warning
+	return							; return
+
+set_powersafe2:
+	movlw	d'13'					; 3,584V
+	cpfsgt	batt_voltage+1
+	bra		set_powersafe1			; Still to low
+	bcf		low_battery_state		; clear flag for battery warning mode
+	return
+
+calc_average_depth:
+	; 1. Add new 2xdepth to the Sum of depths registers
+	movff	rel_pressure+0,b0_lo
+	movff	rel_pressure+1,b0_hi
+
+	movf	b0_lo,w
+	addwf	average_depth_hold+0,F
+	movf	b0_hi,w
+	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
+
+	movf	b0_lo,w
+	addwf	average_depth_hold+0,F
+	movf	b0_hi,w
+	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
+
+	; 2. Compute Average Depth on base of average_divesecs:2
+	
+	movff	average_divesecs+0,xB+0
+	movff	average_divesecs+1,xB+1		; Copy
+	movff	average_depth_hold+0,xC+0
+	movff	average_depth_hold+1,xC+1
+	movff	average_depth_hold+2,xC+2
+	movff	average_depth_hold+3,xC+3
+
+	call	div32x16 	; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
+	movff	xC+0,avr_rel_pressure+0
+	movff	xC+1,avr_rel_pressure+1
+	return
+	
+
+diveloop_boot:	
+		ostc_debug	'Q'		; Sends debug-information to screen if debugmode active
+	clrf	max_pressure+0				; clear some variables
+	clrf	max_pressure+1
+
+	clrf	avr_rel_pressure+0
+	clrf	avr_rel_pressure+1
+
+	call	PLED_brightness_low
+	read_int_eeprom	d'90'				; Brightness offset? (Dim>0, Normal = 0)
+	movlw	d'0'
+	cpfsgt	EEDATA
+	call	PLED_brightness_full
+
+	clrf	average_depth_hold+0
+	clrf	average_depth_hold+1
+	clrf	average_depth_hold+2
+	clrf	average_depth_hold+3		; Clear average depth register
+	movlw	d'1'
+	movwf	average_divesecs+0
+	clrf	average_divesecs+1
+
+	movlw	d'1'
+	movwf	apnoe_max_pressure+0
+	clrf	apnoe_max_pressure+1
+	clrf	apnoe_surface_mins			
+	clrf	apnoe_surface_secs		
+	clrf	apnoe_mins
+	clrf	apnoe_secs
+	clrf	divemins+0
+	clrf	divemins+1
+	clrf	divesecs
+	clrf	samplesecs
+	clrf	apnoe_timeout_counter		; timeout in minutes
+	clrf 	timeout_counter				; takes care of the timeout
+	clrf 	timeout_counter2			; Here: counts to six, then store deco data and temperature
+	clrf	AlarmType					; Clear all alarms
+	bcf		event_occured				; clear flag
+	bcf		depth_greater_100m			; clear flag
+	setf	last_diluent				; to be displayed after first calculation (range: 0 to 100 [%])
+	clrf	char_last_pointer
+	bcf		dekostop_active			
+	call	get_free_EEPROM_location	; get last position in external EEPROM, may be up to 2 secs!
+
+	movff	last_surfpressure_30min+1,int_I_pres_surface+1	; HIGH copy surfacepressure to deco routine
+	movff	last_surfpressure_30min+0,int_I_pres_surface+0	; LOW copy surfacepressure to deco routine
+	movff	temperature+0,mintemp+0						; Reset Min-Temp registers
+	movff	temperature+1,mintemp+1						; Reset Min-Temp registers
+
+	clrf	wait_temp					; Used to clear Bankx registers
+	movff	wait_temp,char_O_GF_low_pointer
+	movff	wait_temp,char_O_actual_pointer
+	lfsr	FSR0,0x250
+	movlw	0x20
+	movwf	wait_temp
+clear_deco_lists:						; Clear Deco list
+	clrf	POSTINC0
+	decfsz	wait_temp,F
+		bra		clear_deco_lists
+	lfsr	FSR0,0x270
+	movlw	0x20
+	movwf	wait_temp
+set_no_forced_stops:					; Init Deco list
+	movlw	0x01
+	movwf	POSTINC0
+	decfsz	wait_temp,F
+		bra		set_no_forced_stops
+	lfsr	FSR0,0x290					; clear int_O_calc_tissue_call_counter (DEBUG)
+	clrf	POSTINC0
+	clrf	POSTINC0
+
+; Load GF values into RAM
+	GETCUSTOM8	d'32'			; GF low
+	movff		EEDATA,char_I_GF_Lo_percentage
+	GETCUSTOM8	d'33'			; GF high
+	movff		EEDATA,char_I_GF_Hi_percentage
+
+; Start with active Stopwatch?
+	bsf			stopwatch_active
+	GETCUSTOM8	d'41'			; =1: Start with active Stopwatch
+	movwf		lo
+	movlw		d'1'
+	cpfseq		lo						; CF41=1?
+	bcf			stopwatch_active		; No!
+
+; Init profile recording parameters	
+	GETCUSTOM8	d'20'			; sample rate
+	movwf	samplesecs_value	; to avoid EEPROM access in the ISR
+	GETCUSTOM8	d'21'
+	movwf	divisor_temperature			; load divisors for profile storage
+	GETCUSTOM8	d'22'
+	movwf	divisor_deco				
+	GETCUSTOM8	d'23'
+	movwf	divisor_tank
+	GETCUSTOM8	d'24'
+	movwf	divisor_ppo2
+	GETCUSTOM8	d'25'
+	movwf	divisor_deco_debug
+	GETCUSTOM8	d'26'
+	movwf	divisor_nuy2
+
+	btfss	FLAG_apnoe_mode		; In Apnoe mode?
+	bra		divemode1
+; Overwrite some parameters in Apnoe mode....
+	movlw	d'1'
+	movwf	samplesecs_value	; to avoid EEPROM access in the ISR
+
+divemode1:
+	read_int_eeprom	d'36'				; Read mix 1 ppO2
+	btfsc	FLAG_const_ppO2_mode
+	movff	EEDATA,char_I_const_ppO2	; Set ppO2 setpoint if in ppO2 mode
+
+	call	clear_LEDnofly				; Clear flags
+	bcf		low_battery_state			; clear flag for battery warning mode
+	bcf		header_stored				
+	bcf		premenu
+	bcf		realdive
+	bsf		update_divetime				; set flag
+	btfss	simulatormode_active		; do not disable in simulator mode!					
+	call	disable_rs232				; Disable RS232 unless in external O2 Sensor mode
+
+	read_int_eeprom 	d'33'			; Read byte (stored in EEDATA)
+	movff	EEDATA,active_gas			; Read start gas (1-5)
+
+; Read Start Gas and configure char_I_He_ratio, char_I_O2_ratio and char_I_N2_ratio
+	decf	active_gas,W				; Gas 0-4
+	mullw	d'4'
+	movf	PRODL,W			
+	addlw	d'7'						; = address for He ratio
+	movwf	EEADR
+	call	read_eeprom					; Read He ratio
+	movff	EEDATA,char_I_He_ratio		; And copy into hold register
+	decf	active_gas,W				; Gas 0-4
+	mullw	d'4'
+	movf	PRODL,W			
+	addlw	d'6'						; = address for O2 ratio
+	movwf	EEADR
+	call	read_eeprom					; Read O2 ratio
+	movff	EEDATA, char_I_O2_ratio		; O2 ratio
+	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	EEDATA,F					; minus O2
+	movff	EEDATA, char_I_N2_ratio		; = N2!
+
+; New in 1.09 - DecoGas can be configured to achieve exact decompression proposal
+ ; required variables
+ ; These values are set when the OSTC is in decompression mode - will be done in routine "check_decogas"
+ ; char_I_deco_gas_change;				; next gas change in meter
+ ; char_I_deco_N2_ratio;				; next gas N2
+ ; char_I_deco_He_ratio;				; next gas He
+  	clrf	lo
+ 	movff	lo, char_I_deco_gas_change	; clear 
+ 	movff	lo, char_I_deco_N2_ratio	; clear
+ 	movff	lo, char_I_deco_He_ratio	; clear
+	bcf		multi_gf_display			; Do not display the multi-gf table screen
+	return
\ No newline at end of file