diff src/ghostwriter.asm @ 631:185ba2f91f59

3.09 beta 1 release
author heinrichsweikamp
date Fri, 28 Feb 2020 15:45:07 +0100
parents 237931377539
children 4050675965ea
line wrap: on
line diff
--- a/src/ghostwriter.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/ghostwriter.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File ghostwriter.asm                      combined next generation V3.06.2
+;   File ghostwriter.asm                      combined next generation V3.08.8
 ;
 ;   Ghostwriter (Log profile recorder)
 ;
@@ -18,12 +18,37 @@
 #include "tft_outputs.inc"
 #include "divemode.inc"
 #include "rtc.inc"
+#include "logbook.inc"
 
 
 	extern	deco_pull_tissues_from_vault
 
 
-	; private local Variables
+; ----------------------------------------------------------------------------
+;  Macros - write PROFILE data to FLASH (all macros are bank-safe)
+
+FLASH_LIT_PROFILE	macro	literal				; write 1 byte LITERAL     to FLASH profile data
+	movlw	literal
+	rcall	ghostwrite_WREG_profile_exec
+	endm
+
+FLASH_WREG_PROFILE	macro						; write 1 byte from WREG   to FLASH profile data
+	rcall	ghostwrite_WREG_profile_exec
+	endm
+
+FLASH_CC_PROFILE	macro	memory_address		; write 1 byte from memory to FLASH profile data
+	MOVCC	memory_address,WREG
+	rcall	ghostwrite_WREG_profile_exec
+	endm
+
+FLASH_II_PROFILE	macro	memory_address		; write 2 byte from memory to FLASH profile data
+	lfsr	FSR0,memory_address
+	rcall	ghostwrite_II_profile_exec
+	endm
+
+
+; ----------------------------------------------------------------------------
+;   private local Variables
 
 	CBLOCK	local3						; max size is 16 Byte !!!
 		divisor_temperature				; divisor used to time the sampling of dive data
@@ -47,17 +72,17 @@
 	movlw	div_temperature				; get divisor for temperature storage
 	movwf	divisor_temperature			; initialize divisor
 
-	movlw	div_deco					; ...
-	movwf	divisor_deco				; ...
+	movlw	div_deco					; get divisor for deco status
+	movwf	divisor_deco				; initialize divisor
 
-	movlw	div_gf
-	movwf	divisor_supersat
+	movlw	div_gf						; get divisor for saturation
+	movwf	divisor_supersat			; initialize divisor
 
-	movlw	div_decoplan
-	movwf	divisor_decoplan
+	movlw	div_decoplan				; get divisor for deco plan
+	movwf	divisor_decoplan			; initialize divisor
 
-	movlw	div_cns
-	movwf	divisor_cns
+	movlw	div_cns						; get divisor for CNS
+	movwf	divisor_cns					; initialize divisor
 
  IFDEF _rx_functions
 	clrf	WREG						; default to no tank data logging
@@ -67,16 +92,13 @@
  ENDIF
 
  IFDEF _external_sensor
-	movlw	div_ppo2_sensors
-	movwf	divisor_ppo2_sensors
-
+	movlw	div_ppo2_sensors			; get divisor for ppO2 sensor
+	movwf	divisor_ppo2_sensors		; initialize divisor by default
 	btfsc	FLAG_ccr_mode				; in CCR mode?
-	bra		init_recording_params_2		; YES
-	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	bra		init_recording_params_2		; YES
-	; in all modes but CCR and pSCR, disable ppO2 logging
-	movlw	.0
-	movwf	divisor_ppo2_sensors
+	bra		init_recording_params_2		; YES - keep divisor
+	btfsc	FLAG_pscr_mode				; NO  - in pSCR mode?
+	bra		init_recording_params_2		;       YES - keep divisor
+	clrf 	divisor_ppo2_sensors		;       NO  - clear divisor again
  ENDIF
 
 init_recording_params_2:
@@ -88,26 +110,26 @@
 	bcf		trigger_sample_divedata		; clear flag
 
  ifndef _DEBUG
+	; In DEBUG compile, write simulated dives to logbook
 	btfsc	sensor_override_active		; in simulator mode?
 	return								; YES - no dive data stored in simulator mode
  endif
 
 	btfss	FLAG_apnoe_mode				; in apnoe mode?
 	bra		store_dive_data_1			; NO  - proceed
-	TSTOSS	opt_store_apnoe_dive		; YES - logging in apnoe mode enabled?
+	TSTOSS	opt_store_apnoe				; YES - logging in apnoe mode enabled?
 	return								;       NO  - done
 
 store_dive_data_1:
-; Store depth with every sample
-	movf	pressure_rel_cur_cached+0,W	; get depth (relative pressure), low  byte
-	rcall	ghostwrite_byte_profile		; store to profile in ext. flash
-	movf	pressure_rel_cur_cached+1,W	; get depth (relative pressure), high byte
-	rcall	ghostwrite_byte_profile		; store to profile in ext. flash
+	; store depth with every sample
+	MOVII	pressure_rel_cur_cached,mpr	; copy current relative pressure to MPR
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
+	FLASH_II_PROFILE mpr				; store depth
 
-; First, find out how many bytes will be appended to this sample set
-	clrf	ProfileFlagByte				; clear number of bytes to append
+	; first, find out how many bytes will be appended to this sample set
+	clrf	ProfileFlagByte				; start with no bytes to append
 
-; Check Extended Information
+	; check extended information
 	decfsz	divisor_temperature,W		; check divisor if it will become 0, dump decremented value to WREG
 	bra		check_extended1				; NO  - skip
 	movlw	infolength_temperature		; YES - get length of extra data
@@ -146,9 +168,9 @@
 	movlw	infolength_tank				; YES - get length of extra data
 	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
  ENDIF
+
 check_extended7:
-
-; Second, check global event flag
+	; second, check global event flag
 	btfss	event_occured				; check global event flag
 	bra		store_dive_data3			; no event
 
@@ -161,7 +183,7 @@
 	addwf	event_byte1,F				; copy to event byte 1, bit 0-3
 	clrf	alarm_type					; reset alarm type
 
-; Third, check events and add additional bytes
+	; third, check events and add additional bytes
 	btfss	event_gas_change_gas6		; did a change to gas 6 occur?
 	bra		check_event2				; NO
 	movlw	d'2'						; YES - set information length
@@ -192,128 +214,122 @@
  ENDIF
 
 check_event5:
-	; more events?
+	; more events in future time...
 
 store_dive_data3:
-	btfsc	event_byte1,7				; =1: another event byte is available
-	incf	ProfileFlagByte,F			; add one byte (the event byte 2)
+	btfsc	event_byte1,7				; is another event byte available?
+	incf	ProfileFlagByte,F			; YES - add one byte (the event byte 2)
 
-	btfsc	event_occured				; check global event flag
-	bsf		ProfileFlagByte,7			; set event byte 1 flag in ProfileFlagByte
+	btfsc	event_occured				; global event flag set?
+	bsf		ProfileFlagByte,7			; YES - set event byte 1 flag in ProfileFlagByte
 
-	movf	ProfileFlagByte,W			; finally, write ProfileFlagByte
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
+	FLASH_CC_PROFILE ProfileFlagByte	; store ProfileFlagByte
 
-	btfss	event_occured				; check global event flag (again)
-	bra		store_dive_data4			; no event
+	btfss	event_occured				; global event flag set?
+	bra		store_dive_data4			; NO - no events to store
+
+	; store the EventByte(s) + additional bytes now
+	FLASH_CC_PROFILE event_byte1		; store 1st event byte
 
-	; Store the EventByte(s) + additional bytes now
-	movf	event_byte1,W
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	movf	event_byte2,W				; write second event byte...
-	btfsc	event_byte1,7				; =1: another event byte is available
-	rcall	ghostwrite_byte_profile		; store that information
+	btfss	event_byte1,7				; another event byte available?
+	bra		store_dive_data3a			; NO  - skip
+	FLASH_CC_PROFILE event_byte2		; YES - store 2nd event byte
 
+store_dive_data3a:
 	btfss	event_gas_change_gas6		; did a change to gas 6 occur?
-	bra		store_dive_data3b			; NO
-	movff	char_I_O2_ratio,WREG		; YES - get gas 6 O2 ratio
-	rcall	ghostwrite_byte_profile		;     - store it
+	bra		store_dive_data3b			; NO  - skip
+	FLASH_CC_PROFILE char_I_O2_ratio	; YES - store gas 6 O2 ratio
  IFDEF _helium
-	movff	char_I_He_ratio,WREG		;     - get gas 6 He ratio
+	FLASH_CC_PROFILE char_I_He_ratio	;     - store gas 6 He ratio
  ELSE
-	clrf	WREG						;     - He ratio is zero
+	FLASH_LIT_PROFILE .0				;     - store He ratio as zero
  ENDIF
-	rcall	ghostwrite_byte_profile		;     - store it
 	bcf		event_gas_change_gas6		;     - clear event flag
 
 store_dive_data3b:
 	btfss	event_gas_change			; did a gas change occur?
