diff src/ghostwriter.asm @ 623:c40025d8e750

3.03 beta released
author heinrichsweikamp
date Mon, 03 Jun 2019 14:01:48 +0200
parents ca4556fb60b9
children cd58f7fc86db
line wrap: on
line diff
--- a/src/ghostwriter.asm	Wed Apr 10 10:51:07 2019 +0200
+++ b/src/ghostwriter.asm	Mon Jun 03 14:01:48 2019 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File ghostwriter.asm							REFACTORED VERSION V2.99a
+;   File ghostwriter.asm                      combined next generation V3.03.1
 ;
 ;   Ghostwriter (Log profile recorder)
 ;
@@ -15,20 +15,20 @@
 #include "surfmode.inc"
 #include "eeprom_rs232.inc"
 #include "strings.inc"
-#include "isr.inc"
 #include "tft_outputs.inc"
 #include "divemode.inc"
 #include "rtc.inc"
 
+
 	extern	deco_pull_tissues_from_vault
 
 
-	;---- Private local variables -------------------------------------------------
+	; private local Variables
 
 	CBLOCK	local3						; max size is 16 Byte !!!
 		divisor_temperature				; divisor used to time the sampling of dive data
 		divisor_deco					; divisor used to time the sampling of dive data
-		divisor_gf						; divisor used to time the sampling of dive data
+		divisor_supersat				; divisor used to time the sampling of dive data
 		divisor_ppo2_sensors			; divisor used to time the sampling of dive data
 		divisor_decoplan				; divisor used to time the sampling of dive data
 		divisor_cns						; divisor used to time the sampling of dive data
@@ -37,33 +37,35 @@
 	ENDC								; used: 8 byte, remaining: 8 byte
 
 
-ghostwriter		CODE
+ghostwriter	CODE
 
 ;=============================================================================
 
 
 	global	init_recording_params		; initialize profile recording parameters
 init_recording_params:
-	movff	samplingrate,samplesecs_value; to avoid EEPROM access in the ISR
-	movlw	div_temperature
-	movwf	divisor_temperature			; load divisors for profile storage
-	movlw	div_deco
-	movwf	divisor_deco
+	movlw	div_temperature				; get divisor for temperature storage
+	movwf	divisor_temperature			; initialize divisor
+
+	movlw	div_deco					; ...
+	movwf	divisor_deco				; ...
+
 	movlw	div_gf
-	movwf	divisor_gf
+	movwf	divisor_supersat
+
+	movlw	div_decoplan
+	movwf	divisor_decoplan
+
+	movlw	div_cns
+	movwf	divisor_cns
+
+	movlw	div_tank
+	movwf	divisor_tank
+
+ IFDEF _external_sensor
 	movlw	div_ppo2_sensors
 	movwf	divisor_ppo2_sensors
-	movlw	div_decoplan
-	movwf	divisor_decoplan
-	movlw	div_cns
-	movwf	divisor_cns
-	movlw	div_tank
-	movwf	divisor_tank
-	btfss	FLAG_apnoe_mode				; in Apnoe mode?
-	bra		init_recording_params_1		; NO
-	movlw	samplingrate_apnoe			; YES - overwrite some parameters in Apnoe mode
-	movwf	samplesecs_value			;       to avoid EEPROM access in the ISR
-init_recording_params_1:
+
 	btfsc	FLAG_ccr_mode				; in CCR mode?
 	bra		init_recording_params_2		; YES
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
@@ -71,116 +73,127 @@
 	; in all modes but CCR and pSCR, disable ppO2 logging
 	movlw	.0
 	movwf	divisor_ppo2_sensors
+ ENDIF
+
 init_recording_params_2:
 	return
 
 
 	global	store_dive_data
 store_dive_data:
-	bcf		store_sample				; clear flag
+	bcf		trigger_sample_divedata		; clear flag
 
-	ifndef __DEBUG
-		btfsc	simulatormode_active	; are we in simulator mode?
-		return							; YES - discard everything
-	endif
+ ifndef _DEBUG
+	btfsc	sensor_override_active		; in simulator mode?
+	return								; YES - no dive data stored in simulator mode
+ endif
 
-	btfsc	FLAG_apnoe_mode				; in Apnoe mode?
-	return								; YES - discard everything
+	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?
+	return								;       NO  - done
 
-	SAFE_2BYTE_COPY rel_pressure, lo
-	movf	lo,W						; store depth with every sample
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	movf	hi,W
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
+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
 
 ; First, find out how many bytes will be appended to this sample set
 	clrf	ProfileFlagByte				; clear number of bytes to append
 
