changeset 631:185ba2f91f59

3.09 beta 1 release
author heinrichsweikamp
date Fri, 28 Feb 2020 15:45:07 +0100
parents 4cd81bdbf15c
children 0347acdf6d8e
files doc/Changenote-3-08.txt doc/changes-V2-97-SP1.txt doc/comm-docu.txt doc/readme-2-95.txt src/aa_fonts.asm src/adc_lightsensor.asm src/calibrate.asm src/comm.asm src/compass_ops.asm src/configuration.inc src/customview.asm src/customview.inc src/divemenu_tree.asm src/divemode.asm src/divemode.inc src/eeprom_rs232.asm src/eeprom_rs232.inc src/external_flash.asm src/external_flash.inc src/gaslist.asm src/gaslist.inc src/ghostwriter.asm src/hwos.asm src/hwos.inc src/i2c.asm src/i2c.inc src/isr.asm src/logbook.asm src/logbook.inc src/math.inc src/menu_processor.asm src/menu_tree.asm src/ms5541.asm src/option_table.asm src/options.asm src/p2_deco.c src/rtc.asm src/rtc.inc src/rx_ops.asm src/shared_definitions.h src/simulator.asm src/sleepmode.asm src/start.asm src/surfmode.asm src/text_english.inc src/text_french.inc src/text_german.inc src/text_italian.inc src/tft.asm src/tft_outputs.asm src/tft_outputs.inc
diffstat 51 files changed, 10030 insertions(+), 8506 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/Changenote-3-08.txt	Fri Feb 28 15:45:07 2020 +0100
@@ -0,0 +1,66 @@
+Change Note hwos TECH Firmware 3.08
+====================================
+
+- Removed option 'ascent speed', ascent calculation is done with a fixed
+  speed of 10 meters/minute now (equals the ascent speed limit by Bühlmann).
+
+- Improved calculation accuracy of the initial ascent. Remark: this will
+  have a slight impact on the resulting deco schedule compared to firmware
+  3.07.
+
+- The deco calculator now figures in the salinity setting.
+
+- Aligned logbook and last dive summery of avg and max depth regarding
+  rounding and incorporation of salinity setting.
+
+- Done some fine-tuning of depth outputs when using imperial units (feet).
+
+- In dive mode, sometimes the temperature was not shown any more after a
+  gas change - fixed now.
+
+- The menu system around setting up the dive mode & settings has been
+  decluttered. All settings are now sorted into the groups dive setup,
+  deco setup, SAC (gas needs) setup, ppO2 setup and stops & depths setup.
+
+- There is a new option "Swap on empty" in Dive Setup -> SAC Setup.
+  It is only effective if "CalcGas(B/O)" is switched on, too. If both
+  options are switched on, the deco calculation will switch to another
+  tank (i.e. gas) once the tank of the current gas is calculated to be
+  used up.
+  This function can be used to automatically calculate a contingency in
+  case of running out of a deco gas, as the deco calculation will then
+  continue to calculate a deco making use of the spares from the another
+  gases carried. Another application is with two or more tanks holding
+  the same gas (i.e. independent double configuration, side-mount), as
+  the calculations will then take the cumulative amount of gas carried
+  into account before raising a gas needs attention or alarm.
+
+- Fixed the urge of the better gas hint to always favor one specific gas
+  out of a set of two or more gases that have the same change depth.
+
+- For dives done on firmware >= 3.08 the logbook will have one more page
+  showing the tissue pressures and supersaturation levels as of at the
+  end of dive (i.e. when surfacing).
+
+- As long as a gas or diluent is currently selected as breathed, it can
+  not be set into the lost state any more.
+
+- When changing the battery or doing a cold start, the current CNS value
+  does not get lost any more.
+
+- During loading of a new firmware the clock will not loose time any more
+  (on old firmware it became late by about 15 sec on each firmware update).
+
+- When run from a 3.6 V battery (either replaceable or built-in), the
+  surface mode timeout is now extended to 4 minutes before going to sleep
+  mode. If the OSTC is run from 1.5 V disposables, the timeout remains at
+  the previous 90 seconds to save on battery runtime.
+
+- Internal improvement: the code for the internal storage system and for
+  the communication system (firmware uploading, dive data downloading)
+  has been re-factored to secure maintainability for the next years to come.
+
+- Internal improvement: the scheduler for the dive mode calculation plans
+  (fTTS, bailout) has been completely rewritten for better maintainability.
+
+- Brand new feature: Cave Mode. See supplemental manual for further details.
\ No newline at end of file
--- a/doc/changes-V2-97-SP1.txt	Fri Feb 21 10:51:36 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-hwos V2.97 SP1
---------------
-
-- Fix in der automatischen Deko-Gas-Auswahl falls zwei oder mehr Deko-Gase mit gleicher Wechseltiefe konfiguriuert sind.
-
-- Code Verbesserung in p2_deco zur Verringerung von Compiler-Abhängigkeiten.
-
-- Kompass-Peilung wird nur noch beim Aufruf des Menus gelöscht, nicht emhr wenn der OSTC über den sleepmode geht.
-
-- Gasmengen im Deko-Kalkulator werden jetzt als Liter statt Barliter bezeichnet.
-
-- Kennzeichung der Firmware als V2.97 SP1 (Service Pack 1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/comm-docu.txt	Fri Feb 28 15:45:07 2020 +0100
@@ -0,0 +1,290 @@
+OSTC hwos Tech Firmware COMM Mode Documentation
+===============================================
+
+Remarks: - timeouts restart on each received byte
+         - 3 byte start address and 3 byte length are expected in network byte format (big endian)
+
+
+comm_mode_selection_loop:							## entry point when COMM Mode is started ##
+
+	try to receive 1 byte, timeout after 4 minutes
+	received 0xBB   ->  goto comm_download_mode
+	received 0xAA   ->  goto comm_service_mode_check
+	timeout         ->  send 0xFF
+	                    quit comm mode
+
+
+comm_service_mode_check:							## received start byte for service mode, await service key ##
+
+	send 0x4B
+	|
+	| Attention: do not send the next 3 bytes in one batch, wait for
+	|            the echo of each byte before sending the next one
+	|
+	try to receive 1 byte (upper byte of comm service key), timeout after 400 ms
+	echo received byte
+	try to receive 1 byte (high  byte of comm service key), timeout after 400 ms
+	echo received byte
+	try to receive 1 byte (low   byte of comm service key), timeout after 400 ms
+	echo received byte
+	service key     correct  ->  enable comm_service_mode, goto comm_command_loop
+	service key not correct  ->                            goto comm_mode_selection_loop
+	timeout                  ->                            goto comm_mode_selection_loop
+
+
+comm_download_mode:									## received start byte for download mode ##
+
+	send 0xBB
+	goto comm_command_loop
+
+
+comm_command_loop:									## wait for a command ##
+
+	if comm_service_mode is enabled  ->  send 0x4C
+	else                             ->  send 0x4D
+
+	try to receive 1 byte, timeout after 2 minutes
+
+	timeout        ->  send 0xFF and quit comm mode
+	received 0x6E  ->  goto comm_show_text				 n  show a text on the screen
+	received 0x69  ->  goto comm_identify				 i  send ID: serial, firmware, and custom text
+	received 0x6A  ->  goto comm_hardware_descriptor	 j  send ID: hardware descriptor byte
+	received 0x60  ->  goto comm_feature_and_hardware	 '  send ID: more detailed information
+	received 0x6D  ->  goto comm_send_headers_short 	 m  send all headers in compact format
+	received 0x61  ->  goto comm_send_headers_full		 a  send all headers is full format
+	received 0x66  ->  goto comm_send_dive				 f  send header and profile for one dive
+	received 0x62  ->  goto comm_set_time				 b  set the real time clock
+	received 0x63  ->  goto comm_set_custom_text		 c  write a new custom text
+	received 0x72  ->  goto comm_read_option			 r  read  an option value
+	received 0x77  ->  goto comm_write_option			 w  write an option value (into RAM)
+	received 0x78  ->  goto comm_option_reset_all		 x  reset all option values to their factory default
+	received 0xFF  ->  send 0xFF and quit comm mode
+
+	the following commands are only evaluated if comm_service_mode is enabled:
+
+	received 0x23  ->  goto comm_reset_battery_gauge	 #  reset the battery gauge registers
+	received 0x22  ->  goto comm_erase_complete_logbook	 "  reset all logbook pointers and the logbook
+	received 0x20  ->  goto comm_read_range				' '  read a memory range from the external FLASH
+	received 0x40  ->  goto comm_erase_4kb				 @  erase one        4 kB block  - Warning: no confirmation or built-in safety here...
+	received 0x42  ->  goto comm_erase_range4kb			 B  erase a range of 4 kB blocks - Warning: no confirmation or built-in safety here...
+	received 0x30  ->  goto comm_write_range_stream		 0  write a stream of     bytes starting at ext_flash_address:3 until timeout
+	received 0x31  ->  goto comm_write_range_block		 1  write a block  of 256 bytes starting at ext_flash_address:3 (only available with FW >= 3.08)
+	received 0x50  ->  goto comm_firmware_update		 P  initiate firmware update
+	received 0xC1  ->  goto comm_cold_start				    start low-level bootloader
+
+
+
+comm_set_time:											## set the real time clock ##
+
+	send 0x62
+	try to receive 6 bytes in sequence: hour, minute, second, month, day, year, timeout 400 ms
+	timeout  ->           goto comm_command_loop
+	else     ->  set RTC, goto comm_command_loop
+
+
+comm_show_text:											## write a 15 char text to the OSTC display ##
+
+	send 0x6E
+	try to receive 16 characters, timeout 400 ms
+	print whatever has been received to the display
+	goto comm_command_loop
+
+
+comm_identify:											## reply serial, firmware and custom text ##
+
+	send 0x69
+	send  1 byte serial number, low  byte
+	send  1 byte serial number, high byte
+	send  1 byte firmware version, major
+	send  1 byte firmware version, minor
+	send 60 byte custom text
+	goto comm_command_loop
+
+
+comm_hardware_descriptor:								## reply short hardware descriptor ##
+
+	send 0x6A
+	send 1 byte hardware descriptor
+	goto comm_command_loop
+
+
+comm_feature_and_hardware:								## reply detailed hardware descriptor ##
+
+	send 0x60
+	send 0x00
+	send 1 byte hardware descriptor
+	send 0x00
+	send 0x00
+	send 0x00
+	goto comm_command_loop
+
+
+comm_send_headers_short:								## send short version of dive headers ##
+
+	send 0x6D
+	send 256 x 16 bytes (extract from the headers)
+	goto comm_command_loop
+
+
+comm_send_headers_full:									## send complete dive headers ##
+
+	send 0x61
+	send 256 x 256 bytes
+	goto comm_command_loop
+
+
+comm_send_dive:											## send one full dive ##
+
+	send 0x66
+	try to receive 1 byte (dive index), timeout 400 ms
+	timeout                    ->  goto comm_command_loop
+	no profile data available  ->  goto comm_command_loop
+	else                       ->  send 256 byte dive header  (begins with 0xFAFA)
+	                               send ??? byte dive profile (ends   with 0xFDFD)
+	                               goto comm_command_loop
+
+
+comm_option_reset_all:									## reset all options to factory default ##
+
+	send 0x78
+	reset all option values to default
+	goto comm_command_loop
+
+
+comm_set_custom_text:									## set custom text ##
+
+	send 0x63
+	try to receive 60 byte, timeout 400 ms
+	clear complete old custom text
+	store the 0...60 bytes that have been received as new custom text
+	goto comm_command_loop
+
+
+comm_reset_battery_gauge:								## reset battery gauge ##
+
+	(no acknowledge send)
+	reset battery registers and battery gauge chip
+	goto comm_command_loop
+
+
+
+comm_erase_complete_logbook:							## erase complete Logbook ##
+
+	(no acknowledge send)
+	erase complete logbook
+	goto comm_command_loop
+
+
+comm_cold_start:										## start bootloader (cold start) ##
+
+	(no acknowledge send)
+	backup crucial data from RAM to EEPROM
+	jump into the bootloader/cold start
+
+
+comm_firmware_update:									## initiate firmware update ##
+
+	send 0x50
+	try to receive 5 byte checksum, timeout 400 ms
+	timeout         ->  send 0xFF, goto comm_command_loop
+	checksum faulty ->  send 0xFF, goto comm_command_loop
+	else            ->  send 0x4C
+	                    backup crucial data from RAM to EEPROM
+	                    jump into bootloader/FW update
+
+
+comm_erase_range4kb:									## erase a memory range ##
+
+	send 0x42
+	try to receive 3 byte start address, timeout 400 ms
+	try to receive 1 byte block count,   timeout 400 ms
+	any timeout  ->  goto comm_command_loop
+	else         ->  erase FLASH from start address, range block_count x 4 kByte
+	                 goto comm_command_loop
+
+
+comm_erase_4kb:											## erase one 4 kB block ##
+
+	(no acknowledge send)
+	try to receive 3 byte start address, timeout 400 ms
+	timeout      ->  goto comm_command_loop
+	else         ->  erase FLASH from start address, range 4 kByte
+	                 goto comm_command_loop
+
+
+comm_write_range_stream:								## write a stream of bytes to the FLASH ##
+
+	send 0x30
+	try to receive 3 byte start address, timeout 400 ms
+	timeout      -> goto comm_command_loop
+	else         -> loop {try to receive 1 byte, write byte to FLASH } until timeout
+	                |
+	                | Attention: Do not send the bytes too fast as the OSTC needs
+	                |            some time for each byte to write it to the FLASH.
+	                |
+	                | Bytes will be received and written to FLASH until a timeout occurs,
+	                | i.e. to end the writing stop sending and await the timeout to trigger.
+	                |
+	                timeout  ->  goto comm_command_loop
+
+
+comm_write_range_block:									## write a block of 256 bytes to the FLASH ##
+														      (only available with FW >= 3.08)
+	send 0x31
+	try to receive 3 byte start address, timeout 400 ms
+	timeout                        ->  goto comm_command_loop
+	low byte of start address <> 0 ->  goto comm_command_loop
+	else                           ->  try to receive 256 byte, timeout 400 ms
+	                                   timeout  ->  goto comm_command_loop
+	                                   else     ->  write the 256 byte to FLASH
+	                                                goto comm_command_loop
+
+
+comm_read_range:										## read a range from FLASH ##
+
+	send 0x20
+	try to receive 3 byte start address, timeout 400 ms
+	try to receive 3 byte length,        timeout 400 ms
+	any timeout  ->  goto comm_command_loop
+	else         ->  loop {read 1 byte from FLASH, send 1 byte } until #length bytes done
+	                 goto comm_command_loop
+
+
+comm_read_option:										## read an option value ##
+
+	send 0x72
+	try to receive 1 byte option index, timeout 400 ms
+	timeout              ->  goto comm_command_loop
+	index = 0x10 - 0x19  ->  send 4 bytes in sequence O2%, He%, type, change depth
+	                         goto comm_command_loop
+	index = 0x1A - 0x1E  ->  send 2 bytes in sequence setpoint cbar, change depth
+	                         goto comm_command_loop
+	index = 0x1F - 0xXX  ->  send 1 byte option value (0xXX last index in use, depends on FW version)
+	                         goto comm_command_loop
+	else                 ->  goto comm_command_loop
+
+
+comm_write_option:										## write an option value ##
+
+	send 0x77
+	try to receive 1 byte option value, timeout 400 ms
+	timeout              ->  goto comm_command_loop
+	|
+	| Attention: do not send the option values too fast after the option index,
+	|            as the OSTC does not know how many bytes will follow after the
+	|            index before it has actually evaluated the index!
+	|            This is a flaw in the protocol design...
+	|
+	index = 0x10 - 0x19  ->  try to receive 4 byte in sequence O2%, He%, type, change depth
+	                         timeout  ->  goto comm_command_loop
+	                         else     ->  update option
+	                                      goto comm_command_loop
+	index = 0x1A - 0x1E  ->  try to receive 2 bytes in sequence setpoint cbar, change depth
+	                         timeout  ->  goto comm_command_loop
+	                         else     ->  update option
+	                                      goto comm_command_loop
+	index = 0x1F - 0xXX  ->  try to receive 1 byte option value (0xXX last index in use, depends on FW version)
+	                         timeout  ->  goto comm_command_loop
+	                         else     ->  update option
+	                                      goto comm_command_loop
+	else                 ->  goto comm_command_loop
--- a/doc/readme-2-95.txt	Fri Feb 21 10:51:36 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,540 +0,0 @@
-
-Doku- & Info-Sammlung zu p2_deco.c und der Einbettung in die V2.95a
-===================================================================
-
-Bedeutung der Bildschirm-Farben (in der Normaleinstellung):
-
-grün: feste Kolumnen oder "gute" Zustände.
-weiß: Zahlenwerte die im Normalbereich liegen
-blau: inaktive Einstellungen und Gase, sowie Werte die noch nicht
-      berechnet wurden oder die aufgrund von Einstellungsänderungen
-	  (Gaswechsel, LostGas, Setpoint-Wechsel, GF/aGF-Umschaltung, usw.)
-	  nicht mehr aktuell sind und gerade neu berechnet werden.
-gelb: Hinweise und Vorwarnungen die zu beachten sind, jedoch noch
-      kein unmittelbares Handeln erfordern.
-rot : Hinweise und Warnungen, die ein unmittelbaren Handeln erfordern.
-
-Die Schwellen für Vorwarnungen sind generell immer auf 70% eingestellt,
-für den aktuellen GF-Wert wird die GF-high Einstellung als Schwelle für
-die Vorwarnung benutzt.
-Vorwarnungen erscheinen als Warnungstext und/oder als Darstellung in
-gelber Farbe. Die endgültige Warnung erscheint dann in roter Farbe.
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Die Deco-Engine wird über zwei Parameter kommandiert:
-
-	char_O_main_status:
-	steuert die Berechnung für die realen Gewebe
-
-	char_O_deco_status:
-	steuert die Berechnung der Deko/Aufstiegssimulation
-	
-Die Kommandos werden über Flags gegeben. Für beide Kommandoparameter
-definert sind:
-
-	DECO_MODE_LOOP:
-	Wenn gesetzt wird für Kreislaufsysteme gerechnet wenn nicht gesetzt
-	wird in OC gerechnet.
-
-	DECO_MODE_PSCR:
-	nur in Verbindung mit DECO_MODE_LOOP, schaltet von CCR auf pSCR um.
-
-Nur für char_O_deco_status definiert sind:
-
-	DECO_PLAN_ALTERNATE:
-	Auswahl ob der Normalplan oder ein alternativer Plan gerechnet
-	werden soll. Von den Ergebnissen des Normal-Plans leiten sich die
-	meisten Bildschirmanzeigen ab. Vom alternativen Plan werden nur
-	ausgewählte Daten angezeigt, z.B. die der fTTS oder Bailout-
-	Berechnung.
-
-	DECO_CNS_CALCULATE:
-	Wenn aktiviert, wird der CNS%-Wert berechnet wie er am Ende des
-	Tauchgangs sein wird. Dies kann sowohl im Rahmen des normalen wie
-	auch des alternativen Plans geschehen, es existieren für beide
-	Pläne eigene Ausgabevariablen.
-
-	DECO_VOLUME_CALCULATE:
-	Wenn aktiviert, werden die Gasbedarfe für den gesamten Tauchgang
-	berechnet. Dies kann sowohl im Rahmen des normalen wie auch des
-	alternativen Plans geschehen, jedoch existiert für diese Funktion
-	nur ein gemeinsamer Satz Ausgabevariablen. Wenn DECO_MODE_LOOP
-	gesetzt ist erfolgen keine Berechnungen, es werden stattdessen
-	Nullwerte ausgegeben.
-
-	DECO_ASCENT_DELAYED:
-	Wenn aktiviert wird der Aufstieg / dier Dekompression so berechnet
-	als ob der Aufstieg nicht sofort, sondern um char_I_extra_time
-	verzögert beginnt. Die Funktion kann in beiden Plänen verwendet
-	werden, wird jedoch sinnvoller Weise in Verbindung mit dem
-	alternativen Plan für fTTS bzw. Bailout-Berechnungen mit delayed
-	ascent benutzt.
-
-Die Deco-Engine generiert Warnungen, die in Form von Flags über die
-Variable char_O_deco_warnings ausgegeben werden:
-
-	DECO_WARNING_IBCD:
-	Wird gesetzt wenn das führende Gewebe im Zustand der isobaren
-	Gegendiffusion ist und derzeit netto tatsächlich am aufsättigen
-	ist. Auf dem Bildschirm wird unter der IBCD-Warnung zusätzlich
-	der aktuelle GF angezeigt, der bei Vorliegen dieser Warnung am
-	steigen ist.
-
-	DECO_WARNING_IBCD_lock:
-	In diesem Flag wird das Auftreten einer IBCD-Warnung bis über
-	das Tauchgangsende hinaus gespeichert. Wird im Deko-Kalkulator
-	benutzt um eine IBCD-Warnung zu geben falls eine solche irgend
-	wann im Verlaufe der Tauchgangs-Berechnung ausgetreten ist.
-
-	DECO_WARNING_MBUBBLES:
-	Wird gesetzt, wenn die Gewebe aktuell soweit übersättigt sind
-	dass mit der Produktion von Mikroblasen gerechnet werden muss.
-	Achtung: wenn dieses Flag zurückgesetzt wird sind nicht etwa
-	die Mikroblasen nicht mehr da, es liegen nur vermutlich nicht
-	mehr die Bedingungen für eine Produktion weiterer Mikroblasen
-	vor. Der Zustand der aktiven Mikroblasengeneration wird über
-	eine Mikroblasen-Warnung in Rot dargestellt.
-
-	DECO_WARNING_MBUBBLES_lock:
-	Wird gesetzt sowie erstmalig während eines Tauchgangs die
-	Mikroblasen-Warnung gegeben wurde. Bleibt über das Ende des
-	Tauchgangs hinaus gesetzt bis die Oberflächen-Berechnungen eine
-	Entsättigung der Gewebe melden. Solange diese Warnung aktiv ist
-	wird eine Mikroblasen-Warnung in Gelb ausgegeben, sowohl im Tauch-
-	wie auch im Oberflächen-Modus.
-
-	DECO_WARNING_OUTSIDE:
-	Wird gesetzt, wenn die Gewebe aktuell soweit übersättigt sind, dass
-	der Gültigkeitsbereich des ZHL-16 Modells verlassen ist.
-	Achtung: wenn dieses Flag zurückgesetzt wird ist nicht etwa der
-	Gültigkeitsbereich des Modells wiederhergestellt, es wird lediglich
-	weiter gerechnet als ob das Modell noch gelten würde. Inwieweit die
-	berechneten Werte (Deko-Plan, Ceiling, ...) dann tatsächlich noch
-	praktische Relevanz haben ist unbekannt und extrem von den
-	Rahmenbedingungen des Einzelfalls abhängig.
-	Solange die Gewebesättigungen außerhalb des Modellbereichs sind
-	wird eine Warnung in Rot ausgegeben.
-
-	DECO_WARNING_OUTSIDE_lock:
-	Wird zusammen mit DECO_WARNING_OUTSIDE gesetzt und wie bei den
-	Mikroblasen erst bei Entsättigung wieder gelöscht.
-
-	DECO_WARNING_STOPTABLE_OVERFLOW:
-	Diese Warnung zeigt an, dass der Tauchgang mehr Stopps erfordert
-	als in der Stopp-Tabelle gespeichert werden können. Abgeleitete
-	Werte wie die Aufstiegszeit, die CNS-Werte am Tauchgangsende und
-	die Gasbedarfe können nicht mehr vollständig ermittelt werden und
-	werden daher in der Farbe Blau für ungültige Werte dargestellt. Die
-	wahren Werte sind mindestens so hoch wie die derart angezeigten.
-	Die Angaben zu den ersten Stopps auf dem Bildschirm und in den
-	Custom-Views sind jedoch trotzdem korrekt und im weiteren Verlaufe
-	des Tauchgangs, wenn die ersten Stopps vorüber sind, wird die
-	Tabelle wieder ausreichen um alle restlichen Stopp-Daten zu
-	speichern und die Warnung wird zurückgenommen.
-	Diese Warnung wird nicht direkt angezeigt, sondern nur indirekt
-	über die ungültig-Kennzeichnung der betroffenen Werte und sollte
-	bei praktisch durchführbaren Tauchgängen nicht auftreten.
-
-	DECO_FLAG:
-	Dieses Flag wird gesetzt, wenn mindestens ein Gewebe am absättigen
-	ist. Mit ihm wird die Warnschwelle für zu hohe ppO2-Werte von der
-	normalen Schwelle auf die Deko-Schwelle umgeschaltet. Sollte wieder
-	tiefer getaucht werden (Jo-Jo) so dass alle Gewebe wieder am
-	aufsättigen sind, dann wird das Flag zurückgenommen und auch die
-	Warnschwelle wieder zurückgeschaltet.
-
-
-Viele der internen Routinen der Deko-Engine sind generisch ausgelegt und
-können sowohl für Berechnungen zu den realen Geweben benutzt werden, als
-auch für die Berechnungen im Rahmen des normalen und des alternativen
-Aufstiegs-/Dekompressionsplans. Gesteuert wird dies intern über die
-Variable tissue_increment, diese besteht aus einem Flag auf der höchsten
-Bitposition und einer Interger-Zahl in den Bitstellen darunter
-(Wertebereich 0 - 127). Ist das Flag (Bit 7) gesetzt, so werden die
-Berechnungen auf die realen Gewebedaten angewendet, andernfalls auf die
-von den Plänen simulierten. Mit der Integerzahl wird die Zeitdauer
-bestimmt, für die die Berechnung durchgeführt werden soll. Null bedeutet
-eine Zeitdauer von 2 Sekunden, die Zahlen von 1 bis 127 stehen für 1 bis
-127 volle Minuten. Durch dieses Vorgehen konnten viele Programmabschnitte
-deutlich beschleunigt werden.
-
-Die Deko-Engine wird jede Sekunde aufgerufen und aktualisiert die obigen
-sowie weitere Warnungen jede Sekunde bzw. wenn die entsprechenden
-Berechnungen durchgeführt wurden. Die Berechnungen für die realen Gewebe
-werden jede zweite Sekunde durchgeführt, sekündlich abwechselnd zwischen
-der Aktualisierung der Gewebedrücke und des CNS%-Wertes.
-Die Aufstiegs- und Dekompressions-Berechnungen werden bei jedem Aufruf
-bearbeitet, also in jeder Sekundescheibe. Es wird abwechselnd der Normal-
-und der Alternativ-Plan berechnet.
-Werden für die Aufstiegsberechnung wesentliche Parameter geändert, wie
-z.B. das geatmete oder die verfügbaren Gase, der Setpoint, die GF-
-Faktoren, usw., dann wird die laufende Berechnung abgebrochen und im
-nächsten Sekunden-Zyklus mit dem nächsten Normalplan begonnen.
-
-Die Daten zu den Gasen werden von der Assembler-Seite aus über folgende
-Funktionen gesetzt:
-
-	Für die Berechnung der realen Gewebe:
-
-		setup_gas_registers:
-		setzt ein OC-Gas und schaltet den Rechenmodus auf OC
-
-		setup_dil_registers:
-		setzt ein Diluent und schaltet auf CCR bzw. pSCR Modus
-
-	Für die Aufstiegs-/Dekoplanung:
-
-		deco_setup_oc_gases:
-		übermittelt die Daten OC-Gase sowie das aktuell geatmete
-		Gas und	schaltet den Rechnenmodus auf OC
-
-		deco_setup_cc_diluents:
-		übermittelt die Daten der Diluent sowie das aktuell benutzte
-		Diluent und schaltet auf den CCR bzw. pSCR Modus
-
-Die Aufstiegs-/Dekoplanung wird über einen Enum in char_O_deco_status
-gesteuert:
-
-- Einmalig am Beginn des Tauchgangs wird der Zustand DECO_STATUS_INIT
-  aufgerufen, dieser initialisiert die Deco-Engine. Nach Abschluss der
-  Initialisierung wechselt die Deco-Engine selbsttätig in den Zustand
-  DECO_STATUS_START weiter.
-
-- DECO_STATUS_START
-  startet eine neue Aufstiegs-/Dekoplanung basierend auf den gesetzten
-  Flags und Gasdaten, falls noch eine Aufstiegs- oder Dekoplanung läuft
-  wird diese abgebrochen. In diesem Zustand wird auch berechnet ob sich
-  der Tauchgang noch innerhalb der Nullzeit befindet. Falls ja, endet die
-  Aufstiegsplanung hier im Zustand ECO_STATUS_FINISHED, ansonsten wird
-  sie beim nächsten Aufruf der Deco-Engine im Zustand DECO_STATUS_ASCENT
-  fortgesetzt.
-
-- DECO_STATUS_ASCENT
-  führt die Berechnung des Aufstiegs bis zum ersten Deko-Stopp aus
-  (initial ascent). Im alternativen Planungsmodus werden hierbei auch
-  Gaswechsel ermittelt. Nach Abschluss der Aufstiegsberechnung wird der
-  Zustand auf DECO_STATUS_STOPS weitergeschaltet, der dann beim wiederum
-  nächsten Aufruf der Deco-Engine bearbeitet wird.
-
-- DECO_STATUS_STOPS
-  berechnet die Dekostopps und alle weiteren Aufstiege, sowie die CNS%-
-  Werte am Tauchgangsende und die Gasbedarfe sofern jeweils angefordert.
-  Diese Berechnungen laufen üblicherweise über mehrere Aufrufzyklen der
-  Deco-Engine, diese signalisiert am Ende jedes Zykluses mit
-  DECO_STATUS_STOPS dass (mindestens) ein weiterer Zyklus benötigt wird
-  oder mit DECO_STATUS_FINISHED dass die Berechnungen abgeschlossen sind.
-
-- DECO_STATUS_FINISHED
-  signalisiert, dass die Aufstiegs-/Dekompressionsplanung abgeschlossen
-  ist und die Ergebnisse in den entsprechenden Variablen bereitstehen
-  bzw. aktualisiert sind.
-  Die Kodierung von DECO_STATUS_FINISHED (benutzt als Ausgabe aus der
-  Deco-Engine) entspricht der Kodierung von DECO_STATUS_START (benutzt
-  als Eingabe in die Deco-Engine). Die Deco-Engine kann sofort wieder im
-  Zustand DECO_STATUS_START aufgerufen werden, worauf ein neuer Planungs-
-  zyklus beginnt.
-
-Die Einstellungen und Gasdaten können zwischen zwei Planungszyklen (d.h.
-zwischen den Zuständen DECO_STATUS_FINISHED und DECO_STATUS_START) ohne
-Einschränkungen geändert werden. Während ein Planungszyklus läuft ist
-dies nicht zulässig und kann zu falschen Ergebnissen führen.
-
-
-Planungsfunktionen 2nd Deco Plan:
-
-Über die Deko-Einstellungen, Untermenu "2nd Deco Plan" können erweiterte
-sowie alternative Aufstiegs-/Dekompressionsberechnungen aktiviert werden.
-
-	fTTS/Delay:
-
-	Wird hier ein Wert größer Null ausgewählt, dann wird ein zweiter,
-	alternativer Aufstiegs-/Dekoplan berechnet unter der Annahme, dass
-	die eingestellte Zeit in Minuten weiterhin auf der aktuellen Tiefe
-	verbracht wird und erst dann der Aufstieg beginnt. Die unter dieser
-	Annahme berechnete Aufstiegszeit wird als fTTS (future Time to
-	Surface) angezeigt. Weiterhin wird der CNS-Wert berechnet, der sich
-	am Ende eines derart verlängerten Tauchgangs ergeben wird, er kann
-	über einen	CustomView angesehen werden. Wenn dieser CNS-Wert 100%
-	erreicht wird außerdem eine Warnung ausgegeben.
-
-	Im Bailout-Fall wird keine fTTS-Berechnung durchgeführt, dafür
-	Erfolgt die Aktualisierung der Bailout-Aufstiegsberechnung dann in
-	Schnellerer 	Folge.	
-
-
-	Calc.Gas(B/O):
-
-	Wird diese Option aktiviert, dann wird der Gasbedarf berechnet, der
-	für die Beendigung des Tauchgangs unter Einhaltung der Aufstiegs-
-	geschwindigkeiten und ggf. Dekompressionsstopps benötigt wird. Wenn
-	bei fTTS/Delay Null eingestellt ist, dann wird diese Berechnung
-	während der normalen Aufstiegs-/Dekoberechnung durchgeführt und die
-	ermittelten Werte gelten bei sofortigem Beginn des Aufstiegs. Wenn
-	bei fTTS/Delay eine Zeit größer Null eingestellt ist, dann wird die
-	Berechnung im Rahmen des zweiten, alternativen Plans durchgeführt
-	Und die berechneten Gasbedarfe gelten für den verzögerten Aufstieg.
-
-
-	fTTS/Delay und Calc.Gas(B/O) im Modus CCR und pSCR:
-
-	Das oben beschriebene Verhalten verändert sich, wenn sich der OSTC
-	im CCR oder im pSCR Modus befindet: Wenn die Option Calc.Gas(B/O)
-	ausgeschaltet ist, dann gelten die berechnete Aufstiegszeit und der
-	CNS-Wert unter der Annahme dass bis zum Ende des Tauchgangs	weiterhin
-	vom Kreislaufgerät geatmet wird.
-	Wenn die Option Calc-Gas(B/O) hingegen eingeschaltet ist, dann wird
-	die Aufstiegszeit und der CNS-Wert unter der Annahme berechnet,
-	dass ab sofort ein Bailout erfolgt, auf dem ersten Bailoutgas für
-	die bei fTTS/Delay eingestellte Zeit auf der aktuellen Tiefe
-	verblieben wird und dann ein Bailout-Aufstieg eingeleitet wird.
-	Die sich so ergebende Aufstiegszeit wird als B/O-Zeit (BailOut)
-	angezeigt und die berechneten Gasmengen gelten für die OC-Bailout-
-	Gase.
-
-
-	Bottom Gas, Deco Gas:
-
-	Hier werden die Gasbedarfe in Litern pro Minute Oberflächenrate
-	(SAC) eingestellt. Diese Einstellungen werden auch vom Deko-
-	Kalkulator benutzt, der über das Simulations-Menu zu erreichen ist.
-
-
-	Tank Sizes:
-
-	Hier sind die Größen der Tanks für die OC-/Bailout-Gase in Litern
-	(Wasservolumen) einzustellen. Diese Einstellungen sind wichtig, da
-	sie für die Berechnung der Gasbedarfe im Tauchmodus benötigt
-	werden: Im Tauchmodus erfolgt die Ausgabe der benötigten Gasmengen
-	in Bar, bezogen auf die jeweiligen Flaschengrößen.
-
-
-	Tank Press Budget: (ex Tank Fill Press)
-
-	Hier wird festgelegt wie viel Gas aus den jeweiligen Tanks (Flaschen)
-	für den Tauchgang verwendet werden darf. Die Einstellung erfolgt in
-	Bar Flaschendruck. Erreicht der Bedarf eines Gases 70% des für das
-	Gas eingestellten Budgets, dann erfolgt eine Warnung in gelber Farbe.
-	Bei 100% erscheint die Warnung in roter Farbe.
-	Die benötigten Flaschendrücke können jederzeit über einen CustomView
-	eingesehen werden. Dieser zeigt aufgrund der begrenzten Bildschirm-
-	fläche nur die Bedarfe von bis zu vier Gasen an, die Warnungen werden
-	jedoch für alle 5 Gas erzeugt.
-	Alle Gasbedarfs- und Druckberechnungen erfolgen unter der Annahme
-	idealer Gase und ohne Betrachtung von temperaturbedingten Druck-
-	änderungen.
-
-
-Gaswechsel:
-
-Im Rahmen der Deko-Pläne werden automatisch Gaswechsel eingeplant, wenn
-ein besseres Gas verfügbar ist. Ein besseres, bzw. das beste Gas ist
-dasjenige Gas, dessen Wechseltiefe am dichtesten unterhalb der aktuellen
-Tiefe liegt. Nur aktivierte Gase die nicht als "Lost" markiert sind
-werden berücksichtigt. Gaswechsel werden als Stopp in die Stopp-Tabelle
-eingetragen. Die Dauer dieser Stopps beträgt standardmäßig 1 Minute.
-Sollte auf der Stopp-Stufe für den Gaswechsel auch ein Dekompressions-
-Stopp notwendig sein, so addiert sich die notwendige Stoppzeit für die
-Dekompression zu der für den Gaswechsel hinzu.
-
-Im Bereich zwischen der Grundtiefe und dem ersten Dekompressions-Stopp
-werden die Gaswechsel-Stopps auf die Tiefen gelegt, ab denen jeweils
-bessere Gase verfügbar werden. Gibt es ein besseres Gas auf der aktuellen
-Tiefe, so wird ein Wechsel auf der aktuellen Tiefe geplant. Dies geschieht
-jedoch nur im Modus alternativer Plan und nur wenn das nächste bessere
-Gas nicht in <= 1 Minute Aufstiegszeit erreicht wird. In Normal-Plan
-werden Wechsel auf ein besseres Gas erst ab dem ersten echten Deko-Stopp
-eingeplant.
-Im Falle, dass im alternativen Plan ein Bail-Out Szenario gerechnet wird
-sieht die Gaswahl- und Gaswechsel-Strategie wie folgt aus: zunächst wird
-dasjenige OC-Gas gewählt welches als 'First' konfiguriert ist. Auf diesem
-wird auf aktueller Tiefe für die Zeit verblieben, die als Delayed-Acent-
-Time eingestellt ist. Dann erfolgt die Suche nach einem besseren Gas, auf
-das je nach Verfügbarkeit im direkten Anschluss oder während des
-initialen Aufstiegs gewechselt wird. Ab Erreichen des ersten Dekostopps
-werden Gaswechsel in beiden Plänen (normaler und alternativer Plan)
-automatisch ermittelt und immer auf die nächsten passenden Dekostopps
-gelegt. Im CCR und im pSCR Modus werden derzeit keine automatischen
-Gaswechsel berechnet.
-
--> Die Gaswechselzeit ist bereits in der Options-Tabelle angelegt, wird
-   aber momentan noch innerhalb von p2_deco.c auf 1 Minute erzwungen.
-
-Die Deko-Engine plant den Aufstieg mit einer einstellbaren Aufstiegs-
-geschwindigkeit von 5-10 Meter pro Minute, diese wird über eine Option in
-der Options-Tabelle eingestellt.
-
--> Die Aufstiegsgeschwindigkeit ist bereits in der Options-Tabelle
-   angelegt, wird aber momentan noch innerhalb von p2_deco.c auf 10 m/min
-   erzwungen.
-
-Für die Ceiling-Berechnung ist eine neue Codezeile angelegt die dafür
-sorgt, dass die Ceiling genau dann zu Null wird, wenn auch die TTS zur
-NDL umschaltet. Bisher wird so gerundet, dass die Ceiling zu Null wird
-während noch eine TTS angezeigt wird. Die neue Zeile ist noch
-auskommentiert und die alte Formel in Betrieb um eine Vergleichbarkeit
-der gesamten Berechnungen mit der V2.27 zu ermöglichen. Zur Release-
-Version sollte entsprechend umkommentiert werden.
-
-
-Gasbedarfs-Berechnung:
-
-Es werden die Bedarfe aller Gase berechnet, die bei der Aufstiegs-/
-Dekompressionsberechnung eingeplant wurden. Es sind diese die Gase 1
-bis 5. Wird aktuell ein manuell konfiguriertes Gas ("Gas 6") geatmet,
-so wird dieses in der Gasbedarfsberechnung außen vor gelassen. Die
-Berechnung teilt sich in die Bereiche bottom und initial ascent, stops
-und intermediate ascents sowie final ascent.
-
-Im Bereich bottom und initial ascent wird die Bottom-Verbrauchsrate
-angesetzt, in den übrigen Bereichen die Deko-Verbrauchsrate.
-Die Aufstiegssegmente werden mit der konfigurierten Aufstiegsrate (5-10
-m/min) berechnet, der final ascent vom letzten Stopp bis zur Oberfläche
-mit 1 Meter/Minute. Gibt es keine Stopps, dann reicht der initial ascent
-vom Bottom bis zur Oberfläche und wird mit der konfigurierten Aufstiegs-
-rate gerechnet, zuzüglich eines Sicherheitsstopps von 3 Minuten auf 5
-Metern. Wenn es keinen Deko-Stopp gibt, aber einen Gaswechsel-Stopp der
-tiefer liegt als ein letzter regulärer Deko-Stopp liegen würde, dann wird
-der Aufstieg geteilt in einen intermediate ascent und einen final ascent.
-Für beide werden dann die entsprechenden Aufstiegsraten angesetzt.
-
-Alle Gaswechsel werden der Stopp-Tabelle entnommen, daher sind dort
-auch reine Gaswechsel-Stopps eingetragen, d.h. Stopps auf denen keine
-Dekompression notwendig ist. Auf den Stopps die einen Gaswechsel
-beinhalten wird der Gasbedarf wie folgt berechnet: Der Bedarf für die
-gesamte Stoppdauer wird dem neuen Gas zugerechnet, für die konfigurierte
-Gaswechsel-Dauer wird ein entsprechender Bedarf zusätzlich auf das alte
-Gas aufgeschlagen. So ist sichergestellt, dass die berechneten Gasvolumina
-genügend Reserve ausweisen um auf einem Gaswechsel-Stopp die Zeit zu haben
-das neue Gas verfügbar zu machen (Stage-Handling).
-
-Die Gasbedarfe werden zum einen in Litern berechnet, diese Werte werden
-vom Deko-Kalkulator genutzt, und zum anderen in bar Flaschendruck
-entsprechend der eingestellten Flaschengrößen. Hierbei wird mit idealen
-Gasen gerechnet, sprich Druck = benötigtes Volumen / Flaschengröße.
-Aus dem Vergleich von berechnetem Druckbedarf und konfiguriertem
-Flaschendruck werden die Vorwarnung (70%, gelb) und die Hauptwarnung
-(100%, rot) generiert. Um bei der Hauptwarnung noch eine minimale Reserve
-zu haben sollte daher der Flaschendruck etwas niedriger eingestellt
-werden als er tatsächlich ist.
-
-
-Gewebegrafik:
-
-Die Gewebegrafik ist so skaliert, dass die Länge der Balken dem Druck des
-Jeweiligen Inertgases entspricht. Während des Tauchgangs werden die
-Balken zusätzlich eingefärbt, die Farbe kennzeichnet ob das Gewebe gerade
-am aufsättigen oder am entsättigen ist. Die Balken für den Stickstoff
-beginnen weiter links da die Gewebe im Ausgleichzustand an der Oberfläche
-bereits zu einem Teil Stickstoff enthalten, nicht jedoch Helium. So
-beginnen die "Überdrücke" aus dem Ausgleichszustand heraus auf gleicher
-Linie.
-
-
-Stopp-Tabelle (Deko-Tabelle):
-
-Der Funktionsaufruf ist so verändert, dass beim Aufruf die Menge
-der einzutragenden Minuten übergeben werden kann. Diese werden dann auf
-den bestehenden Stopp aufaddiert bzw. es wird ein neuer Stopp angelegt.
-Es können auch Null Minuten übergeben werden und so ein Stopp "on the
-fly" erzeugt werden, z.B. für einen reinen Gaswechsel. Alle Operationen
-auf der Stopp-Tabelle sind angepasst um mit Stopps von Null-Dauer zu
-funktionieren.
-Ein Stopp-Eintrag kann maximal 99 Minuten Stoppdauer aufnehmen. Dauert
-ein Stopp länger, so wird eine weiterer Stopp auf gleicher Tiefe angelegt.
-
-
-No-Fly bzw. Altitude-Wait-Zeit:
-
-Diese Wartezeit wird wie eine Dekompression aus dem aktuellen Gewebe-
-zustand heraus auf eine fiktive Tiefe gerechnet, die der gewählten
-Höhenstufe entspricht. Für No-Fly wird dabei ein Kabinendruck von 0,6
-bar angesetzt. Der Rechenaufwand für diese Berechnung wird die die
-Verwendung eines iterativen Optimierungs-Algorithmus wesentlich
-reduziert. Der aktuelle Umgebungsdruck wird laufend in die Berechnung
-einbezogen, die sich ergebene Zeit auf volle 10 Minuten gerundet
-ausgegeben.
-
-
-Entsättigungszeit:
-
-Die Entsättigungzeit ist so definert dass der Rest-Stickstoffdruck in
-allen Geweben maximal 5% des Gewebedrucks aus natürlicher Sättigung
-(Atmung von Luft unter aktuellem Umgebungsdruck) entspricht. Der sich
-ergebene Druckwert wird dann ebenfalls für das Rest-Helium angesetzt.
-Der aktuelle Umgebungsdruck wird laufend in die Berechnung einbezogen,
-die sich ergebene Zeit auf volle 10 Minuten gerundet ausgegeben.
-
-
-pSCR Modus:
-
-Neben dem CCR-Modus wird nun auch der pSCR-Modus vollständig unterstützt,
-inklusive optionalen Sensoren. Die Bedienung und die Menus sind weitest-
-gehend identisch, nur dort wo im CCR-Modus zwischen den Setpoints und
-Sensorbetrieb ausgewählt wird befindet sich im pSCR-Modus die Auswahl
-zwischen Sensorbetrieb und berechneten ppO2-Werten.
-
-
-Handling von Gas 6:
-
-In der bisherigen Implementierung wurden Änderungen an den O2- und He-
-Prozenten des Gases 6 sofort an die Berechnungen für die realen Gewebe
-innerhalb von p2_deco.c übergeben, ohne dass dazu der dedizierte Menu-
-Eintrag welcher die Zusammensetzung von Gas 6 anzeigt explizit ausgewählt
-werden musste. Ebenso wurde das Gas6-Event ausgelöst sowie einer der
-Prozentwerte verstellt wurde. In den Teil von p2_deco.c, der die Deko-
-Berechnungen ausführt, wurden die Werte von Gas 6 jedoch erst übernommen,
-wenn besagter Menu-Eintrag ausgewählt wurde, was in der Praxis zu
-Diskrepanzen führen muss.
-
-In der jetzigen Implementierung werden die O2- und He-Prozentwerte erst
-dann übernommen und als Gas 6 aktiviert, wenn der Gas6-Menueintrag
-explizit ausgewählt wird. Die Übernahme erfolgt sodann konsistent in die
-Berechnung sowohl der realen Gewebe als auch in die Dekoberechnung, und
-auch das Gas6-Event wird erst dann gesetzt.
-
-
-Deko-Kalkulator:
-
-Der Deko-Kalkulator benutzt die Gasverbrauchsraten, die im Deko-Menu,
-Untermenu "2nd Deco Plan" eingestellt sind. Ãœber das Menu "Calculator
-Setup" kann eingestellt werden, welcher CCR Setpoint für die Berechnungen
-benutzt werden soll (nur relevant im CCR Modus) und ob die normalen oder
-die alternativen (aGF) GF-Faktoren für die Dekoberechnung benutzt werden
-sollen (gilt für alle Modi). Der Deko-Kalkulator ermittelt die benötigten
-Gasmengen in Litern (exakt: Barlitern).
-Kommt es aufgrund der benutzen Gase und des Deko-Profils zu einer IBCD,
-dann wird auf der Ergebnisseite eine entsprechende Warnung ausgegeben.
-Erfordert die Dekompression mehr Stopps als im OSTC gespeichert werden
-können, dann wird die Deko-Berechnung abgebrochen und eine "incomplete"
-Warnung ausgegeben. Die angezeigte Aufstiegszeit, der CNS-Wert und die
-ermittelten Gasbedarfe gelten nur bis zum Ende der angezeigten Stopps.
-Achtung: Die tatsächlichen Werte bis zum Erreichen der Oberfläche können
-unter Umständen deutlich größer sein als die angezeigten, da insbesondere
-die letzten Stopps (die nicht mehr berücksichtigt werden konnten) typisch
-am längsten dauern! Dieser Fall sollte jedoch bei Profilen praktisch
-durchführbarer Tauchgängen nicht auftreten.
-
-
-"DECO ZONE" and GF-"Ampel"
-
-Sobald beim Aufstieg mindestens ein Gewebe beginnt abzusättigen erscheint
-auf der Anzeige "DECO ZONE" in grüner Schrift. Ab diesem Zeitpunkt wird
-auch die Warnschwelle für den ppO2 von der normalen Max-Schwelle auf die
-Deco-Max-Schwelle umgestellt. Sollte wieder tiefer getaucht werden und
-keines der Gewebe mehr absättigen, so verschwindet die Anzeige "DECO
-ZONE" wieder und auch die ppO2 Warnschwelle wird wieder auf den normalen
-Max-Wert zurück geschaltet.
-Überschreitet während des Aufenthalts in der DECO ZONE der aktuelle GF-
-Wert den eingestellten Wert für den GF-high, dann erscheint anstatt des
-Textes "DECO ZONE" der aktuelle GF-Wert in gelber Farbe. Erreicht oder
-überschreitet der aktuelle GF-Wert 100%, dann wird dieser in roter Farbe
-angezeigt.
-
-
-Allgemeines:
-
-Der Quellcode von p2_deco.c ist in bezüglich Lesbarkeit und Kommentierung
-überarbeitet, alle Variablen in p2_deco.c und shared_definitions.h sind
-funktional gruppiert und ebenfalls vollständig kommentiert. In diversen
-Assembler-Quellcode-Dateien wurde ebenfalls die Kommentierung verbessert.
--- a/src/aa_fonts.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/aa_fonts.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File aa_fonts.asm                         combined next generation V3.03.5
+;   File aa_fonts.asm                         combined next generation V3.08.3
 ;
 ;   Font-data for the anti-aliased word processor
 ;
@@ -117,12 +117,12 @@
 	; 93 is down arrow (dive start)
 	; 94 is up   arrow (dive end)
 	; 95 is left-right arrow (dive duration)
-	DB	'¤', 0x96						; unused
-	DB	0								; end of translation table
-	DB	aa_font34_firstChar				; to be subtracted
-	DB	aa_font34_chars					; max value
-	DB	0x87-aa_font34_firstChar		; replace by ¤ when unknown
-	DB	aa_font34_height + 0x80
+	DB		'¤', 0x96					; unused
+	DB		0							; end of translation table
+	DB		aa_font34_firstChar			; to be subtracted
+	DB		aa_font34_chars				; max value
+	DB		0x87-aa_font34_firstChar	; replace by ¤ when unknown
+	DB		aa_font34_height + 0x80
 ;
 #include	"../src/Fonts/aa_font34_idx.inc"
 #include	"../src/Fonts/aa_font34.inc"
@@ -135,15 +135,18 @@
 ;---- MEDIUM font description and data ---------------------------------------
 	global	aa_font48_block
 aa_font48_block:
-	DB		0x27, 0x3B					; ' char
-	DB		'"', 0x3C
-	DB		'm', 0x3D
-	DB		'f', 0x3E
-	DB		' ', 0x3F
-	DB		0
-	DB		aa_font48_firstChar
-	DB		aa_font48_chars
-	DB		0x3E-aa_font48_firstChar
+	DB		' ',  0x3F					; space, full-width
+;	DB		',',  0x2C					; space, half-width, on position of ','
+;	DB		'-',  0x2D					; minus, half-width, on position of '-'
+	DB		'|',  0x2F					; |      half-width
+	DB		0x27, 0x3B					; '      half-width
+	DB		'"',  0x3C					; "
+	DB		'm',  0x3D					; m
+	DB		'f',  0x3E					; ft-ligature
+	DB		0							; end of translation table
+	DB		aa_font48_firstChar			; to be subtracted
+	DB		aa_font48_chars				; max value
+	DB		0x3F-aa_font48_firstChar	; replace by space when unknown
 	DB		aa_font48_height + 0x80		; AA flag
 ;
 #include	"../src/Fonts/aa_font48_idx.inc"
--- a/src/adc_lightsensor.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/adc_lightsensor.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File adc_lightsensor.asm                  combined next generation V3.06.1
+;   File adc_lightsensor.asm                  combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -20,19 +20,20 @@
 ;=============================================================================
 
 wait_adc:									; bank-safe
-	movwf	ADCON0
-	nop
+	movwf	ADCON0							; select ADC channel
+	nop										; wait a short moment
 	bsf		ADCON0,1						; start ADC
 wait_adc2:
-	btfsc	ADCON0,1						; wait...
-	bra		wait_adc2
-	return
+	btfsc	ADCON0,1						; ADC done?
+	bra		wait_adc2						; NO  - wait
+	return									; YES - done
 
 	global	get_battery_voltage
 get_battery_voltage:						; start ADC and wait until finished
 	btfss	battery_gauge_available			; battery gauge IC available?
 	bra		get_battery_voltage_2			; NO  - OSTC hardware without gauge IC
-	call	lt2942_get_accumulated_charge	; YES - read coulomb counter
+	bsf		battery_is_36v					; YES - gauge IC available, 3.6V battery
+	call	lt2942_get_accumulated_charge	;     - read coulomb counter
 	call	lt2942_get_voltage				;     - read battery voltage
 	call	lt2942_get_temperature			;     - read battery temperature
 	tstfsz	batt_voltage+1					;     - read voltage < 256 mV ?
@@ -43,6 +44,7 @@
 	;bra	get_battery_voltage_1			;           - proceed
 
 get_battery_voltage_1:
+	rcall	get_battery_voltage_low			; check for battery low condition
 	btfsc	divemode						; in dive mode?
 	return									; YES - done
 
@@ -61,35 +63,35 @@
 	;bra	charge_cv_active				;       YES - charging in CV mode
 
 charge_cv_active:
-	decfsz	get_bat_volt_counter,F
-	return
-	movlw	.15
-	cpfsgt	batt_voltage+1					; battery voltage >= 16*256mV (4.096V) ?
-	bra		charge_cc_active				; NO
-	bsf		cc_active
-	bsf		cv_active
-	bsf		LEDr							; indicate charging
-	call	lt2942_charge_done				; reset accumulating registers to 0xFFFF
-	WAITMS	d'10'
-	bcf		LEDr							; indicate charging
-	bsf		get_bat_volt_counter,0			; =1
-	return
+	decfsz	get_bat_volt_counter,F			; decrement counter, became zero?
+	return									; NO  - not yet, done
+	movlw	.15								; YES - battery voltage >= 16*256mV (4.096V)
+	cpfsgt	batt_voltage+1					;     - ... ?
+	bra		charge_cc_active				;     NO
+	bsf		cc_active						;     YES - set CC charging status
+	bsf		cv_active						;         - set CV charging status
+	bsf		LEDr							;         - indicate charging
+	call	lt2942_charge_done				;         - reset accumulating registers to 0xFFFF
+	WAITMS	d'10'							;         - wait 10 ms
+	bcf		LEDr							;         - indicate charging
+	bsf		get_bat_volt_counter,0			;         - set counter to 1
+	return									;         - done
 
 charge_cc_active:
-	bsf		cc_active
+	bsf		cc_active						; set CC charging mode
 	bsf		LEDr							; indicate charging
-	bcf		CHRG_OUT
+	bcf		CHRG_OUT						; 
 	bsf		TRISJ,2							; set chrg-Out output to high impedance
-	movlw	.15
-	cpfsgt	batt_voltage+1					; battery voltage >= 16*256mV (4.096 V)?
+	movlw	.15								; battery voltage >= 16*256mV (4.096 V)
+	cpfsgt	batt_voltage+1					; ... ?
 	bra		charge_cc_active2				; NO
-	movlw	.81
-	cpfslt	batt_voltage+0					; battery voltage >= 80mV (+4096mV from batt_voltage+1)?
-	bra		charge_cv_active				; YES
+	movlw	.81								; YES - battery voltage >= 80mV (+4096mV from batt_voltage+1)
+	cpfslt	batt_voltage+0					;     - ... ?
+	bra		charge_cv_active				;       YES
 charge_cc_active2:
-	movlw	.10
-	movwf	get_bat_volt_counter
-	return
+	movlw	.10								;       NO  - set counter to 10
+	movwf	get_bat_volt_counter			;           - ...
+	return									;           - done
 
 get_battery_voltage_2:						; no gauge IC available, use ADC to measure battery voltage
 	; additional charging disable in software
@@ -98,10 +100,9 @@
 
 	bsf		adc_is_running					; =1: the ADC is in use
 	movlw	b'00100000'						; 2.048 Volt Vref+ -> 1 LSB = 500 µV
-	movwf	ADCON1
+	movwf	ADCON1							; ...
 	movlw	b'00011001'						; power on ADC, select AN6
-	rcall	wait_adc
-
+	rcall	wait_adc						; take measurement
 	MOVII	ADRESL,batt_voltage				; store value
 	bcf		ADCON0,0						; power off ADC
 
@@ -130,7 +131,7 @@
 	movff	WREG,battery_gauge+5			;     - into battery gauge registers
 
 get_battery_voltage_3:						; 3.6V battery gauge mode
-	; SMOVFF "by hand" as the macro does not work with arguments that have a '+something' with them
+	; SMOVQQ "by hand" as the macro does not work with arguments that have a '+something' with them
 	bcf		trigger_isr_updates				; clear flag, it will be set by the ISR in case it had kicked in
 	movff	battery_gauge+5,xC+3
 	movff	battery_gauge+4,xC+2
@@ -200,7 +201,18 @@
 	btfsc	battery_is_36v					; using a 3.6 volt battery?
 	movff	lo,batt_percent					; YES - take new value (always use computed value for 3.6V battery)
 	bcf		adc_is_running					; done with ADC
-	return
+	;bra	get_battery_voltage_low			; check for battery low condition (and return)
+
+get_battery_voltage_low:
+	; check for battery low condition
+	movlw	battery_warn_level_36+1			; get threshold for 3.6 Volt battery warning, incremented by 1
+	btfss	battery_is_36v					; actually a 3.6 Volt battery detected?
+	movlw	battery_warn_level_15+1			; NO - replace with 1.5 Volt battery warning, incremented by 1
+	bsf		battery_low_condition			; set battery low condition by default
+	cpfslt	batt_percent					; current battery level <= warning threshold ?
+	bcf		battery_low_condition			; NO  - clear battery low condition
+	return									;     - done
+
 
 get_battery_voltage_9:
 	; use 1.5V battery voltage mode
@@ -496,12 +508,12 @@
 	btfsc	adc_is_running					; ADC in use?
 	return									; YES - abort
 	btfsc	cc_active						; NO  - charging?
-	bra	get_analog_switches0					;       YES - abort (And clear both flags)
+	bra		get_analog_switches0			;       YES - abort (and clear both flags)
 	;bra	get_analog_switches_2			;       NO  - read switches
 
 get_analog_switches_2:
-	bsf	adc_is_running
-	bcf	ADCON2,ADFM						; left justified
+	bsf		adc_is_running
+	bcf		ADCON2,ADFM						; left justified
 	clrf	ADCON1
 	movlw	b'00100101'						; power on ADC, select AN9
 	rcall	wait_adc
@@ -611,8 +623,8 @@
 	bsf		analog_sw1_pressed				; set right button as pressed
 
 get_analog_switches_4:
-	bsf	ADCON2,ADFM						; restore to right justified
-	bcf	adc_is_running
+	bsf		ADCON2,ADFM						; restore to right justified
+	bcf		adc_is_running
 	banksel	common							; back to bank common
 	btfsc	analog_sw1_pressed				; right button pressed?
 	return									; YES - done
--- a/src/calibrate.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/calibrate.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File calibration.asm                      combined next generation V3.03.1
+;   File calibration.asm                      combined next generation V3.08.8
 ;
 ;   o2 sensor calibration subroutines
 ;
@@ -42,7 +42,7 @@
 	addwf	lo,F							; add byte to checksum
 tx_to_HUD_cs:								; entry point to transmit the checksum
 	movff	WREG,TXREG2						; transmit byte
-	call	rs232_wait_tx2					; wait for UART
+	call	ir_s8_wait_tx					; wait for UART
 	return
 
 
@@ -222,7 +222,6 @@
 
 	return									; done
 
-
  ENDIF	; _external_sensor
 
 ;=============================================================================
--- a/src/comm.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/comm.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File comm.asm                             combined next generation V3.04.3
+;   File comm.asm                             combined next generation V3.08.8
 ;
 ;   RS232 via USB
 ;
@@ -8,7 +8,7 @@
 ;=============================================================================
 ; HISTORY
 ;  2011-08-22 : [mH] Creation
-;  2012-02-11 : [jDG] Added "c" set custom text, and "i" identify
+;  2012-02-11 : [jDG] Added 0x63 set custom text, and "i" identify
 
 #include "hwos.inc"
 #include "eeprom_rs232.inc"
@@ -23,26 +23,34 @@
 #include "adc_lightsensor.inc"
 #include "shared_definitions.h"
 #include "math.inc"
+#include "i2c.inc"
+#include "logbook.inc"
+
 
 	extern	restart
 	extern	option_reset_all
-	extern	option_check_all
+	extern	option_check_and_store_all
+	extern	option_read_serial
+	extern	option_write_serial
 	extern	gaslist_cleanup_list
-	extern	option_save_all
-	extern	vault_decodata_into_eeprom
+	extern	eeprom_deco_data_write
 
 
-#DEFINE timeout_comm_pre_mode	.240	; timeout before communication is established
-#DEFINE timeout_service_mode	.120	; timeout when communication is established
+; timeouts
+#DEFINE timeout_comm_pre_mode	.240	; [sec] timeout before communication is established
+#DEFINE timeout_service_mode	.120	; [sec] timeout when   communication is established
 
-#DEFINE comm_title_row			.0		; positioning of title
+; positioning of title
+#DEFINE comm_title_row			.0
 #DEFINE comm_title_column_usb	.40
 #DEFINE comm_title_column_ble	.25
 
-#DEFINE comm_string_row			.30		; positioning of host-sent text messages
+; positioning of host-sent text messages
+#DEFINE comm_string_row			.30
 #DEFINE comm_string_column		.40
 
-#DEFINE comm_status1_row		.70		; positioning of COMM mode status messages
+; positioning of COMM mode status messages
+#DEFINE comm_status1_row		.70
 #DEFINE comm_status1_column		.10
 #DEFINE comm_status2_row		.100
 #DEFINE comm_status2_column		comm_status1_column
@@ -51,10 +59,14 @@
 #DEFINE	comm_status4_row		.160
 #DEFINE	comm_status4_column		comm_status1_column
 
-#DEFINE comm_warning_row		.160	; positioning of COMM mode warning messages
+; positioning of COMM mode warning icon
+#DEFINE comm_warning_row		.160
 #DEFINE comm_warning_column		.65
 
 
+;#DEFINE	testloop_avail				; uncomment if testloop code is available
+
+
 comm	CODE
 
 ;=============================================================================
@@ -63,12 +75,12 @@
 comm_mode_usb:										; entry point for comm mode via USB
 	WAITMS	d'1'									; wait 1 ms
 	btfss	vusb_in									; USB still plugged in?
-	return											; NO - it was only a glitch, abort
-	WAITMS	d'1'									; wait 1 ms
-	btfss	vusb_in									; USB still plugged in?
 	return											; NO  - it was only a glitch, abort
-	bsf		aux_flag								; YES - remember to show USB title
-	bra		comm_mode_common						;     - continue with common part
+	WAITMS	d'1'									; YES - wait 1 ms
+	btfss	vusb_in									;     - USB still plugged in?
+	return											;       NO  - it was only a glitch, abort
+	bsf		aux_flag								;       YES - remember to show USB title
+	bra		comm_mode_common						;           - continue with common part
 
 	global	comm_mode_ble
 comm_mode_ble:										; entry point for comm mode via BLE
@@ -76,1134 +88,871 @@
 	;bra	comm_mode_common						; continue with common part
 
 comm_mode_common:
-	clrf	STKPTR									; clear return addresses stack
+	clrf	STKPTR									; reset addresses stack
 	call	TFT_ClearScreen							; clear screen
 	WIN_COLOR color_greenish						; set color
+
 	btfss	aux_flag								; shall show USB title?
-	bra		comm_mode_common_1						; NO
+	bra		comm_mode_common_1						; NO  - show BLE title
 	WIN_SMALL comm_title_column_usb, comm_title_row	; YES - set   USB title position
 	STRCPY_TEXT_PRINT tUsbTitle						;     - print USB title text
-	bra		comm_mode_common_2
+	bra		comm_mode_common_2						;     - continue with common part
+
 comm_mode_common_1:
 	WIN_SMALL comm_title_column_ble, comm_title_row	; set   BLE title position
 	STRCPY_TEXT_PRINT tBleTitle						; print BLE title text
+	;bra	comm_mode_common_2						; continue with common part
+
 comm_mode_common_2:
 	call	TFT_standard_color						; set standard color
-	WIN_TOP  .10									; positioning of USB/BLE logo, row
-	WIN_LEFT .1										; positioning of USB/BLE logo, column
+	WIN_TOP  .10									; set position of USB/BLE logo, row
+	WIN_LEFT .1										; set position of USB/BLE logo, column
 	btfsc	battery_gauge_available					; "+" bootloader ?
-	bra		comm_mode_common_3						; NO
+	bra		comm_mode_common_3						; NO  - show logo type 1
 	TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_2		; YES - show USB/BLE logo 2
-	bra		comm_mode_common_4
+	bra		comm_mode_common_4						;     - continue with common part
+
 comm_mode_common_3:
-	TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_1		; NO  - show USB/BLE logo 1
+	TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_1		; show logo type 1
+	;bra	comm_mode_common_4						; continue with common part
+
 comm_mode_common_4:
-	WIN_SMALL comm_status1_column,comm_status1_row	; positioning of status message
-	STRCPY_TEXT_PRINT tUsbStarting					; print status message "starting..."
+	WIN_SMALL comm_status1_column,comm_status1_row	; print status message "starting..."
+	STRCPY_TEXT_PRINT tUsbStarting					; ...
+
 	WIN_TINY .40,.240-.16							; set output position to bottom line
 	call	TFT_show_serial_and_firmware			; show serial number and firmware version
-	call	option_save_all							; save all settings into EEPROM (comm mode may be entered after settings have been changed without leaving the menu in between)
 
  IFDEF _screendump
-	bcf		screen_dump_avail			; disable screen dump function
+	bcf		screen_dump_avail						; disable screen dump function
  ENDIF
 
-	bcf		switch_right				; clear left-over right button event
-	bcf		comm_service_enabled		; communication is not yet established
-	bsf		surfmode_menu				; flag that restart will be entered from surface menu / comm mode
-	movlw	timeout_comm_pre_mode		; get timeout for phase without communication established yet
-	movwf	comm_timeout_timer			; initialize timeout counter
-	WIN_SMALL comm_status1_column+.80,comm_status1_row
-	STRCPY_TEXT_PRINT tUsbStartDone		; add to status message "done..."
-	call	enable_rs232				; enable serial comm, also sets CPU to normal speed
-comm_mode1:
-	bcf		trigger_full_second			; clear 'one second elapsed' flag
-	bcf		LEDr						; switch off red LED / power down TR co-processor
-	dcfsnz	comm_timeout_timer,F		; decrement timeout, reached zero?
-	bra		comm_service_exit			; YES - timeout, exit comm mode
-comm_mode2:
-	rcall	comm_get_byte				; read 1 byte from RX buffer
-	movlw	0xAA						; coding of service mode start byte: 0xAA
-	cpfseq	RCREG1						; received service mode start byte?
-	bra		comm_mode2a					; NO  - probe for download mode
-	bra		comm_mode2b					; YES - received start byte for service mode
-comm_mode2a:
-	movlw	0xBB						; coding of download mode start byte: 0xBB
-	cpfseq	RCREG1						; received download mode start byte?
-	bra		comm_mode2c					; NO 
-	bra		comm_download_mode			; YES - received start byte for download mode
-comm_mode2c:
-	btfsc	ble_available				; BLE available?
-	bra		comm_mode4a					; YES - skip USB check check (required for very old OSTC sport)
-	btfss	vusb_in						; USB plugged in?
-	bra		comm_service_exit_nousb_delay; NO - disconnected, exit comm mode
-comm_mode4a:
-	btfsc	switch_right				; right button pressed?
-	bra		comm_service_exit			; YES - exit comm mode
-	btfsc	trigger_full_second			; NO  - did 1 second elapsed meanwhile?
-	bra		comm_mode1					;       YES - loop with    clocking down timeout counter
-	bra		comm_mode2					;       NO  - loop without clocking down timeout counter
+	bcf		switch_right							; clear potential left-over right button event
+	call	enable_rs232							; enable serial comm, also sets CPU to normal speed
+
+	WIN_SMALL comm_status1_column+.80,comm_status1_row	; print (adding to status message) "done..."
+	STRCPY_TEXT_PRINT tUsbStartDone						; ...
+
+	movlw	timeout_comm_pre_mode					; get timeout for phase without communication established yet
+	movwf	comm_timeout_timer						; initialize timeout counter
 
-; received start byte for service mode
-comm_mode2b:
-	rcall	comm_write_byte				; wait for completion of transmit
-	movlw	0x4B						; prepare answer
-	movwf	TXREG1						; send    answer
-	; check if correct service key is received
-	rcall	comm_get_byte				; receive first byte
-	rcall	comm_write_byte				; wait for completion of transmit
-	movff	RCREG1,TXREG1				; echo received byte
-	movlw	UPPER comm_service_key		; load expected byte
-	cpfseq	RCREG1						; received expected byte?
-	bra		comm_mode1					; NO - restart
-	rcall	comm_get_byte				; receive second byte
-	rcall	comm_write_byte				; wait for completion of transmit
-	movff	RCREG1,TXREG1				; echo received byte
-	movlw	HIGH (comm_service_key & 0xFFFF) ; load expected byte
-	cpfseq	RCREG1						; received expected byte?
-	bra		comm_mode1					; NO - restart
-	rcall	comm_get_byte				; receive third byte
-	rcall	comm_write_byte				; wait for completion of transmit
-	movff	RCREG1,TXREG1				; echo received byte
-	movlw	LOW comm_service_key		; load expected byte
-	cpfseq	RCREG1						; received expected byte?
-	bra		comm_mode1					; NO - restart
-										; YES to all - enable com service mode
-	WIN_SMALL comm_status2_column, comm_status2_row
-	STRCPY_TEXT_PRINT tUsbServiceMode	; print service mode enabled message
-	bsf		comm_service_enabled		; set flag for com service mode enabled
-	bra		comm_download_mode0			; continue using common routine
-
-comm_service_exit_nousb_delay:
-	WAITMS	d'200'						; wait 200 ms
-	btfsc	vusb_in						; USB plugged in?
-	bra		comm_mode4a					; YES - (still) connected, return
-comm_service_exit_nousb:
-	bcf		LEDr						; switch off red LED
-	WIN_SMALL comm_status3_column, comm_status3_row
-	STRCPY_TEXT_PRINT tUsbClosed		; print port closed message
-	bra		comm_service_exit_common	; exit to restart
-
-comm_service_exit:
-	WIN_SMALL	comm_status3_column, comm_status3_row
-	STRCPY_TEXT_PRINT	tUsbExit		; print exited message
-comm_service_exit_common:
-	rcall	comm_write_byte				; wait for completion of transmit
-	movlw	0xFF						; prepare reply "FF"
-	movwf	TXREG1						; send    reply
-	call	wait_1s						; wait <= 1 second
-	call	wait_1s						; wait    1 second
-	call	disable_rs232				; shut down comm port
-	goto	restart						; restart
+comm_mode_selection_loop:
+	bcf		trigger_full_second						; clear 'one second elapsed' flag
+	bcf		LEDr									; switch off red LED / power down TR co-processor
+	dcfsnz	comm_timeout_timer,F					; decrement timeout, reached zero?
+	bra		comm_service_exit						; YES - timeout, exit comm mode
+	;bra	comm_mode_selection_loop_1				; NO  - try to receive a byte
+comm_mode_selection_loop_1:
+	SERIAL_CC_RECEIVE lo							; (try to) receive 1 byte
+	btfsc	rs232_rx_timeout						; timeout?
+	bra		comm_mode_selection_loop_2				; YES - check for comm mode termination
+	movf	lo,W									; NO  - copy received byte to lo
+	xorlw	0xAA									;     - service mode start byte received?
+	bz		comm_service_mode_check					;       YES - check if correct key will be send
+	movf	lo,W									;       NO  - copy received byte to lo again
+	xorlw	0xBB									;           - download mode start byte received?
+	bz		comm_download_mode						;              YES - enter command loop
+	;bra	comm_mode_selection_loop_2				;              NO  - check for comm mode termination
+comm_mode_selection_loop_2:
+	btfsc	ble_available							; BLE available?
+	bra		comm_mode_selection_loop_3				; YES - skip USB check check (required for very old OSTC sport)
+	btfss	vusb_in									; NO  - USB plugged in?
+	bra		comm_service_exit_nousb_delay			;       NO  - disconnected, check for vusb_in glitch
+	;bra	comm_mode_selection_loop_3				;       YES - check for exit button or continue looping
+comm_mode_selection_loop_3:
+	btfsc	switch_right							; right button pressed?
+	bra		comm_service_exit						; YES - exit comm mode
+	btfsc	trigger_full_second						; NO  - did 1 second elapsed meanwhile?
+	bra		comm_mode_selection_loop				;       YES - loop with    clocking down timeout counter
+	bra		comm_mode_selection_loop_1				;       NO  - loop without clocking down timeout counter
 
 
 ;-----------------------------------------------------------------------------
-; Start Bootloader
-;
-comm_service_ll_bootloader:
-	bsf		LEDr										; switch on red LED
-	WIN_SMALL comm_status3_column, comm_status3_row
-	STRCPY_TEXT_PRINT tUsbLlBld							; print low level bootloader started message
-	WIN_TOP  comm_warning_row							; set row for icon
-	WIN_LEFT comm_warning_column						; set column for icon
-	TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block	; show the warning icon
-	goto	0x1FF0C										; jump into the bootloader code
-
-
-;-----------------------------------------------------------------------------
-; Send Firmware to Bootloader
+; Received start byte for service mode, await service key
 ;
-comm_send_firmware:
-	movlw	0x50						; prepare reply
-	movwf	TXREG1						; send    reply
-	rcall	comm_write_byte				; wait for completion of transmit
-	lfsr	FSR2,buffer					; load base address of buffer
-	movlw	.5							; read 5 bytes into buffer
-	movwf	lo							; initialize loop counter
-	movlw	0x55						; initialize checksum byte
-	movwf	hi							; store in hi
-comm_send_firmware_loop:
-	rcall	comm_get_byte				; receive one byte
-	btfsc	rs232_rx_timeout			; got a byte?
-	bra		comm_send_firmware_abort	; NO  - abort
-	movf	RCREG1,W					; YES - copy received byte to WREG
-	movwf	POSTINC2					;     - copy received byte to buffer
-	xorwf	hi,F						;     - xor  received byte into checksum
-	rlncf	hi,F						;     - rotate checksum byte
-	decfsz	lo,F						;     - decrement loop counter, done?
-	bra		comm_send_firmware_loop		;       NO  - loop
-	movf	hi,W						;       YES - copy checksum to WREG, zero flag set?
-	bnz		comm_send_firmware_failed	;             NO - checksum test failed
-	movlw	0x4C						;             YES - checksum ok, prepare reply
-	movwf	TXREG1						;                 - send reply
-	rcall	comm_write_byte				;                 - wait for completion of transmit
-	call	vault_decodata_into_eeprom	;                 - store last deco data (and time/date) to EEPROM
-	goto	0x1FDF0						;                 - jump into the bootloader code
+comm_service_mode_check:
+
+	SERIAL_LC_SEND 0x4B								; request peer to send service key
+
+	; receive a 3 byte service key transmitted in big-endian, echo each byte
+
+	clrf	WREG									; clear WREG
+
+	SERIAL_CC_RECEIVE lo							; receive 1st byte, store in lo
+	xorwf	lo,W									; exclusive-or received byte into WREG
+	xorlw	UPPER (comm_service_key)				; exclusive-or expected byte into WREG
+	SERIAL_CC_SEND    lo							; echo 1st byte
 
-comm_send_firmware_failed:
-	WIN_SMALL comm_string_column, comm_string_row
-	call	TFT_warning_color			; set warning color
-	STRCPY_PRINT "Checksum failed"		; print failure message
-comm_send_firmware_abort:
-	movlw	0xFF						; prepare reply for ABORTED
-	movwf	TXREG1						; send reply
-	bra		comm_download_mode0			; done
+	SERIAL_CC_RECEIVE lo							; receive 2nd byte, store in lo
+	xorwf	lo,W									; exclusive-or received byte into WREG
+	xorlw	HIGH  (comm_service_key & 0xFFFF)		; exclusive-or expected byte into WREG
+	SERIAL_CC_SEND    lo							; echo 2nd byte
+
+	SERIAL_CC_RECEIVE lo							; receive 3rd byte, store in lo
+	xorwf	lo,W									; exclusive-or received byte into WREG
+	xorlw	LOW   (comm_service_key & 0xFFFF)		; exclusive-or expected byte into WREG
+	SERIAL_CC_SEND    lo							; echo 3rd byte
+
+	; check for correct service key
+	tstfsz	WREG									; received expected service key?
+	bra		comm_mode_selection_loop				; NO  - back to mode selection loop
+	WIN_SMALL comm_status2_column, comm_status2_row	; YES - print service mode enabled message
+	STRCPY_TEXT_PRINT tUsbServiceMode				;     - ...
+	bsf		comm_service_mode						;     - enable service mode commands
+	bra		comm_command_loop						;     - enter command loop
 
 
 ;-----------------------------------------------------------------------------
-; Reset to Dive 1 in Logbook
+; Received start byte for download mode
 ;
-comm_reset_logbook_pointers:
-	call	eeprom_reset_logbook_pointers	; clear logbook pointers in EEPROM
-	call	ext_flash_erase_logbook			; clear complete logbook(!)
-	bra		comm_download_mode0				; done
+comm_download_mode:
+	SERIAL_LC_SEND 0xBB								; inform peer download mode will be started
 
-;-----------------------------------------------------------------------------
-; Reset Battery Gauge
-;
-comm_reset_battery_gauge:				; reset battery gauge registers
-	call	reset_battery_pointer		; reset battery pointer 0x07-0x0C and battery gauge
-	bra		comm_download_mode0			; done
+	WIN_SMALL comm_status2_column, comm_status2_row	; print download mode enabled message
+	STRCPY_TEXT_PRINT tUsbDownloadMode				; ... 
+	bcf		comm_service_mode						; disable service mode commands
+	bra		comm_command_loop						; enter command loop
+
 
 ;-----------------------------------------------------------------------------
-; Erase a Memory Range given byte Start Address and Number of 4 kB Blocks
+; Notify RX timeout occurred
 ;
-comm_erase_range4kb:
-	movlw	0x42						; prepare reply
-	movwf	TXREG1						; send reply
-	rcall	comm_write_byte				; wait for completion of transmit
-	bcf		INTCON,GIE					; disable all interrupts
-	rcall	comm_get_flash_address		; get three bytes start address or return
-	btfsc	rs232_rx_timeout			; got start address?
-	bra		comm_download_mode0			; NO  - done
-	rcall	comm_get_byte				; YES - get number of blocks
-	btfsc	rs232_rx_timeout			;     - got number?
-	bra		comm_download_mode0			;       NO  - done
-	movff	RCREG1,lo					;       YES - copy number of blocks to lo
-comm_erase_range4kb_loop:
-	call	ext_flash_erase4kB			;           - erase a memory block
-	movlw	0x10						;           - increase start address by 4096 (0x1000)
-	addwf	ext_flash_address+1,F		;           - ...
-	movlw	.0							;           - ...
-	addwfc	ext_flash_address+2,F		;           - ...
-	decfsz	lo,F						;           - decrement block counter, all blocks done?
-	bra		comm_erase_range4kb_loop	;             NO  - loop
-	bra		comm_download_mode0			;             YES - done
+comm_command_timeout:
+	; select font and output position
+	WIN_SMALL comm_string_column, comm_string_row
+	call	TFT_warning_color			; select color
+	STRCPY_PRINT "Data Rx Timeout"		; print failure message (fill to 15 chars)
+	call	TFT_standard_color			; back to standard color
+	bra		comm_command_loop			; re-enter command loop
+
 
 ;-----------------------------------------------------------------------------
-; Erase one Memory Block of 4 kB Size
-;
-comm_erase_4kb:
-	bcf		INTCON,GIE					; disable all interrupts
-	rcall	comm_get_flash_address		; get three bytes start address or return
-	btfsc	rs232_rx_timeout			; got start address?
-	bra		comm_download_mode0			; NO  - done
-	call	ext_flash_erase4kB			; YES - erase memory block
-	bra		comm_download_mode0			;     - done
-
-;-----------------------------------------------------------------------------
-; Write a Stream of Data Bytes to Memory
+; Notify error in parameters
 ;
-comm_write_range:
-	movlw	0x30						; prepare reply
-	movwf	TXREG1						; send    reply
-	rcall	comm_write_byte				; wait for completion of transmit
-	bcf		INTCON,GIE					; disable all interrupts
-	rcall	comm_get_flash_address		; get three bytes starts address or return
-	btfsc	rs232_rx_timeout			; got start address?
-	bra		comm_download_mode0			; NO  - done
-comm_write_range_loop:
-	rcall	comm_get_byte				; YES - get data byte to write to memory
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO  - done
-	movf	RCREG1,W					; YES - copy received data byte to WREG
-;	bsf		NCTS						;     - hold Bluetooth chip (requires PC/Android/iOS side to use flow control...)
-	call	ext_flash_byte_write_comms	;     - write data byte to flash memory
-;	bcf		NCTS						;     - release Bluetooth chip (requires PC/Android/iOS side to use flow control...)
-	call	incf_ext_flash_address_p1	;     - increase address
-	bra		comm_write_range_loop		;     - loop
+comm_command_error:
+	; select font and output position
+	WIN_SMALL comm_string_column, comm_string_row
+	call	TFT_warning_color			; switch to waring color
+	STRCPY_PRINT "Parameter Error"		; print failure message (fill to 15 chars)
+	call	TFT_standard_color			; back to standard color
+	;bra	comm_command_loop			; re-enter command loop
 
 
 ;-----------------------------------------------------------------------------
-; Read a Memory Section given by Start Address and Length
+; Command loop: wait for a command
 ;
-comm_send_range:
-	movlw	0x20						; prepare reply
-	movwf	TXREG1						; send    reply
-	rcall	comm_write_byte				; wait for completion of transmit
-	bcf		INTCON,GIE					; disable all interrupts
-	rcall	comm_get_flash_address		; get three bytes start address or return
-	btfsc	rs232_rx_timeout			; got start address?
-	bra		comm_download_mode0			; NO - done
-	rcall	comm_get_byte				; get length, 3rd byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - done
-	movff	RCREG1,up					; store length, 3rd byte
-	rcall	comm_get_byte				; get length, 2nd byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - done
-	movff	RCREG1,hi					; store length, 2nd byte
-	rcall	comm_get_byte				; get length, 1st byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - done
-	movff	RCREG1,lo					; store length, 1st byte
-	; if lo==0, we must precondition hi because there are too many bytes sent
-	movf	lo,W
-	bnz		$+4
-	decf	hi,F
-	movlw	0x40
-	cpfslt	up							; up > 0x3F ?
-	bra		comm_download_mode0			; YES - abort
-	; 6 bytes received, send data
-	; needs ext_flash_address:3 start address and up:hi:lo amount
-	call	ext_flash_read_block_start
-	movwf	TXREG1
-	bra		comm_send_range24			; counter 24 bit
-comm_send_range24_loop:
-	call	ext_flash_read_block		; read one byte
-	movwf	TXREG1						; start new transmit
-comm_send_range24:
-	rcall	comm_write_byte				; wait for completion of transmit
-	decfsz	lo,F
-	bra		comm_send_range24_loop
-	decf	hi,F
-	movlw	0xFF
-	cpfseq	hi
-	bra		comm_send_range24_loop
-	decf	up,F
-	movlw	0xFF
-	cpfseq	up
-	bra		comm_send_range24_loop
-	call	ext_flash_read_block_stop
-	bra		comm_download_mode0			; done
+comm_command_loop:
+	; (re-)initialize
+	bsf		INTCON,GIE								; re-enable all interrupts
+	movlw	timeout_service_mode					; get    timeout value
+	movwf	comm_timeout_timer						; reload timeout timer
 
-;-----------------------------------------------------------------------------
-
-comm_get_flash_address:
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	return								; NO - return
-	movff	RCREG1,ext_flash_address+2
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	return								; NO - return
-	movff	RCREG1,ext_flash_address+1
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	return								; NO - return
-	movff	RCREG1,ext_flash_address+0
-	return
-
-;-----------------------------------------------------------------------------
+	; request peer to send a command
+	movlw	0x4D									; default request code is 0x4D for download mode active
+	btfsc	comm_service_mode						; service mode enabled?
+	movlw	0x4C									; YES - change request to 0x4C for service  mode active
+	SERIAL_CC_SEND WREG								; send request
 
-comm_download_mode:
-	; Enable comm download mode
-	WIN_SMALL comm_status2_column, comm_status2_row
-	STRCPY_TEXT_PRINT tUsbDownloadMode	; download mode enabled
-	bsf		INTCON,GIE					; all interrupts on
-	rcall	comm_write_byte				; wait for completion of transmit
-	movlw	0xBB						; command echo
-	movwf	TXREG1						; send answer
-comm_download_mode0:
-	bsf		INTCON,GIE					; all interrupts on
-	rcall	comm_write_byte				; wait for completion of transmit
-	movlw	0x4C						; default reply is 4C for service mode
-	btfss	comm_service_enabled		; com service enabled?
-	movlw	0x4D						; NO - change to reply 4D for download mode
-	movwf	TXREG1						; send answer
-	movlw	timeout_service_mode		; get timeout value
-	movwf	comm_timeout_timer			; load into timeout counter
-	bcf		switch_right				; clear left-over button event
-comm_download_mode1:
-	bcf		trigger_full_second			; clear 'one second elapsed' flag
-	dcfsnz	comm_timeout_timer,F		; decrement timeout, reached zero?
-	bra		comm_service_exit			; YES - exit
-comm_download_mode2:
-	rcall	comm_get_byte				; NO - check for a byte
-	btfsc	comm_service_enabled		;      com service mode enabled?
-	btg		LEDr						;      YES - blink in service mode
-	btfsc	ble_available				;      BLE available?
-	bra		comm_download_mode3			;      YES - skip USB check (required for very old OSTC sport)
-	btfss	vusb_in						;      USB plugged in?
-	bra		comm_service_exit_nousb		;      NO  - disconnected -> exit
-comm_download_mode3:
-	btfsc	switch_right				; shall abort?
-	bra		comm_service_exit			; YES
-	btfsc	trigger_full_second			; NO  - did 1 second elapsed meanwhile?
-	bra		comm_download_mode1			;       YES - check for timeout
-	btfsc	rs232_rx_timeout			;       NO  - got a byte?
-	bra		comm_download_mode2			;             NO - loop waiting for command byte
-	; Command received
-	bcf		LEDr
-	movlw	0xFF
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_service_exit			; exit
-	movlw	"a"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_send_headers			; send all 256 dive headers
-	movlw	"b"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_set_time				; read time and date from the PC and set clock
-	movlw	"c"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_set_custom_text		; send a opt_name_length byte string of custom text
-	movlw	"f" 						; 0x66
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_send_dive				; send header and profile for one dive
-	movlw	"i"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_identify				; send firmware, serial, etc.
-	movlw	"j"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_hardware_descriptor	; send hardware descriptor byte
-	movlw	0x60
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_feature_and_hardware	; send more detailed information
-	movlw	"n"
-	cpfseq	RCREG1
-	bra		$+4
-	goto	comm_send_string			; send a 15 byte string to the screen
-	movlw	"m"
-	cpfseq	RCREG1
-	bra		$+4
-	goto	comm_send_compact_headers	; send all 256 compact headers
- IFDEF _screendump
-	movlw	"l"
-	cpfseq	RCREG1
-	bra	$+4
-	call	TFT_dump_screen				; dump the screen contents
- ENDIF
-	movlw	"r"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_read_setting			; read a setting (and send via USB)
-	movlw	"w"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_write_setting			; write a setting (into RAM)
-	movlw	"x"
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_option_reset_all		; reset all options to factory default
-
-	btfss	comm_service_enabled		; done for download mode
-	bra		comm_download_mode0			; loop with timeout reset
-
-	movlw	0x20
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_send_range				; send hi:lo:ext_flash_rw bytes starting from ext_flash_address:3
-	movlw	0x22
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_reset_logbook_pointers	; reset all logbook pointers and the logbook
-	movlw	0x23
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_reset_battery_gauge	; reset battery gauge registers
-	movlw	0x30
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_write_range			; write bytes starting from ext_flash_address:3 (stop when timeout)
-	movlw	0x40
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_erase_4kb				; erase 4 kB block from ext_flash_address:3 (Warning: no confirmation or built-in security here...)
-	movlw	0x42
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_erase_range4kb			; erase range in 4 kB steps (get 3 bytes address and 1 byte amount of 4 kB blocks)
-	movlw	0x50
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_send_firmware			; send firmware to bootloader
-;	movlw	"t"
-;	cpfseq	RCREG1
-;	bra		$+4
-;	goto	testloop					; start raw-data test loop
-	movlw	0xC1
-	cpfseq	RCREG1
-	bra		$+4
-	bra		comm_service_ll_bootloader	; start low-level bootloader
-	bra		comm_download_mode0			; loop with timeout reset
-
-;-----------------------------------------------------------------------------
-
-comm_send_compact_headers:
-	movlw	"m"							; send echo
-	movwf	TXREG1
-	; send 13 bytes/dive (compact header)
-	; 1st: 200009h-200016h
-	; 2nd: 201009h-201016h
-	; 3rd: 202009h-202016h
-	; 100: 264009h-264016h
-	; 256: 2FF009h-2FF016h
-	movlw	0x1F
-	movwf	ext_flash_address+2
-	movlw	0xF0
-	movwf	ext_flash_address+1
-
-comm_send_compact_headers2:
-	movlw	0x09
-	movwf	ext_flash_address+0
-	; adjust address for next dive
-	movlw	0x10
-	addwf	ext_flash_address+1
-	movlw	0x00
-	addwfc	ext_flash_address+2
-
-	movlw	0x30
-	cpfseq	ext_flash_address+2			; all 256 dive send?
-	bra		comm_send_compact_headers4	; NO - continue
-	bra		comm_download_mode0			; done, loop with timeout reset
-
-comm_send_compact_headers4:
-	movlw	.13
-	movwf	lo							; counter
-	rcall	comm_write_byte				; wait for completion of transmit
-	call	ext_flash_read_block_start	; 1st byte
-	movwf	TXREG1
-	bra		comm_send_compact_headers3	; counter 24 bit
-comm_send_compact_headers_loop:
-	call	ext_flash_read_block		; read one byte
-	movwf	TXREG1						; start new transmit
-comm_send_compact_headers3:
-	rcall	comm_write_byte				; wait for completion of transmit
-	decfsz	lo,F
-	bra		comm_send_compact_headers_loop
-	call	ext_flash_read_block_stop
-
-	; Offset to total dive counter
-	movlw	.80
-	movwf	ext_flash_address+0
-	call	ext_flash_read_block_start	; 1st byte
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
-	call	ext_flash_read_block		; 2nd byte
-	movwf	TXREG1
-	call	ext_flash_read_block_stop
-	rcall	comm_write_byte				; wait for completion of transmit
-
-	; Offset to Logbook-Profile version
-	movlw	.8
-	movwf	ext_flash_address+0
-	call	ext_flash_byte_read			; get byte
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
-	bra		comm_send_compact_headers2	; continue
+	; wait for peer to send a command
+comm_command_loop_wait:
+	SERIAL_CC_RECEIVE lo							; (try to) receive a command byte
+	btfss	rs232_rx_timeout						; timeout?
+	bra		comm_command_decode						; NO  - decode and execute the command
+	btfsc	comm_service_mode						; YES - service mode enabled?
+	btg		LEDr									;       YES - blink in service mode
+	btfsc	ble_available							;     - BLE available?
+	bra		comm_command_loop_wait_1				;       YES - skip USB check (required for very old OSTC sport)
+	btfss	vusb_in									;       NO  - USB still plugged in?
+	bra		comm_service_exit_nousb					;             NO  - disconnected -> exit comm mode
+comm_command_loop_wait_1:
+	btfsc	switch_right							; right button (abort) pressed?
+	bra		comm_service_exit						; YES - exit comm mode
+	btfss	trigger_full_second						; NO  - did 1 second elapsed meanwhile?
+	bra		comm_command_loop_wait					;       NO  - loop
+	dcfsnz	comm_timeout_timer,F					;       YES - decrement the timeout timer, reached zero?
+	bra		comm_service_exit						;             YES - exit comm mode
+	bcf		trigger_full_second						;             NO  - clear 'one second elapsed' flag
+	bra		comm_command_loop_wait					;                 - loop
 
 
 ;-----------------------------------------------------------------------------
-
-comm_send_headers:
-	movlw	"a"							; send echo
-	movwf	TXREG1
-	; Send 256 bytes/dive (Header)
-	; 1st: 200000h-2000FFh
-	; 2nd: 201000h-2010FFh
-	; 3rd: 202000h-2020FFh
-	; 100: 264000h-2640FFh
-	; 256: 2FF000h-2FF0FFh
-	movlw	0x1F
-	movwf	ext_flash_address+2
-	movlw	0xF0
-	movwf	ext_flash_address+1
-comm_send_headers2:
-	clrf	ext_flash_address+0
-	; Adjust address for next dive
-	movlw	0x10
-	addwf	ext_flash_address+1
-	movlw	0x00
-	addwfc	ext_flash_address+2
-	movlw	0x30
-	cpfseq	ext_flash_address+2			; all 256 dive send?
-	bra		comm_send_headers4			; NO - continue
-	bra		comm_download_mode0			; done, loop with timeout reset
-comm_send_headers4:
-	clrf	lo							; counter
-	rcall	comm_write_byte				; wait for completion of transmit
-	call	ext_flash_read_block_start	; 1st byte
-	movwf	TXREG1
-	bra		comm_send_headers3			; counter 24 bit
-comm_send_headers_loop:
-	call	ext_flash_read_block		; read one byte
-	movwf	TXREG1						; start new transmit
-comm_send_headers3:
-	rcall	comm_write_byte				; wait for completion of transmit
-	decfsz	lo,F
-	bra		comm_send_headers_loop
-	call	ext_flash_read_block_stop
-	bra		comm_send_headers2			; continue
+; Macro for easier writing of command decoding rules
+;
+command_decode  macro  command_id,command_function
+	movf	lo,W				; copy received command to WREG
+	xorlw	command_id			; exclusive-or with command ID
+	btfsc	STATUS,Z			; received command = command ID ?
+	goto	command_function	; YES - execute command
+	endm
 
 ;-----------------------------------------------------------------------------
+; Decode and execute a command
+;
+comm_command_decode:
+	bcf		LEDr									; switch off red led
 
-comm_option_reset_all:					; reset all options to factory default
-	movlw	"x"							; send echo
-	movwf	TXREG1
-	call	option_reset_all
-	bra		comm_download_mode0			; done, back to loop with timeout reset
+	; decode and execute standard commands
+	command_decode 0x6E,comm_show_text				; n  show a text on the screen
+	command_decode 0x69,comm_identify				; i  send ID: serial, firmware, and custom text
+	command_decode 0x6A,comm_hardware_descriptor	; j  send ID: hardware descriptor byte
+	command_decode 0x60,comm_feature_and_hardware	; '  send ID: more detailed information
+	command_decode 0x6D,comm_send_headers_short 	; m  send all headers in compact format
+	command_decode 0x61,comm_send_headers_full		; a  send all headers is full format
+	command_decode 0x66,comm_send_dive				; f  send header and profile for one dive
+	command_decode 0x62,comm_set_time				; b  set the real time clock
+	command_decode 0x63,comm_set_custom_text		; c  write a new custom text
+	command_decode 0x72,comm_read_option			; r  read  an option value
+	command_decode 0x77,comm_write_option			; w  write an option value (into RAM)
+	command_decode 0x78,comm_option_reset_all		; x  reset all option values to their factory default
+	command_decode 0xFF,comm_service_exit			;    exit comm mode
+ IFDEF _screendump
+	command_decode 0x6C,TFT_dump_screen				; l  dump the screen contents
+ ENDIF
+
+	btfss	comm_service_mode						; service mode enabled?
+	bra		comm_command_loop						; NO - ignore unrecognized command, back to command loop
+
+	; decode and execute additional service mode commands
+	command_decode 0x23,comm_reset_battery_gauge	; #  reset the battery gauge registers
+	command_decode 0x22,comm_erase_complete_logbook	; "  reset all logbook pointers and the logbook
+	command_decode 0x20,comm_read_range				;' '  read a memory range from the external FLASH
+	command_decode 0x40,comm_erase_4kb				; @  erase one        4 kB block  - Warning: no confirmation or built-in safety here...
+	command_decode 0x42,comm_erase_range4kb			; B  erase a range of 4 kB blocks - Warning: no confirmation or built-in safety here...
+	command_decode 0x30,comm_write_range_stream		; 0  write a stream of     bytes starting at ext_flash_address:3 until timeout
+	command_decode 0x31,comm_write_range_block		; 1  write a block  of 256 bytes starting at ext_flash_address:3
+	command_decode 0x50,comm_firmware_update		; P  initiate firmware update
+	command_decode 0xC1,comm_cold_start				;    start low-level bootloader
+ IFDEF testloop_avail
+	command_decode 0x74,testloop					; t  start raw-data test loop
+ ENDIF
+
+	bra		comm_command_loop						; ignore unrecognized command, back to command loop
+
 
 ;-----------------------------------------------------------------------------
+; Exit comm mode
+;
+comm_service_exit:
+	WIN_SMALL comm_status3_column, comm_status3_row	; print "Exited" message
+	STRCPY_TEXT_PRINT	tUsbExit					; ...
+	bra		comm_service_exit_common				; acknowledge exit command and restart
 
-comm_set_time:
-	movlw	"b"							; send echo
-	movwf	TXREG1
+comm_service_exit_nousb_delay:
+	WAITMS	d'200'									; wait 200 ms
+	btfsc	vusb_in									; USB sensed again?
+	bra		comm_mode_selection_loop_3				; YES - was just a glitch, continue
+	;bra	comm_service_exit_nousb					; NO  - proceed exiting
 
-	rcall	comm_write_byte				; wait for completion of transmit
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - abort
-	movff	RCREG1, rtc_latched_hour
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - abort
-	movff	RCREG1, rtc_latched_mins
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - abort
-	movff	RCREG1, rtc_latched_secs
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - abort
-	movff	RCREG1, rtc_latched_month
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - abort
-	movff	RCREG1, rtc_latched_day
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - abort
-	movff	RCREG1, rtc_latched_year
-	call	rtc_set_rtc					; write time and date to RTC module
-	bra		comm_download_mode0			; done, back to loop with timeout reset
+comm_service_exit_nousb:
+	WIN_SMALL comm_status3_column, comm_status3_row	; print "Port closed" message
+	STRCPY_TEXT_PRINT tUsbClosed					; ...
+	;bra	comm_service_exit_common				; proceed exiting
+
+comm_service_exit_common:
+	SERIAL_LC_SEND 0xFF								; acknowledge exit command
+	call	wait_1s									; wait <= 1 second
+	call	wait_1s									; wait    1 second
+	call	disable_rs232							; shut down comm port
+	bcf		LEDr									; switch off red LED
+	goto	restart									; restart
+
 
 ;-----------------------------------------------------------------------------
-; Set custom text string (opt_name_length ASCII chars)
+; Set Real-Time-Clock
 ;
+comm_set_time:
+	SERIAL_LC_SEND 0x62					; acknowledge command
+
+	; receive 6 bytes coming in sequence: hour, minute, second, month, day, year
+	SERIAL_RR_RECEIVE_RAM mpr,.6
+
+	; got all 6 bytes?
+	btfsc	rs232_rx_timeout			; timeout?
+	bra		comm_command_timeout		; YES - abort, back to command loop
+
+	; map the received bytes onto the rtc_latched variables
+	movff	mpr+0,rtc_latched_hour
+	movff	mpr+1,rtc_latched_mins
+	movff	mpr+2,rtc_latched_secs
+	movff	mpr+3,rtc_latched_month
+	movff	mpr+4,rtc_latched_day
+	movff	mpr+5,rtc_latched_year
 
-comm_set_custom_text:
-	movlw	"c"							; send echo
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
-	lfsr	FSR2,opt_name
-	movlw	opt_name_length
-	movwf	lo							; counter
-comm_set_ctext_loop:
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_set_ctext_loop_done	; NO - abort
-	movff	RCREG1,POSTINC2				; store character
-	decfsz	lo,F
-	bra		comm_set_ctext_loop
-comm_set_ctext_loop_done:
-	tstfsz	lo							; got opt_name_length bytes?
-	bra		comm_set_ctext_loop_done2	; NO - clear remaining chars
-	bra		comm_download_mode0			; done, loop with timeout reset
-comm_set_ctext_loop_done2:
-	clrf	POSTINC2
-	decfsz	lo,F
-	bra		comm_set_ctext_loop_done2
-	bra		comm_download_mode0			; done, loop with timeout reset
+	; set the RTC
+	call	rtc_set_rtc					; write time and date to RTC module
+
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Write a 15 char text to the OSTC display
+;
+comm_show_text:
+	; set font and output position of the text to show
+	WIN_SMALL comm_string_column, comm_string_row
+
+	SERIAL_LC_SEND 0x6E					; acknowledge command
+
+	SERIAL_RR_RECEIVE_RAM buffer,.16	; (try to) receive 16 chars and write them to 'buffer' using FSR2
+	STRCAT_PRINT ""						; dump whatever was received to the screen
+
+	bra		comm_command_loop			; done, back to command loop
+
 
 ;-----------------------------------------------------------------------------
 ; Reply Serial (2 bytes low:high), firmware (major.minor) and custom text
 ;
-
 comm_identify:
-	movlw	"i"							; send echo
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
+	SERIAL_LC_SEND 0x69					; acknowledge command
 
-	;---- Read serial from internal EEPROM address 0000
-	clrf	EEADRH
-	clrf	EEADR						; get serial number LOW
-	call	read_eeprom					; read byte
-	movff	EEDATA,lo
-	incf	EEADR,F						; get serial number HIGH
-	call	read_eeprom					; read byte
-	movff	EEDATA,hi
-
-	;---- Emit serial number
-	movff	lo,TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
-	movff	hi,TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
+	;---- send OSTC serial number
+	call	eeprom_serial_number_read	; read OSTC serial number
+	SERIAL_CC_SEND mpr+0				; send serial number, low  byte
+	SERIAL_CC_SEND mpr+1				; send serial number, high byte
 
-	;---- Emit firmware hi.lo
-	movlw	softwareversion_x
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
-	movlw	softwareversion_y
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
-
-	;---- Emit custom text
-	movlw	opt_name_length
-	movwf	hi
-	lfsr	FSR2,opt_name
+	;---- send firmware version
+	SERIAL_LC_SEND fw_version_major		; send firmware version, major
+	SERIAL_LC_SEND fw_version_minor		; send firmware version, minor
 
-common_identify_loop:
-	movff	POSTINC2,TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
-	decfsz	hi,F
-	bra		common_identify_loop
-
-	bra		comm_download_mode0			; done
+	;---- send custom text
+	SERIAL_RR_SEND_RAM	opt_name,opt_name_length
 
-;-----------------------------------------------------------------------------
-
-comm_get_byte:
-	goto	rs232_get_byte				; ... and return
-
-comm_write_byte:						; wait for completion of transmit
-	goto	rs232_wait_tx				; ... and return
+	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
 ; Reply hardware descriptor byte
 ;
 comm_hardware_descriptor:
-	movlw	"j"							; prepare echo
-	movwf	TXREG1						; send    echo
-	rcall	comm_write_byte				; wait for completion of transmit
+	SERIAL_LC_SEND 0x6A					; acknowledge command
 
 	movf	HW_descriptor,W				; get hardware descriptor
 	bcf		WREG,6						; clear bit 6 for reason of compatibility with 3rd party software
 	bcf		WREG,7						; clear bit 7 for reason of compatibility with 3rd party software
-	movwf	TXREG1						; send hardware descriptor
+	SERIAL_CC_SEND WREG					; send modified hardware descriptor
+
+	bra		comm_command_loop			; done, back to command loop
 
-	bra		comm_download_mode0			; done
 
+;-----------------------------------------------------------------------------
+; Reply detailed hardware descriptor
+;
 comm_feature_and_hardware:
-	movlw	0x60						; send echo
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
+	SERIAL_LC_SEND 0x60					; acknowledge command
 
-	movlw	0x00						; hardware high byte
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
+	SERIAL_LC_SEND 0x00					; send hardware high byte (fixed zero)
 
 	movf	HW_descriptor,W				; get hardware descriptor
 	bcf		WREG,6						; clear bit 6 for reason of compatibility with 3rd party software
 	bcf		WREG,7						; clear bit 7 for reason of compatibility with 3rd party software
-	movwf	TXREG1						; send hardware descriptor
-	rcall	comm_write_byte				; wait for completion of transmit
+	SERIAL_CC_SEND WREG					; send modified hardware low byte
 
-	movlw	0x00						; feature high Byte
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
+	SERIAL_LC_SEND 0x00					; send feature high byte (fixed zero)
+	SERIAL_LC_SEND 0x00					; send feature low  byte (fixed zero)
 
-	movlw	0x00						; feature low Byte
-	movwf	TXREG1
-	rcall	comm_write_byte				; wait for completion of transmit
+	SERIAL_LC_SEND 0x00					; send model descriptor byte (fixed zero)
 
-	movlw	0x00						; model descriptor byte
-	movwf	TXREG1
+	bra		comm_command_loop			; done, back to command loop
 
-	bra		comm_download_mode0			; done
 
 ;-----------------------------------------------------------------------------
 
-comm_send_dive:
-	movlw	"f"; 0x66					; send echo
-	movwf	TXREG1
+comm_send_headers_short:
+	SERIAL_LC_SEND 0x6D					; acknowledge command
 
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_download_mode0			; NO - abort!
-	movff	RCREG1,lo					; store dive number (0-255)
-; First, send the header (again)
-	; 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
-	; 256: 2FF000h-2FFFFFh -> lo=255
-	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
+	; send short header (16 bytes/dive)
+	; index 0: 0x200009 - 0x200016  +  0x200050 - 0x200051  +  0x200008
+	;       1: 0x201009 - 0x201016  +  0x201050 - 0x201051  +  0x201008
+	;       2: 0x202009 - 0x202016  +  0x202050 - 0x202051  +  0x202008
+	;     ...
+	;     255: 0x2FF009 - 0x2FF016  +  0x2FF050 - 0x2FF051  +  0x2FF008
 
-	incf_ext_flash_address d'2'			; skip 0xFA, 0xFA
-	call	ext_flash_byte_read_plus	; read start address of profile
-	movff	ext_flash_rw,ext_flash_log_pointer+0
-	call	ext_flash_byte_read_plus	; read start address of profile
-	movff	ext_flash_rw,ext_flash_log_pointer+1
-	call	ext_flash_byte_read_plus	; read start address of profile
-	movff	ext_flash_rw,ext_flash_log_pointer+2
-	call	ext_flash_byte_read_plus	; read end address of profile
-	movff	ext_flash_rw,ext_flash_end_pointer+0
-	call	ext_flash_byte_read_plus	; read end address of profile
-	movff	ext_flash_rw,ext_flash_end_pointer+1
-	call	ext_flash_byte_read_plus	; read end address of profile
-	movff	ext_flash_rw,ext_flash_end_pointer+2
-	decf_ext_flash_address	d'8'		; back again to first 0xFA in header
-
-	movf	ext_flash_log_pointer+0,W
-	cpfseq	ext_flash_end_pointer+0		; equal?
-	bra		comm_send_dive1				; NO - send header
-
-	movf	ext_flash_log_pointer+1,W
-	cpfseq	ext_flash_end_pointer+1		; equal?
-	bra		comm_send_dive1				; NO - send header
+	clrf	ex								; start with dive having index 0
+comm_send_headers_short_loop:
+	movf	ex,W							; get index into WREG
+	call	log_header_addr_by_index		; compute header start address from index, result in mpr
 
-	movf	ext_flash_log_pointer+2,W
-	cpfseq	ext_flash_end_pointer+2		; equal?
-	bra		comm_send_dive1				; NO - send header
-
-	; Start=End -> Not good, abort
-	bra		comm_download_mode0			; done, loop with timeout reset
+	; assemble the short header - part 1
+	movlw	index_profile_byte_count		; adjust start address to first  block to go into the short header
+	movwf	mpr+0							; ...
+	FLASH_RR_READ mpr,header_buffer,.13		; read 13 bytes from header into buffer
 
-comm_send_dive1:
-	; Send header
-	clrf	hi							; counter
-	rcall	comm_write_byte				; wait for completion of transmit
-	call	ext_flash_read_block_start	; 1st byte
-	movwf	TXREG1
-	bra		comm_send_dive_header
-comm_send_dive_header2:
-	call	ext_flash_read_block		; read one byte
-	movwf	TXREG1						; start new transmit
-comm_send_dive_header:
-	rcall	comm_write_byte				; wait for completion of transmit
-	decfsz	hi,F
-	bra		comm_send_dive_header2
-	call	ext_flash_read_block_stop
+	; assemble the short header - part 2
+	movlw	index_total_dives				; adjust start address to second block to into the short header
+	movwf	mpr+0							; ...
+	FLASH_RR_READ mpr,header_buffer+.13,.2	; read  2 bytes from header into buffer
 
-	; Set address for profile
-	movff	ext_flash_log_pointer+0,ext_flash_address+0
-	movff	ext_flash_log_pointer+1,ext_flash_address+1
-	movff	ext_flash_log_pointer+2,ext_flash_address+2
-
-	movlw	.6								; skip 6 byte short header in profile - only for internal use
-	call	incf_ext_flash_address0_0x20	; increases bytes in ext_flash_address:3 with 0x200000 bank switching
-
-	; Set address for short header/compact header, Byte 0
+	; assemble the short header - part 3
+	movlw	index_profile_version			; adjust start address to third  block to go into the short header
+	movwf	mpr+0							; ...
+	FLASH_RR_READ mpr,header_buffer+.15,.1	; read  1 byte  from header into buffer
 
-comm_send_dive_profile:
-	call	ext_flash_byte_read_plus_0x20	; read one byte into ext_flash_rw, takes care of banking at 0x200000
-	rcall	comm_write_byte					; wait for completion of transmit
-	movff	ext_flash_rw,TXREG1				; send a byte
+	; send the assembled short header
+	SERIAL_RR_SEND_RAM header_buffer,.16	; send buffer, 16 bytes to do
 
-	; 24bit compare with end address
-	movff	ext_flash_end_pointer+0,WREG
-	cpfseq	ext_flash_address+0
-	bra		comm_send_dive_profile
-	movff	ext_flash_end_pointer+1,WREG
-	cpfseq	ext_flash_address+1
-	bra		comm_send_dive_profile
-	movff	ext_flash_end_pointer+2,WREG
-	cpfseq	ext_flash_address+2
-	bra		comm_send_dive_profile
+	; go to next header
+	incfsz	ex								; increment index, wrap-around. i.e. all dives done ?
+	bra		comm_send_headers_short_loop	; NO  - loop
+	bra		comm_command_loop				; YES - done, back to command loop
 
-	rcall	comm_write_byte				; wait for completion of transmit
-	bra		comm_download_mode0			; done, loop with timeout reset
 
 ;-----------------------------------------------------------------------------
 
-comm_read_setting:
-	movlw	"r"
-	movwf	TXREG1
-	rcall	comm_get_byte
-	btfsc	rs232_rx_timeout			; got byte?
-	bra		comm_read_abort				; NO - abort
-	rcall	comm_write_byte				; wait for completion of transmit
-	movlw	0x0F
-	cpfsgt	RCREG1						; 0x00-0x0F: unused
-	bra		comm_read_abort				; abort!
-	subwf	RCREG1,W					; subtract unused commands
+comm_send_headers_full:
+	SERIAL_LC_SEND 0x61					; acknowledge command
+
+	; send complete headers (256 bytes/dive)
+	; index 0: 0x200000 - 0x2000FF
+	;       1: 0x201000 - 0x2010FF
+	;       2: 0x202000 - 0x2020FF
+	;     ...
+	;     255: 0x2FF000 - 0x2FF0FF
+
+	clrf	ex								; start with dive having index 0
+comm_send_headers_full_loop:
+	movf	ex,W							; get index into WREG
+	call	log_header_addr_by_index		; compute header start address from index, result in mpr
+	FLASH_RR_READ  mpr,header_buffer,.256	; get header from FLASH into memory
+	SERIAL_RR_SEND_RAM header_buffer,.256	; send the header from memory to RS232
+	incfsz	ex								; increment index, wrap-around. i.e. all dives done ?
+	bra		comm_send_headers_full_loop		; NO  - loop
+	bra		comm_command_loop				; YES - done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Send one full dive
+;
+comm_send_dive:
+	SERIAL_LC_SEND 0x66					; acknowledge command
+
+	SERIAL_CC_RECEIVE WREG				; (try to) receive the dive index (0-255)
+	btfsc	rs232_rx_timeout			; got dive index?
+	bra		comm_command_timeout		; NO - abort, back to command loop
+
+	call	log_header_addr_by_index	; compute header start address from index, result in mpr
+	FLASH_RR_READ mpr,header_buffer,.256; copy the complete header into the buffer
+
+	; get pointers and length of profile data
+	MOVTT	header_buffer+index_profile_start_address,ext_flash_address
+	MOVTT	header_buffer+index_profile_end_address,  ext_flash_end_pointer
+	MOVTT	header_buffer+index_profile_byte_count,   ext_flash_length_counter
+
+	; check if profile data are available
+	movf	ext_flash_address+0,W		; compare low   byte of start and end pointer
+	cpfseq	ext_flash_end_pointer+0		; equal?
+	bra		comm_send_dive1				; NO - profile data available, continue
+
+	movf	ext_flash_address+1,W		; compare high  byte of start and end pointer
+	cpfseq	ext_flash_end_pointer+1		; equal?
+	bra		comm_send_dive1				; NO - profile data available, continue
+
+	movf	ext_flash_address+2,W		; compare upper byte of start and end pointer
+	cpfseq	ext_flash_end_pointer+2		; equal?
+	bra		comm_send_dive1				; NO - profile data available, continue
+
+	bra		comm_command_loop			; start = end -> no profile data available, abort, back to command loop
 
-	clrf	up							; set gas/dil index to 0 (0 = gas 1)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x10
-	incf	up							; increment gas/dil index (1 = gas 2)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x11
-	incf	up							; increment gas/dil index (2 = gas 3)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x12
-	incf	up							; increment gas/dil index (3 = gas 4)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x13
-	incf	up							; increment gas/dil index (4 = gas 5)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x14
-	incf	up							; increment gas/dil index (5 = dil 1)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x15
-	incf	up							; increment gas/dil index (6 = dil 2)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x16
-	incf	up							; increment gas/dil index (7 = dil 3)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x17
-	incf	up							; increment gas/dil index (8 = dil 4)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x18
-	incf	up							; increment gas/dil index (9 = dil 5)
-	dcfsnz	WREG
-	bra		comm_read_gas_dil			; RCREG1=0x19
+comm_send_dive1:
+	; send the header from the buffer
+	SERIAL_RR_SEND_RAM header_buffer,.256
+
+	; send the profile directly from the FLASH
+	ext_flash_inc_address_0x20 .6		; skip the first 6 bytes (short header) of the profile data
+	ext_flash_dec_length .3				; adopt the length count (short by 3 bytes)
+	ext_flash_dec_length .1				; decrement length count by 1 so that all bytes will be
+										; done when the counter has wrapped around to 0xFFFFFF
+	movlw	0x20						; now the length count is allowed to be 0x1FFFFF at max
+	cpfslt	ext_flash_length_counter+2	; length count < 0x20(0000) ?
+	bra		comm_command_error			; NO - abort, back to command loop
+	call	ext_flash_read_block_start	; YES - read first byte from FLASH into WREG
+	bra		comm_send_dive_loop_start	;     - jump into transmit loop
+comm_send_dive_loop:
+	call	ext_flash_read_block_0x20	; read next byte into WREG
+comm_send_dive_loop_start:
+	SERIAL_CC_SEND WREG					; transmit byte
+	ext_flash_dec_length .1				; decrement length counter
+	btfss	ext_flash_length_counter+2,7; under-run?
+	bra		comm_send_dive_loop			; NO  - continue loop
+	call	ext_flash_read_block_stop	; YES - end reading from FLASH
+	bra		comm_command_loop			;     - done, back to command loop
+
 
-	clrf	up							; set setpoint index to 0 (0 = SP 1)
-	dcfsnz	WREG
-	bra		comm_read_sp				; RCREG1=0x1A
-	incf	up							; increment setpoint index (1 = SP2)
-	dcfsnz	WREG
-	bra		comm_read_sp				; RCREG1=0x1B
-	incf	up							; increment setpoint index (2 = SP3)
-	dcfsnz	WREG
-	bra		comm_read_sp				; RCREG1=0x1C
-	incf	up							; increment setpoint index (3 = SP4)
-	dcfsnz	WREG
-	bra		comm_read_sp				; RCREG1=0x1D
-	incf	up							; increment setpoint index (4 = SP5)
-	dcfsnz	WREG
-	bra		comm_read_sp				; RCREG1=0x1E
+;-----------------------------------------------------------------------------
+; Reset all Options to Factory Default
+;
+comm_option_reset_all:
+	SERIAL_LC_SEND 0x78					; acknowledge command
+	call	option_reset_all			; reset all options to factory default
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Set Custom Text String (opt_name_length ASCII chars)
+;
+comm_set_custom_text:
+	CLRR	opt_name,opt_name_length	; clear old custom text
+	SERIAL_LC_SEND 0x63					; acknowledge command
+
+	; receive new custom text (less than opt_name_length characters may be sent)
+	SERIAL_RR_RECEIVE_RAM opt_name,opt_name_length
+
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Reset Battery Gauge
+;
+comm_reset_battery_gauge:
+;	SERIAL_LC_SEND 0x23						; acknowledge command (not done)
+	call	reset_battery_gauge_and_lt2942	; reset battery registers and battery gauge chip
+	bra		comm_command_loop				; done, back to command loop
+
 
-	dcfsnz	WREG
-	movff	opt_ccr_mode,				TXREG1	; RCREG1=0x1F
-	dcfsnz	WREG
-	movff	opt_dive_mode,				TXREG1	; RCREG1=0x20
-	dcfsnz	WREG
-	movff	char_I_deco_model,			TXREG1	; RCREG1=0x21
-	dcfsnz	WREG
-	movff	char_I_ppO2_max_work,		TXREG1	; RCREG1=0x22
-	dcfsnz	WREG
-	movff	char_I_ppO2_min,			TXREG1	; RCREG1=0x23
-	dcfsnz	WREG
-	movff	char_I_extra_time,			TXREG1	; RCREG1=0x24
-	dcfsnz	WREG
-	movff	opt_GF_low,					TXREG1	; RCREG1=0x25
-	dcfsnz	WREG
-	movff	opt_GF_high,				TXREG1	; RCREG1=0x26
-	dcfsnz	WREG
-	movff	opt_aGF_low,				TXREG1	; RCREG1=0x27
-	dcfsnz	WREG
-	movff	opt_aGF_high,				TXREG1	; RCREG1=0x28
-	dcfsnz	WREG
-	movff	opt_enable_aGF,				TXREG1	; RCREG1=0x29
-	dcfsnz	WREG
-	movff	opt_sat_multiplier_non_gf,	TXREG1	; RCREG1=0x2A
-	dcfsnz	WREG
-	movff	opt_desat_multiplier_non_gf,TXREG1	; RCREG1=0x2B
-	dcfsnz	WREG
-	movff	opt_last_stop,				TXREG1	; RCREG1=0x2C
-	dcfsnz	WREG
-	movff	opt_brightness,				TXREG1	; RCREG1=0x2D
-	dcfsnz	WREG
-	movff	opt_units,					TXREG1	; RCREG1=0x2E
-	dcfsnz	WREG
-	movff	opt_sampling_rate,			TXREG1	; RCREG1=0x2F
-	dcfsnz	WREG
-	movff	opt_salinity,				TXREG1	; RCREG1=0x30
-	dcfsnz	WREG
-	movff	opt_dive_color_scheme,		TXREG1	; RCREG1=0x31
-	dcfsnz	WREG
-	movff	opt_language,				TXREG1	; RCREG1=0x32
-	dcfsnz	WREG
-	movff	opt_dateformat,				TXREG1	; RCREG1=0x33
-	dcfsnz	WREG
-	movff	opt_compass_gain,			TXREG1	; RCREG1=0x34
-	dcfsnz	WREG
-	movff	opt_pressure_adjust,		TXREG1	; RCREG1=0x35
-	dcfsnz	WREG
-	movff	opt_enable_safetystop,		TXREG1	; RCREG1=0x36
-	dcfsnz	WREG
-	movff	opt_calibration_O2_ratio,	TXREG1	; RCREG1=0x37
-	dcfsnz	WREG
-	clrf	TXREG1								; RCREG1=0x38	NOT USED ANYMORE (ex opt_sensor_fallback)
-	dcfsnz	WREG
-	movff	opt_flip_screen,			TXREG1	; RCREG1=0x39
-	dcfsnz	WREG
-	movff	opt_cR_button_left,			TXREG1	; RCREG1=0x3A
-	dcfsnz	WREG
-	movff	opt_cR_button_right,		TXREG1	; RCREG1=0x3B
-	dcfsnz	WREG
-	movff	char_I_SAC_work,			TXREG1	; RCREG1=0x3C
-	dcfsnz	WREG
-	movff	char_I_SAC_deco,			TXREG1	; RCREG1=0x3D
-	dcfsnz	WREG
-	movff	opt_modwarning,				TXREG1	; RCREG1=0x3E
-	dcfsnz	WREG
-	movff	opt_vsitextv2,				TXREG1	; RCREG1=0x3F
-	dcfsnz	WREG
-	movff	opt_vsigraph,				TXREG1	; RCREG1=0x40
-	dcfsnz	WREG
-	movff	opt_showppo2,				TXREG1	; RCREG1=0x41, always show ppO2
-	dcfsnz	WREG
-	movff	opt_temperature_adjust,		TXREG1	; RCREG1=0x42
-	dcfsnz	WREG
-	movff	opt_safety_stop_length,		TXREG1	; RCREG1=0x43
-	dcfsnz	WREG
-	movff	opt_safety_stop_start,		TXREG1	; RCREG1=0x44
-	dcfsnz	WREG
-	movff	opt_safety_stop_end,		TXREG1	; RCREG1=0x45
-	dcfsnz	WREG
-	movff	opt_safety_stop_reset,		TXREG1	; RCREG1=0x46
-	dcfsnz	WREG
-	clrf	TXREG1								; RCREG1=0x47, ignore conservatism in hwOS tech firmware
-	dcfsnz	WREG
-	movff	opt_diveTimeout,			TXREG1	; RCREG1=0x48
-	dcfsnz	WREG
-	movff	button_polarity,			TXREG1	; RCREG1=0x49
-	dcfsnz	WREG
-	movff	char_I_PSCR_drop,			TXREG1	; RCREG1=0x4A
-	dcfsnz	WREG
-	movff	char_I_PSCR_lungratio,		TXREG1	; RCREG1=0x4B
-	dcfsnz	WREG
-	movff	char_I_ppO2_max_deco,		TXREG1	; RCREG1=0x4C
-	dcfsnz	WREG
-	movff	char_I_ppO2_min_loop,		TXREG1	; RCREG1=0x4D
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+0,	TXREG1	; RCREG1=0x4E
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+1,	TXREG1	; RCREG1=0x4F
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+2,	TXREG1	; RCREG1=0x50
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+3,	TXREG1	; RCREG1=0x51
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+4,	TXREG1	; RCREG1=0x52
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+0,	TXREG1	; RCREG1=0x53
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+1,	TXREG1	; RCREG1=0x54
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+2,	TXREG1	; RCREG1=0x55
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+3,	TXREG1	; RCREG1=0x56
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+4,	TXREG1	; RCREG1=0x57
-	dcfsnz	WREG
-	movff	char_I_CC_max_frac_O2,		TXREG1	; RCREG1=0x58
-	dcfsnz	WREG
-	movff	opt_sim_setpoint_number,	TXREG1	; RCREG1=0x59
-	dcfsnz	WREG
-	movff	opt_calc_asc_gasvolume,		TXREG1	; RCREG1=0x5A
-	dcfsnz	WREG
-	movff	opt_sim_use_aGF,			TXREG1	; RCREG1=0x5B
-	dcfsnz	WREG
-	movff	char_I_altitude_wait,		TXREG1	; RCREG1=0x5C
-	dcfsnz	WREG
-	movff	opt_enable_IBCD,			TXREG1	; RCREG1=0x5D
-	dcfsnz	WREG
-	movff	opt_sat_multiplier_gf,		TXREG1	; RCREG1=0x5E
-	dcfsnz	WREG
-	movff	opt_desat_multiplier_gf,	TXREG1	; RCREG1=0x5F
-	dcfsnz	WREG
-	movff	opt_transmitter_id_1+0,		TXREG1	; RCREG1=0x60
-	dcfsnz	WREG
-	movff	opt_transmitter_id_1+1,		TXREG1	; RCREG1=0x61
-	dcfsnz	WREG
-	movff	opt_transmitter_id_2+0,		TXREG1	; RCREG1=0x62
-	dcfsnz	WREG
-	movff	opt_transmitter_id_2+1,		TXREG1	; RCREG1=0x63
-	dcfsnz	WREG
-	movff	opt_transmitter_id_3+0,		TXREG1	; RCREG1=0x64
-	dcfsnz	WREG
-	movff	opt_transmitter_id_3+1,		TXREG1	; RCREG1=0x65
-	dcfsnz	WREG
-	movff	opt_transmitter_id_4+0,		TXREG1	; RCREG1=0x66
-	dcfsnz	WREG
-	movff	opt_transmitter_id_4+1,		TXREG1	; RCREG1=0x67
-	dcfsnz	WREG
-	movff	opt_transmitter_id_5+0,		TXREG1	; RCREG1=0x68
-	dcfsnz	WREG
-	movff	opt_transmitter_id_5+1,		TXREG1	; RCREG1=0x69
-	dcfsnz	WREG
-	movff	opt_transmitter_id_6+0,		TXREG1	; RCREG1=0x6A
-	dcfsnz	WREG
-	movff	opt_transmitter_id_6+1,		TXREG1	; RCREG1=0x6B
-	dcfsnz	WREG
-	movff	opt_transmitter_id_7+0,		TXREG1	; RCREG1=0x6C
-	dcfsnz	WREG
-	movff	opt_transmitter_id_7+1,		TXREG1	; RCREG1=0x6D
-	dcfsnz	WREG
-	movff	opt_transmitter_id_8+0,		TXREG1	; RCREG1=0x6E
-	dcfsnz	WREG
-	movff	opt_transmitter_id_8+1,		TXREG1	; RCREG1=0x6F
-	dcfsnz	WREG
-	movff	opt_transmitter_id_9+0,		TXREG1	; RCREG1=0x70
-	dcfsnz	WREG
-	movff	opt_transmitter_id_9+1,		TXREG1	; RCREG1=0x71
-	dcfsnz	WREG
-	movff	opt_transmitter_id_10+0,	TXREG1	; RCREG1=0x72
-	dcfsnz	WREG
-	movff	opt_transmitter_id_10+1,	TXREG1	; RCREG1=0x73
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+5,	TXREG1	; RCREG1=0x74
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+6,	TXREG1	; RCREG1=0x75
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+7,	TXREG1	; RCREG1=0x76
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+8,	TXREG1	; RCREG1=0x77
-	dcfsnz	WREG
-	movff	char_I_gas_avail_size+9,	TXREG1	; RCREG1=0x78
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+5,	TXREG1	; RCREG1=0x79
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+6,	TXREG1	; RCREG1=0x7A
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+7,	TXREG1	; RCREG1=0x7B
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+8,	TXREG1	; RCREG1=0x7C
-	dcfsnz	WREG
-	movff	char_I_gas_avail_pres+9,	TXREG1	; RCREG1=0x7D
-	dcfsnz	WREG
-	movff	opt_TR_mode,				TXREG1	; RCREG1=0x7E
-	dcfsnz	WREG
-	movff	opt_TR_1st_pres,			TXREG1	; RCREG1=0x7F
-	dcfsnz	WREG
-	movff	opt_TR_2nd_pres,			TXREG1	; RCREG1=0x80
-	dcfsnz	WREG
-	movff	opt_TR_Bail_pres,			TXREG1	; RCREG1=0x81
-	dcfsnz	WREG
-	movff	char_I_max_pres_diff,		TXREG1	; RCREG1=0x82
-	dcfsnz	WREG
-	movff	opt_ZfactorUse,				TXREG1	; RCREG1=0x83
-	dcfsnz	WREG
-	movff	opt_ZfactorTemp,			TXREG1	; RCREG1=0x84
-	dcfsnz	WREG
-	movff	opt_2ndDepthDisp,			TXREG1	; RCREG1=0x85
-	dcfsnz	WREG
-	movff	opt_max_depth,				TXREG1	; RCREG1=0x86
-	dcfsnz	WREG
-	movff	char_I_descent_speed,		TXREG1	; RCREG1=0x87
-	dcfsnz	WREG
-	movff	opt_store_apnoe_dive,		TXREG1	; RCREG1=0x88
-	dcfsnz	WREG
-	movff	opt_tissue_graphics,		TXREG1	; RCREG1=0x89
-	dcfsnz	WREG
-	movff	opt_layout,					TXREG1	; RCREG1=0x8A
-	dcfsnz	WREG
-	movff	opt_extended_stops,			TXREG1	; RCREG1=0x8B
-	dcfsnz	WREG
-	movff	char_I_gas_density_att,		TXREG1	; RCREG1=0x8C
-	dcfsnz	WREG
-	movff	char_I_gas_density_warn,	TXREG1	; RCREG1=0x8D
-	dcfsnz	WREG
-	movff	char_I_dil_ppO2_check,		TXREG1	; RCREG1=0x8E
+;-----------------------------------------------------------------------------
+; Erase complete Logbook
+;
+comm_erase_complete_logbook:
+;	SERIAL_LC_SEND 0x22					; acknowledge command (not done)
+	call	erase_complete_logbook		; erase complete logbook
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Start Bootloader (aka perform cold start)
+;
+comm_cold_start:
+;	SERIAL_LC_SEND 0xC1									; acknowledge command (not done)
+;	call	rs232_wait_tx								; wait for completion of transmit before hardware goes into reboot
+
+	WIN_SMALL comm_status3_column, comm_status3_row		; print "Low-level Bootloader" message
+	STRCPY_TEXT_PRINT tUsbLlBld							; ...
+
+	WIN_TOP  comm_warning_row							; set row    for icon
+	WIN_LEFT comm_warning_column						; set column for icon
+	TFT_WRITE_PROM_IMAGE_BY_LABEL dive_warning2_block	; show a warning icon
+
+	bsf		LEDr										; switch on red LED
+
+	call	eeprom_deco_data_write						; update deco data     in EEPROM
+	call	eeprom_battery_gauge_write					; update battery gauge in EEPROM
+	btfsc	options_changed								; do the options need to be stored to EEPROM ?
+	call	option_check_and_store_all					; YES - check and store all option values in EEPROM
+
+	goto	0x1FF0C										; jump into the bootloader code
+
+
+;-----------------------------------------------------------------------------
+; Send Firmware to Bootloader (aka initiate firmware update)
+;
+comm_firmware_update:
+	SERIAL_LC_SEND 0x50					; acknowledge command
+
+	SERIAL_RR_RECEIVE_RAM buffer,.5		; (try to) receive 5 byte checksum
+	btfsc	rs232_rx_timeout			; got all 5 bytes?
+	bra		comm_send_firmware_abort	; NO  - abort
 
-comm_read_abort:
-comm_read_done:
-	bra		comm_download_mode0			; done, loop with timeout reset
+	; check the checksum
+	movlw	0x55						; initialize checksum check-byte
+	movwf	hi							; store in hi
+	lfsr	FSR2,buffer					; load base address of buffer
+	movlw	.5							; 5 bytes to process
+	movwf	lo							; initialize loop counter
+comm_firmware_update_loop:
+	movf	POSTINC2,W					; get a checksum byte
+	xorwf	hi,F						; xor   checksum byte with check-byte
+	rlncf	hi,F						; rotate check-byte
+	decfsz	lo,F						; decrement loop counter, done?
+	bra		comm_firmware_update_loop	; NO  - loop
+	tstfsz	hi							; YES - check-byte zero?
+	bra		comm_send_firmware_failed	;       NO  - checksum not valid
+
+	; checksum is valid
+	SERIAL_LC_SEND 0x4C					; inform checksum is ok
+	call	rs232_wait_tx				; wait for completion of transmit before hardware goes into reboot
+
+	call	eeprom_deco_data_write		; update deco data     in EEPROM
+	call	eeprom_battery_gauge_write	; update battery gauge in EEPROM
+	btfsc	options_changed				; do the options need to be stored to EEPROM ?
+	call	option_check_and_store_all	; YES - check and store all option values in EEPROM
+
+	goto	0x1FDF0						; jump into the bootloader code
+
+comm_send_firmware_failed:
+	; select font and output position
+	WIN_SMALL comm_string_column, comm_string_row
+	call	TFT_warning_color			; select color
+	STRCPY_PRINT "Checksum failed"		; print failure message (fill to 15 chars)
+	call	TFT_standard_color			; back to standard color
+	;bra	comm_send_firmware_abort	; abort
+
+comm_send_firmware_abort:
+	SERIAL_LC_SEND 0xFF					; send abort message
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Erase a Memory Range given byte Start Address and Number of 4 kB Blocks
+;
+comm_erase_range4kb:
+	SERIAL_LC_SEND 0x42					; acknowledge command
+	bcf		INTCON,GIE					; disable all interrupts
+	rcall	comm_get_start_address		; (try to) get the start address
+	btfsc	rs232_rx_timeout			; got start address?
+	bra		comm_command_timeout		; NO  - abort, back to command loop
+
+	; (try to) receive the block count (1 byte)
+	SERIAL_CC_RECEIVE ext_flash_length_counter
+	btfsc	rs232_rx_timeout			; got block count?
+	bra		comm_command_timeout		; NO  - abort, back to command loop
+
+	; erase blocks (number of blocks to do was received in ext_flash_length_counter:1)
+comm_erase_range4kb_loop:
+	call	ext_flash_erase_4kB			; erase a 4 kB block
+										; increase start address by 0x1000 (4kB):
+										; nothing to do with low byte
+	movlw	0x10						; add 0x10...
+	addwf	ext_flash_address+1,F		; ... to high byte
+	movlw	0x00						; add 0x00...
+	addwfc	ext_flash_address+2,F		; ... plus carry bit to upper byte
+	btfsc	ext_flash_address+2,6		; reached 0x400000 ?
+	bra		comm_command_loop			; YES - at end of address range, back to command loop
+	decfsz	ext_flash_length_counter,F	; NO  - decrement number of blocks to do, all blocks done?
+	bra		comm_erase_range4kb_loop	;       NO  - loop
+	bra		comm_command_loop			;       YES - done, back to command loop
+
 
 ;-----------------------------------------------------------------------------
+; Erase one Memory Block of 4 kB Size
+;
+comm_erase_4kb:
+;	SERIAL_LC_SEND 0x40					; acknowledge command (not done)
+	bcf		INTCON,GIE					; disable all interrupts
+	rcall	comm_get_start_address		; (try to) get the start address
+	btfsc	rs232_rx_timeout			; got a complete start address?
+	bra		comm_command_timeout		; NO  - abort, back to command loop
+	call	ext_flash_erase_4kB			; YES - erase memory block
+	bra		comm_command_loop			;     - done, back to command loop
 
+
+;-----------------------------------------------------------------------------
+; Write a stream of bytes to the FLASH beginning at given start address, end on timeout
+;
+comm_write_range_stream:
+	SERIAL_LC_SEND 0x30						; acknowledge command
+	bcf		INTCON,GIE						; disable all interrupts
+	rcall	comm_get_start_address			; (try to) get the start address
+	btfsc	rs232_rx_timeout				; got a complete start address?
+	bra		comm_command_timeout			; NO  - abort, back to command loop
+
+	; steam bytes to FLASH
+comm_write_range_loop:
+	SERIAL_CC_RECEIVE WREG					; (try to) receive a byte
+	btfsc	rs232_rx_timeout				; got a byte?
+	bra		comm_command_loop				; NO  - end of byte stream, done, back to command loop
+;	bsf		NCTS							; YES - hold    Bluetooth chip (requires PC/Android/iOS side to use flow control...)
+	call	write_byte_ext_flash_plus_comms	;     - write data byte to FLASH and increase address with rollover at 0x400000
+;	bcf		NCTS							;     - release Bluetooth chip (requires PC/Android/iOS side to use flow control...)
+	bra		comm_write_range_loop			;     - loop
+
+
+;-----------------------------------------------------------------------------
+; Write a block of 256 bytes to the FLASH beginning at given start address (low byte needs to be zero)
+;
+comm_write_range_block:
+	SERIAL_LC_SEND 0x31						; acknowledge command
+	bcf		INTCON,GIE						; disable all interrupts
+
+	rcall	comm_get_start_address			; (try to) get the start address
+	btfsc	rs232_rx_timeout				; got a complete start address?
+	bra		comm_command_timeout			; NO  - abort, back to command loop
+
+	tstfsz	ext_flash_address+0				; low byte of address = 0 ?
+	bra		comm_command_error				; NO  - abort, back to command loop
+
+	SERIAL_RR_RECEIVE_RAM buffer,.256		; (try to) receive 256 byte and buffer them in memory
+	btfsc	rs232_rx_timeout				; got all 256 bytes?
+	bra		comm_command_timeout			; NO  - abort, back to command loop
+
+	FLASH_RR_WRITE buffer,ext_flash_address,.256 ; copy from memory to FLASH
+	bra		comm_command_loop					 ; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Read a range from FLASH given by start address and length
+;
+comm_read_range:
+	SERIAL_LC_SEND 0x20					; acknowledge command
+	bcf		INTCON,GIE					; disable all interrupts
+
+	; receive start address
+	rcall	comm_get_start_address		; (try to) get the start address
+	btfsc	rs232_rx_timeout			; got a complete start address?
+	bra		comm_command_timeout		; NO - abort, back to command loop
+
+	; receive length
+	rcall	comm_get_length				; (try to) get the length
+	btfsc	rs232_rx_timeout			; got a complete length?
+	bra		comm_command_timeout		; NO - abort, back to command loop
+
+	; stream bytes from FLASH
+	ext_flash_dec_length .1				; decrement length count by 1 so that all bytes will be
+										; done when the counter has wrapped around to 0xFFFFFF
+
+	movlw	0x40						; now the length count is allowed to be 0x3FFFFF at max
+	cpfslt	ext_flash_length_counter+2	; length count < 0x40(0000) ?
+	bra		comm_command_error			; NO  - abort, back to command loop
+	call	ext_flash_read_block_start	; YES - read first byte from FLASH into WREG
+	bra		comm_read_range_loop_start	;     - jump into transmit loop
+comm_read_range_loop:
+	call	ext_flash_read_block_0x40	; read next byte into WREG
+comm_read_range_loop_start:
+	SERIAL_CC_SEND WREG					; transmit byte
+	ext_flash_dec_length .1				; decrement length counter
+	btfss	ext_flash_length_counter+2,7; under-run?
+	bra		comm_read_range_loop		; NO  - continue loop
+	call	ext_flash_read_block_stop	; YES - end reading from FLASH
+	bra		comm_command_loop			;     - done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Receive a 3 byte FLASH address (on serial: big-endian, in memory: little-endian)
+;
+comm_get_start_address:
+	SERIAL_RR_RECEIVE_RAM ext_flash_address,.3	; receive 3 bytes
+	btfsc	rs232_rx_timeout					; timeout?
+	return										; YES - abort, no usable address available
+
+	; remap address from network byte format (big endian) to host format (little-endian)
+	movf	ext_flash_address+0,W
+	movff	ext_flash_address+2,ext_flash_address+0
+	movwf	ext_flash_address+2
+
+	return										; done, complete start address available
+
+
+;-----------------------------------------------------------------------------
+; Receive a 3 byte length (on serial: big-endian, in memory: little-endian)
+;
+comm_get_length:
+	SERIAL_RR_RECEIVE_RAM ext_flash_length_counter,.3 	; receive 3 bytes
+	btfsc	rs232_rx_timeout							; timeout?
+	return												; YES - abort, no usable address available
+
+	; remap address from network byte format (big endian) to host format (little-endian)
+	movf	ext_flash_length_counter+0,W
+	movff	ext_flash_length_counter+2,ext_flash_length_counter+0
+	movwf	ext_flash_length_counter+2
+
+	return												; done, complete start address available
+
+
+;-----------------------------------------------------------------------------
+; Read an Option Value
+;
+comm_read_option:
+	SERIAL_LC_SEND 0x72					; acknowledge command
+	SERIAL_CC_RECEIVE lo				; (try to) receive option index
+	btfsc	rs232_rx_timeout			; received option index?
+	bra		comm_command_loop			; NO - abort, back to command loop
+
+	; option index 0x00 - 0x0F: unused
+	movlw	0x0F						; last option index of the unused range
+	cpfsgt	lo							; received option index > end of unused range ?
+	bra		comm_command_error			; NO  - abort, back to command loop
+
+	; option index 0x10 - 0x19: gases & diluents
+	movlw	0x19						; last option index for gases / diluents
+	cpfsgt	lo							; received option index > end of gas/dil range ?
+	bra		comm_read_gas_dil			; NO  - process gas/dil read
+
+	; option index 0x1A - 0x1E: setpoints
+	movlw	0x1E						; last option index for setpoint
+	cpfsgt	lo							; received option index > end of setpoint range ?
+	bra		comm_read_sp				; NO  - process setpoint read
+
+	; option index = 0x49 - special handling button polarity
+	movf	lo,W						; copy option index to WREG
+	iorlw	0x49						; received option index for button polarity ?
+	bz		comm_read_button_polarity	; YES - process button polarity read
+
+	; option index 0x1F - 0xFF: options managed by option-table
+	call	option_read_serial			; try to find the option and read its value
+	tstfsz	WREG						; option found?
+	bra		comm_read_setting_fail		; NO  - send dummy value
+	SERIAL_CC_SEND	hi					; YES - send read  value
+	bra		comm_command_loop			;     - done, back to command loop
+
+comm_read_setting_fail:
+	SERIAL_LC_SEND	0x00				; send a dummy value
+	bra		comm_command_error			; back to command loop with failure message
+
+
+;-----------------------------------------------------------------------------
+; Write an Option Value
+;
+comm_write_option:
+	SERIAL_LC_SEND 0x77					; acknowledge command
+	SERIAL_CC_RECEIVE lo				; (try to) receive option index
+	btfsc	rs232_rx_timeout			; got a byte?
+	bra		comm_command_timeout		; NO - abort, back to command loop
+
+	; option index 0x00 - 0x0F: unused
+	movlw	0x0F						; last option index of the unused range
+	cpfsgt	lo							; received option index > end of unused range ?
+	bra		comm_write_unused			; NO  - but need to consume the option value
+
+	; option index 0x10 - 0x19: gases & diluents
+	movlw	0x19						; last option index for gases / diluents
+	cpfsgt	lo							; received option index > end of gas/dil range ?
+	bra		comm_write_gas_dil			; NO  - process gas/dil write
+
+	; option index 0x1A - 0x1E: setpoints
+	movlw	0x1E						; last option index for setpoint
+	cpfsgt	lo							; received option index > end of setpoint range ?
+	bra		comm_write_sp				; NO  - process setpoint write
+
+	; option index = 0x49 - special handling button polarity
+	movf	lo,W						; copy option index to WREG
+	iorlw	0x49						; received option index for button polarity ?
+	bz		comm_write_button_polarity	; YES - process button polarity write
+
+	; option index 0x1F - 0xFF: options managed by option-table
+	SERIAL_CC_RECEIVE hi				; (try to) receive option value
+	btfsc	rs232_rx_timeout			; got a byte?
+	bra		comm_command_timeout		; NO  - abort
+	call	option_write_serial			; YES - try to find the option and write new value
+	tstfsz	WREG						;     - option found and new value valid ?
+	bra		comm_command_error			;       NO  - back to command loop with failure message
+	bra		comm_command_loop			;       YES - done, back to command loop
+
+comm_write_unused:
+	SERIAL_CC_RECEIVE WREG				; consume unused option value
+	bra		comm_command_error			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Read button polarity
+;
+comm_read_button_polarity:
+	SERIAL_CC_SEND	button_polarity		; send current button polarity setting
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Write button polarity
+; 
+comm_write_button_polarity:
+	SERIAL_CC_RECEIVE hi				; (try to) receive configuration value
+	btfsc	rs232_rx_timeout			; got configuration value?
+	bra		comm_command_timeout		; NO  - abort, back to command loop
+	movff	hi,button_polarity			; YES - store button polarity in memory and EEPROM
+	EEPROM_CC_WRITE button_polarity,eeprom_button_polarity
+	bra		comm_command_loop			;     - done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Read a gas/diluent dataset
+;
 ; Memory map is as follows:
 ; -------------------------
 ; opt_gas_O2_ratio			res 5		; O2 ratios of OC/bailout gases
@@ -1214,334 +963,24 @@
 ; opt_dil_type				res 5		; dil type
 ; opt_gas_change			res 5		; change depths for OC/Bailout gases
 ; opt_dil_change			res 5		; change depths for diluents
-
+;
 comm_read_gas_dil:
 	lfsr	FSR0,opt_gas_O2_ratio		; load base address of gas data arrays
-	movf	up,W						; load index (0-9) of gas/dil into WREG, addressing O2 ratio
-	movff	PLUSW0, TXREG1				; transmit O2 ratio
-	rcall	comm_write_byte				; wait for completion of transmit
-	addlw	.10							; increment index by 10, addressing He ratio now
-	movff	PLUSW0, TXREG1				; transmit He ratio
-	rcall	comm_write_byte				; wait for completion of transmit
-	addlw	.10							; increment index by 10, addressing gas/dil type now
-	movff	PLUSW0, TXREG1				; transmit gas/dil type
-	rcall	comm_write_byte				; wait for completion of transmit
-	addlw	.10							; increment index by 10, addressing change depth now
-	movff	PLUSW0,TXREG1				; transmit change depth
-	bra		comm_read_done				; done, wait for UART and loop with timeout reset
+	movlw	0x10						; compute gas index from option index...
+	subwf	lo,W						; ...making WREG          point to O2 ratio
+	SERIAL_CC_SEND PLUSW0				; send O2 ratio
+	addlw	.10							; increment WREG by 10 to point to He ratio
+	SERIAL_CC_SEND PLUSW0				; send He ratio
+	addlw	.10							; increment WREG by 10 to point to gas/diluent type
+	SERIAL_CC_SEND PLUSW0				; send gas/diluent type
+	addlw	.10							; increment WREG by 10 to point to change depth
+	SERIAL_CC_SEND PLUSW0				; send change depth
+	bra		comm_command_loop			; done, back to command loop
 
 
-; Memory map is as follows:
-; -------------------------
-; opt_setpoint_cbar			res 5	; setpoints in cbar
-; opt_setpoint_change		res 5	; change depth for the setpoints in meter
-
-comm_read_sp:
-	lfsr	FSR0,opt_setpoint_cbar		; load base address of setpoint cbar values
-	movf	up,W						; load index (0-4) of setpoint into WREG, addressing cbar value
-	movff	PLUSW0, TXREG1				; transmit setpoint cbar value
-	rcall	comm_write_byte				; wait for completion of transmit
-	addlw	.5							; increment index by 5, addressing change depth now
-	movff	PLUSW0, TXREG1				; transmit change depth
-	bra		comm_read_done				; done, wait for UART and loop with timeout reset
-
-;-----------------------------------------------------------------------------
-
-comm_write_setting:
-	movlw	"w"
-	movwf	TXREG1
-	rcall	comm_get_byte					; "Byte 2"
-	btfsc	rs232_rx_timeout				; got a byte?
-	bra		comm_write_abort				; NO - abort
-	movff	RCREG1,lo						; copy
-	rcall	comm_get_byte					; "Byte 3"
-	rcall	comm_write_byte					; wait for completion of transmit
-	movlw	0x0F
-	cpfsgt	lo								; 0x00-0x0F: unused
-	bra		comm_write_abort				; abort!
-	subwf	lo,W							; subtract unused commands
-
-	clrf	up								; set gas/dil index to 0  (0 = gas 1)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x10
-	incf	up								; increment gas/dil index (1 = gas 2)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x11
-	incf	up								; increment gas/dil index (2 = gas 3)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x12
-	incf	up								; increment gas/dil index (3 = gas 4)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x13
-	incf	up								; increment gas/dil index (4 = gas 5)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x14
-	incf	up								; increment gas/dil index (5 = dil 1)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x15
-	incf	up								; increment gas/dil index (6 = dil 2)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x16
-	incf	up								; increment gas/dil index (7 = dil 3)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x17
-	incf	up								; increment gas/dil index (8 = dil 4)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x18
-	incf	up								; increment gas/dil index (9 = dil 5)
-	dcfsnz	WREG
-	bra		comm_write_gas_dil				; RCREG1=0x19
-
-	clrf	up								; set setpoint index to 0 (0 = SP 1)
-	dcfsnz	WREG
-	bra		comm_write_sp					; RCREG1=0x1A
-	incf	up								; increment setpoint index (1 = SP2)
-	dcfsnz	WREG
-	bra		comm_write_sp					; RCREG1=0x1B
-	incf	up								; increment setpoint index (2 = SP3)
-	dcfsnz	WREG
-	bra		comm_write_sp					; RCREG1=0x1C
-	incf	up								; increment setpoint index (3 = SP4)
-	dcfsnz	WREG
-	bra		comm_write_sp					; RCREG1=0x1D
-	incf	up								; increment setpoint index (4 = SP5)
-	dcfsnz	WREG
-	bra		comm_write_sp					; RCREG1=0x1E
-
-	dcfsnz	WREG
-	movff	RCREG1, opt_ccr_mode			; RCREG1=0x1F
-	dcfsnz	WREG
-	movff	RCREG1, opt_dive_mode			; RCREG1=0x20
-	dcfsnz	WREG
-	movff	RCREG1, char_I_deco_model		; RCREG1=0x21
-	dcfsnz	WREG
-	movff	RCREG1, char_I_ppO2_max_work	; RCREG1=0x22
-	dcfsnz	WREG
-	movff	RCREG1, char_I_ppO2_min			; RCREG1=0x23
-	dcfsnz	WREG
-	movff	RCREG1, char_I_extra_time		; RCREG1=0x24
-	dcfsnz	WREG
-	movff	RCREG1, opt_GF_low				; RCREG1=0x25
-	dcfsnz	WREG
-	movff	RCREG1, opt_GF_high				; RCREG1=0x26
-	dcfsnz	WREG
-	movff	RCREG1, opt_aGF_low				; RCREG1=0x27
-	dcfsnz	WREG
-	movff	RCREG1, opt_aGF_high			; RCREG1=0x28
-	dcfsnz	WREG
-	movff	RCREG1, opt_enable_aGF			; RCREG1=0x29
-	dcfsnz	WREG
-	movff	RCREG1, opt_sat_multiplier_non_gf	; RCREG1=0x2A
-	dcfsnz	WREG
-	movff	RCREG1, opt_desat_multiplier_non_gf	; RCREG1=0x2B
-	dcfsnz	WREG
-	movff	RCREG1, opt_last_stop			; RCREG1=0x2C
-	dcfsnz	WREG
-	movff	RCREG1, opt_brightness			; RCREG1=0x2D
-	dcfsnz	WREG
-	movff	RCREG1, opt_units				; RCREG1=0x2E
-	dcfsnz	WREG
-	movff	RCREG1, opt_sampling_rate		; RCREG1=0x2F
-	dcfsnz	WREG
-	movff	RCREG1, opt_salinity			; RCREG1=0x30
-	dcfsnz	WREG
-	movff	RCREG1, opt_dive_color_scheme	; RCREG1=0x31
-	dcfsnz	WREG
-	movff	RCREG1, opt_language			; RCREG1=0x32
-	dcfsnz	WREG
-	movff	RCREG1, opt_dateformat			; RCREG1=0x33
-	dcfsnz	WREG
-	movff	RCREG1, opt_compass_gain		; RCREG1=0x34
-	dcfsnz	WREG
-	movff	RCREG1, opt_pressure_adjust		; RCREG1=0x35
-	dcfsnz	WREG
-	movff	RCREG1, opt_enable_safetystop	; RCREG1=0x36
-	dcfsnz	WREG
-	movff	RCREG1, opt_calibration_O2_ratio; RCREG1=0x37
-	dcfsnz	WREG
-	nop										; RCREG1=0x38	NOT USED ANYMORE (ex opt_sensor_fallback)
-	dcfsnz	WREG
-	movff	RCREG1, opt_flip_screen			; RCREG1=0x39
-	dcfsnz	WREG
-	movff	RCREG1, opt_cR_button_left		; RCREG1=0x3A
-	dcfsnz	WREG
-	movff	RCREG1, opt_cR_button_right		; RCREG1=0x3B
-	dcfsnz	WREG
-	movff	RCREG1, char_I_SAC_work			; RCREG1=0x3C
-	dcfsnz	WREG
-	movff	RCREG1, char_I_SAC_deco			; RCREG1=0x3D
-	dcfsnz	WREG
-	movff	RCREG1, opt_modwarning			; RCREG1=0x3E
-	dcfsnz	WREG
-	movff	RCREG1, opt_vsitextv2			; RCREG1=0x3F
-	dcfsnz	WREG
-	movff	RCREG1, opt_vsigraph			; RCREG1=0x40
-	dcfsnz	WREG
-	movff	RCREG1, opt_showppo2			; RCREG1=0x41, always show ppO2
-	dcfsnz	WREG
-	movff	RCREG1, opt_temperature_adjust	; RCREG1=0x42
-	dcfsnz	WREG
-	movff	RCREG1, opt_safety_stop_length	; RCREG1=0x43
-	dcfsnz	WREG
-	movff	RCREG1, opt_safety_stop_start	; RCREG1=0x44
-	dcfsnz	WREG
-	movff	RCREG1, opt_safety_stop_end		; RCREG1=0x45
-	dcfsnz	WREG
-	movff	RCREG1, opt_safety_stop_reset	; RCREG1=0x46
-	dcfsnz	WREG
-	nop										; RCREG1=0x47, ignore conservatism for standard hwOS
-	dcfsnz	WREG
-	movff	RCREG1, opt_diveTimeout			; RCREG1=0x48
-	dcfsnz	WREG
-	bra		comm_write_button_polarity		; RCREG1=0x49
-	dcfsnz	WREG
-	movff	RCREG1, char_I_PSCR_drop		; RCREG1=0x4A
-	dcfsnz	WREG
-	movff	RCREG1, char_I_PSCR_lungratio	; RCREG1=0x4B
-	dcfsnz	WREG
-	movff	RCREG1, char_I_ppO2_max_deco	; RCREG1=0x4C
-	dcfsnz	WREG
-	movff	RCREG1, char_I_ppO2_min_loop	; RCREG1=0x4D
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+0	; RCREG1=0x4E
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+1	; RCREG1=0x4F
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+2	; RCREG1=0x50
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+3	; RCREG1=0x51
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+4	; RCREG1=0x52
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+0	; RCREG1=0x53
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+1	; RCREG1=0x54
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+2	; RCREG1=0x55
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+3	; RCREG1=0x56
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+4	; RCREG1=0x57
-	dcfsnz	WREG
-	movff	RCREG1, char_I_CC_max_frac_O2	; RCREG1=0x58
-	dcfsnz	WREG
-	movff	RCREG1, opt_sim_setpoint_number	; RCREG1=0x59
-	dcfsnz	WREG
-	movff	RCREG1, opt_calc_asc_gasvolume	; RCREG1=0x5A
-	dcfsnz	WREG
-	movff	RCREG1, opt_sim_use_aGF			; RCREG1=0x5B
-	dcfsnz	WREG
-	movff	RCREG1, char_I_altitude_wait	; RCREG1=0x5C
-	dcfsnz	WREG
-	movff	RCREG1, opt_enable_IBCD			; RCREG1=0x5D
-	dcfsnz	WREG
-	movff	RCREG1, opt_sat_multiplier_gf	; RCREG1=0x5E
-	dcfsnz	WREG
-	movff	RCREG1, opt_desat_multiplier_gf	; RCREG1=0x5F
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_1+0	; RCREG1=0x60
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_1+1	; RCREG1=0x61
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_2+0	; RCREG1=0x62
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_2+1	; RCREG1=0x63
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_3+0	; RCREG1=0x64
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_3+1	; RCREG1=0x65
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_4+0	; RCREG1=0x66
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_4+1	; RCREG1=0x67
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_5+0	; RCREG1=0x68
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_5+1	; RCREG1=0x69
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_6+0	; RCREG1=0x6A
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_6+1	; RCREG1=0x6B
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_7+0	; RCREG1=0x6C
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_7+1	; RCREG1=0x6D
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_8+0	; RCREG1=0x6E
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_8+1	; RCREG1=0x6F
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_9+0	; RCREG1=0x70
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_9+1	; RCREG1=0x71
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_10+0	; RCREG1=0x72
-	dcfsnz	WREG
-	movff	RCREG1, opt_transmitter_id_10+1	; RCREG1=0x73
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+5	; RCREG1=0x74
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+6	; RCREG1=0x75
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+7	; RCREG1=0x76
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+8	; RCREG1=0x77
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_size+9	; RCREG1=0x78
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+5	; RCREG1=0x79
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+6	; RCREG1=0x7A
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+7	; RCREG1=0x7B
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+8	; RCREG1=0x7C
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_avail_pres+9	; RCREG1=0x7D
-	dcfsnz	WREG
-	movff	RCREG1, opt_TR_mode				; RCREG1=0x7E
-	dcfsnz	WREG
-	movff	RCREG1, opt_TR_1st_pres			; RCREG1=0x7F
-	dcfsnz	WREG
-	movff	RCREG1, opt_TR_2nd_pres			; RCREG1=0x80
-	dcfsnz	WREG
-	movff	RCREG1, opt_TR_Bail_pres		; RCREG1=0x81
-	dcfsnz	WREG
-	movff	RCREG1, char_I_max_pres_diff	; RCREG1=0x82
-	dcfsnz	WREG
-	movff	RCREG1, opt_ZfactorUse			; RCREG1=0x83
-	dcfsnz	WREG
-	movff	RCREG1, opt_ZfactorTemp			; RCREG1=0x84
-	dcfsnz	WREG
-	movff	RCREG1, opt_2ndDepthDisp		; RCREG1=0x85
-	dcfsnz	WREG
-	movff	RCREG1, opt_max_depth			; RCREG1=0x86
-	dcfsnz	WREG
-	movff	RCREG1, char_I_descent_speed	; RCREG1=0x87
-	dcfsnz	WREG
-	movff	RCREG1, opt_store_apnoe_dive	; RCREG1=0x88
-	dcfsnz	WREG
-	movff	RCREG1, opt_tissue_graphics		; RCREG1=0x89
-	dcfsnz	WREG
-	movff	RCREG1, opt_layout				; RCREG1=0x8A
-	dcfsnz	WREG
-	movff	RCREG1, opt_extended_stops		; RCREG1=0x8B
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_density_att	; RCREG1=0x8C
-	dcfsnz	WREG
-	movff	RCREG1, char_I_gas_density_warn	; RCREG1=0x8D
-	dcfsnz	WREG
-	movff	RCREG1, char_I_dil_ppO2_check	; RCREG1=0x8E
-
-
-comm_write_abort:
-comm_write_done:
-	; check options, gases and diluents
-	call	option_check_all			; check all options (and reset if not within their min/max boundaries)
-	goto	comm_download_mode0			; done, loop with timeout reset
-
-;-----------------------------------------------------------------------------
-
+; ----------------------------------------------------------------------------
+; Write a gas/diluent dataset
+;
 ; Memory map is as follows:
 ; -------------------------
 ; opt_gas_O2_ratio			res 5		; O2 ratios of OC/bailout gases
@@ -1552,70 +991,128 @@
 ; opt_dil_type				res 5		; dil type
 ; opt_gas_change			res 5		; change depths for OC/Bailout gases
 ; opt_dil_change			res 5		; change depths for diluents
+;
+comm_write_gas_dil:
+	SERIAL_RR_RECEIVE_RAM hi,.4			; (try to) receive 4 option values
+	btfsc	rs232_rx_timeout			; got all 4 bytes?
+	bra		comm_command_timeout		; NO - abort, back to command loop
 
-comm_write_gas_dil:
+	; check validity of O2 value
+	movlw	gaslist_min_o2-.1			; get min value minus 1
+	cpfsgt	hi							; received O2% >= min ?
+	bra		comm_command_error			; NO - abort, back to command loop
+	movlw	gaslist_max_o2+.1			; get max value plus 1
+	cpfslt	hi							; received O2% <= max ?
+	bra		comm_command_error			; NO - abort, back to command loop
+
+	; check validity of He value
+	movlw	gaslist_max_He+.1			; get max value plus 1
+	cpfslt	up							; received O2% <= max ?
+	bra		comm_command_error			; NO - abort, back to command loop
+
+	; check O2% + He% <= 100%
+	movlw	.100						; load 100%
+	bsf		STATUS,C					; set carry = clear borrow
+	subfwb	hi,W						; subtract O2% from 100%
+	btfss	STATUS,C					; result negative?
+	bra		comm_command_error			; YES - abort, back to command loop
+	subfwb	up,W						; NO  - subtract He%
+	btfss	STATUS,C					;     - now negative?
+	bra		comm_command_error			;       YES - abort, back to command loop
+
+	; check validity of type
+	movlw	0x14						; last option index for gases
+	cpfsgt	lo							; received option index > end of gas range ?
+	bra		comm_write_dil				; YES - check type for diluents
+	;bra	comm_write_gas				; NO  - check type for gases
+
+comm_write_gas:
+	; check validity of type for a gas
+	movlw	num_gas_types				; load number of gas types
+	bra		comm_write_gas_dil_common	; continue with common part
+
+comm_write_dil:
+	; check validity of type for a diluent
+	movlw	num_dil_types				; load number of diluent types
+	;bra	comm_write_gas_dil_common	; continue with common part
+
+comm_write_gas_dil_common:
+	cpfslt	ex							; received type < max ?
+	bra		comm_command_error			; NO  - abort, back to command loop
+
+	; check validity of change depth
+	movlw	gaslist_max_change_depth+.1	; get max value plus 1
+	cpfslt	ul							; received change depth <= max ?
+	bra		comm_command_error			; NO - abort, back to command loop
+
+	; all values ok, can finally be written
 	lfsr	FSR0,opt_gas_O2_ratio		; load base address of gas data arrays
-	movf	up,W						; load index (0-9) of gas/dil into WREG, addressing O2 ratio
-	movff	RCREG1,PLUSW0				; receive O2 ratio
-	rcall	comm_get_byte				; wait for UART
-	addlw	.10							; increment index by 10, addressing He ratio now
-	movff	RCREG1,PLUSW0				; receive He ratio
-	rcall	comm_get_byte				; wait for UART
-	addlw	.10							; increment index by 10, addressing gas/dil type now
-	movff	RCREG1,PLUSW0				; receive gas/dil type
-	rcall	comm_get_byte				; wait for UART
-	addlw	.10							; increment index by 10, addressing change depth now
-	movff	RCREG1,PLUSW0				; receive change depth
-	bra		comm_write_done				; done, loop with timeout reset
+	movlw	0x10						; compute gas index from option index...
+	subwf	lo,W						; ...making WREG          point to O2 ratio
+	movff	hi,PLUSW0					; set O2 ratio
+	addlw	.10							; increment WREG by 10 to point to He ratio
+	movff	up,PLUSW0					; set He ratio
+	addlw	.10							; increment WREG by 10 to point to gas/dil type
+	movff	ex,PLUSW0					; set gas/dil type
+	addlw	.10							; increment WREG by 10 to point to change depth
+	movff	ul,PLUSW0					; set change depth
+
+	bra		comm_command_loop			; done, back to command loop
 
 
+;-----------------------------------------------------------------------------
+; Read a setpoint dataset
+;
 ; Memory map is as follows:
 ; -------------------------
 ; opt_setpoint_cbar			res 5	; setpoints in cbar
 ; opt_setpoint_change		res 5	; change depth for the setpoints in meter
-
-comm_write_sp:
+;
+comm_read_sp:
 	lfsr	FSR0,opt_setpoint_cbar		; load base address of setpoint cbar values
-	movf	up,W						; load index (0-4) of setpoint into WREG, addressing cbar value
-	movff	RCREG1,PLUSW0				; receive setpoint cbar value
-	rcall	comm_get_byte				; wait for UART
-	addlw	.5							; increment index by 5, addressing change depth now
-	movff	RCREG1,PLUSW0				; receive change depth
-	bra		comm_write_done				; done, loop with timeout reset
+	movlw	0x1A						; compute SP index from option index...
+	subwf	lo,W						; ...making WREG         point to cbar value
+	SERIAL_CC_SEND PLUSW0				; send setpoint cbar value
+	addlw	.5							; increment WREG by 5 to point to change depth
+	SERIAL_CC_SEND PLUSW0				; send change depth
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Write a setpoint dataset
+;
+; Memory map is as follows:
+; -------------------------
+; opt_setpoint_cbar			res 5	; setpoints     in cbar
+; opt_setpoint_change		res 5	; change depths in meter
+;
+comm_write_sp:
+	SERIAL_RR_RECEIVE_RAM hi,.2			; (try to) receive 2 option values
+	btfsc	rs232_rx_timeout			; got both bytes?
+	bra		comm_command_timeout		; NO - abort, back to command loop
+
+	; check validity of setpoint value
+	movlw	gaslist_sp_min-.1			; get min value minus 1
+	cpfsgt	hi							; received O2% >= min ?
+	bra		comm_command_error			; NO - abort, back to command loop
+	movlw	gaslist_sp_max+.1			; get max value plus 1
+	cpfslt	hi							; received O2% <= max ?
+	bra		comm_command_error			; NO - abort, back to command loop
+
+	; check validity of change depth
+	movlw	sp_max_change_depth+.1		; get max value plus 1
+	cpfslt	up							; received change depth <= max ?
+	bra		comm_command_error			; NO - abort, back to command loop
+
+	lfsr	FSR0,opt_setpoint_cbar		; load base address of setpoint cbar values
+	movlw	0x1A						; compute SP index from option index...
+	subwf	lo,W						; ...making WREG         point to cbar value
+	movff	hi,PLUSW0					; set cbar value
+	addlw	.5							; increment WREG by 5 to point to change depth
+	movff	up,PLUSW0					; set change depth
+
+	bra		comm_command_loop			; done, back to command loop
 
 ;-----------------------------------------------------------------------------
 
-comm_send_string:
-	movlw	"n"							; send echo
-	movwf	TXREG1
-	call	comm_write_byte				; wait for completion of transmit
-	WIN_SMALL comm_string_column, comm_string_row
-	movlw	.16
-	movwf	lo							; counter
-comm_send_string_loop:
-	call	comm_get_byte
-	btfsc	rs232_rx_timeout			; got a byte?
-	bra		comm_send_string_abort		; NO - abort
-	movff	RCREG1,POSTINC2				; store character
-	decfsz	lo,F
-	bra		comm_send_string_loop
-comm_send_string_abort:
-	STRCAT_PRINT ""						; show the text
-	goto	comm_download_mode0			; done, loop with timeout reset
-
-;-----------------------------------------------------------------------------
-
-comm_write_button_polarity:
-	; store RCREG1 into EEPROM .897
-	movlw	LOW  .897
-	movwf	EEADR
-	movlw	HIGH .897
-	movwf	EEADRH
-	movff	RCREG1,EEDATA
-	movff	EEDATA,button_polarity		; 0xFF (both normal), 0x00 (both inverted), 0x01 (left inverted only), 0x02 (right inverted only) 
-	call	write_eeprom				; EEDATA into EEPROM@EEADR
-	clrf	EEADRH						; reset EEADRH
-	goto	comm_download_mode0			; done, loop with timeout reset
-
-;----------------------------------------------------------------------------
 	END
\ No newline at end of file
--- a/src/compass_ops.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/compass_ops.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File compass_ops.asm                      combined next generation V3.06.1
+;   File compass_ops.asm                      combined next generation V3.08.8
 ;
 ;   Compass Operations
 ;
@@ -17,6 +17,7 @@
 #include	"divemode.inc"
 #include	"math.inc"
 #include	"convert.inc"
+#include	"start.inc"
 
 
  IFDEF _compass
@@ -63,7 +64,7 @@
 	extern	compass_add_calibration
 	extern	compass_solve_calibration
 
-	extern	option_save_all
+	extern	option_check_and_store_all
 
 
 compass_ops	code
@@ -359,7 +360,7 @@
 	btfsc	trigger_timeout				; timeout (calibration done)?
 	bra		compass_calibration_exit	; YES - done
 	btfss	trigger_full_second			; NO  - new second begun?
-	bra		compass_calibration_loop2	;       NO - loop
+	bra		compass_calibration_loop2	;       NO  - loop
 	bcf		trigger_full_second			;       YES - clear flag
 	rcall	TFT_show_timeout_testmode	;           - show remaining time
 	bra		compass_calibration_loop2	;           - loop
@@ -372,10 +373,13 @@
 
 	call	request_speed_normal		; request CPU speed change to normal speed
 
-	call	option_save_all				; save all settings into EEPROM
-	movlw	.6
-	movff	WREG,customview_surfmode	; set to compass view...
-	goto	surfloop					; ...and exit
+	bsf		options_changed				; flag that option values have changed
+	bsf		restart_fast				; request to skip logos and waits on restart
+
+	movlw	.6							; coding for surface compass view
+	movff	WREG,customview_surfmode	; set to compass view to show
+
+	goto	restart						; done
 
 ;-----------------------------------------------------------------------------
 
--- a/src/configuration.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/configuration.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,7 +1,7 @@
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 ; ============================================================================
 ; 
-;    File configuration.inc                   combined next generation V3.06.2
+;    File configuration.inc                   combined next generation V3.08.8
 ; 
 ;    OSTC hwOS Configuration
 ; 
@@ -15,17 +15,17 @@
 ; Firmware Version
 ; ----------------
 ;
-; softwareversion_x			firmware version, major               (1 -   9)
-; softwareversion_y			firmware version, minor               (0 -  99)
-; softwareversion_beta		0= Release, 1= Beta 1, 2= Beta 2, ... (0 - 255)
+; fw_version_major				firmware version, major               (1 -  9)
+; fw_version_minor				firmware version, minor               (0 - 99)
+; fw_version_beta				0= Release, 1= Beta 1, 2= Beta 2, ... (0 - 99)
 ;
 ; NOTE: all values need to be defined in hex!
 ;
 #endif
 
-#define softwareversion_x		0x03
-#define softwareversion_y		0x08
-#define softwareversion_beta	0x00
+#define fw_version_major		0x03
+#define fw_version_minor		0x09
+#define fw_version_beta			0x01
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -42,13 +42,13 @@
 ;
 #endif
 
-#define firmware_creation_year	0x13
-#define firmware_creation_month	0x08
-#define firmware_creation_day	0x0a
+#define firmware_creation_year	0x14
+#define firmware_creation_month	0x02
+#define firmware_creation_day	0x1C
 
-#define firmware_expire_year	0x14
-#define firmware_expire_month	0x0a
-#define firmware_expire_day		0x1f
+#define firmware_expire_year	0x15
+#define firmware_expire_month	0x01
+#define firmware_expire_day		0x01
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -56,9 +56,10 @@
 ; global Version Selection
 ; ------------------------
 ;
-; _hwos_tech_2_TR		compile Tech  version for OSTC 2, Plus and TR (1 language  only    ) memory: 122.054 used,   884 free
-; _hwos_tech_3_cR		compile Tech  version for OSTC 3       and cR (2 languages possible) memory: 118.148 used, 4.790 free (with 1 language only)
-; _hwos_sport			compile Sport version for all models          (2 languages possible) memory: 115.764 used, 7.174 free (with 1 language only)
+; _hwos_tech_2_TR   compile Tech  version for OSTC 2, Plus and TR (1 language  en   ) memory: 121.832 used, 1.048 free
+; _hwos_tech_3_cR   compile Tech  version for OSTC 3       and cR (2 languages en+de) memory: 122.074 used,   874 free
+; _hwos_sport       compile Sport version for all models          (2 languages en+de) memory: 119.192 used, 3.756 free
+;                                                                                             122.880 max. available
 #endif
 
 #define _hwos_tech_3_cR
@@ -76,30 +77,28 @@
 ; 
 #endif
 
-#define _language_1		en
-#define _language_2		de
+#define _language_1		de
+#define _language_2		none
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 ;
 ; Features Selection
 ; ------------------
+;																memory requirements not up-to-date!
+; _compass				compass function								mem: 10.488 byte
+; _helium				helium (trimix) gases and diluents				mem:  2.182 byte
+; _ccr_pscr				CCR & pSCR modes, basic functionality			mem:  4.110 byte
+; _external_sensor		CCR & pSCR modes, external sensor support		mem:  3.452 byte
+; _gauge_mode			gauge mode										mem:     30 byte  when _not_ included
+; _high_ppO2_max		raised ppO2 max limit (2.0 bar)					mem:      0 byte
+; _rx_functions			RX function        (OSTC TR)					mem:  4.886 byte
+; _rx_update			RX firmware update (OSTC TR)					mem:  2.472 byte
+; _cave_mode			cave mode return calculation					mem:    720 byte
+; _gas_contingency		auto-switch to alternative tanks on depleption	mem:    452 byte
+; _min_depth_option		resettable min. and max. depth					mem:    394 byte  ## special user group only ##
+; _screendump			screen dump function							mem:    338 byte  ## special user group only ##
 ;
-; _screendump			screen dump function				mem:    338 byte
-; _compass				compass function					mem: 10.488 byte
-; _rx_functions			RX functions (OSTC TR)				mem:  4.886 byte
-; _rx_update			updates RX firmware				1)	mem:  2.472 byte
-; _helium				Helium (Trimix) gases and diluents	mem:  2.182 byte
-; _ccr_pscr				loop modes CCR and pSCR				mem:  4.110 byte
-; _external_sensor		external sensor for CCR & pSCR	2)	mem:  3.452 byte
-; _gauge_mode			gauge mode							mem:     30 byte  when _not_ included
-; _high_ppO2_max		raised ppO2 max limit (2.0 bar)		mem:      0 byte
-; _cave_mode			cave mode way-out calculation		mem:        byte  ## under construction yet  ##
-; _min_depth_option		resettable min. and max. depth		mem:    394 byte  ## special user group only ##
-; _gas_contingency		continue deco on other gases		mem:    452 byte  ## special user group only ##
-;
-; 1) needs _rx_functions to be included, too / can not be included without _rx_functions
-; 2) needs _ccr_pscr     to be included, too / can not be included without _ccr_pscr
 ;
 ; NOTES: - Exclude options by prepending NOT_INCLUDED to the label.
 ;        - Not all options will fit concurrently if two languages are slected.
@@ -110,56 +109,56 @@
 
 #ifdef _hwos_tech_2_TR
 
-#define _screendump
 #define _compass
-#define _rx_functions
-#define _rx_update
 #define _helium
 #define _ccr_pscr
+#define _rx_functions
+#define _rx_update
 #define _gauge_mode
 #define _high_ppO2_max
-
-
 #define NOT_INCLUDED_external_sensor
 #define NOT_INCLUDED_cave_mode
+#define NOT_INCLUDED_gas_contingency
 #define NOT_INCLUDED_min_depth_option
+#define NOT_INCLUDED_screendump
 
 #endif
 
 
 #ifdef _hwos_tech_3_cR
 
-#define NOT_INCLUDED_screendump
 #define _compass
 #define _helium
 #define _ccr_pscr
-#define _external_sensor
 #define _gauge_mode
 #define _high_ppO2_max
-#define _gas_contingency
-
 #define NOT_INCLUDED_rx_functions
 #define NOT_INCLUDED_rx_update
-#define NOT_INCLUDED_cave_mode
+#define _external_sensor
+#define _cave_mode
+#define _gas_contingency
+#define NOT_INCLUDED_gas_contingency
 #define NOT_INCLUDED_min_depth_option
+#define NOT_INCLUDED_screendump
 
 #endif
 
 
 #ifdef _hwos_sport
 
-#define _screendump
 #define _compass
-#define _rx_functions
-#define _rx_update
+#define _gas_contingency
 #define NOT_INCLUDED_helium
 #define NOT_INCLUDED_ccr_pscr
-#define NOT_INCLUDED_external_sensor
-
 #define NOT_INCLUDED_gauge_mode
 #define NOT_INCLUDED_high_ppO2_max
+#define _rx_functions
+#define _rx_update
+#define NOT_INCLUDED_external_sensor
 #define NOT_INCLUDED_cave_mode
+#define NOT_INCLUDED_gas_contingency
 #define NOT_INCLUDED_min_depth_option
+#define NOT_INCLUDED_screendump
 
 #endif
 
@@ -170,19 +169,41 @@
 ; -----------
 ;
 ; _DEBUG			put firmware in a global debug mode		default: not included
-; _debug_output		debug outputs (for performance)			default: not included
 ; _profiling		deco engine performance measurements	default: not included
+; _debug_output		performance outputs (for _profiling)	default: not included
 ;
-; NOTE: - Exclude options by prepending NOT_INCLUDED to the label.
+; NOTE: - Exclude options by prepending NOT_INCLUDED to the label
 ;
 #endif
 
 #define NOT_INCLUDED_DEBUG
+#define NOT_INCLUDED_profiling
 #define NOT_INCLUDED_debug_output
-#define NOT_INCLUDED_profiling
 
 
+#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+;
+; Auto-Includes (serve functional dependencies)
+;
+#endif
 
+#ifdef  _cave_mode
+#ifndef _gas_contingency
+#define _gas_contingency
+#endif
+#endif
+
+#ifdef  _rx_update
+#ifndef _rx_functions
+#define _rx_functions
+#endif
+#endif
+
+#ifdef  _external_sensor
+#ifndef _ccr_pscr
+#define _ccr_pscr
+#endif
+#endif
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
--- a/src/customview.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/customview.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File customview.asm                       combined next generation V3.03.5
+;   File customview.asm                       combined next generation V3.08.8
 ;
 ;   Custom Views in Surface and Dive Mode
 ;
@@ -24,13 +24,14 @@
 
 
 	extern	gaslist_strcat_gas_cd
-	extern	char_I_deco_model
+	extern	char_I_model
 
  IFDEF _compass
 	extern	TFT_surface_compass_mask
 	extern	TFT_dive_compass_mask
  ENDIF
 
+#DEFINE num_premenu_items	.11		; overall number of pre-menu items
 
 custview	CODE
 
@@ -46,49 +47,65 @@
 	global	dive_customview_second
 dive_customview_second:
 	movf	active_customview,W			; get current view
-	dcfsnz	WREG,F						; 1:
-	goto	TFT_avr_stopwatch			; average depth and stopwatch
-	dcfsnz	WREG,F						; 2:
-	return								; compass - will be updated separately (faster) in dive mode
-	dcfsnz	WREG,F						; 3:
- IFDEF _external_sensor
-	goto	TFT_ppo2_sensors			; ppO2 sensors
+	dcfsnz	WREG,F						;
+	goto	TFT_avr_stopwatch			;  1: average depth and stopwatch
+	dcfsnz	WREG,F						;
+ IFDEF _compass
+	return								;  2: compass - will be updated separately (faster) in dive mode
  ELSE
-	return								; not available without external sensors
+	return								;  2: not available without compass
  ENDIF
-	dcfsnz	WREG,F						; 4:
- IFDEF _ccr_pscr
-	goto	TFT_sensor_check			; sensor check
+	dcfsnz	WREG,F						;
+ IFDEF _external_sensor
+	goto	TFT_ppo2_sensors			;  3: ppO2 sensors
  ELSE
-	return								; not available without CCR / pSCR mode
+	return								;  3: not available without external sensors
  ENDIF
-	dcfsnz	WREG,F						; 5;
+	dcfsnz	WREG,F						;
  IFDEF _ccr_pscr
-	goto	TFT_pscr_info				; pSCR data
+	goto	TFT_sensor_check			;  4: sensor check
  ELSE
-	return								; not available without CCR / pSCR mode
+	return								;  4: not available without CCR / pSCR mode
+ ENDIF
+	dcfsnz	WREG,F						;
+ IFDEF _ccr_pscr
+	goto	TFT_pscr_info				;  5: pSCR data
+ ELSE
+	return								;  5: not available without CCR / pSCR mode
  ENDIF
-	dcfsnz	WREG,F						; 6:
+	dcfsnz	WREG,F						;
  IFDEF _rx_functions
-	goto	TFT_pressures_SAC			; tank pressure and SAC rate
+	goto	TFT_pressures_SAC			;  6: tank pressure and SAC rate
  ELSE
-	return								; not available without RX functions
+	return								;  6: not available without RX functions
+ ENDIF
+	dcfsnz	WREG,F						;
+	goto	TFT_gas_needs				;  7: gas needs for ascent / cave return
+	dcfsnz	WREG,F						;
+ IFDEF _cave_mode
+	goto	TFT_cave_tts				;  8: cave mode TTS
+ ELSE
+	return								;  8: not available without cave mode functions
  ENDIF
-	dcfsnz	WREG,F						; 7:
-	goto	TFT_gas_needs_ascent		; gas needs for ascent / cave return
-	dcfsnz	WREG,F						; 8:
-	goto	TFT_decoplan				; deco plan
-	dcfsnz	WREG,F						; 9:
-	goto	TFT_ceiling_GF_tissue		; ceiling, current GF and tissues
-	dcfsnz	WREG,F						; 10:
-	goto	TFT_CNS						; CNS values
-	dcfsnz	WREG,F						; 11:
-	goto	TFT_ppo2_ead_end_cns		; ppO2, END/EAD and CNS
-	dcfsnz	WREG,F						; 12:
-	return								; GF factors - static only
-	dcfsnz	WREG,F						; 13:
-	goto	TFT_clock_batt_surfpress	; clock, battery and surface pressure
-	return								; active_customview = 0 -> do nothing
+	dcfsnz	WREG,F						;
+	goto	TFT_decoplan				;  9: deco plan
+	dcfsnz	WREG,F						;
+	goto	TFT_ceiling_GF_tissue		; 10: ceiling, current GF and tissues
+	dcfsnz	WREG,F						;
+	goto	TFT_CNS						; 11: CNS values
+	dcfsnz	WREG,F						;
+	goto	TFT_ppo2_ead_end_cns		; 12: ppO2, END/EAD and CNS / gas density
+	dcfsnz	WREG,F						;
+	goto	TFT_clock_batt_surfpress	; 13: clock, battery and surface pressure
+	dcfsnz	WREG,F						;
+	return								; 14: GF factors - static only
+	dcfsnz	WREG,F						;
+ IFDEF _cave_mode
+	goto	TFT_cave_waypoints			; 15: cave waypoints
+ ELSE
+	return								; 15: not available without cave mode functions
+ ENDIF
+	return								;  0: do nothing
 
 ;-----------------------------------------------------------------------------
 
@@ -268,18 +285,17 @@
 ;-----------------------------------------------------------------------------
 
 	global	menuview_toggle
+	global	menuview_toggle_reset
 menuview_toggle:						; show main menu or the pre-menu
 	bcf		switch_left					; clear button event
 	movlw	divemode_timeout_premenu	; get timeout for dive mode pre-menu
 	call	reset_timeout_time			; reset timeout
 	bsf		dive_options_menu			; flag that the dive options menu is shown
-	incf	active_premenu,F			; current number of pre-menu item
-	movlw	d'10'						; max     number of pre-menu items
+	incf	active_premenu,F			; increment pre-menu item number
+	movlw	num_premenu_items			; get count of pre-menu items
 	cpfsgt	active_premenu				; max reached?
 	bra		menuview_mask				; NO  - show item
 	;bra	menuview_toggle_reset		; YES - reset selector
-
-	global	menuview_toggle_reset
 menuview_toggle_reset:					; timeout occurred, beyond max number of options, or item executed
 	clrf	active_premenu				; reset pre-menu selector
 	bcf		dive_options_menu			; the dive options menu is not shown anymore
@@ -291,31 +307,40 @@
 	btfss	FLAG_apnoe_mode				;     - in apnoe mode?
 	goto	TFT_show_temp_divemode		;       YES - restore temperature and done
 	goto	TFT_standard_color			;       NO  - done
+
 menuview_items:
 	call	TFT_attention_color			; set color
 	bsf		win_invert					; set inverse printing
 	WIN_SMALL dm_premenu_col,dm_premenu_row
 	movf	active_premenu,W			; get active pre-menu item
 	dcfsnz	WREG,F
-	bra		menuview_view_gaschange		; check if a better gas/diluent is advised and prompt for switching if yes
+	bra		menuview_view_gaschange		;  1: gas change	(skipped if no better gas/dil cued)
 	dcfsnz	WREG,F
-	bra		menuview_view1				; "Menu?"		(skipped in gauge and apnoe modes)
+	bra		menuview_view_divemenu		;  2: "Menu?"		(skipped in gauge and apnoe modes)
 	dcfsnz	WREG,F
-	bra		menuview_view2				; "Quit?"		(in simulation mode only)
+ IFDEF _cave_mode
+	bra		menuview_view_cavemenu		;  3: "Cave?"		(skipped if not in cave mode)
+ ELSE
+	bra		menuview_toggle				;  3: cave mode not implemented, go to next menu item
+ ENDIF
 	dcfsnz	WREG,F
-	bra		menuview_view3				; "Sim-1m"		(in simulation mode only)
+	bra		menuview_view_sim_quit		;  4: "Quit?"		(in simulation mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view4				; "Sim+1m"		(in simulation mode only)
+	bra		menuview_view_sim_down		;  5: "Sim down"	(in simulation mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view5				; "Quit?"		(in apnoe mode only)
+	bra		menuview_view_sim_up		;  6: "Sim up"		(in simulation mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view6				; "Reset Avr"	(in gauge mode only)
+	bra		menuview_view_sim_time		;  7: "Sim+5'"		(in simulation mode only)
+	dcfsnz	WREG,F
+	bra		menuview_view_apnoe_quit	;  8: "Quit?"		(in apnoe mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view7				; "Sim+5'"		(in simulation mode only)
+	bra		menuview_view_gauge_reset	;  9: "Reset Avr"	(in gauge mode only)
+	dcfsnz	WREG,F
+	bra		menuview_view_course		; 10: "Course"		(only when compass is shown)
 	dcfsnz	WREG,F
-	bra		menuview_view8				; "Course"		(only when compass is shown)
-	dcfsnz	WREG,F
-	bra		menuview_view9				; "Layout"		(offer alternative layout, aka blind mode)
+	bra		menuview_view_layout		; 11: "Layout"		(offer alternative layout, aka blind mode)
+
+	; when adding or removing pre-menu items, adjust the value num_premenu_items in the #DEFINE !
 
 menuview_exit:
 	call	TFT_standard_color
@@ -324,8 +349,8 @@
 
 
 menuview_view_gaschange:
-	btfsc	request_gaschange			; last gas change request executed yet?
-	bra		menuview_toggle				; NO - call next option
+	btfsc	request_gas_change			; last gas change request executed yet?
+	bra		menuview_toggle				; YES - call next option
  IFDEF _ccr_pscr
 	btfsc	FLAG_oc_mode				; in OC mode?
 	bra		menuview_view_gaschange_OC	; YES
@@ -348,12 +373,12 @@
 	bsf		short_gas_descriptions		; use short version of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
 	bsf		better_gas_hint				; color-code as best gas/diluent
 	call	gaslist_strcat_gas_cd		; append gas description of gas #PRODL (0-4) to current string
-	movlw	.5
-	movwf	FSR2L						; point to 6th character (5 chars are used for the gas/dil description)
-	STRCAT_PRINT "?"
+	movlw	.5							; point to 6th character (5 chars are used for the gas/dil description)
+	movwf	FSR2L						; ...
+	STRCAT_PRINT "?"					; print question mark
 	bra		menuview_exit				; done
 
-menuview_view1:
+menuview_view_divemenu:
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	bra		menuview_toggle				; YES - goto next option
 	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
@@ -362,39 +387,34 @@
 	STRCAT_TEXT_PRINT tDivePreMenu		;           - print "Menu?"
 	bra		menuview_exit				;           - done
 
-menuview_view2:
+ IFDEF _cave_mode
+menuview_view_cavemenu:
+	TSTOSS	opt_cave_mode				; cave mode switched on?
+	bra		menuview_toggle				; NO  - goto next option
+	PUTC	"\xb7"						; YES - print '->' symbol
+	STRCAT_TEXT_PRINT tDivePreCave		;     - print "Cave?"
+	bra		menuview_exit				;     - done
+ ENDIF
+
+menuview_view_sim_quit:
 	btfss	simulatormode				; in simulator mode?
 	bra		menuview_toggle				; NO  - goto next option
 	STRCPY_TEXT_PRINT tQuitSim			; YES - print "Quit Simulation?"
 	bra		menuview_exit				;     - done
 
-menuview_view3:
+menuview_view_sim_down:
 	btfss	simulatormode				; in simulator mode?
 	bra		menuview_toggle				; NO - goto next option
 	STRCPY_PRINT "Sim\xb8"				; print down arrow for going down
 	bra		menuview_exit				; done
 
-menuview_view4:
+menuview_view_sim_up:
 	btfss	simulatormode				; in simulator mode?
 	bra		menuview_toggle				; NO  - goto next option
 	STRCPY_PRINT "Sim\xb9"				; YES - print up arrow for going up
 	bra		menuview_exit				;     - done
 
-menuview_view5:
-	btfss	FLAG_apnoe_mode				; in apnoe mode?
-	bra		menuview_toggle				; NO  - goto next option
-	btfss	apnoe_at_surface			; YES - at the surface?
-	bra		menuview_toggle				;       NO  - goto next option
-	STRCPY_TEXT_PRINT tQuitSim			;       YES - print "Quit Apnea mode?"
-	bra		menuview_exit				;           - done
-
-menuview_view6:
-	btfss	FLAG_gauge_mode				; in gauge mode?
-	bra		menuview_toggle				; NO  - goto next option
-	STRCPY_TEXT_PRINT tResetAvg			; YES - print "Reset Avg."
-	bra		menuview_exit				;     - done
-
-menuview_view7:
+menuview_view_sim_time:
 	btfss	simulatormode				; in simulator mode?
 	bra		menuview_toggle				; NO  - goto next option
 	btfsc	FLAG_gauge_mode				; YES - in gauge mode?
@@ -404,7 +424,21 @@
 	STRCPY_PRINT "Sim+5'"				;             NO  - print "Sim+5'"
 	bra		menuview_exit				;                 - done
 
-menuview_view8:
+menuview_view_apnoe_quit:
+	btfss	FLAG_apnoe_mode				; in apnoe mode?
+	bra		menuview_toggle				; NO  - goto next option
+	btfss	apnoe_at_surface			; YES - at the surface?
+	bra		menuview_toggle				;       NO  - goto next option
+	STRCPY_TEXT_PRINT tQuitSim			;       YES - print "Quit Apnea mode?"
+	bra		menuview_exit				;           - done
+
+menuview_view_gauge_reset:
+	btfss	FLAG_gauge_mode				; in gauge mode?
+	bra		menuview_toggle				; NO  - goto next option
+	STRCPY_TEXT_PRINT tResetAvg			; YES - print "Reset Avg."
+	bra		menuview_exit				;     - done
+
+menuview_view_course:
  IFDEF _compass
 	movlw	index_compass_dm			; index of compass view
 	cpfseq	active_customview			; in compass view?
@@ -415,7 +449,7 @@
 	bra		menuview_toggle				; not available without compass compiled in, goto next option
  ENDIF
 
-menuview_view9:
+menuview_view_layout:
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	bra		menuview_toggle				; YES - goto next option
 	STRCPY_TEXT_PRINT tDiveLayout		; NO  - print "Layout"
@@ -423,20 +457,38 @@
 
 ;-----------------------------------------------------------------------------
 
-; Show next dive mode custom view (and delete this flag)
+; Initialize dive mode custom view
+
+	global	dive_customview_show
+dive_customview_show:
+	btfss	custom_view_locked			; custom view locked?
+	bra		dive_customview_show_1		; NO  - call-up the view
+	movwf	backup_customview			; YES - store requested custom view for later recall
+	return								;     - done
+dive_customview_show_1:
+	movwf	active_customview			; set the requested custom view
+	bra		dive_customview_callup		; call-up the custom view
+
+	global	dive_customview_recall
+dive_customview_recall:
+	movff	backup_customview,active_customview	; recall the saved custom view
+	bra		dive_customview_callup				; call-up the custom view
+
 	global	dive_customview_toggle
 dive_customview_toggle:
 	incf	active_customview,F			; increment number of custom view to show
-
-	movlw	index_compass_dm			; index of custom view compass
-	cpfseq	active_customview			; will compass be shown in custom view?
-	call	I2C_sleep_compass			; NO - stop compass
-
 	movlw	index_cv_dm_max				; highest index in use in dive mode custom view
 	cpfsgt	active_customview			; max reached?
-	bra		dive_customview_mask		; NO  - show
-	clrf	active_customview			; YES - reset to zero (zero = no custom view)
-	;bra	dive_customview_mask		;     - show
+	bra		dive_customview_callup		; NO  - call-up the custom view
+	clrf	active_customview			; YES - reset to zero (zero = blank custom view)
+	;bra	dive_customview_callup		; call-up the custom view
+
+	global	dive_customview_callup
+dive_customview_callup:
+	movlw	index_compass_dm			; get index of compass custom view
+	cpfseq	active_customview			; will compass be shown?
+	call	I2C_sleep_compass			; NO - stop compass
+	;bra	dive_customview_init		; continue with initializing selected custom view
 
 ;----------------------------------------------------------------------------------
 ; Jump table for initialization of the every-second tasks in custom view area (dive mode)
@@ -444,38 +496,41 @@
 ; Attention: the ordering must be in line with the every-second update jump table
 ;            and the index numbers defined in hwos.inc!
 ;
-	global	dive_customview_mask
-dive_customview_mask:
+dive_customview_init:
 	; clear custom view area in dive mode
 	WIN_BOX_BLACK dm_customview_row, dm_customview_bot-.2, dm_customview_column, dm_customview_rgt ; top, bottom, left, right
 	movf	active_customview,W			; get custom view to show
-	dcfsnz	WREG,F						; 1:
-	bra		init_avr_stopwatch			; average depth and stopwatch
-	dcfsnz	WREG,F						; 2:
-	bra		init_TFT_dive_compass		; compass
-	dcfsnz	WREG,F						; 3:
-	bra		init_ppo2_sensors			; ppO2 sensors
-	dcfsnz	WREG,F						; 4:
-	bra		init_sensor_check			; sensor check
-	dcfsnz	WREG,F						; 5:
-	bra		init_pscr_info				; pSCR data
-	dcfsnz	WREG,F						; 6:
-	bra		init_pressures_SAC			; tank pressure and SAC rate
-	dcfsnz	WREG,F						; 7:
-	bra		init_gas_needs_ascent		; gas needs for ascent / cave return
-	dcfsnz	WREG,F						; 8:
-	bra		init_decoplan				; deco plan
-	dcfsnz	WREG,F						; 9:
-	bra		init_ceiling_GF_tissue		; ceiling, current GF and tissues
-	dcfsnz	WREG,F						; 10:
-	bra		init_CNS					; CNS values
-	dcfsnz	WREG,F						; 11:
-	bra		init_ppo2_ead_end_cns		; ppO2, END/EAD and CNS
-	dcfsnz	WREG,F						; 12:
-	bra		init_gf_factors				; GF factors
-	dcfsnz	WREG,F						; 13:
-	bra		init_clock_batt_surfpress	; clock, battery and surface pressure
-	bra		customview_toggle_exit		; no view (blank screen in custom view area)
+	dcfsnz	WREG,F						;
+	bra		init_avr_stopwatch			;  1: average depth and stopwatch
+	dcfsnz	WREG,F						;
+	bra		init_TFT_dive_compass		;  2: compass
+	dcfsnz	WREG,F						;
+	bra		init_ppo2_sensors			;  3: ppO2 sensors
+	dcfsnz	WREG,F						;
+	bra		init_sensor_check			;  4: sensor check
+	dcfsnz	WREG,F						;
+	bra		init_pscr_info				;  5: pSCR data
+	dcfsnz	WREG,F						;
+	bra		init_pressures_SAC			;  6: tank pressure and SAC rate
+	dcfsnz	WREG,F						;
+	bra		init_gas_needs_ascent		;  7: gas needs for ascent / cave return
+	dcfsnz	WREG,F						;
+	bra		init_cave_tts				;  8: cave mode TTS
+	dcfsnz	WREG,F						;
+	bra		init_decoplan				;  9: deco plan (next stops)
+	dcfsnz	WREG,F						;
+	bra		init_ceiling_GF_tissue		; 10: ceiling, current GF and tissues
+	dcfsnz	WREG,F						;
+	bra		init_CNS					; 11: CNS values
+	dcfsnz	WREG,F						;
+	bra		init_ppo2_ead_end_cns		; 12: ppO2, END/EAD and CNS
+	dcfsnz	WREG,F						;
+	bra		init_clock_batt_surfpress	; 13: clock, battery and surface pressure
+	dcfsnz	WREG,F						;
+	bra		init_gf_factors				; 14: GF factors
+	dcfsnz	WREG,F						;
+	bra		init_cave_waypoints			; 15: cave waypoints
+	bra		customview_toggle_exit		;  0: no view (blank screen in custom view area)
 
 
 init_ppo2_sensors:
@@ -523,16 +578,6 @@
 	call	TFT_clock_batt_surfpress		; data for clock, battery and surface pressure
 	bra		customview_toggle_exit			; done
 
-init_gf_factors:
-	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bra		dive_customview_toggle		; YES - goto next view
-	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
-	bra		dive_customview_toggle		;       YES - call next view
-	TSTOSS	char_I_deco_model			;       NO  - in GF mode (0 = ZH-L16, 1 = ZH-L16-GF)?
-	bra		dive_customview_toggle		;             NO  - no GF info for non-GF modes
-	call	TFT_gf_factors_mask			;             YES - mask for GF factors (static only)
-	bra		customview_toggle_exit		;                 - done
-
 init_TFT_dive_compass:					; compass
  IFDEF _compass
 	call	I2C_init_compass			; start compass
@@ -607,12 +652,36 @@
 	bra		dive_customview_toggle		; YES - goto next view
 	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
 	bra		dive_customview_toggle		;       YES - goto next view
-	TSTOSS	opt_calc_asc_gasvolume		;       NO  - check if gas volume calculation is switched on
+	TSTOSS	opt_calc_gasvolume			;       NO  - check if gas volume calculation is switched on
 	bra		dive_customview_toggle		;             NO  - goto next view
-	call	TFT_gas_needs_ascent_mask	;             YES - mask for gas needs ascent
-	call	TFT_gas_needs_ascent		;                 - data for gas needs ascent
+	call	TFT_gas_needs_mask			;             YES - mask for gas needs ascent
+	call	TFT_gas_needs				;                 - data for gas needs ascent
 	bra		customview_toggle_exit		;                 - done
 
+init_cave_tts:							; cave mode data
+ IFDEF _cave_mode
+	btfss	cave_mode					; in cave mode?
+	bra		dive_customview_toggle		; NO  - goto next view
+	call	TFT_cave_tts_mask			; YES - show mask
+	call	TFT_cave_tts				;     - show data
+	bra		customview_toggle_exit		;     - done
+ ELSE
+	bra		dive_customview_toggle		; not available without cave mode, goto next view
+ ENDIF
+
+init_gf_factors:
+	call	TFT_gf_factors_mask			; mask for GF factors (static only)
+	bra		customview_toggle_exit		; done
+
+init_cave_waypoints:
+ IFDEF _cave_mode
+	call	TFT_cave_waypoints			; show waypoint graphics
+	bra		customview_toggle_exit		; done
+ ELSE
+	bra		dive_customview_toggle		; not available without cave mode, goto next view
+ ENDIF
+
+
 customview_toggle_exit:
 	bcf		request_next_custview		; clear request flag
 	return								; done
--- a/src/customview.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/customview.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File customview.inc                       combined next generation V3.03.2
+;   File customview.inc                       combined next generation V3.08.6
 ;
 ;   Customview for divemode and surfacemode
 ;
@@ -10,9 +10,11 @@
 ;   2011-08-10 : [mH] Import into hwOS sources
 
 ; Dive mode
-	extern	dive_customview_mask
 	extern	dive_customview_second
+	extern	dive_customview_show
+	extern	dive_customview_recall
 	extern	dive_customview_toggle
+	extern	dive_customview_callup
 
 	extern	menuview_toggle
 	extern	menuview_toggle_reset
--- a/src/divemenu_tree.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/divemenu_tree.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemenu_tree.asm                    combined next generation V3.03.4
+;   File divemenu_tree.asm                    combined next generation V3.08.8
 ;
 ;   OSTC dive mode menu
 ;
@@ -25,7 +25,9 @@
 dmenu_tree	CODE
 
 ;=============================================================================
-; Main Menu
+;
+; Dive Mode Menu
+;
 
 do_return_main_divemenu:
 	call	menu_processor_double_pop	; drop exit line and back to last line
@@ -35,9 +37,10 @@
 
 	global	do_main_divemenu
 do_main_divemenu:
-	call	menu_processor_reset		; restart from first icon
-	movlw	.1
-	movwf	menu_pos_cur				; set to first option in dive mode menu
+	movff	active_customview,backup_customview	; back up current custom view
+	call	menu_processor_reset				; restart from first icon
+	movlw	.1									; set cursor to first menu item
+	movwf	menu_pos_cur						; ...
 
 do_main_divemenu_common:
  IFDEF _ccr_pscr
@@ -54,28 +57,31 @@
  ENDIF
 
  IFDEF _cave_mode
-	btfss	cave_mode					; in cave mode?
-	bra		main_divemenu_OC_no_cave	; NO - do OC menu without turn option
+	TSTOSS	opt_cave_mode				; cave mode switched on?
+	bra		main_divemenu_OC_nocave		; NO  - use version without cave mode entry
+	;bra	main_divemenu_OC_cave		; YES - use version with    cave mode entry
 
+main_divemenu_OC_cave:
 	MENU_BEGIN	tMainMenu,	.6
 		MENU_CALL		tDivemenu_Gaslist,	do_divemode_gaslist
 		MENU_CALL		tDivemenu_ResetAvg,	do_reset_average
-		MENU_DYNAMIC	do_toggle_gf_label,	do_toggle_gf
+		MENU_DYNAMIC	label_do_toggle_gf,	do_toggle_gf
 		MENU_CALL		tDivemenu_Marker,	do_set_marker
-		MENU_DYNAMIC	do_turn_dive_label,	do_turn_dive
+		MENU_CALL		tCaveMode,			do_main_cavemenu
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
  ENDIF
 
-main_divemenu_OC_no_cave:
+main_divemenu_OC_nocave:
 	MENU_BEGIN	tMainMenu,	.5
 		MENU_CALL		tDivemenu_Gaslist,	do_divemode_gaslist
 		MENU_CALL		tDivemenu_ResetAvg,	do_reset_average
-		MENU_DYNAMIC	do_toggle_gf_label,	do_toggle_gf
+		MENU_DYNAMIC	label_do_toggle_gf,	do_toggle_gf
 		MENU_CALL		tDivemenu_Marker,	do_set_marker
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
+
 ;=============================================================================
 
  IFDEF _ccr_pscr
@@ -83,26 +89,25 @@
 main_divemenu_loop:
 	bsf		is_diluent_menu				; selecting diluents ...
 	bcf		is_bailout_menu				; ... (definitely) not for bailout reason
-	btfsc	FLAG_pscr_mode
-	bra		main_divemenu_pscr			; pSCR menu
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	bra		main_divemenu_pscr			; YES - show pSCR menu
 
 	MENU_BEGIN	tMainMenu,	.6
 		MENU_CALL		tDiveBailout,		do_divemode_gaslist_bail
 		MENU_CALL		tDivemenu_Setpoint,	do_divemode_splist
 		MENU_CALL		tDivemenu_Diluent,	do_divemode_gaslist
 		MENU_CALL		tDivemenu_Avg_Mkr,	do_reset_avg_set_mkr
-		MENU_DYNAMIC	do_toggle_gf_label,	do_toggle_gf
+		MENU_DYNAMIC	label_do_toggle_gf,	do_toggle_gf
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
 
 main_divemenu_pscr:
-
  IFDEF _external_sensor
 	btfsc	analog_o2_input				; do we have an analog  input (OSTC cR)?
-	bra		main_divemenu_pscr_sensors	; YES
+	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
 	btfsc	optical_input				; do we have an optical input (OSTC 3)?
-	bra		main_divemenu_pscr_sensors	; YES
+	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
  ENDIF
 
 main_divemenu_pscr_no_sensors:
@@ -111,19 +116,18 @@
 		MENU_CALL		tDivemenu_Premix,	do_divemode_gaslist
 		MENU_CALL		tBackToLoop,		do_switch_sp_calc
 		MENU_CALL		tDivemenu_Avg_Mkr,	do_reset_avg_set_mkr
-		MENU_DYNAMIC	do_toggle_gf_label,	do_toggle_gf
+		MENU_DYNAMIC	label_do_toggle_gf,	do_toggle_gf
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
-
+main_divemenu_pscr_sensors:
  IFDEF _external_sensor
-main_divemenu_pscr_sensors:
 	MENU_BEGIN	tMainMenu,	.6
 		MENU_CALL		tDiveBailout,		do_divemode_gaslist_bail
 		MENU_CALL		tCCRSensor,			do_divemode_setpoint_pscr
 		MENU_CALL		tDivemenu_Premix,	do_divemode_gaslist
 		MENU_CALL		tDivemenu_Avg_Mkr,	do_reset_avg_set_mkr
-		MENU_DYNAMIC	do_toggle_gf_label,	do_toggle_gf
+		MENU_DYNAMIC	label_do_toggle_gf,	do_toggle_gf
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
  ENDIF	; _external_sensor
@@ -132,44 +136,51 @@
 
 ;=============================================================================
 
+
+do_return_toggle_gf:
+	call	menu_processor_pop			; drop selection from menu stack
+	bra		do_toggle_gf_1				; re-draw the custom view and enter the menu again
+
 do_toggle_gf:
-	TSTOSS	char_I_deco_model			; toggle GF only in GF modes - in GF mode? (0 = ZH-L16, 1 = ZH-L16-GF)
+	TSTOSS	char_I_model				; toggle GF only in GF modes - in GF mode? (0 = ZH-L16, 1 = ZH-L16-GF)
 	bra		do_main_divemenu_common		; NO - do nothing and return
 	TSTOSS	opt_enable_aGF				; =1: aGF can be selected underwater
 	bra		do_main_divemenu_common		; NO - do nothing and return
-	movlw	index_gf_factors-1			; custom view number one below GF factors
-	movwf	active_customview			; set custom view number
-	bsf		request_next_custview		; initiate toggle to desired custom view -> GF factors
-	movlw	.1
-	movwf	menu_pos_cur				; set to first option in dive mode menu
+	bsf		custom_view_locked			; lock custom view
+do_toggle_gf_1:
+	movlw	index_gf_factors			; get  number of GF factors custom view
+	movwf	active_customview			; set  custom view number
+	call	dive_customview_callup		; draw custom view
+	movlw	.1							; set to first option in dive mode menu
+	movwf	menu_pos_cur				; ...
 
 	MENU_BEGIN	tDivemenu_ToggleGF,	.2
-		MENU_CALL		tDivemenu_ToggleGF,	do_togglegf
-		MENU_CALL		tBack,				do_return_main_divemenu
+		MENU_CALL		tDivemenu_ToggleGF,	do_toggle_gf_toggle
+		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
-do_togglegf:
-	bsf		request_toggle_GF			; set request flag
-	bra		do_exit_divemode_menu		; continue with exiting menu code
+do_toggle_gf_toggle:
+	bsf		request_toggle_GF			; set request flag to have the deco engine restarted
+	btg		use_aGF						; toggle normal / alternative GF factor selection
+	btfsc	use_aGF						; alternative GF factors activated?
+	bra		do_togglegf_agf				; YES - branch to using alternative GF
+	;bra	do_togglegf_ngf				; NO  - branch to using normal      GF
+
+do_togglegf_ngf:
+	movff	opt_GF_low, char_I_GF_Low_percentage	; use normal GF factor low
+	movff	opt_GF_high,char_I_GF_High_percentage	; use normal GF factor high
+	bra		do_return_toggle_gf						; back to menu
+
+do_togglegf_agf:
+	movff	opt_aGF_low, char_I_GF_Low_percentage	; use alternative GF factor low
+	movff	opt_aGF_high,char_I_GF_High_percentage	; use alternative GF factor high
+	bra		do_return_toggle_gf						; back to menu
 
 
 do_reset_avg_set_mkr:
-	movlw	.1
-	movwf	menu_pos_cur				; set to first option in dive mode menu
-
- IFDEF _cave_mode
-	btfss	cave_mode					; in cave mode?
-	bra		do_reset_average_no_cave	; NO - do menu without turn option
+	movlw	.1							; set to first option in dive mode menu
+	movwf	menu_pos_cur				; ...
 
-	MENU_BEGIN	tDivemenu_Avg_Mkr,	.4
-		MENU_CALL		tDivemenu_ResetAvg,	do_reset_average
-		MENU_CALL		tDivemenu_Marker,	do_set_marker
-		MENU_DYNAMIC	do_turn_dive_label,	do_turn_dive
-		MENU_CALL		tBack,				do_return_main_divemenu
-	MENU_END
- ENDIF
-
-do_reset_average_no_cave:
 	MENU_BEGIN	tDivemenu_Avg_Mkr,	.3
 		MENU_CALL		tDivemenu_ResetAvg,	do_reset_average
 		MENU_CALL		tDivemenu_Marker,	do_set_marker
@@ -182,27 +193,12 @@
  IFDEF _min_depth_option
 	bsf		reset_trip_pressure			; request ISR to reset the min and max trip-wise pressures
  ENDIF
-	bra		do_exit_divemode_menu		; exit
+	bra		do_exit_divemode_menu		; continue exiting the menu
 
 
 do_set_marker:
 	bsf		request_set_marker			; set request flag
-	bra		do_exit_divemode_menu		; exit
-
-
- IFDEF _cave_mode
-do_turn_dive:
-	bsf		request_turn_dive			; set request flag
-	bra		do_exit_divemode_menu		; exit
- ENDIF
-
-
- IFDEF _external_sensor
-do_switch_sensor:						; entry point when coming from switch to sensor
-	movlw	.1							; switch to sensor
-	movff	WREG,opt_ccr_mode			; =0: fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP
-	bra		do_switch_sp_com			; continue with common part
- ENDIF
+	bra		do_exit_divemode_menu		; continue exiting the menu
 
 ;=============================================================================
 
@@ -210,15 +206,15 @@
 
 do_switch_sp:							; entry point when coming from manual setpoint selection (CCR)
 	decf	menu_pos_cur,W				; 1-5 -> 0-4
-	lfsr	FSR1,opt_setpoint_cbar
-	movff	PLUSW1,char_I_const_ppO2	; setup fixed setpoint
+	lfsr	FSR1,opt_setpoint_cbar		; load base address
+	movff	PLUSW1,char_I_const_ppO2	; set selected setpoint
  IFDEF _external_sensor
 	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
  ENDIF
 	bcf		sp_fallback					; clear fallback condition (stops fallback warning)
 	clrf	WREG						; switch to fixed SP
 	movff	WREG,opt_ccr_mode			; =0: Fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP
-	bra		do_switch_sp_com
+	bra		do_switch_sp_com			; continue with common part
 
 
 do_switch_sp_calc:						; entry point when coming from switch to calculated ppO2 (pSCR)
@@ -226,7 +222,7 @@
 	clrf	WREG						; switch to fixed SP
 	movff	WREG,opt_ccr_mode			; =0: Fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP
 	movff	WREG,char_I_const_ppO2		; set setpoint to 0, this forces deco engine to take the computed ppO2
-	;bra	do_switch_sp_com
+	;bra	do_switch_sp_com			; continue with common part
 
 
 do_switch_sp_com:						; common part
@@ -239,12 +235,12 @@
 	bcf		better_dil_available		; =1: a better diluent is available and a gas change is advised in dive mode
 	bcf		better_gas_blinking			; clear blinking flag
 	bcf		better_dil_blinking			; clear blinking flag
-	call	dive_customview_mask		; redraw custom view mask to (eventually) rewrite "ppO2(Dil)" to "ppO2" or SAC label
+	call	dive_customview_callup		; redraw custom view mask to (if applicable) rewrite "ppO2(Dil)" to "ppO2" or SAC label
 
 	bsf		request_back_to_loop		; indicate that it is a switchback from OC bailout to CCR/pSCR loop
-	bsf		request_gaschange			; initiate reconfiguration to loop mode on last diluent
+	bsf		request_gas_change			; initiate reconfiguration to loop mode on last diluent
 
-	bra		do_exit_divemode_menu		; continue with exiting menu code
+	bra		do_exit_divemode_menu		; continue exiting the menu
 
 
 do_divemode_gaslist_bail:				; entry point from CCR/pSCR to bailout to OC gases
@@ -263,6 +259,7 @@
  ENDIF
 	bsf		short_gas_descriptions		; do not show "Gas x" etc.
 	bsf		better_gas_hint				; mark the gas which is the best gas/diluent
+	bsf		color_code_gases			; color-code the gases/diluents by their ppO2 and current depth
 	movf	best_gas_number,W			; load number of best gas (1-5)into WREG
  IFDEF _ccr_pscr
 	btfsc	is_diluent_menu				; in diluent selection?
@@ -274,23 +271,25 @@
 	movlw	.1							; YES - default to first gas/dil
 do_divemode_gaslist_1:
 	movwf	menu_pos_cur				; position cursor to best gas/dil (or first option if none avail)
+
 	MENU_BEGIN	tGaslist,	.6
 		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_switch_gas
 		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_switch_gas
 		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_switch_gas
 		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_switch_gas
 		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_switch_gas
-		MENU_CALL		tMore,					do_divemode_gaslist_more
+		MENU_CALL		tDivemenu_LostGas,		do_lost_gas
 	MENU_END
 
 
-do_divemode_gaslist_more:
-	movlw	.1
-	movwf	menu_pos_cur					; set to first option in dive mode menu
-
-	movff	char_I_O2_ratio,gas6_O2_ratio	; initialize gas6 with currently breathed gas - O2 ratio
+do_gas6_or_exit:
+	btfsc	gas6_or_EXIT					; shall exit?
+	bra		do_exit_divemode_menu			; YES - continue exiting menu
+	movlw	.1								; NO  - select first item
+	movwf	menu_pos_cur					;     - set cursor
+	movff	char_I_O2_ratio,gas6_O2_ratio	;     - initialize gas6 with currently breathed gas - O2 ratio
  IFDEF _helium
-	movff	char_I_He_ratio,gas6_He_ratio	; initialize gas6 with currently breathed gas - He ratio
+	movff	char_I_He_ratio,gas6_He_ratio	;     - initialize gas6 with currently breathed gas - He ratio
  ENDIF
 
 do_divemode_gaslist_more_common:
@@ -301,32 +300,34 @@
 		MENU_CALL		tHePlus,				do_dive_pHe
 		MENU_CALL		tHeMinus,				do_dive_mHe
 		MENU_DYNAMIC	gaslist_strcat_gas6,	do_switch_gas6
-		MENU_CALL		tDivemenu_LostGas,		do_lost_gas
+		MENU_CALL		tExit,					do_exit_divemode_menu
 	MENU_END
  ELSE
 	MENU_BEGIN	tGaslist,	.4
 		MENU_CALL		tO2Plus,				do_dive_pO2
 		MENU_CALL		tO2Minus,				do_dive_mO2
 		MENU_DYNAMIC	gaslist_strcat_gas6,	do_switch_gas6
-		MENU_CALL		tDivemenu_LostGas,		do_lost_gas
 		MENU_CALL		tExit,					do_exit_divemode_menu
 	MENU_END
  ENDIF
 
 
 do_lost_gas:
-	movlw	.1
-	movwf	menu_pos_cur				; set to first option in dive mode menu
+	movlw	.1							; set to first option in dive mode menu
+	movwf	menu_pos_cur				; ...
+	bcf		gas6_or_EXIT				; default to presenting gas6 option
 do_lost_gas_common:
 	bsf		short_gas_descriptions		; do not show "Gas x" etc.
 	bcf		better_gas_hint				; do not mark the best gas/diluent
+	bcf		color_code_gases			; do not color-code the gases/diluents by their ppO2
+
 	MENU_BEGIN	tDivemenu_LostGas, .6
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_active	; toggle the gas (in)active
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_active	; toggle the gas (in)active
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_active	; toggle the gas (in)active
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_active	; toggle the gas (in)active
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_active	; toggle the gas (in)active
-		MENU_CALL		tExit,					do_exit_divemode_menu
+		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_staged_lost
+		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_staged_lost
+		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_staged_lost
+		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_staged_lost
+		MENU_DYNAMIC	gaslist_strcat_gas_cd,	do_toggle_staged_lost
+		MENU_DYNAMIC	label_do_gas6_or_exit,	do_gas6_or_exit
 	MENU_END
 
 
@@ -338,80 +339,119 @@
 
 
 do_switch_gas:
-	bsf		request_gaschange			; initiate gas change, will also trigger restart of deco_engine
+	bsf		request_gas_change			; initiate gas change, will also trigger restart of deco_engine
+ IFDEF _ccr_pscr
 	btfss	is_bailout_menu				; doing a bailout?
 	bra		do_switch_gas_1				; NO
 	bsf		bailout_mode				; YES - begin bailout mode
+ ENDIF
  IFDEF _cave_mode
-	btfsc	cave_mode					;     - in cave mode?
-	bsf		dive_turned					;       YES - set dive as turned
+	btfsc	cave_mode					;     - cave mode switched on?
+	bsf		request_turn_turn			;       YES - request to turn the dive
+ ENDIF
+ IFDEF _ccr_pscr
+do_switch_gas_1:
+	bcf		sp_fallback					; terminate fallback mode and get rid of its warning if applicable
+	call	dive_customview_callup		; redraw custom view mask to rewrite "ppO2(Dil)" to "ppO2" or SAC label if applicable
  ENDIF
-do_switch_gas_1:
-	bcf		sp_fallback					; eventually terminate fallback mode and get rid of its warning
-	call	dive_customview_mask			; redraw custom view mask to (eventually) rewrite "ppO2(Dil)" to "ppO2" or SAC label
-	;bra	do_exit_divemode_menu		; continue with exiting menu code
+	; revoke staged and lost state on the selected gas
+	lfsr	FSR1,opt_gas_type			; load base address of gas types
+	movff	menu_pos_cur,lo				; copy selected gas to lo
+ IFDEF _ccr_pscr
+	movlw	.5							; load WREG with diluent offset
+	btfsc	is_diluent_menu				; operating on diluents?
+	addwf	lo,F						; YES - add diluent offset to shift 1-5 -> 6-10
+ ENDIF	; _ccr_pscr
+	decf	lo,W						; 1-10 -> 0-4 for gases / 5-9 for diluents with result into WREG
+	bcf		PLUSW1,gas_lost				; revoke lost   state
+ IFDEF _cave_mode
+	bcf		PLUSW1,gas_staged			; revoke staged state
+ ENDIF
+	;bra	do_exit_divemode_menu		; continue exiting the menu
 
 
+; +++ Dive Mode and Cave Mode common exit point +++
 do_exit_divemode_menu:
-	call	timeout_divemode_menu2
-	clrf	STKPTR
-	goto	diveloop_menu_exit
+	call	timeout_divemode_menu2		; check for timeout and do some cleanup
+	clrf	STKPTR						; reset the stack
+	goto	diveloop_menu_exit			; back to the dive loop
 
 
-do_toggle_active:
-	movlw	.5
+do_toggle_staged_lost:
+	movff	menu_pos_cur,lo				; copy selected gas/diluent to lo   (1-5)
+	movf	active_gas,W				; copy currently used gas   to WREG (1-5)
  IFDEF _ccr_pscr
-	btfsc	is_diluent_menu				; operating on diluents?
-	addwf	menu_pos_cur,F				; YES - add offset of 5 to shift 1-5 -> 6-10
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		do_toggle_staged_lost_check	; YES - can't be in diluent menu then, check selected gas against gas in use
+	btfsc	bailout_mode				; NO  - in bailout?
+	bra		do_toggle_staged_lost_check	;       YES - can't be in diluent menu then, check selected gas against bailout gas in use
+	btfss	is_diluent_menu				;       NO  - breathing a diluent then, in diluent menu?
+	bra		do_toggle_staged_lost_exec	;             NO  - can modify any gas, no need for a check
+	movf	active_dil,W				;             YES - check selected diluent against diluent in use
  ENDIF
-	decf	menu_pos_cur,W				; 1-10 -> 0-4 for gases / 5-9 for diluents
-	lfsr	FSR1,opt_gas_type			; load base address of gas types
-	movff	PLUSW1,lo					; get gas/dil type
-	tstfsz	lo							; already disabled?
-	bra		do_toggle_active_disable	; NO  - disable   now
-do_toggle_active_enable					; YES - re-enable now
-	lfsr	FSR1,opt_gas_type_backup	; load base address of backed-up gas types
-	movff	PLUSW1,lo					; get backed-up gas/dil type
+do_toggle_staged_lost_check:
+	cpfseq	lo							; selected gas/dil = currently used gas/dil?
+	bra		do_toggle_staged_lost_exec	; NO  - can set selected gas/dil to lost or staged
+	bra		do_lost_gas_common			; YES - gas/dil in use, can not set to lost or staged, back to menu
+do_toggle_staged_lost_exec:
 	lfsr	FSR1,opt_gas_type			; load base address of gas types
-	movff	lo,PLUSW1					; restore gas type
-	bra		do_toggle_active_common
-do_toggle_active_disable:				; disable gas / diluent
-	;lfsr	FSR1,opt_gas_type			; (still set)
-	clrf	PLUSW1						; set type to disabled (0=disabled, 1=first, 2=travel/normal, 3=deco/-)
-do_toggle_active_common:
-	movlw	.5
+	bcf		better_gas_blinking			; clear blinking flag for gases    to avoid "leftovers"
  IFDEF _ccr_pscr
+	bcf		better_dil_blinking			; clear blinking flag for diluents to avoid "leftovers"
+	movlw	.5							; load WREG with diluent offset
 	btfsc	is_diluent_menu				; operating on diluents?
-	subwf	menu_pos_cur,F				; YES - back to 1-5
-	bcf		better_dil_blinking			; clear blinking flag for diluents to avoid "leftovers"
- ENDIF
-	bcf		better_gas_blinking			; clear blinking flag for gases    to avoid "leftovers"
-	call	restart_deco_engine_wo_ceiling ; invalidate deco data (but not the ceiling) and restart deco engine
-	bra		do_lost_gas_common
+	addwf	lo,F						; YES - add diluent offset to shift 1-5 -> 6-10
+ ENDIF	; _ccr_pscr
+ IFDEF _cave_mode
+	TSTOSS	opt_cave_mode				; cave mode switched on?
+	bra		do_toggle_staged_lost_3		; NO  - just toggle lost state
+	decf	lo,W						; YES - 1-10 -> 0-4 for gases / 5-9 for diluents with result into WREG
+	btfsc	PLUSW1,gas_staged			;     - gas currently set as staged?
+	bra		do_toggle_staged_lost_1		;       YES - set as lost now
+	btfsc	PLUSW1,gas_lost				;       NO  - gas currently set as lost?
+	bra		do_toggle_staged_lost_2		;             YES - set as available now
+	;bra	do_toggle_staged_lost_0		;             NO  - set as staged    now
+do_toggle_staged_lost_0:
+	bsf		PLUSW1,gas_staged			; set    staged state
+	bra		do_toggle_staged_lost_4		; continue with restarting deco engine
+do_toggle_staged_lost_1:
+	bcf		PLUSW1,gas_staged			; revoke staged state
+	bsf		PLUSW1,gas_lost				; set    lost   state
+	bra		do_toggle_staged_lost_4		; continue with restarting deco engine
+do_toggle_staged_lost_2:
+	bcf		PLUSW1,gas_lost				; revoke lost   state
+	bra		do_toggle_staged_lost_4		; continue with restarting deco engine
+ ENDIF	; _cave_mode
+do_toggle_staged_lost_3:
+	decf	lo,W						; 1-10 -> 0-4 for gases / 5-9 for diluents with result into WREG
+	btg		PLUSW1,gas_lost				; toggle lost state
+do_toggle_staged_lost_4:
+	bsf		request_gas_update			; request to update the gases
+	bsf		gas6_or_EXIT				; switch 6th menu item from gas6 to exit
+	bra		do_lost_gas_common			; back to the menu
 
 
 do_dive_pO2:
-	incf	gas6_O2_ratio,F				; O2++
+	incf	gas6_O2_ratio,F				; increment O2 %
  IFDEF _helium
-	movf	gas6_He_ratio,W
-	addwf	gas6_O2_ratio,W
+	movf	gas6_He_ratio,W				; get He %
+	addwf	gas6_O2_ratio,W				; add O2 %
  ELSE
-	movf	gas6_O2_ratio,W
+	movf	gas6_O2_ratio,W				; get O2 %
  ENDIF
-	movwf	lo
-	movlw	.101
-	cpfslt	lo							; O2 + He < 101 ?
-	decf	gas6_O2_ratio,F				; O2-- (unchanged)
+	movwf	lo							; copy to lo
+	movlw	.101						; O2 + He < 101 
+	cpfslt	lo							; ... ?
+	decf	gas6_O2_ratio,F				; NO  - decrement O2 again
 	bra		do_divemode_gaslist_more_common
 
 
 do_dive_mO2:
-	decf	gas6_O2_ratio,F				; O2--
-	movlw	gaslist_min_o2
+	decf	gas6_O2_ratio,F				; decrement O2 %
+	movlw	gaslist_min_o2				; get minimum value
 	cpfslt	gas6_O2_ratio				; O2 < minimum allowed %O2 ?
-	bra		do_dive_mO2_done			; NO
-	movlw	gaslist_min_o2				; YES - restore minimum
-	movwf	gas6_O2_ratio
+	bra		do_dive_mO2_done			; NO  - value is valid
+	movwf	gas6_O2_ratio				; YES - set O2 % to minimum
 do_dive_mO2_done:
 	bra		do_divemode_gaslist_more_common
 
@@ -420,17 +460,17 @@
  IFDEF _helium
 
 do_dive_pHe:
-	incf	gas6_He_ratio,F				; He++
-	movf	gas6_He_ratio,W
-	addwf	gas6_O2_ratio,W
-	movwf	lo
-	movlw	.101
-	cpfslt	lo							; O2 + He < 101 ?
-	decf	gas6_He_ratio,F				; YES - He-- (unchanged)
+	incf	gas6_He_ratio,F				; increment He %
+	movf	gas6_He_ratio,W				; get He %
+	addwf	gas6_O2_ratio,W				; add O2 %
+	movwf	lo							; copy to lo
+	movlw	.101						; O2 + He < 101
+	cpfslt	lo							; ... ?
+	decf	gas6_He_ratio,F				; YES - decrement He again
 	bra		do_divemode_gaslist_more_common
 
 do_dive_mHe:
-	decf	gas6_He_ratio,F				; He--
+	decf	gas6_He_ratio,F				; decrement He %
 	bnn		do_dive_mHe_done			; H2 < 0 ?
 	clrf	gas6_He_ratio				; YES - reset to 0
 do_dive_mHe_done:
@@ -485,11 +525,11 @@
 
 
 do_divemode_sensor:
-	movlw	index_ppo2_sensors-1		; custom view number one below ppO2 sensors
-	movwf	active_customview			; set custom view number
-	bsf		request_next_custview		; initiate toggle to desired custom view -> ppO2 sensors
-	movlw	.1
-	movwf	menu_pos_cur				; set to 1st option: use sensors
+	movlw	index_ppo2_sensors			; number of ppO2 sensors custom view
+	movwf	active_customview			; set     the custom view number
+	call	dive_customview_callup		; call-up the custom view
+	movlw	.1							; set to 1st option: use sensors
+	movwf	menu_pos_cur				; ...
 
 do_return_divemode_sensor:
 	MENU_BEGIN	tGaslist,	.6
@@ -501,10 +541,10 @@
 		MENU_CALL		tDiveHudMask3,			do_toggle_sensor
 	MENU_END
 
-
 do_divemode_setpoint_pscr:
 	movlw	.1
 	movwf	menu_pos_cur				; set to 1st option: use calculated ppO2
+
 	MENU_BEGIN	tGaslist,	.6
 		MENU_CALL		tCalculated,			do_switch_sp_calc
 		MENU_CALL		tDivemenu_UseSensor,	do_switch_sensor
@@ -514,6 +554,10 @@
 		MENU_CALL		tDiveHudMask3,			do_toggle_sensor
 	MENU_END
 
+do_switch_sensor:						; entry point when coming from switch to sensor
+	movlw	.1							; switch to sensor
+	movff	WREG,opt_ccr_mode			; =0: fixed SP (CCR) / calculated (pSCR), =1: Sensor, =2: Auto SP
+	bra		do_switch_sp_com			; continue with common part
 
 do_toggle_sensor:
 	movff	menu_pos_cur,lo				; backup position
@@ -521,11 +565,11 @@
 	decf	menu_pos_cur,f				; 3, 4, 5 ->  2, 3, 4
 	decf	menu_pos_cur,f				; 2, 3, 4 ->  1, 2, 3
 	dcfsnz	menu_pos_cur				; 1, 2, 3 ->  0, 1, 2
-	btg		use_O2_sensor1				;			  = 
+	btg		use_O2_sensor1				;             = 
 	dcfsnz	menu_pos_cur				; 0, 1, 2 -> -1, 0, 1
-	btg		use_O2_sensor2				;				 =
+	btg		use_O2_sensor2				;                =
 	dcfsnz	menu_pos_cur				; -1,0, 1 -> -2,-1, 0
-	btg		use_O2_sensor3				;					=
+	btg		use_O2_sensor3				;                   =
 	movff	lo,menu_pos_cur				; restore position
 	bra		do_return_divemode_sensor
 
@@ -533,5 +577,70 @@
  ENDIF	; _ccr_pscr
 
 ;=============================================================================
+;
+; Cave Mode Menu
+;
+
+ IFDEF _cave_mode
+
+do_return_main_cavemenu:
+	call	menu_processor_pop					; drop selection from menu stack
+	incf	selected_item,W						; item numbers start with 0, menu positions with 1
+	movwf	menu_pos_cur						; position cursor where we came from
+	bra		do_main_cavemenu_common				; continue with common part
+
+	global	do_main_cavemenu
+do_main_cavemenu:
+	bsf		custom_view_locked					; lock custom view
+	movff	active_customview,backup_customview	; back up current custom view
+	call	menu_processor_reset				; restart from first icon
+	movlw	.1									; set cursor to first menu item by default
+	btfsc	dive_turned							; dive turned ?
+	movlw	.4									; YES - set cursor on waypoint out item
+	btfss	cave_mode							; cave mode switched off ?
+	movlw	.3									; YES - set cursor on cave mode off/on menu item
+	movwf	menu_pos_cur						; actually set cursor position
+
+	; The helper functions for MENU_DYNAMIC can be found in
+	; gaslist.asm as it does not work to include them here.
+
+do_main_cavemenu_common:
+	movlw	index_cave_waypoints				; get  number of cave waypoints custom view
+	movwf	active_customview					; set  custom view number
+	call	dive_customview_callup				; draw custom view
+
+	MENU_BEGIN	tMainMenu,	.6
+		MENU_DYNAMIC	label_do_wp_set,		do_waypoint_set			; 1
+		MENU_DYNAMIC	label_do_turn_dive,		do_turndive_toggle		; 2
+		MENU_CALL		tDivemenu_off_on,		do_cavemode_toggle		; 3
+		MENU_DYNAMIC	label_do_wp_out,		do_waypoint_out			; 4
+		MENU_DYNAMIC	label_do_wp_in,			do_waypoint_in			; 5
+		MENU_CALL		tExit,					do_exit_divemode_menu	; 6
+	MENU_END
+
+
+do_waypoint_set:
+	bsf		request_waypoint_set		; set request flag
+	bra		do_return_main_cavemenu		; back to menu
+
+do_turndive_toggle:
+	bsf		request_turn_toggle			; set request flag
+	bra		do_return_main_cavemenu		; back to menu
+
+do_cavemode_toggle:
+	bsf		request_cave_toggle			; set request flag
+	bra		do_return_main_cavemenu		; back to menu
+
+do_waypoint_out:
+	bsf		request_waypoint_out		; set request flag
+	bra		do_return_main_cavemenu		; back to menu
+
+do_waypoint_in:
+	bsf		request_waypoint_in			; set request flag
+	bra		do_return_main_cavemenu		; back to menu
+
+ ENDIF	; _cave_mode
+
+;=============================================================================
 
 	END
--- a/src/divemode.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/divemode.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemode.asm                         combined next generation V3.04.3
+;   File divemode.asm                         combined next generation V3.08.8
 ;
 ;   Dive Mode
 ;
@@ -31,13 +31,16 @@
 	extern	do_line_menu
 	extern	do_main_divemenu
 	extern	menu_draw_lines_divemode
-	extern	option_save_all
 	extern	init_recording_params
+	extern	option_check_and_store_all
 
  IFDEF _compass
 	extern	TFT_dive_compass_heading
  ENDIF
 
+ IFDEF _cave_mode
+	extern	do_main_cavemenu
+ ENDIF
 
 ;---- Private local Variables -------------------------------------------------
 
@@ -78,14 +81,14 @@
 #DEFINE FLAG_TFT_depth_maximum_apnoe	TFT_output_flags_1,4	; =1: show  maximum depth of last apnoe dive
 #DEFINE FLAG_TFT_clear_apnoe_surface	TFT_output_flags_1,5	; =1: clear apnoe mode surface data from screen
 #DEFINE FLAG_TFT_apnoe_divetime			TFT_output_flags_1,6	; =1: show  apnoe mode dive times
-;										TFT_output_flags_1,7	; --- unused
+#DEFINE FLAG_TFT_temperature			TFT_output_flags_1,7	; =1: show  temperature (or resettable dive time when in compass view)
 
 ; TFT_output_flags_2 - phase 2: every second - before deco calculations, deco modes only
 #DEFINE FLAG_TFT_divemode_mask			TFT_output_flags_2,0	; =1: show  dive mode mask
 #DEFINE FLAG_TFT_divetime				TFT_output_flags_2,1	; =1: show  dive time
 #DEFINE FLAG_TFT_safety_stop_show		TFT_output_flags_2,2	; =1: show  safety stop
 #DEFINE FLAG_TFT_safety_stop_clear		TFT_output_flags_2,3	; =1: clear safety stop
-#DEFINE FLAG_TFT_temperature			TFT_output_flags_2,4	; =1: show  temperature (or resettable dive time when in compass view)
+;										TFT_output_flags_2,4	; --- unused
 ;										TFT_output_flags_2,5	; --- unused
 ;										TFT_output_flags_2,6	; --- unused
 ;										TFT_output_flags_2,7	; --- unused
@@ -101,7 +104,7 @@
 ;										TFT_output_flags_3,7	; --- unused
 
 ; TFT_output_flags_4 - phase 4: every second - after deco calculations, all modes
-#DEFINE FLAG_TFT_customview_mask		TFT_output_flags_4,0	; =1: show  the custom view mask
+#DEFINE FLAG_TFT_customview_callup		TFT_output_flags_4,0	; =1: show  the custom view mask
 #DEFINE FLAG_TFT_sign_show				TFT_output_flags_4,1	; =1: show  the advice / attention / warning sign
 #DEFINE FLAG_TFT_sign_clear				TFT_output_flags_4,2	; =1: clear the advice / attention / warning sign
 #DEFINE FLAG_TFT_message_clear_both		TFT_output_flags_4,3	; =1: clear messages, both rows
@@ -132,14 +135,14 @@
 ;										xmitter_flags_mesg,7	; --- unused
 
 ; various Flags
-#DEFINE FLAG_backtrack_full				DM_flags_local,0		; =1: the backtracking storage is full
-#DEFINE new_deco_data_avail				DM_flags_local,1		; =1: new NDL or deco data available
-#DEFINE o2_sensors_agree				DM_flags_local,2		; =1: the ppO2 of all sensors are within the threshold range
-#DEFINE update_menu						DM_flags_local,3		; =1: redraw the dive menu
-#DEFINE FLAG_SP2_used					DM_flags_local,4		; =1: setpoint 2 has been auto-selected already
-#DEFINE FLAG_SP3_used					DM_flags_local,5		; =1: setpoint 3 has been auto-selected already
-#DEFINE FLAG_SP4_used					DM_flags_local,6		; =1: setpoint 4 has been auto-selected already
-#DEFINE FLAG_SP5_used					DM_flags_local,7		; =1: setpoint 5 has been auto-selected already
+#DEFINE new_deco_data_avail				DM_flags_local,0		; =1: new NDL or deco data available
+#DEFINE o2_sensors_agree				DM_flags_local,1		; =1: the ppO2 of all sensors are within the threshold range
+#DEFINE update_menu						DM_flags_local,2		; =1: redraw the dive menu
+#DEFINE FLAG_SP2_used					DM_flags_local,3		; =1: setpoint 2 has been auto-selected already
+#DEFINE FLAG_SP3_used					DM_flags_local,4		; =1: setpoint 3 has been auto-selected already
+#DEFINE FLAG_SP4_used					DM_flags_local,5		; =1: setpoint 4 has been auto-selected already
+#DEFINE FLAG_SP5_used					DM_flags_local,6		; =1: setpoint 5 has been auto-selected already
+;										DM_flags_local,7		; --- unused
 
 
 dmode	CODE
@@ -156,12 +159,16 @@
 
 	; reset global flags
 	clrf	DM_flags_state				; clear all flags for dive mode status
-	clrf	DM_flags_request			; clear all flags for user requests
 	clrf	DM_flags_event				; clear all flags for data recording events
+	clrf	DM_flags_request			; clear all flags for user requests / general
+ IFDEF _cave_mode
+	clrf	DM_flags_cavereq			; clear all flags for user requests / cave mode
+ ENDIF
 	clrf	DM_flags_layout1			; clear all flags for display control / layout (1)
 	clrf	DM_flags_layout2			; clear all flags for display control / layout (2)
+	clrf	DM_flags_layout3			; clear all flags for display control / layout (3)
 	clrf	DM_flags_message			; clear all flags for display control / messages
-	clrf	DM_flags_gas_dil			; clear all flags for display control / gases and diluents
+	clrf	DM_flags_gas_dil			; clear all flags for display control / gases, diluents, depth
 
 	bcf		dive_main_menu				; clear dive main    menu flag
 	bcf		dive_options_menu			; clear dive options menu flag
@@ -175,16 +182,17 @@
 	clrf	xmitter_flags_mesg			; clear all pressure transmitter message flags
 	clrf	DM_flags_local				; clear all the various other flags, too
 
-	; set initial screen layout
-	bcf		alt_layout_active			; default to normal layout
+	; configure screen layout (all flags were cleared above)
 	TSTOSC	opt_layout					; alternative layout enabled?
 	bsf		alt_layout_active			; YES - start with alternative layout
 
- IFDEF _gas_contingency
-	; disable gas contingency mode (may be left over activated by deco calculator)
-	clrf	WREG
-	movff	WREG,char_I_gas_contingency
- ENDIF
+	; configure tissue graphics (all flags were cleared above)
+	TSTOSS	opt_tissue_graphics			; shall show: 0= pres+sat, 1= N2+He
+	bsf		tissue_graphic_layout		; YES - show press+sat
+
+	TSTOSC	char_I_model				; GF factors enabled?
+	bsf		tissue_graphic_gf			; YES - show GF lines
+
 
 	; boot tasks for all modes
 	call	diveloop_boot
@@ -199,7 +207,7 @@
 
 	; reload and redraw last custom view
 	movff	customview_divemode,active_customview
-	bsf		FLAG_TFT_customview_mask
+	bsf		FLAG_TFT_customview_callup
 
 	bcf		divetime_longer_1min		; the dive has just begun
 	btfsc	FLAG_apnoe_mode				; in apnea mode?
@@ -263,7 +271,7 @@
 	bra		diveloop_loop_11			; YES - done with 1/2 second tasks
 
 	; tasks every 1/2 second in deco modes
-	call	calc_deco_engine			; ##### calculate decompression #####
+	call	callup_deco_engine			; ##### manage and invoke the deco calculation engine #####
 	bra		diveloop_loop_11			; done with 1/2 second tasks
 
 diveloop_loop_2:
@@ -309,11 +317,13 @@
 	MOVII	xC,pressure_abs_10			; store result for later use
 
 	; compute current depth in meters
-	MOVII	pressure_rel_cur_cached,xA	; copy current relative pressure to xA
-	ADDLI	.50, xA						; add 0.5 meter = 50 mbar for rounding up/down at 0.5 meters
-	MOVLI	.100,xB						; divide by 100 to turn mbar into meters
+	MOVII	pressure_rel_cur_cached,mpr	; copy current relative pressure in [mbar] to MPR
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
+	ADDLI	.50,mpr						; add 50 cm for rounding up/down around 0.5 meters
+	MOVII	mpr, xA						; copy depth in [cm]   into xA
+	MOVLI	.100,xB						; load factor 100 cm/m into xB
 	call	div16x16					; xC = xA / xB = depth in full meters
-	movff	xC+0,depth_meter			; store result in depth_meter, only LSB of result needed
+	movff	xC+0,depth_meter			; store result as depth in [m], only low byte needed
 
  IFDEF _ccr_pscr
 	; adjust auto-setpoint
@@ -338,6 +348,24 @@
 	rcall	calc_deko_divemode_sensor	; YES - do sensor data acquisition if applicable
  ENDIF
 
+ IFDEF _cave_mode
+	btfss	cave_mode					; cave mode switched on?
+	bra		diveloop_loop_4a			; NO  - no backtracking depth recording
+	btfsc	dive_turned					; dive turned?
+	bra		diveloop_loop_4a			; YES - no backtracking depth recording
+	btfsc	backtrack_entire_full		; backtracking storage entirely used up?
+	bra		diveloop_loop_4a			; YES - no backtracking depth recording
+
+	incf	backtrack_deltatime,F		; increment time elapsed since last depth recording
+	movlw	.59							; load WREG with coding of last second of a minute
+	cpfsgt	backtrack_deltatime			; time elapsed since last depth recording > 59 seconds?
+	bra		diveloop_loop_4a			; NO  - no backtracking depth recording now
+	rcall	write_backtrack_1min_depth	;     - store a backtracking depth data set
+ ENDIF
+
+diveloop_loop_4a:
+	; continue tasks every 1/1 second
+
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	rcall	divemode_apnoe_tasks		; YES - do 1 sec. apnoe tasks
 
@@ -376,7 +404,7 @@
 	btfsc	FLAG_gauge_mode				; in gauge mode?
 	bra		diveloop_loop_7				; YES - skip deco calculations
 
-	call	calc_deco_engine			; ##### calculate decompression #####
+	call	callup_deco_engine			; ##### manage and invoke the deco calculation engine #####
 
 	btfsc	new_deco_data_avail			; new NDL or deco data available?
 	call	show_new_deco_data			; YES - update the display and update the decostop_active flag
@@ -396,7 +424,7 @@
 diveloop_loop_8:
 	; deco mode tasks alternating every 2 seconds on resettable dive time
 	btfss	divesecs_avg_trip+0,0		; on even second of resettable dive time?
-	rcall	calc_average_depth			; YES - calculate average depth
+	call	calc_average_depth			; YES - calculate average depth
 	btfsc	divesecs_avg_trip+0,0		; on odd  second of resettable dive time?
 	rcall	safety_stop_control			; YES - exercise safety stop control
 
@@ -408,7 +436,7 @@
 diveloop_loop_10:
 	; common tasks every 1/1 second
 	rcall	timeout_divemode			; check for timeout condition
-	rcall	check_dive_modes			; test if depth still deeper than threshold
+	call	check_dive_modes			; test if depth still deeper than threshold
 
 	btfsc	trigger_full_minute			; has next minute begun?
 	rcall	update_divemode60			; YES - update clock, etc.
@@ -436,15 +464,36 @@
 	btfsc	request_next_custview		; shall show next custom view?
 	call	dive_customview_toggle		; YES - show next custom view (and delete this flag)
 
-	btfsc	request_gaschange			; shall change gas?
-	call	gas_switched_common			; YES
+	btfsc	request_gas_change			; shall change gas?
+	call	gas_switch_common			; YES
+
+	btfsc	request_gas_update			; shall update the gases?
+	call	gas_update_common			; YES
 
 	btfsc	request_toggle_GF			; shall toggle GF/aGF?
 	rcall	divemodemode_togglegf		; YES
 
  IFDEF _cave_mode
-	btfsc	request_turn_dive			; shall turn dive?
-	rcall	divemodemode_toggleturn		; YES
+	btfsc	request_cave_off_turned		; shall switch cave mode off and set the dive as turned?
+	rcall	cavemode_switch_off_turned	; YES
+
+	btfsc	request_cave_toggle			; shall toggle cave mode off/on?
+	rcall	cavemode_toggle_onoff		; YES
+
+	btfsc	request_turn_turn			; shall turn the dive?
+	rcall	cavemode_turndive_turn		; YES
+
+	btfsc	request_turn_toggle			; shall toggle the turn dive state?
+	rcall	cavemode_turndive_toggle	; YES
+
+	btfsc	request_waypoint_set		; shall set a waypoint?
+	rcall	cavemode_waypoint_set		; YES
+
+	btfsc	request_waypoint_out		; shall step one waypoint out of the cave?
+	rcall	cavemode_waypoint_out		; YES
+
+	btfsc	request_waypoint_in			; shall step one waypoint into the cave?
+	rcall	cavemode_waypoint_in		; YES
  ENDIF
 
 	btfsc	request_set_marker			; shall set a marker?
@@ -475,6 +524,8 @@
 	call	TFT_show_max_depth				; YES - display max depth
 	btfsc	FLAG_TFT_active_gas_divemode	; shall show active gas and dive mode?
 	call	TFT_show_active_gas_divemode	; YES - display gas, setpoint and mode
+	btfsc	FLAG_TFT_temperature			; shall show temperature?
+	call	TFT_show_temp_divemode			; YES - display temperature (or resettable dive time)
 
 	btfsc	FLAG_TFT_apnoe_surface_time		; shall show apnoe mode surface time?
 	call	TFT_show_apnoe_surface			; YES - show apnoe mode surface time
@@ -495,8 +546,6 @@
 	call	TFT_safety_stop_show			; YES - show safety stop
 	btfsc	FLAG_TFT_safety_stop_clear		; shall clear safety stop?
 	call	TFT_safety_stop_clear			; YES - clear safety stop
-	btfsc	FLAG_TFT_temperature			; shall show temperature?
-	call	TFT_show_temp_divemode			; YES - display temperature (or resettable dive time)
 	clrf	TFT_output_flags_2				; mark all TFT updates done
 	goto	dive_customview_second			; do every-second tasks for the custom view area (in sync with the dive time) and return
 
@@ -517,12 +566,12 @@
 	return									; done
 
 TFT_output_4:								; every second - after deco calculations, all modes
-	btfsc	FLAG_TFT_customview_mask		; shall redraw the custom view mask?
-	call	dive_customview_mask			; YES - redraw custom view mask
+	btfsc	FLAG_TFT_customview_callup		; shall show a custom view?
+	call	dive_customview_callup			; YES - show a custom view
 	btfsc	FLAG_TFT_velocity_show			; shall show  vertical velocity?
-	call	TFT_velocity_show				; YES - show  vertical velocity?
+	call	TFT_velocity_show				; YES - show  vertical velocity
 	btfsc	FLAG_TFT_velocity_clear			; shall clear vertical velocity?
-	call	TFT_velocity_clear				; YES - clear vertical velocity?
+	call	TFT_velocity_clear				; YES - clear vertical velocity
 	btfsc	FLAG_TFT_sign_show				; shall show  the advice / attention / warning sign?
 	call	TFT_divemode_sign_show			; YES - show sign
 	btfsc	FLAG_TFT_sign_clear				; shall clear the advice / attention / warning sign?
@@ -569,146 +618,249 @@
 
 	; --------------------------------------------------------------------------------------
 
-calc_deco_engine:
-	; check deco engine state and switch between normal and alternative plan calculations
+	; Manage and invoke the Deco Calculation Engine
+	; =============================================
+	; Any reconfiguration done here only affects the deco calculation (prediction), not the
+	; settings for the calculations done on the real tissues. The later ones are only altered
+	; in case of a gas change, in case of a real bailout, or in case a switchback to setpoint
+	; or sensor is done.
+	; On event of a gas change, a diluent change, a real bailout, or a switchback, the settings
+	; for the deco calculation are also automatically changed to match with the settings for the
+	; real tissues. This is all done in the function 'gas_switch_common' which is triggered by
+	; the flag 'request_gas_change'.
+
+	; Deco Engine Calculation Schedules:
+	;
+	; Schedule	Dive Mode	Bailout	fTTS	Gas Needs	Plan	Deco Mode	Planning Modes
+	; ---------------------------------------------------------------------------------------------
+	;
+	; 1a)		OC			no		 no		(yes)		norm	OC						(gas needs)
+	;													alt		--			--
 	;
-	; Remark: Any reconfigurations done here do only affect the ascent & deco calculation settings,
-	;         not the settings for the calculations done on the real tissues. The later ones are only
-	;         altered in case of a gas change, or in case of a real bailout or switchback to setpoint
-	;         or sensor, respectively.
-	;         In case of a gas change or real bailout/switchback, the settings for the deco calculations
-	;         are also changed to match the settings for the real tissues. This is done on signal through
-	;         'request_gaschange' and will also leave the deco engine status in state as if having done
-	;         the alternative plan last.
+	; 1b)		OC			no		 YES	(yes)		norm	OC			--
+	;													alt		OC			fTTS,		(gas needs)
+	;
+	; 2a)		Loop		no		 no		 no			norm	Loop		--
+	;													alt		--			--
+	;
+	; 2b)		Loop		no		 yes	 no			norm	Loop		--
+	;													alt		Loop		fTTS
+	;
+	; 2c)		Loop		no		(yes)	 YES		norm	Loop		--
+	;													alt		OC			gas needs,	(fTTS*)
+	;
+	; 3)		Loop		YES		 n/a	(yes)		norm	OC			bailout,	(gas needs)
+	;													alt		--			--
+	; _____________________________________________________________________________________________
+	; norm: normal plan, alt: alternative plan, -- none, (): optional, n/a: not applicable
+	; * suppressed when in cave mode and dive is turned
+
+
+callup_deco_engine:
 
 	; get working copies of char_O_main_status and char_O_deco_status
 	movff	char_O_main_status,hi		; get char_O_main_status into hi
 	movff	char_O_deco_status,lo		; get char_O_deco_status into lo
 
 	; check state of deco calculations
-	btfsc	lo,DECO_COMPLETED_NORM		; finished calculations for normal plan?
-	bra		calc_deco_engine_alt		; YES - do an alternative plan next (or a normal one with more features enabled)
-	btfsc	lo,DECO_COMPLETED_ALT		; finished calculations for alternative plan?
-	bra		calc_deco_engine_norm		; YES - do a normal plan next
-	bra		calc_deco_engine_cont		; NO to both - continue calculations / do first invocation in INIT mode
+	btfsc	request_restart_engine		; restart of the deco engine requested?
+	bra		calc_deco_engine_restart	; YES - start a new normal plan
+	btfsc	lo,DECO_COMPLETED_NORM		; NO  - finished calculations for normal plan?
+	bra		calc_deco_engine_alt		;       YES - eventually do an alternative plan next
+	btfsc	lo,DECO_COMPLETED_ALT		;       NO  - finished calculations for alternative plan?
+	bra		calc_deco_engine_norm		;             YES - do a normal plan next
+	bra		calc_deco_engine_exec		;             NO  - continue executing current calculation
+
+calc_deco_engine_restart:
+	bcf		request_restart_engine		; clear request flag
+	bcf		lo,DECO_COMPLETED_NORM		; clear completion flag from normal plan if applicable
+	;bra	calc_deco_engine_norm		; continue with calculating a normal plan
+
+	; ---- normal plans ----
 
 calc_deco_engine_norm:
-	; Last cycle did an alternative plan, or the deco engine has been restarted because of a gas change etc.
-	; --> Reconfigure to normal plan for next computation cycle.
-	bcf		lo,DECO_COMPLETED_ALT		; clear flag indicating last plan was an alternative one
-	bsf		lo,DECO_START_NORM			; set   flag to calculate a normal deco plan next
-	bcf		lo,DECO_ASCENT_FLAG			; clear flag for delayed ascent calculation
-	bcf		lo,DECO_BAILOUT_FLAG		; clear flag for bailout mode
-	bcf		hi,DECO_VOLUME_FLAG			; clear flag for gas needs calculation
- IFDEF _cave_mode
-	bcf		hi,DECO_CAVE_MODE			; clear flag for cave mode
+	bcf		lo,DECO_COMPLETED_ALT		; clear completion flag from alternative plan
+ IFDEF _ccr_pscr
+	btfsc	bailout_mode				; in real bailout?
+	bra		calc_deco_engine_norm_3		; YES - configure real bailout schedule
+	btfss	FLAG_oc_mode				; in OC dive mode?
+	bra		calc_deco_engine_norm_2		; NO  - configure loop schedules
+	;bra	calc_deco_engine_norm_1		; YES - configure OC   schedules
  ENDIF
 
+calc_deco_engine_norm_1:
+	; normal OC schedules
+	TSTOSC	char_I_extra_time			; delay mode activated?
+	bra		calc_deco_engine_norm_1b	; YES - schedule 1b in normal plan
+	;bra	calc_deco_engine_norm_1a	; NO  - schedule 1a in normal plan
+
+calc_deco_engine_norm_1a:
+	; normal schedule 1a: OC with optional gas needs
+;	bcf		lo,DECO_BAILOUT_FLAG		; switch off bailout mode						(will never be activated in this plan)
+;	bcf		lo,DECO_DELAY_FLAG			; switch off delay mode							(will never be activated in this plan)
+;	bcf		hi,DECO_VOLUME_FLAG			; switch off gas needs calculation by default	(if on, will always be on)
+	TSTOSC	opt_calc_gasvolume			; shall calculate gas needs?
+	bsf		hi,DECO_VOLUME_FLAG			; YES - switch on gas needs calculation
+	bra		calc_deco_engine_norm_start	; start deco engine in normal plan
+
+calc_deco_engine_norm_1b:
+	; normal schedule 1b: OC without delay and gas needs
+;	bcf		lo,DECO_BAILOUT_FLAG		; switch off bailout mode						(will never be activated in this plan)
+	bcf		lo,DECO_DELAY_FLAG			; switch off delay mode
+	bcf		hi,DECO_VOLUME_FLAG			; switch off gas needs calculation
+	bra		calc_deco_engine_norm_start	; start deco engine in normal plan
+
  IFDEF _ccr_pscr
-	btfsc	FLAG_ccr_mode				; in CCR mode?
-	bra		calc_deco_engine_norm_loop	; YES - reload diluents and reconfigure CCR mode if not in bailout
-	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	bra		calc_deco_engine_norm_loop	; YES - reload diluents and reconfigure pSCR mode if not in bailout
-	;bra	calc_deco_engine_norm_OC	; neither in CCR nor pSCR mode, so reload OC gases and reconfigure OC mode
-										; (first cycle omits gas needs calculation for faster first deco results)
- ENDIF
-
-calc_deco_engine_norm_OC:
-	movff	active_gas,WREG				; get current OC gas
-	call	deco_setup_oc_gases_pre		; set up deco calculations in OC mode with OC gases
+calc_deco_engine_norm_2:
+	; normal loop schedules
+	TSTOSC	opt_calc_gasvolume			; gas needs calculation activated?
+	bra		calc_deco_engine_norm_2c	; YES - schedule  2c in normal plan
+	;bra	calc_deco_engine_norm_2ab	; NO  - schedules 2a and 2b in normal plan are identical
+
+calc_deco_engine_norm_2ab:
+	; normal schedule 2a & 2b: loop without anything
+	bcf		lo,DECO_BAILOUT_FLAG		; switch off bailout mode						(may return from real bailout)
+;	bcf		hi,DECO_VOLUME_FLAG			; switch off gas needs calculation				(will never be activated in this plans)
+	bcf		lo,DECO_DELAY_FLAG			; switch off delay mode							(may have been set in alt. plan 2b)
+	bra		calc_deco_engine_norm_start	; start deco engine in normal plan
+
+calc_deco_engine_norm_2c:
+	; normal schedule 2c: loop with switch-back from simulated bailout
+	; switch to CCR/pSCR
+	movf	active_dil,W				; get current diluent
+	call	deco_setup_cc_diluents_pre	; set up deco calculation in CCR/pSCR mode with diluents
+calc_deco_engine_norm_2c_XX:
+	bcf		lo,DECO_BAILOUT_FLAG		; switch off bailout mode						(may return from real bailout)
+	bcf		hi,DECO_VOLUME_FLAG			; switch off gas needs calculation
+	bcf		lo,DECO_DELAY_FLAG			; switch off delay mode
+	bra		calc_deco_engine_norm_start	; start deco engine in normal plan
+
+calc_deco_engine_norm_3:
+	; real bailout schedule
+	bcf		lo,DECO_DELAY_FLAG			; switch off delay mode
+	bcf		hi,DECO_VOLUME_FLAG			; switch off gas needs calculation by default
+	TSTOSC	opt_calc_gasvolume			; shall calculate gas needs?
+	bsf		hi,DECO_VOLUME_FLAG			; YES - switch on gas needs calculation
+	bsf		lo,DECO_BAILOUT_FLAG		; switch on bailout mode
+	;bra	calc_deco_engine_norm_start	; start deco engine in normal plan
+ ENDIF	; _ccr_pscr
+
+calc_deco_engine_norm_start:
+	bsf		lo,DECO_START_NORM			; calculate a normal plan
 	bra		calc_deco_engine_start		; start deco engine
 
- IFDEF _ccr_pscr
-calc_deco_engine_norm_loop:				; switch to loop calculation if not in a real bailout situation
-	btfsc	bailout_mode				; check if a real bailout situation is present
-	bra		calc_deco_engine_norm_OC	; YES - revert to OC mode
-										; NO  - switch to loop calculation:
-	movff	active_dil,WREG				;     - get current diluent
-	call	deco_setup_cc_diluents_pre	;     - set up deco calculations in CCR/pSCR mode with diluents
-	bra		calc_deco_engine_start		;     - start deco engine
- ENDIF
+	; ---- alternative plans ----
 
 calc_deco_engine_alt:
-	; A normal plan was computed in the last cycle. For the next calculation cycle the mode may be switched
-	; to alternative plan, or stay in normal plan but with certain features enabled...
-	bcf		lo,DECO_ASCENT_FLAG			; clear flag for delayed ascent calculation
-	bcf		lo,DECO_BAILOUT_FLAG		; clear flag for bailout mode
-	bcf		hi,DECO_VOLUME_FLAG			; clear flag for gas needs calculation
- IFDEF _cave_mode
-	bcf		hi,DECO_CAVE_MODE			; clear flag for cave mode
- ENDIF
-
-	btfsc	bailout_mode				; check if a real bailout situation is present
-	bra		calc_deco_engine_alt_1		; YES - stay in normal plan mode and preclude delayed ascent calculation
-	TSTOSS	char_I_extra_time			; NO  - check if a delayed ascent is enabled
-	bra		calc_deco_engine_alt_1		;       NO  - stay in normal plan mode and preclude delayed ascent calculation
-	bcf		lo,DECO_COMPLETED_NORM		;       YES - clear flag indicating last plan was a normal one
-	bsf		lo,DECO_START_ALT			;           - set   flag to calculate an alternative deco plan next
-	bsf		lo,DECO_ASCENT_FLAG			;           - set   flag for delayed ascent
+	bcf		lo,DECO_COMPLETED_NORM		; clear completion flag from normal plan
+ IFDEF _ccr_pscr
+	btfsc	bailout_mode				; in real bailout?
+	bra		calc_deco_engine_norm_3		; YES - schedule 3 has no alternative plan
+	btfss	FLAG_oc_mode				; in OC dive mode?
+	bra		calc_deco_engine_alt_2		; NO  - loop schedules
+	;bra	calc_deco_engine_alt_1		; YES - OC   schedules
+ ENDIF	; _ccr_pscr
 
 calc_deco_engine_alt_1:
-	TSTOSS	opt_calc_asc_gasvolume		; check if gas volume calculation is enabled
-	bra		calc_deco_engine_start		; NO  - no volume calculation, no simulated bailout plan in this case
-	bsf		hi,DECO_VOLUME_FLAG			; YES - set gas needs calculation flag
-
-	btfsc	bailout_mode				; check if a real bailout situation is present
-	bra		calc_deco_engine_start		; YES - normal plan already does bailout (OC) calculation "for real"
-
+	; alternative OC schedules
+	TSTOSS	char_I_extra_time			; delay mode activated?
+	bra		calc_deco_engine_norm_1a	; NO  - schedule 1a has no alternative plan
  IFDEF _cave_mode
-	bsf		hi,DECO_CAVE_MODE			; activate cave mode by default
-	btfss	cave_mode					; cave mode switched on?
-	bcf		hi,DECO_CAVE_MODE			; NO  - deactivate p2deco cave mode again
-	btfsc	dive_turned					; dive turned?
-	bcf		hi,DECO_CAVE_MODE			; YES - deactivate p2deco cave mode again
-	btfsc	FLAG_backtrack_full			; backtracking storage full?
-	bcf		hi,DECO_CAVE_MODE			; YES - deactivate p2deco cave mode again
+	btfsc	dive_turned					; YES - in cave mode and dive turned?
+	bra		calc_deco_engine_norm_1a	;       YES - suppress delay mode -> do schedule 1a in normal plan
  ENDIF
-
-	btfss	lo,DECO_MODE_LOOP_FLAG		; NO  - has a loop mode calculation been done during the normal plan?
-	bra		calc_deco_engine_start		;       NO  - when not in loop mode, no simulated bailout to be done
-	decf	best_gas_number,W			;       YES - get best gas number -1 into WREG. If not available, WREG will be 255 now. If not computed yet, WREG will be 254 now.
-	btfsc	WREG,7						;           - WREG < 128 (a bailout gas is available)?
-	bra		calc_deco_engine_alt_2		;             NO  - no simulated bailout possible because no bailout gas available to switch to
-	bcf		lo,DECO_COMPLETED_NORM		;             YES - clear flag indicating last plan was a normal one
-	bsf		lo,DECO_START_ALT			;                 - set   flag to calculate an alternative deco plan next
-	bsf		lo,DECO_BAILOUT_FLAG		;                 - set   flag for bailout mode (enables gas switches before 1st stop)
-	movf	best_gas_number,W			;                 - put number of best gas into WREG
-	call	deco_setup_oc_gases_pre		;                 - set up deco calculations in OC mode with OC gases
-	bra		calc_deco_engine_start		;                 - start in alternative plan mode
-
+	;bra	calc_deco_engine_alt_1b		;       NO  - do schedule 1b in alternative plan
+
+calc_deco_engine_alt_1b:
+	; alternative schedule 1b: OC with delay and optional gas needs
+;	bcf		lo,DECO_BAILOUT_FLAG		; switch off bailout mode						(will never be activated in this plan)
+;	bcf		hi,DECO_VOLUME_FLAG			; switch off gas needs calculation by default	(comes in switched off state)
+	TSTOSC	opt_calc_gasvolume			; shall calculate gas needs?
+	bsf		hi,DECO_VOLUME_FLAG			; YES - switch on gas needs calculation
+	bsf		lo,DECO_DELAY_FLAG			; switch on delay mode
+	bra		calc_deco_engine_alt_start	; start deco engine in alternative plan
+
+ IFDEF _ccr_pscr
 calc_deco_engine_alt_2:
-	bcf		lo,DECO_START_ALT			; clear flag to calculate an alternative deco plan next
-	bsf		lo,DECO_START_NORM			; set   flag to calculate a  normal      deco plan next
-	bcf		lo,DECO_ASCENT_FLAG			; clear flag for delayed ascent calculation
-	bcf		hi,DECO_VOLUME_FLAG			; clear flag for gas needs calculation
+	; alternative loop schedules
+	TSTOSC	opt_calc_gasvolume			; gas needs calculation activated?
+	bra		calc_deco_engine_alt_2c		; YES - 2c in alternative plan
+	TSTOSS	char_I_extra_time			; NO  - delay mode activated?
+	bra		calc_deco_engine_norm_2ab	;       NO  - schedule 2a has no alternative plan
+	;bra	calc_deco_engine_alt_2b		;       YES - schedule 2b in alternative plan
+
+calc_deco_engine_alt_2b:
+	; alternative schedule 2b: loop with delay
+;	bcf		lo,DECO_BAILOUT_FLAG		; switch off bailout mode						(will be deactivated in normal plan)
+;	bcf		hi,DECO_VOLUME_FLAG			; switch off gas needs calculation				(will never be activated in this plan)
+	bsf		lo,DECO_DELAY_FLAG			; switch on  delay mode
+	bra		calc_deco_engine_alt_start	; start deco engine in normal plan
+
+calc_deco_engine_alt_2c:
+	; alternative schedule 2c: simulated bailout (if possible)
+	decf	best_gas_number,W			; get best gas number -1 into WREG. If not available, WREG will be 255 now. If not computed yet, WREG will be 254 now.
+	btfsc	WREG,7						; WREG < 128 (a bailout gas is available)?
+	bra		calc_deco_engine_alt_2c_XX	; NO  - no bailout plan possible because no bailout gas available to switch to
+	movf	best_gas_number,W			; YES - get number of best gas into WREG
+	call	deco_setup_oc_gases_pre		;     - set up deco calculation in OC mode with OC gases
+;	bcf		lo,DECO_DELAY_FLAG			;     - switch off delay mode by default		(comes in switched off state)
+	TSTOSC	char_I_extra_time			;     - delay mode activated?
+	bsf		lo,DECO_DELAY_FLAG			;       YES - switch on delay mode
  IFDEF _cave_mode
-	bcf		hi,DECO_CAVE_MODE			; clear flag for cave mode
+	btfsc	dive_turned					;       in cave mode and dive turned?
+	bcf		lo,DECO_DELAY_FLAG			;       YES - suppress delay mode
  ENDIF
+	bsf		lo,DECO_BAILOUT_FLAG		;     - switch on bailout mode
+	bsf		hi,DECO_VOLUME_FLAG			;     - switch on gas needs calculation
+	bra		calc_deco_engine_alt_start	;     - start deco engine in alternative plan
+calc_deco_engine_alt_2c_XX:
 	call	inval_alternative_plan_data	; invalidate all alternative (bailout) plan data because they are not applicable any more
+	bra		calc_deco_engine_norm_start	; continue calculating as normal plan
+ ENDIF	; _ccr_pscr
+
+calc_deco_engine_alt_start:
+	bsf		lo,DECO_START_ALT			; calculate an alternative plan
+	;bra	calc_deco_engine_start		; start deco engine
+
+	; ---- start deco engine ----
 
 calc_deco_engine_start:
+ IFDEF _cave_mode
+	bcf		hi,DECO_CAVE_MODE			; deactivate cave mode by default
+	btfss	cave_mode					; cave mode switched on?
+	bra		calc_deco_engine_start_1	; NO  - keep deactivated, no backtracking depth recording
+	bsf		hi,DECO_CAVE_MODE			; YES - activate cave mode
+	btfss	dive_turned					;     - dive turned?
+	call	write_backtrack_deltatime	;       NO  - update current delta time
+ ENDIF
+calc_deco_engine_start_1:
 	movff	hi,char_O_main_status		; write-back char_O_main_status to deco engine interface
 	movff	lo,char_O_deco_status		; write-back char_O_deco_status to deco engine interface
 
-calc_deco_engine_cont:
+calc_deco_engine_exec:
 ;	+++++++++++++++++++++++++++++++++++++
 	call	deco_calc_hauptroutine		; invoke the deco engine (C-code)
 	banksel	common						; back to bank common
 ;	+++++++++++++++++++++++++++++++++++++
 
+ ifdef _debug_output
 	call	TFT_debug_output			; debug output of scheduling performance data
+ endif
 
 	; check if new calculation results for normal plan mode are available
 	movff	char_O_deco_status,WREG		; get deco status of deco engine
 	btfsc	WREG,DECO_COMPLETED_NORM	; new calculation results for normal plan available?
 	bsf		new_deco_data_avail			; YES - set flag for new NDL or deco data available
-	return								; done
-
+
+	; done
+	return
+
+; -------------------------------------------------------------------------------------------------
 
 show_new_deco_data:
 	bcf		new_deco_data_avail			; reset flag for new NDL or deco data available
 	movff	char_O_deco_info,WREG		; get the deco info vector
-	btfsc	WREG,deco_stops				; deco stops found?
+	btfsc	WREG,deco_stops_norm		; deco stops found?
 	bra		show_new_deco_data_deco		; YES - in deco
 	;bra	show_new_deco_data_ndl		; NO  - within NDL
 
@@ -732,6 +884,7 @@
 
 ;=============================================================================
 
+ IFDEF _ccr_pscr
  IFDEF _external_sensor
 
 	global	calc_deko_divemode_sensor
@@ -1017,10 +1170,10 @@
 	decfsz	WREG,W						;     - opt_ccr_mode = 1 (sensors)?
 	return								;       NO  - not using the sensors in the moment
 show_sensors_custview:
-	movlw	index_ppo2_sensors-1		;       YES - custom view number one below ppO2 sensors
-	movwf	active_customview			;           - set custom view number
-	bsf		request_next_custview		;           - initiate toggle to desired custom view -> ppO2 sensors
-	return
+	btfsc	custom_view_locked			;       YES - custom view locked?
+	return								;             YES - done
+	movlw	index_ppo2_sensors			;             NO  - get  custom view number of ppO2 sensors
+	goto	dive_customview_show		;                 - draw custom view and return
 
 check_sensor_voting_helper:
 	movf	lo,W
@@ -1042,35 +1195,125 @@
 	bra		check_sensor_voting_helper1
 
  ENDIF	; _external_sensor
+ ENDIF	; _ccr_pscr
 
 ;=============================================================================
 
-divemodemode_togglegf:								; toggle aGF/GF
-	bcf		request_toggle_GF						; clear request flag
-	btg		use_aGF									; toggle normal / alternative GF factor selection
-	btfsc	use_aGF									; alternative GF factors activated?
-	bra		divemodemode_togglegf_1					; YES - branch to using aGF
-	movff	opt_GF_low, char_I_GF_Low_percentage	; NO  - use normal GF factor low
-	movff	opt_GF_high,char_I_GF_High_percentage	;     - use normal GF factor high
-	bra		divemodemode_togglegf_2					;     - continue with common part
-divemodemode_togglegf_1:
-	movff	opt_aGF_low, char_I_GF_Low_percentage	; YES - use alternative GF factor low
-	movff	opt_aGF_high,char_I_GF_High_percentage	;     - use alternative GF factor high
-divemodemode_togglegf_2:
-	call	TFT_gf_factors_mask						; update custom view mask to show which one is in use
-													; the custom view itself has been called from divemenu_tree before
-	goto	restart_deco_engine						; ...and return
+divemodemode_togglegf:
+	bcf		request_toggle_GF			; clear request flag
+	goto	restart_deco_engine			; restart the deco engine and return
 
 ;=============================================================================
 
  IFDEF _cave_mode
 
-divemodemode_toggleturn:
-	bcf		request_turn_dive						; clear request flag
-	btg		dive_turned								; toggle dive turned state
-	btfsc	FLAG_backtrack_full						; backtracking storage full?
-	bsf		dive_turned								; YES - allow only activating turned state
-	goto	set_logbook_marker						; set a logbook marker (and return)
+cavemode_toggle_onoff:
+	bcf		request_cave_toggle			; clear request flag
+	btg		cave_mode					; toggle the on/off state
+	return								; done
+
+cavemode_switch_off_turned:
+	bcf		request_cave_off_turned		; clear request flag
+	bcf		cave_mode					; switch cave mode off
+	bra		cavemode_turndive_turn_exec ; set dive as turned (and return)
+
+
+	global	cavemode_turndive_check
+cavemode_turndive_check:
+	btfss	cave_mode					; cave mode switched on?
+	retlw	1							; NO - signal not allowed
+	btfss	dive_turned					; YES - is the dive currently turned?
+	retlw	0							;       NO  - command is allowed
+	movf	backtrack_waypoint_turn,W	;       YES - copy turn point number to WREG
+	cpfslt	backtrack_waypoint_num		;           - current waypoint number < turn point number ?
+	retlw	1							;             NO  - signal not allowed
+	retlw	0							;             YES - command is allowed
+
+cavemode_turndive_toggle:
+	bcf		request_turn_toggle			; clear request flag
+	rcall	cavemode_turndive_check		; check if command is allowed
+	tstfsz	WREG						; command allowed?
+	return								; NO  - abort
+	btfss	dive_turned					; YES - is the dive currently turned?
+	bra		cavemode_turndive_turn_exec	;       NO  - turn the dive
+	bra		request_turndive_cont_exec	;       YES - continue the dive
+
+cavemode_turndive_turn:
+	bcf		request_turn_turn			; clear request flag
+	btfss	cave_mode					; cave mode switched on?
+	return								; NO  - abort
+	btfsc	dive_turned					; YES - is the dive already turned?
+	return								;       YES - nothing to do any more
+	;bra	cavemode_turndive_turn_exec	;       NO  - turn the dive
+
+cavemode_turndive_turn_exec:
+	bsf		dive_turned					; set dive as turned
+	call	set_logbook_marker			; set a logbook marker
+	goto	write_backtrack_turnpoint	; write a turn-point waypoint (and return)
+
+request_turndive_cont_exec:
+	bcf		dive_turned					; set dive         as not turned    any more
+	bcf		backtrack_shutdown			; set backtracking as not shut down any more
+	call	set_logbook_marker			; set a logbook marker
+	goto	resume_backtrack_recording	; append further logging after current waypoint (and return)
+
+
+	global	cavemode_waypoint_set_check
+cavemode_waypoint_set_check:
+	btfss	cave_mode					; cave mode switched on?
+	retlw	1							; NO - command not allowed
+	btfsc	dive_turned					; YES - is the dive turned?
+	retlw	1							;       YES - no setting of waypoints on way out, command not allowed
+	btfsc	backtrack_entire_full		;       NO  - storage entirely used up?
+	retlw	1							;             YES - out of storage capacity, command not allowed
+	movlw	backtrack_waypoint_max		;             NO  - get highest allowed waypoint number
+	cpfslt	backtrack_waypoint_num		;                 - current waypoint number < max allowed number?
+	retlw	1							;                   NO  - command not allowed
+	retlw	0							;                   YES - command is  allowed
+
+cavemode_waypoint_set:
+	bcf		request_waypoint_set		; clear request flag
+	rcall	cavemode_waypoint_set_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	return								; NO  - no waypoint setting possible, abort
+	call	set_logbook_marker			; YES - set a logbook marker
+	goto	write_backtrack_waypoint	;     - execute command (and return)
+
+
+	global	cavemode_waypoint_out_check
+cavemode_waypoint_out_check:
+	btfss	cave_mode					; cave mode switched on?
+	retlw	1							; NO - command not allowed
+	btfss	dive_turned					; YES - is the dive turned?
+	retlw	1							;       NO  - no stepping back on way in, command not allowed
+	btfsc	waypoint_reached_first		;       YES - already at first waypoint?
+	retlw	1							;             YES - command not allowed
+	retlw	0							;             NO  - command is  allowed
+
+cavemode_waypoint_out:
+	bcf		request_waypoint_out		; clear request flag
+	rcall	cavemode_waypoint_out_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	return								; NO  - no further out possible, abort
+	goto	backtrack_waypoint_go_out	; YES - execute the command (and return)
+
+
+	global	cavemode_waypoint_in_check
+cavemode_waypoint_in_check:
+	btfss	cave_mode					; cave mode switched on?
+	retlw	1							; NO - command not allowed
+	btfss	dive_turned					; YES - is the dive turned?
+	retlw	1							;       NO  - no stepping forward on way in, command not allowed
+	btfsc	waypoint_reached_last		;       YES - already at last waypoint?
+	retlw	1							;             YES - command not allowed
+	retlw	0							;             NO  - command is  allowed
+
+cavemode_waypoint_in:
+	bcf		request_waypoint_in			; clear request flag
+	rcall	cavemode_waypoint_in_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	return								; NO  - no further in possible, abort
+	goto	backtrack_waypoint_go_in	; YES - execute command (and return)
 
  ENDIF
 
@@ -1101,7 +1344,7 @@
 	MOVLI	.39,xB						; put scale coefficient into xB (use 77 when called every second)
 	call	mult16x16					; compute differential pressure in mbar * scale coefficient
 	MOVII	xC,divA						; copy result to divA
-	ADDLI	.64,divA					; add some round-up				TODO: too sensitive with this?
+	ADDLI	.64,divA					; add some round-up
 	movlw	.7							; divide by 2^7
 	call	div16						; divA = divA / 2^WREG, yields velocity in m/min
 
@@ -1125,12 +1368,12 @@
 	btfsc	deco_region					; been within the deco stops region before?
 	return								; YES - been in deco then before too, done
 	movff	char_O_deco_info,WREG		; NO  - get deco info vector
-	btfss	WREG,deco_stops				;       do we have a deco obligation right now?
+	btfss	WREG,deco_stops_norm		;       do we have a deco obligation right now?
 	return								;       NO  - done
 	bsf		deco_locked					;       YES - memorize dive was in deco
 	movff	char_O_deco_depth+0,WREG	;           - get depth of first stop in meters into WREG
 	addlw	deco_region_distance+.1		;           - add deco region start distance + 1 meter for the negative test to work
-	subwf	depth_meter,W				;           - compute current depth - (first stop depth + deco distance)
+	subwf	depth_meter,W				;           - compute current depth - (first stop depth + deco region distance)
 	btfss	STATUS,C					;           - result negative?
 	bsf		deco_region					;             YES - memorize to have entered the deco stops region
 	return								;           - done
@@ -1138,7 +1381,7 @@
 ;=============================================================================
 
 safety_stop_control:
-	TSTOSS	opt_enable_safetystop		; safety stop enabled? (=1: show safety stop)
+	TSTOSS	opt_safetystop				; safety stop enabled? (=1: show safety stop)
 	return								; NO  - done
 
 	btfsc	FLAG_gauge_mode				; in gauge mode?
@@ -1152,28 +1395,32 @@
 	bra		safety_stop_finish			; YES - shut down safety stop
 
 	; below "opt_safety_stop_reset"?
-	MOVII	pressure_rel_cur_cached,mpr	; get current depth into hi:lo
-	call	adjust_depth_with_salinity	; compute salinity setting into hi:lo [mbar]
-	MOVII	mpr,sub_a					; move adjusted depth to sub_a
-	movff	opt_safety_stop_reset,WREG	; load safety stop reset threshold [cbar]
-	mullw	.10							; convert threshold from [cbar] to [mbar]
-	MOVII	PROD,sub_b					; move threshold to sub_b
+	MOVII	pressure_rel_cur_cached,mpr	; get current pressure into MPR
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
+	MOVII	mpr,sub_a					; move depth in [cm] to sub_a
+	movff	opt_safety_stop_reset,WREG	; load safety stop reset threshold [dm]
+	mullw	.10							; convert threshold from [dm] to [cm]
+	MOVII	PROD,sub_b					; move threshold in [cm] to sub_b
 	call	cmpU16						; sub_a - sub_b
 	btfss	neg_flag					; below threshold depth?
 	bra		safety_stop_reset			; YES - arm safety stop and delete it from display if still shown
-
+	;bra	safety_stop_control_1		; NO  - check if above end threshold
+
+safety_stop_control_1:
 	; above "opt_safety_stop_end"?
-	movff	opt_safety_stop_end,WREG	; load safety stop end threshold [cbar]
-	mullw	.10							; convert threshold from [cbar] to [mbar]
-	MOVII	PROD,sub_b					; move threshold to sub_b
+	movff	opt_safety_stop_end,WREG	; load safety stop end threshold [dm]
+	mullw	.10							; convert threshold from [dm] to [cm]
+	MOVII	PROD,sub_b					; move threshold in [cm] to sub_b
 	call	cmpU16						; sub_a - sub_b
 	btfsc	neg_flag					; above or at threshold depth?
 	bra		safety_stop_finish			; YES - finish with safety stop
-
+	;bra	safety_stop_control_2		; NO  - check if above start threshold
+
+safety_stop_control_2:
 	; above "opt_safety_stop_start"?
-	movff	opt_safety_stop_start,WREG	; load safety stop start threshold [cbar]
-	mullw	.10							; convert threshold from [cbar] to [mbar]
-	MOVII	PROD,sub_b					; move threshold to sub_b
+	movff	opt_safety_stop_start,WREG	; load safety stop start threshold [dm]
+	mullw	.10							; convert threshold from [dm] to [cm]
+	MOVII	PROD,sub_b					; move threshold in [cm] to sub_b
 	call	cmpU16						; sub_a - sub_b
 	btfss	neg_flag					; above or at threshold depth?
 	return								; NO  - pause safety stop
@@ -1181,6 +1428,7 @@
 	bsf		safety_stop_enabled			;       YES - enable safety stop
 	return								;       NO  - done
 
+
 safety_stop_show:
 	btfss	safety_stop_enabled			; safety stop enabled?
 	return								; NO  - done
@@ -1215,13 +1463,22 @@
 	;bra	timeout_divemode_menu2		; YES - clean up main menu and restore dive data
 
 	global	timeout_divemode_menu2
-timeout_divemode_menu2:					; called from divemenu_tree.asm
-	bcf		dive_main_menu				; timeout, clear flag for dive mode menu shown
-	call	TFT_clear_divemode_menu		; clear menu
+timeout_divemode_menu2:					; jump-in point from divemenu_tree.asm
+	bcf		dive_main_menu				; clear flag for dive mode menu shown
+	call	TFT_clear_divemode_menu		; clear menu area
+
+	btfss	custom_view_locked			; was the custom view locked by the menu system?
+	bra		timeout_divemode_menu3		; NO  - continue with redrawing the lower display
+	bcf		custom_view_locked			; YES - clear flag for custom view locked by menu
+	movf	backup_customview,W			;     - get previous custom view into WREG
+	cpfseq	active_customview			;     - compare with current custom view, equal?
+	call	dive_customview_recall		;       NO - redraw previous custom view
+
+timeout_divemode_menu3:
 	bsf		FLAG_TFT_active_gas_divemode; redraw gas/setpoint/diluent
-	bcf		better_gas_blinking			; clear flag to have temperature updated once
-	bcf		better_dil_blinking			; clear flag to have temperature updated once
 	bsf		FLAG_TFT_temperature		; display temperature (or resettable dive time when in compass view)
+	bcf		better_gas_blinking			; stop better gas cue
+	bcf		better_dil_blinking			; stop better dil cue
 
 request_redraw_NDL_deco_data:
 	btfsc	FLAG_gauge_mode				; in gauge mode?
@@ -1286,48 +1543,169 @@
 
 update_divemode60:						; tasks every full minute
 	bcf		trigger_full_minute			; clear flag
+
 	call	get_battery_voltage			; get battery voltage
-	rcall	set_powersafe				; check if battery is low
- IFDEF _cave_mode
-	movlw	.1							; prepare to add backtrack data for 1 minute
-	btfsc	cave_mode					; cave mode switched on?
-	rcall	update_backtrack			; YES - store backtracking data
- ENDIF
+	btfsc	battery_low_condition		; battery low condition detected?
+	rcall	set_powersafe				; YES - record an alarm and reduce display brightness
+
+	; max allowed runtime in simulator is 254 minutes in
+	; order for the tissue calculation catch-up to work!
+
 	btfss	sensor_override_active		; in simulator mode?
 	return								; NO  - done
-	movlw	.20							; YES - quite dive mode simulation after 21 * 256 sec = 89 min : 36 sec
-	cpfsgt	total_divetime_secs+1		;     - timeout?
+	movlw	simulator_timeout_normal	; YES - set simulation timeout
+ IFDEF _cave_mode
+	TSTOSC	opt_cave_mode				;     - cave mode switched on?
+	movlw	simulator_timeout_cave		;       YES - update simulation timeout
+ ENDIF
+	cpfsgt	counted_divetime_mins+0		;     - timeout?
 	return								;       NO  - done
  IFDEF _DEBUG
-	return								;       YES -  but no timeout in debug mode
+	return								;       YES - but we do not care in debug mode...
+ ELSE
+	bra		divemode_option_sim_quit	;       YES - set depth to 0 m and return
  ENDIF
-	bra		divemode_option1			;       YES - set depth to 0 m and "return"
 
 ;=============================================================================
 
  IFDEF _cave_mode
 
-update_backtrack:
-	btfsc	dive_turned					; dive turned?
-	return								; YES - done
-	btfsc	FLAG_backtrack_full			; NO  - backtracking storage full?
-	return								;       YES - done
-	movwf	lo							;       NO  - store minutes to add in lo
-	lfsr	FSR1,char_I_backtrack_depth ;           - load FSR1 with base address of backtrack storage
-	movff	char_I_backtrack_time,FSR1L	;           - adjust FSR1 to last index
-update_backtrack_loop:
-	movff	depth_meter,PREINC1			; increment index and write current depth to backtrack storage
-	incfsz	FSR1L,W						; increment index once more and dump to WREG, did a wrap-around occur (backtrack storage full)?
-	bra		update_backtrack_loop_1		; NO  - continue loop
-	bsf		FLAG_backtrack_full			; YES - flag backtracking storage is full
-	return								;     - done
-update_backtrack_loop_1:
-	decfsz	lo,F						; decrement loop counter, did it became zero?
-	bra		update_backtrack_loop		; NO  - loop
-	movff	FSR1L,char_I_backtrack_time	; YES - store updated index
-	return								;     - done
-
- ENDIF
+; ** jump-in functions **
+
+write_backtrack_deltatime:
+	rcall	setup_backtrack_index				; setup writing position
+	bra		write_backtrack_datum_deltatime		; store the current delta time (and return)
+
+write_backtrack_1min_depth:
+	rcall	setup_backtrack_index				; setup writing position
+	rcall	write_backtrack_datum_depth			; store depth
+	rcall	write_backtrack_datum_zerotime		; reset the time elapsed since last depth recording and store it
+	bra		write_backtrack_datum_check			; store new writing position, check remaining storage capacity ()and return)
+
+write_backtrack_waypoint:
+	rcall	setup_backtrack_index				; setup writing position
+	rcall	write_backtrack_datum_deltatime		; store the time elapsed since last depth recording
+	movf	POSTINC1,W							; dummy read to increment the writing position index
+	rcall	write_backtrack_datum_depth			; store depth
+	rcall	write_backtrack_datum_gas			; store gas availability vector
+	rcall	write_backtrack_datum_waypoint		; store waypoint number
+	rcall	write_backtrack_datum_zerotime		; reset the time elapsed since last depth recording and store it
+	bra		write_backtrack_datum_check			; store new writing position, check remaining storage capacity (and return)
+
+write_backtrack_turnpoint:
+	rcall	write_backtrack_waypoint			; write a waypoint (see above)
+	movf	POSTDEC1,W							; dummy read to decrement the position index to the waypoint number datum
+	movff	FSR1L,char_I_backtrack_index		; store updated writing position
+	movff	backtrack_waypoint_num,backtrack_waypoint_turn; memorize this waypoint as turn point
+	return										; done
+
+resume_backtrack_recording:
+	clrf	backtrack_waypoint_turn				; clear turn point reference
+	bsf		waypoint_reached_last				; declare to be at last waypoint now
+	rcall	setup_backtrack_index				; setup index position
+	movf	POSTINC1,W							; dummy read to increment the position index to the delta time datum
+	rcall	write_backtrack_datum_zerotime		; reset the time elapsed since last depth recording and store it
+	bra		write_backtrack_datum_check			; store new writing position, check remaining storage capacity (and return)
+
+backtrack_waypoint_go_out:
+	bcf		waypoint_reached_last				; not at last waypoint (or turn point) any more
+	rcall	setup_backtrack_index				; setup index position
+	movlw	b'11100000'-.1						; a waypoint datum has bits 5-7 set, -1 because of cpfsgt
+backtrack_waypoint_go_out_loop:
+	movff	POSTDEC1,lo							; dummy read current datum and go to previous datum (there is no PREDEC)
+	cpfsgt	INDF1								; read datum, is it a waypoint datum?
+	bra		backtrack_waypoint_go_out_loop		; NO - try next datum
+	movff	FSR1L,char_I_backtrack_index		; store new index position
+	movf	INDF1,W								; copy waypoint datum to WREG
+	andlw	b'00011111'							; remove waypoint tag
+	movwf	backtrack_waypoint_num				; store new waypoint number
+	movlw	.1									; number of first waypoint
+	cpfsgt	backtrack_waypoint_num				; current waypoint number > number of first waypoint ?
+	bsf		waypoint_reached_first				; NO - reached first waypoint
+	goto	restart_deco_engine_wo_norm			; invalidate all alternative plan data and restart deco engine
+
+backtrack_waypoint_go_in:
+	bcf		waypoint_reached_first				; not at first waypoint any more
+	rcall	setup_backtrack_index				; setup index position
+	movlw	b'11100000'-.1						; a waypoint datum has bits 5-7 set, -1 because of cpfsgt
+backtrack_waypoint_go_in_loop:
+	cpfsgt	PREINC1								; go to next datum, read it, is it a waypoint datum?
+	bra		backtrack_waypoint_go_in_loop		; NO - try next datum
+	movff	FSR1L,char_I_backtrack_index		; store new index position
+	movf	INDF1,W								; copy waypoint datum to WREG
+	andlw	b'00011111'							; remove waypoint tag
+	movwf	backtrack_waypoint_num				; store new waypoint number
+	movf	backtrack_waypoint_turn,W			; load WREG with waypoint number of turn point
+	cpfslt	backtrack_waypoint_num				; new waypoint number < number of turn point ?
+	bsf		waypoint_reached_last				; NO - reached last waypoint
+	goto	restart_deco_engine_wo_norm			; invalidate all alternative plan data and restart deco engine
+
+
+; ** helper functions **
+
+setup_backtrack_index:
+	lfsr	FSR1,char_I_backtrack_storage		; load   FSR1 with base address of the backtracking storage
+	movff	char_I_backtrack_index,FSR1L		; adjust FSR1 to the current index position
+	return
+
+write_backtrack_datum_zerotime:
+	clrf	backtrack_deltatime					; reset the time elapsed since last depth recording
+write_backtrack_datum_deltatime:
+	movf	backtrack_deltatime,W				; get   the time elapsed since last depth recording
+	bsf		WREG,7								; add   the time marker (bit 7 set) to the time stored in WREG
+	movwf	INDF1								; write the time and keep the writing position index pointing on it
+	return										; done
+
+write_backtrack_datum_depth:
+	movf	depth_meter,W						; get current depth in meters into WREG
+	btfsc	WREG,7								; current depth < 128 m ?
+	movlw	.127								; NO - clip depth to 127 meters
+	movwf	POSTINC1							; write the depth entry and increment the writing position index
+	return										; done
+
+write_backtrack_datum_gas:
+	; Cave mode is currently only available with gas needs calculation enabled,
+	; so deco mode is either OC anyhow or CCR/pSCR in bailout mode. Hence it is
+	; always the OC (bailout) gases whose staging status needs to be stored.
+	lfsr	FSR2,opt_gas_type					; load base address of the OC/bailout gas types
+	movlw	NUM_GAS								; load number of gases
+	movwf	lo									; initialize loop counter
+	movlw	b'00000001'							; load  gas bit pattern for the first gas
+	movwf	hi									; store gas bit pattern in hi
+	movlw	b'11000000'							; initialize WREG with the gas staging status tag
+write_backtrack_datum_gas_loop:
+	movff	POSTINC2,up							; get gas type and increment index
+	btfsc	up,gas_staged						; gas staged?
+	iorwf	hi,W								; YES - set respective gas bit
+	rlncf	hi,F								; rotate gas bit pattern to match the next gas
+	decfsz	lo,F								; decrement loop counter, did it became zero?
+	bra		write_backtrack_datum_gas_loop		; NO  - loop
+	movwf	POSTINC1							; YES - write the gas staging status entry and increment the writing position index
+	return										;     - done
+
+write_backtrack_datum_waypoint:
+	incf	backtrack_waypoint_num,F			; increment the waypoint number
+	movf	backtrack_waypoint_num,W			; copy waypoint number to WREG
+	iorlw	b'11100000'							; add the waypoint marker (bit 7-5 set) to the number stored in WREG
+	movwf	POSTINC1							; write the waypoint datum and increment the writing position index
+	movlw	.2									; load a 2 into WREG
+	cpfslt	backtrack_waypoint_num				; new waypoint number >= 2 ?
+	bcf		waypoint_reached_first				; YES - not at first waypoint any more
+	return										; done
+
+write_backtrack_datum_check:
+	movff	FSR1L,char_I_backtrack_index		; store new index position
+	movlw	backtrack_almost_full_threshold		; load threshold for backtracking storage almost full
+	bcf		backtrack_almost_full				; clear almost full state
+	cpfslt	FSR1L								; index < threshold ?
+	bsf		backtrack_almost_full				; NO - flag backtracking storage is almost full
+	movlw	backtrack_entire_full_threshold		; load threshold for backtracking storage entirely full
+	bcf		backtrack_entire_full				; clear entirely full state
+	cpfslt	FSR1L								; index < threshold ?
+	bsf		backtrack_entire_full				; NO - flag backtracking storage is entirely full
+	return										; done
+
+ ENDIF	; _cave_mode
 
 ;=============================================================================
 
@@ -1389,17 +1767,12 @@
 
 
 set_powersafe:
-	movlw	battery_warn_level_36+1		; get threshold for 3.6 Volt battery warning, incremented by 1
-	btfss	battery_is_36v				; actually a 3.6 Volt battery detected?
-	movlw	battery_warn_level_15+1		; NO - replace with 1.5 Volt battery warning, incremented by 1
-	cpfslt	batt_percent				; current battery level > warning threshold ?
-	return								; YES - ok, done
-	movlw	d'7'						; NO  - set type of alarm = battery low
-	movwf	alarm_type					;     - copy to alarm register
-	bsf		event_occured				;     - set event flag
-	movlw	.0							;     - coding of brightness level ECO
-	movff	WREG,opt_brightness			;     - set brightness to ECO
-	return								;     - done
+	movlw	d'7'						; set type of alarm = battery low
+	movwf	alarm_type					; copy to alarm register
+	bsf		event_occured				; set event flag
+	movlw	.0							; coding of brightness level ECO
+	movff	WREG,opt_brightness			; set brightness to ECO
+	return								; done
 
 
 clear_resettable_average_depth:
@@ -1551,34 +1924,40 @@
 	call	reset_timeout_time			; reset timeout
 	movff	active_premenu,WREG			; get number of active pre-menu
 	dcfsnz	WREG,F
-	bra		divemode_option_gaschange	; switch to the the "better gas" / "better diluent"
+	bra		divemode_option_gaschange	;  1: switch to the the "better gas" / "better diluent"
 	dcfsnz	WREG,F
-	bra		divemode_option0			; start/setup dive mode menu
+	bra		divemode_option_divemenu	;  2: enter dive mode menu
 	dcfsnz	WREG,F
-	bra		divemode_option1			; quit simulation?
-	dcfsnz	WREG,F
-	bra		divemode_option2			; descent 1m
+ IFDEF _cave_mode
+	bra		divemode_option_cavemenu	;  3: enter cave mode menu
+ ELSE
+	return								;  3: (no cave mode compiled in)
+ ENDIF
 	dcfsnz	WREG,F
-	bra		divemode_option3			; ascend  1m
+	bra		divemode_option_sim_quit	;  4: simulation - quit
 	dcfsnz	WREG,F
-	bra		divemode_option4			; quit apnoe mode
+	bra		divemode_option_sim_down	;  5: simulation - descent
+	dcfsnz	WREG,F
+	bra		divemode_option_sim_up		;  6: simulation - ascend
 	dcfsnz	WREG,F
-	bra		divemode_option5			; reset stopwatch (gauge mode only)
+	bra		divemode_option_sim_time	;  7: simulation - +5 min
 	dcfsnz	WREG,F
-	bra		divemode_option6			; +5 min simulation
+	bra		divemode_option_apnoe_quit	;  8: apnoe - quit
+	dcfsnz	WREG,F
+	bra		divemode_option_gauge_reset	;  9: gauge - reset stopwatch and avg depth
 	dcfsnz	WREG,F
  IFDEF _compass
-	bra		divemode_option7			; store heading
+	bra		divemode_option_course		; 10: store heading
  ELSE
-	return								; should never happen without compass
+	return								; 10: (no compass compiled in)
  ENDIF
 	dcfsnz	WREG,F
-	bra		divemode_option8			; switch layout
+	bra		divemode_option_layout		; 11: switch layout
 	return
 
 
-gas_switched_common:
-	bcf		request_gaschange			; clear request flag
+gas_switch_common:
+	bcf		request_gas_change			; clear request flag
  IFDEF _ccr_pscr
 	btfss	request_back_to_loop		; is a switchback from OC bailout to loop requested?
 	bra		gas_switched_common0		; NO  - continue with checking if selected gas is valid
@@ -1591,20 +1970,21 @@
 	bra		gas_switched_common1		; NO  - valid gas
 	return								; YES - something went wrong, invalid gas, abort
 gas_switched_common1:
-	movf	menu_pos_cur,W				; get selected gas into WREG (1-6)
+	movf	menu_pos_cur,W				; get selected gas into WREG (1-5)
  IFDEF _ccr_pscr
 	btfsc	FLAG_oc_mode				; in OC mode?
 	bra		gas_switched_common_OC		; YES
 	btfsc	bailout_mode				; in bailout?
 	bra		gas_switched_common_OC		; YES
 gas_switched_common_loop:				; NO to both - must be loop mode then
-	rcall	setup_dil_registers			; with WREG = diluent 1-6
-	rcall	deco_setup_cc_diluents		; with WREG = diluent 1-6
-	bra		gas_switched_common3
- ENDIF
+	rcall	setup_dil_registers			; set up real tissues  with WREG = diluent 1-6
+	rcall	deco_setup_cc_diluents		; set up deco planning with WREG = diluent 1-6
+	bra		gas_switched_common3		; continue with common part
+ ENDIF	; _ccr_pscr
 gas_switched_common_OC:
-	rcall	setup_gas_registers			; with WREG = Gas 1-6
-	rcall	deco_setup_oc_gases			; with WREG = Gas 1-6
+	rcall	setup_gas_registers			; set up real tissues  with WREG = gas 1-6
+	rcall	deco_setup_oc_gases			; set up deco planning with WREG = gas 1-6
+	;bra	gas_switched_common3		; continue with common part
 gas_switched_common3:
 	banksel	int_O_breathed_ppO2
 	bcf		int_O_breathed_ppO2+1,int_low_flag			; | clear all flags that control color-coding
@@ -1612,18 +1992,31 @@
 	bcf		int_O_breathed_ppO2+1,int_attention_flag	; | memo color instead of a warning or attention
 	bcf		int_O_breathed_ppO2+1,int_warning_flag		; | color that belonged to the previous gas
 	banksel	common
-	bsf		FLAG_TFT_active_gas_divemode				; redraw gas/setpoint/diluent
-	call	restart_deco_engine_wo_ceiling				; abort any running deco calculations and restart the deco engine
-	; set flags for profile recording
-	bsf		event_occured				; set global event flag
+	bsf		FLAG_TFT_active_gas_divemode	; redraw gas/setpoint/diluent
+	bsf		FLAG_TFT_temperature			; redraw temperature
+	bsf		event_occured					; set global event flag
  IFDEF _ccr_pscr
-	btfsc	bailout_mode				; in bailout mode?
-	bsf		event_bailout				; YES - set gas change event due to bailout
-	btfss	bailout_mode				; in bailout mode?
+	btfsc	bailout_mode					; in bailout mode?
+	bsf		event_bailout					; YES - set bailout event
+	btfss	bailout_mode					; in bailout mode?
  ENDIF
-	bsf		event_gas_change			; NO  - set gas change event (normal change)
-	return
-
+	bsf		event_gas_change				; (NO) - set gas change event (normal change)
+	goto	restart_deco_engine_wo_ceiling	; abort running deco calculations and restart (and return)
+
+
+gas_update_common:
+	bcf		request_gas_update			; reset the request flag
+	movf	active_gas,W				; load WREG with currently used gas
+ IFDEF _ccr_pscr
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		gas_switched_common_OC		; YES - reload OC gases
+	btfsc	bailout_mode				; NO  - in bailout?
+	bra		gas_switched_common_OC		;       YES - reload OC gases
+	movf	active_dil,W				;       NO  - load WREG with currently used diluent
+	bra		gas_switched_common_loop	;           - set up diluent gases
+ ELSE
+	bra		gas_switched_common_OC		; reload OC gases
+ ENDIF
 
 ; Code to pass all parameters to the C code
 
@@ -1704,11 +2097,11 @@
 	rcall	deco_setup_copy				; copy all gas types
 	lfsr	FSR1,opt_gas_change			; load FSR1 with base address of opt_gas_change
 	rcall	deco_setup_copy				; copy all gas change depths
-										; switch to oc mode
-	bcf		lo,DECO_MODE_PSCR_FLAG		; clear the pSCR-mode flag (may not be set, but never mind)
-	bcf		lo,DECO_MODE_LOOP_FLAG		; clear the loop/CCR-mode flag
-	movff	lo,char_O_deco_status		; bank safe write-back of char_O_deco_status
-	return
+										; switch deco engine to oc mode:
+	bcf		lo,DECO_MODE_PSCR_FLAG		; - clear the pSCR-mode flag (may not be set, but never mind)
+	bcf		lo,DECO_MODE_LOOP_FLAG		; - clear the loop/CCR-mode flag
+	movff	lo,char_O_deco_status		; - bank safe write-back of char_O_deco_status
+	return								; done
 
 ;=============================================================================
 
@@ -1743,13 +2136,13 @@
 	rcall	deco_setup_copy				; copy all dil types
 	lfsr	FSR1,opt_dil_change			; load FSR1 with base address of opt_dil_change
 	rcall	deco_setup_copy				; copy all dil change depths
-										; switch to CCR / pSCR mode
-	bsf		lo,DECO_MODE_LOOP_FLAG		; loop flag is set in both, CCR and pSCR mode
-	bcf		lo,DECO_MODE_PSCR_FLAG		; clear pSCR mode flag by default
-	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
-	bsf		lo,DECO_MODE_PSCR_FLAG		; YES - set additional flag for pSCR mode
-	movff	lo,char_O_deco_status		; bank safe write-back of char_O_deco_status
-	return
+										; switch to CCR / pSCR mode:
+	bsf		lo,DECO_MODE_LOOP_FLAG		; - loop flag is set in both, CCR and pSCR mode
+	bcf		lo,DECO_MODE_PSCR_FLAG		; - clear pSCR mode flag by default
+	btfsc	FLAG_pscr_mode				; - check if we are in pSCR mode
+	bsf		lo,DECO_MODE_PSCR_FLAG		;   YES - set additional flag for pSCR mode
+	movff	lo,char_O_deco_status		; - bank safe write-back of char_O_deco_status
+	return								; done
 
  ENDIF
 
@@ -1790,7 +2183,7 @@
 	movff	PLUSW1,char_I_current_gas_type ; copy gas type (0=Disabled, 1=First, 2=Travel, 3=Deco)
 setup_gas_registers_com:
 	movff	char_O_main_status,lo		; working copy of char_O_main_status in bank common
-	bcf		lo,DECO_MODE_PSCR_FLAG		; clear the pSCR-mode flag (may not be set, but never mind)
+	bcf		lo,DECO_MODE_PSCR_FLAG		; clear the pSCR-mode flag (if applicable)
 	bcf		lo,DECO_MODE_LOOP_FLAG		; clear the loop/CCR-mode flag
 	movff	lo,char_O_main_status		; bank safe write-back of char_O_main_status
 	movf	active_gas,W				; reload WREG with gas 1-5 or 6 (important!)
@@ -1855,16 +2248,27 @@
 	movff	best_gas_number,menu_pos_cur; select best gas
 	bcf		better_gas_available		; clear flag immediately
 divemode_option_gaschange3				; common part
-	bsf		request_gaschange			; request a gas/diluent change
-	call	menuview_toggle_reset		; terminate the pre-menu
-	return
-
-	global	divemode_option0_return
-divemode_option0:						; start/setup dive mode menu
-	call	TFT_clear_divemode_menu		; clear menu area
-	bcf		dive_options_menu			; dive options menu is not shown anymore
-	call	do_main_divemenu			; hand over to menu processor
-divemode_option0_return:				; return point for menu processor
+	bsf		request_gas_change			; request a gas/diluent change
+	goto	menuview_toggle_reset		; terminate the pre-menu (and return)
+
+divemode_option_divemenu:				; start/setup dive mode menu
+	btfss	divemode					; in dive mode?
+	goto	menuview_toggle_reset		; NO  - block menu, terminate the pre-menu
+	call	TFT_clear_divemode_menu		; YES - clear menu area
+	bcf		dive_options_menu			;     - set dive options menu as not shown anymore
+	goto	do_main_divemenu			;     - hand over to menu processor
+
+ IFDEF _cave_mode
+divemode_option_cavemenu:				; start/setup cave mode menu
+	btfss	divemode					; in dive mode?
+	goto	menuview_toggle_reset		; NO  - block menu, terminate the pre-menu
+	call	TFT_clear_divemode_menu		; YES - clear menu area
+	bcf		dive_options_menu			;     - set dive options menu as not shown anymore
+	goto	do_main_cavemenu			;     - hand over to menu processor
+ ENDIF
+
+	global	divemode_option_divemenu_return
+divemode_option_divemenu_return:		; return point for menu processor
 	call	TFT_show_menu_cursor_divemode ; show the cursor
 	clrf	active_premenu				; set pre-menu    is not shown any more
 	bcf		safety_stop_active			; set safety stop is not shown any more
@@ -1873,7 +2277,7 @@
 	call	reset_timeout_time			; reload timeout
 	goto	diveloop_menu_exit			; go back to dive loop (menu processor resets STKPTR!)
 
-divemode_option1:						; quit simulation mode
+divemode_option_sim_quit:				; quit simulation mode
 	clrf	simulatormode_depth			; set target depth to zero
 	bsf		quit_simulatormode			; request ISR to end simulator mode
 	call	menuview_toggle_reset		; terminate the pre-menu
@@ -1881,30 +2285,19 @@
 	bcf		divemode					; YES - force end of dive mode
 	return								; done
 
-divemode_option2:						; plus 1 meter
+divemode_option_sim_down:				; plus 1 meter
 	movlw	ostc_depth_max-1			; load depth limit into WREG
 	cpfsgt	simulatormode_depth			; simulated depth <= limit ?
 	incf	simulatormode_depth,F		; YES - increment simulated depth
 	return								; done
 
-divemode_option3:						; minus 1 meter
+divemode_option_sim_up:					; minus 1 meter
 	tstfsz	simulatormode_depth			; simulated depth > 0 ?
 	decf	simulatormode_depth,F		; YES - decrement simulated depth
 	return								; done
 
-divemode_option4:						; quit apnoe mode (available while at the surface only)
-	btfsc	sensor_override_active		; in simulator mode?
-	bra		divemode_option1			; YES - use simulator quit procedure
-	bcf		divemode					; NO  - force end of dive mode
-	return								;     - done
-
-
-divemode_option5:
-	bsf		request_reset_avg			; request reset of average depth
-	goto	menuview_toggle_reset		; terminate pre-menu and return
-
-divemode_option6:
-	; check for pending +5 request
+divemode_option_sim_time:
+	; check for pending +5' request on deco engine
 	movff	char_I_sim_advance_time,WREG; get mailbox content
 	tstfsz	WREG						; mailbox clear (=0) ?
 	return								; NO - still having a pending +5' request, refuse new request
@@ -1948,34 +2341,61 @@
 	addwfc	pressure_rel_accu_trip+3,F
 
 	; add to the total depth accumulator
-	movf	xC+0,w
+	movf	xC+0,W
 	addwf	pressure_rel_accu_total+0,F
-	movf	xC+1,w
+	movf	xC+1,W
 	addwfc	pressure_rel_accu_total+1,F
-	movf	xC+2,w
+	movf	xC+2,W
 	addwfc	pressure_rel_accu_total+2,F
-	movf	xC+3,w
+	movf	xC+3,W
 	addwfc	pressure_rel_accu_total+3,F
 
  IFDEF _cave_mode
 	; update backtracking data
-	movlw	.5							; configure 5 minutes
-	call	update_backtrack			; add backtrack data for 5 minutes
- ENDIF
-
+	btfss	cave_mode						; cave mode switched on?
+	bra		divemode_option_sim_time_exit	; NO  - skip backtracking depth recording
+	btfsc	dive_turned						; YES - dive turned?
+	bra		divemode_option_sim_time_exit	;       YES - skip   backtracking depth recording
+	;bra	divemode_option_sim_time_exec	;       NO  - update backtracking depth recording
+divemode_option_sim_time_exec:
+	movff	backtrack_deltatime,hi			; backup time elapsed since last depth recording
+	movlw	.5								; configure 5 minutes
+	movwf	lo								; use lo as loop counter
+divemode_option_sim_time_loop:
+	call	write_backtrack_1min_depth		; store a backtracking depth data set
+	btfsc	backtrack_entire_full			; backtracking storage entirely used up?
+	bra		divemode_option_sim_time_exit	; YES - abort backtracking depth recording
+	decfsz	lo,F							; NO  - decrement loop counter, did it became zero?
+	bra		divemode_option_sim_time_loop	;       NO  - loop
+	;bra	divemode_option_sim_time_done	;       YES - done
+divemode_option_sim_time_done:
+	movff	hi,backtrack_deltatime			; restore time elapsed since last depth recording
+	;bra	divemode_option_sim_time_exit	; finish backtracking depth recording
+ ENDIF	; _cave_mode
+
+divemode_option_sim_time_exit:
 ;	goto	menuview_toggle_reset		; terminate the pre-menu and return
 	return								; just return, leaving option avail for repeated selection
 
+divemode_option_apnoe_quit:				; quit apnoe mode (available while at the surface only)
+	btfsc	sensor_override_active		; in simulator mode?
+	bra		divemode_option_sim_quit	; YES - use simulator quit procedure
+	bcf		divemode					; NO  - force end of dive mode
+	return								;     - done
+
+divemode_option_gauge_reset:
+	bsf		request_reset_avg			; request reset of average depth
+	goto	menuview_toggle_reset		; terminate pre-menu and return
+
  IFDEF _compass
-divemode_option7:
+divemode_option_course:
 	; store heading for compass view
 	MOVII	compass_heading_shown,compass_bearing
 	bsf		compass_bearing_set			; set flag to show heading
 	goto	menuview_toggle_reset		; terminate the pre-menu and return
  ENDIF
 
-
-divemode_option8:
+divemode_option_layout:						; switch layout
 	call	menuview_toggle_reset		; terminate the pre-menu
 	call	TFT_ClearScreen				; clear the whole screen
 	btg		alt_layout_active			; toggle layout
@@ -1992,8 +2412,8 @@
 	bsf		FLAG_TFT_depth_current		; request redraw of current depth
 	bsf		FLAG_TFT_depth_maximum		; request redraw of maximum depth
 	bsf		FLAG_TFT_active_gas_divemode; request redraw of gas and setpoint
-	bsf		FLAG_TFT_customview_mask	; request redraw of custom view mask
 	bsf		FLAG_TFT_temperature		; request redraw of temperature
+	bsf		FLAG_TFT_customview_callup	; request redraw of custom view
 
 	goto	request_redraw_NDL_deco_data; request redraw of NDL/deco data and return
 
@@ -2044,7 +2464,6 @@
 check_gas_best_2:
 
  IFDEF _ccr_pscr
-
 	; check dive mode
 	btfsc	FLAG_oc_mode					; in OC mode?
 	bra		check_gas_best_gas				; YES - skip diluents, check for best gas only
@@ -2056,39 +2475,16 @@
 	movff	char_I_ppO2_min_loop,WREG		; YES - replace by min ppO2 for pure diluent in pSCR mode
 	mullw	.100							; min ppO2 * 100, result in 0.1 mbar
 	MOVII	PROD,ppO2_min					; store in ppO2_min
-	; preset results to nothing found
-	clrf	best_gas_num					; initialize best diluent as 0 = nothing found yet
-	bcf		better_dil_available			; =1: a better diluent is available and a gas change is advised in dive mode
-;	; current diluent = 'gas6' ?
-;	movlw	.6								;
-;	cpfseq	active_dil						; using 'gas6' as current diluent?
-;	bra		check_gas_best_dil0				; NO  - continue
-;	bra		check_gas_best_dil3				; YES - suppress better diluent search in this case
-;check_gas_best_dil0:
-	; check all diluents
+	; check diluents
 	lfsr	FSR1,opt_dil_O2_ratio			; set base address for diluent arrays
-	movff	active_dil,lo					; number of currently used diluent
-	setf	best_gas_depth					; initialize change depth of best dil found so far to 255 meter
-; original code
-	clrf	check_gas_num
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check diluent 1
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check diluent 2
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check diluent 3
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check diluent 4
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check diluent 5
-; alternative code
-;	movlw	.5
-;	movwf	check_gas_num
-;check_gas_best_dil_loop:
-;	rcall	check_gas_best_common
-;	decfsz	check_gas_num
-;	bra		check_gas_best_dil_loop
-;
+	movff	active_dil,lo					; set number of currently used diluent
+	; preset result to nothing found
+	clrf	best_gas_num					; initialize best diluent to   0 = none found yet
+	setf	best_gas_depth					; initialize change depth to 255 = any one will be better
+	; check if current diluent is usable
+	movff	lo,check_gas_num				; check if the current diluent is usable
+	rcall	check_gas_best_common			; if yes, the current diluent will become the best diluent found so far
+	rcall	check_gas_best_all				; check if any other  diluent is better
 	; store result
 	movff	best_gas_num,best_dil_number	; store new best diluent found (1-5 or 0 of no usable diluent available)
 	; check if change advices shall be given in general
@@ -2096,10 +2492,11 @@
 	bra		check_gas_best_gas				; YES - no better diluent advice when in bailout
 check_gas_best_dil1:
 	; check if a change advice shall be given right now
+	bcf		better_dil_available			; default to no better diluent found
 	movf	best_dil_number,W				; load number of best diluent into WREG (1-5)
 	bz		check_gas_best_dil3				; has a best diluent been found at all?  NO - nothing to signal for
 	cpfseq	active_dil						; is this the currently used diluent?
-	bra		check_gas_best_dil2				; NO
+	bra		check_gas_best_dil2				; NO  - a better diluent has been found
 	bra		check_gas_best_dil3				; YES - no need to signal a better diluent if this diluent is already in use
 check_gas_best_dil2:
 	btfsc	sp_fallback						; in fallback condition?
@@ -2110,62 +2507,42 @@
 check_gas_best_dil3:
 	btfss	better_dil_available			; shall a better diluent be signaled for?
 	bcf		better_dil_blinking				; NO  - clear blinking flag
-	; continue with checking for best bailout gas
-
+	;bra	check_gas_best_gas				; ; continue with checking for best bailout gas
  ENDIF	; _ccr_pscr
 
+
 check_gas_best_gas:
 	; set minimum ppO2 required
 	movff	char_I_ppO2_min,WREG			; min ppO2 for OC and bailout
 	mullw	.100							; min ppO2 * 100, result in 0.1 mbar
 	MOVII	PROD,ppO2_min					; store in ppO2_min
-	; preset results to nothing found
-	clrf	best_gas_num					; initialize best gas as 0 = nothing found yet
-	bcf		better_gas_available			; =1: a better gas is available and a gas change is advised in dive mode
-;	; current gas = 'gas6' ?
-;	movlw	.6								;
-;	cpfseq	active_gas						; using 'gas6' as current gas?
-;	bra		check_gas_best_gas0				; NO  - continue
-;	bra		check_gas_best_gas3				; YES - suppress better gas search in this case
-;check_gas_best_gas0:
-	; check all gases
+	; check gases
 	lfsr	FSR1,opt_gas_O2_ratio			; set base address for gas arrays
-	movff	active_gas,lo					; number of currently used gas
-	setf	best_gas_depth					; initialize change depth of best gas found so far to 255 meter
-; original code
-	clrf	check_gas_num
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check gas 1
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check gas 2
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check gas 3
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check gas 4
-	incf	check_gas_num,F
-	rcall	check_gas_best_common			; check gas 5
-; alternative code
-;	movlw	.5
-;	movwf	check_gas_num
-;check_gas_best_gas_loop:
-;	rcall	check_gas_best_common
-;	decfsz	check_gas_num
-;	bra		check_gas_best_gas_loop
-;
+	movff	active_gas,lo					; set number of currently used gas
+	; preset result to nothing found
+	clrf	best_gas_num					; initialize best gas to       0 = none found yet
+	setf	best_gas_depth					; initialize change depth to 255 = any one will be better
+	; check if current gas is usable
+	movff	lo,check_gas_num				; check if the current gas is usable
+	rcall	check_gas_best_common			; if yes, the current gas will become the best gas found so far
+	rcall	check_gas_best_all				; check if any other  gas is better
 	; store result
 	movff	best_gas_num,best_gas_number	; store new best gas found (1-5 or 0 of no usable gas available)
+ IFDEF _ccr_pscr
 	; check if change advices shall be given in general
 	btfsc	FLAG_oc_mode					; in OC mode?
-	bra		check_gas_best_gas1				; YES
-	btfsc	bailout_mode					; in bailout?
-	bra		check_gas_best_gas1				; YES
-	return									; NO  - no better (OC) gas advice when not in OC or bailout mode
+	bra		check_gas_best_gas1				; YES - give advice
+	btfsc	bailout_mode					; NO  - in bailout?
+	bra		check_gas_best_gas1				;       YES - give advice
+	return									;       NO  - no better (OC) gas advice when not in OC or bailout mode
+ ENDIF	; _ccr_pscr
 check_gas_best_gas1:						; check if we are already on the best gas
 	; check if a change advice shall be given right now
+	bcf		better_gas_available			; default to no better gas found
 	movf	best_gas_number,W				; load number of best gas into WREG (1-5)
 	bz		check_gas_best_gas3				; has a best gas been found at all?  NO - nothing to signal for
 	cpfseq	active_gas						; is this the currently used gas?
-	bra		check_gas_best_gas2				; NO
+	bra		check_gas_best_gas2				; NO  - a better gas has been found
 	bra		check_gas_best_gas3				; YES - no need to signal a better gas if this gas is already in use
 check_gas_best_gas2:
 	; not using the best gas - show better gas hint whenever a better gas is available
@@ -2176,6 +2553,20 @@
 	bcf		better_gas_blinking				; NO - clear blinking flag
 	return
 
+
+check_gas_best_all:
+	clrf	check_gas_num					; increment comes first, so initialize with zero
+check_gas_best_loop:
+	incf	check_gas_num,F					; increment number of gas to check
+	movf	lo,W							; copy number of currently used gas to WREG
+	cpfseq	check_gas_num					; gas to be checked = currently used gas ?
+	rcall	check_gas_best_common			; NO - check the gas
+	movlw	NUM_GAS							; get total number of gases
+	cpfseq	check_gas_num					; reached last gas?
+	bra		check_gas_best_loop				; NO  - loop
+	return									; YES - done
+
+
 check_gas_best_common:						; with gas to be checked in check_gas_num (1-5)
 ;											; and  current gas       in lo            (1-5)
 	;
@@ -2205,19 +2596,25 @@
 	bra		check_gas_best_common3			; YES - a gas in use overrides disabled and deco status
 check_gas_best_common0:
 	; check if gas is available (i.e. not disabled)
+	btfsc	check_gas_type,gas_lost			; gas/dil lost?
+	return									; YES - skip as not available any more
+	btfsc	check_gas_type,gas_staged		; gas/dil staged?
+	return									; YES - skip as currently not available
 	tstfsz	check_gas_type					; type = disabled (0) ?
 	bra		check_gas_best_common1			; NO  - continue checks
-	return									; YES - skip disabled gases
+	return									; YES - skip as not available at all
 check_gas_best_common1:
 	; skip deco gases (type=3) if there are no stops, but include them when in bailout mode
 	movlw	.3								; coding for deco gas
 	cpfseq	check_gas_type					; type = deco (3) ?
 	bra		check_gas_best_common3			; NO  - first or travel/normal then, ok to use
+ IFDEF _ccr_pscr
 	btfsc	bailout_mode					; YES - in bailout?
 	bra		check_gas_best_common2			;       YES - ok to use (using deco gases is always allowed when in bailout)
-	TSTOSS	opt_extended_stops				;       NO  - extended stops enables?
-	bra		check_gas_best_common1b			;             NO
-	;bra	check_gas_best_common1a			;             YES
+ ENDIF
+	TSTOSS	opt_ext_stops					;       NO  - extended stops enabled?
+	bra		check_gas_best_common1b			;             NO  - only ok if in deco region
+	;bra	check_gas_best_common1a			;             YES - only ok if in deco mode
 check_gas_best_common1a:
 	movff	char_O_deco_info,WREG			; get deco info vector
 	btfss	WREG,deco_mode					; are we in deco mode?
@@ -2242,11 +2639,11 @@
 	bra		check_gas_best_common5			; YES - check if the new one is better than the one we have so far
 	bra		check_gas_best_common6			; NO  - no need to do the above mentioned check
 check_gas_best_common5:
-	; check if the change depth of the checked gas is <= (shallower or equal) the change depth of the best gas found so far
+	; check if the change depth of the checked gas is < (shallower) than the change depth of the best gas found so far
 	movf	best_gas_depth,W				; load change depth of best gas so far into WREG
-	cpfsgt	check_gas_depth					; change depth of checked gas > (deeper than) change depth of best gas so far?
-	bra		check_gas_best_common6			; NO  - this gas is better or equal, continue
-	return									; YES - this gas is not better than the best already found
+	cpfslt	check_gas_depth					; change depth of checked gas < (shallower than) change depth of best gas so far?
+	return									; NO  - this gas is not better than the best already found
+	;bra	check_gas_best_common6			; YES - this gas is better, continue
 check_gas_best_common6:
 	; check if the gas fits into the ppO2 limits
 	movff	check_gas_O2_ratio,xB+0			; xB = O2 ratio, xA is still loaded with (absolute pressure / 10)
@@ -2268,9 +2665,9 @@
 	btfsc	neg_flag						; within limit?
 	return									; NO - too low, gas is not usable
 	; we have a (new) best gas
-	movff	check_gas_num,  best_gas_num	; set checked gas (1-5) as best gas
-	movff	check_gas_depth,best_gas_depth	; memorize its change depth
-	return
+	movff	check_gas_num,  best_gas_num	; YES - set checked gas (1-5) as best gas
+	movff	check_gas_depth,best_gas_depth	;     - memorize its change depth
+	return									;     - done
 
 
 ;=============================================================================
@@ -2284,7 +2681,7 @@
 	bz		check_dive_autosp2			; YES - check
 	return								; NO  - return for sensor or fixed mode
 check_dive_autosp2:
-	; Check SP2
+	; check SP2
 	btfsc	FLAG_SP2_used				; SP 2 used so far?
 	bra		check_dive_autosp3			; YES - continue with SP 3
 	movff	opt_setpoint_change+1,lo	; NO  - get depth in m
@@ -2300,7 +2697,7 @@
 	rcall	xmit_sp_set_flag			;     - send SP to external devices
 	bsf		FLAG_SP2_used				;     - set SP 2 used flag
 check_dive_autosp3:
-	; Check SP3
+	; check SP3
 	btfsc	FLAG_SP3_used				; SP 3 used so far?
 	bra		check_dive_autosp4			; YES - continue with SP 4
 	movff	opt_setpoint_change+2,lo	; NO  - get depth in m
@@ -2316,7 +2713,7 @@
 	rcall	xmit_sp_set_flag			;     - send SP to external devices
 	bsf		FLAG_SP3_used				;     - set SP 3 used flag
 check_dive_autosp4:
-	; Check SP4
+	; check SP4
 	btfsc	FLAG_SP4_used				; SP 4 used so far?
 	bra		check_dive_autosp5			; YES - continue with SP 5
 	movff	opt_setpoint_change+3,lo	; NO  - get depth in m
@@ -2332,7 +2729,7 @@
 	rcall	xmit_sp_set_flag			;     - send SP to external devices
 	bsf		FLAG_SP4_used				;     - set SP 4 used flag
 check_dive_autosp5:
-	; Check SP5
+	; check SP5
 	btfsc	FLAG_SP5_used				; SP 5 used so far?
 	bra		check_dive_autosp6			; YES - done
 	movff	opt_setpoint_change+4,lo	; NO  - get depth in m
@@ -2372,41 +2769,23 @@
 ;=============================================================================
 ; Setup everything to enter dive mode
 ;
-	global	dive_boot_oc_bail
-dive_boot_oc_bail:
-	; copy opt_gas_types into backup (for "lost gas" feature)
-	movff	opt_gas_type+0,opt_gas_type_backup+0	; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+1,opt_gas_type_backup+1	; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+2,opt_gas_type_backup+2	; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+3,opt_gas_type_backup+3	; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	movff	opt_gas_type+4,opt_gas_type_backup+4	; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	return
-
 	global	dive_boot_oc
 dive_boot_oc:
 	; set-up registers
-	rcall	get_first_gas_to_WREG					; get first gas (1-5) into WREG
-	rcall	setup_gas_registers						; set-up of gas parameters of currently breathed gas (with WREG = gas 1-5)
-	rcall	deco_setup_oc_gases						; set-up of gas list for deco calculations           (with WREG = gas 1-5)
+	rcall	get_first_gas_to_WREG		; get first gas (1-5) into WREG
+	rcall	setup_gas_registers			; set-up of gas parameters of currently breathed gas (with WREG = gas 1-5)
+	rcall	deco_setup_oc_gases			; set-up of gas list for deco calculations           (with WREG = gas 1-5)
 	return
 
-;=============================================================================
 
  IFDEF _ccr_pscr
 
 	global	dive_boot_cc
 dive_boot_cc:
-	; copy opt_dil_types into backup (for "lost diluent" feature)
-	movff	opt_dil_type+0,opt_dil_type_backup+0	; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+1,opt_dil_type_backup+1	; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+2,opt_dil_type_backup+2	; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+3,opt_dil_type_backup+3	; 0=Disabled, 1=First, 2=Normal
-	movff	opt_dil_type+4,opt_dil_type_backup+4	; 0=Disabled, 1=First, 2=Normal
 	; set-up registers
-	rcall	get_first_dil_to_WREG					; get first diluent (1-5) into WREG
-	rcall	setup_dil_registers						; set-up of diluent parameters for currently breathed diluent (with WREG = current diluent 1-5)
-	rcall	deco_setup_cc_diluents					; set-up of diluent list for deco calculations                (with WREG = current diluent 1-5)
-	; done
+	rcall	get_first_dil_to_WREG		; get first diluent (1-5) into WREG
+	rcall	setup_dil_registers			; set-up of diluent parameters for currently breathed diluent (with WREG = current diluent 1-5)
+	rcall	deco_setup_cc_diluents		; set-up of diluent list for deco calculations                (with WREG = current diluent 1-5)
 	return
 
 
@@ -2487,35 +2866,44 @@
 
  IFDEF _cave_mode
 	; initialize the cave mode
-	bsf		cave_mode					; enable cave mode by default
-	movff	opt_calc_asc_gasvolume,WREG	; get gas needs calculation mode (0= off, 1= on, 2= cave mode)
-	xorlw	.2							; coding for cave mode
-	tstfsz	WREG						; cave mode enabled?
-	bcf		cave_mode					; NO - disable cave mode again
- ENDIF
-
-	; configure the deco engine
+	bcf		cave_mode					; disable cave mode by default
+	TSTOSC	opt_cave_mode				; cave mode switched on?
+	bsf		cave_mode					; YES - enable cave mode
+
+	bcf		dive_turned					; dive is not turned yet
+	bcf		backtrack_almost_full		; backtracking storage is not almost   full yet
+	bcf		backtrack_entire_full		; backtracking storage is not entirely full yet
+	bsf		waypoint_reached_first		; current waypoint is the first recorded waypoint
+	bsf		waypoint_reached_last		; current waypoint is the last  recorded waypoint
+
+	clrf	backtrack_waypoint_num		; initialize the waypoint number
+	clrf	backtrack_waypoint_turn		; no turn point yet
+
+	movlw	.0							; initialize backtracking index to first position in storage
+	movff	WREG,char_I_backtrack_index	; ...
+
+	clrf	depth_meter					; store initial depth data set with depth = surface
+	call	write_backtrack_1min_depth	; ...
+ ENDIF	; _cave_mode
+
+	; base configuration of the deco engine
 	clrf	hi							; start with everything disabled
-
-	TSTOSC	opt_ZfactorUse				; shall use Z factors?
-	bsf		hi,DECO_Z_FACTOR_FLAG		; YES - enable Z factors
-
-	TSTOSC	opt_extended_stops			; shall make extended stops?
+	TSTOSC	opt_ext_stops				; shall make extended stops?
 	bsf		hi,DECO_EXTENDED_STOPS		; YES - enable extended stops
-
  IFDEF _rx_functions
 	btfsc	tr_functions_activated		; TR functions activated?
 	bsf		hi,DECO_TR_FUNCTIONS		; YES - enable TR functions
  ENDIF
-
+ IFDEF _gas_contingency
+	; set contingency mode on/off
+	TSTOSC	opt_gas_contingency_dive	; gas contingency for dive mode switched on?
+	bsf		hi,DECO_GAS_CONTINGENCY		; YES - activate gas contingency mode
+ ENDIF	; _gas_contingency
 	movff	hi,char_O_main_status		; bank-safe copy to deco engine
 
-	movff	char_O_deco_status,lo		; bank-safe read
-	bsf		lo,DECO_START_NORM			; set   flag for doing a  normal      plan,
-	bcf		lo,DECO_START_ALT			; clear flag for doing an alternative plan,
-	bsf		lo,DECO_INITIALIZE			; set   flag for initializing the deco engine
-	bcf		lo,DECO_ASCENT_FLAG			; disable delayed ascent calculation
-	bcf		lo,DECO_CALCULATOR_MODE		; deco engine not run from the deco calculator
+	clrf	lo							; start with everything disabled
+	bsf		lo,DECO_START_NORM			; set flag for doing a normal plan
+	bsf		lo,DECO_INITIALIZE			; set flag for initializing the deco engine
 	movff	lo,char_O_deco_status		; bank-safe copy back to deco engine
 
 	; disable "fast forward" function
@@ -2523,7 +2911,7 @@
 	movff	WREG,char_I_sim_advance_time
 
 	; write last stop depth to deco engine
-	movff	opt_last_stop,char_I_depth_last_deco
+	movff	opt_last_stop,char_I_last_stop_depth
 
 	; initialize max depth for apnoe mode
 	CLRI	apnoe_max_pressure
@@ -2541,8 +2929,8 @@
 	; save supersaturation at beginning of dive (only lower byte is used for value)
 	movff	int_O_lead_supersat+0,supersat_start
 
-	clrf	menu_pos_cur
-	clrf	active_premenu				; reset to zero (0= no pre-menu task)
+	clrf	menu_pos_cur				; reset current menu position
+	clrf	active_premenu				; no pre-menu task active
 	bsf		o2_sensors_agree			; initialize sensors disagree warning system
 
 	clrf	safety_stop_countdown		; clear safety stop count-down
@@ -2560,15 +2948,14 @@
 	CLRI	pressure_rel_avg_total		; average depth
 	CLRI	divesecs_avg_total			; time  accumulator
 	clrf	pressure_rel_accu_total+0	; depth accumulator
-	clrf	pressure_rel_accu_total+1
-	clrf	pressure_rel_accu_total+2
-	clrf	pressure_rel_accu_total+3
+	clrf	pressure_rel_accu_total+1	; ...
+	clrf	pressure_rel_accu_total+2	; ...
+	clrf	pressure_rel_accu_total+3	; ...
 
  IFDEF _rx_functions
 
 	btfss	tr_functions_activated		; TR functions activated?
 	bra		diveloop_boot_0				; NO  - skip TR function initialization
-										; YES - initialize TR function variables
 
 	banksel	int_IO_pressure_value
 	clrf	WREG						; clear WREG
@@ -2603,8 +2990,6 @@
 	setf	best_dil_number				; initialize best diluent as not computed yet (255)
  ENDIF
 
-	rcall	dive_boot_oc_bail			; basic settings required for all modes
-
 	btfsc	FLAG_oc_mode				; in OC mode?
 	rcall	dive_boot_oc				; YES - add OC mode settings
 
@@ -2620,6 +3005,8 @@
 	rcall	dive_boot_cc_part2			; YES - add CC sensor and SP settings
  ENDIF
 
+	bcf		bailout_mode				; not in bailout mode
+
 	call	ghostwriter_short_header	; write short header with dive number into profile memory
 	call	init_recording_params		; set up all the divisors for dive data recording
 
@@ -2661,7 +3048,7 @@
 	bra		divemode_check_warnings1	; NO  - update messages every second
 
 ;										; YES - update every 4 seconds:
-;	btfss	timebase_1sec				      - on second 1 or 3 ?
+;	btfss	timebase_1sec				;     - on second 1 or 3 ?
 ;	return								;       NO  - no update in this cycle
 ;	btfss	timebase_2sec				;       YES - on second 3 ?
 ;	return								;             NO  - no update in this cycle
@@ -2693,6 +3080,13 @@
 	bra		divemode_check_warnings2	; YES
 
 	; warnings applicable only in deco modes
+
+ IFDEF _cave_mode
+	rcall	check_cavemode				; check cave mode status
+ ENDIF
+
+	rcall	check_display_ftts			; show @+x time (or cave mode cTTS)
+
 	rcall	check_ppO2					; check ppO2 and displays warning, if required
 
  IFDEF _external_sensor
@@ -2718,14 +3112,8 @@
 
 	rcall	check_mbubbles				; check for micro bubbles
 	rcall	check_cns_violation			; check CNS value and display it, if required
-	rcall	check_gas_needs_ascent		; show gas needs warning if any gas need for ascent is > threshold
+	rcall	check_gas_needs		; show gas needs warning if any gas need for ascent is > threshold
 	rcall	check_eod_cns_violation		; check CNS values for end-of-dive and display warning, if required
-	rcall	check_display_ftts			; show @+x time
-
- IFDEF _cave_mode
-	btfsc	cave_mode					; cave mode switched on?
-	rcall	check_cavemode				; YES - check cave mode status
- ENDIF
 
 	btfsc	use_aGF						; using alternative GF factors?
 	rcall	warn_agf					; YES - show memo
@@ -2734,10 +3122,10 @@
 	rcall	warn_fallback				; YES - show a warning
 
 	btfsc	better_dil_available		; is a better diluent available?
-	rcall	advice_gas_change			; YES - display an advice
+	rcall	advice_gas_change			; YES - display a gas change advice
 
 	btfsc	better_gas_available		; is a better gas     available?
-	rcall	advice_gas_change			; YES - display an advice
+	rcall	advice_gas_change			; YES - display a gas change advice
 
 divemode_check_warnings2:
  IFDEF _rx_functions
@@ -2787,18 +3175,15 @@
 	cpfslt	batt_percent				; battery percentage ok?
 	return								; YES - no display, no warning
 	; Display Battery, but warn?
-	movlw	battery_warn_level_36+1		; get threshold for 3.6 Volt battery warning, incremented by 1
-	btfss	battery_is_36v				; actually a 3.6 Volt battery detected?
-	movlw	battery_warn_level_15+1		; NO - replace with 1.5 Volt battery warning, incremented by 1
-	cpfsgt	batt_percent				; battery percent below warning threshold?
-	bsf		message_warning				; YES - set warning flag
+	btfsc	battery_low_condition		; battery low condition detected?
+	bsf		message_warning				; YES - set warning flag for battery low
 	movlw	index_clock_batt_surfpress	; index of custom view clock, battery and surface pressure
 	cpfseq	active_customview			; battery shown in custom view?
 	bra		check_warn_battery2			; NO  - show warning
 	return								; YES - do not show twice (in custom view and in message area)
 check_warn_battery2:
 	incf	message_counter,F			  ; increase counter
-	goto	TFT_msg_batt_percent_divemode ; show percent (and return)
+	goto	TFT_msg_batt_percent_divemode ; show warning message for battery low (battery percent) and return
 
 
 check_divetimeout:
@@ -2841,15 +3226,17 @@
 check_ppO2_common:
 	movwf	alarm_type					; copy alarm type to alarm register
 	bsf		event_occured				; set event   flag
-	bsf		message_warning				; show warning sign
+	bsf		message_warning				; show warning sign for breathed ppO2
 check_ppO2_common_2:
 	btfsc	FLAG_oc_mode				; are we in OC mode?
 	bra		check_ppo2_display			; YES - show
+ IFDEF _ccr_pscr
 	btfsc	bailout_mode				; are we in bailout mode?
 	bra		check_ppo2_display			; YES - show
+ ENDIF
 	return								; NO  - in loop mode, ppO2 is already shown via setpoint display
 check_ppo2_display_a:
-	bsf		message_attention			; show attention sign
+	bsf		message_attention			; show attention sign for breathed ppO2
 check_ppo2_display:
 	movlw	index_ppo2_ead_end_cns		; index of custom view ppO2, EAD/END and CNS (without He) or gas density (with He)
 	cpfseq	active_customview			; ppO2 shown?
@@ -2861,26 +3248,28 @@
 	bra		check_ppO2_d				; NO  - show ppO2
 	return								; YES - do not show twice (in custom view and in warning area)
 check_ppO2_dw:
-	bsf		message_warning				; show warning sign
+	bsf		message_warning				; show warning   sign for diluent ppO2
 check_ppO2_da:
-	bsf		message_attention			; show attention sign (no problem if a warning sign is set as well, as it will take priority)
+	bsf		message_attention			; show attention sign for diluent ppO2 (no problem if a warning sign is set as well, as it will take priority)
 check_ppO2_d:
 	incf	message_counter,F			; increase counter
-	goto	TFT_show_ppo2_warning		; show breathed gas or diluent ppO2 warning (and return)
+	goto	TFT_show_ppo2_warning		; show warning message for breathed gas or diluent ppO2 and return
 
 
 check_display_ftts:
+ IFDEF _ccr_pscr
+	btfsc	bailout_mode				; in bailout mode?
+	return								; YES - in bailout no fTTS is computed, done
+ ENDIF
 	btfss	count_divetime				; is dive time counted?
-	return								; NO  - omit 
+	return								; NO  - omit, done
 	movff	char_I_extra_time,lo		; YES - get extra time
 	tstfsz	lo							;     - extra time > 0 ?
 	bra		check_display_ftts_1		;       YES - continue checking bailout condition
-	return								;       NO  - done
+	return								;       NO  - no fTTS computed, done
 check_display_ftts_1:
-	btfsc	bailout_mode				; in bailout mode?
-	return								; YES - in bailout no fTTS will be computed, so nothing to display
-	incf	message_counter,F			; NO  - increase counter
-	goto	TFT_show_ftts				;     - show @+x time
+	incf	message_counter,F			; increase counter
+	goto	TFT_show_ftts				; show @+x time
 
 
 	global	check_cns_violation
@@ -2893,9 +3282,9 @@
 	bra		check_cns_violation_2		;       YES - issue attention
 	return								;       NO  - done
 check_cns_violation_1:
-	bsf		message_warning				; show warning sign
+	bsf		message_warning				; show warning   sign for CNS
 check_cns_violation_2:
-	bsf		message_attention			; show attention sign
+	bsf		message_attention			; show attention sign for CNS
  IFNDEF _helium
 	movlw	index_ppo2_ead_end_cns		; index of custom view ppO2, EAD/END and CNS (without He) or gas density (with He)
 	cpfseq	active_customview			; CNS shown?
@@ -2909,7 +3298,7 @@
 	return								; YES - do not show twice (in custom view and in warning area)
 check_cns_violation_4:
 	incf	message_counter,F			; increase counter
-	goto	TFT_show_cns				; show CNS (and return)
+	goto	TFT_show_cns				; show attention/warning message for CNS and return
 
 
 	global	check_eod_cns_violation		; check end-of-dive CNS values
@@ -2930,14 +3319,14 @@
 	bra		check_eod_cns_violation2	;       YES - issue warning
 	return								;       NO  - done with CNS checking
 check_eod_cns_violation2:				; issue warning (actually only on attention level)
-	bsf		message_attention			; show attention sign
+	bsf		message_attention			; show attention sign for end-of-dive CNS
 	movlw	index_CNS					; index of custom view with CNS values
 	cpfseq	active_customview			; CNS values shown?
 	bra		display_eod_cns_violation	; NO  - issue textual warning
 	return								; YES - do not show twice (in custom view and in warning area)
 display_eod_cns_violation:
 	incf	message_counter,F			; increase counter
-	goto	TFT_warning_eod_cns			; issue CNS at end-of-dive warning (and return)
+	goto	TFT_warning_eod_cns			; show warning message for end-of-dive CNS and return
 
 
 	global	check_and_store_sat_violation
@@ -2947,26 +3336,28 @@
 	bra		check_and_store_sat_violation2	; NO  - continue with checking for attention flag
 	movlw	d'2'							; YES - set type of alarm
 	movwf	alarm_type						;     - copy to alarm register
-	bsf		event_occured					;     - set event   flag
-	bsf		message_warning					;     - set warning flag
-	bra		check_and_store_sat_violation3	;     - show GF warning
+	bsf		event_occured					;     - set  event   flag
+	bsf		message_warning					;     - show warning sign for saturation
+	bra		check_and_store_sat_violation3	;     - show saturation
 check_and_store_sat_violation2:
 	btfsc	WREG,int_attention_flag			; check if the attention flag is set
-	bra		check_and_store_sat_violation3	; YES - show gf
+	bra		check_and_store_sat_violation3	; YES - show saturation
 	TSTOSS	opt_enable_IBCD					; NO  - IBCD warning activated?
 	bra		check_and_store_sat_violation4	;       NO  - continue checking of deco info
 	movff	char_O_deco_warnings,WREG		;       YES - get the deco warnings vector
 	btfss	WREG,IBCD_warning				;           - is the IBCD warning flag set?
 	bra		check_and_store_sat_violation4	;             NO  - continue checking for deco info
-check_and_store_sat_violation3:				;             YES - show GF
-	bsf		message_attention				; show attention sign
+check_and_store_sat_violation3:				;             YES - show saturation
+	bsf		message_attention				; show attention sign for saturation
 	incf	message_counter,F				; increase counter
-	goto	TFT_warning_sat					; show saturation (and return)
+	goto	TFT_warning_saturation			; show attention/warning message for saturation and return
 check_and_store_sat_violation4:				; check for deco info
 	btfss	divemode						; in dive mode?
 	return									; NO  - done, return
+ IFDEF _ccr_pscr
 	btfsc	bailout_mode					; YES - in bailout mode?
 	return									;       YES - done, return (deco zone flag is not updated when in bailout mode)
+ ENDIF
 	movff	char_O_deco_info,WREG			;       NO  - get the deco info vector
 	btfss	WREG,deco_zone					;             check if the deco zone flag is set
 	return									;             NO  - done, return
@@ -2983,10 +3374,10 @@
 	movff	opt_max_depth,WREG			; get depth limit
 	cpfsgt	depth_meter					; current depth > depth limit?
 	return								; NO
-	bsf		depth_limit_exceeded		; YES - set warning flag
+	bsf		depth_limit_exceeded		; YES - set flag for depth limit exceeded
 	incf	message_counter,F			;     - increase counter
-	bsf		message_warning				;     - set warning flag
-	goto	TFT_warning_depth			;     - show warning
+	bsf		message_warning				;     - show warning sign    for depth
+	goto	TFT_warning_depth			;     - show warning message for depth
 
 
 check_outside:
@@ -2994,10 +3385,10 @@
 	btfss	WREG,outside_warning_lock	; are we outside of the ZH-L16 model?
 	return								; NO  - done
 	incf	message_counter,F			; YES - increase counter
-	bsf		message_attention			;     - show attention sign
+	bsf		message_attention			;     - show attention sign for outside
 	btfsc	WREG,outside_warning		;     - are we outside the ZH-L16 model right now (-> warning)?
-	bsf		message_warning				;     - set warning flag
-	goto	TFT_warning_outside			;     - show outside-ZHL-model warning/attention (and return)
+	bsf		message_warning				;     - show warning sign for outside
+	goto	TFT_warning_outside			;     - show warning/attention message for outside and return
 
 
 	global	check_mbubbles
@@ -3009,22 +3400,49 @@
 	return								; NO  - done
 check_mbubble_att						; YES - attention level
 	incf	message_counter,F			; increase counter
-	bsf		message_attention			; show attention sign
+	bsf		message_attention			; show attention sign for micro bubbles
 	goto	TFT_warning_mbubbles		; show micro bubble attention (and return) - TFT_warning_mbubbles switches by itself between attention and warning
 check_mbubbles_warn:					; locked micro bubbles - warning level if at issue, attention level if locked
 	incf	message_counter,F			; increase counter
-	bsf		message_warning				; set warning flag
-	goto	TFT_warning_mbubbles		; show micro bubbles warning (and return)
+	bsf		message_warning				; show warning sign    for micro bubbles
+	goto	TFT_warning_mbubbles		; show warning message for micro bubbles (and return)
+
 
  IFDEF _cave_mode
+
 check_cavemode:
+	btfsc	backtrack_entire_full		; is the backtracking storage entirely used up?
+	bra		check_cavemode_full			; YES - turn dive, switch off cave mode and show warning message
+	btfsc	backtrack_almost_full		; NO  - backtracking storage almost full?
+	bra		check_cavemode_almost_full	;       YES - show attention message that cave mode will stop soon
+	btfss	alt_layout_active			;       NO  - alternative layout active?
+	bra		check_cavemode_info			;             NO  - show cave mode active info
+	return								;             YES - suppress info message
+
+check_cavemode_full:
+	btfss	backtrack_shutdown			; backtracking shut down already?
+	bsf		request_cave_off_turned		; NO  - request to switch cave mode off and to set the dive as turned
+	bsf		backtrack_shutdown			; remember shut down as been executed (anyhow)
 	incf	message_counter,F			; increase counter
-	btfsc	dive_turned					; dive turned?
-	goto	TFT_info_dive_turned		; YES - show info that dive is turned
-	btfsc	FLAG_backtrack_full			; NO  - is the backtracking storage full?
-	goto	TFT_warn_cave_shutdown		;       YES - show that cave mode has shut down
-	goto	TFT_info_cave_mode			;       NO  - show that cave mode is active
- ENDIF
+	btfsc	cave_mode					; has the cave mode been switched on again meanwhile?
+	goto	TFT_cave_shutdown_attention	; YES - show attention message for cave mode shutdown ands return
+	bsf		message_warning				; NO  - show warning   sign    for cave mode shutdown
+	goto	TFT_cave_shutdown_warning	;     - show warning   message for cave mode shutdown and return
+
+check_cavemode_almost_full:
+	btfss	cave_mode					; cave mode switched on?
+	return								; NO  - suppress message
+	incf	message_counter,F			; YES - increase counter
+	goto	TFT_cave_shutdown_attention	;     - show attention message that cave mode will shut down soon
+
+check_cavemode_info:
+	btfss	cave_mode					; cave mode switched on?
+	return								; NO  - do not show info
+	incf	message_counter,F			; YES - increase counter
+	goto	TFT_info_cave_mode			;     - show cave mode active info
+
+ ENDIF	; _cave_mode
+
 
 warn_agf:
 	incf	message_counter,F			; increase counter
@@ -3032,8 +3450,8 @@
 
 warn_fallback:
 	incf	message_counter,F			; increase counter
-	bsf		message_warning				; set warning flag
-	goto	TFT_warning_fallback		; show fallback warning (and return)
+	bsf		message_warning				; show warning sign    for fallback
+	goto	TFT_warning_fallback		; show warning message for fallback and return
 
 ;=============================================================================
 
@@ -3047,22 +3465,21 @@
 	bra		check_tr_messages2			;       NO  - skip
 	btfsc	WREG,int_not_avail_flag		;       SAC rate available?
 	bra		check_tr_messages2			;       NO  - continue with swap advice
-	bsf		message_attention			;       YES - show attention sign
+	bsf		message_attention			;       YES - show attention sign for SAC rate
 	movlw	index_pressures_SAC			;           - index of custom view with SAC rate
 	cpfseq	active_customview			;           - SAC rate shown right now?
 	bra		check_tr_messages1			;             NO  - show attention message
 	bra		check_tr_messages2			;             YES - do not show twice, continue with swap advice
 check_tr_messages1:
 	incf	message_counter,F			; increase counter
-	call	TFT_attention_sac			; show SAC attention
+	call	TFT_attention_sac			; show attention message for SAC rate
 check_tr_messages2:
 	movff	char_O_deco_info,WREG		; bank-safe copy of deco info vector
 	btfss	WREG,ind_double_switch		; swap tank flag set?
 	return								; NO
 	incf	message_counter,F			; YES - increase counter
-	bsf		message_advice				;     - show advice sign
-	goto	TFT_advice_switch			;     - show swap advice
-
+	bsf		message_advice				;     - show advice sign    for switching tanks
+	goto	TFT_advice_switch			;     - show advice message for switching tanks and return
 
 check_tr_functions:
 	clrf	xmitter_flags_mesg				; set all messages as not shown yet
@@ -3087,21 +3504,21 @@
 check_tr_functions_show_xmtr:
 	btfss	show_transmitter_attention		; shall show transmitter attention message?
 	bra		check_tr_functions_show_warn	; NO  - continue with pressure warning
-	bsf		message_attention				; YES - set flag for attention
+	bsf		message_attention				; YES - show attention sign for transmitter
 	incf	message_counter,F				;     - increase counter
 	call	TFT_attention_transmitter		;     - show transmitter attention message
 check_tr_functions_show_warn:
 	btfss	show_pres_warning				; shall show pressure warning?
 	bra		check_tr_functions_show_att		; NO  - continue with pressure attention
-	bsf		message_warning					; YES - set flag for warning
+	bsf		message_warning					; YES - show warning sign for pressure
 	incf	message_counter,F				;     - increase counter
-	goto	TFT_warning_pres_reading		;     - pressure reading warning message and done then
+	goto	TFT_warning_pres_reading		;     - show warning message for pressure reading and return
 check_tr_functions_show_att:
 	btfss	show_pres_attention				; shall show pressure attention?
 	return									; NO  - done
-	bsf		message_attention				; YES - set flag for attention
+	bsf		message_attention				; YES - show attention sign for pressure
 	incf	message_counter,F				;     - increase counter
-	goto	TFT_attention_pres_reading		;     - pressure reading warning message and done then
+	goto	TFT_attention_pres_reading		;     - show attention message for pressure reading and return
 
 check_tr_functions_helper1:
 	btfsc	WREG,char_transmitter_lost		; transmitter 1 lost?
@@ -3202,17 +3619,17 @@
 check_tr_functions_show_cv:
 	btfsc	pres_customview_shown			; is the pressure readings custom view not shown yet?
 	return									; NO  - already shown, done
-	bsf		pres_customview_shown			; YES - mark as shown
-	movlw	index_pressures_SAC-1			;     - custom view number one below pressure readings
-	movwf	active_customview				;     - set custom view number
-	bsf		request_next_custview			;     - initiate toggle to desired custom view -> pressure readings view will be shown
-	return									;     - done
+	btfsc	custom_view_locked				; YES - custom view locked?
+	return									;       YES - done
+	bsf		pres_customview_shown			;       NO  - mark as shown now
+	movlw	index_pressures_SAC				;           - get  custom view number of pressure readings
+	goto	dive_customview_show			;           - draw custom view and return
 
  ENDIF
 
 ;=============================================================================
 
-check_gas_needs_ascent:
+check_gas_needs:
 	banksel	int_O_gas_need_pres
 	movf	int_O_gas_need_pres+1,W		; get               high byte from pres need of 1st tank
 	iorwf	int_O_gas_need_pres+3,W		; inclusive or with high byte from pres need of 2nd tank
@@ -3223,34 +3640,38 @@
 	btfsc	WREG,int_invalid_flag		; check if invalid flag is set
 	return								; YES - no further checking required
 	btfsc	WREG,int_warning_flag		; NO  - check if any gas has a pres_need >= pres_fill
-	bra		check_gas_needs_ascent_warn	;       YES - generate a warning
+	bra		check_gas_needs_warn		;       YES - generate a warning
 	btfsc	WREG,int_attention_flag		;       NO  - check if any gas has a pres_need >= pres_fill * threshold
-	bra		check_gas_needs_ascent_att	;             YES - generate an attention
+	bra		check_gas_needs_att	;             YES - generate an attention
 	bcf		gas_needs_attention			;             NO  - clear flag for a new attention
 	bcf		gas_needs_warning			;                 - clear flag for a new warning
 	return								;                 - done
 
-check_gas_needs_ascent_warn:
-	bsf		message_warning				; set warning flag
+check_gas_needs_warn:
+	bsf		message_warning				; show warning sign for gas needs
 	incf	message_counter,F			; increase counter
 	btfsc	gas_needs_warning			; is it a new warning?
-	goto	TFT_warning_gas_needs_warn	; NO  - do not show the gas needs custom view again
-	bsf		gas_needs_warning			; YES - memorize it's an old now
-	movlw	index_gas_needs_ascent-1	;     - custom view number one below gas needs view
-	movwf	active_customview			;     - set custom view number
-	bsf		request_next_custview		;     - initiate toggle to desired custom view -> gas needs view will be shown
-	goto	TFT_warning_gas_needs_warn	;     - show warning message
-
-check_gas_needs_ascent_att:
-	bsf		message_attention			; set attention flag
+	bra		check_gas_needs_warn_1		; NO  - do not show the gas needs custom view again
+	btfsc	custom_view_locked			; YES - custom view locked?
+	bra		check_gas_needs_warn_1		;       YES - done
+	bsf		gas_needs_warning			;       NO  - memorize it's an old now
+	movlw	index_gas_needs_ascent		;           - get  custom view number of gas needs
+	call	dive_customview_show		;           - draw custom view
+check_gas_needs_warn_1:
+	goto	TFT_warning_gas_needs		;     - show warning message for gas needs and return
+
+check_gas_needs_att:
+	bsf		message_attention			; show attention sign for gas needs
 	incf	message_counter,F			; increase counter
 	btfsc	gas_needs_attention			; is it a new attention?
-	goto	TFT_warning_gas_needs_att	; NO  - do not show the gas needs custom view again
-	bsf		gas_needs_attention			; YES - memorize it's an old now
-	movlw	index_gas_needs_ascent-1	;     - custom view number one below gas needs view
-	movwf	active_customview			;     - set custom view number
-	bsf		request_next_custview		;     - initiate toggle to desired custom view -> gas needs view will be shown
-	goto	TFT_warning_gas_needs_att	;     - show attention message
+	bra		check_gas_needs_att_1		; NO  - do not show the gas needs custom view again
+	btfsc	custom_view_locked			; YES - custom view locked?
+	bra		check_gas_needs_att_1		;       YES - done
+	bsf		gas_needs_attention			;       NO  - memorize it's an old now
+	movlw	index_gas_needs_ascent		;           - get  custom view number of gas needs
+	call	dive_customview_show		;           - draw custom view
+check_gas_needs_att_1:
+	goto	TFT_attention_gas_needs		;     - show attention message for gas needs and return
 
 ;=============================================================================
 
@@ -3258,12 +3679,12 @@
 
 check_warn_sensors_disagree:
 	incf	message_counter,F			; increase counter
-	bsf		message_warning				; set warning flag
+	bsf		message_warning				; show warning sign for sensor disagree
 	btfsc	o2_sensors_warning			; is it a new warning?
 	goto	TFT_warning_sensor_disagree	; NO  - don't show sensor custom view again, just show sensor disagree warning and return
 	bsf		o2_sensors_warning			; YES - memorize it's an old warning now
 	call	show_sensors_custview		;     - show sensors custom view
-	goto	TFT_warning_sensor_disagree	;     - show sensor disagree warning and return
+	goto	TFT_warning_sensor_disagree	;     - show warning message for sensor disagree and return
 
  ENDIF
 
@@ -3287,17 +3708,19 @@
 check_OC_gas_avail:
 	tstfsz	best_gas_number				; is a breathable OC (bailout) gas available?
 	return								; YES (>0) - a breathable gas is available
-	btfsc	bailout_mode				; NO  (=0) - in bailout?
-	return								;            YES - suppress warning
-	incf	message_counter,F			;            NO  - increase counter
-	bsf		message_warning				;                - set attention flag
-	goto	TFT_warning_no_BO_gas		;                - show waring (and return)
+ IFDEF _ccr_pscr
+	btfsc	bailout_mode				; in bailout?
+	return								; YES - suppress warning
+ ENDIF
+	incf	message_counter,F			; increase counter
+	bsf		message_warning				; show warning sign    for no bailout gas
+	goto	TFT_warning_no_BO_gas		; show warning message for no bailout gas and return
 
 
 advice_gas_change:
 	bsf		message_advice				; show advice sign
 	incf	message_counter,F			; increase counter
-	goto	TFT_advice_gas_change
+	goto	TFT_advice_gas_change		; show advice (and return)
 
 
 	global	restart_deco_engine
@@ -3309,15 +3732,20 @@
 restart_deco_engine_wo_ceiling:
 	banksel	char_O_deco_gas								; switch to bank where the shared "_O_" variables are stored
 	bsf		char_O_deco_gas+0,char_invalid_flag			; invalidate deco data (stop table data)
-	bsf		int_O_TTS_norm+1,int_invalid_flag			; invalidate ascent time (normal plan)
+	bsf		int_O_NDL_norm+1,int_invalid_flag			; invalidate NDL time (normal plan)
+	bsf		int_O_TTS_norm+1,int_invalid_flag			; invalidate TTS time (normal plan)
+	bsf		int_O_TST_norm+1,int_invalid_flag			; invalidate TST time (normal plan)
 	bsf		int_O_CNS_norm+1,int_invalid_flag			; invalidate CNS at end of dive in normal plan
-														; restart deco engine:
-	bcf		char_O_deco_status,DECO_COMPLETED_NORM		; eventually clear flag stating completion of normal plan
-	bsf		char_O_deco_status,DECO_COMPLETED_ALT		; fake we came from alternative plan to force normal plan to be done next
+
+restart_deco_engine_wo_norm:
+	banksel	common										; bank to bank common
+	bsf		request_restart_engine						; request restart of the deco engine
 
 inval_alternative_plan_data:
 	banksel	int_O_TTS_alt								; switch to bank where the shared "_O_" variables are stored
-	bsf		int_O_TTS_alt+1,int_invalid_flag			; invalidate ascent time (alternative plan)
+	bsf		int_O_NDL_alt+1,int_invalid_flag			; invalidate NDL time (alternative plan)
+	bsf		int_O_TTS_alt+1,int_invalid_flag			; invalidate TTS time (alternative plan)
+	bsf		int_O_TST_alt+1,int_invalid_flag			; invalidate TST time (alternative plan)
 	bsf		int_O_CNS_alt+1,int_invalid_flag			; invalidate CNS at end of dive in alternative plan
 	bsf		int_O_gas_need_pres+1,int_invalid_flag		; invalidate ascent gas needs
 
@@ -3336,13 +3764,17 @@
 ;
 	global	do_demo_divemode
 do_demo_divemode:
+	call	TFT_ClearScreen					; blank screen
+
+	; leaving menu mode, so have option values in EEPROM up-to-date
+	btfsc	options_changed					; do the options need to be stored to EEPROM ?
+	call	option_check_and_store_all		; YES - check and store all option values in EEPROM
+	bcf		options_changed					; clear flag
 
 	; +++ COMMENT OUT FOR TESTING PURPOSE ONLY  !!! +++
-	bsf		simulatormode					; will restore tissue pressures and CNS value after simulator use
+	bsf		simulatormode					; restore tissue pressures and CNS value after finishing simulator use
 	; +++ DO NOT COMMENT OUT IN OPERATIONAL USE !!! +++
 
-	call	TFT_ClearScreen					; blank screen
-	call	option_save_all					; save all settings into EEPROM before starting simulation
 	call	deco_push_tissues_to_vault		; back-up the tissue pressures (C-code)
 	banksel	common							; back to bank common
 
--- a/src/divemode.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/divemode.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemode.inc                         combined next generation V3.03.5
+;   File divemode.inc                         combined next generation V3.08.5
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -365,7 +365,7 @@
 #DEFINE dm_custom_ppDil_column					.2								;   2
 
 
-;******* Custom View: PSCR Info *******
+;******* Custom View: pSCR Info *******
 
 #DEFINE dm_custom_pscr_title_row				dm_customview_row+.1			; 102
 #DEFINE dm_custom_pscr_row						dm_customview_row+.18			; 119
@@ -373,6 +373,20 @@
 #DEFINE dm_custom_pscr_ratio_column				.105							; 105
 
 
+;******* Custom View: cave TTS *******
+
+#DEFINE dm_custom_cave_title_row				dm_customview_row+.1			; 102
+#DEFINE dm_custom_cave_title_column1			.2								;   2
+#DEFINE dm_custom_cave_title_column2			.64								;  64
+#DEFINE dm_custom_cave_title_column3			.118							; 118
+
+#DEFINE dm_custom_cave_data_row					dm_customview_row+.16			; 117
+#DEFINE dm_custom_cave_data_column1				.8								;   8
+#DEFINE dm_custom_cave_data_column2				.60								;  60
+#DEFINE dm_custom_cave_data_column3				.114							; 114
+
+
+
 ; II. end of the custom content row (101-163)
 
 ; 1px space between the 2nd and 3rd content rows
--- a/src/eeprom_rs232.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/eeprom_rs232.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File eeprom_rs232.asm                     combined next generation V3.06.2
+;   File eeprom_rs232.asm                     combined next generation V3.08.8
 ;
 ;   Internal EEPROM, RS232
 ;
@@ -13,51 +13,27 @@
 #include "wait.inc"
 #include "shared_definitions.h"
 #include "rtc.inc"
+#include "external_flash.inc"
+
+#DEFINE INSIDE_EEPROM_RS232
+#include "eeprom_rs232.inc"
+
 
 	extern	lt2942_charge_done
 
 ;-----------------------------------------------------------------------------
-; Macros
+;
+;			for EEPROM Macros and Memory Map, see eeprom_rs232.inc
+;
+;-----------------------------------------------------------------------------
 
-write_int_eeprom	macro	eeprom_address
-	movlw	eeprom_address
-	call	write_int_eeprom_1
-	endm
+ee_rs232	CODE
 
-read_int_eeprom		macro	eeprom_address
-	movlw	eeprom_address
-	call	read_int_eeprom_1
-	endm
+;=============================================================================
+;   EEPROM Functions
+;=============================================================================
 
 ;-----------------------------------------------------------------------------
-; Reserved memory locations in EEPROM
-
-eeprom		code	0xF00000+0x10		; skip SERIAL number - it should not be overwritten
-
-	global	eeprom_serial_save
-	global	eeprom_opt_backup
-
-eeprom_serial_save	res 2
-eeprom_opt_backup	res 0x3E
-
-;-----------------------------------------------------------------------------
-
-ee_rs232		CODE
-
-;=============================================================================
-
-	global	write_int_eeprom_1
-write_int_eeprom_1:
-	movwf	EEADR
-	bra		write_eeprom				; writes and "returns" after write
-
-
-	global	read_int_eeprom_1
-read_int_eeprom_1:
-	movwf	EEADR
-	bra		read_eeprom					; reads and "returns" after write
-
-;=============================================================================
 ; read from internal EEPROM
 ;
 ; Input:   EEADRH:EEADR = EEPROM address
@@ -66,12 +42,12 @@
 ;
 	global	read_eeprom
 read_eeprom:
-	bcf		EECON1,EEPGD
-	bcf		EECON1,CFGS
-	bsf		EECON1,RD
+	bcf		EECON1,EEPGD					;
+	bcf		EECON1,CFGS						;
+	bsf		EECON1,RD						;
 	return
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; write into internal EEPROM
 ;
 ; Input:   EEADRH:EEADR = EEPROM address
@@ -80,24 +56,173 @@
 ;
 	global	write_eeprom
 write_eeprom:
-	bcf		EECON1,EEPGD
-	bcf		EECON1,CFGS
-	bsf		EECON1,WREN
+	bcf		EECON1,EEPGD					;
+	bcf		EECON1,CFGS						;
+	bsf		EECON1,WREN						;
+	bcf		INTCON,GIE						; disable interrupts for the next 5 instructions
+	movlw	0x55							; unlock sequence
+	movwf	EECON2							; ...
+	movlw	0xAA							; ...
+	movwf	EECON2							; ...
+	bsf		EECON1,WR						; start write operation
+write_eeprom_loop:
+	btfsc	EECON1,WR						; write completed?
+	bra		write_eeprom_loop				; NO - loop waiting
+	bcf		EECON1,WREN						;
+	bsf		INTCON,GIE						; ...but the flag for the ISR routines were still set, so they will interrupt now!
+	return
+
+;-----------------------------------------------------------------------------
+; these 2 functions are meant to be used through the macros, see eeprom_rs232!
+;
+	global	eeprom_read_common
+eeprom_read_common:
+	movwf	eeprom_loop						; initialize loop counter
+eeprom_read_common_loop:
+	rcall	read_eeprom						; execute read
+	movff	EEDATA,POSTINC1					; copy byte  from EEPROM data register to memory
+	incf	EEADR,F							; advance to next EEPROM cell
+	decfsz	eeprom_loop,F					; decrement loop counter, all done?
+	bra		eeprom_read_common_loop			; NO  - loop
+	return									; YES - done
 
-	bcf		INTCON,GIE					; disable interrupts for the next 5 instructions
-	movlw	0x55
-	movwf	EECON2
-	movlw	0xAA
-	movwf	EECON2
-	bsf		EECON1,WR
+	global	eeprom_write_common
+eeprom_write_common:
+	movwf	eeprom_loop						; initialize loop counter
+eeprom_write_common_loop:
+	movff	POSTINC1,EEDATA					; copy byte from memory to EEPROM data register
+	rcall	write_eeprom					; execute write
+	incf	EEADR,F							; advance to next EEPROM cell
+	decfsz	eeprom_loop,F					; decrement loop counter, all done?
+	bra		eeprom_write_common_loop		; NO  - loop
+	return									; YES - done
+
+;-----------------------------------------------------------------------------
+; REad OSTC serial number
+;
+	global	eeprom_serial_number_read
+eeprom_serial_number_read:
+	EEPROM_II_READ eeprom_ostc_serial,mpr
+	return
 
-write_eep2:
-	btfsc	EECON1,WR
-	bra		write_eep2					; wait about 4ms...
-	bcf		EECON1,WREN
-	bsf		INTCON,GIE					; ...but the flag for the ISR routines were still set, so they will interrupt now!
+;-----------------------------------------------------------------------------
+; Read and write dive number offset
+;
+	global	eeprom_log_offset_read
+eeprom_log_offset_read:
+	EEPROM_II_READ	eeprom_log_offset,mpr
+	return
+
+	global	eeprom_log_offset_write
+eeprom_log_offset_write:
+	EEPROM_II_WRITE mpr,eeprom_log_offset
+	return
+
+
+;-----------------------------------------------------------------------------
+; Read and write total number of dives
+;
+	global	eeprom_total_dives_read
+eeprom_total_dives_read:
+	EEPROM_II_READ	eeprom_num_dives,mpr
+	return
+
+	global	eeprom_total_dives_write
+eeprom_total_dives_write:
+	EEPROM_II_WRITE mpr,eeprom_num_dives
 	return
 
+
+;-----------------------------------------------------------------------------
+; Read and write the battery gauge and type
+;
+	global	eeprom_battery_gauge_read
+eeprom_battery_gauge_read:
+	; retrieve battery gauge from EEPROM 0x07-0x0C
+	bsf		block_battery_gauge								; suspend ISR from accessing the battery gauge
+	EEPROM_CC_READ eeprom_battery_type, battery_type		; 1 byte read from EEPROM
+	EEPROM_RR_READ eeprom_battery_gauge,battery_gauge,.6	; 6 byte read from EEPROM
+	bcf		block_battery_gauge								; allow ISR to access the battery gauge again
+	return
+
+	global	eeprom_battery_gauge_write
+eeprom_battery_gauge_write:
+	bsf		block_battery_gauge								; suspend ISR from accessing the battery gauge
+	EEPROM_CC_WRITE battery_type, eeprom_battery_type		; 1 byte write to EEPROM
+update_battery_gauge:
+	EEPROM_RR_WRITE battery_gauge,eeprom_battery_gauge,.6	; 6 byte write to EEPROM
+	bcf		block_battery_gauge								; allow ISR to access the battery gauge again
+	return
+
+
+;-----------------------------------------------------------------------------
+; Read and write the deco status
+;
+	global	eeprom_deco_data_read
+eeprom_deco_data_read:
+
+	btfsc	RCON,POR												; was there a power outage ?
+	bra		eeprom_deco_data_read_1									; NO  - RTC is up-to-date
+
+	EEPROM_RR_READ eeprom_deco_data_timestamp,rtc_latched_year,.6	;   6 byte read from EEPROM
+	call	rtc_set_rtc												;     recover RTC to last known time & date
+
+eeprom_deco_data_read_1:
+
+	; restore surface interval
+	EEPROM_II_READ eeprom_deco_data_surfinterval,mpr				;   2 byte read from EEPROM
+	SMOVII	mpr,surface_interval_mins								;     ISR-safe copy of surface interval
+
+	; bank 3: restore desaturation status
+	EEPROM_RR_READ eeprom_deco_data_bank3,0x300,.9					;   9 byte read from EEPROM
+
+	; bank 5: restore CNS
+	EEPROM_RR_READ eeprom_deco_data_bank5,0x500,.4					;   4 byte read from EEPROM
+
+	; bank 7: restore tissue pressures
+	EEPROM_RR_READ eeprom_deco_data_bank7,0x700,.128				; 128 byte read from EEPROM
+
+	return															;   done
+
+
+	global	eeprom_deco_data_write
+eeprom_deco_data_write:
+
+	; invalidate current data in vault
+	movlw	DECO_DATA_INVALID_TOKEN									;     deco data invalid token
+	EEPROM_CC_WRITE WREG,eeprom_deco_data_validity					;   1 byte write to EEPROM
+
+	; store vault version
+	movlw	eeprom_vault_version									;     deco data format version
+	EEPROM_CC_WRITE WREG,eeprom_deco_data_version					;   1 byte write to EEPROM
+
+	; store date/time
+	SMOVSS	rtc_year,rtc_latched_year								;     ISR-safe 6 byte copy of date and time
+	EEPROM_RR_WRITE rtc_latched_year,eeprom_deco_data_timestamp,.6	;   6 byte write to EEPROM
+
+	; store surface interval
+	SMOVII	surface_interval_mins,mpr								;     ISR-safe copy of surface interval
+	EEPROM_II_WRITE mpr,eeprom_deco_data_surfinterval				;   2 byte write to EEPROM
+
+	; bank 3: store desaturation status
+	EEPROM_RR_WRITE 0x300,eeprom_deco_data_bank3,.9					;   9 byte write to EEPROM
+
+	; bank 5: store CNS
+	EEPROM_RR_WRITE 0x500,eeprom_deco_data_bank5,.4					;   4 byte write to EEPROM
+
+	; bank 7: store tissue pressures
+	EEPROM_RR_WRITE 0x700,eeprom_deco_data_bank7,.128				; 128 byte write to EEPROM
+
+	; indicate new valid data in vault
+	movlw	DECO_DATA_VALID_TOKEN									;     deco data valid token
+	EEPROM_CC_WRITE WREG,eeprom_deco_data_validity					;   1 byte write to EEPROM
+
+	return															;   done
+
+
+
+;=============================================================================
+;   RS232 Functions
 ;=============================================================================
 
 	global	disable_ir_s8
@@ -139,34 +264,22 @@
 
 enable_s8:
 	banksel	TXSTA2						; select bank for IO register access
-	clrf	TXSTA2
-	clrf	RCSTA2
+	clrf	TXSTA2						; reset UART 2 TX function
+	clrf	RCSTA2						; reset UART 2 RX function
 	banksel	common						; back to bank common
-	; Check for Digital/Analog
-	bsf		s8_npower					; power-down S8 HUD
-	WAITMS	d'2'						; very short delay
-	bsf		mcp_power					; power-up instrumentation amp
-	btfss	mcp_power
-	bra		$-4
+
+	bsf		mcp_power					; power-up instrumentation amp (for analog AND digital)
+	btfss	mcp_power					; power-up completed?
+	bra		$-4							; NO - loop
 
-	; It may be digital, check for voltage when isolator is powered
-	bcf		s8_npower					; power S8 HUD
-	WAITMS	d'1'						; wait 1 ms
-	btfsc	PORTG,2						; RX2=1?
-	bra		enable_s8_2					; YES - digital
+	; toggle for digital/analog
+	TSTOSS	opt_s8_mode					; =0: analog, =1: digital RS232
+	bra		enable_s8_analog			; -> analog
+
+	; configure S8 digital interface
+	bcf		s8_npower					; power S8 HUD (inverted via P-MOS transistor)
 	WAITMS	d'30'						; NO  - wait 30 ms
-	btfsc	PORTG,2						;     - RX2=1?
-	bra		enable_s8_2					;       YES - digital
-	;bra	enable_s8_analog			;       NO  - not found, set to analog (fail-safe)
-
-enable_s8_analog:
-	; S8 analog interface
-	bsf		s8_npower					; power-down S8 HUD
-	bcf		s8_digital_avail			; digital S8 interface not available
-	return
-
-enable_s8_2:							; configure S8 digital interface
-	banksel BAUDCON2					; select bank for IO register access
+	banksel	BAUDCON2					; select bank for IO register access
 	movlw	b'00000000'					; BRG16=0, normal for S8
 	movwf	BAUDCON2
 	movlw	b'00100000'					; BRGH=0, SYNC=0
@@ -176,330 +289,137 @@
 	movlw	b'10010000'
 	movwf	RCSTA2
 	banksel	common						; back to bank common
+	bsf		PIE3,RC2IE					; enable RC2 INT
 	bsf		s8_digital_avail			; digital S8 interface available
 	return
 
-;=============================================================================
+enable_s8_analog:
+	; S8 analog interface
+	bcf		PIE3,RC2IE					; disable RC2 INT
+	bsf		s8_npower					; power-down S8 HUD
+	bcf		s8_digital_avail			; digital S8 interface not available
+	return
+
+
+	global	ir_s8_wait_tx
+ir_s8_wait_tx:
+	banksel	TXSTA2						; select bank for IO register access
+rs232_wait_tx2_loop:
+	btfss	TXSTA2,TRMT					; RS232 busy?
+	bra		rs232_wait_tx2_loop			; YES - wait...
+	banksel	common						; NO  - back to bank common
+	return								;     - done
+
+;-----------------------------------------------------------------------------
 
 	global	enable_rs232
 enable_rs232:
 	call	request_speed_normal		; request CPU speed change to normal speed
 enable_rs232_1:
 	btfss	speed_is_normal				; speed = normal?
-	bra		enable_rs232_1				; NO - wait for ISR to adjust speed
-	bcf		PORTE,0						; start comm
-	bsf		PORTJ,2						; /Reset (for very old OSTC sport)
-	;initialize serial port1 (TRISC6/7)
-	movlw	b'00100100'					; BRGH=1, SYNC=0
-	movwf	TXSTA1
-	movlw	b'10010000'
-	movwf	RCSTA1
-	return
+	bra		enable_rs232_1				; NO  - loop waiting for ISR to have adjusted the speed
+	bcf		PORTE,0						; YES - switch port to comm
+	bsf		PORTJ,2						;     - /Reset (required for very old OSTC sport)
+	movlw	b'00100100'					;     - TX configuration: TX enabled, async, high speed
+	movwf	TXSTA1						;     - ...
+	movlw	b'10010000'					;     - RX configuration: port enabled, RX enabled
+	movwf	RCSTA1						;     - ...
+	movlw	HIGH(.65536-rx_timeout*.32)	;     - define TMR5H initialization value for RX timeout
+	movwf	rx_timoeut_tmr5h_load		;     - store for later use
+	return								;     - done
 
 
 	global	disable_rs232
 disable_rs232:
-	clrf	RCSTA1
-	clrf	TXSTA1						; UART disable
-	bcf		PORTC,6						; TX hard to GND
+	clrf	RCSTA1						; disable RX
+	clrf	TXSTA1						; disable TX
+	bcf		PORTC,6						; switch TX pin hard to GND
 	bsf		PORTE,0						; stop comm
-	bcf		PORTJ,2						; /Reset (for very old OSTC sport)
-	return
-
-
-	global	rs232_wait_tx
-rs232_wait_tx:
-	btfss	TXSTA1,TRMT					; RS232 busy?
-	bra		rs232_wait_tx				; YES - wait...
-
-	btfss	ble_available				; ble available?
-	return								; NO - done
-
-	btfsc	NRTS						; wait for Bluetooth module
-	bra		rs232_wait_tx				; YES - wait...
-	return								; done
-
-
-	global	rs232_wait_tx2
-rs232_wait_tx2:
-	banksel	TXSTA2						; select bank for IO register access
-rs232_wait_tx2_loop:
-	btfss	TXSTA2,TRMT					; RS232 busy?
-	bra		rs232_wait_tx2_loop			; YES - wait...
-	banksel	common						; back to bank common
-	return								; done
-
-
-	global	rs232_get_byte
-rs232_get_byte:
-	bcf		rs232_rx_timeout			; clear timeout flag
-										; set timeout timer to approx. 400 ms:
-	clrf	uart_timeout_timer+0		; set low   byte of timeout timer to 0
-	clrf	uart_timeout_timer+1		; set high  byte of timeout timer to 0
-										; set upper byte of timeout timer to 10 without using WREG:
-	clrf	uart_timeout_timer+2		; first clear to 0, then...
-	bsf		uart_timeout_timer+2,1		; set bit 1 (value 2),
-	bsf		uart_timeout_timer+2,3		; and bit 3 (value 8).
-
-rs232_get_byte_loop:
-	btfsc	PIR1,RCIF					; received a data byte?
-	return								; YES - done
-	decfsz	uart_timeout_timer+0,F		; NO  - decrement low byte of timer, became zero?
-	bra		rs232_get_byte_loop			;       NO  - loop
-	decfsz	uart_timeout_timer+1,F		;       YES - decrement high byte of timer, became zero?
-	bra		rs232_get_byte_loop			;             NO  - loop
-	decfsz	uart_timeout_timer+2,F		;             YES - decrement upper byte of timer, became zero?
-	bra		rs232_get_byte_loop			;                   NO  - loop
-	bsf		rs232_rx_timeout			;                   YES - set timeout flag
-	bcf		RCSTA1,CREN					;                       - clear receiver status
-	bsf		RCSTA1,CREN					;                       - ...
-	return								;                       - and return anyway
-
-;=============================================================================
-
-	global	do_logoffset_common_write
-do_logoffset_common_write:
-	movff	lo,EEDATA
-	write_int_eeprom 0x0D
-	movff	hi,EEDATA
-	write_int_eeprom 0x0E
-	return
-
-	global	do_logoffset_common_read
-do_logoffset_common_read:
-	clrf	EEADRH
-	read_int_eeprom 0x0D
-	movff	EEDATA,lo
-	read_int_eeprom 0x0E
-	movff	EEDATA,hi
-	return
-
-;=============================================================================
-
-	global	update_battery_registers
-update_battery_registers:
-	; save battery gauge to EEPROM 0x07-0x0C
-	bsf		block_battery_gauge			; suspend ISR from accessing the battery gauge
-	clrf	EEADRH
-	movff	battery_gauge+0,EEDATA
-	write_int_eeprom 0x07
-	movff	battery_gauge+1,EEDATA
-	write_int_eeprom 0x08
-	movff	battery_gauge+2,EEDATA
-	write_int_eeprom 0x09
-	movff	battery_gauge+3,EEDATA
-	write_int_eeprom 0x0A
-	movff	battery_gauge+4,EEDATA
-	write_int_eeprom 0x0B
-	movff	battery_gauge+5,EEDATA
-	write_int_eeprom 0x0C
-	movff	battery_type,EEDATA			; =0:1.5V, =1:3.6V Saft, =2:LiIon 3.7V/0.8Ah, =3:LiIon 3.7V/3.1Ah, =4: LiIon 3.7V/2.3Ah
-	write_int_eeprom 0x0F
-	bcf		block_battery_gauge			; allow ISR to access the battery gauge again
+	bcf		PORTJ,2						; /Reset (required for very old OSTC sport)
 	return
 
 
-	global	retrieve_battery_registers
-retrieve_battery_registers:
-	; retrieve battery gauge from EEPROM 0x07-0x0C
-	bsf		block_battery_gauge			; suspend ISR from accessing the battery gauge
-	clrf	EEADRH
-	read_int_eeprom 0x07
-	movff	EEDATA,battery_gauge+0
-	read_int_eeprom 0x08
-	movff	EEDATA,battery_gauge+1
-	read_int_eeprom 0x09
-	movff	EEDATA,battery_gauge+2
-	read_int_eeprom 0x0A
-	movff	EEDATA,battery_gauge+3
-	read_int_eeprom 0x0B
-	movff	EEDATA,battery_gauge+4
-	read_int_eeprom 0x0C
-	movff	EEDATA,battery_gauge+5
-	read_int_eeprom 0x0F
-	movff	EEDATA,battery_type			; =0:1.5V, =1:3,6V Saft, =2:LiIon 3,7V/0.8Ah, =3:LiIon 3,7V/3.1Ah, =4: LiIon 3,7V/2.3Ah
-	bcf		block_battery_gauge			; allow ISR to access the battery gauge again
-	return
+	global	rs232_wait_tx				; ++++ do not touch WREG here! ++++
+rs232_wait_tx:
+	btfss	TXSTA1,TRMT					; last byte completely shifted out on TX pin?
+	bra		rs232_wait_tx				; NO  - wait...
+	btfss	ble_available				; YES - OSTC running with Bluetooth?
+	return								;       NO  - done
+	btfsc	NRTS						;       YES - Bluetooth module also completed TX?
+	bra		rs232_wait_tx				;             NO  - wait...
+	return								;             YES - done
 
-;=============================================================================
-
-	global	vault_decodata_into_eeprom
-vault_decodata_into_eeprom:
-	; Vault in EEPROM 512...1023
-	; Write 0xAA at 512 to indicate valid data in vault
-	; Store last time/date
-	; Store 0x700 to 0x780 (pres_tissue_N2 and pres_tissue_He)
-	movlw	HIGH .512						; =2
-	movwf	EEADRH							; set EEPROM address, high byte
-
-	; indicate valid data in vault
-	movlw	0xAA
-	movwf	EEDATA
-	write_int_eeprom .0
 
-	; store date/time
-	SMOVSS	rtc_year,rtc_latched_year		; ISR-safe 6 byte copy of date and time
-	movff	rtc_latched_year+0,EEDATA
-	write_int_eeprom .1
-	movff	rtc_latched_year+1,EEDATA
-	write_int_eeprom .2
-	movff	rtc_latched_year+2,EEDATA
-	write_int_eeprom .3
-	movff	rtc_latched_year+3,EEDATA
-	write_int_eeprom .4
-	movff	rtc_latched_year+4,EEDATA
-	write_int_eeprom .5
-	movff	rtc_latched_year+5,EEDATA
-	write_int_eeprom .6
-
-	movff	int_O_CNS_current+0,EEDATA		; get current CNS, low  byte
-	write_int_eeprom .7						; store value
-	movff	int_O_CNS_current+1,EEDATA		; get current CNS, high byte
-	write_int_eeprom .8						; store value
-
-	movff	int_O_desaturation_time+0,EEDATA; get desaturation time, low  byte
-	write_int_eeprom .9						; store value
-	movff	int_O_desaturation_time+1,EEDATA; get desaturation time, high byte
-	write_int_eeprom .10					; store value
+										; ++++ make this code as fast as possible! ++++
+	global	rs232_get_byte				; ++++       do not touch WREG here!       ++++
+rs232_get_byte:
+	bcf		rs232_rx_timeout			; clear timeout flag
+	btfsc	PIR1,RCIF					; received a data byte? (bit is set on RX complete and reset on reading RCREG1)
+	return								; YES - done, received a byte (fast path)
+	movff	rx_timoeut_tmr5h_load,TMR5H	;     - load TMR5 high with timeout value
+	clrf	TMR5L						;     - load TMR5 low  with a zero, writing low starts the timer
+	bcf		PIR5,TMR5IF					;     - clear timer overflow flag
+rs232_get_byte_loop:
+	btfsc	PIR1,RCIF					; received a data byte?
+	return								; YES - done, received a byte
+	btfss	PIR5,TMR5IF					; NO  - timer overflow (timeout)?
+	bra		rs232_get_byte_loop			;       NO  - continue looping
+	;bra	rs232_rx_get_timeout		;       YES - give up
 
-	SMOVII	surface_interval_mins,mpr		; ISR-safe copy of surface interval
-	movff	mpr+0,EEDATA					; get surface interval, low  byte
-	write_int_eeprom .11					; store value
-	movff	mpr+1,EEDATA					; get surface interval, high byte
-	write_int_eeprom .12					; store value
-
-	movff	int_O_lead_supersat+0,EEDATA	; get leading tissue's supersaturation, value is limited to 255 so only the lower byte is used for the value
-	write_int_eeprom .13
-
-	movff	int_O_nofly_time+0,EEDATA		; get time, low  byte
-	write_int_eeprom .14					; store value
-	movff	int_O_nofly_time+1,EEDATA		; get time, high byte
-	write_int_eeprom .15					; store value
-
-	; tissue data from 16 to 144
-	movlw	.16
-	movwf	EEADR
-	movlw	.128							; 2 * 16 floats = 2*16*4 byte = 128 byte
-	movwf	lo
-	lfsr	FSR1,0x700						; pres_tissue_N2+0
-vault_decodata_into_eeprom2:
-	movff	POSTINC1,EEDATA
-	call	write_eeprom					; EEDATA into EEPROM@EEADR
-	incf	EEADR,F
-	decfsz	lo,F							; all done?
-	bra		vault_decodata_into_eeprom2		; NO  - loop
-	clrf	EEADRH							; YES - reset EEPROM pointer
-	return									;     - done
+rs232_rx_get_timeout:
+	bsf		rs232_rx_timeout			; set timeout flag
+	bcf		RCSTA1,CREN					; clear receiver status by toggling CREN
+	bsf		RCSTA1,CREN					; ...
+	return								; done, given up
 
 
-	global	restore_decodata_from_eeprom
-restore_decodata_from_eeprom:
-	movlw	LOW  .512						; =0
-	movwf	EEADR							; set EEPROM address, low  byte
-	movlw	HIGH .512						; =2
-	movwf	EEADRH							; set EEPROM address, high byte
-
-	; restore date and time
-	read_int_eeprom .1
-	movff	EEDATA,rtc_latched_year
-	read_int_eeprom .2
-	movff	EEDATA,rtc_latched_month
-	read_int_eeprom .3
-	movff	EEDATA,rtc_latched_day
-	read_int_eeprom .4
-	movff	EEDATA,rtc_latched_hour
-	read_int_eeprom .5
-	movff	EEDATA,rtc_latched_mins
-	read_int_eeprom .6
-	movff	EEDATA,rtc_latched_secs
-	call	rtc_set_rtc						; write time and date to RTC module
+;-----------------------------------------------------------------------------
+; Send and Receive functions to be used through the macros
 
-	read_int_eeprom .7						; read CNS%, low  byte
-	movff	EEDATA,int_O_CNS_current+0		; restore value
-	read_int_eeprom .8						; read CNS%, high byte
-	movff	EEDATA,int_O_CNS_current+1		; restore value
-
-	read_int_eeprom .9						; read desaturation time, low  byte
-	movff	EEDATA,int_O_desaturation_time+0; restore value
-	read_int_eeprom .10						; read desaturation time, high byte
-	movff	EEDATA,int_O_desaturation_time+1; restore value
+; send a range of 1-256 bytes from memory to the RS232 interface
+;
+	global	serial_tx_ram
+serial_tx_ram:
+	movwf	eeprom_loop					; initialize loop counter (eeprom variable used here)
+serial_tx_ram_loop:
+	rcall	rs232_wait_tx				; wait for completion of last transmit
+	movff	POSTINC2,TXREG1				; send a byte from memory to serial
+	decfsz	eeprom_loop,F				; decrement loop counter, became zero?
+	bra		serial_tx_ram_loop			; NO  - loop
+	return								; YES - done
 
-	read_int_eeprom .11						; read surface interval, low  byte
-	movff	EEDATA,mpr+0					; cache value in mpr
-	read_int_eeprom .12						; read surface interval, high byte
-	movff	EEDATA,mpr+1					; cache value in mpr
-	SMOVII	mpr,surface_interval_mins		; ISR-safe copy-back of surface interval
-
-	read_int_eeprom .13						; read leading tissue's supersaturation
-	movff	EEDATA,int_O_lead_supersat+0	; restore value
-
-	read_int_eeprom .14						; read no-fly/no-altitude time, low  byte
-	movff	EEDATA,int_O_nofly_time+0		; restore value
-	read_int_eeprom .15						; read no-fly/no-altitude time, high byte
-	movff	EEDATA,int_O_nofly_time+1		; restore value
 
-	; tissue data from 16 to 144
-	movlw	.16
-	movwf	EEADR
-	movlw	.128							; 2 * 16 floats = 2*16*4 byte = 128 byte
-	movwf	lo
-	lfsr	FSR1,0x700						; pres_tissue_N2+0
-restore_decodata_from_eeprom2:
-	call	read_eeprom						; EEPROM@EEADR into EEDATA
-	movff	EEDATA,POSTINC1
-	incf	EEADR,F
-	decfsz	lo,F							; all done?
-	bra		restore_decodata_from_eeprom2	; NO  - loop
-	clrf	EEADRH							; YES - revert EEPROM high address pointer to default
-	return									;     - done
-
-;=============================================================================
-
-	global	reset_battery_pointer			; called from comm and menu tree
-	global	reset_battery_internal_only
-reset_battery_pointer:						; reset battery pointer 0x07-0x0C and battery gauge
-	btfsc	battery_gauge_available			; something to reset?
-	call	lt2942_charge_done				; YES - reset accumulating registers to 0xFFFF
-reset_battery_internal_only:
-	clrf	EEADRH
-	clrf	EEDATA							; delete to zero
-	write_int_eeprom 0x07
-	write_int_eeprom 0x08
-	write_int_eeprom 0x09
-	write_int_eeprom 0x0A
-	write_int_eeprom 0x0B
-	write_int_eeprom 0x0C
+; receive a range of 1-256 byte from the RS232 interface and write them to memory
+;
+	global	serial_rx_stream_ram		; ++++ make this code as fast as possible! ++++
+serial_rx_stream_ram:
+	movwf	eeprom_loop					; initialize loop counter (eeprom variable used here)
+serial_rx_stream_ram_loop_1:
+	btfss	PIR1,RCIF					; received a data byte? (bit is set on RX complete and reset on reading RCREG1)
+	bra		serial_rx_stream_ram_tmr	; NO  - enter loop with timeout
+	movff	RCREG1,POSTINC2				; YES - copy received byte to memory
+	decfsz	eeprom_loop,F				;     - decrement loop counter, became zero?
+	bra		serial_rx_stream_ram_loop_1	;       NO  - loop
+	bcf		rs232_rx_timeout			;       YES - clear timeout flag
+	return								;           - all bytes received, done
+serial_rx_stream_ram_tmr:
+	movff	rx_timoeut_tmr5h_load,TMR5H	; load TMR5 high with timeout value
+	clrf	TMR5L						; load TMR5 low  with a zero, writing low starts the timer
+	bcf		PIR5,TMR5IF					; clear timer overflow flag
+serial_rx_stream_ram_loop_2a:
+	clrf	TMR5L						; restart timer (see above)
+serial_rx_stream_ram_loop_2b:
+	btfss	PIR1,RCIF					; received a data byte? (bit is set on RX complete and reset on reading RCREG1)
+	bra		serial_rx_stream_ram_chk	; NO  - check timeout
+	movff	RCREG1,POSTINC2				; YES - copy received byte to memory
+	decfsz	eeprom_loop,F				;     - decrement loop counter, became zero?
+	bra		serial_rx_stream_ram_loop_2a;       NO  - loop
+	bcf		rs232_rx_timeout			;       YES - clear timeout flag
+	return								;           - all bytes received, done
+serial_rx_stream_ram_chk:
+	btfss	PIR5,TMR5IF					; timer overflow (timeout)?
+	bra		serial_rx_stream_ram_loop_2b; NO  - continue looping
+	bra		rs232_rx_get_timeout		; YES - give up
 
-	bsf		block_battery_gauge				; suspend ISR from accessing the battery gauge
-	banksel	battery_gauge					; select bank ISR data
-	clrf	battery_gauge+0					; null the battery gauge
-	clrf	battery_gauge+1
-	clrf	battery_gauge+2
-	clrf	battery_gauge+3
-	clrf	battery_gauge+4
-	clrf	battery_gauge+5
-	banksel	common							; back to bank common
-	bcf		block_battery_gauge				; allow ISR to access the battery gauge again
-
-	movlw	.100
-	movwf	batt_percent					; set battery level to 100%
-	return
-
-;=============================================================================
-
-	global	eeprom_reset_logbook_pointers
-eeprom_reset_logbook_pointers:
-	clrf	EEADRH							; make sure to select EEPROM bank 0
-	clrf	EEDATA
-	write_int_eeprom .4
-	write_int_eeprom .5
-	write_int_eeprom .6
-	write_int_eeprom .2						; also delete total dive counter
-	write_int_eeprom .3
-	write_int_eeprom .16
-	write_int_eeprom .17					; ...and the backup counter, too
-	return
-
-;=============================================================================
-
+;-----------------------------------------------------------------------------
 	END
--- a/src/eeprom_rs232.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/eeprom_rs232.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File eeprom_rs232.inc                     combined next generation V3.06.1
+;   File eeprom_rs232.inc                     combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -9,40 +9,305 @@
 ;  2011-08-03 : [mH] moving from OSTC code
 
 
-write_int_eeprom	macro	eeprom_address
-	movlw	eeprom_address
-	call	write_int_eeprom_1
+; --------------------------------------------------------------------------------------------
+;           EEPROM read & write Macros
+; --------------------------------------------------------------------------------------------
+
+
+; read 1 byte from EEPROM to memory
+;
+; eeprom_address: address:2 containing source address in EEPROM
+; memory_address: address:2 containing target address in memory
+;
+EEPROM_CC_READ		macro	eeprom_address, memory_address
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	call	read_eeprom				; read from EEPROM
+	movff	EEDATA,memory_address	; store to memory
+	endm
+
+
+; read 2 bytes from EEPROM to memory, both bytes must be in same EEPROM bank
+;
+; eeprom_address: address:2 containing start address in EEPROM
+; memory_address: address:2 containing start address in memory
+;
+EEPROM_II_READ		macro	eeprom_address, memory_address
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	lfsr	FSR1,memory_address		; set start address in memory
+	movlw	.2						; read  2 bytes
+	call	eeprom_read_common		; execute read
+	endm
+
+
+; read 3 bytes from EEPROM to memory, all bytes must be in same EEPROM bank
+;
+; eeprom_address: address:2 containing start address in EEPROM
+; memory_address: address:2 containing start address in memory
+;
+EEPROM_TT_READ		macro	eeprom_address, memory_address
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	lfsr	FSR1,memory_address		; set start address in memory
+	movlw	.3						; read  3 bytes
+	call	eeprom_read_common		; execute read
+	endm
+
+
+; read a range of bytes from EEPROM to memory, all bytes must be in same EEPROM bank
+;
+; eeprom_address: address:2 containing start address in EEPROM
+; memory_address: address:2 containing start address in memory (bank safe)
+; range         : number of bytes to read (1-256), will wrap-around staying in same EEPROM bank!
+;
+EEPROM_RR_READ		macro	eeprom_address, memory_address, range
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	lfsr	FSR1,memory_address		; set start address in memory
+	movlw	low(range)				; set size of range to read
+	call	eeprom_read_common		; execute read
+	endm
+
+
+; write 1 byte from memory to EEPROM
+;
+; memory_address: address:2 containing source      address in memory (bank safe)
+; eeprom_address: address:2 containing destination address in EEPROM
+;
+EEPROM_CC_WRITE		macro	memory_address, eeprom_address
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	movff	memory_address,EEDATA	; copy byte to EEPROM data register
+	call	write_eeprom			; execute write
+	endm
+
+
+; write 2 bytes from memory to EEPROM, both bytes must go into the same EEPROM bank
+;
+; memory_address: address:2 containing start address in memory (bank safe)
+; eeprom_address: address:2 containing start address in EEPROM
+;
+EEPROM_II_WRITE		macro	memory_address, eeprom_address
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	lfsr	FSR1,memory_address		; set start address in memory
+	movlw	.2						; write 2 bytes
+	call	eeprom_write_common		; execute write
+	endm
+
+
+; write 3 bytes from memory to EEPROM, all bytes must go into the same EEPROM bank
+;
+; memory_address: address:2 containing start address in memory (bank safe)
+; eeprom_address: address:2 containing start address in EEPROM
+;
+EEPROM_TT_WRITE		macro	memory_address, eeprom_address
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	lfsr	FSR1,memory_address		; set start address in memory
+	movlw	.3						; write 3 bytes
+	call	eeprom_write_common		; execute write
+	endm
+
+
+; write a range of bytes from memory to EEPROM, all bytes must go into the same EEPROM bank
+;
+; memory_address: address:2 containing start address in memory (bank safe)
+; eeprom_address: address:2 containing start address in EEPROM
+; range         : number of bytes to write (1-256), will wrap-around staying in same EEPROM bank!
+;
+EEPROM_RR_WRITE		macro	memory_address, eeprom_address, range
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM
+	movwf	EEADRH					; set     bank in EEPROM
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     start address in EEPROM
+	lfsr	FSR1,memory_address		; set start address in memory
+	movlw	low(range)				; set size of range to write
+	call	eeprom_write_common		; execute write
+	endm
+
+
+; set up EEPROM address register for subsequent read/write operations
+;
+; eeprom_address: address:2 containing the EEPROM address to set up
+;
+EEPROM_SET_ADDRESS	macro	eeprom_address							; Set EEPROM address
+	movlw	HIGH(eeprom_address)	; extract bank in EEPROM		; for subsequent calls to
+	movwf	EEADRH					; set     EEPROM bank			; write_eeprom / read_eeprom
+	movlw	LOW (eeprom_address)	; extract start address in EEPROM
+	movwf	EEADR					; set     EEPROM cell
 	endm
 
-read_int_eeprom		macro	eeprom_address
-	movlw	eeprom_address
-	call	read_int_eeprom_1
+
+; --------------------------------------------------------------------------------------------
+;       EEPROM Defines
+; --------------------------------------------------------------------------------------------
+
+#DEFINE DECO_DATA_VALID_TOKEN			0x55		; deco data valid
+#DEFINE DECO_DATA_INVALID_TOKEN			0xAA		; deco data invalid
+
+
+; --------------------------------------------------------------------------------------------
+;       EEPROM Memory Map
+; --------------------------------------------------------------------------------------------
+
+;       Label						EEPROM Address	 Size  Description
+
+; bank 1+2: settings & options
+; ----------------------------						  +--- do not change the position of these data!
+#DEFINE eeprom_ostc_serial				0x000		; | 2  OSTC dive computer unique serial number
+#DEFINE eeprom_num_dives				0x002		; | 2  total number of dives
+#DEFINE eeprom_log_pointer				0x004		; | 3  pointer used for accessing log data in external flash
+#DEFINE eeprom_battery_gauge			0x007		; | 6  backup storage for the battery gauge meter
+#DEFINE eeprom_log_offset				0x00D		; | 2  offset between OSTC dive counting and user's counting
+#DEFINE eeprom_battery_type				0x00F		; | 1  battery type inside the OSTC
+#DEFINE eeprom_options_version			0x010		;   2  options version identifier
+;										0x012		;   8  unused
+#DEFINE eeprom_options_storage			0x01A		; 486  backup storage for the options
+
+
+; bank 2: deco data backup
+; ------------------------
+#DEFINE eeprom_deco_data_validity		0x200		;   1  deco data validity
+#DEFINE eeprom_deco_data_version		0x201		;   1  deco data format version
+#DEFINE eeprom_deco_data_timestamp		0x202		;   6  date/time of deco data
+#DEFINE eeprom_deco_data_surfinterval	0x208		;   2  surface interval
+;										0x20A		;   6  unused
+#DEFINE eeprom_deco_data_bank3			0x210		;   9  desaturation status
+;										0x219		;   1  unused
+#DEFINE eeprom_deco_data_bank5			0x21A		;   4  CNS
+;										0x21E		;   2  unused
+#DEFINE eeprom_deco_data_bank7			0x220		; 128  tissue pressures
+; 										0x2A0		;  96  unused
+
+
+; bank 3: flash backup & factory use
+; ----------------------------------
+#DEFINE eeprom_prog_page0_backup		0x300		; 128  backup storage for the first program memory page
+;										0x380		;   1  unused
+#DEFINE eeprom_button_polarity			0x381		;   1  button polarity (factory use only, do not change position!)
+;										0x382		; 126  unused
+
+
+
+; --------------------------------------------------------------------------------------------
+;           Serial read & write Macros
+; --------------------------------------------------------------------------------------------
+
+; receive 1 byte and write to memory, in case of timeout the flag 'rs232_rx_timeout' will be set
+;
+SERIAL_CC_RECEIVE	macro	mem_address
+	call	rs232_get_byte				; (try to) receive one byte
+	movff	RCREG1,mem_address			; copy received byte to memory
 	endm
 
 
+; stream a range of bytes to memory, in case of timeout the flag 'rs232_rx_timeout' will be set
+;
+; mem_address: address:2 containing the start address in memory (bank safe)
+; range      : number of bytes to receive (1-256)
+;
+SERIAL_RR_RECEIVE_RAM	macro	mem_address, range
+	lfsr	FSR2,mem_address			; set start address in memory
+	movlw	low(range)					; set number of bytes to receive
+	extern	serial_rx_stream_ram
+	call	serial_rx_stream_ram
+	endm
+
+
+
+; send 1 byte literal
+;
+SERIAL_LC_SEND	macro	literal
+	call	rs232_wait_tx				; wait for completion of last transmit
+	movlw	literal						; load literal
+	movwf	TXREG1						; send literal to serial TX
+	endm
+
+
+; send 1 byte from memory
+;
+; mem_address: address:2 containing the source address in memory (bank safe)
+;
+SERIAL_CC_SEND	macro	mem_address
+	call	rs232_wait_tx				; wait for completion of last transmit
+	movff	mem_address,TXREG1			; send byte from memory to serial TX
+	endm
+
+
+; send a range of bytes from memory
+;
+; mem_address: address:2 containing the start address in memory (bank safe)
+; range      : number of bytes to send (1-256)
+;
+SERIAL_RR_SEND_RAM	macro	mem_address, range
+	lfsr	FSR2,mem_address			; set start address in memory
+	movlw	low(range)					; set number of bytes to send
+	extern	serial_tx_ram
+	call	serial_tx_ram
+	endm
+
+
+; --------------------------------------------------------------------------------------------
+;       EXTERN Directives
+; --------------------------------------------------------------------------------------------
+
+ IFNDEF INSIDE_EEPROM_RS232
+
+; EEPROM - basic read & write
+
+	extern	eeprom_read_common
+	extern	eeprom_write_common
+
+	extern	read_eeprom
+	extern	write_eeprom
+
+
+; EEPROM high-level access
+
+	extern	eeprom_serial_number_read
+
+	extern	eeprom_total_dives_read
+	extern	eeprom_total_dives_write
+
+	extern	eeprom_log_offset_read
+	extern	eeprom_log_offset_write
+
+	extern	eeprom_battery_gauge_read
+	extern	eeprom_battery_gauge_write
+
+	extern	eeprom_deco_data_read
+	extern	eeprom_deco_data_write
+
+
+; Serial - IR / S8
+
+	extern	enable_ir_s8
+	extern	disable_ir_s8
+	extern	ir_s8_wait_tx
+
+
+; Serial - RS232 (USB / BT)
+
 	extern	enable_rs232
 	extern	disable_rs232
 	extern	rs232_get_byte
 	extern	rs232_wait_tx
-	extern	rs232_wait_tx2
 
-	extern	enable_ir_s8
-	extern	disable_ir_s8
-
-	extern	write_int_eeprom_1
-	extern	read_int_eeprom_1
-	extern	read_eeprom
-	extern	write_eeprom
 
-	extern	update_battery_registers
-	extern	retrieve_battery_registers
-
-	extern	vault_decodata_into_eeprom
-	extern	restore_decodata_from_eeprom
-
-	extern	do_logoffset_common_write
-	extern	do_logoffset_common_read
-	extern	eeprom_reset_logbook_pointers
-
-	extern	reset_battery_pointer			; reset battery pointer 0x07-0x0C and battery_gauge
-	extern	reset_battery_internal_only		; reset internal battery registers only
+ ENDIF	; INSIDE_EEPROM_RS232
--- a/src/external_flash.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/external_flash.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File external_flash.asm                    combined next generation V3.0.1
+;   File external_flash.asm                   combined next generation V3.08.8
 ;
 ;   External flash
 ;
@@ -11,352 +11,407 @@
 
 	#include "hwos.inc"
 	#include "wait.inc"
+	#include "eeprom_rs232.inc"
 
 ext_flash	CODE
 
 ;=============================================================================
 
-; increase flash address by one
-;
-	global	incf_ext_flash_address_p1
-incf_ext_flash_address_p1:
-	movlw	.1
-	;bra	incf_ext_flash_address0
+; increase flash address by one with wrap-around at 0x400000 to 0x000000
+incf_ext_flash_address_p1_0x40:
+	movlw	.1								; increase by 1
+	;bra	incf_ext_flash_address0_0x40	; continue
 
 
-; increase flash address by value in WREG
-;
-	global	incf_ext_flash_address0
-incf_ext_flash_address0:
-	addwf	ext_flash_address+0,F			; increase address
-	movlw	d'0'
-	addwfc	ext_flash_address+1,F
-	addwfc	ext_flash_address+2,F
-
-	movlw	0x40
-	cpfseq	ext_flash_address+2				; at address 40FFFF?
-	return									; NO -  return
-;	clrf	ext_flash_address+0
-;	clrf	ext_flash_address+1
-	clrf	ext_flash_address+2				; YES - rollover to 0x000000
-	return
+; increase flash address by value in WREG with wrap-around at 0x400000 to 0x000000
+	global	incf_ext_flash_address0_0x40
+incf_ext_flash_address0_0x40:
+	clrf	ext_flash_rollover_threshold	; set wrap-around threshold without destroying WREG to ...
+	bsf		ext_flash_rollover_threshold,6	; ... 0x40
+	bra		incf_ext_flash_address0_common	; continue with common part
 
 
-; increase flash address by one with roll-over at 0x200000 to 0x000000
-;
-	global	incf_ext_flash_address0_p1_0x20
-incf_ext_flash_address0_p1_0x20:			; increase by one
-	movlw	.1
-	;bra	incf_ext_flash_address0_0x20
+; increase flash address by one with wrap-around at 0x200000 to 0x000000
+incf_ext_flash_address_p1_0x20:
+	movlw	.1								; increase by one
+	;bra	incf_ext_flash_address0_0x20	; continue
 
 
-; increase flash address by value in WREG with roll-over at 0x200000 to 0x000000
-;
+; increase flash address by value in WREG with wrap-around at 0x200000 to 0x000000
 	global	incf_ext_flash_address0_0x20
 incf_ext_flash_address0_0x20:
-	addwf	ext_flash_address+0,F			; increase address
-	movlw	d'0'
-	addwfc	ext_flash_address+1,F
-	addwfc	ext_flash_address+2,F
-	movlw	0x20
-	cpfseq	ext_flash_address+2				; at address 0x200000?
-	return									; NO  - return
-;	clrf	ext_flash_address+0
-;	clrf	ext_flash_address+1
-	clrf	ext_flash_address+2				; YES - rollover to 0x000000
-	return
+	clrf	ext_flash_rollover_threshold	; set wrap-around threshold without destroying WREG to ...
+	bsf		ext_flash_rollover_threshold,5	; ... 0x20
+	;bra	incf_ext_flash_address0_common	; continue with common part
 
 
-; decrease flash address by value in WREG
-;
-	global	decf_ext_flash_address0
-decf_ext_flash_address0:
-	subwf	ext_flash_address+0,F			; decrease address: do a 16-8bits subtract
-	movlw	d'0'
-	subwfb	ext_flash_address+1,F
-	movlw	d'0'
-	subwfb	ext_flash_address+2,F
-	btfss	ext_flash_address+2,7			; under-run?
-	return									; NO  - return
-	clrf	ext_flash_address+2				; YES - set to 0x00FFFFF
-	setf	ext_flash_address+1
-	setf	ext_flash_address+0
-	return
-
-
-	global	ext_flash_byte_read_plus		; return data read in WREG and SSP2BUF and
-ext_flash_byte_read_plus:					; increase address after read
-	rcall	ext_flash_byte_read
-	movwf	ext_flash_rw					; store received data
-	bra		incf_ext_flash_address_p1		; +1 and return
+incf_ext_flash_address0_common:
+	bcf		address_wrap_around				; clear wrap-around flag
+	addwf	ext_flash_address+0,F			; add WREG to address:3
+	movlw	d'0'							; ...
+	addwfc	ext_flash_address+1,F			; ...
+	addwfc	ext_flash_address+2,F			; ...
+	movf	ext_flash_rollover_threshold,W	; get wrap-around threshold
+	cpfseq	ext_flash_address+2				; at  wrap-around threshold ?
+	bra		incf_ext_flash_address1			; NO  - no wrap-around needed
+;	clrf	ext_flash_address+0				; YES - wrap-around to 0x000000
+;	clrf	ext_flash_address+1				;     - ...
+	clrf	ext_flash_address+2				;     - ...
+	bsf		address_wrap_around				;     - set wrap-around flag
+incf_ext_flash_address1:
+	movf	ext_flash_rw,W					; export current value of ext_flash_rw via WREG, too
+	return									; done
 
 
-	global	ext_flash_byte_read_plus_0x20	; return data read in WREG and SSP2BUF and 
-ext_flash_byte_read_plus_0x20:				; increase address after read with banking at 0x200000
-	rcall	ext_flash_byte_read
-	movwf	ext_flash_rw					; store received data
-	bra		incf_ext_flash_address0_p1_0x20	; +1 and return
+; decrease flash length counter by value in WREG
+	global	decf_ext_flash_length0
+decf_ext_flash_length0:
+	subwf	ext_flash_length_counter+0,F	; decrease address by value in WREG
+	movlw	d'0'							; ...
+	subwfb	ext_flash_length_counter+1,F	; ...
+	subwfb	ext_flash_length_counter+2,F	; ...
+	return									; done
+
+; ----------------------------------------------------------------------------
+
+;	global	ext_flash_byte_read_plus_0x40	; return data read in ext_flash_rw and WREG, increase address after read with wrap-around at 0x400000
+;ext_flash_byte_read_plus_0x40:
+;	rcall	ext_flash_byte_read				; read byte into ext_flash_rw
+;	bra		incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000 to 0x000000 (and return)
 
 
-	global	ext_flash_byte_read				; return data read in WREG
-ext_flash_byte_read:
-	movlw	0x03							; read command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	rcall	write_spi						; dummy write to read data into WREG
-	bsf		flash_ncs						; CS=1
-	movwf	ext_flash_rw
-	return									; return data read in WREG and ext_flash_rw
+	global	ext_flash_byte_read_plus_0x20	; return data read in ext_flash_rw and WREG, increase address after read with wrap-around at 0x200000
+ext_flash_byte_read_plus_0x20:
+	rcall	ext_flash_byte_read				; read byte into ext_flash_rw
+	bra		incf_ext_flash_address_p1_0x20	; increase address with roll-over at 0x200000 to 0x000000 (and return)
 
 
-ext_flash_write_address:					; write 24 bit address ext_flash_address:3 via SPI
-	movf	ext_flash_address+2,W			; 24 bit address
-	rcall	write_spi
-	movf	ext_flash_address+1,W
-	rcall	write_spi
-	movf	ext_flash_address+0,W
-	bra 	write_spi						; and return....
+	global	ext_flash_byte_read				; return data read in WREG and ext_flash_rw, no address change
+ext_flash_byte_read:
+	movlw	0x03							; set up  read command
+	rcall	shift_spi						; prepare read command
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	rcall	shift_spi						; shift the SPI to read data into WREG
+	bsf		flash_ncs						; set CS=1
+	movwf	ext_flash_rw					; return data read in WREG and ext_flash_rw
+	return									; done
 
+; ----------------------------------------------------------------------------
+; read-range base functions
 
 	global	ext_flash_read_block_start		; return data read in WREG
 ext_flash_read_block_start:
-	movlw	0x03							; read command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	rcall	write_spi						; dummy write to read data into WREG
-	return									; return data read in WREG
+	movlw	0x03							; set up  read command
+	rcall	shift_spi						; execute read command
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	bra		shift_spi						; shift the SPI to read data into WREG (and return)
 
 
-	global	ext_flash_read_block			; return data read in WREG
-ext_flash_read_block:
-	rcall	incf_ext_flash_address_p1		; increase address +1
-	bra		write_spi1						; dummy write to read data into WREG and return
-
-
-	global	ext_flash_read_block_stop		; return data read in WREG
-ext_flash_read_block_stop:
-	bsf		flash_ncs						; CS=1
-	return									; nO data in WREG
+	global	ext_flash_read_block_0x40		; return data read in WREG
+ext_flash_read_block_0x40:
+	rcall	incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000
+	btfss	address_wrap_around				; did the address wrap-around?
+	bra		shift_spi_loop_1				; NO  - shift the SPI to  read data into WREG and return
+	rcall	ext_flash_read_block_stop		; YES - do a block-stop
+	bra		ext_flash_read_block_start		;     - do a block-start, read data into WREG and return
 
 
-	global	write_byte_ext_flash_plus_header
-write_byte_ext_flash_plus_header:			; write from WREG and increase address after write
-	movwf	ext_flash_rw					; store data
-	; test if write is done at first byte of 4kB block
-	; if yes -> delete 4kB block first
-	tstfsz	ext_flash_address+0				; at 0x00?
-	bra		write_byte_ext_flash_plus_h1	; NO - normal write
-	movf	ext_flash_address+1,W
-	andlw	0x0F							; mask lower nibble
-	tstfsz	WREG							; at 0x.0?
-	bra		write_byte_ext_flash_plus_h1	; NO  - normal write
-											; YES - at beginning of 4kB block -> erase first!
-	rcall	ext_flash_erase4kB				;     - erases 4kB sector @ext_flash_address:3
-write_byte_ext_flash_plus_h1:
-	movf	ext_flash_rw,W
-	rcall	ext_flash_byte_write			; write the byte
-	bra		incf_ext_flash_address_p1		; +1 and return
+	global	ext_flash_read_block_0x20		; return data read in WREG
+ext_flash_read_block_0x20:
+	rcall	incf_ext_flash_address_p1_0x20	; increase address with wrap-around at 0x200000
+	btfss	address_wrap_around				; did the address wrap-around?
+	bra		shift_spi_loop_1				; NO  - shift the SPI to  read data into WREG and return
+	rcall	ext_flash_read_block_stop		; YES - do a block-stop
+	bra		ext_flash_read_block_start		;     - do a block-start, read data into WREG and return
 
 
-	global	write_byte_ext_flash_plus_nocnt	; no increase of ext_flash_dive_counter:3
-write_byte_ext_flash_plus_nocnt:
-	movwf	ext_flash_rw					; store data
-	bra		write_byte_ext_flash_plus2
+	global	ext_flash_read_block_stop		; end block operation
+ext_flash_read_block_stop:
+	bsf		flash_ncs						; set CS=1
+	return									; done
+
+; ----------------------------------------------------------------------------
+; read-range function, to be used through macro
+;
+	global	ext_flash_read_range
+ext_flash_read_range:
+	movwf	eeprom_loop						; load loop counter (eeprom variable used here)
+	rcall	ext_flash_read_block_start		; read first byte from flash
+	bra		ext_flash_read_range_loop_start	; jump into loop
+ext_flash_read_range_loop:
+	rcall	ext_flash_read_block_0x40		; read next byte from flash
+ext_flash_read_range_loop_start:
+	movwf	POSTINC1						; write byte to memory
+	decfsz	eeprom_loop,F					; decrement loop counter, all done?
+	bra		ext_flash_read_range_loop		; NO  - continue loop
+	bra		ext_flash_read_block_stop		; YES - end reading from flash (and return)
 
 
-	global	write_byte_ext_flash_plus_nodel	; does NOT delete 4kB page when required
-write_byte_ext_flash_plus_nodel:			; write from WREG and increase address after write with banking at 0x200000
-	movwf	ext_flash_rw					; store data
-	bra		write_byte_ext_flash_plus1		; ignore possible begin of 4kB page, there have been written 0xFF already
+; ----------------------------------------------------------------------------
+; write-range base functions
 
-	global	write_byte_ext_flash_plus		; write from WREG and increase address after write with banking at 0x200000
-write_byte_ext_flash_plus:
-	movwf	ext_flash_rw					; store data
-	; First, increase dive length counter
-	incf	ext_flash_dive_counter+0,F
-	movlw	.0
-	addwfc	ext_flash_dive_counter+1,F
-	addwfc	ext_flash_dive_counter+2,F		; 24 bit ++
+ext_flash_write_block_start:
+	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; set up  WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x02							; set up  write (PP, Page-Program) command
+	rcall	shift_spi						; execute write
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	movf	ext_flash_rw,W					; get byte to write
+	bra		shift_spi						; write the byte (and return)
+
+ext_flash_write_block:
+	movf	ext_flash_rw,W					; get byte to write
+	bra		shift_spi_loop_1				; shift the SPI to write data into FLASH (and return)
+
+ext_flash_write_block_stop:
+	bra		ext_flash_wait_write			; wait for completion (and return)
 
-write_byte_ext_flash_plus2:
-	; Now test if write is done at first byte of 4kB block
-	; if yes -> delete 4kB block first
-	tstfsz	ext_flash_address+0				; at 0x00?
-	bra		write_byte_ext_flash_plus1		; NO - normal write
-	movf	ext_flash_address+1,W
-	andlw	0x0F							; mask lower nibble
-	tstfsz	WREG							; at 0x.0?
-	bra		write_byte_ext_flash_plus1		; NO  - normal write
-											; YES - at beginning of 4kB block -> erase first!
-	rcall	ext_flash_erase4kB				;     - erases 4kB sector @ext_flash_address:3
-write_byte_ext_flash_plus1:
-	movf	ext_flash_rw,W
-	rcall	ext_flash_byte_write			; write the byte
-	bra		incf_ext_flash_address0_p1_0x20	; +1 and roll over at 0x200000 to 0x000000	and return
+; ----------------------------------------------------------------------------
+; write-range function, to be used through macro
+;
+	global	ext_flash_write_range
+ext_flash_write_range:
+	movwf	eeprom_loop						; load loop counter (eeprom variable used here)
+	movff	POSTINC1,ext_flash_rw			; read  first byte from memory
+	rcall	ext_flash_write_block_start		; write first byte to FLASH
+	bra		ext_flash_write_range_loop_start; jump into loop
+ext_flash_write_range_loop:
+	movff	POSTINC1,ext_flash_rw			; read  next byte from memory
+	rcall	ext_flash_write_block			; write next byte to FLASH
+ext_flash_write_range_loop_start:
+	decfsz	eeprom_loop,F					; decrement loop counter, all done?
+	bra		ext_flash_write_range_loop		; NO  - continue loop
+	bra		ext_flash_write_block_stop		; YES - end writing to flash (and return)
+
+; ----------------------------------------------------------------------------
+
+;	global	write_byte_ext_flash_plus_header
+; write_byte_ext_flash_plus_header:
+;	movwf	ext_flash_rw					; store byte to write
+;											 ; test if write is done at first byte of 4kB block, if yes delete 4kB block first
+;	tstfsz	ext_flash_address+0				; at 0x....00 ?
+;	bra		write_byte_ext_flash_plus_h1	; NO - normal write
+;	movf	ext_flash_address+1,W			; YES - get high byte
+;	andlw	0x0F							;     - mask lower nibble
+;	tstfsz	WREG							;     - at 0x..0...?
+;	bra		write_byte_ext_flash_plus_h1	;       NO  - normal write
+;	rcall	ext_flash_erase_4kB				;       YES - at beginning of 4kB block -> erases 4kB sector @ext_flash_address:3
+;write_byte_ext_flash_plus_h1:
+;	rcall	ext_flash_byte_write			; write the byte in ext_flash_rw
+;	bra		incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000 and return
 
 
-	global	ext_flash_byte_write			; write from WREG
-ext_flash_byte_write:
-	movwf	ext_flash_rw					; store data byte
-	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x02							; write (PP, Page-Program) command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	movf	ext_flash_rw,W					; load data byte
-	rcall	write_spi						; write one byte of data
-	bra		ext_flash_wait_write			; and return...
+	global	write_byte_ext_flash_plus_prof
+write_byte_ext_flash_plus_prof:
+	movwf	ext_flash_rw					; store byte to write
+	incf	ext_flash_length_counter+0,F	; increase dive length counter
+	movlw	.0								; ...
+	addwfc	ext_flash_length_counter+1,F	; ...
+	addwfc	ext_flash_length_counter+2,F	; ...
+	bra		write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new page
+
+
+	global	write_byte_ext_flash_plus_nocnt
+write_byte_ext_flash_plus_nocnt:
+	movwf	ext_flash_rw					; store byte to write
+write_byte_ext_flash_plus_nocnt1:			; test if write is done at first byte of 4kB block, if yes delete 4kB block first
+	tstfsz	ext_flash_address+0				; at 0x....00?
+	bra		write_byte_ext_flash_plus_nodel1; NO  - execute write
+	movf	ext_flash_address+1,W			; YES - mask lower nibble
+	andlw	0x0F							;     - ...
+	tstfsz	WREG							;     - at 0x..0...?
+	bra		write_byte_ext_flash_plus_nodel1;       NO  - execute write
+											;       YES - at beginning of 4kB block -> erase first!
+	rcall	ext_flash_erase_4kB				;           - erases 4kB sector @ext_flash_address:3
+	bra		write_byte_ext_flash_plus_nodel1;           - execute write
 
 
-	global	ext_flash_byte_write_comms		; without wait, ~86us fixed delay due to 115200 Baud
-ext_flash_byte_write_comms:
-	movwf	ext_flash_rw					; store data byte
-	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x02							; write PP (Page-Program) command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-	movf	ext_flash_rw,W					; load data byte
-	rcall	write_spi						; write one byte of data
-	bsf		flash_ncs						; CS=1
-	return
+	global	write_byte_ext_flash_plus_nodel
+write_byte_ext_flash_plus_nodel:
+	movwf	ext_flash_rw					; store byte to write
+write_byte_ext_flash_plus_nodel1:
+	rcall	ext_flash_byte_write			; write the byte in ext_flash_rw
+	bra		incf_ext_flash_address_p1_0x20	; increase address with wrap-around at 0x200000 and return
+
+
+	global	write_byte_ext_flash_plus_comms	; write from WREG without wait, ~86us fixed delay due to 115200 Baud, use with caution!
+write_byte_ext_flash_plus_comms:
+	movwf	ext_flash_rw					; store byte to write
+	bcf		flash_wait						; do not wait on flash write to complete
+	rcall	ext_flash_byte_write_common		; write the byte in ext_flash_rw
+	bra		incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000 and return
+
 
+ext_flash_byte_write:
+	bsf		flash_wait						; wait for flash write to complete
+ext_flash_byte_write_common:
+	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; set up  WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x02							; set up  write (PP, Page-Program) command
+	rcall	shift_spi						; execute write
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	movf	ext_flash_rw,W					; get byte to write
+	rcall	shift_spi						; write the byte
+	btfsc	flash_wait						; shall wait on flash write to complete?
+	bra		ext_flash_wait_write			; YES - wait for completion (and return)
+	bsf		flash_ncs						; NO  - set CS=1
+	return									;     - done
+
+; ----------------------------------------------------------------------------
 
 	global	ext_flash_disable_protection	; disable write protection
 ext_flash_disable_protection:
 	; unlock old memory
 	bsf		flash_ncs						; CS=1
 	movlw	0x50							; EWSR command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x01							; WRSR command
-	rcall	write_spi
+	rcall	shift_spi
 	movlw	b'00000000'						; new status
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	; unlock new memory
 	movlw	0x06							; WREN command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x98							; ULBPR command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x06							; WREN command
-	rcall	write_spi
+	rcall	shift_spi
 	bsf		flash_ncs						; CS=1
 	movlw	0x42							; WBPR command
-	rcall	write_spi
-	movlw	.18
-	movwf	lo
-ext_flash_disable_protection2:
-	movlw	0x00
-	rcall	write_spi
-	decfsz	lo,F							; 18 bytes with 0x00
-	bra		ext_flash_disable_protection2
-	bsf		flash_ncs						; CS=1
-	return
+	rcall	shift_spi
+	movlw	.18								; 18 bytes to do
+	movwf	lo								; initialize loop counter
+ext_flash_disable_prot_loop:
+	movlw	0x00							; prepare writing a zero
+	rcall	shift_spi						; execute write
+	decfsz	lo,F							; all bytes done?
+	bra		ext_flash_disable_prot_loop		; NO  - loop
+	bsf		flash_ncs						; YES - set CS=1
+	return									;     - done
 
 
 	global	ext_flash_enable_protection
 ext_flash_enable_protection:
 	; lock old memory
-	bsf		flash_ncs						; CS=1
-	movlw	0x50							; EWSR command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x01							; WRSR command
-	rcall	write_spi
-	movlw	b'00011100'						; new status (write protection on)
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
+	bsf		flash_ncs						; set CS=1
+	movlw	0x50							; prepare EWSR command
+	rcall	shift_spi						; execute EWSR command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x01							; prepare WRSR command
+	rcall	shift_spi						; execute WRSR command
+	movlw	b'00011100'						; prepare write protection on
+	rcall	shift_spi						; execute write protection on
+	bsf		flash_ncs						; set CS=1
 	; lock new memory
 ;	movlw	0x06							; WREN command
-;	rcall	write_spi
+;	rcall	shift_spi
 ;	bsf		flash_ncs						; CS=1
 ;	movlw	0x8D							; LBPR command
-;	rcall	write_spi
-;	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x42							; WBPR command
-	rcall	write_spi
-	movlw	.18
-	movwf	lo
-ext_flash_enable_protection2:
-	movlw	0xFF
-	rcall	write_spi
-	decfsz	lo,F							; 18 bytes with 0xFF
-	bra		ext_flash_enable_protection2
-	bsf		flash_ncs						; CS=1
-	return
+;	rcall	shift_spi
+;	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; prepare WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x42							; prepare WBPR command
+	rcall	shift_spi						; execute WBPR command
+	movlw	.18								; 18 bytes to do
+	movwf	lo								; initialize loop counter
+ext_flash_enable_prot_loop:
+	movlw	0xFF							; prepare writing 0xFF
+	rcall	shift_spi						; execute write
+	decfsz	lo,F							; all bytes done?
+	bra		ext_flash_enable_prot_loop		; NO  - loop
+	bsf		flash_ncs						; YES - set CS=1
+	return									;     - done
 
+; ----------------------------------------------------------------------------
 
-	global	ext_flash_erase4kB				; erases 4kB sector
-ext_flash_erase4kB:
-	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	write_spi
+	global	erase_complete_logbook
+erase_complete_logbook:
+	; clear logbook data in EPROM
+	CLRT	mpr								; prepare a 3 byte zero integer
+	EEPROM_II_WRITE mpr,eeprom_num_dives	; reset total number of dives
+	EEPROM_TT_WRITE mpr,eeprom_log_pointer	; reset pointer to begin of log data
+	; erase logbook data in FLASH (0x000000 -> 0x2FFFFF -> 3 MByte -> 3145728 Bytes)
 	bsf		flash_ncs						; CS=1
-	movlw	0x20							; sector erase command
-	rcall	write_spi
-	rcall	ext_flash_write_address			; write 24 bit address ext_flash_address:3 via SPI
-;	bra		ext_flash_wait_write			; wait for write... and return
-ext_flash_wait_write:
-	bsf		flash_ncs						; CS=1
-;	WAITMS	d'1'							; TBE/TSE=25ms...
-	movlw	0x05							; RDSR command
-	rcall	write_spi						; read status
-	rcall	write_spi						; read status into WREG
-	bsf		flash_ncs						; CS=1
-	btfsc	SSP2BUF,0						; write operation in process?
-	bra		ext_flash_wait_write			; ES - loop waiting
-	return
-
-
-	global	ext_flash_erase_logbook			; erases logbook memory (000000h -> 2FFFFFh -> 3MByte -> 3145728 Bytes)
-ext_flash_erase_logbook:
-	bsf		flash_ncs						; CS=1
-	clrf	ext_flash_address+0
-	clrf	ext_flash_address+1
-	clrf	ext_flash_address+2
-
-	clrf	ext_flash_rw					; 256 * 12 kB = 3145728 bytes
-ext_flash_erase_logbook_loop:
-	rcall	ext_flash_erase4kB				; 4kB
+	clrf	ext_flash_address+0				; set address to 0x000000
+	clrf	ext_flash_address+1				; ...
+	clrf	ext_flash_address+2				; ...
+	clrf	ext_flash_rw					; write zeros
+ext_flash_erase_logbook_loop:				; 256 * 12 kB = 3.145.728 bytes to do
+	rcall	ext_flash_erase_4kB				; erase 4kB block
 	rcall	ext_flash_add_4kB				; increase ext_flash_address:3 by 4kB
-	rcall	ext_flash_erase4kB				; 4kB
+	rcall	ext_flash_erase_4kB				; erase 4kB block
 	rcall	ext_flash_add_4kB				; increase ext_flash_address:3 by 4kB
-	rcall	ext_flash_erase4kB				; 4kB
+	rcall	ext_flash_erase_4kB				; erase 4kB block
 	rcall	ext_flash_add_4kB				; increase ext_flash_address:3 by 4kB
 	decfsz	ext_flash_rw,F					; decrement loop counter, done?
 	bra		ext_flash_erase_logbook_loop	; NO  - loop
 	return									; YES - done
 
+
+	global	ext_flash_erase_4kB				; erase a 4kB sector
+ext_flash_erase_4kB:
+	bsf		flash_ncs						; set CS=1
+	movlw	0x06							; prepare WREN command
+	rcall	shift_spi						; execute WREN command
+	bsf		flash_ncs						; set CS=1
+	movlw	0x20							; prepare sector erase command
+	rcall	shift_spi						; execute sector erase command
+	rcall	ext_flash_set_address			; write 24 bit address ext_flash_address:3 via SPI
+	bra		ext_flash_wait_write			; wait for write to complete and return
+
+; ----------------------------------------------------------------------------
+
+; send address
+ext_flash_set_address:
+	movf	ext_flash_address+2,W			; write 24 bit address ext_flash_address:3 via SPI
+	rcall	shift_spi						; ...
+	movf	ext_flash_address+1,W			; ...
+	rcall	shift_spi						; ...
+	movf	ext_flash_address+0,W			; ...
+	bra 	shift_spi						; ... and return
+
+; wait on write operation to complete
+ext_flash_wait_write:
+	bsf		flash_ncs						; set CS=1
+;	WAITMS	d'1'							; TBE/TSE=25ms...
+	movlw	0x05							; prepare RDSR command
+	rcall	shift_spi						; 1st cycle: execute command to read status
+	rcall	shift_spi						; 2nd cycle: read status
+	bsf		flash_ncs						; set CS=1
+	btfsc	SSP2BUF,0						; write operation still in process?
+	bra		ext_flash_wait_write			; YES - loop waiting
+	return									; NO  - done
+
+; add 0x001000 to flash address
 ext_flash_add_4kB:
-	movlw	0x10
-	addwf	ext_flash_address+1,F
-	movlw	d'0'
-	addwfc	ext_flash_address+2,F
-	return
+	movlw	0x10							; add 0x10 to high byte
+	addwf	ext_flash_address+1,F			; ...
+	movlw	d'0'							; propagate carry to upper byte
+	addwfc	ext_flash_address+2,F			; ...
+	return									; done
 
-
-write_spi:									; with data in WREG...
-	bcf		flash_ncs						; CS
-	global	write_spi1
-write_spi1:									; with data in WREG...
+; shift the SPI bus for a combined write/read: WREG --->\      /---> WREG
+shift_spi:                                  ;          flash chip
+	bcf		flash_ncs						; set CS=0
+shift_spi_loop_1:
 	bcf		SSP2STAT,WCOL					; clear flag
 	movwf	SSP2BUF							; write to buffer
 	btfsc	SSP2STAT,WCOL					; was buffer full?
-	bra		write_spi1						; YES - try again
-write_spi2:									; wait for write command
-	btfss	SSP2STAT, BF					; buffer full?
-	bra		write_spi2						; NO  - loop waiting
-	movf	SSP2BUF,W						; YES - copy RX data to WREG
-	return									;     - return with RX data in WREG and SSP2BUF
+	bra		shift_spi_loop_1				; YES - try again
+shift_spi_loop_2:
+	btfss	SSP2STAT,BF						; buffer full?
+	bra		shift_spi_loop_2				; NO  - loop waiting
+	movf	SSP2BUF,W						; YES - copy received data to WREG
+	return									;     - done
 
 	END
--- a/src/external_flash.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/external_flash.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File external_flash.inc                    combined next generation V3.0.1
+;   File external_flash.inc                   combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -8,53 +8,141 @@
 ; HISTORY
 ;  2011-08-12 : [mH] creation
 
-; Misc
-	extern	incf_ext_flash_address_p1			; +1 for the ext_flash_address:3
-	extern	ext_flash_disable_protection		; disables write protection
-	extern	ext_flash_enable_protection			; enables  write protection
+
+; FLASH Memory Layout:
+;
+; 0x000000 - 0x1FFFFF    2 MB dive profile data, shared ring buffer
+; 0x200000 - 0x2FFFFF    1 MB dive header  data, last 256 dives, 4 kB / dive
+; 0x300000 - 0x3DFFFF  896 kB unused
+; 0x3E0000 - 0x3DFFFF  120 kB firmware buffer
+; 0x3E0000 - 0x3FFFFF    8 kB unused
+
+
+; Write: WREG -> FLASH with address increment and wrap-around at 0x200000
+	extern	write_byte_ext_flash_plus_prof		; with    increase of ext_flash_dive_counter
+	extern	write_byte_ext_flash_plus_nocnt		; without increase of ext_flash_dive_counter
+	extern	write_byte_ext_flash_plus_nodel		; without increase of ext_flash_dive_counter, without delete on entering new page
+
 
-; Writes
-	extern	write_byte_ext_flash_plus			; write from WREG and increase address after write with banking at 0x200000
-	extern	write_byte_ext_flash_plus_nocnt		; no increase of ext_flash_dive_counter:3
-	extern	write_byte_ext_flash_plus_nodel		; does NOT delete 4kB Page when required
-	extern	write_byte_ext_flash_plus_header	; write from WREG and increase address after write
-	extern	ext_flash_byte_write				; writes one byte from WREG @ext_flash_address:3
-	extern	ext_flash_byte_write_comms			; without wait, ~86us fixed delay due to 115200 Bauds (Use with caution)
-	extern	write_spi1							; just (dummy)write to read a byte
+; Write: WREG -> FLASH with address increment and wrap-around at 0x400000
+	extern	write_byte_ext_flash_plus_comms		; without wait for use with fast comm (~86us fixed delay due to 115200 Bauds - use with caution)
+
+
+; Read: block-read FLASH -> WREG
+	extern	ext_flash_read_block_start			; initial    read of one  byte at ext_flash_address:3
+	extern	ext_flash_read_block_0x40			; subsequent read of next byte(s) with wrap-around at 0x400000
+	extern	ext_flash_read_block_0x20			; subsequent read of next byte(s) with wrap-around at 0x200000
+	extern	ext_flash_read_block_stop			; terminate  read
 
-; Delete
-	extern	ext_flash_erase_logbook				; erases logbook memory (000000h -> 2FFFFFh -> 3MByte)
-	extern	ext_flash_erase4kB					; erases 4kB sector @ext_flash_address:3
+
+; Erase:
+	extern	ext_flash_erase_4kB					; erase one 4 kB sector @ext_flash_address:3
+	extern	erase_complete_logbook				; erase complete logbook (FLASH and EEPROM)
 
-; Reads
-	extern	ext_flash_read_block_start			; block read start and reads one byte@ext_flash_address:3 into WREG
-	extern	ext_flash_read_block				; read another byte into WREG
-	extern	ext_flash_read_block_stop			; stop block read
-	extern	ext_flash_byte_read					; read one byte@ext_flash_address:3 into WREG and ext_flash_rw 
-	extern	ext_flash_byte_read_plus			; return data read in WREG and ext_flash_rw and increase address after read with banking at 0x200000
-	extern	ext_flash_byte_read_plus_0x20		; return data read in WREG and ext_flash_rw
+
+; Protection:
+	extern	ext_flash_enable_protection			; enable  write protection
+	extern	ext_flash_disable_protection		; disable write protection
+
 
 
 ;-----------------------------------------------------------------------------
 ; Macros
+;-----------------------------------------------------------------------------
 
-; decrease ext_flash_address:2 by the 8 bit value "ext_flash_temp1"
-	extern	decf_ext_flash_address0
-decf_ext_flash_address	macro	ext_flash_temp1
-		movlw	ext_flash_temp1
-		call	decf_ext_flash_address0
+
+; read 1 byte from FLASH to WREG with address auto-increment and wrap-around at 0x200000
+;
+; the byte read is also copied to ext_flash_rw
+;
+FLASH_CW_READ_0x20	macro
+	extern	ext_flash_byte_read_plus_0x20
+	call	ext_flash_byte_read_plus_0x20
+	endm
+
+
+; read 1 byte from FLASH to memory with address auto-increment and wrap-around at 0x200000
+;
+; mem_address: address:2 containing target address in memory
+;
+FLASH_CC_READ_0x20	macro	mem_address
+	extern	ext_flash_byte_read_plus_0x20
+	call	ext_flash_byte_read_plus_0x20		; read from flash
+	movff	WREG,mem_address					; copy to   memory
+	endm
+
+
+; read 2 bytes from FLASH to memory with address auto-increment and wrap-around at 0x200000
+;
+; mem_address: address:2 containing start address in memory
+;
+FLASH_II_READ_0x20	macro	mem_address
+	extern	ext_flash_byte_read_plus_0x20
+	call	ext_flash_byte_read_plus_0x20		; read 1st byte from flash
+	movff	WREG,mem_address+0					; copy 1st byte to   memory
+	call	ext_flash_byte_read_plus_0x20		; read 2nd byte from flash
+	movff	WREG,mem_address+1					; copy 2nd byte to   memory
 	endm
 
-; increase ext_flash_address:2 by the 8 bit value "ext_flash_temp1"
-	extern	incf_ext_flash_address0
-incf_ext_flash_address	macro	ext_flash_temp1
-		movlw	ext_flash_temp1
-		call	incf_ext_flash_address0
+
+; read a range of data from FLASH to memory (destroys WREG, FSR1) - wraps around at 0x400000
+;                                                                 - increments ext_flash_address
+; flash_start : address:3 containing start address in flash
+; memory_start: address:2 containing start address in memory
+; range       : literal:1 giving the number of bytes to read (1-256)
+;
+FLASH_RR_READ		macro	flash_start, memory_start, range
+	MOVTT	flash_start,ext_flash_address			; set start address in FLASH
+	lfsr	FSR1,memory_start						; set start address in memory
+	movlw	low(range)								; set size of range to read
+	extern	ext_flash_read_range
+	call	ext_flash_read_range					; execute range-read
+	endm
+
+
+; write a range of data from memory to FLASH (destroys WREG, FSR1) - Attention: range must fit into a 256 byte block!
+;                                                                  - does not increment ext_flash_address!
+; memory_start: address:2 containing start address in memory
+; flash_start : address:3 containing start address in flash
+; range       : literal:1 giving the number of bytes to write (1-256)
+;
+FLASH_RR_WRITE		macro	memory_start, flash_start, range
+	lfsr	FSR1,memory_start						; set start address in memory
+	MOVTT	flash_start,ext_flash_address			; set start address in FLASH
+	movlw	low(range)								; set size of range to read
+	extern	ext_flash_write_range
+	call	ext_flash_write_range					; execute range-write
 	endm
 
-; increase ext_flash_address:2 by the 8 bit value "ext_flash_temp1" with banking at 0x200000
-	extern	incf_ext_flash_address0_0x20
-incf_ext_flash_address_0x20	macro	ext_flash_temp1
-		movlw	ext_flash_temp1
+
+; move forward in FLASH with wrap-around at 0x400000 to 0x000000
+;
+; increment: literal (1-255)
+;
+ext_flash_inc_address_0x40		macro	increment
+		movlw	increment
+		extern	incf_ext_flash_address0_0x40
+		call	incf_ext_flash_address0_0x40
+	endm
+
+
+; move forward in FLASH with wrap-around at 0x200000 to 0x000000
+;
+; increment: literal (1-255)
+;
+ext_flash_inc_address_0x20		macro	increment
+		movlw	increment
+		extern	incf_ext_flash_address0_0x20
 		call	incf_ext_flash_address0_0x20
 	endm
+
+
+; decrement length count
+;
+; decrement: literal (1-255)
+;
+ext_flash_dec_length			macro	decrement
+		movlw	decrement
+		extern	decf_ext_flash_length0
+		call	decf_ext_flash_length0
+	endm
--- a/src/gaslist.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/gaslist.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File gaslist.asm                          combined next generation V3.03.5
+;   File gaslist.asm                          combined next generation V3.08.8
 ;
 ;   Managing OSTC gas list
 ;
@@ -20,7 +20,7 @@
 #include "rx_ops.inc"
 
 
-	extern	convert_mbar_to_feet
+	extern	convert_meter_to_feet
 	extern	tSetup_GasDepth
 	extern	tGasDisabled
 	extern	tDilDisabled
@@ -28,6 +28,13 @@
 	extern	tbar10
 	extern	tbar
 
+ IFDEF _cave_mode
+	extern	cavemode_waypoint_set_check
+	extern	cavemode_waypoint_out_check
+	extern	cavemode_waypoint_in_check
+	extern	cavemode_turndive_check
+ ENDIF
+
 
 gaslist	CODE
 
@@ -36,12 +43,14 @@
 ;=============================================================================
 ; Helper Functions for divemenu_tree.asm
 ;
-; They need to be put in a different file than
-; where the MENU_DYNAMIC macros uses them.
+; These functions need to be placed in a different
+; file than where the MENU_DYNAMIC macros use them.
 
-	global	do_toggle_gf_label
-do_toggle_gf_label:
-	movff	char_I_deco_model,WREG		; 0 = ZH-L16, 1 = ZH-L16-GF
+;-----------------------------------------------------------------------------
+
+	global	label_do_toggle_gf
+label_do_toggle_gf:
+	movff	char_I_model,WREG			; 0 = ZH-L16, 1 = ZH-L16-GF
 	decfsz	WREG,W						; toggle GF only in GF modes - in GF mode?
 	bra		do_toggle_gf_label_1		; NO - print in disabled color
 	movff	opt_enable_aGF,WREG			; =1: aGF can be selected underwater
@@ -49,27 +58,68 @@
 	bra		do_toggle_gf_label_1		; NO - print in disabled color
 	bra		do_toggle_gf_label_2		; YES to both - print in standard color
 do_toggle_gf_label_1:
-	call	TFT_disabled_color
+	call	TFT_disabled_color			; print in disabled color
 do_toggle_gf_label_2:
-	STRCAT_TEXT tDivemenu_ToggleGF
-	return
+	STRCAT_TEXT tDivemenu_ToggleGF		; output label
+	return								; done
+
 
-;=============================================================================
+	global	label_do_gas6_or_exit
+label_do_gas6_or_exit:
+	btfsc	gas6_or_EXIT				; shall print exit?
+	bra		label_do_gas6_or_exit_1		; YES - print exit  label
+	STRCAT_TEXT tGas6					; NO  - print gas 6 label
+	return								;     - done
+label_do_gas6_or_exit_1:
+	STRCAT_TEXT tExit					; print exit label
+	return								; done
+
+;-----------------------------------------------------------------------------
 
  IFDEF _cave_mode
 
-	global	do_turn_dive_label
-do_turn_dive_label:
+	global	label_do_turn_dive
+label_do_turn_dive:
+	call	cavemode_turndive_check		; check if command is allowed
+	tstfsz	WREG						; command allowed?
+	call	TFT_disabled_color			; NO - switch to disabled color
 	btfss	cave_mode					; cave mode switched on?
-	call	TFT_disabled_color			; NO  - print in disabled color
-	btfsc	dive_turned					; dive already turned?
-	call	TFT_attention_color			; YES - print in attention color
-	STRCAT_TEXT tDivemenu_TurnDive		; output label
-	return
+	bra		label_do_turn_dive_1		; NO  - print turn dive label
+	btfss	dive_turned					; YES - dive turned?
+	bra		label_do_turn_dive_1		;       NO  - print turn dive label
+	STRCAT_TEXT tDivemenu_ContDive		;       YES - print continue dive label
+	return								;           - done
+label_do_turn_dive_1:
+	STRCAT_TEXT tDivemenu_TurnDive		; print turn dive label
+	return								; done
+
+	global	label_do_wp_set
+label_do_wp_set:
+	call	cavemode_waypoint_set_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	call	TFT_disabled_color			; NO - switch to disabled color
+	STRCAT_TEXT tDivemenu_wp_set		; print label
+	return								; done
+
+	global	label_do_wp_out
+label_do_wp_out:
+	call	cavemode_waypoint_out_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	call	TFT_disabled_color			; NO - switch to disabled color
+	STRCAT_TEXT tDivemenu_wp_out		; print label
+	return								; done
+
+	global	label_do_wp_in
+label_do_wp_in:
+	call	cavemode_waypoint_in_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	call	TFT_disabled_color			; NO - switch to disabled color
+	STRCAT_TEXT tDivemenu_wp_in			; print label
+	return								; done
 
  ENDIF
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
  IFDEF _rx_functions
 
@@ -87,7 +137,7 @@
 
  ENDIF
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
  IFDEF _ccr_pscr
 
@@ -177,8 +227,8 @@
 
 	global	gaslist_strcat_gas6
 gaslist_strcat_gas6:					; show current O2/He mix
-	STRCAT_TEXT tGas					; print "Gas"
-	STRCAT	": "						; print ":"
+	STRCAT_TEXT tTakeGas				; print "take"
+	PUTC	" "							; print one space
 	movff	gas6_O2_ratio,hi			; TFT_color_code_gaslist needs O2 ratio in hi
 	call	TFT_color_code_gaslist		; color-code according to O2 ratio and depth
 	movff	gas6_O2_ratio,lo			; gaslist_show_mix needs O2 ratio in lo
@@ -227,23 +277,18 @@
 
 	global	gaslist_toggle_type
 gaslist_toggle_type:
-	movf	gaslist_gas,W
 	lfsr	FSR1,opt_gas_type			; load base address of opt_gas_type
-	movff	PLUSW1,lo					; read gas type
-	incf	lo,F						; increment type
+	movf	gaslist_gas,W				; copy gas number (0-9) to WREG
+	movff	PLUSW1,lo					; read      type value
+	incf	lo,F						; increment type value
+	movlw	num_gas_types				; get number of gas types by default
 	btfsc	is_diluent_menu				; setting up diluents?
-	bra		gaslist_toggle_type2		; YES - diluents
-	btfsc	lo,2						; NO  - gases, type index > 3 ?
-	clrf	lo							;       YES - clear to zero
-	movff	lo,PLUSW1					;     - copy back result
-	return
-gaslist_toggle_type2:
-	movlw	.3
-	cpfslt	lo							; index > 2 ?
-	clrf	lo							; YES - clear to zero
-	movf	gaslist_gas,W				; restore gaslist_gas in WREG
+	movlw	num_dil_types				; YES - replace by number of diluent types
+	cpfslt	lo							; type value valid?
+	clrf	lo							; NO - clear to zero
+	movf	gaslist_gas,W				; restore gas number (0-9) in WREG
 	movff	lo,PLUSW1					; copy back result
-	return
+	return								; done
 
 ;=============================================================================
 
@@ -305,27 +350,29 @@
 ; NOTE: used in the menu-tree for the MENU_CALLBACK entry
 
 	global	gaslist_strcat_gas_cd
-	global	gaslist_gastitle
 gaslist_strcat_gas_cd:					; entry point with gas in PRODL (0-4) and flag 'is_diluent_menu' set accordingly
 	movff	PRODL,gaslist_gas			; get current menu item (0-4)
 	movlw	.5							; offset between gases and diluents
-	btfsc	is_diluent_menu				; setting up diluents?
+	btfsc	is_diluent_menu				; dealing with diluents?
 	addwf	gaslist_gas,F				; YES - add the offset
+	;bra	gaslist_gastitle			; continue with gaslist_gastitle function
+
+	global	gaslist_gastitle
 gaslist_gastitle:						; entry point with gas/dil in gaslist_gas (0-4 for gases, 5-9 for diluents)
 	bcf		win_invert					; clear flag for inverted output by default
 	btfsc	short_gas_descriptions		; shall use short versions of gaslist_strcat_gas_cd?
 	bra		gaslist_gastitle1			; YES - use short version
 	incf	gaslist_gas,W				; (0-9) -> (1-10) into WREG
-	movwf	lo
+	movwf	lo							; copy gas index to lo
 	movlw	.6							; diluents start with 6
 	cpfslt	lo							; gas number < 6 ?
 	bra		gaslist_gastitle_dil		; NO  - it's a diluent
 	STRCAT_TEXT tGas					; YES - it's a gas
-	bra		gaslist_gastitle0
+	bra		gaslist_gastitle0			;     - continue
 gaslist_gastitle_dil:
-	STRCAT_TEXT tDil
+	STRCAT_TEXT tDil					; it's a diluent
 	movlw	.5							; offset between gases and diluents
-	subwf	lo,F						; subtract offset from diluent number (6-10) -> (1-5)
+	subwf	lo,F						; subtract offset from diluent number (6-10) -> (1-5) again
 gaslist_gastitle0:
 	bsf		leftbind
 	output_8							; print gas/dil number (1-5)
@@ -353,20 +400,27 @@
 gaslist_gastitle3:
 	call	TFT_standard_color
 	btfsc	divemode					; in dive mode?
-	rcall	gaslist_strcat_gas_better	; YES - check if this is a "better gas"
+	rcall	gaslist_strcat_gas_better	; YES - check if this is a "better gas", if yes switch to green and inverted output
 	lfsr	FSR1,opt_gas_type			; load base address of gas types
 	movf	gaslist_gas,W				; load index into WREG (0-4 for gases, 5-9 for diluents)
 	movf	PLUSW1,W					; read gas/dil type into WREG
-	bnz		gaslist_gastitle4			; type = disabled? NO  - keep color
-	call	TFT_disabled_color			;                  YES - switch color to disabled
-	bra		gaslist_gastitle5			;                      - skip ppO2 check for disabled gases
+	btfsc	WREG,gas_lost				; gas/dil lost?
+	bra		gaslist_gastitle3a			; YES - switch to disabled color
+	btfsc	WREG,gas_staged				; gas/dil staged?
+	bra		gaslist_gastitle3a			; YES - switch to disabled color
+	bnz		gaslist_gastitle4			; type = disabled ?
+gaslist_gastitle3a:
+	call	TFT_disabled_color			; YES - switch to disabled color
+	bra		gaslist_gastitle5			;     - skip ppO2 check for disabled gases
 gaslist_gastitle4:
 	btfss	divemode					; in dive mode?
-	bra		gaslist_gastitle5			; NO  - no ppO2 check if not in dive mode
-	lfsr	FSR1,opt_gas_O2_ratio		; YES - load base address of opt_gas_O2_ratio
-	movf	gaslist_gas,W				;     - load index into WREG (0-4 for gases, 5-9 for diluents)
-	movff	PLUSW1,hi					;     - read O2 ratio into hi
-	call	TFT_color_code_gaslist		;     - set color according to ppO2 limits
+	bra		gaslist_gastitle5			; NO  - no color-coding if not in dive mode
+	btfss	color_code_gases			; YES - shall color-code the gases by ppO2 and current depth?
+	bra		gaslist_gastitle5			;       NO  - skip color-coding
+	lfsr	FSR1,opt_gas_O2_ratio		;       YES - load base address of opt_gas_O2_ratio
+	movf	gaslist_gas,W				;           - load index into WREG (0-4 for gases, 5-9 for diluents)
+	movff	PLUSW1,hi					;           - read O2 ratio into hi
+	call	TFT_color_code_gaslist		;           - set color according to ppO2 limits
 gaslist_gastitle5:
 	movf	gaslist_gas,W				; copy gas/dil index to WREG (0-9)
 	rcall	gaslist_strcat_gas_WREG		; print gas composition
@@ -384,11 +438,7 @@
 	TSTOSS	opt_units					; check depth units
 	bra		gaslist_strcat_depth_metric	; 0 - use Meters
 gaslist_strcat_depth_imperial:			; 1 - use Feet
-	movf	lo,W
-	mullw	.100						; convert meters to mbar
-	movff	PRODL,lo
-	movff	PRODH,hi
-	call	convert_mbar_to_feet		; convert value in lo:hi from mbar to feet
+	call	convert_meter_to_feet		; convert value in lo from [m] to [feet]
 	output_16_3							; limit to 999 and display only 0-999
 	STRCAT_TEXT tFeets					; append "ft"	REMARK: still one char to long for space available in dive mode menu!
 	return
@@ -427,7 +477,14 @@
 gaslist_strcat_gas_type:
 	lfsr	FSR1,opt_gas_type			; load base address of gas types
 	movf	gaslist_gas,W				; load index to WREG (0-4 for gases, 5-9 for diluents)
-	decf	PLUSW1,W					; get and decrement gas type (-1 for disabled,  0 for first,  1 for work/normal, 2 for deco)
+	movf	PLUSW1,W					; get gas/dil type into WREG
+	btfsc	WREG,gas_lost				; gas set as lost?
+	bra		gaslist_strcat_gas_type_4	; YES - print lost marking
+ IFDEF _cave_mode
+	btfsc	WREG,gas_staged				; gas set as staged?
+	bra		gaslist_strcat_gas_type_5	; YES - print staged marking
+ ENDIF
+	decf	WREG,W						; decrement gas type (-1 for disabled,  0 for first,  1 for work/normal, 2 for deco)
 	bnz		gaslist_strcat_gas_type_1	; type = first? NO  - continue with checking for work and deco gas
 	PUTC	"*"							;               YES - print "*" for first
 	return								;                   - done
@@ -443,7 +500,15 @@
 	return								;                   - done
 gaslist_strcat_gas_type_3:
 	PUTC	" "							; neither first nor deco, print a space
-	return
+	return								; done
+gaslist_strcat_gas_type_4:
+	PUTC	"x"							; print lost marking
+	return								; done
+ IFDEF _cave_mode
+gaslist_strcat_gas_type_5:
+	PUTC	"S"							; print staged marking
+	return								; done
+ ENDIF
 
 
 ;----------------------------------------------------------------------------
@@ -492,7 +557,6 @@
  ENDIF
 	movlw	.1							;           - load coding for first gas
 	movwf	INDF1						;           - make gas/dil 1 the first gas
-	bsf		option_repaired				;           - flag that an option was repaired
 	return								;           - done
 gaslist_cleanup_list4:
 	movlw	.1							; total number of Firsts that should exist is 1
@@ -509,7 +573,6 @@
 	addlw	.5							; YES - adjust offset
  ENDIF
 	clrf	PLUSW1						; disable gas
-	bsf		option_repaired				; flag that an option was repaired
 	bra		gaslist_cleanup_list0		; redo from start until only one "first" is left over
 	return
 
--- a/src/gaslist.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/gaslist.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File gaslist.inc                          combined next generation V3.03.1
+;   File gaslist.inc                          combined next generation V3.08.7
 ;
 ;   Interface to OSTC gas list management.
 ;
@@ -14,12 +14,30 @@
 	extern	gaslist_strcat_gas_WREG
 	extern	gaslist_strcat_gas_cd
 	extern	gaslist_show_mix				; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2
-	extern	do_toggle_gf_label
+	extern	label_do_toggle_gf
+	extern	label_do_gas6_or_exit
+	extern	gaslist_gastitle
+
+	; Main Gaslist Menu
+	extern	gaslist_pO2
+	extern	gaslist_mO2
+	extern	gaslist_GasDepth
+	extern	gaslist_show_type
+	extern	gaslist_toggle_type
+	extern	gaslist_cleanup_list
 
- IFDEF _cave_mode
-	extern	do_turn_dive_label
- ENDIF
+	; Depth Sub-Menu
+	extern	gaslist_pDepth
+	extern	gaslist_mDepth
+	extern	gaslist_MOD_END
+	extern	gaslist_ppo2
+	extern	gaslist_reset_mod_title
+	extern	gaslist_reset_mod
 
+	; Tank Sub-Menu
+	extern	gaslist_tank_size_pres
+	extern	gaslist_tank_size
+	extern	gaslist_tank_pres
 
 	; Setpoints and Diluents
  IFDEF _ccr_pscr
@@ -30,39 +48,21 @@
 	extern	gaslist_copy_dil_to_oc
  ENDIF
 
-
-	; Select currently edited Gas
-	extern	gaslist_gastitle
-
-
-	; Main Gaslist Menu
-	extern	gaslist_pO2
-	extern	gaslist_mO2
-	extern	gaslist_GasDepth
-	extern	gaslist_show_type
-	extern	gaslist_toggle_type
-	extern	gaslist_cleanup_list
-
+	; Helium Editing
  IFDEF _helium
 	extern	gaslist_pHe
 	extern	gaslist_mHe
  ENDIF
 
+	; Cave Mode
+ IFDEF _cave_mode
+	extern	label_do_turn_dive
+	extern	label_do_wp_set
+	extern	label_do_wp_out
+	extern	label_do_wp_in
+ ENDIF
 
-	; Depth Sub-Menu
-	extern	gaslist_pDepth
-	extern	gaslist_mDepth
-	extern	gaslist_MOD_END
-	extern	gaslist_ppo2
-	extern	gaslist_reset_mod_title
-	extern	gaslist_reset_mod
-
-
-	; Tank Sub-Menu
-	extern	gaslist_tank_size_pres
-	extern	gaslist_tank_size
-	extern	gaslist_tank_pres
-
+	; RX Functions
  IFDEF _rx_functions
 	extern	gaslist_tank_id_pres
 	extern	gaslist_tank_pairing
--- 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
--- a/src/hwos.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/hwos.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File hwos.asm                             combined next generation V3.06.1
+;   File hwos.asm                             combined next generation V3.08.8
 ;
 ;   Definition of the hwOS dive computer platform.
 ;
@@ -83,7 +83,6 @@
 apnoe_dive_mins					res 1		; dive    time minutes        | Attention: do not change the position of
 apnoe_dive_secs					res 1		; dive    time seconds        | these 2 Variables relative to each other!
 
-
 ;---- Profile Recording
 sampling_rate					res 1		; configured sampling rate
 sampling_timer					res 1		; sampling timer
@@ -102,6 +101,7 @@
 ; ==
 ; 80 byte used, 16 byte free (96 byte total available)
 
+
 	global	HW_descriptor
 	global	HW_variants
 	global	HW_flags_state1
@@ -269,20 +269,22 @@
 	movwf	ADCON0
 	movlw	b'00100000'			; 2.048V Vref+
 	movwf	ADCON1
-	movlw	b'10111010'			; right aligned, 20 x T_AD acquisition time, FOSC/32 -> Max. 40MHz device clock speed
+	movlw	b'10111010'			; right aligned, 20 x T_AD acquisition time, FOSC/32 -> max. 40 MHz device clock speed
 	movwf	ADCON2
 
 
 ; serial Port 1 (TRISC6/7)
-	movlw	b'00001000'			; BRG16=1
-	movwf	BAUDCON1
-	movlw	.34					; SPBRGH:SPBRG =  .34 : 114285 BAUD @ 16MHz (+0.79% Error at 115200 BAUD)
-	movwf	SPBRG1				; SPBRGH:SPBRG = .207 :  19230 BAUD @ 16MHz (-0.16% Error at  19200 BAUD)
-	clrf	SPBRGH1				;
+	movlw	b'00001000'			; switch baud generator to 16 bit mode (BRG16=1)
+	movwf	BAUDCON1			; ...
+								; SPBRGH:SPBRG =  .34 : 114285 BAUD @ 16MHz (+0.79% error at 115200 baud)
+								; SPBRGH:SPBRG = .207 :  19230 BAUD @ 16MHz (-0.16% error at  19200 baud)
+	movlw	.34					; select 114285 baud (low byte)
+	movwf	SPBRG1				; ...
+	clrf	SPBRGH1				; ...                (high byte)
 
-	clrf	RCSTA1
-	clrf	TXSTA1				; UART disable
-	bcf		PORTC,6				; TX hard to GND
+	clrf	RCSTA1				; disable UART RX
+	clrf	TXSTA1				; disable UART TX
+	bcf		PORTC,6				; tie TX output hard to GND
 
 
 ; serial Port 2 (TRISG2) for IR/S8 digital interface
@@ -434,28 +436,27 @@
 	global	backup_flash_page
 backup_flash_page:
 	banksel	common
-	movlw	0x00					; start address in internal program memory
-	movwf	TBLPTRL
-	movwf	TBLPTRH
-	movwf	TBLPTRU
+
+	; set start address in internal program memory
+	movlw	0x00					; set 0x000000
+	movwf	TBLPTRL					; ...
+	movwf	TBLPTRH					; ...
+	movwf	TBLPTRU					; ...
+	TBLRD*-							; dummy read to be in 128 byte block
+
+	; set start address in EEPROM
+	EEPROM_SET_ADDRESS eeprom_prog_page0_backup
 
 	movlw	.128					; copy 1 block = 128 byte
-	movwf	lo						; byte counter
-
-	clrf	EEADR					; start address in EEPROM, low
-	movlw	.3						; start address in EEPROM, high
-	movwf	EEADRH
-
-	TBLRD*-							; dummy read to be in 128 byte block
+	movwf	eeprom_loop				; initialize loop counter
 backup_flash_loop:
 	tblrd+*							; read one byte from program memory (with pre-increment)
 	movff	TABLAT,EEDATA			; transfer byte from program memory read to EEPROM write
-	call	write_eeprom			; execute EEPROM write
+	call	write_eeprom			; execute   EEPROM write
 	incf	EEADR,F					; increment EEPROM address
-	decfsz	lo,F					; 128 byte done?
+	decfsz	eeprom_loop,F			; all 128 byte done?
 	bra		backup_flash_loop		; NO  - loop
-	clrf	EEADRH					; YES - reset EEPROM high address
-	return							;     - done
+	return							; YES - done
 
 ;=============================================================================
 ; Restore the first 128 bytes from EEPROM to program memory
@@ -463,42 +464,59 @@
 	global	restore_flash
 restore_flash:
 	banksel	common
-	movlw	0x00					; start address in internal program memory
-	movwf	TBLPTRL
-	movwf	TBLPTRH
-	movwf	TBLPTRU
+
+	;set start address in internal program memory
+	movlw	0x00					; set 0x000000
+	movwf	TBLPTRL					; ...
+	movwf	TBLPTRH					; ...
+	movwf	TBLPTRU					; ...
+	TBLRD*-							; dummy read to be in 128 byte block
 
 	movlw	b'10010100'				; setup   block erase
 	rcall	restore_write			; execute block erase
 
-	movlw	.128					; copy 1 block = 128 byte
-	movwf	lo						; byte counter
+	; set start address in EEPROM
+	EEPROM_SET_ADDRESS eeprom_prog_page0_backup
 
-	clrf	EEADR					; start address in EEPROM, low
-	movlw	.3						; start address in EEPROM, high
-	movwf	EEADRH
-
-	TBLRD*-							; dummy read to be in 128 byte block
+	movlw	.128					; copy 1 block = 128 byte
+	movwf	eeprom_loop				; initialize loop counter
 restore_flash_loop:
-	call	read_eeprom				; read one byte from EEPROM
+	call	read_eeprom				; execute   EEPROM read
 	incf	EEADR,F					; increment EEPROM address
 	movff	EEDATA,TABLAT			; transfer byte from EEPROM read to program memory write
 	tblwt+*							; execute program memory write (with pre-increment)
-	decfsz	lo,F					; 128 bytes done?
-	bra		restore_flash_loop		; NO - loop
+	decfsz	eeprom_loop,F			; all 128 bytes done?
+	bra		restore_flash_loop		; NO  - loop
 	movlw	b'10000100'				; YES - setup   block write
 	rcall	restore_write			;     - execute block write
 	reset							;     - done, reset CPU
 
 restore_write:
-	movwf	EECON1					; type of memory to write in
-	movlw	0x55
-	movwf	EECON2
-	movlw	0xAA
-	movwf	EECON2
-	bsf		EECON1,WR				; execute write
-	nop
-	nop
-	return
+	movwf	EECON1					; configure operation
+	movlw	0x55					; unlock sequence
+	movwf	EECON2					; ...
+	movlw	0xAA					; ...
+	movwf	EECON2					; ...
+	bsf		EECON1,WR				; execute operation
+	nop								; wait for operation to complete
+	nop								; ...
+	return							; done
+
+;=============================================================================
+; Memory clear and move functions, to be used through macros
+;
+	global	memory_clear
+memory_clear:
+	clrf	POSTINC1				; clear address
+	decfsz	WREG					; decrement loop counter, became zero?
+	bra		memory_clear			; NO  - loop
+	return							; YES - done
+
+	global	memory_move
+memory_move:
+	movff	POSTINC1,POSTINC2		; copy from-to
+	decfsz	WREG					; decrement loop counter, became zero?
+	bra		memory_move				; NO  - loop
+	return							; YES - done
 
 	END
\ No newline at end of file
--- a/src/hwos.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/hwos.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File hwos.inc                             combined next generation V3.06.2
+;   File hwos.inc                             combined next generation V3.08.8
 ;
 ;   OSTC Platform Definitions
 ;
@@ -30,7 +30,7 @@
 
 
 ; Magic Cookie Definition
-#DEFINE comm_service_key		0xABCDEF	; simsalabim to establish data connection
+#DEFINE comm_service_key		0xABCDEF	; simsalabim to establish comm service mode
 
 
 ; Logo Address Vectors
@@ -41,7 +41,8 @@
 
 ;-----------------------------EEPROM DATA ------------------------------------
 ; Automatic reset of all options when this is changed:
-#DEFINE eeprom_opt_serial		0x0008		; Version 0.8
+#DEFINE eeprom_opt_version				.8		; range: 16 bit
+#DEFINE eeprom_vault_version			.1		; range:  8 bit
 ;-----------------------------------------------------------------------------
 
 
@@ -62,6 +63,7 @@
 
 
 ; Divemode Custom View Indexes - Attention: these numbers need to be in line with the jump tables in customview.asm!
+#DEFINE index_blank						 .0			; blank view
 #DEFINE index_avr_stopwatch				 .1			; average depth and stopwatch
 #DEFINE index_compass_dm				 .2			; compass
 #DEFINE index_ppo2_sensors				 .3			; ppO2 sensors
@@ -69,19 +71,21 @@
 #DEFINE index_pscr_info					 .5			; pSCR data
 #DEFINE index_pressures_SAC				 .6			; tank pressure and SAC rate
 #DEFINE index_gas_needs_ascent			 .7			; gas needs for ascent / cave return
-#DEFINE index_decoplan					 .8			; deco plan
-#DEFINE index_ceiling_GF_tissue			 .9			; ceiling, current GF and tissues
-#DEFINE index_CNS						.10			; CNS values
-#DEFINE index_ppo2_ead_end_cns			.11			; ppO2, END/EAD and CNS or gas density
-#DEFINE index_gf_factors				.12			; GF factors
+#DEFINE index_cave_tts					 .8			; cave mode TTS
+#DEFINE index_decoplan					 .9			; deco plan
+#DEFINE index_ceiling_GF_tissue			.10			; ceiling, current GF and tissues
+#DEFINE index_CNS						.11			; CNS values
+#DEFINE index_ppo2_ead_end_cns			.12			; ppO2, END/EAD and CNS or gas density
 #DEFINE index_clock_batt_surfpress		.13			; clock, battery and surface pressure
-#DEFINE index_cv_dm_max					.13			; highest index in use in dive mode custom view
+#DEFINE index_gf_factors				.14			; GF factors
+#DEFINE index_cave_waypoints			.15			; cave waypoints
+#DEFINE index_cv_dm_max					.13			; highest index used in normal custom view rotation
 
 
 ; Timing for button hold-down flags
-#DEFINE TMR1H_VALUE_FIRST				.255-.128	; in steps of 7.8125 ms -> 1    s
+#DEFINE TMR1H_VALUE_FIRST				.255-.128	; in steps of 7.8125 ms -> 1.00 s
 #DEFINE TMR1H_VALUE_CONT				.255-.32	; in steps of 7.8125 ms -> 0.25 s
-#DEFINE TMR1H_VALUE_CONT_DIVE			.255-.64	; in steps of 7.8125 ms -> 0.5  s
+#DEFINE TMR1H_VALUE_CONT_DIVE			.255-.64	; in steps of 7.8125 ms -> 0.50 s
 
 
 ; Color Definitions: 8 bit RGB b'RRRGGGBB'
@@ -119,7 +123,7 @@
 
 
 ; Profile Recording Parameters
-#DEFINE logbook_profile_version			0x24
+#DEFINE logbook_profile_version			0x24		; logbook recording format
 #DEFINE samplingrate_apnoe				.1			; [seconds]
 
 
@@ -155,11 +159,12 @@
 #DEFINE tr_pres_options					.6			; number of options for pressure measurement source / OC gases only
  ENDIF
 
+
 ; Cave Mode 
  IFDEF _cave_mode
-#DEFINE calc_gas_options				.3			; 3 options: off, on, cave
- ELSE
-#DEFINE calc_gas_options				.2			; 2 options: off, on
+#DEFINE backtrack_waypoint_max			.30			; highest user-available waypoint number (max allowed: 30)
+#DEFINE backtrack_almost_full_threshold	.240		; backtrack index position at which the almost   full flag will be set
+#DEFINE backtrack_entire_full_threshold	.250		; backtrack index position at which the entirely full flag will be set
  ENDIF
 
 
@@ -171,20 +176,31 @@
 
 
 ; Timeouts for Menus
-#DEFINE surfmode_timeout_default		.90			; [s] default timeout for surface mode and surface menus
-#DEFINE surfmode_timeout_simulator		.240		; [s] special timeout for simulator (deco calculator) mode
-#DEFINE surfmode_timeout_sensor			.240		; [s] special timeout for surface mode when in CCR/pSCR sensor mode
-#DEFINE surfmode_timeout_calibrate		.240		; [s] special timeout when in surface CCR calibrate sensors menu
-#DEFINE surfmode_timeout_xmitter		.240		; [s] special timeout when in surface transmitter pairing menu
+#DEFINE surfmode_timeout_default		.240		; [s] default timeout for surface mode and surface menus
+#DEFINE surfmode_timeout_aa_15v			.90			; [s] timeout for surface mode and surface menus when on 1.5V battery
+#DEFINE surfmode_timeout_simulator		.240		; [s] special timeout for simulator mode
+;#DEFINE surfmode_timeout_sensor		.240		; [s] special timeout for surface mode when in CCR/pSCR sensor mode
+;#DEFINE surfmode_timeout_calibrate		.240		; [s] special timeout when in surface CCR calibrate sensors menu
+;#DEFINE surfmode_timeout_xmitter		.240		; [s] special timeout when in surface transmitter pairing menu
 
 #DEFINE divemode_timeout_premenu		.10			; [s] timeout for dive mode pre-menu
 #DEFINE divemode_timeout_mainmenu		.30			; [s] timeout for dive mode main menu
 
 
+; RS232 Timeout
+#DEFINE rx_timeout						.400		; [ms] timeout for RS232 RX
+
+
+; Dive-End Timeouts
+#DEFINE simulator_timeout_normal		.90			; [min] timeout simulator mode
+#DEFINE simulator_timeout_cave			.240		; [min] timeout simulator mode (cave mode)
+#DEFINE apnoe_timeout					.15			; [min] timeout at surface in apnoe mode
+#DEFINE simulator_timeout				.15			; [s]   timeout at surface in simulator mode
+
+
 ; other Timeouts
-#DEFINE simulator_timeout				.15			; [s]
-#DEFINE apnoe_timeout					.15			; [min]
-#DEFINE	deep_sleep_10mins				.144		; [x 10mins] (24h in this example)
+#DEFINE deep_sleep_10mins				.144		; [x 10mins] (24h in this example)
+
 
 ; Surface Mode Thresholds and Limits
 #DEFINE high_altitude_threshold			.880		; [mbar] ambient pressure at which to switch into high altitude mode
@@ -206,6 +222,11 @@
 #DEFINE sensor_voting_logic_threshold	.10			; threshold in 0.01 bar
 
 
+; Gas and Dil types
+#DEFINE num_gas_types					.4			; Disabled, First, Normal, Deco
+#DEFINE num_dil_types					.3			; Disabled, First, Normal
+
+
 ; ppO2 Limits
 #DEFINE ppo2_warning_low_lowest			.15			; [cbar] minimum value for minimum ppO2 on OC
 #DEFINE ppo2_warning_low_default		.17			; [cbar] default value for minimum ppO2 on OC
@@ -229,6 +250,9 @@
 #DEFINE ppo2_warning_deco_highest		.160		; [cbar] maximum value for maximum ppO2 in deco phase
  ENDIF
 
+; Salinity Limits
+#DEFINE salinity_min					.0			; [%] minimum value for salinity percentage
+#DEFINE salinity_max					.4			; [%] maximum value for salinity percentage
 
 ; Color-Code Parameters for the Dive Mode
 #DEFINE color_code_velocity_warn_high	.11			; [m/min]
@@ -252,7 +276,7 @@
 #DEFINE aa_15v_low						.1100		; [mV] Energizer 1.5 V E2 AA - lowest  possible voltage, according to Energizer data sheet EBC-4201R, page 2
 #DEFINE battery_show_level				.30			; [%]  threshold when to show battery level
 #DEFINE battery_warn_level_36			.15			; [%]  threshold for 3.6 V battery warning, also acts as threshold for setting display brightness level to ECO when in dive mode
-#DEFINE battery_warn_level_15			.25			; [%]  threshold for 1.5 V battery warning, also acts as threshold for setting display brightness level to ECO when in dive modebattery warning level, also acts as threshold for setting display brightness level to ECO when in dive mode
+#DEFINE battery_warn_level_15			.25			; [%]  threshold for 1.5 V battery warning, also acts as threshold for setting display brightness level to ECO when in dive mode
 
 
 ; 3.6 Volt Battery Sensing Data Points at 70 mA Load
@@ -311,21 +335,34 @@
 
 
 ; IR Link Timeout
-#DEFINE ir_timeout_value				.128			; in multiples of 62.5 ms
+#DEFINE ir_timeout_value				.128		; in multiples of 62.5 ms
 
 
 ; Setpoint Control
 #DEFINE surface_sp						.50			; in cbar
 
 
+; Gas / Diluent Type & State
+;										.0			; | 0: disabled, 1: first, 2: normal/work, 3: deco
+;										.1			; |
+#DEFINE gas_lost						.2			; =1: gas/diluent is lost   (permanently unavailable)
+#DEFINE gas_staged						.3			; =1: gas/diluent is staged (temporary   unavailable)
+;										.4			; --- unused
+;										.5			; --- unused
+;										.6			; --- unused
+;										.7			; --- unused
+
+
 ; Gaslist hard-coded Limits
  IFDEF _helium
 #DEFINE gaslist_min_o2					.7			; minimum O2 [%] ( 7% is minimum value to keep MOD < 255 meters / 1 Byte)
+#DEFINE gaslist_max_o2					.100		; maximum O2 [%]
 #DEFINE gaslist_max_He			.100-gaslist_min_o2 ; maximum He [%]
 #DEFINE gaslist_max_change_depth		.220		; max. change depth [m] (219 is maximum value that can be produced by gaslist_calc_mod with 7% O2)
 #DEFINE tissue_graphics_options			.2			; tissue graphics "Pres+Sat" and "N2+He" available
  ELSE
 #DEFINE gaslist_min_o2					.21			; minimum O2 [%]
+#DEFINE gaslist_max_o2					.100		; maximum O2 [%]
 #DEFINE gaslist_max_He					.0			; maximum He [%]
 #DEFINE gaslist_max_change_depth		.70			; max. change depth [m] (67 is maximum value that can be produced by gaslist_calc_mod with 21% O2)
 #DEFINE tissue_graphics_options			.1			; tissue graphics "Pres+Sat" only available
@@ -336,6 +373,7 @@
 #DEFINE gaslist_sp_stepsize				.10			; steps for setpoint setup [cbar]
 #DEFINE gaslist_sp_max					.160		; max. setpoint [cbar]
 #DEFINE gaslist_sp_min					.50			; min. setpoint [cbar]
+#DEFINE sp_max_change_depth				.100		; max change depth [m]
 
 
 ; Compass Display
@@ -347,7 +385,7 @@
 #DEFINE DECO_VOLUME_FLAG				.0			; =1: calculate gas needs
 #DEFINE DECO_BOTTOM_FLAG				.1			; =1: calculate gas needs for full bottom segment, =0: ...for extra time only
 #DEFINE DECO_CAVE_MODE					.2			; =1: calculate ascent and gas needs using backtracking data
-#DEFINE DECO_Z_FACTOR_FLAG				.3			; =1: calculate with Z factor when converting gas volumes <-> pressures
+#DEFINE DECO_GAS_CONTINGENCY			.3			; =1: use a second best gas if best gas is all used up
 #DEFINE DECO_TR_FUNCTIONS				.4			; =1: calculate TR functions (pressure readings)
 #DEFINE DECO_EXTENDED_STOPS				.5			; =1: place gas changes also below 1st stop depth
 #DEFINE DECO_MODE_LOOP_FLAG				.6			; =1: calculate real tissues in loop mode (CCR or pSCR)
@@ -362,7 +400,7 @@
 #DEFINE DECO_INITIALIZE					.2			; =1: write: initialize deco engine (to be done only once at the begin of every dive)
 #DEFINE DECO_CALCULATOR_MODE			.3			; =1: deco engone is run from the deco calculator
 #DEFINE DECO_BAILOUT_FLAG				.4			; =1: allow gas switches before first deco stop (used in bailout plans)
-#DEFINE DECO_ASCENT_FLAG				.5			; =1: figure in a delayed ascent (fTTS)
+#DEFINE DECO_DELAY_FLAG					.5			; =1: figure in a delayed ascent (fTTS)
 ;       DECO_MODE_LOOP_FLAG				.6			; =1: calculate simulated tissues in loop mode (CCR or pSCR)
 ;       DECO_MODE_PSCR_FLAG				.7			; =1: calculate simulated tissues in pSCR mode (loop flag needs to be set, too)
 
@@ -381,12 +419,12 @@
 ; Bit Flags for Communication with p2_deco.c - char_O_deco_info
 #DEFINE deco_mode						.0			; =1: in deco mode, deco ppO2 levels permitted
 #DEFINE ind_double_switch				.1			; =1: switch to other tank advice active
-;										.2			; --- unused
+#DEFINE gas_needs_fTTS					.2			; =1: indicated gas needs are calculated in fTTS mode
 #DEFINE deco_zone						.3			; =1: fTTS is <= TTS (not updated when in bailout mode)
 #DEFINE deco_ceiling					.4			; =1: ceiling depth > 0
-#DEFINE deco_stops						.5			; =1: deco stops found
-#DEFINE gas_needs_cave					.6			; =1: indicated gas needs are calculated in cave mode
-;										.7			; --- unused
+#DEFINE deco_stops_norm					.5			; =1: deco stops found in normal      plan
+#DEFINE deco_stops_alt					.6			; =1: deco stops found in alternative plan
+#DEFINE gas_needs_cave					.7			; =1: indicated gas needs are calculated in cave mode
 
 
 ; Bit Flags for Status on Variables of Type char
@@ -395,7 +433,7 @@
 #DEFINE char_transmitter_low_bat		.7
 
 
-; Bit Flags for Status on Variables of Type int (Flags are placed in the upper byte)
+; Bit Flags for Status on Variables of Type int (Flags are placed in the UPPER byte!)
 #DEFINE int_invalid_flag				.2
 #DEFINE int_not_yet_computed			.3
 #DEFINE int_is_zero						.3
@@ -466,10 +504,10 @@
 ;---- Hardware - States 2 (stored in access RAM, NOT cleared on restart)
 #DEFINE cc_active				HW_flags_state2,0	; =1: constant current charging active (cR hardware only)
 #DEFINE cv_active				HW_flags_state2,1	; =1: constant voltage charging active (cR hardware only)
-;								HW_flags_state2,2	; --- unused
-;								HW_flags_state2,3	; --- unused
-;								HW_flags_state2,4	; --- unused
-;								HW_flags_state2,5	; --- unused
+#DEFINE i2c_error_flag			HW_flags_state2,2	; =1: an I2C error occurred
+#DEFINE rs232_rx_timeout		HW_flags_state2,3	; =1: RS232 receive timeout occurred
+#DEFINE address_wrap_around		HW_flags_state2,4	; =1: the ext_flash_address wrapped around on increment
+#DEFINE battery_low_condition	HW_flags_state2,5	; =1: low battery condition detected
 ;								HW_flags_state2,6	; --- unused
 ;								HW_flags_state2,7	; --- unused
 
@@ -480,8 +518,8 @@
 #DEFINE sensor3_calibrated_ok	OS_flags_persist,2	; =1: sensor 3 calibration ok
 #DEFINE compass_bearing_set		OS_flags_persist,3	; =1: compass bearing is set
 #DEFINE use_old_batt_flag		OS_flags_persist,4	; =1: load old battery data after power-on reset
-#DEFINE option_repaired			OS_flags_persist,5	; =1: options have been repaired
-#DEFINE restart_fast			OS_flags_persist,6	; =1: skip logos and waits on restart
+#DEFINE options_changed			OS_flags_persist,5	; =1: option values have been changed, EEPROM needs to be updated
+#DEFINE restart_fast			OS_flags_persist,6	; =1: request to skip logos and waits on restart
 #DEFINE battery_overtemp		OS_flags_persist,7	; =1: battery charging temperature limit exceeded
 
 
@@ -537,13 +575,13 @@
 
 ;---- Dive Mode - Dive States
 #DEFINE use_aGF					DM_flags_state,0	; =1: use aGF, =0: use GF
-#DEFINE sp_fallback				DM_flags_state,1	; =1: fall-back to SP1 due to external O2 sensor failure
-#DEFINE dive_turned				DM_flags_state,2	; =1: dive is turned
-#DEFINE cave_mode				DM_flags_state,3	; =1: in cave mode (gas needs by backtracking)
-#DEFINE depth_limit_exceeded	DM_flags_state,4	; =1: depth limit exceeded
-#DEFINE deco_locked				DM_flags_state,5	; =1: in or has been in deco obligation       during the dive
-#DEFINE deco_region				DM_flags_state,6	; =1: in or has been in the deco stops region during the dive
-;								DM_flags_state,7	; --- unused
+#DEFINE deco_locked				DM_flags_state,1	; =1: in or has been in deco obligation       during the dive
+#DEFINE deco_region				DM_flags_state,2	; =1: in or has been in the deco stops region during the dive
+#DEFINE cave_mode				DM_flags_state,3	; =1: cave mode is active                                 (cave mode)
+#DEFINE dive_turned				DM_flags_state,4	; =1: dive is turned                                      (cave mode)
+#DEFINE backtrack_almost_full	DM_flags_state,5	; =1: the backtracking storage is almost   full           (cave mode)
+#DEFINE backtrack_entire_full	DM_flags_state,6	; =1: the backtracking storage is entirely full           (cave mode)
+#DEFINE backtrack_shutdown		DM_flags_state,7	; =1: the backtracking has shut down due to entirely full (cave mode)
 
 ;---- Dive Mode - O2 Sensors
 #DEFINE use_O2_sensor1			DM_flags_sensor,0	; =1: sensor 1 shall be used
@@ -552,18 +590,28 @@
 #DEFINE voting_logic_sensor1	DM_flags_sensor,3	; =1: sensor 1 is within the voting logic threshold
 #DEFINE voting_logic_sensor2	DM_flags_sensor,4	; =1: sensor 2 is within the voting logic threshold
 #DEFINE voting_logic_sensor3	DM_flags_sensor,5	; =1: sensor 3 is within the voting logic threshold
-;								DM_flags_sensor,6	; --- unused
+#DEFINE sp_fallback				DM_flags_sensor,6	; =1: fall-back to SP1 due to external O2 sensor failure
 ;								DM_flags_sensor,7	; --- unused
 
-;---- Dive Mode - User Requests
-#DEFINE request_gaschange		DM_flags_request,0	; =1: request to change the gas
-#DEFINE request_reset_avg		DM_flags_request,1	; =1: request to reset the average depth
-#DEFINE request_next_custview	DM_flags_request,2	; =1: request to show the next custom view
-#DEFINE request_back_to_loop	DM_flags_request,3	; =1: request to switch back from bailout to loop
-#DEFINE request_toggle_GF		DM_flags_request,4	; =1: request to toggle between GF and aGF
-#DEFINE request_set_marker		DM_flags_request,5	; =1: request to set a marker in the logbook
-#DEFINE request_turn_dive		DM_flags_request,6	; =1: request to toggle the dive turned status
-;								DM_flags_request,7	; --- unused
+;---- Dive Mode - User Requests / General
+#DEFINE request_gas_change		DM_flags_request,0	; =1: request to change the gas
+#DEFINE request_gas_update		DM_flags_request,1	; =1: request to update the gas
+#DEFINE request_reset_avg		DM_flags_request,2	; =1: request to reset the average depth
+#DEFINE request_next_custview	DM_flags_request,3	; =1: request to show the next custom view
+#DEFINE request_back_to_loop	DM_flags_request,4	; =1: request to switch back from bailout to loop
+#DEFINE request_toggle_GF		DM_flags_request,5	; =1: request to toggle between GF and aGF
+#DEFINE request_set_marker		DM_flags_request,6	; =1: request to set a marker in the logbook
+#DEFINE request_restart_engine	DM_flags_request,7	; =1: request to restart the deco engine
+
+;---- Dive Mode - User Requests / Cave Mode
+#DEFINE request_cave_toggle		DM_flags_cavereq,0	; =1: request to toggle cave mode off/on            (cave mode)
+#DEFINE request_cave_off_turned	DM_flags_cavereq,1	; =1: request to switch cave mode off               (cave mode)
+#DEFINE request_turn_toggle		DM_flags_cavereq,2	; =1: request to toggle dive turned state           (cave mode)
+#DEFINE request_turn_turn		DM_flags_cavereq,3	; =1: request to switch dive turned state to turned (cave mode)
+#DEFINE request_waypoint_set	DM_flags_cavereq,4	; =1: request to set a waypoint                     (cave mode)
+#DEFINE request_waypoint_out	DM_flags_cavereq,5	; =1: request to go one waypoint out of the cave    (cave mode)
+#DEFINE request_waypoint_in		DM_flags_cavereq,6	; =1: request to go one waypoint into   the cave    (cave mode)
+;								DM_flags_cavereq,7	; --- unused
 
 ;---- Dive Mode - Data Recording Events
 #DEFINE event_occured			DM_flags_event,0	; =1: an event occurred (global indicator flag)
@@ -572,8 +620,8 @@
 #DEFINE event_bailout			DM_flags_event,3	; =1: a change to or of the OC gas occurred due to bailout
 #DEFINE event_SP_change			DM_flags_event,4	; =1: a change of the setpoint has occurred
 ;								DM_flags_event,5	; --- unused
-#DEFINE rs232_rx_timeout		DM_flags_event,6	; =1: RS232 receive timeout occurred  | no better place found
-#DEFINE i2c_error_flag			DM_flags_event,7	; =1: an I2C error occurred           | for these two flags...
+;								DM_flags_event,6	; --- unused
+;								DM_flags_event,7	; --- unused
 
 ;---- Dive Mode - Display Control / Layout
 #DEFINE safety_stop_enabled		DM_flags_layout1,0	; =1: safety        stop is enabled
@@ -594,6 +642,16 @@
 #DEFINE gas_needs_mode_last		DM_flags_layout2,6	; =1: last gas needs were computed for cave mode, =0: direct ascent
 #DEFINE tts_greater_99			DM_flags_layout2,7	; =1: TTS > 99 minutes
 
+#DEFINE tissue_graphic_layout	DM_flags_layout3,0	; =1: show pres+sat, =0: show N2/He pressures
+#DEFINE tissue_graphic_gf		DM_flags_layout3,1	; =1: show GF lines
+#DEFINE tissue_graphic_cns		DM_flags_layout3,2	; =1: shwo CNS value (surface mode graphic only)
+#DEFINE tissue_graphic_mode		DM_flags_layout3,3	; =1: logbook mode   (surface mode graphic only)
+;								DM_flags_layout3,4	; --- unused
+;								DM_flags_layout3,5	; --- unused
+;								DM_flags_layout3,6	; --- unused
+;								DM_flags_layout3,7	; --- unused
+
+
 ;---- Dive Mode - Display Control / Messages
 #DEFINE message_advice			DM_flags_message,0	; =1: an advice    is active in dive mode
 #DEFINE message_attention		DM_flags_message,1	; =1: an attention is active in dive mode or surface mode
@@ -604,16 +662,15 @@
 #DEFINE gas_needs_warning		DM_flags_message,6	; =1: the gas needs  warning   has been shown before
 #DEFINE o2_sensors_warning		DM_flags_message,7	; =1: the O2 sensors warning   has been shown before
 
-;---- Dive Mode - Display Control / Gas, Diluent
+;---- Dive Mode - Display Control / Gas, Diluent, Depth
 #DEFINE better_gas_hint			DM_flags_gas_dil,0	; =1: mark a gas when it is a better gas
-#DEFINE better_gas_available	DM_flags_gas_dil,1	; =1: a better gas is available
-#DEFINE better_gas_blinking		DM_flags_gas_dil,2	; =1: gas is blinking
-#DEFINE better_dil_available	DM_flags_gas_dil,3	; =1: a better diluent is available
-#DEFINE better_dil_blinking		DM_flags_gas_dil,4	; =1: diluent is blinking
-;								DM_flags_gas_dil,5	; --- unused
-;								DM_flags_gas_dil,6	; --- unused
-;								DM_flags_gas_dil,7	; --- unused
-
+#DEFINE color_code_gases		DM_flags_gas_dil,1	; =1: color code the gases by ppO2 & current depth
+#DEFINE better_gas_available	DM_flags_gas_dil,2	; =1: a better gas is available
+#DEFINE better_gas_blinking		DM_flags_gas_dil,3	; =1: gas is blinking
+#DEFINE better_dil_available	DM_flags_gas_dil,4	; =1: a better diluent is available
+#DEFINE better_dil_blinking		DM_flags_gas_dil,5	; =1: diluent is blinking
+#DEFINE gas6_or_EXIT			DM_flags_gas_dil,6	; =1: exit menu, =0: provide gas6 option
+#DEFINE depth_limit_exceeded	DM_flags_gas_dil,7	; =1: depth limit exceeded
 
 ;---- Menu System - Control
 #DEFINE surfmode_menu			MS_flags_control,0	; =1: surface      menu is shown (i.e. returning from it)
@@ -622,7 +679,7 @@
 #DEFINE compass_menu			MS_flags_control,3	; =1: "set bearing"     is shown
 #DEFINE is_diluent_menu			MS_flags_control,4	; =1: setting up diluents, =0: setting up OC gases
 #DEFINE is_bailout_menu			MS_flags_control,5	; =1: in bailout menu
-;								MS_flags_control,6	; --- unused
+#DEFINE custom_view_locked		MS_flags_control,6	; =1: the custom view is locked (defer CV auto-popup)
 ;								MS_flags_control,7	; --- unused
 
 ;---- Menu System - Data Imprinting
@@ -651,10 +708,10 @@
 #DEFINE leftbind				CVT_flags1,0		; =1: align numbers to the left
 #DEFINE win_invert				CVT_flags1,1		; =1: the text   shall be printed in inverse
 #DEFINE short_gas_descriptions	CVT_flags1,2		; =1: use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
-#DEFINE ignore_digit3			CVT_flags1,3
-#DEFINE ignore_digit4			CVT_flags1,4
-#DEFINE ignore_digit5			CVT_flags1,5
-#DEFINE aux_flag				CVT_flags1,6		;     provided for local boolean arguments and storage
+#DEFINE ignore_digit3			CVT_flags1,3		;     controls suppression of digits when printing numbers
+#DEFINE ignore_digit4			CVT_flags1,4		;     controls suppression of digits when printing numbers
+#DEFINE ignore_digit5			CVT_flags1,5		;     controls suppression of digits when printing numbers
+;								CVT_flags1,6		; --- unused
 ;								CVT_flags1,7		; --- unused
 
 #DEFINE pre_zero_flag			CVT_flags2,0
@@ -667,15 +724,15 @@
 #DEFINE neg_flag				CVT_flags2,7		; =1: result is negative
 
 
-;---- Miscellaneous Flags 
+;---- Miscellaneous Flags
 #DEFINE ignore_last_edited_gas	misc_flags,0		; =1: ignore last edited gas while cleaning up gas/dil list
 #DEFINE copying_dil				misc_flags,1		; =1: copying a diluent
-#DEFINE comm_service_enabled	misc_flags,2		; =1: COMM service mode is enabled
-;								misc_flags,3		; --- unused
-;								misc_flags,4		; --- unused
-;								misc_flags,5		; --- unused
-;								misc_flags,6		; --- unused
-;								misc_flags,7		; --- unused
+#DEFINE comm_service_mode		misc_flags,2		; =1: service mode (extended command set) is enabled
+#DEFINE waypoint_reached_first	misc_flags,3		; =1: the first (most outside) waypoint is reached (cave mode)
+#DEFINE waypoint_reached_last	misc_flags,4		; =1: the last  (most inside)  waypoint is reached (cave mode)
+#DEFINE option_repaired			misc_flags,5		; =1: option value was set to default
+#DEFINE flash_wait				misc_flags,6		; =1: wait for flash write operation to complete
+#DEFINE aux_flag				misc_flags,7		;     local flag, used in various places
 
 ;---- HUD Status Byte (stored in access RAM)
 #DEFINE hud_connection_ok		hud_status_byte,0	; =1 HUD connection ok
@@ -690,76 +747,112 @@
 
 ;---------------------------- Macros ------------------------------------
 
+
+; ---- options checking ----
+
 TSTOSS	macro opt_reg				; TeST Option Skip next instruction if Set (not zero)
-	movff	opt_reg,WREG			; Attention: destroys WREG!
-	tstfsz	WREG,A					; Attention: must be followed by a plain machine
+	movff	opt_reg,EEDATA			; Attention: destroys EEDATA!
+	tstfsz	EEDATA,A				; Attention: must be followed by a plain machine
 	bra		$+4						;            command, do not let follow a macro!
 	endm							;
 
-
 TSTOSC	macro opt_reg				; TeST Option Skip next instruction if Clear (zero)
-	movff	opt_reg,WREG			; Attention: destroys WREG!
-	tstfsz	WREG,A					; Attention: must be followed by a plain machine
+	movff	opt_reg,EEDATA			; Attention: destroys EEDATA!
+	tstfsz	EEDATA,A				; Attention: must be followed by a plain machine
 	endm							;            command, do not let follow a macro!
 
 
-CLRI	macro int					; CLeaR Integer (version of clrf for 2 byte integers)
-	clrf	int+0					; Attention: must be in bank where target variable resides!
-	clrf	int+1					;
+; ---- literal operations ----
+
+CLRI	macro address				; CLeaR Integer (version of clrf for 2 byte integers)
+	clrf	address+0				; Attention: must be in bank where target variable resides!
+	clrf	address+1				;
+	endm							;
+
+CLRT	macro address				; CLeaR Three byte integer (version of clrf for 3 byte integers)
+	clrf	address+0				; Attention: must be in bank where target variable resides!
+	clrf	address+1				;
+	clrf	address+2				;
 	endm							;
 
+CLRR	macro	address,range		; CLeaR a Range of bytes   (version of clrf for 1-256 bytes)
+	movlw	low(range)				; initialize loop counter
+	lfsr	FSR1,address			; set start address
+	extern	memory_clear
+	call	memory_clear
+	endm
 
-SETI	macro int					; SET Integer (version of setf for 2 byte integers)
-	setf	int+0					; Attention: must be in bank where target variable resides!
-	setf	int+1					;
+SETI	macro address				; SET Integer (version of setf for 2 byte integers)
+	setf	address+0				; Attention: must be in bank where target variable resides!
+	setf	address+1				;
 	endm							;
 
-
-MOVLI	macro lit, int				; MOVe Literal to Integer
-	movlw	LOW  (lit)				; Attention: destroys WREG!
-	movwf	int+0					; Attention: must be in bank where target variable resides!
-	movlw	HIGH (lit)				;
-	movwf	int+1					;
+MOVLI	macro literal,address		; MOVe Literal to Integer
+	movlw	LOW  (literal)			; Attention: destroys WREG!
+	movwf	address+0				; Attention: must be in bank where target variable resides!
+	movlw	HIGH (literal)			;
+	movwf	address+1				;
 	endm							;
 
 
-INCI	macro int					; INCrement Integer (version of incf for 2 byte integers)
-	infsnz	int+0,F					; Attention: must be in bank where target variable resides!
-	incf	int+1,F					;
+; ---- arithetics ----
+
+INCI	macro address				; INCrement Integer (version of incf for 2 byte integers)
+	infsnz	address+0,F				; Attention: must be in bank where target variable resides!
+	incf	address+1,F				;
 	endm							;
 
-
-DECI	macro int					; DECrement Integer (version of decf for 2 byte integers)
+DECI	macro address				; DECrement Integer (version of decf for 2 byte integers)
 	movlw	.1						; Attention: destroys WREG!
-	subwf	int+0,F					; Attention: must be in bank where target variable resides!
+	subwf	address+0,F				; Attention: must be in bank where target variable resides!
 	movlw	.0						;
-	subwfb	int+1,F					;
+	subwfb	address+1,F				;
+	endm							;
+
+ADDLI	macro literal, address		; ADD Literal to Integer
+	movlw	LOW  (literal)			; Attention: destroys WREG!
+	addwf	address+0,F				; Attention: must be in bank where target variable resides!
+	movlw	HIGH (literal)			;
+	addwfc	address+1,F				;
+	endm							;
+
+SUBLI	macro literal, address		; SUBtract Literal from Integer
+	movlw	LOW  (literal)			; Attention: destroys WREG!
+	subwf	address+0,F				; Attention: must be in bank where target variable resides!
+	movlw	HIGH (literal)			;
+	subwfb	address+1,F				;
 	endm							;
 
 
-ADDLI	macro lit, int				; ADD Literal to Integer
-	movlw	LOW  (lit)				; Attention: destroys WREG!
-	addwf	int+0,F					; Attention: must be in bank where target variable resides!
-	movlw	HIGH (lit)				;
-	addwfc	int+1,F					;
+; ---- moves ----
+
+MOVCC	macro from,to				; MOVe     1 byte Char    (actually an alias for movff)
+	movff	from,to
+	endm
+
+MOVII	macro from,to				; MOVe     2 byte Integer (version of movff for 2 bytes)
+	movff	from+0,to+0				; copy 1st byte
+	movff	from+1,to+1				; copy 2nd byte
 	endm							;
 
+MOVTT	macro from,to				; MOVe Three byte Integer (version of movff for 3 bytes)
+	movff	from+0,to+0				; copy 1st byte
+	movff	from+1,to+1				; copy 2nd byte
+	movff	from+2,to+2				; copy 3rd byte
+	endm							;
+
+MOVRR	macro from,to,range			; MOVe a Range of bytes   (version of movff for 1-256 bytes)
+	movlw	low(range)				; initialize loop counter
+	lfsr	FSR1,from				; from
+	lfsr	FSR2,to					; to
+	extern	memory_move
+	call	memory_move
+	endm
+
 
-SUBLI	macro lit, int				; SUBtract Literal from Integer
-	movlw	LOW  (lit)				; Attention: destroys WREG!
-	subwf	int+0,F					; Attention: must be in bank where target variable resides!
-	movlw	HIGH (lit)				;
-	subwfb	int+1,F					;
-	endm							;
-
+; ---- ISR-safe moves ----
 
-MOVII	macro from, to				; MOVe Integer to Integer (version of movff for 2 byte integers)
-	movff	from+0,to+0				; banksafe
-	movff	from+1,to+1				;
-	endm							;
-
-
-SMOVII	macro from, to				; isr-Safe MOVe 2 byte Integer to Integer (version of MOVII for integers updated in ISR)
+SMOVII	macro from, to				; isr-Safe MOVe     2 byte Integer (version of MOVII for ISR-safe copying)
 	local	retry					;
 retry:
 	bcf		trigger_isr_updates		; clear flag, it will be set by the ISR in case it had kicked in
@@ -769,8 +862,7 @@
 	bra		retry					; YES - retry copy
 	endm							; NO  - done
 
-
-SMOVTT	macro from, to				; isr-Safe MOVe Three byte integer to integer (version of MOVII for integers updated in ISR)
+SMOVTT	macro from, to				; isr-Safe MOVe Three byte integer (version of MOVTT for ISR-safe copying)
 	local	retry					;
 retry:
 	bcf		trigger_isr_updates		; clear flag, it will be set by the ISR in case it had kicked in
@@ -781,8 +873,7 @@
 	bra		retry					; YES - retry copy
 	endm							; NO  - done
 
-
-SMOVFF	macro from, to				; isr-Safe MOVe Four byte integer to integer (version of MOVII for integers updated in ISR)
+SMOVQQ	macro from, to				; isr-Safe MOVe  Quad byte integer (version of MOVII for ISR-safe copying)
 	local	retry					;
 retry:
 	bcf		trigger_isr_updates		; clear flag, it will be set by the ISR in case it had kicked in
@@ -794,7 +885,6 @@
 	bra		retry					; YES - retry copy
 	endm							; NO  - done
 
-
 SMOVSS	macro from, to				; isr-Safe MOVe Six byte integer to integer (version of MOVII for integers updated in ISR)
 	local	retry					;
 retry:
@@ -869,21 +959,27 @@
 	extern	hud_status_byte
 	extern	hud_battery_mv
 
- endif
+ endif	; ACCESS_RAM_VARS
 
 ;---------------------------- Bank0 NORMAL RAM ------------------------------
 isr_backup	equ			0x060		; Alias for "banksel isr_backup"
 isr_backup	udata_ovr	isr_backup	; Bank 0 ISR data
 
-;---- Backup for general Registers
+;---- Backup for general Registers, used by ISR Routines
 PROD_backup						res 2
 FSR0_backup						res 2
 BSR_backup						res 1
 
-;---- Multi-Purpose Register for ISR Routines
+;---- Multi-Purpose Registers, used by ISR Routines
 isr_mpr							res 2		; used in ms5541.asm and isr.asm
-#DEFINE isr_lo					isr_mpr+0	;
-#DEFINE isr_hi					isr_mpr+1	;
+#DEFINE isr_lo					isr_mpr+0	; ...
+#DEFINE isr_hi					isr_mpr+1	; ...
+
+;---- Multi-Purpose Registers, NOT USED by ISR Routines
+backup_mpr						res 2		; used in rtc.asm
+#DEFINE backup_lo				backup_mpr+0
+#DEFINE backup_hi				backup_mpr+1
+
 
 ;---- Time and Date - Real Time Clock
 rtc_year						res 1		; running year     | Attention:
@@ -983,13 +1079,14 @@
 analog_sw2						res 1		; analog value for switch 2
 button_polarity					res 1		; 0xFF (both normal), 0x00 (both inverted), 0x01 (left inverted only), 0x02 (right inverted only)
 
+
 ;--- resettable min and max Depth Option
  IFDEF _min_depth_option
 pressure_rel_min_trip			res 2		; resettable minimum relative pressure
 pressure_rel_max_trip			res 2		; resettable maximum relative pressure
  ENDIF
 
-; 141 byte used, 19 byte free
+; 143 byte used, 17 byte free
 
  
 ;---------------------------- Common DATA ------------------------------------
@@ -1010,13 +1107,14 @@
 MS_flags_control				res 1		; menu system - control
 MS_flags_imprint				res 1		; menu system - data imprinting
 
-;---- Flags - Dive Mode (7 byte)
+;---- Flags - Dive Mode (9 byte)
 DM_flags_state					res 1		; dive mode - dive states
 DM_flags_sensor					res 1		; dive mode - O2 sensors
-DM_flags_request				res 1		; dive mode - user requests
+DM_flags_request				res 1		; dive mode - user requests / general
 DM_flags_event					res 1		; dive mode - data recording events
 DM_flags_layout1				res 1		; dive mode - display control / layout (1)
 DM_flags_layout2				res 1		; dive mode - display control / layout (2)
+DM_flags_layout3				res 1		; dive mode - display control / layout (3)
 DM_flags_message				res 1		; dive mode - display control / messages
 DM_flags_gas_dil				res 1		; dive mode - display control / gas, diluent
 
@@ -1048,11 +1146,12 @@
 sub_b							res 2
 sub_c							res 2
 
-;---- Menu System and Views (4 byte)
+;---- Menu System and Views (5 byte)
 menu_pos_cur					res 1		; current position in main menu
 menu_pos_max					res 1		; highest position in main menu
 active_premenu					res 1		; currently shown pre-menu (0: none)
-active_customview				res 1		; currently shown custom view
+active_customview				res 1		; currently  shown custom view
+backup_customview				res 1		; previously shown custom view
 
 ;---- Miscellaneous (6 byte)
 batt_voltage					res 2		; battery voltage in mV (no ISR involved)
@@ -1061,7 +1160,7 @@
 message_page					res 1		; current message page number
 pairing_slot					res 1		; slot number, used in transmitter pairing
 
-;---- Dive Mode / all modes (25 byte)
+;---- Dive Mode / all modes (26 byte)
 divesecs_avg_trip				res 2		; time accumulator for the resettable average depth & stopwatch
 divesecs_avg_total				res 2		; time accumulator for the total dive average depth
 pressure_rel_avg_trip			res 2		; calculated resettable average depth
@@ -1082,6 +1181,13 @@
 active_dil						res 1		; the currently used diluent (1-5)
  ENDIF
 
+ IFDEF _cave_mode
+DM_flags_cavereq				res 1		; dive mode - user requests / cave mode
+backtrack_deltatime				res 1		; time elapsed since last depth recording in seconds
+backtrack_waypoint_num			res 1		; current waypoint number
+backtrack_waypoint_turn			res 1		; waypoint number of the turn point
+ ENDIF
+
 ;---- Dive Mode / apnoe mode (2 byte)
 apnoe_max_pressure				res 2		; max depth over all dives in the series
 
@@ -1097,12 +1203,13 @@
 event_byte2						res 1		;
 CNS_start						res 2		; CNS value at beginning of dive
 
-;---- External Flash (13 byte)
-ext_flash_rw					res 1		; transfer register for data read / write
+;---- External Flash (14 byte)
 ext_flash_address				res 3		; 24 bit address
+ext_flash_length_counter		res 3		; 24 bit length counter
 ext_flash_log_pointer			res 3		; 24 bit address for logbook profile storing
 ext_flash_end_pointer			res 3		; 24 bit address for logbook profile storing
-ext_flash_dive_counter			res 3		; 24 bit counter for dive length (increased in write_byte_ext_flash_plus)
+ext_flash_rw					res 1		; transfer register for data read / write
+ext_flash_rollover_threshold	res 1		; rollover threshold for address increment operations
 
 ;---- Battery Management (12 byte)
 battery_capacity_internal		res 2		; for internal battery gauging
@@ -1149,7 +1256,8 @@
 comm_timeout_timer				res 1		; timeout for communication
 
 ;---- eeprom_rs232.asm
-uart_timeout_timer				res 3		; RS232 receive timeout counter
+eeprom_loop						res 1		; loop counter (actually used in flash and serial, too)
+rx_timoeut_tmr5h_load			res 1		; TMR5H load value for RS232 RX timeout
 
 ;---- i2c.asm
 i2c_temp1						res 1		; temporary data
@@ -1174,14 +1282,19 @@
 text_item						res 2		; address of the current text
 
 ;---- options.asm
-opt_type						res 1		; option type
-opt_default						res 1		; default value
-opt_inc							res 1		; also used for default+1 (string) and enum low
-opt_min							res 1		; minimum value, also used for enum high
-opt_max							res 1		; maximum value
-opt_unit						res 2		; multi-lingual unit text
-opt_eeprom						res 1		; storage position in EEPROM
-opt_backup_tbl					res 3		; buffer for table pointer
+#DEFINE opt_definiton_bytes		.12			; | Attention: do not change the relative position of these vars!
+opt_type						res 1		; | option type
+opt_serial						res 1		; | index used for option read/write via RS232
+opt_inc							res 1		; | increment value, also used for enum low  and string default+1
+opt_min							res 1		; | minimum   value, also used for enum high
+opt_max							res 1		; | maximum   value
+opt_default						res 1		; | default   value
+opt_unit						res 2		; | pointer to multi-lingual unit text
+opt_memory						res 2		; | pointer to memory position
+opt_eeprom_index				res 1		; | pointer to EEPROM position (index)
+opt_eeprom_bank					res 1		; | pointer to EEPROM position (bank)
+opt_end_token					res 1		; | =0xFF: end of table reached (does not count into opt_definiton_bytes)
+
 
 ;---- tft.asm
 tft_save_top					res 1
@@ -1205,7 +1318,7 @@
 wait_counter					res 1
 
 
-; 193 byte used, 15 byte free (208 byte total)
+; 201 byte used, 7 byte free (208 byte total)
 
 
 ;============================ LOCAL DATA ======================================
@@ -1252,10 +1365,6 @@
 
 supersat_start					res 1		; leading tissue supersaturation at beginning of the dive
 
-;---- Backup for lost Gas Function (10 byte)
-opt_gas_type_backup				res 5		; 0=Disabled, 1=First, 2=Travel, 3=Deco   | ATTENTION:
-opt_dil_type_backup				res 5		; 0=Disabled, 1=First, 2=Normal           | (as above)
-
 ;---- O2 Sensors (9 byte, updated by ISR when sensors are connected via datalink)
  IFDEF _external_sensor
 sensor1_mv						res 2		; sensor 1 voltage in 0.1  mV  steps
@@ -1305,9 +1414,9 @@
 accel_DX_f						res 2		; filtered Data
 accel_DY_f						res 2		; filtered Data
 accel_DZ_f						res 2		; filtered Data
-compass_CX_f					res 2		; calibration data
-compass_CY_f					res 2		; calibration data
-compass_CZ_f					res 2		; calibration data
+compass_CX_f					res 2		; calibration data (stored via options system)
+compass_CY_f					res 2		; calibration data (stored via options system)
+compass_CZ_f					res 2		; calibration data (stored via options system)
 
 ;---- temporary Data for Q15 Arithmetics (7 byte, compass_ops.asm, called from C)
 compass_a						res 2		;
@@ -1336,16 +1445,30 @@
  ENDIF
 
 
-; 166 byte used, 90 byte free
+; 156 byte used, 100 byte free
+
+
+;----------------------- Bank 2 General Purpose Buffer 1 -----------------------
+; general purpose buffer no.1
+;
+; NOTE: needs to be aligned with a bank (low(buffer)=0)
+
+buffer		udata_ovr	0x200
+buffer							res	.256	; buffer 1 - string buffer, etc.
 
 
-;----------------------- Bank 2 General Purpose Buffer -------------------------
-; Reserved for general purpose buffer (strings, images, etc).
-; NOTE: Needs to be aligned with a bank (LOW(buffer)==0).
+;----------------------- Bank 11 General Purpose Buffer 2 ----------------------
+; general purpose buffer no. 2
+;
+; NOTE: needs to be aligned with a bank (low(buffer)=0)
 
-buffer		udata_ovr	0x200
+; Remark: this memory block is already allocated in shared_definitions.h for
+;         use while in dive mode, so we need to make a hard reference here
+;
+;buffer2	udata_ovr	0xB00
+;buffer2						res	.256	; buffer 2 - backtracking, flash mirror, etc.
 
-buffer							res	.256	; used for string assembly / display output
+#DEFINE buffer2					0xB00
 
 
 ;---------------------- Bank 14 Options Table ---------------------------------
@@ -1375,6 +1498,9 @@
 opt_name						res opt_name_length
 
 ;---- various other Settings
+opt_fw_version_major			res 1		; firmware version, major | use read-only!
+opt_fw_version_minor			res 1		; firmware version, minor |
+opt_fw_version_beta				res 1		; firmware version, beta  |
 opt_surface_interval			res 1		; surface interval, used by deco calculator
 opt_brightness					res 1		; =0: Eco, =1:Medium, =2:Full
 opt_salinity					res 1		; 0-5%
@@ -1391,7 +1517,7 @@
 opt_sampling_rate				res 1		; =1: 10s, =0: 2s
 opt_dive_color_scheme			res 1		; 0-3
 opt_pressure_adjust				res 1		; SIGNED char (two's complement), -20/+20mbar max.
-opt_enable_safetystop			res 1		; =1: a safety stop is shown
+opt_safetystop					res 1		; =1: a safety stop is shown
 opt_calibration_O2_ratio		res 1		; %O2 of calibration gas
 opt_x_s1						res 2		; calibration factor (Not stored in EEPROM)
 opt_x_s2						res 2		; calibration factor (Not stored in EEPROM)
@@ -1400,8 +1526,8 @@
 opt_flip_screen					res 1		; =1: flip the screen
 opt_cR_button_left				res 1		; left button  sensitivity (cR hardware)
 opt_cR_button_right				res 1		; right button sensitivity (cR hardware)
-opt_modwarning					res 1		; =1:do a red blinking warning, =0:default behavior
-opt_vsitextv2					res 1		; =1:use the depth dependent ascend rate limits
+opt_depth_warn					res 1		; =1:do a red blinking warning, =0:default behavior
+opt_vsitext						res 1		; =1:use the depth dependent ascend rate limits
 opt_vsigraph					res 1		; =1:draw the graphical VSI bar
 opt_showppo2					res 1		; =1:always show the ppO2 value in the warning position
 opt_temperature_adjust			res 1		; SIGNED char (two's complement), -2.0/+2.0 °C max.
@@ -1411,22 +1537,24 @@
 opt_safety_stop_reset			res 1		; [cbar]
 opt_diveTimeout					res 1		; timeout for dive mode [min]
 opt_sim_setpoint_number			res 1		; setpoint to use for deco calculation
-opt_calc_asc_gasvolume			res 1		; calculate OC gas volume needs for ascent
+opt_calc_gasvolume				res 1		; calculate OC gas volume needs for ascent
 opt_sim_use_aGF					res 1		; =0: use GF, =1: use aGF for deco calculation
 opt_enable_IBCD					res 1		; enable IBCD warning
 opt_sat_multiplier_gf			res 1		; Buhlmann safety factor for GF deco
 opt_desat_multiplier_gf			res 1		; Buhlmann safety factor for GF deco
 opt_sat_multiplier_non_gf		res 1		; Buhlmann safety factor for NON-GF deco
 opt_desat_multiplier_non_gf		res 1		; Buhlmann safety factor for NON-GF deco
-opt_ZfactorUse					res 1		; =1: figure in compression factor Z when converting gas volume <-> gas pressure
-opt_ZfactorTemp					res 1		; temperature setpoint for compression factor Z
 opt_2ndDepthDisp				res 1		; =1: show average depth instead of max depth
 opt_max_depth					res 1		; depth at which a warning will be given
-opt_store_apnoe_dive			res 1		; =1: store dives in apnoe mode into logbook
+opt_store_apnoe					res 1		; =1: store dives in apnoe mode into logbook
 opt_tissue_graphics				res 1		; =0: show N2 and He pressures, =1: show pressures and saturations
 opt_logoffset_step				res 1		; step size when adjusting log offset
 opt_layout						res 1		; initial layout of dive mode screen
-opt_extended_stops				res 1		; =1: place gas switches also below 1st stop depth
+opt_ext_stops					res 1		; =1: place gas switches also below 1st stop depth
+opt_s8_mode						res 1		; S8 mode - analog / digital
+opt_gas_contingency_sim			res 1		; =1: deco calculator: switch to alternative gas if best gas is used up
+opt_gas_contingency_dive		res 1		; =1: real dive mode:  switch to alternative gas if best gas is used up
+opt_cave_mode					res 1		; =1: cave mode switched on
 
 ;---- RX Function Settings
 opt_transmitter_id_1			res 2		; 16 bit transmitter ID for Gas 1
@@ -1444,7 +1572,7 @@
 opt_TR_2nd_pres					res 1		; TR functions - 2nd pressure assignment
 opt_TR_Bail_pres				res 1		; TR functions - bailout pressure assignment
 
-; ==> 187 bytes used - 57 bytes free (244 usable bytes only in bank 14 as the upper 12
-;                                     bytes may be used for SFRs on some PIC devices)
+; ==> 190 bytes used - 54 bytes free (244 usable bytes only in bank 14 as the upper 12
+;                                     bytes are reserved for special function registers)
 
 ;-----------------------------------------------------------------------------
--- a/src/i2c.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/i2c.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File i2c.asm                              combined next generation V3.03.5
+;   File i2c.asm                              combined next generation V3.08.8
 ;
 ;   I2C Interface
 ;
@@ -49,6 +49,7 @@
 #include "wait.inc"
 #include "math.inc"
 #include "external_flash.inc"
+#include "eeprom_rs232.inc"
 
 
 i2c	CODE
@@ -569,7 +570,7 @@
 	rcall		WaitMSSP
 	
 	; accelerometer
-	rcall	I2C_sleep_accelerometer0		; registers can only be changed in standby mode
+	rcall	I2C_sleep_accelerometer0	; registers can only be changed in standby mode
 
 	bsf		SSP1CON2,SEN				; start condition
 	rcall	WaitMSSP
@@ -691,50 +692,50 @@
 
 I2C_init_compass3:
 	; magnetic
-	bsf		SSP1CON2,SEN	; Start condition
+	bsf		SSP1CON2,SEN				; start condition
 	rcall	WaitMSSP
-	movlw	0x3C            ; address
-	rcall       I2C_TX
-	movlw	0xA0		; 0x20 with auto-increment (MSB=1)
-	rcall       I2C_TX
-	movlw	b'01110000'	; CTRL_REG1_M (10Hz) 0x20
-	rcall       I2C_TX
-	movlw	b'01100000'	; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21
-	rcall       I2C_TX
-	movlw	b'01000000'	; CTRL_REG3_M (Continuous) 0x22
-	rcall       I2C_TX
-	movlw	b'00000000'	; CTRL_REG4_M (Z in Low-power mode) 0x23
-	rcall       I2C_TX
-	movlw	b'00000000'	; CTRL_REG5_M 0x24
-	rcall       I2C_TX
-	movlw	b'00000000'	; CTRL_REG5_M 0x24
-	rcall       I2C_TX
-	bsf		SSP1CON2,PEN	; Stop condition
+	movlw	0x3C						; address
+	rcall	I2C_TX
+	movlw	0xA0						; 0x20 with auto-increment (MSB=1)
+	rcall	I2C_TX
+	movlw	b'01110000'					; CTRL_REG1_M (10Hz) 0x20
+	rcall	I2C_TX
+	movlw	b'01100000'					; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21
+	rcall	I2C_TX
+	movlw	b'01000000'					; CTRL_REG3_M (Continuous) 0x22
+	rcall	I2C_TX
+	movlw	b'00000000'					; CTRL_REG4_M (Z in Low-power mode) 0x23
+	rcall	I2C_TX
+	movlw	b'00000000'					; CTRL_REG5_M 0x24
+	rcall	I2C_TX
+	movlw	b'00000000'					; CTRL_REG5_M 0x24
+	rcall	I2C_TX
+	bsf		SSP1CON2,PEN				; Stop condition
 	rcall	WaitMSSP
-	
+
 	;accelerometer
-	bsf	SSP1CON2,SEN		; Start condition
-        rcall	WaitMSSP
-	movlw	0x3A            ; address
+	bsf	SSP1CON2,SEN					; start condition
+	rcall	WaitMSSP
+	movlw	0x3A						; address
 	rcall	I2C_TX
 	movlw	0x20
-	rcall   I2C_TX
-	movlw	b'10010111'	; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20
-	rcall   I2C_TX
-	movlw	b'00000000'	; CTRL_REG2_A 0x21
-	rcall   I2C_TX
-	movlw	b'00000000'	; CTRL_REG3_A 0x22
-	rcall   I2C_TX
-        movlw	b'11001100'	; CTRL_REG4_A 0x23
-        rcall       I2C_TX
-	bsf	SSP1CON2,PEN		; Stop condition
-	bra	WaitMSSP	; (And return)
+	rcall	I2C_TX
+	movlw	b'10010111'					; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20
+	rcall	I2C_TX
+	movlw	b'00000000'					; CTRL_REG2_A 0x21
+	rcall	I2C_TX
+	movlw	b'00000000'					; CTRL_REG3_A 0x22
+	rcall	I2C_TX
+	movlw	b'11001100'					; CTRL_REG4_A 0x23
+	rcall	I2C_TX
+	bsf	SSP1CON2,PEN					; stop condition
+	bra	WaitMSSP						; (and return)
 
 
 	global	I2C_sleep_compass
 I2C_sleep_compass:
 	btfss	compass_enabled				; compass active?
-	return						; NO - return
+	return								; NO - return
 	bcf		compass_enabled
 	btfsc	compass_type3				; compass 3 ?
 	bra		I2C_sleep_compass3			; YES
@@ -760,7 +761,7 @@
 	rcall	I2C_TX
 	bsf		SSP1CON2,PEN				; stop condition
 	rcall	WaitMSSP
-	
+
 I2C_sleep_accelerometer0:   ;(needed)
 	; accelerometer
 	bsf		SSP1CON2,SEN				; start condition
@@ -794,8 +795,8 @@
 	movlw	b'00000010'					; data for CTRL_REG7: magnetic sensor power-down mode
 	rcall	I2C_TX
 	bsf		SSP1CON2,PEN				; stop condition
-	bra 	WaitMSSP					; (And return) - no I2C_sleep_accelerometer1 required (sleeps with magnetic sensor)
-	
+	bra		WaitMSSP					; (And return) - no I2C_sleep_accelerometer1 required (sleeps with magnetic sensor)
+
 
 I2C_sleep_compass2:
 	; magnetic
@@ -853,7 +854,7 @@
 	movlw	b'00000000'					; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20
 	rcall	I2C_TX
 	bsf		SSP1CON2,PEN				; stop condition
-	bra	WaitMSSP					; ... and return
+	bra		WaitMSSP					; ... and return
 
 WaitMSSP:
 	decfsz	i2c_temp1,F					; check for timeout during I2C action
@@ -1076,7 +1077,7 @@
 	movlw	.100						; max. value is  100 %
 	cpfslt	batt_percent				; batt_percent < 100 % ?
 	movwf	batt_percent				; NO  - limit to 100 %
-	return
+	return								; done
 
 lt2942_set_to_zero_percent:
 	clrf	i2c_temp1
@@ -1128,6 +1129,28 @@
 	bra		WaitMSSP					; ... and return
 
 
+	global	reset_battery_gauge_and_lt2942	; called from comm and menu tree
+reset_battery_gauge_and_lt2942:				; reset battery gauge chip and battery registers
+	btfsc	battery_gauge_available			; battery gauge chip available?
+	call	lt2942_charge_done				; YES - reset meter to 0xFFFF
+	;bra	reset_battery_gauge				; continue resetting gauge registers
+
+	global	reset_battery_gauge
+reset_battery_gauge:						; reset gauge registers
+	bsf		block_battery_gauge				; suspend ISR from accessing the battery registers
+	movlw	.100							; set battery level to 100%
+	movwf	batt_percent					; ...
+	banksel	battery_gauge					; select bank ISR data
+	clrf	battery_gauge+0					; null the battery registers
+	clrf	battery_gauge+1					; ...
+	clrf	battery_gauge+2					; ...
+	clrf	battery_gauge+3					; ...
+	clrf	battery_gauge+4					; ...
+	clrf	battery_gauge+5					; ...
+	banksel	common							; back to bank common
+	goto	eeprom_battery_gauge_write		; update battery registers in EEPROM, unblock ISR and return
+
+
 ;=============================================================================
 ; Transmitter Functions
 ;
--- a/src/i2c.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/i2c.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File i2c.inc                               combined next generation V3.1.0
+;   File i2c.inc                              combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -19,6 +19,9 @@
 	extern	lt2942_get_accumulated_charge	; read battery gauge register
 	extern	lt2942_charge_done				; set  battery gauge register to fully charged
 
+	extern	reset_battery_gauge_and_lt2942	; reset battery registers and battery gauge chip
+	extern	reset_battery_gauge				; reset battery registers only
+
  IFDEF _rx_functions
 	extern	I2C_probe_OSTC_rx				; set ostc_rx_present bit if present
 	extern	I2C_get_tankdata				; get the tank data
--- a/src/isr.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/isr.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File isr.asm                              combined next generation V3.06.2
+;   File isr.asm                              combined next generation V3.08.8
 ;
 ;   INTERUPT subroutines
 ;
@@ -610,7 +610,7 @@
 
 	; reset the surface interval timers if requested
 	btfsc	reset_surface_interval		; shall reset both surface interval timers?
-	call	clr_surface_interval		; YES
+	call	rst_surface_interval		; YES
 
 	; reset the timebase if requested
 	btfss	reset_timebase				; shall reset the timebase?
@@ -716,9 +716,11 @@
 	; Remark: although all the constants are named current_xxxx, in reality they mean charge!
 
 	; Calculate current consumption for LED backlight: 47*CCPR1L+272  (according to values in hwos.inc: 115*CCPR1L+216)
-	movf	CCPR1L,W						; get CCPR1L into WREG
-	mullw	current_backlight_multi			; PRODH:PRODL  = k * WREG = current_backlight_multi * CCPR1L
-	ADDLI	current_backlight_offset,PRODL	; PRODH:PRODL += current_backlight_offset
+	movlw	.70								; screen type 3 has a fix backlight current slope
+	btfss	screen_type3					; does the OSTC have a screen type 3 ?
+	movf	CCPR1L,W						; NO - for screen types 0, 1 and 2 get the slope from CCPR1L
+	mullw	current_backlight_multi			; multiply with backlight factor current_backlight_multi
+	ADDLI	current_backlight_offset,PRODL	; add           backlight offset current_backlight_offset
 	MOVII	PRODL,isr_mpr					; copy result to isr_mpr
 
 	; Add current for CPU and GPU
@@ -936,20 +938,24 @@
 	INCI	surface_interval_mins				; NO  - increment surface interval
 	return										;     - done
 
-clr_surface_interval:
+rst_surface_interval:
 	bcf		reset_surface_interval					; reset request flag
-	; clear the surface interval counted in seconds
+	; reset the surface interval counted in seconds
 	clrf	surface_interval_secs+0					; reset surface interval (seconds), lowest  byte
 	clrf	surface_interval_secs+1					; ...
 	clrf	surface_interval_secs+2					; ...
 	clrf	surface_interval_secs+3					; reset surface interval (seconds), highest byte
-clr_surface_interval_mins:
-	; clear the surface interval counted in minutes
+	; reset the surface interval counted in minutes
 	movff	opt_diveTimeout,surface_interval_mins+0	; set   surface interval (minutes), low  byte, to dive timeout offset
 	clrf	surface_interval_mins+1					; reset surface interval (minutes), high byte
+	return											; done
 
+clr_surface_interval_mins:
+	clrf	surface_interval_mins+0					; reset surface interval (minutes), low byte
+	clrf	surface_interval_mins+1					; reset surface interval (minutes), high byte
 	return											; done
 
+
 ;=============================================================================
 
 	END
--- a/src/logbook.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/logbook.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File logbook.asm                          combined next generation V3.06.1
+;   File logbook.asm                          combined next generation V3.08.8
 ;
 ;   Logbook
 ;
@@ -25,12 +25,17 @@
 #include "surfmode.inc"
 #include "divemode.inc"
 #include "ghostwriter.inc"
+#include "rtc.inc"
+
+#DEFINE inside_loogbook
+#include "logbook.inc"
+
 
 	extern	do_main_menu2
 	extern	gaslist_show_mix
 
 
-	;---- Private local variables -------------------------------------------------
+;---- Private local variables ------------------------------------------------
 
 	CBLOCK	local1						; max size is 16 byte !!!
 		count_temperature				; current sample count for temperature divisor
@@ -66,7 +71,6 @@
 		vertical_interval:2				; holds interval of samples for vertical 10min line
 		backup_color1					; used for restoring drawing color
 		backup_color2					; used for restoring drawing color
-		salinity						; salinity during the dive
 		fill_between_rows				; used for fill between rows
 		logbook_temp					; used as temp
 		logbook_temp_backup				; used as backup for temp
@@ -77,7 +81,8 @@
 		divisor_decoplan				; divisor used while sampling of the dive data
 		divisor_cns						; divisor used while sampling of the dive data
 		divisor_tank					; divisor used while sampling of the dive data
-	ENDC								; used: 16 byte, remaining: 0 byte => FULL
+		total_num_dives					; total number of dives (low byte on)
+	ENDC								; used: 16 byte, remaining: 0 byte => full
 
 
 	; Remarks: The variable gaslist_gas is "misused" here as a local variable,
@@ -99,10 +104,11 @@
 #DEFINE log_show_gas_short			logbook_flags,6
 ;									logbook_flags,7	; unused
 
+
 ; Logbook Coordinates
 #DEFINE logbook_list_left			.10				; column of dive# in list
 #DEFINE logbook_row_offset			.27				; distance between rows of list
-#DEFINE logbook_row_number			.7				; amount of rows in the list
+#DEFINE logbook_row_number			.7				; number of dive entry rows per list
 
 ; Profile display
 #DEFINE profile_height_pixels		.157			; amount of pixels height for profile display
@@ -129,8 +135,8 @@
 #DEFINE log_max_value_column		.1
 
 ; Divetime
-#DEFINE log_divetime_value_row		.38
-#DEFINE log_divetime_value_column	.60
+#DEFINE log_divetime_mins_value_row		.38
+#DEFINE log_divetime_mins_value_column	.60
 
 ; Gaslist below profile
 #DEFINE log_gas_row					.225
@@ -186,51 +192,6 @@
 #DEFINE MBAR_column					log2_salinity_column
 
 
-; Header coordinates
-#DEFINE log_profile_version			.8
-#DEFINE log_date					.12
-#DEFINE log_time					.15
-#DEFINE log_max_depth				.17
-#DEFINE log_divetime				.19
-#DEFINE log_min_temp				.22
-#DEFINE log_surface_press			.24
-#DEFINE log_desattime				.26
-#DEFINE log_gas1					.28
-#DEFINE log_gas2					.32
-#DEFINE log_gas3					.36
-#DEFINE log_gas4					.40
-#DEFINE log_gas5					.44
-#DEFINE log_firmware				.48
-#DEFINE log_battery					.50
-#DEFINE log_samplingrate			.52
-#DEFINE log_cns_start				.53
-#DEFINE log_gf_start				.55
-#DEFINE log_gf_end					.56
-#DEFINE log_batt_info				.59
-#DEFINE log_sp1						.60
-#DEFINE log_sp2						.62
-#DEFINE log_sp3						.64
-#DEFINE log_sp4						.66
-#DEFINE log_sp5						.68
-#DEFINE log_salinity				.70
-#DEFINE log_cns_end					.71
-#DEFINE log_avr_depth				.73
-#DEFINE log_total_seconds			.75
-#DEFINE log_gf_lo					.77
-#DEFINE log_sat_mult				.77
-#DEFINE log_gf_hi					.78
-#DEFINE log_desat_mult				.78
-#DEFINE log_decomodel				.79
-#DEFINE log_total_dives				.80
-#DEFINE log_divemode				.82
-#DEFINE log_last_stop				.243
-
-
-LOG_POINT_TO	macro	address
-	movlw	address
-	movwf	ext_flash_address+0
-	endm
-
 logbook		CODE
 
 ;=============================================================================
@@ -240,7 +201,6 @@
 
 	WIN_LEFT logbook_list_left-.8					; set horizontal position
 	WIN_FONT FT_SMALL								; select small font
-;	bcf		win_invert								; reset invert flag
 	call	TFT_standard_color						; print in white color
 	decf	menu_pos_cur,W							; get row number -1 into WREG
 	mullw	logbook_row_offset						; multiply with vertical offset between rows
@@ -251,83 +211,73 @@
 
 	global	logbook									; entry point coming from menu_tree.asm
 logbook:
-	clrf	logbook_flags
 	call	TFT_boot
 ;	call	TFT_standard_color
-	clrf	menu_pos_max							; number of used rows on current logbook-page
+
+	clrf	logbook_flags							; clear all flags
+	clrf	menu_pos_max							; clear number of used rows on current page
 	clrf	logbook_page_number						; here: # of current displayed page
 	clrf	logbook_divenumber						; # of dive in list during search
 	clrf	logbook_temp
 	clrf	logbook_temp_backup
-	movlw	logbook_row_number
-	movwf	menu_pos_cur							; number of current position on display (logbook_row_number-x)
-	read_int_eeprom .2								; get low-byte of total dives
-	movff	EEDATA,logbook_max_dive_counter
+
+	movlw	logbook_row_number						; get number of dive entry rows per list
+	movwf	menu_pos_cur							; initialize cursor position to last entry
 
-;-----------------------------------------------------------------------------	
-; display dive headers backwards from read_int_eeprom .2 = lo-1
-; 1st: 200000h-200FFFh -> lo=0
-; 2nd: 201000h-201FFFh -> lo=1
-; 3rd: 202000h-202FFFh -> lo=2
-; 256: 2FF000h-2FFFFFh -> lo=255 (And hi>0...)
-; Stop when
-; a) no dive is stored (no valid header found)
-; b) current dive has no valid header (Number of stored dives < 256)
-; c) when 255 dives are reached logbook_temp = 255
+	call	eeprom_total_dives_read					; read total number of dives
+	movf	mpr+0,W									; extract low byte
+	movwf	logbook_max_dive_counter				; copy to logbook_max_dive_counter
+	movwf	total_num_dives							; copy to total_num_dives, too
+
+
+;-----------------------------------------------------------------------------
+; display dive headers backwards from latest dive to first dive, stop when
+; - no dive is stored                (no valid header found)
+; - current dive has no valid header (past last dive, < 256 dives)
+; - when 255 dives are reached       (logbook display limit)
 
 logbook2:
 	incf	logbook_temp,F							; increase dive counter
 	incf	logbook_temp,W							; = 0x..FF ?
-	bz		logbook_reset							; YES - ..FF --> loop
+	bz		logbook_reset							; YES - loop
 
-	; Set ext_flash_address:3 to TOC entry of this dive
-	; 1st: 200000h-200FFFh -> logbook_max_dive_counter=0
-	; 2nd: 201000h-201FFFh -> logbook_max_dive_counter=1
-	; 3rd: 202000h-202FFFh -> logbook_max_dive_counter=2
-	; 256: 2FF000h-2FFFFFh -> logbook_max_dive_counter=255 (and hi>0...)
-
-	decf	logbook_max_dive_counter,F				; -1
+	; compute index for dive to show / goto previous dive
+	decf	logbook_max_dive_counter,F
 
-	clrf	ext_flash_address+0
-	clrf	ext_flash_address+1
-	movlw	0x20
-	movwf	ext_flash_address+2
-	movlw	.16
-	mulwf	logbook_max_dive_counter				; logbook_max_dive_counter*16 = offset to 0x2000 (up:hi)
-	movf	PRODL,W
-	addwf	ext_flash_address+1,F
-	movf	PRODH,W
-	addwfc	ext_flash_address+2,F
-	; pointer at the first 0xFA of header
+	; compute the start address of the header of the dive to show
+	movf	logbook_max_dive_counter,W				; hand over index in WREG
+	call	log_header_addr_by_index				; compute address of header start
 
-	call	ext_flash_byte_read						; reads one byte@ext_flash_address:3 into WREG and ext_flash_rw
-	movwf	ext_flash_rw
-	movlw	0xFA
-	cpfseq	ext_flash_rw							; 0xFA found?
-	bra		logbook3b								; NO - abort
+	; copy the first 22 byte of the header from FLASH to memory
+	FLASH_RR_READ mpr,header_buffer,.22
+
+	; check if there is a header
+	MOVCC	header_buffer+index_header_start,WREG	; read first byte of header
+	xorlw	0xFA									; header start code found?
+	bnz		logbook3b								; NO  - abort
 	incf	logbook_divenumber,F					; YES - new header found, increase logbook_divenumber
 	bra		logbook4								;     - done with searching, display the header
 
 logbook3b:
 	btfss	logbook_page_not_empty					; was there at least one dive?
-	bra		exit_logbook							; not a single header was found, leave logbook
-	bra		logbook_display_loop2
+	bra		exit_logbook							; NO  - not a single header was found, leave logbook
+	bra		logbook_display_loop2					; YES - can show something
 
 logbook_reset:
 	tstfsz	logbook_divenumber						; was there at least one dive?
-	bra		logbook_reset2
-	bra		logbook3b								; NO - nothing to do
+	bra		logbook_reset2							; YES - proceed
+	bra		logbook3b								; NO  - nothing to do
 
 logbook_reset2:
-	bsf		all_dives_shown							; YES
-	bra		logbook_display_loop2					; continue
+	bsf		all_dives_shown							; flag all dives are shown
+	bra		logbook_display_loop2					; check number of dives on page and append navigation
 
 logbook4:
-	btfsc	all_dives_shown							; all dives displayed?
-	bra		logbook_display_loop2					; YES - display first page again
+	btfsc	all_dives_shown							; all dives shown?
+	bra		logbook_display_loop2					; YES - page done
 	call	display_listdive						; NO  - display short header for list on current list position
-	movlw	logbook_row_number						;     - 
-	cpfseq	menu_pos_cur							;     - first dive on list (top row)?
+	movlw	logbook_row_number						;     - load max number of lines
+	cpfseq	menu_pos_cur							;     - cursor on last line (exit)?
 	bra		logbook_display_loop1					;       NO - skip saving of address
 
 	; store all registers required to rebuilt the current logbook page after the detail/profile view
@@ -336,15 +286,16 @@
 	movff	logbook_temp,logbook_temp_backup						; amount of dives drawn until now
 
 logbook_display_loop1:
-	decfsz	menu_pos_cur,F							; list full?
-	bra		logbook2								; NO - search another dive for our current logbook page
-
+	decfsz	menu_pos_cur,F							; all lines used up?
+	bra		logbook2								; NO  - loop to show another dive
 logbook_display_loop2:
-	btfss	logbook_page_not_empty					; was there one dive at all?
-	bra		logbook									; YES - so reload the first page
+	btfss	logbook_page_not_empty					; YES - was there one dive at all?
+	bra		logbook									;       NO  - restart from the first page
+	;bra	logbook_display_loop3					;       YES - complete page and start HMI
 
-	; TFT_mask...
+logbook_display_loop3:
 
+	; print navigation lines
 	WIN_LEFT	logbook_list_left
 	WIN_TOP		logbook_row_offset*(logbook_row_number+.0)
 	STRCPY_TEXT_PRINT tNextLog						; "Next Page"
@@ -353,161 +304,123 @@
 	WIN_TOP		logbook_row_offset*(logbook_row_number+.1)
 	STRCPY_TEXT_PRINT tExit							; "Exit"
 
-	movlw	d'1'									; set cursor to position 1...
-	btfsc	return_from_profileview					; .. unless we are returning from a detail/profile view
-	movf	logbook_menupos_temp,W					; load last cursor position again
-	movwf	menu_pos_cur							; and set menu_pos_cur byte
-	bcf		return_from_profileview					; do this only once while the page is loaded again
+	movlw	d'1'									; default cursor to position 1
+	btfsc	return_from_profileview					; returning from a detail/profile view?
+	movf	logbook_menupos_temp,W					; YES - reload last cursor position
+	movwf	menu_pos_cur							; set cursor position
+	movlw	logbook_row_number+.1					; get menu line where the next page item is
+	btfsc	keep_cursor_new_page					; do we come from the "next page" line?
+	movwf	menu_pos_cur							; YES - set cursor to "next line" again
 
+	bcf		return_from_profileview					; clear flag for returning from detail/profile view
+	bcf		keep_cursor_new_page					; clear flag for coming from "next page"
 	bcf		logbook_page_not_empty					; obviously the current page is NOT empty
 
-	movlw	d'8'									; set cursor to position 7...
-	btfsc	keep_cursor_new_page					; ... if we came from the "new page" line
-	movwf	menu_pos_cur							; and set menu_pos_cur byte
-	bcf		keep_cursor_new_page
-
 	call	TFT_logbook_cursor						; show the cursor
 
 logbook_loop_pre:
 	call	logbook_preloop_tasks					; clear timeout, some flags and switch on backlight
 logbook_loop:
 	btfsc	switch_left								; left button pressed?
-	goto	next_logbook3							; YES - adjust cursor or create new page
-	btfsc	switch_right							; right button pressed?
-	bra		display_profile_or_exit					; YES - view details/profile or exit logbook
-	call	housekeeping							; NO to both - handle screen dump request, timeout and entering dive mode
-	bra		logbook_loop							;            - loop waiting for something to do
+	goto	next_logbook3							; YES - move cursor
+	btfsc	switch_right							; NO  - right button pressed?
+	bra		display_profile_or_exit					;       YES - view details/profile
+	call	housekeeping							;       NO  - handle screen dump request, timeout and entering dive mode
+	bra		logbook_loop							;           - loop waiting for something to do
 
 display_profile_or_exit:
-	movlw	logbook_row_number+.2					; exit?
-	cpfseq	menu_pos_cur							; YES
-	bra		display_profile_or_exit2				; NO  - check for "Next Page"
+	movlw	logbook_row_number+.2					; get menu line were the exit item is
+	cpfseq	menu_pos_cur							; cursor on exit line?
+	bra		display_profile_or_next					; NO  - show profile or next page
+	;bra	exit_logbook							; YES - exit logbook
 
 exit_logbook:
 	bcf		switch_right							; clear pending button events
 	bcf		switch_left								; ...
-	goto	do_main_menu2							; jump-back to menu_tree.asm
+	goto	do_main_menu2							; jump-back to main menu (in menu_tree.asm)
 
-display_profile_or_exit2:
-	movlw	logbook_row_number+.1					;
-	cpfseq	menu_pos_cur							; do next page?
-	bra		display_profile							; NO  - show details/profile
-	goto	next_logbook2							; YES - next page
+display_profile_or_next:
+	movlw	logbook_row_number+.1					; get menu line were the next page item is
+	cpfseq	menu_pos_cur							; cursor on next page line?
+	bra		display_profile							; NO  - show profile of selected dive
+	goto	next_logbook2							; YES - show next page
 
+;-----------------------------------------------------------------------------
+; show graphical dive profile
+;
 display_profile:
 	bcf		bailout_mode							; clear event flag
 	bcf		event_gas_change_gas6					; clear event flag
 	movff	menu_pos_cur,logbook_menupos_temp		; store current cursor position
 	bsf		return_from_profileview					; tweak search routine to exit after found
 
-	movf	logbook_page_number,W					; number of page
-	mullw	logbook_row_number
-	movf	PRODL,W
-	addwf	menu_pos_cur,W							; page * logbook_row_number + menu_pos_cur =
-	movwf	divenumber								; # of dive to show
+	; compute the number of the dive to show
+	movf	logbook_page_number,W					; get page number of page we are on
+	mullw	logbook_row_number						; multiply with number of dives per page
+	movf	PRODL,W									; copy low byte to WREG
+	addwf	menu_pos_cur,W							; add number of selected dive on current page page
+	movwf	divenumber								; result is the number of the dive to show
+
+	; compute the header address by the dive number
+	call	log_header_addr_by_divenumber
+
+	; copy the complete header from FLASH to memory
+	FLASH_RR_READ mpr,header_buffer,.256
+
+	; read the sampling rate
+	MOVCC	header_buffer+index_samplingrate,sampling_rate
+
+	; --- start drawing the dive profile page ---
 
 display_profile2:
 	call	TFT_boot
-
-; set ext_flash pointer to "#divenumber-oldest" dive
-; compute read_int_eeprom .2 - divenumber
-; read required header data for profile display
-; look in header for pointer to begin of dive profile (Byte 2-4)
-; set pointer (ext_flash_log_pointer:3) to this address, start drawing
+	call	TFT_standard_color
 
-	decf	divenumber,F							; -1
-	read_int_eeprom .2
-	movf	EEDATA,W
-	bcf		STATUS,C
-	subfwb	divenumber,W							; max. dives (low value) - dive number
-	movwf	lo										; result
-	incf	divenumber,F							; +1
-	; 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
-	; 256: 2FF000h-2FFFFFh -> lo=255 (And hi>0...)
-	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
-	; pointer at the first 0xFA of header
-
-	; Now, show profile
-	LOG_POINT_TO log_samplingrate
-	call	ext_flash_byte_read						; read sampling rate
-	movff	ext_flash_rw,sampling_rate				; store for later use
-
-	LOG_POINT_TO .2
-	call	ext_flash_byte_read_plus				; read start address of profile
-	movff	ext_flash_rw,ext_flash_log_pointer+0
-	call	ext_flash_byte_read_plus				; read start address of profile
-	movff	ext_flash_rw,ext_flash_log_pointer+1
-	call	ext_flash_byte_read_plus				; read start address of profile
-	movff	ext_flash_rw,ext_flash_log_pointer+2
-
-	CLRI	logbook_sample_counter					; holds amount of read samples
-
-	call	TFT_standard_color
+	; show dive number
 	call	logbook_show_divenumber					; show the dive number in medium font
 
+	; show date
 	WIN_SMALL logbook_date_column, logbook_date_row
-	LOG_POINT_TO log_date
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,up							; year
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,hi							; month
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,lo							; day
+	MOVTT	header_buffer+index_date,mpr			; read date
 	call	TFT_convert_date						; converts into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2
 	STRCAT_PRINT ""
 
-	WIN_SMALL log_divetime_value_column,logbook_date_row	; align with surrounding data
-	LOG_POINT_TO log_divemode
-	call	ext_flash_byte_read_plus				; read dive mode
-	movff	ext_flash_rw,lo							; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR
+	; show dive mode
+	WIN_SMALL log_divetime_mins_value_column,logbook_date_row	; align with surrounding data
+	MOVCC	header_buffer+index_divemode,lo			; read dive type (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR)
 	call	TFT_decotype_logbook					; "strcat_print"s dive mode (OC, CC, Gauge, Apnea or pSCR)
 													; also sets aux_flag in case the dive was done in a deco mode
 
+	; show time
 	WIN_SMALL logbook_time_column, logbook_time_row
-	LOG_POINT_TO log_time
-	call	ext_flash_byte_read_plus				; hour
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; minutes
-	movff	ext_flash_rw,hi
-	output_99x										; hour
-	PUTC	':'
-	movff	hi,lo
-	output_99x										; minute
+	MOVII	header_buffer+index_time,mpr			; get time
+	output_99x										; print hour
+	PUTC	':'										; print spacing ":"
+	movff	hi,lo									; print minute
+	output_99x										; ...
 	STRCAT_PRINT ""									; display 1st row of details
 
-	LOG_POINT_TO log_profile_version
-	call	ext_flash_byte_read_plus				; profile version
+	; get log format version
+	MOVCC	header_buffer+index_profile_version,lo	; read profile format version
 	movlw	0x24
-	cpfslt	ext_flash_rw							; < 0x24 ?
-	bra		log_skip_extra_icon						; YES -  skip
+	cpfslt	lo										; < 0x24 ?
+	bra		log_skip_extra_icon						; YES -  skip end of dive icon
 
+	; print end of dive icon
 	WIN_SMALL logbook_time_column-.8, logbook_time_row
-	STRCPY_PRINT 0x94								; "End of dive" icon
+	STRCPY_PRINT 0x94
 
 log_skip_extra_icon:
-	LOG_POINT_TO log_max_depth
-	call	ext_flash_byte_read_plus				; read max depth
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; read max depth
-	movff	ext_flash_rw,hi
-	MOVII	mpr,xA									; calculate y-scale for profile display
-	MOVLI	profile_height_pixels,xB				; pixel height available for profile
+	MOVII	header_buffer+index_max_depth,mpr		; get max depth in [mbar]
+
+	; compute vertical scale (y-axis)
+	MOVII	mpr,xA
+	MOVLI	profile_height_pixels,xB				; number of pixels available for plot
 	call	div16x16								; xC = xA / xB with xA as remainder
 	MOVII	xC,y_scale								; y-scale (mbar/pixel)
-	INCI	y_scale									; increase one, because there may be a remainder
+	INCI	y_scale									; increase by one to include potential remainder (round up)
 
+	; compute number of pixels per each 10 m
 	movlw	LOW   ((profile_height_pixels+1)*.1000)
 	movwf	xC+0
 	movlw	HIGH  (((profile_height_pixels+1)*.1000) & h'FFFF')
@@ -515,23 +428,48 @@
 	movlw	UPPER ((profile_height_pixels+1)*.1000)
 	movwf	xC+2
 	clrf	xC+3
+	MOVII	mpr,xB									; get max. depth in mbar
+	call	div32x16								; xC:4 = xC:4 / xB:2 with xA as remainder
+	MOVII	xC,x_scale								; pixels/10m (for scale, draw any xx rows a scale-line)
 
-	MOVII	mpr,xB									; max. Depth in mbar
-	call	div32x16								; xC:4 = xC:4 / xB:2 with xA as remainder
-	MOVII	xC,x_scale								; Pixels/10m (for scale, draw any xx rows a scale-line)
+	; safeguard scale to become zero
+	movf	x_scale+0,W								; get      low  byte
+	iorwf	x_scale+1,W								; ior with high byte
+	btfsc	STATUS,Z								; x_scale = zero ?
+	incf	x_scale+1,F								; YES - set to 256 to make "display_profile2e" working
 
-	movf	x_scale+0,W
-	iorwf	x_scale+1,W								; x_scale:2 = zero ?
-	bnz		display_profile_offset4					; NO  - continue
-	incf	x_scale+1,F								; YES - make x_scale+1>1 to make "display_profile2e" working
+	; calculate vertical interval
+	MOVLI	.600,xA									; a vertical line every 600 seconds (10 minutes)
+	movff	sampling_rate,xB+0						; copy sampling rate to xB, low  byte
+	clrf	xB+1									; clear                 xB, high byte
+	call	div16x16								; xC=xA/xB with xA as remainder
+	MOVII	xC,vertical_interval					; vertical_interval:2 holds number of samples between each vertical 10 min lines
+
+	; get total sample time in seconds
+	MOVII	header_buffer+index_total_seconds,xA
 
-display_profile_offset4:
+	; calculate x-scale value
+	MOVLI	profile_width_pixels,xB					; horizontal width of plot area in pixels
+	call	div16x16								; xC = xA / xB with xA as remainder: seconds per pixel
+	MOVII	xC,xA									; copy seconds/pixel to xA
+	movff	sampling_rate,xB+0						; divide through sampling rate
+	clrf	              xB+1						; ...
+	call	div16x16								; xC = xA / xB with xA as remainder: samples per pixel
+	MOVII	xC,profile_temp1						; store samples/pixel
+	INCI	profile_temp1							; increment result by 1 to include potential remainder (round up)
+
 	WIN_SMALL log_max_value_column,log_max_value_row
 
+	; get max depth in [mbar]
+	MOVII	header_buffer+index_max_depth,mpr
+
+	; print depth
 	TSTOSS	opt_units								; 0=Meters, 1=Feets
 	bra		display_profile_offset4_metric			; 0 - do metric
-													; 1 - do imperial
-	call	convert_mbar_to_feet					; convert value in lo:hi from mbar to feet
+	;bra	display_profile_offset4_imperial		; 1 - do imperial
+
+display_profile_offset4_imperial:
+	call	convert_cm_to_feet						; convert value in mpr from [cm] to [feet]
 	PUTC	' '
 	bcf		leftbind
 	output_16_3										; limit to 999 and display only (0-999)
@@ -539,228 +477,189 @@
 	bra		display_profile_offset4_common
 
 display_profile_offset4_metric:
-	bsf		leftbind
-	output_16dp d'3'								; max. depth
+	bsf		ignore_digit5							; no cm...
+	movlw	d'1'									; no 1000 m
+	movwf	ignore_digits							; ...
+	output_16dp d'3'								; xxx.y
 	STRCAT_TEXT_PRINT tMeters
+	;bra	display_profile_offset4_common
 
 display_profile_offset4_common:
-	call	ext_flash_byte_read_plus				; dive time in minutes
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,hi							; dive time in minutes
-
-	MOVII	mpr,xA									; calculate x-scale for profile display, calculate total dive seconds first
-	MOVLI	.60,xB									; 60 seconds are one minute
-	call	mult16x16								; result is in xC:2
-
-	WIN_SMALL log_divetime_value_column,log_divetime_value_row
+	WIN_SMALL log_divetime_mins_value_column,log_divetime_mins_value_row
 	bsf		leftbind
-	output_16										; dive time minutes
-	MOVLI	.600,xA									; a vertical line every 600 seconds
-	movff	sampling_rate,xB+0						; copy sampling rate to xB, low  byte
-	clrf	xB+1									; clear                 xB, high byte
-	call	div16x16								; xA/xB=xC with xA as remainder
-	MOVII	xC,vertical_interval					; vertical_interval:2 holds interval of samples for vertical 10min line
 
-	; Restore dive time in minutes:
-	; get real sample time
-	LOG_POINT_TO log_total_seconds
-	call	ext_flash_byte_read_plus				; total sample time in seconds
-	movff	ext_flash_rw,xC+0
-	call	ext_flash_byte_read_plus				; total sample time in seconds
-	movff	ext_flash_rw,xC+1
+	; show dive time minutes : seconds
+	MOVTT	header_buffer+index_divetime,mpr		; get   dive time
+	output_16										; print dive time minutes
+	PUTC	'm'										; print "m" (minutes)
+	movff	up,lo									; print dive time seconds
+	output_99x										; dive time seconds
+	STRCAT_PRINT "s"								; print "s" (seconds)
 
-	PUTC	':'
-	LOG_POINT_TO log_divetime+.2
-	call	ext_flash_byte_read_plus				; read dive time seconds
-	movff	ext_flash_rw,lo
-	MOVII	xC,xA									; now calculate x-scale value
-	MOVLI	profile_width_pixels,xB					; pix width available
-	call	div16x16								; xC = xA / xB with xA as remainder
-	MOVII	xC,xA
-	movff	sampling_rate,xB+0						; divide through sampling rate (time interval)
-	clrf	              xB+1
-	call	div16x16								; xC = xA / xB with xA as remainder
-	MOVII	xC,profile_temp1						; store value (use any #xC sample, skip xC-1) into temp registers
-	INCI	profile_temp1							; increase by one, there might be a remainder
+	; get minimum temperature (for later use)
+	MOVII	header_buffer+index_min_temp,logbook_min_tp
 
-	bsf		leftbind
-	output_99x										; dive time seconds
-	call	TFT_standard_color
-	STRCAT_PRINT ""
-
-	call	ext_flash_byte_read_plus				; read min. temperature, low  byte
-	movff	ext_flash_rw,logbook_min_tp+0
-	call	ext_flash_byte_read_plus				; read min. temperature, high byte
-	movff	ext_flash_rw,logbook_min_tp+1
-
+	; print gases
 	btfss	aux_flag								; dive done in a deco mode?
 	bra		logbook_set_gas_color					; NO - always use gas 1 color (white) then
 
-	; Set pointer to gas 1 type
-	LOG_POINT_TO log_gas1+.3
-	call	ext_flash_byte_read_plus				; read gas type
-	decfsz	ext_flash_rw,W							; = 1 (= "First") ?
+	; set pointer to gas 1 type
+	MOVCC	header_buffer+index_gas1+.3,WREG		; read gas type
+	decfsz	WREG,W									; = 1 (= "First") ?
 	bra		logbook_find_first_gas2					; NO
 logbook_set_gas_color:
 	movlw	.1										; YES - select white color
-	movwf	ext_flash_rw
 	bra		logbook_find_first_gas_done
+
 logbook_find_first_gas2:
-	; Set pointer to gas 2 type
-	LOG_POINT_TO log_gas2+.3
-	call	ext_flash_byte_read_plus				; read gas type
-	decfsz	ext_flash_rw,W							; = 1 (= "First") ?
+	; set pointer to gas 2 type
+	MOVCC	header_buffer+index_gas2+.3,WREG		; read gas type
+	decfsz	WREG,W									; = 1 (= "First") ?
 	bra		logbook_find_first_gas3					; NO
 	movlw	.2										; YES - select green color
-	movwf	ext_flash_rw
 	bra		logbook_find_first_gas_done
+
 logbook_find_first_gas3:
-	; Set pointer to gas 3 type
-	LOG_POINT_TO log_gas3+.3
-	call	ext_flash_byte_read_plus				; read gas type
-	decfsz	ext_flash_rw,W							; = 1 (= "First") ?
+	; set pointer to gas 3 type
+	MOVCC	header_buffer+index_gas3+.3,WREG		; read gas type
+	decfsz	WREG,W									; = 1 (= "First") ?
 	bra		logbook_find_first_gas4					; NO
 	movlw	.3										; YES - select red color
-	movwf	ext_flash_rw
 	bra		logbook_find_first_gas_done
+
 logbook_find_first_gas4:
-	; Set pointer to gas 4 type
-	LOG_POINT_TO log_gas4+.3
-	call	ext_flash_byte_read_plus				; read gas type
-	decfsz	ext_flash_rw,W							; = 1 (= "First") ?
+	; set pointer to gas 4 type
+	MOVCC	header_buffer+index_gas4+.3,WREG		; read gas type
+	decfsz	WREG,W									; = 1 (= "First") ?
 	bra		logbook_find_first_gas5					; NO
 	movlw	.4										; YES - select yellow color
-	movwf	ext_flash_rw
 	bra		logbook_find_first_gas_done
+
 logbook_find_first_gas5:
-	movlw	.5										; must be gas 5, select cyan color
-	movwf	ext_flash_rw
+	; must be gas 5 then
+	movlw	.5										; select cyan color
+	;bra	logbook_find_first_gas_done
+
 logbook_find_first_gas_done:
-	movff	ext_flash_rw,backup_color1				; keep copy to restore color
-	movff	ext_flash_rw,WREG						; copy gas number to WREG for color coding
+	movwf	backup_color1							; keep copy of color for later restore
 	call	TFT_color_code_gas						; set color
-	; Pointer is now trashed!
 
-	; Point to profile portion of this dive
-	movff	ext_flash_log_pointer+0,ext_flash_address+0
-	movff	ext_flash_log_pointer+1,ext_flash_address+1
-	movff	ext_flash_log_pointer+2,ext_flash_address+2
+	; set ext_flash_address to the begin of the profile data
+	MOVTT	header_buffer+index_profile_start_address,ext_flash_address
 
-	incf_ext_flash_address_0x20 d'2'				; skip 0xFA 0xFA
-	call	ext_flash_byte_read_plus_0x20			; read low byte of total dives into ext_flash_rw (at the time the dive was made)
+	; skip the 0xFA 0xFA header of the profile data
+	ext_flash_inc_address_0x20 d'2'
 
-	; Load total number of dives (low byte only)
-	read_int_eeprom .2
-	incf	EEDATA,W								; +1
+	; initialize flag for signaling when last sample set was read
+	bcf		end_of_profile
+
+	; check if the profile actually belongs to this dive (check done with low bytes only)
+	FLASH_CC_READ_0x20 lo								; read dive  number in profile
+	incf	total_num_dives,W						; WREG = total number of dives + 1
 	bsf		STATUS,C								; set borrow
-	subfwb	divenumber,W							; total dives - dive# to show - 1 = low byte of total dives (at the time the dive was made)
-	cpfseq	ext_flash_rw							; # of dive in logbook (Must be equal with low byte in short header)
-	bra		display_profile_no_profile				; not equal, no profile for this dive available
+	subfwb	divenumber,W							; WREG = total number of dives - number of dive to show - 1
+	cpfseq	lo										; number of dive in profile = number of dive to show?
+	bra		display_profile_no_profile				; NO  - no profile data for this dive available
+	;bra	display_profile_show_profile			; YES - show profile
 
-	; Skip rest of short header: 3 Bytes
-	; Skip length of profile data: 3 Bytes
-	; Skip sampling rate in profile section: 1Byte
-	; Skip number of divisors: 1Byte
-	incf_ext_flash_address_0x20 d'8'
+display_profile_show_profile:
 
-; divisor temp
-	incf_ext_flash_address_0x20 d'2'
-;	call	ext_flash_byte_read_plus_0x20			; read information type
-;	call	ext_flash_byte_read_plus_0x20			; read information length
-	call	ext_flash_byte_read_plus_0x20			; read information divisor
-	movf	ext_flash_rw,W
-	movwf	divisor_temperature						; store divisor
-	movwf	count_temperature						; store to tp° counter, too
-; divisor deco
-	incf_ext_flash_address_0x20 d'2'
-;	call	ext_flash_byte_read_plus_0x20			; read information type
-;	call	ext_flash_byte_read_plus_0x20			; read information length
-	call	ext_flash_byte_read_plus_0x20			; read information divisor
-	movf	ext_flash_rw,W
-	movwf	divisor_deco							; store divisor
-	movwf	count_deco								; store as temp, too
-; divisor GF
-	incf_ext_flash_address_0x20 d'2'
-;	call	ext_flash_byte_read_plus_0x20			; read information type
-;	call	ext_flash_byte_read_plus_0x20			; read information length
-	call	ext_flash_byte_read_plus_0x20			; read information divisor
-	movff	ext_flash_rw,divisor_gf					; store divisor
-; divisor ppO2 sensors
-	incf_ext_flash_address_0x20 d'2'
-;	call	ext_flash_byte_read_plus_0x20			; read information type
-;	call	ext_flash_byte_read_plus_0x20			; read information length
-	call	ext_flash_byte_read_plus_0x20			; read information divisor
-	movff	ext_flash_rw,divisor_ppo2_sensors		; store divisor
-; divisor decoplan
-	incf_ext_flash_address_0x20 d'2'
-;	call	ext_flash_byte_read_plus_0x20			; read information type
-;	call	ext_flash_byte_read_plus_0x20			; read information length
-	call	ext_flash_byte_read_plus_0x20			; read information divisor
-	movff	ext_flash_rw,divisor_decoplan			; store divisor
-; divisor CNS
-	incf_ext_flash_address_0x20 d'2'
-;	call	ext_flash_byte_read_plus_0x20			; read information type
-;	call	ext_flash_byte_read_plus_0x20			; read information length
-	call	ext_flash_byte_read_plus_0x20			; read information divisor
-	movff	ext_flash_rw,divisor_cns				; store divisor
-; divisor tank data
-	incf_ext_flash_address_0x20 d'2'
-;	call	ext_flash_byte_read_plus_0x20			; read information type
-;	call	ext_flash_byte_read_plus_0x20			; read information length
-	call	ext_flash_byte_read_plus_0x20			; read information divisor
-	movff	ext_flash_rw,divisor_tank				; store divisor
+	; skip high byte of dive number          1 byte
+	; skip second header code                2 byte
+	; skip length of profile data            3 byte
+	; skip sampling rate in profile section  1 byte
+	; skip number of divisors                1 byte
+	;                                        ======
+	;        total number of bytes to skip = 8 byte
+	ext_flash_inc_address_0x20 d'8'
+
+	; read divisor temp
+	ext_flash_inc_address_0x20 d'2'					; skip information type and length
+	FLASH_CW_READ_0x20								; read  temperature divisor
+	movwf	divisor_temperature						; store temperature divisor
+	movwf	count_temperature						; store to temperature counter, too
+
+	; read divisor deco
+	ext_flash_inc_address_0x20 d'2'					; skip information type and length
+	FLASH_CW_READ_0x20								; read  deco divisor
+	movwf	divisor_deco							; store deco divisor
+	movwf	count_deco								; store to deco status counter, too
 
-	; Start profile display
+	; read divisor GF
+	ext_flash_inc_address_0x20 d'2'					; skip information type and length
+	FLASH_CC_READ_0x20 divisor_gf						; store saturation divisor
+
+	; read divisor ppO2 sensors
+	ext_flash_inc_address_0x20 d'2'					; skip information type and length
+	FLASH_CC_READ_0x20 divisor_ppo2_sensors			; store ppO2 divisor
+
+	; read divisor deco plan
+	ext_flash_inc_address_0x20 d'2'					; skip information type and length
+	FLASH_CC_READ_0x20 divisor_decoplan				; store deco plan divisor
+
+	; read divisor CNS
+	ext_flash_inc_address_0x20 d'2'					; skip information type and length
+	FLASH_CC_READ_0x20 divisor_cns						; store CNS divisor
+
+	; read divisor tank data
+	ext_flash_inc_address_0x20 d'2'					; skip information type and length
+	FLASH_CC_READ_0x20 divisor_tank					; store tank pressure divisor
+
+
+	; start drawing the profile
+
+	; set color
 	movlw	color_deepblue
 	call	TFT_set_color
-	; Draw a frame around profile area
+
+	; draw a frame around profile area
 	WIN_FRAME_COLOR16 profile_top-1,profile_top+profile_height_pixels+1,profile_left-1,profile_left+profile_width_pixels+1
 
-	movlw	profile_top
-	movwf	win_top
-	movlw	profile_left
-	movwf	win_leftx2								; left border (0-159)
-	movlw	d'1'
-	movwf	win_height
-	movlw	profile_width_pixels+.1
-	movwf	win_width+0								; right border (0-159)
-	clrf	win_width+1
-	bra		display_profile2f						; no 0m line
-display_profile2e:
-	call	TFT_box									; inputs: win_top, win_leftx2, win_height, win_width, win_color1, win_color2
-display_profile2f:
-	movf	win_top,W								; get row
-	addwf	x_scale+0,W								; add line interval distance to win_top
-	tstfsz	x_scale+1								; > 255 ?
-	movlw	d'255'									; YES - make win_top>239 -> abort here
-	btfsc	STATUS,C								; a carry from the addwf above?
-	movlw	d'255'									; YES - make win_top>239 -> abort here
-	movwf	win_top									; result in win_top again
-	movlw	profile_top+profile_height_pixels+.1	; limit
-	cpfsgt	win_top									; > 239 ?
-	bra		display_profile2e						; NO - draw another line
+	; draw depth grid
+	movlw	profile_top								; set top  position of plot area
+	movwf	win_top									; ...
+	movlw	profile_left							; set left position of plot area
+	movwf	win_leftx2								; ...
+	movlw	d'1'									; draw lines of 1 pixel width
+	movwf	win_height								; ...
+	movlw	profile_width_pixels+.1					; set right position of plot area
+	movwf	win_width+0								; ...
+	clrf	win_width+1								; ...
+	bra		display_profile2_loline					; do not draw the 0 m line
+display_profile2_loop:
+	call	TFT_box									; draw the line
+display_profile2_loline:
+	movf	win_top,W								; get last row drawn
+	addwf	x_scale+0,W								; add line interval distance, low byte
+	tstfsz	x_scale+1								; interval distance > 255 ?
+	movlw	d'255'									; YES - would make win_top > 239 -> prepare abort
+	btfsc	STATUS,C								; did the add produce a carry?
+	movlw	d'255'									; YES - would make win_top > 239 -> prepare abort
+	movwf	win_top									; write position of next line back to win_top
+	movlw	profile_top+profile_height_pixels+.1	; get limit for last line
+	cpfsgt	win_top									; line to draw beyond limit?
+	bra		display_profile2_loop					; NO - draw the line
 
+	; do various initializations for drawing the curves
 	clrf	gaslist_gas								; here: used as counter for depth readings
 	movlw	profile_width_pixels+profile_left-.1
 	movwf	ignore_digits							; here: used as counter for x-pixels
-	bcf		end_of_profile							; clear flag
 
 	movlw	profile_left+.1
 	movwf	logbook_pixel_x_pos						; here: used as column x2 (start at column 5)
 
 	movlw	profile_top+.1							; zero-m row
 	movwf	fill_between_rows
-	movwf	logbook_last_tp							; initialize for Tp° curve, too
+	movwf	logbook_last_tp							; initialize for temperature curve, too
 
-	movlw	LOW(-.100)								; initialize max tp° to -10.0 °C
+	movlw	LOW(-.100)								; initialize max temperature to -10.0 °C
 	movwf	logbook_max_tp+0
 	movlw	HIGH 0xFFFF & (-.100)
 	movwf	logbook_max_tp+1
 
-	setf	logbook_cur_tp+0						; initialize Tp°, before the first recorded point
-	setf	logbook_cur_tp+1
-	clrf	logbook_last_tp							; also reset previous Y for Tp°
+	setf	logbook_cur_tp+0						; initialize temperature to 0xFFFF = 'no data'
+	setf	logbook_cur_tp+1						; ...
+	clrf	logbook_last_tp							; also reset previous Y for temperature
 	clrf	logbook_ceiling							; ceiling = 0, correct value for no ceiling
 	movlw	profile_top+.1
 	movwf	logbook_min_temp_pos					; initialize for displaying the lowest  temperature
@@ -781,8 +680,11 @@
 
 ;	INIT_PIXEL_WRITE logbook_pixel_x_pos			; pixel x2 (also sets standard color!)
 
+	; start profile plotting loop
+	CLRI	logbook_sample_counter					; clear counter for amount of samples read so far
+
 profile_display_loop:
-	; Init pixel write
+	; initialize pixel write
 	movf	logbook_pixel_x_pos,W
 	mullw	2
 	call	pixel_write_col320
@@ -795,55 +697,55 @@
 	incf	profile_temp2+0,F						; YES - increase by 1
 
 profile_display_loop2:
-	rcall	profile_view_get_depth					; reads depth, temp and profile data
-
-	btfsc	end_of_profile							; end-of profile reached?
+	rcall	profile_view_get_depth					; read one set of depth, temp and event data
+	btfsc	end_of_profile							; end of profile data reached?
 	bra		profile_display_loop_done				; YES - skip all remaining pixels
 
 
-	;---- Draw Ceiling curve, if any ---------------------------------------------
-	movf	divisor_deco,W
-	bz		profile_display_skip_deco
+	;---- draw ceiling curve, if any ---------------------------------------------
+
+	movf	divisor_deco,W							; get divisor, deco data logged?
+	bz		profile_display_skip_deco				; NO - skip
 
 	movf	logbook_ceiling,W						; any deco ceiling?
-	bz		profile_display_skip_deco
+	bz		profile_display_skip_deco				; NO  - skip
 
 	mullw	.100									; YES - convert to mbar
-	MOVII	PROD,               sub_a				; ceiling depth
-	MOVII	logbook_cur_depth+0,sub_b				; current depth
-	call	cmpU16									; ceiling - current depth
-
-	movlw	color_dark_green						; dark green if ok
-	btfss	neg_flag								; current depth > ceiling ?
-	movlw	color_dark_red							; NO - dark red because ceiling is violated
-	call	TFT_set_color
-
-	MOVII	PROD,xA
-	MOVII	y_scale,xB								; divide pressure in mbar/quant for row offset
-	call	div16x16								; xC = xA / xB with xA as remainder
-
-	movlw	profile_top+.1							; starts right after the top line
-	movwf	win_top
-	movff	logbook_pixel_x_pos,win_leftx2			; left border (0-159)
-	movff	xC+0,win_height
-	call	half_vertical_line						; inputs: win_top, win_leftx2, win_height, win_color1, win_color2
+	MOVII	PROD,               sub_a				;     - ceiling depth
+	MOVII	logbook_cur_depth+0,sub_b				;     - current depth
+	call	cmpU16									;     - compute ceiling - current depth
+	movlw	color_dark_green						;     - dark green if ok
+	btfss	neg_flag								;     - current depth > ceiling ?
+	movlw	color_dark_red							;       NO - dark red because ceiling is violated
+	call	TFT_set_color							;     - set color
+	MOVII	PROD,xA									;     - divide pressure in mbar/pixel for row offset
+	MOVII	y_scale,xB								;     - ...
+	call	div16x16								;     - xC = xA / xB with xA as remainder
+	movlw	profile_top+.1							;     - start right after the top line
+	movwf	win_top									;     - ...
+	movff	logbook_pixel_x_pos,win_leftx2			;     - set left border (0-159)
+	movff	xC+0,win_height							;     - set hight
+	call	half_vertical_line						;     - color the area
 
 profile_display_skip_deco:
-	;---- Draw Tp° curve, if any ---------------------------------------------
-	movf	divisor_temperature,W
-	bz		profile_display_skip_temp
+
+	;---- draw temperature curve, if any ---------------------------------------------
+
+	movf	divisor_temperature,W					; get divisor, deco data logged?
+	bz		profile_display_skip_temp				; NO - skip
 
-	movf	logbook_cur_tp+0,W						; did we had already a valid Tp°C record?
-	andwf	logbook_cur_tp+1,W
-	incf	WREG
-	bz		profile_display_skip_temp				; NO - just skip drawing
+	movf	logbook_cur_tp+0,W						; did we had a valid temperature record already (0xFF = 'no data')?
+	andwf	logbook_cur_tp+1,W						; ...
+	incf	WREG									; ...
+	bz		profile_display_skip_temp				; NO - skip drawing
 
-	movlw	LOW  (((profile_height_pixels-.10)*.256)/.370)	; fixed tp° scale: (-2 .. +35°C * scale256 )/153pix
+	; fixed temperature scale: (-2 .. +35°C * scale256 ) / 153 pixel
+	movlw	LOW  (((profile_height_pixels-.10)*.256)/.370)
 	movwf	xB+0
 	movlw	HIGH (((profile_height_pixels-.10)*.256)/.370)
 	movwf	xB+1
 
-	movf	logbook_cur_tp+0,W						; current Tp° - (-2.0°C) == Tp° + 20
+	movf	logbook_cur_tp+0,W						; current temperature - (-2.0°C) == temperature + 20
 	addlw	LOW(.20)								; low byte
 	movwf	xA+0
 	movf	logbook_cur_tp+1,W
@@ -852,7 +754,7 @@
 	movwf	xA+1
 	call	mult16x16								; xA*xB=xC
 
-	; scale: divide by 256, ie. take just high byte.
+	; scale: divide by 256 -> just take the high byte
 	movf	xC+1,W
 	sublw	profile_top+profile_height_pixels-.10	; upside-down: Y = .75 + (.153 - result)
 	movwf	xC+0
@@ -867,64 +769,70 @@
 	call	TFT_set_color							; set color
 
 	movf	logbook_last_tp,W						; do we have a valid previous value?
-	bz		profile_display_temp_1					; NO - skip the vertical line
-	movwf	xC+1
-	call	profile_display_fill					; in this column between this row (xC+0) and the last row (xC+1)
+	bz		profile_display_temp_1					; NO  - skip the vertical line
+	movwf	xC+1									; YES - set end position
+	call	profile_display_fill					;     - draw in this column between this row (xC+0) and the last row (xC+1)
+
 profile_display_temp_1:
-	movf	xC+0,W									; current row
-	cpfsgt	logbook_min_temp_pos					; check limit
-	movwf	logbook_min_temp_pos					; lowest row in the temp graph
-	cpfslt	logbook_max_temp_pos					; check limit
-	movwf	logbook_max_temp_pos					; highest row in the temp graph
+	movf	xC+0,W									; get position
+	cpfsgt	logbook_min_temp_pos					; > min limit?
+	movwf	logbook_min_temp_pos					; NO - set to lowest  position for the temp graph
+	cpfslt	logbook_max_temp_pos					; < max limit?
+	movwf	logbook_max_temp_pos					; NO - set to highest position for the temp graph
 
-	movff	xC+0,logbook_last_tp
-	PIXEL_WRITE logbook_pixel_x_pos,xC+0			; set col (0..159) x row (0..239), put a current color pixel
+	movff	xC+0,logbook_last_tp					; set col (0..159) x row (0..239)
+	PIXEL_WRITE logbook_pixel_x_pos,xC+0			; draw a pixel
 
 profile_display_skip_temp:
-	;---- Draw depth curve ---------------------------------------------------
-	MOVII	y_scale,          xB					; divide pressure in mbar/quant for row offset
-	MOVII	logbook_cur_depth,xA
-	call	div16x16								; xC = xA / xB with xA as remainder
-	movlw	profile_top+.1
-	addwf	xC+0,F									; add 75 pixel offset to result
+
+	;---- draw depth curve ---------------------------------------------------
 
-	btfsc	STATUS,C								; ignore potential profile errors
-	movff	fill_between_rows,xC+0
+	MOVII	y_scale,          xB					; divide pressure in mbar/pixel for row offset
+	MOVII	logbook_cur_depth,xA					; get current depth
+	call	div16x16								; xC = xA / xB with xA as remainder
+	movlw	profile_top+.1							; get offset
+	addwf	xC+0,F									; add offset
+	btfsc	STATUS,C								; profile error?
+	movff	fill_between_rows,xC+0					; YES - ignore
 
-	movff	backup_color1,WREG						; copy gas number to WREG for color-coding
-	call	TFT_color_code_gas						; back to normal profile color
+	movf	backup_color1,W							; copy gas number to WREG for color-coding
+	call	TFT_color_code_gas						; set color
 
-	movff	fill_between_rows,xC+1
+	movff	fill_between_rows,xC+1					; set position
 	call	profile_display_fill					; in this column between this row (xC+0) and the last row (xC+1)
 	movff	xC+0,fill_between_rows					; store last row for fill routine
 
-	PIXEL_WRITE logbook_pixel_x_pos,xC+0			; set col (0..159) x row (0..239), put a std color pixel
-	incf	logbook_pixel_x_pos,F					; next column
+	PIXEL_WRITE logbook_pixel_x_pos,xC+0			; draw a pixel
+	incf	logbook_pixel_x_pos,F					; advance to next column
+
+	;---- draw marker square, if any -----------------------------------------
 
-	;---- Draw Marker square, if any -----------------------------------------
 	btfss	log_marker_found						; any marker to draw?
-	bra		profile_display_skip_marker				; NO
+	bra		profile_display_skip_marker				; NO  - skip
+	bcf		log_marker_found						; YES - clear flag
 
-	; tiny "m"
+	; set position
 	incf	fill_between_rows,W						; increase row (Y)
 	movwf	win_top
+
 	; limit win_top to 220
 	movlw	.220
 	cpfslt	win_top
 	movwf	win_top
 	decf	logbook_pixel_x_pos,W					; decrease column (X)
 	movwf	win_leftx2
+
 	; limit win_leftx2 to 151
 	movlw	.151
 	cpfslt	win_leftx2
 	movwf	win_leftx2
 
+	; print marker
 	movlw	color_orange
 	call	TFT_set_color
 	WIN_FONT FT_TINY
 	lfsr	FSR2,buffer
 	STRCPY_PRINT "m"
-	bcf		log_marker_found						; clear flag
 
 	movlw	profile_left
 	movwf	win_leftx2
@@ -939,112 +847,92 @@
 	call	TFT_box_write							; re-open box for d1
 
 profile_display_skip_marker:
-	;---- Draw CNS curve, if any ---------------------------------------------
-	movf	divisor_cns,W
-	bz		profile_display_skip_cns
+
+	;---- draw CNS curve, if any ---------------------------------------------
+
+	movf	divisor_cns,W							; get divisor, CNS logged?
+	bz		profile_display_skip_cns				; NO - skip
 	;
 	; add further code here...
 	;
+
 profile_display_skip_cns:
 
-	;---- Draw GF curve, if any ----------------------------------------------
-	movf	divisor_gf,W
-	bz		profile_display_skip_gf
+	;---- draw saturation curve, if any --------------------------------------
+
+	movf	divisor_gf,W							; get divisor, saturation logged?
+	bz		profile_display_skip_gf					; NO - skip
 	;
 	; add further code here...
 	;
+
 profile_display_skip_gf:
 
-	;---- All curves done
-
-profile_display_skip_loop1:							; skips readings
-	dcfsnz	profile_temp2+0,F
-	bra		profile_display_loop3					; check 16bit
-
-	rcall	profile_view_get_depth					; reads depth, temp and profile data
-
-	btfsc	end_of_profile							; end-of profile reached?
-	bra		profile_display_loop_done				; YES - skip all remaining pixels
-
+	; all curves done
 	bra		profile_display_skip_loop1
 
-profile_display_loop3:
-	decfsz	profile_temp2+1,F						; 16 bit x-scaler test
-	bra		profile_display_skip_loop1				; skips readings
 
-	decfsz	ignore_digits,F							; counts drawn x-pixels to zero
-	bra		profile_display_loop					; not ready yet
-	; done
+profile_display_skip_loop1:
+	dcfsnz	profile_temp2+0,F						; decrement low byte of x-scaler, became zero?
+	bra		profile_display_loop3					; YES - decrement high byte
+	rcall	profile_view_get_depth					; NO  - read next depth, temp and profile data set
+	btfsc	end_of_profile							;     - end-of profile reached?
+	bra		profile_display_loop_done				;       YES - skip all remaining pixels
+	bra		profile_display_skip_loop1				;       NO  - continue
 
-display_profile_no_profile:							; no profile available for this dive
+profile_display_loop3:
+	decfsz	profile_temp2+1,F						; decrement high byte of x-scaler, became zero?
+	bra		profile_display_skip_loop1				; NO  - continue
+	decfsz	ignore_digits,F							; YES - count drown x-pixels to zero, became zero?
+	bra		profile_display_loop					;       NO  - draw next sample
+	bra		profile_display_loop_done				;       YES - done
 
 profile_display_loop_done:
 	btfss	bailout_mode							; bailout during the dive?
-	bra		profile_display_loop_done_nobail		; NO
-													; YES - show "Bailout"
-	movlw	color_pink
-	call	TFT_set_color
-	WIN_TINY logbook_bailout_column,logbook_bailout_row
-	STRCPY_TEXT_PRINT tDiveBailout					; bailout
-profile_display_loop_done_nobail:
+	bra		profile_display_gas6					; NO  - skip next
+	movlw	color_pink								; YES - show "Bailout" in pink color
+	call	TFT_set_color							;     - ...
+	WIN_TINY logbook_bailout_column,logbook_bailout_row;  - ...
+	STRCPY_TEXT_PRINT tDiveBailout					;     - print text
+
+profile_display_gas6:
 	btfss	event_gas_change_gas6					; did a change to gas 6 occurred?
-	bra		profile_display_loop_done_nogas6		; NO
+	bra		profile_display_temperatures			; NO  - skip next
 	movlw	color_pink								; YES - select color
 	call	TFT_set_color							;     - set color
 	WIN_TINY logbook_bailout_column,logbook_bailout_row-.15
 	STRCPY_TEXT tGas								;     - print "Gas"
 	STRCAT_PRINT " 6!"								;     - print " 6!"
 
-profile_display_loop_done_nogas6:
-	decf	divenumber,F							; -1
-	read_int_eeprom .2
-	movf	EEDATA,W
-	bcf		STATUS,C
-	subfwb	divenumber,W							; max. dives (low value) - dive number
-	movwf	lo										; result
-	incf	divenumber,F							; +1
-	; 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
-	; 256: 2FF000h-2FFFFFh -> lo=255 (And hi>0...)
-	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
-	; pointer at the first 0xFA of header
+profile_display_temperatures:
+	movff	logbook_min_temp_pos,win_top			; get Y position at lowest temperature
+	movff	logbook_pixel_x_pos,win_leftx2			; get X ...
+	movlw	.130									; left border limit
+	cpfslt	win_leftx2								; too far to the left?
+	movwf	win_leftx2								; YES - set to limit
+	WIN_FONT FT_TINY								; select font
+	movlw	color_yellow							; select color
+	call	TFT_set_color							; set    color
 
-	movff	logbook_min_temp_pos,win_top			; Y position at lowest temperature
-	movff	logbook_pixel_x_pos,win_leftx2
-	movlw	.130
-	cpfslt	win_leftx2								; limit left border to 130
-	movwf	win_leftx2
-	WIN_FONT FT_TINY
-	movlw	color_yellow							; changed from color_orange to color_yellow for better readability
-	call	TFT_set_color
-
-	MOVII	logbook_min_tp,mpr
-	lfsr	FSR2,buffer
+	MOVII	logbook_min_tp,mpr						; get min temperature
+	lfsr	FSR2,buffer								; initialize string buffer
 
 	TSTOSS	opt_units								; 0=°C, 1=°F
 	bra		logbook_show_temp_metric				; 0 - do Celsius
-													; 1 - do Fahrenheit
-	call	TFT_convert_signed_16bit				; converts lo:hi into signed-short and adds '-' to POSTINC2 if required
+	;bra	logbook_show_temp_imperial				; 1 - do Fahrenheit
+
+logbook_show_temp_imperial:
+	; min temperature
+	call	TFT_convert_signed_16bit				; convert lo:hi into signed-short and add '-' to POSTINC2 if required
 	call	convert_celsius_to_fahrenheit			; convert value in lo:hi from Celsius to Fahrenheit
 	lfsr	FSR2,buffer								; overwrite "-"
 	bsf		ignore_digit5							; full degrees only
 	output_16
 	STRCAT_TEXT_PRINT tLogTunitF
-	; Now, the max. temperature
+	; max temperature
 	movlw	.15
 	subwf	logbook_max_temp_pos,W
-	movff	WREG,win_top							; Y position at max temperature
+	movwf	win_top									; Y position at max temperature
 	MOVII	logbook_max_tp,mpr
 	lfsr	FSR2,buffer
 	call	TFT_convert_signed_16bit				; converts lo:hi into signed-short and adds '-' to POSTINC2 if required
@@ -1052,17 +940,17 @@
 	output_16
 	bcf		ignore_digit5
 	STRCAT_TEXT_PRINT tLogTunitF
-
-	bra		logbook_show_temp_common
+	bra		logbook_show_gases
 
 logbook_show_temp_metric:
-	call	TFT_convert_signed_16bit				; converts lo:hi into signed-short and adds '-' to POSTINC2 if required
+	; min temperature
+	call	TFT_convert_signed_16bit				; convert lo:hi into signed-short and add '-' to POSTINC2 if required
 	movlw	d'3'
 	movwf	ignore_digits
 	bsf		leftbind
 	output_16dp d'2'								; temperature
 	STRCAT_TEXT_PRINT tLogTunitC
-	; Now, the max. temperature
+	; max temperature
 	movlw	.15
 	subwf	logbook_max_temp_pos,W
 	movwf	win_top									; Y position at max temperature
@@ -1074,16 +962,25 @@
 	bsf		leftbind
 	output_16dp d'2'								; temperature
 	STRCAT_TEXT_PRINT tLogTunitC
+	bra		logbook_show_gases
 
-logbook_show_temp_common:
+
+display_profile_no_profile:
+	; print message "No Data anymore..."
+	WIN_SMALL .4,.110								; set text size and position
+	call	TFT_disabled_color						; use the color for disabled things
+	STRCPY_TEXT_PRINT tNoProfileData				; print message
+
+
+logbook_show_gases:
 	bcf		leftbind
 	call	TFT_standard_color
 
 	btfss	aux_flag								; dive done in a deco mode?
-	bra		logbook_show_gases_done					; NO
+	bra		logbook_show_gases_done					; NO - don't show gases
 
 	; show gases
-	LOG_POINT_TO log_gas1							; get pointer to gaslist
+	lfsr	FSR0,header_buffer+index_gas1			; load base address of gases
 	bsf		log_show_gas_short						; do the short version of log_show_gas
 	bsf		leftbind
 
@@ -1114,14 +1011,15 @@
 	rcall	logbook_preloop_tasks					; clear timeout, some flags and set to Speed_eco
 display_profile_loop:
 	btfsc	switch_right							; right button pressed?
-	bra		logbook_page2							; YES - show more information
-	btfsc	switch_left								; left button pressed?
-	bra		exit_profileview						; YES - back to list
-	call	housekeeping							; NO to both - handle screen dump request, timeout and entering dive mode
-	bra		display_profile_loop					;            - loop waiting for something to do
+	bra		logbook_page1							; YES - show more information
+	btfsc	switch_left								; NO  - left button pressed?
+	bra		exit_profileview						;       YES - back to list
+	call	housekeeping							;       NO  - handle screen dump request, timeout and entering dive mode
+	bra		display_profile_loop					;           - loop waiting for something to do
+
 
 ;=============================================================================
-; Draw a vertical line between xC+1 and xC+0, at current X position.
+; Draw a vertical line between xC+1 and xC+0, at current X position
 ;
 ; Note: should keep xC+0
 ; Note: ascending or descending !
@@ -1195,60 +1093,55 @@
 	call	half_horizontal_line					; inputs: win_top, win_leftx2, win_width, win_color1, win_color2
 
 profile_view_get_depth_no_line:
-	call	ext_flash_byte_read_plus_0x20			; read depth first
-	movff	ext_flash_rw,logbook_cur_depth+0		; low value
-	call	ext_flash_byte_read_plus_0x20			; read depth first
-	movff	ext_flash_rw,logbook_cur_depth+1		; high value
-	call	ext_flash_byte_read_plus_0x20			; read  Profile Flag Byte
-	movff	ext_flash_rw,gaslist_gas				; store Profile Flag Byte
+	FLASH_II_READ_0x20 logbook_cur_depth				; read depth (2 bytes)
+	FLASH_CC_READ_0x20 gaslist_gas						; read Profile Flag Byte
 
 	bcf		event_occured							; clear flag by default
 	btfsc	gaslist_gas,7							; event recorded?
 	bsf		event_occured							; YES - we also have an event byte
 	bcf		gaslist_gas,7							; clear event byte flag (if any)
+
 	; gaslist_gas now holds the number of additional bytes to ignore (0-127)
-	movlw	0xFD									; end of profile bytes ?
-	cpfseq	logbook_cur_depth+0
-	bra		profile_view_get_depth_new1				; no 1st. 0xFD
-	cpfseq	logbook_cur_depth+1
-	bra		profile_view_get_depth_new1				; no 2nd. 0xFD
-	bsf		end_of_profile							; end found - set flag, skip remaining pixels
-	return
+
+	; check for end of profile
+	movlw	0xFD									; load token for end of profile data
+	cpfseq	logbook_cur_depth+0						; end of profile token in 1st depth byte?
+	bra		profile_view_get_depth_new1				; NO  - profile continues
+	cpfseq	logbook_cur_depth+1						; YES - end of profile token in 2nd depth byte?
+	bra		profile_view_get_depth_new1				;       NO  - profile continues
+	bsf		end_of_profile							;       YES - end of profile, set flag to skip remaining pixels
+	return											;           - done
 
 profile_view_get_depth_new1:
 	btfsc	event_occured							; was there an event attached to this sample?
 	rcall	profile_view_get_depth_events			; YES - get information about this event(s)
 
-	;---- read Tp°, if any AND divisor reached AND bytes available -----------
-	movf	divisor_temperature,W					; is Tp° divisor null ?
-	bz		profile_view_get_depth_no_tp			; YES - no Tp° curve
-	decf	count_temperature,F						; decrement tp° counter
-	bnz		profile_view_get_depth_no_tp			; no temperature this time
+	; read temperature if available AND divisor reached AND bytes available
+	movf	divisor_temperature,W					; is temperature divisor null ?
+	bz		profile_view_get_depth_no_tp			; YES - no temperature curve
+	decf	count_temperature,F						; NO  - decrement temperature counter, counter zero now?
+	bnz		profile_view_get_depth_no_tp			;       NO  - no temperature this time
+	FLASH_II_READ_0x20 logbook_cur_tp					;       YES - read temperature (2 bytes)
+	decf	gaslist_gas,F							;           - reduce counter twice
+	decf	gaslist_gas,F							;           - ...
+	movff	divisor_temperature,count_temperature	;           - restart counter
 
-	call	ext_flash_byte_read_plus_0x20			; Tp° low
-	decf	gaslist_gas,F
-	movff	ext_flash_rw,logbook_cur_tp+0
-	call	ext_flash_byte_read_plus_0x20			; Tp° high
-	decf	gaslist_gas,F
-	movff	ext_flash_rw,logbook_cur_tp+1
-	movff	divisor_temperature,count_temperature	; restart counter
+	; compute max temperature on the fly...
+	MOVII	logbook_cur_tp,sub_a					; copy current temperature to sub_a
+	MOVII	logbook_max_tp,sub_b					; copy maximum temperature to sub_b
+	call	sub16									; SIGNED sub_a - sub_b
+	btfsc	neg_flag								; current temperature > maximum temperature ?
+	bra		profile_view_get_depth_no_tp			; NO  - no new max temperature
 
-	; Compute Tp° max on the fly...
-	MOVII	logbook_cur_tp,sub_a					; compare cur_tp > max_tp ?
-	MOVII	logbook_max_tp,sub_b
-	call	sub16									; SIGNED sub_a - sub_b
-	btfsc	neg_flag
-	bra		profile_view_get_depth_no_tp
-
-	; store max. temp only below dive_threshold_norm_alt_start
-	tstfsz	logbook_cur_depth+1						; > 2.56 m ?
+	; store new max. temperature, but only if below dive_threshold_norm_alt_start
+	tstfsz	logbook_cur_depth+1						; deeper than 2.55 m ?
 	bra		profile_view_compute_max_temp			; YES - include in max. temp measurement
 	movlw	dive_threshold_norm_alt_start+0			; get start-of-dive depth in mbar / cm, low byte
 	cpfsgt	logbook_cur_depth+0						; deeper that start-of-dive threshold?
-	bra		profile_view_get_depth_no_tp			; NO - ignore temperature
+	bra		profile_view_get_depth_no_tp			; NO - ignore current temperature
 
 profile_view_compute_max_temp:
-	MOVII	logbook_cur_tp,logbook_max_tp
+	MOVII	logbook_cur_tp,logbook_max_tp			; store new max temperature
 
 	;---- read deco, if any AND divisor=0 AND bytes available ----------------
 profile_view_get_depth_no_tp:
@@ -1257,33 +1150,31 @@
 	decf	count_deco,F
 	bnz		profile_view_get_depth_no_deco
 
-	call	ext_flash_byte_read_plus_0x20
-	decf	gaslist_gas,F
-	movff	ext_flash_rw,logbook_ceiling
+	FLASH_CC_READ_0x20 logbook_ceiling					; read the ceiling
+	decf	gaslist_gas,F							; reduce the counter
 	movff	divisor_deco,count_deco					; restart counter
-	call	ext_flash_byte_read_plus_0x20			; skip stop length
-	decf	gaslist_gas,F
+	ext_flash_inc_address_0x40 d'1'					; skip the stop duration
+	decf	gaslist_gas,F							; reduce the counter
 
 	;---- read GF, if any AND divisor=0 AND bytes available ------------------
+
 profile_view_get_depth_no_deco:
-	; Then skip remaining bytes...
-	movf	gaslist_gas,W							; number of additional bytes to ignore (0-127)
-	tstfsz	gaslist_gas								; anything to skip?
-	call	incf_ext_flash_address0_0x20			; YES - increases bytes in ext_flash_address:3 with 0x200000 bank switching
+	; then skip remaining bytes...
+	movf	gaslist_gas,W							; get number of additional bytes to ignore (0-127)
+	tstfsz	WREG									; anything to skip?
+	call	incf_ext_flash_address0_0x20			; YES - skip #WREG bytes
 	return
 
 profile_view_get_depth_events:
 	clrf	event_byte2								; clear event byte 2
-	call	ext_flash_byte_read_plus_0x20			; read event byte
-	movff	ext_flash_rw,event_byte1				; store event byte 1
+	FLASH_CC_READ_0x20 event_byte1						; read  event byte 1
 	decf	gaslist_gas,F							; reduce counter
 
 	btfss	event_byte1,7							; another event byte?
-	bra		profile_no_second_eventbyte				; NO
-	call	ext_flash_byte_read_plus_0x20			; read  event byte 2
-	movff	ext_flash_rw,event_byte2				; store event byte 2
-	decf	gaslist_gas,F							; reduce counter
-	bcf		event_byte1,7							; clear flag
+	bra		profile_no_second_eventbyte				; NO  - skip next
+	FLASH_CC_READ_0x20 event_byte2						; YES - read event byte 2
+	decf	gaslist_gas,F							;     - reduce counter
+	bcf		event_byte1,7							;     - clear flag
 
 profile_no_second_eventbyte:
 	; Check event flags in the EventBytes
@@ -1306,11 +1197,9 @@
 	return											;     - done
 
 logbook_event4:										; stored gas changed
-	call	ext_flash_byte_read_plus_0x20			; read gas number
+	FLASH_CC_READ_0x20 backup_color1					; read gas number, to be used as color index
 	decf	gaslist_gas,F							; reduce counter
-	movff	ext_flash_rw,backup_color1
-	movff	ext_flash_rw,WREG						; copy gas number to WREG for color-coding
-	call	TFT_color_code_gas						; change profile color according to gas number
+	call	TFT_color_code_gas						; change profile color according to gas number (still in WREG)
 	return
 
 logbook_event1:										; gas 6 used
@@ -1318,7 +1207,7 @@
 	movlw	.6										; use gas 6 color
 	movwf	backup_color1							; select color for gas 6
 	call	TFT_color_code_gas						; set profile color
-	incf_ext_flash_address_0x20 .2					; skip two bytes
+	ext_flash_inc_address_0x20 d'2'					; skip two bytes
 	decf	gaslist_gas,F							; reduce counter
 	decf	gaslist_gas,F							; reduce counter
 	return
@@ -1329,21 +1218,20 @@
 	movlw	.6										; use Gas6 color
 	movwf	backup_color1
 	call	TFT_color_code_gas						; use gas 6 color
-	incf_ext_flash_address_0x20 .2					; skip two bytes
+	ext_flash_inc_address_0x20 d'2'					; skip two bytes
 	decf	gaslist_gas,F							; reduce counter
 	decf	gaslist_gas,F							; reduce counter
 	return
 
 logbook_event3:										; setpoint change
-	incf_ext_flash_address_0x20 .1					; skip one byte
+	ext_flash_inc_address_0x20 d'1'					; skip one byte
 	decf	gaslist_gas,F							; reduce counter
 	btfss	bailout_mode							; in bailout?
-	return											; NO - return
-	; We were in bailout before, restore profile color
-	movff	backup_color2,backup_color1				; restore color
-	movff	backup_color2,WREG						; copy gas number to WREG for color-coding
-	call	TFT_color_code_gas						; back to normal profile color
-	return
+	return											; NO  - done
+	movff	backup_color2,backup_color1				; YES - restore color
+	movf	backup_color2,W							;     - copy gas number to WREG for color-coding
+	call	TFT_color_code_gas						;     - back to normal profile color
+	return											;     - done
 
 ; ------------------------------------------------------------------------
 
@@ -1355,7 +1243,7 @@
 	incf	logbook_max_dive_counter,F
 	decf	logbook_divenumber,F
 	bcf		all_dives_shown
-	clrf	menu_pos_max							; number of used rows on current logbook-page
+	clrf	menu_pos_max							; number of rows used on current logbook-page
 	movlw	logbook_row_number
 	movwf	menu_pos_cur							; here: active row on current page
 	call	TFT_boot
@@ -1373,13 +1261,13 @@
 	goto	logbook2								; start search
 
 next_logbook3:
-	incf	menu_pos_cur,F							; +1
-	movlw	logbook_row_number+.2
-	cpfsgt	menu_pos_cur							; = logbook_row_number + 3 ?
-	bra		next_logbook3a							; NO
-	movlw	.1
-	movwf	menu_pos_cur
-	bra		next_logbook3b
+	incf	menu_pos_cur,F							; set cursor to next line
+	movlw	logbook_row_number+.2					; get maximum number of lines
+	cpfsgt	menu_pos_cur							; cursor position beyond last line?
+	bra		next_logbook3a							; NO - ok, done
+	movlw	.1										; YES - reset to first line
+	movwf	menu_pos_cur							;     - ...
+	bra		next_logbook3b							;     - done
 
 next_logbook3a:
 	incf	menu_pos_max,W							; last entry on current page +1
@@ -1396,69 +1284,70 @@
 	call	TFT_logbook_cursor
 	goto	logbook_loop_pre
 
+; ------------------------------------------------------------------
+; list one dive
+;
 display_listdive:
-	bsf		logbook_page_not_empty					; page not empty
-	incf	menu_pos_max,F
-
-	WIN_FONT FT_SMALL
-	WIN_LEFT logbook_list_left
+	bsf		logbook_page_not_empty					; flag page will not be empty
+	incf	menu_pos_max,F							; increment number of lines shown
 
-	decf	menu_pos_max,W							; -1 into WREG
-	mullw	logbook_row_offset
-	movff	PRODL,win_top
 	lfsr	FSR2,buffer								; initialize output buffer
+	WIN_FONT FT_SMALL								; select font
+	WIN_LEFT logbook_list_left						; set horizontal output position
+	decf	menu_pos_max,W							; get current line -1 into WREG
+	mullw	logbook_row_offset						; multiply with row spacing
+	movff	PRODL,win_top							; set vertical output position
 
-	movf	logbook_divenumber,W					; log_compute_divenumber needs the list number
-	call	log_compute_divenumber					; compute dive number
-	bsf		leftbind
+	; print dive number
+	movf	logbook_divenumber,W					; get running number of the dive
+	call	log_compute_divenumber					; compute dive number to show (incorporate dive number offset)
+	bsf		leftbind								; start left-aligned
 	movlw	.3										; start with 3rd digit (i.e. suppress the thousands)
-	movwf	ignore_digits
-	output_16dp .0									; show dive number
-	bcf		leftbind
-	PUTC	' '
-	; display_listdive2:
-	LOG_POINT_TO log_date+1							; point to month
-	call	ext_flash_byte_read_plus				; read month
-	movff	ext_flash_rw,hi							; month
-	call	ext_flash_byte_read_plus				; read day
-	movff	ext_flash_rw,lo							; day
-	call	TFT_convert_date_short					; converts into "DD/MM" or "MM/DD" or "MM/DD" into buffer
-	PUTC	' '
+	movwf	ignore_digits							; ...
+	output_16dp .0									; print dive number
+	bcf		leftbind								; end left-alignment
+
+	PUTC	' '										; print a space char
+
+	; print dive date
+	MOVTT	header_buffer+index_date,mpr			; get date
+	call	TFT_convert_date_short					; convert and print date
+
+	PUTC	' '										; print a space char
 
-	LOG_POINT_TO log_max_depth						; point to max. depth
-	call	ext_flash_byte_read_plus				; max. depth
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,hi
+	; print dive depth
+	MOVII	header_buffer+index_max_depth,mpr		; get max depth
+
+	TSTOSS	opt_units								; switch by configured units
+	bra		display_listdive2_metric				; 0 - do metric
+	;bra	display_listdive2_imperial				; 1 - do imperial
 
-	TSTOSS	opt_units								; 0=Meters, 1=Feets
-	bra		display_listdive2_metric				; 0 - do metric
-													; 1 - do imperial
-	call	convert_mbar_to_feet					; convert value in lo:hi from mbar to feet
-	PUTC	' '
-	output_16_3										; limit to 999 and display only (0-999)
-	STRCAT_TEXT tFeets1
-	bra		display_listdive3
+display_listdive2_imperial:
+	call	convert_cm_to_feet						; convert value in mpr from [cm] to [feet]
+	PUTC	' '										; print one space char
+	output_16_3										; print depth, limited to 999
+	STRCAT_TEXT tFeets1								; print unit label
+	bra		display_listdive3						; continue with common part
 
 display_listdive2_metric:
-	bsf		ignore_digit5							; no cm...
-	movlw	d'1'									; +1
-	movwf	ignore_digits							; no 1000 m
-	output_16dp .3									; xxx.y
-	STRCAT_TEXT tMeters
-	PUTC	' '
+	bsf		ignore_digit5							; do not print the cm
+	movlw	d'1'									; do not print the first digit (no 1000 m)
+	movwf	ignore_digits							; ...
+	output_16dp .3									; print depth in format xxx.y
+	STRCAT_TEXT tMeters								; print unit label
+	PUTC	' '										; print one space char
+	;bra	display_listdive3						; continue with common part
 
+	; print dive time
 display_listdive3:
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,lo							; read dive time minutes
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,hi
-	output_16_3										; dive time minutes (0-999min)
-	STRCAT_TEXT tMinutes
-	clrf	WREG
-	movff	WREG,buffer+.21							; limit to 21 chars
-	STRCAT_PRINT ""									; display header-row in list
-	return
+	MOVII	header_buffer+index_divetime,mpr		; get dive time (minutes only)
+	output_16_3										; print minutes (0-999 min)
+	STRCAT_TEXT tMinutes							; print minutes mark ("'")
+	clrf	WREG									; create string terminator
+	movff	WREG,buffer+.21							; hard limit the output to 21 chars
+	STRCAT_PRINT ""									; finalize output
+
+	return											; done
 
 ; ------------------------------------------------------------------
 
@@ -1472,111 +1361,106 @@
 	STRCAT_PRINT ""									; finalize output
 	return											; done
 
-; -------------------------------------------------------------------
 
-logbook_page2:										; show more info
+;-----------------------------------------------------------------------------
+;  1st Details Page after Profile: Dive Statistics
+
+logbook_page1:										; show more info
 	rcall	log_details_header						; shows number, time/date and basic dive info
 
 	btfss	aux_flag								; dive done in a deco mode?
-	bra		logbook_page2_1							; NO
+	bra		logbook_page1_1							; NO
 
-	; Deco model
+	; deco model
 	WIN_SMALL .5,.65
-	LOG_POINT_TO log_decomodel
-	call	ext_flash_byte_read_plus				; read deco model
-	movff	ext_flash_rw,lo
-	decfsz	ext_flash_rw,F
-	bra		logbook_decomodel1
-	; Deco model GF Version
+	MOVCC	header_buffer+index_decomodel,WREG		; get deco model (0= ZH-L16, 1=ZH-L16+GF)
+	decfsz	WREG,W									; GF model?
+	bra		logbook_decomodel_1						; NO  - ZH-L16
+	;bra	logbook_decomodel_2						; YES - ZH-L16+GF
+
+logbook_decomodel_2:
+	; deco model GF version
 	STRCAT_PRINT "ZHL-16+GF"
-	LOG_POINT_TO log_gf_lo
 	WIN_SMALL .5,.90
-	STRCPY_TEXT tGF
-	call	ext_flash_byte_read_plus				; read GF lo
-	movff	ext_flash_rw,lo
-	output_8
+	STRCPY_TEXT tGF2
+	MOVII	header_buffer+index_gf_lo_hi,mpr		; get  GF factors
+	output_8										; print GF lo
 	STRCAT	"%/"
-	bra		logbook_decomodel_common
-logbook_decomodel1:
-	; Deco model NON-GF Version
+	movff	hi,lo									; print GF hi
+	output_8										; ...
+	STRCAT_PRINT "%"
+	bra		logbook_cns
+
+logbook_decomodel_1:
+	; deco model none-GF version
 	STRCAT_PRINT "ZH-L16"
-	LOG_POINT_TO log_sat_mult
 	WIN_SMALL .5,.90
-	call	ext_flash_byte_read_plus				; read sat_mult or GF low
-	movff	ext_flash_rw,lo
-	output_8
+	MOVII	header_buffer+index_factor_sat_desat,mpr; get both factors
+	output_8										; print saturation factor
 	STRCAT	"%/"
-logbook_decomodel_common:
-	call	ext_flash_byte_read_plus				; read desat_mult or GF high
-	movff	ext_flash_rw,lo
-	output_8
+	movff	hi,lo									; print desaturation factor
+	output_8										; ...
 	STRCAT_PRINT "%"
+	;bra	logbook_cns
 
-	; CNS
-	LOG_POINT_TO log_cns_start
+logbook_cns:
 	WIN_SMALL .5,.115
 	STRCPY_TEXT tCNS2
-	call	ext_flash_byte_read_plus				; read CNS low
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; read CNS high
-	movff	ext_flash_rw,hi
-	bcf		hi,int_warning_flag						; clear warning   flag (fix for cases were the flags already got stored to EEPROM)
-	bcf		hi,int_attention_flag					; clear attention flag (fix for cases were the flags already got stored to EEPROM)
+	MOVII	header_buffer+index_cns_start,mpr		; get CNS at start of dive
+	bcf		mpr+1,int_warning_flag					; clear warning   flag (fix for cases were the flags already got stored to EEPROM)
+	bcf		mpr+1,int_attention_flag				; clear attention flag (fix for cases were the flags already got stored to EEPROM)
 	output_16
-	LOG_POINT_TO log_cns_end
 	STRCAT	"->"
-	call	ext_flash_byte_read_plus				; read CNS low
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; read CNS high
-	movff	ext_flash_rw,hi
+	MOVII	header_buffer+index_cns_end,mpr			; get CNS at end of dive
 	bcf		hi,int_warning_flag						; clear warning   flag (fix for cases were the flags already got stored to EEPROM)
 	bcf		hi,int_attention_flag					; clear attention flag (fix for cases were the flags already got stored to EEPROM)
 	output_16
 	STRCAT_PRINT "%"
 
-logbook_page2_1:
+logbook_page1_1:
+	WIN_SMALL .5,.140
+	STRCPY_TEXT tAVG
+	MOVII	header_buffer+index_avr_depth,mpr		; get average depth
+
+	TSTOSS	opt_units								; 0=Meters, 1=Feets
+	bra		logbook_page1_1_metric					; do metric
+	;bra	logbook_page1_1_imperial				; do imperial
 
-	; Salinity
-	WIN_SMALL .5,.165								; ex WIN_SMALL .5,.140
-	LOG_POINT_TO log_salinity
-	STRCPY_TEXT tDvSalinity
-	bsf		leftbind
-	call	ext_flash_byte_read_plus				; read salinity
-	movff	ext_flash_rw,lo
-	movff	ext_flash_rw,salinity					; store salinity for later use
-	output_8
-	STRCAT_PRINT "%"
+logbook_page1_1_imperial:
+	call	convert_cm_to_feet						; convert value in lo:hi from [cm] to [feet]
+	PUTC	' '
+	output_16_3										; limit to 999 and display only (0-999)
+	STRCAT_PRINT "ft"
+	bra		logbook_page1_1_common
 
-	; Average depth
-	WIN_SMALL .5,.140								; ex WIN_SMALL .5,.165
-	STRCPY_TEXT tAVG
-	LOG_POINT_TO log_avr_depth
-	call	ext_flash_byte_read_plus				; read average low
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; read average high
-	movff	ext_flash_rw,hi
-	movf	salinity,W								; salinity for this dive
-	call	adjust_depth_with_salinity_log			; compute salinity into lo:hi [mbar]
+logbook_page1_1_metric:
 	bsf		ignore_digit5							; no cm (flag will be cleared by output_16)
 	movlw	.1										; no 1000 meters
 	movwf	ignore_digits							; ...
 	output_16dp .3									; xxx.y
 	STRCAT_PRINT "m"
+	;bra	logbook_page1_1_common
 
+logbook_page1_1_common:
 	btfss	aux_flag								; dive done in a deco mode?
-	bra		logbook_page2_2							; NO
+	bra		logbook_page1_2							; NO
+
+	; Salinity
+	WIN_SMALL .5,.165								; ex WIN_SMALL .5,.140
+	STRCPY_TEXT tDvSalinity2
+	bsf		leftbind
+	MOVCC	header_buffer+index_salinity,lo			; read salinity
+	output_8
+	STRCAT_PRINT "%"
 
 	; Last deco
-	LOG_POINT_TO log_last_stop
 	WIN_SMALL .5,.190
-	STRCPY_TEXT tLastDecostopSurf
-	call	ext_flash_byte_read_plus				; read last stop
-	movff	ext_flash_rw,lo
+	STRCPY_TEXT tLastDeco
+	MOVCC	header_buffer+index_last_stop,lo		; read last stop depth
 	output_8
 	STRCAT_PRINT "m"
 
-logbook_page2_2:
-
+logbook_page1_2:
 	movlw	color_lightblue
 	call	TFT_set_color
 	WIN_FRAME_COLOR16 .63,.220,.2,.105				; top, bottom, left, right
@@ -1585,37 +1469,30 @@
 	call	TFT_standard_color
 	WIN_SMALL .110,.65
 	STRCAT	"V:"
-	LOG_POINT_TO log_firmware
-	call	ext_flash_byte_read_plus				; read firmware major number
-	movf	ext_flash_rw,W							; copy to WREG
-	movwf	hi										; copy from WREG to hi
-	movwf	lo										; copy from WREG to lo, too
+	MOVII	header_buffer+index_firmware,mpr		; get firmware version
+	movff	lo,up									; keep a backup of major in up
 	bsf		leftbind								; print left-aligned
-	output_8										; print major number
+	output_8										; print major version (in 1 digit due to leftbind)
 	PUTC	"."										; print "."
-	call	ext_flash_byte_read_plus				; read firmware minor number
-	movff	ext_flash_rw,lo							; store in lo
-	output_99x										; print minor version in 2 digit format
+	movff	hi,lo									; print minor version...
+	output_99x										; ... in 2 digit format
 	STRCAT_PRINT ""									; finalize output
 
-	movf	hi,W									; get major into WREG
+	movf	up,W									; get major into WREG
 	xorlw	.3										; major == 3 ?
 	bz		logbook_battery_percent					; YES - show battery %
-
-	movf	hi,W									; get major into WREG (again)
-	xorlw	.2										; major == 2 ?
-	bnz		logbook_battery_voltage					; NO  - skip battery %
-	movlw	.14										; YES - check minor version
-	cpfsgt	lo										;     - minor > 14 ?
-	bra		logbook_battery_voltage					;       NO  - skip battery %
-	;bra	logbook_battery_percent					;       YES - show battery %
+	movf	up,W									; NO  - get major into WREG (again)
+	xorlw	.2										;       major == 2 ?
+	bnz		logbook_battery_voltage					;       NO  - skip battery %
+	movlw	.14										;       YES - check minor version
+	cpfsgt	lo										;           - minor > 14 ?
+	bra		logbook_battery_voltage					;             NO  - skip battery %
+	;bra	logbook_battery_percent					;             YES - show battery %
 
 	; Battery %
 logbook_battery_percent:
-	WIN_SMALL .110,.140								; show battery percent
-	LOG_POINT_TO log_batt_info						; address battery percent
-	call	ext_flash_byte_read_plus				; read  battery percent
-	movff	ext_flash_rw,lo							; copy  battery percent to lo
+	WIN_SMALL .110,.140
+	MOVCC	header_buffer+index_batt_percent,lo		; get   battery percent
 	output_8										; print battery percent
 	STRCAT_PRINT "%"								; print "%" and finalize output
 
@@ -1624,46 +1501,169 @@
 	WIN_SMALL .110,.90
 	STRCAT_PRINT "Batt:"
 	WIN_SMALL .110,.115
-	LOG_POINT_TO log_battery						; address battery voltage
-	call	ext_flash_byte_read_plus				; read    battery voltage, low  byte
-	movff	ext_flash_rw,lo							; store in lo
-	call	ext_flash_byte_read_plus				; read    battery voltage, high byte
-	movff	ext_flash_rw,hi							; store in hi
+	MOVII	header_buffer+index_battery_voltage,mpr	; get   battery voltage
 	output_16dp .2									; print battery voltage
-	STRCAT_PRINT "V"								; ...
+	STRCAT_PRINT "V"								; print unit (Volt)
 
-	LOG_POINT_TO log_surface_press					; address surface pressure in mbar
-	call	ext_flash_byte_read_plus				; read surface pressure, low  byte
-	movff	ext_flash_rw,lo							; store in lo
-	call	ext_flash_byte_read_plus				; read surface pressure, high byte
-	movff	ext_flash_rw,hi							; store in hi
+	; Surface Pressure
+	MOVII	header_buffer+index_surface_press,mpr	; get surface pressure
 	WIN_SMALL .110,.165								; set output position
-	lfsr	FSR2,buffer								; set base address of output buffer
 	bsf		leftbind								; print without leading spaces
-	output_16										; print air pressure before dive
-	STRCAT_TEXT tMBAR								; ...
+	output_16										; print surface pressure before dive
+	STRCAT_TEXT tMBAR								; print unit
 	clrf	WREG									; string terminator
 	movff	WREG,buffer+7							; limit to 7 chars
 	STRCAT_PRINT ""									; dump buffer to screen
 
 	movlw	color_greenish							; select color
 	call	TFT_set_color							; ...
-	WIN_FRAME_COLOR16 .63,.220,.107,.159			; draw a frame around coordinates top, bottom, left, right
+	WIN_FRAME_COLOR16 .63,.220,.107,.159			; draw a frame with coordinates top, bottom, left, right
 
+	; handle HMI
 	rcall	logbook_preloop_tasks					; clear timeout and remaining button events
-display_details_loop:
-	btfss	switch_right							; right button pressed?
-	bra		display_details_loop_1					; NO
-	btfsc	aux_flag								; YES - dive done in a deco mode?
-	bra		logbook_page3							;       YES - show more details, 2nd page
-	goto	display_profile2						;       NO  - show the profile view again
-display_details_loop_1:
+display_details1_loop:
+	btfsc	switch_right							; right button pressed?
+	bra		display_details1_more					; YES - more info or back to profile
 	btfsc	switch_left								; left button pressed?
 	bra		exit_profileview						; YES - back to list
-	call	housekeeping							; NO to both - handle screen dump request, timeout and entering dive mode
-	bra		display_details_loop					;            - loop waiting for something to do
+	call	housekeeping							; NO  - handle screen dump request, timeout and entering dive mode
+	bra		display_details1_loop					;     - loop waiting for something to do
+
+display_details1_more:
+	btfss	aux_flag								; YES - dive done in a deco mode?
+	goto	display_profile2						;       NO  - show the profile view again
+	;bra	logbook_page2							;       YES - show more details
 
 
+;-----------------------------------------------------------------------------
+;  2nd Details Page after Profile: Tissue and Decompression Status
+
+logbook_page2:
+
+; ################# to be removed later ##################################
+;	movlw	fw_version_beta				; get beta status
+;	tstfsz	WREG						; beta?
+;	bra		display_page2_betajump		; YES - omit firmware version check
+; ########################################################################
+
+	; skip this page for dives recorded with firmwares < 3.09
+	MOVII	header_buffer+index_firmware,mpr		; get firmware version major and minor
+
+	movlw	.2										; minimum required major is 3, -1 for cpfsgt
+	cpfsgt	lo										; major >= requirement?
+	bra		logbook_page3							; NO  - skip this page
+	movlw	.8										; YES - minimum required minor is 9, -1 for cpfsgt
+	cpfsgt	hi										;     - minor >= requirement?
+	bra		logbook_page3							;       NO  - skip this page
+
+; ################# to be removed later ##################################
+display_page2_betajump:
+; ########################################################################
+
+	rcall	log_details_header						; shows number, time/date and basic dive info
+
+	; basic configuration of tissue graphics
+	bsf		tissue_graphic_mode						; select logbook mode
+	bcf		tissue_graphic_layout					; select press+sat
+	bcf		tissue_graphic_cns						; do not show CNS value
+	bcf		tissue_graphic_gf						; do not show GF lines by default
+
+	; GF configuration
+	MOVCC	header_buffer+index_decomodel,WREG		; get deco model (0= ZH-L16, 1=ZH-L16+GF)
+	dcfsnz	WREG									; GF model?
+	bsf		tissue_graphic_gf						; YES - show GF lines
+
+	; draw the graphics
+	call	TFT_surface_tissues
+
+	; calculate time/date of the end of the dive
+	MOVTT	header_buffer+index_date,      rtc_latched_year		; get start    of the dive - year, month, day
+	MOVII	header_buffer+index_time,      rtc_latched_hour		; get start    of the dive - hour, minute
+	MOVCC	header_buffer+index_divetime+2,rtc_latched_secs		; get duration of the dive - seconds
+	MOVII	header_buffer+index_divetime+0,mpr					; get duration of the dive - minutes
+	call	rtc_add_minutes										; add minutes in mpr to time/date in rtc_latched
+
+	; print time/date of the end of the dive
+	WIN_SMALL .8,.193									; select font and output position
+	MOVTT	rtc_latched_year,mpr						; get computed end-of-dive date
+	call	TFT_convert_date_short						; convert and print date
+	STRCAT	".-"										; print spacing ".-"
+	MOVII	rtc_latched_hour,mpr						; get computed end-of-dive time
+	output_99x											; print hour
+	PUTC	':'											; print spacing ":"
+	movff	hi,lo										; print minute
+	output_99x											; ...
+	STRCAT_PRINT ""										; finalize output
+
+
+	; draw a white frame around the time/date
+	WIN_FRAME_STD surf_tissue_diagram_bottom,.220, surf_tissue_diagram_left, surf_tissue_diagram_right
+
+	bra		logbook_page2_rightside					; continue with right side
+
+logbook_page2_nograph:
+	WIN_SMALL .6,.118								; no tissue graphics because the
+	STRCAT_PRINT "(< FW 3.08)"						; profile was recorded on a FW < 3.08
+
+logbook_page2_rightside:
+
+	; 1st line: supersaturation at end of dive
+	WIN_SMALL .100,.68
+	STRCAT_TEXT_PRINT tBeginOfDive					; print "Begin"
+
+	; 2nd line: 
+	WIN_SMALL .100+.28,.93							; +16 for centered, +28 for right-aligned
+	MOVCC	header_buffer+index_supersat_start,lo	; get supersaturation at start of dive
+	bcf		leftbind
+	output_8										; print percent value
+	STRCAT_PRINT "%"								; print "%" and finalize output
+
+	; 3rd line: 
+	WIN_SMALL .100,.118
+	STRCAT_TEXT_PRINT tEndOfDive					; print "End"
+
+	; 4th line: 
+	WIN_SMALL .100+.28,.143							; +16 for centered, +28 for right-aligned
+	MOVCC	header_buffer+index_supersat_end,lo		; get supersaturation at end of dive
+	bcf		leftbind
+	output_8										; print percent value
+	STRCAT_PRINT "%"								; print "%" and finalize output
+
+	; 5th line: desaturation time label
+	WIN_SMALL .100,.168
+	STRCAT_TEXT_PRINT tDesatTime					; print "Desat"
+
+	; 6th line: desaturation time value
+	WIN_SMALL .100+.14,.193							; +?? for centered, +14 for right-aligned
+	MOVII	header_buffer+index_desattime,mpr		; get desaturation time
+	call	convert_time							; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
+	movf	lo,W									; swap hi and lo
+	movff	hi,lo									; ...
+	movwf	hi										; ...
+	output_99										; print hours in 0-99
+	PUTC	'h'										; print hours mark
+	movff	hi,lo									; print minutes...
+	output_99x										; ... in two digits, leading zero
+	STRCAT_PRINT "m"								; print minutes mark and finalize output
+
+	; draw a colored frame around the right side
+	movlw	color_orange							; select color
+	call	TFT_set_color							; ...
+	WIN_FRAME_COLOR16 .65,.220,.97,.159				; draw a frame with coordinates top, bottom, left, right
+
+	; handle HMI
+	rcall	logbook_preloop_tasks					; clear timeout and remaining button events
+display_details1b_loop:
+	btfsc	switch_right							; right button pressed?
+	bra		logbook_page3							; YES - show more info
+	btfsc	switch_left								; left button pressed?
+	bra		exit_profileview						; YES - back to list
+	call	housekeeping							; NO  - handle screen dump request, timeout and entering dive mode
+	bra		display_details1b_loop					;     - loop waiting for something to do
+
+
+;-----------------------------------------------------------------------------
+; helper function
 logbook_preloop_tasks:
 	movlw	CCP1CON_VALUE							; see hwos.inc
 	movwf	CCP1CON									; power-on backlight
@@ -1673,10 +1673,12 @@
 	bcf		switch_right							; clear left-over right button event
 	return											; done
 
+;-----------------------------------------------------------------------------
+; 3rd Details Page after Profile: Gases / Diluents
 
-logbook_page3:										; show even more info
+logbook_page3:
 	rcall	log_details_header						; shows number, time/date and basic dive info
-	LOG_POINT_TO log_gas1
+	lfsr	FSR0,header_buffer+index_gas1			; load base address of the gases
 	bcf		log_show_gas_short						; do the long version of log_show_gas
 	bcf		leftbind
 
@@ -1700,40 +1702,45 @@
 	movlw	.5										; color for gas 5
 	rcall	log_show_gas
 
-	; OC/CC Gas List
+	; OC/CC gas list
 	WIN_SMALL .5,.65
 	WIN_COLOR color_greenish
-	LOG_POINT_TO log_divemode
-	call	ext_flash_byte_read_plus				; 0=OC, 1=CC, 2=Gauge, 3=Apnea into ext_flash_rw
-	decfsz	ext_flash_rw,w							; =1 (CC)?
-	bra		logbook_page3a
-	STRCPY_TEXT_PRINT tGaslistCC
-	bra		logbook_page3b
+
+	MOVCC	header_buffer+index_divemode,WREG		; read dive mode (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4= pSCR)
+	decfsz	WREG,W									; dive mode = CC ?
+	bra		logbook_page3a							; NO  - print OC title
+	STRCPY_TEXT_PRINT tGaslistCC					; YES - print CC title
+	bra		logbook_page3b							;     - continue with common part
 logbook_page3a:
-	STRCPY_TEXT_PRINT tGaslist
+	STRCPY_TEXT_PRINT tGaslist						; print OC title
 logbook_page3b:
-	movlw	color_lightblue
-	call	TFT_set_color
-	WIN_FRAME_COLOR16 .63,.220,.2,.90+.24			; top, bottom, left, right (added .24 to the right as extra space needed for gas typ markings)
+	movlw	color_lightblue							; select color
+	call	TFT_set_color							; set    color
+	WIN_FRAME_COLOR16 .63,.220,.2,.114				; draw a frame with coordinates top, bottom, left, right
 
-	rcall	logbook_preloop_tasks					; clear timeout, some flags and set to Speed_eco
+	; handle HMI
+	rcall	logbook_preloop_tasks					; clear timeout, some flags and set to speed_eco
 display_details2_loop:
 	btfsc	switch_right							; right button pressed?
 	goto	logbook_page4							; YES - show more info
-	btfsc	switch_left								; left button pressed?
-	bra		exit_profileview						; YES - back to list
-	call	housekeeping							; NO to both - handle screen dump request, timeout and entering dive mode
-	bra		display_details2_loop					;            - loop waiting for something to do
+	btfsc	switch_left								; NO  - left button pressed?
+	bra		exit_profileview						;       YES - back to list
+	call	housekeeping							;       NO  - handle screen dump request, timeout and entering dive mode
+	bra		display_details2_loop					;           - loop waiting for something to do
+
 
-logbook_page4:										; show even more info in CC mode
-	LOG_POINT_TO log_divemode
-	call	ext_flash_byte_read						; 0=OC, 1=CC, 2=Gauge, 3=Apnea into WREG and ext_flash_rw 
-	decfsz	ext_flash_rw,w							; =1 (CC)? 
-	goto	display_profile2						; no 
+;-----------------------------------------------------------------------------
+; 4th Details Page after Profile: Setpoints
+
+logbook_page4:
+	MOVCC	header_buffer+index_divemode,WREG		; get dive mode (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4= pSCR)
+	decfsz	WREG,W									; =1 (CC)?
+	goto	display_profile2						; NO - skip setpoints
 
 	rcall	log_details_header						; shows number, time/date and basic dive info
-	; Setpoint list
-	LOG_POINT_TO log_sp1
+
+	; print setpoint list
+	lfsr	FSR0,header_buffer+index_sp1			; load base address of the setpoints
 	WIN_SMALL .5,.65
 	WIN_COLOR color_greenish
 	STRCPY_TEXT_PRINT tFixedSetpoints
@@ -1753,6 +1760,7 @@
 	call	TFT_set_color
 	WIN_FRAME_COLOR16 .63,.220,.2,.112				; top, bottom, left, right
 
+	; handle HMI
 	rcall	logbook_preloop_tasks					; clear timeout, some flags and set to Speed_eco
 display_details3_loop:
 	btfsc	switch_right							; right button pressed?
@@ -1763,81 +1771,40 @@
 	bra		display_details3_loop					;            - loop waiting for something to do
 
 
+;-----------------------------------------------------------------------------
+; Helper Functions
+
 log_details_header:
 	call	TFT_boot
+	call	TFT_standard_color
 
-; Set ext_flash pointer to "#divenumber-oldest" dive
-; compute read_int_eeprom .2 - divenumber
-; read required header data for profile display
-; look in header for pointer to begin of diveprofile (byte 2-4)
-; Set pointer (ext_flash_log_pointer:3) to this address, start drawing
+	rcall	logbook_show_divenumber					; show the dive number in medium font
 
-	decf	divenumber,F							; -1
-	read_int_eeprom .2
-	movf	EEDATA,W
-	bcf		STATUS,C
-	subfwb	divenumber,W							; max. dives (low value) - dive number
-	movwf	lo										; result
-	incf	divenumber,F							; +1
-	; 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
-	; 256: 2FF000h-2FFFFFh -> lo=255 (And hi>0...)
-	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
-	; pointer at the first 0xFA of header
-	rcall	logbook_show_divenumber					; show the dive number in medium font
-	; Show date and time in first row
+	; show date and time in first row
 	WIN_SMALL .59,.10
-	LOG_POINT_TO log_date
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,up							; year
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,hi							; month
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,lo							; day
-	call	TFT_convert_date						; converts into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2
+	MOVTT	header_buffer+index_date,mpr			; get date
+	call	TFT_convert_date						; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in buffer
+
 	PUTC	"-"
-	call	ext_flash_byte_read_plus				; hour
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; minutes
-	movff	ext_flash_rw,hi
-	output_99x										; hour
-	PUTC	':'
-	movff	hi,lo
-	output_99x										; minute
+
+	MOVII	header_buffer+index_time,mpr			; get time
+	output_99x										; print hour
+	PUTC	':'										; print spacing ":"
+	movff	hi,lo									; print minute
+	output_99x										; ...
 	STRCAT_PRINT ""									; display 1st row of details
 
-	; Get salinity for this dive
-	LOG_POINT_TO log_salinity
-	call	ext_flash_byte_read_plus				; read  salinity
-	movff	ext_flash_rw,salinity					; store salinity
-
-	; Show max depth and dive time
+	; show max depth and dive time
 	WIN_SMALL .5,.35
 	STRCAT	"Max:"
-	LOG_POINT_TO log_max_depth
-	call	ext_flash_byte_read_plus				; read max depth, low  byte
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; read max depth, high byte
-	movff	ext_flash_rw,hi
+	MOVII	header_buffer+index_max_depth,mpr		; get max depth
 
-	movf	salinity,W								; salinity for this dive
-	call	adjust_depth_with_salinity_log			; compute salinity setting into lo:hi [mbar]
+	TSTOSS	opt_units								; 0=Meters, 1=Feet
+	bra		logbook_page2_depth_metric				; 1 - do metric
+	;bra	logbook_page2_depth_imperial			; 0 - do imperial
 
-	TSTOSS	opt_units								; 0=Meters, 1=Feets
-	bra		logbook_page2_depth_metric				; 1 - do metric
-													; 0 - do imperial
-	call	convert_mbar_to_feet					; convert value in lo:hi from mbar to feet
+logbook_page2_depth_imperial:
+	call	convert_cm_to_feet						; convert value in lo:hi from [cm] to [feet]
 	PUTC	' '
 	bcf		leftbind
 	output_16_3
@@ -1845,63 +1812,56 @@
 	bra		logbook_page2_depth_common
 
 logbook_page2_depth_metric:
-	bsf		leftbind
-	output_16dp d'3'								; max. depth
+	bsf		ignore_digit5							; no cm...
+	movlw	d'1'									; no 1000 m
+	movwf	ignore_digits							; ...
+	output_16dp d'3'								; xxy.y
 	STRCAT_TEXT tMeters
+	;bra	logbook_page2_depth_common
 
 logbook_page2_depth_common:
 	STRCAT	" - "
-	call	ext_flash_byte_read_plus				; dive time in minutes
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus
-	movff	ext_flash_rw,hi							; dive time in minutes
-
+	MOVTT	header_buffer+index_divetime,mpr		; get dive time
 	bsf		leftbind
-	output_16										; dive time minutes
+	output_16										; print minutes
 	PUTC	"m"
-	LOG_POINT_TO log_divetime+.2
-	call	ext_flash_byte_read_plus				; read dive time seconds
-	movff	ext_flash_rw,lo
-	bsf		leftbind
-	output_99x										; dive time seconds
-	call	TFT_standard_color
+	movff	up,lo									; print seconds
+	output_99x										; ...
 	STRCAT_PRINT "s"
-;	; Dive mode
-;	LOG_POINT_TO log_divemode
-;	call	ext_flash_byte_read_plus				; read dive mode
-;	movff	ext_flash_rw,lo
-;	call	TFT_decotype_logbook					; "strcat_print"s dive mode (OC, CC, APNEA or GAUGE)
 	return
 
-; ----------------------------------------------------------------
 
 log_show_sp:
-	lfsr	FSR2,buffer
-	call	ext_flash_byte_read_plus				; read setpoint
-	movff	ext_flash_rw,lo
-	clrf	hi
+	; log point is set by caller
+	MOVCC	POSTINC0,lo								; copy set point    into lo
+	MOVCC	POSTINC0,hi								; copy change depth into hi
+
+	movff	mpr+1,mpr+2								; save change depth
+	clrf	mpr+1									; set high byte to zero for printing setpoint
 	bsf		leftbind
-	output_16dp d'3'
+	output_16dp d'3'								; print setpoint x.xx
 	bcf		leftbind
 	STRCAT_TEXT tbar
 	PUTC	" "
-	call	ext_flash_byte_read_plus				; change depth
-	movff	ext_flash_rw,lo
+	movff	mpr+2,mpr+0								; restore change depth to lo
 
 	TSTOSS	opt_units								; 0=Meter, 1=Feet
 	bra		log_show_sp_metric						; 0 - do metric
-	movf	lo,W									; 1 - do imperial
-	mullw	.100									; convert meters to mbar
-	MOVII	PROD,mpr
-	call	convert_mbar_to_feet					; convert value in lo:hi from mbar to feet
+	;bra	log_show_sp_imperial					; 1 - do imperial
+
+log_show_sp_imperial:
+	call	convert_meter_to_feet					; convert value in lo from [m] to [feet]
 	output_16_3
 	PUTC	" "
 	STRCAT_TEXT tFeets								; "ft"
 	bra		log_show_sp_common
+
 log_show_sp_metric:
 	output_8
 	PUTC	" "
 	STRCAT_TEXT tMeters								; "m"
+	;bra	log_show_sp_common
+
 log_show_sp_common:
 	STRCAT_PRINT ""
 	return
@@ -1909,33 +1869,30 @@
 
 log_show_gas:										; show gas data
 	call	TFT_color_code_gas						; color the output (gas number is in WREG)
-	lfsr	FSR2,buffer
-	call	ext_flash_byte_read_plus				; read gas O2 fraction
-	movff	ext_flash_rw,lo
-	call	ext_flash_byte_read_plus				; read gas He fraction
-	movff	ext_flash_rw,hi
-	call	gaslist_show_mix						; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2
-	call	ext_flash_byte_read_plus				; read change depth
-	movff	ext_flash_rw,up
-	call	ext_flash_byte_read_plus				; read gas type - just to increment the pointer
-	movff	ext_flash_rw,ex
+	MOVCC	POSTINC0,lo								; copy O2 fraction into lo
+	MOVCC	POSTINC0,hi								; copy He fraction into hi
+	call	gaslist_show_mix						; put "Nxlo", "Txlo/hi", "Air" or "O2" into buffer
 
+	MOVCC	POSTINC0,lo								; copy change depth into lo
+	MOVCC	POSTINC0,hi								; copy gas    type  into hi
 	btfsc	log_show_gas_short						; shall we do the short version?
-	bra		log_show_gas_common						; YES
-													; NO  - do the long version
+	bra		log_show_gas_common						; YES - do short version
+	;bra	log_show_gas_long						; NO  - add gas types
+
+log_show_gas_long:
 	PUTC	" "										; put one space between gas composition and gas type marking
-	tstfsz	ex										; gas disabled?
+	tstfsz	hi										; gas disabled?
 	bra		log_show_gas_1							; NO  - next check
 	PUTC	"x"										; YES - mark with "x"
 	bra		log_show_gas_4							;     - continue with change depth
 log_show_gas_1:
-	decfsz	ex,F									; now: -1 disabled, 0 first, 1 travel, 2 deco -> first?
+	decfsz	hi,F									; now: -1 disabled, 0 first, 1 travel, 2 deco -> first?
 	bra		log_show_gas_2							; NO  - next check
 	PUTC	"*"										; YES - mark with "*"
 	bra		log_show_gas_4							;     - continue with change depth
 log_show_gas_2:
-	decf	ex,F									; now: -2 disabled, -1 first,  0 travel, 1 deco
-	decfsz	ex,F									; now: -3 disabled, -2 first, -1 travel, 0 deco -> deco?
+	decf	hi,F									; now: -2 disabled, -1 first,  0 travel, 1 deco
+	decfsz	hi,F									; now: -3 disabled, -2 first, -1 travel, 0 deco -> deco?
 	bra		log_show_gas_3							; NO  - nothing to mark
 	PUTC	"="										; YES - mark with "="
 	bra		log_show_gas_4							;     - continue with change depth
@@ -1943,36 +1900,42 @@
 	PUTC	" "										; print a space in absence of any other marking
 log_show_gas_4:
 	PUTC	" "										; put one space between gas type marking and change depth
+
 	TSTOSS	opt_units								; 0=Meter, 1=Feet
 	bra		log_show_gas_metric						; 0 - do metric
-	movf	up,W									; 1 - do imperial
-	mullw	.100									; convert meters to mbar
-	MOVII	PROD,mpr
-	call	convert_mbar_to_feet					; convert value in lo:hi from mbar to feet
+	;bra	log_show_gas_imperial					; 1 - do imperial
+
+log_show_gas_imperial:
+	call	convert_meter_to_feet					; convert value in lo from [m] to [feet]
 	output_16_3										; limit to 999 and display only 0-999
 	STRCAT_TEXT tFeets								; "ft"
 	bra		log_show_gas_common
+
 log_show_gas_metric:
-	movff	up,lo
 	output_8
 	STRCAT_TEXT tMeters								; "m"
+	;bra	log_show_gas_common
+
 log_show_gas_common:
 	STRCAT_PRINT ""
 	return
 
 
 log_compute_divenumber:
-	movwf	mpr+2									; store current dive number to mpr+2
-	call	do_logoffset_common_read				; read log offset into mpr
+	movwf	mpr+2									; store current dive number in mpr+2
+	call	eeprom_log_offset_read					; read log offset into mpr+0 & +1
 	; check if offset = 0
-	tstfsz	mpr+0									; mpr+0 (low  byte) = 0 ?
-	bra		log_compute_divenumber_2				; NO - apply offset
-	tstfsz	mpr+1									; mpr+1 (high byte) = 0 ?
-	bra		log_compute_divenumber_2				; NO - apply offset
-log_compute_divenumber_1:							; YES to both - no offset
+	tstfsz	mpr+0									; low  byte = 0 ?
+	bra		log_compute_divenumber_2				; NO  - apply offset
+	tstfsz	mpr+1									; YES - high byte = 0 ?
+	bra		log_compute_divenumber_2				;       NO  - apply offset
+	;bra	log_compute_divenumber_1				;       YES - no offset
+
+log_compute_divenumber_1:
 	movff	mpr+2,mpr+0								; use plain number from dive list
 	clrf	mpr+1									; set high byte to 0
 	return											; done
+
 log_compute_divenumber_2:
 	; check limit (offset must be < 10000)
 	MOVLI	.9999,sub_a								; sub_a = 9999
@@ -1988,6 +1951,45 @@
 	MOVII	sub_c,mpr								;     - copy result back to mpr
 	return											;     - done
 
+;----------------------------------------------------------------------------
+; Compute flash address for header data of a particular dive
+;
+; Memory map in flash:
+;
+; low(total number of dives) -> index -> start address    end address
+; --------------------------------------------------------------------
+;          1                      0       0x2|00|000   -   0x2|00|FFF
+;          2                      1       0x2|01|000   -   0x2|01|FFF
+;          3                      2       0x2|02|000   -   0x2|02|FFF
+;        ...
+;  256 ->  0                    255       0x2|FF|000   -   0x2|FF|FFF
+
+log_header_addr_by_divenumber:
+	; compute index of the dive with number 'divenumber'
+	decf	divenumber,W							; compute number of dive to show -1...
+	movwf	mpr+3									; ... and store in mpr+3
+	movf	total_num_dives,W						; get number of total dives (low byte)
+	bcf		STATUS,C								; clear carry/borrow bit
+	subfwb	mpr+3,W									; index = number of total dives - number of dive to show + 1
+	;bra	log_header_addr_by_index				; get address by index
+
+	global	log_header_addr_by_index
+log_header_addr_by_index:
+	; compute the start address of the header belonging to the dive whose index is in WREG
+	movwf	mpr+3									; copy index to mpr+3
+	clrf	mpr+0									; set up base address 0x200000
+	clrf	mpr+1									; ...
+	movlw	0x20									; ...
+	movwf	mpr+2									; ...
+	movlw	.16										; prepare a shift left by 4 bit
+	mulwf	mpr+3									; shift left index to create offset
+	movf	PRODL,W									; get    low   byte of offset
+	addwf	mpr+1,F									; add to high  byte of address
+	movf	PRODH,W									; get    high  byte of offset
+	addwfc	mpr+2,F									; add to upper byte of address
+
+	return
+
 ; ----------------------------------------------------------------
 
 	END
\ No newline at end of file
--- a/src/logbook.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/logbook.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File logbook.inc                           combined next generation V3.0.1
+;   File logbook.inc                          combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -8,5 +8,66 @@
 ; HISTORY
 ;  2011-11-12 : [mH] moving from OSTC code
 
+
+ #ifndef inside_loogbook
 	extern	logbook
+	extern	log_header_addr_by_index
+ #endif
 
+
+; Buffer for Dive Header Data
+#DEFINE header_buffer				buffer2
+
+
+; Dive Header Layout
+;
+;       Label						Index	Size  Description
+;-----------------------------------------------------------------------------------------
+#DEFINE index_header_start			.0		;  2  header start sequence 0xFAFA
+#DEFINE index_profile_start_address	.2		;  3  pointer to profile data start in flash
+#DEFINE index_profile_end_address	.5		;  3  pointer to profile data end   in flash
+#DEFINE index_profile_version		.8		;  1  profile format version
+#DEFINE index_profile_byte_count	.9		;  3  number of bytes in profile data
+#DEFINE index_date					.12		;  3  date in sequence year, month, day
+#DEFINE index_time					.15		;  2  time in sequence hour, minute
+#DEFINE index_max_depth				.17		;  2  maximum depth
+#DEFINE index_divetime				.19		;  3  dive time in sequence minutes:2, seconds:1
+#DEFINE index_min_temp				.22		;  2  minimum temperature during the dive
+#DEFINE index_surface_press			.24		;  2  surface pressure during the dive
+#DEFINE index_desattime				.26		;  2  desaturation time at end of dive
+#DEFINE index_gas1					.28		;  4  gas 1 in sequence O2%, He%, change depth, type
+#DEFINE index_gas2					.32		;  4  gas 2 ...
+#DEFINE index_gas3					.36		;  4  gas 3 ...
+#DEFINE index_gas4					.40		;  4  gas 4 ...
+#DEFINE index_gas5					.44		;  4  gas 5 ...
+#DEFINE index_firmware				.48		;  2  firmware version used in sequence major, minor
+#DEFINE index_battery_voltage		.50		;  2  battery voltage at end of dive
+#DEFINE index_samplingrate			.52		;  1  sampling rate of profile data
+#DEFINE index_cns_start				.53		;  2  CNS % at begin of dive
+#DEFINE index_supersat_start		.55		;  1  supersaturation % at begin of dive
+#DEFINE index_supersat_end			.56		;  1  supersaturation % at end   of dive
+#DEFINE index_logoffset				.57		;  2  logbook offset
+#DEFINE index_batt_percent			.59		;  1  battery % at end of dive
+#DEFINE index_sp1					.60		;  2  setpoint 1 in sequence setpoint, change depth
+#DEFINE index_sp2					.62		;  2  setpoint 2 ...
+#DEFINE index_sp3					.64		;  2  setpoint 3 ...
+#DEFINE index_sp4					.66		;  2  setpoint 4 ...
+#DEFINE index_sp5					.68		;  2  setpoint 5 ...
+#DEFINE index_salinity				.70		;  1  salinity setting %
+#DEFINE index_cns_end				.71		;  2  CNS % at end of dive
+#DEFINE index_avr_depth				.73		;  2  average depth
+#DEFINE index_total_seconds			.75		;  2  total dive time in seconds
+#DEFINE index_gf_lo_hi				.77		;  2  GF factors  (if using ZH-L16+GF) in sequence lo, hi
+#DEFINE index_factor_sat_desat		.77		;  2  multipliers (if using ZH-L16)    in sequence saturation, desaturation
+#DEFINE index_decomodel				.79		;  1  deco model (ZH-L16, ZH-L16+GF)
+#DEFINE index_total_dives			.80		;  2  total number of dives logged on unit
+#DEFINE index_divemode				.82		;  1  dive mode (OC, CCR, ...)
+#DEFINE index_tissue_pres_total		.83		; 16  total    tissue pressures at end of dive (16x uint8) (since FW 3.08, else N2 pressures)
+#DEFINE index_tissue_pres_N2		.99		; 64  Nitrogen tissue pressures at end of dive (16x float)
+#DEFINE index_tissue_supersat		.163	; 16  tissue   supersaturations at end of dive (16x uint8) (since FW 3.08, else He pressures)
+#DEFINE index_tissue_pres_He		.179	; 64  Helium   tissue pressures at end of dive (16x float)
+#DEFINE index_last_stop				.243	;  1  depth of the last stop
+#DEFINE index_decodistance			.244	;  1  assumed deco distance (not used anymore)
+#DEFINE index_hud_data				.245	;  3  last HUD data set received
+#DEFINE index_battery_gauge			.248	;  6  battery gauge register at end of dive
+#DEFINE index_header_stop			.254	;  2  header stop code 0xFBFB
--- a/src/math.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/math.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File math.inc                             combined next generation V3.04.3
+;   File math.inc                             combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -8,45 +8,45 @@
 ; HISTORY
 ;  2011-08-03 : [mH] moving from OSTC code
 
-	extern	convert_time			; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
+	extern	convert_time			; convert minutes in hi:lo to hours (up:hi) and minutes (lo)
 									; also usable for conversion of seconds to minutes and seconds
 									; trashes xA, xB, xC
 
-	extern	div16					; divA:2 = divA:2 / 2^WREG
+	extern	div16					; divA:2 = divA:2 / 2^WREG					SHIFT-RIGHT    with UNSIGNED values
 									; trashes WREG
 
-	extern	mult16					; divA:2 = divA:2 * 2^WREG
+	extern	mult16					; divA:2 = divA:2 * 2^WREG					SHIFT-LEFT     with UNSIGNED values
 									; trashes WREG
 
-	extern	addU16					; sub_c:2 = sub_a:2 + sub_b:2	with USIGNED values
+	extern	addU16					; sub_c:2 = sub_a:2 + sub_b:2				ADDITION       with UNSIGNED values
 									; trashes WREG
 
-	extern	sub16					; sub_c:2 = sub_a:2 - sub_b:2	with SIGNED   values
+	extern	sub16					; sub_c:2 = sub_a:2 - sub_b:2				SUBTRACTION    with SIGNED   values
 									; sets neg_flag if result is < 0
 									; trashes WREG
 
-	extern	subU16					; sub_c:2 = sub_a:2 - sub_b:2	with UNSIGNED values
+	extern	subU16					; sub_c:2 = sub_a:2 - sub_b:2				SUBTRACTION    with UNSIGNED values
 									; sets neg_flag if result is < 0
 									; trashes WREG
 
-	extern	cmpU16					; trashed = sub_a:2 - sub_b:2	with UNSIGNED values
+	extern	cmpU16					; trashed = sub_a:2 - sub_b:2				COMPARE        with UNSIGNED values
 									; sets neg_flag if result is < 0, but does not store result itself
 									; trashes WREG
 
-	extern	mult16x16				; xC:4 = xA:2 * xB:2			with UNSIGNED values
+	extern	mult16x16				; xC:4 = xA:2 * xB:2						MULTIPLICATION with UNSIGNED values
 									; trashes PRODL, PRODH, WREG
 
-	extern	div16x16				; xC:2 = xA:2 / xB:2 with xA as remainder
+	extern	div16x16				; xC:2 = xA:2 / xB:2 with xA as remainder	DIVISION       with UNSIGNED values
 									; trashes xB, WREG
 
-	extern	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder
+	extern	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder	DIVISION       with UNSIGNED values
 									; trashes WREG
 
-	extern	isr_shift_C31			; 24 bit shift, repeated WREG times,
-									; dedicated to a specific usage
+	extern	isr_shift_C31			; 24 bit shift, repeated WREG times, dedicated to a specific usage
 
-	extern	isr_unsigned_mult16x16	; isr_xC = isr_xA * _isr_xB		with UNSIGNED values
+
+	extern	isr_unsigned_mult16x16	; isr_xC = isr_xA * isr_xB		MULTIPLICATION with UNSIGNED values ** for ISR only **
 									; trashes PRODL, PRODH, WREG
 
-	extern	isr_signed_mult16x16	; isr_xC = isr_xA * _isr_xB		with SIGNED values
+	extern	isr_signed_mult16x16	; isr_xC = isr_xA * isr_xB		MULTIPLICATION with SIGNED   values ** for ISR only **
 									; trashes PRODL, PRODH, WREG
--- a/src/menu_processor.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/menu_processor.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File menu_processor.asm                   combined next generation V3.03.2
+;   File menu_processor.asm                   combined next generation V3.08.6
 ;
 ;   Routines to handle all hwOS graphic/text menus.
 ;
@@ -43,7 +43,7 @@
 	extern	TFT_clear_divemode_menu
 	extern	TFT_divemask_color
 	extern	rtc_set_rtc
-	extern	divemode_option0_return
+	extern	divemode_option_divemenu_return
 	extern	TFT_fillup_with_spaces
 
 
@@ -256,8 +256,8 @@
 
 menu_line_loop_pre3:
 	btfsc	divemode						; in dive mode?
-	goto	divemode_option0_return			; YES - return to it
-	;bra	menu_line_loop_surface			;     - proceed to surface mode dispatcher
+	goto	divemode_option_divemenu_return	; YES - return to it
+	;bra	menu_line_loop_surface			; NO  - proceed to surface mode dispatcher
 
 ; dispatcher for surface mode menus
 menu_line_loop_surface:
@@ -328,10 +328,10 @@
 menu_draw_lines:
 	btfsc	divemode						; in dive mode?
 	bra		menu_draw_lines_divemode		; YES
-	btfsc	menu_flags,0					; Dynamic title?
+	btfsc	menu_flags,0					; dynamic title?
 	rcall	menu_processor_title			; YES - redraw it then
 	MENU_LINE_FONT MENU_LEFT, 0				; initialize start position/font
-	movff	menu_center,win_top				; computed in menu block.
+	movff	menu_center,win_top				; computed in menu block
 
 	; Does the menu have more than 6 lines ?
 	movf	item_max,W
--- a/src/menu_tree.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/menu_tree.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File menu_tree.asm                        next combined generation V3.04.3
+;   File menu_tree.asm                        next combined generation V3.08.8
 ;
 ;   OSTC Surface Menus
 ;
@@ -30,16 +30,15 @@
 
 	extern	do_demo_divemode
 	extern	restart
-	extern	option_save_all
+	extern	option_check_and_store_all
 	extern	option_reset
 	extern	do_demo_planner
 	extern	comm_mode_ble				; will also set CPU speed to normal
 	extern	piezo_config
 	extern	option_reset_all
-	extern	rtc_set_rtc
 	extern	surfloop
 	extern	oColorSetDive
-	extern	vault_decodata_into_eeprom
+	extern	eeprom_deco_data_write
 
  IFDEF _ccr_pscr
 	extern	option_cleanup_oCCRMode
@@ -68,9 +67,9 @@
 	clrf	MS_flags_imprint						; clear all flags for data imprinting
 
 	global	do_main_menu2
-do_main_menu2:							; entry point used by logbook.asm
-	call	TFT_boot					; initialize display
-	call	menu_processor_reset		; reset menu stack
+do_main_menu2:										; entry point used by logbook.asm
+	call	TFT_boot								; initialize display
+	call	menu_processor_reset					; reset menu stack
 
 do_main_menu_common:
  IFDEF _ccr_pscr
@@ -78,8 +77,8 @@
 		MENU_CALL		tLogbook,					logbook
 		MENU_CALL		tGasSetup,					do_gas_menu
 		MENU_CALL		tCCRSetup,					do_ccr_menu
-		MENU_CALL		tPlan,						do_planner_menu
 		MENU_CALL		tDiveModeMenu,				do_divemode_menu
+		MENU_CALL		tSimulator,					do_simulator_menu
 		MENU_CALL		tSystSets,					do_settings_menu
 		MENU_CALL		tExit,						do_restart
 	MENU_END
@@ -87,8 +86,8 @@
 	MENU_BEGIN	tMainMenu, .6
 		MENU_CALL		tLogbook,					logbook
 		MENU_CALL		tGasSetup,					do_gas_menu
-		MENU_CALL		tPlan,						do_planner_menu
 		MENU_CALL		tDiveModeMenu,				do_divemode_menu
+		MENU_CALL		tSimulator,					do_simulator_menu
 		MENU_CALL		tSystSets,					do_settings_menu
 		MENU_CALL		tExit,						do_restart
 	MENU_END
@@ -210,6 +209,16 @@
 
 
 do_ccr_menu_more:
+ IFDEF _external_sensor
+	MENU_BEGIN	tCCRSetup, .6			; CCR/pSCR more menu
+		MENU_OPTION		tS8Mode,					oS8Mode,				0
+		MENU_OPTION		tCCmaxFracO2,				oCCmaxFracO2,			0
+		MENU_OPTION		tDilppO2Check,				oDilppO2Check,			0
+		MENU_OPTION		tPSCR_O2_drop,				oPSCR_drop,				0
+		MENU_OPTION		tPSCR_lungratio,			oPSCR_lungratio,		0
+		MENU_CALL		tBack,						do_return_ccr_menu
+	MENU_END
+ ELSE
 	MENU_BEGIN	tCCRSetup, .5			; CCR/pSCR more menu
 		MENU_OPTION		tCCmaxFracO2,				oCCmaxFracO2,			0
 		MENU_OPTION		tDilppO2Check,				oDilppO2Check,			0
@@ -217,6 +226,7 @@
 		MENU_OPTION		tPSCR_lungratio,			oPSCR_lungratio,		0
 		MENU_CALL		tBack,						do_return_ccr_menu
 	MENU_END
+ ENDIF	; _external_sensor
 
  ENDIF	; _ccr_pscr
 
@@ -363,10 +373,7 @@
 	call	menu_processor_pop			; back to last line
 	bra		do_planner_common
 
-do_planner_menu:
-	; ensure correct simulator results after mode changes without prior excursion to surface mode
-	call	option_save_all
-
+do_simulator_menu:
 	; reset planning parameters to default values
 	lfsr	FSR0,odiveInterval
 	call	option_reset
@@ -378,9 +385,9 @@
 	call	option_reset
 
  IFDEF _gas_contingency
-	; switch off gas contingency mode by default
+	; switch off gas contingency mode by default when entering the simulator menu
 	clrf	WREG
-	movff	WREG,char_I_gas_contingency
+	movff	WREG,opt_gas_contingency_sim
  ENDIF
 
 do_planner_common:
@@ -390,7 +397,7 @@
 	dcfsnz	WREG,W						; subtract one, became zero?
 	bra		do_planner_common_ccr		; YES - use CCR version
 
-	MENU_BEGIN	tPlan, .7
+	MENU_BEGIN	tSimulator, .7
 		MENU_OPTION		tIntvl,						odiveInterval,			0
 		MENU_OPTION		tBtDep,						obottomDepth,			0
 		MENU_CALL		tInter,						do_demo_divemode
@@ -401,26 +408,26 @@
 	MENU_END
 
 do_planner_common_ccr:
-	MENU_BEGIN	tPlan, .7
+	MENU_BEGIN	tSimulator, .7
 		MENU_OPTION		tIntvl,						odiveInterval,			0
 		MENU_OPTION		tBtDep,						obottomDepth,			0
 		MENU_CALL		tInter,						do_demo_divemode
 		MENU_OPTION		tBtTm,						obottomTime,			0
-		MENU_CALL		tDecoSetup,					do_planner_config
+		MENU_CALL		tCalculatorSetup,			do_planner_config
 		MENU_CALL		tDeco,						do_demo_planner
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
 do_planner_config:
  IFDEF _gas_contingency
-	MENU_BEGIN	tPlan, .4
+	MENU_BEGIN	tSimulator, .4
 		MENU_OPTION		tSelectSetpoint,			oSimSetpoint,			0
 		MENU_OPTION		tuseAGF,					oSimAGF,				0
-		MENU_OPTION		tGasContingency,			oGasContingency,		0
+		MENU_OPTION		tGasContingencySim,			oGasContingencySim,		0
 		MENU_CALL		tBack,						do_return_planner_menu
 	MENU_END
  ELSE
-	MENU_BEGIN	tPlan, .3
+	MENU_BEGIN	tSimulator, .3
 		MENU_OPTION		tSelectSetpoint,			oSimSetpoint,			0
 		MENU_OPTION		tuseAGF,					oSimAGF,				0
 		MENU_CALL		tBack,						do_return_planner_menu
@@ -435,196 +442,229 @@
 	call	menu_processor_double_pop	; drop exit line and back to last line
 
 do_divemode_menu:
-	MENU_BEGIN	tDiveModeMenu, .7
-		MENU_OPTION		tDvMode,					oDiveMode,				0
-		MENU_OPTION		tDkMode,					oDecoMode,				0
-		MENU_CALL		tppO2settings,				do_ppo2_menu
-		MENU_OPTION		tsafetystopmenu,			oSafetyStop,			0
-		MENU_CALL		tDecoparameters,			do_decoparameters_menu
-		MENU_CALL		t2ndDecoPlanMenu,			do_2nd_deco_plan_menu
+	MENU_BEGIN	tDiveModeMenu, .6
+		MENU_CALL		tDiveSetup,					do_dive_menu				; dive setup
+		MENU_CALL		tDecoSetup,					do_deco_menu				; deco setup
+		MENU_CALL		tSACSetup,					do_SAC_menu					; SAC  setup
+		MENU_CALL		tppO2Setup,					do_ppo2_menu				; ppO2 limits
+		MENU_CALL		tStopsSetup,				do_stops_menu				; stops setup
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
 
-do_ppo2_menu:
- IFDEF _ccr_pscr
-	MENU_BEGIN	tppO2settings, .6
-		MENU_DYNAMIC	divesets_ppo2_max,			do_toggle_ppo2_max_work
-		MENU_DYNAMIC	divesets_ppo2_max_deco,		do_toggle_ppo2_max_deco
-		MENU_DYNAMIC	divesets_ppo2_min,			do_toggle_ppo2_min
-		MENU_DYNAMIC	divesets_ppo2_min_cc,		do_toggle_ppo2_min_cc
-		MENU_OPTION		tShowppO2,					oShowppO2,				0
+do_dive_menu:
+ IFDEF _cave_mode
+	MENU_BEGIN	tDiveModeMenu, .6
+		MENU_OPTION		tDvMode,					oDiveMode,				0	; dive mode
+		MENU_OPTION		tCvMode,					oCaveMode,				0	; cave mode
+		MENU_OPTION		tFTTSMenu,					oExtraTime,				0	; fTTS/delay
+		MENU_OPTION		tTimeoutDive,				oDiveTimeout,			0	; dive timeout
+		MENU_OPTION		tStoreApnoeDive,			oStoreApnoe,			0	; store apnoe
 		MENU_CALL		tBack,						do_return_divemode_menu
 	MENU_END
  ELSE
-	MENU_BEGIN	tppO2settings, .5
-		MENU_DYNAMIC	divesets_ppo2_max,			do_toggle_ppo2_max_work
-		MENU_DYNAMIC	divesets_ppo2_max_deco,		do_toggle_ppo2_max_deco
-		MENU_DYNAMIC	divesets_ppo2_min,			do_toggle_ppo2_min
-		MENU_OPTION		tShowppO2,					oShowppO2,				0
+	MENU_BEGIN	tDiveModeMenu, .5
+		MENU_OPTION		tDvMode,					oDiveMode,				0	; dive mode
+		MENU_OPTION		tFTTSMenu,					oExtraTime,				0	; fTTS/delay
+		MENU_OPTION		tTimeoutDive,				oDiveTimeout,			0	; dive timeout
+		MENU_OPTION		tStoreApnoeDive,			oStoreApnoe,			0	; store apnoe
 		MENU_CALL		tBack,						do_return_divemode_menu
 	MENU_END
  ENDIF
 
 
-do_return_decoparameters_menu:
+do_return_deco_menu:
 	call	menu_processor_double_pop	; drop exit line and back to last line
 
-do_decoparameters_menu:
-	movff	char_I_deco_model,lo		; 0 = ZH-L16, 1 = ZH-L16-GF
-	tstfsz	lo
-	bra		do_decoparameters_menu_gf	; <> 0 -> GF menu!
-	; NON-GF menu
-	MENU_BEGIN	tDecoparameters, .6
-		MENU_OPTION		tSetBotUse,					obottom_usage,			0
-		MENU_OPTION		tSetDecoUse,				odeco_usage,			0
-		MENU_OPTION		tSaturationMult,			osatmult,				0
-		MENU_OPTION		tDesaturationMult,			odesatmult,				0
-		MENU_CALL		tMore,						do_decoparameters_menu_more
-		MENU_CALL		tBack,						do_return_divemode_menu
-	MENU_END
-
-do_decoparameters_menu_gf:
-	; GF menu
-	MENU_BEGIN	tDecoparameters, .7
-		MENU_OPTION		tSetBotUse,					obottom_usage,			0
-		MENU_OPTION		tSetDecoUse,				odeco_usage,			0
-		MENU_CALL		tGFMenu,					do_GF_menu
-		MENU_OPTION		tSaturationMult,			osatmultgf,				0
-		MENU_OPTION		tDesaturationMult,			odesatmultgf,			0
-		MENU_CALL		tMore,						do_decoparameters_menu_more
+do_deco_menu:
+	MENU_BEGIN	tDecoSetup, .6
+		MENU_OPTION		tDkMode,					oDecoMode,				0	; ZH-L16 /GF
+		MENU_OPTION		tSaturationMult,			osatmultgf,				0	; saturation
+		MENU_OPTION		tDesaturationMult,			odesatmultgf,			0	; desaturation
+		MENU_OPTION		tAltMode,					oAltMode,				0	; altitude mode
+		MENU_CALL		tGFMenu,					do_GF_menu					; GF settings
 		MENU_CALL		tBack,						do_return_divemode_menu
 	MENU_END
 
 
-do_decoparameters_menu_more:
-	MENU_BEGIN	tDecoparameters, .7
-		MENU_OPTION		tLastDecostop,				oLastDeco,				0
-		MENU_OPTION		tAscentSpeed,				oAscentSpeed,			0
-		MENU_OPTION		tGasChangeTime,				oGasChangeTime,			0
-		MENU_OPTION		tExtendedStops,				oExtendedStops,			0
-		MENU_OPTION		tTimeoutDive,				oDiveTimeout,			0
-		MENU_OPTION		tStoreApnoeDive,			oStoreApnoeDive,		0
-		MENU_CALL		tBack,						do_return_decoparameters_menu
+do_SAC_menu:
+ IFDEF _gas_contingency
+	MENU_BEGIN	tSACSetup, .6
+		MENU_OPTION		tCalcGasNeeds,				oCalcAscGas,			0	; calc.gas
+		MENU_OPTION		tGasContingencyDive,		oGasContingencyDive,	0	; switch tank if used up
+		MENU_OPTION		tGasChangeTime,				oGasChangeTime,			0	; gas change time
+		MENU_OPTION		tSetWorkSAC,				oWork_SAC,				0	; work SAC
+		MENU_OPTION		tSetDecoSAC,				oDeco_SAC,				0	; deco SAC
+		MENU_CALL		tBack,						do_return_divemode_menu
 	MENU_END
+ ELSE
+	MENU_BEGIN	tSACSetup, .5
+		MENU_OPTION		tCalcGasNeeds,				oCalcAscGas,			0	; calc.gas
+		MENU_OPTION		tGasChangeTime,				oGasChangeTime,			0	; gas change time
+		MENU_OPTION		tSetWorkSAC,				oWork_SAC,				0	; work SAC
+		MENU_OPTION		tSetDecoSAC,				oDeco_SAC,				0	; deco SAC
+		MENU_CALL		tBack,						do_return_divemode_menu
+	MENU_END
+ ENDIF
 
 
-do_2nd_deco_plan_menu:
-	MENU_BEGIN	t2ndDecoPlanMenu, .3
-		MENU_OPTION		tFTTSMenu,					oExtraTime,				0
-		MENU_OPTION		tCalcAscGas,				oCalcAscGas,			0
+do_ppo2_menu:
+ IFDEF _ccr_pscr
+ IFDEF _helium
+	MENU_BEGIN	tppO2Setup, .6
+		MENU_DYNAMIC	divesets_ppo2_max,			do_toggle_ppo2_max_work		; max work
+		MENU_DYNAMIC	divesets_ppo2_max_deco,		do_toggle_ppo2_max_deco		; max deco
+		MENU_DYNAMIC	divesets_ppo2_min,			do_toggle_ppo2_min			; min OC
+		MENU_DYNAMIC	divesets_ppo2_min_cc,		do_toggle_ppo2_min_cc		; min loop
+		MENU_OPTION		tIBCDwarning,				oEnable_IBCD,			0	; IBCD warning
+		MENU_CALL		tBack,						do_return_divemode_menu
+	MENU_END
+ ELSE
+	MENU_BEGIN	tppO2Setup, .5
+		MENU_DYNAMIC	divesets_ppo2_max,			do_toggle_ppo2_max_work		; max work
+		MENU_DYNAMIC	divesets_ppo2_max_deco,		do_toggle_ppo2_max_deco		; max deco
+		MENU_DYNAMIC	divesets_ppo2_min,			do_toggle_ppo2_min			; min OC
+		MENU_DYNAMIC	divesets_ppo2_min_cc,		do_toggle_ppo2_min_cc		; min loop
+		MENU_CALL		tBack,						do_return_divemode_menu
+	MENU_END
+ ENDIF	; _helium
+ ELSE
+ IFDEF _helium
+	MENU_BEGIN	tppO2Setup, .5
+		MENU_DYNAMIC	divesets_ppo2_max,			do_toggle_ppo2_max_work		; max work
+		MENU_DYNAMIC	divesets_ppo2_max_deco,		do_toggle_ppo2_max_deco		; max deco
+		MENU_DYNAMIC	divesets_ppo2_min,			do_toggle_ppo2_min			; min OC
+		MENU_OPTION		tIBCDwarning,				oEnable_IBCD,			0	; IBCD warning
+		MENU_CALL		tBack,						do_return_divemode_menu
+ ELSE
+	MENU_BEGIN	tppO2Setup, .4
+		MENU_DYNAMIC	divesets_ppo2_max,			do_toggle_ppo2_max_work		; max work
+		MENU_DYNAMIC	divesets_ppo2_max_deco,		do_toggle_ppo2_max_deco		; max deco
+		MENU_DYNAMIC	divesets_ppo2_min,			do_toggle_ppo2_min			; min OC
+		MENU_CALL		tBack,						do_return_divemode_menu
+	MENU_END
+ ENDIF	; _helium
+ ENDIF	; _ccr_pscr
+
+
+do_stops_menu:
+	MENU_BEGIN	tStopsSetup, .6
+		MENU_OPTION		tSafetyStop,				oSafetyStop,			0	; safety stop
+		MENU_OPTION		tExtendedStops,				oExtendedStops,			0	; extended stops
+		MENU_OPTION		tLastDecostop,				oLastDeco,				0	; last deco stop
+		MENU_OPTION		tDvSalinity,				oDiveSalinity,			0	; salinity
+		MENU_OPTION		tDepthWarn,					oMaxDepth,				0	; depth limit
 		MENU_CALL		tBack,						do_return_divemode_menu
 	MENU_END
 
 
 do_GF_menu:
 	MENU_BEGIN	tGFMenu, .6
-		MENU_OPTION		tGF_low,					oGF_low,				0
-		MENU_OPTION		tGF_high,					oGF_high,				0
-		MENU_OPTION		taGF_enable,				oEnable_aGF,			0
-		MENU_OPTION		taGF_low,					oaGF_low,				0
-		MENU_OPTION		taGF_high,					oaGF_high,				0
-		MENU_CALL		tBack,						do_return_decoparameters_menu
+		MENU_OPTION		tGF_low,					oGF_low,				0	; GF  low
+		MENU_OPTION		tGF_high,					oGF_high,				0	; GF  high
+		MENU_OPTION		taGFenable,					oEnable_aGF,			0	; aGF selectable
+		MENU_OPTION		taGF_low,					oaGF_low,				0	; aGF low
+		MENU_OPTION		taGF_high,					oaGF_high,				0	; aGF high
+		MENU_CALL		tBack,						do_return_deco_menu
 	MENU_END
 
 
 ;=============================================================================
 ; Setup Menu
-do_return_settings_deeper:                ; entry point for return from info menu 2
-	call    menu_processor_pop            ; drop one more stack entry
-	
+do_return_settings_deeper:				; entry point for return from info menu 2
+	call	menu_processor_pop			; drop one more stack entry
+
 do_return_settings:
 	bcf		imprint_time_date			; stop imprinting of current time & date
 	call	menu_processor_double_pop	; drop exit line and back to last line
+
  IFDEF _rx_mode
 	bcf		tr_functions_activated		; set TR functions as deactivated by default
 	btfss	ostc_rx_present				; TR model / TR module up & running?
-	bra		do_settings_menu			; NO
+	bra		do_settings_menu			; NO  - use version w/o TR
 	movff	opt_TR_mode,WREG			; YES - get TR mode
 	tstfsz	WREG						;     - TR mode <> off ?
 	bsf		tr_functions_activated		;       YES - set TR functions as activated
  ENDIF
 
 do_settings_menu:
- IFDEF	_hwos_sport
-	bsf	ble_available				; For very old OSTC sport
- ENDIF	
-
+ IFDEF _hwos_sport
+	bsf		ble_available				; for very old OSTC sport
+ ENDIF
 	btfsc	ble_available				; BLE available?
 	bra		do_settings_menu_ble		; YES
-	
- 	MENU_BEGIN	tSystSets, .5
+
+	MENU_BEGIN	tSystSets, .5
 		MENU_CALL		tInfoMenu,					do_info_menu
 		MENU_CALL		tSetTimeDate,				do_date_time_menu
 		MENU_CALL		tDispSets,					do_dispsets_menu
-		MENU_CALL		tMore,						do_settings_menu_more
+		MENU_CALL		tSysSets,					do_syssets_menu
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
+
 do_settings_menu_ble:
  IFDEF _rx_functions
-	btfsc	ostc_rx_present				; TR model?
-	bra		do_settings_menu_rx			; YES
- ENDIF
+	btfss	ostc_rx_present				; TR model and TR activated?
+	bra		do_settings_menu_noRX		; NO
 
-	MENU_BEGIN	tSystSets, .6
-		MENU_CALL		tInfoMenu,					do_info_menu
-		MENU_CALL		tBleTitle,					comm_mode_ble
-		MENU_CALL		tSetTimeDate,				do_date_time_menu
-		MENU_CALL		tDispSets,					do_dispsets_menu
-		MENU_CALL		tMore,						do_settings_menu_more
-		MENU_CALL		tBack,						do_return_main_menu
-	MENU_END
-
- IFDEF _rx_functions
-do_settings_menu_rx:
 	MENU_BEGIN	tSystSets, .7
 		MENU_CALL		tInfoMenu,					do_info_menu
 		MENU_CALL		tBleTitle,					comm_mode_ble
 		MENU_CALL		tTrSettings,				do_settings_menu_TR
 		MENU_CALL		tSetTimeDate,				do_date_time_menu
 		MENU_CALL		tDispSets,					do_dispsets_menu
-		MENU_CALL		tMore,						do_settings_menu_more
+		MENU_CALL		tSysSets,					do_syssets_menu
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
  ENDIF
 
+do_settings_menu_noRX:
+	MENU_BEGIN	tSystSets, .6
+		MENU_CALL		tInfoMenu,					do_info_menu
+		MENU_CALL		tBleTitle,					comm_mode_ble
+		MENU_CALL		tSetTimeDate,				do_date_time_menu
+		MENU_CALL		tDispSets,					do_dispsets_menu
+		MENU_CALL		tSysSets,					do_syssets_menu
+		MENU_CALL		tBack,						do_return_main_menu
+	MENU_END
+
 
 do_info_menu:
  IFDEF _rx_functions
-	btfsc	ostc_rx_present				; TR model?
-	bra		do_info_menu_TR				; YES
- ENDIF
+	btfss	ostc_rx_present				; TR model?
+	bra		do_info_menu_noRX			; NO
 
-	MENU_BEGIN	tInfoMenu, .6
+	MENU_BEGIN	tInfoMenu, .7
+		MENU_DYNAMIC	info_menu_uptime,			0
 		MENU_DYNAMIC	info_menu_serial,			0
 		MENU_DYNAMIC	info_menu_firmware,			0
-		MENU_DYNAMIC	info_menu_config,			0
-		MENU_DYNAMIC	info_menu_battery_volts,	0
-		MENU_DYNAMIC	info_menu_uptime,			0
-		MENU_CALL		tMore,						do_info_menu2
-	MENU_END
-
- IFDEF _rx_functions
-do_info_menu_TR:
-	MENU_BEGIN	tInfoMenu, .7
-		MENU_DYNAMIC	info_menu_serial,			0
-		MENU_DYNAMIC	info_menu_firmware,			0
+		MENU_DYNAMIC	info_menu_fw_cration_date,	0
 		MENU_DYNAMIC	info_menu_firmware_rx,		0
-		MENU_DYNAMIC	info_menu_config,			0
-		MENU_DYNAMIC	info_menu_battery_volts,	0
-		MENU_DYNAMIC	info_menu_uptime,			0
+		MENU_DYNAMIC	info_menu_total_dives,		0
 		MENU_CALL		tMore,						do_info_menu2
 	MENU_END
  ENDIF
 
-do_info_menu2: ;same for all hardware versions
-	MENU_BEGIN	tInfoMenu, .2
+do_info_menu_noRX:
+	MENU_BEGIN	tInfoMenu, .6
+		MENU_DYNAMIC	info_menu_uptime,			0
+		MENU_DYNAMIC	info_menu_serial,			0
+		MENU_DYNAMIC	info_menu_firmware,			0
+		MENU_DYNAMIC	info_menu_fw_cration_date,	0
 		MENU_DYNAMIC	info_menu_total_dives,		0
+		MENU_CALL		tMore,						do_info_menu2
+	MENU_END
+
+do_info_menu2:
+	MENU_BEGIN	tInfoMenu, .5
+		MENU_DYNAMIC	info_menu_battery_volts,	0
+		MENU_DYNAMIC	info_menu_config,			0
+		MENU_DYNAMIC	info_menu_sensor_calib,		0
+		MENU_DYNAMIC	info_menu_sensor_offset,	0
 		MENU_CALL		tBack,						do_return_settings_deeper
 	MENU_END
- 
- 
+
 
  IFDEF _rx_functions
 
@@ -696,53 +736,47 @@
 do_return_settings_more:
 	call	menu_processor_double_pop	; drop exit line and back to last line
 
-do_settings_menu_more:
+do_syssets_menu:
 	btfsc	battery_gauge_available		; piezo buttons available?
-	bra		do_settings_menu_more_piezo	; YES
+	bra		do_syssets_menu_piezo		; YES
 
  IFDEF _compass
-	MENU_BEGIN	tSystSets, .6													; All MENU_CALLs
-		MENU_CALL		tCompassMenu,				do_compass_menu				; in this menu need to
-		MENU_CALL		tLogOffset,					do_log_offset_menu			; stay together on this
-		MENU_OPTION		tAltMode,					oAltMode,				0	; menu level in order to
-		MENU_OPTION		tDvSalinity,				oDiveSalinity,			0	; not mess up the menu
-		MENU_CALL		tResetMenu,					do_reset_menu				; stack on doing the
-		MENU_CALL		tBack,						do_return_settings			; do_return_settings !
+	MENU_BEGIN	tSystSets, .4													; All MENU_CALLs in this menu
+		MENU_CALL		tCompassMenu,				do_compass_menu				; need to stay together on this
+		MENU_CALL		tLogOffset,					do_log_offset_menu			; menu level in order to not
+		MENU_CALL		tResetMenu,					do_reset_menu				; mess up the menu stack on doing
+		MENU_CALL		tBack,						do_return_settings			; the do_return_settings !
 	MENU_END
  ELSE
-	MENU_BEGIN	tSystSets, .5													; see above
+	MENU_BEGIN	tSystSets, .3													; see above
 		MENU_CALL		tLogOffset,					do_log_offset_menu			;
-		MENU_OPTION		tAltMode,					oAltMode,				0	;
-		MENU_OPTION		tDvSalinity,				oDiveSalinity,			0	;
 		MENU_CALL		tResetMenu,					do_reset_menu				;
 		MENU_CALL		tBack,						do_return_settings			;
 	MENU_END
  ENDIF	; _compass
 
 
-do_return_settings_menu_more_pz:
+do_return_syssets_menu_piezo:
 	call	TFT_ClearScreen
 	call	piezo_config				; configure buttons
 	call	menu_processor_double_pop	; drop exit line and back to last line
 
-do_settings_menu_more_piezo:
+do_syssets_menu_piezo:
  IFDEF _compass
-	MENU_BEGIN	tSystSets, .7
+	MENU_BEGIN	tSystSets, .6
 		MENU_CALL		tCompassMenu,				do_compass_menu				; see above
 		MENU_CALL		tLogOffset,					do_log_offset_menu			;
-		MENU_OPTION		tAltMode,					oAltMode,				0	;
-		MENU_OPTION		tDvSalinity,				oDiveSalinity,			0	;
+		MENU_DYNAMIC	info_menu_total_dives,		0
 		MENU_CALL		tResetMenu,					do_reset_menu				;
-		MENU_CALL		tMore,						do_settings_piezo_menu		;
+		MENU_CALL		tPiezo,						do_settings_piezo_menu		;
 		MENU_CALL		tBack,						do_return_settings			;
 	MENU_END
  ELSE
-	MENU_BEGIN	tSystSets, .6
+	MENU_BEGIN	tSystSets, .5
 		MENU_CALL		tLogOffset,					do_log_offset_menu			; see above
-		MENU_OPTION		tAltMode,					oAltMode,				0	;
-		MENU_OPTION		tDvSalinity,				oDiveSalinity,			0	;
+		MENU_DYNAMIC	info_menu_total_dives,		0
 		MENU_CALL		tResetMenu,					do_reset_menu				;
-		MENU_CALL		tMore,						do_settings_piezo_menu		;
+		MENU_CALL		tPiezo,						do_settings_piezo_menu		;
 		MENU_CALL		tBack,						do_return_settings			;
 	MENU_END
  ENDIF
@@ -750,17 +784,17 @@
 
 do_settings_piezo_menu:
 	; Menu with features only available in piezo button hardware
-	MENU_BEGIN	tSystSets, .3
+	MENU_BEGIN	tPiezo, .3
 		MENU_OPTION		tButtonleft,				ocR_button_left,		0		; left  button sensitivity
 		MENU_OPTION		tButtonright,				ocR_button_right,		0		; right button sensitivity
-		MENU_CALL		tBack,						do_return_settings_menu_more_pz
+		MENU_CALL		tBack,						do_return_syssets_menu_piezo
 	MENU_END
 
 
  IFDEF _compass
 
 do_compass_menu:
-	MENU_BEGIN	tSystSets, .5
+	MENU_BEGIN	tCompassMenu, .5
 		MENU_CALL		tCompassMenu,				compass_calibration_loop	; exits to surface loop
 ;		MENU_OPTION		tCompassGain,				oCompassGain,	0
 		MENU_DYNAMIC	menu_cal_x,					0
@@ -811,41 +845,31 @@
 
 
 do_reset_logbook:
-	clrf	EEADRH						; make sure to select EEPROM bank 0
-	clrf	EEDATA
-	read_int_eeprom  .2
-	write_int_eeprom .16
-	read_int_eeprom  .3
-	write_int_eeprom .17				; copy number of dives
-	clrf	EEDATA
-	write_int_eeprom .2
-	write_int_eeprom .3					; clear total dives
-	write_int_eeprom .4
-	write_int_eeprom .5
-	write_int_eeprom .6					; reset logbook pointers
-	call	ext_flash_erase_logbook		; and complete logbook
+	call	erase_complete_logbook			; erase complete logbook
 	bra		do_return_settings_more_deeper
 
-
 do_reset_deco:
 	call	deco_clear_tissue				; set all tissues to absolute pressure * N2_ratio           (C-code)
 	call	deco_calc_dive_interval_1min	; update tissues by 1 minute to calculate current GF factor (C-code)
 	call	deco_calc_desaturation_time		; calculate desaturation and no-fly/no-altitude time        (C-code)
 	banksel	common
-	call	vault_decodata_into_eeprom		; store updated deco data to EEPROM
+	call	eeprom_deco_data_write		; store updated deco data into EEPROM
 	bra		do_return_settings_more_deeper
 
 
 do_reset_settings:
-	call	TFT_ClearScreen				; clear screen
+	call	TFT_ClearScreen				; clear screen to show start of activity
 	call	option_reset_all			; reset all options to factory default
 	call	do_logoffset_reset			; reset log offset
 	goto	restart						; restart into surface mode
 
 do_reboot:
-	call	ext_flash_enable_protection	; set write protection on external EEPROM
-	call	rtc_init					; reset the real time clock (will reset to firmware creation date)
-	reset
+	call	ext_flash_enable_protection	; set write protection on external flash
+	call	eeprom_deco_data_write		; update deco data     in EEPROM
+	call	eeprom_battery_gauge_write	; update battery gauge in EEPROM
+	btfsc	options_changed				; do the options need to be stored to EEPROM ?
+	call	option_check_and_store_all	; YES - check and store all option values in EEPROM
+	reset								; cold-start the processor
 
 do_return_date_time_menu:
 	call	menu_processor_double_pop	; drop exit line and back to last line
@@ -884,7 +908,7 @@
 	MENU_END
 
 
-do_toggle_ppo2_max_work:				; add 0.1 bar, with hard-coded max.
+do_toggle_ppo2_max_work:				; add 0.1 bar
 	movff	char_I_ppO2_max_work,lo		; bank-safe copy
 	movlw	.10
 	addwf	lo,F
@@ -897,7 +921,7 @@
 	movff	lo,char_I_ppO2_max_work
 	return
 
-do_toggle_ppo2_max_deco:				; add 0.1 bar, with hard-coded max.
+do_toggle_ppo2_max_deco:				; add 0.1 bar
 	movff	char_I_ppO2_max_deco,lo		; bank-safe copy
 	movlw	.10
 	addwf	lo,F
@@ -910,7 +934,7 @@
 	movff	lo,char_I_ppO2_max_deco
 	return
 
-do_toggle_ppo2_min:						; sub 0.1 bar, with hard-coded min.
+do_toggle_ppo2_min:						; sub 0.1 bar
 	movff	char_I_ppO2_min,lo			; bank-safe copy
 	incf	lo,F
 	movlw	ppo2_warning_low_highest
@@ -922,7 +946,7 @@
 	movff	lo,char_I_ppO2_min
 	return
 
-do_toggle_ppo2_min_cc:					; sub 0.1 bar, with hard-coded min.
+do_toggle_ppo2_min_cc:					; sub 0.1 bar
 	movff	char_I_ppO2_min_loop,lo		; bank-safe copy
 	incf	lo,F
 	movlw	ppo2_warning_loop_highest
@@ -951,7 +975,7 @@
 
 
 do_logoffset_common:
-	call	do_logoffset_common_read	; read current offset into mpr+1:mpr+0
+	call	eeprom_log_offset_read		; read current offset into mpr+1:mpr+0
 	movff	opt_logoffset_step,ul		; get step size: 0=1, 1=10, 2=100, 3=1000
 	incf	ul,F						; 0...3 -> 1...4
 	clrf	mpr+3						; clear   step size, high byte
@@ -1000,12 +1024,11 @@
 	btfsc	STATUS,C					; borrow to propagate (B == /CARRY) ?
 	bra		do_logoffset_exit			; NO  - result >= 0, store and return
 do_logoffset_reset:
-	clrf	mpr+0						; YES - revert offset to 0, low  byte
-	clrf	mpr+1						;     - ...                 high byte
+	CLRI	mpr							; YES - revert offset to 0
 	;bra	do_logoffset_exit			;     - store offset and return
 
 do_logoffset_exit:
-	goto	do_logoffset_common_write	; store offset and return
+	goto	eeprom_log_offset_write		; store offset and return
 
 
 do_return_dispsets_menu:
@@ -1016,21 +1039,21 @@
  IF _language_2!=none
 	MENU_BEGIN	tDispSets, .7
 		MENU_OPTION		tBright,					oBrightness,			0
+		MENU_OPTION		tLayout,					oLayout,				0
+		MENU_OPTION		tUnits,						oUnits,					0
 		MENU_OPTION		tLanguage,					oLanguage,				0
-		MENU_OPTION		tUnits,						oUnits,					0
+		MENU_OPTION		tFlip,						oFlipScreen,			0
 		MENU_CALL		tColorScheme,				do_color_scheme
-		MENU_OPTION		tFlip,						oFlipScreen,			0
 		MENU_CALL		tMore,						do_dispsets_menu_more
-		MENU_CALL		tBack,						do_return_settings
 	MENU_END
  ELSE
 	MENU_BEGIN	tDispSets, .6
 		MENU_OPTION		tBright,					oBrightness,			0
+		MENU_OPTION		tLayout,					oLayout,				0
 		MENU_OPTION		tUnits,						oUnits,					0
-		MENU_CALL		tColorScheme,				do_color_scheme
 		MENU_OPTION		tFlip,						oFlipScreen,			0
+		MENU_CALL		tColorScheme,				do_color_scheme
 		MENU_CALL		tMore,						do_dispsets_menu_more
-		MENU_CALL		tBack,						do_return_settings
 	MENU_END
  ENDIF
 
@@ -1038,24 +1061,22 @@
 do_dispsets_menu_more:
  IFDEF _helium
 	MENU_BEGIN	tDispSets, .7
-		MENU_OPTION		tMODwarning,				oMODwarning,			0
-;		MENU_OPTION		tIBCDwarning,				oEnable_IBCD,			0		; taken out in favor of option oLayout
-		MENU_OPTION		tVSItext2,					oVSItextv2,				0
 		MENU_OPTION		tVSIgraph,					oVSIgraph,				0
-		MENU_OPTION		tLayout,					oLayout,				0
+		MENU_OPTION		tVSItext2,					oVSItext,				0
+		MENU_OPTION		tShowppO2,					oShowppO2,				0
+		MENU_OPTION		tDepthWarning,				oDepthWarn,				0
 		MENU_OPTION		t2ndDepth,					o2ndDepthDisp,			0
 		MENU_OPTION		tTissueGraphics,			oTissueGraphics,		0
-		MENU_CALL		tBack,						do_return_dispsets_menu
+		MENU_CALL		tBack,						do_return_settings_deeper
 	MENU_END
  ELSE
 	MENU_BEGIN	tDispSets, .6
-		MENU_OPTION		tMODwarning,				oMODwarning,			0
-;		MENU_OPTION		tIBCDwarning,				oEnable_IBCD,			0		; taken out in favor of option oLayout
-		MENU_OPTION		tVSItext2,					oVSItextv2,				0
 		MENU_OPTION		tVSIgraph,					oVSIgraph,				0
-		MENU_OPTION		tLayout,					oLayout,				0
+		MENU_OPTION		tVSItext2,					oVSItext,				0
+		MENU_OPTION		tShowppO2,					oShowppO2,				0
+		MENU_OPTION		tDepthWarning,				oDepthWarn,				0
 		MENU_OPTION		t2ndDepth,					o2ndDepthDisp,			0
-		MENU_CALL		tBack,						do_return_dispsets_menu
+		MENU_CALL		tBack,						do_return_settings_deeper
 	MENU_END
  ENDIF
 
@@ -1090,7 +1111,7 @@
 	movwf	batt_percent				; set battery level to full
 
 	; default (in cases of timeout or USB): use old battery
-	call	retrieve_battery_registers	; retrieve stored battery gauge value from EEPROM
+	call	eeprom_battery_gauge_read	; retrieve stored battery gauge value from EEPROM
 
  IFDEF _screendump
 	bsf		screen_dump_avail			; enable screen dump function to prevent exiting into COMM mode immediately
@@ -1193,18 +1214,15 @@
 
 	global	use_old_prior_209
 use_old_prior_209:
-	clrf	EEADRH
-	read_int_eeprom 0x0F				; =0:1.5V, =1:3,6V Saft, =2:LiIon 3,7V/0.8Ah, =3:LiIon 3,7V/3.1Ah, =4: LiIon 3,7V/2.3Ah
-	incfsz	EEDATA,F					; was 0xFF?
-	return								; NO - done
-
-	call	lt2942_get_status			; check for gauge IC
-	movlw	.3							; Assume a 18650
-	btfss	battery_gauge_available		; cR/2 hardware?
-	movlw	.1							; assume a Saft
-	movwf	EEDATA
-	write_int_eeprom 0x0F				; store the new battery type into EEPROM
-	return
+	EEPROM_CC_READ eeprom_battery_type,WREG	; read battery type from EEPROM
+	incfsz	WREG,W							; battery type = 0xFF (undefined) ?
+	return									; NO  - done
+	call	lt2942_get_status				; YES - check for gauge IC
+	movlw	.3								;     - default to a 18650 (LiIon 3.7V/3.1Ah)
+	btfss	battery_gauge_available			;     - OSTC 2 or cR hardware?
+	movlw	.1								;     - NO - assume a Saft (disposable 3.6 V)
+	EEPROM_CC_WRITE WREG,eeprom_battery_type;     - write battery type to EEPROM
+	return									;     - done
 
 
 use_old_batteries:
@@ -1214,7 +1232,7 @@
 
 	global	get_battery_data
 get_battery_data:
-	call	retrieve_battery_registers	; retrieve stored battery gauge value from EEPROM
+	call	eeprom_battery_gauge_read	; retrieve stored battery gauge value from EEPROM
 	movff	battery_type,lo				; copy retrieved battery type to lo
 	rcall	setup_new_saft				; default battery configuration
 	incf	lo,F						; (0-4) -> (1-5)
@@ -1300,7 +1318,7 @@
 
 use_37V_rechargeable:
 	rcall	setup_new_panasonic
-	call	reset_battery_internal_only
+	call	reset_battery_gauge
 	bra		use_batt_exit_1
 
 use_16650_battery:
@@ -1312,7 +1330,7 @@
 	;bra	use_batt_exit
 
 use_batt_exit:
-	call	reset_battery_pointer		; reset battery pointer 0x07-0x0C and battery gauge
+	call	reset_battery_gauge_and_lt2942		; reset battery pointer 0x07-0x0C and battery gauge
 use_batt_exit_1:
  IFNDEF _screendump
 	bcf		comm_mode_disabled			; re-enable COMM mode again
--- a/src/ms5541.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/ms5541.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File ms5541.asm                           combined next generation V3.0.3b
+;   File ms5541.asm                           combined next generation V3.8.6
 ;
 ;   Sensor subroutines
 ;
@@ -116,8 +116,8 @@
 	movf	isr_xC+2,W
 	addwfc	SENS+1,F
 
-	; calculate absolute pressure = (sens * (d1-off))/2^12 + 1000 (For MS5541C)
-	; calculate absolute pressure = (sens * (d1-off))/2^11 + 1000 (For MS5541C-30)
+	; calculate absolute pressure = (sens * (d1-off))/2^12 + 1000 (for MS5541C)
+	; calculate absolute pressure = (sens * (d1-off))/2^11 + 1000 (for MS5541C-30)
 	movf	OFF+0,W						; d1-off --> a
 	subwf	D1+0,W
 	movwf	isr_xA+0
@@ -128,17 +128,14 @@
 	MOVII	SENS,isr_xB					; sens --> b
 	call	isr_signed_mult16x16
 	movlw	.13
-	cpfslt	C1+1		; C1 > 3328 (Must be MS5541-30)
-	bra	isr_shift_ms5541_30
-	; MS5541
-	movlw	.12-.8						; a 12 bit shift = 1 byte + 4 bits
+	cpfslt	C1+1						; C1 > 3328 ?
+	bra		isr_shift_ms5541_30			; YES - MS5541-30
+	movlw	.12-.8						; NO  - MS5541: 12 bit shift = 1 byte + 4 bits
+	bra		isr_shift_ms5541_common
+isr_shift_ms5541_30:
+	movlw	.11-.8						; MS5541-30:    11 bit shift = 1 byte + 3 bits
+isr_shift_ms5541_common:
 	call	isr_shift_C31
-	bra	isr_shift_ms5541_all
-isr_shift_ms5541_30:
-	; MS5541-30
-    	movlw	.11-.8						; a 11 bit shift = 1 byte + 3 bits
-	call	isr_shift_C31
-isr_shift_ms5541_all:
 	movlw	LOW  .1000					; add 1000
 	addwf	isr_xC+1,F
 	movlw	HIGH .1000
--- a/src/option_table.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/option_table.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File option_table.asm                     combined next generation V3.04.3
+;   File option_table.asm                     combined next generation V3.08.8
 ;
 ;   The Option Table
 ;
@@ -10,105 +10,99 @@
 ;   2014-08-03 : mH creation
 ;
 
-#include "hwos.inc"					; Mandatory Header
+#include "hwos.inc"                    ; Mandatory Header
 #include "eeprom_rs232.inc"
 
 ;=============================================================================
 ; Options Tables
 
-option_table	CODE 0x00700
+option_table	CODE 0x00700	; keep in lower page!
+
 
-OPTION_UINT8	MACRO lbl, min, max, default, unit, eeprom, register
-		global	lbl
-lbl:	db		.0, default			; type0 = INT8
-		db		.1, min
-		db		max, eeprom
-		dw		unit
-		dw		register
+OPTION_UINT8	MACRO lbl, min, max, default, unit, eeprom, serial, register
+	global	lbl
+lbl:	db	.0, serial					; type   : 0 = INT8
+		db	.1, min, max, default		; value  : increment, min, max, default
+		dw	unit, register, eeprom		; pointer: unit, variable, EEPROM
 		ENDM
 
-OPTION_UINT8d	MACRO lbl, min, max, default, unit, eeprom, register
-		global	lbl
-lbl:	db		.3, default			; type3 = INT8 with automatic display in meters or feet
-		db		.1, min
-		db		max, eeprom
-		dw		unit
-		dw		register
+OPTION_UINT8d	MACRO lbl, min, max, default, unit, eeprom, serial, register
+	global	lbl
+lbl:	db	.3, serial					; type   : 3 = INT8 with automatic display in meters or feet
+		db	.1, min, max, default		; value  : increment, min, max, default
+		dw	unit, register, eeprom		; pointer: unit, variable, EEPROM
 		ENDM
 
-OPTION_UINT8p2	MACRO lbl, min, max, default, unit, eeprom, register
-		global	lbl
-lbl:	db		.0, default			; type0 = INT8
-		db		.2, min
-		db		max, eeprom
-		dw		unit
-		dw	register
+OPTION_UINT8p2	MACRO lbl, min, max, default, unit, eeprom, serial, register
+	global	lbl
+lbl:	db	.0, serial					; type   : 0 = INT8 with increment 2
+		db	.2, min, max, default		; value  : increment, min, max, default
+		dw	unit, register, eeprom		; pointer: unit, variable, EEPROM
 		ENDM
 
-OPTION_UINT8p3	MACRO lbl, min, max, default, unit, eeprom, register
+OPTION_UINT8p3	MACRO lbl, min, max, default, unit, eeprom, serial, register
 		global	lbl
-lbl:	db		.0, default			; type0 = INT8
-		db		.3, min
-		db		max, eeprom
-		dw		unit
-		dw		register
+lbl:	db	.0, serial					; type   : 0 = INT8 with increment 3
+		db	.3, min, max, default		; value  : increment, min, max, default
+		dw	unit, register, eeprom		; pointer: unit, variable, EEPROM
 		ENDM
 
-OPTION_UINT8p3d	MACRO lbl, min, max, default, unit, eeprom, register
+OPTION_UINT8p3d	MACRO lbl, min, max, default, unit, eeprom, serial, register
 		global	lbl
-lbl:	db		.3, default			; type3 = INT8 with automatic display in meters or feet
-		db		.3, min
-		db		max, eeprom
-		dw		unit
-		dw		register
+lbl:	db	.3, serial					; type   : 3 = INT8 with increment 3 and automatic display in meters or feet
+		db	.3, min, max, default		; value  : increment, min, max, default
+		dw	unit, register, eeprom		; pointer: unit, variable, EEPROM
 		ENDM
 
-OPTION_UINT8p5	MACRO lbl, min, max, default, unit, eeprom, register
+OPTION_UINT8p5	MACRO lbl, min, max, default, unit, eeprom, serial, register
 		global	lbl
-lbl:	db		.0, default			; type0 = INT8
-		db		.5, min
-		db		max, eeprom
-		dw		unit
-		dw		register
+lbl:	db	.0, serial					; type   : 0 = INT8 with increment 5
+		db	.5, min, max, default		; value  : increment, min, max, default
+		dw	unit, register, eeprom		; pointer: unit, variable, EEPROM
 		ENDM
 
-OPTION_UINT8p10	MACRO lbl, min, max, default, unit, eeprom, register
+OPTION_UINT8p10	MACRO lbl, min, max, default, unit, eeprom, serial, register
 		global	lbl
-lbl:	db		.0, default			; type0 = INT8
-		db		.10, min
-		db		max, eeprom
-		dw		unit
-		dw		register
+lbl:	db	.0, serial					; type   : 0 = INT8 with increment 10
+		db	.10, min, max, default		; value  : increment, min, max, default
+		dw	unit, register, eeprom		; pointer: unit, variable, EEPROM
 		ENDM
 
-OPTION_ENUM8	MACRO lbl, max, default, tValue, eeprom, register
+OPTION_ENUM8	MACRO lbl, max, default, tValue, eeprom, serial, register
 		global	lbl
 		extern	tValue
-lbl:	db		.1, default			; type1 = ENUM
-		db		LOW(tValue), HIGH(tValue)
-		db		max, eeprom
-		dw		.0					; no unit
-		dw		register
+lbl:	db	.1, serial					; type   : 1 = ENUM
+		db	LOW(tValue), HIGH(tValue)	; value  : pointer to base text
+		db	max-1, default				; value  : number of ENUMS, default
+		dw	.0, register, eeprom		; pointer: (no unit), variable, EEPROM
 		ENDM
 
-OPTION_BOOL		MACRO lbl, default, eeprom, register
-		OPTION_ENUM8 lbl, 2, default, tNo, eeprom, register
+OPTION_BOOL		MACRO lbl, default, eeprom, serial, register
+		global	lbl
+		extern	tNo
+lbl:	db	.1, serial					; type   : 1 = ENUM
+		db	LOW(tNo), HIGH(tNo)			; value  : pointer to base of text "no"
+		db	.2-1, default				; value  : number of ENUMS, default
+		dw	.0, register, eeprom		; pointer: (no unit), variable, EEPROM
 		ENDM
 
-OPTION_STRING	MACRO lbl, length, defText, eeprom, register
+OPTION_STRING	MACRO lbl, stringlength, defText, eeprom, serial, register
 		global	lbl
-lbl:	db		.2, LOW(defText)	; type2 = STRING
-		db		HIGH(defText), 0
-		db		length, eeprom
-		dw		.0					; no unit
-		dw		register
+lbl:	db	.2, serial					; type   : 2 = STRING
+		db	LOW(defText), HIGH(defText)	; value  : pointer to string
+		db	stringlength, .0			; value  : length, (no default)
+		dw	.0, register, eeprom		; pointer: (no unit), variable, EEPROM
 		ENDM
 
+OPTION_END	MACRO
+		db	0xFF, 0xFF					; type   : 255 = end of table
+		ENDM
 
 ;=============================================================================
+
 	extern	tPercent, tMeters, tMinutes, tGasDisabled, tbar, tNo, tTrModeOff, tTrPresNone, tDefName, tblank, tLogTunitC, tTissuePresSat
-	extern	char_I_dive_interval, char_I_bottom_time, char_I_bottom_depth
-	extern	char_I_deco_model
+	extern	char_I_bottom_time, char_I_bottom_depth
+	extern	char_I_model
 	extern	char_I_extra_time
 	extern	char_I_SAC_work, char_I_SAC_deco, tLitersMinute
 	extern	char_I_PSCR_drop, char_I_PSCR_lungratio
@@ -116,250 +110,249 @@
 	extern	char_I_CC_max_frac_O2
 	extern	char_I_altitude_wait
 	extern	char_I_ppO2_max_work, char_I_ppO2_min, char_I_ppO2_max_deco, char_I_ppO2_min_loop
-	extern	char_I_ascent_speed, char_I_descent_speed, tMeterMinute
+	extern	char_I_descent_speed, tMeterMinute
 	extern	char_I_gas_change_time
 	extern	char_I_max_pres_diff
 	extern	char_I_gas_density_att, char_I_gas_density_warn
-	extern	char_I_dil_ppO2_check
-
- IFDEF _gas_contingency
-	extern	char_I_gas_contingency
- ENDIF
-
+	extern	char_I_dil_check
 
-;	Option Table - Format:
-;	----------------------
-;	OPTION_UINT8	Label,				min,			max,		  default, unit text,	EEPROM location, RAM location
-;	OPTION_ENUM8	Label,				number of enums				  default, unit text,	EEPROM location, RAM location	; number of enums = 2, 3, ..., default starts with 0
-;	OPTION_BOOL		Label,											  default,				EEPROM location, RAM location
+#DEFINE nounit		0x0000	; no unit text associated
+#DEFINE volatile	0xFFFF	; not stored in EEPROM
+#DEFINE nocomm		0x00	; not accessible via RS232
 
-#DEFINE notext		.0		; no text-string associated
-#DEFINE volatile	-1		; do not store to EEPROM
-
+;=============================================================================
 
 	global	option_table_begin
 option_table_begin:
-;=============================================================================
-; Manage Deco Planer & Dive Parameters
-	OPTION_ENUM8	oDiveMode,			.5,								.0,		tDvOC,			.8,		opt_dive_mode					; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR
-	OPTION_ENUM8	oDecoMode,			.2,								.1,		tZHL16,			.9,		char_I_deco_model				; 0 = ZH-L16, 1 = ZH-L16-GF
-	;																							.10										; in use, see below
-	OPTION_UINT8d	oLastDeco,			.3,				.6,				.3,		tMeters,		.11,	opt_last_stop					; depth of the last deco stop
-	OPTION_UINT8	oGF_low,			.10,			.100,			.30,	tPercent,		.12,	opt_GF_low						; normal GF low
-	OPTION_UINT8	oGF_high,			.45,			.110,			.85,	tPercent,		.13,	opt_GF_high						; normal GF high
-	OPTION_UINT8p5	osatmultgf,			.100,			.140,			.100,	tPercent,		.14,	opt_sat_multiplier_gf			; saturation factor   for GF mode
-	OPTION_UINT8p5	odesatmultgf,		.60,			.100,			.100,	tPercent,		.15,	opt_desat_multiplier_gf			; desaturation factor for GF mode
-	;																							.16										; in use, see below
-	OPTION_UINT8	oaGF_low,			.10,			.100,			.30,	tPercent,		.17,	opt_aGF_low						; alternative GF low
-	OPTION_UINT8	oaGF_high,			.45,			.110,			.85,	tPercent,		.18,	opt_aGF_high					; alternative GF high
-	OPTION_BOOL		oEnable_aGF,		.0,														.19,	opt_enable_aGF					; =1: aGF can be selected underwater
-	OPTION_UINT8	oCompassGain,		.0,				.7,				.6,		tMinutes,		.20,	opt_compass_gain				; 0-7 (230LSB/Gauss to 1370LSB/Gauss)
-	OPTION_ENUM8	oSamplingRate,		.2,								.0,		tSetSeconds,	.21,	opt_sampling_rate				; =1: 10s, =0: 2s
+
+;	Option Table - Format:
+;	----------------------
+;	OPTION_UINT8    Label,              min,                  max,            default,      unit text,      EEPROM,  serial,  RAM location
+;	OPTION_ENUM8    Label,        number of ENUMS,                            default,      unit text,      EEPROM,  serial,  RAM location 					; number of enums = 2, 3, ..., default starts with 0
+;	OPTION_BOOL     Label,                                                    default,                      EEPROM,  serial,  RAM location
 
-;=============================================================================
-; Managing Settings
-	OPTION_UINT8	oExtraTime,			.0,				.9,				.0,		tMinutes,		.22,	char_I_extra_time				; extra bottom time for future TTS calculation
-	OPTION_ENUM8	oBrightness,		.3,								.0,		tEco,			.23,	opt_brightness					; =0: Eco, =1:Medium, =2:Full
-	OPTION_UINT8	oDiveSalinity,		.0,				.4,				.0,		tPercent,		.24,	opt_salinity					; 0-4%
-	OPTION_ENUM8	oCCRMode,			.3,								.0,		tCCRModeFixedSP,.25,	opt_ccr_mode					; =0: Fixed SP, =1: Sensor, =2: Auto SP
-	OPTION_ENUM8	oLanguage,			.2,								.0,		tLang1,			.26,	opt_language					; language selection
-	OPTION_ENUM8	oDateFormat,		.3,								.1,		tDateformat,	.27,	opt_dateformat					; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD
-	OPTION_ENUM8	oUnits,				.2,								.0,		tMetric,		.28,	opt_units						; =0:Meter, =1:Feet
+	; Manage Deco Planer & Dive Parameters
+	OPTION_ENUM8    oDiveMode,           .5,                                       .0,      tDvOC,           0x01A,    0x20,  opt_dive_mode					; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR
+	OPTION_ENUM8    oDecoMode,           .2,                                       .1,      tZHL16,          0x01B,    0x21,  char_I_model					; 0 = ZH-L16, 1 = ZH-L16-GF
+	;                                                                                                        0x01C											; in use, see below
+	OPTION_UINT8d   oLastDeco,           .3,                   .6,                 .3,      tMeters,         0x01D,    0x2C,  opt_last_stop					; depth of the last deco stop
+	OPTION_UINT8    oGF_low,            .10,                 .100,                .30,      tPercent,        0x01E,    0x25,  opt_GF_low					; normal GF low
+	OPTION_UINT8    oGF_high,           .45,                 .110,                .85,      tPercent,        0x01F,    0x26,  opt_GF_high					; normal GF high
+	OPTION_UINT8p5  osatmultgf,        .100,                 .140,               .100,      tPercent,        0x020,    0x5E,  opt_sat_multiplier_gf			; saturation factor   for GF mode
+	OPTION_UINT8p5  odesatmultgf,       .60,                 .100,               .100,      tPercent,        0x021,    0x5F,  opt_desat_multiplier_gf		; desaturation factor for GF mode
+	;                                                                                                        0x022											; in use, see below
+	OPTION_UINT8    oaGF_low,           .10,                 .100,                .30,      tPercent,        0x023,    0x27,  opt_aGF_low					; alternative GF low
+	OPTION_UINT8    oaGF_high,          .45,                 .110,                .85,      tPercent,        0x024,    0x28,  opt_aGF_high					; alternative GF high
+	OPTION_BOOL     oEnable_aGF,         .0,                                                                 0x025,    0x29,  opt_enable_aGF				; =1: aGF can be selected underwater
+	OPTION_UINT8    oCompassGain,        .0,                   .7,                 .6,      tMinutes,        0x026,    0x34,  opt_compass_gain				; 0-7 (230 LSB/Gauss to 1370LSB/Gauss)
+	OPTION_ENUM8    oSamplingRate,       .2,                                       .0,      tSetSeconds,     0x027,    0x2F,  opt_sampling_rate				; =1: 10s, =0: 2s
 
-;=============================================================================
-; Compass calibration data
-	OPTION_UINT8	oCalx0,				.0,				.255,			.0,		notext,			.29,	compass_CX_f+0					; compass calibration data x, low  byte
-	OPTION_UINT8	oCalx1,				.0,				.255,			.0,		notext,			.30,	compass_CX_f+1					;                          x, high byte
-	OPTION_UINT8	oCaly0,				.0,				.255,			.0,		notext,			.31,	compass_CY_f+0					;                          y, low  byte
-	OPTION_UINT8	oCaly1,				.0,				.255,			.0,		notext,			.32,	compass_CY_f+1					;                          y, high byte
-	OPTION_UINT8	oCalz0,				.0,				.255,			.0,		notext,			.33,	compass_CZ_f+0					;                          z, low  byte
-	OPTION_UINT8	oCalz1,				.0,				.255,			.0,		notext,			.34,	compass_CZ_f+1					;                          z, high byte
+	; Managing Settings
+	OPTION_UINT8    oExtraTime,          .0,                   .9,                 .0,      tMinutes,        0x028,    0x24,  char_I_extra_time				; extra bottom time for future TTS calculation
+	OPTION_ENUM8    oBrightness,         .3,                                       .0,      tEco,            0x029,    0x2D,  opt_brightness				; =0: Eco, =1:Medium, =2:Full
+	OPTION_UINT8    oDiveSalinity,   salinity_min,      salinity_max,              .0,      tPercent,        0x02A,    0x30,  opt_salinity					; 0-4%
+	OPTION_ENUM8    oCCRMode,            .3,                                       .0,      tCCRModeFixedSP, 0x02B,    0x1F,  opt_ccr_mode					; =0: Fixed SP, =1: Sensor, =2: Auto SP
+	OPTION_ENUM8    oLanguage,           .2,                                       .0,      tLang1,          0x02C,    0x32,  opt_language					; language selection
+	OPTION_ENUM8    oDateFormat,         .3,                                       .1,      tDateformat,     0x02D,    0x33,  opt_dateformat				; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD
+	OPTION_ENUM8    oUnits,              .2,                                       .0,      tMetric,         0x02E,    0x2E,  opt_units						; =0:Meter, =1:Feet
+
+	; Compass calibration data
+	OPTION_UINT8    oCalx0,              .0,                 .255,                 .0,      nounit,          0x02F,  nocomm,  compass_CX_f+0				; compass calibration data x, low  byte
+	OPTION_UINT8    oCalx1,              .0,                 .255,                 .0,      nounit,          0x030,  nocomm,  compass_CX_f+1				;                          x, high byte
+	OPTION_UINT8    oCaly0,              .0,                 .255,                 .0,      nounit,          0x031,  nocomm,  compass_CY_f+0				;                          y, low  byte
+	OPTION_UINT8    oCaly1,              .0,                 .255,                 .0,      nounit,          0x032,  nocomm,  compass_CY_f+1				;                          y, high byte
+	OPTION_UINT8    oCalz0,              .0,                 .255,                 .0,      nounit,          0x033,  nocomm,  compass_CZ_f+0				;                          z, low  byte
+	OPTION_UINT8    oCalz1,              .0,                 .255,                 .0,      nounit,          0x034,  nocomm,  compass_CZ_f+1				;                          z, high byte
 
-;=============================================================================
-; Gas list
-	OPTION_ENUM8	oGas1,				.3,								.1,		tGasDisabled,	.35,	opt_gas_type+0					; gas type: 0=Disabled, 1=First, 2=Travel, 3=Deco
-	OPTION_ENUM8	oGas2,				.3,								.0,		tGasDisabled,	.36,	opt_gas_type+1
-	OPTION_ENUM8	oGas3,				.3,								.0,		tGasDisabled,	.37,	opt_gas_type+2
-	OPTION_ENUM8	oGas4,				.3,								.0,		tGasDisabled,	.38,	opt_gas_type+3
-	OPTION_ENUM8	oGas5,				.3,								.0,		tGasDisabled,	.39,	opt_gas_type+4
-	OPTION_UINT8	oGas1O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.40,	opt_gas_O2_ratio+0				; O2 % of gas 1
-	OPTION_UINT8	oGas1He,			.0,				gaslist_max_He,	.0,		tPercent,		.41,	opt_gas_He_ratio+0				; He % of gas 1 
-	OPTION_UINT8	oGas2O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.42,	opt_gas_O2_ratio+1
-	OPTION_UINT8	oGas2He,			.0,				gaslist_max_He,	.0,		tPercent,		.43,	opt_gas_He_ratio+1
-	OPTION_UINT8	oGas3O2,			gaslist_min_o2,		.100,		.21,	tPercent,		.44,	opt_gas_O2_ratio+2
-	OPTION_UINT8	oGas3He,			.0,				gaslist_max_He,	.0,		tPercent,		.45,	opt_gas_He_ratio+2
-	OPTION_UINT8	oGas4O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.46,	opt_gas_O2_ratio+3
-	OPTION_UINT8	oGas4He,			.0,				gaslist_max_He,	.0,		tPercent,		.47,	opt_gas_He_ratio+3
-	OPTION_UINT8	oGas5O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.48,	opt_gas_O2_ratio+4				; O2 % of gas 5
-	OPTION_UINT8	oGas5He,			.0,				gaslist_max_He,	.0,		tPercent,		.49,	opt_gas_He_ratio+4				; He % of gas 5
-	OPTION_UINT8d	oGas1Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.50,	opt_gas_change+0				; change depth of gas 1
-	OPTION_UINT8d	oGas2Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.51,	opt_gas_change+1
-	OPTION_UINT8d	oGas3Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.52,	opt_gas_change+2
-	OPTION_UINT8d	oGas4Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.53,	opt_gas_change+3
-	OPTION_UINT8d	oGas5Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.54,	opt_gas_change+4				; change depth of gas 5
-	OPTION_UINT8	oDil1O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.55,	opt_dil_O2_ratio+0				; O2 % of diluent 1
-	OPTION_UINT8	oDil1He,			.0,				gaslist_max_He,	.0,		tPercent,		.56,	opt_dil_He_ratio+0				; He % of diluent 1
-	OPTION_UINT8	oDil2O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.57,	opt_dil_O2_ratio+1
-	OPTION_UINT8	oDil2He,			.0,				gaslist_max_He,	.0,		tPercent,		.58,	opt_dil_He_ratio+1
-	OPTION_UINT8	oDil3O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.59,	opt_dil_O2_ratio+2
-	OPTION_UINT8	oDil3He,			.0,				gaslist_max_He,	.0,		tPercent,		.60,	opt_dil_He_ratio+2
-	OPTION_UINT8	oDil4O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.61,	opt_dil_O2_ratio+3
-	OPTION_UINT8	oDil4He,			.0,				gaslist_max_He,	.0,		tPercent,		.62,	opt_dil_He_ratio+3
-	OPTION_UINT8	oDil5O2,			gaslist_min_o2,	.100,			.21,	tPercent,		.63,	opt_dil_O2_ratio+4				; O2 % of diluent 5
-	OPTION_UINT8	oDil5He,			.0,				gaslist_max_He,	.0,		tPercent,		.64,	opt_dil_He_ratio+4				; He % of diluent 5
-	OPTION_UINT8	oSetPoint1,			gaslist_sp_min,	gaslist_sp_max,	.70,	tbar,			.65,	opt_setpoint_cbar+0				; ppO2 of setpoint 1
-	OPTION_UINT8	oSetPoint2,			gaslist_sp_min,	gaslist_sp_max,	.90,	tbar,			.66,	opt_setpoint_cbar+1				; ppO2 of setpoint 2
-	OPTION_UINT8	oSetPoint3,			gaslist_sp_min,	gaslist_sp_max,	.100,	tbar,			.67,	opt_setpoint_cbar+2				; ...
-	OPTION_UINT8	oSetPoint4,			gaslist_sp_min,	gaslist_sp_max,	.120,	tbar,			.68,	opt_setpoint_cbar+3				; ...
-	OPTION_UINT8	oSetPoint5,			gaslist_sp_min,	gaslist_sp_max,	.140,	tbar,			.69,	opt_setpoint_cbar+4				; ppO2 of setpoint 5
-	OPTION_UINT8d	oSP1Depth,			.0,				.100,			.0,		tMeters,		.70,	opt_setpoint_change+0			; change depth of setpoint 1 (forced to 0 in code)
-	OPTION_UINT8d	oSP2Depth,			.0,				.100,			.0,		tMeters,		.71,	opt_setpoint_change+1			; change depth of setpoint 2
-	OPTION_UINT8d	oSP3Depth,			.0,				.100,			.0,		tMeters,		.72,	opt_setpoint_change+2			; ...
-	OPTION_UINT8d	oSP4Depth,			.0,				.100,			.0,		tMeters,		.73,	opt_setpoint_change+3			; ...
-	OPTION_UINT8d	oSP5Depth,			.0,				.100,			.0,		tMeters,		.74,	opt_setpoint_change+4			; change depth of setpoint 5
-	OPTION_ENUM8	oDil1,				.2,								.1,		tDilDisabled,	.75,	opt_dil_type+0					; diluent type: 0=Disabled, 1=First, 2=Normal
-	OPTION_ENUM8	oDil2,				.2,								.0,		tDilDisabled,	.76,	opt_dil_type+1
-	OPTION_ENUM8	oDil3,				.2,								.0,		tDilDisabled,	.77,	opt_dil_type+2
-	OPTION_ENUM8	oDil4,				.2,								.0,		tDilDisabled,	.78,	opt_dil_type+3
-	OPTION_ENUM8	oDil5,				.2,								.0,		tDilDisabled,	.79,	opt_dil_type+4
-	OPTION_UINT8d	oDil1Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.80,	opt_dil_change+0				; change depth of diluent 1
-	OPTION_UINT8d	oDil2Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.81,	opt_dil_change+1
-	OPTION_UINT8d	oDil3Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.82,	opt_dil_change+2
-	OPTION_UINT8d	oDil4Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.83,	opt_dil_change+3
-	OPTION_UINT8d	oDil5Depth,			.0,	gaslist_max_change_depth,	.56,	tMeters,		.84,	opt_dil_change+4				; change depth of diluent 5
+	; Gas list
+	OPTION_ENUM8    oGas1,           num_gas_types,                                .1,      tGasDisabled,    0x035,  nocomm,  opt_gas_type+0				; gas type: 0=Disabled, 1=First, 2=Travel, 3=Deco
+	OPTION_ENUM8    oGas2,           num_gas_types,                                .0,      tGasDisabled,    0x036,  nocomm,  opt_gas_type+1
+	OPTION_ENUM8    oGas3,           num_gas_types,                                .0,      tGasDisabled,    0x037,  nocomm,  opt_gas_type+2
+	OPTION_ENUM8    oGas4,           num_gas_types,                                .0,      tGasDisabled,    0x038,  nocomm,  opt_gas_type+3
+	OPTION_ENUM8    oGas5,           num_gas_types,                                .0,      tGasDisabled,    0x039,  nocomm,  opt_gas_type+4
+	OPTION_UINT8    oGas1O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x03A,  nocomm,  opt_gas_O2_ratio+0			; O2 % of gas 1
+	OPTION_UINT8    oGas1He,             .0,            gaslist_max_He,            .0,      tPercent,        0x03B,  nocomm,  opt_gas_He_ratio+0			; He % of gas 1 
+	OPTION_UINT8    oGas2O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x03C,  nocomm,  opt_gas_O2_ratio+1
+	OPTION_UINT8    oGas2He,             .0,            gaslist_max_He,            .0,      tPercent,        0x03D,  nocomm,  opt_gas_He_ratio+1
+	OPTION_UINT8    oGas3O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x03E,  nocomm,  opt_gas_O2_ratio+2
+	OPTION_UINT8    oGas3He,             .0,            gaslist_max_He,            .0,      tPercent,        0x03F,  nocomm,  opt_gas_He_ratio+2
+	OPTION_UINT8    oGas4O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x040,  nocomm,  opt_gas_O2_ratio+3
+	OPTION_UINT8    oGas4He,             .0,            gaslist_max_He,            .0,      tPercent,        0x041,  nocomm,  opt_gas_He_ratio+3
+	OPTION_UINT8    oGas5O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x042,  nocomm,  opt_gas_O2_ratio+4			; O2 % of gas 5
+	OPTION_UINT8    oGas5He,             .0,            gaslist_max_He,            .0,      tPercent,        0x043,  nocomm,  opt_gas_He_ratio+4			; He % of gas 5
+	OPTION_UINT8d   oGas1Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x044,  nocomm,  opt_gas_change+0				; change depth of gas 1
+	OPTION_UINT8d   oGas2Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x045,  nocomm,  opt_gas_change+1
+	OPTION_UINT8d   oGas3Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x046,  nocomm,  opt_gas_change+2
+	OPTION_UINT8d   oGas4Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x047,  nocomm,  opt_gas_change+3
+	OPTION_UINT8d   oGas5Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x048,  nocomm,  opt_gas_change+4				; change depth of gas 5
+	OPTION_UINT8    oDil1O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x049,  nocomm,  opt_dil_O2_ratio+0			; O2 % of diluent 1
+	OPTION_UINT8    oDil1He,             .0,            gaslist_max_He,            .0,      tPercent,        0x04A,  nocomm,  opt_dil_He_ratio+0			; He % of diluent 1
+	OPTION_UINT8    oDil2O2,         gaslist_min_o2,         .100,                .21,      tPercent,        0x04B,  nocomm,  opt_dil_O2_ratio+1
+	OPTION_UINT8    oDil2He,             .0,            gaslist_max_He,            .0,      tPercent,        0x04C,  nocomm,  opt_dil_He_ratio+1
+	OPTION_UINT8    oDil3O2,         gaslist_min_o2,         .100,                .21,      tPercent,        0x04D,  nocomm,  opt_dil_O2_ratio+2
+	OPTION_UINT8    oDil3He,             .0,            gaslist_max_He,            .0,      tPercent,        0x04E,  nocomm,  opt_dil_He_ratio+2
+	OPTION_UINT8    oDil4O2,         gaslist_min_o2,         .100,                .21,      tPercent,        0x04F,  nocomm,  opt_dil_O2_ratio+3
+	OPTION_UINT8    oDil4He,             .0,            gaslist_max_He,            .0,      tPercent,        0x050,  nocomm,  opt_dil_He_ratio+3
+	OPTION_UINT8    oDil5O2,         gaslist_min_o2,         .100,                .21,      tPercent,        0x051,  nocomm,  opt_dil_O2_ratio+4			; O2 % of diluent 5
+	OPTION_UINT8    oDil5He,             .0,            gaslist_max_He,            .0,      tPercent,        0x052,  nocomm,  opt_dil_He_ratio+4			; He % of diluent 5
+	OPTION_UINT8    oSetPoint1,      gaslist_sp_min,    gaslist_sp_max,           .70,      tbar,            0x053,  nocomm,  opt_setpoint_cbar+0			; ppO2 of setpoint 1
+	OPTION_UINT8    oSetPoint2,      gaslist_sp_min,    gaslist_sp_max,           .90,      tbar,            0x054,  nocomm,  opt_setpoint_cbar+1			; ppO2 of setpoint 2
+	OPTION_UINT8    oSetPoint3,      gaslist_sp_min,    gaslist_sp_max,          .100,      tbar,            0x055,  nocomm,  opt_setpoint_cbar+2			; ...
+	OPTION_UINT8    oSetPoint4,      gaslist_sp_min,    gaslist_sp_max,          .120,      tbar,            0x056,  nocomm,  opt_setpoint_cbar+3			; ...
+	OPTION_UINT8    oSetPoint5,      gaslist_sp_min,    gaslist_sp_max,          .140,      tbar,            0x057,  nocomm,  opt_setpoint_cbar+4			; ppO2 of setpoint 5
+	OPTION_UINT8d   oSP1Depth,           .0,            sp_max_change_depth,       .0,      tMeters,         0x058,  nocomm,  opt_setpoint_change+0			; change depth of setpoint 1 (forced to 0 in code)
+	OPTION_UINT8d   oSP2Depth,           .0,            sp_max_change_depth,       .0,      tMeters,         0x059,  nocomm,  opt_setpoint_change+1			; change depth of setpoint 2
+	OPTION_UINT8d   oSP3Depth,           .0,            sp_max_change_depth,       .0,      tMeters,         0x05A,  nocomm,  opt_setpoint_change+2			; ...
+	OPTION_UINT8d   oSP4Depth,           .0,            sp_max_change_depth,       .0,      tMeters,         0x05B,  nocomm,  opt_setpoint_change+3			; ...
+	OPTION_UINT8d   oSP5Depth,           .0,            sp_max_change_depth,       .0,      tMeters,         0x05C,  nocomm,  opt_setpoint_change+4			; change depth of setpoint 5
+	OPTION_ENUM8    oDil1,           num_dil_types,                                .1,      tDilDisabled,    0x05D,  nocomm,  opt_dil_type+0				; diluent type: 0=Disabled, 1=First, 2=Normal
+	OPTION_ENUM8    oDil2,           num_dil_types,                                .0,      tDilDisabled,    0x05E,  nocomm,  opt_dil_type+1
+	OPTION_ENUM8    oDil3,           num_dil_types,                                .0,      tDilDisabled,    0x05F,  nocomm,  opt_dil_type+2
+	OPTION_ENUM8    oDil4,           num_dil_types,                                .0,      tDilDisabled,    0x060,  nocomm,  opt_dil_type+3
+	OPTION_ENUM8    oDil5,           num_dil_types,                                .0,      tDilDisabled,    0x061,  nocomm,  opt_dil_type+4
+	OPTION_UINT8d   oDil1Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x062,  nocomm,  opt_dil_change+0				; change depth of diluent 1
+	OPTION_UINT8d   oDil2Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x063,  nocomm,  opt_dil_change+1
+	OPTION_UINT8d   oDil3Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x064,  nocomm,  opt_dil_change+2
+	OPTION_UINT8d   oDil4Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x065,  nocomm,  opt_dil_change+3
+	OPTION_UINT8d   oDil5Depth,          .0,            gaslist_max_change_depth, .56,      tMeters,         0x066,  nocomm,  opt_dil_change+4				; change depth of diluent 5
 
-;=============================================================================
-; opt_name from 85 to 145
-	OPTION_STRING	oName,				opt_name_length,						tDefName,		.85,	opt_name
+	; opt_name from 85 to 145
+	OPTION_STRING    oName,          opt_name_length,                                       tDefName,        0x067,  nocomm,  opt_name						; custom text on surface screen
 
-;=============================================================================
-; Misc
-	OPTION_ENUM8	oColorSetDive,		.4,								.0,		tColorSetName0,	.146,	opt_dive_color_scheme			; color scheme dive mode
-	OPTION_UINT8	oPressureAdjust,	.0,				.255,			.0,		notext,			.147,	opt_pressure_adjust				; pressure sensor correction, SIGNED int (clipped to -20/+20 mbar in code)
-	OPTION_BOOL		oSafetyStop,										.0,						.148,	opt_enable_safetystop			; =1: show safety stops
-	OPTION_UINT8	oCalGasO2,			.21,			.100,			.21,	tPercent,		.149,	opt_calibration_O2_ratio		; calibration gas %O2 (do not move in EEPROM, must stay at .149!)
-	OPTION_BOOL		oFlipScreen,										.0,						.151,	opt_flip_screen					; =1: flip the screen
-	OPTION_UINT8p10	ocR_button_left,	.20,			.80,			.40,	tPercent,		.152,	opt_cR_button_left				; left  button sensitivity
-	OPTION_UINT8p10	ocR_button_right,	.20,			.80,			.40,	tPercent,		.153,	opt_cR_button_right				; right button sensitivity
-	OPTION_UINT8	obottom_usage,		.5,				.50,			.20,	tLitersMinute,	.154,	char_I_SAC_work					; surface air consumption rate during working    phase, l/min
-	OPTION_UINT8	odeco_usage,		.5,				.50,			.20,	tLitersMinute,	.155,	char_I_SAC_deco					; surface air consumption rate during deco stops phase, l/min
-	OPTION_BOOL		oMODwarning,										.1,						.156,	opt_modwarning					; =1: blink on depth related attentions and warnings
-	OPTION_BOOL		oVSItextv2,											.0,						.157,	opt_vsitextv2					; =1: use the dynamic (depends on depth) ascend rate limits
-	OPTION_BOOL		oVSIgraph,											.1,						.158,	opt_vsigraph					; =1: draw the graphical VSI bar
-	OPTION_BOOL		oShowppO2,											.0,						.159,	opt_showppo2					; =1:always show the ppO2 value in the warning position
-	OPTION_UINT8	oTemperatureAdjust,	.0,				.255,			.0,		notext,			.160,	opt_temperature_adjust			; temperature sensor correction, SIGNED int (clipped to -2.0/+2.0 °C in code)
-	OPTION_UINT8	oSafetyStopLength,	.60,			.240,			.180,	notext,			.161,	opt_safety_stop_length			; [s], duration of the safety stop
-	OPTION_UINT8	oSafetyStopStart,	.21,			.61,			.51,	notext,			.162,	opt_safety_stop_start			; [cbar], depth at which safety stop appears,           default 510mbar, min 210mbar, max 610mbar
-	OPTION_UINT8	oSafetyStopEnd,		.19,			.39,			.29,	notext,			.163,	opt_safety_stop_end				; [cbar], depth at which safety stop disappears,        default 290mbar, min 190mbar, max 390mbar
-	OPTION_UINT8	oSafetyStopReset,	.81,			.151,			.101,	notext,			.164,	opt_safety_stop_reset			; [cbar], depth at which safety stop timer is reloaded, default 1010mbar, min 810mbar, max 1510mbar
-	OPTION_UINT8	oDiveTimeout,		.1,				.20,			.5,		tMinutes,		.168,	opt_diveTimeout					; [minutes] timeout for switch from dive mode to surface mode
-	OPTION_UINT8	oPSCR_drop,			.0,				.15,			.4,		tPercent,		.169,	char_I_PSCR_drop				; pSCR drop [%]
-	OPTION_UINT8	oPSCR_lungratio,	.5,				.20,			.10,	tPercent,		.170,	char_I_PSCR_lungratio			; pSCR lung ratio [1/x]
-;																								.171									; in use, see below
-;																								.172									; in use, see below
-	OPTION_UINT8	oTankSize1,			min_tank_size,	max_tank_size,	.11,	tLiter,			.173,	char_I_gas_avail_size+0			; size of OC gas tank 1, in liters
-	OPTION_UINT8	oTankSize2,			min_tank_size,	max_tank_size,	.11,	tLiter,			.174,	char_I_gas_avail_size+1			; size of OC gas tank 2, in liters
-	OPTION_UINT8	oTankSize3,			min_tank_size,	max_tank_size,	.11,	tLiter,			.175,	char_I_gas_avail_size+2			; size of OC gas tank 3, in liters
-	OPTION_UINT8	oTankSize4,			min_tank_size,	max_tank_size,	.11,	tLiter,			.176,	char_I_gas_avail_size+3			; size of OC gas tank 4, in liters
-	OPTION_UINT8	oTankSize5,			min_tank_size,	max_tank_size,	.11,	tLiter,			.177,	char_I_gas_avail_size+4			; size of OC gas tank 5, in liters
-	OPTION_UINT8	oTankFillPres1,		min_fill_press,	max_fill_press,	.20,	tbar10,			.178,	char_I_gas_avail_pres+0			; available press of OC gas tank 1, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres2,		min_fill_press,	max_fill_press,	.20,	tbar10,			.179,	char_I_gas_avail_pres+1			; available press of OC gas tank 2, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres3,		min_fill_press,	max_fill_press,	.20,	tbar10,			.180,	char_I_gas_avail_pres+2			; available press of OC gas tank 3, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres4,		min_fill_press,	max_fill_press,	.20,	tbar10,			.181,	char_I_gas_avail_pres+3			; available press of OC gas tank 4, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres5,		min_fill_press,	max_fill_press,	.20,	tbar10,			.182,	char_I_gas_avail_pres+4			; available press of OC gas tank 5, in multiples of 10 bars
-	OPTION_UINT8	oCCmaxFracO2,		.80,			.100,			.90,	tPercent,		.183,	char_I_CC_max_frac_O2			; max. O2 % in Loop
-	OPTION_UINT8	oSimSetpoint,		.1,				.5,				.1,		tblank,			.184,	opt_sim_setpoint_number			; setpoint to use for deco calculation
-	OPTION_ENUM8	oCalcAscGas,		calc_gas_options,				.0,		tNo,			.185,	opt_calc_asc_gasvolume			; calculate OC gas volume needs for ascent: no, yes, cave
-	OPTION_ENUM8	oAltMode,			.4,								.0,		tAltModeFly,	.186,	char_I_altitude_wait			; no-fly time calculation for: 0=no-fly, 1=1000m, 2=2000m, 3=3000m
-	OPTION_BOOL		oEnable_IBCD,										.1,						.187,	opt_enable_IBCD					; =1: IBCD warning activated
-	OPTION_UINT8	oAscentSpeed,		.5,				.10,			.10,	tMeterMinute,	.188,	char_I_ascent_speed				; [meter/minute] ascent speed
-	OPTION_UINT8	oGasChangeTime,		.0,				.3,				.0,		tMinutes,		.189,	char_I_gas_change_time			; (extra) time at a stop to change the gas
-	OPTION_UINT8p5	osatmult,			.100,			.140,			.110,	tPercent,		.190,	opt_sat_multiplier_non_gf		; saturation   factor for NON-GF Mode
-	OPTION_UINT8p5	odesatmult,			.60,			.100,			.90,	tPercent,		.191,	opt_desat_multiplier_non_gf		; desaturation factor for NON-GF Mode
-	OPTION_UINT8	oTransID1_0,		.0,				.255,			.0,		notext,			.192,	opt_transmitter_id_1+0			; ID of transmitter for gas 1 (LOW)
-	OPTION_UINT8	oTransID1_1,		.0,				.255,			.0,		notext,			.193,	opt_transmitter_id_1+1			; ID of transmitter for gas 1 (HIGH)
-	OPTION_UINT8	oTransID2_0,		.0,				.255,			.0,		notext,			.194,	opt_transmitter_id_2+0			; ID of transmitter for gas 2 (LOW)
-	OPTION_UINT8	oTransID2_1,		.0,				.255,			.0,		notext,			.195,	opt_transmitter_id_2+1			; ID of transmitter for gas 2 (HIGH)
-	OPTION_UINT8	oTransID3_0,		.0,				.255,			.0,		notext,			.196,	opt_transmitter_id_3+0			; ID of transmitter for gas 3 (LOW)
-	OPTION_UINT8	oTransID3_1,		.0,				.255,			.0,		notext,			.197,	opt_transmitter_id_3+1			; ID of transmitter for gas 3 (HIGH)
-	OPTION_UINT8	oTransID4_0,		.0,				.255,			.0,		notext,			.198,	opt_transmitter_id_4+0			; ID of transmitter for gas 4 (LOW)
-	OPTION_UINT8	oTransID4_1,		.0,				.255,			.0,		notext,			.199,	opt_transmitter_id_4+1			; ID of transmitter for gas 4 (HIGH)
-	OPTION_UINT8	oTransID5_0,		.0,				.255,			.0,		notext,			.200,	opt_transmitter_id_5+0			; ID of transmitter for gas 5 (LOW)
-	OPTION_UINT8	oTransID5_1,		.0,				.255,			.0,		notext,			.201,	opt_transmitter_id_5+1			; ID of transmitter for gas 5 (HIGH)
-	OPTION_UINT8	oTransID6_0,		.0,				.255,			.0,		notext,			.202,	opt_transmitter_id_6+0			; ID of transmitter for dil 1 (LOW)
-	OPTION_UINT8	oTransID6_1,		.0,				.255,			.0,		notext,			.203,	opt_transmitter_id_6+1			; ID of transmitter for dil 1 (HIGH)
-	OPTION_UINT8	oTransID7_0,		.0,				.255,			.0,		notext,			.204,	opt_transmitter_id_7+0			; ID of transmitter for dil 2 (LOW)
-	OPTION_UINT8	oTransID7_1,		.0,				.255,			.0,		notext,			.205,	opt_transmitter_id_7+1			; ID of transmitter for dil 2 (HIGH)
-	OPTION_UINT8	oTransID8_0,		.0,				.255,			.0,		notext,			.206,	opt_transmitter_id_8+0			; ID of transmitter for dil 3 (LOW)
-	OPTION_UINT8	oTransID8_1,		.0,				.255,			.0,		notext,			.207,	opt_transmitter_id_8+1			; ID of transmitter for dil 3 (HIGH)
-	OPTION_UINT8	oTransID9_0,		.0,				.255,			.0,		notext,			.208,	opt_transmitter_id_9+0			; ID of transmitter for dil 4 (LOW)
-	OPTION_UINT8	oTransID9_1,		.0,				.255,			.0,		notext,			.209,	opt_transmitter_id_9+1			; ID of transmitter for dil 4 (HIGH)
-	OPTION_UINT8	oTransID10_0,		.0,				.255,			.0,		notext,			.210,	opt_transmitter_id_10+0			; ID of transmitter for dil 5 (LOW)
-	OPTION_UINT8	oTransID10_1,		.0,				.255,			.0,		notext,			.211,	opt_transmitter_id_10+1			; ID of transmitter for dil 5 (HIGH)
-	OPTION_UINT8	oTankSize6,			min_tank_size,	max_tank_size,	.11,	tLiter,			.212,	char_I_gas_avail_size+5			; size of DIL gas tank 1, in liters
-	OPTION_UINT8	oTankSize7,			min_tank_size,	max_tank_size,	.11,	tLiter,			.213,	char_I_gas_avail_size+6			; size of DIL gas tank 2, in liters
-	OPTION_UINT8	oTankSize8,			min_tank_size,	max_tank_size,	.11,	tLiter,			.214,	char_I_gas_avail_size+7			; size of DIL gas tank 3, in liters
-	OPTION_UINT8	oTankSize9,			min_tank_size,	max_tank_size,	.11,	tLiter,			.215,	char_I_gas_avail_size+8			; size of DIL gas tank 4, in liters
-	OPTION_UINT8	oTankSize10,		min_tank_size,	max_tank_size,	.11,	tLiter,			.216,	char_I_gas_avail_size+9			; size of DIL gas tank 5, in liters
-	OPTION_UINT8	oTankFillPres6,		min_fill_press,	max_fill_press,	.20,	tbar10,			.217,	char_I_gas_avail_pres+5			; available press of DIL gas tank 1, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres7,		min_fill_press,	max_fill_press,	.20,	tbar10,			.218,	char_I_gas_avail_pres+6			; available press of DIL gas tank 2, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres8,		min_fill_press,	max_fill_press,	.20,	tbar10,			.219,	char_I_gas_avail_pres+7			; available press of DIL gas tank 3, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres9,		min_fill_press,	max_fill_press,	.20,	tbar10,			.220,	char_I_gas_avail_pres+8			; available press of DIL gas tank 4, in multiples of 10 bars
-	OPTION_UINT8	oTankFillPres10,	min_fill_press,	max_fill_press,	.20,	tbar10,			.221,	char_I_gas_avail_pres+9			; available press of DIL gas tank 5, in multiples of 10 bars
-	OPTION_ENUM8	oTrMode,			.4,								.1,		tTrModeOff,		.222,	opt_TR_mode						; TR functions - mode
-	OPTION_ENUM8	oTr1stPres,			tr_pres_options,				.1,		tTrPresNone,	.223,	opt_TR_1st_pres					; TR functions - 1st pressure assignment
-	OPTION_ENUM8	oTr2ndPres,			tr_pres_options,				.0,		tTrPresNone,	.224,	opt_TR_2nd_pres					; TR functions - 2nd pressure assignment
-	OPTION_ENUM8	oTrBailPres,		tr_pres_options,				.1,		tTrPresNone,	.225,	opt_TR_Bail_pres				; TR functions - bailout pressure assignment
-	OPTION_UINT8p5	oTrMaxDeltaPres,	max_pres_diff_min,max_pres_diff_max,.5,	tbar,			.226,	char_I_max_pres_diff			; TR functions - maximum delta pressure in independent double mode
-	;																							.227									; spare / unused
-	;																							.228									; spare / unused
-	OPTION_ENUM8	o2ndDepthDisp,		.2,								.0,		tMaxDepth,		.229,	opt_2ndDepthDisp				; =1: show average depth instead of max depth
-	OPTION_UINT8d	oMaxDepth,			.5,	ostc_depth_max,	ostc_depth_max,		tMeters,		.230,	opt_max_depth					; depth at which a warning will be given
-	OPTION_UINT8	oDescentSpeed,		.5,				.30,			.10,	tMeterMinute,	.231,	char_I_descent_speed			; descent speed for deco calculator          [future option, not used yet]
-	OPTION_BOOL		oStoreApnoeDive,									.0,						.232,	opt_store_apnoe_dive			; =1: store dives in apnoe mode into logbook
-	OPTION_ENUM8	oTissueGraphics,	tissue_graphics_options,		.0,		tTissuePresSat,	.233,	opt_tissue_graphics 			; =0: show N2 and He pressures, =1: show pressures and saturations
-	OPTION_ENUM8	oLayout,			.2,								.0,		tLayoutNormal,	.234,	opt_layout						; initial layout of dive mode screen =0: normal, =1: big
-	OPTION_BOOL		oExtendedStops,										.1,						.235,	opt_extended_stops				; =1: place gas switches also below 1st stop depth
-	OPTION_UINT8	oGasDensityAttention,.40,			.80,			.60,	notext,			.236,	char_I_gas_density_att			; threshold for gas density attention [0.1 grams/l]
-	OPTION_UINT8	oGasDensityWarning,	.40,			.80,			.65,	notext,			.237,	char_I_gas_density_warn			; threshold for gas density warning   [0.1 grams/l]
-	OPTION_BOOL		oDilppO2Check,										.1,						.238,	char_I_dil_ppO2_check			; =1: check ppO2 of the pure diluent against current setpoint
+	; Misc
+	OPTION_ENUM8    oColorSetDive,       .4,                                       .0,      tColorSetName0,  0x0A4,    0x31,  opt_dive_color_scheme			; color scheme dive mode
+	OPTION_UINT8    oPressureAdjust,     .0,                 .255,                 .0,      nounit,          0x0A5,    0x35,  opt_pressure_adjust			; pressure sensor correction, SIGNED int (clipped to -20/+20 mbar in code)
+	OPTION_BOOL     oSafetyStop,                                                   .0,                       0x0A6,    0x36,  opt_safetystop				; =1: show safety stops
+	OPTION_UINT8    oCalGasO2,          .21,                 .100,                .21,      tPercent,        0x0A7,    0x37,  opt_calibration_O2_ratio		; calibration gas %O2 (do not move in EEPROM, must stay at .149!)
+	;                                                                                                        0x0A8											; not used any more (ex opt_sensor_fallback)
+	OPTION_BOOL     oFlipScreen,                                                   .0,                       0x0A9,    0x39,  opt_flip_screen				; =1: flip the screen
+	OPTION_UINT8p10 ocR_button_left,    .20,                  .80,                .40,      tPercent,        0x0AA,    0x3A,  opt_cR_button_left			; left  button sensitivity
+	OPTION_UINT8p10 ocR_button_right,   .20,                  .80,                .40,      tPercent,        0x0AB,    0x3B,  opt_cR_button_right			; right button sensitivity
+	OPTION_UINT8    oWork_SAC,           .5,                  .50,                .20,      tLitersMinute,   0x0AC,    0x3C,  char_I_SAC_work				; surface air consumption rate during working    phase, l/min
+	OPTION_UINT8    oDeco_SAC,           .5,                  .50,                .20,      tLitersMinute,   0x0AD,    0x3D,  char_I_SAC_deco				; surface air consumption rate during deco stops phase, l/min
+	OPTION_BOOL     oDepthWarn,                                                    .1,                       0x0AE,    0x3E,  opt_depth_warn				; =1: blink on depth related attentions and warnings
+	OPTION_BOOL     oVSItext,                                                      .0,                       0x0AF,    0x3F,  opt_vsitext					; =1: use the dynamic (depends on depth) ascend rate limits
+	OPTION_BOOL     oVSIgraph,                                                     .1,                       0x0B0,    0x40,  opt_vsigraph					; =1: draw the graphical VSI bar
+	OPTION_BOOL     oShowppO2,                                                     .0,                       0x0B1,    0x41,  opt_showppo2					; =1: always show the ppO2 value in the warning position
+	OPTION_UINT8    oTempAdjust,         .0,                 .255,                 .0,      nounit,          0x0B2,    0x42,  opt_temperature_adjust		; temperature sensor correction, SIGNED int (clipped to -2.0/+2.0 °C in code)
+	OPTION_UINT8    oSafetyStopLength,  .60,                 .240,               .180,      nounit,          0x0B3,    0x43,  opt_safety_stop_length		; [s], duration of the safety stop
+	OPTION_UINT8    oSafetyStopStart,   .21,                  .61,                .51,      nounit,          0x0B4,    0x44,  opt_safety_stop_start			; [dm], depth at which safety stop appears,    default   51 dm, min 210 dm, max  610 dm
+	OPTION_UINT8    oSafetyStopEnd,     .19,                  .39,                .29,      nounit,          0x0B5,    0x45,  opt_safety_stop_end			; [dm], depth at which safety stop disappears, default  290 dm, min 190 dm, max  390 dm
+	OPTION_UINT8    oSafetyStopReset,   .81,                 .151,               .101,      nounit,          0x0B6,    0x46,  opt_safety_stop_reset			; [dm], depth at which safety stop re-arms,    default 1010 dm, min 810 dm, max 1510 dm
+	;                                                                                                    0x0B7 - 0x0B9										; unused
+	OPTION_UINT8    oDiveTimeout,        .1,                  .20,                 .5,      tMinutes,        0x0BA,    0x48,  opt_diveTimeout				; [minutes] timeout for switch from dive mode to surface mode
+	OPTION_UINT8    oPSCR_drop,          .0,                  .15,                 .4,      tPercent,        0x0BB,    0x4A,  char_I_PSCR_drop				; pSCR drop [%]
+	OPTION_UINT8    oPSCR_lungratio,     .5,                  .20,                .10,      tPercent,        0x0BC,    0x4B,  char_I_PSCR_lungratio			; pSCR lung ratio [1/x]
+	;                                                                                                        0x0BD											; in use, see below
+	;                                                                                                        0x0BE											; in use, see below
+	OPTION_UINT8    oTankSize1,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0BF,    0x4E,  char_I_gas_avail_size+0		; size of OC gas tank 1, in liters
+	OPTION_UINT8    oTankSize2,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0C0,    0x4F,  char_I_gas_avail_size+1		; size of OC gas tank 2, in liters
+	OPTION_UINT8    oTankSize3,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0C1,    0x50,  char_I_gas_avail_size+2		; size of OC gas tank 3, in liters
+	OPTION_UINT8    oTankSize4,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0C2,    0x51,  char_I_gas_avail_size+3		; size of OC gas tank 4, in liters
+	OPTION_UINT8    oTankSize5,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0C3,    0x52,  char_I_gas_avail_size+4		; size of OC gas tank 5, in liters
+	OPTION_UINT8    oTankFillPres1,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0C4,    0x53,  char_I_gas_avail_pres+0		; available press of OC gas tank 1, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres2,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0C5,    0x54,  char_I_gas_avail_pres+1		; available press of OC gas tank 2, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres3,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0C6,    0x55,  char_I_gas_avail_pres+2		; available press of OC gas tank 3, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres4,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0C7,    0x56,  char_I_gas_avail_pres+3		; available press of OC gas tank 4, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres5,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0C8,    0x57,  char_I_gas_avail_pres+4		; available press of OC gas tank 5, in multiples of 10 bars
+	OPTION_UINT8    oCCmaxFracO2,       .80,                .100,                 .90,      tPercent,        0x0C9,    0x58,  char_I_CC_max_frac_O2			; max. O2 % in Loop
+	OPTION_UINT8    oSimSetpoint,        .1,                  .5,                  .1,      tblank,          0x0CA,    0x59,  opt_sim_setpoint_number		; setpoint to use for deco calculation
+	OPTION_BOOL     oCalcAscGas,                                                   .0,                       0x0CB,    0x5A,  opt_calc_gasvolume			; calculate OC gas volume needs for ascent
+	OPTION_ENUM8    oAltMode,            .4,                                       .0,      tAltModeFly,     0x0CC,    0x5C,  char_I_altitude_wait			; no-fly time calculation for: 0=no-fly, 1=1000m, 2=2000m, 3=3000m
+	OPTION_BOOL     oEnable_IBCD,                                                  .1,                       0x0CD,    0x5D,  opt_enable_IBCD				; =1: IBCD warning activated
+	;                                                                                                        0x0CE											; not used any more (ex ascent speed)
+	OPTION_UINT8    oGasChangeTime,      .0,                   .3,                 .0,      tMinutes,        0x0CF,    0x5B,  char_I_gas_change_time		; (extra) time at a stop to change the gas
+	OPTION_UINT8p5  osatmult,          .100,                 .140,               .110,      tPercent,        0x0D0,    0x2A,  opt_sat_multiplier_non_gf		; saturation   factor for NON-GF Mode
+	OPTION_UINT8p5  odesatmult,         .60,                 .100,                .90,      tPercent,        0x0D1,    0x2B,  opt_desat_multiplier_non_gf	; desaturation factor for NON-GF Mode
+	OPTION_UINT8    oTransID1_0,         .0,                 .255,                 .0,      nounit,          0x0D2,    0x60,  opt_transmitter_id_1+0		; ID of transmitter for gas 1 (LOW)
+	OPTION_UINT8    oTransID1_1,         .0,                 .255,                 .0,      nounit,          0x0D3,    0x61,  opt_transmitter_id_1+1		; ID of transmitter for gas 1 (HIGH)
+	OPTION_UINT8    oTransID2_0,         .0,                 .255,                 .0,      nounit,          0x0D4,    0x62,  opt_transmitter_id_2+0		; ID of transmitter for gas 2 (LOW)
+	OPTION_UINT8    oTransID2_1,         .0,                 .255,                 .0,      nounit,          0x0D5,    0x63,  opt_transmitter_id_2+1		; ID of transmitter for gas 2 (HIGH)
+	OPTION_UINT8    oTransID3_0,         .0,                 .255,                 .0,      nounit,          0x0D6,    0x64,  opt_transmitter_id_3+0		; ID of transmitter for gas 3 (LOW)
+	OPTION_UINT8    oTransID3_1,         .0,                 .255,                 .0,      nounit,          0x0D7,    0x65,  opt_transmitter_id_3+1		; ID of transmitter for gas 3 (HIGH)
+	OPTION_UINT8    oTransID4_0,         .0,                 .255,                 .0,      nounit,          0x0D8,    0x66,  opt_transmitter_id_4+0		; ID of transmitter for gas 4 (LOW)
+	OPTION_UINT8    oTransID4_1,         .0,                 .255,                 .0,      nounit,          0x0D9,    0x67,  opt_transmitter_id_4+1		; ID of transmitter for gas 4 (HIGH)
+	OPTION_UINT8    oTransID5_0,         .0,                 .255,                 .0,      nounit,          0x0DA,    0x68,  opt_transmitter_id_5+0		; ID of transmitter for gas 5 (LOW)
+	OPTION_UINT8    oTransID5_1,         .0,                 .255,                 .0,      nounit,          0x0DB,    0x69,  opt_transmitter_id_5+1		; ID of transmitter for gas 5 (HIGH)
+	OPTION_UINT8    oTransID6_0,         .0,                 .255,                 .0,      nounit,          0x0DC,    0x6A,  opt_transmitter_id_6+0		; ID of transmitter for dil 1 (LOW)
+	OPTION_UINT8    oTransID6_1,         .0,                 .255,                 .0,      nounit,          0x0DD,    0x6B,  opt_transmitter_id_6+1		; ID of transmitter for dil 1 (HIGH)
+	OPTION_UINT8    oTransID7_0,         .0,                 .255,                 .0,      nounit,          0x0DE,    0x6C,  opt_transmitter_id_7+0		; ID of transmitter for dil 2 (LOW)
+	OPTION_UINT8    oTransID7_1,         .0,                 .255,                 .0,      nounit,          0x0DF,    0x6D,  opt_transmitter_id_7+1		; ID of transmitter for dil 2 (HIGH)
+	OPTION_UINT8    oTransID8_0,         .0,                 .255,                 .0,      nounit,          0x0E0,    0x6E,  opt_transmitter_id_8+0		; ID of transmitter for dil 3 (LOW)
+	OPTION_UINT8    oTransID8_1,         .0,                 .255,                 .0,      nounit,          0x0E1,    0x6F,  opt_transmitter_id_8+1		; ID of transmitter for dil 3 (HIGH)
+	OPTION_UINT8    oTransID9_0,         .0,                 .255,                 .0,      nounit,          0x0E2,    0x70,  opt_transmitter_id_9+0		; ID of transmitter for dil 4 (LOW)
+	OPTION_UINT8    oTransID9_1,         .0,                 .255,                 .0,      nounit,          0x0E3,    0x71,  opt_transmitter_id_9+1		; ID of transmitter for dil 4 (HIGH)
+	OPTION_UINT8    oTransID10_0,        .0,                 .255,                 .0,      nounit,          0x0E4,    0x72,  opt_transmitter_id_10+0		; ID of transmitter for dil 5 (LOW)
+	OPTION_UINT8    oTransID10_1,        .0,                 .255,                 .0,      nounit,          0x0E5,    0x73,  opt_transmitter_id_10+1		; ID of transmitter for dil 5 (HIGH)
+	OPTION_UINT8    oTankSize6,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0E6,    0x74,  char_I_gas_avail_size+5		; size of DIL gas tank 1, in liters
+	OPTION_UINT8    oTankSize7,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0E7,    0x75,  char_I_gas_avail_size+6		; size of DIL gas tank 2, in liters
+	OPTION_UINT8    oTankSize8,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0E8,    0x76,  char_I_gas_avail_size+7		; size of DIL gas tank 3, in liters
+	OPTION_UINT8    oTankSize9,      min_tank_size,     max_tank_size,            .11,      tLiter,          0x0E9,    0x77,  char_I_gas_avail_size+8		; size of DIL gas tank 4, in liters
+	OPTION_UINT8    oTankSize10,     min_tank_size,     max_tank_size,            .11,      tLiter,          0x0EA,    0x78,  char_I_gas_avail_size+9		; size of DIL gas tank 5, in liters
+	OPTION_UINT8    oTankFillPres6,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0EB,    0x79,  char_I_gas_avail_pres+5		; available press of DIL gas tank 1, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres7,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0EC,    0x7A,  char_I_gas_avail_pres+6		; available press of DIL gas tank 2, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres8,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0ED,    0x7B,  char_I_gas_avail_pres+7		; available press of DIL gas tank 3, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres9,  min_fill_press,    max_fill_press,           .20,      tbar10,          0x0EE,    0x7C,  char_I_gas_avail_pres+8		; available press of DIL gas tank 4, in multiples of 10 bars
+	OPTION_UINT8    oTankFillPres10, min_fill_press,    max_fill_press,           .20,      tbar10,          0x0EF,    0x7D,  char_I_gas_avail_pres+9		; available press of DIL gas tank 5, in multiples of 10 bars
+	OPTION_ENUM8    oTrMode,             .4,                                       .1,      tTrModeOff,      0x0F0,    0x7E,  opt_TR_mode					; TR functions - mode
+	OPTION_ENUM8    oTr1stPres,      tr_pres_options,                              .1,      tTrPresNone,     0x0F1,    0x7F,  opt_TR_1st_pres				; TR functions - 1st pressure assignment
+	OPTION_ENUM8    oTr2ndPres,      tr_pres_options,                              .0,      tTrPresNone,     0x0F2,    0x80,  opt_TR_2nd_pres				; TR functions - 2nd pressure assignment
+	OPTION_ENUM8    oTrBailPres,     tr_pres_options,                              .1,      tTrPresNone,     0x0F3,    0x81,  opt_TR_Bail_pres				; TR functions - bailout pressure assignment
+	OPTION_UINT8p5  oTrMaxDeltaPres, max_pres_diff_min, max_pres_diff_max,         .5,      tbar,            0x0F4,    0x82,  char_I_max_pres_diff			; TR functions - maximum delta pressure in independent double mode
+	;                                                                                                        0x0F5											; not used
+	;                                                                                                        0x0F6											; not used
+	OPTION_ENUM8    o2ndDepthDisp,       .2,                                       .0,      tMax,            0x0F7,    0x85,  opt_2ndDepthDisp				; =1: show average depth instead of max depth
+	OPTION_UINT8p3d oMaxDepth,          .30,            ostc_depth_max,    ostc_depth_max,  tMeters,         0x0F8,    0x86,  opt_max_depth					; depth at which a warning will be given
+	OPTION_UINT8    oDescentSpeed,       .5,                  .30,                .10,      tMeterMinute,    0x0F9,    0x87,  char_I_descent_speed			; descent speed for deco calculator          [future option, not used yet]
+	OPTION_BOOL     oStoreApnoe,                                                   .0,                       0x0FA,    0x88,  opt_store_apnoe				; =1: store dives in apnoe mode into logbook
+	OPTION_ENUM8    oTissueGraphics, tissue_graphics_options,                      .0,      tTissuePresSat,  0x0FB,    0x88,  opt_tissue_graphics			; =0: show pressures and saturations, =1: show N2 and He pressures
+	OPTION_ENUM8    oLayout,             .2,                                       .0,      tLayoutNormal,   0x0FC,    0x8A,  opt_layout					; initial layout of dive mode screen =0: normal, =1: big
+	OPTION_BOOL     oExtendedStops,                                                .1,                       0x0FD,    0x8B,  opt_ext_stops					; =1: place gas switches also below 1st stop depth
+	OPTION_UINT8    oGasDensityAtt,     .40,                  .80,                .60,      nounit,          0x0FE,    0x8C,  char_I_gas_density_att		; threshold for gas density attention [0.1 grams/l]
+	OPTION_UINT8    oGasDensityWarn,    .40,                  .80,                .65,      nounit,          0x0FF,    0x8D,  char_I_gas_density_warn		; threshold for gas density warning   [0.1 grams/l]
+	OPTION_BOOL     oDilppO2Check,                                                .1,                        0x100,    0x8E,  char_I_dil_check				; =1: check ppO2 of the pure diluent against current setpoint
+	OPTION_UINT8    oFirmwareMajor,  fw_version_major,  fw_version_major, fw_version_major, nounit,          0x101,  nocomm,  opt_fw_version_major			; firmware version, major | use as read-only,
+	OPTION_UINT8    oFirmwareMinor,  fw_version_minor,  fw_version_minor, fw_version_minor, nounit,          0x102,  nocomm,  opt_fw_version_minor			; firmware version, minor | do not change eeprom index number!
+	OPTION_UINT8    oFirmwarebeta,   fw_version_beta ,  fw_version_beta,  fw_version_beta,  nounit,          0x103,  nocomm,  opt_fw_version_beta			; firmware version, beta  |
+	OPTION_ENUM8    oS8Mode,             .2,                                       .0,      tCCRS8Mode,      0x104,    0x8F,  opt_s8_mode					; =0: analog, =1: digital RS232
+	OPTION_ENUM8    oCaveMode,           .2,                                       .0,      tOff,            0x105,    0x90,  opt_cave_mode					; =1: cave mode switched on
+	OPTION_BOOL     oGasContingencyDive,                                           .0,                       0x106,    0x91,  opt_gas_contingency_dive		; =1: dive mode: switch to alternative gas if best gas is depleted
 
-	;	+---------------------------+
-	;	| /|\                       |
-	;	|  |  add new options here! |
-	;	+---------------------------+
+	;	+---------------------------------------------------------------------------------------------------------------------------------------------+
+	;   |  .                                                                                                                                          |
+	;	| /|\                                                                                                                                         |
+	;	|  |  add new options here!                                                                                                                   |
+	;	|  |  option items                max:   192,  existing:   181, spare:   11                                                                   |
+	;	|  |  EEPROM address  min: 0x012, max: 0x1FF, last used: 0x105, spare: 0x0B7-0x0B9, 0x0F5-0x0F6, disused: 0x0A8, 0x0CE                        |
+	;	|  |  serial address  min:  0xFE, max:  0xFE, last used:  0x90, spare: 0x38 (ex fallback), 0x47 (ex conservatism), 0x83 (spare), 0x84 (spare) |
+	;	+---------------------------------------------------------------------------------------------------------------------------------------------+
 
-; ppO2 warnings, sorted by ppO2 levels
-	OPTION_UINT8p10	oPPO2Min,		ppo2_warning_low_lowest,	ppo2_warning_low_highest,	ppo2_warning_low_default,	notext,	.16,	char_I_ppO2_min			; ppO2 min on OC   and for pure diluent in CCR
-	OPTION_UINT8p10	oPPO2MinCC,		ppo2_warning_loop_lowest,	ppo2_warning_loop_highest,	ppo2_warning_loop_default,	notext,	.172,	char_I_ppO2_min_loop	; ppO2 min on Loop and for pure diluent in pSCR
-	OPTION_UINT8p10	oPPO2Max,		ppo2_warning_high_lowest,	ppo2_warning_high_highest,	ppo2_warning_high_default,	notext,	.10,	char_I_ppO2_max_work	; ppO2 max while in working phase
-	OPTION_UINT8p10	oPPO2MaxDeco,	ppo2_warning_deco_lowest,	ppo2_warning_deco_highest,	ppo2_warning_deco_default,	notext,	.171,	char_I_ppO2_max_deco	; ppO2 max while in deco stops phase
+	; ppO2 warnings, sorted by ppO2 levels
+	OPTION_UINT8p10 oPPO2Min,     ppo2_warning_low_lowest,  ppo2_warning_low_highest,  ppo2_warning_low_default,  nounit, 0x022, 0x23, char_I_ppO2_min		; ppO2 min on OC   and for pure diluent in CCR
+	OPTION_UINT8p10 oPPO2MinCC,   ppo2_warning_loop_lowest, ppo2_warning_loop_highest, ppo2_warning_loop_default, nounit, 0x0BE, 0x4D, char_I_ppO2_min_loop	; ppO2 min on Loop and for pure diluent in pSCR
+	OPTION_UINT8p10 oPPO2Max,     ppo2_warning_high_lowest, ppo2_warning_high_highest, ppo2_warning_high_default, nounit, 0x01C, 0x22, char_I_ppO2_max_work	; ppO2 max while in working phase
+	OPTION_UINT8p10 oPPO2MaxDeco, ppo2_warning_deco_lowest, ppo2_warning_deco_highest, ppo2_warning_deco_default, nounit, 0x0BD, 0x4C, char_I_ppO2_max_deco	; ppO2 max while in deco stops phase
 
 
-;=============================================================================
-; volatile options
-
-	OPTION_UINT8p10	odiveInterval,		.0,				.240,			.0,		tMinutes,	volatile,	opt_surface_interval			; additional surface interval for deco calculator
-	OPTION_UINT8p2	obottomTime,		.2,				.60,			.10,	tMinutes,	volatile,	char_I_bottom_time				; bottom time  for deco calculator
-	OPTION_UINT8p3d	obottomDepth,		.12,			.120,			.21,	tMeters,	volatile,	char_I_bottom_depth				; bottom depth for deco calculator and simulator
-	OPTION_BOOL		oSimAGF,											.0,					volatile,	opt_sim_use_aGF					; use GF (no) or aGF (yes) in deco calculator
-	OPTION_ENUM8	oLogOffsetStep,		.4,								.0,		tLogOffStep1, volatile,	opt_logoffset_step				; step size when adjusting the log offset
+	; volatile options
+	OPTION_UINT8p10 odiveInterval,       .0,                 .240,                 .0,      tMinutes,    volatile,   nocomm,  opt_surface_interval			; additional surface interval for deco calculator
+	OPTION_UINT8p2  obottomTime,         .2,                  .60,                .10,      tMinutes,    volatile,   nocomm,  char_I_bottom_time			; bottom time  for deco calculator
+	OPTION_UINT8p3d obottomDepth,       .12,                 .120,                .21,      tMeters,     volatile,   nocomm,  char_I_bottom_depth			; bottom depth for deco calculator and simulator
+	OPTION_BOOL     oSimAGF,                                                       .0,                   volatile,   nocomm,  opt_sim_use_aGF				; =1: use GF (no) or aGF (yes) in deco calculator
+	OPTION_ENUM8    oLogOffsetStep,      .4,                                       .0,      tLogOffStep1,volatile,   nocomm,  opt_logoffset_step			; step size when adjusting the log offset
+	OPTION_UINT8    oClearSeconds,       .0,                   .0,                 .0,      nounit,      volatile,   nocomm,  rtc_latched_secs				; used for setting time & date via menu
+	OPTION_UINT8    oSetMinutes,         .0,                  .59,                 .0,      nounit,      volatile,   nocomm,  rtc_latched_mins				; ...
+	OPTION_UINT8    oSetHours,           .0,                  .23,                 .0,      nounit,      volatile,   nocomm,  rtc_latched_hour				; ...
+	OPTION_UINT8    oSetDay,             .1,                  .31,                 .0,      nounit,      volatile,   nocomm,  rtc_latched_day				; ...
+	OPTION_UINT8    oSetMonth,           .1,                  .12,                 .0,      nounit,      volatile,   nocomm,  rtc_latched_month				; ...
+	OPTION_UINT8    oSetYear,           .18,                  .24,                 .0,      nounit,      volatile,   nocomm,  rtc_latched_year				; ...
 
  IFDEF _gas_contingency
-	OPTION_BOOL		oGasContingency,									.0,					volatile,	char_I_gas_contingency			; =1: switch to alternative gas if best gas is depleted
+	OPTION_BOOL     oGasContingencySim,                                            .0,                   volatile,   nocomm,  opt_gas_contingency_sim		; =1: deco calculator: switch to alternative gas if best gas is depleted
  ENDIF
 
-
-;=============================================================================
-; Set Time/Set Date (RAM only)
-	OPTION_UINT8	oClearSeconds,		.0,				.0,				.0,		notext,		volatile,	rtc_latched_secs
-	OPTION_UINT8	oSetMinutes,		.0,				.59,			.0,		notext,		volatile,	rtc_latched_mins
-	OPTION_UINT8	oSetHours,			.0,				.23,			.0,		notext,		volatile,	rtc_latched_hour
-	OPTION_UINT8	oSetDay,			.1,				.31,			.0,		notext,		volatile,	rtc_latched_day
-	OPTION_UINT8	oSetMonth,			.1,				.12,			.0,		notext,		volatile,	rtc_latched_month
-	OPTION_UINT8	oSetYear,			.18,			.24,			.0,		notext,		volatile,	rtc_latched_year
-
 	global	option_table_end
 option_table_end:
+	OPTION_END		; end of option table - important: DO NOT OMIT THIS MACRO!
 
-	END
\ No newline at end of file
+	END
--- a/src/options.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/options.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File options.asm                          next combined generation V3.04.3
+;   File options.asm                          next combined generation V3.08.8
 ;
 ;   Manage all options data.
 ;
@@ -22,14 +22,13 @@
 
 	extern	write_eeprom
 	extern	read_eeprom
-	extern	eeprom_serial_save,eeprom_opt_backup
 	extern	option_table_begin,option_table_end
 	extern	convert_meter_to_feet
 
 options		CODE
 
 ;=============================================================================
-; Reset all options to factory defaults
+; Reset all options to factory defaults (in memory only)
 ;
 ; INPUT:  none
 ; OUTPUT: none
@@ -37,163 +36,27 @@
 ;
 	global	option_reset_all				; reset all options to factory default
 option_reset_all:
-	clrf	EEADRH
-	read_int_eeprom .2
-	tstfsz	EEDATA							; number of total dives = 0 ?
-	bra		option_reset_all2				; NO - skip resetting logbook
-	read_int_eeprom .3
-	tstfsz	EEDATA							; number of total dives = 0 ?
-	bra		option_reset_all2				; NO - skip resetting logbook
-
-	clrf	EEDATA
-	write_int_eeprom .4
-	write_int_eeprom .5
-	write_int_eeprom .6
-	write_int_eeprom .2						; delete total dive counter, too
-	write_int_eeprom .3
-	call	ext_flash_erase_logbook			; complete logbook
-
-option_reset_all2:
-	clrf	lo
-	clrf	hi
-	call	do_logoffset_common_write		; reset logbook offset
-	movlw	LOW(option_table_begin)			; point to option table begin
-	movwf	FSR0L
-	movlw	HIGH(option_table_begin)
-	movwf	FSR0H
-option_reset_all_1:
-	movlw	LOW(option_table_end)			; get low byte of end of table address
-	cpfseq	FSR0L							; does it equal the current pointer position?
-	bra		option_reset_all_2				; NO - more options to process
-	movlw	HIGH(option_table_end)			; get high byte of end of table address
-	cpfseq	FSR0H							; does it equal the current pointer position?
-	bra		option_reset_all_2				; NO - more options to process
-	return									; YES to both - end of option table reached, done
-option_reset_all_2:
-	rcall	option_reset					; reset one option...
-	bra		option_reset_all_1				; ... and loop
+	call	eeprom_total_dives_read			; read total number of dives
+	tstfsz	mpr+0							; number of total dives, low  byte = 0 ?
+	bra		option_reset_all_1				; NO - skip resetting logbook
+	tstfsz	mpr+1							; number of total dives, high byte = 0 ?
+	bra		option_reset_all_1				; NO - skip resetting logbook
 
-;=============================================================================
-; Check all option and reset option if out of min/max boundary
-;
-; INPUT:  none
-; OUTPUT: none
-; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1, FSR2
-;
-	global	option_check_all				; check all option and reset option if out of min/max boundary
-option_check_all:
-	bcf		option_repaired					; no option needed repair up to now
-	movlw	LOW(option_table_begin)			; point to option table begin
-	movwf	FSR0L
-	movlw	HIGH(option_table_begin)
-	movwf	FSR0H
-option_check_all_1:
-	movlw	LOW(option_table_end)			; get low byte of end of table address
-	cpfseq	FSR0L							; does it equal the current pointer position?
-	bra		option_check_all_2				; NO - more options to process
-	movlw	HIGH(option_table_end)			; get high byte of end of table address
-	cpfseq	FSR0H							; does it equal the current pointer position?
-	bra		option_check_all_2				; NO - more options to process
-	bra		option_check_all_3				; YES to both - end of option table reached
-option_check_all_2:
-	rcall	option_check					; check one option...
-	bra		option_check_all_1				; ... and loop
-option_check_all_3:
-	bsf		is_diluent_menu					; setup checking diluents
-	call	gaslist_cleanup_list			; check and correct multiple or none First diluent
-	bcf		is_diluent_menu					; setup checking gases
-	call	gaslist_cleanup_list			; check and correct multiple or none First gas
- IFNDEF _gauge_mode
-	call	option_cleanup_gauge			; check and correct Gauge mode
- ENDIF
- IFDEF _ccr_pscr
-	call	option_cleanup_oCCRMode			; check and correct CCR / pSCR mode
- ENDIF
-	call	option_cleanup_GF				; check and correct GFlow <= GFhigh
-	return									; all done
-
-
+	; reset logbook
+	call	erase_complete_logbook			; erase complete logbook
 
-;=============================================================================
-; Read option handle
-; INPUT:  FSR0 = option handle
-; OUTPUT: FSR1 = address of variable.
-; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
-;
-option_read:
-	movff	FSR0L,TBLPTRL					; set memory address of option data set, low byte
-	movlw	HIGH(option_table_begin)		; get table begin address, high byte
-	andlw	0xF0							; keep only the upper nibble
-	iorwf	FSR0H,W							; add the memory address of the option data set, high byte
-	movwf	TBLPTRH							; set the resulting memory address, high byte
-	movlw	UPPER(option_table_begin)		; get table begin address, upper byte
-	movwf	TBLPTRU							; set memory address of option data set, upper byte
-
-	; Read type, default and register from table
-	tblrd*+
-	movff	TABLAT,opt_type
-	tblrd*+
-	movff	TABLAT,opt_default
-	tblrd*+
-	movff	TABLAT,opt_inc
-	tblrd*+
-	movff	TABLAT,opt_min
-	tblrd*+
-	movff	TABLAT,opt_max
-	tblrd*+
-	movff	TABLAT,opt_eeprom
-	tblrd*+
-	movff	TABLAT,opt_unit+0
-	tblrd*+
-	movff	TABLAT,opt_unit+1
-	tblrd*+
-	movff	TABLAT,FSR1L
-	tblrd*+
-	movff	TABLAT,FSR1H
-	movff	TBLPTRL,FSR0L					; advance handle to next option data set (used for reset_all)
-	movff	TBLPTRH,FSR0H
-	return
+	; reset logbook offset
+	CLRI	mpr								; set   logbook offset to zero
+	call	eeprom_log_offset_write			; store logbook offset
 
-;=============================================================================
-; Check one option and reset if it's out of it's min/max boundaries
-; INPUT:  FSR0 = option handle
-; OUTPUT: none
-; TRASH:  TBLPTR, TABLAT, WREG, FSR1, FSR2, lo
-;
-option_check:
-	; Read type, default and register from table
-	rcall	option_read
+option_reset_all_1:
+	lfsr	FSR0,option_table_begin			; point to start of option definition table
+option_reset_all_loop:
+	rcall	option_reset					; reset option
+	incfsz	opt_end_token,F					; was this the last option (was opt_end_token = 255) ?
+	bra		option_reset_all_loop			; NO  - do next option
+	return									; YES - done
 
-	; Switch on type
-	movf	opt_type,W						; get option type
-	xorlw	.2								; type == STRING ?
-	bz		option_check_string				; YES
-	movf	opt_type,W						; get option type (again)
-	xorlw	.1								; type == ENUM8 ?
-	bz		option_check_enum8				; YES - check if lower then max. value only
-											; NO to all - must be integer then
-	tstfsz	opt_min							; opt_min = 0 ?
-	bra		option_check_both				; NO - check it
-	bra		option_check_enum8				; check max only
-
-option_check_both:
-	decf	opt_min,W						; check against minimum value
-	cpfsgt	INDF1							; bigger than opt_min - 1 ?
-	bra		option_check_reset				; NO - reset option
-option_check_enum8:							; check against maximum value
-	infsnz	opt_max,W						; max = 255?
-	return									; YES - ignore the max. test
-	cpfslt	INDF1							; NO  - smaller then opt_max + 1 ?
-	bra		option_check_reset				;       NO  - reset option
-	return									;       YES - within range, return
-
-option_check_reset:
-	movff	opt_default,INDF1				; reset option to default
-	bsf		option_repaired					; flag that an option was repaired
-	return									; done
-
-option_check_string:
-	return
 
 ;=============================================================================
 ; Reset an option to its default value
@@ -201,170 +64,316 @@
 ; OUTPUT: none
 ; TRASH:  TBLPTR, TABLAT, WREG, FSR1, FSR2
 ;
-	global	option_reset					; reset FSR0 option to factory default
+	global	option_reset					; reset option value to default
 option_reset:
-	; Read type, default and register from table
-	rcall	option_read						; read option data
+	; read type, default and register from table
+	rcall	option_read_definition			; read option definition
+
+option_reset_loaded:						; entry point with option definition already read
+	bsf		option_repaired					; flag that an option was repaired
+	bsf		options_changed					; flag that EEPROM needs to be updated
 	movf	opt_type,W						; get option type
-	xorlw	2								; Type == STRING ?
-	bz		opt_reset_string				; YES - special copy
-	movff	opt_default,INDF1				; NO  - just a 8 bit indirect copy
-	return
+	xorlw	.2								; type = STRING ?
+	bz		opt_reset_string				; YES - string copy
+	movff	opt_default,INDF1				; NO  - 1 byte copy
+	return									;     - done
+
 opt_reset_string:
 	movff	FSR1L,FSR2L						; set string destination address
 	movff	FSR1H,FSR2H						; ...
 	movff	opt_default+0,FSR1L				; get handle to multi-lingual text in FSR1
 	movff	opt_default+1,FSR1H				; ...
-	movff	TBLPTRL,opt_backup_tbl+0		; TBLPTR trashed by text routine...
-	movff	TBLPTRH,opt_backup_tbl+1		; ...
-	movff	TBLPTRU,opt_backup_tbl+2		; ...
+	movff	TBLPTRL,mpr+0					; TBLPTR will be trashed by text routine, so make a back-up
+	movff	TBLPTRH,mpr+1					; ...
+	movff	TBLPTRU,mpr+2					; ...
 	call	strcat_text						; copy translated text to FSR2
-	movff	opt_backup_tbl+0,TBLPTRL		; restore TBLPTR
-	movff	opt_backup_tbl+1,TBLPTRH		; ...
-	movff	opt_backup_tbl+2,TBLPTRU		; ...
+	movff	mpr+0,TBLPTRL					; restore TBLPTR
+	movff	mpr+1,TBLPTRH					; ...
+	movff	mpr+2,TBLPTRU					; ...
+	return									; done
+
 
-	return
+;=============================================================================
+; Read option definition
+; INPUT:  FSR0 = option handle
+; OUTPUT: FSR1 = address of variable.
+; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
+;
+option_read_definition:
+	movff	FSR0L,TBLPTRL					; low byte  : set memory address of option data set
+	movlw	HIGH(option_table_begin)		; high byte : get table start address
+	andlw	0xF0							;             keep only the upper nibble
+	iorwf	FSR0H,W							;             add the memory address of the option data set
+	movwf	TBLPTRH							;             set the resulting memory address
+	movlw	UPPER(option_table_begin)		; upper byte: get table start address
+	movwf	TBLPTRU							;             set memory address of option data set
+
+	lfsr	FSR1,opt_type					; load FSR1 with base address of option definition vars
+	movlw	opt_definiton_bytes				; get number of bytes to copy
+	movwf	eeprom_loop						; initialize loop counter (using an EEPROM variable here)
+option_read_definition_loop:
+	tblrd*+									; read one byte from program memory and increment address
+	movff	TABLAT,POSTINC1					; transfer byte from program memory to memory
+	decfsz	eeprom_loop,F					; all bytes done?
+	bra		option_read_definition_loop		; NO  - loop
+	tblrd*									; YES - read one byte ahead without incrementing address
+	movff	TABLAT,POSTINC1					;     - store byte
+	movff	opt_memory+0,FSR1L				;     - load FSR1 with the address of the option value variable
+	movff	opt_memory+1,FSR1H				;     - ...
+	movff	TBLPTRL,FSR0L					;     - advance handle to the next option definition data set
+	movff	TBLPTRH,FSR0H					;     - ...
+	return									;     - done
+
 
 ;=============================================================================
-; Save all options to EEPROM
+; Check one option and reset its value if it is out of min/max boundary
+; INPUT:  opt_* vars and FSR1
+; OUTPUT: option value set to default if out of min/max
+; TRASH:  WREG
 ;
-	global	option_save_all					; save options to EEPROM
-option_save_all:
-	bcf	PIR3,RC2IE
-	;---- Save option serial into EEPROM to detect reset and new version
-	movlw	LOW(eeprom_serial_save)
-	movwf	EEADR
-	movlw	HIGH(eeprom_serial_save)
-	movwf	EEADRH
-	movlw	LOW(eeprom_opt_serial)
-	movwf	EEDATA
-	call	write_eeprom
-	incf	EEADR,F
-	movlw	HIGH(eeprom_opt_serial)
-	movwf	EEDATA
-	call	write_eeprom
+option_check_loaded:
+	; switch on type
+	movf	opt_type,W						; get type
+	bz		option_check_uint8				; type 0: INT8
+	dcfsnz	WREG							; decrement
+	bra		option_check_enum8				; type 1: ENUM
+	dcfsnz	WREG							; decrement
+	bra		option_check_string				; type 2: STRING
+	;bra	option_check_uint8				; type 3: INT8
+
+option_check_uint8:
+	tstfsz	opt_min							; opt_min = 0 ?
+	bra		option_check_min				; NO  - check it
+	bra		option_check_enum8				; YES - continue with check for maximum
+
+option_check_min:
+	decf	opt_min,W						; get (minimum permissible value - 1) into WREG
+	cpfsgt	INDF1							; option value > (minimum permissible value - 1) ?
+	bra		option_reset_loaded				; NO  - reset option value
+	;bra	option_check_enum8				; YES - continue with check for maximum
+
+option_check_enum8:
+	infsnz	opt_max,W						; get (highest permissible value + 1) into WREG
+	return									; highest permissible value was 255, skip check, done
+	cpfslt	INDF1							; option value < (highest permissible value + 1) ?
+	bra		option_reset_loaded				; NO  - reset option value
+	return									; YES - within range, done
+
+option_check_string:
+	return									; nothing to check with strings
 
-	;---- Save all options
-	movlw	LOW(option_table_begin)
-	movwf	FSR0L
-	movlw	HIGH(option_table_begin)
-	movwf	FSR0H
+
+;=============================================================================
+; Check and store all option values in EEPROM
+;
+	global	option_check_and_store_all
+option_check_and_store_all:
+	bcf		PIR3,RC2IE						; disable EUSART interrupts
+
+	;---- save option version
+	MOVLI	eeprom_opt_version,mpr				; get   options version number
+	EEPROM_II_WRITE mpr,eeprom_options_version	; store options version number in EEPROM
+
+	;---- check and resolve some interdependencies among options
+	bsf		is_diluent_menu					; setup checking diluents
+	call	gaslist_cleanup_list			; check and correct multiple or none First diluents
 
-option_save_all_1:
-	movlw	LOW(option_table_end)
-	cpfseq	FSR0L
-	bra		option_save_all_2				; not yet done...
-	movlw	HIGH(option_table_end)
-	cpfseq	FSR0H
-	bra		option_save_all_2				; not yet done...
-	bsf	PIR3,RC2IE
-	return									; all done
-option_save_all_2:
-	rcall	option_save						; save one option...
-	bra		option_save_all_1				; ...and loop
+	bcf		is_diluent_menu					; setup checking gases
+	call	gaslist_cleanup_list			; check and correct multiple or none First gases
+
+ IFNDEF _gauge_mode
+	call	option_cleanup_gauge			; check and correct gauge mode
+ ENDIF
+
+ IFDEF _ccr_pscr
+	call	option_cleanup_oCCRMode			; check and correct CCR / pSCR mode
+ ENDIF
+
+	call	option_cleanup_GF				; check and correct GFlow <= GFhigh
+
+	;---- check and save all option values
+	lfsr	FSR0,option_table_begin			; point to start of option definition table
+option_save_all_loop:
+	rcall	option_check_and_store			; check and save option value
+	incfsz	opt_end_token,F					; was this the last option (was opt_end_token = 255) ?
+	bra		option_save_all_loop			; NO  - do next option
+	return									; YES - done
 
 
-	global	option_save
-option_save:
-	rcall	option_read
-	incf	opt_eeprom,W					; should we save it ?
-	btfsc	STATUS,Z						; EEPROM address is FFh ?
-	return									; YES - nothing to do
-	movf	opt_eeprom,W					; compute backup address in EEPROM
-	addlw	LOW(eeprom_opt_backup)			; add offset
-	movwf	EEADR
-	movlw	HIGH(eeprom_opt_backup)
-	btfsc	STATUS,C						; > 256 ?
-	addlw	.1								; YES - +1
-	movwf	EEADRH
+;=============================================================================
+; Check and store an option value in EEPROM
+;
+	global	option_check_and_store
+option_check_and_store:
+	rcall	option_read_definition			; read the option definition
+	rcall	option_check_loaded				; check if option value is within min/max, set to default if not
+
+option_save_loaded_checked:
+	movf	opt_eeprom_bank,W				; get bank
+	andlw	b'11111110'						; keep only bits 7-1
+	tstfsz	WREG							; bank < 0x02 ?
+	return									; NO  - volatile option or illegal address, abort
+	tstfsz	opt_eeprom_bank					; YES - bank = 0 ?
+	bra		option_save_execute				;       NO  - address is valid
+	movlw	low(eeprom_options_storage-1)	;       YES - get start address of options storage minus 1
+	cpfsgt	opt_eeprom_index				;           - index >= start address ?
+	return									;             NO  - illegal address, abort
+	;bra	option_save_execute				;             YES - address is valid
+
+option_save_execute:
+	movff	opt_eeprom_index,EEADR			; set EEPROM index (address low  byte)
+	movff	opt_eeprom_bank, EEADRH			; set EEPROM page  (address high byte)
+
 	movf	opt_type,W						; get option type
-	xorlw	2								; option type is string ?
-	bz		option_save_string				; YES
-	movff	INDF1,EEDATA					; NO  - one byte to be saved to EEPROM
-	btfss	EEADRH,1						;     - EEADR:EEADRH < 512 ?
-	call	write_eeprom					;       YES  - write
-	return									;       (NO) - done
+	xorlw	.2								; option type = string ?
+	bz		option_save_string				; YES - special handling
+	movff	INDF1,EEDATA					; NO  - copy option value to EEPROM write register
+	call	write_eeprom					;     - execute write
+	return									;     - done
+
 option_save_string:
-	movff	POSTINC1,EEDATA					; write one byte
-	btfss	EEADRH,1						; EEADR:EEADRH < 512 ?
-	call	write_eeprom					; YES  - write
-	infsnz	EEADR,F							; (NO) - increment EEPROM address
-	incf	EEADRH,F						;      - ...
-	decfsz	opt_max							;      - decrement string length, done?
-	bra		option_save_string				;        NO  - loop
-	return									;        YES
+	movff	POSTINC1,EEDATA					; copy a character from the option value to the EEPROM write register
+	btfss	EEADRH,1						; current EEPROM address < 512 ?
+	call	write_eeprom					; YES  - execute write
+	infsnz	EEADR,F							; increment EEPROM address, low  byte
+	incf	EEADRH,F						; increment EEPROM address, high byte
+	decfsz	opt_max							; decrement string length, done?
+	bra		option_save_string				; NO  - loop
+	return									; YES - done
+
+
+;=============================================================================
+; Restore and check all option values from EEPROM
+;
+	global	option_restore_and_check_all	; restore options from EEPROM
+option_restore_and_check_all:
+	;---- Read option version from EEPROM
+	EEPROM_II_READ	eeprom_options_version,mpr
+
+	movlw	LOW(eeprom_opt_version)			; get options version from current firmware, low  byte
+	xorwf	mpr+0,W							; compare with EEPROM version, do they match?
+	bnz		option_restore_reset			; NO - reset to defaults of current firmware
+
+	movlw	HIGH(eeprom_opt_version)		; get options version from current firmware, high byte
+	xorwf	mpr+1,W							; compare with EEPROM version, do they match?
+	bnz		option_restore_reset			; NO  - reset to defaults of current firmware
+
+	;---- restore all option values
+	lfsr	FSR0,option_table_begin			; point to start of option definition table
+option_restore_all_loop:
+	rcall	option_restore_and_check		; restore and check the option
+	incfsz	opt_end_token,F					; was this the last option (was opt_end_token = 255) ?
+	bra		option_restore_all_loop			; NO  - do next option
+	return									; YES - done
+
+option_restore_reset:
+	call	option_reset_all				; reset all option values to their default
+	goto	option_check_and_store_all		; write back all option values to EEPROM (and return)
+
 
 ;=============================================================================
+; Restore an option value from EEPROM and check it
+;
+	global	option_restore_and_check
+option_restore_and_check:
+	rcall	option_read_definition			; read the option definition
 
-	global	option_restore_all				; restore options from EEPROM
-option_restore_all:
-	;---- Read option serial from EEPROM
-	movlw	LOW(eeprom_serial_save)
-	movwf	EEADR
-	movlw	HIGH(eeprom_serial_save)
-	movf	EEADRH
-	call	read_eeprom
-	movlw	LOW(eeprom_opt_serial)
-	xorwf	EEDATA,W
-	bnz		option_restore_bad				; auto reset if changed
-	incf	EEADR,F
-	call	read_eeprom
-	movlw	HIGH(eeprom_opt_serial)
-	xorwf	EEDATA,W
-	bz		option_restore_ok				; auto reset if changed
+	movf	opt_eeprom_bank,W				; get bank
+	andlw	b'11111110'						; keep only bits 7-1
+	tstfsz	WREG							; bank < 0x02 ?
+	bra		option_reset_loaded				; NO  - volatile option or illegal address, restore to default
+	tstfsz	opt_eeprom_bank					; YES - bank = 0 ?
+	bra		option_restore_execute			;       NO  - address is valid
+	movlw	low(eeprom_options_storage-1)	;       YES - get start address of options storage minus 1
+	cpfsgt	opt_eeprom_index				;           - index >= start address ?
+	bra		option_reset_loaded				;             NO  - illegal address, restore to default
+	;bra	option_restore_execute			;             YES - address is valid
 
-option_restore_bad:
-	call	option_reset_all				; reset RAM contains
-	goto	option_save_all					; then save to EEPROM
-
-	;---- Proper restore
-option_restore_ok:
-	movlw	LOW(option_table_begin)
-	movwf	FSR0L
-	movlw	HIGH(option_table_begin)
-	movwf	FSR0H
+option_restore_execute:
+	movff	opt_eeprom_index,EEADR			; set EEPROM index (address low  byte)
+	movff	opt_eeprom_bank, EEADRH			; set EEPROM page  (address high byte)
 
-option_restore_all_1:
-	movlw	LOW(option_table_end)
-	cpfseq	FSR0L
-	bra		option_restore_all_2			; not yet done...
-	movlw	HIGH(option_table_end)
-	cpfseq	FSR0H
-	bra		option_restore_all_2			; not yet done...
-	return									; all done
-option_restore_all_2:
-	rcall	option_restore					; Restore one option
-	bra		option_restore_all_1			; and loop
+	movf	opt_type,W						; get option type
+	xorlw	.2								; option type = string ?
+	bz		option_restore_string			; YES - special handling
+	call	read_eeprom						; NO  - execute read
+	movff	EEDATA,INDF1					;     - read option value from EEPROM read register
+	bcf		option_repaired					;     - clear option repaired flag
+	bra		option_check_loaded				;     - check if option value is within min/max, reset to default if not
+	btfsc	option_repaired					;     - was the option repaired?
+	bra		option_save_loaded_checked		;       YES - save repaired value to EEPROM
+	return									;       NO  - done
 
-option_restore:
-	rcall	option_read
-	incf	opt_eeprom,W					; shall we save it ?
-	btfsc	STATUS,Z						; EEPROM address is FFh ?
-	return									; YES - nothing to do.
-	movf	opt_eeprom,W					; compute backup address in EEPROM
-	addlw	LOW(eeprom_opt_backup)			; add offset
-	movwf	EEADR
-	movlw	HIGH(eeprom_opt_backup)
-	btfsc	STATUS,C						; > 256 ?
-	addlw	.1								; YES - +1
-	movwf	EEADRH
-	movf	opt_type,W						; get option type
-	xorlw	2								; Option type is string?
-	bz		option_restore_string			; YES
-	call	read_eeprom						; read one byte from EEPROM
-	movff	EEDATA, INDF1					; restore option register
-	return
 option_restore_string:
-	call	read_eeprom						; read one byte, and...
-	movff	EEDATA,POSTINC1					; ... restore it
-	infsnz	EEADR,F
-	incf	EEADRH,F
-	decfsz	opt_max							; decrement string length
-	bra		option_restore_string			; loop while not finished
-	return
+	call	read_eeprom						; read one character from the EEPROM
+	movff	EEDATA,POSTINC1					; copy it to the option value
+	infsnz	EEADR,F							; increment EEPROM address, low  byte
+	incf	EEADRH,F						; increment EEPROM address, high byte
+	decfsz	opt_max							; decrement string length, done?
+	bra		option_restore_string			; NO  - loop
+	return									; YES - done (nothing to check with strings)
+
+
 
 ;=============================================================================
-; Increment an option, based on type, and boundary
+; Read an option value via RS232
+; INPUT:  lo   = serial index
+; OUTPUT: hi   = option value
+;         WREG =0: option found and value valid, =1: option not found
+; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
+;
+	global	option_read_serial
+option_read_serial:
+	lfsr	FSR0,option_table_begin			; point to start of option definition table
+option_read_serial_loop:
+	rcall	option_read_definition			; read option definition
+	movf	opt_serial,W					; get serial index of the option into WREG
+	xorwf	lo,W							; received index = index of this option ?
+	bz		option_read_serial_execute		; YES - read value
+	incfsz	opt_end_token,F					; NO  - was this the last option (was opt_end_token = 255) ?
+	bra		option_read_serial_loop			;       NO  - try next option
+	retlw	.1								;       YES - done, option not found
+
+option_read_serial_execute:
+	movff	INDF1,hi						; read option value into hi
+	retlw	.0								; done, option found
+
+
+;=============================================================================
+; Write an option value via RS232
+; INPUT:  lo   = serial index
+;         hi   = option value
+; OUTPUT: WREG =0: option found and value valid, =1: option not found, =2: value not valid
+; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1, up
+;
+	global	option_write_serial
+option_write_serial:
+	lfsr	FSR0,option_table_begin			; point to start of option definition table
+option_write_serial_loop:
+	rcall	option_read_definition			; read option definition
+	movf	opt_serial,W					; get serial index of the option into WREG
+	xorwf	lo,W							; received index = index of this option ?
+	bz		option_write_serial_execute		; YES - check and update value
+	incfsz	opt_end_token,F					; NO  - was this the last option (was opt_end_token = 255) ?
+	bra		option_write_serial_loop		;       NO  - try next option
+	retlw	.1								;       YES - done, option not found
+
+option_write_serial_execute:
+	movff	INDF1,up						; backup old value
+	movff	hi,INDF1						; write  new value
+	bcf		option_repaired					; clear option repaired flag
+	rcall	option_check_loaded				; check the new value
+	btfsc	option_repaired					; was   the new value valid?
+	bra		option_write_serial_execute_fail; NO  - restore old value
+	bsf		options_changed					; YES - flag that EEPROM needs to be updated
+	retlw	.0								;     - done, success
+option_write_serial_execute_fail:
+	movff	up,INDF1						; restore old value
+	retlw	.2								; done, value not valid
+
+
+;=============================================================================
+; Increment an option value based on type and min/max boundary
 ; INPUT:  FSR0 = option handle
 ; OUTPUT: none
 ; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
@@ -372,28 +381,31 @@
 	global	option_inc						; increment FSR0 option
 option_inc:
 	; read type, default and register from table
-	rcall	option_read
+	rcall	option_read_definition
+
+	bsf		options_changed					; flag that EEPROM needs to be updated
 
 	; switch on type
-	movf	opt_type,W
-	bz		option_inc_uint8
-	dcfsnz	WREG
-	bra		option_inc_enum8
-	dcfsnz	WREG
-	bra		option_inc_string
+	movf	opt_type,W						; get option type
+	bz		option_inc_uint8				; type 0: INT8
+	dcfsnz	WREG							; decrement
+	bra		option_inc_enum8				; type 1: ENUM
+	dcfsnz	WREG							; decrement
+	bra		option_inc_string				; type 2: STRING
+	;bra	option_inc_uint8				; type 3: INT8
 
-option_inc_uint8:							; default type too...
-	movf	INDF1,W
-	addwf	opt_inc,W
-	cpfslt	opt_max
-	bra		option_inc_uint8_0
-	movf	opt_min,W
+option_inc_uint8:
+	movf	INDF1,W							; get option value
+	addwf	opt_inc,W						; add increment
+	cpfslt	opt_max							; max < option value ?
+	bra		option_inc_uint8_0				; NO  - new option value ok
+	movf	opt_min,W						; YES - reset to min value
 option_inc_uint8_0:
-	movwf	INDF1
+	movwf	INDF1							; store new value
 option_inc_uint8_1:
-	; Now some rather crude hack into this routine to make CCR Calibration more convenient:
-	movlw	.149							; EEPROM address of option CalGasO2
-	cpfseq	opt_eeprom						; editing CalGasO2 right now?
+	; now some rather crude hack into this routine to make CCR calibration more convenient:
+	movlw	0x37							; serial ID of option CalGasO2
+	cpfseq	opt_serial						; editing CalGasO2 right now?
 	bra		option_inc_uint8_2				; NO - check next option
 	movff	opt_dive_mode,WREG				; YES - get dive mode: 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR
 	decfsz	WREG,W							;     - in CCR mode?
@@ -405,8 +417,8 @@
 	movwf	INDF1							;                 - store it
 	return
 option_inc_uint8_2:
-	movlw	.12								; EEPROM address of option opt_GF_low
-	cpfseq	opt_eeprom						; editing opt_GF_low right now?
+	movlw	0x25							; serial ID of option opt_GF_low
+	cpfseq	opt_serial						; editing opt_GF_low right now?
 	bra		option_inc_uint8_3				; NO - check next option
 	movff	opt_GF_high,WREG				; get value of associated GF high into WREG
 	cpfsgt	INDF1							; GF low > GF high?
@@ -414,8 +426,8 @@
 	movff	opt_min,INDF1					; YES - wrap around to minimum value
 	return									;     - done
 option_inc_uint8_3:
-	movlw	.13								; EEPROM address of option opt_GF_high
-	cpfseq	opt_eeprom						; editing opt_GF_high right now?
+	movlw	0x26							; serial ID of option opt_GF_high
+	cpfseq	opt_serial						; editing opt_GF_high right now?
 	bra		option_inc_uint8_4				; NO - check next option
 	movff	opt_GF_low,WREG					; get value of associated GF low into WREG
 	cpfslt	INDF1							; GF high < GF low?
@@ -423,8 +435,8 @@
 	movwf	INDF1							; YES - rise GF high to GF low
 	return									;     - done
 option_inc_uint8_4:
-	movlw	.17								; EEPROM address of option opt_aGF_low
-	cpfseq	opt_eeprom						; editing opt_aGF_low right now?
+	movlw	0x27							; serial ID of option opt_aGF_low
+	cpfseq	opt_serial						; editing opt_aGF_low right now?
 	bra		option_inc_uint8_5				; NO - check next option
 	movff	opt_aGF_high,WREG				; get value of associated GF high into WREG
 	cpfsgt	INDF1							; GF low > GF high?
@@ -432,8 +444,8 @@
 	movff	opt_min,INDF1					; YES - wrap around to minimum value
 	return									;     - done
 option_inc_uint8_5:
-	movlw	.18								; EEPROM address of option opt_aGF_high
-	cpfseq	opt_eeprom						; editing opt_aGF_high right now?
+	movlw	0x28							; serial ID of option opt_aGF_high
+	cpfseq	opt_serial						; editing opt_aGF_high right now?
 	bra		option_inc_uint8_6				; NO - check next option
 	movff	opt_aGF_low,WREG				; get value of associated GF low into WREG
 	cpfslt	INDF1							; GF high < GF low?
@@ -444,16 +456,20 @@
 	return									; all done
 
 
-option_inc_enum8:							; always +1
-	incf	INDF1,W
-	cpfsgt	opt_max
-	clrf	WREG
-	movwf	INDF1
+option_inc_enum8:
+	movf	opt_max,W						; copy maximum permissible value to WREG
+	cpfslt	INDF1							; option value < maximum permissible value ?
+	bra		option_inc_enum8_reset			; NO  - reset     option value
+	incf	INDF1,F							; YES - increment option value
+	bra		option_inc_enum8_1				;     - continue
+option_inc_enum8_reset:
+	clrf	INDF1							; reset option value to zero
+
 option_inc_enum8_1:
  IFDEF _ccr_pscr
-	; Now some rather crude hack into this routine to unify CCR & pSCR mode setting
-	movlw	.25								; EEPROM address of option oCCRMode
-	cpfseq	opt_eeprom						; editing oCCRMode right now?
+	; now some rather crude hack into this routine to unify CCR & pSCR mode setting
+	movlw	0x1F							; serial ID of option oCCRMode
+	cpfseq	opt_serial						; editing oCCRMode right now?
 	bra		option_inc_enum8_2				; NO  - check next option
  IFDEF _external_sensor
 	btfsc	analog_o2_input					; YES - does hosting OSTC have an analog interface?
@@ -473,12 +489,26 @@
 option_inc_enum8_1_exit:
 	return									; done
  ENDIF	; _ccr_pscr
+
 option_inc_enum8_2:
-											; (unused)
+ IFDEF _gas_contingency
+	; now some rather crude hack to switch off contingency mode if gas needs calculation is switched off
+	movlw	0x5A							; serial ID of option opt_calc_gasvolume
+	cpfseq	opt_serial						; editing opt_calc_gasvolume right now?
+	bra		option_inc_enum8_3				; NO  - check next option
+	movf	INDF1,W							; YES - get option value
+;	xorlw	.0								;     - option value = off ?
+	bnz		option_inc_enum8_2_exit			;       NO  - done
+	clrf	WREG							;       YES - force contingency to be off, too
+	movff	WREG,opt_gas_contingency_dive	;           - ...
+option_inc_enum8_2_exit:
+	return
+ ENDIF	; _gas_contingency
+
 option_inc_enum8_3:
-	; Now some rather crude hack to correct opt_TR_mode in dependency of opt_dive_mode
-	movlw	.8								; EEPROM address of option opt_dive_mode
-	cpfseq	opt_eeprom						; editing opt_dive_mode right now?
+	; now some rather crude hack to correct opt_TR_mode in dependency of opt_dive_mode
+	movlw	0x20							; serial ID of option opt_dive_mode
+	cpfseq	opt_serial						; editing opt_dive_mode right now?
 	bra		option_inc_enum8_4				; NO  - check next option
 	movf	INDF1,W							; YES - get option value: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR
 	xorlw	.1								;       in CCR mode?
@@ -525,9 +555,9 @@
 
 option_inc_enum8_4:
  IFDEF _rx_functions
-	; Now some rather crude hack to advance opt_TR_mode in dependency of opt_dive_mode
-	movlw	.222							; EEPROM address of option opt_TR_mode
-	cpfseq	opt_eeprom						; editing opt_TR_mode right now?
+	; now some rather crude hack to advance opt_TR_mode in dependency of opt_dive_mode
+	movlw	0x7E							; serial ID of option opt_TR_mode
+	cpfseq	opt_serial						; editing opt_TR_mode right now?
 	bra		option_inc_enum8_5				; NO  - check next option
 	movff	opt_dive_mode,WREG				; YES - get dive mode: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR
 	decfsz	WREG,W							;       dive mode = 1 CCR?
@@ -545,7 +575,21 @@
 option_inc_enum8_4_exit:
 	return									; done
  ENDIF	; _rx_functions
+
 option_inc_enum8_5:
+ IFDEF _gas_contingency
+	; now some rather crude hack to keep contingency mode switched off if gas needs calculation is switched off
+	movlw	0x91							; serial ID of option opt_gas_contingency_dive
+	cpfseq	opt_serial						; editing opt_gas_contingency_dive right now?
+	bra		option_inc_enum8_6				; NO  - check next option
+	movff	opt_calc_gasvolume,WREG			; YES - get current setting of gas needs calculation
+	tstfsz	WREG							;     - gas needs calculation switched off?
+	return									;       NO  - done, opt_gas_contingency_dive may be switched on
+	clrf	INDF1							;       YES - force opt_gas_contingency_dive to off
+	return									;           - done
+ ENDIF	; _gas_contingency
+
+option_inc_enum8_6:
 	return
 
 
@@ -558,9 +602,8 @@
 	movff	opt_dive_mode,WREG				; get dive mode into WREG (0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR)
 	xorlw	.2								; in Gauge mode?
 	bnz		option_cleanup_gauge_1			; NO  - done
-	banksel	opt_dive_mode					; YES - setting not allowed, select options bank
-	clrf	opt_dive_mode					;     - reset to OC mode
-	banksel	common							;     - back to bank common
+	movff	WREG,opt_dive_mode				; YES - setting not allowed, WREG is zero -> reset to OC mode
+	bsf		options_changed					;     - flag that EEPROM needs to be updated
 option_cleanup_gauge_1:
 	return									; done
  ENDIF
@@ -578,7 +621,7 @@
 	banksel	opt_ccr_mode					; YES - select options bank
 	bcf		opt_ccr_mode,1					;     - clear bit 1 because opt_ccr_mode may only be 0 or 1 (reverts AutoSP to calculated SP, keeps sensor)
 	banksel	common							;     - back to bank common
-	bsf		option_repaired					;     - flag that an option was repaired
+	bsf		options_changed					;     - flag that EEPROM needs to be updated
 option_cleanup_oCCRMode_CCR:				; continue from above & jump-in from start.asm if known to be in CCR mode
  IFDEF _external_sensor
 	btfsc	analog_o2_input					; analog interface available?
@@ -593,7 +636,7 @@
 	banksel	opt_ccr_mode					;              YES - setting not allowed, select options bank
 	clrf	opt_ccr_mode					;                  - revert setting to 0 (fixed or calculated SP)
 	banksel	common							;                  - back to bank common
-	bsf		option_repaired					;                  - flag that an option was repaired
+	bsf		options_changed					;                  - flag that EEPROM needs to be updated
 	return									;                  - done
  ENDIF	; _ccr_pscr
 
@@ -611,7 +654,7 @@
 	movwf	mpr								;       YES - correct GF low to 100%
 option_cleanup_GF_1:
 	movff	mpr,opt_GF_low					; store corrected GF low
-	bsf		option_repaired					; flag that an option was repaired
+	bsf		options_changed					; flag that EEPROM needs to be updated
 option_cleanup_GF_2:
 	; cleanup alternative GF
 	movff	opt_aGF_high,WREG				; copy alternative GF high to WREG
@@ -625,7 +668,7 @@
 	movwf	mpr								;       YES - correct GF low to 100%
 option_cleanup_GF_3:
 	movff	mpr,opt_aGF_low					; store corrected GF low
-	bsf		option_repaired					; flag that an option was repaired
+	bsf		options_changed					; flag that EEPROM needs to be updated
 option_cleanup_GF_4:
 	return									; done
 
@@ -635,11 +678,11 @@
 ;
 	global	option_draw						; STRCAT FRS0 option
 option_draw:
-	; Read type, default and register from table
-	rcall	option_read
+	; read type, default and register from table
+	rcall	option_read_definition
 
-	; Switch on type
-	movf	opt_type,W
+	; switch on type
+	movf	opt_type,W						; get option type
 	bz		option_draw_uint8				; type0 = INT8
 	dcfsnz	WREG
 	bra		option_draw_enum8				; type1 = ENUM
@@ -647,7 +690,7 @@
 	bra		option_draw_string				; type2 = string
 	dcfsnz	WREG
 	bra		option_draw_uint8_depth			; type3 = INT8 with automatic display in meters or feet
-	return									; unknown, return
+	return									; unknown, do nothing
 
 option_draw_string:
 	movff	POSTINC1,POSTINC2
@@ -692,13 +735,15 @@
 
 ;---- Draw an enumerated value (set of translated strings)
 option_draw_enum8:
-	movff	INDF1,lo						; memorize current value
-	movf	INDF1,W							; copy current value to WREG
-	cpfsgt	opt_max							; max value (= highest usable value + 1) > current value?
-	clrf	WREG							; NO  - to avoid printing rubbish, reset to first value
+	movf	INDF1,W							; copy option value to WREG
+	movwf	lo								; memorize option value, too
+	cpfslt	opt_max							; option value > maximum permissible value ?
+	bra		option_draw_enum8_0				; NO  - option value allowed
+	clrf	WREG							; YES - to avoid printing rubbish, use first ENUM item instead
+option_draw_enum8_0:
 	addwf	WREG							; current value *= 2
 	addwf	opt_inc,W						; base text + 2 * current value
-	movwf	FSR1L							; load FSR0
+	movwf	FSR1L							; load FSR1
 	movlw	.0								; propagate carry...
 	addwfc	opt_min,W						; ...
 	movwf	FSR1H							; ...into FSR1
@@ -711,7 +756,6 @@
 	PUTC	"*"								; print "*"
 	return									; done
 
-
 ;-----------------------------------------------------------------------------
 
 	END
--- a/src/p2_deco.c	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/p2_deco.c	Fri Feb 28 15:45:07 2020 +0100
@@ -1,5 +1,5 @@
 // ***************************************************************************
-// p2_deco.c                                  combined next generation V3.06.1
+// p2_deco.c                                  combined next generation V3.08.8
 //
 //  Created on: 12.05.2009
 //  Author: heinrichs weikamp, contributions by Ralph Lembcke and others
@@ -35,7 +35,7 @@
 // 07/xx/2008 v102a: debug of bottom time routine
 // 09/xx/2008 v102d: Gradient Factor Model implementation
 // 10/10/2008 v104: renamed to build v103 for v118 stable
-// 10/14/2008 v104: integration of char_I_depth_last_deco for Gradient Model
+// 10/14/2008 v104: integration of char_I_last_stop_depth for Gradient Model
 // 03/31/2009 v107: integration of FONT Incon24
 // 05/23/2010 v109: 5 gas changes & 1 min timer
 // 07/13/2010 v110: cns vault added
@@ -47,7 +47,7 @@
 // 2011/02/11: [jDG] Reworked gradient-factor implementation.
 // 2011/02/15: [jDG] Fixed inconsistencies introduced by gas switch delays.
 // 2011/03/21: [jDG] Added gas consumption (CF56 & CF57) evaluation for OCR mode.
-// 2011/04/15: [jDG] Store GF_low_depth in 32 bits (w/o rounding), for a better stability.
+// 2011/04/15: [jDG] Store GF_depth in 32 bits (w/o rounding), for a better stability.
 // 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for deco planning.
 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor.
 // 2011/05/02: [jDG] Added "Future TTS" function (CF58).
@@ -59,7 +59,7 @@
 // 2012/02/25: [jDG] Looking for a more stable LOW grad factor reference.
 // 2012/09/10: [mH]  Fill char_O_deco_time_for_log for logbook write
 // 2012/10/05: [jDG] Better calc_gas_needs_ascent accuracy (average depth, switch between stop).
-// 2013/03/05: [jDG] Should vault GF_low_depth too.
+// 2013/03/05: [jDG] Should vault GF_depth too.
 // 2013/03/05: [jDG] Wrobell remark: ascent_to_first_stop works better with finer steps (2sec).
 // 2013/05/08: [jDG] A. Salm remark: NOAA tables for CNS are in ATA, not bar.
 // 2013/12/21: [jDG] Fix CNS calculation in deco plan w/o marked gas switch
@@ -123,30 +123,29 @@
 												//        0.135 bar safety margin
 
 // constants and factors
-#define ppWater							0.06270	// water vapor partial pressure in the lungs
-#define METER_TO_BAR					0.09985	// conversion factor
-#define BAR_TO_METER					10.0150	// conversion factor (1.0/METER_TO_BAR)
-#define SURFACE_DESAT_FACTOR			0.70420	// surface desaturation safety factor
-#define HYST							1.0E-06	// threshold for tissue graphics on-gassing / off-gassing visualization
+#define ppWater						 0.06270	// water vapor partial pressure in the lungs
+#define METER_TO_BAR				 0.09807	// conversion factor (1 m water column =  0.09807 bar)
+#define BAR_TO_METER				10.19716	// conversion factor (1 bar            = 10.19716 m  )
+#define SURFACE_DESAT_FACTOR		 0.70420	// surface desaturation safety factor
+#define HYST						 1.0E-06	// threshold for tissue graphics on-gassing / off-gassing visualization
 
 // thresholds
 #define CNS_LIMIT_WARNING				100		// threshold for CNS  warning
 #define CNS_LIMIT_ATTENTION				 70		// threshold for CNS  attention
 #define PRESSURE_LIMIT_WARNING			200		// threshold for pressure reading warning  : 20.0 bar
 #define PRESSURE_LIMIT_ATTENTION		500		// threshold for pressure reading attention: 50.0 bar
-#define GAS_NEEDS_LIMIT_ATTENTION		0.70	// threshold for gas needs attention [1.00 = 100%]
+#define GAS_NEEDS_ATTENTION				  0.7	// threshold for gas needs attention [1 = 100%]
 #define O2_CONSUMPTION_LIMIT_ATTENTION	 20		// threshold for O2 "SAC"         attention:  2.0 l/min
 #define ppO2_GAP_TO_SETPOINT			 10		// gap between setpoint and max. ppO2 of the pure diluent [cbar]
 #define ppO2_MARGIN_ON_MAX				  3		// [cbar] margin on ppO2 max to compensate for surface pressures > 1.000 mbar
-#define STOP_CHAINING_LIMIT				  5		// max. number of chained stop table entries before deco calculation is aborted
+#define STOP_CHAINING_LIMIT				  3		// max. number of chained stop table entries before deco calculation is aborted
 
 
 // deco engine states and modes - (char_O_)main_status: controls current tissue and deco status calculation (as-is situation)
 #define CALC_VOLUME						0x01	// =1: calculate gas needs
 #define CALCULATE_BOTTOM				0x02	// =1: calculate gas needs in deco calculator mode, =0: in dive mode
-#define CAVE_MODE						0x04	// =1: calculate ascent and gas needs using backtracking data
-#define USE_Z_FACTOR					0x08	// =1: calculate with Z factor when converting gas volumes <-> pressures
-
+#define CAVE_MODE						0x04	// =1: calculate return path and gas needs using backtracking data
+#define GAS_CONTINGENCY					0x08	// =1: use a second best gas if best gas is all used up
 #define TR_FUNCTIONS					0x10	// =1: calculate TR functions (pressure reading) processing
 #define EXTENDED_STOPS					0x20	// =1: allow placement of gas switches below the depth of the 1st stop
 
@@ -166,12 +165,12 @@
 #define CALC_ALT						0x02	// internal: calculating          an alternative deco plan
 #define COMPLETED_ALT					0x02	// output:   calculation of       an alternative deco plan has completed
 #define INITIALIZE						0x04	// input:    initialize deco engine
-#define INITIALIZE_START_NORM			0x05	// input:    initialize deco engine and start calculation of a normal       deco plan
+#define INITIALIZE_START_NORM			0x05	// input:    initialize deco engine and start calculation of a  normal      deco plan
 #define INITIALIZE_START_ALT			0x06	// input:    initialize deco engine and start calculation of an alternative deco plan
 #define DECO_CALCULATOR_MODE			0x08	// input:    deco engine is run from deco calculator
 
 #define BAILOUT_MODE					0x10	// =1: allow gas switches before first deco stop
-#define DELAYED_ASCENT					0x20	// =1: figure in a delayed ascent (fTTS)
+#define DELAYED_ASCENT					0x20	// =1: figure in a delayed ascent / delayed turn of the dive (fTTS)
 
 //      MODE_MASK						0xC0	// mask for simulated tissues mode selection
 //      MODE_LOOP						0x40	// =1: CCR (MODE_PSCR needs to be cleared) or pSCR mode
@@ -187,22 +186,22 @@
 #define DECO_WARNING_OUTSIDE			0x10	// tissue pressures outside the Buhlmann model now
 #define DECO_WARNING_OUTSIDE_lock		0x20	// tissue pressures outside the model sometime during the dive
 #define DECO_ATTENTION_OUTSIDE			0x40	// tissue pressures are very close to the Buhlmann limit
-#define DECO_WARNING_INCOMPLETE			0x80	// internal error: deco calculation incomplete
+#define DECO_WARNING_INCOMPLETE			0x80	// deco calculation incomplete due to too long compute time
 
 // deco engine status (char_O_)deco_info
 #define DECO_MODE						0x01	// =1: deco ppO2 levels are permitted
 #define IND_DOUBLE_SWITCH_FLAG			0x02	// =1: switch to other tank advice active
-//										0x04	// --- unused
+#define GAS_NEEDS_fTTS					0x04	// =1: gas needs are calculated in fTTS mode
 #define DECO_ZONE						0x08	// =1: fTTS < TTS (not updated when in bailout mode)
-#define DECO_CEILING					0x10	// =1: ceiling depth > 0
-#define DECO_STOPS						0x20	// =1: deco stops found
-#define GAS_NEEDS_CAVE					0x40	// =1: indicated gas needs are calculated in cave mode
-//										0x80	// --- unused
+#define DECO_CEILING					0x10	// =1: deco obligation (ceiling > 0)
+#define DECO_STOPS_NORM					0x20	// =1: deco stops found in normal      plan
+#define DECO_STOPS_ALT					0x40	// =1: deco stops found in alternative plan
+#define GAS_NEEDS_CAVE					0x80	// =1: indicated gas needs are calculated in cave mode
 
 
 // deco engine control - tissue_increment
-#define TIME_MASK						0x7F	// =0: time increment is 2 seconds, 1..127: time increments is 1..127 minutes
-#define TISSUE_SELECTOR					0x80	// =1: calculate on real tissues, =0: calculate on simulated tissues
+#define TIME_MASK						0x7F	// =0: time increment is 2 or 6 seconds, 1..127: time increments is 1..127 minutes
+#define TISSUE_SELECTOR					0x80	// =0: calculate on simulated tissues,   1     : calculate on real tissues
 
 
 // deco engine control - next_planning_phase
@@ -212,16 +211,30 @@
 #define PHASE_30_EXTENDED_BOTTOM_TIME	0x30	// calculate extended bottom time
 #define PHASE_40_BOTTOM_GAS_NEED		0x40	// calculate gas needs for bottom segment
 #define PHASE_50_NDL_TIME				0x50	// calculate NDL time
-#define PHASE_60_CAVE_RETURN			0x60	// calculate cave mode  return
-#define PHASE_70_OPEN_WATER_ASCENT		0x70	// calculate open water ascent
+#define PHASE_70_ASCENT_OR_RETURN		0x70	// calculate open water ascent or cave return
 #define PHASE_80_RESULTS				0x80	// results - initialization
 #define PHASE_81_RESULTS_STOPS_TABLE	0x81	// results - publish stops table
 #define PHASE_82_RESULTS_NDL			0x82	// results - publish data / within NDL
 #define PHASE_83_RESULTS_DECO			0x83	// results - publish data / in deco
 #define PHASE_84_GAS_NEEDS_PRESSURES	0x84	// results - convert gas needs from volumes to pressures
+#define PHASE_85_GAS_NEEDS_CAVE			0x85	// results - tag gas needs as calculated in cave or open water mode
 #define PHASE_90_FINISH					0x90	// finish calculation cycle
 
 
+// gas & diluent - type and availability state
+//										0x01	// | 0: disabled, 1: first, 2: normal/work, 3: deco
+//										0x02	// |
+#define GAS_TYPE_MASK					0x03	// bit mask covering the type enumerator
+#define GAS_AVAIL_LOST					0x04	// =1: gas/diluent lost   flag (permanently unavailable)
+#define GAS_AVAIL_STAGED				0x08	// =1: gas/diluent staged flag (temporary   unavailable)
+#define GAS_AVAIL_MASK					0x0C	// bit mask covering the availability flags
+#define GAS_NEED_ATTENTION				0x10	// =1: gas need >= attention threshold
+#define GAS_NEED_WARNING				0x20	// =1: gas need >= warning   threshold
+#define GAS_NEED_MASK					0x30	// bit mask covering the need flags
+#define GAS_NEARLY_USED_UP				0x40	// =1: the gas is nearly used up (= at attention threshold)
+#define GAS_FULLY_USED_UP				0x80	// =1: the gas is fully  used up (= at warning   threshold)
+
+
 // flags used with integer numbers
 #define INT_FLAG_INVALID				0x0400	// =1: value not valid
 #define INT_FLAG_NOT_COMPUTED_YET		0x0800	// =1: value not computed yet
@@ -264,26 +277,31 @@
 static void			 calc_tissues(void);				// Updates the tissues   dependent on the partial pressures of N2 and He.
 static void			 calc_CNS(void);					// Updates the CNS value dependent on the partial pressure  of the O2.
 static void			 calc_limit(PARAMETER float GF_current);
-														// Calculates ceiling, current GF (supersaturation) and some more data.
+														// Calculates ceiling, current supersaturation factor and some more data.
 
 // Functions for TR
 #ifdef _rx_functions
 static void			 calc_TR_functions(void);			// Calculates SAC etc.
 #endif
 
+// Functions for Cave Mode
+#ifdef _cave_mode
+static void			 read_backtrack_data(void);			// Gets the data of the next backtracking data set
+#endif
+
 // Functions dedicated to Deco Calculations
 static void			 clear_deco_table(void);			// Clears the deco stops table, invoked at the start of each calculation cycle.
-static void			 gas_take_current(void);			// Sets the first gas used for deco calculation, invoked at start of cycle, too.
+static void			 gas_take_current(void);			// Take the actual currently used gas for ascent & deco calculation
 static unsigned char gas_find_best(void);				// Searches for the best gas available.
 static void			 gas_take_best(void);				// Switches to the best gas that has been found found before by gas_find_best().
 static void			 gas_set_ratios(void);				// Sets the gas ratios for use in deco calculation (simulated tissues),
 														// needs to be called after each gas change (gas_take_current/_better).
 static void			 calc_NDL_time_tissue(void);		// Calculates the remaining NDL time for a given tissue.
 static unsigned char find_next_stop(void);				// Finds the next stop when in a deco ascent.
-static unsigned char update_deco_table(PARAMETER unsigned char time_increment);
+static void			 update_deco_table(PARAMETER unsigned char time_increment);
 														// Enters a new stop or extends an existing stop in the deco stops table.
-static void			 calc_due_by_depth_time_sac(void);	// Calculates gas volume required for a given depth, time and usage (SAC rate).
-static void			 convert_gas_needs_to_press(void);	// Converts gas volumes into pressures and sets respective flags.
+static void			 calc_required_volume(void);		// Calculates gas volume required for a given depth, time and usage (SAC rate).
+static void			 convert_volume_to_pressure(void);	// Converts gas volumes into pressures and sets respective flags.
 
 // Functions for Results Reporting
 static void			 publish_deco_table(void);			// Copies the internal deco stops table to the export interface.
@@ -305,7 +323,6 @@
 static void			 adopt_Buhlmann_coefficients(void);	// Computes average a and b coefficient by the N2/He tissue ratio.
 static void			 push_tissues_to_vault(void);		// Stores the state of the real tissues during simulator runs.
 static void			 pull_tissues_from_vault(void);		// Restores the state of the real tissues after a simulator run.
-static void			 calc_sim_pres_respiration(void);	// Calculate sim_pres_respiration from char_depth_sim.
 static void			 calc_N2_equilibrium(void);			// Calculate partial pressure of N2 in respired air at surface pressure.
 static void			 get_saturation_factors(void);		// Get, safeguard and convert the saturation and desaturation factors.
 static void			 apply_saturation_factors(void);	// Applies saturation and desaturation factors.
@@ -322,15 +339,19 @@
 #   pragma udata bank5=0x500
 #endif
 
-// Environmental and Gas Data (52 byte)
+// Data that go into the deco data vault (4 byte)
+
+static float			CNS_fraction_real;				// || current real CNS (1.00 = 100%)
+
+
+// Environmental and Gas Data (51 byte)
 
 static float			pres_surface;					// absolute pressure at the surface
 
 static float			float_depth_real;				// current real               depth in meters, float
 static unsigned char	char_depth_real;				// current real               depth in meters, integer
-static unsigned char	char_depth_sim_start;			// start   value of simulated depth in meters, integer
+static unsigned char	char_depth_start;				// start   value of simulated depth in meters, integer
 static unsigned char	char_depth_sim;					// current value of simulated depth in meters, integer
-static unsigned char	char_depth_last;				// last    value of simulated depth in meters, integer
 
 static float			real_pres_respiration;			// current real depth in absolute pressure
 static float			real_O2_ratio;					// real breathed gas oxygen ratio
@@ -345,33 +366,32 @@
 static float			sim_pSCR_drop;					// simulated ppO2 drop in pSCR loop
 
 
-// general Deco Parameters (57 byte)
+// general Deco Parameters (64 byte)
 
 static float			GF_low;							// gradient factor to determine 1st stop
 static float			GF_high;						// gradient factor to determine surfacing
 
-static unsigned char	GF_low_last;					// last GF low,  used to detect changes
-static unsigned char	GF_high_last;					// last GF high, used to detect changes
-
-static unsigned char	GF_low_depth;					// GF low reference depth in current calculation cycle
-static unsigned char	GF_low_depth_norm;				// GF low reference depth in normal plan
-static unsigned char	GF_low_depth_alt;				// GF low reference depth in alternative plan
-
-static float			GF_slope;						// (GF_high - GF_low) / GF_low_depth      in current calculation cycle
-static float			GF_slope_norm;					// (GF_high - GF_low) / GF_low_depth_norm in normal plan
-static float			GF_slope_alt;					// (GF_high - GF_low) / GF_low_depth_alt  in alternative plan
-
-static float			float_ascent_speed;				// ascent speed from options_table (5.0 .. 10.0 m/min)
-static float			float_deco_distance;			// additional depth below stop depth - not used any more
+static unsigned char	GF_low_last;					// last GF low,  used to detect a GF change
+static unsigned char	GF_high_last;					// last GF high, used to detect a GF change
+
+static unsigned char	GF_depth;						// GF low reference depth in current calculation cycle
+static unsigned char	GF_depth_norm;					// GF low reference depth in normal plan
+static unsigned char	GF_depth_alt;					// GF low reference depth in alternative plan
+
+static float			GF_slope;						// (GF_high - GF_low) / GF_depth      in current calculation cycle
+static float			GF_slope_norm;					// (GF_high - GF_low) / GF_depth_norm in normal plan
+static float			GF_slope_alt;					// (GF_high - GF_low) / GF_depth_alt  in alternative plan
+
 static float			float_saturation_multiplier;	// safety factor for  on-gassing rates
 static float			float_desaturation_multiplier;	// safety factor for off-gassing rates
 
 static unsigned char	split_N2_He[NUM_COMP];			// used for calculating the desaturation time
-
-
-// real Context: what we are doing now (16 byte)
-
-static float			CNS_fraction_real;				// current real CNS (1.00 = 100%)
+static unsigned char	deco_gas_type[NUM_GAS];			// type and state of the deco gases
+static unsigned char	peer_tank[NUM_GAS];				// bit flag vector indicating peer tanks holding same gas
+
+
+// real Context: what we are doing now (12 byte)
+
 static unsigned short	IBCD_tissue_vector;				// 16 bit vector to memorize all tissues that experience IBCD
 
 static float			pres_respiration_sac;			// used in SAC calculation: current depth in absolute pressure
@@ -394,38 +414,112 @@
 
 static float			ceiling;						// minimum tolerated relative pressure (i.e. without surface pressure)
 static float			lead_supersat;					// supersaturation of the leading tissue, 1.0 = 100%
-static unsigned char	lead_tissue;					// number of the leading tissue
+static unsigned char	lead_tissue;					// number of the leading tissue (0-15)
 
 
 // Transfer Variables between calc_desaturation_time() and calc_desaturation_time_helper() (18 byte)
 
 static float			desat_factor;					// used to cache a pre-computed factor
-static float			var_ht;							// buffer for a half-time factor
-static float			pres_target;					// target pressure for a compartment
-static float			pres_actual;					// current pressure of the compartment
+static float			var_ht;							// half-time factor for the compartment
+static float			pres_target;					// target  pressure for the compartment
+static float			pres_actual;					// current pressure of  the compartment
 static unsigned short	int_time;						// time it takes for the compartment to reach the target pressure
 
 
-// Gas in Use and Gas Needs (26 byte)
+// Gas in Use and Gas Needs (67 byte)
+
+static unsigned char	start_gas_num;					// number of the gas/dil to start with
 
 static unsigned char	sim_gas_last_num;				// number       of the last      used gas
 static unsigned char	sim_gas_current_num;			// number       of the currently used gas
 static unsigned char	sim_gas_current_depth;			// change depth of the currently used gas
 
-static unsigned char	sim_gas_best_num;				// number       of the better gas
-static unsigned char	sim_gas_best_depth;				// change depth of the better gas
+static unsigned char	sim_gas_best_num;				// number       of the best gas available
+static unsigned char	sim_gas_best_depth;				// change depth of the best gas available
 
 static unsigned char	gas_needs_gas_index;			// index to the gas and tank data arrays
-static float			gas_volume_need[NUM_GAS];		// gas volumes required  for return/ascent in liters
-static float			gas_volume_avail[NUM_GAS];		// gas volumes available for return/ascent in liters
-
-
-// Transfer Variables for calc_due_by_depth_time_sac() (7 byte)
+static float			gas_volume_need[NUM_GAS];		// gas volumes required  for ascent / cave return in liters
+static float			gas_volume_avail[NUM_GAS];		// gas volumes available for ascent / cave return in liters
+static float			gas_volume_atten[NUM_GAS];		// attention threshold for gas volumes available
+
+
+// Transfer Variables for calc_required_volume() (7 byte)
 
 static unsigned char	gas_needs_depth;				// depth of the stop or half-way point
-static unsigned char	gas_needs_time;					// duration of the stop or ascent phase
+static unsigned char	gas_needs_time;					// duration of the stop, ascent or travel phase
 static unsigned char	gas_needs_usage_rate;			// gas usage in l/min
-static float			gas_needs_volume_due;			// computed due of gas volume required
+static float			gas_needs_volume_due;			// computed amount of required gas volume
+
+
+// 243 byte used, 13 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char)
+
+
+//---- Bank 6 parameters -----------------------------------------------------
+#ifndef UNIX
+#   pragma udata bank6=0x600
+#endif
+
+// Timer5 Interface (3 byte) - Attention: keep order and keep at beginning of bank 6, i.e. at address 0x600 !
+
+static volatile unsigned short	tmr5_value;				// | timer 5 value buffer		MUST be at address 0x600
+static volatile unsigned char	tmr5_overflow;			// | timer 5 overflow flag	MUST be at address 0x602
+
+
+// Modes, Sequencing and Indexing (14 byte)
+
+static unsigned char	main_status;					// shadow register for char_O_main_status
+static unsigned char	deco_status;					// shadow register for char_O_deco_status
+static unsigned char	deco_info;						// shadow register for char_O_deco_info
+static unsigned char	deco_warnings;					// shadow register for char_O_deco_warnings
+static unsigned char	next_planning_phase;			// next calculation phase to be executed
+static unsigned char	tissue_increment;				// selector for real/simulated tissues and time increment
+static unsigned char	sequence_timer;					// timer to sequence deco engine tasks
+static unsigned char	ci;								// index to the Buhlmann tables (compartment index)
+static unsigned char	cns_i;							// index to the CNS      tables (ppO2 range  index)
+static unsigned char	i;								// general purpose loop counter and index
+static unsigned char	j;								// general purpose loop counter and index
+static unsigned char	stop_index;						// current stop table position
+static unsigned char	chained_stops;					// counter for chained stop entries
+static unsigned char	backtrack_index;				// index into the depth backtracking array char_I_backtrack_storage
+static unsigned char	backtrack_target_depth;			// current backtracking target depth
+static unsigned char	backtrack_step_counter;			// counter for number of 1/10 minute steps done
+
+
+// Result Values from Calculation Functions (28 byte)
+
+static float			ppO2_O2;						// ppO2 calculated for breathing pure oxygen in OC   mode
+static float			ppO2_OC;						// ppO2 calculated for breathing current gas in OC   mode
+static float			ppO2_pSCR;						// ppO2 calculated for breathing current gas in pSCR mode
+
+static float			ppO2;							// partial pressure of breathed oxygen
+static float			ppN2;							// partial pressure of breathed nitrogen
+static float			ppHe;							// partial pressure of breathed helium
+
+static unsigned char	char_ppO2;						// partial pressure of breathed oxygen, 100 = 1.00 bar
+static unsigned char	NDL_time;						// time in full minutes until reaching  no-deco limit (NDL)
+static unsigned short	TTS_time;						// time in 1/10 minutes until finishing ascent / cave return
+static unsigned short	TST_time;						// time in full minutes of all stops in ascent / cave return
+
+
+// Buhlmann Model Parameters (40 byte)
+
+static float			var_N2_a;						// Buhlmann a for current N2 tissue
+static float			var_N2_b;						// Buhlmann b for current N2 tissue
+static float			var_He_a;						// Buhlmann a for current He tissue
+static float			var_He_b;						// Buhlmann b for current He tissue
+static float			var_a;							// Buhlmann a adopted to current N2/He ratio
+static float			var_b;							// Buhlmann b adopted to current N2/He ratio
+static float			var_N2_e;						// exposition for current N2 tissue
+static float			var_He_e;						// exposition for current He tissue
+static float			var_N2_ht;						// half-time  for current N2 tissue
+static float			var_He_ht;						// half-time  for current He tissue
+
+
+// CNS Coefficients (10 byte)
+
+static float			var_cns_gain;					// two coefficients approximation, gain
+static float			var_cns_offset;					// two coefficients approximation, offset
+static unsigned short	var_cns_value;					// one coefficient  approximation, value
 
 
 // Auxiliary Variables for Data Buffering (28 byte)
@@ -439,87 +533,10 @@
 static float			old_pres_respiration;			// auxiliary variable to buffer sim_pres_respiration
 
 
-// 244 byte used, 12 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char)
-
-
-//---- Bank 6 parameters -----------------------------------------------------
-#ifndef UNIX
-#   pragma udata bank6=0x600
-#endif
-
-// Timer5 Interface (3 byte) - Attention: keep order and keep at beginning of bank 6, i.e. at address 0x600 !
-
-static volatile unsigned short	tmr5_value;				// timer 5 value buffer		MUST be at address 0x600
-static volatile unsigned char	tmr5_overflow;			// timer 5 overflow flag	MUST be at address 0x602
-
-
-// Modes, Sequencing and Indexing (12 byte)
-
-static unsigned char	main_status;					// shadow register for char_O_main_status
-static unsigned char	deco_status;					// shadow register for char_O_deco_status
-static unsigned char	deco_info;						// shadow register for char_O_deco_info
-static unsigned char	deco_warnings;					// shadow register for char_O_deco_warnings
-static unsigned char	next_planning_phase;			// next calculation phase to be executed
-static unsigned char	tissue_increment;				// selector for real/simulated tissues and time increment
-static unsigned char	sequence_timer;					// timer to sequence deco engine tasks
-static unsigned char	ci;								// index to the Buhlmann tables (compartment index)
-static unsigned char	cns_i;							// index to the CNS      tables (ppO2 range  index)
-static unsigned char	i;								// general purpose loop counter and index
-static unsigned char	fast;							// selects 1 minute or 2 second ascent steps
-static unsigned char	stop_index;						// current stop table position
-static unsigned char	chained_stops;					// counter for chained stop entries
-
-
-// Result Values from Calculation Functions (28 byte)
-
-static float			O2_ppO2;						// ppO2 - calculated for pure oxygen at current depth
-static float			OC_ppO2;						// ppO2 - calculated for breathing in OC   mode
-static float			pSCR_ppO2;						// ppO2 - calculated for breathing in pSCR mode
-
-static float			ppO2;							// partial pressure of breathed oxygen
-static float			ppN2;							// partial pressure of breathed nitrogen
-static float			ppHe;							// partial pressure of breathed helium
-
-static unsigned char	char_ppO2;						// partial pressure of breathed oxygen, as integer 100 = 1.00 bar
-static unsigned char	NDL_time;						// time in minutes until reaching NDL
-static unsigned short	ascent_time;					// time in minutes needed for the ascent
-
-
-// Buhlmann Model Parameters (40 byte)
-
-static float			var_N2_a;						// Buhlmann a, for current N2 tissue
-static float			var_N2_b;						// Buhlmann b, for current N2 tissue
-static float			var_He_a;						// Buhlmann a, for current He tissue
-static float			var_He_b;						// Buhlmann b, for current He tissue
-static float			var_a;							// Buhlmann a, adopted to current N2/He ratio
-static float			var_b;							// Buhlmann b, adopted to current N2/He ratio
-static float			var_N2_e;						// exposition, for current N2 tissue
-static float			var_He_e;						// exposition, for current He tissue
-static float			var_N2_ht;						// half-time,  for current N2 tissue
-static float			var_He_ht;						// half-time,  for current He tissue
-
-
-// CNS Coefficients (10 byte)
-
-static float			var_cns_a;						// two coefficients approximation, gain
-static float			var_cns_b;						// two coefficients approximation, offset
-static unsigned short	var_cns_c;						// one coefficient  approximation, value
-
-
-// Vault to back-up & restore Tissue related Data (134 byte)
-
-static float			vault_pres_tissue_N2[NUM_COMP];	// stores the nitrogen tissue pressures
-static float			vault_pres_tissue_He[NUM_COMP];	// stores the helium tissue pressures
-static float			vault_CNS_fraction_real;		// stores current CNS (float representation)
-static unsigned char	vault_deco_warnings;			// stores warnings status
-static unsigned char	vault_deco_info;				// stores info status
-
-
-// Transfer values for convert_float_int and convert_float_to_char() (7 byte)
+// Transfer Values for convert_float_to_int() (6 byte)
 
 static float			float_value;					// input value,   float
 static unsigned short	int_value;						// output value, 16 bit
-static unsigned char	char_value;						// output value,  8 bit
 
 
 // Performance Profiling (4 byte)
@@ -532,7 +549,7 @@
 // 7 byte occupied by compiler-placed vars
 
 
-// 245 byte used, 11 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char)
+// 139 byte used, 117 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char)
 
 
 
@@ -548,7 +565,15 @@
 static unsigned char	internal_deco_gas[NUM_STOPS];	// gases used on the stops (0 / 1-5)
 
 
-// 96 byte used, 160 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char)
+// Vault to back-up & restore Tissue related Data (134 byte)
+
+static float			vault_pres_tissue_N2[NUM_COMP];	// stores the nitrogen tissue pressures
+static float			vault_pres_tissue_He[NUM_COMP];	// stores the helium   tissue pressures
+static float			vault_CNS_fraction_real;		// stores CNS percentage (1.0 = 100%)
+static unsigned char	vault_deco_warnings;			// stores warnings status
+static unsigned char	vault_deco_info;				// stores info     status
+
+// 230 byte used, 26 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char)
 
 
 //---- Bank 7 parameters -----------------------------------------------------
@@ -591,12 +616,39 @@
 // *********************************************************************************************************************************
 
 #ifndef UNIX
+#   pragma romdata Buhlmann_ht = 0x1DC00  // needs to be in the UPPER bank
+#endif
+
+rom const float Buhlmann_ht[2*16] = {
+// Compartment half-times, in minutes
+//--- N2 ---- He ----------------------
+	  4.0,    1.51,
+	  8.0,    3.02,
+	 12.5,    4.72,
+	 18.5,    6.99,
+	 27.0,   10.21,
+	 38.3,   14.48,
+	 54.3,   20.53,
+	 77.0,   29.11,
+	109.0,   41.20,
+	146.0,   55.19,
+	187.0,   70.69,
+	239.0,   90.34,
+	305.0,  115.29,
+	390.0,  147.42,
+	498.0,  188.24,
+	635.0,  240.03
+};
+
+
+#ifndef UNIX
 #   pragma romdata CNS_tables = 0x1DC80  // needs to be in the UPPER bank
 #endif
 
-rom const float CNS_ab[2*11] = {
-// CNS increment per 2 sec = 1 / (a*ppO2 + b) with ppO2 in [cbar]
-//   a          b       for ppO2 cbar range
+rom const float CNS_2_approx[2*11] = {
+// 2 coefficient approximation for ppO2 = 51 ... 160 cbar
+// CNS increment per 2 sec = 1 / (gain*ppO2 + offset) with ppO2 in [cbar]
+//   gain       offset      for ppO2 cbar range
 	-533.07,    54000,	//  51 -  60   (index  0)
 	-444.22,    48600,	//  61 -  70   (index  1)
 	-355.38,    42300,	//  71 -  80   (index  2)
@@ -610,9 +662,10 @@
 	-222.11,    37350	// 151 - 160   (index 10)
 };
 
-rom const unsigned short CNS_c[1*18] = {
-//  CNS increment per 2 sec = c / 100000.0
-//   c in [1/100000]   for ppO2 cbar range
+rom const unsigned short CNS_1_approx[1*18] = {
+// 1 coefficient approximation for ppO2 = 161 ... 250 cbar
+// CNS increment per 2 sec = c / 100000.0
+//  value in [1/100000]    for ppO2 cbar range
 	  75,				// 161 - 165   (index  0)
 	 102,				// 166 - 170   (index  1)
 	 136,				// 171 - 175   (index  2)
@@ -635,12 +688,13 @@
 
 
 #ifndef UNIX
-#   pragma romdata Buhlmann_tables = 0x1DD00  // needs to be in the UPPER bank
+#   pragma romdata Buhlmann_ab = 0x1DD00  // needs to be in the UPPER bank
 #endif
 
 rom const float Buhlmann_ab[4*16] = {
+// Compartment a and b factors
 // Data ZH-L16C, from Bühlmann Tauchmedizin 2002, option 1a (4mn)
-// a for N2    b for N2     a of He     b for He
+// a for N2    b for N2    a for He    b for He
 	1.2599,     0.5050,     1.7424,     0.4245,
 	1.0000,     0.6514,     1.3830,     0.5747,
 	0.8618,     0.7222,     1.1919,     0.6527,
@@ -659,30 +713,14 @@
 	0.2327,     0.9653,     0.5119,     0.9267
 };
 
-rom const float Buhlmann_ht[2*16] = {
-// Compartment half-life, in minutes
-//--- N2 ---- He ----------------------
-	  4.0,    1.51,
-	  8.0,    3.02,
-	 12.5,    4.72,
-	 18.5,    6.99,
-	 27.0,   10.21,
-	 38.3,   14.48,
-	 54.3,   20.53,
-	 77.0,   29.11,
-	109.0,   41.20,
-	146.0,   55.19,
-	187.0,   70.69,
-	239.0,   90.34,
-	305.0,  115.29,
-	390.0,  147.42,
-	498.0,  188.24,
-	635.0,  240.03
-};
-
-rom const float e2secs[2*16] = {
-// Integration constant for 2 seconds,
-// result of  1 - 2^(-1/(2sec/60sec * HT))
+
+#ifndef UNIX
+#   pragma romdata e_tables = 0x1DE00  // needs to be in the UPPER bank
+#endif
+
+rom const float e2sec[2*16] = {
+// Integration constants for 2 seconds,
+// result of  1 - 2^(-(2sec/60sec / HT))
 //---- N2 ------------- He ------------
 	5.75958E-03,    1.51848E-02,
 	2.88395E-03,    7.62144E-03,
@@ -703,9 +741,32 @@
 //-------------------------------------
 };
 
+rom const float e6sec[2*16] = {
+// Integration constants for 6 seconds,
+// result of  1 - 2^(-(6sec/60sec / HT))
+//---- N2 ------------- He ------------
+	1.71794E-02,    4.48661E-02,
+	8.62691E-03,    2.26905E-02,
+	5.52983E-03,    1.45780E-02,
+	3.73973E-03,    9.86726E-03,
+	2.56392E-03,    6.76591E-03,
+	1.80815E-03,    4.77549E-03,
+	1.27570E-03,    3.37057E-03,
+	8.99786E-04,    2.37830E-03,
+	6.35713E-04,    1.68098E-03,
+	4.74646E-04,    1.25514E-03,
+	3.70598E-04,    9.80064E-04,
+	2.89978E-04,    7.66971E-04,
+	2.27236E-04,    6.01040E-04,
+	1.77714E-04,    4.70075E-04,
+	1.39176E-04,    3.68157E-04,
+	1.09151E-04,    2.88734E-04
+//-------------------------------------
+};
+
 rom const float e1min[2*16] = {
-// Integration constant for 1 minute,
-// result of  1 - 2^(-1/HT)
+// Integration constants for 1 minute,
+// result of  1 - 2^(-(1min / HT))
 //----- N2 --------- e 1min He --------
 	1.59104E-01,    3.68109E-01,
 	8.29960E-02,    2.05084E-01,
@@ -727,8 +788,8 @@
 };
 
 rom const float e10min[2*16] = {
-// Integration constant for 10 minutes,
-//  result of  1 - 2^(-10/ht)
+// Integration constants for 10 minutes,
+// result of  1 - 2^(-(10min / HT))
 //---- N2 -------------- He -----------
 	8.23223E-01,    9.89851E-01,
 	5.79552E-01,    8.99258E-01,
@@ -853,7 +914,7 @@
 
 
 //////////////////////////////////////////////////////////////////////////////
-// Read CNS coefficients a and b
+// Read CNS coefficients gain and offset
 //
 static void read_CNS_ab_coefficient(void)
 {
@@ -869,9 +930,9 @@
 #endif
 
 	{
-		overlay rom const float* ptr = &CNS_ab[2*cns_i];
-		var_cns_a = *ptr++;
-		var_cns_b = *ptr++;
+		overlay rom const float* ptr = &CNS_2_approx[2*cns_i];
+		var_cns_gain   = *ptr++;
+		var_cns_offset = *ptr++;
 	}
 }
 
@@ -893,8 +954,8 @@
 #endif
 
 	{
-		overlay rom const unsigned short* ptr = &CNS_c[cns_i];
-		var_cns_c = *ptr++;
+		overlay rom const unsigned short* ptr = &CNS_1_approx[cns_i];
+		var_cns_value = *ptr++;
 	}
 }
 
@@ -937,7 +998,7 @@
 #ifndef CROSS_COMPILE
 	// Note: We don't use far ROM pointer, because handling
 	//       24 bit is to complex, hence we have to set the
-	//       UPPER page ourself...
+	//       UPPER page by hand...
 	//       -> set to zero if tables are moved to lower pages!
 	_asm
 		movlw	1
@@ -950,15 +1011,27 @@
 	// Integration Intervals
 	switch(period)
 	{
-	case 0: //---- 2 sec -----------------------------------------------------
+	case 0: //---- 2 or 6 seconds --------------------------------------------
 		{
-			overlay rom const float* ptr = &e2secs[2*ci];
-			var_N2_e = *ptr++;
-			var_He_e = *ptr++;
+			// check which tissues are selected
+			if(tissue_increment & TISSUE_SELECTOR)
+			{
+				// real tissues - 2 seconds
+				overlay rom const float* ptr = &e2sec[2*ci];
+				var_N2_e = *ptr++;
+				var_He_e = *ptr++;
+			}
+			else
+			{
+				// simulated tissues - 6 seconds
+				overlay rom const float* ptr = &e6sec[2*ci];
+				var_N2_e = *ptr++;
+				var_He_e = *ptr++;
+			}
 		}
 		break;
 
-	case 1: //---- 1 min -----------------------------------------------------
+	case 1: //---- 1 minutes -------------------------------------------------
 		{
 			overlay rom const float* ptr = &e1min[2*ci];
 			var_N2_e = *ptr++;
@@ -966,7 +1039,7 @@
 		}
 		break;
 
-	case 2: //---- 10 min ----------------------------------------------------
+	case 2: //---- 10 minutes ------------------------------------------------
 		{
 			overlay rom const float* ptr = &e10min[2*ci];
 			var_N2_e = *ptr++;
@@ -1040,20 +1113,6 @@
 
 
 //////////////////////////////////////////////////////////////////////////////
-// Calculate sim_pres_respiration from char_depth_sim
-//
-// Input:  char_depth_sim        simulated depth in meters
-//         pres_surface          surface pressure
-//
-// Output: sim_pres_respiration  simulated depth in absolute pressure
-//
-static void calc_sim_pres_respiration(void)
-{
-	sim_pres_respiration = (float)char_depth_sim * METER_TO_BAR + pres_surface;
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
 // Calculate partial pressure of N2 in respired air at surface pressure
 //
 // Input:  pres_surface     surface pressure
@@ -1120,18 +1179,6 @@
 }
 
 
-//////////////////////////////////////////////////////////////////////////////
-// convert_float_to_char
-//
-// Converts a float within range 0.0 - 255 into 8 bit integer
-//
-static void convert_float_to_char(void)
-{
-		if      (float_value <    0.0) char_value = 0;
-		else if (float_value >= 254.5) char_value = 255;
-		else                           char_value = (unsigned char)(float_value + 0.5);
-}
-
 
 // *********************************************************************************************************************************
 //
@@ -1299,25 +1346,23 @@
 //
 // INPUT, fixed during dive:
 //        pres_surface             : surface pressure (as absolute pressure)
-//        char_I_depth_last_deco   : depth of the last deco stop
+//        char_I_last_stop_depth   : depth of the last deco stop
 //
 // INPUT, may change during dive:
 //        GF_high                  : GF high factor
 //        GF_low                   : GF low  factor
-//
-// INPUT & OUTPUT
+//        GF_depth                 : GF low  reference depth
+//        GF_slope                 : GF slope
+//
+// MODIFIED
 //        char_depth_sim           : simulated depth in meters
-//        GF_low_depth             : GF low  depth in current calculation cycle
-//        GF_slope                 : GF slope      in current calculation cycle
-//        GF_low_depth_norm/_alt   : frozen GF low depth reference
-//        GF_slope_norm/_alt       : frozen GF slope
 //
 // OUTPUT
-//        char_depth_last          : depth we came from
-//        sim_pres_respiration     : simulated depth in absolute pressure
+//        GF_depth_norm/_alt       : updated GF low depth reference
+//        GF_slope_norm/_alt       : updated GF slope
 //
 // RETURN
-//        TRUE: a stop is needed, FALSE: no stop needed
+//        TRUE: a deco stop is required, FALSE: no deco stop required
 //
 static unsigned char find_next_stop(void)
 {
@@ -1325,63 +1370,72 @@
 	overlay unsigned char depth_limit;
 	overlay unsigned char stop_depth;
 	overlay unsigned char next_stop;
-	overlay unsigned char need_stop;
-
-
-	// memorize the depth we came from
-	char_depth_last = char_depth_sim;
-
-	// calculate the ceiling (minimum relative pressure) for the current depth
-	     if( char_I_deco_model == 0            ) calc_limit(1.0);											// deco or not - straight Buhlmann
-	else if( NDL_time                          ) calc_limit(GF_high);										// not in deco
-	else if( char_depth_sim    >= GF_low_depth ) calc_limit(GF_low);										// in deco with GF, below or at low depth reference
-	else                                         calc_limit(GF_high - GF_slope * (float)char_depth_sim);	// in deco with GF, above       low depth reference
-
-	// convert the ceiling from relative pressure to meters,
-	// rounded up (i.e. made deeper) to next full meter,
-	// limiting at surface.
-	depth_limit = (ceiling > 0.0) ? (unsigned char)(ceiling * BAR_TO_METER + 0.99) : 0;
-
-	// calculate the stop depth, i.e. round up (make deeper) to
-	// the next multiple of 3 meters using integer arithmetics
-	stop_depth = 3 * ( (depth_limit + 2) / 3 );
-
-	// apply correction for the shallowest stop
-	if( stop_depth == 3 ) stop_depth = char_I_depth_last_deco;
-
-	// compute depth in meters that will be reached in 1 minute of ascent
-	// at a speed of char_I_ascent_speed (5..10 m/min)
-	if( char_depth_sim > char_I_ascent_speed )
+
+
+	// calculate the current deco ceiling (minimum relative pressure)
+	     if( char_I_model   == 0        ) calc_limit(1.0);											// straight Buhlmann
+	else if( NDL_time                   ) calc_limit(GF_high);										// with GF: not in deco
+	else if( char_depth_sim >= GF_depth ) calc_limit(GF_low);										//          in deco, below or at low depth reference
+	else                                  calc_limit(GF_high - GF_slope * (float)char_depth_sim);	//          in deco, above       low depth reference
+
+	// convert the deco ceiling from relative pressure to meters,
+	// rounded up (i.e. made deeper) to the next full meter
+	depth_limit = (unsigned char)(ceiling * BAR_TO_METER + 0.99);
+
+
+#ifdef _cave_mode
+	// in cave or open water mode?
+	if( main_status & CAVE_MODE )
 	{
-		depth_1min = char_depth_sim - char_I_ascent_speed;
+		// cave mode
+
+		// does backtracking require descent or keeping depth?
+		if( backtrack_target_depth >= char_depth_sim )
+		{
+			// YES - decent to target depth or stay at current depth
+			char_depth_sim = backtrack_target_depth;
+
+			//     - done, no stop required
+			return(0);
+		}
+		else
+		{
+			// NO
+
+			// target depth requires an ascent - determine ascent limit due to deco obligation
+			stop_depth = depth_limit;
+
+			// apply correction for the shallowest stop
+			if( stop_depth && (stop_depth < char_I_last_stop_depth) ) stop_depth = char_I_last_stop_depth;
+		}
 	}
 	else
+#endif
 	{
-		depth_1min = 0;
+		// open water vertical ascent mode - determine the stop depth
+
+		// stop depth is depth limit rounded up (made deeper) to the next multiple of 3 meters
+		stop_depth = 3 * ( (depth_limit + 2) / 3 );
+
+		// apply correction for the shallowest stop
+		if( stop_depth == 3 ) stop_depth = char_I_last_stop_depth;
 	}
 
-	// is the stop depth shallower than the depth that can be reached within 1 minute,
-	// or are we allowed to surface AND can we reach the surface within 1 minute?
-	if(    ( ( stop_depth <  depth_1min )                        )
-	    || ( ( stop_depth == 0          ) && ( depth_1min == 0 ) )
-	  )
+	// is the stop depth shallower than the current depth (can we ascent)?
+	if( stop_depth < char_depth_sim )
 	{
-		// YES - report the depth that will be reached within 1 minute of ascent
-		char_depth_sim = depth_1min;
-
-		//     - no stop needed
-		need_stop = 0;
-
-		//     - done
-		goto done;
+		// YES - ascent by 1 meter
+		char_depth_sim--;
+
+		// done, no stop needed
+		return(0);
 	}
 
 	// -----------------------------------------------------------------------
-	// we need to make a stop now, or need to stay at the current stop depth
+	// we need to make a stop because we are not allowed to ascent any further
 	// -----------------------------------------------------------------------
 
-	// set stop data
-	need_stop      = 1;
+	// set depth to stop depth
 	char_depth_sim = stop_depth;
 
 	// Apply correction in case the stop is to be placed deeper than a
@@ -1393,115 +1447,113 @@
 	// the duration of the deco stop itself.
 	if( 0              < internal_deco_depth[stop_index] )
 	if( char_depth_sim > internal_deco_depth[stop_index] )
-		char_depth_sim = internal_deco_depth[stop_index];
-
-	// done so far if using straight Buhlmann
-	if( char_I_deco_model == 0 ) goto done;
+	    char_depth_sim = internal_deco_depth[stop_index];
+
+	// if using straight Buhlmann: done, stop needed
+	if( char_I_model == 0 ) return(1);
 
 	// -----------------------------------------------------------------------
 	// we need to make or hold a stop and we are using the GF extension
 	// -----------------------------------------------------------------------
 
-	// is the stop depth deeper than the GF low depth reference used up to now?
-	if( stop_depth > GF_low_depth )
+	// is the stop_depth deeper than the GF low depth reference used up to now?
+	if( stop_depth > GF_depth )
 	{
-		// YES - update the reference
-		GF_low_depth = stop_depth;
-		GF_slope     = (GF_high - GF_low) / (float)GF_low_depth;
+		// YES - update the GF low depth reference
+		GF_depth = stop_depth;
+		GF_slope = (GF_high - GF_low) / (float)GF_depth;
 
 		// store for use in next cycles
 		if( deco_status & CALC_NORM )
 		{
-			GF_low_depth_norm = GF_low_depth;
-			GF_slope_norm     = GF_slope;
+			GF_depth_norm = GF_depth;
+			GF_slope_norm = GF_slope;
 		}
 		else
 		{
-			GF_low_depth_alt = GF_low_depth;
-			GF_slope_alt     = GF_slope;
+			GF_depth_alt = GF_depth;
+			GF_slope_alt = GF_slope;
 		}
 	}
 
-	// We have a (first) stop. But with a steep GF slope, the stop(s) after this
-	// first stop may be allowed to ascent to, too. This is because the gradient
+#ifdef _cave_mode
+	// if in cave mode: done, stop needed
+	if( main_status & CAVE_MODE ) return(1);
+#endif
+
+	// We have a stop depth candidate. But with a steep GF slope, the stop(s) after
+	// this first stop may be allowed to ascent to, too. This is because the gradient
 	// factor that will be used at the next depth(s) will allow more tissue super-
-	// saturation, maybe so much more that the next stop(s) will be allowed to
-	// ascent to. So we have to probe the next stops that are within the reach of
-	// 1 minute of ascent as well.
+	// saturation, maybe so much more that the next stop(s) will be allowed to ascent
+	// to. So we have to probe the next stops that are within the reach of 1 minute
+	// of ascent as well.
+
+	// compute depth in meters that is reachable within 1 minute of ascent at 10 m/min
+	depth_1min = ( char_depth_sim > 10 ) ? char_depth_sim - 10 : 0;
 
 	// probe all stop depths that are in reach of 1 minute of ascent
-	next_stop = stop_depth;
+	next_stop  = stop_depth;
 
 	while(next_stop > 0)
 	{
-		// compute the depth of the next stop ...
-		if      ( next_stop <= char_I_depth_last_deco ) next_stop  = 0;
-		else if ( next_stop == 6                      ) next_stop  = char_I_depth_last_deco;
+		// compute the depth of the next stop to probe
+		if      ( next_stop <= char_I_last_stop_depth ) next_stop  = 0;
+		else if ( next_stop == 6                      ) next_stop  = char_I_last_stop_depth;
 		else                                            next_stop -= 3;
 
-		// would the next stop be beyond the 1 minute limit?
-		if( next_stop < depth_1min )
-		{
-			// YES - signal that probing is done
-			next_stop = 0;
-		}
-		else
-		{
-			// NO - compute the ceiling at the next stop depth
-			calc_limit(GF_high - GF_slope * (float)next_stop);
-
-			//    - limit ceiling to positive values, i.e. the surface
-			if( ceiling < 0.0 ) ceiling = 0.0;
-
-			//    - check if this stop depth would be allowed
-			if( next_stop >= (unsigned char)(ceiling * BAR_TO_METER + 0.99) )
-			{
-				// YES - this stop depth is allowed
-				char_depth_sim = next_stop;
-
-				//     - no stop needed if stop depth actually is the surface
-				if( next_stop == 0 ) need_stop = 0;
-			}
-		}
+		// done if the next stop would be above the 1 minute limit
+		if( next_stop < depth_1min ) return(1);
+
+		// compute the ceiling for the next stop depth
+		calc_limit(GF_high - GF_slope * (float)next_stop);
+
+		// done if the next stop would be above the ceiling
+		if( next_stop < (unsigned char)(ceiling * BAR_TO_METER + 0.99) ) return(1);
+
+		// the next stop depth is allowed, ascent to it and redo trying further stop
+		char_depth_sim = next_stop;
 	}
 
-
-	// -----------------------------------------------------------------------
-	// common end for straight Buhlmann and Buhlmann with GF extension
-	// -----------------------------------------------------------------------
-
-done:
-
-	// calculate absolute pressure at the depth found
-	calc_sim_pres_respiration();
-
-	return need_stop;
+	// reached the surface, done with no further stop
+	return(0);
 }
 
 
 //////////////////////////////////////////////////////////////////////////////
-// Find current gas in the list and get its change depth
-//
-// Input:  char_I_current_gas_num   number of current gas (1..5 or 6)
+// Take the actual currently used gas for ascent & deco calculation
+//
+// Input:  start_gas_num            number of the gas/dil to start with (1..5 or 6)
 //
 // Output: sim_gas_current_num      1..6 or 0 for the manually configured gas/dil
 //         sim_gas_current_depth    change depth (MOD) of the gas/dil in meters
 //
 static void gas_take_current(void)
 {
-	assert( 1 <= char_I_current_gas_num && char_I_current_gas_num <= 6 );
-
-	if( char_I_current_gas_num <= NUM_GAS )			// gas/diluent 1-5
+	assert( 1 <= start_gas_num && start_gas_num <= 6 );
+
+
+	// check origin of the gas/diluent to start with
+	if( start_gas_num <= NUM_GAS )
 	{
-		sim_gas_current_num   = char_I_current_gas_num;
-		sim_gas_current_depth = char_I_deco_gas_change[sim_gas_current_num-1];
+		// pre-configured gas/diluent
+
+		// set gas number
+		sim_gas_current_num   = sim_gas_last_num = start_gas_num;
+
+		// set change depth
+		sim_gas_current_depth = char_I_deco_gas_change[start_gas_num-1];
 
 		// capture case of non-configured change depth
 		if( sim_gas_current_depth == 0 ) sim_gas_current_depth = 255;
 	}
 	else
 	{
-		sim_gas_current_num   = 0;
+		// on-the-fly configured gas/diluent ("gas 6")
+
+		// set gas number
+		sim_gas_current_num   = sim_gas_last_num = 0;
+
+		// set change depth
 		sim_gas_current_depth = char_I_gas6_depth;
 	}
 }
@@ -1512,8 +1564,8 @@
 //
 // Input:    char_depth_sim             simulated depth in meters
 //           sim_gas_current_num        number of the currently used gas/dil
-//           char_I_deco_gas_type[]     types         of the gases/dils
-//           char_I_deco_gas_change[]   change depths of the gases/dils
+//           deco_gas_type[]            types and state of the gases/dils
+//           char_I_deco_gas_change[]   change depths   of the gases/dils
 //
 // Modified: sim_gas_best_num           index of the gas (1..5) - only if return value is true
 //           sim_gas_best_depth         switch depth            - only if return value is true
@@ -1524,34 +1576,51 @@
 {
 	overlay unsigned char switch_depth = 255;
 	overlay unsigned char switch_gas   =   0;
-	overlay unsigned char j;
+
 
 	// loop over all gases to find the shallowest one below or at current depth
 	for( j = 0; j < NUM_GAS; ++j )
 	{
-		// Is this gas available?
-		if( char_I_deco_gas_type[j] > 0 )
-
-		// Is the change depth of the this gas deeper than or
+		// is this gas available?
+		if(     ( deco_gas_type[j] & GAS_TYPE_MASK  )		// gas enabled (type > 0)  ?
+		    && !( deco_gas_type[j] & GAS_AVAIL_MASK )		// neither lost nor staged ?
+		  )
+
+		// is it not a deco gas unless:
+		//    extended stops are activated
+		// OR we are on a deco stop
+		// OR we are in bailout but not in cave mode
+		if(    ( ( deco_gas_type[j] & GAS_TYPE_MASK  ) < 3                            )
+		    || ( ( main_status      & EXTENDED_STOPS )                                )
+		    || ( ( deco_status & CALC_NORM    ) &&  ( deco_info   & DECO_STOPS_NORM ) )
+		    || ( ( deco_status & CALC_ALT     ) &&  ( deco_info   & DECO_STOPS_ALT  ) )
+		    || ( ( deco_status & BAILOUT_MODE ) && !( main_status & CAVE_MODE       ) )
+		  )
+
+		// is the change depth of the this gas deeper than or
 		// at least equal to the current depth?
 		if( char_I_deco_gas_change[j] >= char_depth_sim )
 
-		// Is the change depth of this gas shallower than or
-		// at least equal to the change depth of the best gas
-		// found so far, or is it the first better gas found?
-		if( char_I_deco_gas_change[j] <= switch_depth )
+		// is the change depth of this gas shallower than
+		// the change depth of the best gas found so far,
+		// or is it the first better gas found?
+		if( char_I_deco_gas_change[j] <  switch_depth )
 
 #ifdef _gas_contingency
-		// Is there still enough of this gas or doesn't it matter?
-		if( ( gas_volume_need[j] < gas_volume_avail[j] ) || ( !char_I_gas_contingency ) )
+		// is there still enough of this gas or shall we don't care?
+		if(    !(deco_gas_type[j] & GAS_FULLY_USED_UP )
+		    || !( main_status     & GAS_CONTINGENCY   )
+		    || !( main_status     & CALC_VOLUME       )
+		)
 #endif
 
-		// If there is a yes to all these questions, we have a better gas!
+		// if there is a yes to all these questions, we have a better gas!
 		{
 			// memorize this gas (1..5) and its change depth
 			switch_gas   = j+1;
 			switch_depth = char_I_deco_gas_change[j];
 		}
+
 	}	// continue looping through all gases to eventually find an even better gas
 
 	// has a best gas been found?
@@ -1585,6 +1654,9 @@
 //
 static void gas_take_best(void)
 {
+	// memorize current gas as last gas used
+	sim_gas_last_num      = sim_gas_current_num;
+
 	// set new gas
 	sim_gas_current_num   = sim_gas_best_num;
 	sim_gas_current_depth = sim_gas_best_depth;
@@ -1655,7 +1727,7 @@
 //////////////////////////////////////////////////////////////////////////////
 // Compute respired ppO2, ppN2 and ppHe
 //
-// Input:  tissue_increment           : selector for targeting simulated or real tissues
+// Input:  tissue_increment           : selector  for simulated/real tissues and gases
 //         main_status                : breathing mode for real      tissues
 //         deco_status                : breathing mode for simulated tissues
 //         sim_/real_O2_ratio         : (simulated) O2 ratio breathed
@@ -1665,7 +1737,6 @@
 //         sim_/real_pSCR_drop        : (simulated) pSCR O2 drop
 //         pres_surface               : surface pressure [bar]
 //         char_I_const_ppO2          : ppO2 reported from sensors or setpoint [cbar]
-//         float_deco_distance        : safety factor, additional depth below stop depth [bar] - not used any more
 //         ppWater                    : water-vapor pressure inside respiratory tract [bar]
 //
 // Output: ppN2                       : respired N2 partial pressure
@@ -1743,21 +1814,21 @@
 	//---- OC, CCR and Bailout Mode Gas Calculations -----------------------------------
 
 	// calculate ppO2 of pure oxygen
-	O2_ppO2 = calc_pres_respiration - ppWater;
+	ppO2_O2 = calc_pres_respiration - ppWater;
 
 	// capture failure condition in case real_pres_respiration is < ppWater (should never happen...)
-	if( O2_ppO2 < 0.0 ) O2_ppO2 = 0.0;
+	if( ppO2_O2 < 0.0 ) ppO2_O2 = 0.0;
 
 	// calculate ppO2 of the pure gas (OC, diluent)
-	OC_ppO2 = O2_ppO2 * calc_O2_ratio;
+	ppO2_OC = ppO2_O2 * calc_O2_ratio;
 
 #ifdef _ccr_pscr
 
 	// calculate pSCR ppO2
-	pSCR_ppO2 = OC_ppO2 - calc_pSCR_drop;
-
-	// capture failure condition in case pSCR_ppO2 becomes negative
-	if( pSCR_ppO2 < 0.0 ) pSCR_ppO2 = 0.0;
+	ppO2_pSCR = ppO2_OC - calc_pSCR_drop;
+
+	// capture failure condition in case ppO2_pSCR becomes negative
+	if( ppO2_pSCR < 0.0 ) ppO2_pSCR = 0.0;
 
 
 	//---- Loop modes : adjust ppN2 and ppHe for change in ppO2 due to setpoint (CCR) or drop (pSCR) ---
@@ -1783,10 +1854,8 @@
 		{
 			//---- pSCR Mode --------------------------------------------------------------------------
 
-			// Use the sensor value if available, but only in real tissue context!
-			// In all other cases use calculated ppO2.
-			if   ( char_I_const_ppO2 && (tissue_increment & TISSUE_SELECTOR)) ppO2 = const_ppO2;
-			else                                                              ppO2 = pSCR_ppO2;
+			// Use the sensor value if available and in real tissue context, else use calculated ppO2.
+			ppO2 = ( char_I_const_ppO2 && (tissue_increment & TISSUE_SELECTOR)) ? const_ppO2 : ppO2_pSCR;
 		}
 		else
 		{
@@ -1821,7 +1890,7 @@
 		//---- OC mode ---------------------------------------------------------------------------------
 
 		// breathed ppO2 is ppO2 of pure gas
-		ppO2 = OC_ppO2;
+		ppO2 = ppO2_OC;
 	}
 
 
@@ -1834,9 +1903,6 @@
 
 	//---- calculate ppN2 and ppHe ---------------------------------------------------------------------
 
-	// add deco safety distance when working on simulated tissues - not used any more
-	// if( !(tissue_increment & TISSUE_SELECTOR) ) calc_pres_respiration += float_deco_distance;
-
 	// compute ppN2 and ppHe, capture potential failure conditions first:
 	if( calc_pres_respiration > ppWater )
 	{
@@ -1912,10 +1978,15 @@
 	int_O_CNS_alt           = 0 + INT_FLAG_INVALID;
 
 	// initialize NDL times
-	char_O_NDL_norm         = 240;
-	char_O_NDL_alt          = 240;
-
-	// initialize ascent times
+	int_O_NDL_norm         = 240;
+	int_O_NDL_alt          = 240;
+
+	// initialize stop times
+	int_O_TST_norm        = 0;
+	int_O_TST_alt         = 0 + INT_FLAG_INVALID + INT_FLAG_NOT_COMPUTED_YET + INT_FLAG_ZERO;
+
+
+	// initialize ascent / return times
 	int_O_TTS_norm          = 0;
 	int_O_TTS_alt           = 0 + INT_FLAG_INVALID + INT_FLAG_NOT_COMPUTED_YET;
 
@@ -1951,8 +2022,8 @@
 //         int_O_CNS_norm                 CNS value at end of normal      dive plan
 //         int_O_CNS_alt                  CNS value at end of alternative dive plan
 //         char_O_deco_warnings           deco warnings vector
-//         char_O_NDL_norm                remaining NDL time in normal      dive plan
-//         char_O_NDL_alt                 remaining NDL time in alternative dive plan
+//         int_O_NDL_norm                 remaining NDL time in normal      dive plan
+//         int_O_NDL_alt                  remaining NDL time in alternative dive plan
 //         int_O_TTS_norm                 ascent time (TTS)  in normal      dive plan
 //         int_O_TTS_alt                  ascent time (TTS)  in alternative dive plan
 //         int_O_lead_supersat            supersaturation of the leading tissue
@@ -1974,7 +2045,7 @@
 		real_pres_tissue_N2[ci]    = N2_equilibrium;	// N2
 
 		// reset tissue pressures for scaled tissue graphics
-		char_O_tissue_pres_He[ci]  = 0;					// He
+		char_O_tissue_pres_He[ci]  =  0;				// He
 		char_O_tissue_pres_N2[ci]  = 10;				// N2
 		char_O_tissue_pressure[ci] = 10;				// combined
 	}
@@ -1984,15 +2055,17 @@
 	int_O_CNS_current = int_O_CNS_norm = int_O_CNS_alt = 0;
 
 	// reset some more vars to their defaults
-	char_O_NDL_norm       = 240;
-	char_O_NDL_alt        = 240;
-	int_O_TTS_norm        = 0;
-	int_O_TTS_alt         = 0;
-	int_O_lead_supersat   = 0;
+	int_O_NDL_norm       = 240;
+	int_O_NDL_alt        = 240;
+	int_O_TST_norm       = 0;
+	int_O_TST_alt        = 0 + INT_FLAG_ZERO;
+	int_O_TTS_norm       = 0;
+	int_O_TTS_alt        = 0;
+	int_O_lead_supersat  = 0;
 
 	// reset all warning and info flags
-	char_O_deco_warnings  = 0;
-	char_O_deco_info      = 0;
+	char_O_deco_warnings = 0;
+	char_O_deco_info     = 0;
 }
 
 
@@ -2009,12 +2082,11 @@
 //           char_I_SAC_work                 gas usage rate during working    phase in l/min
 //           char_I_SAC_deco                 gas usage rate during deco stops phase in l/min
 //
-//           char_I_deco_model               selector for GF extension
-//           char_I_ascent_speed             ascent speed
+//           char_I_model                    selector for GF extension
 //           char_I_saturation_multiplier    safety factor for tissue saturation
 //           char_I_desaturation_multiplier  safety factor for tissue desaturation
 //
-//           char_I_pressure_gas[]           amount of gas available for ascent in bar
+//           char_I_pressure_gas[]           amount of gas available for ascent / cave return in bar
 //           int_I_pressure_drop[]           pressure drop used to calculate SAC rate
 //           char_I_gas_avail_size[]         size of the tanks in liters
 //
@@ -2027,15 +2099,15 @@
 //           char_O_deco_info                deco engine information vector
 //           char_O_deco_warnings            deco engine warnings    vector
 //
-//           char_O_NDL_norm                 remaining NDL time in normal      dive plan
-//           char_O_NDL_alt                  remaining NDL time in alternative dive plan
+//           int_O_NDL_norm                  remaining NDL time in normal      dive plan
+//           int_O_NDL_alt                   remaining NDL time in alternative dive plan
 //           int_O_TTS_norm                  ascent time (TTS)  in normal      dive plan
 //           int_O_TTS_alt                   ascent time (TTS)  in alternative dive plan
 //           int_O_CNS_norm                  CNS value at end   of normal      dive plan
 //           int_O_CNS_alt                   CNS value at end   of alternative dive plan
 //
-//           int_O_gas_need_vol              calculated gas volumes   needed for ascent
-//           int_O_gas_need_pres             calculated gas pressures needed for ascent
+//           int_O_gas_need_vol[]            calculated gas volumes   needed for ascent / cave return
+//           int_O_gas_need_pres[]           calculated gas pressures needed for ascent / cave return
 //
 //           int_O_SAC_measured              measured surface air consumption (SAC) rate in l/min
 // 
@@ -2048,8 +2120,8 @@
 	overlay unsigned short int_ppO2_max_warn;
 	overlay unsigned short int_ppO2_max_att;
 	overlay unsigned short int_ppO2_max_dil;
-	overlay float          EAD;
-	overlay float          END;
+	overlay float          EAD_pres;
+	overlay float          END_pres;
 
 	//=============================================================================================
 
@@ -2179,8 +2251,8 @@
 		calc_CNS();
 
 		// calculate ceiling (at GF_high or 100%) and leading tissue supersaturation
-		if   ( char_I_deco_model ) calc_limit(GF_high);		// GF factors enabled
-		else                       calc_limit(  1.0  );		// classic Buhlmann
+		if   ( char_I_model ) calc_limit(GF_high);		// GF factors enabled
+		else                  calc_limit(  1.0  );		// classic Buhlmann
 
 		// convert the ceiling value to integer
 		convert_ceiling_for_display();
@@ -2203,28 +2275,31 @@
 	{
 		//---- Calculate and Export EAD and END ------------------------------------------------------
 
-		// calculate EAD (Equivalent Air Depth): equivalent depth for the same N2 level with plain air
-		EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * BAR_TO_METER;
-
-		// calculate END (Equivalent Narcotic Depth): here O2 is treated as narcotic, too
-		// Source cited: The Physiology and Medicine of Diving by Peter Bennett and David Elliott,
-		//               4th edition, 1993, W.B.Saunders Company Ltd, London.
-		END = (real_pres_respiration - ppHe - pres_surface) * BAR_TO_METER;
-
-		// export EAD
-		float_value = EAD; convert_float_to_char(); char_O_EAD = char_value;
-
-		// export END
-		float_value = END; convert_float_to_char(); char_O_END = char_value;
+		// calculate EAD (Equivalent Air Depth) as pressure in [bar]:
+		// equivalent depth for the same N2 level with plain air
+		EAD_pres = ppN2 / 0.7902 + ppWater - pres_surface;
+
+		// calculate END (Equivalent Narcotic Depth) as pressure in [bar]:
+		// as before, but with O2 treated as narcotic, too
+		// Source: The Physiology and Medicine of Diving by Peter Bennett and David Elliott,
+		//         4th edition, 1993, W.B.Saunders Company Ltd, London.
+		END_pres = real_pres_respiration - ppHe - pres_surface;
+
+
+		// export EAD, factor 10 is because conversion delivers in [cbar] but we need [mbar]
+		float_value = EAD_pres; convert_float_to_int(); int_O_EAD_pres = int_value * 10;
+
+		// export END, factor 10 is because conversion delivers in [cbar] but we need [mbar]
+		float_value = END_pres; convert_float_to_int(); int_O_END_pres = int_value * 10;
 
 
 		//---- Compute ppO2 Values in [cbar] ---------------------------------------------------------
 
 		float_value = ppO2;      convert_float_to_int(); int_O_breathed_ppO2 = int_value;	// breathed gas
 #ifdef _ccr_pscr
-		float_value = O2_ppO2;   convert_float_to_int(); int_O_O2_ppO2       = int_value;	// pure oxygen
-		float_value = OC_ppO2;   convert_float_to_int(); int_O_pure_ppO2     = int_value;	// pure gas
-		float_value = pSCR_ppO2; convert_float_to_int(); int_O_pSCR_ppO2     = int_value;	// pSCR calculated
+		float_value = ppO2_O2;   convert_float_to_int(); int_O_O2_ppO2       = int_value;	// pure oxygen
+		float_value = ppO2_OC;   convert_float_to_int(); int_O_pure_ppO2     = int_value;	// pure gas
+		float_value = ppO2_pSCR; convert_float_to_int(); int_O_pSCR_ppO2     = int_value;	// pSCR calculated
 #endif
 
 
@@ -2236,19 +2311,22 @@
 		//      (7 meters chosen as to be 2 stop depth intervals plus 1 additional meter below)
 		if (    ( deco_info & DECO_MODE ) > 0                        )
 		if (    ( char_depth_real       ) > char_O_deco_depth[0] + 7 )
-				deco_info &= ~DECO_MODE;
+				  deco_info &= ~DECO_MODE;
 
 		// Set the deco mode flag if:
 		//     deco mode is not set
 		// AND     breathing an OC deco gas (gas type 3)
 		//     OR  breathing a gas or diluent that officially is disabled (type 0)
 		//     OR  there is a deco stop
+		//
+		// Remark: when breathing a gas, its lost & staged flags are cleared
+		//
 		if (    ( deco_info & DECO_MODE ) == 0 )
 		if (    ( char_I_current_gas_type == 3 )
 		     || ( char_I_current_gas_type == 0 )
 		     || ( char_O_deco_depth[0]     > 0 )
 		   )
-				deco_info |=  DECO_MODE;
+				  deco_info |=  DECO_MODE;
 
 
 		//---- Compute ppO2 Warnings ------------------------------------------------------------------
@@ -2277,7 +2355,7 @@
 		int_ppO2_max_dil = int_ppO2_max_warn;
 
 		// when enabled and in CCR mode, the upper diluent warning threshold gets adjust according to the current setpoint
-		if(  char_I_dil_ppO2_check                )
+		if(  char_I_dil_check                     )
 		if( (main_status & MODE_MASK) == MODE_CCR )
 		{
 			overlay unsigned short max_dil;
@@ -2365,47 +2443,28 @@
 		// initialize all output variables to defaults
 		init_output_vars();
 
-		// safeguard input parameters that are constant during the course of the dive
-		if( char_I_ascent_speed  <   5 ) char_I_ascent_speed  =   5;
-		if( char_I_ascent_speed  >  10 ) char_I_ascent_speed  =  10;
-
-		// convert input parameters to float numbers
-		float_ascent_speed  = 1.00 * char_I_ascent_speed;
-
-
 		// initialize values that will be recalculated later on periodically
-		deco_warnings            = 0;		// reset all deco warnings
-		deco_info                = 0;		// reset all deco infos
-		IBCD_tissue_vector       = 0;		// reset tissue IBCD vector
-		NDL_tissue_start_norm    = 0;		// initialize the tissue to start with when calculating normal      NDL time
-		NDL_tissue_start_alt     = 0;		// initialize the tissue to start with when calculating alternative NDL time
+		deco_warnings         = 0;		// reset all deco warnings
+		deco_info             = 0;		// reset all deco infos
+		IBCD_tissue_vector    = 0;		// reset tissue IBCD vector
+		NDL_tissue_start_norm = 0;		// initialize the tissue to start with when calculating normal      NDL time
+		NDL_tissue_start_alt  = 0;		// initialize the tissue to start with when calculating alternative NDL time
 
 		// enforce initialization of GF data on first cyclic initialization
-		GF_high_last             = 255;
-		GF_low_last              = 255;
-
-#ifdef _gas_contingency
-		// shall check for gas pan out?
-		if( char_I_gas_contingency )
+		GF_high_last          = 255;
+		GF_low_last           = 255;
+
+
+		// calculate volumes available for each gas
+		for( i = 0; i < NUM_GAS; i++ )
 		{
-			overlay float reduction = 0.5 * (float)char_I_SAC_deco * (1.0 + (float)char_I_depth_last_deco / 10.0);
-
-			// YES - calculate volumes available for each gas
-			for( i = 0; i < NUM_GAS; i++ )
-			{
-				// total available volume = tank size * fill press, char_I_gas_avail_pres is in multiples of 10 bar
-				gas_volume_avail[i]  = (float)char_I_gas_avail_size[i] * (float)char_I_gas_avail_pres[i] * 10.0;
-
-				// reduce total available volumes by due for 1/2 minute on last stop
-				gas_volume_avail[i] -= reduction;
-			}
+			// total available volume = tank size * fill press, char_I_gas_avail_pres is in multiples of 10 bar
+			gas_volume_avail[i] = (float)char_I_gas_avail_size[i] * (float)char_I_gas_avail_pres[i] * 10.0;
+
+			// attention threshold
+			gas_volume_atten[i] = gas_volume_avail[i] * GAS_NEEDS_ATTENTION;
 		}
-#endif
-
-#ifdef _cave_mode
-		char_I_backtrack_time    = 0;		//clear backtracking time (index to char_I_backtrack_depth)
-		char_I_backtrack_depth   = 0;		//prime first entry with a depth of 0 meter
-#endif
+
 
 #ifdef _profiling
 		int_O_profiling_overrun_max = 0;
@@ -2433,6 +2492,10 @@
 		// clear the internal stops table
 		clear_deco_table();
 
+		// clear deco stops info
+		if( deco_status & CALC_NORM ) deco_info &= ~DECO_STOPS_NORM;
+		else                          deco_info &= ~DECO_STOPS_ALT;
+
 		// initialize the simulated tissues with the current state of the real tissues
 		for( i = 0; i < NUM_COMP; i++ )
 		{
@@ -2440,8 +2503,47 @@
 			sim_pres_tissue_He[i] = real_pres_tissue_He[i];
 		}
 
+		// initialize the gas types
+		for( i = 0; i < NUM_GAS; i++ )
+		{
+			deco_gas_type[i] = char_I_deco_gas_type[i];
+		}
+
+#ifdef _gas_contingency
+		// if in gas contingency mode,
+		// check if there are multiple tanks with the same gas
+		// (or at least with the same change depth...)
+		if( main_status & GAS_CONTINGENCY )
+		{
+			for( i = 0; i < NUM_GAS; i++ )
+			{
+				// default to no peer tanks existing
+				peer_tank[i] = 0;
+
+				// tank enabled?
+				if( char_I_deco_gas_type[i] )
+				{
+					// YES - check for peer tanks
+					for( j = 0; j < NUM_GAS; j++ )
+					{
+						// do not check a tank against itself
+						if( i == j ) continue;
+
+						// is the other tank also enabled and does it have the same change depth?
+						if( char_I_deco_gas_type[j]   &  GAS_TYPE_MASK             )
+						if( char_I_deco_gas_change[i] == char_I_deco_gas_change[j] )
+						{
+							// YES - memorize it as a peer tank
+							peer_tank[i] |= (1 << j);
+						}
+					}
+				}
+			}
+		}
+#endif
+
 		// initialize GF parameters if using GF model
-		if( char_I_deco_model != 0 )
+		if( char_I_model != 0 )
 		{
 			// update GF parameters (GFs may have been switched between GF and aGF)
 			if( (char_I_GF_Low_percentage != GF_low_last) || (char_I_GF_High_percentage != GF_high_last) )
@@ -2456,33 +2558,37 @@
 
 
 				// reset low depth references and slopes
-				GF_low_depth_norm = 0;
-				GF_low_depth_alt  = 0;
-				GF_slope_norm     = 0.0;
-				GF_slope_alt      = 0.0;
+				GF_depth_norm = 0;
+				GF_depth_alt  = 0;
+				GF_slope_norm = 0.0;
+				GF_slope_alt  = 0.0;
 			}
 
 			// retrieve GF parameters for current calculation cycle
 			if( deco_status & CALC_NORM )
 			{
-				GF_low_depth = GF_low_depth_norm;
-				GF_slope     = GF_slope_norm;
+				GF_depth = GF_depth_norm;
+				GF_slope = GF_slope_norm;
 			}
 			else
 			{
-				GF_low_depth = GF_low_depth_alt;
-				GF_slope     = GF_slope_alt;
+				GF_depth = GF_depth_alt;
+				GF_slope = GF_slope_alt;
 			}
 		}
 
 		// initialize the simulated CNS value with the current CNS value of the real tissues
 		CNS_fraction_sim = CNS_fraction_real;
 
-		// initialize the simulated depth with the current depth,
-		// memorize current depth as start depth of the simulation
+		// initialize the simulated pressure with the current real pressure
 		sim_pres_respiration = real_pres_respiration;
-		char_depth_sim       = char_depth_real;
-		char_depth_sim_start = char_depth_real;
+
+		// initialize the simulated depth with the current real depth
+		char_depth_sim = char_depth_start = char_depth_real;
+
+		// cache the gas/dil to start calculations with
+		start_gas_num = char_I_current_gas_num;
+
 
 		// Lookup the gas that is currently breathed with the real tissues and set it as
 		// the gas to be used with the simulated tissues, too. This gas will be used until
@@ -2501,8 +2607,9 @@
 		// initialize the no decompression limit (NDL) time to 240 minutes
 		NDL_time = 240;
 
-		// initialize the total ascent time to 0 minutes
-		ascent_time = 0;
+		// clear the Total Time to Surface (TTS) and the Total Stops Time (TST)
+		TTS_time = 0;
+		TST_time = 0;
 
 		// retrieve the tissue that had the shortest NDL time during last calculation
 		NDL_tissue_start = ( deco_status & CALC_NORM ) ? NDL_tissue_start_norm : NDL_tissue_start_alt;
@@ -2511,12 +2618,11 @@
 		NDL_tissue      = NDL_tissue_start;
 		NDL_tissue_lead = NDL_tissue_start;
 
-		// initialization for calculating the initial ascent
-		// start with 1 minute ascent steps when calculating the initial ascent
-		fast = 1;
-
-		// initialization for convert_gas_needs_to_press()
-		gas_needs_gas_index  = 0;
+		// initialization for convert_volume_to_pressure()
+		gas_needs_gas_index = 0;
+
+		// tag gas needs as not calculated in fTTS mode by default
+		deco_info &= ~GAS_NEEDS_fTTS;
 
 		// shall calculate gas needs?
 		if( main_status & CALC_VOLUME )
@@ -2538,6 +2644,19 @@
 #endif
 		}
 
+
+#ifdef _cave_mode
+		if( main_status & CAVE_MODE )
+		{
+			// get the position of the first data set to start the backtracking from
+			backtrack_index = char_I_backtrack_index;
+
+			// get the first backtracking data set
+			read_backtrack_data();
+		}
+#endif
+
+
 #ifdef _profiling
 		profiling_runs = 0;
 #endif
@@ -2558,6 +2677,9 @@
 		//
 		case PHASE_30_EXTENDED_BOTTOM_TIME:
 
+		// tag gas needs as calculated in fTTS mode
+		deco_info |= GAS_NEEDS_fTTS;
+
 		// program interval on simulated tissues (flag bit 7 = 0)
 		tissue_increment = char_I_extra_time;
 
@@ -2585,17 +2707,21 @@
 		// on gas 1-5 ?
 		if( sim_gas_current_num )
 		{
-			// YES - set the bottom depth
-			gas_needs_depth = char_depth_sim_start;
-
-			// take either the whole bottom time or just the fTTS/bailout extra time
+			// YES - take either the whole bottom time or just the fTTS/bailout extra time
 			gas_needs_time = ( main_status & CALCULATE_BOTTOM ) ? char_I_bottom_time : char_I_extra_time;
 
-			// calculate gas demand
-			calc_due_by_depth_time_sac();
-
-			// take the result
-			gas_volume_need[sim_gas_current_num-1] = gas_needs_volume_due;
+			// any time to do?
+			if( gas_needs_time )
+			{
+				// YES - set the bottom depth
+				gas_needs_depth = char_depth_start;
+
+				// calculate required gas volume
+				calc_required_volume();
+
+				// take the result
+				gas_volume_need[sim_gas_current_num-1] = gas_needs_volume_due;
+			}
 		}
 
 
@@ -2633,260 +2759,324 @@
 			if( deco_status & CALC_NORM ) NDL_tissue_start_norm = NDL_tissue_lead;
 			else                          NDL_tissue_start_alt  = NDL_tissue_lead;
 
-			// done with calculating NDL time, set next calculation phase:
-			// - calculate return and ascent in cave mode if configured, else
-			// - proceed with no-stop ascent              if within NDL time, or
-			// - proceed with deco ascent                 if beyond NDL time.
-#ifdef _cave_mode
-			if   ( main_status & CAVE_MODE ) next_planning_phase = PHASE_60_CAVE_RETURN;
-			else
-#endif
-			                                 next_planning_phase = PHASE_70_OPEN_WATER_ASCENT;
+			// done with calculating NDL time, next phase will calculate the ascent / cave return
+			next_planning_phase = PHASE_70_ASCENT_OR_RETURN;
 		}
 
 		break;
 
 
-#ifdef _cave_mode
-		//
-		//---- Cave Mode Return -------------------------------------------------------------------
-		//
-		case PHASE_60_CAVE_RETURN:
-
-		// TODO
-
-		// the next calculation phase will gather all results
-		next_planning_phase = PHASE_80_RESULTS;
-
-		break;
-#endif
-
-
 		//
-		//---- Open Water Ascent ------------------------------------------------------------------
+		//---- Ascent or Return (cave mode) -------------------------------------------------------
 		//
-		case PHASE_70_OPEN_WATER_ASCENT:
-
-		// program 1 minute interval on simulated tissues
-		tissue_increment = 1;
-
-		// memorize current gas in case there will be a gas change
-		sim_gas_last_num = sim_gas_current_num;
-
-		// find_next_stop():
-		// stays at the current stop depth, ascents to the next stop depth, or
-		// ascents to the depth that is reachable within one minute of ascent
-		// without needing to stop.
-		//
-		// return value    : 1/true if a stop is required, else 0/false
-		// char_depth_sim  : current depth (depth achieved)
-		// char_depth_last : last    depth (depth we came from)
-		//
-		if( find_next_stop() )
+		case PHASE_70_ASCENT_OR_RETURN:
+
 		{
-			overlay unsigned char silent_stop = 0;
-			overlay unsigned char gas_change  = 0;
-
-			//---- stop required --------------------
-
-			// check if there is a better gas to switch to
-			if( gas_find_best() )
+			overlay unsigned char doing_deco_stop  = 0;
+			overlay unsigned char doing_gas_change = 0;
+
+
+			// target simulated tissues, default is 1 minute interval
+			tissue_increment = 1;
+
+			// check if a deco stop is required:
+			// - stays at the current depth if a stop is required,
+			// - ascents to the next stop if possible, else
+			// - ascents by 1 meter
+			if( find_next_stop() )
+			{
+				//---- stop required --------------------
+
+				// memorize doing a deco stop
+				doing_deco_stop = 1;
+
+				// set flag for deco stops found
+				if( deco_status & CALC_NORM ) deco_info |= DECO_STOPS_NORM;
+				else                          deco_info |= DECO_STOPS_ALT;
+
+				// encountered a deco stop, so switch to deco usage rate (SAC deco)
+				gas_needs_usage_rate = char_I_SAC_deco;
+
+				// check if there is a better gas to switch to
+				if( gas_find_best() )
+				{
+					// YES - memorize doing a gas change
+					doing_gas_change = 1;
+
+					// take the gas
+					gas_take_best();
+
+					// set the new calculation ratios for N2, He and O2
+					gas_set_ratios();
+
+					// add the gas change time to the stop time
+					tissue_increment += char_I_gas_change_time;
+				}
+
+				// add the stop to an existing stop or add a new stop
+				update_deco_table(tissue_increment);
+			}
+			else
 			{
-				// YES - memorize it
-				gas_change = 1;
-
-				// take the gas
-				gas_take_best();
-
-				// set the new calculation ratios for N2, He and O2
-				gas_set_ratios();
-
-				// add the gas change time to the stop time
-				tissue_increment += char_I_gas_change_time;
-
-				// extended stops option enabled and
-				// gas change depth deeper than the current depth ?
-				if( main_status & EXTENDED_STOPS           )
-				if( sim_gas_current_depth > char_depth_sim )
+				//---- no stop required -----------------
+
+				// switch to 1/10 minute interval
+				tissue_increment = 0;
+
+				// memorize not doing a deco stop
+				doing_deco_stop = 0;
+
+				// check if there is a better gas to switch to, but only:
+				//
+				//      if extended stops are activated OR if cave mode is enabled OR if in bailout
+				// AND  if the actual depth (char_depth_start) is deeper or at the change
+				//      depth of the better gas (change depth has not been passed yet) *)
+				// AND  if the depth of the last stop is above (shallower) or at the change
+				//      depth of the better gas (do not switch on final ascent)        *)
+				//
+				// *) skipped when calculating in cave mode
+				//
+				// Attention: do not use a && formula over all 'if' terms, the
+				//            conditions need to be evaluated in the given order!
+				//
+				if(    ( main_status & EXTENDED_STOPS )
+				    || ( main_status & CAVE_MODE      )
+				    || ( deco_status & BAILOUT_MODE   )
+				  )
+				if(          gas_find_best()          )
+#ifdef _cave_mode
+				if( ( char_depth_start       >= sim_gas_best_depth ) || ( main_status & CAVE_MODE ) )
+				if( ( char_I_last_stop_depth <= sim_gas_best_depth ) || ( main_status & CAVE_MODE ) )
+#else
+				if( ( char_depth_start       >= sim_gas_best_depth )                                )
+				if( ( char_I_last_stop_depth <= sim_gas_best_depth )                                )
+#endif
 				{
-					// YES - make a "silent" stop at the gas change depth
-					// to figure in the gas change
-					silent_stop = 1;
-
-					// locate the stop at the shallower one of the
-					// gas change depth or the depth we came from
-					char_depth_sim = (sim_gas_current_depth < char_depth_last) ?
-						sim_gas_current_depth : char_depth_last;
-
-					// calculate sim_pres_respiration for
-					// the adjusted value of char_depth_sim
-					calc_sim_pres_respiration();
-
-					// as we didn't travel the full distance,
-					// account for the gas change time only
+					// YES - memorize doing a gas change
+					doing_gas_change = 1;
+
+					// take the gas
+					gas_take_best();
+
+					// set the new calculation values for N2, He and O2
+					gas_set_ratios();
+
+					// create a stop lasting the gas change time
 					tissue_increment = char_I_gas_change_time;
 
-					// if run from the deco calculator,
-					// put the gas change into the stops table or
-					// abort deco calculation if the table is full
-					if( deco_status & DECO_CALCULATOR_MODE   )
-					if( !update_deco_table(tissue_increment) )
-						next_planning_phase = PHASE_80_RESULTS;
+					// if in deco and run from the deco calculator:
+					// create a stop for the gas change in the stops table
+					if( !NDL_time && (deco_status & DECO_CALCULATOR_MODE) )
+						update_deco_table(tissue_increment);
+				}
+
+			} // stop / no stop
+
+
+#ifdef _cave_mode
+			// cave mode actions
+			if( main_status & CAVE_MODE )
+			{
+				// doing a deco stop?
+				if( doing_deco_stop )
+				{
+					// YES - not moving, reset the 1/10 minute steps counter
+					backtrack_step_counter = 10;
 				}
-			} // better gas
-
-
-			// if the stop is not a silent one,
-			// add the stop to an existing stop or add a new stop,
-			// or abort deco calculation if the deco table is full
-			if( !silent_stop                         )
-			if( !update_deco_table(tissue_increment) )
-				next_planning_phase = PHASE_80_RESULTS;
-
+				else
+				{
+					// NO - on the move, switch back to SAC work
+					gas_needs_usage_rate = char_I_SAC_work;
+
+					//    - decrement the 1/10 minute steps counter if not already zero
+					if( backtrack_step_counter ) backtrack_step_counter--;
+
+					//    - target backtracking depth reached?
+					if( char_depth_sim == backtrack_target_depth )
+					{
+						// YES - on target depth
+
+						// target depth reached within first 1/10 minute?
+						if( backtrack_step_counter == 9 )
+						{
+							// YES - will not change depth any more while remaining 9/10 of
+							//       the minute, so can do the full full minute in one step
+							tissue_increment       = 1;
+							backtrack_step_counter = 0;
+						}
+
+						// on the move for a minute or more now?
+						// (incl. doing full minute in one step)
+						if( backtrack_step_counter == 0 )
+						{
+							// YES - get the data of the next backtracking data set
+							read_backtrack_data();
+						}
+					}
+				}
+			} // cave mode
+#endif
 
 			// shall calculate gas needs?
 			if( main_status & CALC_VOLUME )
 			{
-				// encountered a stop, so switch to deco usage rate (SAC deco)
-				gas_needs_usage_rate = char_I_SAC_deco;
-
-				// set the depth for gas need calculation to the shallower one
-				// of the start depth (current real depth) and the stop depth
-				// (assumed depth to be) as we may be shallower than we should be
-				gas_needs_depth = ( char_depth_sim_start < char_depth_sim ) ?
-					char_depth_sim_start : char_depth_sim;
-
-				// did a gas change occur and last gas is 1-5 and a gas change time set?
-				if( gas_change && sim_gas_last_num && char_I_gas_change_time )
+				overlay unsigned char index_last_gas = sim_gas_last_num-1;
+				overlay unsigned char index_curr_gas = sim_gas_current_num-1;
+
+#ifdef _cave_mode
+				// in cave mode?
+				if( main_status & CAVE_MODE )
+				{
+					// YES - set the depth for the gas needs calculation to the
+					//       simulated stop / on-the-move depth
+					gas_needs_depth = char_depth_sim;
+				}
+				else
+#endif
+				{
+					// NO - set the depth for the gas needs calculation to the shallower
+					//      one of the actual depth (char_depth_start, current real depth)
+					//      and the simulated (stop) depth, as we may on purpose dive
+					//      shallower than we should to conserve on a low running gas supply
+					gas_needs_depth = ( char_depth_start < char_depth_sim ) ?
+							char_depth_start : char_depth_sim;
+				}
+
+				// doing a gas change and a gas change time is set?
+				if( doing_gas_change && char_I_gas_change_time )
 				{
 					// YES - set time it takes for switching the gas
 					gas_needs_time = char_I_gas_change_time;
 
-					// calculate gas demand
-					calc_due_by_depth_time_sac();
-
-					// add the demand to the overall demand on the last gas
-					gas_volume_need[sim_gas_last_num-1] += gas_needs_volume_due;
+					//     - calculate required gas volume for the gas change
+					calc_required_volume();
+
+					//     - add gas change demand to overall demand on the last gas
+					if( sim_gas_last_num    ) gas_volume_need[index_last_gas] += gas_needs_volume_due;
+
+					//     - add gas change demand to overall demand on the current gas
+					if( sim_gas_current_num ) gas_volume_need[index_curr_gas] += gas_needs_volume_due;
 				}
 
-				// current gas is 1-5 ?
+				// current gas is 1-5 ? (i.e. not 0 aka gas 6)
 				if( sim_gas_current_num )
 				{
-					// YES - time is 1 minute plus the gas change time (if set)
+					// set time: doing a deco stop ->    1 minute, encoded by tissue_increment = 1
+					//                no deco stop -> 1/10 minute, encoded by tissue_increment = 0
 					gas_needs_time = tissue_increment;
 
-					// calculate gas demand
-					calc_due_by_depth_time_sac();
+					// calculate required gas volume for the stop, ascent or travel
+					calc_required_volume();
 
 					// add the demand to the overall demand on the current gas
-					gas_volume_need[sim_gas_current_num-1] += gas_needs_volume_due;
+					gas_volume_need[index_curr_gas] += gas_needs_volume_due;
 				}
-			} // gas need
-		}
-		else
-		{
-			//---- no stop required -----------------
-
-			// switch to a better gas, but only:
-			//
-			//      if extended stops are activated OR if in bailout OR if within NDL
-			// AND  if the actual depth is below (deeper) or at the change depth of the
-			//      better gas (switch depth has not been passed yet)
-			// AND  if the depth of the last stop is above (shallower) or at the change
-			//      depth of the better gas (do not switch on final ascent)
-			//
-			// Attention: do not use a && formula over all 'if' terms, the
-			//            conditions need to be evaluated in the given order!
-			//
-			if( (main_status & EXTENDED_STOPS) || (deco_status & BAILOUT_MODE) || NDL_time )
-			if( gas_find_best()                                                            )
-			if( char_depth_real        >= sim_gas_best_depth                               )
-			if( char_I_depth_last_deco <= sim_gas_best_depth                               )
-			{
-				// YES - take the gas
-				gas_take_best();
-
-				// set the new calculation values for N2, He and O2
-				gas_set_ratios();
-
-				// set char_depth_sim to the gas change depth
-				char_depth_sim = sim_gas_current_depth;
-
-				// calculate sim_pres_respiration for
-				// the adjusted value of char_depth_sim
-				calc_sim_pres_respiration();
-
-				// as we didn't travel the full distance,
-				// account for the gas change time only
-				tissue_increment = char_I_gas_change_time;
-
-				// if in deco and
-				// if run from the deco calculator:
-				// create a stop for the gas change in the stops table,
-				// abort deco calculation if the deco table is full
-				if( !NDL_time                            )
-				if( deco_status & DECO_CALCULATOR_MODE   )
-				if( !update_deco_table(tissue_increment) )
-					next_planning_phase = PHASE_80_RESULTS;
-
-				// shall calculate gas needs and gas change time is set?
-				if( main_status & CALC_VOLUME )
-				if( char_I_gas_change_time    )
+
+#ifdef _gas_contingency
+				// in gas contingency mode?
+				if( main_status & GAS_CONTINGENCY )
 				{
-					// YES - set depth to current depth
-					gas_needs_depth = char_depth_sim;
-
-					// set time it takes for switching the gas
-					gas_needs_time = tissue_increment;
-
-					// calculate gas demand
-					calc_due_by_depth_time_sac();
-
-					// add gas demand to the overall demand on the new gas
-					gas_volume_need[sim_gas_current_num-1] += gas_needs_volume_due;
-
-					// was the last gas one of the gases 1-5 ?
-					if( sim_gas_last_num )
+					overlay unsigned char all_peer_tanks_used_up = 1;
+
+
+					// when doing a gas change and the there is an overdraw on the last gas,
+					// then transfer the overdraw to the current gas if the current gas has
+					// an equal or deeper change depth than the overdrawn gas
+					if( doing_gas_change                                                                 )
+					if( gas_volume_need[index_last_gas]        >= gas_volume_avail[index_last_gas]       )
+					if( char_I_deco_gas_change[index_last_gas] <= char_I_deco_gas_change[index_curr_gas] )
+					{
+						overlay float overdraw;
+
+						// calculate overdraw
+						overdraw = gas_volume_need[index_last_gas] - gas_volume_avail[index_last_gas];
+
+						// transfer overdraw
+						gas_volume_need[index_last_gas] -= overdraw;
+						gas_volume_need[index_curr_gas] += overdraw;
+
+						// tag last gas as fully used up
+						deco_gas_type[index_last_gas] |= GAS_FULLY_USED_UP;
+					}
+
+					// if there are peer tanks with the current gas (i.e. other tanks that have the same
+					// change depth), check if there is at least one tank that is not yet fully used up
+					if( peer_tank[index_curr_gas] )
 					{
-						// YES - add the same demand to the overall demand on the last gas
-						gas_volume_need[sim_gas_last_num-1] += gas_needs_volume_due;
+						// scan all tanks
+						for( i = 0; i < NUM_GAS; i++ )
+						{
+							// check if
+							// - tank is a peer tank
+							// - tank is currently neither staged nor lost
+							// - tank is not fully used up yet
+							if(  (peer_tank[index_curr_gas] &    (1 << i)      ) )
+							if( !(deco_gas_type[i]          & GAS_AVAIL_MASK   ) )
+							if( !(deco_gas_type[i]          & GAS_FULLY_USED_UP) )
+							{
+								// found a peer tank that is available and not fully used up yet
+								all_peer_tanks_used_up = 0;
+							}
+						}
+					}
+
+					// select which threshold is sensible to check for
+					if     ( deco_gas_type[index_curr_gas] & GAS_FULLY_USED_UP  )
+					{
+						// already found as fully used up, nothing to do any more
 					}
-				} // gas switching needs
-			} // gas switch
-
-			// shall calculate gas needs and
-			// last (or still current) gas is 1-5 ?
-			if( main_status & CALC_VOLUME )
-			if( sim_gas_last_num          )
+					else if( deco_gas_type[index_curr_gas] & GAS_NEARLY_USED_UP )
+					{
+						// check for fully used up threshold
+						if( gas_volume_need[index_curr_gas] >= gas_volume_avail[index_curr_gas] )
+						{
+							// tag the gas as fully used up
+							deco_gas_type[index_curr_gas] |= GAS_FULLY_USED_UP;
+
+							// set warning if all peer tanks are fully used up, too
+							if( all_peer_tanks_used_up ) deco_gas_type[index_curr_gas] |= GAS_NEED_WARNING;
+						}
+					}
+					else
+					{
+						// check for nearly used up threshold
+						if( gas_volume_need[index_curr_gas] >= gas_volume_atten[index_curr_gas] )
+						{
+							// tag the gas as nearly used up
+							deco_gas_type[index_curr_gas] |= GAS_NEARLY_USED_UP;
+
+							// set attention if all peer tanks are already fully used up
+							if( all_peer_tanks_used_up ) deco_gas_type[index_curr_gas] |= GAS_NEED_ATTENTION;
+						}
+					}
+				}
+#endif // _gas_contingency
+
+			} // gas needs
+
+			// update the total stops time
+			if( doing_deco_stop )
 			{
-				// YES - compute distance traveled
-				gas_needs_depth = char_depth_last - char_depth_sim;
-
-				// at least some positive distance traveled?
-				if( gas_needs_depth > 1 )
-				{
-					// YES - set depth to average depth along the distance
-					gas_needs_depth += 1;
-					gas_needs_depth /= 2;
-					gas_needs_depth += char_depth_sim;
-
-					// ascent time is 1 minute
-					gas_needs_time = 1;
-
-					// calculate gas demand
-					calc_due_by_depth_time_sac();
-
-					// add to overall demand
-					gas_volume_need[sim_gas_last_num-1] += gas_needs_volume_due;
-				}
-			} // gas travel needs
-
-		} // stop / no stop
-
-		// --- one or more minutes have passed by now ---
-
-		// update the ascent time
-		ascent_time += tissue_increment;
+				// total stops time is counted in full minutes, add 1 minute
+				TST_time += 1;
+			}
+
+			// update the total ascent / cave return time
+			if( tissue_increment )
+			{
+				// total time to surface is counted in 1/10 minutes, add 1 minute
+				TTS_time += 10 * tissue_increment;
+			}
+			else
+			{
+				// total time to surface is counted in 1/10 minutes, add 1/10 minute
+				TTS_time += 1;
+			}
+
+		} // overlay
+
+		// calculate absolute pressure at the current depth
+		sim_pres_respiration = (float)char_depth_sim * METER_TO_BAR + pres_surface;
 
 		// compute current ppO2, ppN2 and ppHe
 		calc_alveolar_pressures();
@@ -2894,11 +3084,13 @@
 		// update the tissues
 		calc_tissues();
 
-		// update the CNS value
+		// update the CNS
 		calc_CNS();
 
-		// finish stops calculation if the surface is reached
-		if( char_depth_sim == 0 ) next_planning_phase = PHASE_80_RESULTS;
+		// finish stops calculation if the surface is reached or
+		// if the deco table is full / calculations took too long
+		if( (char_depth_sim == 0) || (deco_warnings & DECO_WARNING_INCOMPLETE) )
+			next_planning_phase = PHASE_80_RESULTS;
 
 		break;
 
@@ -2911,17 +3103,22 @@
 		// convert the CNS value to integer
 		convert_sim_CNS_for_display();
 
+		// normal or alternative plan?
 		if( deco_status & CALC_NORM )
 		{
-			// export the integer CNS value
+			// normal plan - export the integer CNS value
 			int_O_CNS_norm  = int_sim_CNS_fraction;
 		}
 		else
 		{
-			// export the integer CNS value
+			// alternative plan - export the integer CNS value
 			int_O_CNS_alt   = int_sim_CNS_fraction;
 		}
 
+		// limit total time to surface to display max. and rescale to full minutes
+		if( TTS_time < 9995 ) TTS_time = (TTS_time + 5) / 10;
+		else                  TTS_time = 999 | INT_FLAG_INVALID;
+
 		// The next calculation phase will
 		// - publish the stops table if in normal plan mode,
 		// - proceed with remaining results dependent on if within NDL, or
@@ -2946,20 +3143,16 @@
 		// the deco obligation will vanish during the ascent, create an
 		// artificial stop to signal that expedite surfacing ("popping
 		// up") is not allowed anymore.
-		if( char_O_deco_depth[0] == 0 )	// simulated ascent reveals no required stops
-		if( int_O_ceiling        >  0 )	// real tissues have a ceiling
+		if( char_O_deco_depth[0] == 0 )		// simulated ascent reveals no required stops
+		if( int_O_ceiling        >  0 )		// real tissues have a ceiling
 		{
 			// set a pro forma stop at the configured last stop depth
-			char_O_deco_depth[0] = char_I_depth_last_deco;
+			char_O_deco_depth[0] = char_I_last_stop_depth;
 
 			// set a stop time of 0 minutes, this will be displayed as "..'"
 			char_O_deco_time[0]  = 0;
 		}
 
-		// update deco info vector
-		if( char_O_deco_depth[0] ) deco_info |=  DECO_STOPS;		// set   flag for deco stops found
-		else                       deco_info &= ~DECO_STOPS;		// clear flag for deco stops found
-
 		// The next calculation phase will publish the main results dependent on being
 		// - within NDL,
 		// - in deco.
@@ -2974,29 +3167,31 @@
 		//
 		case PHASE_82_RESULTS_NDL:
 
-		// results to publish depend on normal or alternative plan
+		// normal or alternative plan?
 		if( deco_status & CALC_NORM )
 		{
-			// output the NDL time
-			char_O_NDL_norm = NDL_time;
-
-			// clear the normal ascent time
-			int_O_TTS_norm  = 0;
+			// normal plan - output the NDL and TTS time
+			int_O_NDL_norm = NDL_time;
+			int_O_TTS_norm = TTS_time;
+
+			// clear the stops time
+			int_O_TST_norm = 0;
 		}
 		else
 		{
-			// output the NDL time
-			char_O_NDL_alt = NDL_time;
-
-			// clear the alternative ascent time
-			int_O_TTS_alt  = 0;
+			// alternative plan - output the NDL time
+			int_O_NDL_alt = NDL_time;
+			int_O_TTS_alt = TTS_time;
+
+			// clear the alternative TTS and stops time
+			int_O_TST_alt = 0 + INT_FLAG_ZERO;
 		}
 
 		// The next calculation phase will
-		// - finish the calculation cycle if no gas needs calculation configured, else
-		// - calculate the gas needs pressures
-		if      ( !(main_status & CALC_VOLUME ) ) next_planning_phase = PHASE_90_FINISH;
-		else                                      next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES;
+		// - convert the gas needs from volume to pressure if gas needs calculation is configured
+		// - else finish the calculation cycle
+		if   ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES;
+		else                               next_planning_phase = PHASE_90_FINISH;
 
 		break;
 
@@ -3006,35 +3201,35 @@
 		//
 		case PHASE_83_RESULTS_DECO:
 
-		// limit ascent time to display max.
-		if( ascent_time > 999) ascent_time = 999;
-
-		// tag ascent time as invalid if there is an overflow in the stops table
-		if( deco_warnings & DECO_WARNING_INCOMPLETE ) ascent_time |= INT_FLAG_INVALID;
-
-		// results to publish depend on normal or alternative plan
+		// limit total stops time to display max.
+		if( TST_time > 999 ) TST_time = 999 | INT_FLAG_INVALID;
+
+
+		// normal or alternative plan?
 		if( deco_status & CALC_NORM )
 		{
-			// clear the normal NDL time
-			char_O_NDL_norm = 0;
-
-			// export the ascent time
-			int_O_TTS_norm  = ascent_time;
+			// normal plan - clear the normal NDL time
+			int_O_NDL_norm = 0;
+
+			// export the TTS and total stops time
+			int_O_TTS_norm = TTS_time;
+			int_O_TST_norm = TST_time;
 		}
 		else
 		{
-			// clear the alternative NDL time
-			char_O_NDL_alt  = 0;
-
-			// export the ascent time
-			int_O_TTS_alt   = ascent_time;
+			// alternative plan - clear the alternative NDL time
+			int_O_NDL_alt  = 0;
+
+			// export the TTS and total stops time
+			int_O_TTS_alt  = TTS_time;
+			int_O_TST_alt  = TST_time;
 		}
 
 		// The next calculation phase will
-		// - finish the calculation cycle if no gas needs calculation configured, else
-		// - calculate the gas needs along the ascent
-		if      ( !(main_status & CALC_VOLUME ) ) next_planning_phase = PHASE_90_FINISH;
-		else                                      next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES;
+		// - convert the gas needs from volume to pressure if gas needs calculation is configured
+		// - else finish the calculation cycle
+		if   ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES;
+		else                               next_planning_phase = PHASE_90_FINISH;
 
 		break;
 
@@ -3046,26 +3241,59 @@
 
 		// convert required volume of the gas pointed to by gas_needs_gas_index
 		// into the respective pressure and set the flags
-		convert_gas_needs_to_press();
+		convert_volume_to_pressure();
 
 		// increment index to address next gas
 		gas_needs_gas_index++;
 
 		// if all gases have been converted, advance to next calculation phase
+#ifdef _cave_mode
+		if( gas_needs_gas_index == NUM_GAS ) next_planning_phase = PHASE_85_GAS_NEEDS_CAVE;
+#else
 		if( gas_needs_gas_index == NUM_GAS ) next_planning_phase = PHASE_90_FINISH;
+#endif
 
 		break;
 
 
+#ifdef _cave_mode
+		//
+		//--- Results - tag Gas Needs as Cave or Open Water Mode ----------------------------------
+		//
+		case PHASE_85_GAS_NEEDS_CAVE:
+
+		// in cave mode?
+		if( main_status & CAVE_MODE )
+		{
+			// YES - tag gas needs as calculated in cave mode (return along recorded depth profile)
+			deco_info |= GAS_NEEDS_CAVE;
+		}
+		else
+		{
+			// NO  - tag gas needs as calculated in open water mode (vertical ascent)
+			deco_info &= ~GAS_NEEDS_CAVE;
+		}
+
+		// advance to next calculation phase
+		next_planning_phase = PHASE_90_FINISH;
+
+		break;
+#endif
+
+
 		//
 		//--- finish Calculation Cycle ------------------------------------------------------------
 		//
 		case PHASE_90_FINISH:
 
 		// Check if deco obligation is steady state or decreasing.
-		// This works only when an alternative plan is enabled and if it is not a bailout plan,
-		// thus BAILOUT_MODE must not be set while doing the alternative plan.
-		if( (deco_status & CALC_ALT) && !(deco_status & BAILOUT_MODE) )
+		// Update the result only:
+		// - if an alternative plan is enabled, and
+		// - if a valid alternative plan TTS exists, and
+		// - if it is not a bailout plan
+		if(  (deco_status   & CALC_ALT        ) )
+		if(  (int_O_TTS_alt & INT_FLAG_INVALID) )
+		if( !(deco_status   & BAILOUT_MODE    ) )
 		{
 			if( int_O_TTS_alt < int_O_TTS_norm ) deco_info |=  DECO_ZONE;
 			if( int_O_TTS_alt > int_O_TTS_norm ) deco_info &= ~DECO_ZONE;
@@ -3215,7 +3443,7 @@
 //
 // INPUT:    ppN2                       partial pressure of inspired N2
 //           ppHe                       partial pressure of inspired He
-//           tissue_increment           integration time and tissue selector (real or simulated)
+//           tissue_increment           tissue selector (real or simulated) and interval time
 //
 // MODIFIED: real_pres_tissue_N2[]      tissue N2 pressures (in real tissues context)
 //           real_pres_tissue_He[]      tissue He pressures (in real tissues context)
@@ -3242,12 +3470,12 @@
 
 	for( ci=0; ci < NUM_COMP; ci++ )		// iterate through all compartments
 	{
-		i = tissue_increment & TIME_MASK;	// extract number of minutes to do    (if i > 0)
-											// or if one 2 second period is to do (if i = 0)
-
-		if( i == 0 )						// check if we shall do one 2-seconds period
+		i = tissue_increment & TIME_MASK;	// i > 0: do a number of i full minutes
+											// I = 0: do 2 (real tissues) or 6 (simulated tissues) seconds
+
+		if( i == 0 )						// check if we shall do one 2 or 6 seconds interval
 		{
-			read_Buhlmann_times(0);			// YES - program coefficients for a 2 seconds period
+			read_Buhlmann_times(0);			// YES - program coefficients for a 2 or 6 seconds period
 			period = 1;						//     - set period length (in cycles)
 			i      = 1;						//     - and one cycle to do
 		}
@@ -3436,8 +3664,8 @@
 //
 static void calc_limit(PARAMETER float GF_parameter)
 {
-	overlay float         pres_respiration_min_total = 0.0;
-	overlay unsigned char surface_mode               = 0;		// 0: off, 1: on
+	overlay float         pres_ambient_min_overall = 0.0;
+	overlay unsigned char surface_mode             = 0;		// 0: off, 1: on
 
 
 	// check mode
@@ -3466,7 +3694,7 @@
 	// loop over all tissues
 	for( ci = 0; ci < NUM_COMP; ci++ )
 	{
-		overlay float pres_respiration_min_tissue;
+		overlay float pres_ambient_min_tissue;
 
 
 		// get the coefficients for tissue ci
@@ -3569,29 +3797,32 @@
 		} // real tissues
 
 		// calculate the minimum ambient pressure that the tissue can withstand
-		if( char_I_deco_model == 0 )
+		if( char_I_model == 0 )
 		{
 			// straight Buhlmann
-			pres_respiration_min_tissue = (pres_tissue - var_a) * var_b;
+			pres_ambient_min_tissue = (pres_tissue - var_a) * var_b;
 		}
 		else
 		{
 			// Buhlmann with Eric Baker's varying gradient factor correction
 			// note: this equation [1] is the inverse of equation [2]
-			pres_respiration_min_tissue =   ( pres_tissue        - (var_a        * GF_parameter) )
-			                              / ( 1.0 - GF_parameter + (GF_parameter / var_b       ) );
+			pres_ambient_min_tissue =   ( pres_tissue        - (var_a        * GF_parameter) )
+			                          / ( 1.0 - GF_parameter + (GF_parameter / var_b       ) );
 		}
 
 		// check if this tissue requires a higher ambient pressure than was found to be needed up to now
-		if( pres_respiration_min_tissue > pres_respiration_min_total )
+		if( pres_ambient_min_tissue > pres_ambient_min_overall )
 		{
-			pres_respiration_min_total = pres_respiration_min_tissue;
-			lead_tissue                = ci;
+			pres_ambient_min_overall = pres_ambient_min_tissue;
+			lead_tissue               = ci;
 		}
 	} // for
 
-	// compute ceiling for the real tissues in bar relative pressure
-	ceiling = pres_respiration_min_total - pres_surface;
+	// compute ceiling in bar relative pressure
+	ceiling = pres_ambient_min_overall - pres_surface;
+
+	// limit ceiling to positive values
+	if( ceiling < 0.0 ) ceiling = 0.0;
 
 #ifdef _helium
 	// IBCD is checked for real tissues only
@@ -3681,7 +3912,7 @@
 
 		// compute the maximum tissue pressure allowed to be exposed to an
 		// ambient pressure equaling the surface pressure
-		if( char_I_deco_model != 0 )
+		if( char_I_model != 0 )
 		{
 			// GF model enabled, this equation [2] is the inverse of equation [1]
 			pres_limit = (1.0 - GF_high + GF_high / var_b) * pres_surface + GF_high * var_a;
@@ -3859,7 +4090,7 @@
 //          internal_deco_time []  time     (in minutes) of each stop
 //          internal_deco_gas  []  gas used (index 1-5)  at each stop
 //
-static unsigned char update_deco_table(PARAMETER unsigned char time_increment)
+static void update_deco_table(PARAMETER unsigned char time_increment)
 {
 	assert( char_depth_sim > 0 );		// no stop at surface
 
@@ -3873,9 +4104,11 @@
 		if( internal_deco_time[stop_index] < (100 - time_increment) )
 		{
 			// YES - time increment fits into current stop entry,
-			//       increment stop time and return with status 'success'
+			//       increment stop time
 			internal_deco_time[stop_index] += time_increment;
-			return 1;
+
+			// done
+			return;
 		}
 		else
 		{
@@ -3885,9 +4118,11 @@
 			//      running deco calculation. Too many chained entries?
 			if( ++chained_stops >= STOP_CHAINING_LIMIT )
 			{
-				// YES - set overflow warning and return with status 'failed'
+				// YES - set warning that calculations took too long
 				deco_warnings |= DECO_WARNING_INCOMPLETE;
-				return 0;
+
+				// done
+				return;
 			}
 		}
 	}
@@ -3909,18 +4144,24 @@
 		}
 		else
 		{
-			// YES - set overflow warning and return with status 'failed'
-			deco_warnings |= DECO_WARNING_INCOMPLETE;
-			return 0;
+			// YES - if run in deco calculator mode, set a warning that there is an overflow in the stops table
+			if( main_status & CALCULATE_BOTTOM ) deco_warnings |= DECO_WARNING_INCOMPLETE;
+
+			// limit runtime via reached TTS (scaled in 1/10 minutes here)
+			if( TTS_time > 9999 ) deco_warnings |= DECO_WARNING_INCOMPLETE;
+
+			// done
+			return;
 		}
 	}
 
-	// initial use of a new (or the very first) stop entry,
-	// store all stop data and return with status 'success'
+	// initial use of a new (or the very first) stop entry, store all stop data
 	internal_deco_time [stop_index] = time_increment;
 	internal_deco_depth[stop_index] = char_depth_sim;
 	internal_deco_gas  [stop_index] = sim_gas_current_num;
-	return 1;
+
+	// done
+	return;
 }
 
 
@@ -4133,7 +4374,7 @@
 
 		// adjust target pressure by GF-high in case the GF model is in use, but not
 		// for the no-fly time as it's target pressure is hard to reach anyhow
-		if( char_I_deco_model && char_I_altitude_wait )
+		if( char_I_model && char_I_altitude_wait )
 		    pres_tissue_max = P_ambient_altitude +
 		                      0.01 * char_I_GF_High_percentage * (pres_tissue_max - P_ambient_altitude);
 
@@ -4331,9 +4572,10 @@
 //
 // Modified: tissue pressures       N2 and He pressures of the tissues
 //           CNS_fraction_real      current real CNS value
-//           ceiling                minimum allowed depth in mbar relative pressure
+//           ceiling                minimum allowed depth in bar relative pressure
 //           lead_supersat          supersaturation of the leading tissue (float)
 //           int_O_lead_supersat    supersaturation of the leading tissue (integer)
+//           char_O_lead_tissue     number of the leading tissue
 //
 static void calc_interval(PARAMETER unsigned char time_interval)
 {
@@ -4348,6 +4590,9 @@
 	if( int_I_pres_surface < 500) pres_surface = 0.500;
 	else                          pres_surface = 0.001 * int_I_pres_surface;
 
+	// safeguard time interval
+	if( time_interval > 254 ) time_interval = 254;
+
 	// set breathed pressure to surface pressure
 	real_pres_respiration = pres_surface;
 
@@ -4426,7 +4671,7 @@
 // calc_CNS
 //
 // Input:    char_ppO2          current ppO2 [in 0.1 bars]
-//           tissue_increment   time increment and tissue selector
+//           tissue_increment   tissue selector and time interval
 //
 // Modified: CNS_fraction_real  accumulated CNS (real      tissue context)
 //           CNS_fraction_sim   accumulated CNS (simulated tissue context)
@@ -4436,13 +4681,13 @@
 	overlay float CNS_fraction_inc;			// increment of CNS load, 0.01 = 1%
 
 
-	// calculate CNS increment for 2 seconds interval
+	// calculate CNS increment for a 2 seconds interval
 	if( char_ppO2 > 160 )
 	{
 		// step-wise CNS increment
 
-		// calculate index for increment look-up
-		cns_i = (char_ppO2 - 161) / 5;	// integer division
+		// calculate index for increment look-up (uses integer division)
+		cns_i = (char_ppO2 - 161) / 5;
 
 		// indexes > 17 use increment of index 17
 		if( cns_i > 17 ) cns_i = 17;
@@ -4451,31 +4696,32 @@
 		read_CNS_c_coefficient();
 
 		// re-scale coefficient from storage format in [1/100000] to productive value
-		CNS_fraction_inc = (float)var_cns_c / 100000.0;
+		CNS_fraction_inc = (float)var_cns_value / 100000.0;
 	}
 	else if( char_ppO2 > 50 )
 	{
 		// range wise CNS increment approximation
 
-		// calculate index for approximation coefficients look-up
-		cns_i = (char_ppO2 - 51) / 10;	// integer division
+		// calculate index for approximation coefficients look-up (uses integer division)
+		cns_i = (char_ppO2 - 51) / 10;
 
 		// read coefficients
 		read_CNS_ab_coefficient();
 
 		// calculate the CNS increment
-		CNS_fraction_inc = 1.0 / (var_cns_a * char_ppO2 + var_cns_b );
+		CNS_fraction_inc = 1.0 / (var_cns_gain * char_ppO2 + var_cns_offset );
 	}
 	else
-	{	// no increment up to 0.5 bar ppO2
+	{	// no increment for a ppO2 of up to 0.5 bar
 		CNS_fraction_inc = 0.0;
 	}
 
-	// apply a time factor in case of minute-based interval (factor = N * 30.0)
-	if( tissue_increment & TIME_MASK )
-	{
-		CNS_fraction_inc *= (float)(tissue_increment & TIME_MASK) * 30.0;
-	}
+	// apply a time factor in case of:
+	// - simulated tissues and interval = 0 (i.e. 6 seconds to do) -> factor  3
+	// - any       tissues and interval > 0 (i.e. i minutes to do) -> factor 30 * i
+	     if( tissue_increment == 0         ) CNS_fraction_inc *=  3.0;
+	else if( tissue_increment &  TIME_MASK ) CNS_fraction_inc *= 30.0 * (float)(tissue_increment & TIME_MASK);
+
 
 	// update the CNS accumulator
 	if   ( tissue_increment & TISSUE_SELECTOR ) CNS_fraction_real += CNS_fraction_inc;	// real tissues
@@ -4484,24 +4730,32 @@
 
 
 //////////////////////////////////////////////////////////////////////////////
-// calc_due_by_depth_time_sac       (Helper Function saving Code Space)
+// calc_required_volume
 //
 // Calculates the gas volume required for a given depth, time and usage (SAC)
 // rate. It uses a fixed surface pressure of 1.0 bar to deliver stable results
 // when used through the deco calculator.
 //
 // Input:  gas_needs_depth       depth     in meters
-//         gas_needs_time        time      in minutes
+//         gas_needs_time        time      in minutes (0 encodes 1/10 minute)
 //         gas_needs_usage_rate  gas usage in liters per minute at surface pressure
 //
 // Output: gas_needs_volume_due  required gas volume in liters
 //
-static void calc_due_by_depth_time_sac(void)
+static void calc_required_volume(void)
 {
-	gas_needs_volume_due = ((float)gas_needs_depth * METER_TO_BAR + pres_surface) * gas_needs_time * gas_needs_usage_rate;
+	// calculate volume for 1 minute
+	gas_needs_volume_due = ((float)gas_needs_depth * METER_TO_BAR + pres_surface) * gas_needs_usage_rate;
+
+	// multiply 1-minute-volume with time factor if time factor <> 1
+	if      ( gas_needs_time == 0 ) gas_needs_volume_due *= 0.1;				// 1/10 minute
+	else if ( gas_needs_time >  1 ) gas_needs_volume_due *= gas_needs_time;		// multiple minutes
 }
 
 
+
+#ifdef _rx_functions
+
 //////////////////////////////////////////////////////////////////////////////
 // calc_TR_functions
 //
@@ -4511,7 +4765,6 @@
 //
 // Output: todo
 //
-#ifdef _rx_functions
 static void calc_TR_functions(void)
 {
 	// pressure warnings for reading 1, but only if enabled and pressure value available
@@ -4663,8 +4916,7 @@
 	// strip flags
 	int_O_tank_pressure &= 0x0FFF;
 
-	// TODO: decide if log shall be in 0.1 bar of full bar only
-	// scale to full bar only
+	// scale to recording format of full bar only
 	int_O_tank_pressure /= 10;
 
 
@@ -4734,11 +4986,115 @@
 		}
 	}
 }
-#endif
+#endif	// _rx_functions
+
+
+#ifdef _cave_mode
+
+//////////////////////////////////////////////////////////////////////////////
+// read_backtrack_data
+//
+// Gets the data of the next backtracking data set
+//
+// Modified: backtrack_index         last current position in backtracking storage
+//
+// Output:   backtrack_step_counter  number of 1/10 min calculation steps to do on next target depth
+//           backtrack_target_depth  next target depth
+//
+static void read_backtrack_data(void)
+{
+	overlay unsigned char firstround = 1;
+
+
+	// load the step counter with the default of ten 1/10 minute steps to go between two depth samples
+	backtrack_step_counter = 10;
+
+	// repeat until having read the whole data set or having reached the first storage position
+	while(backtrack_index)
+	{
+		// backtracking data recording format:
+		// ---------------------------------------------------------------------------
+		// 0ddddddd -> datum is a depth recording    with d = 0..127 depth in meters
+		// 10tttttt ->            delta time         with t = 0.. 59 time  in seconds
+		// 110ggggg ->            gas staging status with g =      1 gas staged
+		// 111nnnnn ->            waypoint marker    with n = 1.. 31 waypoint number
+		//
+		// gas availability vector: LSB   : gas 1 (and so on)
+		// waypoint marker        : 1 - 30: user waypoints, last waypoint is turn point
+		//                        :     31: spare for turn point if all 30 waypoints used up
+		//                        :      0: reserved
+
+		// read recording entry and then advance (backward direction!) the reading index
+		overlay unsigned char datum = char_I_backtrack_storage[backtrack_index--];
+
+		// is it a target depth?
+		if( datum < 128 )
+		{
+			// YES - assign the target depth
+			backtrack_target_depth = datum;
+
+			// a depth entry closes a data set, so done with this data set
+			return;
+		}
+
+		// is it a delta time entry?
+		else if( datum < 128 + 64 )
+		{
+			// YES - When a delta time entry is contained in a data set, the time
+			//       stored in the delta time entry is the time that has elapsed
+			//       between storage of the depth that is part of this data set
+			//       and the previous depth recording.
+			//       This entry is stored whenever the delta time is shorter than
+			//       the default 1 minute depth sampling interval time.
+
+			// assign the delta time to the step counter: remove entry tag and
+			// convert datum from 0..59 seconds to 0..9 steps by integer division
+			backtrack_step_counter = (datum - 128) / 6;
+		}
+
+		// is it a gas staging status entry?
+		else if( datum < 128 + 64 + 32 )
+		{
+			// YES - extract gas staging status
+			overlay unsigned char gas_status = datum - (128 + 64);
+
+			// decode and update gas staging status
+			//
+			// bit set    : gas is     staged (not available) during next section of backtracking,
+			// bit cleared: gas is not staged (    available) during next section of backtracking.
+			//
+			// bit 0 corresponds to gas 1, ..., bit 4 corresponds to gas 5
+			//
+			for( i = 0; i < NUM_GAS; i++ )
+			{
+				if ( gas_status & (1 << i) ) deco_gas_type[i] |=  GAS_AVAIL_STAGED;	//     staged
+				else                         deco_gas_type[i] &= ~GAS_AVAIL_STAGED;	// not staged
+			}
+		}
+
+		// must be waypoint marker entry then
+		else
+		{
+			// set step counter to zero if first entry read is a waypoint entry
+			if( firstround ) backtrack_step_counter = 0;
+		}
+
+		// first round done
+		firstround = 0;
+
+	} // while
+
+	// first storage position reached, by convention it contains
+	// the final target depth which is zero meters aka the surface
+	backtrack_target_depth = 0;
+}
+
+#endif	// _cave_mode
+
 
 
 //////////////////////////////////////////////////////////////////////////////
-// convert_gas_needs_to_press
+// convert_volume_to_pressure
 //
 // Converts gas volumes into pressures and sets respective flags
 //
@@ -4748,13 +5104,12 @@
 //         char_I_gas_avail_size[]   size of the tanks in liters
 //         char_I_pressure_gas[]     gas configured on reading 1/2 (TR only)
 //
-// Output: int_O_gas_need_vol[]      required gas amount in liters, including flags
-//         int_O_gas_need_pres[]     required gas amount in bar,    including flags
+// Output: int_O_gas_need_vol[]      required gas amount in liters
+//         int_O_gas_need_pres[]     required gas amount in bar, including flags
 //         int_O_pressure_need[]     required gas amount for reading 1/2 (TR only)
 //
-static void convert_gas_needs_to_press(void)
+static void convert_volume_to_pressure(void)
 {
-
 	// just to make the code more readable...
 	i = gas_needs_gas_index;
 
@@ -4765,29 +5120,55 @@
 	}
 	else
 	{
-		overlay unsigned short int_pres_warn;
-		overlay unsigned short int_pres_attn;
-
-		// set warning and attention thresholds
-		int_pres_warn = 10.0 * (unsigned short)char_I_gas_avail_pres[i];
-		int_pres_attn = GAS_NEEDS_LIMIT_ATTENTION * int_pres_warn;
-
-		// convert ascent gas volume need from float to integer [in liter]
-		int_O_gas_need_vol[i]  = (unsigned short)gas_volume_need[i];
+		// convert gas volume need from float to integer [in liter]
+		int_O_gas_need_vol[i]  = (unsigned short)( gas_volume_need[i] + 0.5 );
 
 		// compute how much pressure in the tank will be needed [in bar]
-		int_O_gas_need_pres[i] = (unsigned short)( gas_volume_need[i] / char_I_gas_avail_size[i] + 0.999 );
+		int_O_gas_need_pres[i] = (unsigned short)( gas_volume_need[i] / char_I_gas_avail_size[i] + 0.5 );
 
 		// limit result to 999 bar because of display constraints
 		if( int_O_gas_need_pres[i] > 999 ) int_O_gas_need_pres[i] = 999 | INT_FLAG_HIGH;
 
-		// set flags for fast evaluation by dive mode
-		if      ( int_O_gas_need_pres[i] ==             0 ) int_O_gas_need_pres[i] |= INT_FLAG_ZERO;
-		else if ( int_O_gas_need_pres[i] >= int_pres_warn ) int_O_gas_need_pres[i] |= INT_FLAG_WARNING;
-		else if ( int_O_gas_need_pres[i] >= int_pres_attn ) int_O_gas_need_pres[i] |= INT_FLAG_ATTENTION;
+		// set flags for fast evaluation by output routine
+		if( int_O_gas_need_pres[i] == 0 ) int_O_gas_need_pres[i] |= INT_FLAG_ZERO;
+		else
+#ifdef _gas_contingency
+		if( main_status & GAS_CONTINGENCY )
+		{
+			// take warning and attention computed en-route
+			if     ( deco_gas_type[i]   &  GAS_NEED_WARNING   )
+			{
+				// tag the tank with a warning
+				int_O_gas_need_pres[i] |= INT_FLAG_WARNING;
+
+				// tag the peer tanks with a warning, too
+				for( j = 0; j < NUM_GAS; j++ )
+				{
+					if( peer_tank[i] & (1 << j) ) int_O_gas_need_pres[j] |= INT_FLAG_WARNING;
+				}
+			}
+			else if( deco_gas_type[i]   &  GAS_NEED_ATTENTION )
+			{
+				// tag the tank with an attention
+				int_O_gas_need_pres[i] |= INT_FLAG_ATTENTION;
+
+				// tag the peer tanks with an attention, too
+				for( j = 0; j < NUM_GAS; j++ )
+				{
+					if( peer_tank[i] & (1 << j) ) int_O_gas_need_pres[j] |= INT_FLAG_ATTENTION;
+				}
+			}
+		}
+		else
+#endif
+		{
+			// compute warning and attention now
+			if     ( gas_volume_need[i] >= gas_volume_avail[i] ) int_O_gas_need_pres[i] |= INT_FLAG_WARNING;
+			else if( gas_volume_need[i] >= gas_volume_atten[i] ) int_O_gas_need_pres[i] |= INT_FLAG_ATTENTION;
+		}
 	}
 
-	// set invalid flag if there is an overflow in the stops table
+	// set invalid flag if there is an overflow in the stops table or calculation took too long
 	if( deco_warnings & DECO_WARNING_INCOMPLETE ) int_O_gas_need_pres[i] |= INT_FLAG_INVALID;
 
 #ifdef _rx_functions
@@ -4795,7 +5176,7 @@
 	if( main_status & TR_FUNCTIONS )
 	{
 		// char_I_pressure_gas[] uses gas indexes from 1-10, loop variable i runs from 0 to 4
-		overlay unsigned char j = i+1;
+		j = i+1;
 
 		// check if the current gas is configured on pressure reading 1 or 2
 		if( (char_I_pressure_gas[0] == j) || (char_I_pressure_gas[1] == j) )
@@ -4809,7 +5190,7 @@
 			// limit to 400 bar and multiply by 10 to get required pressure in 0.1 bar
 			int_pres_need = (int_pres_need > 400) ? 4000 | INT_FLAG_OUT_OF_RANGE : 10 * int_pres_need;
 
-			// tag as not available if there is an overflow in the stops table
+			// tag as not available if there is an overflow in the stops table or calculation took too long
 			if( deco_warnings & DECO_WARNING_INCOMPLETE ) int_pres_need |= INT_FLAG_NOT_AVAIL;
 
 			// copy to reading data (in both readings the same gas could be configured)
@@ -4857,7 +5238,7 @@
 	if      ( int_sim_CNS_fraction >= CNS_LIMIT_WARNING   ) int_sim_CNS_fraction |= INT_FLAG_WARNING;
 	else if ( int_sim_CNS_fraction >= CNS_LIMIT_ATTENTION ) int_sim_CNS_fraction |= INT_FLAG_ATTENTION;
 
-	// set invalid flag if there is an overflow in the stops table
+	// set invalid flag if there is an overflow in the stops table or calculation took too long
 	if      ( deco_warnings & DECO_WARNING_INCOMPLETE ) int_sim_CNS_fraction |= INT_FLAG_INVALID;
 }
 
@@ -4888,8 +5269,8 @@
 		int_O_lead_supersat |= INT_FLAG_WARNING;			// make GF factor shown in red
 		deco_warnings       |= DECO_WARNING_OUTSIDE;		// make depth     shown in red
 	}
-	else if(    (char_I_deco_model != 0) && (int_O_lead_supersat > char_I_GF_High_percentage)
-	         || (char_I_deco_model == 0) && (int_O_lead_supersat > 99                       ) )
+	else if(    (char_I_model != 0) && (int_O_lead_supersat > char_I_GF_High_percentage)
+	         || (char_I_model == 0) && (int_O_lead_supersat > 99                       ) )
 	{
 		int_O_lead_supersat |= INT_FLAG_ATTENTION;			// make GF factor shown in yellow
 		deco_warnings       |= DECO_ATTENTION_OUTSIDE;		// make depth     shown in yellow
--- a/src/rtc.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/rtc.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File rtc.asm                              combined next generation V3.02.1
+;   File rtc.asm                              combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -16,83 +16,82 @@
 ;=============================================================================
 
 	global	rtc_init
+rtc_init:
+	banksel	isr_backup				; select bank ISR data
+	movlw	.0						; reset time to 12:00:00
+	movwf	rtc_latched_secs		; ...
+	movlw	.0						; ...
+	movwf	rtc_latched_mins		; ...
+	movlw	.12						; ...
+	movwf	rtc_latched_hour		; ...
+	movlw	firmware_creation_day	; reset date to firmware creation date
+	movwf	rtc_latched_day			; ...
+	movlw	firmware_creation_month	; ...
+	movwf	rtc_latched_month		; ...
+	movlw	firmware_creation_year	; ...
+	movwf	rtc_latched_year		; ...
+	;bra	rtc_set_rtc				; set the real time clock
+
 	global	rtc_set_rtc
-rtc_init:
-	banksel	isr_backup			; select bank ISR data
-	movlw	.0
-	movwf	rtc_latched_secs
-	movlw	.0
-	movwf	rtc_latched_mins
-	movlw	.12
-	movwf	rtc_latched_hour
-	movlw	firmware_creation_day
-	movwf	rtc_latched_day
-	movlw	firmware_creation_month
-	movwf	rtc_latched_month
-	movlw	firmware_creation_year
-	movwf	rtc_latched_year
 rtc_set_rtc:
-	banksel	isr_backup
-	movlw	d'24'				; safeguard hour
-	cpfslt	rtc_latched_hour
-	clrf	rtc_latched_hour
-	movlw	d'60'				; safeguard minutes
-	cpfslt	rtc_latched_mins
-	clrf	rtc_latched_mins
-	movlw	d'60'				; safeguard seconds
-	cpfslt	rtc_latched_secs
-	clrf	rtc_latched_secs
-	movlw	d'99'				; safeguard year
-	cpfslt	rtc_latched_year
-	movwf	rtc_latched_year
-	movlw	d'12'				; safeguard month
-	cpfslt	rtc_latched_month
-	movwf	rtc_latched_month
+	banksel	isr_backup				; select bank ISR data
+	movlw	d'24'					; safeguard hour
+	cpfslt	rtc_latched_hour		; hour < 24 ?
+	clrf	rtc_latched_hour		; NO - reset to 0
+	movlw	d'60'					; safeguard minutes and seconds
+	cpfslt	rtc_latched_mins		; minute < 60 ?
+	clrf	rtc_latched_mins		; NO - reset to 0
+	cpfslt	rtc_latched_secs		; seconds < 60 ?
+	clrf	rtc_latched_secs		; NO - reset to 0
+	movlw	d'100'					; safeguard year
+	cpfslt	rtc_latched_year		; year < 100 ?
+	clrf	rtc_latched_year		; NO - reset to 0
+	movlw	d'12'					; safeguard month
+	cpfslt	rtc_latched_month		; month < 12 ?
+	movwf	rtc_latched_month		; NO - clip at 12
 
-	banksel	common				; select bank common
-	rcall	rtc_check_day		; safeguard day
-	bsf		block_rtc_access	; suspend the ISR from accessing the RTC
-
+	rcall	rtc_check_day			; safeguard day
+	bsf		block_rtc_access		; suspend the ISR from accessing the RTC
 
-	banksel	0xF16				; addresses F16h through F5Fh are also used by SFRs, but are not part of the access RAM
+	banksel	0xF16					; addresses F16h through F5Fh are also used by SFRs, but are not part of the access RAM
 
-	movlw	0x55				; | unlock sequence for RTCWREN, EECON2 is located in the access RAM
-	movwf	EECON2				; |
-	movlw	0xAA				; |
-	movwf	EECON2				; |
-	bsf		RTCCFG,RTCWREN		; RTC write unlock, must follow directly after above unlock sequence!
-	bsf		RTCCFG,RTCPTR1
-	bsf		RTCCFG,RTCPTR0
-	movff	rtc_latched_year,WREG
-	rcall	rtc_dec2bcd			; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
-	movwf	RTCVALL				; year
-	movwf	RTCVALH				; dummy write
-	movff	rtc_latched_day,WREG
-	rcall	rtc_dec2bcd			; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
-	movwf	RTCVALL				; day
-	movff	rtc_latched_month,WREG
-	rcall	rtc_dec2bcd			; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
-	movwf	RTCVALH				; month
-	movff	rtc_latched_hour,WREG
-	rcall	rtc_dec2bcd			; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
-	movwf	RTCVALL				; hour
-	movlw	d'0'
-	rcall	rtc_dec2bcd			; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
-	movwf	RTCVALH				; weekday
-	movff	rtc_latched_secs,WREG
-	rcall	rtc_dec2bcd			; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
-	movwf	RTCVALL				; seconds
-	movff	rtc_latched_mins,WREG
-	rcall	rtc_dec2bcd			; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
-	movwf	RTCVALH				; minutes
+	movlw	0x55					; | unlock sequence for RTCWREN, EECON2 is located in the access RAM
+	movwf	EECON2					; |
+	movlw	0xAA					; |
+	movwf	EECON2					; |
+	bsf		RTCCFG,RTCWREN			; | RTC write unlock, must follow directly after above unlock sequence!
+	bsf		RTCCFG,RTCPTR1			; |
+	bsf		RTCCFG,RTCPTR0			; |
+	movff	rtc_latched_year,WREG	; get year
+	rcall	rtc_dec2bcd				; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
+	movwf	RTCVALL					; write year
+	movwf	RTCVALH					; dummy write
+	movff	rtc_latched_day,WREG	; get day
+	rcall	rtc_dec2bcd				; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
+	movwf	RTCVALL					; write day
+	movff	rtc_latched_month,WREG	; get month
+	rcall	rtc_dec2bcd				; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
+	movwf	RTCVALH					; write month
+	movff	rtc_latched_hour,WREG	; get  hour
+	rcall	rtc_dec2bcd				; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
+	movwf	RTCVALL					; write hour
+	movlw	d'0'					; set weekday to 0 (unused)
+	rcall	rtc_dec2bcd				; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
+	movwf	RTCVALH					; (dummy) write weekday
+	movff	rtc_latched_secs,WREG	; get seconds
+	rcall	rtc_dec2bcd				; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
+	movwf	RTCVALL					; write seconds
+	movff	rtc_latched_mins,WREG	; get minutes
+	rcall	rtc_dec2bcd				; IN: WREG in decimal, OUT: WREG in BCD, also sets to bank16h!
+	movwf	RTCVALH					; write minutes
 
-	movlw	0x55				; | probably not needed when clearing RTCWREN
-	movwf	EECON2				; |
-	movlw	0xAA				; |
-	movwf	EECON2				; |
-	bcf		RTCCFG,RTCWREN		; lock sequence for RTCWREN
+	movlw	0x55					; | probably not needed when clearing RTCWREN
+	movwf	EECON2					; |
+	movlw	0xAA					; |
+	movwf	EECON2					; |
+	bcf		RTCCFG,RTCWREN			; lock sequence for RTCWREN
 
-	banksel	common
+	banksel	common					; back to bank common
 
 	; update the "live" RTC variables to bridge the time until the ISR reads the updated data from the RTC
 	movff	rtc_latched_year, rtc_year
@@ -102,66 +101,117 @@
 	movff	rtc_latched_mins, rtc_mins
 	movff	rtc_latched_secs, rtc_secs
 
-	bcf		block_rtc_access	; allow the ISR to access the RTC again
-	return
+	bcf		block_rtc_access		; allow the ISR to access the RTC again
+	return							; done
 
 
 rtc_dec2bcd:
-	banksel	common				; switch to bank common
-	movwf	lo					; input in decimal
-	setf	hi					; 10s
+	banksel	common					; switch to bank common
+	movwf	lo						; input in decimal
+	setf	hi						; 10s
 rtc_dec2bcd2:
-	incf	hi,F				; count 10's
+	incf	hi,F					; count 10's
 	movlw	d'10'
 	subwf	lo,F
-	btfss	STATUS,N
-	bra		rtc_dec2bcd2
-	movlw	d'10'
-	addwf	lo,F				; 1s
-	swapf	hi,W				; swap to bit 7-4 -> WREG
-	addwf	lo,W				; result in BCD
-	banksel	0xF16				; switch back to bank for I/O registers
-	return
+	btfss	STATUS,N				; result negative?
+	bra		rtc_dec2bcd2			; NO  - loop
+	movlw	d'10'					; YES - 
+	addwf	lo,F					;     - 1s
+	swapf	hi,W					;     - swap to bit 7-4 -> WREG
+	addwf	lo,W					;     - result in BCD
+	banksel	0xF16					;     - switch back to bank for I/O registers
+	return							;     - done
 
+
+; wrap-around the month depending on the number of days per month
+; Attention: needs to be called in bank isr_backup!
 rtc_check_day:
-	movlw	.28					; the default February has 28 days
-	movff	rtc_latched_year,lo	; bank-safe get of the current year
-	btfsc	lo,0				; is the current year an even year?
-	bra		rtc_check_day_1		; NO
-	btfss	lo,1				; YES - is it a multiple of 4 years?
-	movlw	.29					;       YES - leap year, February has 29 days
-rtc_check_day_1:				;       NO  - keep the 28 days
-	movwf	hi					; store highest day in February in hi
-	movff	rtc_latched_month,lo; bank-safe get of the current month
-	dcfsnz	lo,F				; current month = January?
-	movlw	.31					; YES - highest day is 31
-	dcfsnz	lo,F				; current month = February?
-	movf	hi,W				; YES - highest day is 28/29
-	dcfsnz	lo,F				; current month = March?
-	movlw	.31					; YES - highest day is 31
-	dcfsnz	lo,F				; current month = April?
-	movlw	.30					; YES - highest day is 30
-	dcfsnz	lo,F				; current month = May?
-	movlw	.31					; YES - highest day is 31
-	dcfsnz	lo,F				; current month = June?
-	movlw	.30					; YES - highest day is 30
-	dcfsnz	lo,F				; current month = July?
-	movlw	.31					; YES - highest day is 31
-	dcfsnz	lo,F				; current month = August?
-	movlw	.31					; YES - highest day = 31
-	dcfsnz	lo,F				; current month = September?
-	movlw	.30					; YES - highest day = 30
-	dcfsnz	lo,F				; current month = October?
-	movlw	.31					; YES - highest day = 31
-	dcfsnz	lo,F				; current month = November?
-	movlw	.30					; YES - highest day = 30
-	dcfsnz	lo,F				; current month = December?
-	movlw	.31					; YES - highest day = 31
-	movff	rtc_latched_day,hi	; bank-safe get of the current day
-	cpfsgt	hi					; current day > highest day?
-	return						; NO  - day is ok
-	movlw	.1					; YES - wrap around to 1st day in month
-	movff	WREG,rtc_latched_day;     - bank-safe write-back of corrected day
-	return						;     - done
+	movlw	.28						; the default February has 28 days
+	btfsc	rtc_latched_year,0		; is the year an even year?
+	bra		rtc_check_day_1			; NO  - keep the 28 days
+	btfss	rtc_latched_year,1		; YES - is it a multiple of 4 years?
+	movlw	.29						;       YES - leap year, February has 29 days
+rtc_check_day_1:
+	movwf	backup_hi				; store highest day in February in backup_hi
+	decf	rtc_latched_month,W		; compute month - 1 and...
+	movwf	backup_lo				; store result in backup_lo
+	movlw	.31						; default highest day is 31
+	dcfsnz	backup_lo,F				; month = February?
+	movf	backup_hi,W				; YES - highest day is 28/29
+	dcfsnz	backup_lo,F				; month = March?
+	movlw	.31						; YES - highest day is 31
+	dcfsnz	backup_lo,F				; month = April?
+	movlw	.30						; YES - highest day is 30
+	dcfsnz	backup_lo,F				; month = May?
+	movlw	.31						; YES - highest day is 31
+	dcfsnz	backup_lo,F				; month = June?
+	movlw	.30						; YES - highest day is 30
+	dcfsnz	backup_lo,F				; month = July?
+	movlw	.31						; YES - highest day is 31
+	dcfsnz	backup_lo,F				; month = August?
+	movlw	.31						; YES - highest day = 31
+	dcfsnz	backup_lo,F				; month = September?
+	movlw	.30						; YES - highest day = 30
+	dcfsnz	backup_lo,F				; month = October?
+	movlw	.31						; YES - highest day = 31
+	dcfsnz	backup_lo,F				; month = November?
+	movlw	.30						; YES - highest day = 30
+	dcfsnz	backup_lo,F				; month = December?
+	movlw	.31						; YES - highest day = 31
+	cpfsgt	rtc_latched_day			; current day > highest day?
+	retlw	.1						; NO  - done, signal day was ok
+	movlw	.1						; YES - wrap around to 1st day in month
+	movwf	rtc_latched_day			;     - ...
+	retlw	.0						;     - done, signal a correction was made
+
+
+; Add minutes in mpr:2 to the time/date in in rtc_latched and rounds up/down to next full minute
+;
+; Attention: This code works for a maximum of 1439 minutes to add (23 hours, 59 minutes)!
+;
+	global	rtc_add_minutes
+rtc_add_minutes:
+	call	convert_time			; convert minutes in hi:lo to hours (up:hi) and minutes (lo)
+	banksel	isr_backup				; switch to bank isr_backup
+	bcf		STATUS,C				; clear carry bit
+	movlw	.30						; rounding point for seconds
+	cpfslt	rtc_latched_secs		; seconds < rounding point?
+	bsf		STATUS,C				; NO - set carry bit -> round up to next full minute
+	clrf	rtc_latched_secs		; set the second to zero
+	movff	lo,WREG					; get minutes to add
+	addwfc	rtc_latched_mins,F		; add minutes to add
+	movlw	.59						; limit for minute
+	cpfsgt	rtc_latched_mins		; resulting minute > 59 ?
+	bra		rtc_add_minutes_1		; NO  - minute is ok
+	movlw	.60						; YES - subtract 60 from resulting minute
+	subwf	rtc_latched_mins,F		;     - ...
+	bsf		STATUS,C				;     - set carry bit
+rtc_add_minutes_1:
+	movff	hi,WREG					; get hours to add
+	addwfc	rtc_latched_hour,F		; add hours to add plus carry bit
+	movlw	.23						; limit for hour
+	cpfsgt	rtc_latched_hour		; resulting hour > 23 ?
+	bra		rtc_add_minutes_2		; NO  - hour is ok
+	movlw	.24						; YES - subtract 24 from resulting hour
+	subwf	rtc_latched_hour		;     - ...
+	bsf		STATUS,C				;     - set carry bit
+rtc_add_minutes_2:
+	clrf	WREG					; create a zero
+	addwfc	rtc_latched_day,F		; add the carry bit
+	rcall	rtc_check_day			; check & correct the resulting day with respect to #days in month
+	tstfsz	WREG					; was the day beyond the last day of the month before correction?
+	bra		rtc_add_minutes_3		; NO  - done
+	banksel	isr_backup				; YES - select bank isr_backup again
+	incf	rtc_latched_month,F		;     - increment month
+	movlw	.12						;     - limit for month
+	cpfsgt	rtc_latched_month		;     - resulting month > 12 ?
+	bra		rtc_add_minutes_3		;       NO  - month is ok
+	subwf	rtc_latched_month,F		;       YES - subtract 12 from resulting month (actually sets back to January)
+	incf	rtc_latched_year,F		;           - increment year
+rtc_add_minutes_3
+	banksel	common					; back to bank common
+	return							; done
+
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/rtc.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/rtc.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File rtc.inc                               combined next generation V3.0.1
+;   File rtc.inc                              combined next generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -10,3 +10,4 @@
 
 	extern	rtc_init
 	extern	rtc_set_rtc
+	extern	rtc_add_minutes
--- a/src/rx_ops.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/rx_ops.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File rx_ops.asm                           combined next generation V3.03.7
+;   File rx_ops.asm                           combined next generation V3.03.8
 ;
 ;   RX (Tank Pressure Transmitter) Routines.
 ;
@@ -225,11 +225,11 @@
 	;bsf	ex,char_transmitter_low_bat	;                                          DEBUG CODE TO FAKE A LOW BAT WARNING
 	retlw	.0							;     - return with success code 0
 output_pressure_3:
-	movf	POSTINC1,W					; dummy read to advance FSR0 to byte 2 position
+	movf	POSTINC1,W					; dummy read to advance FSR1 to byte 2 position
 output_pressure_4:
 	dcfsnz	up,F						; decrement loop counter, last slot searched?
 	bra		output_pressure_5			; YES - return with error code
-	movf	POSTINC1,W					; NO  - dummy reads to advance FSR0 to byte 3 (any other code would not be more compact...)
+	movf	POSTINC1,W					; NO  - dummy reads to advance FSR1 to byte 3 (any other code would not be more compact...)
 	movf	POSTINC1,W					;     -                            ... byte 4
 	movf	POSTINC1,W					;     -                            ... byte 5
 	movf	POSTINC1,W					;     -                            ... byte 6 = first byte of next slot
--- a/src/shared_definitions.h	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/shared_definitions.h	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 ;
-;    shared_definitions.h                     combined next generation V3.04.3
+;    shared_definitions.h                     combined next generation V3.08.8
 ;
 ;    Declare variables used both in C and ASM code
 ;
@@ -89,7 +89,11 @@
 #ifdef __18CXX
 	//---- BANK 3 DATA -------------------------------------------------------
 	// Gather all Data C-Code --> ASM-Code
-	// Memory usage: 247 Byte used, 9 Byte free
+	//
+	// Attention: keep the first block of variables on position and also do not change
+	//            their relative position - this block goes into the deco data vault!
+	//
+	// Memory usage: 253 Byte used, 3 Byte free
 #   pragma udata overlay bank3=0x300
 #else
 	; in ASM, put the same bank, in overlay mode, at the same address
@@ -97,30 +101,32 @@
 bank3	udata_ovr	bank3
 #endif
 
-VAR_UINT  (int_O_desaturation_time);			// time until tissues desaturated to 5% remains, in minutes
-VAR_UINT  (int_O_nofly_time);					// altitude / no-fly waiting time time in minutes
+VAR_UINT  (int_O_desaturation_time);			// || time until tissues desaturated to 5% remains, in minutes
+VAR_UINT  (int_O_nofly_time);					// || altitude / no-fly waiting time time in minutes
+VAR_UINT  (int_O_CNS_current);					// || current CNS %
+VAR_UINT  (int_O_lead_supersat);				// || supersaturation of the leading tissue in %, 100% = on M-line of straight Buhlmann
+VAR_UCHAR (char_O_lead_tissue);					// || number of the leading tissue
+
 
-VAR_UINT  (int_O_TTS_norm);						// ascent time (TTS) in normal      plan in minutes
-VAR_UINT  (int_O_TTS_alt);						// ascent time (TTS) in alternative plan in minutes
+VAR_UINT  (int_O_TTS_norm);						// total time to surface (TTS)  in normal      plan in minutes
+VAR_UINT  (int_O_TTS_alt);						// total time to surface (TTS)  in alternative plan in minutes
 
-VAR_UINT  (int_O_CNS_current);					// current CNS %
+VAR_UINT  (int_O_TST_norm);						// total time of all deco stops in normal      plan in minutes
+VAR_UINT  (int_O_TST_alt);						// total time of all deco stops in alternative plan in minutes
+
 VAR_UINT  (int_O_CNS_norm);						// CNS% at end of dive in normal dive plan
 VAR_UINT  (int_O_CNS_alt);						// CNS% at end of dive in alternative plan
 
-VAR_UINT  (int_O_lead_supersat);				// supersaturation of the leading tissue in %, 100% = on M-line of straight Buhlmann
-
-VAR_UCHAR (char_O_lead_tissue);					// number of the leading tissue
-
-VAR_UCHAR (char_O_NDL_norm);					// remaining NDL time for the normal      dive plan in minutes
-VAR_UCHAR (char_O_NDL_alt);						// remaining NDL time for the alternative dive plan in minutes
+VAR_UINT  (int_O_NDL_norm);						// remaining NDL time for the normal      dive plan in minutes
+VAR_UINT  (int_O_NDL_alt);						// remaining NDL time for the alternative dive plan in minutes
 
 VAR_UCHAR (char_O_main_status);					// setup of the deco engine regarding the real tissue   computations
 VAR_UCHAR (char_O_deco_status);					// setup of the deco engine regarding the decompression computations
 VAR_UCHAR (char_O_deco_warnings);				// vector of warnings generated by the deco engine
 VAR_UCHAR (char_O_deco_info);					// vector of infos    generated by the deco engine
 
-VAR_UCHAR (char_O_EAD);							// equivalent air      depth (EAD) of breathed gas
-VAR_UCHAR (char_O_END);							// equivalent narcosis depth (END) of breathed gas
+VAR_UINT  (int_O_EAD_pres);						// equivalent air      depth (EAD) of breathed gas as relative pressure in[mbar]
+VAR_UINT  (int_O_END_pres);						// equivalent narcosis depth (END) of breathed gas as relative pressure in[mbar]
 
 TAB_UCHAR (char_O_tissue_pres_N2,    NUM_COMP);	// N2    tissue pressures   for display purpose
 TAB_UCHAR (char_O_tissue_pres_He,    NUM_COMP);	// He    tissue pressures   for display purpose
@@ -138,7 +144,6 @@
 VAR_UINT  (int_O_pure_ppO2);					// ppO2 of the current gas or diluent if breathed pure
 VAR_UINT  (int_O_pSCR_ppO2);					// ppO2 calculated in pSCR loop
 
-
 TAB_UINT  (int_O_pressure_need, 2);				// pressure reading, need by deco calculations, in 0.1 bar
 VAR_UINT  (int_O_SAC_measured);					// measured SAC rate in 0.1 liter/minute
 
@@ -158,12 +163,12 @@
 VAR_UCHAR (char_I_GF_High_percentage);			// GF model high value
 VAR_UCHAR (char_I_GF_Low_percentage);			// GF model low value
 
-VAR_UCHAR (char_I_depth_last_deco);				// depth of the last deco stop in meters
+VAR_UCHAR (char_I_last_stop_depth);				// depth of the last deco stop in meters
 
-VAR_UCHAR (char_I_deco_model);					// deco model selection: 0 = ZH-L16, 1 = ZH-L16-GF (with gradient factors)
+VAR_UCHAR (char_I_model);						// deco model selection: 0 = ZH-L16, 1 = ZH-L16-GF (with gradient factors)
 
-VAR_UCHAR (char_I_bottom_depth);				// bottom depth, used for gas volume calculations
-VAR_UCHAR (char_I_bottom_time);					// bottom time,  used for gas volume calculations
+VAR_UCHAR (char_I_bottom_depth);				// bottom depth for deco calculator and simulator
+VAR_UCHAR (char_I_bottom_time);					// bottom time  for deco calculator
 
 VAR_UCHAR (char_I_dive_interval);				// duration of surface break before next dive in minutes, used in simulation
 VAR_UCHAR (char_I_sim_advance_time);			// 'fast forward' of dive time, used in simulation (+5 min function)
@@ -195,7 +200,6 @@
 VAR_UCHAR (char_I_ppO2_min);					// warning threshold for maximum ppO2 when breathing OC
 VAR_UCHAR (char_I_ppO2_min_loop);				// warning threshold for maximum ppO2 when breathing from CCR or pSCR
 
-VAR_UCHAR (char_I_ascent_speed);				// ascent  speed in meters/minute
 VAR_UCHAR (char_I_descent_speed);				// descent speed in meters/minute
 VAR_UCHAR (char_I_gas_change_time);				// extra time spent during a stop for doing a gas change, in minutes
 
@@ -220,13 +224,12 @@
 VAR_UINT  (int_O_tank_pressure);				// tank pressure for logging in [bar]
 VAR_UINT  (int_O_gas_density);					// gas density of currently breathed mix in multiples of 0.01 grams per liter
 
-VAR_UCHAR (char_I_backtrack_time);				// index (in minutes) of backtrack entries in char_I_backtrack_depth
-VAR_UCHAR (char_I_gas_contingency);				// =1: switch to alternative gas if best gas is depleted
+VAR_UCHAR (char_I_backtrack_index);				// pointer to next writing position in the char_I_backtrack_storage array
 
 VAR_UCHAR (char_I_gas_density_att);				// threshold for gas density attention [0.1 grams/l]
 VAR_UCHAR (char_I_gas_density_warn);			// threshold for gas density warning   [0.1 grams/l]
 
-VAR_UCHAR (char_I_dil_ppO2_check);				// =1: check ppO2 of the pure diluent against current setpoint
+VAR_UCHAR (char_I_dil_check);					// =1: check ppO2 of the pure diluent against current setpoint
 
 
 #ifdef __18CXX
@@ -255,4 +258,4 @@
 bank11	udata_ovr	0xB00
 #endif
 
-TAB_UCHAR (char_I_backtrack_depth, 0x100);		// recorded depths for backtracking in cave mode
+TAB_UCHAR (char_I_backtrack_storage, 0x100);		// recorded depths for backtracking in cave mode
--- a/src/simulator.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/simulator.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File simulator.asm                        combined next generation V3.04.3
+;   File simulator.asm                        combined next generation V3.08.8
 ;
 ;   Deco Calculator
 ;
@@ -31,11 +31,13 @@
 	extern deco_pull_tissues_from_vault
 	extern TFT_decotype_logbook
 	extern do_return_demo_planner
-	extern dive_boot_oc_bail
+	extern convert_meter_to_feet
 	extern dive_boot_oc
+	extern get_first_gas_to_WREG
 
  IFDEF _ccr_pscr
 	extern dive_boot_cc
+	extern get_first_dil_to_WREG
  ENDIF
 
 
@@ -131,16 +133,28 @@
 	btfsc	update_surface_pressure			; is there a pending surface pressure update?
 	bra		$-2								; YES - loop waiting for the ISR to kick in
 
-	; set absolute pressure at selected depth
+	; calculate absolute pressure at selected depth
 	movff	char_I_bottom_depth,WREG		; get selected depth in meters
-	movwf	depth_meter						; set depth for check_gas_best code
-	mullw	.100							; multiply depth with 100 to get relative pressure in mbar
-	movff	int_I_pres_surface+0,WREG		; low  byte - get surface pressure to WREG
-	addwf	PRODL,W							;           - add relative pressure
-	movff	WREG,int_I_pres_respiration+0	;           - store as absolute pressure at depth
-	movff	int_I_pres_surface+1,WREG		; high byte - get surface pressure to WREG
-	addwfc	PRODH,W							;           - add relative pressure
-	movff	WREG,int_I_pres_respiration+1	;           - store as absolute pressure at depth
+	movwf	depth_meter						; store depth for check_gas_best code
+
+	movwf	xA+0							; copy depth in [m] to xA, low  byte
+	clrf	xA+1							; clear                xA, high byte
+
+	movff	opt_salinity,WREG				; get salinity setting (0 - 4 %)
+	addlw	d'100'							; add density of fresh water (1.00 kg/l)
+	mullw	.100							; multiply by 100 to counteract the x 100 with the freshwater conversion factor
+	MOVII	PRODL,xB						; copy result to xB
+	call	mult16x16						; xC:4 = xA:2 * xB:2
+
+	MOVLI	.102,xB							; load conversion factor x 100 for fresh water (1.02 cm per each 1 mbar)
+	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder = relative pressure [mbar] at depth
+
+	movff	int_I_pres_surface+0,WREG		; get surface  pressure,      low  byte
+	addwf	xC+0,W							; add relative pressure,      low  byte
+	movff	WREG,int_I_pres_respiration+0	; store as absolute pressure, low  byte
+	movff	int_I_pres_surface+1,WREG		; get surface pressure,       high byte
+	addwfc	xC+1,W							; add relative pressure,      high byte
+	movff	WREG,int_I_pres_respiration+1	; store as absolute pressure, high byte
 
 	; compute absolute pressure / 10, will be used by check_gas_best
 	MOVII	int_I_pres_respiration,xA		; get absolute pressure at depth
@@ -151,11 +165,14 @@
 	; set up gas / diluent to be used on bottom segment
 	clrf	WREG							; reset the deco info vector / deco flag so that ...
 	movff	WREG,char_O_deco_info			; ... check_gas_best will not pick any deco gases
+
+	call	get_first_gas_to_WREG			; find first gas
+	movwf	active_gas						; set  first gas
  IFDEF _ccr_pscr
-	clrf	active_dil						; invalidate active diluent
+	call	get_first_dil_to_WREG			; find first diluent
+	movwf	active_dil						; set  first diluent
  ENDIF
-	clrf	active_gas						; invalidate active gas
-	call	check_gas_best					; determine best diluent and/or gas
+	call	check_gas_best					; check if first gas & dil are usable, if not replace by usable gas / dil
 
  IFDEF _ccr_pscr
 	btfsc	FLAG_oc_mode					; in OC mode?
@@ -191,7 +208,7 @@
 
 deco_calculate_0_com:
 	; set deco stop settings
-	movff	opt_last_stop,char_I_depth_last_deco	; write last stop depth to deco engine
+	movff	opt_last_stop,char_I_last_stop_depth	; write last stop depth to deco engine
 
 	; set GF factors
 	movff	opt_GF_low, char_I_GF_Low_percentage	; load normal GF factors by default
@@ -212,7 +229,7 @@
 	bra		deco_calculate_2				; NO  - skip next
 	movff	opt_sim_setpoint_number,WREG	; YES - get selected setpoint
 	decf	WREG,W							;     - 1-5 -> 0-4
-	lfsr	FSR1,opt_setpoint_cbar			;     - load base address of setpoint list
+	lfsr	FSR1,opt_setpoint_cbar			;     - set base address of setpoint list
 	movff	PLUSW1,char_I_const_ppO2		;     - configure setpoint value
  ENDIF
 
@@ -222,12 +239,19 @@
 	movff	char_O_main_status,hi			; get the configuration set by dive_boot_oc / dive_boot_cc
 	bsf		hi,DECO_VOLUME_FLAG				; enable gas volume calculation
 	bsf		hi,DECO_BOTTOM_FLAG				; include bottom segment into gas needs
+
+ IFDEF _cave_mode
 	bcf		hi,DECO_CAVE_MODE				; cave mode not supported in deco calculator
-	bcf		hi,DECO_Z_FACTOR_FLAG			; disable Z factors by default
-	TSTOSC	opt_ZfactorUse					; shall use Z factors?
-	bsf		hi,DECO_Z_FACTOR_FLAG			; YES - enable Z factors
+ ENDIF
+
+ IFDEF _gas_contingency
+	bcf		hi,DECO_GAS_CONTINGENCY			; disable gas contingency mode by default
+	TSTOSC	opt_gas_contingency_sim			; gas contingency switched on?
+	bsf		hi,DECO_GAS_CONTINGENCY			; YES - activate gas contingency mode
+ ENDIF
+
 	bcf		hi,DECO_EXTENDED_STOPS			; disable extended stops by default
-	TSTOSC	opt_extended_stops				; shall make extended stops?
+	TSTOSC	opt_ext_stops					; shall make extended stops?
 	bsf		hi,DECO_EXTENDED_STOPS			; YES - activate extended stops
 	bcf		hi,DECO_TR_FUNCTIONS			; execution of TR functions is not needed in deco calculator mode
 	movff	hi,char_O_main_status			; bank-safe copy to deco engine control
@@ -239,7 +263,7 @@
 	bsf		lo,DECO_INITIALIZE				; set   flag for once-per-dive initialization
 	bsf		lo,DECO_CALCULATOR_MODE			; signal that the deco engine is run from the deco calculator
 	bcf		lo,DECO_BAILOUT_FLAG			; no gas switches before first deco stop
-	bcf		lo,DECO_ASCENT_FLAG				; no delayed ascent
+	bcf		lo,DECO_DELAY_FLAG				; no delayed ascent
 	movff	lo,char_O_deco_status			; bank-safe copy to deco engine control
 
 deco_calculate_redo:
@@ -285,7 +309,7 @@
 	movff	hi,char_O_main_status			;     - bank-safe copy back to deco engine control
 	movff	char_O_deco_status,lo			;     - bank-safe copy from deco engine control (deco status)
 	bsf		lo,DECO_BAILOUT_FLAG			;     - allow gas switches before first deco stop
-	bsf		lo,DECO_ASCENT_FLAG				;     - allow delayed ascent
+	bsf		lo,DECO_DELAY_FLAG				;     - allow delayed ascent
 	movff	lo,char_O_deco_status			;     - bank-safe copy back to deco engine control
 
 	TEXT_SMALL	.20,.125, tCalcBailout		;     - print what we are doing
@@ -304,8 +328,23 @@
 	banksel	common							;     - back to bank common
 	movff	char_O_depth_sim,lo				;     - get the depth reached (in meters)
 	WIN_SMALL .75,.150						;     - set output position
-	output_8								;     - print depth reached (in meters)
-	STRCAT	" m"							;     - print unit (meters)
+
+	TSTOSS	opt_units						; check depth units
+	bra		deco_calculate_loop_metric		; 0 - use Meters
+	;bra	deco_calculate_loop_imperial	; 1 - use Feet
+
+deco_calculate_loop_imperial:
+	call	convert_meter_to_feet			; convert value in lo from [m] to [feet]
+	output_16_3								; print depth reached
+	STRCAT_TEXT tFeets						; print unit (feet)
+	bra		deco_calculate_loop_0
+
+deco_calculate_loop_metric:
+	output_8								; print depth reached (in meters)
+	STRCAT_TEXT tMeters						; print unit (meters)
+	;bra	deco_calculate_loop_0			; continue
+
+deco_calculate_loop_0:
 	btg		decoplan_toggleflag				;     - toggle the toggle flag
 	btfsc	decoplan_toggleflag				;     - toggle flag set?
 	bra		deco_calculate_loop_1			;       YES - print ". "
@@ -405,7 +444,7 @@
 	TEXT_SMALL .80,.1, tDivePlan
 deco_results_page_2:
 	movff	char_O_deco_info,WREG			; get the deco info vector
-	btfsc	WREG,deco_stops					; are there deco stops?
+	btfsc	WREG,deco_stops_norm			; are there deco stops?
 	bra		deco_plan_show_1				; YES
 
 	;---- no deco --------------------------------------------------------
@@ -415,7 +454,7 @@
 	; output of remaining NDL time
 	WIN_SMALL .80, .50						; same line as bottom time
 	PUTC	"+"
-	movff	char_O_NDL_norm,lo				; get NDL time in normal plan
+	movff	int_O_NDL_norm+0,lo				; get NDL time in normal plan
 	bsf		leftbind
 	output_8
 	bcf		leftbind
@@ -429,7 +468,7 @@
 	;---- deco stops ---------------------------------------------------------
 deco_plan_show_1:
 	lfsr	FSR0,char_O_deco_depth			; initialize indexed addressing
-	lfsr	FSR1,char_O_deco_time
+	lfsr	FSR1,char_O_deco_time			; ...
 
 	clrf	decoplan_index					; start with index = 0
 	movlw	.24
@@ -510,8 +549,24 @@
 	STRCPY_TEXT tDepth
 	PUTC	":"
 	movff	char_I_bottom_depth,lo
-	output_8
-	STRCAT_PRINT "m"
+
+	TSTOSS	opt_units								; check depth units
+	bra		deco_results_metric						; 0 - use Meters
+	;bra	deco_results_imperial					; 1 - use Feet
+
+deco_results_imperial:
+	call	convert_meter_to_feet					; convert value in lo from [m] to [feet]
+	output_16_3										; print depth reached
+	STRCAT_TEXT tFeets								; print unit (feet)
+	bra		deco_results_0							; continue
+
+deco_results_metric:
+	output_8										; print depth reached (in meters)
+	STRCAT_TEXT tMeters								; print unit (meters)
+	;bra	deco_results_0							; continue
+
+deco_results_0:
+	STRCAT_PRINT ""									; finalize bottom depth output
 
 	; print warnings or sat/dsat factors
 	WIN_SMALL .0,.105
@@ -555,7 +610,7 @@
 	call	TFT_standard_color				; clean-up from warnings
 
 	; get model
-	movff	char_I_deco_model,WREG			; 0: straight Buhlmann, 1: with GF
+	movff	char_I_model,WREG				; 0: straight Buhlmann, 1: with GF
 	iorwf	WREG							; GF factors in use?
 	bz		deco_results_m2					; NO
 
@@ -594,7 +649,7 @@
 
 	btfss	FLAG_oc_mode					; current dive mode = OC ?
 	bra		deco_results_2d					; NO  - skip
-	TSTOSS	opt_extended_stops				; YES - extended stops activated?
+	TSTOSS	opt_ext_stops					; YES - extended stops activated?
 	bra		deco_results_2d					;       NO  - skip
 	WIN_SMALL .18,.155						;       YES - set position
 	STRCAT_PRINT "ext.Stop"					;           - print notice
@@ -690,7 +745,7 @@
 	movf	gas_index,W						; copy gas index to WREG for color-coding
 	call	TFT_color_code_gas				; set output color according to gas (1-5)
 
-	lfsr	FSR2,buffer						; load base address of output buffer
+	lfsr	FSR2,buffer						; set base address of output buffer
 	bsf		short_gas_descriptions			; configure gaslist_strcat_gas output format
 	bsf		divemode						; configure gaslist_strcat_gas output format
 	call	gaslist_strcat_gas				; write "Nxlo", "Txlo/hi", "Air" or "O2" into output buffer
@@ -776,7 +831,7 @@
 	btfsc	decoplan_pressures_shown		; results shown in bar?
 	bra		deco_results_1					; YES - show deco stops again
 	bsf		decoplan_pressures_shown		; NO  - but now
-	lfsr	FSR0,int_O_gas_need_pres		;     - load base address of gas needs in bar
+	lfsr	FSR0,int_O_gas_need_pres		;     - set base address of gas needs in bar
 	bra		deco_results_gas_common			;     - re-run gas needs output in pressure mode
 
 
--- a/src/sleepmode.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/sleepmode.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File sleepmode.asm                        combined next generation V3.06.1
+;   File sleepmode.asm                        combined next generation V3.08.8
 ;
 ;   Sleep Mode
 ;
@@ -26,7 +26,8 @@
 #include "tft_outputs.inc"
 
 
-	extern	vault_decodata_into_eeprom
+	extern	eeprom_deco_data_write
+	extern	option_check_and_store_all
 	extern	power_up_switches			; from hwos.asm
 
 
@@ -81,9 +82,14 @@
 	call	disable_rs232					; power-down USB
 	call	I2C_sleep_compass				; power-down compass
 
-	call	vault_decodata_into_eeprom		; store deco data
+	call	eeprom_deco_data_write			; update deco data     in EEPROM
+	call	eeprom_battery_gauge_write		; update battery gauge in EEPROM
+
+	btfsc	options_changed					; do the options need to be stored to EEPROM ?
+	call	option_check_and_store_all		; YES - check and store all option values in EEPROM
+	bcf		options_changed					; clear flag
+
 	call	ext_flash_enable_protection		; enable write protection on external flash
-	call	update_battery_registers		; update battery registers into EEPROM
 
 	clrf	sm_timer_10sec					; clear 10 seconds timer
 	clrf	sm_timer_10min					; clear 10 minutes timer
@@ -92,7 +98,7 @@
 
 	call	TFT_Display_FadeOut				; power-down backlight
 	call	TFT_DisplayOff					; power-down display
-	
+
 sleeploop_loop:
 	btfsc	trigger_full_second				; one second in sleep?
 	rcall	one_sec_sleep					; YES - check switches, pressure sensor, etc.
@@ -293,8 +299,8 @@
 one_hour_sleep:
 	; tasks every hour in sleep mode mode
 	bcf		trigger_full_hour				; clear one hour flag
-	call	update_battery_registers		; update battery registers into EEPROM
-	call	vault_decodata_into_eeprom		; update tissue  pressures into EEPROM
+	call	eeprom_deco_data_write			; update deco data     into EEPROM
+	call	eeprom_battery_gauge_write		; update battery gauge into EEPROM
 	return									; done
 
 
--- a/src/start.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/start.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File start.asm                            combined next generation V3.06.1
+;   File start.asm                            combined next generation V3.08.8
 ;
 ;   Startup subroutines
 ;
@@ -28,19 +28,23 @@
 
 
 	extern	init_ostc
-	extern	option_restore_all
 	extern	backup_flash_page
-	extern	restore_decodata_from_eeprom
-	extern	oPressureAdjust
+	extern	eeprom_deco_data_read
+	extern	option_restore_and_check_all
+	extern	option_restore_and_check
+	extern	option_check_and_store_all
+	extern	option_check_and_store
 	extern	option_reset
-	extern	option_save
-	extern	option_save_all
-	extern	option_check_all
+	extern	rtc_init
 	extern	do_new_battery_select
 	extern	get_battery_data
 	extern	use_old_prior_209
 	extern	get_first_gas_to_WREG
 
+	extern	oFirmwareMajor
+	extern	oFirmwareMinor
+	extern	oPressureAdjust
+
  IFDEF _ccr_pscr
 	extern	option_cleanup_oCCRMode_pSCR
 	extern	option_cleanup_oCCRMode_CCR
@@ -94,16 +98,16 @@
 
 	; initialize averaging for analog buttons
 	movlw	.16								; set averaging span
-	movff	WREG,analog_counter				; write to counter
+	movff	WREG,analog_counter				; write to counter (in bank isr_backup)
 
 	; get button type from bootloader info
-	bsf		analog_switches
-	movlw	0x7C
-	movwf	TBLPTRL
-	movlw	0xF7
-	movwf	TBLPTRH
-	movlw	0x01
-	movwf	TBLPTRU
+	bsf		analog_switches					; assume analog buttons by default
+	movlw	0x7C							; address bootloader at 0x01F77C
+	movwf	TBLPTRL							; ...
+	movlw	0xF7							; ...
+	movwf	TBLPTRH							; ...
+	movlw	0x01							; ...
+	movwf	TBLPTRU							; ...
 	TBLRD*+									; read configuration byte
 	movlw	0x07							; coding for analog buttons
 	cpfseq	TABLAT							; equal?
@@ -123,13 +127,7 @@
 	bcf		screen_type3					; NO  -  not screen type 3
 
 	; get button polarity from configuration data (EEPROM)
-	movlw	LOW  .897
-	movwf	EEADR
-	movlw	HIGH .897
-	movwf	EEADRH
-	call	read_eeprom						; EEDATA into EEPROM @ EEADR
-	clrf	EEADRH							; reset EEADRH
-	movff	EEDATA,button_polarity			; 0xFF (both normal), 0x00 (both inverted), 0x01 (left inverted only), 0x02 (right inverted only)
+	EEPROM_CC_READ eeprom_button_polarity,button_polarity
 
 	; initialize pressure sensor calibration
 	call	get_calibration_data			; get calibration data from pressure sensor
@@ -141,16 +139,10 @@
 	; first pass, will not have valid temperature yet
 	call	wait_1s
 	call	wait_1s
-;	bcf		trigger_pres_update				; make sure ISR pressure update confirmation is not older than from now on
-;	btfss	trigger_pres_update				; has the ISR confirmed a pressure update?
-;	bra		$-2								; NO  - not yet, loop waiting for the ISR to kick in
 
 	; second pass - complete sensor initialization
 	call	wait_1s
 	call	wait_1s
-;	bcf		trigger_pres_update				; make sure ISR pressure update confirmation is not older than from now on
-;	btfss	trigger_pres_update				; has the ISR confirmed a pressure update?
-;	bra		$-2								; NO  - not yet, loop waiting for the ISR to kick in
 
 	; sensor calibration completed, first valid pressure value is available
 	bcf		LEDr							; turn off red LED again
@@ -167,23 +159,24 @@
 
 	; reset all tissue pressures to surface pressure equilibrium state by default
 	call	deco_clear_tissue				; (C-code)
-	banksel	common
+	banksel	common							; back to bank common
 
-	; restore tissue pressures from EEPROM (if available)
-	movlw	HIGH .512						; =2
-	movwf	EEADRH							; set EEPROM address, high byte
-	read_int_eeprom	.0						; read tissue storage information flag
-	clrf	EEADRH							; revert EEPROM high address pointer to default
-	movlw	0xAA							; load coding for tissue pressures available
-	cpfseq	EEDATA							; tissue pressures available?
-	bra		start_1							; NO  - no tissue pressures available
-	call	restore_decodata_from_eeprom	; YES - reload tissue pressures from EEPROM
+	; restore deco status from EEPROM (if possible)
+	EEPROM_CC_READ eeprom_deco_data_validity,WREG	; read deco data validity
+	xorlw	DECO_DATA_VALID_TOKEN					; deco data valid?
+	bnz		start_clean								; NO  - start "clean"
+	EEPROM_CC_READ eeprom_deco_data_version,WREG	; YES - read deco data format version
+	xorlw	eeprom_vault_version					;     - deco data format compatible?
+	bnz		start_clean								;       NO  - start "clean"
+	call	eeprom_deco_data_read					;       YES - restore deco data from EEPROM
+	bra		start_common							;           - continue with common part
 
-start_1:
+start_clean:
 	bsf		reset_surface_interval			; request ISR to reset the surface interval timer
+	btfss	RCON,POR						; was there a power outage ?
+	call	rtc_init						; YES - initialize RTC to firmware creation date
 
-;	call	rtc_init						; initialize the real time clock (will reset to firmware creation date)
-
+start_common:
 	; check for power-on reset
 	btfsc	RCON,POR						; was this a power-on reset?
 	call	use_old_prior_209				; NO - migrate the last battery status from firmware 2.09 or earlier
@@ -209,56 +202,44 @@
 	WIN_LEFT .10
 	TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block
 
-	; check if a new firmware was loaded, if yes reset option oPressureAdjust
-	movlw	d'1'							; set EEPROM address to 0x101
-	movwf	EEADR							; = 0x001
-	movwf	EEADRH							; = 0x101
-	call	read_eeprom						; read current version, major
-	movff	EEDATA,lo						; store major in lo
-	incf	EEADR,F							; set EEPROM address to 0x102
-	call	read_eeprom						; read current version, minor
-	movff	EEDATA,hi						; store minor in hi
-	clrf	EEADRH							; reset EEADRH
-
-	movlw	softwareversion_x				; get current major version
-	cpfseq	lo								; compare with stored version, equal?
-	bra		start_check_new_firmware_new	; NO - reset some options and store new version in EEPROM
-
-	movlw	softwareversion_y				; get current minor version
-	cpfseq	hi								; compare with stored version, equal?
-	bra		start_check_new_firmware_new	; NO  - reset some options and store new version in EEPROM
-	bra		start_check_new_firmware_old	; YES - both equal, do not reset options
+	; check if a new firmware was loaded
+	lfsr	FSR0,oFirmwareMajor				; address firmware version
+	call	option_restore_and_check		; read    firmware version, major
+	call	option_restore_and_check		; read    firmware version, minor
+	call	option_restore_and_check		; read    firmware version, beta
 
-start_check_new_firmware_new:
-	; new firmware version detected
-	call	show_fw_mesg_update				; show firmware update message
-
-	; place "after-update reset" here...
-	lfsr	FSR0,oPressureAdjust			; memory address of option data
-	call	option_reset					; reset oPressureAdjust to factory default
-	lfsr	FSR0,oPressureAdjust			; memory address of option data
-	call	option_save						; save reseted value of oPressureAdjust in EEPROM
+	movff	opt_fw_version_major,WREG		; get stored major version
+	xorlw	fw_version_major				; compare with currently active version, equal?
+	bnz		start_check_new_firmware_new	; NO  - a new firmware was loaded
 
-	; store current version in EEPROM
-	movlw	d'1'							; set EEPROM address to 0x101
-	movwf	EEADR							; = 0x001
-	movwf	EEADRH							; = 0x101
-	movlw	softwareversion_x				; get version, major number
-	movwf	EEDATA							; prepare write
-	call	write_eeprom					; execute write
-	incf	EEADR,F							; set EEPROM address to 0x102
-	movlw	softwareversion_y				; get version, minor number
-	movwf	EEDATA							; prepare write
-	call	write_eeprom					; execute write
-	clrf	EEADRH							; reset EEADRH
-	bra		start_check_new_firmware_common	;
+	movff	opt_fw_version_minor,WREG		; get stored minor version
+	xorlw	fw_version_minor				; compare with currently active version, equal?
+	bnz		start_check_new_firmware_new	; NO  - a new firmware was loaded
+
+	movff	opt_fw_version_beta,WREG		; get stored beta version
+	xorlw	fw_version_beta					; compare with currently active version, equal?
+	bnz		start_check_new_firmware_new	; NO  - a new firmware was loaded
+	;bz		start_check_new_firmware_old	; YES - same  firmware as  before
 
 start_check_new_firmware_old:
 	call	show_fw_mesg_kept				; show firmware is kept message
+	bra		start_check_new_firmware_common	; continue with common part
+
+start_check_new_firmware_new:
+	call	show_fw_mesg_update				; show firmware update message
+
+	; reset the pressure sensor correction to factory default
+	lfsr	FSR0,oPressureAdjust			; address pressure sensor correction
+	call	option_reset					; set correction to default
+
+	lfsr	FSR0,oPressureAdjust			; address pressure sensor correction
+	call	option_check_and_store			; update correction in EEPROM
 
 start_check_new_firmware_common:
 	call	TFT_Display_FadeIn				; display resulting screen
+
 	call	backup_flash_page				; back-up the first 128 bytes from program flash memory to EEPROM
+	call	option_restore_and_check_all	; restore all option values from EEPROM and check them
 
 	; pause 5 seconds
 	movlw	.5								; load loop counter
@@ -277,46 +258,34 @@
 ;
 	global	restart
 restart:
-	banksel	common							; for safety purpose only
+	; for safety purpose only
+	banksel	common							; select bank common
 	clrf	STKPTR							; clear return addresses stack
+	call	request_speed_normal			; request CPU speed change to normal speed
+
+	; switch off backlight
 	clrf	CCP1CON							; stop PWM
 	bcf		PORTC,2							; pull PWM out to GND
-
-	call	request_speed_normal			; request CPU speed change to normal speed (for safety only)
-
-	; manage the option settings
-	btfsc	surfmode_menu					; was restart entered by return from surface menu or comm mode?
-	call	option_save_all					; YES - save all settings into EEPROM
-
-	btfss	surfmode_menu					; was restart entered by return from surface menu or comm mode?
-	call	option_restore_all				; NO  - load all settings from EEPROM
-
-	call	option_check_all				; check all options and repair them if not within their min/max boundaries
-
-	btfsc	option_repaired					; errors found & repaired during options check?
-	call	option_save_all					; YES - save corrected settings into EEPROM
+	bsf		tft_is_dimming					; ignore ambient sensor
 
 	; clear flag groups
 	clrf	HW_descriptor					; hardware - OSTC model descriptor
 	clrf	HW_flags_state1					; hardware - states
 	;										; do not clear HW_flags_state2 !
 	clrf	DM_flags_sensor					; hardware - O2 sensors
-
 	clrf	OS_flags_ISR1					; operating system - ISR control 1
 	clrf	OS_flags_ISR2					; operating system - ISR control 2
-
 	clrf	eventbase						; event triggers generated by ISR
-
 	clrf	DM_flags_deco					; dive deco modes
-
 	clrf	MS_flags_control				; menu system - control
 	clrf	MS_flags_imprint				; menu system - data imprinting
-
 	clrf	CVT_flags1						; convert and display functions
 	clrf	CVT_flags2						; convert and display functions
 
-	; TFT will be dimming soon, ignore ambient sensor
-	bsf		tft_is_dimming
+	; check if option values have changed and thus if the EEPROM needs to be updated
+	btfsc	options_changed					; do the options need to be stored to EEPROM ?
+	call	option_check_and_store_all		; YES - check and store all option values in EEPROM
+	bcf		options_changed					; clear flag
 
 	; configure the OSTC model descriptor (stored in HW_descriptor)
 	bcf		tft_power						; inverted, here needed for I2C_probe_OSTC_rx, to wake-up RX circuity
@@ -347,41 +316,41 @@
 restart2:
  IFNDEF _hwos_sport
 	btfsc	vusb_in							; USB power detected?
-	bra		restart3						; YES
-	bcf		PORTE,0							; start comm
-	WAITMS	d'5'							; wait 5 ms
-	btfss	vusb_in							; USB power detected?
-	bra		restart3						; NO
+	bra		restart3						; YES - no BLE then
+	bcf		PORTE,0							; NO  - power up BT chip (if available)
+	WAITMS	d'5'							;     - wait 5 ms
+	btfss	vusb_in							;     - BT chip detected?
+	bra		restart3						;       NO  - no BLE then
  ENDIF
-	bsf		ble_available					; YES - BLE available
+	bsf		ble_available					;       YES - BLE available
 
 restart3:
-	bsf		PORTE,0							; stop comm
+	bsf		PORTE,0							; power down BLE chip
 	btfsc	ble_available					; BLE available?
-	bra		restart4						; YES - can't be a cR
-	btfss	battery_gauge_available			; rechargeable?
-	bra		restart4						; NO  - can't be a cR
-	bsf		analog_o2_input					; set flag for analog
+	bra		restart4						; YES - can't be a cR then
+	btfss	battery_gauge_available			; NO  - rechargeable?
+	bra		restart4						;       NO  - can't be a cR
+	bsf		analog_o2_input					;       YES - it's a cR, analog input available
 
 restart4:
 	bsf		lv_core							; default to low voltage core
 	movlw	0x80							; point to 0x1F780
-	movwf	TBLPTRL
-	movlw	0xF7
-	movwf	TBLPTRH
-	movlw	0x01
-	movwf	TBLPTRU
+	movwf	TBLPTRL							; ...
+	movlw	0xF7							; ...
+	movwf	TBLPTRH							; ...
+	movlw	0x01							; ...
+	movwf	TBLPTRU							; ...
 	TBLRD*+									; read from 0x1F780
 	movlw	0x83							; coding for low voltage core, part 1
 	cpfseq	TABLAT							; equal?
-	bra		restart4a						; NO - no low voltage core then
-	movlw	0x81							; point to  0x1F781
-	movwf	TBLPTRL
-	TBLRD*+									; read from 0x1F781
-	movlw	0x94 							; coding for low voltage core, part 2
-	cpfseq	TABLAT							; equal?
+	bra		restart4a						; NO  - no low voltage core then
+	movlw	0x81							; YES - point to  0x1F781
+	movwf	TBLPTRL							;     - ...
+	TBLRD*+									;     - read from 0x1F781
+	movlw	0x94 							;     - coding for low voltage core, part 2
+	cpfseq	TABLAT							;     - equal?
 restart4a:
-	bcf		lv_core							; NO - no low voltage core then
+	bcf		lv_core							;       NO - no low voltage core then
 
 
  IFDEF _rx_functions
@@ -411,14 +380,12 @@
 restart4b:
 	; print TR module update message
 	call	TFT_boot						; initialize TFT (includes clear screen & backlight switch-off)
-	WIN_TOP  .40							; show heinrichsweikamp logo
-	WIN_LEFT .10
-	TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block
-	WIN_SMALL .10,.130
+	WIN_TOP  .40							; set position
+	WIN_LEFT .10							; ...
+	TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block ; show heinrichsweikamp logo
+	WIN_SMALL .10,.130						; set position
 	STRCAT_PRINT "Updating TR Module..."	; print update message
-	call	TFT_Display_FadeIn				; display screen
-	WIN_SMALL .10,.160
-	STRCAT	"TR Update "					; prepare result message
+	call	TFT_Display_FadeIn				; dimm up backlight to show outputs
 
 	; update firmware in RX module
 	call	I2C_sleep_compass				; stop compass
@@ -505,7 +472,6 @@
 ;
 	global	restart_set_modes_and_flags
 restart_set_modes_and_flags:
-	call	option_restore_all				; restore all options settings from EEPROM
 	call	disable_ir_s8					; switch off IR/S8 digital interface by default (for all compile versions!)
 
  IFDEF _external_sensor
@@ -535,7 +501,7 @@
 	; configure saturation / desaturation safety factors
 	movff	opt_sat_multiplier_gf,  char_I_saturation_multiplier		; use factors for GF mode by default
 	movff	opt_desat_multiplier_gf,char_I_desaturation_multiplier		; ...
-	TSTOSC	char_I_deco_model											; get deco model ZH-L16-GF (1) selected?
+	TSTOSC	char_I_model												; get deco model ZH-L16-GF (1) selected?
 	bra		restart_set_modes_and_flags2								; YES - keep them
 	movff	opt_sat_multiplier_non_gf,  char_I_saturation_multiplier	; NO  - overwrite them with non-GF factors
 	movff	opt_desat_multiplier_non_gf,char_I_desaturation_multiplier	;     - ...
@@ -582,8 +548,8 @@
 	decfsz	lo,F							; Apnea mode?
 	bra		restart_set_modes_and_flags6	; NO
 	bsf		FLAG_apnoe_mode					; YES - set apnea flag
-	movlw	samplingrate_apnoe				; get apnoe sampling rate
-	movwf	sampling_rate					; overwrite user-selected 2/10 seconds setting with apnoe default
+	movlw	samplingrate_apnoe				;     - get apnoe sampling rate
+	movwf	sampling_rate					;     - overwrite user-selected 2/10 seconds setting with apnoe default
  IFDEF _rx_functions
 	call	option_cleanup_oTrMode_no_CCR	;     - revert TR mode from 'CCR Dil+O2' to 'on'
  ENDIF
--- a/src/surfmode.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/surfmode.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File surfmode.asm                         next combined generation V3.04.3
+;   File surfmode.asm                         next combined generation V3.08.8
 ;
 ;   Surface Mode
 ;
@@ -111,9 +111,8 @@
 
 	call	I2C_sleep_compass		; shut down compass
 
-	clrf	ext_flash_address+0
-	clrf	ext_flash_address+1
-	clrf	ext_flash_address+2
+	CLRT	ext_flash_address
+
 
  IFDEF _ccr_pscr
 	movlw	surface_sp				; load default surface setpoint (in cbar)
@@ -126,7 +125,6 @@
 
 	bcf		surfmode_menu			; not in surface menu (any more)
 	bcf		compass_menu			; not in "set bearing" selection (any more)
-	bcf		bailout_mode			; not in bailout menu (any more)
 
 	bcf		switch_left				; clear intermediate button event since start/restart
 	bcf		switch_right			; clear intermediate button event since start/restart
@@ -192,6 +190,18 @@
 	TSTOSS	opt_dive_mode					; in OC? (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR)
 	call	TFT_show_OC_startgas_surface	; YES - show first gas and "OSTC2-like" active gases
 
+	; configure tissue graphics
+	bcf		tissue_graphic_mode				; select surface mode
+	bsf		tissue_graphic_cns				; show CNS value
+
+	bsf		tissue_graphic_layout			; default to N2+He
+	TSTOSS	opt_tissue_graphics				; shall show press+sat?
+	bcf		tissue_graphic_layout			; YES - show press+sat
+
+	bcf		tissue_graphic_gf				; default to none-GF
+	TSTOSC	char_I_model					; GF factors enabled?
+	bsf		tissue_graphic_gf				; YES - show GF lines
+
 	movff	customview_surfmode,active_customview	; reload last custom view
 	call	surf_customview_mask					; redraw last custom view
 
@@ -305,7 +315,7 @@
 
 test_switches_surfmode2:				; right button pressed
 	bcf		switch_right				; clear button event
-	rcall	reset_timeout_surfmode		; reset timeout
+	rcall	reset_timeout_surfmode		; set up timeout
  IFDEF _compass
 	movlw	.6							; coding for surface custom compass view
 	cpfseq	active_customview			; in compass view?
@@ -323,7 +333,7 @@
 
 test_switches_surfmode3:				; left button pressed
 	bcf		switch_left					; clear button event
-	rcall	reset_timeout_surfmode		; reset timeout
+	rcall	reset_timeout_surfmode		; set up timeout
  IFDEF _compass
 	movlw	.6							; coding for surface custom view compass
 	cpfseq	active_customview			; in compass view?
@@ -486,41 +496,46 @@
 	return								; YES - suppress COMM mode to not jeopardize backup/restore of tissue data
 
 	btfss	vusb_in						; USB plugged in?
-	return								; NO - done
+	return								; NO  - done
  IFDEF _screendump
 	btfsc	screen_dump_avail			; YES - screen dump enabled?
 	return								;       YES - no COMM mode to be able to make screen shots of the menu and simulator mode
  ENDIF
-	btfss	ble_available				; Skip "USB" check in all Bluetooth models (Required for very old OSTC sport)
+	btfss	ble_available				; skip "USB" check in all Bluetooth models (required for very old OSTC sport)
 	goto	comm_mode_usb				; YES / NO  - proceed to COMM mode, will also set CPU to speed normal
 	return
 
+
 	global	reset_timeout_surfmode
 reset_timeout_surfmode:
 	movlw	surfmode_timeout_default	; load default timeout value
-	btfsc	imprint_sensor_mv			; currently imprinting O2 sensor mV data?
-	movlw	surfmode_timeout_calibrate	; YES - replace with CCR Calibrate Menu timeout
+	btfss	battery_is_36v				; running on a 3.6 V battery?
+	movlw	surfmode_timeout_aa_15v		; NO  - replace by timeout for 1.5V battery
 	btfsc	simulatormode				; currently in simulator (deco calculator) mode?
 	movlw	surfmode_timeout_simulator	; YES - replace with simulator timeout
- IFDEF _rx_functions
-	btfsc	imprint_xmitter_ID			; currently selecting pressure transmitter?
-	movlw	surfmode_timeout_xmitter	; YES - replace with transmitter selection timeout
- ENDIF	; _rx_functions
- IFDEF _external_sensor
-	btfsc	surfmode_menu				; in surface menu?
-	bra		reset_timeout_time			; YES - keep timeout value
-	btfsc	FLAG_ccr_mode				; NO  - in CCR mode?
-	bra		reset_timeout_surfmode_loop	;       YES - continue checking if in sensor mode
-	btfsc	FLAG_ccr_mode				;       NO  - in pSCR mode?
-	bra		reset_timeout_surfmode_loop	;             YES - continue checking if in sensor mode
-	bra		reset_timeout_time			;             NO  - keep timeout value
-reset_timeout_surfmode_loop:
-	movff	opt_ccr_mode,lo				; get loop mode (=0: fixed/calculated SP, =1: sensor, =2: auto SP)
-	decfsz	lo,f						; in sensor mode?
-	bra		reset_timeout_time			; NO  - keep timeout value
-	movlw	surfmode_timeout_sensor		; YES - replace with sensor mode timeout
- ENDIF	; _external_sensor
-	;bra	reset_timeout_time			;     - set  timeout value
+	;bra	reset_timeout_time			; set timeout value
+
+;	btfsc	imprint_sensor_mv			; currently imprinting O2 sensor mV data?
+;	movlw	surfmode_timeout_calibrate	; YES - replace with CCR Calibrate Menu timeout
+; IFDEF _rx_functions
+;	btfsc	imprint_xmitter_ID			; currently selecting pressure transmitter?
+;	movlw	surfmode_timeout_xmitter	; YES - replace with transmitter selection timeout
+; ENDIF	; _rx_functions
+; IFDEF _external_sensor
+;	btfsc	surfmode_menu				; in surface menu?
+;	bra		reset_timeout_time			; YES - keep timeout value
+;	btfsc	FLAG_ccr_mode				; NO  - in CCR mode?
+;	bra		reset_timeout_surfmode_loop	;       YES - continue checking if in sensor mode
+;	btfsc	FLAG_ccr_mode				;       NO  - in pSCR mode?
+;	bra		reset_timeout_surfmode_loop	;             YES - continue checking if in sensor mode
+;	bra		reset_timeout_time			;             NO  - keep timeout value
+;reset_timeout_surfmode_loop:
+;	movff	opt_ccr_mode,lo				; get loop mode (=0: fixed/calculated SP, =1: sensor, =2: auto SP)
+;	decfsz	lo,f						; in sensor mode?
+;	bra		reset_timeout_time			; NO  - keep timeout value
+;	movlw	surfmode_timeout_sensor		; YES - replace with sensor mode timeout
+; ENDIF	; _external_sensor
+;	;bra	reset_timeout_time			; set  timeout value
 
 
 	global	reset_timeout_time
--- a/src/text_english.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/text_english.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_english.asm                     next combined generation V3.04.3
+;	File text_english.asm                     next combined generation V3.08.8
 ;
 ;	English texts reference file.
 ;
@@ -8,20 +8,28 @@
 ;=============================================================================
 
 ; Basic texts
-	TCODE	tNo,				"No"					; 0 No    | ENUM group
-	TCODE	tYes,				"Yes"					; 1 Yes   |
+	TCODE	tNo,				"No"					; 0 No		| ENUM group
+	TCODE	tYes,				"Yes"					; 1 Yes		|
+
  IFDEF _cave_mode
-	TCODE	tCave,				"Cave"					; 2 Cave  |
+	TCODE	tOff,				"off"					; OFF		| Enum group
+	TCODE	tOn,				"on"					; ON		|
+ ELSE
+	TCODE	tOff,				" "						; needed for option table
  ENDIF
 
 	TCODE	tblank,				" "						; (a single space character)
 
-; Surface-mode texts
+; Surface-Mode texts
 	TCODE	tMenu,				"<Menu"					; <Menu
 	TCODE	tView,				"View>"					; View>
 	TCODE	tHeading,			"Heading:"				; Heading:
 	TCODE	tLastDive,			"Last Dive"				; Last Dive (Max 10 chars)
 
+	TCODE	tFTTSSurf,			"fTTS/Delay:"			; Future TTS / Ascent Delay
+	TCODE	tLastDecostopSurf,	"Last Deco :"			; last deco stop depth Surface Custom View
+	TCODE	tDvSalinitySurf,	"Salinity  :"			; Salinity
+
  IFDEF _external_sensor
 	TCODE	tSensorMilliVolt,	"Sensors mV"			; Sensors mV
  ENDIF
@@ -33,7 +41,12 @@
 	TCODE	tDivemenu_Avg_Mkr,	"Avg/Marker"			; Reset Avg, Set Marker (and Turn Dive)
 	TCODE	tDivemenu_ToggleGF,	"Toggle GF"				; Toggle GF
 	TCODE	tDivemenu_Marker,	"Set Marker"			; Set Marker
+
+ IFDEF _cave_mode
+	TCODE	tDivemenu_LostGas,	"Gas avail."			; Gas Availability
+ ELSE
 	TCODE	tDivemenu_LostGas,	"Lost Gas"				; Lost Gas
+ ENDIF
 
  IFDEF _ccr_pscr
 	TCODE	tDivemenu_Diluent,	"Diluents"				; Diluents (CCR)
@@ -46,7 +59,13 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tDivemenu_TurnDive,	"Turn Dive"				; Turn Dive
+	TCODE	tDivePreCave,		"Cave?"					; Enter Cave Menu          ( 5 chars max)
+	TCODE	tDivemenu_wp_set,	"Waypoint"				; Set Waypoint             (10 chars max)
+	TCODE	tDivemenu_wp_out,	"WP go <-()"			; go one Waypoint outwards (10 chars max)
+	TCODE	tDivemenu_wp_in,	"WP go ->()"			; go one Waypoint inwards  (10 chars max)
+	TCODE	tDivemenu_TurnDive,	"Turn Dive"				; Turn Dive                (10 chars max)
+	TCODE	tDivemenu_ContDive,	"Cont.Dive"				; Continue Dive            (10 chars max)
+	TCODE	tDivemenu_off_on, 	"Off / On"				; Cave Mode Off/On         (10 chars max)
  ENDIF
 
 
@@ -58,11 +77,19 @@
 	TCODE	tGasSetup,			"OC Gas Setup"			; OC Gas Setup
 	TCODE	tSetTime,			"Set Time"				; Set Time
 	TCODE	tSetDate,			"Set Date"				; Set Date
-	TCODE	tSetTimeDate,		"Set Time & Date"		; Set Time & Date
+	TCODE	tSetTimeDate,		"Time & Date"			; Time & Date
 	TCODE	tDispSets,			"Display Settings"		; Display Settings
+	TCODE	tSysSets,			"System  Settings"		; System  Settings
 	TCODE	tExit,				"Exit"					; Exit
 	TCODE	tResetMenu,			"Reset Menu"			; Reset Menu
-	TCODE	tDiveModeMenu,		"Deco Setup"			; Deco Setup
+	TCODE	tDiveModeMenu,		"Dive Setup"			; Dive Setup
+
+	TCODE	tDiveSetup,			"Dive Setup"			; Dive Setup
+	TCODE	tDecoSetup,			"Deco Setup"			; Deco Setup
+	TCODE	tSACSetup,			"SAC  Setup"			; SAC Setup
+	TCODE	tppO2Setup,			"ppO2 Setup"			; ppO2 Setup
+	TCODE	tStopsSetup,		"Stops & Depths"		; Stops & Depths
+
 	TCODE	tInfoMenu,			"Information"			; Information
  IFDEF _ccr_pscr
 	TCODE	tCCRSetup,			"CCR/pSCR Setup"		; CCR/pSCR Setup
@@ -70,6 +97,7 @@
  ENDIF
 	TCODE	tFixedSetpoints,	"CCR Setpoints"			; Fixed Setpoints for CCR
 	TCODE	tBack,				"back"					; back
+	TCODE	tGas6,				"extra Gas"				; edit & select Gas 6
 
  IFDEF _rx_functions
 	TCODE	tTrSettings,		"Pressure Display"		; Pressure Display
@@ -80,13 +108,16 @@
 	TCODE	tTrMaxDeltaP,		"max deltaP: "			; independent double max diffenerce
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tCCRSensor,			"Sensor"				; CCR/pSCR Sensor
 	TCODE	tCalibrateMenu,		"Calibration"			; Calibration
 	TCODE	tCalibrationGas,	"Cal. Gas O2:"			; Cal. Gas O2:
 	TCODE	tCalibrate,			"Calibrate"				; Calibrate
- ENDIF
+	TCODE	tS8Mode,			"S8 Input: "			; Sensor Input
+	TCODE	tCCRS8Mode,			"Analog"				; Analog
+	TCODE	tCCRS8Mode2,		"Digital"				; Digital
+ ELSE
+	TCODE	tCCRS8Mode,			" "						; needed for option table
  ENDIF
 
 
@@ -124,7 +155,7 @@
 	TCODE	tppO2O2,			"ppO2(O2)"				; ppO2(O2)
 	TCODE	tppO2Dil,			"ppO2(Dil)"				; ppO2(Dil)
 	TCODE	tppO2Mix,			"ppO2(Mix)"				; ppO2(Mix)
-	TCODE	tCCRMode,			"Mode:"					; Mode:
+	TCODE	tCCRMode,			"Mode: "				; CCR/pSCR Mode
 	TCODE	tCCRModeFixedSP,	"Fixed SP"				; 0 fixed for CCR / calculated for pSCR  | ENUM group
 	TCODE	tCCRModeSensor,		"Sensor"				; 1 Sensor                               |
 	TCODE	tCCRModeAutoSP,		"Auto SP"				; 2 Auto SP                              |
@@ -153,7 +184,8 @@
 ; Gaslist Management
 	TCODE	tGas,				"Gas"					; Gas
 	TCODE	tDil,				"Dil"					; Diluent
-	TCODE	tGasErr,			"Err"					; Err (3 chars)
+	TCODE	tGasErr,			"Err"					; Err      (max 3 chars)
+	TCODE	tTakeGas,			"take"					; take gas (max 4 chars)
 
 
 ; Communication menu
@@ -169,12 +201,18 @@
 
 
 ; Dive settings
-	TCODE	tDvMode,			"Dive Mode: "
-	TCODE	tDvOC,				"OC"					; 0      - keep order, enum!
-	TCODE	tDvCCR,				"CCR"					; 1
-	TCODE	tDvGauge,			"Gauge"					; 2
-	TCODE	tDvApnea,			"Apnea"					; 3
-	TCODE	tDvPSCR,			"pSCR"					; 4
+	TCODE	tDvMode,			"Dive Mode   : "		; Dive Mode
+ IFDEF _cave_mode
+	TCODE	tCvMode,			"Cave Mode   : "		; Cave Mode
+ ENDIF
+	TCODE	tFTTSMenu,			"fTTS/Delay  : "		; Future TTS / Ascent Delay
+	TCODE	tTimeoutDive,		"Dive Timeout: "		; Dive Timeout
+	TCODE	tStoreApnoeDive,	"Store Apnoe : "		; Store Apnoe Dives
+	TCODE	tDvOC,				"OC"					; 0 | keep order, enum!
+	TCODE	tDvCCR,				"CCR"					; 1 |
+	TCODE	tDvGauge,			"Gauge"					; 2 |
+	TCODE	tDvApnea,			"Apnea"					; 3 |
+	TCODE	tDvPSCR,			"pSCR"					; 4 |
 	TCODE	tDvCC,				"CC"
 	TCODE	tDkMode,			"Decotype: ZH-L16"
 	TCODE	tZHL16,				" "						; 0      - keep order, enum!
@@ -187,30 +225,29 @@
  ELSE
 	TCODE	tPPO2MIN,			"Min     :"				; min ppO2 in OC mode
  ENDIF
-	TCODE	tLastDecostop,		"Last Deco    : "		; last deco stop depth
-	TCODE	tAscentSpeed,		"Ascent Speed : "		; Ascent Speed
-	TCODE	tGasChangeTime,		"Gas Change   :+"		; additional Gas Change Time
-	TCODE	tExtendedStops,		"extended Stop: "		; extended stops
-	TCODE	tTimeoutDive,		"Dive Timeout : "		; Dive Timeout
-	TCODE	tStoreApnoeDive,	"Store Apnoe  : "		; Store Apnoe Dives
 	TCODE	tDecoparameters,	"Deco Parameters"
 	TCODE	tGF_low,			"GF  low :"
 	TCODE	tGF_high,			"GF  high:"
 	TCODE	tSaturationMult,	"Saturation  : "
 	TCODE	tDesaturationMult,	"Desaturation: "
-	TCODE	tFTTSMenu,			"fTTS/Delay:"			; Future TTS / Ascent Delay
-	TCODE	tLastDecostopSurf,	"Last Deco :"			; last deco stop depth Surface Custom View
 	TCODE	tGFMenu,			"GF Settings"			; GF Settings
 	TCODE	taGF_low,			"aGF low :"				; aGF low
 	TCODE	taGF_high,			"aGF high:"				; aGF high
-	TCODE	taGF_enable,		"aGF selectable:"		; aGF Selectable
+	TCODE	taGFenable,			"aGF selectable:"		; aGF Selectable
 	TCODE	tDiveaGF_active,	"using aGF"				; using aGF
-	TCODE	tppO2settings,		"ppO2 Settings"			; ppO2 Settings
-	TCODE	tsafetystopmenu,	"Safety Stop: "			; Safety Stop:
+	TCODE	tSafetyStop,		"Safety Stop  : "		; Safety Stop:  (max. 16 chars)
+	TCODE	tExtendedStops,		"extended Stop: "		; Extended Stops
+	TCODE	tLastDecostop,		"Last Deco    : "		; last Deco Stop Depth
+	TCODE	tDvSalinity,		"Salinity     : "		; Salinity
+	TCODE	tDepthWarn,			"Depth Warning: "		; Depth Warning
 	TCODE	tGasUsage,			"Gas Usage"				; Gas Usage
-	TCODE	tSetBotUse,			"Bottom Gas: "			; Bottom Gas: (space)
-	TCODE	tSetDecoUse,		"Deco   Gas: "			; Deco   Gas: (space)
-	TCODE	tCalcAscGas,		"Calc.Gas (B/O):"		; Calculate Gas (Bail Out) needs?
+	TCODE	tSetWorkSAC,		"SAC Work: "			; SAC Work: (space)
+	TCODE	tSetDecoSAC,		"SAC Deco: "			; SAC Deco: (space)
+	TCODE	tCalcGasNeeds,		"Calc.Gas(B/O): "		; Calculate  Gas (Bail Out) Needs
+ IFDEF _gas_contingency
+	TCODE	tGasContingencyDive,"Swap on empty: "		; swap tank on becoming empty
+ ENDIF
+	TCODE	tGasChangeTime,		"Gas Change   :+"		; additional Gas Change Time
 	TCODE	tSetup_Tank,		"Setup Tank"			; Setup Tank
 	TCODE	tTankSize,			"Tank Size"				; Tank Size
 	TCODE	tTankUsablePress,	"Turn Pres/Asc.Need"	; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars)
@@ -222,7 +259,7 @@
 	TCODE	tCCmaxFracO2,		"Loop %O2 max. : "		; max O2 percent (absolute) in the loop
 	TCODE	tDilppO2Check,		"Check Dil ppO2: "		; check ppO2 of the diluent against the setpoint
 	TCODE	tPSCR_O2_drop,		"pSCR   O2 Drop: "		; pSCR O2 drop
-	TCODE	tPSCR_lungratio,	"    Lung Ratio: "		; pSCR lung ratio
+	TCODE	tPSCR_lungratio,	"... Lung Ratio: "		; pSCR lung ratio
 	TCODE	tCopyDilToOC,		"Copy Dil.-> OC"		; copy diluent settings to OC gas
 	TCODE	tBackToLoop,		"goto loop"				; back to loop (10 chars max)
  ENDIF
@@ -257,30 +294,37 @@
 
 
 ; Display settings
-	TCODE	tBright,			"Brightness:"
-	TCODE	tEco,				"Eco"
-	TCODE	tMedium,			"Medium"
-	TCODE	tHigh,				"High"
-	TCODE	tDvSalinity,		"Salinity:  "			; Salinity
-	TCODE	tShowppO2,			"Always show ppO2:"		; Always show ppO2:
-	TCODE	tFlip,				"Rotate Screen:"		; Rotate Screen
-	TCODE	tMODwarning,		"Depth Warnings:"		; depth Warnings
-;	TCODE	tIBCDwarning,		"IBCD  Warning :"		; IBCD Warning
-	TCODE	tLayout,			"Layout   :"			; Layout
-	TCODE	t2ndDepth,			"2nd Depth:"			; 2nd depth display content (11 chars max)
-	TCODE	tTissueGraphics,	"Graphics :"			; tissue graphics
+	TCODE	tBright,			"Brightness: "			; Brightness
+	TCODE	tLayout,			"Layout    : "			; Layout
+	TCODE	tUnits,				"Units     : "			; Units
+ IF _language_2!=none
+	TCODE	tLanguage,			"Language  : "			; used in menu_tree
+ ENDIF
+	TCODE	tFlip,				"Rotate Screen: "		; Rotate Screen
+	TCODE	tColorScheme,		"Colour Scheme"			; Colour Scheme
+	TCODE	tVSIgraph,			"Speed Graph : "		; Speed Graph
+	TCODE	tVSItext2,			"Var.  Speed : "		; variable Speed
+	TCODE	tShowppO2,			"ppO2 always : "		; always show ppO2
+	TCODE	tDepthWarning,		"Depth blink.: "		; Depth blinking
+	TCODE	t2ndDepth,			"2nd Depth: "			; 2nd Depth Display Content (11 chars max)
+	TCODE	tTissueGraphics,	"Graphics : "			; Tissue Graphics
+	TCODE	tIBCDwarning,		"IBCD Warning: "		; IBCD Warning
 
-	TCODE	tLayoutNormal,		"normal"				; normal
-	TCODE	tLayoutBig,			"large"					; large
-
-
-; VSI display settings
-	TCODE	tVSItext2,			"Variable Speed:"		; Variable speed:
-	TCODE	tVSIgraph,			"Speed Graph   :"		; Speed graph:
+	TCODE	tEco,				"Eco"					; eco     | ENUM group
+	TCODE	tMedium,			"Medium"				; medium  |
+	TCODE	tHigh,				"High"					; high    |
+	TCODE	tLayoutNormal,		"normal"				; normal  | ENUM group
+	TCODE	tLayoutBig,			"large"					; large   |
+	TCODE	tMax,				"max."					; max     | ENUM group
+	TCODE	tAvg,				"avg."					; average |
+	TCODE	tTissuePresSat,		"Pres+Sat"				; pressure and saturation | ENUM group
+ IFDEF _helium
+	TCODE	tTissueN2He,		"N2+He"					; N2 + He pressure        |
+ ENDIF
 
 
 ; Setup menu
-	TCODE	tSystSets,			"Settings"
+	TCODE	tSystSets,			"Settings"				; System Settings
  IFDEF _compass
 	TCODE	tCompassMenu,		"Compass Calibration"
 	TCODE	tCompassGain,		"Compass Gain:"
@@ -288,14 +332,14 @@
 	TCODE	tCalY,				"Cal Y:"				; Cal Y
 	TCODE	tCalZ,				"Cal Z:"				; Cal Z
  ENDIF
-	TCODE	tUnits,				"Units: "
 	TCODE	tMetric,			" m/°C"					; 0   - keep order, enum!
 	TCODE	tImperial,			"ft/°F"					; 1
 								;         111         111         111         111         111
 	; 5 rows by 12 chars each:	 123456789012123456789012123456789012123456789012123456789012
-	TCODE	tDefName,			"HW OSTC"	;"  Read the  Manual, know& understandthe inherentLimitations!"
-	TCODE	tButtonleft,		"Left  button:"			; Left button
-	TCODE	tButtonright,		"Right button:"			; Right button
+	TCODE	tDefName,			"HW OSTC"				; "  Read the  Manual, know& understandthe inherentLimitations!"
+	TCODE	tPiezo,				"Buttons"				; Buttons
+	TCODE	tButtonleft,		"Left  Button:"			; Left  Button
+	TCODE	tButtonright,		"Right Button:"			; Right Button
 	TCODE	tAltMode,			"Waiting Time:"
 	TCODE	tAltModeFly,		"Flying"
 	TCODE	tAltMode1000,		"1000m"
@@ -324,7 +368,7 @@
 
 ; Simulator menu
 	TCODE	tInter,				"Start Simulator"		; Start Simulator
-	TCODE	tPlan,				"Simulator"				; Simulator
+	TCODE	tSimulator,			"Simulator"				; Simulator
 
 
 ; Decoplanner submenu
@@ -332,7 +376,7 @@
 	TCODE	tBtTm_short,		"Time :"				; Bot. Time: (max. 6 chars)
 	TCODE	tBtDep,				"Bot.Depth: "			; Max Depth: (10 chars)
 	TCODE	tIntvl,				"Interval : "			; Interval : (10 chars)
-	TCODE	tDecoSetup,			"Calculator Setup"
+	TCODE	tCalculatorSetup,	"Calculator Setup"		; Calculator Setup
 	TCODE	tDeco,				"Start Calculator"		; Calculate Deco
 	TCODE	tDivePlan,			"Dive Plan"				; Dive Plan (max. 10 chars)
 	TCODE	tNoDeco,			"No Deco"				; No Deco
@@ -340,7 +384,7 @@
 	TCODE	tSelectSetpoint,	"Setpoint : "			; Setpoint
 	TCODE	tuseAGF,			"use aGF  : "			; use alternative Grdient Factors
  IFDEF _gas_contingency
-	TCODE	tGasContingency,	"Gas Cont.: "			; Gas Contingency
+	TCODE	tGasContingencySim,	"Gas Cont.: "			; Gas Contingency
  ENDIF
 
 ; Decoplanner progress indication
@@ -356,10 +400,12 @@
 
 ; Information menu
 	TCODE	tFirmware,			"Firmware: "			; Firmware: (space)
+	TCODE	tFirmwareDate,		"created : "			; created : (space)  firmware creation date
 	TCODE	tHardware,			"Hardware: "			; Hardware: (space)
 	TCODE	tSerial,			"Serial  : "			; Serial  : (space)
-	TCODE	tTotalDives,		"Total Dives:"			; Total Dives: (no space, moved to logbook)
 	TCODE	tBatteryV,			"Battery : "			; Battery : (space)
+	TCODE	tSensorC,			"Sensor  : "			; Sensor  : (space)
+	TCODE	tSensorD,			"Offset  : "			; Offset  : (space)
 	TCODE	tUptime,			"Uptime  : "			; Uptime  : (space)
 
  IFDEF _rx_functions
@@ -368,8 +414,8 @@
 
 
 ; Divemode screen
-	TCODE	tNDL,				"NDL"					; 3 chars max
-	TCODE	tTTS,				"TTS"					; 3 chars max
+	TCODE	tNDL,				"NDL"					; 3 chars
+	TCODE	tTTS,				"TTS"					; 3 chars
 	TCODE	tSlow,				" slow "				; slow - max 7 chars
 	TCODE	tVelMetric,			"m/min"
 	TCODE	tVelImperial,		"ft/m "
@@ -381,10 +427,6 @@
 	TCODE	tDepth,				"Depth"					; Depth (max 5 chars)
 	TCODE	tMaxDepth,			"Max.Depth"				; Max. Depth    - max 9 chars!
 	TCODE	tAvgDepth,			"Average"				; average Depth - max 9 chars!
-	TCODE	tTissuePresSat,		"Pres+Sat"				; 0 pressure and saturation    | ENUM group
- IFDEF _helium
-	TCODE	tTissueN2He,		"N2+He"					; 1 N2 + He pressure           |
- ENDIF
 	TCODE	tDivetime,			"Divetime"				; Divetime (max 8 chars)
 	TCODE	tDiveTotalAvg,		"Total Avg"
 	TCODE	tDiveStopwatch,		"Stopwatch"
@@ -410,16 +452,18 @@
 	TCODE	tSensorCheck,		"Sensor Check"			; Sensor Check
 	TCODE	tdil,				"Dil:"					; Diluent ppO2 Warning
 	TCODE	tmix,				"Mix:"					; Pre-Mix ppO2 Warning
-	TCODE	tGasNeedsWarn,		"Gas Needs"
-	TCODE	tGasNeedsAscent,	"Gas Needs Ascent"
-	TCODE	tCNSsurf,			"CNS Surf."
-	TCODE	tCNSfTTS,			"CNS fTTS"
-	TCODE	tCNSBO,				"CNS B/O"
-	TCODE	tCNSnow,			"CNS now"
-	TCODE	tCNSeod,			"CNS final"
-	TCODE	tnoBOgas,			"-B/O-Gas-"
-	TCODE	tMicroBubbles,		"M.Bubbles"
-	TCODE	tCNS,				"CNS: "
+	TCODE	tGasNeedsWarn,		"Gas Needs"				;
+	TCODE	tCNSsurf,			"CNS Surf."				;
+	TCODE	tCNSfTTS,			"CNS fTTS"				;
+	TCODE	tCNSBO,				"CNS B/O"				;
+	TCODE	tCNSnow,			"CNS now"				;
+	TCODE	tCNSeod,			"CNS final"				;
+ IFDEF _cave_mode
+	TCODE	tCNScave,			"CNS Cave"				;
+ ENDIF
+	TCODE	tnoBOgas,			"-B/O-Gas-"				;
+	TCODE	tMicroBubbles,		"M.Bubbles"				;
+	TCODE	tCNS,				"CNS: "					;
 	TCODE	tgaschange,			"Change?"				; better gas found
 	TCODE	tNeed,				"Need "					; gas need (5 chars)
 	TCODE	tBattery,			"Battery"				; Battery
@@ -447,10 +491,15 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tGasNeedsCaveMode,	"Gas Needs Cave Mode"	; title for gas needs custom view
-	TCODE	tDiveTurned,		"Dv.turned"				; dive is turned      (max. 9 char)
+	TCODE	tGasNeedsCaveMode,	"Gas Needs -CAVE-"		; title for gas needs custom view (cave mode)		| need to be
+	TCODE	tGasNeedsAscent,	"Gas Needs Ascent"		; title for gas needs custom view (open water mode)	| same length
 	TCODE	tCaveMode,			"Cave Mode"				; cave mode activated (max. 9 char)
 	TCODE	tCaveModeShutdown,	"X-Cave-X"				; cave mode shut down (max. 9 char)
+	TCODE	tCaveTTS,			"Cave TTS"				; cave mode total time to surface
+	TCODE	tCaveStops,			"total Stops"			; cave mode total time for stops
+	TCODE	tCaveRuntime,		"total RT"				; cave mode total runtime
+ ELSE
+	TCODE	tGasNeedsAscent,	"Gas Needs Ascent"		; title for gas needs custom view
  ENDIF
 
 
@@ -468,11 +517,19 @@
 
 
 ; Logbook
-	TCODE	tCNS2,				"CNS:"
-	TCODE	tAVG,				"Avg:"
+	TCODE	tCNS2,				"CNS: "
+	TCODE	tAVG,				"Avg: "
+	TCODE	tGF2,				"GF : "
+	TCODE	tSAT,				"Sat: "					; max  4 chars
+	TCODE	tDvSalinity2,		"Salinity :"			; max 11 chars
+	TCODE	tLastDeco,			"Last Deco:"			; max 11 chars
+	TCODE	tNoProfileData,		"no profile anymore..."	; max 21 chars
+	TCODE	tBeginOfDive,		"Begin:"				; max  8 chars
+	TCODE	tEndOfDive,			"End:"					; max  8 chars
+	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
+
+; other users
 	TCODE	tGF,				"GF:"
-	TCODE	tSAT,				"Sat:"					; 4 chars max
-
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -505,6 +562,7 @@
 
 
 ; Logbook Offset Menu
+	TCODE	tTotalDives,		"Total Dives: "			; Total Dives
 	TCODE	tLogOffset,			"Logbook Offset"		; Logbook offset
 	TCODE	tLogOffsetValue,	"Offset   : "			; Offset
 	TCODE	tLogOffStepSize,	"Step Size: "			; Step Size
@@ -528,7 +586,6 @@
 
 
 ; Color Scheme menu
-	TCODE	tColorScheme,		"Colour Scheme"			; Colour Scheme
 	TCODE	tColorSetDive,		"Divemode:"				; Divemode:
 	TCODE	tColorSetName0,		"Standard"				; Standard
 	TCODE	tColorSetName1,		"Red"					; Red
@@ -537,21 +594,17 @@
 
 
 ; Language selection
- IF _language_2!=none
-	TCODE	tLanguage,			"Language: "			; used in menu_tree
- ENDIF
-
  IF _language_1==en
-	TCODE	tLang1,				"English"				; tLang1 is 1st language, enum context
+	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
  ELSE
  IF _language_1==de
-	TCODE	tLang1,				"German"
+	TCODE	tLang1,				"DE"
  ELSE
  IF _language_1==fr
-	TCODE	tLang1,				"French"
+	TCODE	tLang1,				"FR"
  ELSE
  IF _language_1==it
-	TCODE	tLang1,				"Italian"
+	TCODE	tLang1,				"IT"
  ELSE
 	TCODE	tLang1,				""						; dummy target for options table
  ENDIF
@@ -560,16 +613,16 @@
  ENDIF
 
  IF _language_2==en
-	TCODE	tLang2,				"English"				; tLang2 is 2nd language, enum context
+	TCODE	tLang2,				"EN"					; tLang2 is 2nd language, enum context
  ELSE
  IF _language_2==de
-	TCODE	tLang2,				"German"
+	TCODE	tLang2,				"DE"
  ELSE
  IF _language_2==fr
-	TCODE	tLang2,				"French"
+	TCODE	tLang2,				"FR"
  ELSE
  IF _language_2==it
-	TCODE	tLang2,				"Italian"
+	TCODE	tLang2,				"IT"
  ENDIF
  ENDIF
  ENDIF
--- a/src/text_french.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/text_french.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_french.sm                       next combined generation V3.04.3
+;	File text_french.sm                       next combined generation V3.08.8
 ;
 ;	French texts translation file.
 ;
@@ -8,10 +8,14 @@
 ;=============================================================================
 
 ; Basic texts
-	TCODE	tNo,				"Non"					; 0 No    | ENUM group
-	TCODE	tYes,				"Oui"					; 1 Yes   |
+	TCODE	tNo,				"Non"					; 0 No		| ENUM group
+	TCODE	tYes,				"Oui"					; 1 Yes		|
+
  IFDEF _cave_mode
-	TCODE	tCave,				"Cave"					; 2 Cave  |
+	TCODE	tOff,				"off"					; OFF		| Enum group
+	TCODE	tOn,				"on"					; ON		|
+ ELSE
+	TCODE	tOff,				" "						; needed for option table
  ENDIF
 
 	TCODE	tblank,				" "						; (a single space character)
@@ -22,6 +26,10 @@
 	TCODE	tHeading,			"Cap:"					; Heading:
 	TCODE	tLastDive,			"Dern.Plong"			; Last Dive (Max 10 chars)
 
+	TCODE	tFTTSSurf,			"Future DTR :"			; Future TTS
+	TCODE	tLastDecostopSurf,	"Dern.Palier:"			; last deco stop depth Surface Custom View
+	TCODE	tDvSalinitySurf,	"Salinité   :"			; Salinity
+
  IFDEF _external_sensor
 	TCODE	tSensorMilliVolt,	"Cellules mV"			; Sensors mV
  ENDIF
@@ -33,7 +41,12 @@
 	TCODE	tDivemenu_Avg_Mkr,	"Moyen/Mark"			; Reset Avg, Set Marker (and Turn Dive)
 	TCODE	tDivemenu_ToggleGF,	"Bascul.GF"				; Toggle GF
 	TCODE	tDivemenu_Marker,	"Repère"				; Set Marker
+
+ IFDEF _cave_mode
+	TCODE	tDivemenu_LostGas,	"Gaz avail."			; Gas Availability
+ ELSE
 	TCODE	tDivemenu_LostGas,	"Gaz Perdu"				; Lost Gas
+ ENDIF
 
  IFDEF _ccr_pscr
 	TCODE	tDivemenu_Diluent,	"Liste Dil"				; Diluents (CCR)
@@ -46,10 +59,16 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tDivemenu_TurnDive,	"Turn Dive"				; Turn Dive
+	TCODE	tDivePreCave,		"Cave?"					; Enter Cave Menu          ( 5 chars max)
+	TCODE	tDivemenu_wp_set,	"Waypoint"				; Set Waypoint             (10 chars max)
+	TCODE	tDivemenu_wp_out,	"WP go <-()"			; go one Waypoint outwards (10 chars max)
+	TCODE	tDivemenu_wp_in,	"WP go ->()"			; go one Waypoint inwards  (10 chars max)
+	TCODE	tDivemenu_TurnDive,	"Retour"				; Turn Dive                (10 chars max)
+	TCODE	tDivemenu_ContDive,	"Cont.Dive"				; Continue Dive            (10 chars max)
+	TCODE	tDivemenu_off_on, 	"Off / On"				; Cave Mode Off/On         (10 chars max)
  ENDIF
 
- 
+
 ; Main menu
 	TCODE	tNext,				"<Suivant"				; <Next
 	TCODE	tEnter,				"Entrer>"				; Enter>
@@ -58,11 +77,19 @@
 	TCODE	tGasSetup,			"Paramètres Gaz OC"		; OC Gas Setup
 	TCODE	tSetTime,			"Réglage Heure"			; Set Time
 	TCODE	tSetDate,			"Réglage Date"			; Set Date
-	TCODE	tSetTimeDate,		"Date & Heure"			; Set Time & Date
+	TCODE	tSetTimeDate,		"Date & Heure"			; Time & Date
 	TCODE	tDispSets,			"Préfér. Réglages"		; Display Settings
+	TCODE	tSysSets,			"Préfér. System"		; System  Settings
 	TCODE	tExit,				"Sortie"				; Exit
 	TCODE	tResetMenu,			"Menu RaZ"				; Reset Menu
-	TCODE	tDiveModeMenu,		"Menu Déco"				; Deco Mode
+	TCODE	tDiveModeMenu,		"Menu Déco"				; Dive Setup
+
+	TCODE	tDiveSetup,			"Dive Setup"			; Dive Setup
+	TCODE	tDecoSetup,			"Deco Setup"			; Deco Setup
+	TCODE	tSACSetup,			"SAC  Setup"			; SAC Setup
+	TCODE	tppO2Setup,			"ppO2 Setup"			; ppO2 Setup
+	TCODE	tStopsSetup,		"Stops & Depths"		; Stops & Depths
+
 	TCODE	tInfoMenu,			"Informations"			; Information
  IFDEF _ccr_pscr
 	TCODE	tCCRSetup,			"Paramètres CCR"		; CCR Setup
@@ -70,6 +97,7 @@
  ENDIF
 	TCODE	tFixedSetpoints,	"Setpoints Fixes"		; Fixed Setpoints
 	TCODE	tBack,				"Retour"				; back
+	TCODE	tGas6,				"extra Gas"				; edit & select Gas 6
 
  IFDEF _rx_functions
 	TCODE	tTrSettings,		"Affich.Pression"		; Pressure Display
@@ -80,13 +108,16 @@
 	TCODE	tTrMaxDeltaP,		"max deltaP: "			; independent double max diffenerce
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tCCRSensor,			"Cellules CCR"			; CCR Sensor
 	TCODE	tCalibrateMenu,		"Calibration"			; Calibration
 	TCODE	tCalibrationGas,	"Cal. Gaz O2:"			; Cal. Gas O2:
 	TCODE	tCalibrate,			"Calibrate"				; Calibrate
- ENDIF
+	TCODE	tS8Mode,			"S8 Input: "			; Sensor Input
+	TCODE	tCCRS8Mode,			"Analog"				; Analog
+	TCODE	tCCRS8Mode2,		"Digital"				; Digital
+ ELSE
+	TCODE	tCCRS8Mode,			" "						; needed for option table
  ENDIF
 
 
@@ -124,7 +155,7 @@
 	TCODE	tppO2O2,			"PpO2(O2)"				; ppO2(O2)
 	TCODE	tppO2Dil,			"PpO2(Dil)"				; ppO2(Dil)
 	TCODE	tppO2Mix,			"PpO2(Mix)"				; ppO2(Mix)
-	TCODE	tCCRMode,			"Mode CCR:"				; CCR Mode:
+	TCODE	tCCRMode,			"Mode: "				; CCR/pSCR Mode
 	TCODE	tCCRModeFixedSP,	"SP Fixe"				; 0 fixed for CCR / calculated for pSCR  | ENUM group
 	TCODE	tCCRModeSensor,		"Cellule"				; 1 Sensor                               |
 	TCODE	tCCRModeAutoSP,		"SP Auto"				; 2 Auto SP                              |
@@ -135,7 +166,6 @@
 	TCODE	tppO2,				"PpO2:"					; ppO2:
 
 
-
 ; New batteries menu
 	;                                     1         2	;
 	;                            12345678901234567890	; max 20 chars
@@ -154,7 +184,8 @@
 ; Gaslist management
 	TCODE	tGas,				"Gaz"					; Gas
 	TCODE	tDil,				"Dil"					; Diluent
-	TCODE	tGasErr,			"Err"					; Err (3 chars)
+	TCODE	tGasErr,			"Err"					; Err      (max 3 chars)
+	TCODE	tTakeGas,			"take"					; take gas (max 4 chars)
 
 
 ; Communication Menu
@@ -170,12 +201,18 @@
 
 
 ; Dive Settings
-	TCODE	tDvMode,			"Mode: "
-	TCODE	tDvOC,				"OC"
-	TCODE	tDvCCR,				"CCR"
-	TCODE	tDvGauge,			"Gauge"
-	TCODE	tDvApnea,			"Apnée"
-	TCODE	tDvPSCR,			"pSCR"
+	TCODE	tDvMode,			"Mode        : "		; Dive Mode
+ IFDEF _cave_mode
+	TCODE	tCvMode,			"Cave        : "		; Cave Mode
+ ENDIF
+	TCODE	tFTTSMenu,			"Future DTR  :"			; Future TTS
+	TCODE	tTimeoutDive,		"Fin Plongée : "		; Dive Timeout
+	TCODE	tStoreApnoeDive,	"Carnet Apnée: "		; Store Apnoe Dives
+	TCODE	tDvOC,				"OC"					; 0 | keep order, enum!
+	TCODE	tDvCCR,				"CCR"					; 1 |
+	TCODE	tDvGauge,			"Gauge"					; 2 |
+	TCODE	tDvApnea,			"Apnée"					; 3 |
+	TCODE	tDvPSCR,			"pSCR"					; 4 |
 	TCODE	tDvCC,				"CC"
 	TCODE	tDkMode,			"Modèle: ZH-L16"
 	TCODE	tZHL16,				" "
@@ -188,30 +225,29 @@
  ELSE
 	TCODE	tPPO2MIN,			"Min        :"
  ENDIF
-	TCODE	tLastDecostop,		"Dern.Palier  : "
-	TCODE	tAscentSpeed,		"Vitesse Rem. : "		; Ascent Speed
-	TCODE	tGasChangeTime,		"Tps Change Gaz :+"		; additional Gas Change Time
-	TCODE	tExtendedStops,		"Paliers + Longs: "		; extended stops
-	TCODE	tTimeoutDive,		"Fin Plongée    : "		; Dive Timeout
-	TCODE	tStoreApnoeDive,	"Carnet Apnée   : "		; Store Apnoe Dives
 	TCODE	tDecoparameters,	"Paramètres Déco"
 	TCODE	tGF_low,			"GF  Bas :"
 	TCODE	tGF_high,			"GF  Haut:"
 	TCODE	tSaturationMult,	"Saturation  : "
 	TCODE	tDesaturationMult,	"Désaturation: "
-	TCODE	tFTTSMenu,			"Future DTR:"			; Future TTS
-	TCODE	tLastDecostopSurf,	"Dern.Palier:"			; last deco stop depth Surface Custom View
 	TCODE	tGFMenu,			"Menu GF"				; GF Settings
 	TCODE	taGF_low,			"aGF Bas :"				; aGF Low
 	TCODE	taGF_high,			"aGF Haut:"				; aGF High
-	TCODE	taGF_enable,		"aGF Possible:"			; aGF Selectable
+	TCODE	taGFenable,			"aGF Possible:"			; aGF Selectable
 	TCODE	tDiveaGF_active,	"aGF Actif"				; using aGF
-	TCODE	tppO2settings,		"Menu PpO2"				; ppO2 Settings (max. 18 chars)
-	TCODE	tsafetystopmenu,	"Palier Sécurité:"		; Safety Stop: (max. 16 chars)
+	TCODE	tSafetyStop,		"Palier Sécurité:"		; Safety Stop:  (max. 16 chars)
+	TCODE	tExtendedStops,		"Paliers + Longs:"		; Extended Stops
+	TCODE	tLastDecostop,		"Dern.Palier: "			; last DecoStop Depth
+	TCODE	tDvSalinity,		"Salinité   : "			; Salinity
+	TCODE	tDepthWarn,			"Depth Warn.: "			; Depth Warning
 	TCODE	tGasUsage,			"Usage Gaz"				; Gas Usage
-	TCODE	tSetBotUse,			"Gaz Fond: "			; Bottom Gas: (space)
-	TCODE	tSetDecoUse,		"Gaz Déco: "			; Deco   Gas: (space)
-	TCODE	tCalcAscGas,		"Calc.Gaz (B/O):"		; Calculate Gas (Bail Out) needs?
+	TCODE	tSetWorkSAC,		"SAC Fond: "			; SAC Work: (space)
+	TCODE	tSetDecoSAC,		"SAC Déco: "			; SAC Deco: (space)
+	TCODE	tCalcGasNeeds,		"Calc.Gaz (B/O): "		; Calculate  Gas (Bail Out) needs
+ IFDEF _gas_contingency
+	TCODE	tGasContingencyDive,"Swap on empty: "		; swap tank on becoming empty
+ ENDIF
+	TCODE	tGasChangeTime,		"Tps Change Gaz:+"		; additional Gas Change Time
 	TCODE	tSetup_Tank,		"Config. Blocs"			; Setup Tank
 	TCODE	tTankSize,			"Volume   Bloc"			; Tank Sizes
 	TCODE	tTankUsablePress,	"Besoin Press. Rem."	; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars)
@@ -222,8 +258,8 @@
  IFDEF _ccr_pscr
 	TCODE	tCCmaxFracO2,		"Loop %O2 max. : "		; max O2 percent (absolute) in the loop
 	TCODE	tDilppO2Check,		"Check Dil ppO2: "		; check ppO2 of the diluent against the setpoint
-	TCODE	tPSCR_O2_drop,		"pSCR   O2 Drop: "		; pSCR O2 drop
-	TCODE	tPSCR_lungratio,	"    Lung Ratio: "		; pSCR lung ratio
+	TCODE	tPSCR_O2_drop,		"pSCR O2 Drop  : "		; pSCR O2 Drop
+	TCODE	tPSCR_lungratio,	"... Lung Ratio: "		; pSCR Lung Ratio
 	TCODE	tCopyDilToOC,		"Copie Diluant -> OC"	; copy diluent settings to OC gas
 	TCODE	tBackToLoop,		"goto loop"				; back to loop (10 chars max)
  ENDIF
@@ -258,30 +294,37 @@
 
 
 ; Display Settings
-	TCODE	tBright,			"Luminosité:"
-	TCODE	tEco,				"Eco"
-	TCODE	tMedium,			"Moyenne"
-	TCODE	tHigh,				"Haute"
-	TCODE	tDvSalinity,		"Salinité:  "			; Salinity
-	TCODE	tShowppO2,			"Afficher PpO2:"		; Always show ppO2:
+	TCODE	tBright,			"Luminosité: "			; Brightness
+	TCODE	tLayout,			"Affichage : "			; Layout
+	TCODE	tUnits,				"Unités    : "			; Units
+ IF _language_2!=none
+	TCODE	tLanguage,			"Langue    : "			; Language
+ ENDIF
 	TCODE	tFlip,				"Pivoter l'écran:"		; Rotate Screen
-	TCODE	tMODwarning,		"Alerte  Prof.   :"		; depth Warnings
-;	TCODE	tIBCDwarning,		"Alerte CDI  :"			; IBCD Warning
-	TCODE	tLayout,			"Affichage :"			; Layout
-	TCODE	t2ndDepth,			"Choix Prof:"			; 2nd depth display content (11 chars max)
-	TCODE	tTissueGraphics,	"Dessin    :"			; tissue graphics
+	TCODE	tColorScheme,		"Jeu de Couleurs"		; Colour Scheme
+	TCODE	tVSIgraph,			"Graph.Vitesse: "		; Speed Graph
+	TCODE	tVSItext2,			"Var.  Vitesse: "		; variable Speed
+	TCODE	tShowppO2,			"Afficher PpO2: "		; always show ppO2
+	TCODE	tDepthWarning,		"Prof. luire  : "		; Depth blinking
+	TCODE	t2ndDepth,			"Choix Prof:"			; 2nd Depth Display Content (11 chars max)
+	TCODE	tTissueGraphics,	"Dessin    :"			; Tissue Graphics
+	TCODE	tIBCDwarning,		"Alerte CDI: "			; IBCD Warning
 
-	TCODE	tLayoutNormal,		"normal"				; normal
-	TCODE	tLayoutBig,			"large"					; large
-
-
-; VSI display Settings
-	TCODE	tVSItext2,			"Vitesse Variable:"		; Variable speed:
-	TCODE	tVSIgraph,			"Graph.  Vitesse :"		; Speed graph:
+	TCODE	tEco,				"Eco"					; eco     | ENUM group
+	TCODE	tMedium,			"Moyenne"				; medium  |
+	TCODE	tHigh,				"Haute"					; high    |
+	TCODE	tLayoutNormal,		"normal"				; normal  | ENUM group
+	TCODE	tLayoutBig,			"large"					; large   |
+	TCODE	tMax,				"max."					; max     | ENUM group
+	TCODE	tAvg,				"avg."					; average |
+	TCODE	tTissuePresSat,		"Pres+Sat"				; pressure and saturation | ENUM group
+ IFDEF _helium
+	TCODE	tTissueN2He,		"N2+He"					; N2 + He pressure        |
+ ENDIF
 
 
 ; Setup Menu
-	TCODE	tSystSets,			"Réglages"
+	TCODE	tSystSets,			"Réglages"				; System Settings
  IFDEF _compass
 	TCODE	tCompassMenu,		"Calibration Compas"	; Compass Calibration
 	TCODE	tCompassGain,		"Sensibilité:"			; Compass Gain:
@@ -289,12 +332,12 @@
 	TCODE	tCalY,				"Cal Y:"				; Cal Y
 	TCODE	tCalZ,				"Cal Z:"				; Cal Z
  ENDIF
-	TCODE	tUnits,				"Unités:"
 	TCODE	tMetric,			" m/°C"					; Enum menu
 	TCODE	tImperial,			"ft/°F"
 								;         111         111         111         111         111
 	; 5 rows by 12 chars each:	 123456789012123456789012123456789012123456789012123456789012
 	TCODE	tDefName,			"HW OSTC"	;"Lire la doc.Connaitre etComprendre  les limites de l'OSTC ! "
+	TCODE	tPiezo,				"Bouton"				; Buttons
 	TCODE	tButtonleft,		"Bouton gauche:"		; Left button
 	TCODE	tButtonright,		"Bouton droit :"		; Right button
 	TCODE	tAltMode,			"Temps Attente:"		; Waiting Time
@@ -325,7 +368,7 @@
 
 ; Simulator menu
 	TCODE	tInter,				"Lancer Simulation"		; Start Simulator
-	TCODE	tPlan,				"Simulateur"			; Simulator
+	TCODE	tSimulator,			"Simulateur"			; Simulator
 
 
 ; Decoplanner submenu
@@ -333,7 +376,7 @@
 	TCODE	tBtTm_short,		"Temps:"				; Bot. Time: (max. 6 chars)
 	TCODE	tBtDep,				"Prof. Max :"			; Max Depth: (10 chars)
 	TCODE	tIntvl,				"Intervalle:"			; Interval : (10 chars)
-	TCODE	tDecoSetup,			"Réglage Ordinateur"	; Calculator Setup
+	TCODE	tCalculatorSetup,	"Réglage Ordinateur"	; Calculator Setup
 	TCODE	tDeco,				"Calcul Déco"			; Calculate Deco
 	TCODE	tDivePlan,			"Runtime"				; Dive Plan (max. 10 chars)
 	TCODE	tNoDeco,			"Pas de Déco"			; No Deco
@@ -341,7 +384,7 @@
 	TCODE	tSelectSetpoint,	"Setpoint  : "
 	TCODE	tuseAGF,			"aGF Permis: "			; use aGF
  IFDEF _gas_contingency
-	TCODE	tGasContingency,	"Gas Cont. : "			; Gas Contingency			## translation pending
+	TCODE	tGasContingencySim,	"Gas Cont. : "			; Gas Contingency			## translation pending
  ENDIF
 
 ; Decoplanner progress indication
@@ -357,10 +400,12 @@
 
 ; Information menu
 	TCODE	tFirmware,			"Logiciel: "			; Firmware: (space)
+	TCODE	tFirmwareDate,		"created : "			; created : (space)  firmware creation date
 	TCODE	tHardware,			"Hardware: "			; Hardware: (space)
 	TCODE	tSerial,			"N. Série: "			; Serial  : (space)
-	TCODE	tTotalDives,		"Nbre Plongées:"		; Total Dives:
-	TCODE	tBatteryV,			"Batterie: "			; Battery:
+	TCODE	tBatteryV,			"Batterie: "			; Battery : (space)
+	TCODE	tSensorC,			"Sensor  : "			; Sensor  : (space)
+	TCODE	tSensorD,			"Offset  : "			; Offset  : (space)
 	TCODE	tUptime,			"Mise a Jour:"			; Uptime:
 
  IFDEF _rx_functions
@@ -369,8 +414,8 @@
 
 
 ; Divemode screen
-	TCODE	tNDL,				"NDL"					; 3 chars max
-	TCODE	tTTS,				"DTR"					; 3 chars max
+	TCODE	tNDL,				"NDL"					; 3 chars
+	TCODE	tTTS,				"DTR"					; 3 chars
 	TCODE	tSlow,				"lente "				; slow - max 7 chars
 	TCODE	tVelMetric,			"m/min"
 	TCODE	tVelImperial,		"ft/m "
@@ -382,10 +427,6 @@
 	TCODE	tDepth,				"Prof."					; Depth (max 5 chars)
 	TCODE	tMaxDepth,			"Prof.Max."				; Max.Depth     - max 9 chars!
 	TCODE	tAvgDepth,			"Prof.Moy."				; average Depth - max 9 chars!
-	TCODE	tTissuePresSat,		"Press+Sat"				; 0 pressure and saturation  | ENUM group
- IFDEF _helium
-	TCODE	tTissueN2He,		"N2+He"					; 1 N2 + He pressure         |
- ENDIF
 	TCODE	tDivetime,			"Durée"					; Divetime (max 8 chars)
 	TCODE	tDiveTotalAvg,		"Prof. Moy."
 	TCODE	tDiveStopwatch,		"Chrono"
@@ -412,12 +453,14 @@
 	TCODE	tdil,				"Dil:"					; Diluent ppO2 Warning
 	TCODE	tmix,				"Mix:"					; Pre-Mix ppO2 Warning
 	TCODE	tGasNeedsWarn,		"Gaz Needs"				;
-	TCODE	tGasNeedsAscent,	"Besoin Gaz Remontée"	; Gas Needs for Ascent
 	TCODE	tCNSsurf,			"SNC Surf."				; CNS Surf.
 	TCODE	tCNSfTTS,			"SNC fDTR"				; CNS fTTS
 	TCODE	tCNSBO,				"SNC B/O"				; CNS B/O
 	TCODE	tCNSnow,			"SNC actuel"			; CNS now
 	TCODE	tCNSeod,			"SNC final"				; CNS fin
+ IFDEF _cave_mode
+	TCODE	tCNScave,			"SNC Sout"				; CNS cave
+ ENDIF
 	TCODE	tnoBOgas,			"-B/O-Gaz-"				; no bailout gas
 	TCODE	tMicroBubbles,		"M.Bulles "				;
 	TCODE	tCNS,				"SNC: "					;
@@ -448,10 +491,15 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tGasNeedsCaveMode,	"Besoins Gaz Cave Mode"	; title for gas needs custom view
-	TCODE	tDiveTurned,		"Ret.Plong"				; dive is turned      (max. 9 char)
-	TCODE	tCaveMode,			"Cave Mode"				; cave mode activated (max. 9 char)
-	TCODE	tCaveModeShutdown,	"X-Cave-X"				; cave mode shut down (max. 9 char)
+	TCODE	tGasNeedsCaveMode,	"Besoin Gaz  -SOUT- "	; title for gas needs custom view (cave mode)		| need to be
+	TCODE	tGasNeedsAscent,	"Besoin Gaz Remontée"	; title for gas needs custom view (open water mode)	| same length
+	TCODE	tCaveMode,			"Mode Sout"				; cave mode activated (max. 9 char)
+	TCODE	tCaveModeShutdown,	"X-Sout-X"				; cave mode shut down (max. 9 char)
+	TCODE	tCaveTTS,			"Cave TTS"				; cave mode total time to surface
+	TCODE	tCaveStops,			"total Stops"			; cave mode total time for stops
+	TCODE	tCaveRuntime,		"total RT"				; cave mode total runtime
+ ELSE
+	TCODE	tGasNeedsAscent,	"Besoin Gaz Remontée"	; title for gas needs custom view
  ENDIF
 
 
@@ -469,11 +517,19 @@
 
 
 ; Logbook
-	TCODE	tCNS2,				"SNC:"
-	TCODE	tAVG,				"Moy:"
+	TCODE	tCNS2,				"SNC: "
+	TCODE	tAVG,				"Moy: "
+	TCODE	tGF2,				"GF : "
+	TCODE	tSAT,				"Sat:"					; max  4 chars
+	TCODE	tDvSalinity2,		"Salinité  :"			; max 11 chars
+	TCODE	tLastDeco,			"Der.Palier:"			; max 11 chars
+	TCODE	tNoProfileData,		"no data anymore..."	; max 21 chars
+	TCODE	tBeginOfDive,		"Begin:"				; max  8 chars
+	TCODE	tEndOfDive,			"End:"					; max  8 chars
+	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
+
+; other users
 	TCODE	tGF,				"GF:"
-	TCODE	tSAT,				"Sat:"					; 4 chars max
-
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -506,6 +562,7 @@
 
 
 ; Logbook Offset Menu
+	TCODE	tTotalDives,		"Nbre Plongées:"		; Total Dives
 	TCODE	tLogOffset,			"N° 1ère Plongée"		; Logbook offset (Max. 15 Chars!)
 	TCODE	tLogOffsetValue,	"N°1ère Plongé:"		; Offset
 	TCODE	tLogOffStepSize,	"Incrément    :"		; Step Size
@@ -529,7 +586,6 @@
 
 
 ; Color Scheme menu
-	TCODE	tColorScheme,		"Jeu de Couleurs"		; Colour scheme
 	TCODE	tColorSetDive,		"Mode Plongée:"			; Divemode:
 	TCODE	tColorSetName0,		"Blanc"					; White
 	TCODE	tColorSetName1,		"Rouge"					; Red
@@ -538,21 +594,17 @@
 
 
 ; Language selection
- IF _language_2!=none
-	TCODE	tLanguage,			"Langue: "				; used in menu_tree
- ENDIF
-
  IF _language_1==en
-	TCODE	tLang1,				"Anglais"				; tLang1 is 1st language, enum context
+	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
  ELSE
  IF _language_1==de
-	TCODE	tLang1,				"Allemand"
+	TCODE	tLang1,				"DE"
  ELSE
  IF _language_1==fr
-	TCODE	tLang1,				"Français"
+	TCODE	tLang1,				"FR"
  ELSE
  IF _language_1==it
-	TCODE	tLang1,				"Italien"
+	TCODE	tLang1,				"IT"
  ELSE
 	TCODE	tLang1,				""						; dummy target for options table
  ENDIF
@@ -561,16 +613,16 @@
  ENDIF
 
  IF _language_2==en
-	TCODE	tLang2,				"Anglais"
+	TCODE	tLang2,				"EN"					; tLang2 is 2nd language, enum context
  ELSE
  IF _language_2==de
-	TCODE	tLang2,				"Allemand"				; tLang2 is 2nd language, enum context
+	TCODE	tLang2,				"DE"
  ELSE
  IF _language_2==fr
-	TCODE	tLang2,				"Français"
+	TCODE	tLang2,				"FR"
  ELSE
  IF _language_2==it
-	TCODE	tLang2,				"Italien"
+	TCODE	tLang2,				"IT"
  ENDIF
  ENDIF
  ENDIF
--- a/src/text_german.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/text_german.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_german.asm                      next combined generation V3.04.3
+;	File text_german.asm                      next combined generation V3.08.8
 ;
 ;	German texts translation file.
 ;
@@ -8,10 +8,14 @@
 ;=============================================================================
 
 ; Basic texts
-	TCODE	tNo,				"Nein"					; 0 No
-	TCODE	tYes,				"Ja"					; 1 Yes
+	TCODE	tNo,				"Nein"					; 0 No		| Enum group
+	TCODE	tYes,				"Ja"					; 1 Yes		|
+
  IFDEF _cave_mode
-	TCODE	tCave,				"Höhle"					; 2 Cave
+	TCODE	tOff,				"Aus"					; OFF		| Enum group
+	TCODE	tOn,				"Ein"					; ON		|
+ ELSE
+	TCODE	tOff,				" "						; needed for option table
  ENDIF
 
 	TCODE	tblank,				" "						; (a single space character)
@@ -22,6 +26,10 @@
 	TCODE	tHeading,			"Kurs:"					; Heading:
 	TCODE	tLastDive,			"Letzter TG"			; Last Dive (Max 10 chars)
 
+	TCODE	tFTTSSurf,			"fTTS/Verz.:"			; Future TTS
+	TCODE	tLastDecostopSurf,	"Letzt.Stop:"			; last deco stop surface custom view
+	TCODE	tDvSalinitySurf,	"Salinität :"			; Salinity
+
  IFDEF _external_sensor
 	TCODE	tSensorMilliVolt,	"Sensoren mV"			; Sensors mV
  ENDIF
@@ -33,7 +41,12 @@
 	TCODE	tDivemenu_Avg_Mkr,	"Uhr/Marker"			; Reset Avg, Set Marker (and Turn Dive)
 	TCODE	tDivemenu_ToggleGF,	"Toggle GF"				; Toggle GF
 	TCODE	tDivemenu_Marker,	"Markierung"			; Set Marker
+
+ IFDEF _cave_mode
+	TCODE	tDivemenu_LostGas,	"verfügbar"				; Gas Availability
+ ELSE
 	TCODE	tDivemenu_LostGas,	"Gasverlust"			; Lost Gas
+ ENDIF
 
  IFDEF _ccr_pscr
 	TCODE	tDivemenu_Diluent,	"Diluents"				; Diluent (CCR)
@@ -46,7 +59,13 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tDivemenu_TurnDive,	"Rückweg"				; Turn Dive
+	TCODE	tDivePreCave,		"Höhle"					; Enter Cave Menu          ( 5 chars max)
+	TCODE	tDivemenu_wp_set,	"Wegepunkt"				; Set Waypoint             (10 chars max)
+	TCODE	tDivemenu_wp_out,	"gehe <-()"				; go one Waypoint outwards (10 chars max)
+	TCODE	tDivemenu_wp_in,	"gehe ->()"				; go one Waypoint inwards  (10 chars max)
+	TCODE	tDivemenu_TurnDive,	"Rückweg"				; Turn Dive                (10 chars max)
+	TCODE	tDivemenu_ContDive,	"Fortsetzen"			; Continue Dive            (10 chars max)
+	TCODE	tDivemenu_off_on, 	"Aus / Ein"				; Cave Mode Off/On         (10 chars max)
  ENDIF
 
 
@@ -58,18 +77,27 @@
 	TCODE	tGasSetup,			"OC Gas Setup"			; OC Gas Setup
 	TCODE	tSetTime,			"Zeit  stellen"			; Set Time
 	TCODE	tSetDate,			"Datum stellen"			; Set Date
-	TCODE	tSetTimeDate,		"Datum & Uhrzeit"		; Set Time & Date
+	TCODE	tSetTimeDate,		"Datum & Uhrzeit"		; Time & Date
 	TCODE	tDispSets,			"Anzeige"				; Display Settings
+	TCODE	tSysSets,			"System"				; System  Settings
 	TCODE	tExit,				"Ende"					; Exit
 	TCODE	tResetMenu,			"Reset Menü"			; Reset Menu
-	TCODE	tDiveModeMenu,		"Deko Einstellung"		; Deco Mode
+	TCODE	tDiveModeMenu,			"TG-Einstellungen"	; Dive Setup
+
+	TCODE	tDiveSetup,			"Tauchgang"				; Dive Setup
+	TCODE	tDecoSetup,			"Dekompression"			; Deco Setup
+	TCODE	tSACSetup,			"SAC Einstellung"		; SAC Setup
+	TCODE	tppO2Setup,			"O2 Partialdruck"		; ppO2 Setup
+	TCODE	tStopsSetup,		"Stopps & Tiefen"		; Stops & Depths
+
 	TCODE	tInfoMenu,			"Informationen"			; Information
  IFDEF _ccr_pscr
 	TCODE	tCCRSetup,			"CCR/pSCR Menü"			; CCR/pSCR Setup
 	TCODE	tDiluentSetup,		"Diluent Menü"			; Diluent Setup
  ENDIF
 	TCODE	tFixedSetpoints,	"CCR Setpoints"			; Fixed Setpoints
-	TCODE	tBack,				"zurück"
+	TCODE	tBack,				"zurück"				; back
+	TCODE	tGas6,				"Extra-Gas"				; edit & select Gas 6
 
  IFDEF _rx_functions
 	TCODE	tTrSettings,		"Druckanzeige"			; Pressure Display
@@ -80,13 +108,16 @@
 	TCODE	tTrMaxDeltaP,		"max Diff.: "			; independent double max difference
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tCCRSensor,			"Sensor"				; CCR/pSCR Sensor
 	TCODE	tCalibrateMenu,		"Kalibrierung"			; Calibration
 	TCODE	tCalibrationGas,	"Kal. Gas O2:"			; Cal. Gas O2:
 	TCODE	tCalibrate,			"Kalibrieren"			; Calibrate
- ENDIF
+	TCODE	tS8Mode,			"S8 Eingang:"			; Sensor Input
+	TCODE	tCCRS8Mode,			"Analog"				; Analog
+	TCODE	tCCRS8Mode2,		"Digital"				; Digital
+ ELSE
+	TCODE	tCCRS8Mode,			" "						; needed for option table
  ENDIF
 
 
@@ -124,7 +155,7 @@
 	TCODE	tppO2O2,			"ppO2(O2)"				; ppO2(O2)
 	TCODE	tppO2Dil,			"ppO2(Dil)"				; ppO2(Dil)
 	TCODE	tppO2Mix,			"ppO2(Mix)"				; ppO2(Mix)
-	TCODE	tCCRMode,			"Modus:"				; Mode:
+	TCODE	tCCRMode,			"Modus: "				; CCR/pSCR Mode
 	TCODE	tCCRModeFixedSP,	"fixe SP"				; 0 fixed for CCR / calculated for pSCR  | ENUM group
 	TCODE	tCCRModeSensor,		"Sensor"				; 1 Sensor                               |
 	TCODE	tCCRModeAutoSP,		"Auto SP"				; 2 Auto SP                              |
@@ -153,7 +184,8 @@
 ; Gaslist management
 	TCODE	tGas,				"Gas"					; Gas
 	TCODE	tDil,				"Dil"					; Diluent
-	TCODE	tGasErr,			"Err"					; Err (3 chars)
+	TCODE	tGasErr,			"Err"					; Err      (max 3 chars)
+	TCODE	tTakeGas,			"nimm"					; take gas (max 4 chars)
 
 
 ; Communication Menu
@@ -169,12 +201,18 @@
 
 
 ; Dive Settings
-	TCODE	tDvMode,			"Betrieb : "
-	TCODE	tDvOC,				"OC"
-	TCODE	tDvCCR,				"CCR"
-	TCODE	tDvGauge,			"Gauge"
-	TCODE	tDvApnea,			"Apnoe"
-	TCODE	tDvPSCR,			"pSCR"
+	TCODE	tDvMode,			"Betriebsart : "		; Dive Mode
+ IFDEF _cave_mode
+	TCODE	tCvMode,			"Höhlenmodus : "		; Cave Mode
+ ENDIF
+	TCODE	tFTTSMenu,			"fTTS/Verz.  : "		; Future TTS
+	TCODE	tTimeoutDive,		"TG-Ende nach: "		; Dive Timeout
+	TCODE	tStoreApnoeDive,	"Log Apnoe   : "		; Store Apnoe Dives
+	TCODE	tDvOC,				"OC"					; 0 | keep order, enum!
+	TCODE	tDvCCR,				"CCR"					; 1 |
+	TCODE	tDvGauge,			"Gauge"					; 2 |
+	TCODE	tDvApnea,			"Apnoe"					; 3 |
+	TCODE	tDvPSCR,			"pSCR"					; 4 |
 	TCODE	tDvCC,				"CC"
 	TCODE	tDkMode,			"Decotype: ZH-L16"
 	TCODE	tZHL16,				" "						; keep order, enum from here...
@@ -187,30 +225,29 @@
  ELSE
 	TCODE	tPPO2MIN,			"Min.       :"
  ENDIF
-	TCODE	tLastDecostop,		"Letzt.Stop  : "
-	TCODE	tAscentSpeed,		"Auf.Geschw. : "		; Ascent Speed
-	TCODE	tGasChangeTime,		"Gaswechsel  :+"		; additional Gas Change Time
-	TCODE	tExtendedStops,		"erw. Stopps : "		; extended stops
-	TCODE	tTimeoutDive,		"TG-Ende nach: "		; Dive Timeout
-	TCODE	tStoreApnoeDive,	"Log Apnoe   : "		; Store Apnoe Dives
 	TCODE	tDecoparameters,	"Deko Parameter"
 	TCODE	tGF_low,			"GF  low :"
 	TCODE	tGF_high,			"GF  high:"
 	TCODE	tSaturationMult,	"Sättigung   : "
 	TCODE	tDesaturationMult,	"Entsättigung: "
-	TCODE	tFTTSMenu,			"fTTS/Verz.:"			; Future TTS
-	TCODE	tLastDecostopSurf,	"Letzt.Stop:"			; last deco stop surface custom view
 	TCODE	tGFMenu,			"GF Parameter"			; GF Settings
 	TCODE	taGF_low,			"aGF low :"				; aGF low
 	TCODE	taGF_high,			"aGF high:"				; aGF high
-	TCODE	taGF_enable,		"aGF wählbar:"			; aGF Selectable
+	TCODE	taGFenable,			"aGF wählbar:"			; aGF Selectable
 	TCODE	tDiveaGF_active,	"aGF aktiv"				; using aGF
-	TCODE	tppO2settings,		"ppO2 Parameter"		; ppO2 Settings
-	TCODE	tsafetystopmenu,	"Sicherheitsstop:"		; Safety Stop:
+	TCODE	tSafetyStop,		"Sicherheitsstop:"		; Safety Stop:  (max. 16 chars)
+	TCODE	tExtendedStops,		"erweit. Stopps :"		; Extended Stops
+	TCODE	tLastDecostop,		"Letzt.Stop : "			; last Deco Stop Depth
+	TCODE	tDvSalinity,		"Salinität  : "			; Salinity
+	TCODE	tDepthWarn,			"Tiefenlimit: "			; Depth Warning
 	TCODE	tGasUsage,			"Gasbedarf"				; Gas Usage
-	TCODE	tSetBotUse,			"Arbeits-Gas:"			; Bottom Gas:
-	TCODE	tSetDecoUse,		"Deko    Gas:"			; Deco   Gas:
-	TCODE	tCalcAscGas,		"Gasmenge(B/O):"		; Calculate Gas (Bail Out) needs?
+	TCODE	tSetWorkSAC,		"Arbeits-SAC:"			; SAC Work:
+	TCODE	tSetDecoSAC,		"Deko    SAC:"			; SAC Deco:
+	TCODE	tCalcGasNeeds,		"Gasmenge(B/O): "		; Calculate  Gas (Bail Out) Needs
+ IFDEF _gas_contingency
+	TCODE	tGasContingencyDive,"Swap on empty: "		; swap tank on becoming empty
+ ENDIF
+	TCODE	tGasChangeTime,		"Gaswechsel   :+"		; additional Gas Change Time
 	TCODE	tSetup_Tank,		"Tank Einstellen"		; Setup Tank
 	TCODE	tTankSize,			"Tank Größe"
 	TCODE	tTankUsablePress,	"Umkehrdruck (Aufst)"	; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars)
@@ -221,8 +258,8 @@
  IFDEF _ccr_pscr
 	TCODE	tCCmaxFracO2,		"Loop %O2 max. : "		; max O2 percent (absolute) in the loop
 	TCODE	tDilppO2Check,		"Check Dil ppO2: "		; check ppO2 of the diluent against the setpoint
-	TCODE	tPSCR_O2_drop,		"pSCR O2 Abfall: "		; pSCR O2 drop
-	TCODE	tPSCR_lungratio,	"    L.Verhält.: "		; pSCR lung ratio
+	TCODE	tPSCR_O2_drop,		"pSCR O2 Abfall: "		; pSCR O2 Drop
+	TCODE	tPSCR_lungratio,	".. Lungenverh.: "		; pSCR Lung Ratio
 	TCODE	tCopyDilToOC,		"Kopiere Dil.-> OC"		; copy diluent settings to OC gas
 	TCODE	tBackToLoop,		"auf Loop"				; back to loop (10 chars max)
  ENDIF
@@ -257,30 +294,37 @@
 
 
 ; Display Settings
-	TCODE	tBright,			"Helligkeit:"
-	TCODE	tEco,				"Eco"
-	TCODE	tMedium,			"Mittel"
-	TCODE	tHigh,				"Hoch"
-	TCODE	tDvSalinity,		"Salinität: "			; Salinity
-	TCODE	tShowppO2,			"ständig zeigen:"		; Always show ppO2:
-	TCODE	tFlip,				"Anzeige drehen:"		; Rotate Screen
-	TCODE	tMODwarning,		"Tiefe Warnung:"		; depth Warnings
-;	TCODE	tIBCDwarning,		"IBCD  Warnung:"		; IBCD warning
-	TCODE	tLayout,			"Layout :"				; Layout
-	TCODE	t2ndDepth,			"2.Tiefe:"				; 2nd depth display content (11 chars max)
-	TCODE	tTissueGraphics,	"Grafik :"				; tissue graphics
+	TCODE	tBright,			"Helligkeit: "			; Brightness
+	TCODE	tLayout,			"Layout    : "			; Layout
+	TCODE	tUnits,				"Einheiten : "			; Units
+ IF _language_2!=none
+	TCODE	tLanguage,			"Sprache   : "			; Language
+ ENDIF
+	TCODE	tFlip,				"Anzeige drehen: "		; Rotate Screen
+	TCODE	tColorScheme,		"Farbschema"			; Colour Scheme
+	TCODE	tVSIgraph,			"Geschw.Grafik: "		; Speed Graph
+	TCODE	tVSItext2,			"Var.   Geschw: "		; variable Speed
+	TCODE	tShowppO2,			"ppO2 immer   : "		; always show ppO2
+	TCODE	tDepthWarning,		"Tiefe blinken: "		; Depth blinking
+	TCODE	t2ndDepth,			"2.Tiefe: "				; 2nd Depth Display Content (11 chars max)
+	TCODE	tTissueGraphics,	"Grafik : "				; Tissue Graphics
 
-	TCODE	tLayoutNormal,		"normal"				; normal
-	TCODE	tLayoutBig,			"groß"					; big
-
-
-; VSI display Settings
-	TCODE	tVSItext2,			"Variable Geschw:"		; Variable speed:
-	TCODE	tVSIgraph,			"Geschw.  Grafik:"		; Speed graph:
+	TCODE	tIBCDwarning,		"IBCD  Warnung: "		; IBCD warning
+	TCODE	tEco,				"Eco"					; eco     | ENUM group
+	TCODE	tMedium,			"Mittel"				; medium  |
+	TCODE	tHigh,				"Hoch"					; high    |
+	TCODE	tLayoutNormal,		"normal"				; normal  | ENUM group
+	TCODE	tLayoutBig,			"groß"					; big     |
+	TCODE	tMax,				"max."					; max     | ENUM group
+	TCODE	tAvg,				"mittel"				; average |
+	TCODE	tTissuePresSat,		"Druck+Sat."			; pressure and saturation | ENUM group
+ IFDEF _helium
+	TCODE	tTissueN2He,		"N2+He"					; N2 + He pressure        |
+ ENDIF
 
 
 ; Setup Menu
-	TCODE	tSystSets,			"Konfiguration"
+	TCODE	tSystSets,			"Konfiguration"			; System Settings
  IFDEF _compass
 	TCODE	tCompassMenu,		"Kompass-Kalibrierung"	; Compass calibration
 	TCODE	tCompassGain,		"Empfindlichkeit:"		; Compass gain:
@@ -288,12 +332,12 @@
 	TCODE	tCalY,				"Kal. Y:"				; Cal Y
 	TCODE	tCalZ,				"Kal. Z:"				; Cal Z
  ENDIF
-	TCODE	tUnits,				"Einheiten: "
 	TCODE	tMetric,			" m/°C"					; Enum menu
 	TCODE	tImperial,			"ft/°F"
 								;         111         111         111         111         111
 	; 5 rows by 12 chars each:	 123456789012123456789012123456789012123456789012123456789012
-	TCODE	tDefName,		"HW OSTC"	;"  Lese die   Anleitung,  kenne  und verstehe die  Grenzen!"
+	TCODE	tDefName,			"HW OSTC"	;"  Lese die   Anleitung,  kenne  und verstehe die  Grenzen!"
+	TCODE	tPiezo,				"Taster"				; Buttons
 	TCODE	tButtonleft,		"Taster links :"		; Left button
 	TCODE	tButtonright,		"Taster rechts:"		; Right button
 	TCODE	tAltMode,			"Wartezeit:"
@@ -324,7 +368,7 @@
 
 ; Simulator menu
 	TCODE	tInter,				"Start Simulator"		; Start Simulator
-	TCODE	tPlan,				"Simulator"				; Simulator
+	TCODE	tSimulator,			"Simulator"				; Simulator
 
 
 ; Decoplanner submenu
@@ -332,7 +376,7 @@
 	TCODE	tBtTm_short,		"Zeit :"				; Bot. Time: (max. 6 chars)
 	TCODE	tBtDep,				"Tiefe    :"			; Max Depth: (10 chars)
 	TCODE	tIntvl,				"Intervall:"			; Interval : (10 chars)
-	TCODE	tDecoSetup,			"Deko Parameter"
+	TCODE	tCalculatorSetup,	"Deko Parameter"		; Calculator Setup
 	TCODE	tDeco,				"Deko Berechnung"		; Calculate Deco
 	TCODE	tDivePlan,			"Tauchplan"				; Dive Plan (max. 10 chars)
 	TCODE	tNoDeco,			"Keine Deko"			; No Deco
@@ -340,7 +384,7 @@
 	TCODE	tSelectSetpoint,	"Setpoint   : "
 	TCODE	tuseAGF,			"Benutze aGF: "
  IFDEF _gas_contingency
-	TCODE	tGasContingency,	"Gas Cont. : "			; Gas Contingency			## translation pending
+	TCODE	tGasContingencySim,	"Gas Cont. : "			; Gas Contingency			## translation pending
  ENDIF
 
 ; Decoplanner progress indication
@@ -356,10 +400,12 @@
 
 ; Information menu
 	TCODE	tFirmware,			"Firmware: "			; Firmware: (space)
+	TCODE	tFirmwareDate,		"erstellt: "			; created : (space)  firmware creation date
 	TCODE	tHardware,			"Hardware: "			; Hardware: (space)
 	TCODE	tSerial,			"Seriennr: "			; Serial  : (space)
-	TCODE	tTotalDives,		"Anzahl TG:"			; Total Dives:
-	TCODE	tBatteryV,			"Batterie: "			; Battery:
+	TCODE	tBatteryV,			"Batterie: "			; Battery : (space)
+	TCODE	tSensorC,			"Sensor  : "			; Sensor  : (space)
+	TCODE	tSensorD,			"Offset  : "			; Offset  : (space)
 	TCODE	tUptime,			"Laufzeit: "			; Uptime:
 
  IFDEF _rx_functions
@@ -368,8 +414,8 @@
 
 
 ; Divemode screen
-	TCODE	tNDL,				" NZ"					; 3 chars max
-	TCODE	tTTS,				"TTS"					; 3 chars max
+	TCODE	tNDL,				" NZ"					; 3 chars
+	TCODE	tTTS,				"TTS"					; 3 chars
 	TCODE	tSlow,				"langsam"				; slow - max 7 chars
 	TCODE	tVelMetric,			"m/min"
 	TCODE	tVelImperial,		"ft/m "
@@ -381,10 +427,6 @@
 	TCODE	tDepth,				"Tiefe"					; Depth (max 5 chars)
 	TCODE	tMaxDepth,			"Max.Tiefe"				; Max.Depth     - max 9 chars!
 	TCODE	tAvgDepth,			"Durchschn."			; average Depth - max 9 chars! (extra dot is ok)
-	TCODE	tTissuePresSat,		"Druck+Sat."			; 0 pressure and saturation  | ENUM group
- IFDEF _helium
-	TCODE	tTissueN2He,		"N2+He"					; 1 N2 + He pressure         |
- ENDIF
 	TCODE	tDivetime,			"Dauer"					; Divetime (max 8 chars)
 	TCODE	tDiveTotalAvg,		"Durchschn.1"
 	TCODE	tDiveStopwatch,		"Stoppuhr"
@@ -410,16 +452,18 @@
 	TCODE	tSensorCheck,		"Sensor Test"			; Sensor Check
 	TCODE	tdil,				"Dil:"					; Diluent ppO2 Warning
 	TCODE	tmix,				"Mix:"					; Pre-Mix ppO2 Warning
-	TCODE	tGasNeedsWarn,		"Gasbedarf"
-	TCODE	tGasNeedsAscent,	"Gas Bedarf Aufstieg"
-	TCODE	tCNSsurf,			"ZNS Oberfl."
-	TCODE	tCNSfTTS,			"ZNS fTTS"
-	TCODE	tCNSBO,				"ZNS B/O"
-	TCODE	tCNSnow,			"ZNS jetzt"
-	TCODE	tCNSeod,			"ZNS Ende"
-	TCODE	tnoBOgas,			"-B/O-Gas-"
-	TCODE	tMicroBubbles,		"M.Blasen"
-	TCODE	tCNS,				"CNS: "
+	TCODE	tGasNeedsWarn,		"Gasbedarf"				;
+	TCODE	tCNSsurf,			"ZNS Oberfl."			;
+	TCODE	tCNSfTTS,			"ZNS fTTS"				;
+	TCODE	tCNSBO,				"ZNS B/O"				;
+	TCODE	tCNSnow,			"ZNS jetzt"				;
+	TCODE	tCNSeod,			"ZNS Ende"				;
+ IFDEF _cave_mode
+	TCODE	tCNScave,			"ZNS Höhle"				;
+ ENDIF
+	TCODE	tnoBOgas,			"-B/O-Gas-"				;
+	TCODE	tMicroBubbles,		"M.Blasen"				;
+	TCODE	tCNS,				"ZNS: "					;
 	TCODE	tgaschange,			"wechseln?"				; better gas found
 	TCODE	tNeed,				"Bedf."					; gas need (5 chars)
 	TCODE	tBattery,			"Batterie"				; Battery
@@ -447,10 +491,15 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tGasNeedsCaveMode,	"Gas Bedarf Höhlen-Modus"; title for gas needs custom view
-	TCODE	tDiveTurned,		"Rückweg"				; dive is turned      (max. 9 char)
+	TCODE	tGasNeedsCaveMode,	"Gas Bedarf -HÖHLE- "	; title for gas needs custom view (cave mode)		| need to be
+	TCODE	tGasNeedsAscent,	"Gas Bedarf Aufstieg"	; title for gas needs custom view (open water mode)	| same length
 	TCODE	tCaveMode,			"Höhle"					; cave mode activated (max. 9 char)
 	TCODE	tCaveModeShutdown,	"X-Höhle-X"				; cave mode shut down (max. 9 char)
+	TCODE	tCaveTTS,			"Cave TTS"				; cave mode total time to surface
+	TCODE	tCaveStops,			"total Stops"			; cave mode total time for stops
+	TCODE	tCaveRuntime,		"total RT"				; cave mode total runtime
+ ELSE
+	TCODE	tGasNeedsAscent,	"Gas Bedarf Aufstieg"	; title for gas needs custom view
  ENDIF
 
 
@@ -470,9 +519,17 @@
 ; Logbook
 	TCODE	tCNS2,				"ZNS:"
 	TCODE	tAVG,				"Mit:"
+	TCODE	tGF2,				"GF :"
+	TCODE	tSAT,				"Sät:"					; max  4 chars
+	TCODE	tDvSalinity2,		"Salinität :"			; max 11 chars
+	TCODE	tLastDeco,			"Letzt.Stop:"			; max 11 chars
+	TCODE	tNoProfileData,		"keine Daten mehr..."	; max 21 chars
+	TCODE	tBeginOfDive,		"Beginn:"				; max  8 chars
+	TCODE	tEndOfDive,			"Ende:"					; max  8 chars
+	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
+
+; other useser
 	TCODE	tGF,				"GF:"
-	TCODE	tSAT,				"Sät:"					; 4 chars max
-
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -505,6 +562,7 @@
 
 
 ; Logbook Offset Menu
+	TCODE	tTotalDives,		"Anzahl TG: "			; Total Dives
 	TCODE	tLogOffset,			"Logbuch-Offset"		; Logbook offset
 	TCODE	tLogOffsetValue,	"Offset      : "		; Offset
 	TCODE	tLogOffStepSize,	"Schrittweite: "		; Step Size
@@ -528,7 +586,6 @@
 
 
 ; Color Scheme menu
-	TCODE	tColorScheme,		"Farbschema"			; Colour Scheme
 	TCODE	tColorSetDive,		"Tauchmodus:"			; Divemode:
 	TCODE	tColorSetName0,		"Standard"				; Standard
 	TCODE	tColorSetName1,		"Rot"					; Red
@@ -537,21 +594,17 @@
 
 
 ; Language selection
- IF _language_2!=none
-	TCODE	tLanguage,			"Sprache: "				; used in menu_tree
- ENDIF
-
  IF _language_1==en
-	TCODE	tLang1,				"Englisch"				; tLang1 is 1st language, enum context
+	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
  ELSE
  IF _language_1==de
-	TCODE	tLang1,				"Deutsch"
+	TCODE	tLang1,				"DE"
  ELSE
  IF _language_1==fr
-	TCODE	tLang1,				"Französisch"
+	TCODE	tLang1,				"FR"
  ELSE
  IF _language_1==it
-	TCODE	tLang1,				"Italienisch"
+	TCODE	tLang1,				"IT"
  ELSE
 	TCODE	tLang1,				""						; dummy target for options table
  ENDIF
@@ -560,16 +613,16 @@
  ENDIF
 
  IF _language_2==en
-	TCODE	tLang2,				"Englisch"				; tLang2 is 2nd language, enum context
+	TCODE	tLang2,				"EN"					; tLang2 is 2nd language, enum context
  ELSE
  IF _language_2==de
-	TCODE	tLang2,				"Deutsch"
+	TCODE	tLang2,				"DE"
  ELSE
  IF _language_2==fr
-	TCODE	tLang2,				"Französisch"
+	TCODE	tLang2,				"FR"
  ELSE
  IF _language_2==it
-	TCODE	tLang2,				"Italienisch"
+	TCODE	tLang2,				"IT"
  ENDIF
  ENDIF
  ENDIF
--- a/src/text_italian.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/text_italian.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_italian.asm                     next combined generation V3.04.3
+;	File text_italian.asm                     next combined generation V3.08.8
 ;
 ;	Italian texts translation file.
 ;
@@ -8,10 +8,14 @@
 ;=============================================================================
 
 ; Basic texts
-	TCODE	tNo,				"No"					; 0 No
-	TCODE	tYes,				"Si"					; 1 Yes
+	TCODE	tNo,				"No"					; 0 No		| Enum group
+	TCODE	tYes,				"Si"					; 1 Yes		|
+
  IFDEF _cave_mode
-	TCODE	tCave,				"Cave"					; 2 Cave
+	TCODE	tOff,				"off"					; OFF		| Enum group
+	TCODE	tOn,				"on"					; ON		|
+ ELSE
+	TCODE	tOff,				" "						; needed for option table
  ENDIF
 
 	TCODE	tblank,				" "						; (a single space character)
@@ -22,6 +26,10 @@
 	TCODE	tHeading,			"Direzione:"			; Heading:
 	TCODE	tLastDive,			"UltimaImm."			; Last Dive (Max 10 chars)
 
+	TCODE	tFTTSSurf,			"TTS Futuro  :"			; Future TTS
+	TCODE	tLastDecostopSurf,	"Ultima Tappa:"			; last deco stop surface custom view
+	TCODE	tDvSalinitySurf,	"Salinita'   :"			; Salinity
+
  IFDEF _external_sensor
 	TCODE	tSensorMilliVolt,	"Sensori mV"			; Sensors mV
  ENDIF
@@ -33,7 +41,12 @@
 	TCODE	tDivemenu_Avg_Mkr,	"Med/Segna"				; Reset Avg, Set Marker (and Turn Dive)	
 	TCODE	tDivemenu_ToggleGF,	"Alterna GF"			; Toggle GF
 	TCODE	tDivemenu_Marker,	"Set Marker"			; Set Marker
+
+ IFDEF _cave_mode
+	TCODE	tDivemenu_LostGas,	"Gas avail."			; Gas Availability
+ ELSE
 	TCODE	tDivemenu_LostGas,	"Gas perso"				; Lost Gas
+ ENDIF
 
  IFDEF _ccr_pscr
 	TCODE	tDivemenu_Diluent,	"Lista Dil"				; Diluents (CCR)
@@ -46,7 +59,13 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tDivemenu_TurnDive,	"Turn Dive"				; Turn Dive
+	TCODE	tDivePreCave,		"Cave?"					; Enter Cave Menu          ( 5 chars max)
+	TCODE	tDivemenu_wp_set,	"Waypoint"				; Set Waypoint             (10 chars max)
+	TCODE	tDivemenu_wp_out,	"WP go <-()"			; go one Waypoint outwards (10 chars max)
+	TCODE	tDivemenu_wp_in,	"WP go ->()"			; go one Waypoint inwards  (10 chars max)
+	TCODE	tDivemenu_TurnDive,	"Turn Dive"				; Turn Dive                (10 chars max)
+	TCODE	tDivemenu_ContDive,	"Cont.Dive"				; Continue Dive            (10 chars max)
+	TCODE	tDivemenu_off_on, 	"Off / On"				; Cave Mode Off/On         (10 chars max)
  ENDIF
 
 
@@ -58,11 +77,19 @@
 	TCODE	tGasSetup,			"Imposta Gas OC"		; OC Gas Setup
 	TCODE	tSetTime,			"Imposta Ora"			; Set Time
 	TCODE	tSetDate,			"Imposta Data"			; Set Date
-	TCODE	tSetTimeDate,		"Imp. Ora e Data"		; Set Time & Date
+	TCODE	tSetTimeDate,		"Ora e Data"			; Time & Date
 	TCODE	tDispSets,			"Visualizzazione"		; Display Settings
+	TCODE	tSysSets,			"System Settings"		; System  Settings
 	TCODE	tExit,				"Esci"					; Exit
 	TCODE	tResetMenu,			"Resetta Menu"			; Reset Menu
-	TCODE	tDiveModeMenu,		"Modalita' Deco"		; Deco Mode
+	TCODE	tDiveModeMenu,		"Modalita' Deco"		; Dive Setup
+
+	TCODE	tDiveSetup,			"Dive Setup"			; Dive Setup
+	TCODE	tDecoSetup,			"Deco Setup"			; Deco Setup
+	TCODE	tSACSetup,			"SAC  Setup"			; SAC Setup
+	TCODE	tppO2Setup,			"ppO2 Setup"			; ppO2 Setup
+	TCODE	tStopsSetup,		"Stops & Depths"		; Stops & Depths
+
 	TCODE	tInfoMenu,			"Informazioni"			; Information
  IFDEF _ccr_pscr
 	TCODE	tCCRSetup,			"Imposta CCR"			; CCR Setup
@@ -70,6 +97,7 @@
  ENDIF
 	TCODE	tFixedSetpoints,	"Setpoints Fissi"		; Fixed Setpoints
 	TCODE	tBack,				"back"					; back
+	TCODE	tGas6,				"extra Gas"				; edit & select Gas 6
 
  IFDEF _rx_functions
 	TCODE	tTrSettings,		"Display Press.ni"		; Pressure Display
@@ -80,13 +108,16 @@
 	TCODE	tTrMaxDeltaP,		"DeltaP Max: "			; independent double max diffenerce
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tCCRSensor,			"Sensori CCR"			; CCR Sensor
 	TCODE	tCalibrateMenu,		"Calibrazione"			; Calibration
 	TCODE	tCalibrationGas,	"Cal. Gas O2:"			; Cal. Gas O2:
 	TCODE	tCalibrate,			"Calibra"				; Calibrate
- ENDIF
+	TCODE	tS8Mode,			"S8 Input: "			; Sensor Input
+	TCODE	tCCRS8Mode,			"Analog"				; Analog
+	TCODE	tCCRS8Mode2,		"Digital"				; Digital
+ ELSE
+	TCODE	tCCRS8Mode,			" "						; needed for option table
  ENDIF
 
 
@@ -124,7 +155,7 @@
 	TCODE	tppO2O2,			"ppO2(O2)"				; ppO2(O2)
 	TCODE	tppO2Dil,			"ppO2(Dil)"				; ppO2(Dil)
 	TCODE	tppO2Mix,			"ppO2(Mix)"				; ppO2(Mix)
-	TCODE	tCCRMode,			"Modo CCR:"				; CCR Mode:
+	TCODE	tCCRMode,			"Modo: "				; CCR/pSCR Mode
 	TCODE	tCCRModeFixedSP,	"SP Fissi"				; 0 fixed for CCR / calculated for pSCR  | ENUM group
 	TCODE	tCCRModeSensor,		"Sensori"				; 1 Sensor                               |
 	TCODE	tCCRModeAutoSP,		"SP Auto"				; 2 Auto SP                              |
@@ -153,7 +184,8 @@
 ; Gaslist management
 	TCODE	tGas,				"Gas"					; Gas
 	TCODE	tDil,				"Dil"					; Diluent
-	TCODE	tGasErr,			"Err"					; Err (3 chars)
+	TCODE	tGasErr,			"Err"					; Err      (max 3 chars)
+	TCODE	tTakeGas,			"take"					; take gas (max 4 chars)
 
 
 ; Communication Menu
@@ -169,12 +201,18 @@
 
 
 ; Dive Settings
-	TCODE	tDvMode,			"Tipo Tuffo:"
-	TCODE	tDvOC,				"OC"
-	TCODE	tDvCCR,				"CCR"
-	TCODE	tDvGauge,			"Gauge"
-	TCODE	tDvApnea,			"Apnea"
-	TCODE	tDvPSCR,			"pSCR"
+	TCODE	tDvMode,			"Tipo Tuffo    : "		; Dive Mode
+ IFDEF _cave_mode
+	TCODE	tCvMode,			"Cave Mode     : "		; Cave Mode
+ ENDIF
+	TCODE	tFTTSMenu,			"TTS Futuro    : "		; Future TTS
+	TCODE	tTimeoutDive,		"Timeout Immsni: "		; Dive Timeout
+	TCODE	tStoreApnoeDive,	"Salva Apnee   : "		; Salva Tuffi Apnea
+	TCODE	tDvOC,				"OC"					; 0 | keep order, enum!
+	TCODE	tDvCCR,				"CCR"					; 1 |
+	TCODE	tDvGauge,			"Gauge"					; 2 |
+	TCODE	tDvApnea,			"Apnea"					; 3 |
+	TCODE	tDvPSCR,			"pSCR"					; 4 |
 	TCODE	tDvCC,				"CC"
 	TCODE	tDkMode,			"Algorit.: ZH-L16"
 	TCODE	tZHL16,				" "
@@ -187,30 +225,29 @@
  ELSE
 	TCODE	tPPO2MIN,			"Min     :"
  ENDIF
-	TCODE	tLastDecostop,		"Ultima Tappa  : "
-	TCODE	tAscentSpeed,		"Velox Risalita : "		; Ascent Speed
-	TCODE	tGasChangeTime,		"Cambio Gas :+"			; additional Gas Change Time
-	TCODE	tExtendedStops,		"Anticipa Tappa: "		; extended stops
-	TCODE	tTimeoutDive,		"Timeout Immsni: "		; Dive Timeout
-	TCODE	tStoreApnoeDive,	"Salva Apnee   : "		; Salva Tuffi Apnea
 	TCODE	tDecoparameters,	"Parametri Deco"
 	TCODE	tGF_low,			"GF  Basso:"
 	TCODE	tGF_high,			"GF  Alto :"
 	TCODE	tSaturationMult,	"Saturazione  : "
 	TCODE	tDesaturationMult,	"Desaturazione: "
-	TCODE	tFTTSMenu,			"TTS Futuro:"			; Future TTS
-	TCODE	tLastDecostopSurf,	"Ultima Tappa:"			; last deco stop surface custom view
 	TCODE	tGFMenu,			"Menu GF"				; GF Settings
 	TCODE	taGF_low,			"aGF Basso:"			; aGF low
 	TCODE	taGF_high,			"aGF Alto :"			; aGF high
-	TCODE	taGF_enable,		"aGF Selezionabile:"	; aGF Selectable
+	TCODE	taGFenable,			"aGF Selezionabile:"	; aGF Selectable
 	TCODE	tDiveaGF_active,	"Usa aGF"				; using aGF
-	TCODE	tppO2settings,		"Menu ppO2"				; ppO2 Settings (max. 18 chars)
-	TCODE	tsafetystopmenu,	"Tappa Sicurezza:"		; Safety Stop: (max. 16 chars)
+	TCODE	tSafetyStop,		"Tappa Sicurezza:"		; Safety Stop:  (max. 16 chars)
+	TCODE	tExtendedStops,		"Anticipa Tappa :"		; Extended Stops
+	TCODE	tLastDecostop,		"Ultima Tappa  : "		; last Deco Stop Depth
+	TCODE	tDvSalinity,		"Salinita'     : "		; Salinity
+	TCODE	tDepthWarn,			"Depth Warning : "		; Depth Warning
 	TCODE	tGasUsage,			"Utilizzo Gas"			; Gas Usage
-	TCODE	tSetBotUse,			"Gas Fondo: "			; Bottom Gas: (space)
-	TCODE	tSetDecoUse,		"Gas Deco : "			; Deco   Gas: (space)
-	TCODE	tCalcAscGas,		"Calc.Gas (B/O):"		; Calculate Gas (Bail Out) needs?
+	TCODE	tSetWorkSAC,		"SAC Fondo: "			; SAC Work: (space)
+	TCODE	tSetDecoSAC,		"SAC Deco : "			; SAC Deco: (space)
+	TCODE	tCalcGasNeeds,		"Calc.Gas(B/O): "		; Calculate  Gas (Bail Out) Needs
+ IFDEF _gas_contingency
+	TCODE	tGasContingencyDive,"Swap on empty: "		; swap tank on becoming empty
+ ENDIF
+	TCODE	tGasChangeTime,		"Cambio Gas   :+"		; additional Gas Change Time
 	TCODE	tSetup_Tank,		"Imposta Bombola"		; Setup Tank
 	TCODE	tTankSize,			"Capac. Bombola"		; Tank Size
 	TCODE	tTankUsablePress,	"Press. X Risalita"		; Tank Press Budget for Ascent (turn pressure)
@@ -221,8 +258,8 @@
  IFDEF _ccr_pscr
 	TCODE	tCCmaxFracO2,		"%O2 max Loop  : "		; max O2 percent (absolute) in the loop
 	TCODE	tDilppO2Check,		"Check Dil ppO2: "		; check ppO2 of the diluent against the setpoint
-	TCODE	tPSCR_O2_drop,		"pSCR Caduta O2: "		; pSCR O2 drop
-	TCODE	tPSCR_lungratio,	"    Lung Ratio: "		; pSCR lung ratio
+	TCODE	tPSCR_O2_drop,		"pSCR Caduta O2: "		; pSCR O2 Drop
+	TCODE	tPSCR_lungratio,	"... Lung Ratio: "		; pSCR Lung Ratio
 	TCODE	tCopyDilToOC,		"Copia Dil-OC"			; copy diluent settings to OC gas
 	TCODE	tBackToLoop,		"Usa Loop"				; back to loop (10 chars max)
  ENDIF
@@ -257,30 +294,37 @@
 
 
 ; Display Settings
-	TCODE	tBright,			"Luminosita':"
-	TCODE	tEco,				"Eco"
-	TCODE	tMedium,			"Media"
-	TCODE	tHigh,				"Alta"
-	TCODE	tDvSalinity,		"Salinita': "			; Salinity
-	TCODE	tShowppO2,			"ppO2 Permanente:"		; Always show ppO2:
-	TCODE	tFlip,				"Ruota schermo:"		; Rotate Screen
-	TCODE	tMODwarning,		"Avvertimento Prof:"	; depth warnings
-;	TCODE	tIBCDwarning,		"Avvertimento IBCD:"	; IBCD Warning
-	TCODE	tLayout,			"Layout :"				; Layout
-	TCODE	t2ndDepth,			"2a Prof.:"				; 2nd depth display content (11 chars max)
-	TCODE	tTissueGraphics,	"Grafica:"				; tissue graphics
+	TCODE	tBright,			"Luminosita': "			; Brightness
+	TCODE	tLayout,			"Layout     : "			; Layout
+	TCODE	tUnits,				"Unita'     : "			; Units
+ IF _language_2!=none
+	TCODE	tLanguage,			"Lingua     : "			; Language
+ ENDIF
+	TCODE	tFlip,				"Ruota schermo: "		; Rotate Screen
+	TCODE	tColorScheme,		"Schema colori"			; Colour Scheme
+	TCODE	tVSIgraph,			"Grafico Veloc. : "		; Speed Graph
+	TCODE	tVSItext2,			"Velox Variab.  : "		; variable Speed
+	TCODE	tShowppO2,			"ppO2 Permanente: "		; always show ppO2:
+	TCODE	tDepthWarning,		"Prof luccicare : "		; Depth blinking
+	TCODE	t2ndDepth,			"2a Prof.: "			; 2nd depth display content (11 chars max)
+	TCODE	tTissueGraphics,	"Grafica : "			; tissue graphics
 
-	TCODE	tLayoutNormal,		"Normale"				; normal
-	TCODE	tLayoutBig,			"Max"					; big ("Maxi")
-
-
-; VSI display Settings
-	TCODE	tVSItext2,			"Velox Variabile:"		; Variable speed:
-	TCODE	tVSIgraph,			"Grafico Velocita':"	; Speed graph:
+	TCODE	tIBCDwarning,		"Avvertimento IBCD:"	; IBCD Warning
+	TCODE	tEco,				"Eco"					; eco     | ENUM group
+	TCODE	tMedium,			"Media"					; medium  |
+	TCODE	tHigh,				"Alta"					; high    |
+	TCODE	tLayoutNormal,		"Normale"				; normal  | ENUM group
+	TCODE	tLayoutBig,			"Max"					; big     |
+	TCODE	tMax,				"max."					; max     | ENUM group
+	TCODE	tAvg,				"avg."					; average |
+	TCODE	tTissuePresSat,		"Pres+Sat"				; 0 pressure and saturation | ENUM group
+ IFDEF _helium
+	TCODE	tTissueN2He,		"N2+He"					; 1 N2 + He pressure        |
+ ENDIF
 
 
 ; Setup Menu
-	TCODE	tSystSets,			"Impostazioni"
+	TCODE	tSystSets,			"Impostazioni"			; System Settings
  IFDEF _compass
 	TCODE	tCompassMenu,		"Calibra Bussola"		; Compass calibration
 	TCODE	tCompassGain,		"Suscettibilita:"		; Compass gain:
@@ -288,14 +332,14 @@
 	TCODE	tCalY,				"Cal Y:"				; Cal Y
 	TCODE	tCalZ,				"Cal Z:"				; Cal Z
  ENDIF
-	TCODE	tUnits,				"Unita':"
 	TCODE	tMetric,			" m/°C"					; Enum menu
 	TCODE	tImperial,			"ft/°F"
 								;         111         111         111         111         111
 	; 5 rows by 12 chars each:	 123456789012123456789012123456789012123456789012123456789012
 	TCODE	tDefName,			"HW OSTC"	;"  Read the  Manual, know& understandthe inherentLimitations!"
-	TCODE	tButtonleft,		"Bottone Sx:"			; Left button
-	TCODE	tButtonright,		"Bottone Dx:"			; Right button
+	TCODE	tPiezo,				"Bottone"				; Buttons
+	TCODE	tButtonleft,		"Bottone Sx:"			; Left  Button
+	TCODE	tButtonright,		"Bottone Dx:"			; Right Button
 	TCODE	tAltMode,			"Attesa   :"			; Waiting Time
 	TCODE	tAltModeFly,		"Volo"					; Flying
 	TCODE	tAltMode1000,		"1000m"					;
@@ -324,7 +368,7 @@
 
 ; Simulator menu
 	TCODE	tInter,				"Avvia Simulatore"		; Start Simulator
-	TCODE	tPlan,				"Simulatore"			; Simulator
+	TCODE	tSimulator,			"Simulatore"			; Simulator
 
 
 ; Decoplanner submenu
@@ -332,7 +376,7 @@
 	TCODE	tBtTm_short,		"Tempo:"				; Bot. Time: (max. 6 chars)
 	TCODE	tBtDep,				"Profond. Max:"			; Max Depth: (10 chars)
 	TCODE	tIntvl,				"Int.Superf. :"			; Interval : (10 chars)
-	TCODE	tDecoSetup,			"Setta Calcoli"			; Deco Setup
+	TCODE	tCalculatorSetup,	"Setta Calcoli"			; Calculator Setup
 	TCODE	tDeco,				"Calcola Deco"			; Calculate Deco
 	TCODE	tDivePlan,			"Pianificat"			; Dive Plan (max. 10 chars)
 	TCODE	tNoDeco,			"No Deco"				; No Deco
@@ -340,7 +384,7 @@
 	TCODE	tSelectSetpoint,	"Setpoint CCR: "		;
 	TCODE	tuseAGF,			"usa aGF     : "		; use aGF
  IFDEF _gas_contingency
-	TCODE	tGasContingency,	"Gas Cont. : "			; Gas Contingency			## translation pending
+	TCODE	tGasContingencySim,	"Gas Cont. : "			; Gas Contingency			## translation pending
  ENDIF
 
 ; Decoplanner progress indication
@@ -356,10 +400,12 @@
 
 ; Information menu
 	TCODE	tFirmware,			"Firmware: "			; Firmware: (space)
+	TCODE	tFirmwareDate,		"created : "			; created : (space)  firmware creation date
 	TCODE	tHardware,			"Hardware: "			; Hardware: (space)
 	TCODE	tSerial,			"Seriale : "			; Serial  : (space)
-	TCODE	tTotalDives,		"Tot Immersioni:"		; Total Dives:
-	TCODE	tBatteryV,			"Batteria: "			; Battery:
+	TCODE	tBatteryV,			"Batteria: "			; Battery : (space)
+	TCODE	tSensorC,			"Sensor  : "			; Sensor  : (space)
+	TCODE	tSensorD,			"Offset  : "			; Offset  : (space)
 	TCODE	tUptime,			"Uptime: "				; Uptime: 
 
  IFDEF _rx_functions
@@ -368,8 +414,8 @@
 
 
 ; Divemode screen
-	TCODE	tNDL,				"NDL"					; 3 chars max
-	TCODE	tTTS,				"TTS"					; 3 chars max
+	TCODE	tNDL,				"NDL"					; 3 chars
+	TCODE	tTTS,				"TTS"					; 3 chars
 	TCODE	tSlow,				"piano "				; slow - max 7 chars
 	TCODE	tVelMetric,			"m/min"
 	TCODE	tVelImperial,		"ft/m "
@@ -381,10 +427,6 @@
 	TCODE	tDepth,				"Prof."					; Depth (max 5 chars)
 	TCODE	tMaxDepth,			"Prof.Max"				; Max. Depth    - max 9 chars!
 	TCODE	tAvgDepth,			"Prof.Med."				; average Depth - max 9 chars!
-	TCODE	tTissuePresSat,		"Pres+Sat"				; 0 pressure and saturation  | ENUM group
- IFDEF _helium
-	TCODE	tTissueN2He,		"N2+He"					; 1 N2 + He pressure         |
- ENDIF
 	TCODE	tDivetime,			"Divetime"				; Divetime  (max 8 chars)
 	TCODE	tDiveTotalAvg,		"Media"
 	TCODE	tDiveStopwatch,		"Cronometro"
@@ -411,12 +453,14 @@
 	TCODE	tdil,				"Dil:"					; Diluent ppO2 Warning
 	TCODE	tmix,				"Mix:"					; Pre-Mix ppO2 Warning
 	TCODE	tGasNeedsWarn,		"Gas Neces"				;
-	TCODE	tGasNeedsAscent,	"Pres.Gas x Risalita"	;
 	TCODE	tCNSsurf,			"CNS Surf."				;
 	TCODE	tCNSfTTS,			"CNS fTTS"				;
 	TCODE	tCNSBO,				"CNS B/O"				;
 	TCODE	tCNSnow,			"CNS ora"				;
 	TCODE	tCNSeod,			"CNS finale"			;
+ IFDEF _cave_mode
+	TCODE	tCNScave,			"CNS Cave"				;
+ ENDIF
 	TCODE	tnoBOgas,			"-B/O-Gas-"				;
 	TCODE	tMicroBubbles,		"M.Bolle"				;
 	TCODE	tCNS,				"CNS: "					;
@@ -447,10 +491,15 @@
  ENDIF
 
  IFDEF _cave_mode
-	TCODE	tGasNeedsCaveMode,	"Gas Necess. Mod. Cave"	; title for gas needs custom view
-	TCODE	tDiveTurned,		"Dv.turned"				; dive is turned      (max. 9 char)	
+	TCODE	tGasNeedsCaveMode,	"Gas Necess.  -CAVE- "	; title for gas needs custom view (cave mode)		| need to be
+	TCODE	tGasNeedsAscent,	"Gas Necess. Risalita"	; title for gas needs custom view (open water mode)	| same length
 	TCODE	tCaveMode,			"Cave Mode"				; cave mode activated (max. 9 char)
 	TCODE	tCaveModeShutdown,	"X-Cave-X"				; cave mode shut down (max. 9 char)
+	TCODE	tCaveTTS,			"Cave TTS"				; cave mode total time to surface
+	TCODE	tCaveStops,			"total Stops"			; cave mode total time for stops
+	TCODE	tCaveRuntime,		"total RT"				; cave mode total runtime
+ ELSE
+	TCODE	tGasNeedsAscent,	"Pres.Gas x Risalita"	; title for gas needs custom view
  ENDIF
 
 
@@ -470,9 +519,17 @@
 ; Logbook
 	TCODE	tCNS2,				"CNS:"
 	TCODE	tAVG,				"Media:"
+	TCODE	tGF2,				"GF :"
+	TCODE	tSAT,				"Sat:"					; max  4 chars
+	TCODE	tDvSalinity2,		"Salinita':"			; max 11 chars
+	TCODE	tLastDeco,			"Ult.Tappa:"			; max 11 chars
+	TCODE	tNoProfileData,		"no data anymore..."	; max 21 chars
+	TCODE	tBeginOfDive,		"Begin:"				; max  8 chars
+	TCODE	tEndOfDive,			"End:"					; max  8 chars
+	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
+
+; other users
 	TCODE	tGF,				"GF:"
-	TCODE	tSAT,				"Sat:"					; 4 chars max
-
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -505,6 +562,7 @@
 
 
 ; Logbook Offset Menu
+	TCODE	tTotalDives,		"Tot Immersioni:"		; Total Dives
 	TCODE	tLogOffset,			"Devia Logbook"			; Logbook offset
 	TCODE	tLogOffsetValue,	"Devio    : "			; Offset
 	TCODE	tLogOffStepSize,	"Moltiplico:"			; Step Size
@@ -528,7 +586,6 @@
 
 
 ; Color Scheme menu
-	TCODE	tColorScheme,		"Schema colori"			; Colour scheme
 	TCODE	tColorSetDive,		"Immersione:"			; Divemode:
 	TCODE	tColorSetName0,		"Standard"				; Standard
 	TCODE	tColorSetName1,		"Rosso"					; Red
@@ -537,21 +594,17 @@
 
 
 ; Language selection
- IF _language_2!=none
-	TCODE	tLanguage,			"Lingua: "				; used in menu_tree
- ENDIF
-
  IF _language_1==en
-	TCODE	tLang1,				"Inglese"				; tLang1 is 1st language, enum context
+	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
  ELSE
  IF _language_1==de
-	TCODE	tLang1,				"Tedesco"
+	TCODE	tLang1,				"DE"
  ELSE
  IF _language_1==fr
-	TCODE	tLang1,				"Francese"
+	TCODE	tLang1,				"FR"
  ELSE
  IF _language_1==it
-	TCODE	tLang1,				"Italiano"
+	TCODE	tLang1,				"IT"
  ELSE
 	TCODE	tLang1,				""						; dummy target for options table
  ENDIF
@@ -560,16 +613,16 @@
  ENDIF
 
  IF _language_2==en
-	TCODE	tLang2,				"Inglese"				; tLang2 is 2nd language, enum context
+	TCODE	tLang2,				"EN"					; tLang2 is 2nd language, enum context
  ELSE
  IF _language_2==de
-	TCODE	tLang2,				"Tedesco"
+	TCODE	tLang2,				"DE"
  ELSE
  IF _language_2==fr
-	TCODE	tLang2,				"Francese"
+	TCODE	tLang2,				"FR"
  ELSE
  IF _language_2==it
-	TCODE	tLang2,				"Italiano"
+	TCODE	tLang2,				"IT"
  ENDIF
  ENDIF
  ENDIF
--- a/src/tft.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/tft.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File tft.asm                              combined next generation V3.03.7
+;   File tft.asm                              combined next generation V3.08.8
 ;
 ;   low-level Display Outputs
 ;
@@ -190,7 +190,7 @@
 TFT_ClearScreen_display3:
 	movlw	0x35				; vertical start address HIGH:LOW
 	rcall	TFT_CmdWrite
-	mullw   0
+	mullw	0
 	rcall	TFT_DataWrite_PROD
 
 	movlw	0x36				; vertical end address HIGH:LOW
@@ -227,10 +227,10 @@
 	global	TFT_DisplayOff
 TFT_DisplayOff:
 	bcf		lightsen_power  		; power-down light sensor
-	btfsc	screen_type3
-	bra		TFT_DisplayOff_display3	; screen needs special power-down sequence
-	clrf	CCP1CON					; stop PWM
-	bcf		PORTC,2					; pull PWM out to GND
+	btfsc	screen_type3			; screen type 3 ?
+	bra		TFT_DisplayOff_display3	; YES - screen needs special power-down sequence
+	clrf	CCP1CON					; NO  - stop PWM
+	bcf		PORTC,2					;     - pull PWM out to GND
 	clrf	PORTA
 	clrf	PORTH
 	RD_L							; LOW
@@ -1051,6 +1051,7 @@
 
 
 TFT_box_write_display2:
+	; setup left border
 	movlw	0x06
 	rcall	TFT_CmdWrite
 	movf	PRODH,W
@@ -1064,10 +1065,11 @@
 	addwf	PRODL,F
 	movf	win_width+1,W
 	addwfc	PRODH,F
-	decf	PRODL,F,A				; decrement result
+	decf	PRODL,F					; decrement result
 	btfss	STATUS,C
-	decf	PRODH,F,A
+	decf	PRODH,F
 
+	; setup right border
 	movlw	0x08
 	rcall	TFT_CmdWrite
 	movf	PRODH,W
@@ -1106,22 +1108,22 @@
 TFT_box_write_display3:
 	;---- Normal horizontal window ---------------------------------------
 	; Output 0x35 left,
-	;        0x36 right ==  left + width - 1.
+	;        0x36 right == left + width - 1.
 
 	Index_out 0x35					; window vertical start address
 	rcall	TFT_DataWrite_PROD		; output left
 	Index_out 0x21					; also the horizontal first pix coordinate
 	rcall	TFT_DataWrite_PROD		; output left
 
-	movf	win_width+0,W,ACCESS	; right = left + width - 1
+	movf	win_width+0,W			; right = left + width - 1
 	addwf	PRODL,F
-	movf	win_width+1,W,ACCESS
+	movf	win_width+1,W
 	addwfc	PRODH,F
-	decf	PRODL,F,A				; decrement result
+	decf	PRODL,F					; decrement result
 	btfss   STATUS,C
-	decf	PRODH,F,A
+	decf	PRODH,F
 
-	Index_out	0x36				; Write and the right border
+	Index_out	0x36				; write and the right border
 	rcall	TFT_DataWrite_PROD
 
 	;---- Normal vertical window -----------------------------------------
@@ -1152,7 +1154,7 @@
 	movff	win_top,tft_save_top		; backup everything
 	movff	win_height,tft_save_height
 	movff	win_leftx2,tft_save_left
-	movff	win_width,tft_save_width
+	movff	win_width+0,tft_save_width
 
 	;---- TOP line -----------------------------------------------------------
 	movlw	.1							; row ~ height = 1
@@ -1184,7 +1186,7 @@
 
 	;---- Restore everything -------------------------------------------------
 	movff	tft_save_left,win_leftx2
-	movff	tft_save_width,win_width
+	movff	tft_save_width,win_width+0
 	return
 
 ;=============================================================================
@@ -1253,6 +1255,7 @@
 	movff	win_color1,PRODH
 	movff	win_color2,PRODL
 	rcall	convert_for_display2
+	clrf	PRODH					; column counter
 TFT_box2_display2:					; loop height times
 	movff	win_height,PRODL
 TFT_box3_display2:					; loop width times
@@ -1328,8 +1331,8 @@
 
 	global	TFT_set_color
 TFT_set_color:
-	movwf	tft_temp1				; get 8 Bit RGB b'RRRGGGBB'
-	movwf	tft_temp2				; copy
+	movwf	tft_temp1				; get 8 bit RGB b'RRRGGGBB' into tft_temp1...
+	movwf	tft_temp2				; ... and tft_temp2
 
 	; mask bit 7,6,5,4,3,2
 	movlw	b'00000011'
@@ -1472,25 +1475,26 @@
 ; Dump screen contents to the UART
 ;
 	global	TFT_dump_screen_check
-	global	TFT_dump_screen
 TFT_dump_screen_check:
-    return
+	return
 	btfss	vusb_in					; USB (still) plugged in?
 	bcf		screen_dump_avail		; NO - disable screen dump function
-	call	rs232_get_byte			; try to read data from RS232
+
+	SERIAL_CC_RECEIVE WREG			; try to read a byte from RS232
 	btfsc	rs232_rx_timeout		; anything received?
-	return							; NO  - return
-	movlw	"l"						; YES - load coding for screen dump command
-	cpfseq	RCREG1					;       screen dump command received?
+	return							; NO  - done
+	xorlw	"l"						; YES - exclusive-or with coding of screen dump command
+	tstfsz	WREG					;     - screen dump command received?
 	return							;       NO  - return
+	;bra	TFT_dump_screen			;       YES - serve screen dump request
 
+	global	TFT_dump_screen
 TFT_dump_screen:
 	btfsc	screen_type2			; is this an OSTC with a screen of type 2?
-	return							; YES - not supported
+	return							; YES - not supported, abort
 	bsf		block_sensor_interrupt	; NO  - disable sensor interrupts
-	movlw	'l'						;     - prepare response
-	movwf	TXREG					;     - send    response
-	call	rs232_wait_tx			;     - wait for UART
+	SERIAL_LC_SEND 'l'				;     - send command acknowledge
+
 
 	;---- Send DISPLAY box command for the full screen window -------------------
 	Index_out 0x50					; window horizontal start address
@@ -1506,7 +1510,7 @@
 	rcall	dump_screen_pixel_reset
 dump_screen_1:
 	btg		LEDr					; LED activity toggle
-	; Dump even column
+	; dump even column
 	movlw	.240					; 240 lines, once
 	movwf	ds_line
 dump_screen_2:
@@ -1526,7 +1530,7 @@
 	bra		dump_screen_2
 	rcall	dump_screen_pixel_flush
 
-	; Dump odd column
+	; dump odd column
 	movlw	.240					; 240 lines, twice
 	movwf	ds_line
 dump_screen_3:
@@ -1541,7 +1545,7 @@
 	rcall	pixel_write_col320		; start address vertical (.0 - .319)
 
 	rcall	TFT_DataRead_PROD		; read pixel
-	rcall	dump_screen_pixel
+	rcall	dump_screen_pixel		; compress and send pixel
 
 	decfsz	ds_line,F
 	bra		dump_screen_3
@@ -1555,7 +1559,7 @@
 	bcf		block_sensor_interrupt	; re-enable sensor interrupts
 	clrf	RCREG1					; clear receive buffer
 	bcf		RCSTA1,CREN				; clear receiver status
-	bsf		RCSTA1,CREN
+	bsf		RCSTA1,CREN				; ...
 	bsf		screen_dump_avail		; enable screen dump function
 	return
 
@@ -1602,12 +1606,10 @@
 	decf	WREG					; save as 0..63
 	iorlw	b'10000000'				; mark as a color pixel
 
-	movwf	TXREG
-	call	rs232_wait_tx			; wait for UART
-	movff	ds_pixel+1,TXREG
-	call	rs232_wait_tx			; wait for UART
-	movff	ds_pixel+0,TXREG
-	call	rs232_wait_tx			; wait for UART
+	SERIAL_CC_SEND WREG				; send byte in WREG
+	SERIAL_CC_SEND ds_pixel+1		; send bytes in ds_pixel, high byte first
+	SERIAL_CC_SEND ds_pixel+0		;                         low  byte last
+
 	bra		dump_screen_pixel_1
 
 dump_screen_pixel_2:
@@ -1625,8 +1627,7 @@
 	decf	WREG					; save as 0..127
 
 dump_screen_pix_3:
-	movwf	TXREG
-	call	rs232_wait_tx
+	SERIAL_CC_SEND WREG				; send byte in WREG
 	bra		dump_screen_pixel_1		; more to dump ?
 
 dump_screen_pix_white:
@@ -1634,9 +1635,9 @@
 	cpfsgt	ds_count				; skip if count > 64
 	movf	ds_count,W				; W <- min(64,count)
 	subwf	ds_count,F				; ds_count <- ds_count-W
-	decf	WREG					; Save as 0..63
+	decf	WREG					; save as 0..63
 	iorlw	b'11000000'				; mark as a compressed white
-	bra		dump_screen_pix_3
+	bra		dump_screen_pix_3		; send pixel
 
 dump_screen_pixel_flush:
 	clrf	PRODH
--- a/src/tft_outputs.asm	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/tft_outputs.asm	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File tft_outputs.asm                      next combined generation V3.06.2
+;   File tft_outputs.asm                      next combined generation V3.08.7
 ;
 ;   high-level Display Outputs
 ;
@@ -29,6 +29,7 @@
 #include "calibrate.inc"
 #include "gaslist.inc"
 #include "rx_ops.inc"
+#include "logbook.inc"
 
 
 ;---- external Functions -----------------------------------------------------
@@ -40,10 +41,13 @@
 ;---- external Texts ---------------------------------------------------------
 
 	extern	tFirmware
+	extern	tFirmwareDate
 	extern	tHardware
 	extern	tSerial
 	extern	tTotalDives
 	extern	tBatteryV
+	extern	tSensorC
+	extern	tSensorD
 	extern	tUptime
 	extern	tPPO2MIN
 	extern	tPPO2Max
@@ -81,6 +85,12 @@
 	call	TFT_standard_color
 	lfsr	FSR2,buffer
 
+	; print an 16 bit integer as x.yy
+	;MOVII	int_O_profiling_overrun,mpr
+	;output_16dp .3
+	;STRCAT_PRINT ""
+	;return
+
 	; deco engine scheduling performance
 	MOVII	int_O_profiling_overrun,mpr		; runtime +/- versus target
 	btfss	mpr+1,7
@@ -320,7 +330,7 @@
 
 
 TFT_color_code_depth:
-	TSTOSS	opt_modwarning				; MOD warning switched on?
+	TSTOSS	opt_depth_warn				; depth warning switched on?
 	bra		TFT_color_code_depth_no_mod	; NO
 	btfsc	depth_limit_exceeded		; YES - deeper than depth limit?
 	bra		TFT_color_code_depth_warn	;       YES - set to warning color
@@ -447,10 +457,7 @@
 ;=============================================================================
 
 TFT_color_code_battery:					; color-code the battery display, with battery percent in lo
-	movlw	battery_warn_level_36+1		; get threshold for 3.6 Volt battery warning, incremented by 1
-	btfss	battery_is_36v				; actually a 3.6 Volt battery detected?
-	movlw	battery_warn_level_15+1		; NO - replace with 1.5 Volt battery warning, incremented by 1
-	cpfsgt	batt_percent				; is battery percent < threshold?
+	btfsc	battery_low_condition		; battery low condition detected?
 	bra		TFT_warning_color			; YES - set to warning color and return
 	bra		TFT_memo_color				; NO  - set to memo    color and return
 
@@ -569,12 +576,12 @@
 	movlw	d'4'
 	movwf	ignore_digits
 	bsf		ignore_digit5				; (flag will be cleared by output_16)
-	output_16dp	d'0'					; .1m in SMALL font
+	output_16dp d'0'					; .1m in SMALL font
 	STRCAT_PRINT ""						; display decimeters
 
 	; Max. Depth demo
 	WIN_MEDIUM .64,.54
-	bsf		ignore_digit4				; no 0.1m
+	bsf		ignore_digit4				; no 0.1 m
 	bsf		leftbind
 	MOVLI	.6349,mpr
 	output_16
@@ -588,7 +595,7 @@
 	bsf		ignore_digit5				; (flag will be cleared by output_16)
 	bsf		leftbind
 	MOVLI	.6349,mpr
-	output_16dp	d'0'
+	output_16dp d'0'
 	STRCAT_PRINT ""						; display decimeters
 	bcf		leftbind
 
@@ -699,7 +706,7 @@
 TFT_velocity_set_color:						; set color based on speed table or use static thresholds, with divA+0 = m/min
 	bsf		aux_flag						; for alternative layout: default is to show numerical VSI
 	; check if old/new ascend logic is used
-	TSTOSS	opt_vsitextv2					; 0=standard, 1=dynamic
+	TSTOSS	opt_vsitext						; 0=standard, 1=dynamic
 	bra		TFT_velocity_set_color_static	; static ascend rate limit
 
 	; point to speed table
@@ -757,7 +764,7 @@
 	movff	divA+0,WREG						; divA+0 = m/min
 	mullw	.100							; PROD   = mbar/min
 	MOVII	PRODL,mpr						; copy to hi:lo
-	call	convert_mbar_to_feet			; convert value in hi:lo from mbar to feet
+	call	convert_cm_to_feet				; convert value in hi:lo from [cm] to [feet]
 	tstfsz	hi								; > 255 ?
 	setf	lo								; YES - set lo to 255
 	movlw	'-'								; load coding for minus sign
@@ -990,7 +997,7 @@
 	MOVII	int_O_TTS_norm,mpr			;     - get the TTS
 	btfsc	hi,int_invalid_flag			;     - is the invalid flag set?
 	call	TFT_disabled_color			;       YES - use disabled color
-	bcf		hi,int_invalid_flag			;     - eventually clear the invalid flag
+	bcf		hi,int_invalid_flag			;     - clear the invalid flag if applicable
 	btfss	alt_layout_active			;     - in alternative layout?
 	bra		TFT_display_tts_999x		;       NO
 	MOVII	mpr, sub_a					;       YES - copy TTS to   sub_a
@@ -1036,7 +1043,11 @@
 TFT_show_ndl:
 	btfsc	dive_main_menu				; is the dive mode menu shown?
 	return								; YES - abort
-	movff	char_O_NDL_norm,lo			; NO  - get NDL time in normal plan
+	call	TFT_memo_color				; NO  - set color
+	movff	int_O_NDL_norm+1,lo			;     - get high byte of NDL time in normal plan
+	btfsc	lo,int_invalid_flag			;     - is the invalid flag set?
+	call	TFT_disabled_color			;       YES - switch to disabled color
+	movff	int_O_NDL_norm+0,lo			;     - get low byte of NDL time in normal plan
 	btfsc	deco_locked					;     - was the dive in deco?
 	bra		TFT_show_ndl_norm			;       YES - use normal layout
 	btfsc	alt_layout_active			;       NO  - alternative layout active?
@@ -1045,7 +1056,6 @@
 
 TFT_show_ndl_norm:						; set position
 	WIN_MEDIUM dm_ndl_value_col_norm,dm_ndl_value_row_norm
-	call	TFT_memo_color				; set color
 	output_8							; display 0...240
 TFT_show_ndl_exit_1:
 	STRCAT_PRINT "'"					; print minutes symbol
@@ -1058,14 +1068,12 @@
 										; clear potential remains from NDL normal and set position
 	WIN_BOX_BLACK dm_ndl_value_row_norm, dm_3rdrow_bot, dm_ndl_value_col_norm, dm_ndl_value_col_alt ; top, bottom, left, right
 	WIN_LARGE dm_ndl_value_col_alt, dm_ndl_value_row_alt
-	call	TFT_memo_color				; set color
 	output_99							; display 0...99
 	STRCAT_PRINT ""						; finalize output
 	bra		TFT_show_ndl_exit_2			; done
 
 TFT_show_ndl_alt_safety:
 	WIN_MEDIUM dm_ndl_value_col_norm,dm_ndl_value_row_norm
-	call	TFT_memo_color				; set color
 	PUTC	" "							; fill first digit position
 	output_99							; display 0...99
 	bra		TFT_show_ndl_exit_1			; print minutes symbol and done
@@ -1089,7 +1097,7 @@
 	bra		TFT_divemode_sign_show_alt_1;       YES - no need to clear area again
 	btfsc	bailout_mode				;       NO  - in bailout?
 	bra		TFT_divemode_sign_show_alt_1;             YES - no need to clear the area
-										;             NO  - eventually clear area from "bar" label and loop mode
+										;             NO  - clear area from "bar" label and loop mode if applicable
 	WIN_BOX_BLACK dm_active_dil_row, dm_3rdrow_bot, dm_active_sp_label_col, dm_sign_rgt_alt ; top, bottom, left, right
 TFT_divemode_sign_show_alt_1:
 	WIN_TOP  dm_sign_row_alt			;     - set row    position
@@ -1388,10 +1396,9 @@
  ENDIF
 
 
-	global	TFT_avr_stopwatch			; data for average depth and stopwatch
+	global	TFT_avr_stopwatch			; dive mode custom view: average depth and stopwatch
 TFT_avr_stopwatch:
 	call	TFT_memo_color
-	bsf		leftbind
 
  IFNDEF _min_depth_option
 
@@ -1404,27 +1411,25 @@
 	bra		TFT_avr_stopwatch_max		;       NO  - show max depth
 	;bra	TFT_avr_stopwatch_avg		;       YES - show avg depth
 TFT_avr_stopwatch_avg:
-	MOVII	pressure_rel_avg_total,mpr	; get total dive average depth into hi:lo
+	MOVII	pressure_rel_avg_total,mpr	; get total dive average pressure into hi:lo
 	bra		TFT_avr_stopwatch_2			; continue
 TFT_avr_stopwatch_1:
 	btfss	alt_layout_active			; YES - in alternative layout?
 	bra		TFT_avr_stopwatch_avg		;       NO  - show avg depth
 	;bra	TFT_avr_stopwatch_max		;       YES - show max depth
 TFT_avr_stopwatch_max:
-	MOVII	pressure_rel_max_cached,mpr	; get maximum depth into hi:lo
+	MOVII	pressure_rel_max_cached,mpr	; get maximum pressure into hi:lo
 	;bra	TFT_avr_stopwatch_2			; continue
 TFT_avr_stopwatch_2:
-	call	adjust_depth_with_salinity	; compute salinity setting into hi:lo [mbar]
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
 	TSTOSS	opt_units						 ; 0=m, 1=ft
 	bra		TFT_update_avr_stopwatch1_metric ; 0 - metric
 TFT_update_avr_stopwatch1_imp:				 ; 1 - imperial
-	call	convert_mbar_to_feet		; convert value in hi:lo from mbar to feet
-	output_16							; yxz
-	STRCAT	"  "						; wipe out remains from last output
-	clrf	WREG
-	movff	WREG,buffer+.3				; limit string length to 3 digits
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
+	output_16_3							; yxz
 	bra		TFT_update_avr_stopwatch2
 TFT_update_avr_stopwatch1_metric:
+	bsf		leftbind
 	bsf		ignore_digit5				; no cm (flag will be cleared by output_16)
 	output_16dp .3						; yxz.a
 	PUTC	" "							; wipe out remains from last output
@@ -1435,18 +1440,16 @@
 
 	; stopped average depth
 	WIN_MEDIUM dm_custom_avr_stop_column3,dm_custom_avr_stop_row
-	MOVII	pressure_rel_avg_trip,mpr	; get the resettable average depth
-	call	adjust_depth_with_salinity	; compute salinity setting into hi:lo [mbar]
+	MOVII	pressure_rel_avg_trip,mpr	; get the resettable average pressure
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
 	TSTOSS	opt_units						 ; 0=m, 1=ft
 	bra		TFT_update_avr_stopwatch2_metric ; 0 - metric
 TFT_update_avr_stopwatch2_imp:				 ; 1 - imperial
-	call	convert_mbar_to_feet		; convert value in hi:lo from mbar to feet
-	output_16							; yxz
-	STRCAT	"  "						; wipe out remains from last output
-	clrf	WREG
-	movff	WREG,buffer+.3				; limit string length to 3 digits/characters
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
+	output_16_3							; yxz
 	bra		TFT_update_avr_stopwatch3
 TFT_update_avr_stopwatch2_metric:
+	bsf		leftbind
 	bsf		ignore_digit5				; no cm (flag will be cleared by output_16)
 	output_16dp .3						; yxz.a
 	PUTC	" "							; wipe out remains from last output
@@ -1460,26 +1463,26 @@
 	; resettable maximum depth - needs ISR-safe copy!
 	WIN_MEDIUM dm_custom_avr_stop_column1,dm_custom_avr_stop_row		; column   0
 	call	TFT_memo_color
-	SMOVII	pressure_rel_max_trip,mpr
+	SMOVII	pressure_rel_max_trip,mpr	; get resettable maximum pressure
 	rcall	TFT_avr_stopwatch_helper
 
 	; resettable average depth
 	WIN_MEDIUM dm_custom_avr_stop_column2-.1,dm_custom_avr_stop_row		; column  54 -  1 =  53
 	call	TFT_attention_color
-	MOVII	pressure_rel_avg_trip,mpr
+	MOVII	pressure_rel_avg_trip,mpr	; get resettable average pressure
 	rcall	TFT_avr_stopwatch_helper
 
 	; resettable minimum depth - needs ISR safe copy!
 	WIN_MEDIUM dm_custom_avr_stop_column3-.12,dm_custom_avr_stop_row	; column 118 - 12 = 106
 	call	TFT_memo_color
-	SMOVII	pressure_rel_min_trip,mpr
+	SMOVII	pressure_rel_min_trip,mpr	; get resettable minimum pressure
 	rcall	TFT_avr_stopwatch_helper
 
 	; done
 	bra		TFT_display_exit_2
 
 TFT_avr_stopwatch_helper:
-	call	adjust_depth_with_salinity	; compute salinity setting into hi:lo [mbar]
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
 	output_16dp .3						; yxz.ab
 	PUTC	" "							; wipe out remains from last output
 	clrf	WREG
@@ -1515,7 +1518,7 @@
 	clrf	WREG
 	movff	WREG,buffer+.5				; limit to 5 chars
 	STRCAT_PRINT ""
-	bra		TFT_display_exit_2
+	bra		TFT_display_exit_2			; clear leftbind and return
 TFT_update_stopwatch_2:
 	movff	hi,lo						; transfer minutes (low  byte) to lo
 	movff	up,hi						; transfer minutes (high byte) to hi
@@ -1530,19 +1533,28 @@
 	WIN_TINY dm_custom_cns3_column1, dm_custom_cns3_title_row
 	STRCPY_TEXT_PRINT tCNSsurf
 	WIN_TINY dm_custom_cns3_column2, dm_custom_cns3_title_row
+
+ IFDEF _cave_mode
+	btfss	cave_mode					; cave mode switched on?
+	bra		TFT_CNS_mask_1				; NO
+	STRCPY_TEXT_PRINT tCNScave			; YES - print cave TTS label
+	bra		TFT_CNS_mask_3				;     - continue with 3rd column
+ ENDIF
+
+TFT_CNS_mask_1:
 	btfsc	FLAG_oc_mode				; in OC mode?
-	bra		TFT_CNS_mask_1				; YES - print fTTS label
+	bra		TFT_CNS_mask_2				; YES - print fTTS label
 	btfsc	bailout_mode				; in bailout?
-	bra		TFT_CNS_mask_1				; YES - print fTTS label (label will be printed, but a fTTS will actually not be calculated)
-	TSTOSS	opt_calc_asc_gasvolume		; bailout volume calculation requested?
-	bra		TFT_CNS_mask_1				; NO  - print fTTS label
+	bra		TFT_CNS_mask_2				; YES - print fTTS label (label will be printed, but a fTTS will actually not be calculated)
+	TSTOSS	opt_calc_gasvolume			; bailout volume calculation requested?
+	bra		TFT_CNS_mask_2				; NO  - print fTTS label
 	STRCPY_TEXT_PRINT tCNSBO			; YES - print bailout label
-	bra		TFT_CNS_mask_2
-TFT_CNS_mask_1:							; OC or bailout
+	bra		TFT_CNS_mask_3				;     - continue with 3rd column
+TFT_CNS_mask_2:							; OC or bailout
 	STRCPY_TEXT_PRINT tCNSfTTS			; print fTTS label
-TFT_CNS_mask_2:
+TFT_CNS_mask_3:
 	WIN_TINY dm_custom_cns3_column3, dm_custom_cns3_title_row
-	STRCPY_TEXT_PRINT tCNSnow
+	STRCPY_TEXT_PRINT tCNSnow			; print CNS now label
 	bra		TFT_display_exit_2
 
 
@@ -1559,7 +1571,7 @@
 	WIN_STD dm_custom_cns3_column2+.2,dm_custom_cns3_row
 	btfsc	bailout_mode				; in bailout?
 	bra		TFT_CNS_3					; YES - show "---"
-	TSTOSS	opt_calc_asc_gasvolume		; NO  - bailout volume calculation requested?
+	TSTOSS	opt_calc_gasvolume			; NO  - bailout volume calculation requested?
 	bra		TFT_CNS_1					;       NO  - continue checking fTTS extra time
 	btfss	FLAG_oc_mode				;       YES - in OC mode?
 	bra		TFT_CNS_2					;             NO - show CNS%
@@ -1573,6 +1585,16 @@
 	STRCAT_PRINT "% "
 	bra		TFT_CNS_4
 TFT_CNS_3:
+ IFDEF _cave_mode
+	btfss	cave_mode					; cave mode switched on?
+	bra		TFT_CNS_3a					; NO  - show dashes
+	btfsc	backtrack_entire_full		; YES - cave mode shut down due to storage fully used up?
+	bra		TFT_CNS_3a					;       YES - show dashes
+	btfss	dive_turned					;       NO  - dive turned?
+	bra		TFT_CNS_2					;             NO  - show cave CNS
+	;bra	TFT_CNS_3a					;             YES - show dashes
+ ENDIF
+TFT_CNS_3a:
 	call	TFT_memo_color
 	STRCPY_PRINT "---  "
 TFT_CNS_4:
@@ -1586,6 +1608,181 @@
 	bcf		leftbind
 	goto	TFT_standard_color			; and return...
 
+;=============================================================================
+
+ IFDEF _cave_mode
+
+	global	TFT_cave_tts_mask				; mask for cave mode data
+TFT_cave_tts_mask:
+	call	TFT_divemask_color
+	WIN_TINY dm_custom_cave_title_column1,dm_custom_cave_title_row
+	STRCPY_TEXT_PRINT tCaveStops
+	WIN_TINY dm_custom_cave_title_column2,dm_custom_cave_title_row
+	STRCPY_TEXT_PRINT tCaveTTS
+	WIN_TINY dm_custom_cave_title_column3,dm_custom_cave_title_row
+	STRCPY_TEXT_PRINT tCaveRuntime
+	bra		TFT_display_exit_2
+
+
+	global	TFT_cave_tts				; dive mode custom view: cave TTS
+TFT_cave_tts:
+	; total time of all stops
+	WIN_MEDIUM dm_custom_cave_data_column1,dm_custom_cave_data_row		; column 8
+	call	TFT_memo_color				; set default color
+	btfss	cave_mode					; cave mode switched on?
+	bra		TFT_cave_1b					; NO  - print dashes
+	MOVII	int_O_TST_norm,mpr			; YES - get normal plan total stops time
+	btfss	mpr+1,int_not_yet_computed	;     - not yet computed?
+	bra		TFT_cave_1a					;       NO  - continue
+	call	TFT_disabled_color			;       YES - switch to disabled color
+	bra		TFT_cave_1b					;           - print dashes
+TFT_cave_1a:
+	btfsc	mpr+1,int_invalid_flag		; stops time invalid?
+	call	TFT_disabled_color			; YES - switch to disabled color
+	bcf		mpr+1,int_invalid_flag		; clear invalid flag if applicable
+	movf	mpr+0,W						; copy     low  byte of stops time to WREG
+	iorwf	mpr+1,W						; ior with high byte of stops time
+	bz		TFT_cave_1b					; print dashes if stops time is zero
+	output_16_3							; output as xxx
+	STRCAT_PRINT "'"					; print minutes symbol
+	bra		TFT_cave_2					; continue
+TFT_cave_1b:
+	STRCAT_PRINT ",-,-,-,"				; print 3 dashes (',' produces a half-width space)
+TFT_cave_2:
+	; cave TTS
+	WIN_MEDIUM dm_custom_cave_data_column2,dm_custom_cave_data_row		; column 60
+	call	TFT_memo_color				; set default color
+	btfsS	cave_mode					; cave mode switched on?
+	bra		TFT_cave_2b					; NO  - print dashes
+	MOVII	int_O_TTS_norm,mpr			; YES - get normal plan total time to surface
+	btfss	mpr+1,int_not_yet_computed	;     - not yet computed?
+	bra		TFT_cave_2a					;       NO  - continue
+	call	TFT_disabled_color			;       YES - switch to disabled color
+	bra		TFT_cave_2b					;           - print dashes
+TFT_cave_2a:
+	btfsc	mpr+1,int_invalid_flag		; TTS invalid?
+	call	TFT_disabled_color			; YES - switch to disabled color
+	bcf		mpr+1,int_invalid_flag		; clear invalid flag if applicable
+	output_16_3							; output as xxx
+	STRCAT_PRINT "'"					; print minutes symbol
+	bra		TFT_cave_3					; continue
+TFT_cave_2b:
+	STRCAT_PRINT ",-,-,-,"				; print 3 dashes (',' produces a half-width space)
+TFT_cave_3:
+	; estimated total runtime
+	WIN_MEDIUM dm_custom_cave_data_column3,dm_custom_cave_data_row		; column 114
+	;									; keep color from cave TTS
+	btfss	cave_mode					; cave mode switched on?
+	bra		TFT_cave_3b					; NO  - print dashes
+	SMOVII	counted_divetime_mins,mpr	; YES - ISR safe copy of counted dive time to MPR
+	movff	int_O_TTS_norm+0,WREG		;     - get TTS, low  byte, into WREG
+	addwf	mpr+0,F						;     - add TTS, low  byte, to dive time in MPR
+	movff	int_O_TTS_norm+1,WREG		;     - get TTS, high byte, into WREG
+	btfsc	WREG,int_not_yet_computed	;     - not yet computed?
+	bra		TFT_cave_3b					;       YES - print dashes
+	bcf		WREG,int_invalid_flag		;       NO  - clear invalid flag if applicable
+	addwfc	mpr+1,F						;           - add TTS, high byte, to dive time in MPR
+	output_16_3							;           - output as xxx
+	STRCAT_PRINT "'"					;           - print minutes symbol
+	bra		TFT_display_exit_2			;           - done
+TFT_cave_3b:
+	STRCAT_PRINT ",-,-,-,"				; print 3 dashes (',' produces a half-width space)
+	bra		TFT_display_exit_2			; done
+
+
+	global	TFT_cave_waypoints
+TFT_cave_waypoints:
+	; title row
+	WIN_TINY .70,dm_custom_cave_title_row;adjust column to display position of current waypoint
+	call	TFT_divemask_color			; select color
+	btfss	cave_mode					; cave mode switched on?
+	bra		TFT_cave_waypoints_3		; NO  - do not show any marker (any more)
+	btfss	dive_turned					; YES - dive turned?
+	bra		TFT_cave_waypoints_1		;       NO  - print marker on right side
+	bra		TFT_cave_waypoints_2		;       YES - print marker in the middle
+TFT_cave_waypoints_1:
+	movlw	.12							; start with 12 space chars
+	call	TFT_fillup_with_spaces		; fill buffer with space chars
+TFT_cave_waypoints_2:
+	STRCAT	"<====="					; print marker symbol
+TFT_cave_waypoints_3:
+	movlw	.18							; set overall number of chars
+	call	TFT_fillup_with_spaces		; fill buffer with space chars
+	STRCAT_PRINT ""						; finalize output
+	; data row
+	btfsc	cave_mode					; cave mode switched on?
+	bra		TFT_cave_waypoints_4		; YES - show graphics
+	WIN_STD .0,dm_custom_cave_data_row	; NO  - show "Cave Mode off" text
+	call	TFT_attention_color			;     - select attention color
+	STRCPY	"  "						;     - print 2 space chars
+	STRCAT_TEXT tCaveMode				;     - print "Cave Mode"
+	PUTC	" "							;     - print a space char
+	STRCAT_TEXT tOff					;     - print "off"
+	movlw	.17							;     - set max number of chars
+	call	TFT_fillup_with_spaces		;     - fill up FSR2 with spaces (total string length in #WREG)
+	STRCAT_PRINT ""						;     - finalize output
+	return								;     - done
+TFT_cave_waypoints_4:
+	WIN_MEDIUM .0,dm_custom_cave_data_row; start in column 0
+	call	TFT_memo_color				; select default color
+	tstfsz	DM_flags_cavereq			; any pending cave mode requests?
+	call	TFT_disabled_color			; YES - switch to disabled color
+	; 1st section: previous waypoint number or beginning line
+	movlw	.1							; load a one into WREG
+	cpfsgt	backtrack_waypoint_num		; current waypoint number > 1 ?
+	bra		TFT_cave_waypoints_5		; NO  - print line segment only
+	STRCAT	",-,"						; YES - print one dash
+	movff	backtrack_waypoint_num,lo	;     - copy current waypoint number to lo
+	decf	lo,F						;     - create previous waypoint number
+	output_99							;     - print previous waypoint number in two digit format
+	STRCAT	","							;     - print a half-space
+	bra		TFT_cave_waypoints_6		;     - continue with next section
+TFT_cave_waypoints_5:
+	STRCAT	",-,-----"					; print line segment
+TFT_cave_waypoints_6:
+	; 2nd section: solid line
+	STRCAT	"---"						; print a solid line
+	; 3rd section: current waypoint number, turn point symbol or line segment
+	tstfsz	backtrack_waypoint_num		; does a current waypoint exist?
+	bra		TFT_cave_waypoints_8		; YES - print its number or the turn point symbol
+	btfss	dive_turned					; NO  - dive turned?
+	bra		TFT_cave_waypoints_7		;       NO  - print a separated  line segment
+	STRCAT	"------"					;       YES - print a continuous line
+	bra		TFT_cave_waypoints_10		;           - continue with next section
+TFT_cave_waypoints_7:
+	STRCAT	",----,"					; print a separated line segment
+	bra		TFT_cave_waypoints_10		; continue with next section
+TFT_cave_waypoints_8:
+	STRCAT	","							; print a half-width space
+	movff	backtrack_waypoint_num,lo	; copy current waypoint number to lo
+	movf	backtrack_waypoint_turn,W	; copy turn point number to WREG
+	cpfseq	lo							; current waypoint = turn point ?
+	bra		TFT_cave_waypoints_9		; NO  - show waypoint number
+	STRCAT_PRINT "--|,     "			; YES - print end-of-line symbol, clear remaining output and finalize output
+	return								;     - done
+TFT_cave_waypoints_9:
+	movff	backtrack_waypoint_num,lo	; copy  current waypoint number to lo
+	output_99 							; print current waypoint number in two digit format
+	STRCAT	","							; print a half-space
+TFT_cave_waypoints_10:
+	; 4th section: solid line
+	STRCAT	"---"						; print a solid line
+	; 5th section: next waypoint number or end of line symbol
+	incf	backtrack_waypoint_num,W	; load WREG with next waypoint number
+	cpfseq	backtrack_waypoint_turn		; next waypoint number = turn point number ?
+	btfsc	waypoint_reached_last		; NO  - is the current waypoint the last waypoint?
+	bra		TFT_cave_waypoints_11		; YES / YES - print end-of-line symbol
+	STRCAT	","							;       NO  - print a half-space
+	incf	backtrack_waypoint_num,W	;           - (re)load WREG with next waypoint number
+	movwf	lo							;       NO  - copy  next waypoint number to lo
+	output_99 							;           - print next waypoint number in two digit format
+	STRCAT_PRINT ""						;           - finalize output
+	return								;           - done
+TFT_cave_waypoints_11:
+	STRCAT_PRINT "---|,"				; print end-of-line symbol and finalize output
+	return								; done
+
+ ENDIF
 
 ;=============================================================================
 
@@ -1899,7 +2096,15 @@
 	SMOVII	sensor3_mv,mpr				; in 0.1mV steps
 	output_16dp .4						; xxx.y mV
 	STRCAT_PRINT "mV  "
-	bra		TFT_display_exit_3
+	TSTOSS	opt_s8_mode					; =0: analog, =1: digital RS232
+	bra		TFT_display_exit_3			; analog - done
+	; also imprint HUD battery voltage
+	WIN_TINY .20,.209					; digital
+	STRCPY	"HUD Batt: "				; print label
+	SMOVII	hud_battery_mv,mpr			; get HUD battery voltage
+	output_16dp .2						; print as -x.yyy
+	STRCAT_PRINT "V "					; finalize output
+	bra		TFT_display_exit_3			; done
 
  ENDIF	; _external_sensor
 
@@ -1940,9 +2145,9 @@
 	movff	rtc_latched_secs,lo
 	output_99x
 	STRCAT	"  "
-	movff	rtc_latched_day,lo
+	movff	rtc_latched_year, lo
 	movff	rtc_latched_month,hi
-	movff	rtc_latched_year,up
+	movff	rtc_latched_day,  up
 	call	TFT_convert_date			; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2
 	STRCAT_PRINT " "
 	return
@@ -1955,7 +2160,7 @@
 	call	TFT_standard_color
 	WIN_SMALL surf_gaslist_column,surf_gaslist_row
 	STRCAT_PRINT "ZH-L16"
-	movff	char_I_deco_model,WREG
+	movff	char_I_model,WREG
 	iorwf	WREG
 	bnz		TFT_surface_decosettings1
 	; Display ZH-L16 sat/desat model
@@ -1982,7 +2187,7 @@
 	STRCAT_PRINT ""
 TFT_surface_decosettings2:				; fTTS
 	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
-	STRCPY_TEXT tFTTSMenu
+	STRCPY_TEXT tFTTSSurf
 	movff	char_I_extra_time,lo
 	bsf		leftbind
 	output_8
@@ -1995,7 +2200,7 @@
 	STRCAT_TEXT_PRINT tMeters
 	; Salinity
 	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
-	STRCPY_TEXT tDvSalinity
+	STRCPY_TEXT tDvSalinitySurf
 	movff	opt_salinity,lo
 	output_8
 	bcf		leftbind
@@ -2003,11 +2208,11 @@
 	return
 
 
-	global	TFT_divetimeout				; show timeout counter
+	global	TFT_divetimeout
 TFT_divetimeout:
-	call	TFT_set_message_window		; set the row and column for the current message
+	call	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_memo_color
 	STRCPY	0x94						; "End of dive" symbol
 	movff	opt_diveTimeout,WREG		; in [min]
@@ -2033,49 +2238,75 @@
 
 	global	TFT_show_ftts
 TFT_show_ftts:
-	call	TFT_set_message_window		; sets the row and column for the current warning
+	call	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO  - done
-	btfsc	FLAG_oc_mode				; YES - in OC mode?
-	bra		TFT_display_ftts_1			;       YES - print fTTS label
-	TSTOSS	opt_calc_asc_gasvolume		;       NO  - bailout volume calculation requested?
-	bra		TFT_display_ftts_1			;             NO  - print fTTS label
-	STRCPY	"B/O"						;             YES - print bailout label
-	bra		TFT_display_ftts_2
-TFT_display_ftts_1:						; OC or CCR/pSCR but no bailout volume calculation
+	return								; NO  - skip message in this cycle
+	bsf		leftbind					; print with alignment to the left
+ IFDEF _cave_mode
+	btfss	cave_mode					; cave mode switched on?
+	bra		TFT_display_ftts_2			; NO  - classic open water TTS
+	btfss	dive_turned					; YES - dive turned?
+	bra		TFT_display_ftts_1			;       NO  - cTTS from current position
+	STRCPY	"WP"						;       YES - print waypoint mark
+	movf	backtrack_waypoint_num,W	;           - copy current waypoint number to WREG
+	cpfseq	backtrack_waypoint_turn		;           - current waypoint = turn point ?
+	bra		TFT_display_ftts_0			;             NO - print waypoint number
+	STRCAT	"-| "						;             YES - print turn point symbol
+	bra		TFT_display_ftts_5			;                 - continue with TTS
+TFT_display_ftts_0:
+	movwf	lo							; copy current waypoint number to lo
+	output_99							; print waypoint number
+	PUTC	" "							; append a space char
+	bra		TFT_display_ftts_5			; continue with TTS
+TFT_display_ftts_1:
+	STRCPY	"cTTS "						; print cave TTS label followed by a space
+	bra		TFT_display_ftts_5			; continue with TTS
+ ENDIF	; _cave_mode
+TFT_display_ftts_2:
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		TFT_display_ftts_3			; YES - print fTTS label
+	TSTOSS	opt_calc_gasvolume			; NO  - bailout volume calculation requested?
+	bra		TFT_display_ftts_3			;       NO  - print fTTS label
+	STRCPY	"B/O"						;       YES - print bailout label
+	bra		TFT_display_ftts_4			;           - continue
+TFT_display_ftts_3:						; OC or CCR/pSCR but no bailout volume calculation
 	STRCPY	"@+"						; print fTTS label
-TFT_display_ftts_2:
-	movff	char_I_extra_time,lo		; get fTTS delay time
-	bsf		leftbind					; print with alignment to the left
+TFT_display_ftts_4:
+	movff	char_I_extra_time,lo		; get   fTTS delay time
 	output_8							; print fTTS delay time
 	PUTC	":"							; ":"
+TFT_display_ftts_5:
 	MOVII	int_O_TTS_alt,mpr			; get alternative TTS
 	call	TFT_memo_color				; set memo color
 	btfss	hi,int_invalid_flag			; is the invalid flag set?
-	bra		TFT_display_ftts_3			; NO  - keep memo color
+	bra		TFT_display_ftts_6			; NO  - keep memo color
 	bcf		hi,int_invalid_flag			; YES - clear flag
 	call	TFT_disabled_color			;     - switch to disabled color
-TFT_display_ftts_3:
-	btfsc	hi,int_not_yet_computed		; is the not-computed-yet flag set?
-	bra		TFT_display_ftts_4			; YES - show dashes
-	movf	lo,W
-	iorwf	hi,W						; extra_ascenttime = 0 ?
-	bz		TFT_display_ftts_5			; YES - show "NDL"
-	movff	char_O_deco_info,up			; get deco info vector
-	btfsc	up,deco_zone				; fTTS <= TTS ?
-	call	TFT_advice_color			; YES - set to advice color (green)
+TFT_display_ftts_6:
+	btfsc	hi,int_not_yet_computed		; is the not-yet-computed flag set?
+	bra		TFT_display_ftts_8			; YES - show dashes
+ IFDEF _cave_mode
+	btfsc	cave_mode					; cave mode switched on?
+	bra		TFT_display_ftts_7			; YES - take shortcut
+ ENDIF
+	movff	int_O_TST_alt+1,WREG		; get high byte of the alternative total stops time
+	btfsc	WREG,int_is_zero			; total stops time = zero ?
+	bra		TFT_display_ftts_9			; YES - show "NDL"
+	btfsc	WREG,deco_zone				; NO  - fTTS <= TTS ?
+	call	TFT_advice_color			;       YES - set to advice color (green)
+TFT_display_ftts_7:
 	output_16							; print ascent time
 	PUTC	"'"							; print minutes symbol
-	bra		TFT_display_ftts_6
-TFT_display_ftts_4:
-	STRCAT	"---"						; "---" for not computed
-	bra		TFT_display_ftts_6
-TFT_display_ftts_5:
-	STRCAT_TEXT tNDL					; "NDL"
-TFT_display_ftts_6:
+	bra		TFT_display_ftts_10			; continue
+TFT_display_ftts_8:
+	STRCAT	"---"						; print "---" for not computed
+	bra		TFT_display_ftts_10			; continue
+TFT_display_ftts_9:
+	STRCAT_TEXT tNDL					; print "NDL"
+TFT_display_ftts_10:
 	movlw	dm_warning_length			; dive mode string length
 	call	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
+	STRCAT_PRINT ""						; finalize output
 	bcf		leftbind					; clear left alignment
 	goto	TFT_standard_color			; ...and return
 
@@ -2115,7 +2346,7 @@
 	movlw	index_compass_dm				; index of compass custom view
 	cpfseq	active_customview				; compass shown in custom view?
 	bra		TFT_temp_common					; NO  - proceed with temperature
-	bra		TFT_update_stopwatch			; YES - show resettable dive time instead of temperature
+	goto	TFT_update_stopwatch			; YES - show resettable dive time instead of temperature
 TFT_temp_common:
 	SMOVII	temperature_cur,mpr				; ISR-safe 2 byte copy of current temperature to hi:lo
 	TSTOSC	opt_units						; 0=°C, 1=°F
@@ -2130,7 +2361,7 @@
 	cpfslt	lo
 	bra		TFT_temp_common_1				; > 10.0°C, skip here
 	bsf		leftbind
-	output_16dp	d'4'						; x.y°C
+	output_16dp d'4'						; x.y°C
 	bcf		leftbind
 	bra		TFT_temp_common_3				; done
 TFT_temp_common_1:
@@ -2496,8 +2727,8 @@
 
 	global	TFT_show_depth
 TFT_show_depth:
-	MOVII	pressure_rel_cur_cached,mpr	; copy relative pressure to hi:lo
-	call	adjust_depth_with_salinity	; compute salinity setting into hi:lo [mbar]
+	MOVII	pressure_rel_cur_cached,mpr	; copy relative pressure to MPR
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
 	call	TFT_color_code_depth		; set warning / attention flags and color-code the output
 	rcall	TFT_depth_blink				; control animation (blinking)
 	rcall	TFT_depth_position_m_ft		; set output position
@@ -2512,19 +2743,15 @@
 	call	cmpU16						; compare (sub_a - sub_b)
 	btfss	neg_flag					; depth shallower than 30 cm ?
 	bra		depth_0_feet				; YES - print a zero directly
-	call	convert_mbar_to_feet		; NO  - convert value in hi:lo from mbar to feet
-	bsf		leftbind					;     - print left-aligned
-	output_16							;     - feet in large or huge font
-	bcf		leftbind					;     - reset alignment
-	movlw	.3							;     - limit to three chars
-	call	TFT_fillup_with_spaces		;     - fill up FSR2 with spaces
+	call	convert_cm_to_feet			; NO  - convert value in hi:lo from [cm] to [feet]
+	output_16_3							;     - feet in large or huge font
 	STRCAT_PRINT ""						;     - finalize output
 TFT_depth_imperial_1:
 	bcf		win_invert					;      - reset invert flag
 	bra		TFT_depth_exit			;      - show target depth if in simulator mode and return
 
 depth_0_feet:
-	STRCAT_PRINT "0  "					; print a zero directly
+	STRCAT_PRINT "  0"					; print a zero directly
 	bra		TFT_depth_imperial_1		; continue with common part
 
 TFT_depth_metric:
@@ -2591,10 +2818,10 @@
 	bcf		leftbind					; reset alignment
 	STRCAT_PRINT ""						; finalize output
 	bcf		win_invert					; reset invert flag
-	bra		TFT_depth_exit			; show target depth if in simulator mode and return
+	bra		TFT_depth_exit				; show target depth if in simulator mode and return
 
 TFT_depth_blink:
-	TSTOSS	opt_modwarning				; 0=standard, 1=blink
+	TSTOSS	opt_depth_warn				; 0=standard, 1=blink
 	return								; standard, done
 	btfsc	depth_warn_att_last			; was there a warning or attention on the depth in the previous cycle?
 	bra		TFT_depth_blink_prev		; YES
@@ -2858,7 +3085,7 @@
 	output_8
 	PUTC	":"
 	MOVII	batt_voltage,mpr
-	output_16dp .2
+	output_16dp .2					; print as -x.yyy
 	bcf		leftbind
 	PUTC	'V'
 	movff	buffer+8,buffer+6
@@ -2904,74 +3131,82 @@
 	return							; done
 
 ;=============================================================================
-
+; input: lo  year
+;        hi  month
+;        up  day
+;
+; output format by option opt_dateformat:
+;         0: MMDDYY
+;         1: DDMMYY
+;         2: YYMMDD
+;
 	global	TFT_convert_date
-TFT_convert_date:					; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2
-	movff	opt_dateformat,WREG		; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD
-	movwf	EEDATA					; used as temp here
-	tstfsz	EEDATA
-	bra		TFT_convert_date_1		; opt_dateformat is 1 or 2
-									; opt_dateformat is 0
-									; use MMDDYY
-	movff	lo,hy					; incoming: lo = day,   hi = month
-	movff	hi,lo					; swap
-	movff	hy,hi					; now:      lo = month, hi = day
-	bra		TFT_convert_date_common
-
+TFT_convert_date:					; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in output buffer
+	movff	opt_dateformat,EEDATA	; get format (EEDATA used as temp here)
+	tstfsz	EEDATA					; shall use format 0 ?
+	bra		TFT_convert_date_1		; NO  - check for format 1 or 2
+									; YES - use format 0: MMDDYY
+	movff	lo,hy					;     - backup year  to hy
+	movff	hi,lo					;     - copy   month to lo
+	movff	up,hi					;     - copy   day   to hi
+	movff	hy,up					;     - copy   year  to up
+	bra		TFT_convert_date_common	;     - start output
 TFT_convert_date_1:
-	decfsz	EEDATA,F
-	bra		TFT_convert_date_2		; opt_dateformat is 2
-									; opt_dateformat is 1
-									; use DDMMYY
+	decfsz	EEDATA,F				; shall use format 1 ?
+	bra		TFT_convert_date_common	; NO  - use format 2: YYMMDD - can print directly
+									; YES - use format 1: DDMMYY
+	movff	lo,hy					;     - backup year to hy
+	movff	up,lo					;     - copy day    to lo
+	movff	hy,up					;     - copy year   to up
+
 TFT_convert_date_common:
-	bsf		leftbind
-	output_99x						; with lo = month or day   or year
-	PUTC	'.'
-	movff	hi,lo					; now  lo = day   or month or month
-	output_99x
-	PUTC	'.'
-	movff	up,lo					; now  lo = year  or year  or day
-	output_99x
-	bcf		leftbind
-	return
-
-TFT_convert_date_2:
-									; opt_dateformat is 2
-									; use YYMMDD
-	movff	lo,hy					; incoming: lo = day,  up = year
-	movff	up,lo					; swap
-	movff	hy,up					; now     : lo = year, up = day
-	bra		TFT_convert_date_common
+	bsf		leftbind				; start left-alignment
+	output_99x						; print lo
+	PUTC	'.'						; print spacing dot
+	movff	hi,lo					; print hi
+	output_99x						; ...
+	PUTC	'.'						; print spacing dot
+	movff	up,lo					; print up
+	output_99x						; ...
+	bcf		leftbind				; end left-alignment
+	return							; done
+
 
 ;=============================================================================
-
+; show date by month & day
+;
+; input: lo  year   (not used here)
+;        hi  month
+;        up  day
+;
+; output format by option opt_dateformat:
+;         0: MMDD(YY)
+;         1: DDMM(YY)
+;         2: (YY)MMDD
+;
 	global	TFT_convert_date_short
-TFT_convert_date_short:				; convert into "DD/MM" or "MM/DD" or "MM/DD" in postinc2
-	movff	opt_dateformat,WREG		; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD
-	movwf	EEDATA					; used as temp here
-	tstfsz	EEDATA
-	bra		TFT_convert_date_short_1
-									; opt_dateformat is 0
-									; use MMDD(YY)
-TFT_convert_date_short_0:
-	movff	lo,hy					; incoming: lo = day,   hi = month
-	movff	hi,lo					; swap
-	movff	hy,hi					; now:      lo = month, hi = day
-	bra		TFT_convert_date_short_common
-
-TFT_convert_date_short_1:
-	decfsz	EEDATA,F
-	bra		TFT_convert_date_short_0; opt_dateformat is 2 -> use (YY)MMDD
-									; opt_dateformat is 1
-									; use DDMM(YY)
-TFT_convert_date_short_common:
-	bsf		leftbind
-	output_99x						; with lo = month or day
-	PUTC	'.'
-	movff	hi,lo					; now  lo = day   or month
-	output_99x
-	bcf		leftbind
-	return
+TFT_convert_date_short:				; convert into "DD/MM" or "MM/DD" or "MM/DD" into output buffer
+	movff	opt_dateformat,EEDATA	; get format (EEDATA used as temp here)
+	tstfsz	EEDATA					; shall use format 0 ?
+	bra		TFT_convert_date_short2	; NO  - check for format 1 or 2
+TFT_convert_date_short1:			; YES - use format 0: MMDD
+	movff	hi,lo					;     - copy month to lo
+	movff	up,hi					;     - copy day   to hi
+	bra		TFT_convert_date_short3 ;     - start output
+TFT_convert_date_short2:
+	decfsz	EEDATA,F				; format 1 ?
+	bra		TFT_convert_date_short1	; NO  - use format 2: MMDD (here its like format 0)
+									; YES - use format 1: DDMM
+	movff	up,lo					;     - copy day to lo,
+									;     - month is already in hi
+TFT_convert_date_short3:
+	bsf		leftbind				; start left-alignment
+	output_99x						; print lo
+	PUTC	'.'						; print spacing dot
+	movff	hi,lo					; print hi
+	output_99x						; ...
+	bcf		leftbind				; end left-alignment
+	return							; done
 
 ;=============================================================================
 
@@ -2980,9 +3215,9 @@
 	WIN_SMALL	surf_date_column,surf_date_row
 	call	TFT_standard_color
 	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
-	movff	rtc_latched_day,lo
+	movff	rtc_latched_year, lo
 	movff	rtc_latched_month,hi
-	movff	rtc_latched_year,up
+	movff	rtc_latched_day,  up
 	call	TFT_convert_date			; convert into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2
 	STRCAT_PRINT ""
 	return
@@ -3009,27 +3244,27 @@
 	;bra	TFT_avg_depth_current		; YES - show avg depth
 
 TFT_avg_depth_current:
-	MOVII	pressure_rel_avg_total,mpr	; YES - get total dive average depth
+	MOVII	pressure_rel_avg_total,mpr	; YES - get total dive average pressure
 	bra		TFT_max_depth_common		;     - continue with common part
 
 TFT_max_depth_apnoe:
 	btfss	apnoe_at_surface			; apnoe mode, at the surface?
 	bra		TFT_max_depth_current		; NO  - show max depth of current dive
-	MOVII	apnoe_max_pressure,mpr		; YES - show max depth of all dives so far
+	MOVII	apnoe_max_pressure,mpr		; YES - get max pressure of all dives so far
 	bra		TFT_max_depth_common		;     - continue with common part
 
 TFT_max_depth_current:
-	MOVII	pressure_rel_max_cached,mpr	; get the "normal" max depth in mbar = cm
+	MOVII	pressure_rel_max_cached,mpr	; get the "normal" max pressure
 	;bra	TFT_max_depth_common		; continue with common part
 
 TFT_max_depth_common:
-	call	adjust_depth_with_salinity	; compute salinity setting into hi:lo [mbar]
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
 	TSTOSS	opt_units					; 0=m or 1=ft ?
 	bra		TFT_max_depth_metric		; 0 - use metric   version
 	;bra	TFT_max_depth_imperial		; 1 - use imperial version
 
 TFT_max_depth_imperial:
-	call	convert_mbar_to_feet		; convert value in hi:lo from mbar to feet
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
 	call	TFT_memo_color				; set output color
 	output_16_3							; print depth
 	bra		TFT_max_depth_finish		; finish output
@@ -3120,7 +3355,7 @@
 	rcall	TFT_show_gauge_max_depth							; show max depth
 	call	TFT_memo_color										; set color
 	WIN_MEDIUM dm_gauge_avg_depth_col, dm_gauge_avg_depth_row	; set position for avg depth
-	MOVII	pressure_rel_avg_total,mpr							; get average depth into hi:lo
+	MOVII	pressure_rel_avg_total,mpr							; get average pressure into hi:lo
 	bra		TFT_show_gauge_depth								; show avg depth and return
 
 
@@ -3140,13 +3375,15 @@
 	WIN_MEDIUM	dm_apnoe_last_max_depth_column, dm_apnoe_last_max_depth_row
 	call	TFT_memo_color
 TFT_show_gauge_max_depth:
-	MOVII	pressure_rel_max_cached,mpr		; get max depth into hi:lo
+	MOVII	pressure_rel_max_cached,mpr		; get max pressure into hi:lo
+	;bra	TFT_show_gauge_depth			; show max depth and return
+
 TFT_show_gauge_depth:
-	call	adjust_depth_with_salinity		; compute salinity setting into hi:lo [mbar]
+	call	convert_pres_to_depth			; convert pressure in [mbar] to depth in [cm]
 	TSTOSS	opt_units						; 0=m, 1=ft
 	bra		TFT_display_apnoe_last_m_metric ; 0 - metric
 TFT_display_apnoe_last_max_imp:				; 1 - imperial
-	call	convert_mbar_to_feet			; convert value in hi:lo from mbar to feet
+	call	convert_cm_to_feet				; convert value in hi:lo from [cm] to [feet]
 	output_16
 	bra		TFT_max_depth_finish			; finish output
 TFT_display_apnoe_last_m_metric:
@@ -3296,7 +3533,7 @@
 ; check if firmware is within expiry period, will return aux_flag set if not
 
 check_expiry:						; check if it is time for a firmware update
-	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
+	SMOVSS	rtc_year,rtc_latched_year; ISR-safe 6 byte copy of date and time
 	movff	rtc_latched_day,lo		; get current day
 	movff	rtc_latched_month,hi	; get current month
 	movff	rtc_latched_year,up		; get current year
@@ -3342,7 +3579,7 @@
 	STRCAT	"DBG."					; show short version
 	goto	TFT_warning_color		; set color
  ELSE
-	movlw	softwareversion_beta	; =0: release, =1: beta 1, =2: beta 2, ...
+	movlw	fw_version_beta	; =0: release, =1: beta 1, =2: beta 2, ...
 	movwf	lo						; copy to lo
 	tstfsz	lo						; release version?
 	bra		TFT_cat_beta_1			; NO  - must be beta version then
@@ -3432,29 +3669,26 @@
 
 	global	info_menu_total_dives
 info_menu_total_dives:
-	lfsr	FSR1,tTotalDives
-	call	strcat_text
+	lfsr	FSR1,tTotalDives				; locate text
+	call	strcat_text						; print  text
 TFT_cat_total_dives:
-	read_int_eeprom	.2
-	movff	EEDATA,lo
-	read_int_eeprom	.3
-	movff	EEDATA,hi
-	bsf		leftbind
-	output_16
-	bcf		leftbind
-	return
-	
+	call	eeprom_total_dives_read			; read total number of dives
+	bsf		leftbind						; print left-aligned
+	output_16								; print number of total dives
+	bcf		leftbind						; quit  left-aligned
+	return									; done
+
 ;-----------------------------------------------------------------------------
 ; append firmware version to current string, including color-coding
 
 	global	TFT_cat_firmware
 TFT_cat_firmware:
-	movlw	softwareversion_x
+	movlw	fw_version_major
 	movwf	lo
 	bsf		leftbind
 	output_8								; print major in 1 or 2 digit format
 	PUTC	'.'
-	movlw	softwareversion_y
+	movlw	fw_version_minor
 	movwf	lo
 	output_99x								; print minor in two digit format
 	bcf		leftbind
@@ -3465,17 +3699,30 @@
 	goto	TFT_attention_color				;     - print in attention color (and return)
 
 ;-----------------------------------------------------------------------------
-; For the Information menu: firmware version
+; For the Information menu: firmware version and creation date
 
 	global	info_menu_firmware
 info_menu_firmware:
-	lfsr	FSR1,tFirmware
-	call	strcat_text
-	rcall	TFT_cat_firmware
-	PUTC	" "
-	rcall	TFT_cat_beta_rel
-	STRCAT_PRINT ""
-	return
+	lfsr	FSR1,tFirmware					; select label text
+	call	strcat_text						; print label
+	rcall	TFT_cat_firmware				; print firmware version
+	PUTC	" "								; print a dot
+	rcall	TFT_cat_beta_rel				; print beta/release
+	STRCAT_PRINT ""							; finalize output
+	return									; done
+
+	global	info_menu_fw_cration_date
+info_menu_fw_cration_date:
+	lfsr	FSR1,tFirmwareDate				; select label text
+	call	strcat_text						; print label
+	movlw	firmware_creation_year			; get firmware creation year
+	movwf	lo								; copy to lo
+	movlw	firmware_creation_month			; get firmware creation month
+	movwf	hi								; copy to hi
+	movlw	firmware_creation_day			; get firmware creation day
+	movwf	up								; copy to up
+	call	TFT_convert_date				; converts into "DD/MM/YY" or "MM/DD/YY" or "YY/MM/DD" in postinc2
+	return									; done
 
 ;-----------------------------------------------------------------------------
 ; For the Information menu: firmware version of the RX processor
@@ -3505,38 +3752,31 @@
 	global	info_menu_serial
 	global	TFT_cat_serial
 info_menu_serial:
-	lfsr	FSR1,tSerial
-	call	strcat_text
+	lfsr	FSR1,tSerial				; locate text
+	call	strcat_text					; print  text
 TFT_cat_serial:
-	clrf	EEADRH
-	clrf	EEADR					; get serial number LOW
-	call	read_eeprom				; read byte
-	movff	EEDATA,lo
-	incf	EEADR,F					; get serial number HIGH
-	call	read_eeprom				; read byte
-	movff	EEDATA,hi
-
-	bsf		leftbind
-	output_16
-	bcf		leftbind
-	return
+	call	eeprom_serial_number_read	; read OSTC serial number
+	bsf		leftbind					; start left-alignment
+	output_16							; print serial number
+	bcf		leftbind					; end   left-alignment
+	return								; done
 
 ;-----------------------------------------------------------------------------
 ; For the Information menu: hardware / software configuration
 
 	global	info_menu_config
 info_menu_config:
-	lfsr	FSR1,tHardware
-	call	strcat_text
-	call	I2C_init_compass		; start compass
-	movf	HW_descriptor,W			; copy hardware descriptor to WREG
-	output_hex						; print as hex
-	PUTC	"-"						; print a separator
-	movf	HW_variants,W			; copy hardware variants   to WREG
-	output_hex						; print as hex
-	PUTC	"-"						; print a separator
-	movlw	SW_CONF					; get software configuration
-	output_hex						; print as hex
+	lfsr	FSR1,tHardware				; locate text
+	call	strcat_text					; print  text
+	call	I2C_init_compass			; start compass
+	movf	HW_descriptor,W				; copy hardware descriptor to WREG
+	output_hex							; print as hex
+	PUTC	"-"							; print a separator
+	movf	HW_variants,W				; copy hardware variants   to WREG
+	output_hex							; print as hex
+	PUTC	"-"							; print a separator
+	movlw	SW_CONF						; get software configuration
+	output_hex							; print as hex
 	return
 
 
@@ -3549,14 +3789,60 @@
 	call	strcat_text
 	MOVII	batt_voltage,mpr
 	bsf		leftbind
-	output_16dp .2				; x.xxx
+	output_16dp .2						; print as -x.yyy
 	STRCAT	"V(T"
-	movff	battery_type,lo		; =0:1.5V, =1:3.6V Saft, =2:LiIon 3.7V/0.8Ah, =3:LiIon 3.7V/3.1Ah, =4: LiIon 3.7V/2.3Ah
+	movff	battery_type,lo				; =0:1.5V, =1:3.6V Saft, =2:LiIon 3.7V/0.8Ah, =3:LiIon 3.7V/3.1Ah, =4: LiIon 3.7V/2.3Ah
 	output_8
 	bcf		leftbind
 	PUTC	")"
 	return
 
+
+;-----------------------------------------------------------------------------
+; For the Information menu: sensor C1 and C5 values
+
+	global	info_menu_sensor_calib
+info_menu_sensor_calib:
+	lfsr	FSR1,tSensorC				; locate label
+	call	strcat_text					; print  label
+	movff	C1+1,WREG					; get   C1, high byte
+	output_hex							; print C1, high byte
+	movff	C1+0,WREG					; get   C1, low  byte
+	output_hex							; print C1, low  byte
+	PUTC	"-"							; print a separator
+	movff	C5+1,WREG					; get   C5, high byte
+	output_hex							; print C5, high byte
+	movff	C5+0,WREG					; get   C5, low  byte
+	output_hex							; print C5, low  byte
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; For the Information menu: sensor depth correction
+
+	global	info_menu_sensor_offset
+info_menu_sensor_offset:
+	lfsr	FSR1,tSensorD				; locate label
+	call	strcat_text					; print  label
+	movff	opt_pressure_adjust,WREG	; get pressure sensor offset
+	btfsc	WREG,7						; value negative?
+	bra		info_menu_sensor_offset_1	; YES
+	PUTC	"+"							; NO  - print plus sign
+	bra		info_menu_sensor_offset_2	;     - continue with common part
+info_menu_sensor_offset_1:
+	PUTC	"-"							; print a minus sign
+	negf	WREG						; negate WREG
+info_menu_sensor_offset_2:
+	PUTC	" "							; print a space
+	bsf		leftbind					; start left-bind printing
+	output_8							; print value
+	bcf		leftbind					; end left-bind printing
+	PUTC	" "							; print a space
+	lfsr	FSR1,tMBAR					; locate unit
+	call	strcat_text					; print  unit
+	return								; done
+
+
 ;-----------------------------------------------------------------------------
 ; For the Information menu: uptime
 
@@ -3564,23 +3850,23 @@
 info_menu_uptime:
 	lfsr	FSR1,tUptime
 	call	strcat_text
-	SMOVFF	uptime,xC		; ISR-safe copy of uptime:4 to xC:4
+	SMOVQQ	uptime,xC					; ISR-safe copy of uptime:4 to xC:4
 
 info_menu_uptime_com:
-	MOVLI	.3600,xB		; one hour = 3600s
-	call	div32x16		; xC:4 = xC:4 / xB:2 with xA as remainder -> xC+1:xC+0 holds full hours
+	MOVLI	.3600,xB					; one hour = 3600s
+	call	div32x16					; xC:4 = xC:4 / xB:2 with xA as remainder -> xC+1:xC+0 holds full hours
 	MOVII	xC,xA
-	MOVLI	.24,xB			; one day = 24 hours
-	call	div16x16		; xC:2 = xA:2 / xB:2 with xA as remainder -> xC+1:xC+0 holds full days, xA holds full hours
-	MOVII	xC,mpr			; copy full days into hi:lo
+	MOVLI	.24,xB						; one day = 24 hours
+	call	div16x16					; xC:2 = xA:2 / xB:2 with xA as remainder -> xC+1:xC+0 holds full days, xA holds full hours
+	MOVII	xC,mpr						; copy full days into hi:lo
 	bsf		leftbind
 	output_16
 	PUTC	"d"
-	movff	xA+0,lo			; full hours
+	movff	xA+0,lo						; full hours
 	output_8
 	PUTC	"h"
 	bcf		leftbind
-	return					; done
+	return								; done
 
 ;-----------------------------------------------------------------------------
 
@@ -3730,9 +4016,9 @@
 
 	global	TFT_desaturation_time
 TFT_desaturation_time:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_memo_color
 	STRCPY	"Desat:"
 	MOVII	int_O_desaturation_time,mpr
@@ -3740,10 +4026,10 @@
 	movf	lo,W						; swap hi and lo
 	movff	hi,lo						; ...
 	movwf	hi							; ...
-	output_99x							; hours
-	PUTC	':'
-	movff	hi,lo						; minutes
-	output_99x
+	output_99x							; print hours
+	PUTC	':'							; print ":"
+	movff	hi,lo						; print minutes...
+	output_99x							; ... in two digits, leading zero
 	movlw	surf_warning_length			; only use surface string length
 	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
 	STRCAT_PRINT ""
@@ -3752,9 +4038,9 @@
 
 	global	TFT_nofly_time
 TFT_nofly_time:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_memo_color
 	movff	char_I_altitude_wait,WREG
 	tstfsz	WREG
@@ -3782,9 +4068,9 @@
 
 	global	TFT_warning_agf
 TFT_warning_agf:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_attention_color
 	STRCPY_TEXT tDiveaGF_active			; "aGF!"
 	movlw	dm_warning_length			; dive mode string length
@@ -3795,9 +4081,9 @@
 
 	global	TFT_warning_fallback
 TFT_warning_fallback:					; show fallback warning
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_warning_color
 	STRCPY_TEXT tDiveFallback			; "Fallback!"
 	movlw	dm_warning_length			; dive mode string length
@@ -3811,9 +4097,9 @@
 
 	global	TFT_advice_switch
 TFT_advice_switch:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_advice_color
 	STRCPY_TEXT tswap					; "Swap Tank"
 	movlw	dm_warning_length			; dive mode string length
@@ -3823,9 +4109,9 @@
 
 	global	TFT_attention_transmitter
 TFT_attention_transmitter:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_attention_color
 	STRCPY_TEXT tTransmitter			; "P.Transm."
 	movlw	dm_warning_length			; dive mode string length
@@ -3842,9 +4128,9 @@
 	call	TFT_warning_color			; use warnings color
 	;bra	TFT_common_pres_reading		; continue with common code
 TFT_common_pres_reading:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO - done
+	return								; NO - skip message in this cycle
 	STRCPY_TEXT tPressure				; "Tank Pres"
 	movlw	dm_warning_length			; dive mode string length
 	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
@@ -3853,9 +4139,9 @@
 
 	global	TFT_attention_sac
 TFT_attention_sac:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	MOVII	int_O_SAC_measured,mpr		; copy measured SAC rate to hi:lo
 	call	TFT_color_code_tank_pres_sac; color-code the output
 	STRCPY_TEXT tSAC					; "SAC", needs to be exactly 3 chars long
@@ -3874,9 +4160,9 @@
 
 	global	TFT_info_deco
 TFT_info_deco							; show info when decompression obligation is steady or decreasing
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO  - return
+	return								; NO  - skip message in this cycle
 	call	TFT_advice_color			; YES - actually it is a memo, but we break the rules here and display in advice color (green)
 	STRCPY_TEXT tDecoInfo				;     - write "Deco Zone"
 	movlw	dm_warning_length			;     - select dive mode string length
@@ -3890,49 +4176,52 @@
 
 	global	TFT_info_cave_mode
 TFT_info_cave_mode:
-	rcall	TFT_set_message_window		; sets the row and column for the current warning
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO  - return
+	return								; NO  - skip message in this cycle
 	call	TFT_memo_color				; YES - set memo color
-	STRCPY_TEXT tCaveMode				;       write "Cave Mode"
-	movlw	dm_warning_length			;       select dive mode string length
-	rcall	TFT_fillup_with_spaces		;       fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""						;       print buffer
-	bra		TFT_warn_att_info_exit		; and return...
-
-	global	TFT_info_dive_turned
-TFT_info_dive_turned:
-	rcall	TFT_set_message_window		; sets the row and column for the current warning
+	bsf		win_invert					;     - print in inverse
+	STRCPY_TEXT tCaveMode				;     - write "Cave Mode"
+	movlw	dm_warning_length			;     - select dive mode string length
+	rcall	TFT_fillup_with_spaces		;     - fill up FSR2 with spaces (total string length in #WREG)
+	STRCAT_PRINT ""						;     - print buffer
+	bcf		win_invert					;     - end inverse printing
+	bra		TFT_warn_att_info_exit		;     - and return...
+
+
+	global	TFT_cave_shutdown_attention
+TFT_cave_shutdown_attention:
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO  - return
-	call	TFT_attention_color			; YES - set attention color
-	STRCPY_TEXT tDiveTurned				;       write "Dv.turned"
-	movlw	dm_warning_length			;       select dive mode string length
-	rcall	TFT_fillup_with_spaces		;       fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""						;       print buffer
-	bra		TFT_warn_att_info_exit		; and return...
-
-	global	TFT_warn_cave_shutdown
-TFT_warn_cave_shutdown:
-	rcall	TFT_set_message_window		; sets the row and column for the current warning
+	return								; NO  - skip message in this cycle
+	call	TFT_attention_color			; YES - set warning color
+	bra		TFT_cave_shutdown_common	;     - continue with common part
+
+
+	global	TFT_cave_shutdown_warning
+TFT_cave_shutdown_warning:
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO  - return
+	return								; NO  - skip message in this cycle
 	call	TFT_warning_color			; YES - set warning color
-	STRCPY_TEXT tCaveModeShutdown		;       write "X-Cave-X"
-	movlw	dm_warning_length			;       select dive mode string length
-	rcall	TFT_fillup_with_spaces		;       fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""						;       print buffer
+	;bra	TFT_cave_shutdown_common	;     - continue with common part
+
+TFT_cave_shutdown_common:
+	STRCPY_TEXT tCaveModeShutdown		; write "X-Cave-X"
+	movlw	dm_warning_length			; select dive mode string length
+	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
+	STRCAT_PRINT ""						; print buffer
 	bra		TFT_warn_att_info_exit		; and return...
 
  ENDIF	; _cave_mode
 
 ;=============================================================================
 
-	global	TFT_warning_sat
-TFT_warning_sat							; Saturation
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	global	TFT_warning_saturation
+TFT_warning_saturation
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	MOVII	int_O_lead_supersat,mpr		; bank-safe copy of leading tissue's supersaturation
 	call	TFT_color_code_gf			; color-code output
 ;	STRCPY	"GF:  "						; the two spaces are on purpose to align the output with other warnings' outputs
@@ -3954,12 +4243,12 @@
 
 	global	TFT_warning_mbubbles
 TFT_warning_mbubbles:
-	rcall	TFT_set_message_window		; sets the row and column for the current warning
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_attention_color			; set attention color as default
 	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
-	btfsc	WREG,mbubble_warning		; are we in the microbubbles zone right now?
+	btfsc	WREG,mbubble_warning		; are we in the micro bubbles zone right now?
 	call	TFT_warning_color			; YES - reconfigure to warning color
 	STRCPY_TEXT tMicroBubbles
 	movlw	dm_warning_length			; dive mode string length
@@ -3972,9 +4261,9 @@
 
 	global	TFT_warning_outside
 TFT_warning_outside:
-	rcall	TFT_set_message_window		; sets the row and column for the current warning
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_attention_color
 	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
 	btfsc	WREG,outside_warning		; are we outside the ZH-L16 model right now?
@@ -3990,9 +4279,9 @@
 
 	global	TFT_warning_depth
 TFT_warning_depth:
-	rcall	TFT_set_message_window		; sets the row and column for the current warning
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_warning_color
 	STRCPY_TEXT tMaxDepth				; "max.Depth"
 	movlw	dm_warning_length			; dive mode string length
@@ -4001,19 +4290,19 @@
 	bra		TFT_warn_att_info_exit		; and return...
 
 
-	global	TFT_warning_gas_needs_warn
-TFT_warning_gas_needs_warn:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	global	TFT_warning_gas_needs
+TFT_warning_gas_needs:
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO  - skip message in this cycle
 	call	TFT_warning_color			; YES - set warning color
 	bra		TFT_warning_gas_needs_com	;     - continue with common part
 
-	global	TFT_warning_gas_needs_att
-TFT_warning_gas_needs_att:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	global	TFT_attention_gas_needs
+TFT_attention_gas_needs:
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO  - skip message in this cycle
 	call	TFT_attention_color			; YES - set attention color
 	;bra	TFT_warning_gas_needs_com	;     - continue with common part
 
@@ -4030,9 +4319,9 @@
 
 	global	TFT_warning_IBCD
 TFT_warning_IBCD:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_attention_color			; select attention color as default
 	STRCPY_TEXT tIBCD					; "IBCD N2He"
 	movlw	dm_warning_length			; dive mode string length
@@ -4046,9 +4335,9 @@
 
 	global	TFT_warning_no_BO_gas
 TFT_warning_no_BO_gas:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_warning_color			; select warning color
 	STRCPY_TEXT tnoBOgas				; print "-B/O-Gas-"
 	movlw	dm_warning_length			; dive mode string length
@@ -4059,9 +4348,9 @@
 
 	global	TFT_advice_gas_change
 TFT_advice_gas_change:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_advice_color			; set advice color
 	STRCPY_TEXT tgaschange				; "Change?"
 	movlw	dm_warning_length			; dive mode string length
@@ -4074,10 +4363,10 @@
  IFDEF _external_sensor
 
 	global	TFT_warning_sensor_disagree
-TFT_warning_sensor_disagree:			; show sensor disagree warning
-	rcall	TFT_set_message_window		; set the row and column for the current message
+TFT_warning_sensor_disagree:
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_warning_color
 	STRCPY_TEXT tSensorDisagree			; "Sensors<>"
 	movlw	dm_warning_length			; dive mode string length
@@ -4089,7 +4378,7 @@
 
 ;=============================================================================
 
-TFT_set_message_window:						; set the row and column for the current message
+TFT_set_message_window:						; sets the row and column for the current message
 	; ignore warning (now)?
 	decf	message_counter,W				; load (message counter - 1) into WREG
 	bcf		STATUS,C						; clear carry bit
@@ -4138,9 +4427,9 @@
 
 	global	TFT_msg_batt_percent_divemode
 TFT_msg_batt_percent_divemode:
-	rcall	TFT_set_message_window		; set the row and column for the current message
+	rcall	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	movff	batt_percent,lo				; get battery percent
 	call	TFT_color_code_battery		; color-code battery percent
 	STRCPY	"Batt:"
@@ -4220,20 +4509,20 @@
 	global	TFT_ceiling_GF_tissue		; data for ceiling, current GF and tissues
 TFT_ceiling_GF_tissue:
 	WIN_MEDIUM dm_custom_ceiling_column,dm_custom_ceiling_row
-	MOVII	int_O_ceiling,mpr
-	call	TFT_color_code_ceiling		; color-code the output
-	call	adjust_depth_with_salinity	; compute salinity setting into hi:lo [mbar]
-	bsf		leftbind
+	MOVII	int_O_ceiling,mpr			; get ceiling in [mbar] relative pressure
+	call	TFT_color_code_ceiling		; color-code the output (also strips off flags)
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
 	TSTOSS	opt_units					; 0=m, 1=ft
 	bra		TFT_ceiling_tissue_cGF_m
-	call	convert_mbar_to_feet		; convert value in hi:lo from mbar to feet
-	output_16							; yxz
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
+	output_16_3							; yxz
 	bra		TFT_ceiling_tissue_cGF0
 TFT_ceiling_tissue_cGF_m:
+	bsf		leftbind
 	bsf		ignore_digit5				; no cm (flag will be cleared by output_16)
 	output_16dp .3						; yxz.a
+	bcf		leftbind
 TFT_ceiling_tissue_cGF0:
-	bcf		leftbind
 	STRCAT_PRINT " "
 	; Show tissue diagram
 	call	TFT_dive_tissues			; show tissue pressure diagram
@@ -4289,7 +4578,7 @@
 	WIN_SMALL dm_custom_battery_column, dm_custom_battery_volt_row
 	MOVII	batt_voltage,mpr
 	bsf		leftbind
-	output_16dp .2
+	output_16dp .2						; print as -x.yyy
 	PUTC	'V'
 	movff	buffer+5,buffer+4
 	movlw	0x00
@@ -4352,8 +4641,8 @@
 
 ;=============================================================================
 
-	global	TFT_gas_needs_ascent_mask	; mask for gas needs ascent
-TFT_gas_needs_ascent_mask:
+	global	TFT_gas_needs_mask			; mask for gas needs ascent
+TFT_gas_needs_mask:
 	WIN_TINY dm_custom_gas_column_title, dm_custom_gas_mask_row
 	call	TFT_divemask_color
  IFDEF _cave_mode
@@ -4370,12 +4659,17 @@
  ELSE
 	STRCPY_TEXT tGasNeedsAscent			; "Gas Needs Ascent"
  ENDIF
+	movff	char_O_deco_info,WREG		; get the deco info vector
+	btfss	WREG,gas_needs_fTTS			; are the gas needs calculated for fTTS?
+	bra		TFT_gas_needs_mask_ascent_3	; NO  - continue
+	STRCAT	" fTTS"						; YES - append fTTS marking
+TFT_gas_needs_mask_ascent_3:
 	STRCAT_PRINT " (bar)"				; " (bar)"
 	bra		TFT_custview_exit1			; and return...
 
 
-	global	TFT_gas_needs_ascent		; data for gas needs ascent
-TFT_gas_needs_ascent:					; LIMITATION: there is only space for 4 gases on the screen - if 5 gases have a pres_need > 0, then only the first 4 will be shown!
+	global	TFT_gas_needs				; data for gas needs ascent
+TFT_gas_needs:							; LIMITATION: there is only space for 4 gases on the screen - if 5 gases have a pres_need > 0, then only the first 4 will be shown!
  IFDEF _cave_mode
 	movff	char_O_deco_info,WREG		; get deco info vector
 	btfss	WREG,gas_needs_cave			; are the gas needs calculated for cave mode?
@@ -4388,7 +4682,7 @@
 	bra		TFT_gas_needs_ascent_3		;       YES - mask still valid
 	;bra	TFT_gas_needs_ascent_2		;       NO  - redraw mask
 TFT_gas_needs_ascent_2:
-	rcall	TFT_gas_needs_ascent_mask	; redraw mask
+	rcall	TFT_gas_needs_mask			; redraw mask
 TFT_gas_needs_ascent_3:
  ENDIF
 	clrf	up							; initialize gas index (0-4)
@@ -4400,7 +4694,7 @@
 	rcall	TFT_gas_needs_helper
 	WIN_SMALL dm_custom_gas_column2+.5,dm_custom_gas_row2
 	rcall	TFT_gas_needs_helper
-	return
+	bra		TFT_custview_exit2			; and return...
 
 TFT_gas_needs_helper:
 	call	TFT_memo_color
@@ -4447,7 +4741,7 @@
 	output_16_3							; limit to 999 and display only (0-999)
 	STRCAT_PRINT " "					; adds a space to overwrite any potential remains of earlier outputs
 	incf	up,F						; increment to next gas
-	bra		TFT_custview_exit2			; and return...
+	return								; done
 
 
 	global	TFT_show_ppo2_mask			; helper function for several custom views
@@ -4507,12 +4801,12 @@
 	; Show END/EAD
 	WIN_SMALL	dm_custom_ead_column, dm_custom_ead_row
 	STRCPY_TEXT tEAD					; EAD:
-	movff	char_O_EAD,lo
-	rcall	TFT_end_ead_common			; print "lo m" (or ft) and limit to 8 chars
+	MOVII	int_O_EAD_pres,mpr			; copy EAD in [mbar] to MPR
+	rcall	TFT_end_ead_common			; convert to depth, print and limit to 8 chars
 	WIN_SMALL dm_custom_end_column, dm_custom_end_row
 	STRCPY_TEXT tEND					; END:
-	movff	char_O_END,lo
-	rcall	TFT_end_ead_common			; print "lo m" (or ft) and limit to 8 chars
+	MOVII	int_O_END_pres,mpr			; copy END in [mbar] to MPR
+	rcall	TFT_end_ead_common			; convert to depth, print and limit to 8 chars
  IFDEF _helium
 	; Show Gas Density
 	WIN_MEDIUM	dm_custom_cns_column-.5, dm_custom_cns_row
@@ -4521,7 +4815,7 @@
 	bsf		leftbind					; print left-aligned
 	movlw	.2							; suppress first and second digit
 	movwf	ignore_digits				; ...
-	output_16dp .2						; print as --x.yy
+	output_16dp .2						; print as -x.yyy
 	bcf		leftbind					; back to normal alignment
 	STRCAT_PRINT	""					; finalize output
  ELSE
@@ -4537,29 +4831,27 @@
 TFT_custview_exit2:
 	goto	TFT_standard_color			; and return...
 
-TFT_end_ead_common:						; print "lo m" (or ft) and limit to 8 chars
-	bsf		leftbind
+TFT_end_ead_common:
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
 	TSTOSS	opt_units					; 0=Meter, 1=Feet
-	bra		TFT_end_ead_common_metric
+	bra		TFT_end_ead_common_metric	; 0: meter
+	;bra	TFT_end_ead_common_imperial	; 1: feet
+
 TFT_end_ead_common_imperial:
-	movf	lo,W						; with lo in m
-	mullw	.100						; PRODL:PRODH = mbar/min
-	MOVII	PRODL,mpr
-	call	convert_mbar_to_feet		; convert value in hi:lo from mbar to feet
-	output_16_3
-	STRCAT_TEXT tFeets
-	clrf	WREG
-	movff	WREG,buffer+.8				; limit string length to 8
+	call	convert_cm_to_feet			; convert depth in [cm] to depth in [feet]
+	output_16_3							; print as xyz
 	bra		TFT_end_ead_common_exit
+
 TFT_end_ead_common_metric:
-	output_8
-	STRCAT_TEXT tMeters
+	bsf		ignore_digit4				; no decimals (flag will be cleared by output_16)
+	output_16dp .3						; print as yxz.--
+	movlw	'm'							; hard-coded unit
+	movff	WREG,buffer+.7				; place the unit onto the decimal point
+	;bra	TFT_end_ead_common_exit
+
 TFT_end_ead_common_exit:
-	bcf		leftbind
-	movlw	.8
-	call	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	return
+	STRCAT_PRINT ""						; finalize output
+	return								; done
 
 ;=============================================================================
 
@@ -4632,8 +4924,9 @@
 	STRCAT_PRINT "m "						;
 	bra		TFT_surface_lastdive_2			;
 TFT_surface_lastdive_1:
-	SMOVFF	surface_interval_secs,xC		; ISR-safe copy of surface_interval_secs:4 to xC:4
+	SMOVQQ	surface_interval_secs,xC		; ISR-safe copy of surface_interval_secs:4 to xC:4
 	call	info_menu_uptime_com			; use part of info_menu_uptime to convert and display in days and hours
+	STRCAT_PRINT ""							; finalize output
 TFT_surface_lastdive_2:
 	WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.1)
 	MOVII	lastdive_duration,mpr			; get duration of last dive, minutes
@@ -4645,8 +4938,7 @@
 	rcall	TFT_surface_common				; finalize output
 TFT_surface_lastdive_3:
 	WIN_SMALL	surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.2)
-	MOVII	lastdive_maxdepth,mpr
-	call	adjust_depth_with_salinity		; compute (current) salinity setting into hi:lo [mbar]
+	MOVII	lastdive_maxdepth,mpr			; get max depth of last dive
 	bsf		leftbind						; print without leading spaces
 	TSTOSS	opt_units						; 0=Meter, 1=Feet
 	bra		TFT_surface_lastdive_metric		; 0 - metric
@@ -4656,24 +4948,26 @@
 	rcall	TFT_surface_metric				; print depth in meters
 TFT_surface_lastdive_4:
 	WIN_SMALL	surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.3)
-	MOVII	lastdive_avgdepth,mpr
-	call	adjust_depth_with_salinity		; compute (current) salinity setting into hi:lo [mbar]
+	MOVII	lastdive_avgdepth,mpr			; get avg depth of last dive
 	bsf		leftbind						; print without leading spaces
 	TSTOSS	opt_units						; 0=Meter, 1=Feet
 	bra		TFT_surface_metric				; 0 - metric   and return
 	;bra	TFT_surface_imperial			; 1 - imperial and return
 
 TFT_surface_imperial:
-	rcall	convert_mbar_to_feet			; convert value in hi:lo from mbar to feet
+	rcall	convert_cm_to_feet				; convert value in hi:lo from [cm] to [feet]
 	output_16_3								; limit to 999 and display only (0-999)
 	STRCAT_TEXT tFeets1						; "ft"
 	bra		TFT_surface_common				; finalize output
+
 TFT_surface_metric:
 	bsf		ignore_digit5					; no cm (flag will be cleared by output_16)
 	movlw	.1								; no 1000 meters
 	movwf	ignore_digits					; ...
 	output_16dp .3							; xxx.y
 	STRCAT_TEXT tMeters						; "m"
+	;bra	TFT_surface_common				; finalize output
+
 TFT_surface_common:
 	STRCAT_PRINT ""							; finalize output
 	bcf		leftbind						; clear left-alignment
@@ -4692,16 +4986,17 @@
 	call	TFT_standard_color
 	WIN_SMALL surf_tissue_N2_column,surf_tissue_N2_row
  IFDEF _helium
-	TSTOSS	opt_tissue_graphics 			; shall show N2+He or pressure and saturation?
-	bra		TFT_surface_tissues_1			; =0: show pressures and saturations
-											; =1: show N2 and He pressures
-	STRCPY_TEXT_PRINT tN2					; print "N2"
+	btfss	tissue_graphic_layout			; shall N2 and He?
+	bra		TFT_surface_tissues_1			; NO  - print "Tissues"
+	STRCPY_TEXT_PRINT tN2					; YES - print "N2"
 	WIN_SMALL surf_tissue_He_column,surf_tissue_He_row
-	STRCPY_TEXT_PRINT tHe					; print "He"
-	bra		TFT_surface_tissues_2			; continue with common part
+	STRCPY_TEXT_PRINT tHe					;     - print "He"
+	bra		TFT_surface_tissues_2			;     - continue with common part
  ENDIF
+
 TFT_surface_tissues_1:
 	STRCPY_TEXT_PRINT tDiveTissues			; print "Tissues"
+
 TFT_surface_tissues_2:
 	;---- draw scale ----------------------------------	;
 	movlw	color_deepblue
@@ -4740,9 +5035,11 @@
 	;---- Draw combined or N2 Tissue Pressures---------	;
 	lfsr	FSR2,char_O_tissue_pressure					; load base address of combined pressures by default
  IFDEF _helium
-	TSTOSC	opt_tissue_graphics							; shall show N2+He or pressure and saturation?
-	lfsr	FSR2,char_O_tissue_pres_N2					; =1: load base address of N2 pressures
+	btfsc	tissue_graphic_layout						; shall show N2+He ?
+	lfsr	FSR2,char_O_tissue_pres_N2					; YES - replace with base address of N2 pressures
  ENDIF
+	btfsc	tissue_graphic_mode							; in logbook mode?
+	lfsr	FSR2,header_buffer+index_tissue_pres_total	; YES - replace with base address from logbook
 	movlw	d'16'
 	movwf	lo											; tissue counter, 16 tissues
 	clrf	hi											; row    counter
@@ -4754,12 +5051,14 @@
 	decfsz	lo,F										; decrement tissue counter, done?
 	bra		TFT_surf_tissues_N2_loop					; NO - loop
  IFDEF _helium
-	TSTOSC	opt_tissue_graphics 						; shall show N2+He or pressure and saturation?
-	bra		TFT_surface_tissues_3						; =1: show He tissue pressures
+	btfsc	tissue_graphic_layout						; shall show N2+He ?
+	bra		TFT_surface_tissues_3						; YES - show He tissue pressures
  ENDIF
 
 	;---- Draw Tissue Saturations ---------------------	;
 	lfsr	FSR2,char_O_tissue_saturation				; load base address of tissue supersaturation
+	btfsc	tissue_graphic_mode							; in logbook mode?
+	lfsr	FSR2,header_buffer+index_tissue_supersat	; YES - replace with base address from logbook
 	movlw	d'16'
 	movwf	lo											; tissue counter, 16 tissues
 	clrf	hi											; row    counter
@@ -4793,13 +5092,15 @@
 	call	TFT_box										; draw line
 
 	; GF factors enabled?
-	TSTOSS	char_I_deco_model							; GF factors enabled?
+	btfss	tissue_graphic_gf							; GF factors enabled?
 	bra		TFT_surface_tissues_4						; NO - continue with CNS
 
 	;---- Print GF low Line --------------------------	;
 	movlw	surf_tissue_diagram_left+.4					; get left base position
 	movwf	win_leftx2									; set left base position (0-159)
 	movff	opt_GF_low,WREG								; get GF low in 0.01 %
+	btfsc	tissue_graphic_mode							; in logbook mode?
+	movff	header_buffer+index_gf_lo_hi+0,WREG			; YES - replace by GF low from logbook
 	mullw	.164										; multiply with 164
 	movf	PRODH,W										; divide   by   256 -> resulting scale factor is 164/256 = 0.640625
 	addwf	win_leftx2,F								; add to base position
@@ -4811,6 +5112,8 @@
 	movlw	surf_tissue_diagram_left+.4					; get left base position
 	movwf	win_leftx2									; set left base position (0-159)
 	movff	opt_GF_high,WREG							; get GF high in 0.01 %
+	btfsc	tissue_graphic_mode							; in logbook mode?
+	movff	header_buffer+index_gf_lo_hi+1,WREG			; YES - replace by GF high from logbook
 	mullw	.164										; multiply with 164
 	movf	PRODH,W										; divide   by   256 -> resulting scale factor is 164/256 = 0.640625
 	addwf	win_leftx2,F								; add to base position
@@ -4841,6 +5144,9 @@
  ENDIF
 
 TFT_surface_tissues_4:
+	btfss	tissue_graphic_cns							; shall show CNS value?
+	goto	TFT_standard_color							; NO  - done
+
 	; ---- Draw CNS% ----------------------------------	;
 	WIN_SMALL surf_tissue_He_column+.22,surf_tissue_He_row	; position in-between tissue bars
 	MOVII	int_O_CNS_current,mpr						; get current CNS
@@ -4869,16 +5175,18 @@
 
 
 ;=============================================================================
-; Draw saturation graph in dive mode
-
+; Draw saturation graph in dive mode custom view
+;
 TFT_dive_tissues:
-	;---- Draw Frame
+
+	;---- draw outer frame
 	call	TFT_standard_color
 	WIN_FRAME_COLOR16 dm_custom_tissue_diagram_top, dm_custom_tissue_diagram_bottom, dm_custom_tissue_diagram_left, .159 ; outer frame
 
 	;---- clear area showing leading tissue number as it may not be printed over
 	WIN_BOX_BLACK dm_custom_tissue_diagram_top+.16, dm_custom_tissue_diagram_top+.16+.10, dm_custom_tissue_diagram_left+.32, dm_custom_tissue_diagram_left+.32+.8 ; top, bottom, left, right
 
+TFT_dive_tissues_1:
 	;---- common initialization for Tissue Pressures and Saturation ----------
 	movlw	.1
 	movwf	win_height									; hight of the bargraph (0-239)
@@ -4895,8 +5203,8 @@
 	;---- Draw combined or N2 Tissue Pressures --------	;
 	lfsr	FSR2,char_O_tissue_pressure					; load base address of combined pressures by default
  IFDEF _helium
-	TSTOSC	opt_tissue_graphics 						; shall show N2+He or pressure and saturation?
-	lfsr	FSR2,char_O_tissue_pres_N2					; =1: load base address of N2 pressures
+	btfsc	tissue_graphic_layout						; shall show N2+He ?
+	lfsr	FSR2,char_O_tissue_pres_N2					; YES - load base address of N2 pressures
  ENDIF
 	movlw	d'16'
 	movwf	lo											; tissue counter, 16 tissues
@@ -4908,8 +5216,8 @@
 	decfsz	lo,F										; decrement tissue counter, done?
 	bra		TFT_dive_tissues_N2_loop					; NO - loop
  IFDEF _helium
-	TSTOSC	opt_tissue_graphics 						; shall show N2+He or pressure and saturation?
-	bra		TFT_dive_tissues_3							; =1: show He tissue pressures
+	btfsc	tissue_graphic_layout						; shall show N2+He ?
+	bra		TFT_dive_tissues_3							; YES - show He tissue pressures
  ENDIF
 
 	;---- Draw Tissue Saturations ---------------------	;
@@ -4945,7 +5253,7 @@
 	call	TFT_box										; draw line
 
 	; GF factors enabled?
-	TSTOSS	char_I_deco_model							; GF factors enabled?
+	btfss	tissue_graphic_gf							; shall show GF lines?
 	bra		TFT_dive_tissues_4							; NO - continue with number of leading tissue
 
 	;---- Print GF low Line --------------------------	;
@@ -4974,12 +5282,12 @@
  IFDEF _helium
 TFT_dive_tissues_3:
 	;---- Draw He Tissues Pressures -------------------	;
+	lfsr	FSR2,char_O_tissue_pres_He					; load base address of He pressures
 	movlw	dm_custom_tissue_diagram_left+.3+.4			; get dive mode left start position for He bars
 	movwf	win_leftx2									; set column left (0-159)
 	movlw	.159-dm_custom_tissue_diagram_left-.4-.4	; get max width for He bars
 	movwf	win_width+0									; set width (low byte)
 	clrf	win_width+1									; ...
-	lfsr	FSR2,char_O_tissue_pres_He					; load base address of He pressures
 	movlw	d'16'
 	movwf	lo											; tissue counter, 16 tissues
 	clrf	hi											; row    counter
@@ -4988,7 +5296,7 @@
 	rcall	TFT_dive_tissues_bargraph					; draw tissue bargraph
 	incf	hi,F										; increment row counter
 	decfsz	lo,F										; decrement tissue counter, done?
-	bra		TFT_dive_tissues_He_loop					; NO - loop
+	bra		TFT_dive_tissues_He_loop					; NO  - loop
  ENDIF
 
 TFT_dive_tissues_4:
@@ -5039,9 +5347,9 @@
 
 	global	TFT_show_cns
 TFT_show_cns:
-	call	TFT_set_message_window		; set the row and column for the current message
+	call	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	STRCPY_TEXT tCNS					; CNS:
 	MOVII	int_O_CNS_current,mpr		; get current CNS
 	call	TFT_color_code_cns			; color-code CNS output
@@ -5060,9 +5368,9 @@
 
 	global	TFT_warning_eod_cns
 TFT_warning_eod_cns:
-	call	TFT_set_message_window		; set the row and column for the current message
+	call	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_warning_color			; switch to warnings (red) text color
 	STRCPY_TEXT tCNSeod					; end-of-dive CNS warning text
 	movlw	dm_warning_length			; dive mode string length
@@ -5072,10 +5380,10 @@
 
 
 	global	TFT_show_ppo2_warning
-TFT_show_ppo2_warning:					; with ppO2 including attention/warning flags in hi:lo
-	call	TFT_set_message_window		; set the row and column for the current message
+TFT_show_ppo2_warning:
+	call	TFT_set_message_window		; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO
+	return								; NO - skip message in this cycle
 	call	TFT_color_code_ppo2			; color-code output
 	btfsc	bailout_mode				; in bailout?
 	bra		TFT_display_diluent_2		; YES
@@ -5123,7 +5431,7 @@
 	global	TFT_LogOffset
 TFT_LogOffset:
 	STRCPY_TEXT tLogOffsetValue			; print "Offset" in selected language
-	call	do_logoffset_common_read	; read offset into lo:hi
+	call	eeprom_log_offset_read		; read offset into lo:hi
 ;	bsf		leftbind
 	output_16_4							; print offset in 4 digits
 ;	bcf		leftbind
@@ -5426,64 +5734,64 @@
 
  ENDIF	; _rx_functions
 
-;=============================================================================    
-
-	global	adjust_depth_with_salinity
-	global	adjust_depth_with_salinity_log
-adjust_depth_with_salinity:			; computes salinity setting into hi:lo [mbar]
-	btfsc	sensor_override_active	; in pressure sensor override mode?
-	return							; YES - do not apply salinity in override mode
-	movff	opt_salinity,WREG		; 0-5%
-adjust_depth_with_salinity_log:		; computes salinity setting (FROM WREG!) into hi:lo [mbar]
-	addlw	d'100'					; 1.00kg/l
-	movwf	up
-
-	movlw	d'105'					; 105% ?
-	cpfslt	up						; salinity upper limit
-	return							; out of limit, do not adjust hi:lo
-	movlw	d'99'					; 99% ?
-	cpfsgt	up						; salinity lower limit
-	return							; out of limit, do not adjust hi:lo
-
-	MOVII	mpr,  xA				; depth in mbar
-	MOVLI	.102,xB					; 0.98 bar / 10 meter
+;=============================================================================
+
+	global	convert_pres_to_depth
+convert_pres_to_depth:				; converts pressure in [mbar] to depth in [cm]
+	btfsc	sensor_override_active	; in pressure sensor override (simulator) mode?
+	return							; YES - convert with factor 1.0, i.e. make [mbar] = [cm]
+
+	movff	opt_salinity,WREG		; get salinity setting (0 - 4 %, see option_table.asm)
+	addlw	d'100'					; add density of fresh water (1.00 kg/l)
+	movwf	up						; store salinity factor in up
+
+	movlw	.101+salinity_max		; load (upper limit + 1)
+	cpfslt	up						; current setting > upper limit?
+	bra		convert_fix_salinity	; YES - fix salinity setting
+
+	movlw	.99+salinity_min		; load (lower limit - 1)
+	cpfsgt	up						; current setting > lower limit?
+	bra		convert_fix_salinity	; YES - fix salinity setting
+
+convert_pres_to_depth_1:
+	MOVII	mpr, xA					; get pressure in [mbar]
+	MOVLI	.102,xB					; conversion factor x 100 for fresh water (1.02 cm per each 1 mbar)
 	call	mult16x16				; xC:4 = xA:2 * xB:2
-	movff	up,xB+0					; salinity
-	clrf	xB+1
+	movff	up,xB+0					; get salinity in [%]
+	clrf	xB+1					; ...
 	call	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder
-	MOVII	xC,mpr					; copy corrected values back to hi:lo
+	MOVII	xC,mpr					; copy back result as depth in [cm]
 	return
 
+convert_fix_salinity:
+	movlw	.100					; reset to 100%, i.e. set salinity to 0%
+	movwf	up						; fix value in up
+	bra		convert_pres_to_depth_1	; continue
+
 ;=============================================================================
 
-	global	convert_mbar_to_feet
-convert_mbar_to_feet:				; convert value in hi:lo from mbar to feet
-	MOVII	mpr, xA					; depth in mbar (multiples of 0.01 meter)
-	btfsc	sensor_override_active	; in pressure sensor override mode?
-	bra		convert_mbar_to_feet_1	; YES
+	global	convert_cm_to_feet
+convert_cm_to_feet:					; converts depth in [cm] to depth in [feet]
+	MOVII	mpr, xA					; depth in [cm]
+	btfsc	sensor_override_active	; in pressure sensor override (simulator) mode?
+	bra		convert_meter_to_feet_1	; YES - convert with 334feet/100m
 	MOVLI	.328,xB					; NO  - convert with 328feet/100m
 	bra		convert_common_to_feet	;     - continue with common part
-convert_mbar_to_feet_1:
-	MOVLI	.334,xB					; YES - convert with 334feet/100m to be in sync with values shown in menu
-	bra		convert_common_to_feet	;     - continue with common part
 
 
 	global	convert_meter_to_feet
-convert_meter_to_feet:				; convert value in lo from meters to feet
-	movf	lo,W					; depth in meter
-	mullw	.100					; convert meter to mbar
-	MOVII	PRODL,xA				; depth in mbar (multiples of 0.01 meter)
-	MOVLI	.334,xB					; convert with 334feet/100m to have 10ft, 20ft, 30ft for stop depths
+convert_meter_to_feet:				; converts depth in [m] to depth in [feet]
+	movf	lo,W					; depth in [m]
+	mullw	.100					; factor to convert [m] to [cm]
+	MOVII	PRODL,xA				; copy depth in [cm] to xA
+convert_meter_to_feet_1:
+	MOVLI	.334, xB				; convert with 334feet/100m to have 10ft, 20ft, 30ft, ... for stop depths
+	;bra	convert_common_to_feet	; continue with common part
+
 
 convert_common_to_feet:
-	call	mult16x16				; xC = xA * xB = depth in 0.01 meter * xxx feet / 100 meter
-	movlw	d'50'					; round up
-	addwf	xC+0,F
-	movlw	.0
-	addwfc	xC+1,F
-	addwfc	xC+2,F
-	addwfc	xC+3,F
-	MOVLI	.10000,xB				; 10000 = 100 for depth in 0.01 meter to full meter  x  100 for feet factor is per 100 meter
+	call	mult16x16				; xC = xA * xB = depth in [cm] * 334 feet/100 m = depth in 0.0001 feet
+	MOVLI	.10000,xB				; divide by 10000 to turn into full feet
 	call	div32x16				; xC = xC / xB with xA as remainder
 	MOVII	xC,mpr					; store result
 
--- a/src/tft_outputs.inc	Fri Feb 21 10:51:36 2020 +0100
+++ b/src/tft_outputs.inc	Fri Feb 28 15:45:07 2020 +0100
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File tft_outputs.inc                      next combined generation V3.03.8
+;   File tft_outputs.inc                      next combined generation V3.08.8
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -84,15 +84,15 @@
 	extern	TFT_clear_divemode_menu				; clear the divemode menu
 	extern	TFT_clear_message_window
 	extern	TFT_clear_message_window_row2
-	extern	TFT_warning_sat
+	extern	TFT_warning_saturation
 	extern	TFT_warning_agf						; show a warning if aGF is selected
 	extern	TFT_divetimeout						; show timeout counter
 	extern	TFT_safety_stop_show				; show the safety stop
 	extern	TFT_safety_stop_clear				; clear safety stop
 	extern	TFT_clear_deco_data					; clear deco data (NDL or stop & TTS)
 	extern	TFT_warning_fallback				; show fallback warning
-	extern	TFT_warning_gas_needs_warn
-	extern	TFT_warning_gas_needs_att
+	extern	TFT_warning_gas_needs
+	extern	TFT_attention_gas_needs
 	extern	TFT_advice_gas_change
 	extern	TFT_warning_no_BO_gas
 	extern	TFT_warning_eod_cns
@@ -109,12 +109,15 @@
 	extern	TFT_warning_sensor_disagree
  ENDIF
 
+; Date
+	extern	TFT_convert_date					; print day, month and year
+	extern	TFT_convert_date_short				; print day and month
 
 ; Divemode Custom Views
 	extern	TFT_avr_stopwatch_mask				; mask for average depth and stopwatch
 	extern	TFT_avr_stopwatch					; data for average depth and stopwatch
-	extern	TFT_gas_needs_ascent_mask			; mask for gas needs ascent
-	extern	TFT_gas_needs_ascent				; data for gas needs ascent
+	extern	TFT_gas_needs_mask					; mask for gas needs ascent
+	extern	TFT_gas_needs						; data for gas needs ascent
 	extern	TFT_decoplan_mask					; mask for deco plan
 	extern	TFT_decoplan						; data for deco plan
 	extern	TFT_ceiling_GF_tissue_mask			; mask for ceiling, current GF and tissues
@@ -140,6 +143,12 @@
 	extern	TFT_ppo2_sensors					; data for ppO2 sensors
  ENDIF
 
+ IFDEF _cave_mode
+	extern	TFT_cave_tts_mask					; mask for cave mode TTS, total stops and runtime
+	extern	TFT_cave_tts						; data for cave mode TTS, total stops and runtime
+	extern	TFT_cave_waypoints					; data for cave mode waypoints
+ ENDIF
+
 
 ; Surface Custom Views
 
@@ -148,7 +157,7 @@
  ENDIF
 
 
-; Misc
+; Color-coding
 	extern	TFT_standard_color
 	extern	TFT_disabled_color
 	extern	TFT_memo_color
@@ -162,15 +171,14 @@
 	extern	TFT_color_code_cns
 	extern	TFT_color_code_tank_pres_sac
 
-	extern	adjust_depth_with_salinity			; computes salinity setting into lo:hi [mbar]
-	extern	adjust_depth_with_salinity_log		; computes salinity setting (FROM WREG!) into lo:hi [mbar]
-	extern	TFT_convert_date_short
+; Misc
+	extern	convert_pres_to_depth				; converts pressure in [mbar] to depth in [cm]
+	extern	convert_cm_to_feet					; converts depth in [cm] to depth in [feet]
+	extern	convert_meter_to_feet				; converts depth in [m]  to depth in [feet]
+	extern	convert_celsius_to_fahrenheit		; converts temperature from celsius to fahrenheit
 	extern	TFT_convert_signed_16bit
-	extern	TFT_convert_date
-	extern	convert_mbar_to_feet				; convert value in hi:lo from mbar to feet
-	extern	convert_meter_to_feet				; convert value in    lo from meters to feet
-	extern	convert_celsius_to_fahrenheit		; convert value in hi:lo from celsius to fahrenheit
 
+; Debug output
 	extern	TFT_debug_output
 
 
@@ -189,7 +197,7 @@
  ENDIF
 
  IFDEF _cave_mode
-	extern	TFT_info_cave_mode					; show info    that in cave mode
-	extern	TFT_info_dive_turned				; show info    that dive is turned
-	extern	TFT_warn_cave_shutdown				; show warning that cave mode has shut down
+	extern	TFT_info_cave_mode					; show info      that cave mode is active
+	extern	TFT_cave_shutdown_attention			; show attention that cave mode will shut down soon
+	extern	TFT_cave_shutdown_warning			; show warning   that cave mode has  shut down
  ENDIF