-	bra		store_dive_data3c			; NO
+	bra		store_dive_data3c			; NO  - skip
  IFDEF _ccr_pscr
 	movf	active_dil,W				; YES - get active diluent by default
 	btfsc	FLAG_oc_mode				;     - in OC mode?
 	movf	active_gas,W				;       YES - replace by active gas
 	btfsc	bailout_mode				;     - in bailout?
  ENDIF
-	movf	active_gas,W				;       YES - get active OC (bailout) gas
-	rcall	ghostwrite_byte_profile		;     - store it
+	movf	active_gas,W				;       (YES) - get (replace with) active OC (bailout) gas
+	FLASH_WREG_PROFILE					;     - store active gas/diluent
 	bcf		event_gas_change			;     - clear event flag
 
 store_dive_data3c:
  IFDEF _ccr_pscr
 	btfss	event_SP_change				; did a setpoint change occur?
-	bra		store_dive_data3d			; NO
-	movff	char_I_const_ppO2,WREG		; YES - get setpoint
-	rcall	ghostwrite_byte_profile		;     - store it
+	bra		store_dive_data3d			; NO  - skip
+	FLASH_CC_PROFILE char_I_const_ppO2	; YES - store setpoint
 	bcf		event_SP_change				;     - clear event flag
  ENDIF
 
 store_dive_data3d:
  IFDEF _ccr_pscr
 	btfss	event_bailout				; did a gas change due to bailout occur?
-	bra		store_dive_data4			; NO
-	movff	char_I_O2_ratio,WREG		; YES - get O2 ratio of bailout gas
-	rcall	ghostwrite_byte_profile		;     - store it
+	bra		store_dive_data4			; NO  - skip
+	FLASH_CC_PROFILE char_I_O2_ratio	; YES - store O2 ratio of bailout gas
  IFDEF _helium
-	movff	char_I_He_ratio,WREG		;     - get He ratio of bailout gas
+	FLASH_CC_PROFILE char_I_He_ratio	;     - store He ratio of bailout gas
  ELSE
-	clrf	WREG						;     - He ratio is zero
+	FLASH_LIT_PROFILE .0				;     - store He ratio as zero
  ENDIF	; helium
-	rcall	ghostwrite_byte_profile		;     - store it
 	bcf		event_bailout				;     - clear event flag
  ENDIF	; _ccr_pscr
 
 store_dive_data4:
 	; Store extended information
-
-	decfsz	divisor_temperature,F		; time to store a temperature sample ?
+	decfsz	divisor_temperature,F		; decrement timer, did it became 0 ?
 	bra		store_dive_data4a			; NO  - skip
-	rcall	store_dive_temperature		; YES - store data
+	rcall	store_dive_temperature		; YES - store temperature
 store_dive_data4a:
-	btfsc	divisor_temperature,7		; did the timer under-run?
+	btfsc	divisor_temperature,7		; did the divisor under-run?
 	clrf	divisor_temperature			; YES - reset timer
 
-	decfsz	divisor_deco,F				; time to store the current deco data?
+	decfsz	divisor_deco,F				; decrement timer, did it became 0 ?
 	bra		store_dive_data4b			; NO  - skip
-	rcall	store_dive_decodata			; YES - store data
+	rcall	store_dive_decodata			; YES - store deco data
 store_dive_data4b:
 	btfsc	divisor_deco,7				; did the timer under-run?
 	clrf	divisor_deco				; YES - reset timer
 
-	decfsz	divisor_supersat,F			; time to store the current supersaturation ?
+	decfsz	divisor_supersat,F			; decrement timer, did it became 0 ?
 	bra		store_dive_data4c			; NO  - skip
-	rcall	store_dive_supersat			; YES - store data
+	rcall	store_dive_supersat			; YES - store supersaturation
 store_dive_data4c:
 	btfsc	divisor_supersat,7			; did the timer under-run?
 	clrf	divisor_supersat			; YES - reset timer
 
  IFDEF _external_sensor
-	decfsz	divisor_ppo2_sensors,F		; decrement divisor, did it became 0 ?
+	decfsz	divisor_ppo2_sensors,F		; decrement timer, did it became 0 ?
 	bra		store_dive_data4d			; NO  - skip
-	rcall	store_dive_ppO2_sensors		; YES - store data
+	rcall	store_dive_ppO2_sensors		; YES - store sensor data
 store_dive_data4d:
 	btfsc	divisor_ppo2_sensors,7		; did the timer under-run?
 	clrf	divisor_ppo2_sensors		; YES - reset timer
  ENDIF
 
-	decfsz	divisor_decoplan,F			; decrement divisor, did it became 0 ?
+	decfsz	divisor_decoplan,F			; decrement timer, did it became 0 ?
 	bra		store_dive_data4e			; NO  - skip
-	rcall	store_dive_decoplan			; YES - store data
+	rcall	store_dive_decoplan			; YES - store deco plan
 store_dive_data4e:
 	btfsc	divisor_decoplan,7			; did the timer under-run?
 	clrf	divisor_decoplan			; YES - reset timer
 
-	decfsz	divisor_cns,F				; decrement divisor, did it became 0 ?
+	decfsz	divisor_cns,F				; decrement timer, did it became 0 ?
 	bra		store_dive_data4f			; NO  - skip
-	rcall	store_dive_cns				; YES - store data
+	rcall	store_dive_cns				; YES - store CNS
 store_dive_data4f:
 	btfsc	divisor_cns,7				; did the timer under-run?
 	clrf	divisor_cns					; YES - reset timer
 
  IFDEF _rx_functions
-	decfsz	divisor_tank,F				; decrement divisor, did it became 0 ?
+	decfsz	divisor_tank,F				; decrement timer, did it became 0 ?
 	bra		store_dive_data4g			; NO  - skip
-	rcall	store_dive_tank				; YES - store data
+	rcall	store_dive_tank				; YES - store tank pressure
 store_dive_data4g:
 	btfsc	divisor_tank,7				; did the timer under-run?
 	clrf	divisor_tank				; YES - reset timer
@@ -323,39 +339,34 @@
 	bcf		event_occured				; clear the global event flag
 	clrf	event_byte1					; reset event byte 1
 	clrf	event_byte2					; reset event byte 2
-	return								; done (sample with all information written to external flash)
+	return								; done
 
 
  IFDEF _rx_functions
 store_dive_tank:
-	movff	int_O_tank_pressure+0,WREG	; get tank pressure, low  byte
-	rcall	ghostwrite_byte_profile		; store it
-	movff	int_O_tank_pressure+1,WREG	; get tank pressure, high byte
-	rcall	ghostwrite_byte_profile		; store it
-	movlw	div_tank					; get sampling rate
-	movwf	divisor_tank				; reload timer
+	FLASH_II_PROFILE int_O_tank_pressure	; store tank pressure
+	movlw	div_tank						; get sampling rate
+	movwf	divisor_tank					; reload timer
 	return
  ENDIF
 
 store_dive_cns:
-	movff	int_O_CNS_current+0,WREG	; get current CNS, low  byte
-	rcall	ghostwrite_byte_profile		; store it
-	movff	int_O_CNS_current+1,WREG	; get current CNS, high byte
-	bcf		WREG,int_warning_flag		; clear warning   flag
-	bcf		WREG,int_attention_flag		; clear attention flag
-	rcall	ghostwrite_byte_profile		; store it
-	movlw	div_cns						; get sampling rate
-	movwf	divisor_cns					; reload timer
+	MOVII	int_O_CNS_current,mpr			; get current CNS
+	bcf		mpr+1,int_warning_flag			; clear warning   flag
+	bcf		mpr+1,int_attention_flag		; clear attention flag
+	FLASH_II_PROFILE mpr					; store CNS
+	movlw	div_cns							; get sampling rate
+	movwf	divisor_cns						; reload timer
 	return
 
 store_dive_decoplan:
-	; Store the deco plan
+	; store the deco plan
 	lfsr	FSR1,char_O_deco_time_for_log	; load base address of deco stop times table
 	movlw	NUM_STOPS_LOG					; load size         of deco stop times table
 	movwf	lo								; copy size to loop counter
 store_dive_decoplan_loop:
 	movf	POSTINC1,W						; get a stop time
-	rcall	ghostwrite_byte_profile			; store it
+	FLASH_WREG_PROFILE						; store it
 	decfsz	lo,F							; decrement loop counter, became zero?
 	bra		store_dive_decoplan_loop		; NO  - loop
 	movlw	div_decoplan					; YES - get sampling rate
@@ -365,288 +376,228 @@
 
  IFDEF _external_sensor
 store_dive_ppO2_sensors:
-	movff	sensor1_ppO2,WREG				; get sensor 1 ppO2 (in 0.01 bar steps)
-	rcall	ghostwrite_byte_profile			; store it
-	SMOVII	sensor1_mv,mpr					; ISR-safe 2 byte copy of o2_mv_sensor to hi:lo
-	movf	lo,W							; in 0.1 mV steps, low  byte
-	rcall	ghostwrite_byte_profile			; store it
-	movf	hi,W							; in 0.1 mV steps, high byte
-	rcall	ghostwrite_byte_profile			; store it
+	FLASH_CC_PROFILE sensor1_ppO2			; store sensor 1 ppO2 (in 0.01 bar steps)
+	SMOVII	sensor1_mv,mpr					; ISR-safe 2 byte copy of o2_mv_sensor
+	FLASH_II_PROFILE mpr					; store sensor 1 mV
 
-	movff	sensor2_ppO2,WREG				; get sensor 2 ppO2 (in 0.01 bar steps)
-	rcall	ghostwrite_byte_profile			; store it
-	SMOVII	sensor2_mv,mpr					; ISR-safe 2 byte copy of o2_mv_sensor to hi:lo
-	movf	lo,W							; in 0.1 mV steps, low  byte
-	rcall	ghostwrite_byte_profile			; store it
-	movf	hi,W							; in 0.1 mV steps, high byte
-	rcall	ghostwrite_byte_profile			; store it
+	FLASH_CC_PROFILE sensor2_ppO2			; store sensor 2 ppO2 (in 0.01 bar steps)
+	SMOVII	sensor2_mv,mpr					; ISR-safe 2 byte copy of o2_mv_sensor
+	FLASH_II_PROFILE mpr					; store sensor 2 mV
 
-	movff	sensor3_ppO2,WREG				; get sensor 3 ppO2 (in 0.01 bar steps)
-	rcall	ghostwrite_byte_profile			; store it
-	SMOVII	sensor3_mv,mpr					; ISR-safe 2 byte copy of o2_mv_sensor to hi:lo
-	movf	lo,W							; in 0.1 mV steps, low  byte
-	rcall	ghostwrite_byte_profile			; store it
-	movf	hi,W							; in 0.1 mV steps, high byte
-	rcall	ghostwrite_byte_profile			; store it
+	FLASH_CC_PROFILE sensor3_ppO2			; store sensor 3 ppO2 (in 0.01 bar steps)
+	SMOVII	sensor3_mv,mpr					; ISR-safe 2 byte copy of o2_mv_sensor
+	FLASH_II_PROFILE mpr					; store sensor 3 mV
 
 	movlw	div_ppo2_sensors				; get sampling rate
 	movwf	divisor_ppo2_sensors			; reload timer
-	return
+	return									; done
  ENDIF
 
-
 store_dive_supersat:
-	movff	int_O_lead_supersat+0,WREG		; get leading tissue's supersaturation (value is limited to 255, only lower byte is used for the value)
-	rcall	ghostwrite_byte_profile			; store it
+	FLASH_CC_PROFILE int_O_lead_supersat+0	; store leading tissue's supersaturation (value is limited to 255, only lower byte is used for the value)
 	movlw	div_gf							; get sampling rate
 	movwf	divisor_supersat				; reload timer
-	return
+	return									; done
 
 store_dive_decodata:
 	; Check if deco stops are necessary
 	movff	char_O_deco_depth,WREG			; get depth of the first stop
 	tstfsz	WREG							; depth of first stop > 0 m (aka in deco) ?
 	bra		store_dive_decodata_deco		; YES
-	; NO - within NDL
-	clrf	WREG							; =0: no stop dive
-	rcall	ghostwrite_byte_profile			; store it
-	movff	char_O_NDL_norm,WREG			; get NDL time in normal plan
-	rcall	ghostwrite_byte_profile			; store it
+	;bra	store_dive_decodata_ndl			; NO
+
+store_dive_decodata_ndl:
+	FLASH_LIT_PROFILE .0					; store depth of first stop as zero (encodes NDL dive)
+	FLASH_CC_PROFILE int_O_NDL_norm+0		; store NDL time from normal plan
 	bra		store_dive_decodata_common
+
 store_dive_decodata_deco:
-	; YES - in deco
-	movff	char_O_deco_depth,WREG			; get depth of the first stop in meters
-	rcall	ghostwrite_byte_profile			; store it
-	movff	char_O_deco_time,WREG			; get time of the first stop in minutes
-	rcall	ghostwrite_byte_profile			; store it
+	FLASH_CC_PROFILE char_O_deco_depth		; store depth    of the first stop in meters
+	FLASH_CC_PROFILE char_O_deco_time		; store duration of the first stop in minutes
+	;bra	store_dive_decodata_common
+
 store_dive_decodata_common:
 	movlw	div_deco						; get sampling rate
 	movwf	divisor_deco					; reload timer
-	return
+	return									; done
 
 store_dive_temperature:
-	SMOVII	temperature_cur,mpr				; ISR-safe 2 byte copy of current temperature to hi:lo
-	movf	lo,W							; get low  byte
-	rcall	ghostwrite_byte_profile			; store it
-	movf	hi,W							; get high byte
-	rcall	ghostwrite_byte_profile			; store it
+	SMOVII	temperature_cur,mpr				; ISR-safe 2 byte copy of current temperature
+	FLASH_II_PROFILE mpr					; store temperature
 	movlw	div_temperature					; get sampling rate
 	movwf	divisor_temperature				; reload timer
-	return
+	return									; done
+
 
-ghostwrite_byte_header:
-	goto	write_byte_ext_flash_plus_header ; (this call will also delete the 4kB TOC entry first)
-	; returns...
-
-ghostwrite_byte_profile:
-	goto	write_byte_ext_flash_plus		; writes byte and increases address with banking at 0x200000
-	; returns...
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; flash writing through the macros
+;
+ghostwrite_II_profile_exec:
+	movf	POSTINC0,W							; get byte into WREG
+	call	write_byte_ext_flash_plus_prof		; write to external flash -> profile data
+	movf	POSTINC0,W							; get next byte into WREG
+ghostwrite_WREG_profile_exec:
+	goto	write_byte_ext_flash_plus_prof		; write to external flash -> profile data (and return)
+;
+; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 	global	ghostwriter_end_dive
 ghostwriter_end_dive:
-	; save end-of-profile pointer to store in header
-	movff	ext_flash_address+0,ext_flash_log_pointer+0
-	movff	ext_flash_address+1,ext_flash_log_pointer+1
-	movff	ext_flash_address+2,ext_flash_log_pointer+2
+	; save end-of-profile pointer for later storage in EEPROM
+	MOVTT	ext_flash_address,ext_flash_log_pointer
 
 	; remember last custom view shown in dive mode
 	movff	active_customview,customview_divemode
 
-	btfss	divetime_longer_1min			; dive longer then one minute
+	; reset gas/diluent lost & staged flags
+	lfsr	FSR1,opt_gas_type				; load FSR1 with base address of opt_gas_type
+ IFDEF _ccr_pscr
+	movlw	2*NUM_GAS						; load loop counter with number of gases + diluents = 2*5
+ ELSE
+	movlw	NUM_GAS							; load loop counter with number of gases = 5
+ ENDIF
+ghostwriter_end_dive_0:
+	bcf		INDF1,gas_lost					; clear lost   flag and keep    index at present gas/dil
+	bcf		POSTINC1,gas_staged				; clear staged flag and advance index to next    gas/dil
+	decfsz	WREG							; decrement loop counter and check if it became zero
+	bra		ghostwriter_end_dive_0			; NO  - not yet, loop
+
+	; clear bailout state (if applicable)
+	bcf		bailout_mode
+
+	; check if dive is worth storage at all
+	btfss	divetime_longer_1min			; dive longer than one minute?
 	goto	ghostwriter_end_dive_common		; NO - discard everything
 
-; In DEBUG compile, write simulated dives to logbook
  ifndef _DEBUG
-	btfsc	sensor_override_active			; are we in simulator mode?
+	; in DEBUG compile, write simulated dives to logbook
+	btfsc	sensor_override_active			; in simulator mode?
 	goto	ghostwriter_end_dive_common		; YES - discard everything
  endif
 
+	; calculate desaturation time
+	call	deco_calc_desaturation_time		; call the C-code
+	banksel	common							; back to bank common
+
+	; condition apnoe mode
+	btfss	FLAG_apnoe_mode								; are we in apnoe mode?
+	bra		ghostwriter_end_dive_00						; NO  - proceed
+	MOVII	apnoe_max_pressure,pressure_rel_max_cached	; YES - get max pressure of all yoyo dives
+
+ghostwriter_end_dive_00:
+	; compute max depth for storage and last dive statistics
+	MOVII	pressure_rel_max_cached,mpr		; get max pressure
+	call	convert_pres_to_depth			; convert pressure in [mbar] to depth in [cm]
+	MOVII	mpr,lastdive_maxdepth			; store for last dive statistics
+
+	; compute avg depth for storage and last dive statistics
+	MOVII	pressure_rel_avg_total,mpr		; get average pressure
+	call	convert_pres_to_depth			; convert pressure in [mbar] to depth in [cm]
+	MOVII	mpr,lastdive_avgdepth			; store in last dive statistics
+
+	; get dive duration for last dive statistics
+	SMOVTT	counted_divetime_mins,lastdive_duration	; ISR-safe 3 byte copy of minutes:2 and seconds
+
+	; check logging of apnoe mode
 	btfss	FLAG_apnoe_mode					; are we in apnoe mode?
 	bra		ghostwriter_end_dive_1			; NO  - proceed