-; Check Extended informations
-	decfsz	divisor_temperature,W		; check divisor
-	bra		check_extended1
-	movlw	infolength_temperature
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
+; 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
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
 check_extended1:
-	decfsz	divisor_deco,W				; check divisor
-	bra		check_extended2
-	movlw	infolength_deco
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
+	decfsz	divisor_deco,W				; check divisor if it will become 0, dump decremented value to WREG
+	bra		check_extended2				; NO  - skip
+	movlw	infolength_deco				; YES - get length of extra data
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
 check_extended2:
-	decfsz	divisor_gf,W				; check divisor
-	bra		check_extended3
-	movlw	infolength_gf
+	decfsz	divisor_supersat,W			; check divisor if it will become 0, dump decremented value to WREG
+	bra		check_extended3				; NO  - skip
+	movlw	infolength_gf				; YES - get length of extra data
 	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
 check_extended3:
-	decfsz	divisor_ppo2_sensors,W		; check divisor
-	bra		check_extended4
-	movlw	infolength_ppo2_sensors
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
+ IFDEF _external_sensor
+	decfsz	divisor_ppo2_sensors,W		; check divisor if it will become 0, dump decremented value to WREG
+	bra		check_extended4				; NO  - skip
+	movlw	infolength_ppo2_sensors		; YES - get length of extra data
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
+ ENDIF
 check_extended4:
-	decfsz	divisor_decoplan,W			; check divisor
-	bra		check_extended5
-	movlw	infolength_decoplan
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
+	decfsz	divisor_decoplan,W			; check divisor if it will become 0, dump decremented value to WREG
+	bra		check_extended5				; NO  - skip
+	movlw	infolength_decoplan			; YES - get length of extra data
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
 check_extended5:
-	decfsz	divisor_cns,W				; check divisor
-	bra		check_extended6
-	movlw	infolength_cns
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
+	decfsz	divisor_cns,W				; check divisor if it will become 0, dump decremented value to WREG
+	bra		check_extended6				; NO  - skip
+	movlw	infolength_cns				; YES - get length of extra data
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
 check_extended6:
-	decfsz	divisor_tank,W				; check divisor
-	bra		check_extended7
-	movlw	infolength_tank
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
+	decfsz	divisor_tank,W				; check divisor if it will become 0, dump decremented value to WREG
+	bra		check_extended7				; NO  - skip
+	movlw	infolength_tank				; YES - get length of extra data
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
 check_extended7:
 
 ; Second, check global event flag
 	btfss	event_occured				; check global event flag
 	bra		store_dive_data3			; no event
 
-	incf	ProfileFlagByte,F			; add one byte (the EventByte1)
+	incf	ProfileFlagByte,F			; add one byte (the event byte 1)
 
-	clrf	EventByte1					; reset EventByte1
-	clrf	EventByte2					; reset EventByte2
+	clrf	event_byte1					; reset event byte 1
+	clrf	event_byte2					; reset event byte 2
 
-	movf	AlarmType,W					; type of Alarm Bit 0-3
-	addwf	EventByte1,F				; copy to EventByte1 Bit 0-3
-	clrf	AlarmType					; reset AlarmType
+	movf	alarm_type,W				; type of alarm Bit 0-3
+	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
-	btfss	gas6_changed				; check flag
-	bra		check_event2
-	movlw	d'2'						; information length
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
-	bsf		EventByte1,4				; also set Flag in EventByte1!
+	btfss	event_gas_change_gas6		; did a change to gas 6 occur?
+	bra		check_event2				; NO
+	movlw	d'2'						; YES - set information length
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
+	bsf		event_byte1,4				;     - set flag in event byte 1
 check_event2:
-	btfss	stored_gas_changed			; check flag
-	bra		check_event3
-	movlw	d'1'						; information length
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
-	bsf		EventByte1,5				; also set Flag in EventByte1!
+	btfss	event_gas_change			; did a gas change occur?
+	bra		check_event3				; NO
+	movlw	d'1'						; YES - set information length
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
+	bsf		event_byte1,5				;     - set flag in event byte 1
 check_event3:
-	btfss	setpoint_changed			; check flag
-	bra		check_event4
-	movlw	d'1'						; information length
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
-	bsf		EventByte1,6				; also set Flag in EventByte1!
+ IFDEF _ccr_pscr
+	btfss	event_SP_change				; did a setpoint change occur?
+	bra		check_event4				; NO
+	movlw	d'1'						; YES - set information length
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
+	bsf		event_byte1,6				;     - set flag in event byte 1
+ ENDIF
 check_event4:
-	btfss	bailoutgas_event			; =1: bailout was selected or a gas change during bailout
+ IFDEF _ccr_pscr
+	btfss	event_bailout				; did a gas change due to bailout occur?
 	bra		check_event5
 	movlw	d'2'						; information length
 	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
-	bsf		EventByte2,0				; set flag in EventByte2!
-	bsf		EventByte1,7				; =1: another EventByte1 is available
+	bsf		event_byte2,0				; set flag in event byte 2
+	bsf		event_byte1,7				; =1: another event byte is available
+ ENDIF
 
 check_event5:
 	; more events?
 
 store_dive_data3:
-	btfsc	EventByte1,7				; =1: Another EventByte1 is available
-	incf	ProfileFlagByte,F			; add one byte (The EventByte2)
+	btfsc	event_byte1,7				; =1: another event byte is available
+	incf	ProfileFlagByte,F			; add one byte (the event byte 2)
 
 	btfsc	event_occured				; check global event flag
-	bsf		ProfileFlagByte,7			; set EventByte1 flag in ProfileFlagByte
+	bsf		ProfileFlagByte,7			; set event byte 1 flag in ProfileFlagByte
 
 	movf	ProfileFlagByte,W			; finally, write ProfileFlagByte
 	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
@@ -189,105 +202,127 @@
 	bra		store_dive_data4			; no event
 
 ; Store the EventByte(s) + additional bytes now
-	movf	EventByte1,W
+	movf	event_byte1,W
 	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-
-	movf	EventByte2,W				; write second event byte...
-	btfsc	EventByte1,7				; =1: another EventByte1 is available
-	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	gas6_changed				; check flag
-	bra		store_dive_data3b
-	movff	char_I_O2_ratio,WREG		; store gas 6 o2 ratio
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	movff	char_I_He_ratio,WREG		; store gas 6 He ratio
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	bcf		gas6_changed				; clear this event
+	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
+ IFDEF _helium
+	movff	char_I_He_ratio,WREG		;     - get gas 6 He ratio
+ ELSE
+	clrf	WREG						;     - He ratio is zero
+ ENDIF
+	rcall	ghostwrite_byte_profile		;     - store it
+	bcf		event_gas_change_gas6		;     - clear event flag
 store_dive_data3b:
-	btfss	stored_gas_changed			; check flag
-	bra		store_dive_data3c
-	movf	active_dil,W				; store active diluent (default, may be overwritten soon)
-	btfsc	FLAG_oc_mode				; in OC mode?
-	movf	active_gas,W				; YES - store active gas
-	btfsc	FLAG_bailout_mode			; in bailout?
-	movf	active_gas,W				; YES - store active OC = bailout gas
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	bcf		stored_gas_changed			; clear this event
+	btfss	event_gas_change			; did a gas change occur?
+	bra		store_dive_data3c			; NO
+ IFDEF _ccr_pscr
+	movf	active_dil,W				; YES - store active diluent (default, may be overwritten soon)
+	btfsc	FLAG_oc_mode				;     - in OC mode?
+	movf	active_gas,W				;       YES - get active gas
+	btfsc	bailout_mode				;     - in bailout?
+ ENDIF
+	movf	active_gas,W				;       YES - get active OC = bailout gas
+	rcall	ghostwrite_byte_profile		;     - store it
+	bcf		event_gas_change			;     - clear event flag
 store_dive_data3c:
-	btfss	setpoint_changed			; check flag
-	bra		store_dive_data3d
-	movff	char_I_const_ppO2,WREG		; store setpoint
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	bcf		setpoint_changed			; clear this event
+ 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
+	bcf		event_SP_change				;     - clear event flag
+ ENDIF
 store_dive_data3d:
-	btfss	bailoutgas_event			; check flag
-	bra		store_dive_data4
-	movff	char_I_O2_ratio,WREG		; store O2 ratio of bailout gas
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	movff	char_I_He_ratio,WREG		; store He ratio of bailout gas
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	bcf		bailoutgas_event			; clear this event
-
+ 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
+ IFDEF _helium
+	movff	char_I_He_ratio,WREG		;     - get He ratio of bailout gas
+ ELSE
+	clrf	WREG						;     - He ratio is zero
+ ENDIF
+	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		; check divisor
-	bra		store_extended1	
-	rcall	store_dive_temperature
+	decfsz	divisor_temperature,F		; time to store a temperature sample ?
+	bra		store_extended1				; NO  - skip
+	rcall	store_dive_temperature		; YES - store data
 store_extended1:
-	decfsz	divisor_deco,F				; check divisor
-	bra		store_extended2	
-	rcall	store_dive_decodata
+	decfsz	divisor_deco,F				; time to store the current deco data?
+	bra		store_extended2				; NO  - skip
+	rcall	store_dive_decodata			; YES - store data
 store_extended2:
-	decfsz	divisor_gf,F				; check divisor
-	bra		store_extended3
-	rcall	store_dive_gf
+	decfsz	divisor_supersat,F			; time to store the current supersaturation ?
+	bra		store_extended3				; NO  - skip
+	rcall	store_dive_supersat			; YES - store data
 store_extended3:
-	decfsz	divisor_ppo2_sensors,F		; check divisor
-	bra		store_extended4
-	rcall	store_dive_ppO2_sensors
+ IFDEF _external_sensor
+	decfsz	divisor_ppo2_sensors,F		; decrement divisor, did it became 0 ?
+	bra		store_extended4				; NO  - skip
+	rcall	store_dive_ppO2_sensors		; YES - store data
+ ENDIF
 store_extended4:
-	decfsz	divisor_decoplan,F			; check divisor
-	bra		store_extended5
-	rcall	store_dive_decoplan
+	decfsz	divisor_decoplan,F			; decrement divisor, did it became 0 ?
+	bra		store_extended5				; NO  - skip
+	rcall	store_dive_decoplan			; YES - store data
 store_extended5:
-	decfsz	divisor_cns,F				; check divisor
-	bra		store_extended6
-	rcall	store_dive_cns
+	decfsz	divisor_cns,F				; decrement divisor, did it became 0 ?
+	bra		store_extended6				; NO  - skip
+	rcall	store_dive_cns				; YES - store data
 store_extended6:
-	decfsz	divisor_tank,F				; check divisor
-	bra		store_extended7
-	rcall	store_dive_tank
+	decfsz	divisor_tank,F				; decrement divisor, did it became 0 ?
+	bra		store_extended7				; NO  - skip
+	rcall	store_dive_tank				; YES - store data
 store_extended7:
 
 ; 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
 	clrf	divisor_deco
-	btfsc	divisor_gf,7
-	clrf	divisor_gf
+
+	btfsc	divisor_supersat,7
+	clrf	divisor_supersat
+
+ IFDEF _external_sensor
 	btfsc	divisor_ppo2_sensors,7
 	clrf	divisor_ppo2_sensors
+ ENDIF
+
 	btfsc	divisor_decoplan,7
 	clrf	divisor_decoplan
+
 	btfsc	divisor_cns,7
 	clrf	divisor_cns
+
 	btfsc	divisor_tank,7
 	clrf	divisor_tank
 
 store_dive_data5:
 	bcf		event_occured				; clear the global event flag
-	clrf	EventByte1					; reset EventByte1
-	clrf	EventByte2					; reset EventByte2
+	clrf	event_byte1					; reset event byte 1
+	clrf	event_byte2					; reset event byte 2
 	return								; done (sample with all informations written to external flash)
 
 store_dive_cns:
-	movff	int_O_CNS_fraction+0,WREG
-	rcall	ghostwrite_byte_profile		; WREG -> profile in ext. flash
-	movff	int_O_CNS_fraction+1,WREG
+	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		; WREG -> profile in ext. flash
+	rcall	ghostwrite_byte_profile		; store it
 	movlw	div_cns
 	movwf	divisor_cns					; reload divisor from CF
 	return
@@ -300,84 +335,92 @@
 
 store_dive_decoplan:
 	; Store the deco plan
-	lfsr	FSR1,char_O_deco_time_for_log+.0
-	movlw	.15
-	movwf	lo
+	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
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	decfsz	lo,F
-	bra		store_dive_decoplan_loop
-	movlw	div_decoplan
-	movwf	divisor_decoplan				; reload divisor from CF
-	return
+	movf	POSTINC1,W						; get a stop time
+	rcall	ghostwrite_byte_profile			; store it
+	decfsz	lo,F							; decrement loop counter, became zero?
+	bra		store_dive_decoplan_loop		; NO  - loop
+	movlw	div_decoplan					; YES - get divisor for deco plan recording
+	movwf	divisor_decoplan				;     - reload timer
+	return									;     - done
+
+;=============================================================================
+
+ IFDEF _external_sensor
 
 store_dive_ppO2_sensors:
-	movf	o2_ppo2_sensor1,W				; Sensor1 ppO2 (in 0.01 bar steps)
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	SAFE_2BYTE_COPY o2_mv_sensor1,lo		; o2_mv_sensor may be modified via ISR during the two writes here...
-	movf	lo,W							; in 0.1 mV steps
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movf	hi,W							; in 0.1 mV steps
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	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
 