-	TSTOSS	opt_store_apnoe_dive			; YES - logging in apnoe mode enabled?
-	goto	ghostwriter_end_dive_common		;       NO  - discard everything
+	TSTOSS	opt_store_apnoe					; YES - logging in apnoe mode enabled?
+	goto	ghostwriter_end_dive_cleanup	;       NO  - skip logging but do the after-dive cleanup
 
 ghostwriter_end_dive_1:
-	; Dive finished (and longer than one minute)
-
-	btfsc	FLAG_apnoe_mode					; are we in apnoe mode?
-	call	apnoe_calc_maxdepth				; YES - calculate max. depth (again) for very short apnoe dives
+	; dive finished (and longer than one minute)
 
-	movlw	0xFD							; coding for End-of-Profile, byte 1
-	rcall	ghostwrite_byte_profile			; store it
-	movlw	0xFD							; coding for End-of-Profile, byte 2
-	rcall	ghostwrite_byte_profile			; store it
+	; close profile recording
+	FLASH_LIT_PROFILE 0xFD					; write end-of-profile code, byte 1
+	FLASH_LIT_PROFILE 0xFD					; write end-of-profile code, byte 2
 
-	; Save end-of-profile pointer to store in header
-	movff	ext_flash_address+0,ext_flash_log_pointer+0
-	movff	ext_flash_address+1,ext_flash_log_pointer+1
-	movff	ext_flash_address+2,ext_flash_log_pointer+2
-
-	; Set to first address again to store dive length ext_flash_dive_counter:3
-	rcall	ghostwriter_load_pointer		; load ext_flash_address:3 from EEPROM .4-.6
+	; save end-of-profile pointer for later storage in header and EEPROM
+	MOVTT	ext_flash_address,ext_flash_log_pointer
 
-	incf_ext_flash_address_0x20 d'6'		; skip internal "0xFA 0xFA #Divenumber:2 0xFA 0xFA" Header
-	; Store dive length
-	movf	ext_flash_dive_counter+0,W
-	call	write_byte_ext_flash_plus_nodel	; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) and does NOT delete 4kB page
-	movf	ext_flash_dive_counter+1,W
-	call	write_byte_ext_flash_plus_nodel	; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) and does NOT delete 4kB page
-	movf	ext_flash_dive_counter+2,W
-	call	write_byte_ext_flash_plus_nodel	; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) and does NOT delete 4kB page
+	; set to first address of profile data again to store dive length (number of recorded bytes)
+	rcall	ghostwriter_load_pointer
 
-; profile recording done
+	; skip internal "0xFA 0xFA #Divenumber:2 0xFA 0xFA" header, i.e. the first 6 bytes
+	ext_flash_inc_address_0x20 d'6'
 
-	; Load total number of dives
-	read_int_eeprom .2
-	movff	EEDATA,lo
-	read_int_eeprom .3
-	movff	EEDATA,hi
-
-	INCI	mpr								; increase total dive counter
+	; store dive length (-> profile, NO ext_flash_length_counter increase, NO page delete)
+	movf	ext_flash_length_counter+0,W
+	call	write_byte_ext_flash_plus_nodel
+	movf	ext_flash_length_counter+1,W
+	call	write_byte_ext_flash_plus_nodel
+	movf	ext_flash_length_counter+2,W
+	call	write_byte_ext_flash_plus_nodel
 
-	; Store new number in EEPROM
-	movff	lo,EEDATA
-	write_int_eeprom .2
-	movff	hi,EEDATA
-	write_int_eeprom .3
-
-	decf	lo,F							; -1
+	; ... profile recording done
 
-	; Set ext_flash_address:3 to TOC entry of this dive
-	; 1st: 200000h-200FFFh -> lo=0
-	; 2nd: 201000h-201FFFh -> lo=1
-	; 3rd: 202000h-202FFFh -> lo=2
-	; 255: 2FF000h-2FFFFFh -> lo=255
+	; read, increment, and store again total number of dives
+	call	eeprom_total_dives_read			; read total number of dives
+	INCI	mpr								; increment by one
+	call	eeprom_total_dives_write		; store updated number of total dives
 
-	clrf	ext_flash_address+0
-	clrf	ext_flash_address+1
-	movlw	0x20
-	movwf	ext_flash_address+2
-	movlw	.16
-	mulwf	lo								; lo*16 = offset to 0x2000 (up:hi)
-	movf	PRODL,W
-	addwf	ext_flash_address+1,F
-	movf	PRODH,W
-	addwfc	ext_flash_address+2,F
+	; prepare header
+	CLRR	header_buffer,.256				; initialize header to all zeros
 
-	; write header start code
-	movlw	0xFA							; header start
-	rcall	ghostwrite_byte_header			; (this call will also delete the 4kB TOC entry first)
-	movlw	0xFA
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; store header start code
+	MOVLI	0xFAFA,mpr
+	MOVII	mpr,header_buffer+index_header_start
 
 	; store pointer to begin of dive profile
-	read_int_eeprom .4
-	movf	EEDATA,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	read_int_eeprom .5
-	movf	EEDATA,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	read_int_eeprom .6
-	movf	EEDATA,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	EEPROM_TT_READ	eeprom_log_pointer,mpr
+	MOVTT	mpr,header_buffer+index_profile_start_address
 
 	; store pointer to end of dive profile
-	movf	ext_flash_log_pointer+0,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	ext_flash_log_pointer+1,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	ext_flash_log_pointer+2,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	MOVTT	ext_flash_log_pointer,header_buffer+index_profile_end_address
 
-	; write the remainder of the header
-	movlw	logbook_profile_version			; defined in hwos.inc
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; write the profile format version (defined in hwos.inc)
+	movlw	logbook_profile_version
+	MOVCC	WREG,header_buffer+index_profile_version
 
-	; store dive length
-	movf	ext_flash_dive_counter+0,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	ext_flash_dive_counter+1,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	ext_flash_dive_counter+2,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; store dive length (in units of recording entries)
+	MOVTT	ext_flash_length_counter,header_buffer+index_profile_byte_count
 
-	; store start of time time & date
-	lfsr	FSR0,start_year					; load base address of start-of-dive data
-	movf	POSTINC0,W						; year
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; month
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; day
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; hour
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; minute
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-
-	btfss	FLAG_apnoe_mode					; store apnoe max or normal max (which is only max from the last descent)
-	bra		end_dive1						; store normal depth
-
-	; apnoe max depth
-	MOVII	apnoe_max_pressure,mpr
-	call	adjust_depth_with_salinity		; compute salinity setting into hi:lo [mbar]
-	MOVII	mpr,apnoe_max_pressure
-	bra		end_dive2						; store max depth
+	; store time time & date of dive begin
+	MOVTT	start_year,header_buffer+index_date
+	MOVTT	start_hour,header_buffer+index_time
 
-end_dive1:
-	; normal max depth
-	MOVII	pressure_rel_max_cached,mpr
-	call	adjust_depth_with_salinity		; compute salinity setting into hi:lo [mbar]
-	MOVII	mpr,pressure_rel_max_cached
+	; store max depth
+	MOVII	lastdive_maxdepth,header_buffer+index_max_depth
 
-end_dive2:
-	; store max depth (common part)
-	movf	lo,W							; max. depth, low  byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	hi,W							; max. depth, high byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-
-	; store dive time
-	SMOVTT	counted_divetime_mins,mpr		; ISR-safe 3 byte copy of minutes:2 and seconds
-	movf	mpr+0,W							; dive time minutes, low  byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	mpr+1,W							; dive time minutes, high byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	mpr+2,W							; dive time seconds
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; store dive time (ISR-safe 3 byte copy of minutes:2 and seconds)
+	SMOVTT	counted_divetime_mins,header_buffer+index_divetime
 
 	; store minimum temperature
-	movff	temperature_min+0,WREG			; minimum temperature, low  byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	temperature_min+1,WREG			; minimum temperature, high byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	MOVII	temperature_min,header_buffer+index_min_temp
 
 	; store surface pressure (as used by deco engine)
-	movff	int_I_pres_surface+0,WREG		; surface pressure, low  byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	int_I_pres_surface+1,WREG		; surface pressure, high byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	MOVII	int_I_pres_surface,header_buffer+index_surface_press
 
 	; store desaturation time
-	movff	int_O_desaturation_time+0,WREG	; desaturation time in minutes, low  byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	int_O_desaturation_time+1,WREG	; desaturation time in minutes, high byte
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	MOVII	int_O_desaturation_time,header_buffer+index_desattime
+
+	; store gases / diluents
+	lfsr	FSR1,header_buffer+index_gas1	; load FSR1 with base address of gases / diluents in header
 
  IFDEF _ccr_pscr
 	btfsc	FLAG_ccr_mode					; in CCR mode?
-	bra		end_dive_dil_gaslist			; YES - write diluent gas list
-	btfsc	FLAG_pscr_mode					; in pSCR mode?
-	bra		end_dive_dil_gaslist			; YES - write diluent gas list
+	bra		end_dive_gaslist_diluent		; YES - write diluent gas list
+	btfsc	FLAG_pscr_mode					; NO  - in pSCR mode?
+	bra		end_dive_gaslist_diluent		;       YES - write diluent gas list
+	;bra	end_dive_gaslist_gas			;       NO  - write OC      gas list
  ENDIF
 
-end_dive_oc_gaslist:						; write OC gases
+end_dive_gaslist_gas:						; write OC gases
 	lfsr	FSR0,opt_gas_O2_ratio-.1		; set base address to (opt_gas_O2_ratio - 1) because of pre-increment statement
-	bra		end_dive_gaslist				; write all 5 OC gases
+	bra		end_dive_gaslist_common			; write all 5 OC gases
 
  IFDEF _ccr_pscr
-end_dive_dil_gaslist:						; write diluents
+end_dive_gaslist_diluent:					; write diluents
 	lfsr	FSR0,opt_dil_O2_ratio-.1		; set base address to (opt_dil_O2_ratio - 1) because of pre-increment statement
-	;bra	end_dive_gaslist				; write all 5 diluents
+	;bra	end_dive_gaslist_common			; write all 5 diluents
  ENDIF
 
-end_dive_gaslist:							; helper function for writing gas list entries
+end_dive_gaslist_common:					; helper function for writing gas list entries
 ;
 ;   Memory Map:
 ;   -------------------------
@@ -662,263 +613,205 @@
 	movlw	.5								; 5 gases to store
 	movwf	lo								; use lo as counter
 end_dive_gaslist_loop:
-	movf	PREINC0,W						; increment base address and get O2 ratio into WREG
-	rcall	ghostwrite_byte_header			; store data
+	movff	PREINC0,POSTINC1				; increment FSR0 address and copy O2 ratio to buffer
 	movlw	.10								; offset for H2 ratios
-	movf	PLUSW0,W						; get H2 ratio into WREG
-	rcall	ghostwrite_byte_header			; store data
+	movff	PLUSW0,POSTINC1					; copy H2 ratio to buffer
 	movlw	.30								; offset for change depths
-	movf	PLUSW0,W						; get change depth into WREG
-	rcall	ghostwrite_byte_header			; store data
+	movff	PLUSW0,POSTINC1					; copy change depth to buffer
 	movlw	.20								; offset for types
-	movf	PLUSW0,W						; get type into WREG
-	rcall	ghostwrite_byte_header			; store data
+	movff	PLUSW0,POSTINC1					; copy type to buffer
 	decfsz	lo								; decrement counter, did it became 0 ?
 	bra		end_dive_gaslist_loop			; NO  - loop
-	;bra	end_dive_oc_cc_common			; YES - done
 
-end_dive_oc_cc_common:
-	movlw	softwareversion_x				; get firmware version X (major)
-	rcall	ghostwrite_byte_header			; store data
-	movlw	softwareversion_y				; get firmware version Y (minor)
-	rcall	ghostwrite_byte_header			; store data
+	; store major firmware version
+	movlw	fw_version_major
+	MOVCC	WREG,header_buffer+index_firmware+0
+
+	; store minor firmware version
+	movlw	fw_version_minor
+	MOVCC	WREG,header_buffer+index_firmware+1
 
 	; store battery voltage
-	movf	batt_voltage+0,W				; get battery voltage, low  byte
-	rcall	ghostwrite_byte_header			; store data
-	movf	batt_voltage+1,W				; get battery voltage, high byte
-	rcall	ghostwrite_byte_header			; store data
+	MOVII	batt_voltage,header_buffer+index_battery_voltage
 
 	; store sampling rate
-	movf	sampling_rate,W					; get sampling rate
-	rcall	ghostwrite_byte_header			; store data
+	MOVCC	sampling_rate,header_buffer+index_samplingrate
 
 	; store CNS at beginning of dive
-	movf	CNS_start+0,W					; get CNS at start of dive, low  byte
-	rcall	ghostwrite_byte_header			; store data
-	movf	CNS_start+1,W					; get CNS at start of dive, high byte
-	rcall	ghostwrite_byte_header			; store data
+	MOVII	CNS_start,header_buffer+index_cns_start
 
-	; store gradient factors
-	movff	supersat_start,WREG				; get supersaturation at start of dive
-	rcall	ghostwrite_byte_header			; store data
-	movff	int_O_lead_supersat+0,WREG		; get supersaturation at end   of dive
-	rcall	ghostwrite_byte_header			; store data
+	; store supersaturations
+	MOVCC	supersat_start,       header_buffer+index_supersat_start
+	MOVCC	int_O_lead_supersat+0,header_buffer+index_supersat_end		; low byte only needed
 
 	; store logbook offset
-	call	do_logoffset_common_read		; read into mpr:2
-	movf	mpr+0,W
-	rcall	ghostwrite_byte_header			; store data
-	movf	mpr+1,W
-	rcall	ghostwrite_byte_header			; store data
+	call	eeprom_log_offset_read
+	MOVII	mpr,header_buffer+index_logoffset
+
+	; increment log offset
+	rcall	increment_log_offset
 
-	; store battery info at Byte 59
-	movf	batt_percent,W					; 0-100%
-	rcall	ghostwrite_byte_header			; store data
+	; store battery level
+	MOVCC	batt_percent,header_buffer+index_batt_percent
 
+ IFDEF _ccr_pscr
 	; store setpoints
- IFDEF _ccr_pscr
 	lfsr	FSR0,opt_setpoint_cbar			; base address of ppO2 values
 	lfsr	FSR1,opt_setpoint_change		; base address of change depths
- ENDIF
-	movlw	.5								; 5 setpoints to be stored
+	lfsr	FSR2,header_buffer+index_sp1	; base address of setpoint data in header buffer
+	movlw	.5								; 5 setpoints (ppo2, depth) to be stored
 	movwf	lo								; use lo as counter
 end_dive_sp_loop:
- IFDEF _ccr_pscr
-	movf	POSTINC0,W						; get ppO2 value
- ELSE
-	clrf	WREG
- ENDIF
-	rcall	ghostwrite_byte_header			; store data
- IFDEF _ccr_pscr
-	movf	POSTINC1,W						; get change depth
- ELSE
-	clrf	WREG
- ENDIF
-	rcall	ghostwrite_byte_header			; store data
+	movff	POSTINC0,POSTINC2				; copy ppO2 value
+	movff	POSTINC1,POSTINC2				; copy change depth
 	decfsz	lo								; decrement counter, did it became 0 ?
 	bra		end_dive_sp_loop				; NO  - loop
+ ELSE
+	; just leave the zero bytes written during header initialization in place
+ ENDIF
 
 	; store salinity
-	movff	opt_salinity,WREG				; get salinity (0-4%)
-	rcall	ghostwrite_byte_header			; store data
+	MOVCC	opt_salinity,header_buffer+index_salinity
 
 	; store CNS at end of dive
-	movff	int_O_CNS_current+0,WREG		; get current CNS, low  byte
-	rcall	ghostwrite_byte_header			; store data
-	movff	int_O_CNS_current+1,WREG		; get current CNS, high byte
-	bcf		WREG,int_warning_flag			; clear warning   flag
-	bcf		WREG,int_attention_flag			; clear attention flag
-	rcall	ghostwrite_byte_header			; store data
+	MOVII	int_O_CNS_current,mpr			; get CNS into mpr
+	bcf		mpr+1,int_warning_flag			; clear warning   flag
+	bcf		mpr+1,int_attention_flag		; clear attention flag
+	MOVII	mpr,header_buffer+index_cns_end	; store CNS
 
 	; store average depth
-	movff	pressure_rel_avg_total+0,WREG	; get total dive average depth, low  byte
-	rcall	ghostwrite_byte_header			; store data
-	movff	pressure_rel_avg_total+1,WREG	; get total dive average depth, high byte
-	rcall	ghostwrite_byte_header			; store data
+	MOVII	lastdive_avgdepth,header_buffer+index_avr_depth
+
+	; store total dive time (ISR-safe 2 byte copy)
+	SMOVII	total_divetime_secs,header_buffer+index_total_seconds
 
-	; store total dive time
-	SMOVII	total_divetime_secs,mpr			; ISR-safe 2 byte copy of the total dive time
-	movff	mpr+0,WREG						; total dive time, low  byte
-	rcall	ghostwrite_byte_header			; store data
-	movff	mpr+1,WREG						; total dive time, high byte
-	rcall	ghostwrite_byte_header			; store data
+	; store GF low/high or saturation/desaturation multiplier
+	movff	char_I_model,WREG				; get deco model
+	xorlw	.1								; deco model = ZH-L16-GF ?
+	bz		end_dive_gf						; YES - store GFs
+	;bnz	end_dive_sat					; NO  - store sat/desat
 