-	movf	o2_ppo2_sensor2,W				; Sensor2 ppO2 (in 0.01 bar steps)
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	SAFE_2BYTE_COPY o2_mv_sensor2,lo		; o2_mv_sensor may be modified via ISR during the two writes here...
-	movf	lo,W							; in 0.1 mV steps
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movf	hi,W							; in 0.1 mV steps
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	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
 
-	movf	o2_ppo2_sensor3,W				; Sensor3 ppO2 (in 0.01 bar steps)
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	SAFE_2BYTE_COPY o2_mv_sensor3,lo		; o2_mv_sensor may be modified via ISR during the two writes here...
-	movf	lo,W							; in 0.1 mV steps
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movf	hi,W							; in 0.1 mV steps
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	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
 
 	movlw	div_ppo2_sensors
-	movwf	divisor_ppo2_sensors			; reload divisor
+	movwf	divisor_ppo2_sensors			; reload timer
 	return
 
-store_dive_gf:
-	movff	int_O_gradient_factor+0,WREG	; gradient factor absolute (range is limited to 255, only lower byte used for value)
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+ 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
 	movlw	div_gf
-	movwf	divisor_gf						; reload divisor
+	movwf	divisor_supersat				; reload timer
 	return
 
 store_dive_decodata:
 	; Check if deco stops are necessary
-	movff	char_O_first_deco_depth,WREG	; get ceiling
-	tstfsz	WREG							; ceiling < 0 m (aka in deco) ?
+	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			; WREG -> profile in ext. flash
-	movff	char_O_nullzeit,WREG			; remaining NDL time
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	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_common
 store_dive_decodata_deco:
 	; YES - in deco
-	movff	char_O_first_deco_depth,WREG	; ceiling in m
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movff	char_O_first_deco_time,WREG		; length of first stop in minutes
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	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
 store_dive_decodata_common:
 	movlw	div_deco
-	movwf	divisor_deco					; Reload divisor
+	movwf	divisor_deco					; reload timer
 	return
 
 store_dive_temperature:
-	SAFE_2BYTE_COPY temperature,lo
-	movf	lo,W							; append temperature to current sample!
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movf	hi,W
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	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
 	movlw	div_temperature
-	movwf	divisor_temperature				; reload divisor
+	movwf	divisor_temperature				; reload timer
 	return
 
 ghostwrite_byte_header:
@@ -388,46 +431,46 @@
 	goto	write_byte_ext_flash_plus		; writes byte and increases address with banking at 0x200000
 	; returns...
 
+
 	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 to store in header
+	movff	ext_flash_address+2,ext_flash_log_pointer+2
 
-	movff	menupos3,customview_divemode	; store last custom view
+	; remember last custom view shown in dive mode
+	movff	active_customview,customview_divemode
 
-	btfss	realdive						; dive longer then one minute
+	btfss	divetime_longer_1min			; dive longer then one minute
 	goto	ghostwriter_end_dive_common		; NO - discard everything
 
-; In DEBUG compile, keep all simulated dives in logbook, Desat time, nofly, etc...
-  ifndef __DEBUG
-	btfsc	simulatormode_active			; are we in simulator mode?
-	goto	ghostwriter_end_dive_common_sim	; YES - discard everything
-  endif
+; In DEBUG compile, write simulated dives to logbook
+ ifndef _DEBUG
+	btfsc	sensor_override_active			; are we in simulator mode?
+	goto	ghostwriter_end_dive_common		; YES - discard everything
+ endif
 
-	btfsc	FLAG_apnoe_mode					; in Apnoe mode?
-	goto	ghostwriter_end_dive_common		; YES - discard everything
+	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
 
+ghostwriter_end_dive_1:
 	; Dive finished (and longer than one minute)
 
-	btfsc	FLAG_apnoe_mode					; calc max. depth (again) for very short apnoe dives
-	call	apnoe_calc_maxdepth
-
-	; calculate desaturation time
-	movff	last_surfpressure_30min+0,int_I_pres_surface+0	; pass surface to desat routine !
-	movff	last_surfpressure_30min+1,int_I_pres_surface+1
+	btfsc	FLAG_apnoe_mode					; are we in apnoe mode?
+	call	apnoe_calc_maxdepth				; YES - calculate max. depth (again) for very short apnoe dives
 
-	call	deco_calc_dive_interval_1min	; calculate deco in surface mode
-	call	deco_calc_desaturation_time		; calculate desaturation time
-	banksel	common							; select ram bank 1
+	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
 
-	movlw	0xFD							; .... End-of-Profile bytes
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
-	movlw	0xFD
-	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
+	; 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 to store in header
+	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
@@ -448,9 +491,9 @@
 	movff	EEDATA,lo
 	read_int_eeprom .3
 	movff	EEDATA,hi