-	; store GF low or saturation multiplier
-	movff	char_I_GF_Low_percentage,WREG	; get GF_lo
-	movff	char_I_deco_model,lo
-	decfsz	lo,F							; skip next line if char_I_deco_model == 1
-	movff	char_I_saturation_multiplier,WREG ; get saturation multiplier
-	rcall	ghostwrite_byte_header			; store data
+end_dive_sat:
+	movff	char_I_saturation_multiplier,  header_buffer+index_factor_sat_desat+0	; saturation  multiplier
+	movff	char_I_desaturation_multiplier,header_buffer+index_factor_sat_desat+1	; desaturation multiplier
+	bra		end_dive_sat_gf_done													; continue
 
-	; store GF high or desaturation multiplier
-	movff	char_I_GF_High_percentage,WREG	; get GF_hi
-	movff	char_I_deco_model,lo
-	decfsz	lo,F							; jump over next line if char_I_deco_model == 1
-	movff	char_I_desaturation_multiplier,WREG ; get desaturation multiplier
-	rcall	ghostwrite_byte_header			; store data
+end_dive_gf:
+	movff	char_I_GF_Low_percentage,      header_buffer+index_gf_lo_hi+0			; GF low
+	movff	char_I_GF_High_percentage,     header_buffer+index_gf_lo_hi+1			; GF high
+	;bra	end_dive_sat_gf_done													; continue
 
+end_dive_sat_gf_done:
 	; store deco model
-	movff	char_I_deco_model,WREG			; get deco model (0 = ZH-L16, 1 = ZH-L16-GF)
-	rcall	ghostwrite_byte_header			; store data
+	MOVCC	char_I_model,header_buffer+index_decomodel
 
 	; store total dive number
-	read_int_eeprom .2						; get total dive counter, low
-	movf	EEDATA,W						; ...
-	rcall	ghostwrite_byte_header			; store data
-	read_int_eeprom .3						; get total dive counter, high
-	movf	EEDATA,W						; ...
-	rcall	ghostwrite_byte_header			; store data
+	call	eeprom_total_dives_read
+	MOVII	mpr,header_buffer+index_total_dives
 
-	; store deco mode
-	movff	opt_dive_mode,WREG				; get deco mode (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR)
-	rcall	ghostwrite_byte_header			; store data
+	; store dive mode
+	MOVCC	opt_dive_mode,header_buffer+index_divemode
 
-	; store tissue data - N2 chars
-	movlw	.16
-	movwf	lo
-	lfsr	FSR1,char_O_tissue_pres_N2
-end_dive_store_tissues_N2:
-	movf	POSTINC1,W
-	bcf		WREG,7							; clear flag bit for on-gassing/off-gassing
-	rcall	ghostwrite_byte_header			; store data
-	decfsz	lo,F
-	bra		end_dive_store_tissues_N2		; NO
+	; store tissue data - total tissue pressure
+	lfsr	FSR1,char_O_tissue_pressure					; load base address of total tissue pressures (chars)
+	lfsr	FSR2,header_buffer+index_tissue_pres_total	; load corresponding base address in header
+	bsf		aux_flag									; clear bit 7 (on-/off-gassing flag bit)
+	movlw	.16											; 16 tissues to copy
+	rcall	copy_tissuepres_to_header					; store the tissue pressures
 
 	; store tissue data - N2 floats
-	movlw	.64
-	movwf	lo
-	lfsr	FSR1,0x700						; pres_tissue_N2+0 ; 16*4 Byte Float = 64 Bytes
-end_dive_store_tissues_N2_2:
-	movf	POSTINC1,W
-	rcall	ghostwrite_byte_header			; store data
-	decfsz	lo,F
-	bra		end_dive_store_tissues_N2_2		; NO
+	lfsr	FSR1,0x700									; load base address of N2 tissue pressures (floats)
+	;lfsr	FSR2,header_buffer+index_tissue_pres_N2		; load corresponding base address in header
+	bcf		aux_flag									; do not touch bit 7
+	movlw	.64											; 16 tissue x 4 byte/tissue to copy
+	rcall	copy_tissuepres_to_header					; store the tissue pressures
 
-	; store tissue data - He chars
-	movlw	.16
-	movwf	lo
-	lfsr	FSR1,char_O_tissue_pres_He
-end_dive_store_tissues_He:
-	movf	POSTINC1,W
-	bcf		WREG,7							; clear flag bit for on-gassing/off-gassing
-	rcall	ghostwrite_byte_header			; store data
-	decfsz	lo,F
-	bra		end_dive_store_tissues_He		; NO
+	; store tissue data - tissue supersaturations
+	lfsr	FSR1,char_O_tissue_saturation				; load base address of tissue saturations (chars)
+	;lfsr	FSR2,header_buffer+index_tissue_supersat	; load corresponding base address in header
+	bsf		aux_flag									; clear bit 7 (on-/off-gassing flag bit)
+	movlw	.16											; 16 tissues to copy
+	rcall	copy_tissuepres_to_header					; store the tissue pressures
 
 	; store tissue data - He floats
-	movlw	.64
-	movwf	lo
-	lfsr	FSR1,0x740						; pres_tissue_He+0 ; 16*4 Byte Float = 64 Bytes
-end_dive_store_tissues_He_2:
-	movf	POSTINC1,W
-	rcall	ghostwrite_byte_header 			; store data
-	decfsz	lo,F
-	bra		end_dive_store_tissues_He_2		; NO
+	lfsr	FSR1,0x740									; load base address of He tissue pressures (floats)
+	;lfsr	FSR2,header_buffer+index_tissue_pres_He		; load corresponding base address in header
+	bcf		aux_flag									; do not touch bit 7
+	movlw	.64											; 16 tissue x 4 byte/tissue to copy
+	rcall	copy_tissuepres_to_header					; store the tissue pressures
 
 	; store last stop depth
-	movff	char_I_depth_last_deco,WREG		; get last stop depth [m]
-	rcall	ghostwrite_byte_header			; store data
+	MOVCC	char_I_last_stop_depth,header_buffer+index_last_stop
 
 	; store deco distance
-	clrf	WREG							; assumed deco distance - disposed, hard-coded to zero
-	rcall	ghostwrite_byte_header			; store data
+	; -> the deco distance concept is disposed of, so just store a hard-coded zero
+	; --> so just leave the zero written during header initialization in place
+	;clrf	WREG
+	;MOVCC	WREG,header_buffer+index_decodistance
 
  IFDEF _external_sensor
-	; store last HUD data
-	SMOVTT	hud_status_byte,mpr				; ISR-safe 3 byte copy of last HUD status (1 byte) and battery voltage (2 byte)
-	movff	mpr+1,WREG						; HUD battery value, low  byte
-	rcall	ghostwrite_byte_header			; store data
-	movff	mpr+2,WREG						; HUD battery value, high byte
-	rcall	ghostwrite_byte_header			; store data
-	movff	mpr+0,WREG						; HUD status
-	rcall	ghostwrite_byte_header			; store data
+	; store last HUD data (ISR-safe 3 byte copy)
+	SMOVTT	hud_status_byte,header_buffer+index_hud_data
  ELSE
-	; store dummy data to keep format
-	clrf	WREG
-	rcall	ghostwrite_byte_header			; store null byte
-	clrf	WREG
-	rcall	ghostwrite_byte_header			; store null byte
-	clrf	WREG
-	rcall	ghostwrite_byte_header			; store null byte
+	; just leave the zero bytes in place
  ENDIF
 
-	; store battery gauge registers [nAs]
-	SMOVSS	battery_gauge,mpr				; ISR-safe 6 byte copy of battery gauge value
-	movf	mpr+0,W							; get byte 0
-	rcall	ghostwrite_byte_header			; store data
-	movf	mpr+1,W							; get byte 1
-	rcall	ghostwrite_byte_header			; store data
-	movf	mpr+2,W							; get byte 2
-	rcall	ghostwrite_byte_header			; store data
-	movf	mpr+3,W							; get byte 3
-	rcall	ghostwrite_byte_header			; store data
-	movf	mpr+4,W							; get byte 4
-	rcall	ghostwrite_byte_header			; store data
-	movf	mpr+5,W							; get byte 5
-	rcall	ghostwrite_byte_header			; store data
+	; store battery gauge registers [nAs] (ISR-safe 6 byte copy)
+	SMOVSS	battery_gauge,header_buffer+index_battery_gauge
 
 	; write header stop code
-	movlw	0xFB
-	rcall	ghostwrite_byte_header			; store data
-	movlw	0xFB
-	rcall	ghostwrite_byte_header			; store data
+	MOVLI	0xFBFB,mpr
+	MOVII	mpr,header_buffer+index_header_stop
+
+	; compute start address of header data
+	call	eeprom_total_dives_read			; read total number of dives
+	decf	mpr+0,W							; compute index from low(total number of dives)
+	call	log_header_addr_by_index		; compute start address (returned in mpr:3)
 
-	call	divemode_store_statistics		; store/update statistics for this unit
+	; erase the FLASH 4 kB block where the header will be stored
+	MOVTT	mpr,ext_flash_address
+	call	ext_flash_erase_4kB
+
+	; write the header to the FLASH
+	FLASH_RR_WRITE	header_buffer,mpr,.256
+
+ghostwriter_end_dive_cleanup:
+	call	eeprom_deco_data_write			; update deco data in EEPROM
 	bsf		reset_surface_interval			; request ISR to reset the surface interval timer
 
 ghostwriter_end_dive_common:
-; Update ext_flash_log_pointer into EEPROM
-	clrf	EEADRH
-	movff	ext_flash_log_pointer+0,EEDATA
-	write_int_eeprom .4
-	movff	ext_flash_log_pointer+1,EEDATA
-	write_int_eeprom .5
-	movff	ext_flash_log_pointer+2,EEDATA
-	write_int_eeprom .6
+	; memorize current ext_flash_log_pointer in EEPROM
+	EEPROM_TT_WRITE ext_flash_log_pointer,eeprom_log_pointer
 
-; In DEBUG compile, write simulated dives to logbook and keep tissue pressures from simulation
-	btfss	simulatormode						; in simulator mode, i.e. need to restore tissue pressures?
-	bra		ghostwriter_end_dive_common_1		; NO
-	bcf		simulatormode						; YES - clear mode flag
+	; terminate simulator mode
+	btfss	simulatormode					; in simulator mode, i.e. need to restore tissue pressures?
+	bra		ghostwriter_end_dive_common_1	; NO  - continue
+	bcf		simulatormode					; YES - end simulator mode
+	bcf		sensor_override_request			;     - request ISR to terminate the simulator mode
+	btfsc	sensor_override_active			;     - has the ISR confirmed termination of simulator mode?
+	bra		$-2								;       NO - not yet, loop waiting for the ISR
+
  ifndef _DEBUG
-	call	deco_pull_tissues_from_vault		;     - restore tissue pressures (C-code)
-	banksel	common								;     - back to bank common
+	; in DEBUG compile, keep tissue pressures from simulated dives
+	call	deco_pull_tissues_from_vault	;     - restore tissue pressures (C-code)
+	banksel	common							;     - back to bank common
  endif
 
 ghostwriter_end_dive_common_1:
-	bsf		reset_timebase						; request ISR to reset the timebase
-;	btfsc	reset_timebase						; has the ISR confirmed reset of timebase?
-;	bra		$-2									; NO - not yet, loop waiting for the ISR
-	bcf		sensor_override_request				; request ISR to terminate the simulator mode
-	btfsc	sensor_override_active				; has the ISR confirmed termination of simulator mode?
-	bra		$-2									; NO - not yet, loop waiting for the ISR
-	call	update_battery_registers			; update battery registers into EEPROM
+	; restart the timebase
+	bsf		reset_timebase					; request ISR to reset the timebase
+;	btfsc	reset_timebase					; has the ISR confirmed reset of timebase?
+;	bra		$-2								; NO - not yet, loop waiting for the ISR
+
+	; update battery gauge into EEPROM
+	call	eeprom_battery_gauge_write
+
+	; catch-up simulator runtime / calculate deco data for surface mode
 	movff	simulator_time,char_I_dive_interval	; get the simulator runtime, reads 0 if exiting from a real dive
 	call	deco_calc_dive_interval				; catch up with tissue desaturation when exiting from simulator,
 												; else calculates for 2 seconds only when exiting from a real dive,
-												; needed to update CNS, GF and tissue graphics for surface display  (C-code)
-	call	deco_calc_desaturation_time			; calculate desaturation and no-fly/no-altitude time after catch-up (C-code)
+												; needed to update CNS, GF and tissue graphics for surface display.
+	call	deco_calc_desaturation_time			; calculate desaturation and no-fly/no-altitude time after catch-up
 	banksel	common								; back to bank common
 
 	; the last surface pressure sample may have been taken while being submerged a bit already,
@@ -926,182 +819,158 @@
 	; became the surface pressure reference used while this dive.
 	MOVII	pressure_abs_ref,pressure_abs_sampled
 
-	goto	surfloop							; done with post-dive operations, return to surface loop
-
-
-ghostwriter_load_pointer:						; load ext_flash_address:3 from EEPROM .4-.6
-	clrf	EEADRH								; make sure to select EEPROM bank 0
-	read_int_eeprom	.4
-	movff	EEDATA,ext_flash_address+0
-	read_int_eeprom	.5
-	movff	EEDATA,ext_flash_address+1
-	read_int_eeprom	.6
-	movff	EEDATA,ext_flash_address+2
-	return
-
-ghostwriter_short_header_init:					; proceed one page forward
-	clrf	EEDATA
-	write_int_eeprom .4							; ext_flash_address+0 = 0
-	movlw	.16
-	addwf	ext_flash_address+1,F
-	movlw	.0
-	addwfc	ext_flash_address+2,F
-	movlw	0x20
-	cpfseq	ext_flash_address+2					; at address 0x200000?
-	bra		ghostwriter_short_header_init2		; NO
-	clrf	ext_flash_address+2					; YES - rollover to 0x000000
-ghostwriter_short_header_init2:
-	movlw	0xF0
-	andwf	ext_flash_address+1,F				; keep higher nibble, set lower nibble to 0
-
-	movff	ext_flash_address+1,EEDATA
-	write_int_eeprom .5							; write new pointer
-	movff	ext_flash_address+2,EEDATA
-	write_int_eeprom .6							; write new pointer
-	bra		ghostwriter_short_header2			; Done
+	; done with post-dive operations, return to surface loop
+	goto	surfloop
 
 
-	global	ghostwriter_short_header
-ghostwriter_short_header:						; write short header with dive number into profile memory
-	; load pointer for profile storing into RAM (Updated in EEPROM after the dive)
-	rcall	ghostwriter_load_pointer			; load ext_flash_address:3 from EEPROM .4-.6
+;-----------------------------------------------------------------------------
+; helper function for copying tissue pressures
+;
+copy_tissuepres_to_header:
+	movwf	eeprom_loop						; initialize loop counter (EEPROM var used here)
+copy_tissuepres_to_header_loop:
+	movf	POSTINC1,W						; copy tissue pressure to WREG
+	btfsc	aux_flag						; shall clear bit 7 ?
+	bcf		WREG,7							; YES - clear bit for on-gassing/off-gassing
+	movwf	POSTINC2						; copy WREG to header buffer
+	decfsz	eeprom_loop,F					; decrement loop counter, all done?
+	bra		copy_tissuepres_to_header_loop	; NO  - loop
+	return									; YES - done
 
-	; The following code is used to write a clean new dive after the previous hasn't been
-	; stored correctly. e.g. after a battery fail during the dive
-	call	ext_flash_byte_read_plus_0x20		; into ext_flash_rw
-	incfsz	ext_flash_rw,F
-	bra		ghostwriter_short_header_init		; not 0xFF -> init page
-	call	ext_flash_byte_read_plus_0x20		; into ext_flash_rw
-	incfsz	ext_flash_rw,F
-	bra		ghostwriter_short_header_init		; not 0xFF -> init page
+;-----------------------------------------------------------------------------
+; load ext_flash_address from EEPROM
+;
+ghostwriter_load_pointer:
+	EEPROM_TT_READ	eeprom_log_pointer,ext_flash_address
+	return
 
-ghostwriter_short_header2:
-	; All ok, reload the pointer and start
-	rcall	ghostwriter_load_pointer			; load ext_flash_address:3 from EEPROM .4-.6
+;-----------------------------------------------------------------------------
+; write short header with dive number into profile memory
+;
+	global	ghostwriter_short_header
+ghostwriter_short_header:
+	; get pointer for profile storing
+	rcall	ghostwriter_load_pointer
+
+	; the following code is used to write a clean new dive after the previous
+	; hasn't been stored correctly. e.g. after a power loss during the dive
+	FLASH_II_READ_0x20 mpr					; read first two bytes
+	incfsz	mpr+0,F							; is 1st byte = 0xFF ?
+	bra		ghostwriter_short_header_init	; NO  - initialize page
+	incfsz	mpr+1,F							;     - is 2nd byte = 0xFF ?
+	bra		ghostwriter_short_header_init	;       NO  - initialize page
+	bra		ghostwriter_short_header_2		;       YES - page is clean, can continue
 