-	; +1									; increase total dive counter
-	infsnz	lo,F
-	incf	hi,F
+
+	INCI	mpr								; increase total dive counter
+
 	; Store new number in EEPROM
 	movff	lo,EEDATA
 	write_int_eeprom .2
@@ -476,8 +519,7 @@
 	movf	PRODH,W
 	addwfc	ext_flash_address+2,F
 
-; Now, write header
-
+	; write header start code
 	movlw	0xFA							; header start
 	rcall	ghostwrite_byte_header			; (this call will also delete the 4kB TOC entry first)
 	movlw	0xFA
@@ -502,11 +544,11 @@
 	movf	ext_flash_log_pointer+2,W
 	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
 
-	; write rest of header
+	; write the remainder of the header
 	movlw	logbook_profile_version			; defined in hwos.inc
 	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
 
-	; Store dive length
+	; 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
@@ -514,6 +556,7 @@
 	movf	ext_flash_dive_counter+2,W
 	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
 
+	; 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
@@ -529,62 +572,68 @@
 	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	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
-	bra		end_dive2						; skip normal max. 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
 
 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
+	; 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
 
+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
 
-end_dive2:
-	movf	divemins+0,W					; dive time minutes
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	divemins+1,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	divesecs,W						; dive time seconds
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	minimum_temperature+0,WREG		; minimum temperature
+	; 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
-	movff	minimum_temperature+1,WREG
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	last_surfpressure_30min+0,WREG	; air pressure before dive
+	movf	mpr+1,W							; dive time minutes, high byte
 	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	last_surfpressure_30min+1,WREG
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	int_O_desaturation_time+0,WREG	; desaturation time in minutes
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	int_O_desaturation_time+1,WREG
+	movf	mpr+2,W							; dive time seconds
 	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
 
+	; 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
+
+	; 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
+
+	; 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
+
+ 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
+ ENDIF
 
 end_dive_oc_gaslist:						; 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
 
+ IFDEF _ccr_pscr
 end_dive_dil_gaslist:						; 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
+ ENDIF
 
 end_dive_gaslist:							; helper function for writing gas list entries
 ;
@@ -618,179 +667,214 @@
 	;bra	end_dive_oc_cc_common			; YES - done
 
 end_dive_oc_cc_common:
-	movlw	softwareversion_x				; firmware version
-	rcall	ghostwrite_byte_header
-	movlw	softwareversion_y
-	rcall	ghostwrite_byte_header
-	movf	batt_voltage+0,W				; battery voltage
-	rcall	ghostwrite_byte_header
-	movf	batt_voltage+1,W
-	rcall	ghostwrite_byte_header
+	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
 
-	movf	samplingrate,W					; Sampling rate
-	btfsc	FLAG_apnoe_mode					; Apnoe mode?
-	movlw	samplingrate_apnoe				; Apnoe sampling rate
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; 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
+
+	; store sampling rate
+	movf	sampling_rate,W					; get sampling rate
+	rcall	ghostwrite_byte_header			; store data
+
+	; 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
 
-	; CNS at beginning of dive
-	movff	CNS_start+0,WREG
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	CNS_start+1,WREG
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	; Gradient factor
-	movff	GF_start,WREG
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	int_O_gradient_factor+0,WREG	; value limited to 255, only lower byte in use
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; 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
 
-	; Logbook offset
-	call	do_logoffset_common_read		; Read into lo:hi
-	movf	lo,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	hi,W
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; 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
 
-	; Battery info at Byte 59
-	movf	batt_percent,W					; 0-100
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; store battery info at Byte 59
+	movf	batt_percent,W					; 0-100%
+	rcall	ghostwrite_byte_header			; store data
 
-	; Store the setpoints
-	lfsr	FSR0,char_I_setpoint_cbar		; base address of ppO2 values
-	lfsr	FSR1,char_I_setpoint_change		; base address of change depths
-	movlw	.5								; 5 setpoints to store
+	; 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
 	movwf	lo								; use lo as counter
 end_dive_sp_loop:
-	movf	POSTINC0,W						; get   ppO2 value
-	rcall	ghostwrite_byte_header			; store ppO2 value
-	movf	POSTINC1,W						; get   change depth
-	rcall	ghostwrite_byte_header			; store change depth
+ 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
 	decfsz	lo								; decrement counter, did it became 0 ?
 	bra		end_dive_sp_loop				; NO  - loop
 