-	; Clear dive length counter
-	clrf	ext_flash_dive_counter+0
-	clrf	ext_flash_dive_counter+1
-	clrf	ext_flash_dive_counter+2
+ghostwriter_short_header_init:
+	clrf	ext_flash_address+0				; low  byte: set to zero
+	movlw	0xF0							; high byte: keep higher nibble, set lower nibble to zero
+	andwf	ext_flash_address+1,F			; ...
+	movlw	.16								; increment ext_flash_address to next multiple of 16*256
+	addwf	ext_flash_address+1,F			; ...
+	movlw	.0								; ...
+	addwfc	ext_flash_address+2,F			; ...
+	movlw	0x20							; at address 0x200000 ?
+	cpfseq	ext_flash_address+2				; ...
+	bra		ghostwriter_short_header_init_2	; NO  - continue
+	clrf	ext_flash_address+2				; YES - rollover to 0x000000
+
+ghostwriter_short_header_init_2:
+	; update pointer in EEPROM
+	EEPROM_TT_WRITE ext_flash_address,eeprom_log_pointer
 
-	; Write short header with dive number into profile memory
-	movlw	0xFA
-	rcall	ghostwrite_byte_profile				; WREG -> profile in ext. flash
-	movlw	0xFA
-	rcall	ghostwrite_byte_profile				; WREG -> profile in ext. flash
-	; Load total number of dives (low byte only)
-	read_int_eeprom .2
-	incf	EEDATA,W							; +1
-	rcall	ghostwrite_byte_profile				; WREG -> profile in ext. flash
-	read_int_eeprom .3
-	movf	EEDATA,W
-	rcall	ghostwrite_byte_profile				; WREG -> profile in ext. flash
-	movlw	0xFA
-	rcall	ghostwrite_byte_profile				; WREG -> profile in ext. flash
-	movlw	0xFA
-	rcall	ghostwrite_byte_profile				; WREG -> profile in ext. flash
+ghostwriter_short_header_2:
+	; reload the pointer (required after above checks)
+	rcall	ghostwriter_load_pointer		; reload ext_flash_address from EEPROM
+
+	; clear dive length counter
+	CLRT	ext_flash_length_counter
+
+	; write short start header with dive number into profile memory
+	FLASH_LIT_PROFILE 0xFA					; 1st byte
+	FLASH_LIT_PROFILE 0xFA					; 2nd byte
 
-	; Keep room for dive length ext_flash_dive_counter:3 (stored at the end of the dive)
+	; load total number of dives
+	call	eeprom_total_dives_read			; read total number of dives
+	incf	mpr+0,F							; increment low byte + 1
+	FLASH_II_PROFILE mpr
+
+	; close short header
+	FLASH_LIT_PROFILE 0xFA					; 1st byte
+	FLASH_LIT_PROFILE 0xFA					; 2nd byte
+
+	; Keep room for dive length ext_flash_length_counter:3 (stored at the end of the dive)
 	; Writing 0xFF three times here is mandatory
 	; - 0xFF can be overwritten after the dive
-	; - ghostwrite_byte_profile takes care of 4kB page switching
+	; - write_byte_ext_flash_plus_prof takes care of 4kB page switching
 	; - fixes an issue when we are at exactly 0xXXX000 here...
 
-	movlw	0xFF
-	call	write_byte_ext_flash_plus_nocnt		; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase)
-	movlw	0xFF
-	call	write_byte_ext_flash_plus_nocnt		; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase)
-	movlw	0xFF
-	call	write_byte_ext_flash_plus_nocnt		; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase)
+	setf	WREG								; write 0xFF
+	call	write_byte_ext_flash_plus_nocnt		; write to profile without ext_flash_length_counter increase
+	setf	WREG								; write 0xFF
+	call	write_byte_ext_flash_plus_nocnt		; write to profile without ext_flash_length_counter increase
+	setf	WREG								; write 0xFF
+	call	write_byte_ext_flash_plus_nocnt		; write to profile without ext_flash_length_counter increase
 
 	; store sizes and sampling rates of recording datasets
 
-	movf	sampling_rate,W					; get general sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	FLASH_CC_PROFILE  sampling_rate				; get general sampling rate
 
-	movlw	.7								; get number of additional datasets
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	FLASH_LIT_PROFILE .7						; number of additional datasets
 
-	movlw	.0								; type: temperature
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	infolength_temperature			; get size of recording data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	div_temperature					; get sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	FLASH_LIT_PROFILE .0						; type: temperature
+	FLASH_LIT_PROFILE infolength_temperature	; get size of recording data
+	FLASH_LIT_PROFILE div_temperature			; get sampling rate
 
-	movlw	.1								; type: +++
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	infolength_deco					; get size of recording data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	div_deco						; get sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
 
-	movlw	.2								; type: saturation
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	infolength_gf					; get size of recording data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	div_gf							; get sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	FLASH_LIT_PROFILE .1						; type: +++
+	FLASH_LIT_PROFILE infolength_deco			; get size of recording data
+	FLASH_LIT_PROFILE div_deco					; get sampling rate
+
+	FLASH_LIT_PROFILE .2						; type: saturation
+	FLASH_LIT_PROFILE infolength_gf				; get size of recording data
+	FLASH_LIT_PROFILE div_gf					; get sampling rate
 
-	movlw	.3								; type: ppO2 sensor data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	infolength_ppo2_sensors			; get size of recording data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	.0								; default to no ppO2 data
-	btfsc	FLAG_ccr_mode					; in CCR mode?
-	movlw	div_ppo2_sensors				; YES - get sampling rate
-	btfsc	FLAG_pscr_mode					; in pSCR mode?
-	movlw	div_ppo2_sensors				; YES - get sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	FLASH_LIT_PROFILE .3						; type: ppO2 sensor data
+	FLASH_LIT_PROFILE infolength_ppo2_sensors	; get size of recording data
+	movlw	.0									; default to no ppO2 data
+ IFDEF _external_sensor
+	btfsc	FLAG_ccr_mode						; in CCR mode?
+	movlw	div_ppo2_sensors					; YES - get sampling rate
+	btfsc	FLAG_pscr_mode						; in pSCR mode?
+	movlw	div_ppo2_sensors					; YES - get sampling rate
+ ENDIF
+	FLASH_WREG_PROFILE							; WREG -> profile in ext. flash
 
-	movlw	.4								; type: deco plan (stop times)
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	infolength_decoplan				; get size of recording data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	div_decoplan					; get sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	FLASH_LIT_PROFILE .4						; type: deco plan (stop times)
+	FLASH_LIT_PROFILE infolength_decoplan		; get size of recording data
+	FLASH_LIT_PROFILE div_decoplan				; get sampling rate
+
+	FLASH_LIT_PROFILE .5						; type: CNS
+	FLASH_LIT_PROFILE infolength_cns			; get size of recording data
+	FLASH_LIT_PROFILE div_cns					; get sampling rate
 
-	movlw	.5								; type: CNS
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	infolength_cns					; get size of recording data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	div_cns							; get sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-
-	movlw	.6								; type: tank pressure
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	infolength_tank					; get size of recording data
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	.0								; default to no tank pressure data
-	btfsc	tr_functions_activated			; TR functions activated?
-	movlw	div_tank						; YES - get sampling rate
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	FLASH_LIT_PROFILE .6						; type: tank pressure
+	FLASH_LIT_PROFILE infolength_tank			; get size of recording data
+	movlw	.0									; default to no tank pressure data
+ IFDEF _rx_functions
+	btfsc	tr_functions_activated				; TR functions activated?
+	movlw	div_tank							; YES - get sampling rate
+ ENDIF
+	FLASH_WREG_PROFILE							; WREG -> profile in ext. flash
 
 	return
 
-
-divemode_store_statistics:					; store/update statistics for this unit
-	call	vault_decodata_into_eeprom		; update deco data
-	call	do_logoffset_common_read		; read current logbook offset into mpr
-
-	tstfsz	lo								; offset, low  byte = 0 ?
-	bra		change_logbook_offset1			; NO - adjust offset
-	tstfsz	hi								; offset, high byte = 0 ?
-	bra		change_logbook_offset1			; NO - adjust offset
-	bra		change_logbook_offset2			; YES to both - skip offset routine
-
-change_logbook_offset1:
-	INCI	mpr								; increment offset
-	call	do_logoffset_common_write		; write incremented offset as the new offset
-
-change_logbook_offset2:
-	; ISR-safe 3 byte copy of minutes:2 and seconds to last dive duration
-	SMOVTT	counted_divetime_mins,lastdive_duration
-
-	; 2 byte copies of max and avg relative pressures to last dive data
-	MOVII	pressure_rel_max_cached,lastdive_maxdepth
-	MOVII	pressure_rel_avg_total, lastdive_avgdepth
-
-	return
+;-----------------------------------------------------------------------------
+; increment log offset
+;
+increment_log_offset:
+	call	eeprom_log_offset_read			; read current logbook offset into mpr
+	movf	mpr+0,W							; get               low  byte
+	iorwf	mpr+1,W							; inclusive-or with high byte, result zero?
+	bz		increment_log_offset_1			; YES - skip offset correction
+	INCI	mpr								; NO  - increment offset
+	call	eeprom_log_offset_write			;     - store incremented offset as new offset
+increment_log_offset_1:
+	return									; done
 
 	END