-	; Store further data
-	movff	opt_salinity,WREG				; salinity (0-4%)
-	rcall	ghostwrite_byte_header			; store salinity
+	; store salinity
+	movff	opt_salinity,WREG				; get salinity (0-4%)
+	rcall	ghostwrite_byte_header			; store data
 
-	movff	int_O_CNS_fraction+0,WREG		; CNS value, low  byte
-	rcall	ghostwrite_byte_header			; store CNS%
-	movff	int_O_CNS_fraction+1,WREG		; CNS value, high byte
+	; 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 CNS%
+	rcall	ghostwrite_byte_header			; store data
 
-	movff	avg_rel_pressure_total+0,WREG	; average depth
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	avg_rel_pressure_total+1,WREG	; average depth
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; 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
 
-	movff	total_divetime_seconds+0,WREG	; total dive time (regardless of start_dive_threshold)
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	total_divetime_seconds+1,WREG	; total dive time (regardless of start_dive_threshold)
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; 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
 
-	movff	char_I_GF_Low_percentage,WREG	; GF_lo
+	; 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
+
+	; 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_saturation_multiplier,WREG ; saturation multiplier
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	movff	char_I_desaturation_multiplier,WREG ; get desaturation multiplier
+	rcall	ghostwrite_byte_header			; store data
 
-	movff	char_I_GF_High_percentage,WREG	; 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 ; desaturation multiplier
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-
-	movff	char_I_deco_model,WREG			; 0 = ZH-L16, 1 = ZH-L16-GF
-	rcall	ghostwrite_byte_header			; writes byte and increases address (no banking)
+	; 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
 
-	read_int_eeprom .2
-	movf	EEDATA,W
-	rcall	ghostwrite_byte_header			; total dive counter, low
-	read_int_eeprom .3
-	movf	EEDATA,W
-	rcall	ghostwrite_byte_header			; total dive counter, high
+	; 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
 
-	movff	opt_dive_mode,WREG
-	rcall	ghostwrite_byte_header			; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR
+	; 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 all tissue data available
+	; store tissue data - N2 chars
 	movlw	.16
 	movwf	lo
-	lfsr	FSR1,char_O_tissue_N2_saturation+0
+	lfsr	FSR1,char_O_tissue_pres_N2
 end_dive_store_tissues_N2:
 	movf	POSTINC1,W
-	bcf		WREG,7							; clear flag bit for ongassing/offgassing
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	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 - 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			; WREG -> header in ext. flash
+	rcall	ghostwrite_byte_header			; store data
 	decfsz	lo,F
 	bra		end_dive_store_tissues_N2_2		; NO
 
+	; store tissue data - He chars
 	movlw	.16
 	movwf	lo
-	lfsr	FSR1,char_O_tissue_He_saturation+0
+	lfsr	FSR1,char_O_tissue_pres_He
 end_dive_store_tissues_He:
 	movf	POSTINC1,W
-	bcf		WREG,7							; clear flag bit for ongassing/offgassing
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	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 - 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			; WREG -> header in ext. flash
+	rcall	ghostwrite_byte_header 			; store data
 	decfsz	lo,F
 	bra		end_dive_store_tissues_He_2		; NO
 
-	; Some deco stuff
-	movff	char_I_depth_last_deco,WREG		; last stop [m]
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	char_I_deco_distance,WREG		; assumed distance to shown stop
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; store last stop depth
+	movff	char_I_depth_last_deco,WREG		; get last stop depth [m]
+	rcall	ghostwrite_byte_header			; store data
 
-	; Last HUD data
-	movff	hud_battery_mv+0,WREG			; last HUD battery value
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	hud_battery_mv+1,WREG			; last HUD battery value
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movff	hud_status_byte,WREG			; last HUD status
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	; store deco distance
+	movff	char_I_deco_distance,WREG		; get assumed distance to shown stop
+	rcall	ghostwrite_byte_header			; store data
 
-	; Battery gauge registers [nAs]
-	lfsr	FSR0,battery_gauge				; load base address of battery gauge register
-	movf	POSTINC0,W						; get byte 0
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; get byte 1
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; get byte 2
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; get byte 3
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; get byte 4
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
-	movf	POSTINC0,W						; get byte 5
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+ 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
+ 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
+ ENDIF
 
-	; Header stop
+	; 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
+
+	; write header stop code
 	movlw	0xFB
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	rcall	ghostwrite_byte_header			; store data
 	movlw	0xFB
-	rcall	ghostwrite_byte_header			; WREG -> header in ext. flash
+	rcall	ghostwrite_byte_header			; store data
 
 	call	divemode_store_statistics		; store/update statistics for this unit
-
-	clrf	surface_interval+0
-	clrf	surface_interval+1				; clear surface interval timer
+	bsf		reset_surface_interval			; request ISR to reset the surface interval timer
 
 ghostwriter_end_dive_common:
 ; Update ext_flash_log_pointer into EEPROM
@@ -802,30 +886,36 @@
 	movff	ext_flash_log_pointer+2,EEDATA
 	write_int_eeprom .6
 
-	bcf		simulatormode_active			; if we were in simulator mode
-
-; In DEBUG compile, keep all simulated dives in logbook, Desat time, nofly, etc...
-  ifndef __DEBUG
-	btfsc	restore_deco_data					; restore decodata?
-	call	deco_pull_tissues_from_vault
-	banksel	common								; bank 1
-  endif
-	call	update_battery_registers			; update battery registers into EEPROM
-	goto	surfloop							; and return to surface loop
-
+; 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
+ ifndef _DEBUG
+	call	deco_pull_tissues_from_vault		;     - restore tissue pressures (C-code)
+	banksel	common								;     - back to bank common
+ endif
 
-ghostwriter_end_dive_common_sim:
-	tstfsz	surface_interval+0					; was interval zero?
-	bra		ghostwriter_end_dive_common_sim2	; NO
-	tstfsz	surface_interval+1					; was interval zero?
-	bra		ghostwriter_end_dive_common_sim2	; NO
-	bra		ghostwriter_end_dive_common			; YES - done
-ghostwriter_end_dive_common_sim2:
-	movf	divemins+0,W
-	addwf	surface_interval+0,F
-	movf	divemins+1,W
-	addwfc	surface_interval+1					; add simulated dive time to surface interval
-	bra		ghostwriter_end_dive_common
+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
+	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)
+	banksel	common								; back to bank common
+
+	; the last surface pressure sample may have been taken while being submerged a bit already,
+	; therefore it will be replaced by the sample taken one more before, which is the one that
+	; 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
@@ -859,6 +949,7 @@
 	write_int_eeprom .6							; write new pointer
 	bra		ghostwriter_short_header2			; Done
 
+
 	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)
@@ -912,9 +1003,7 @@
 	movlw	0xFF
 	call	write_byte_ext_flash_plus_nocnt		; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase)
 
-	movf	samplingrate,W					; sampling rate
-	btfsc	FLAG_apnoe_mode					; apnoe mode?
-	movlw	samplingrate_apnoe				; apnoe sampling rate
+	movf	sampling_rate,W					; get sampling rate
 	rcall	ghostwrite_byte_profile			; WREG -> profile in ext. flash
 
 	movlw	.7								; number of divisors
@@ -975,36 +1064,33 @@
 
 divemode_store_statistics:					; store/update statistics for this unit
 	call	vault_decodata_into_eeprom		; update deco data
-	call	do_logoffset_common_read		; existing logbook offset into lo:hi
+	call	do_logoffset_common_read		; read current logbook offset into mpr
 
-	tstfsz	lo								; lo=0?
+	tstfsz	lo								; offset, low  byte = 0 ?
 	bra		change_logbook_offset1			; NO - adjust offset
-	tstfsz	hi								; hi=0?
+	tstfsz	hi								; offset, high byte = 0 ?
 	bra		change_logbook_offset1			; NO - adjust offset
-	bra		change_logbook_offset2			; lo=0 and hi=0 -> skip offset routine
+	bra		change_logbook_offset2			; YES to both - skip offset routine
 
 change_logbook_offset1:
-	movlw	d'1'
-	addwf	lo
-	movlw	d'0'
-	addwfc	hi
-	call	do_logoffset_common_write		; lo:hi -> EEPROM
+	INCI	mpr								; increment offset
+	call	do_logoffset_common_write		; write incremented offset as the new offset
 
 change_logbook_offset2:
-	; Clear lastdive:4
-	banksel	lastdive_time+0
-	clrf	lastdive_time+0
-	clrf	lastdive_time+1
-	clrf	lastdive_time+2
-	clrf	lastdive_time+3
-	movff	divemins+0,lastdive_duration+0
-	movff	divemins+1,lastdive_duration+1
-	movff	divesecs,  lastdive_duration+2
-	movff	max_pressure+0,lastdive_maxdepth+0
-	movff	max_pressure+1,lastdive_maxdepth+1
-	banksel	common
+	clrf	mpr+0							; prepare a 4 byte null value to clear the last dive time
+	clrf	mpr+1							; ...
+	clrf	mpr+2							; ...
+	clrf	mpr+3							; ...
+	SMOVFF	mpr,lastdive_time				; ISR-safe 4 byte copy of null value to last dive time counter
+
 
-	; Add more here...
+	; 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
 
 	END