changeset 634:4050675965ea

3.10 stable release
author heinrichsweikamp
date Tue, 28 Apr 2020 17:34:31 +0200
parents 690c48db7b5b
children 9a64914a8fca
files src/Docu/Cave-Backtracking-Storage-Format.pdf src/Docu/Cave-Backtracking-Storage-Format.xlsx src/Docu/Cave-Mode-Manual.txt src/Docu/Changenote-3-08.txt src/Docu/Changenote-3-09.txt src/Docu/Code-Addresses.txt src/Docu/Deco-Engine-Calculation-Schedules.txt src/Docu/Dive-Setup-Menu-Structure.txt src/Docu/Gas-Switching-Conditions.txt src/Docu/OSTC-Calculation-Schedules.png src/Docu/code-statistics.txt src/Docu/comm-docu.txt src/Docu/font-color.txt src/Docu/ostc_hardware_string.xlsx src/aa_fonts.asm src/aa_wordprocessor.asm src/adc_lightsensor.asm src/calibrate.asm src/calibrate.inc src/color_processor.asm src/colorschemes.inc src/comm.asm src/comm.inc src/compass_calib.c src/compass_ops.asm src/configuration.inc src/convert.asm src/convert.inc src/customview.asm 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/isr.asm src/logbook.asm src/math.asm src/math.inc src/mcp.asm src/menu_processor.asm src/menu_processor.inc src/menu_tree.asm src/ms5541.asm src/option_table.asm src/options.asm src/p2_deco.c src/rtc.asm src/rx_firmware-1-40.inc src/rx_firmware.asm src/rx_ops.asm src/simulator.asm src/sleepmode.asm src/start.asm src/strings.asm src/strings.inc src/surfmode.asm src/surfmode.inc src/text_english.inc src/text_french.inc src/text_german.inc src/text_italian.inc src/text_multilang.asm src/text_multilang.inc src/tft.asm src/tft.inc src/tft_outputs.asm src/tft_outputs.inc src/varargs.inc src/wait.asm src/wait.inc
diffstat 78 files changed, 21227 insertions(+), 15904 deletions(-) [+]
line wrap: on
line diff
Binary file src/Docu/Cave-Backtracking-Storage-Format.pdf has changed
Binary file src/Docu/Cave-Backtracking-Storage-Format.xlsx has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/Cave-Mode-Manual.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,265 @@
+
+Supplemental Manual for the Cave Mode Function (V1.0)
+=====================================================
+
+The intended use of hwos Cave Mode is to monitor if the gases that are carried
+by the diver are sufficient to end the dive, especially taking into account the
+amount of gases that will be needed to finish decompression stops.
+
+The Cave Mode function extends the normal deco and gas needs calculating made for
+open water vertical ascent, by tracking back the whole depth profile of the dive
+and including final and/or intermediate deco stops that may become necessary.
+The cave mode function may be used in OC diving as well as in CCR/pSCR mode. When
+using it in CCR/pSCR mode, it will calculate the way back in bailout mode.
+
+  || NOTICE:
+  || With cave mode switched on, the normal 3 meter step size of deco stop spacing
+  || changes to a 1 meter spacing, reducing the indicated required stop time in front
+  || of passages that are less than 3 meters shallower than the current stop depth.
+
+In order to produce accurate results, the user has to understand the following
+concepts and settings, and has to configure these settings with appropriate values:
+
+- While on the way in, the depth profile will be sampled once every minute. For
+  the return way calculation, it is assumed that the diver will travel at the same
+  speed as on the way in and will travel along the same depth profile as on the way
+  in.
+
+  || IMPORTANT:
+  || The cave mode provides capacity for 4 hours of depth profile recording.
+  || 10 minutes before storage capacity is exhausted (i.e. after 4 hours), an
+  || attention message will be given. When the storage capacity becomes fully
+  || used up, the cave mode function switches itself off and a respective warning
+  || is shown.
+
+  If the cave mode function has switched itself off due to running out of storage
+  capacity, it can be recovered on exiting the cave: When manually switching it on
+  again, it comes back on again in turned state (see below), showing gas needs and
+  TTS as of the position where it had switched off.
+
+- Gas needs for the travel portions of the return way are calculated using the SAC
+  work rate. While spending time on required deco stops, the SAC deco rate is used.
+  Both SAC values, SAC work and SAC deco, need to be set by the diver to consumption
+  rates that match personal rates, taking into account elevated rates due to stress
+  etc., especially when using the cave mode function for bailout capacity checking.
+
+  || WARNING:
+  || If the actual SAC rate is higher than the configured on, or if traveling back
+  || slower than on the way in, the real needs will be under-estimated and the
+  || diver may run into an out-of-air situation if taking the dive to the limits!
+
+- Every tank needs to be configured with its size and with the amount of pressure
+  that is in it. The cave function will use these numbers to calculate how much gas
+  will be available from each tank to be used for the way back.
+
+  || IMPORTANT:
+  || For tanks that is breathed from while on the way in, the tank pressures have
+  || to be set to the turn pressures that have been determined for the respective
+  || tanks during dive planning!
+
+- While on the way in, the cave function constantly recalculates how much gas from
+  each tank will be needed to exit the cave. Upon reaching 70% utilization on any
+  tank, an attention message (color-coded in yellow) will be given. Upon reaching
+  100% utilization, a warning message (color-coded in red) will be issued.
+  
+- In case Dive Setup -> SAC Setup -> Swap on empty is set to yes, at the time a tank
+  is calculated to be fully used up, the calculations will try to switch to another
+  tank that still contains some gas according to the calculations. If such a tank
+  exists, the remaining way out will be calculated based on this tank and hence on the
+  gas in that tank, which may be sub-optimal in terms of decompression. If such a tank
+  does not exist, or if the swap-function is set no 'no', the remaining gas needs will
+  continue to get added on the depleted tank, resulting in displayed required tank
+  pressure higher than configured pressure available.
+
+- When turning the dive, i.e. upon starting on the way back out of the cave again,
+  the cave function needs to set into 'turned' state. This will stop the cave function
+  to assume that the actual way out is still part of the way in and subsequently will
+  stop taking further depth recordings and figuring them in for gas needs calculation.
+
+  || WARNING:
+  || The diver shall turn the dive ultimately latest when any one of the gases
+  || calculates to be fully needed! In this situation, the diver will be without
+  || any reserves! It is advised to set the tank pressures a bit lower than their
+  || actual fill pressure is, and to set the SAC rates a bit higher, to put the
+  || calculation results onto the safe side.
+
+- When setting the dive as 'turned', the indicated gas needs are likely to still rise.
+  This will be due to the fact that the cave function still calculates the gas needs
+  for all the way back from turn point to the surface, not knowing how much of this
+  way has been traveled already. In consequence, the tissue saturations that are gained
+  on the portion of the way back that has already been traveled are calculated twice,
+  resulting in an increased estimated deco obligation at the end of the dive. This
+  effect can be overcome by using 'waypoints' (see below).
+
+  || IMPORTANT:
+  || Without having set at least one waypoint (see below) before setting the dive
+  || as turned, it is not possible to revoke the 'turned' state again!
+
+- When the cave mode is switched off, the gas needs calculation reverts to the open
+  water vertical ascent mode, i.e. no dedicated time for horizontal movement is
+  figured in any more. It is appropriate to switch off cave mode when the remaining
+  horizontal movements (further swimming out of the cave) can be done in parallel with
+  doing the decompression "stops". This way, calculation results will become independent
+  of the remaining way to go, and thus accurate again.
+
+  || NOTICE:
+  || When being back near the cave entrance, with only final decompression stops
+  || remaining to be done, and with the remaining way being doable while doing the
+  || decompression stops, it is appropriate to switch off the cave mode.
+
+- The cave mode function can be switched off and on again at any time of the dive.
+  Temporary switching off the cave mode while the dive is not set as turned yet can
+  be used to pause the recording, e.g. while undertaking some tasks that take time
+  on the way in, but not while on the way out, e.g. fixing the line or doing survey
+  tasks.
+
+- To tell the cave mode calculations where the diver is while on the way out, waypoints
+  can be set while on the way in. Initially on setting the dive as turned, the gas needs
+  are calculated for the full way back. Then the diver can select one of the waypoints
+  and the cave mode function will calculate how much gas will be needed to return from
+  this waypoint. Upon physically reaching the respective waypoint, indicated gas needs
+  will become accurate again for this position in the cave, given that the rules discussed
+  above are obeyed.
+
+  || IMPORTANT:
+  || Waypoints should be set at regular distances and/or important features in the cave
+  || profile, e.g. at places where intermediate deco stops are expected. While on the
+  || way back out of the cave, whenever a waypoint is reached, the cave function shall
+  || be updated to this waypoint. This way the indicated gas needs will always stay near
+  || the expected real needs, but on the safe side, given that the rules discussed above
+  || are met.
+
+  || IMPORTANT:
+  || The cave mode function provides for 30 waypoints. Every waypoint that is set
+  || reduces the available storage capacity by the equivalent of four minutes of depth
+  || profile recording time. Thus, when all 30 waypoints are used, the depth profile
+  || storage capacity reduces to 2 hours for the inwards part of the dive.
+
+  || IMPORTANT:
+  || To establish a relationship between the numbering of the waypoints within the cave
+  || mode function and their physical positions in the cave, it is recommended to place
+  || cookies that are marked with the respective waypoint numbers.
+
+- Every time a waypoint is set, also a marker will be set in the normal logbook recording.
+
+- If at least one waypoint has been set, the 'turned' state of the dive can be revoked
+  again. To revoke the turned state and thus continue the dive in inward direction, the
+  diver has to physically go back to a previously created waypoint in the cave and select
+  that waypoint in the cave mode function, too, to keep the backtracking data in sync with
+  reality.
+
+  || NOTICE:
+  || The turned state can not be revoked while being at the original turn point of
+  || the dive. Going back to a previous waypoint is required.
+  
+- When the 'turned' state is revoked, the depth profile recording resumes. The new recordings
+  are appended after the waypoint where the dive was resumed.
+
+  || IMPORTANT:
+  || The depth profile and all waypoints that were originally recorded after the waypoint
+  || from which the dive is resumed again in inward direction are lost. The respective
+  || recording space will be freed up and used for the recording of the new leg.
+
+- This feature can e.g. be used for exploring different branches of a cave:
+
+  1) set a waypoint at the forking point of the branches,
+  2) explore the first branch (further waypoints may be set),
+  3) when done, set the dive as turned,
+  4) return to the forking point,
+  5) recall the respective waypoint that was set at the forking point,
+  6) check if gas reserves allow for exploring another branch,
+  7) select 'continue' to revoke the turned state and start the recording
+     for the next branch to be explored now.
+
+  Steps 2) to 7) may be repeated several times.
+
+- The cave mode function can account for gases that are temporary unavailable because
+  their tanks have been staged. On page two of the dive menu item 'Gaslist', tanks
+  can be toggled between available, staged (disabled color and "S" marking for staged),
+  and lost (disabled color and "x" marking aka crossed-out).
+
+- If a tank is set to lost state, it will not be considered in deco as well as gas
+  needs calculation any more. This state is revocable.
+
+- If a tank is set to staged state, it will currently not be considered any more,
+  but: Whenever a waypoint is set, a snapshot of the staged / not staged state of
+  all tanks is taken. When the cave mode function works it way through the stored
+  cave profile recording and hits a waypoint entry, it extracts this snapshots again
+  and continues choosing gases for deco and gas needs calculation based on these
+  snapshots.
+
+  || IMNPORTANT:
+  || When staging a tank:
+  ||
+  || 1) Set a waypoint.
+  ||
+  ||    Within this waypoint the tank will be recorded as (still) being available,
+  ||    that is it will be available (again) upon passing this waypoint on the way
+  ||    out again.
+  ||
+  || 2) Set the tank as staged.
+  ||
+  ||    This will set the tank as being not available during the portion of the dive
+  ||    that lies to the inside of the above waypoint.
+
+  || NOTICE:
+  || While a tank is set as staged, no better gas cue will be generated for it!
+
+  || IMPORTANT:
+  || When a tank is picked up again, it needs to be set to available state again
+  || in order to positively confirm that it really is available again!
+
+- When diving in OC mode or when in bailout mode, selecting a gas that is still set
+  as staged automatically reverts that gas to the available state. The same holds
+  true for gases that were declared as lost: on selecting them, they are also set
+  to the available state again.
+
+  || IMPORTANT:
+  || When diving in CCR or pSCR mode and initiating a bailout, the dive will be
+  || automatically set to turned state (given cave mode is switch on and the dive
+  || is not already turned)!
+
+  || IMPORTANT:
+  || While the cave mode is switched on and the dive is in turned state, the fTTS
+  || calculation will be suppressed - gas needs are calculated on the basis of an
+  || immediate return to the exit.
+
+
+
+Operating the Cave Mode Function:
+---------------------------------
+
+The Cave Mode Function is activated by setting the the surface menu item
+
+         Dive Setup -> Dive Setup (again) -> Cave Mode to 'on'
+
+It will then be active right from the start of the following dives. All further
+operation is done during the dive via a dedicated cave mode menu. This menu can
+be accessed via the left button: after pressing the left button for 'Menu?',
+press it again to show up 'Cave?', then press the right button to enter the cave
+mode menu. In OC mode, the cave mode menu is also reachable via the main dive menu,
+using the menu item 'Cave Mode'.
+
+Depending on the 'dive turned' state, certain menu items are available or not.
+This will be indicated by the color coding of the respective menu items.
+
+When the cave mode menu is active, the custom view is temporary replaced by a
+graphical representation of the waypoint situation. The last waypoint placed is
+shown in the middle of the display. The "-|" symbol depicts the end of the line,
+representing the deepest penetration point during the dive. The green arrow shows
+for which position in the cave the return gas needs are calculated.
+
+In the message field, either a "cTTS xx'" or "WPyy xx'" is shown. While the dive
+is not turned yet, cTTS (Cave Time-to-Surface) is shown, with xx being the total
+time in minutes required for swimming all the way back and doing the decompression
+stops, if required. When the dive is turned, WP is shown to indicate that the TTS
+is computed from off the waypoint yy. If yy reads the symbol -|, the TTS is computed
+from off the turn point of the dive.
+
+All cave mode functions are usable in simulator mode, too. Opposite to that, the
+deco calculator does not support cave mode, it calculates vertical open water ascents
+only.
+
+|| IMPORTANT:
+|| It is strongly advised to familiarize with the cave mode functions by using
+|| the OSTC simulator mode!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/Changenote-3-08.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/Changenote-3-09.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,102 @@
+Change Note hwos Firmware 3.09.4
+================================
+
+- When diving in CCR or pSCR mode: An attention and a warning for the gas
+  density has been added. The attention will be given when the density
+  of the current gas mixture reaches 6.0 grams per liter. Upon reaching
+  6.5 grams per liter, a warning will be given. The checks can be enabled
+  or disabled via the menu CCR/pSCR setup > more.
+
+- Incremented upper limit for SAC Work to 80 l/min to ease usage of the
+  OSTC gas needs calculation in Rock-Bottom mode.
+
+- Faster response to button events while in dive mode.
+
+- Hardened all USB/Bluetooth communication against data losses and timeouts.
+
+- Fixed Bluetooth item disappearing from menu.
+
+- A new Firmware Recovery Feature has been added: the currently active firmware
+  can be backed-up and restored later on while other firmwares have been loaded
+  thereafter. The feature is accessible via Settings -> System Settings ->
+  Reset Menu -> Reboot and becomes available with the first firmware load after
+  the V3.09 beta 4 (or later) is already on the unit.
+
+
+Change Note hwos Firmware 3.09.2 + 3.09.3
+=========================================
+
+- Added a function to acknowledge pending alarms, attentions and advices
+  so that the exclamation-mark sign disappears: after pressing the left
+  button until "Ackn?" appears, a press on the right button acknowledges
+  the current alarm, attention or advice and suppresses the related sign.
+
+- Bugfixes: NDL not shown in big layout, external sensor not selectable,
+  flash-write operation on some OSTC hardware, graphical garbage in depth
+  output in big layout when deeper than 100 m.
+
+
+Change Note hwos Firmware 3.09.1
+================================
+
+- 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.09 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/Code-Addresses.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,20 @@
+    fixed Start Addresses
+--------------------------------
+reset_v				CODE 0x00000
+start_v				CODE 0x00004
+isr_high			CODE 0x00008
+fingerprint			CODE 0x0000A
+isr_low				CODE 0x00018
+restore				CODE 0x00080
+isr_handler			CODE 0x00084
+surf_menu			CODE 0x01000	; menu call addresses need to be within 0x0xxxx
+dive_menu			CODE 0x02000	; menu call addresses need to be within 0x0xxxx
+option_table		CODE 0x08000	; all table data      need to be within 0x08xxx
+text_1_base			CODE 0x09000	; all text indices    need to be within 0x09yxx, y = 0...3
+text_2_base			CODE 0x09400	; all text indices    need to be within 0x09yxx, y = 4...7
+pallet_table		CODE 0x09800
+p2deco				CODE 0x0B000
+fonts_data			CODE 0x10000
+rx_firmware_storage	CODE 0x18000
+Buhlmann Tables		CODE 0x1DC00
+(bootloader)		CODE 0x1E000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/Deco-Engine-Calculation-Schedules.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,26 @@
+
+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		--			--
+
+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
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/Dive-Setup-Menu-Structure.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,59 @@
+
+		MENU_CALL																; Dive  Setup
+		MENU_CALL																; Deco  Setup
+		MENU_CALL																; Gas   Setup
+		MENU_CALL																; ppO2  Setup
+		MENU_CALL																; Stops Setup
+
+
+
+	Dive Setup
+		MENU_OPTION		tDvMode,					oDiveMode,				0	; Dive Mode
+		MENU_OPTION		tCaveMode,					oCaveMode,				0	; cave mode
+		MENU_OPTION		tFTTSMenu,					oExtraTime,				0	; fTTS/Delay
+		MENU_OPTION		tTimeoutDive,				oDiveTimeout,			0	; dive timeout
+		MENU_OPTION		tStoreApnoeDive,			oStoreApnoeDive,		0	; store Apnoe
+
+
+	Deco Setup
+		MENU_OPTION		tDkMode,					oDecoMode,				0	; ZH-L16 /GF
+		MENU_OPTION		tSaturationMult,			osatmultgf,				0	; saturation
+		MENU_OPTION		tDesaturationMult,			odesatmultgf,			0	; desaturation
+		MENU_CALL																; GF Settings
+		MENU_OPTION		taGFenable,					oEnable_aGF,			0	; aGF selectable
+
+	GF Setup
+		MENU_OPTION		tGF_low,					oGF_low,				0	; GF low
+		MENU_OPTION		tGF_high,					oGF_high,				0	; GF high
+		MENU_OPTION		taGF_low,					oaGF_low,				0	; aGF low
+		MENU_OPTION		taGF_high,					oaGF_high,				0	; aGF high
+
+
+	Gas Setup
+		MENU_OPTION		tCalcGasNeeds,				oCalcAscGas,			0	; calc.gas
+		MENU_OPTION		tSetWorkSAC,				oWork_SAC,				0	; work SAC
+		MENU_OPTION		tSetDecoSAC,				oDeco_SAC,				0	; deco SAC
+																				; (bailout SAC)
+		MENU_OPTION		tGasChangeTime,				oGasChangeTime,			0	; gas change time
+
+
+	ppO2 Setup
+		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
+																				;
+
+
+	Stops Setup
+		MENU_OPTION		tSafetyStop,				oSafetyStop,			0	; safety stop
+		MENU_OPTION		tExtendedStops,				oExtendedStops,			0	; extended stops
+		MENU_OPTION		tLastDecostop,				oLastDeco,				0	; last deco stop
+																				;
+																				;
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+ -> Display Settings 2nd Page
+		MENU_OPTION		tShowppO2,					oShowppO2,				0	; always show ppO2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/Gas-Switching-Conditions.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,65 @@
+
+Rules for Gas Switching in the Deco Calculation
+===============================================
+
+The deco calculation switches gases on the following rules and conditions.
+
+
+A new gas to eventually switch to is searched for:
+--------------------------------------------------
+
+a) Whenever arriving or staying on a deco stop.
+
+   If a new gas is found, it will be taken.
+
+or
+
+b) On each calculation step, given:
+
+   1) Cave mode is activated.
+
+      If a new gas is found, it will be taken.
+
+   or
+
+   2) - extended stops are activated, or
+      - the dive is in bailout mode.
+
+      If a new gas is found, it will only be taken if
+
+      + the change depth of the new gas has not been passed yet (i.e. the
+        diver has not passed the change depth of this gas without actually
+        switching to it, so on purpose is breathing another gas),
+
+     and
+
+      + the dive is not on the final ascent. (i.e. no gas change will be
+        considered any more after leaving the last deco stop for surfacing)
+
+
+When searching for a new gas, in order to qualify a gas must:
+-------------------------------------------------------------
+
+a) Be available, i.e. neither be disabled, lost, nor staged,
+
+b) not be of type 'deco gas' unless:
+
+   - extended stops are activated, or
+   - the ascent calculation has arrived on a deco stop, or
+   - the dive is in bailout mode,
+
+c) have a change depth that is not shallower than the current depth,
+   (i.e. it must be breathable by configured change depth)
+
+d) have the shallowest change depth among all new gas candidates that
+   have qualified so far,
+
+e) not yet be fully used up in case contingency mode* is activated.
+
+For a gas to become elected as the new gas, it must match all of the above criteria.
+
+If none of the configured gases qualifies to become a new gas, the deco calculation
+will continue on the current (last selected) gas.
+
+____
+* contingency mode is auto-activated in case the dive started in cave mode
Binary file src/Docu/OSTC-Calculation-Schedules.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/code-statistics.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,61 @@
+
+Compass Memory Footprint
+------------------------
+
+Section       Size Hex   Size Dec   Source           Function
+------------  ---------  ---------  ---------------  ----------------------------------------------------------
+compass_cal   0x001340      4.928   compass_calib.c  calibrate hard-iron for magnetic compass measurements
+compass_run   0x00074e      1.870   compass.c        compute north direction from magnetic/acceleration measures
+compass_ops1  0x00008a        138   compass_ops.asm  compass_filter
+compass_ops2  0x00006e        110   compass_ops.asm  compass_umul & compass_imul
+compass_ops3  0x000250        592   compass_ops.asm  compass_calibration_loop
+compass_ops4  0x00008c        140   compass_ops.asm  TFT_surface_compass_mask & TFT_surface_compass_heading
+compass_ops5  0x0006b8      1.720   compass_ops.asm  TFT_dive_compass_mask    & TFT_dive_compass_heading 
+compass_ops6  0x000102        258   compass_ops.asm  compass_heading_common
+                              746   embedded in menus, texts, operations, etc.
+
+
+
+
+   Program Memory Usage for
+------------------------------
+     _hwos_tech_3_cR_cave
+
+Block-Start  used up to  Spare
+-----------  ----------  -----
+ 0x000000     0x008b01   1.278
+ 0x009000     0x00fffb       4
+ 0x010000     0x01dcfb       4
+ 0x01dd00     0x01dfff       0
+
+
+
+; Features Selection
+; ------------------
+; base code witout any features, 1 language (en)                      mem:   97.500 byte
+; _compass            compass function                                mem: + 10.502 byte
+; _helium             helium (trimix) gases and diluents              mem: +  2.162 byte || both together:
+; _ccr_pscr           CCR & pSCR modes, basic functionality           mem: +  4.540 byte || + 6.724 byte
+; _external_sensor    CCR & pSCR modes, external sensor support       mem: +  3.690 byte
+; _gauge_mode         gauge mode                                      mem: -     30 byte
+; _high_ppO2_max      raised ppO2 max limit (2.0 bar)                 mem:        0 byte (neutral)
+; _rx_functions       RX function        (OSTC TR)                    mem: +  4.776 byte
+; _rx_update          RX firmware update (OSTC TR)                    mem: +  2.438 byte (dependent on RX firmware size)
+; _gas_contingency    auto-switch to alternative tanks on depleption  mem: +    814 byte
+; _cave_mode          cave mode return calculation                    mem: +  2.366 byte
+; _min_depth_option   resettable min. and max. depth                  mem: -      6 byte  ## special user group only ##
+; _screendump         screen dump function                            mem: +    348 byte  ## special user group only ##
+
+
+
+; global Version Selection
+; ------------------------
+;
+; _hwos_tech_2_TR      *) compile Tech  version for OSTC 2, Plus and TR (1 language en) memory: 120.492 used, 2.388 free
+; _hwos_tech_2_TR_cave *) compile Tech  version for OSTC 2, Plus and TR (1 language en) memory: 122.854 used,    26 free
+; _hwos_tech_3_cR         compile Tech  version for OSTC 3       and cR (1 language en) memory: 119.244 used, 3.636 free
+; _hwos_tech_3_cR_cave    compile Tech  version for OSTC 3       and cR (1 language en) memory: 121.600 used, 1.280 free
+; _hwos_sport             compile Sport version for all models          (1 language en) memory: 116.016 used, 6.864 free
+; _hwos_sport             compile Sport version for all models          (2 lang. en+de) memory: 120.292 used, 2.588 free
+;                                                                                               122.880 max. available
+; *) without _rx_update (does not fit)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/comm-docu.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,311 @@
+===================================================================================================
+
+                            OSTC hwos3 COMM Mode Documentation
+
+                                       16.03.2020
+
+===================================================================================================
+
+Remarks: - send and receive as given here are from OSTC point of view,
+
+         - timeouts restart on each next byte received,
+
+         - when designing the peer side, account for additional delays caused
+           by USB/BT low level drivers,
+
+         - initiate a buffer flush after each command or parameter/data block
+           and wait on the OSTC response before sending the next command/data,
+
+         - the 3 byte start address and the 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						(hardware high byte)
+	send 1 byte hardware descriptor	(hardware low  byte)
+	send 0x00						(feature  high byte)
+	send 0x00						(feature  low  byte)
+	send 0x00						(model)
+	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
+	header contains no dive    ->  goto comm_command_loop
+	no profile data available  ->  send 256 byte dive header  (begins with 0xFAFA),
+	                               send empty profile: <length = 0x000008> <end = 0xFDFD>,
+	                               goto comm_command_loop
+	else                       ->  send 256 byte dive header  (begins with 0xFAFA),
+	                               send xxx 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,
+	                 takes up to block_count * 25 ms, i.e. for 120 kB (30 blocks) up to 750 ms
+	                 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, takes up to 25 ms
+	                 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.09)
+	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,
+	                                                takes up to 2 or 5 ms dependent on FLASH chip
+	                                                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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Docu/font-color.txt	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,6 @@
+=============================================================
+                  Setting the Font Color
+=============================================================
+
+
+           ===>> refer to colorschemes.inc <<===
\ No newline at end of file
Binary file src/Docu/ostc_hardware_string.xlsx has changed
--- a/src/aa_fonts.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/aa_fonts.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File aa_fonts.asm                         combined next generation V3.08.3
+;   File aa_fonts.asm                       * combined next generation V3.08.4f
 ;
 ;   Font-data for the anti-aliased word processor
 ;
@@ -14,14 +14,14 @@
 
 #include "configuration.inc"
 
-
 ; Attention: all fonts need to be in the same 64 kByte page
+;============================================================================
 fonts_data	CODE_PACK	0x10000			; ex 0x11000
-
 ;============================================================================
 
 
 ;---- TINY font description and data ----------------------------------------
+;
 	global	aa_font16_block
 aa_font16_block:
 	DB		'°', 0x7F					; remap a few ASCII chars, to avoid
@@ -41,10 +41,10 @@
 	DB		'¡', 0x8D
 	DB		'¿', 0x8E
 	DB		0							; end of translation table
-	DB		aa_font16_firstChar			; to be subtracted
-	DB		aa_font16_chars				; max value
-	DB		'¿'-aa_font16_firstChar		; replace by ¿ when unknown
-	DB		aa_font16_height + 0x80
+	DB		aa_font16_firstChar			; code of first char  in font set
+	DB		aa_font16_chars				; number of     chars in font set
+	DB		'¿'-aa_font16_firstChar		; default char
+	DB		aa_font16_height + 0x80		; font hight and AA flag
 ;
 #include	"../src/Fonts/aa_font16_idx.inc"
 #include	"../src/Fonts/aa_font16.inc"
@@ -54,7 +54,9 @@
 		error TINY font should be encoded with 3 bits anti-aliasing!
 	endif
 
+
 ;---- SMALL font description and data ----------------------------------------
+;
 	global	aa_font28_block
 aa_font28_block:
 	DB		'°', 0x7F					; remap a few ASCII chars, to avoid
@@ -79,20 +81,22 @@
 	DB		0xB8,0x93					; arrow down
 	DB		0xB9,0x94					; arrow up
 	DB		0							; end of translation table
-	DB		aa_font28_firstChar			; to be subtracted
-	DB		aa_font28_chars				; max value
-	DB		0x83-aa_font28_firstChar	; replace by ¤ when unknown
-	DB		aa_font28_height + 0x80
+	DB		aa_font28_firstChar			; code of first char  in font set
+	DB		aa_font28_chars				; number of     chars in font set
+	DB		0x83-aa_font28_firstChar	; default char
+	DB		aa_font28_height + 0x80		; font hight and AA flag
 ;
 #include	"../src/Fonts/aa_font28_idx.inc"
 #include	"../src/Fonts/aa_font28.inc"
 aa_font28_end:
-; Attention: make sure this is coherent...
+; Attention: make sure this is coherent:
 	if aa_font28_nbbits != 3
 		error SMALL font should be encoded with 3 bits anti-aliasing!
 	endif
 
+
 ;---- STD font description and data ------------------------------------------
+;
 	global	aa_font34_block
 aa_font34_block:
 	DB		'°', 0x7F					; remap a few ASCII chars, to avoid
@@ -119,20 +123,22 @@
 	; 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		aa_font34_firstChar			; code of first char  in font set
+	DB		aa_font34_chars				; number of     chars in font set
+	DB		0x87-aa_font34_firstChar	; default char
+	DB		aa_font34_height + 0x80		; font hight and AA flag
 ;
 #include	"../src/Fonts/aa_font34_idx.inc"
 #include	"../src/Fonts/aa_font34.inc"
 aa_font36_end:
-; Attention: make sure this is coherent...
+; Attention: make sure this is coherent:
 	if aa_font34_nbbits != 3
 		error STANDARD font should be encoded with 3 bits anti-aliasing!
 	endif
 
+
 ;---- MEDIUM font description and data ---------------------------------------
+;
 	global	aa_font48_block
 aa_font48_block:
 	DB		' ',  0x3F					; space, full-width
@@ -144,54 +150,59 @@
 	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
+	DB		aa_font48_firstChar			; code of first char  in font set
+	DB		aa_font48_chars				; number of     chars in font set
+	DB		0x3F-aa_font48_firstChar	; default char
+	DB		aa_font48_height + 0x80		; font hight and AA flag
 ;
 #include	"../src/Fonts/aa_font48_idx.inc"
 #include	"../src/Fonts/aa_font48.inc"
 aa_font48_end:
-; Attention: make sure this is coherent...
+; Attention: make sure this is coherent:
 	if aa_font48_nbbits != 3
 		error MEDIUM font should be encoded with 3 bits anti-aliasing!
 	endif
 
+
 ;---- LARGE font description and data ----------------------------------------
+;
 	global	aa_font90_block
 aa_font90_block:
-	DB		' ', 0x2F
-	DB		0
-	DB		aa_font90_firstChar
-	DB		aa_font90_chars
-	DB		0x2F-aa_font90_firstChar
-	DB		aa_font90_height + 0x80		; AA flag
+	DB		' ', 0x2F					; space
+	DB		0							; end of translation table
+	DB		aa_font90_firstChar			; code of first char  in font set
+	DB		aa_font90_chars				; number of     chars in font set
+	DB		0x2F-aa_font90_firstChar	; default char
+	DB		aa_font90_height + 0x80		; font hight and AA flag
 ;
 #include	"../src/Fonts/aa_font90_idx.inc"
 #include	"../src/Fonts/aa_font90.inc"
 aa_font90_end:
-; Attention: make sure this is coherent...
+; Attention: make sure this is coherent:
 	if aa_font90_nbbits != 3
 		error SMALL font should be encoded with 3 bits anti-aliasing!
 	endif
 
+
 ;---- HUGE font description and data ----------------------------------------
+;
 	global aa_font92_block
 aa_font92_block:
-			DB	' ', 0x2F
-			DB	0
-			DB	aa_font92_firstChar
-			DB	aa_font92_chars
-			DB	0x2F-aa_font92_firstChar
+			DB	' ', 0x2F					; space
+			DB	0							; end of translation table
+			DB	aa_font92_firstChar			; code of first char  in font set
+			DB	aa_font92_chars				; number of     chars in font set
+			DB	0x2F-aa_font92_firstChar	; default char
 			DB	aa_font92_height + 0x80		; AA flag
 ;
 #include	"../src/Fonts/aa_font92_idx.inc"
 #include	"../src/Fonts/aa_font92.inc"
 aa_font92_end:
-; Make sure this is coherent...
+; Attention: make sure this is coherent:
 	if aa_font92_nbbits != 3
 		error SMALL font should be encoded with 3bits anti-aliasing...
 	endif
 
-;=============================================================================
-	END
\ No newline at end of file
+;-----------------------------------------------------------------------------
+
+	END
--- a/src/aa_wordprocessor.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/aa_wordprocessor.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File aa_wordprocessor.asm                 combined next generation V3.03.7
+;   File aa_wordprocessor.asm               * combined next generation V3.08.4l
 ;
 ;   Anti-aliased word processor
 ;
@@ -11,33 +11,31 @@
 ;  2010-12-01 : [jDG] Adding 3bits anti-aliased fonts
 ;  2010-12-30 : [jDG] Revised to put temp into ACCESSRAM0
 ;  2012-08-12 : [mH]  Moved font28 into bootloader section 0x1C000
-;
-; BUGS :
-;  * If the three fonts are not in the same half of the PROM memory, TBLPTRU
-;    will be badly set, and font48 or font90 will display gibberish...
-;=============================================================================
-;
-; MEMORY FOOTPRINT:
-;------------------
+
+
+;-----------------------------------------------------------------------------
+; Attention:
+; If the fonts are not in the same half of the PROM memory, TBLPTRU
+; will be set wrong and gibberish font output will result
+;-----------------------------------------------------------------------------
+
+
+;-----------------------------------------------------------------------------
+; Input registers:
+; ----------------
+;  buffer:26            string to print
+;  font_size            font size (0=tiny, 1=small, 2=std, 3=medium, 4=large, 5=XL)
+;  font_color           font color (8 bit)
+;  win_top, win_leftx2  output position on screen
+;  win_inverse          inverse video mode selection
 ;
-; wp_wordprocessor : 8   KB, including fonts
-; aa_wordprocessor : 0.5 KB code
-;                  + 3.5 KB aa_font28 (reduced to 99 chars)
-;                  + 1.6 KB aa_font48
-;                  + 2.2 KB aa_font90
-;                  = 7.9 KB including fonts
+; Trashed:
+; --------
+;  PRODH, PRODL         needed for array indexing
+;  FSRx                 12 bits, used for indirect addressing
 ;
-; Input registers:
-;  buffer:26            String to print
-;  win_font             Font size (0=tiny, 1=small, 2=std, 3=medium, 4=large, 5=XL)
-;  win_color1:2         16bits unpacked color
-;  win_top, win_leftx2  Position on screen
-;  win_inverse          Inverse video mode
-;
-; Available general purpose registers:
-;  PRODH, PRODL         needed for array indexing
-;  FSRx                 12bits, used for indirect addressing
-;=============================================================================
+;-----------------------------------------------------------------------------
+
 
 #include "hwos.inc"
 #include "tft.inc"
@@ -52,24 +50,38 @@
 	extern	convert_for_display2
 
 
+;=============================================================================
 aa_word		CODE
+;=============================================================================
 
-;=============================================================================
 
 ;------------------------------------------------------------------------------
-; Setup pointers for a char:
-; Inputs   WREG = char to draw, win_font
-; Output   aa_start, aa_end, win_height, AA_flags
-; Trashed  PRODH, PRODL, TBLPTR, TABLAT
+; Setup Pointers for a Char
+;
+; Input    WREG       char to draw
+;          font_size  selected font
+;
+; Output   aa_start    pointer to start of character bitmap
+;          aa_end      pointer to end   of character bitmap
+;          win_height  font height
+;          AA_flags    font attributes
+;
+; Trashed  PRODH
+;          PRODL
+;          TBLPTR
+;          TABLAT
 ;
 aa_char_setup:
-	movwf	PRODL					; save char into PROD for now
-	movf	win_font,W				; get font number (updates Z flag)
-	bnz		aa_char_1				; requested tiny font? (bra of no)
+	movwf	PRODL					; save char to draw in PROD for later use
+	movf	font_size,W				; get font size
 
 	; 0: TINY font -------------------------------------------------------
 	; Font TINY character folding...
 aa_char_0:
+	tstfsz	WREG					; requested tiny font?
+	bra		aa_char_1				; NO
+
+aa_char_00:
 	movlw	LOW   aa_font16_block
 	movwf	TBLPTRL
 	movlw	HIGH  aa_font16_block
@@ -83,6 +95,7 @@
 aa_char_1:
 	decfsz	WREG					; requested small font?
 	bra		aa_char_2				; NO
+
 	movlw	LOW   aa_font28_block
 	movwf	TBLPTRL
 	movlw	HIGH  aa_font28_block
@@ -96,6 +109,7 @@
 aa_char_2:
 	decfsz	WREG					; requested std font?
 	bra		aa_char_3				; NO
+
 	movlw	LOW   aa_font34_block
 	movwf	TBLPTRL
 	movlw	HIGH  aa_font34_block
@@ -108,6 +122,7 @@
 aa_char_3:
 	decfsz	WREG				 	; requested medium font?
 	bra		aa_char_4				; NO
+
 	movlw	LOW   aa_font48_block
 	movwf	TBLPTRL
 	movlw	HIGH  aa_font48_block
@@ -120,6 +135,7 @@
 aa_char_4:
 	decfsz	WREG				 	; requested large font?
 	bra		aa_char_5				; NO
+
 	movlw	LOW   aa_font90_block
 	movwf	TBLPTRL
 	movlw	HIGH  aa_font90_block
@@ -128,65 +144,68 @@
 	movwf	TBLPTRU
 	bra		aa_char_99
 
-	; 5: XTRA LARGE font -------------------------------------------------
+	; 5: EXTRA LARGE font ------------------------------------------------
 aa_char_5:
+	decfsz	WREG				 	; requested extra large font?
+	bra		aa_char_00				; NO - illegal font code, default to tiny font
+
 	movlw	LOW   aa_font92_block
 	movwf	TBLPTRL
 	movlw	HIGH  aa_font92_block
 	movwf	TBLPTRH
 	movlw	UPPER aa_font92_block
 	movwf	TBLPTRU
+	;bra	aa_char_99
 
 
-	; Execute font block -------------------------------------------------
+	; Execute Font Block -------------------------------------------------
 aa_char_99:
-	; This is safe if all fonts are in the same code segment
-	; (and that segment does not span the 64K edge...)
+	; this is safe if all fonts are in the same code segment
+	; (and this segment does not cross the 64 K boundary)
 	movlw	UPPER aa_font16_block
 	movwf	TBLPTRU
 
-	; Proceed to character substitutions
+	; execute the character substitutions
 aa_char_30:
 	tblrd*+							; read FROM char
-	movf	TABLAT,W				; get it, and set Z,N
-	bz		aa_char_32				; break at end of translations
+	movf	TABLAT,W				; get  FROM char
+	bz		aa_char_32				; break at end of translation table
 
 	tblrd*+							; read TO char
-	cpfseq	PRODL					; FROM == current char ?
-	bra		aa_char_30				; different -> loop
-	movff	TABLAT, PRODL			; make substitution
-	bra		aa_char_30				; loop
+	cpfseq	PRODL					; FROM char == current char ?
+	bra		aa_char_30				; NO  - different, loop
+	movff	TABLAT, PRODL			; YES - make substitution
+	bra		aa_char_30				;     - loop to consume the rest of the translations
 
-	; Make sure char is in the available range
+	; make sure char is within the font set
 aa_char_32:
-	tblrd*+							; read first char
-	movf	TABLAT,W				; get it
-	subwf	PRODL,F					; (char - first) --> PRODL
-	tblrd*+							; read nb chars
-	movf	TABLAT,W				; nbchars --> WREG
+	tblrd*+							; read code of first char in font set
+	movf	TABLAT,W				; get  code of first char in font set
+	subwf	PRODL,F					; compute code of current char - of first char
+	tblrd*+							; read number of chars in font set
+	movf	TABLAT,W				; get  number of chars in font set
 	tblrd*+							; read default char
-	cpfslt	PRODL					; char > WREG ?
-	movff	TABLAT,PRODL			; replace PRODL
+	cpfslt	PRODL					; current char beyond last char in font set?
+	movff	TABLAT,PRODL			; YES - current char with default char
 
-	; Decode font height and anti-aliasing mode
+	; decode font height and anti-aliasing mode
 	bcf		aa_antialias			; default to no AA
 	tblrd*+							; read font height + AA flag
-	movf	TABLAT,W				; into WREG
-	bnn		aa_char_34				; high bit set ?
+	movf	TABLAT,W				; get  font height + AA flag
+	btfsc	WREG,7					; AA bit set?
 	bsf		aa_antialias			; YES - then the font is AA
-aa_char_34:
-	andlw	0x7F					; keep just font height,
-	movwf	win_height				; then save it (its a register)
+	andlw	0x7F					; strip the AA bit
+	movwf	win_height				; store the font height
 
-	; Set PROM pointer to the char index
+	; set PROM pointer to the char index
 	movf	PRODL,W					; read back char
 	mullw	2						; PROD = 2*(char - base), TBLPTR=idx
-	movf	PRODL,W
-	addwf	TBLPTRL,F				; add into TBLPTR (low byte)
-	movf	PRODH,W
-	addwfc	TBLPTRH,F				; and high byte
+	movf	PRODL,W					; add to base address of font data
+	addwf	TBLPTRL,F				; ...
+	movf	PRODH,W					; ...
+	addwfc	TBLPTRH,F				; ...
 
-	; Read start and stop pointers
+	; read pointers to character bitmap
 	tblrd*+							; aa_start = PROM16(*tblptr++)
 	movff	TABLAT,aa_start+0		; read low byte
 	tblrd*+
@@ -197,126 +216,120 @@
 	tblrd*+
 	movff	TABLAT,aa_end+1			; and high byte
 
-	return
+	return							; done
 
 
 ;------------------------------------------------------------------------------
-; Character width
+; Compute Character Width
 ; Input    aa_start, aa_end, win_width, win_height, AA_flags
 ; Output   width added to win_width
 ; Trashed  aa_bitlen, TBLPTR, TABLAT
 ;
 aa_char_width:
 	movff	aa_start+0, TBLPTRL		; TBLPTR = aa_start
-	movff	aa_start+1, TBLPTRH
-	clrf	aa_bitlen				; clear reminders...
-
-	; Read bitmap byte, and decode length:
-aa_char_width_1:
+	movff	aa_start+1, TBLPTRH		; ...
+	clrf	aa_bitlen				; clear remaining pixels counter
 
-	ifdef AA_BYTE_SWAP
-		btg		TBLPTRL				; toggle low ptr bit
-		tblrd*
-		movf	TABLAT,W			; store to WREG
-		btg		TBLPTRL				; get is back
-		tblrd*+						; then increment (but trash TABLAT)
-		movwf	TABLAT				; then restore copy to TABLAT
-	else
-		tblrd*+						; normal read...
-		movf	TABLAT,W			; store copy to WREG
-	endif
-
+	; read bitmap byte and decode length
+aa_char_width_1:
+ ifdef AA_BYTE_SWAP
+	btg		TBLPTRL					; toggle low ptr bit
+	tblrd*							; read bitmap data
+	movf	TABLAT,W				; store to WREG
+	btg		TBLPTRL					; toggle back
+	tblrd*+							; do a dummy read to increment the pointer
+	movwf	TABLAT					; restore TABLAT
+ else
+	tblrd*+							; read bitmap data
+	movf	TABLAT,W				; store to WREG
+ endif
 	btfss	aa_antialias			; anti-aliased font ?
-	bra		aa_char_width_10		; NO - always 7 bit count
-
-	bn		aa_char_width_10		; none-white pixels?
-	andlw	0x1F					; YES - 5 bit count
+	bra		aa_char_width_10		; NO  - always 7 bit count
+	btfss	WREG,7					; YES - none-white pixels?
+	andlw	0x1F					;       YES - 5 bit count
 aa_char_width_10:
-	andlw	0x7F					; NO  - 7 bit count
-	incf	WREG 					; WREG = repetition count
-	addwf	aa_bitlen,F				; add remaining pixels from last code
+	andlw	0x7F					; mask out none-white pixel flag
+	incf	WREG,W					; WREG = repetition count
+	addwf	aa_bitlen,F				; add to remaining pixels
 
 	movf	win_height,W			; WREG -= height
-	negf	WREG
+	negf	WREG					; ...
 
-	; This is a hand-made division by successive subtraction of height
+	; this is a hand-made division by successive subtraction of the height
 aa_char_width_2:
-	addwf	aa_bitlen,F				; try to subtract win_height
-	bn		aa_char_width_3			; if neg it was a bad idea...
-
-	infsnz	win_width+0,F			; succeeded: do a 16 bit increment
-	incf	win_width+1,F			; on the win_width counter
-	bra		aa_char_width_2			; and loop
+	addwf	aa_bitlen,F				; try to subtract win_height, does it fit?
+	bn		aa_char_width_3			; NO  - done
+	infsnz	win_width+0,F			; YES - do a 16 bit increment of the win_width
+	incf	win_width+1,F			;     - ...
+	bra		aa_char_width_2			;     - loop
 
 aa_char_width_3:
 	negf	WREG					; WREG = +height
 	addwf	aa_bitlen,F				; restore true reminder
 
-	; Are we done ?
-	movf	TBLPTRL,W				; compare TBLPTR to aa_end
-	cpfseq	aa_end+0  
-	bra		aa_char_width_1			; loop if LOW is different
-	movf	TBLPTRH,W
-	cpfseq	aa_end+1				; loop to if HIGH is different
-	bra		aa_char_width_1
-	return
+	; all pixel data processed?
+	movf	TBLPTRL,W				; get TBLPTR, low  byte
+	cpfseq	aa_end+0				; TBLPTR, low  byte == end pointer, low  byte?
+	bra		aa_char_width_1			; NO  - loop
+	movf	TBLPTRH,W				; YES - get TBLPTR, high byte
+	cpfseq	aa_end+1				;     - TBLPTR, high byte == end pointer, high byte?
+	bra		aa_char_width_1			;       NO  - loop
+	return							;       YES - done
 
 
 ;------------------------------------------------------------------------------
-; String width
-; Input    buffer (SHOULD BE NULL TERMINATED)
+; Compute String Width
+; Input    buffer (NEEDS TO BE NULL TERMINATED)
 ; Output   win_width, win_height
 ; Trashed  PROD, TBLPTR, FSR2, aa_bitlen, aa_start, aa_end, AA_flags
 ;
 aa_string_width:
 	lfsr	FSR2, buffer			; FSR2 pointer to start of string
-	clrf	win_width+0				; clear width sum
-	clrf	win_width+1				; (16 bit counter)
+	clrf	win_width+0				; clear 16 bit width sum
+	clrf	win_width+1				; ...
 
 aa_string_width_1:
-	movf	POSTINC2,W  			; WREG = *FSR2++
+	movf	POSTINC2,W				; get character
 	bz		aa_string_width99		; exit if null byte encountered
 
-	rcall	aa_char_setup			; setup aa_start / aa_end
-	rcall	aa_char_width			; sum-up width into win_width
-	bra		aa_string_width_1		; and loop
+	rcall	aa_char_setup			; setup pointers for the char
+	rcall	aa_char_width			; win_width += character width
+	bra		aa_string_width_1		; loop
 
 aa_string_width99:
-	return
+	return							; done
 
 
 ;------------------------------------------------------------------------------
-; Decode a compressed char
+; Print a Character
 ; Input    aa_start, aa_end, win_height, win_invert, win_color1, win_color2
 ; Output   none
 ; Trashed  TBLPTR, TABLAT, PROD, aa_bitlen, AA_flags, aa_colorDir:2
 ;
 aa_decode_char:
-	movff	aa_start+0, TBLPTRL		; TBLPTR = aa_start
-	movff	aa_start+1, TBLPTRH
-
-	; Read bitmap byte, and decode color & length
-aa_decode_1:
+	movff	aa_start+0, TBLPTRL		; set TBLPTR to start of character data
+	movff	aa_start+1, TBLPTRH		; ...
 
-	ifdef AA_BYTE_SWAP
-		btg		TBLPTRL				; toggle low ptr bit
-		tblrd*
-		movf	TABLAT,W			; store to WREG
-		btg		TBLPTRL				; get is back
-		tblrd*+						; then increment (but trash TABLAT)
-		movwf	TABLAT				; then restore copy to TABLAT
-	else
-		tblrd*+						; normal read...
-		movf	TABLAT,W			; store copy to WREG
-	endif
-
-	btfss	aa_antialias			; anti-aliased font?
-	bra		aa_decode_10			; NO - always 7 bit count
-	bn		aa_decode_10			; none-white pixels?
-	andlw	0x1F					; Yes - 5 bit count
+	; read bitmap byte and decode color & length
+aa_decode_1:
+ ifdef AA_BYTE_SWAP
+	btg		TBLPTRL					; toggle low ptr bit
+	tblrd*							; read bitmap data
+	movf	TABLAT,W				; back-up TABLAT
+	btg		TBLPTRL					; toggle back
+	tblrd*+							; do a dummy read to increment the pointer
+	movwf	TABLAT					; restore TABLAT
+ else
+	tblrd*+							; normal read...
+	movf	TABLAT,W				; store copy to WREG
+ endif
+	btfss	aa_antialias			; anti-aliased font ?
+	bra		aa_decode_10			; NO  - always 7 bit count
+	btfss	WREG,7					; YES - none-white pixels?
+	andlw	0x1F					;       YES - 5 bit count
 aa_decode_10:
-	andlw	0x7F					; NO  - 7 bit count
-	incf	WREG
+	andlw	0x7F					; mask out none-white pixel flag
+	incf	WREG,W					; WREG = repetition count
 	movwf	aa_bitlen				; repetition count --> aa_bitlen
 
 	;---- COLOR DECODING -------------------------------------------------
@@ -327,25 +340,24 @@
 	;   010       50%       50%
 	;   001       75%       25%
 	;   000      100%        0% : Managed by aa_decode_13, too
-	;
-	movf	TABLAT,W				; get back code
+
+	movf	TABLAT,W				; get back pixel data
 	btfss	aa_antialias			; anti-aliased font?
 	bra		aa_decode_13			; NO - 1 bit case
 
-	; Asymmetry test: 1xx code is another case for 1bit color.
-	; This have to be done before inverse video, because
-	; of the asymmetric processing!
+	; asymmetry test: 1xx code is another case for 1 bit color
+	; This has to be done before inverse video, because of the asymmetric processing!
 	bn		aa_decode_13			; decode as none-aa
 
-	; Manage 000 special case too:
+	; manage 000 special case
 	andlw	0xE0					; select color bits, is it a 000 ?
 	bz		aa_decode_13			; YES
 
-	; Apply reverse video, in a reversed way
+	; apply reverse video, in a reversed way
 	btfss	win_invert				; inverse video mode?
 	sublw	0x80					; NO
 
-	; Extract color quarter and color half information
+	; extract color quarter and color half information
 	bsf		aa_antialias			; set AA mode
 	bcf		aa_color_quarter		; default to no color quarter
 	btfsc	WREG,5					; color quarter encoded?
@@ -355,10 +367,10 @@
 	bsf		aa_color_half			; YES - set flag
 
 	;---- 2 bit x RGB(16bits) computation --------------------------------
-	clrf	PRODL					; we will accumulate result here...
-	clrf	PRODH
+	clrf	PRODL					; clear accumulator
+	clrf	PRODH					; ...
 
-	; Take color div 2 into aa_temp. Max red = 15/31
+	; take color / 2 into aa_temp (max red = 15/31)
 	rrcf	win_color1,W			; xRRRRxGG
 	andlw	b'01111011'				; 0RRRR0GG (don't change C)
 	movwf	aa_temp+0
@@ -366,16 +378,16 @@
 	andlw	b'11101111'				; GGG0BBBB
 	movwf	aa_temp+1
 
-	btfss	aa_color_half
-	bra		aa_decode_12
+	btfss	aa_color_half			; color half encoded?
+	bra		aa_decode_12			; NO
+	movff	aa_temp+0,PRODH			; YES - add color/2, TFT is big endian, so swap here
+	movff	aa_temp+1,PRODL			;     - ...
 
-	movff	aa_temp+0,PRODH			; add color/2 if bit set
-	movff	aa_temp+1,PRODL			; TFT is big endian, so swap here
 aa_decode_12:
-	btfss	aa_color_quarter
-	bra		aa_decode_3
+	btfss	aa_color_quarter		; color quarter encoded?
+	bra		aa_decode_3				; NO
 
-	; Divide it once again by 2. Max red = 7/31.
+	; divide once again by 2 (max red = 7/31)
 	rrcf	aa_temp+0,W				; xxRRRxxG
 	andlw	b'00111001'				; 00RRR00G (don't change C)
 	movwf	aa_temp+0
@@ -389,30 +401,27 @@
 	addwfc	PRODH,F					; in right order, to propagate carry
 
 aa_decode_12b:
-	btfss	screen_type2			; display 2?
-	bra		aa_decode_3				; NO - done
-
-	call	convert_for_display2	; convert 16 bit RGB b'RRRRRGGG GGGBBBBB' into 24 bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00'
+	btfsc	screen_type2			; display type 2 ?
+	call	convert_for_display2	; YES - convert 16 bit RGB b'RRRRRGGG GGGBBBBB' into 24 bit RGB b'RRRRRR00 GGGGGG00 BBBBBB00'
+	bra		aa_decode_3				; continue
 
-	bra		aa_decode_3				; done
-
-	; ---- Simple BLACK and WHITE cases ------------------------------
-aa_decode_13:						; got a 1xx or a 000 code...
-	btfsc	win_invert				; inverse video mode ?
+	; ---- simple BLACK and WHITE cases ------------------------------
+aa_decode_13:						; got a 1xx or a 000 code
+	btfsc	win_invert				; inverse video mode?
 	xorlw	0x80					; YES - invert levels
-	bn		aa_decode_2				; then test high bit
+	bn		aa_decode_2				; black pixel? -> YES
 
 	; WHITE pixel (i.e. full color)
-	movff	win_color1,PRODH		; current draw color
-	movff	win_color2,PRODL		; remark: DISPLAY is big endian
-	bra		aa_decode_12b
+	movff	win_color1,PRODH		; set current drawing color (display is big endian)
+	movff	win_color2,PRODL		; ...
+	bra		aa_decode_12b			; post-process in case of display type 2
 
 aa_decode_2:
-	clrf	PRODH					; BLACK pixel
-	clrf	PRODL
-	clrf	win_color5
-	clrf	win_color4
-	clrf	win_color3
+	clrf	PRODH					; set drawing color to black
+	clrf	PRODL					; ...
+	clrf	win_color5				; set drawing color to black (display type 2)
+	clrf	win_color4				; ...
+	clrf	win_color3				; ...
 
 aa_decode_3:
 	;---- PIXEL WRITE LOOP -----------------------------------------------
@@ -426,75 +435,76 @@
 	movff	PRODH,PORTA				; move high byte to PORTA
 	movff	PRODL,PORTH				; move low  byte to PORTH
 aa_decode_3_display0and1:
-	bcf		tft_nwr
-	bsf		tft_nwr					; tick
-	decf	aa_bitlen,F
-	bnz		aa_decode_3_display0and1
-	bra		aa_decode_3_done
+	bcf		tft_nwr					; tick
+	bsf		tft_nwr					; ...
+	decfsz	aa_bitlen,F				; decrement length counter, became zero?
+	bra		aa_decode_3_display0and1; NO  - loop
+	bra		aa_decode_3_done		; YES -  done
 
 aa_decode_3_display2:
-	movff	win_color5,PORTH		; move high byte to PORTH (DISPLAY is big endian)
-	bcf		tft_nwr
-	bsf		tft_nwr					; tick
-	movff   win_color4,PORTH		; move low byte to PORTH
-	bcf		tft_nwr
-	bsf		tft_nwr					; tick
-	movff   win_color3,PORTH		; move low(est) byte to PORTH
-	bcf		tft_nwr
-	bsf		tft_nwr					; tick
-	decf	aa_bitlen,F
-	bnz		aa_decode_3_display2
-	bra		aa_decode_3_done
+	movff	win_color5,PORTH		; move high byte to PORTH (display is big endian)
+	bcf		tft_nwr					; tick
+	bsf		tft_nwr					; ...
+	movff	win_color4,PORTH		; move low byte to PORTH
+	bcf		tft_nwr					; tick
+	bsf		tft_nwr					; ...
+	movff	win_color3,PORTH		; move low(est) byte to PORTH
+	bcf		tft_nwr					; tick
+	bsf		tft_nwr					; ...
+	decfsz	aa_bitlen,F				; decrement length counter, became zero?
+	bra		aa_decode_3_display2	; NO  - loop
+	bra		aa_decode_3_done		; YES - done
 
 aa_decode_3_display3:
-	movff	PRODH,PORTH				; move high byte to PORTH (DISPLAY is big endian)
-	bcf		tft_nwr
-	bsf		tft_nwr					; tick
-	movff	PRODL,PORTH				; move low byte to PORTH
-	bcf		tft_nwr
-	bsf		tft_nwr					; tick
-	decf	aa_bitlen,F
-	bnz		aa_decode_3_display3
+	movff	PRODH,PORTH				; move high byte to PORTH (display is big endian)
+	bcf		tft_nwr					; tick
+	bsf		tft_nwr					; ...
+	movff	PRODL,PORTH				; move low  byte to PORTH
+	bcf		tft_nwr					; tick
+	bsf		tft_nwr					; ...
+	decfsz	aa_bitlen,F				; decrement length counter, became zero?
+	bra		aa_decode_3_display3	; NO  - loop
 
 aa_decode_3_done:
 	;---- BYTE-CODE LOOP -------------------------------------------------
-	; are we done ?
-	movf	TBLPTRL,W				; compare TBLPTR with aa_end
-	cpfseq	aa_end+0
-	bra		aa_decode_1				; loop if LOW is different
-	movf	TBLPTRH,W
-	cpfseq	aa_end+1				; loop to if HIGH is different
-	bra		aa_decode_1
-	return
+	; all pixel data processed?
+	movf	TBLPTRL,W				; get TBLPTR, low  byte
+	cpfseq	aa_end+0				; TBLPTR, low  byte == end pointer, low  byte?
+	bra		aa_decode_1				; NO  - loop
+	movf	TBLPTRH,W				; YES - get TBLPTR, high byte
+	cpfseq	aa_end+1				;     - TBLPTR, high byte == end pointer, high byte?
+	bra		aa_decode_1				;       NO  - loop
+	return							;       YES - done
 
 
 ;------------------------------------------------------------------------------
-; Setup pointers for a char:
-; Inputs : buffer : string to print (NULL TERMINATED)
-; Output : TFT commands on PORTH (Upper) and PORTA (lower) + clocks
+; Print the Output Buffer to Screen
 ;
-	global	aa_wordprocessor		; callable from C-code
+; Input   buffer - string to print (NULL TERMINATED)
+; Output  chars printed to screen
+;
+	global	aa_wordprocessor
 aa_wordprocessor:
-	rcall	aa_string_width			; set win_height, compute win_width:2
-	call	TFT_box_write			; use that for the box
-
-	; Restart the loop for each char to print
-	lfsr	FSR2, buffer			; FSR2 points to the start of the string
-
-	; DATA block command
-	Index_out	0x22				; index_out is a macro defined in tft.inc
+	movf	font_color,W			; get selected font color (8 bit)
+	call	TFT_set_color			; compute printing color (16 bit)
+	rcall	aa_string_width			; set win_height and compute win_width:2
+	call	TFT_box_write			; set up output box
+	lfsr	FSR2,buffer				; set FSR2 to the start of the output buffer
+	Index_out	0x22				; DATA block command (macro defined in tft.inc)
 
 aa_wordprocessor_1:
-	movf	POSTINC2,W				; WREG = *FSR2++
-	bz		aa_wordprocessor_99		; exit if null byte encountered
+	movf	POSTINC2,W				; read character from the buffer
+	bz		aa_wordprocessor_99		; done if null byte encountered
 
-	rcall	aa_char_setup			; setup aa_start / aa_end
-	rcall	aa_decode_char			; write pixels to screen
-	bra		aa_wordprocessor_1		; and loop
+	rcall	aa_char_setup			; setup pointers for the char
+	rcall	aa_decode_char			; print character to screen
+	bra		aa_wordprocessor_1		; loop
 
 aa_wordprocessor_99:
-	; END of bloc command
-	Index_out	0x00
-	return
+	Index_out	0x00				; send end of bloc command
+	bcf		win_invert				; terminate inverse printing
+	return							; done
+
+;------------------------------------------------------------------------------
 
 	END
--- a/src/adc_lightsensor.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/adc_lightsensor.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File adc_lightsensor.asm                  combined next generation V3.08.8
+;   File adc_lightsensor.asm                * combined next generation V3.09.4e
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -15,21 +15,34 @@
 #include "i2c.inc"
 
 
+;=============================================================================
 adc_light	CODE
-
 ;=============================================================================
 
-wait_adc:									; bank-safe
+
+;-----------------------------------------------------------------------------
+; Helper Function - wait on ADC to finish conversion
+;
+; bank safe
+;
+wait_adc:
 	movwf	ADCON0							; select ADC channel
 	nop										; wait a short moment
+	nop										; ...
+	nop										; .....
+	nop										; .......
 	bsf		ADCON0,1						; start ADC
 wait_adc2:
 	btfsc	ADCON0,1						; ADC done?
 	bra		wait_adc2						; NO  - wait
 	return									; YES - done
 
+
+;-----------------------------------------------------------------------------
+; get Battery Voltage
+;
 	global	get_battery_voltage
-get_battery_voltage:						; start ADC and wait until finished
+get_battery_voltage:
 	btfss	battery_gauge_available			; battery gauge IC available?
 	bra		get_battery_voltage_2			; NO  - OSTC hardware without gauge IC
 	bsf		battery_is_36v					; YES - gauge IC available, 3.6V battery
@@ -106,7 +119,7 @@
 	MOVII	ADRESL,batt_voltage				; store value
 	bcf		ADCON0,0						; power off ADC
 
-; Multiply with 2.006 to be exact here...
+;	; multiply with 2.006 to be exact here...
 ;	bcf		STATUS,C
 ;	rlcf	xA+0,F
 ;	rlcf	xA+1,F							; x2
@@ -115,14 +128,14 @@
 	bcf		battery_is_36v					; by default assume it is a 1.5 battery
 	MOVII	batt_voltage,sub_b				; load measured battery voltage
 
-	; Check if the battery is a 3.6V lithium
+	; check if the battery is a 3.6V lithium
 	MOVLI	lithium_36v_low,sub_a			; load threshold for 3.6 Volt lithium battery
 	call	cmpU16							; sub_a - sub_b
 	btfss	neg_flag						; battery voltage > 3.6 V lithium threshold ?
 	bra		get_battery_voltage_9			; NO  - keep assumption of 1.5V battery
 	bsf		battery_is_36v					; YES - set flag
 
-	; Check if the battery is near-dead already
+	; check if the battery is near-dead already
 	MOVLI	lithium_36v_empty,sub_a			; load threshold for near-dead lithium battery
 	call	cmpU16							; sub_a - sub_b
 	btfsc	neg_flag						; battery voltage > dead-battery threshold ?
@@ -213,7 +226,6 @@
 	bcf		battery_low_condition			; NO  - clear battery low condition
 	return									;     - done
 
-
 get_battery_voltage_9:
 	; use 1.5V battery voltage mode
 	; use approximation (batt_voltage-aa_15v_low)/4 = lo
@@ -230,7 +242,12 @@
 	bra		get_battery_voltage_8			; check limits and return
 
 
-	global	get_ambient_level				; called from ISR only, in context bank isr_backup
+;-----------------------------------------------------------------------------
+; get ambient Light Level
+;
+; called from ISR only, in context bank isr_backup
+;
+	global	get_ambient_level
 get_ambient_level:
 	btfsc	sleepmode						; in sleep mode?
 	return									; YES - done
@@ -261,18 +278,28 @@
 
 	; ambient_light:2 is between 4096 (direct sunlight) and about 200 (darkness)
 	; first: divide by 16
-	bcf		STATUS,C
-	rrcf	ambient_light+1
-	rrcf	ambient_light+0
-	bcf		STATUS,C
-	rrcf	ambient_light+1
-	rrcf	ambient_light+0
-	bcf		STATUS,C
-	rrcf	ambient_light+1
-	rrcf	ambient_light+0
-	bcf		STATUS,C
-	rrcf	ambient_light+1
-	rrcf	ambient_light+0
+
+	; bcf	STATUS,C						; old /16 code
+	; rrcf	ambient_light+1
+	; rrcf	ambient_light+0
+	; bcf	STATUS,C
+	; rrcf	ambient_light+1
+	; rrcf	ambient_light+0
+	; bcf	STATUS,C
+	; rrcf	ambient_light+1
+	; rrcf	ambient_light+0
+	; bcf	STATUS,C
+	; rrcf	ambient_light+1
+	; rrcf	ambient_light+0
+
+	movlw	.4								; divide by 2^4 = 16
+get_ambient_level1_loop:
+	bcf		STATUS,C						; clear carry
+	rrcf	ambient_light+1					; rotate right high byte, carry into MSB, LSB into carry
+	rrcf	ambient_light+0					; rotate right low  byte, carry into MSB, LSB into carry
+	decfsz	WREG							; decrement counter, done?
+	bra		get_ambient_level1_loop			; NO  - loop
+
 	; result: ambient_light:2/16
 	; now make sure to have value between ambient_light_low and ambient_light_max
 
@@ -296,6 +323,7 @@
 
 	btfsc	RCSTA1,7						; UART module on?
 	clrf	isr_lo							; YES - set temporary to eco mode
+
 	incf	isr_lo,F						; adjust 0-2 to 1-3
 
 	movlw	ambient_light_max_high_cr		; cR and 2 hardware brightest setting
@@ -307,127 +335,104 @@
 	movlw	ambient_light_max_high_36V		; YES - 3.6V battery brightest setting
 	banksel	isr_backup						; back to ISR default bank
 
-	dcfsnz	isr_lo,F
-	movlw	ambient_light_max_eco			; eco setting
-	dcfsnz	isr_lo,F
-	movlw	ambient_light_max_medium		; brightest setting
+	dcfsnz	isr_lo,F						; eco setting?
+	movlw	ambient_light_max_eco			; YES
+	dcfsnz	isr_lo,F						; medium setting?
+	movlw	ambient_light_max_medium		; YES
 
 	incf	ambient_light+0,F				; +1
 	cpfslt	ambient_light+0					; smaller than WREG?
 	movwf	ambient_light+0					; NO - set to max.
 
-	movff	opt_brightness,isr_lo
+	movff	opt_brightness,isr_lo			; get brightness setting
 	incf	isr_lo,F						; adjust 0-2 to 1-3
-	movlw	ambient_light_min_high			; darkest setting
-	dcfsnz	isr_lo,F
-	movlw	ambient_light_min_eco			; darkest setting
-	dcfsnz	isr_lo,F
-	movlw	ambient_light_min_medium		; darkest setting
-	dcfsnz	isr_lo,F
-	movlw	ambient_light_min_high			; darkest setting
+	movlw	ambient_light_min_high			; default to highest setting
+	dcfsnz	isr_lo,F						; eco setting?
+	movlw	ambient_light_min_eco			; YES
+	dcfsnz	isr_lo,F						; medium setting?
+	movlw	ambient_light_min_medium		; YES
+	dcfsnz	isr_lo,F						; highest setting?
+	movlw	ambient_light_min_high			; YES
 
 	cpfsgt	ambient_light+0					; bigger than WREG?
 	movwf	ambient_light+0					; NO - set to min
 
 	movff	ambient_light+0,max_CCPR1L		; store value for dimming in TMR7 interrupt
-	return
+	return									; done
 
 
-;=============================================================================
-; routines for reading analog-attached external sensors
+;-----------------------------------------------------------------------------
+; Read analog external Sensors
+;
+; called from outside ISR only
 ;
  IFDEF _external_sensor
 
-	global	get_analog_inputs				; called from outside ISR only
-get_analog_inputs:							; start ADC and wait until finished
+	global	get_analog_inputs
+get_analog_inputs:
 	bsf		adc_is_running					; =1: the ADC is in use
-	btfsc	TFT_PWM
-	bra		get_analog_inputs				; wait for PWM low
+	btfsc	TFT_PWM							; PWM active?
+	bra		get_analog_inputs				; YES - wait for PWM low
+
 	movlw	b'00100000'						; 2.048V Vref+ -> 1 LSB = 500 µV
-	movwf	ADCON1
-	banksel	sensor1_mv						; select bank where sensor1_mv is stored
+	movwf	ADCON1							; ...
+
 	; Sensor 1
 	movlw	b'00100001'						; power on ADC, select AN8
-	rcall	wait_adc
-	bcf		STATUS,C
-	rrcf	ADRESH,F						; /2
-	rrcf	ADRESL,W
-	addwf	sensor1_mv+0,F					; add to sensor1_mv:2
-	movf	ADRESH,W
-	addwfc	sensor1_mv+1,F
-	bcf		STATUS,C
-	rrcf	sensor1_mv+1,F					; divide /2
-	rrcf	sensor1_mv+0,F
-	movlw	HIGH ignore_mv
-	cpfsgt	sensor1_mv+1					; > ignore_mv ?
-	bra		get_analog_inputs1a				; NO
-	CLRI	sensor1_mv						; YES - ignore this reading
-get_analog_inputs1a:						; ignore 1.9 mV noise for not-connected inputs
-	tstfsz	sensor1_mv+1					; > 25.5 mV ?
-	bra		get_analog_inputs2				; YES - skip here
-	movlw	.19
-	cpfsgt	sensor1_mv+0					; > 1.9 mV ?
-	clrf	sensor1_mv+0					; NO - clear result
+	MOVII	sensor1_mv,mpr					; get last sensor voltage
+	rcall	get_analog_inputs_common		; update value
+	MOVII	mpr,sensor1_mv					; store new value
 
-get_analog_inputs2:
 	; Sensor 2
 	movlw	b'00100101'						; power on ADC, select AN9
-	rcall	wait_adc
-	bcf		STATUS,C
-	rrcf	ADRESH,F						; /2
-	rrcf	ADRESL,W
-	addwf	sensor2_mv+0,F					; add to sensor2_mv:2
-	movf	ADRESH,W
-	addwfc	sensor2_mv+1,F
-	bcf		STATUS,C
-	rrcf	sensor2_mv+1,F					; divide /2
-	rrcf	sensor2_mv+0,F
-	movlw	HIGH ignore_mv
-	cpfsgt	sensor2_mv+1					; > ignore_mv ?
-	bra		get_analog_inputs2a				; NO
-	CLRI	sensor2_mv						; YES - ignore this reading
-get_analog_inputs2a:						; ignore 1.9 mV noise for not-connected inputs
-	tstfsz	sensor2_mv+1					; > 25.5 mV ?
-	bra		get_analog_inputs3				; YES - skip here
-	movlw	.19
-	cpfsgt	sensor2_mv+0					; > 1.9 mV ?
-	clrf	sensor2_mv+0					; NO - clear result
+	MOVII	sensor2_mv,mpr					; get last sensor voltage
+	rcall	get_analog_inputs_common		; update value
+	MOVII	mpr,sensor2_mv					; store new value
 
-get_analog_inputs3:
 	; Sensor 3
 	movlw	b'00101001'						; power on ADC, select AN10
-	rcall	wait_adc
-	bcf		STATUS,C
-	rrcf	ADRESH,F						; /2
-	rrcf	ADRESL,W
-	addwf	sensor3_mv+0,F					; add to sensor3_mv:2
-	movf	ADRESH,W
-	addwfc	sensor3_mv+1,F
-	bcf		STATUS,C
-	rrcf	sensor3_mv+1,F					; divide /2
-	rrcf	sensor3_mv+0,F
-	movlw	HIGH ignore_mv
-	cpfsgt	sensor3_mv+1					; > ignore_mv ?
-	bra		get_analog_inputs3a				; NO
-	CLRI	sensor3_mv						; YES - ignore this reading
-get_analog_inputs3a:						; ignore 1.9 mV noise for not-connected inputs
-	tstfsz	sensor3_mv+1					; > 25.5 mV ?
-	bra		get_analog_inputs4				; YES - skip here
-	movlw	.19
-	cpfsgt	sensor3_mv+0					; > 1.9 mV ?
-	clrf	sensor3_mv+0					; NO - clear result
-get_analog_inputs4:
-	banksel	common							; back to bank common
+	MOVII	sensor3_mv,mpr					; get last sensor voltage
+	rcall	get_analog_inputs_common		; update value
+	MOVII	mpr,sensor3_mv					; store new value
+
 	bcf		ADCON0,0						; power off ADC
 	bcf		adc_is_running					; done with ADC
-	return
+	return									; done
+
+get_analog_inputs_common:
+	rcall	wait_adc						; wait for ADC
+	bcf		STATUS,C						; clear carry flag
+	rrcf	ADRESH,F						; divide /2
+	rrcf	ADRESL,W						; ...
+	addwf	mpr+0,F							; add to sensor_mv:2
+	movf	ADRESH,W						; ...
+	addwfc	mpr+1,F							; ...
+	bcf		STATUS,C						; clear carry flag
+	rrcf	mpr+1,F							; divide /2
+	rrcf	mpr+0,F							; ...
+	movlw	HIGH ignore_mv_above			; get upper limit of operational range
+	cpfsgt	mpr+1							; > limit ?
+	bra		get_analog_inputs_common_1		; NO  - ok to use
+	CLRI	mpr								; YES - ignore this reading
+	return									;     - done
+get_analog_inputs_common_1:
+	tstfsz	mpr+1							; > 25.5 mV ?
+	return									; YES - ok to use anyway
+	movlw	ignore_mv_below					; NO  - get lower limit of operational range
+	cpfsgt	mpr+0							;     - > limit ?
+	clrf	mpr+0							;       NO - ignore this reading
+	return									;     - done
 
  ENDIF	; _external_sensor
 
-;=============================================================================
 
-	global	piezo_config					; called from outside ISR only
-piezo_config:								; set up sensitivity of heinrichsweikamp piezo buttons (~30ms)
+;-----------------------------------------------------------------------------
+; Set the Sensitivity of the Piezo Buttons
+; 
+; called from outside ISR only, ~ 30 ms
+;
+	global	piezo_config
+piezo_config:
 	clrf	TMR5H							; clear TMR5H first
 	clrf	TMR5L							; clear TMR5L thereafter
 	bcf		PIR5,TMR5IF						; clear timer 5 overrun flag, will take ~ 2 seconds to overrun after reset
@@ -442,195 +447,212 @@
 	btfss	PIR5,TMR5IF						; timeout?
 	bra		piezo_config0					; NO - not yet, loop
 
-	bcf		INTCON,GIE
+	bcf		INTCON,GIE						; disable all interrupts
 
 	movff	opt_cR_button_right,WREG		; right button
 	btfsc	flip_screen						; 180° rotation ?
 	movff	opt_cR_button_left,WREG			; YES - left button
-	rcall	piezo_config_tx
+	rcall	piezo_config_tx					; send to button
 
 	movff	opt_cR_button_left,WREG			; left button
 	btfsc	flip_screen						; 180° rotation ?
 	movff	opt_cR_button_right,WREG		; YES - right button
-	rcall	piezo_config_tx
+	rcall	piezo_config_tx					; send to button
 
 	movlw	.20								; reserved
-	rcall	piezo_config_tx
+	rcall	piezo_config_tx					; send to button
 	movlw	.20								; reserved
-	rcall	piezo_config_tx
+	rcall	piezo_config_tx					; send to button
+
+	bsf		INTCON,GIE						; re-enable all interrupts
+	return									; done
+
 
-	bsf		INTCON,GIE
-	return
-
-piezo_config_tx:							; send one byte
-	movwf	lo								; store byte
-	movlw	.8
-	movwf	hi								; bit counter
+;-----------------------------------------------------------------------------
+; Helper Function - send 1 Byte to the Piezo Buttons
+;
+piezo_config_tx:
+	movwf	lo								; store byte to be sent
+	movlw	.8								; set up bit count
+	movwf	hi								; ...
 	bcf		TX3_PIEZO_CFG					; start bit
-	rcall	piezo_config_wait_bit
-piezo_config_tx_loop:
-	btfss	lo,0							; LSB first
-	bcf		TX3_PIEZO_CFG
-	btfsc	lo,0							; LSB first
-	bsf		TX3_PIEZO_CFG
-	rcall	piezo_config_wait_bit
-	rrncf	lo,F
-	decfsz	hi,F
-	bra		piezo_config_tx_loop
-	bsf		TX3_PIEZO_CFG					; stop bit
-	rcall	piezo_config_wait_bit
-	return
+	rcall	piezo_config_wait_bit			; wait
+piezo_config_tx_loop:						; LSB first
+	btfss	lo,0							; bit = 0 ?
+	bcf		TX3_PIEZO_CFG					; YES
+	btfsc	lo,0							; bit = 1 ?
+	bsf		TX3_PIEZO_CFG					; YES
+	rcall	piezo_config_wait_bit			; wait
+	rrncf	lo,F							; shift lo to access next bit
+	decfsz	hi,F							; decrement bit counter, all done?
+	bra		piezo_config_tx_loop			; NO  - loop
+	bsf		TX3_PIEZO_CFG					; YES - stop bit
+	rcall	piezo_config_wait_bit			;     - wait
+	return									;     - done
 
 piezo_config_wait_bit:
 	setf	TMR5H							; set TMR5H first (to 255)
-	movlw	.255-.26 						; 26 x 31.5 µs = 819 us
+	movlw	.255-.26 						; 26 x 31.5 µs = 819 µs
 	movwf	TMR5L							; set TMR5L thereafter
 	bcf		PIR5,TMR5IF						; clear timer 5 overrun flag
-piezo_config_wait_bit3:
+piezo_config_wait_bit_loop:
 	btfss	PIR5,TMR5IF						; timeout?
-	bra		piezo_config_wait_bit3			; NO  - loop
+	bra		piezo_config_wait_bit_loop		; NO  - loop
 	return									; YES - done
 
 
-	global	get_analog_switches				; called from ISR and from sleep mode, returns in bank common
-get_analog_switches:						; start ADC and wait until finished
-	banksel	HW_variants						; switch to bank where OSTC model variant is stored
+;-----------------------------------------------------------------------------
+; get the analog Switches
+;
+; called from ISR and from sleep mode, returns in bank common
+;
+	global	get_analog_switches
+get_analog_switches:
 	btfsc	analog_switches					; does the OSTC have analog switches?
 	bra		get_analog_switches_1			; YES
+
 get_analog_switches0:
-	banksel	common							; NO  - back to bank common
-	bcf		analog_sw1_pressed				;     - clear flag for analog switch 1
-	bcf		analog_sw2_pressed				;     - clear flag for analog switch 2
-	return									;     - done
+	bcf		analog_sw1_pressed				; clear flag for analog switch 1
+	bcf		analog_sw2_pressed				; clear flag for analog switch 2
+	return									; done
 
 get_analog_switches_1:
-	banksel	common							; back to bank common
 	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_switches_2			;       NO  - read switches
 
 get_analog_switches_2:
-	bsf		adc_is_running
+	bsf		adc_is_running					; flag that ADC is in use
 	bcf		ADCON2,ADFM						; left justified
-	clrf	ADCON1
+	clrf	ADCON1							;
 	movlw	b'00100101'						; power on ADC, select AN9
-	rcall	wait_adc
+	rcall	wait_adc						; wait for ADC
 
 	banksel	isr_backup						; select bank ISR data
-	movff	ADRESH,WREG
-	addwf	analog_sw2_raw+0
-	movlw	.0
-	addwfc	analog_sw2_raw+1
+
+	movlw	.250							; set   upper limit
+	cpfslt	ADRESH							; above upper limit?
+	movff	analog_sw2,ADRESH				; YES - use (last) average instead
+
+	movf	ADRESH,W						; get ADC result (high byte)
+	addwf	analog_sw2_raw+0				; add to averaging register
+	movlw	.0								; ...
+	addwfc	analog_sw2_raw+1				; ...
 	decfsz	analog_counter,F				; continue averaging?
 	bra		get_analog_switches_2a			; YES
-	bcf		STATUS,C						; NO  - done, compute average
-	rrcf	analog_sw2_raw+1
-	rrcf	analog_sw2_raw+0				; /2
-	bcf		STATUS,C
-	rrcf	analog_sw2_raw+1
-	rrcf	analog_sw2_raw+0				; /4
-	bcf		STATUS,C
-	rrcf	analog_sw2_raw+1
-	rrcf	analog_sw2_raw+0				; /8
-	bcf		STATUS,C
-	rrcf	analog_sw2_raw+1
-	rrcf	analog_sw2_raw+0				; /16
-	movff	analog_sw2_raw+0,analog_sw2
-	clrf	analog_sw2_raw+1
-	clrf	analog_sw2_raw+0				; reset average registers
-;	movlw	.16
-;	movwf	analog_counter					; only once...
+
+	; compute average - divide by 16
+	swapf	analog_sw2_raw+1,F				; swap nibbles in high byte
+	movlw	b'11110000'						; keep only upper nibble
+	andwf	analog_sw2_raw+1,W				; ...
+	movwf	analog_sw2						; copy ex lower nibble of high byte to upper nibble of result
+	swapf	analog_sw2_raw+0,F				; swap nibble in low  byte
+	movlw	b'00001111'						; keep only lower nibble
+	andwf	analog_sw2_raw+0,W				; ...
+	iorwf	analog_sw2,F					; copy ex upper nibble of low  byte to lower nibble of result
+
+	clrf	analog_sw2_raw+1				; reset average registers
+	clrf	analog_sw2_raw+0				; ...
 
 get_analog_switches_2a:
 	bcf		analog_sw2_pressed				; default to not pressed
-	movff	opt_cR_button_left,WREG			; 20-100
-	bcf		STATUS,C
+	movff	opt_cR_button_left,WREG			; get button sensitivity (20-100)
+	bcf		STATUS,C						; clear carry bit
 	rrcf	WREG							; /2 -> 10-50
-	bcf		STATUS,C
-	rrcf	WREG							; /2 -> 5-25
+	bcf		STATUS,C						; clear carry bit
+	rrcf	WREG							; /4 -> 5-25
 	decf	WREG,W							; -1
 	decf	WREG,W							; -1
 	decf	WREG,W							; -1 -> 2-22
 	btfss	button_polarity,1				; (1= normal, 0=inverted)
-	bra		get_analog_switches_sw2_inv
-	addwf	analog_sw2,W					; average (~128)
-	cpfsgt	ADRESH							; pressed?
-	bra		get_analog_switches_3			; NO
-	bra		get_analog_switches_sw2_pressed	; YES (left button normal)
+	bra		get_analog_switches_sw2_inv		; 0
+	addwf	analog_sw2,W					; 1 - add average (~128)
+	cpfsgt	ADRESH							;   - pressed?
+	bra		get_analog_switches_3			;     NO  - continue with other button
+	bra		get_analog_switches_sw2_pressed	;     YES - (left button normal)
 
 get_analog_switches_sw2_inv:
-	subwf	analog_sw2,W					; average (~128)
+	subwf	analog_sw2,W					; subtract average (~128)
 	cpfslt	ADRESH							; pressed?
-	bra		get_analog_switches_3			; NO
-	;bra	get_analog_switches_sw2_pressed	; YES (left button inverted)
+	bra		get_analog_switches_3			; NO  - continue with other button
+	;bra	get_analog_switches_sw2_pressed	; YES - (left button inverted)
 
 get_analog_switches_sw2_pressed:
 	bsf		analog_sw2_pressed				; set left button as pressed
 
 get_analog_switches_3:
 	movlw	b'00101001'						; power on ADC, select AN10
-	rcall	wait_adc
-	movff	ADRESH,WREG
-	addwf	analog_sw1_raw+0
-	movlw	.0
-	addwfc	analog_sw1_raw+1
+	rcall	wait_adc						; wait on ADC
+
+	movlw	.250							; set   upper limit
+	cpfslt	ADRESH							; above upper limit?
+	movff	analog_sw1,ADRESH				; YES - use (last) average instead
+
+	movf	ADRESH,W						; get ADC result (high byte)
+	addwf	analog_sw1_raw+0				; add to averaging register
+	movlw	.0								; ...
+	addwfc	analog_sw1_raw+1				; ...
 	tstfsz	analog_counter					; continue averaging?
 	bra		get_analog_switches_3a			; YES
-	bcf		STATUS,C						; NO - done, compute average
-	rrcf	analog_sw1_raw+1
-	rrcf	analog_sw1_raw+0				; /2
-	bcf		STATUS,C
-	rrcf	analog_sw1_raw+1
-	rrcf	analog_sw1_raw+0				; /4
-	bcf		STATUS,C
-	rrcf	analog_sw1_raw+1
-	rrcf	analog_sw1_raw+0				; /8
-	bcf		STATUS,C
-	rrcf	analog_sw1_raw+1
-	rrcf	analog_sw1_raw+0				; /16
-	movff	analog_sw1_raw+0,analog_sw1
-	clrf	analog_sw1_raw+1
-	clrf	analog_sw1_raw+0				; reset average registers
-	movlw	.16
-	movwf	analog_counter					; only once...
+
+	; compute average - divide by 16
+	swapf	analog_sw1_raw+1,F				; swap nibbles in high byte
+	movlw	b'11110000'						; keep only upper nibble
+	andwf	analog_sw1_raw+1,W				; ...
+	movwf	analog_sw1						; copy ex lower nibble of high byte to upper nibble of result
+	swapf	analog_sw1_raw+0,F				; swap nibble in low  byte
+	movlw	b'00001111'						; keep only lower nibble
+	andwf	analog_sw1_raw+0,W				; ...
+	iorwf	analog_sw1,F					; copy ex upper nibble of low  byte to lower nibble of result
+
+	clrf	analog_sw1_raw+1				; reset average registers
+	clrf	analog_sw1_raw+0				; ...
+
+	; set up averaging counter for next call-up
+	movlw	.16								; 16 averaging rounds
+	movwf	analog_counter					; ...
 
 get_analog_switches_3a:
 	bcf		analog_sw1_pressed				; default to not pressed
 	movff	opt_cR_button_right,WREG		; 20-100
-	bcf		STATUS,C
+	bcf		STATUS,C						; clear carry bit
 	rrcf	WREG							; /2 -> 10-50
-	bcf		STATUS,C
+	bcf		STATUS,C						; clear carry bit
 	rrcf	WREG							; /2 -> 5-25
 	decf	WREG,W							; -1
 	decf	WREG,W							; -1
 	decf	WREG,W							; -1 -> 2-22
 	btfss	button_polarity,0				; (1= normal, 0=inverted)
-	bra		get_analog_switches_sw1_inv
-	addwf	analog_sw1,W					; average (~128)
-	cpfsgt	ADRESH							; pressed?
-	bra		get_analog_switches_4			; NO
-	bra		get_analog_switches_sw1_pressed	; YES (right button normal)
+	bra		get_analog_switches_sw1_inv		; 0
+	addwf	analog_sw1,W					; 1 - add to average (~128)
+	cpfsgt	ADRESH							;   - pressed?
+	bra		get_analog_switches_4			;     NO  - continue with clean-up
+	bra		get_analog_switches_sw1_pressed	;     YES - (right button normal)
 
 get_analog_switches_sw1_inv:
-	subwf	analog_sw1,W					; average (~128)
+	subwf	analog_sw1,W					; subtract from average (~128)
 	cpfslt	ADRESH							; pressed?
-	bra		get_analog_switches_4			; NO
-	;bra	get_analog_switches_sw1_pressed	; YES (right button inverted)
+	bra		get_analog_switches_4			; NO  - continue with clean-up
+	;bra	get_analog_switches_sw1_pressed	; YES - (right button inverted)
 
 get_analog_switches_sw1_pressed:
 	bsf		analog_sw1_pressed				; set right button as pressed
 
 get_analog_switches_4:
 	bsf		ADCON2,ADFM						; restore to right justified
-	bcf		adc_is_running
+	bcf		adc_is_running					; flag ADC not in use any more
+
 	banksel	common							; back to bank common
+
 	btfsc	analog_sw1_pressed				; right button pressed?
 	return									; YES - done
 	btfsc	analog_sw2_pressed				; left button pressed?
 	return									; YES - done
 	setf	TMR1H							; NO to both - no button pressed, set timer1 to overflow quickly
-	return
+	setf	TMR1L							;            - ...
+	return									;            - done
 
-	END
\ No newline at end of file
+;-----------------------------------------------------------------------------
+
+	END
--- a/src/calibrate.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/calibrate.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File calibration.asm                      combined next generation V3.08.8
+;   File calibration.asm                    * combined next generation V3.09.4n
 ;
 ;   o2 sensor calibration subroutines
 ;
@@ -14,216 +14,228 @@
 #include "eeprom_rs232.inc"
 
 
-calibrate	CODE
+;=============================================================================
+calibrate1	CODE
+;=============================================================================
 
-;=============================================================================
 
  IFDEF _external_sensor
 
-	global	transmit_setpoint				; transmit current setpoint from WREG (in cbar) to external electronics
+;-----------------------------------------------------------------------------
+; Transmit current Setpoint from WREG (in cbar) to external Electronics
+;
+	global	transmit_setpoint
 transmit_setpoint:
 	return									; !!!! FUNCTION IS CURRENTLY DISABLED !!!!
-	btfss	s8_digital_avail				; do we have a digital S8 interface?
-	return									; NO  - ignore
-											; YES - transmit setpoint from WREG
-	clrf	lo								; initialize checksum
-	movff	char_I_const_ppO2,hi			; copy setpoint value to hi
-	movlw	0xAA							; start byte
-	rcall	tx_to_HUD						; transmit to HUD
-	movlw	0x60							; command new SP
-	rcall	tx_to_HUD						; transmit to HUD
-	movff	hi,WREG							; SP in cbar
-	rcall	tx_to_HUD						; transmit to HUD
-	movff	lo,WREG							; checksum
-	rcall	tx_to_HUD_cs					; transmit checksum
-	return
 
-tx_to_HUD:									; entry point to transmit a byte to the HUD
-	addwf	lo,F							; add byte to checksum
-tx_to_HUD_cs:								; entry point to transmit the checksum
-	movff	WREG,TXREG2						; transmit byte
-	call	ir_s8_wait_tx					; wait for UART
-	return
+;	btfsc	ext_input_optical				; optical input in use?
+;	return									; YES - setpoint - TX not supported
+;	TSTOSS	opt_s8_mode						; NO  - S8 mode selected?
+;	return									;       NO
+;	clrf	lo								;       YES - initialize checksum
+;	movff	char_I_const_ppO2,hi			;           - copy setpoint value to hi
+;	movlw	0xAA							;           - load start byte
+;	rcall	tx_to_HUD_chksum				;           - transmit to HUD
+;	movlw	0x60							;           - load command 'new SP'
+;	rcall	tx_to_HUD_chksum				;           - transmit to HUD
+;	movf	hi,W							;           - load SP in cbar
+;	rcall	tx_to_HUD_chksum				;           - transmit to HUD
+;	movf	lo,W							;           - load checksum
+;	rcall	tx_to_HUD						;           - transmit checksum
+;	return									;           - done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Transmit Byte to external Electronics
+;
+tx_to_HUD_chksum:
+	addwf	lo,F							; add byte to checksum
+tx_to_HUD:
+	goto	ir_s8_tx_single					; transmit byte and return
+
+
+;-----------------------------------------------------------------------------
+; Compute Calibration Factors
+;
 	global	calibrate_mix
 calibrate_mix:
-	; set usage and calibration flags as per default
-	bsf		use_O2_sensor1
-	bsf		use_O2_sensor2
-	bsf		use_O2_sensor3
-	bsf		sensor1_calibrated_ok
-	bsf		sensor2_calibrated_ok
-	bsf		sensor3_calibrated_ok
+	; set usage and calibration flags to default values
+	bsf		use_O2_sensor1					; sensor in use
+	bsf		use_O2_sensor2					; ...
+	bsf		use_O2_sensor3					; ...
+	bsf		sensor1_calibrated_ok			; sensor calibration ok
+	bsf		sensor2_calibrated_ok			; ...
+	bsf		sensor3_calibrated_ok			; ...
 
 	; ISR-safe 2 byte copy of the current pressure to xB for later use
 	SMOVII	pressure_abs,xB
 
 	; check for HUD
-	btfss	s8_digital_avail				; do we have a digital S8 interface?
-	bra		calibrate_mix1					; NO  - skip HUD part
+	btfsc	ext_input_optical				; optical interface in use?
+	bra		calibrate_mix1					; YES - skip
+	TSTOSS	opt_s8_mode						; NO  - S8 interface in use?
+	bra		calibrate_mix1					;       NO  - skip HUD part
+	;bra	calibrate_mix0					;       YES - calibrate S8 HUD
 
-	; calibrate any S8-connected HUD
+	; calibrate S8-connected external electronics
+calibrate_mix0:
 	clrf	lo								; initialize checksum
-	movlw	0xAA							; start byte
-	rcall	tx_to_HUD						; transmit to HUD
-	movlw	0x31							; calibration command
+	movlw	0xAA							; load start byte
+	rcall	tx_to_HUD_chksum				; transmit to HUD
+	movlw	0x31							; load calibration command
+	rcall	tx_to_HUD_chksum				; transmit to HUD
+	movff	opt_calibration_O2_ratio,WREG	; load calibration gas %O2
+	rcall	tx_to_HUD_chksum				; transmit to HUD
+	movf	xB+0,W							; load current absolute pressure low  byte
+	rcall	tx_to_HUD_chksum				; transmit to HUD
+	movf	xB+1,W							; load current absolute pressure high byte
+	rcall	tx_to_HUD_chksum				; transmit to HUD
+	movf	lo,W							; load checksum
 	rcall	tx_to_HUD						; transmit to HUD
-	movff	opt_calibration_O2_ratio,WREG	; calibration gas %O2
-	rcall	tx_to_HUD						; transmit to HUD
-	movff	xB+0,WREG						; current absolute pressure low byte
-	rcall	tx_to_HUD						; transmit to HUD
-	movff	xB+1,WREG						; current absolute pressure high byte
-	rcall	tx_to_HUD						; transmit to HUD
-	movff	lo,WREG							; checksum
-	rcall	tx_to_HUD_cs					; transmit to HUD
-;	bra		calibrate_mix2
 
 	; calibrate internal sensors
-calibrate_mix1:								; compute %O2 * 100 * absolute pressure [mbar] / 100
-	movff	opt_calibration_O2_ratio,WREG
-	mullw	.100
-	MOVII	PROD,xA
-	call	mult16x16						; xA*xB=xC
-	MOVLI	.100,xB
+calibrate_mix1:								; compute C = %O2 * 100 * absolute pressure [mbar] / 100
+	movff	opt_calibration_O2_ratio,WREG	; load calibration gas %O2
+	mullw	.100							; multiply with 100
+	MOVII	PROD,xA							; copy result to xA
+	call	mult16x16						; xC = xA * xB
+	MOVLI	.100,xB							; prepare division by 100
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
 
-	; keep a copy of the result
-	movff	xC+0,mpr+0
-	movff	xC+1,mpr+1
-	movff	xC+2,mpr+2
-	movff	xC+3,mpr+3
-
 	; compute factor for sensor 1
-	MOVII	sensor1_mv,xB
+	MOVRR	xC,mpr,.4						; backup calibration value C
+	MOVII	sensor1_mv,xB					; get mV from sensor 1
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
 	MOVII	xC,opt_x_s1						; xC = ppO2/mV as factor for sensor 1
 
-	; restore result
-	movff	mpr+0,xC+0
-	movff	mpr+1,xC+1
-	movff	mpr+2,xC+2
-	movff	mpr+3,xC+3
-
 	; compute factor for sensor 2
-	MOVII	sensor2_mv,xB
+	MOVRR	mpr,xC,.4						; restore C
+	MOVII	sensor2_mv,xB					; get mV from sensor 2
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
 	MOVII	xC,opt_x_s2						; xC = ppO2/mV as factor for sensor 2
 
-	; restore result
-	movff	mpr+0,xC+0
-	movff	mpr+1,xC+1
-	movff	mpr+2,xC+2
-	movff	mpr+3,xC+3
-
 	; compute factor for sensor 3
-	MOVII	sensor3_mv,xB
+	MOVRR	mpr,xC,.4						; restore C
+	MOVII	sensor3_mv,xB					; get mV from sensor 3
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
 	MOVII	xC,opt_x_s3						; xC = ppO2/mV as factor for sensor 3
 
 	; check sensor 1 for min/max mV
 	MOVII	sensor1_mv,sub_a				; get mV from sensor 1
-	rcall	calibrate_mix_helper			; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1
-	TSTFSZ	WREG							; sensor mV within thresholds?
-	bcf		use_O2_sensor1					; NO - clear usage flag
+	rcall	calibrate_mix_helper			; check mV for min/max boundary, returns with WREG = 0 if ok, else WREG = 1
+	TSTFSZ	WREG							; sensor mV within boundary?
+	bcf		use_O2_sensor1					; NO - revoke sensor from usage
 
 	; check sensor 2 for min/max mV
 	MOVII	sensor2_mv,sub_a				; get mV from sensor 2
-	rcall	calibrate_mix_helper			; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1
-	TSTFSZ	WREG							; sensor mV within thresholds?
-	bcf		use_O2_sensor2					; NO - clear usage flag
+	rcall	calibrate_mix_helper			; check mV for min/max boundary, returns with WREG = 0 if ok, else WREG = 1
+	TSTFSZ	WREG							; sensor mV within boundary?
+	bcf		use_O2_sensor2					; NO - revoke sensor from usage
 
 	; check sensor 3 for min/max mV
 	MOVII	sensor3_mv,sub_a				; get mV from sensor 3
-	rcall	calibrate_mix_helper			; check mV for min/max thresholds, returns with WREG = 0 if ok, else WREG = 1
-	TSTFSZ	WREG							; sensor mV within thresholds?
-	bcf		use_O2_sensor3					; NO - clear usage flag
+	rcall	calibrate_mix_helper			; check mV for min/max boundary, returns with WREG = 0 if ok, else WREG = 1
+	TSTFSZ	WREG							; sensor mV within boundary?
+	bcf		use_O2_sensor3					; NO - revoke sensor from usage
 
 calibrate_mix2:
 	; check for HUD
 	btfss	hud_connection_ok				; HUD connection existing?
 	bra		calibrate_mix3					; NO - skip HUD part
 
+	; TODO: wait for HUD to complete calibration an send updated data
+
 	; copy disable flags from HUD digital input
-	btfss	sensor1_active
-	bcf		use_O2_sensor1
-	btfss	sensor2_active
-	bcf		use_O2_sensor2
-	btfss	sensor3_active
-	bcf		use_O2_sensor3
+	btfss	sensor1_active					; sensor 1 usable?
+	bcf		use_O2_sensor1					; NO - revoke sensor from usage
+	btfss	sensor2_active					; sensor 2 usable?
+	bcf		use_O2_sensor2					; NO - revoke sensor from usage
+	btfss	sensor3_active					; sensor 3 usable?
+	bcf		use_O2_sensor3					; NO - revoke sensor from usage
 
 calibrate_mix3:
-	; clear calibration flags if sensors are not found to be ok
-	btfss	use_O2_sensor1					; sensor 1 out of range?
-	bcf		sensor1_calibrated_ok			; YES - disable this sensor
-	btfss	use_O2_sensor2					; sensor 2 out of range?
-	bcf		sensor2_calibrated_ok			; YES - disable this sensor
-	btfss	use_O2_sensor3					; sensor 3 out of range?
-	bcf		sensor3_calibrated_ok			; YES - disable this sensor
-
-	; when no sensor is found, enable all three to show error state and clear calibration factors
-	btfsc	use_O2_sensor1
-	return
-	btfsc	use_O2_sensor2
-	return
-	btfsc	use_O2_sensor3
-	return
+	; clear calibration flags if sensors are not usable
+	btfss	use_O2_sensor1					; sensor 1 usable?
+	bcf		sensor1_calibrated_ok			; NO  - revoke calibration
+	btfss	use_O2_sensor2					; sensor 2 usable?
+	bcf		sensor2_calibrated_ok			; NO  - revoke calibration
+	btfss	use_O2_sensor3					; sensor 3 usable?
+	bcf		sensor3_calibrated_ok			; NO  - revoke calibration
 
-	; enable all sensors
-	bsf		use_O2_sensor1
-	bsf		use_O2_sensor2
-	bsf		use_O2_sensor3
-	; clear calibration factors
-	banksel	opt_x_s1						; switch to bank options table
-	CLRI	opt_x_s1
-	CLRI	opt_x_s2
-	CLRI	opt_x_s3
-	banksel	common							; back to bank common
-	return
-
-calibrate_mix_helper:
-	MOVLI	min_mv,sub_b					; load minimum threshold into sub_b
-	call	sub16							; sub_c = sub_a - sub_b
-	btfsc	neg_flag						; sensor mV lower than minimum threshold?
-	retlw	.1								; YES - return signaling threshold violation
-	MOVLI	max_mv,sub_b					; load maximum threshold into sub_b
-	call	sub16							; sub_c = sub_a - sub_b
-	btfss	neg_flag						; sensor mV higher than maximum threshold?
-	retlw	.1								; YES - return signaling threshold violation
-	retlw	.0								; NO  - return signaling min/max ok
+	; if there is no usable sensor at all, then enable all three
+	; sensors to show error state and clear calibration factors
+	btfsc	use_O2_sensor1					; sensor 1 usable?
+	return									; YES - done
+	btfsc	use_O2_sensor2					; NO  - sensor 2 usable?
+	return									;       YES - done
+	btfsc	use_O2_sensor3					;       NO  - sensor 3 usable?
+	return									;             YES - done
+	bsf		use_O2_sensor1					;             NO  - enable all sensors
+	bsf		use_O2_sensor2					;                 - ...
+	bsf		use_O2_sensor3					;                 - ...
+	CLRR	opt_x_s1,.6						;                 - clear calibration factors (3x 16 bit)
+	return									;                 - done
 
 
-	global	compute_mvolts_for_all_sensors
-compute_mvolts_for_all_sensors:				; compute mV or all sensors (S8 mode)
+;-----------------------------------------------------------------------------
+; Helper Function - Check if Sensor mV Value is within Min/Max Boundary
+;
+calibrate_mix_helper:
+	MOVLI	min_mv,sub_b					; load minimum boundary into sub_b
+	call	sub16							; sub_c = sub_a - sub_b
+	btfsc	neg_flag						; sensor mV lower than minimum boundary?
+	retlw	.1								; YES - return signaling boundary violation
+
+	MOVLI	max_mv,sub_b					; load maximum boundary into sub_b
+	call	sub16							; sub_c = sub_a - sub_b
+	btfss	neg_flag						; sensor mV higher than maximum boundary?
+	retlw	.1								; YES - return signaling boundary violation
+
+	retlw	.0								; return signaling min/max ok
+
+ ENDIF	; _external_sensor
+
+;=============================================================================
+calibrate2	CODE
+;=============================================================================
+
+ IFDEF _external_sensor
+
+;-----------------------------------------------------------------------------
+; Compute Sensor mV from Raw Values received via S8 digital Interface
+;
+	global	compute_mvolts_from_rawdata
+compute_mvolts_from_rawdata:
+
 	; compute AD results in 100 µV steps (16 bit/sensor)
 	; 24 bit AD result is in 244.1406541 nV
 	; divide 24 bit value by 409.5999512 -> 410 with only 0.01% error
 	#DEFINE	ad2mv_factor .410
 
-	MOVLI	ad2mv_factor,xB
+	MOVLI	ad2mv_factor,xB					; load conversion factor into xB
 
 	; Sensor 1
 	SMOVTT	s8_rawdata_sensor1,xC			; ISR-safe copy of 3 bytes to xC
 	clrf	xC+3							; clear MSB of xC
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
-	MOVII	xC,sensor1_mv					; in 100 µV steps
+	MOVII	xC,sensor1_mv					; store result
 
 	; Sensor 2
 	SMOVTT	s8_rawdata_sensor2,xC			; ISR-safe copy of 3 bytes to xC
 	clrf	xC+3							; clear MSB of xC
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
-	MOVII	xC,sensor2_mv					; in 100 µV steps
+	MOVII	xC,sensor2_mv					; store result
 
 	; Sensor 3
 	SMOVTT	s8_rawdata_sensor3,xC			; ISR-safe copy of 3 bytes to xC
 	clrf	xC+3							; clear MSB of xC
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
-	MOVII	xC,sensor3_mv					; in 100 µV steps
+	MOVII	xC,sensor3_mv					; store result
 
 	return									; done
 
  ENDIF	; _external_sensor
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/calibrate.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/calibrate.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,12 +1,12 @@
 ;=============================================================================
 ;
-;   File calibrate.inc                        combined next generation V3.03.1
+;   File calibrate.inc                      * combined next generation V3.09.4n
 ;
 ;=============================================================================
 
 
  IFDEF _external_sensor
 	extern	calibrate_mix					; calibrate sensors
-	extern	compute_mvolts_for_all_sensors	; compute sensor mV values from digital transmitted data
+	extern	compute_mvolts_from_rawdata		; compute sensor mV values from digital transmitted data
 	extern	transmit_setpoint				; transmit current setpoint to external electronics
  ENDIF
--- a/src/color_processor.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/color_processor.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File File color_processor.asm             combined next generation V3.03.7
+;   File File color_processor.asm           * combined next generation V3.09.4l
 ;
 ;   Decompress and draw an image
 ;
@@ -59,28 +59,30 @@
 
 	extern	convert_for_display2
 
-
+;=============================================================================
 color_proc	CODE
+;=============================================================================
 
 ;-----------------------------------------------------------------------------
-
+; Print a colored Bitmap Image
+;
 	global	color_image
 color_image:
 	tblrd*+							; read image width (in true width / 2)
-	movff	TABLAT,win_width
+	movff	TABLAT,win_width+0		; store in win_width, low  byte
+	clrf	win_width+1				; clear    win_width, high byte
 	tblrd*+							; read image height
-	movff	TABLAT,win_height
+	movff	TABLAT,win_height		; store in win_height
 	rcall	get_colors				; read the colors
-
 	tstfsz	encoding_format			; image encoded in version 0 format?
 	bra		color_image_1			; NO
 
-	; image encoding version 0 format: compute the overall number of pixels - 1 to draw
-	movf	win_width,W				; get width into WREG
-	mulwf	win_height				; multiply by hight
+	; image encoding version 0 format: compute overall number of pixels - 1
+	movf	win_width,W				; get           image width (/2) into WREG
+	mulwf	win_height				; multiply with image hight
 	movff	PRODL,overall_pixels+0	; store product, low  byte
 	movff	PRODH,overall_pixels+1	; ...            high byte
-	clrf	overall_pixels+2		; clear upper byte
+	clrf	overall_pixels+2		; clear product, upper byte
 	bcf		STATUS,C				; clear carry flag
 	rlcf	overall_pixels+0		; multiply by 2 via shift left, low   byte
 	rlcf	overall_pixels+1		; ...                           high  byte
@@ -91,7 +93,6 @@
 	subwfb	overall_pixels+2,F		; ...
 
 color_image_1:
-	clrf	win_width+1				; clear width, high byte
 	bcf		STATUS,C				; clear carry flag
 	rlcf	win_width+0				; multiply width x 2 to get the true box width
 	rlcf	win_width+1				; ...
@@ -104,20 +105,20 @@
 	clrf	pixel_count+1			; ...
 
 color_image_read_byte:
-	tblrd*+							; get next byte
+	tblrd*+							; get next image data byte
 	btfss	TABLAT,7				; high bit cleared ?
-	bra		color_image_decode_color; YES - this is a color byte
-	;bra	color_image_decode_count; NO  - this is a pixel count byte
+	bra		color_image_decode_color; YES - this is color data
+	;bra	color_image_decode_count; NO  - this is pixel count data
 
 color_image_decode_count:
 	; decode pixel repetition count
 	rlcf	TABLAT,F				; drop high bit
 	movlw	.7						; move 7 bits
 color_image_decode_count_loop:
-	rlcf	TABLAT,F				; get upper bit into carry
-	rlcf	pixel_count+0,F			; push bit into pixel count (16 bit operation)
-	rlcf	pixel_count+1,F			; ...
-	decfsz	WREG					; decrement loop counter, all bits done?
+	rlcf	TABLAT,F						; get upper bit into carry
+	rlcf	pixel_count+0,F					; push bit into pixel count (16 bit operation)
+	rlcf	pixel_count+1,F					; ...
+	decfsz	WREG							; decrement loop counter, all bits done?
 	bra		color_image_decode_count_loop	; NO  - loop
 	bra		color_image_read_byte			; YES - decode next byte
 
@@ -127,7 +128,7 @@
 	cpfslt	TABLAT					; color index < end-of-image tag?
 	return							; NO - done
 
-	; get pixel color into PROD
+	; translate color index into pixel color
 	lfsr	FSR2,buffer				; set FSR2 pointer to base address of color table
 	rlncf	TABLAT,W				; get color index * 2 into WREG
 	movwf	FSR2L					; adjust pointer to selected color
@@ -136,6 +137,7 @@
 
 	tstfsz	encoding_format			; image encoded in version 0 format?
 	bra		color_image_pixel		; NO
+
 	; image encoding version 0 format: subtract pixel count from the overall number of pixels to do
 	movf	pixel_count+0,W			; YES - 24 bit subtraction, low   byte
 	subwf	overall_pixels+0,F		; ...
@@ -145,12 +147,12 @@
 	subwfb	overall_pixels+2,F		; ...
 
 color_image_pixel:
-	; prepare sending of pixels to display
+	; prepare sending the pixels to display
 	infsnz	pixel_count+0			; increment pixel repetition count by 1
 	incf	pixel_count+1			; ...
 	incf	pixel_count+1			; because decrement is done first, increment high byte once more
 	bsf		tft_rs,0				; RS_H data
-	bcf		INTCON,GIE				; disable global interrupts
+	bcf		INTCON,GIE				; disable all interrupts
 
 	btfsc	screen_type2			; display type 2 ?
 	bra		color_image_display2	; YES
@@ -202,7 +204,7 @@
 ;	bra		color_image_pixel_com	; all pixels transmitted
 
 color_image_pixel_com:
-	bsf		INTCON,GIE				; re-enable global interrupts
+	bsf		INTCON,GIE				; re-enable all interrupts
 
 	tstfsz	encoding_format			; image encoded in version 0 format?
 	bra		color_image_loop_xy		; NO - loop to process next byte from image data
@@ -216,14 +218,16 @@
 	return							;                  YES - done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - set up Pixel-Color Look-Up Table
+;
 	global	get_colors
 get_colors:
-	tblrd*+							; read number of image colors
-	movff	TABLAT,lo				; store in lo
-	movf	lo,W
+	tblrd*+							; read number of color indexes
+	movf	TABLAT,W				; store in lo
 	tblrd*+							; read image encoding format
 	movff	TABLAT,encoding_format	; store encoding format
-	lfsr	FSR2,buffer				; set up buffer as storage for the colors
+	lfsr	FSR2,buffer				; load base address of the look-up table
 get_colors_loop:
 	tblrd*+							; read color from stored image, low  byte
 	btfss	use_custom_colors		; shall use custom colors?
@@ -236,4 +240,6 @@
 	bcf		use_custom_colors		; YES - clear custom colors request
 	return							;     - done
 
+;-----------------------------------------------------------------------------
+
 	END
--- a/src/colorschemes.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/colorschemes.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,27 +1,86 @@
 ;=============================================================================
 ;
-;   File colorschemes.inc                      combined next generation V3.0.1
+;   File colorschemes.inc                   * combined next generation V3.09.5
 ;
 ;=============================================================================
 
-; Dive mode
+
+;-----------------------------------------------------------------------------
+; Font Color Selection - fixed Colors
+
+FONT_COLOR_STANDARD		macro
+	setf	font_color							; full white
+	endm
+
+FONT_COLOR	macro	font_color_input
+	movlw	font_color_input					; 8 bit color
+	movwf	font_color
+	endm
+
 
-; Standard
-#DEFINE color_scheme_divemode_mask1		color_green
-#DEFINE color_scheme_divemode_std1		color_white
-#DEFINE color_scheme_divemode_dis1		color_lightblue		; color_grey
+;-----------------------------------------------------------------------------
+; 8 Bit fixed Color Definitions
+;
+;										b'RRRGGGBB'
+;										-----------
+#DEFINE color_red						b'11100000'	; (7,0,0)
+#DEFINE color_dark_red					b'10000101'	; (4,1,1)
+#DEFINE color_violet					b'11101011'	; (7,2,3)
+#DEFINE color_blue						b'11000111'	; (6,1,3)
+#DEFINE color_green						b'00011100'	; (0,7,0)
+#DEFINE color_greenish					b'00111110'	; (1,7,2)
+#DEFINE color_dark_green				b'00111001'	; (1,6,1)
+#DEFINE color_yellow					b'11111101'	; (7,7,1)
+#DEFINE color_white						b'11111111'	; (7,7,3)
+#DEFINE color_black						b'00000000'	; (0,0,0)
+#DEFINE color_deepblue					b'00000010'	; (0,0,2)
+#DEFINE color_grey						b'11011111'	; (6,7,3)
+#DEFINE color_cyan						b'11011111'	; (6,7,3)
+#DEFINE color_lightblue					b'11011011'	; (6,7,3)
+#DEFINE color_orange					b'11111000'	; (7,6,0)
+#DEFINE color_pink						b'11111010'	; (7,6,2)
+
+
+;-----------------------------------------------------------------------------
+; Font Color Selection - pallet-based Colors
 
-; redish
-#DEFINE color_scheme_divemode_mask2		color_red
-#DEFINE color_scheme_divemode_std2		color_orange
-#DEFINE color_scheme_divemode_dis2		color_dark_red
+; the use of pallet-based colors requires the prior call of
+;
+; - TFT_load_std_color_pallet   to load the standard color pallet, or
+; - TFT_load_dive_color_pallet  to load the dive     color pallet
+;
+; Attention: the following macros must resolve to single commands!
+
+
+FONT_COLOR_MASK			macro					; labels and fixed items
+	movff	pallet_color_mask,font_color
+	endm
+
+FONT_COLOR_DISABLED		macro					; disabled & outdated items
+	movff	pallet_color_disabled,font_color
+	endm
+
+FONT_COLOR_MEMO			macro					; information & values within normal range,
+	movff	pallet_color_memo,font_color		; things without a need to react upon
+	endm
 
-; greenish
-#DEFINE color_scheme_divemode_mask3		color_cyan
-#DEFINE color_scheme_divemode_std3		color_green
-#DEFINE color_scheme_divemode_dis3		color_dark_green
+FONT_COLOR_ADVICE		macro					; advices to do something, but without
+	movff	pallet_color_advice,font_color		; essential need to actually do it
+	endm
+
+FONT_COLOR_ATTENTION	macro					; important things to be aware of and
+	movff	pallet_color_attention,font_color	; that develop towards a warning
+	endm
 
-; blueish
-#DEFINE color_scheme_divemode_mask4		color_blue
-#DEFINE color_scheme_divemode_std4		color_lightblue
-#DEFINE color_scheme_divemode_dis4		color_deepblue
\ No newline at end of file
+FONT_COLOR_WARNING		macro					; important things with immediate
+	movff	pallet_color_warning,font_color		; need to react upon
+	endm
+
+
+;-----------------------------------------------------------------------------
+; 8 Bit Pallet Color Definitions
+;
+; => see 'pallet_table' in tft_outputs.asm
+;
+
+;-----------------------------------------------------------------------------
--- a/src/comm.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/comm.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File comm.asm                             combined next generation V3.08.8
+;   File comm.asm                           * combined next generation V3.09.5
 ;
 ;   RS232 via USB
 ;
@@ -25,6 +25,7 @@
 #include "math.inc"
 #include "i2c.inc"
 #include "logbook.inc"
+#include "colorschemes.inc"
 
 
 	extern	restart
@@ -34,6 +35,7 @@
 	extern	option_write_serial
 	extern	gaslist_cleanup_list
 	extern	eeprom_deco_data_write
+	extern	eeprom_memorize_fw_checksum
 
 
 ; timeouts
@@ -58,6 +60,9 @@
 #DEFINE comm_status3_column		comm_status1_column
 #DEFINE	comm_status4_row		.160
 #DEFINE	comm_status4_column		comm_status1_column
+#DEFINE	comm_status5_row		.190
+#DEFINE	comm_status5_column		comm_status1_column
+
 
 ; positioning of COMM mode warning icon
 #DEFINE comm_warning_row		.160
@@ -66,11 +71,13 @@
 
 ;#DEFINE	testloop_avail				; uncomment if testloop code is available
 
-
+;=============================================================================
 comm	CODE
-
 ;=============================================================================
 
+;-----------------------------------------------------------------------------
+; Entry Point for Comm Mode / USB
+;
 	global	comm_mode_usb
 comm_mode_usb:										; entry point for comm mode via USB
 	WAITMS	d'1'									; wait 1 ms
@@ -82,46 +89,60 @@
 	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
+
+;-----------------------------------------------------------------------------
+; Entry Point for Comm Mode / BT
+;
+	global	comm_mode_bt
+comm_mode_bt:										; entry point for comm mode via BT
 	bcf		aux_flag								; remember to show BLE title
 	;bra	comm_mode_common						; continue with common part
 
+
+;-----------------------------------------------------------------------------
+; Common Part of Comm Mode Entry
+;
 comm_mode_common:
 	clrf	STKPTR									; reset addresses stack
 	call	TFT_ClearScreen							; clear screen
-	WIN_COLOR color_greenish						; set color
+	FONT_COLOR color_greenish						; set color
 
 	btfss	aux_flag								; shall show USB title?
-	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						;     - continue with common part
+	bra		comm_mode_common_bt						; NO  - show BT  title
+	;bra	comm_mode_common_usb					; YES - show USB title
 
-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_usb:
+	WIN_SMALL comm_title_column_usb, comm_title_row	; set   USB title position
+	STRCPY_TEXT_PRINT tUsbTitle						; print USB title text
+	bra		comm_mode_common_logo					; continue with logo
 
-comm_mode_common_2:
-	call	TFT_standard_color						; set standard color
+comm_mode_common_bt:
+	WIN_SMALL comm_title_column_ble, comm_title_row	; set   BT title position
+	STRCPY_TEXT_PRINT tBleTitle						; print BT title text
+	;bra	comm_mode_common_logo					; continue with logo
+
+comm_mode_common_logo:
 	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  - 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						;     - continue with common part
+	btfss	battery_gauge_available					; "+" bootloader ?
+	bra		comm_mode_common_logo2					; YES - show logo type 2
+	;bra	comm_mode_common_logo1					; NO  - show logo type 1
+
+comm_mode_common_logo1:
+	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_1		; show USB/BT logo
+	bra		comm_mode_common_start					; continue with starting message
 
-comm_mode_common_3:
-	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_logo2:
+	TFT_WRITE_PROM_IMAGE_BY_ADDR comm_logo_2		; show BT logo / OSTC+
+	;bra	comm_mode_common_start					; continue with starting message
 
-comm_mode_common_4:
-	WIN_SMALL comm_status1_column,comm_status1_row	; print status message "starting..."
-	STRCPY_TEXT_PRINT tUsbStarting					; ...
+comm_mode_common_start:
+	WIN_SMALL comm_status1_column,comm_status1_row	; set position
+	FONT_COLOR_MEMO									; set standard color
+	STRCPY_TEXT_PRINT tUsbStarting					; print status message "starting..."
 
 	WIN_TINY .40,.240-.16							; set output position to bottom line
-	call	TFT_show_serial_and_firmware			; show serial number and firmware version
+	call	TFT_print_serial_and_firmware			; show serial number and firmware version
 
  IFDEF _screendump
 	bcf		screen_dump_avail						; disable screen dump function
@@ -130,12 +151,18 @@
 	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						; ...
+	WIN_SMALL comm_status1_column+.80,comm_status1_row	; set position after starting message
+	FONT_COLOR_MEMO										; set standard color
+	STRCPY_TEXT_PRINT tUsbStartDone						; print (adding to status message) "done..."
 
 	movlw	timeout_comm_pre_mode					; get timeout for phase without communication established yet
 	movwf	comm_timeout_timer						; initialize timeout counter
+	;bra	comm_mode_selection_loop				; continue with mode selection loop
 
+
+;-----------------------------------------------------------------------------
+; Mode Selection Loop: Download Mode or Service Mode
+;
 comm_mode_selection_loop:
 	bcf		trigger_full_second						; clear 'one second elapsed' flag
 	bcf		LEDr									; switch off red LED / power down TR co-processor
@@ -151,10 +178,10 @@
 	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
+	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?
+	btfsc	ble_available							; BT 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
@@ -168,10 +195,9 @@
 
 
 ;-----------------------------------------------------------------------------
-; Received start byte for service mode, await service key
+; Check Service Mode Pass-Key and notify Service Mode on Success
 ;
 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
@@ -197,53 +223,82 @@
 	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
+	FONT_COLOR_MEMO									;     - set standard color
 	STRCPY_TEXT_PRINT tUsbServiceMode				;     - ...
 	bsf		comm_service_mode						;     - enable service mode commands
 	bra		comm_command_loop						;     - enter command loop
 
 
 ;-----------------------------------------------------------------------------
-; Received start byte for download mode
+; Notify RX Timeout occurred
+;
+comm_command_timeout:
+	WIN_SMALL comm_status4_column, comm_status4_row	; select font and output position
+	FONT_COLOR_WARNING								; set warning color
+	STRCPY_PRINT "Data Rx Timeout"					; print failure message
+	FONT_COLOR_MEMO									; back to standard color
+	bra		comm_drain_rx_queue						; continue with draining the RX queue
+
+
+;-----------------------------------------------------------------------------
+; Notify Error in Parameters
+;
+comm_command_error:
+	WIN_SMALL comm_status4_column, comm_status4_row	; select font and output position
+	FONT_COLOR_WARNING								; set warning color
+	STRCPY_PRINT "Parameter Error"					; print failure message
+	FONT_COLOR_MEMO									; back to standard color
+	;bra	comm_drain_rx_queue						; continue with draining the RX queue
+
+
+;-----------------------------------------------------------------------------
+; Drain the RX Queue until next Timeout
+;
+comm_drain_rx_queue:
+	bsf		INTCON,GIE								; re-enable all interrupts
+comm_drain_rx_queue_loop:
+	btfsc	switch_right							; right button (abort) pressed?
+	bra		comm_service_exit						; YES - exit comm mode
+	SERIAL_CC_RECEIVE WREG							; NO  - (try to) receive one byte
+	btfss	rs232_rx_timeout						;     - got a byte?
+	bra		comm_drain_rx_queue_loop				;       YES - try to drain more bytes
+	bra		comm_command_loop						;       NO  - re-enter command loop
+
+
+;-----------------------------------------------------------------------------
+; Debug Code - show Number of Bytes received
+;
+ IFDEF _comm_debug
+comm_command_debug:
+	WIN_SMALL comm_status5_column, comm_status5_row	; select font and output position
+	FONT_COLOR_MEMO									; set standard color
+	STRCPY	"last RX: "								; print label
+	output_9999										; print number of bytes received (0-9999)
+	STRCAT_PRINT " Byte"							; finalize output
+	bra		comm_command_loop						; re-enter command loop
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; Notify Download Mode selected
 ;
 comm_download_mode:
 	SERIAL_LC_SEND 0xBB								; inform peer download mode will be started
 
-	WIN_SMALL comm_status2_column, comm_status2_row	; print download mode enabled message
-	STRCPY_TEXT_PRINT tUsbDownloadMode				; ... 
+	WIN_SMALL comm_status2_column, comm_status2_row	; set position
+	FONT_COLOR_MEMO									; set standard color
+	STRCPY_TEXT_PRINT tUsbDownloadMode				; print download mode enabled message
 	bcf		comm_service_mode						; disable service mode commands
-	bra		comm_command_loop						; enter command loop
+	;bra	comm_command_loop						; enter command loop
 
 
 ;-----------------------------------------------------------------------------
-; Notify RX timeout occurred
-;
-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
-
-
-;-----------------------------------------------------------------------------
-; Notify error in parameters
-;
-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
-
-
-;-----------------------------------------------------------------------------
-; Command loop: wait for a command
+; Command Loop: await, decode and execute Commands
 ;
 comm_command_loop:
-	; (re-)initialize
 	bsf		INTCON,GIE								; re-enable all interrupts
+
+	; restart command timeout
 	movlw	timeout_service_mode					; get    timeout value
 	movwf	comm_timeout_timer						; reload timeout timer
 
@@ -260,10 +315,12 @@
 	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?
+	btfsc	ble_available							;     - BT 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
+	;bra	comm_command_loop_wait_1				;             YES - proceed
+
 comm_command_loop_wait_1:
 	btfsc	switch_right							; right button (abort) pressed?
 	bra		comm_service_exit						; YES - exit comm mode
@@ -276,17 +333,18 @@
 
 
 ;-----------------------------------------------------------------------------
-; Macro for easier writing of command decoding rules
+; 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
+	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
+; Decode and execute a Command
 ;
 comm_command_decode:
 	bcf		LEDr									; switch off red led
@@ -315,9 +373,9 @@
 	; 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 0x20,comm_read_range				;' ' read a memory range from the external FLASH
+	command_decode 0x40,comm_erase_single_4kb		; @  erase a single   4 kB block  - Warning: no confirmation or built-in safety here...
+	command_decode 0x42,comm_erase_range_4kb		; 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
@@ -330,10 +388,11 @@
 
 
 ;-----------------------------------------------------------------------------
-; Exit comm mode
+; Exit Comm Mode
 ;
 comm_service_exit:
 	WIN_SMALL comm_status3_column, comm_status3_row	; print "Exited" message
+	FONT_COLOR_MEMO									; set standard color
 	STRCPY_TEXT_PRINT	tUsbExit					; ...
 	bra		comm_service_exit_common				; acknowledge exit command and restart
 
@@ -345,15 +404,17 @@
 
 comm_service_exit_nousb:
 	WIN_SMALL comm_status3_column, comm_status3_row	; print "Port closed" message
+	FONT_COLOR_MEMO									; set standard color
 	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
+	WAITS	.1										; wait 1 second to give the serial I/F time
+													; to send the 0xFF before it gets shut down
 	call	disable_rs232							; shut down comm port
 	bcf		LEDr									; switch off red LED
+	WAITS	.1										; wait 1 second for BT module supply to drain
 	goto	restart									; restart
 
 
@@ -361,220 +422,247 @@
 ; Set Real-Time-Clock
 ;
 comm_set_time:
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x62					; acknowledge command
+	SERIAL_RR_RECEIVE mpr,.6			; (try to) receive 6 bytes: hour, minute, second, month, day, year
+	bsf		INTCON,GIE					; re-enable all interrupts
 
-	; 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
+	btfsc	rs232_rx_timeout			; got all 6 bytes?
+	bra		comm_command_timeout		; NO  - show rx timeout message and 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
-
-	; set the RTC
+	movff	mpr+0,rtc_latched_hour		; map the received bytes onto the rtc_latched variables
+	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		; ...
 	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
+; Write a 15 char Text to the OSTC Display
 ;
 comm_show_text:
-	; set font and output position of the text to show
+	; set font and output position (needs to be done before SERIAL_RR_RECEIVE)
 	WIN_SMALL comm_string_column, comm_string_row
+	FONT_COLOR_MEMO						; set standard color
 
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x6E					; acknowledge command
+	SERIAL_RR_RECEIVE buffer,.16		; (try to) receive 16 chars into the string buffer
+	bsf		INTCON,GIE					; re-enable all interrupts
 
-	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
+	movlw	.15							; set maximum text length
+	call	TFT_buffer_trim_length		; fill or trim the text to correct length
+	PRINT								; print text to screen
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Send Serial (2 bytes low:high), Firmware (major.minor) and Custom Text
+;
+comm_identify:
+	SERIAL_LC_SEND 0x69					; acknowledge command
+
+	; 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
+
+	; send firmware version
+	SERIAL_LC_SEND fw_version_major		; send firmware version, major
+	SERIAL_LC_SEND fw_version_minor		; send firmware version, minor
+
+	; send custom text
+	SERIAL_RR_SEND	opt_name,opt_name_length
 
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Reply Serial (2 bytes low:high), firmware (major.minor) and custom text
+; Send short Hardware Descriptor
 ;
-comm_identify:
-	SERIAL_LC_SEND 0x69					; acknowledge command
-
-	;---- 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
-
-	;---- send firmware version
-	SERIAL_LC_SEND fw_version_major		; send firmware version, major
-	SERIAL_LC_SEND fw_version_minor		; send firmware version, minor
-
-	;---- send custom text
-	SERIAL_RR_SEND_RAM	opt_name,opt_name_length
-
+comm_hardware_descriptor:
+	SERIAL_LC_SEND 0x6A					; acknowledge command
+	rcall	comm_helper_hw_descriptor	; send hardware descriptor
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Reply hardware descriptor byte
+; Helper Function for sending Hardware Descriptor
 ;
-comm_hardware_descriptor:
-	SERIAL_LC_SEND 0x6A					; acknowledge command
-
+comm_helper_hw_descriptor:
 	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
 	SERIAL_CC_SEND WREG					; send modified hardware descriptor
-
-	bra		comm_command_loop			; done, back to command loop
+	return
 
 
 ;-----------------------------------------------------------------------------
-; Reply detailed hardware descriptor
+; Send detailed Hardware Descriptor
 ;
 comm_feature_and_hardware:
 	SERIAL_LC_SEND 0x60					; acknowledge command
 
-	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
-	SERIAL_CC_SEND WREG					; send modified hardware low byte
-
-	SERIAL_LC_SEND 0x00					; send feature high byte (fixed zero)
-	SERIAL_LC_SEND 0x00					; send feature low  byte (fixed zero)
-
+	SERIAL_LC_SEND 0x00					; send hardware high byte    (fixed zero)
+	rcall	comm_helper_hw_descriptor	; send hardware descriptor
+	SERIAL_LC_SEND 0x00					; send feature high byte     (fixed zero)
+	SERIAL_LC_SEND 0x00					; send feature low  byte     (fixed zero)
 	SERIAL_LC_SEND 0x00					; send model descriptor byte (fixed zero)
 
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-
-comm_send_headers_short:
-	SERIAL_LC_SEND 0x6D					; acknowledge command
-
-	; 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
-
-	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
+; Helper Function to retrieve a Header, hide the internal Profile Version,
+;                 and to check if the Header is empty
+;
+comm_helper_read_header:
+	; copy header from FLASH into memory
+	call	log_header_addr_by_index					; compute header start address from index in WREG
+	FLASH_RR_READ header_buffer,.256					; copy from FLASH to header buffer
 
-	; 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
-
-	; 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
-
-	; 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
-
-	; send the assembled short header
-	SERIAL_RR_SEND_RAM header_buffer,.16	; send buffer, 16 bytes to do
-
-	; 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
+	; hide internal profile version ID from the outside
+	movff	header_buffer+index_profile_version,WREG	; get byte at the profile version position
+	infsnz	WREG,W										; was the byte = 0xFF (i.e. empty header) ?
+	return												; YES - leave it as it is (WREG now 0)
+	decf	WREG,W										; NO  - restore the profile version
+	andlw	b'00111111'									;     - keep only the external part
+	movff	WREG,header_buffer+index_profile_version	;     - write back the cleaned byte
+	return												;     - done (WREG now ext. profile version)
 
 
 ;-----------------------------------------------------------------------------
+; Send Dive Headers in short or full Format
+;
+comm_send_headers_short:
+	SERIAL_LC_SEND 0x6D					; acknowledge command
+	bcf		aux_flag					; send short headers
+	bra		comm_send_headers_common	; continue with common part
 
 comm_send_headers_full:
 	SERIAL_LC_SEND 0x61					; acknowledge command
+	bsf		aux_flag					; send full  headers
+	;bra	comm_send_headers_common	; continue with common part
 
-	; send complete headers (256 bytes/dive)
-	; index 0: 0x200000 - 0x2000FF
-	;       1: 0x201000 - 0x2010FF
-	;       2: 0x202000 - 0x2020FF
-	;     ...
-	;     255: 0x2FF000 - 0x2FF0FF
+comm_send_headers_common:
+	clrf	ex							; start with dive having index 0
+
+comm_send_headers_loop:
+	movf	ex,W						; get index  into WREG
+	rcall	comm_helper_read_header		; get header into header_buffer
+
+	btfss	aux_flag					; shall send full  headers?
+	bra		comm_send_headers_loop_short; NO  - send short headers
+	;bra	comm_send_headers_loop_full	; YES - send full  headers
 
-	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
+comm_send_headers_loop_full:
+	SERIAL_RR_SEND header_buffer,.256	; send the full header
+	bra		comm_send_headers_loop_com	; continue with common part
+
+comm_send_headers_loop_short:
+	; send the fractions of the short header (16 byte/dive)
+	SERIAL_RR_SEND header_buffer+index_profile_byte_count,.13
+	SERIAL_RR_SEND header_buffer+index_total_dives,        .2
+	SERIAL_CC_SEND header_buffer+index_profile_version   ; .1
+	;bra	comm_send_headers_loop_com	; continue with common part
+
+comm_send_headers_loop_com:
+	incfsz	ex							; increment index, wrap-around. i.e. all dives done ?
+	bra		comm_send_headers_loop		; NO  - loop
+	bra		comm_command_loop			; YES - done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Send one full dive
+; 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)
+	SERIAL_CC_RECEIVE WREG				; (try to) receive the dive index
 	btfsc	rs232_rx_timeout			; got dive index?
-	bra		comm_command_timeout		; NO - abort, back to command loop
+	bra		comm_command_timeout		; NO - show rx timeout message and 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
+	rcall	comm_helper_read_header		; read header into header_buffer
+	bz		comm_send_dive_exit			; abort if header contains no dive
 
-	; get pointers and length of profile data
+	; get the start and end address of the 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
+
+	; header start code sequence present?
+	bcf		aux_flag					; default to no profile available
 
-	; 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
+	FLASH_CW_READ_0x20					; get the 1st byte of profile data
+	xorlw	0xFA						; 1st byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
+
+	FLASH_CW_READ_0x20					; get the 2nd byte of profile data
+	xorlw	0xFA						; 2nd byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
+
+	EXT_FLASH_INC_ADDRESS_0x20 .2		; skip the 3rd and 4th byte (dive number)
 
-	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
+	FLASH_CW_READ_0x20					; get the 5th byte of profile data
+	xorlw	0xFA						; 5th byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
+
+	FLASH_CW_READ_0x20					; get the 6th byte of profile data
+	xorlw	0xFA						; 6th byte = header start byte?
+	bnz		comm_send_dive_modify_header; NO  - no profile data available
 
-	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
+	bsf		aux_flag					; memorize profile data available
+	bra		comm_send_dive_header		; continue with sending header 
 
-	bra		comm_command_loop			; start = end -> no profile data available, abort, back to command loop
+comm_send_dive_modify_header:
+	; set profile data start and end address to 0x000000
+	CLRR	header_buffer+index_profile_start_address,.6
+
+	; set hi = 0x00, lo = 0x08
+	MOVLI	0x0008,mpr
 
-comm_send_dive1:
-	; send the header from the buffer
-	SERIAL_RR_SEND_RAM header_buffer,.256
+	; set byte count to 0x000008
+	movff	lo,header_buffer+index_profile_byte_count+0		; = 0x08
+	movff	hi,header_buffer+index_profile_byte_count+1		; = 0x00
+	movff	hi,header_buffer+index_profile_byte_count+2		; = 0x00
+
+comm_send_dive_header:
+	SERIAL_RR_SEND header_buffer,.256	; send the header from the buffer
+
+	btfss	aux_flag					; profile data available?
+	bra		comm_send_dive_empty_profile; NO - send empty profile
+
+comm_send_dive_profile:
+	FLASH_CW_READ_0x20					; read one byte and increment address with rollover at 0x200000
+	SERIAL_CC_SEND WREG					; transmit the byte
+
+	; 24 bit compare of current address with end address
+	movf	ext_flash_end_pointer+0,W	; check low   byte of addresses
+	cpfseq	ext_flash_address+0			; current address = end address ?
+	bra		comm_send_dive_profile		; NO  - more bytes to do, loop
 
-	; 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
+	movf	ext_flash_end_pointer+1,W	; check high  byte of addresses
+	cpfseq	ext_flash_address+1			; current address = end address ?
+	bra		comm_send_dive_profile		; NO  - more bytes to do, loop
+
+	movf	ext_flash_end_pointer+2,W	; check upper byte of addresses
+	cpfseq	ext_flash_address+2			; current address = end address ?
+	bra		comm_send_dive_profile		; NO  - more bytes to do, loop
+
+comm_send_dive_exit:
+	bra		comm_command_loop			; done, back to command loop
+
+comm_send_dive_empty_profile:
+
+	; send profile length
+	SERIAL_RR_SEND header_buffer+index_profile_byte_count,.3
+
+	SERIAL_LC_SEND 0xFD					; send end-of-profile sequence, byte 1
+	SERIAL_LC_SEND 0xFD					; send end-of-profile sequence, byte 2
+
+	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
@@ -587,16 +675,18 @@
 
 
 ;-----------------------------------------------------------------------------
-; Set Custom Text String (opt_name_length ASCII chars)
+; Set Custom Text (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
+	CLRR	opt_name,opt_name_length			; clear old custom text
 
-	; receive new custom text (less than opt_name_length characters may be sent)
-	SERIAL_RR_RECEIVE_RAM opt_name,opt_name_length
+	bcf		INTCON,GIE							; disable all interrupts
+	SERIAL_LC_SEND 0x63							; acknowledge command
+	SERIAL_RR_RECEIVE opt_name,opt_name_length	; receive new custom text
+	bsf		INTCON,GIE							; re-enable all interrupts
+	bsf		option_changed						; flag that EEPROM needs to be updated
 
-	bra		comm_command_loop			; done, back to command loop
+	bra		comm_command_loop					; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
@@ -612,9 +702,9 @@
 ; 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
+;	SERIAL_LC_SEND 0x22						; acknowledge command (not done)
+	call	erase_complete_logbook			; erase complete logbook
+	bra		comm_command_loop				; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
@@ -622,10 +712,10 @@
 ;
 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_SMALL comm_status3_column, comm_status3_row		; set position
+	FONT_COLOR_MEMO										; set standard color
+	STRCPY_TEXT_PRINT tUsbLlBld							; print "Low-level Bootloader" message
 
 	WIN_TOP  comm_warning_row							; set row    for icon
 	WIN_LEFT comm_warning_column						; set column for icon
@@ -635,26 +725,31 @@
 
 	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 ?
+	btfsc	option_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
+;	WAITS	.1											; wait 1 second to give the serial I/F time
+;														; to send the ackn before it gets shut down
+
+	goto	0x1FF0C										; jump into the bootloader code for cold start
 
 
 ;-----------------------------------------------------------------------------
-; Send Firmware to Bootloader (aka initiate firmware update)
+; Send Firmware to Bootloader (aka initiate Firmware Update)
 ;
 comm_firmware_update:
+	bcf		INTCON,GIE					; disable all interrupts
 	SERIAL_LC_SEND 0x50					; acknowledge command
+	SERIAL_RR_RECEIVE buffer,.5			; (try to) receive 5 byte checksum
+	bsf		INTCON,GIE					; re-enable all interrupts
 
-	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
 
 	; check the checksum
 	movlw	0x55						; initialize checksum check-byte
 	movwf	hi							; store in hi
-	lfsr	FSR2,buffer					; load base address of buffer
+	INIT_BUFFER							; go back to start of the buffer
 	movlw	.5							; 5 bytes to process
 	movwf	lo							; initialize loop counter
 comm_firmware_update_loop:
@@ -668,146 +763,161 @@
 
 	; 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
+	WAITS	.1							; wait 1 second to give the serial I/F time
+										; to send the 0x4C before it gets shut down
+	;bra	comm_firmware_update_exec	; execute update
 
+	global	comm_firmware_update_exec
+comm_firmware_update_exec:
+	call	eeprom_memorize_fw_checksum	; memorize fw checksum in EEPROM
 	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 ?
+	btfsc	option_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 for firmware update
 
-	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
+	FONT_COLOR_WARNING					; set warning 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
+	SERIAL_LC_SEND 0xFF					; send checksum failure message
+	bra		comm_command_loop			; done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; Erase a single Block or a Range of Blocks
+;
+comm_erase_single_4kb:
+	bcf		INTCON,GIE					; disable all interrupts
+	bcf		aux_flag					; do a single block only
+;	SERIAL_LC_SEND 0x40					; acknowledge command (not done)
+	bra		comm_erase_get_start		; continue with getting start address
+
+comm_erase_range_4kb:
+	bcf		INTCON,GIE					; disable all interrupts
+	bsf		aux_flag					; do a range of blocks
+	SERIAL_LC_SEND 0x42					; acknowledge command
+	;bra	comm_erase_get_start		; continue with getting start address
+
+comm_erase_get_start:
+	rcall	comm_get_start_address		; (try to) get the start address
+	btfsc	rs232_rx_timeout			; got start address?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
+	btfsc	aux_flag					; YES - shall erase a range of blocks?
+	bra		comm_erase_get_count		;       YES - get the block count
+	movlw	.1							;       NO  - set   1 block to do
+	movwf	WREG						;           - ...
+	bra		comm_erase_common			;           - start the erasing
+
+comm_erase_get_count:
+	SERIAL_CC_RECEIVE WREG				; (try to) receive the block count
+	btfsc	rs232_rx_timeout			; got block count?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
+	tstfsz	WREG						; YES - block count = 0 ?
+	bra		comm_erase_common			;       NO  - start the erasing
+	bra		comm_command_error			;       YES - invalid, show error message and back to command loop
+
+comm_erase_common:
+	bsf		INTCON,GIE					; re-enable all interrupts
+	call	ext_flash_erase_range		; erase #WREG 4kB blocks starting at ext_flash_address
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Erase a Memory Range given byte Start Address and Number of 4 kB Blocks
+; Write a Stream of Bytes to the FLASH beginning at given Start Address, finish on Timeout
 ;
-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
+comm_write_range_stream:
+	bcf		INTCON,GIE						; disable all interrupts
+	SERIAL_LC_SEND 0x30						; acknowledge command
 
-	; (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
+	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  - show rx timeout message and back to command loop
+
+ IFDEF _comm_debug
+	CLRI	mpr								; clear mpr to be used as a 16 bit counter
+ ENDIF
 
-	; 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
+comm_write_range_stream_loop:
+	SERIAL_CC_RECEIVE WREG					; (try to) receive one byte
+	btfsc	rs232_rx_timeout				; got a byte?
+ IFNDEF _comm_debug
+	bra		comm_command_loop				; NO  - timeout, done, back to command loop
+ ELSE
+	bra		comm_command_debug				; NO  - timeout, done, show number of bytes received
+ ENDIF
+;	bsf		NCTS							; YES - hold    Bluetooth chip (requires PC/Android/iOS side to use flow control...)
+	call	ext_flash_write_byte_0x40_nowait;     - write byte to FLASH, increase address with rollover at 0x400000, does not wait on FLASH
+;	bcf		NCTS							;     - release Bluetooth chip (requires PC/Android/iOS side to use flow control...)
+ IFDEF _comm_debug
+	INCI	mpr								; increment counter
+ ENDIF
+	bra		comm_write_range_stream_loop	;     - loop
 
 
 ;-----------------------------------------------------------------------------
-; Write a stream of bytes to the FLASH beginning at given start address, end on timeout
+; Write a Block of 256 Bytes to the FLASH beginning at given Start Address (low byte needs to be zero)
 ;
-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
+comm_write_range_block:
+	bcf		INTCON,GIE					; disable all interrupts
+	SERIAL_LC_SEND 0x31					; acknowledge command
+
+	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  - show rx timeout message and 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
+	tstfsz	ext_flash_address+0			; low byte of start address = 0 ?
+	bra		comm_command_error			; NO  - show error message and back to command loop
+
+	SERIAL_RR_RECEIVE buffer,.256		; (try to) receive 256 byte and buffer them in memory
+	bsf		INTCON,GIE					; re-enable all interrupts
+	btfsc	rs232_rx_timeout			; got all 256 bytes?
+	bra		comm_command_timeout		; NO  - show rx timeout message and back to command loop
+
+	FLASH_RR_WRITE buffer,.256 			; copy from memory to FLASH
+	bra		comm_command_loop			; done, back to command 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
+; Read a Memory Range from FLASH given by Start Address and Byte Count
 ;
 comm_read_range:
+	bcf		INTCON,GIE					; disable all interrupts
 	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
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
+
+	; receive byte count
+	rcall	comm_get_length				; (try to) get the byte count
+	btfsc	rs232_rx_timeout			; got a complete byte count?
+	bra		comm_command_timeout		; NO - show rx timeout message and 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
+	bsf		INTCON,GIE					; re-enable all interrupts
+
+	; decrement byte counter by 1 so that all bytes will be done when the counter wraps around to 0xFFFFFF
+	EXT_FLASH_DEC_LENGTH
+
+	; check validity of the byte count
+	movlw	0x40						; now the byte count is allowed to be 0x3FFFFF at max
+	cpfslt	ext_flash_length_counter+2	; length count < 0x40(0000) ?
+	bra		comm_command_error			; NO  - show error message and 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
+	call	ext_flash_read_block_start	; 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
+	EXT_FLASH_DEC_LENGTH				; decrement byte 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
@@ -818,32 +928,32 @@
 ; 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
+	SERIAL_RR_RECEIVE ext_flash_address,.3	; (try to) 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
+	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
+	SERIAL_RR_RECEIVE 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
+	return											; done, complete start address available
 
 
 ;-----------------------------------------------------------------------------
@@ -853,12 +963,12 @@
 	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
+	bra		comm_command_loop			; NO - show rx timeout message and 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
+	bra		comm_command_error			; NO  - show error message and back to command loop
 
 	; option index 0x10 - 0x19: gases & diluents
 	movlw	0x19						; last option index for gases / diluents
@@ -875,26 +985,23 @@
 	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
+	; option index 0x1F - 0xF9: options managed by option table
+	movlw	0xF9						; last option index for options
+	cpfsgt	lo							; received option index > end of options range?
+	bra		comm_read_option_index		; YES - process option value read via index
 
-comm_read_setting_fail:
-	SERIAL_LC_SEND	0x00				; send a dummy value
-	bra		comm_command_error			; back to command loop with failure message
+	bra		comm_command_error			; NO  - illegal option index
 
 
 ;-----------------------------------------------------------------------------
 ; Write an Option Value
 ;
 comm_write_option:
+	bcf		INTCON,GIE					; disable all interrupts
 	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
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
 
 	; option index 0x00 - 0x0F: unused
 	movlw	0x0F						; last option index of the unused range
@@ -916,7 +1023,33 @@
 	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
+	; option index 0x1F - 0xF9: options managed by option table
+	movlw	0xF9						; last option index for options
+	cpfsgt	lo							; received option index > end of options range?
+	bra		comm_write_option_index		; YES - process option value write via index
+
+	bra		comm_write_unused			; NO  - illegal option index
+
+
+;-----------------------------------------------------------------------------
+; Read an Option Value via its Serial Index
+;
+comm_read_option_index:
+	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 via its Serial Index
+;
+comm_write_option_index:
 	SERIAL_CC_RECEIVE hi				; (try to) receive option value
 	btfsc	rs232_rx_timeout			; got a byte?
 	bra		comm_command_timeout		; NO  - abort
@@ -931,7 +1064,7 @@
 
 
 ;-----------------------------------------------------------------------------
-; Read button polarity
+; Read Button Polarity
 ;
 comm_read_button_polarity:
 	SERIAL_CC_SEND	button_polarity		; send current button polarity setting
@@ -939,21 +1072,21 @@
 
 
 ;-----------------------------------------------------------------------------
-; Write button polarity
+; 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
+	bra		comm_command_timeout		; NO  - show rx timeout message and 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
+; Read a Gas/Diluent Dataset
 ;
-; Memory map is as follows:
+; memory map is as follows:
 ; -------------------------
 ; opt_gas_O2_ratio			res 5		; O2 ratios of OC/bailout gases
 ; opt_dil_O2_ratio			res 5		; O2 ratios of diluents
@@ -979,9 +1112,9 @@
 
 
 ; ----------------------------------------------------------------------------
-; Write a gas/diluent dataset
+; Write a Gas/Diluent Dataset
 ;
-; Memory map is as follows:
+; memory map is as follows:
 ; -------------------------
 ; opt_gas_O2_ratio			res 5		; O2 ratios of OC/bailout gases
 ; opt_dil_O2_ratio			res 5		; O2 ratios of diluents
@@ -993,62 +1126,63 @@
 ; 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
+	SERIAL_RR_RECEIVE 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
+	bra		comm_command_timeout		; NO - show rx timeout message and back to command loop
 
 	; 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
+	bra		comm_command_error			; NO - show error message and 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
+	bra		comm_command_error			; NO - show error message and 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
+	bra		comm_command_error			; NO - show error message and back to command loop
 
+ IFDEF _helium
 	; check O2% + He% <= 100%
-	movlw	.100						; load 100%
+	movlw	.100						; load WREG with 100%
 	bsf		STATUS,C					; set carry = clear borrow
-	subfwb	hi,W						; subtract O2% from 100%
+	subfwb	hi,W						; subtract O2% from WREG
+	subfwb	up,W						; subtract He% from WREG
 	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
+	bra		comm_command_error			; YES - show error message and back to command loop
+ ENDIF	; _helium
 
 	; 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
+	bra		comm_write_check_dil		; YES - check type for diluents
+	;bra	comm_write_check_gas		; NO  - check type for gases
 
-comm_write_gas:
+comm_write_check_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
+	bra		comm_write_check_com		; continue with common part
 
-comm_write_dil:
+comm_write_check_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
+	;bra	comm_write_check_com		; continue with common part
 
-comm_write_gas_dil_common:
+comm_write_check_com:
 	cpfslt	ex							; received type < max ?
-	bra		comm_command_error			; NO  - abort, back to command loop
+	bra		comm_command_error			; NO  - show error message and 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
+	bra		comm_command_error			; NO - show error message and back to command loop
 
 	; all values ok, can finally be written
 	lfsr	FSR0,opt_gas_O2_ratio		; load base address of gas data arrays
 	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
@@ -1057,13 +1191,14 @@
 	addlw	.10							; increment WREG by 10 to point to change depth
 	movff	ul,PLUSW0					; set change depth
 
+	bsf		option_changed				; flag that EEPROM needs to be updated
 	bra		comm_command_loop			; done, back to command loop
 
 
 ;-----------------------------------------------------------------------------
-; Read a setpoint dataset
+; Read a Setpoint Dataset
 ;
-; Memory map is as follows:
+; 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
@@ -1079,38 +1214,45 @@
 
 
 ;-----------------------------------------------------------------------------
-; Write a setpoint dataset
+; Write a Setpoint Dataset
 ;
-; Memory map is as follows:
+; 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
+	SERIAL_RR_RECEIVE 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
+	bra		comm_command_timeout		; NO - show rx timeout message and 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
+	bra		comm_command_error			; NO - show error message and 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
+	bra		comm_command_error			; NO - show error message and back to command loop
 
 	; check validity of change depth
-	movlw	sp_max_change_depth+.1		; get max value plus 1
+	movlw	gaslist_sp_max_depth+.1		; get max value plus 1
 	cpfslt	up							; received change depth <= max ?
-	bra		comm_command_error			; NO - abort, back to command loop
+	bra		comm_command_error			; NO - show error message and 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
+
+	bnz		comm_write_sp_exec			; selected SP is 2...5 -> execute write
+	tstfsz	up							; SP1: change depth = 0 ?
+	bra		comm_command_error			; NO - show error message and back to command loop
+
+comm_write_sp_exec:
 	movff	hi,PLUSW0					; set cbar value
 	addlw	.5							; increment WREG by 5 to point to change depth
 	movff	up,PLUSW0					; set change depth
 
+	bsf		option_changed				; flag that EEPROM needs to be updated
 	bra		comm_command_loop			; done, back to command loop
 
 ;-----------------------------------------------------------------------------
--- a/src/comm.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/comm.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File comm.inc                              combined next generation V3.0.1
+;   File comm.inc                            * combined next generation V3.9.4b
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -9,3 +9,4 @@
 ;  2011-08-22 : [mH] creation
 
 	extern	comm_mode_usb
+	extern	comm_mode_bt
--- a/src/compass_calib.c	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/compass_calib.c	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 //
-// compass_calib.c                                    next generation V3.03.4
+// compass_calib.c                                    next generation V3.09.4
 //
 // Calibrate hard-iron for magnetic compass measurements.
 // Copyright (c) 2012-2019, JD Gascuel, HeinrichsWeikamp, all rights reserved.
@@ -31,6 +31,7 @@
 			LFSR	2, 0x800	\
 		_endasm
 #	pragma udata overlay bank9_compass
+#	pragma code compass_cal
 #else
 #	define RESET_C_STACK
 #endif
--- a/src/compass_ops.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/compass_ops.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,23 +1,24 @@
 ;=============================================================================
 ;
-;   File compass_ops.asm                      combined next generation V3.08.8
+;   File compass_ops.asm                      combined next generation V3.09.5
 ;
 ;   Compass Operations
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
 ;=============================================================================
 
-#include	"hwos.inc"
-#include	"i2c.inc"
-#include	"tft_outputs.inc"
-#include	"tft.inc"
-#include	"strings.inc"
-#include	"wait.inc"
-#include	"surfmode.inc"
-#include	"divemode.inc"
-#include	"math.inc"
-#include	"convert.inc"
-#include	"start.inc"
+#include "hwos.inc"
+#include "i2c.inc"
+#include "tft_outputs.inc"
+#include "tft.inc"
+#include "strings.inc"
+#include "wait.inc"
+#include "surfmode.inc"
+#include "divemode.inc"
+#include "math.inc"
+#include "convert.inc"
+#include "start.inc"
+#include "colorschemes.inc"
 
 
  IFDEF _compass
@@ -67,9 +68,10 @@
 	extern	option_check_and_store_all
 
 
-compass_ops	code
+;=============================================================================
+compass_ops1	CODE
+;=============================================================================
 
-;=============================================================================
 
 ;-----------------------------------------------------------------------------
 ; Filter compass values
@@ -116,17 +118,10 @@
 	banksel	common						; back to bank common
 	return
 
-;-----------------------------------------------------------------------------
 
-compass_filter_init:
-	MOVII	compass_DX,compass_DX_f
-	MOVII	compass_DY,compass_DY_f
-	MOVII	compass_DZ,compass_DZ_f
-
-	MOVII	accel_DX,accel_DX_f
-	MOVII	accel_DY,accel_DY_f
-	MOVII	accel_DZ,accel_DZ_f
-	return
+;=============================================================================
+compass_ops2	CODE
+;=============================================================================
 
 ;-----------------------------------------------------------------------------
 ; Q15 fractional numbers: a * b / 2**16 (UNSIGNED)
@@ -215,22 +210,25 @@
 	bsf		compass_r+1,6
 	bra		compass_mul_2
 
-;-----------------------------------------------------------------------------
 
-	global	compass_calibration_loop
-compass_calibration_loop:				; compass calibration
+;=============================================================================
+compass_ops3	CODE
+;=============================================================================
+
+	global	compass_calibration
+compass_calibration:					; compass calibration
 	bsf		block_sensor_interrupt		; disable sensor interrupts
 	call	I2C_sleep_compass			; stop compass
-	call	TFT_ClearScreen
+	call	TFT_ClearScreen				; clear the screen
 	; Mask
-	WIN_COLOR color_greenish
-	WIN_SMALL .16,.0
-	STRCPY_TEXT_PRINT tCompassMenu
-	btfss	switch_right2				; wait until button is released
+	WIN_STD .16,.0						; set position
+	FONT_COLOR color_greenish			; set font color
+	STRCPY_TEXT_PRINT tCompassCalibration
+	btfss	switch_right2				; wait until button (with a moving magnet in some OSTC!) is released
 	bra		$-2
 
-	call	TFT_standard_color
 ;	WIN_SMALL .0,.215
+;	FONT_COLOR	color_standard
 ;	STRCPY_TEXT_PRINT tExit
 	WAITMS	d'255'
 	WAITMS	d'255'
@@ -238,11 +236,11 @@
 	call	request_speed_fastest		; request CPU speed change to fastest speed
 
 	movlw	.7							; initialize gain
-	movff	WREG,opt_compass_gain
+	movff	WREG,opt_compass_gain		; ...
 
 	movlw	.60							; initialize timeout to 60 seconds
 	movwf	isr_timeout_reload			; copy WREG to isr_timeout_reload
-	bsf		reset_timeout				; request ISR to reset the timeout
+	bsf		restart_timeout				; request ISR to restart the timeout
 	bcf		trigger_timeout				; clear any pending timeout trigger
 compass_calibration_gainset:			; reduce the gain, set bank here!
 	banksel	opt_compass_gain			; select bank options table
@@ -250,10 +248,10 @@
 	btfsc	STATUS,N					; < 0 ?
 	clrf	opt_compass_gain			; YES - keep at zero
 	btfsc	STATUS,N					; < 0 ?
-	bra	compass_calibration_loop1		; YES - skip gain stuff (Would hang here in case of compass failure)
+	bra		compass_calibration_loop1	; YES - skip gain stuff (Would hang here in case of compass failure)
 	banksel	common						; bank to bank common
 
-	call	I2C_init_compass
+	call	I2C_init_compass			; initialize compass chip
 
 	btfsc	compass_type3				; compass type 3 ?
 	bra		compass_calibration_loop1	; YES - skip gain stuff
@@ -266,7 +264,7 @@
 	WAITMS	d'250'						; wait for first reading...
 
 	movlw	.60							; calibration shall run for 60 seconds
-	call	reset_timeout_time			; set timeout
+	call	restart_timeout_time		; restart the timeout
 
 	call	I2C_RX_compass				; read compass
 	call	I2C_RX_accelerometer		; read accelerometer
@@ -305,12 +303,12 @@
 compass_calibration_loop2:
 	call	I2C_RX_compass				; read compass
 	call	I2C_RX_accelerometer		; test accelerometer
-	rcall	compass_filter				; filter compass raw data
+	call	compass_filter				; filter compass raw data
 
 	; Twice
 	call	I2C_RX_compass				; read compass
 	call	I2C_RX_accelerometer		; test accelerometer
-	rcall	compass_filter				; filter compass raw data
+	call	compass_filter				; filter compass raw data
 
 ;	btfsc	compass_type1				; compass1?
 ;	bra		compass_calibration_loop3	; YES -  skip gain stuff
@@ -340,7 +338,7 @@
 	bra		$+4
 	bra		compass_calibration_gainset
 	banksel	common						; back to bank common
-;
+
 ;	; Three
 ;	call	I2C_RX_compass				; read compass
 ;	call	I2C_RX_accelerometer		; test accelerometer
@@ -373,7 +371,7 @@
 
 	call	request_speed_normal		; request CPU speed change to normal speed
 
-	bsf		options_changed				; flag that option values have changed
+	bsf		option_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
@@ -381,85 +379,125 @@
 
 	goto	restart						; done
 
-;-----------------------------------------------------------------------------
 
-TFT_compass_fast:
-	WIN_TINY .0,.50
-	STRCPY	"Cx:"
-	MOVII	compass_DX,mpr
-	call	TFT_convert_signed_16bit	; convert lo:hi into signed-short and add '-' to POSTINC2 if required
-	output_16
-	STRCAT	" Cy:"
-	MOVII	compass_DY,mpr
-	call	TFT_convert_signed_16bit	; convert lo:hi into signed-short and add '-' to POSTINC2 if required
-	output_16
-	STRCAT	" Cz:"
-	MOVII	compass_DZ,mpr
-	call	TFT_convert_signed_16bit	; convert lo:hi into signed-short and add '-' to POSTINC2 if required
-	output_16
-	STRCAT_PRINT "  "
+;-----------------------------------------------------------------------------
+; Helper Function
+;
+compass_filter_init:
+	MOVII	compass_DX,compass_DX_f
+	MOVII	compass_DY,compass_DY_f
+	MOVII	compass_DZ,compass_DZ_f
 
-	WIN_TINY .0,.104
-	STRCPY	"Ax:"
-	MOVII	accel_DX,mpr
-	call	TFT_convert_signed_16bit	; convert lo:hi into signed-short and add '-' to POSTINC2 if required
-	output_16
-	STRCAT	" Ay:"
-	MOVII	accel_DY,mpr
-	call	TFT_convert_signed_16bit	; convert lo:hi into signed-short and add '-' to POSTINC2 if required
-	output_16
-	STRCAT	" Az:"
-	MOVII	accel_DZ,mpr
-	call	TFT_convert_signed_16bit	; convert lo:hi into signed-short and add '-' to POSTINC2 if required
-	output_16
-	STRCAT_PRINT "  "
+	MOVII	accel_DX,accel_DX_f
+	MOVII	accel_DY,accel_DY_f
+	MOVII	accel_DZ,accel_DZ_f
 	return
 
-TFT_show_timeout_testmode:
-	WIN_TINY .0,.68
-	STRCPY	"T:"
-	movff	isr_timeout_timer,lo
-	bsf		leftbind
-	output_8							; display remaining time
-	bcf		leftbind
-	STRCAT_PRINT "s "
+;-----------------------------------------------------------------------------
+; Show Calibration Progress
+;
+TFT_compass_fast:
+	WIN_TINY .0,.50					; set font and position
+	FONT_COLOR_MEMO					; set font color
+
+	STRCPY	"Cx:"					; print label
+	MOVII	compass_DX,mpr			; get   value
+	rcall	TFT_compass_fast_helper ; print value
+
+	STRCAT	" Cy:"					; print label
+	MOVII	compass_DY,mpr			; get   value
+	rcall	TFT_compass_fast_helper ; print value
+
+	STRCAT	" Cz:"					; print label
+	MOVII	compass_DZ,mpr			; get   value
+	rcall	TFT_compass_fast_helper ; print value
+
+	PRINT							; dump to screen
+
+	WIN_TINY .0,.104				; set font and position
+	FONT_COLOR_MEMO					; set font color
+
+	STRCPY	"Ax:"					; print label
+	MOVII	accel_DX,mpr			; get   value
+	rcall	TFT_compass_fast_helper ; print value
+
+	STRCAT	" Ay:"					; print label
+	MOVII	accel_DY,mpr			; get   value
+	rcall	TFT_compass_fast_helper ; print value
+
+	STRCAT	" Az:"					; print label
+	MOVII	accel_DZ,mpr			; get   value
+	rcall	TFT_compass_fast_helper ; print value
+
+	PRINT							; dump to screen
+	return							; done
+
+
+TFT_compass_fast_helper:
+	call	convert_signed_16bit	; convert lo:hi into unsigned-short and add '-' to POSTINC2 if required
+	btfsc	neg_flag				; is value negative?
+	bra		TFT_compass_fast_helper1; YES - print value
+	PUTC	'+'						; NO  - print a plus sign first
+TFT_compass_fast_helper1:
+	output_65535					; print value (0-65535)
 	return
 
+
+
+;-----------------------------------------------------------------------------
+; Show remaining Calibration Time
+;
+TFT_show_timeout_testmode:
+	WIN_TINY .0,.68						; set font and position
+	FONT_COLOR_MEMO						; set font color
+	STRCPY	"T:"						; print label
+	movff	isr_timeout_timer,lo		; get remaining time
+	output_256							; print remaining time (xxx)
+	PUTC_PRINT "s"						; append unit and dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Show current Compass Gain
+;
 TFT_compass_show_gain:					; show the current compass gain
 ;	movff	opt_compass_gain,lo			; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss)
 ;	tstfsz	lo
-;	return								; do not show unless gain=0
-	WIN_TINY .0,.86
-	STRCPY_TEXT tCompassGain
-	movff	opt_compass_gain,lo			; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss)
-	bsf		leftbind
-	output_8
-	bcf		leftbind
-	STRCAT_PRINT ""
-	return
+;	return								; do not show unless gain > 0
+	WIN_TINY .0,.86						; set font and position
+	FONT_COLOR_MEMO						; set font color
+	STRCPY_TEXT tCompassGain			; print label
+	movff	opt_compass_gain,lo			; get value: 0-7 (230 LSB/Gauss to 1370 LSB/Gauss)
+	output_99							; print value (xx)
+	PRINT								; dump to screen
+	return								; done
+
+
+;=============================================================================
+compass_ops4	CODE
+;=============================================================================
 
 ;-----------------------------------------------------------------------------
-
+; Mask for Compass in Surface Mode
+;
 	global	TFT_surface_compass_mask
 TFT_surface_compass_mask:
 	WIN_SMALL surf_compass_mask_column,surf_compass_mask_row
-	call	TFT_standard_color
+	FONT_COLOR_MEMO						; set font color
 	STRCPY_TEXT_PRINT tHeading			; print "Heading:"
-	return
+	return								; done
 
 
-	global	TFT_dive_compass_mask		; draws the white box around the heading tape
-TFT_dive_compass_mask:
-	WIN_FRAME_STD dm_custom_compass_graph_row, dm_custom_compass_graph_row+dm_custom_compass_graph_height, .0, .159
-	return
-
-
+;-----------------------------------------------------------------------------
+; Compass Display in Surface Mode
+;
 	global	TFT_surface_compass_heading
 TFT_surface_compass_heading:
-	rcall	compass_heading_common
+	call	compass_heading_common		; compute heading
 	WIN_STD	surf_compass_head_column,surf_compass_head_row
-	call	TFT_standard_color
+
 TFT_surface_compass_heading_com:		; show "000° N"
+	FONT_COLOR_MEMO						; set default / dive-mode standard color
 	movff	compass_heading_new+1,WREG	; get upper byte of actual heading
 	btfsc	WREG,7						; compass calibrated?
 	bra		TFT_compass_uncalibrated	; NO
@@ -474,22 +512,15 @@
 	return								; YES - done
 	; show bearing
 	WIN_SMALL surf_compass_bear_column,surf_compass_bear_row
-	call	TFT_attention_color
+	FONT_COLOR	color_yellow			; set font color
 	MOVII	compass_bearing,mpr			; get bearing
 	;bra	TFT_compass_helper			; show number and cardinal and return
 
 TFT_compass_helper:
-	bsf		leftbind
-	output_16dp .2						; result is "0.000" in buffer
-	bcf		leftbind
-	; rearrange figures to "000"
-	movff	buffer+2,buffer+0
-	movff	buffer+3,buffer+1
-	movff	buffer+4,buffer+2
-	lfsr	FSR2,buffer+3
-	STRCAT	"° "
-	rcall	tft_compass_cardinal		; add cardinal to POSTINC2
-	STRCAT_PRINT ""						; finalize output
+	output_999							; print bearing
+	STRCAT	"° "						; append unit and a space
+	call	tft_compass_cardinal		; append cardinal buffer
+	PRINT								; dump to screen
 	return								; done
 
 TFT_compass_uncalibrated:
@@ -497,17 +528,34 @@
 	return								; done
 
 
+;=============================================================================
+compass_ops5	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Mask for Compass in Dive Mode
+;
+	global	TFT_dive_compass_mask		; draws the white box around the heading tape
+TFT_dive_compass_mask:
+	WIN_FRAME_STD dm_custom_compass_graph_row, dm_custom_compass_graph_row+dm_custom_compass_graph_height, .0, .159
+	return
+
+
+;-----------------------------------------------------------------------------
+; Compass Display in Dive Mode
+;
 	global	TFT_dive_compass_heading
 TFT_dive_compass_heading:
-	rcall	compass_heading_common
-	WIN_FONT FT_SMALL					; set font size
+	call	compass_heading_common		; compute heading
 
 ;	; ### for development only, hard-coding the bearing ###
 ;	; 244° : SW - W
 ;	MOVLI	.244,xA						; xA used as temp
 ;	MOVII	xA,compass_bearing			; compass_bearing is stored in bank isr_backup
 
-	MOVII	compass_heading_shown,xA
+	FONT_SIZE FT_SMALL					; set font size
+	MOVII	compass_heading_shown,xA	; get heading
 	; 160° viewing angle: add +360 offset if xA <= 292 for non-negative scale
 	MOVLI	.292,sub_a
 	MOVII	xA,  sub_b
@@ -734,14 +782,14 @@
 	movwf	win_top						; set position for upper ticks
 	movlw	dm_custom_compass_tick_height
 	movwf	win_height					; set hight of ticks
-	call	TFT_standard_color			; set color
-	call	TFT_box						; draw tick
+	movf	pallet_color_memo,W			; select color
+	BOX_COLOR							; draw tick
 	movlw	dm_custom_compass_tick_bot_top
 	movwf	win_top						; set position for lower ticks
 	movlw	dm_custom_compass_tick_height
 	movwf	win_height					; set hight of ticks
-	call	TFT_standard_color			; color in WREG is trashed, must be set again!
-	call	TFT_box						; draw tick
+	movf	pallet_color_memo,W			; select color
+	BOX_COLOR							; draw tick
 	; 4. If D < 82 and RM > 79: means we put something over the center line,
 	;							so redraw the center line
 	movlw	d'82'
@@ -776,6 +824,7 @@
 
 TFT_dive_compass_labels:
 	; done with the compass ruler, put the labels on the screen
+	FONT_COLOR_MEMO						; set dive-mode standard color
 	clrf	hi							; hi stores the display position
 	movff	hi,xHI						; bank-safe clear of xHI
 	clrf	lo							; lo stores the last item's display position
@@ -898,8 +947,7 @@
 	bra		TFT_dive_compass_text
 
 TFT_dive_compass_dir_text_2:
-	movlw	color_green
-	call	TFT_set_color
+	FONT_COLOR color_green
 	btfsc	compass_bearing_lft
 	bra		TFT_dive_compass_dir_ldir	; bearing_lft=1, print the left marker
 ;TFT_dive_compass_text_rdir:
@@ -919,9 +967,8 @@
 	WIN_BOX_BLACK dm_custom_compass_tick_top_bot+.1,dm_custom_compass_tick_bot_top-.1,.158,.159	; top, bottom, left, right
 
 	; Text output
-	call	TFT_standard_color
 	WIN_SMALL dm_custom_compass_head_column, dm_custom_compass_head_row
-	rcall	TFT_surface_compass_heading_com	; show "xxx° N"
+	call	TFT_surface_compass_heading_com	; show "xxx° N"
 	return
 
 TFT_dive_compass_dir_lclr:
@@ -971,13 +1018,13 @@
 	rcall	TFT_dive_compass_clr_label
 TFT_dive_compass_label_proc_p:
 	; 4. print the SQ on the screen
-	call	TFT_standard_color
+	FONT_COLOR_MEMO
 	bsf		compass_show_cardinal
 ;TFT_dive_compass_label_print:
-	movlw	dm_custom_compass_label_row
-	movff	WREG,win_top
-	movff	lo,win_leftx2
-	WIN_FONT FT_SMALL
+	movlw	dm_custom_compass_label_row	; set output position
+	movff	WREG,win_top				; ...
+	movff	lo,win_leftx2				; ...
+	FONT_SIZE FT_SMALL					; set font size
 	; 6. retain the new display positions
 	movff	lo,hi
 	movff	up,WREG
@@ -1079,9 +1126,8 @@
 	clrf	win_width+1
 	movlw	color_green
 	btfss	compass_show_cardinal
-	movlw	color_red
-	call	TFT_set_color
-	call	TFT_box
+	movlw	color_red						; select color
+	BOX_COLOR									; draw box
 TFT_dive_compass_mk_print_5:
 	return
 
@@ -1120,9 +1166,8 @@
 	cpfsgt	win_width+0
 	bra		TFT_dive_compass_clear3		; do not clear a single pixel (or less)
 	movff	hi,win_leftx2
-	movlw	color_black
-	call	TFT_set_color
-	call	TFT_box
+	movlw	color_black					; select color
+	BOX_COLOR								; draw box
 TFT_dive_compass_clear3:
 	return
 
@@ -1192,8 +1237,13 @@
 	STRCAT_TEXT	tNW
 	return
 
+;=============================================================================
+compass_ops6	CODE
+;=============================================================================
+
 ;-----------------------------------------------------------------------------
-
+; get and process heading
+;
 compass_heading_common:
 	btfss	compass_enabled				; compass enabled?
 	bra		compass_heading_common_zero	; NO
@@ -1255,7 +1305,6 @@
 	call	subU16						;     - wrap decrement result around
 	bra		compass_heading_common_6	;     - store wrapped result
 
-
 compass_heading_common_5:
 	; increment compass_heading_shown towards compass_heading_new
 	rcall	compass_heading_stepsize_1	; calculate step size and put it into sub_b
@@ -1292,7 +1341,8 @@
 	MOVII	sub_c,sub_b					; transfer result to sub_b
 	return
 
-
  ENDIF	; _compass
 
+;-----------------------------------------------------------------------------
+
 	END
--- a/src/configuration.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/configuration.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,7 +1,7 @@
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 ; ============================================================================
 ; 
-;    File configuration.inc                   combined next generation V3.08.8
+;    File configuration.inc                 * combined next generation V3.09.5
 ; 
 ;    OSTC hwOS Configuration
 ; 
@@ -24,8 +24,8 @@
 #endif
 
 #define fw_version_major		0x03
-#define fw_version_minor		0x09
-#define fw_version_beta			0x02
+#define fw_version_minor		0x0A
+#define fw_version_beta			0x00
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -43,12 +43,12 @@
 #endif
 
 #define firmware_creation_year	0x14
-#define firmware_creation_month	0x03
-#define firmware_creation_day	0x05
+#define firmware_creation_month	0x04
+#define firmware_creation_day	0x1C
 
 #define firmware_expire_year	0x15
-#define firmware_expire_month	0x01
-#define firmware_expire_day		0x01
+#define firmware_expire_month	0x02
+#define firmware_expire_day	0x01
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -56,10 +56,12 @@
 ; global Version Selection
 ; ------------------------
 ;
-; _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
+; _hwos_tech_2_TR        compile Tech  version for OSTC 2, Plus and TR en    memory: 118.656 used, 4.224 free
+; _hwos_tech_2_TR_cave   compile Tech  version for OSTC 2, Plus and TR en    memory: 120.883 used, 1.997 free
+; _hwos_tech_3_cR        compile Tech  version for OSTC 3       and cR en+de memory: 119.496 used, 3.384 free
+; _hwos_tech_3_cR_cave   compile Tech  version for OSTC 3       and cR en+de memory: 122.079 used,   801 free *
+; _hwos_sport            compile Sport version for all models          en+de memory: 116.365 used, 6.515 free
+;                                                                                    122.880 max. available
 #endif
 
 #define _hwos_tech_3_cR
@@ -73,37 +75,60 @@
 ; _language_1			first or single language,
 ;						set to 'en', 'de', 'fr', or 'it', defaults to 'en'
 ;
-; _language_2			second language, coding as above or 'none'		mem: approx. 4.0 kbyte in Sport, 4.228 kbyte in Tech
+; _language_2			second language, coding as above or 'none'		mem: approx. 4.0 kB in Sport, 4.3 kB in Tech
 ; 
 #endif
 
 #define _language_1		en
-#define _language_2		none
+#define _language_2		de
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 ;
-; Features Selection
+; Features Selection												 CODE SIZES ARE OUTDATED
 ; ------------------
-;																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 ##
+; base code without any features, 1 language (en)						mem:   93.964 byte
+; _compass				compass function								mem: + 10.404 byte
+; _helium				helium (trimix) gases and diluents				mem: +  2.113 byte || both together
+; _ccr_pscr				CCR & pSCR modes, basic functionality			mem: +  4.117 byte ||  + 6.250 byte
+; _external_sensor		CCR & pSCR modes, external sensor support		mem: +  3.343 byte
+; _gauge_mode			gauge mode										mem: -     28 byte (less)
+; _high_ppO2_max		raised ppO2 max limit (2.0 bar)					mem:        0 byte (neutral)
+; _rx_functions			RX function        (OSTC TR)					mem: +  4.497 byte
+; _rx_update			RX firmware update (OSTC TR)					mem: +  2.282 byte (dependent on RX firmware size)
+; _gas_contingency		auto-switch to alternative tanks on depleption	mem: +    804 byte
+; _cave_mode			cave mode return calculation					mem: +  3.035 byte
+; _firmware_recovery	means for backing up and restoring 2nd firmware mem: +    472 byte
+; _min_depth_option		resettable min. and max. depth					mem: +      4 byte  ## special user group only ##
+; _screendump			screen dump function							mem: +    348 byte  ## special user group only ##
 ;
 ;
-; NOTES: - Exclude options by prepending NOT_INCLUDED to the label.
-;        - Not all options will fit concurrently if two languages are slected.
-;        - Option sizes are based on single language (english), will increase
-;          with 2nd language and will differ slightly between languages.
+; NOTES: - exclude features by prepending NOT_INCLUDED to the label,
+;        - sizes may be incorrect by a couple of bytes,
+;        - not all features will fit concurrently at the same time or if two languages are slected,
+;        - feature sizes are based on single language (english)
+;        - feature sizes will increase with 2nd language and will differ slightly between languages,
+;        - combinations of features will yield code sizes that differ
+;          slightly from the simple sum of the individual sizes.
+#endif
+
+
+#ifdef _base_code
+
+#define NOT_INCLUDED_compass
+#define NOT_INCLUDED_helium
+#define NOT_INCLUDED_ccr_pscr
+#define NOT_INCLUDED_rx_functions
+#define NOT_INCLUDED_rx_update
+#define NOT_INCLUDED_gauge_mode
+#define NOT_INCLUDED_high_ppO2_max
+#define NOT_INCLUDED_gas_contingency
+#define NOT_INCLUDED_external_sensor
+#define NOT_INCLUDED_cave_mode
+#define NOT_INCLUDED_firmware_recovery
+#define NOT_INCLUDED_min_depth_option
+#define NOT_INCLUDED_screendump
+
 #endif
 
 
@@ -116,9 +141,29 @@
 #define _rx_update
 #define _gauge_mode
 #define _high_ppO2_max
+#define _gas_contingency
 #define NOT_INCLUDED_external_sensor
 #define NOT_INCLUDED_cave_mode
-#define NOT_INCLUDED_gas_contingency
+#define _firmware_recovery
+#define NOT_INCLUDED_min_depth_option
+#define NOT_INCLUDED_screendump
+
+#endif
+
+
+#ifdef _hwos_tech_2_TR_cave
+
+#define _compass
+#define _helium
+#define _ccr_pscr
+#define _rx_functions
+#define _rx_update
+#define _gauge_mode
+#define _high_ppO2_max
+#define _gas_contingency
+#define NOT_INCLUDED_external_sensor
+#define _cave_mode
+#define _firmware_recovery
 #define NOT_INCLUDED_min_depth_option
 #define NOT_INCLUDED_screendump
 
@@ -135,9 +180,28 @@
 #define NOT_INCLUDED_rx_functions
 #define NOT_INCLUDED_rx_update
 #define _external_sensor
-#define _cave_mode
 #define _gas_contingency
-#define NOT_INCLUDED_gas_contingency
+#define NOT_INCLUDED_cave_mode
+#define _firmware_recovery
+#define NOT_INCLUDED_min_depth_option
+#define NOT_INCLUDED_screendump
+
+#endif
+
+
+#ifdef _hwos_tech_3_cR_cave
+
+#define _compass
+#define _helium
+#define _ccr_pscr
+#define _gauge_mode
+#define _high_ppO2_max
+#define NOT_INCLUDED_rx_functions
+#define NOT_INCLUDED_rx_update
+#define _external_sensor
+#define _gas_contingency
+#define _cave_mode
+#define _firmware_recovery
 #define NOT_INCLUDED_min_depth_option
 #define NOT_INCLUDED_screendump
 
@@ -156,7 +220,7 @@
 #define _rx_update
 #define NOT_INCLUDED_external_sensor
 #define NOT_INCLUDED_cave_mode
-#define NOT_INCLUDED_gas_contingency
+#define _firmware_recovery
 #define NOT_INCLUDED_min_depth_option
 #define NOT_INCLUDED_screendump
 
@@ -168,9 +232,11 @@
 ; Debug Modes
 ; -----------
 ;
-; _DEBUG			put firmware in a global debug mode		default: not included
-; _profiling		deco engine performance measurements	default: not included
-; _debug_output		performance outputs (for _profiling)	default: not included
+; _DEBUG				put firmware in a global debug mode		default: not included
+; _profiling			deco engine performance measurements	default: not included
+; _debug_output			performance outputs (for _profiling)	default: not included
+; _comm_debug			add run-time adjustable RX timeout		default: not included
+; _rx_functions_debug	switch to transmitter debug custom view	default: not included
 ;
 ; NOTE: - Exclude options by prepending NOT_INCLUDED to the label
 ;
@@ -179,6 +245,8 @@
 #define NOT_INCLUDED_DEBUG
 #define NOT_INCLUDED_profiling
 #define NOT_INCLUDED_debug_output
+#define NOT_INCLUDED_comm_debug
+#define NOT_INCLUDED_rx_functions_debug
 
 
 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -213,51 +281,53 @@
 #endif
 
 #ifdef _screendump
-#define SW_CONF_1    0x01
+#define FW_CONF_1    0x01
 #else
-#define SW_CONF_1    0x00
+#define FW_CONF_1    0x00
 #endif
 
 #ifdef _compass
-#define SW_CONF_2    0x02
+#define FW_CONF_2    0x02
 #else
-#define SW_CONF_2    0x00
+#define FW_CONF_2    0x00
 #endif
 
 #ifdef _rx_functions
-#define SW_CONF_3    0x04
+#define FW_CONF_3    0x04
 #else
-#define SW_CONF_3    0x00
+#define FW_CONF_3    0x00
 #endif
 
 #ifdef _rx_update
-#define SW_CONF_4    0x08
+#define FW_CONF_4    0x08
 #else
-#define SW_CONF_4    0x00
+#define FW_CONF_4    0x00
 #endif
 
 #ifdef _helium
-#define SW_CONF_5    0x10
+#define FW_CONF_5    0x10
 #else
-#define SW_CONF_5    0x00
+#define FW_CONF_5    0x00
 #endif
 
 #ifdef _ccr_pscr
-#define SW_CONF_6    0x20
+#define FW_CONF_6    0x20
 #else
-#define SW_CONF_6    0x00
+#define FW_CONF_6    0x00
 #endif
 
 #ifdef _external_sensor
-#define SW_CONF_7    0x40
+#define FW_CONF_7    0x40
 #else
-#define SW_CONF_7    0x00
+#define FW_CONF_7    0x00
 #endif
 
 #ifdef _cave_mode
-#define SW_CONF_8    0x80
+#define FW_CONF_8    0x80
 #else
-#define SW_CONF_8    0x00
+#define FW_CONF_8    0x00
 #endif
 
-#define SW_CONF  SW_CONF_1 + SW_CONF_2 + SW_CONF_3 + SW_CONF_4 + SW_CONF_5 + SW_CONF_6 + SW_CONF_7 + SW_CONF_8
+#define FW_CONF  FW_CONF_1 + FW_CONF_2 + FW_CONF_3 + FW_CONF_4 + FW_CONF_5 + FW_CONF_6 + FW_CONF_7 + FW_CONF_8
+
+#define FW_ID    LOW( fw_version_major + fw_version_minor + fw_version_beta )
--- a/src/convert.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/convert.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File convert.asm                          combined next generation V3.04.2
+;   File convert.asm                          combined next generation V3.09.4l
 ;
 ;   Converts register values to string
 ;
@@ -11,310 +11,649 @@
 ;   2010-12-10 : [jDG] Optimize macro size
 ;
 
-#include "hwos.inc"						; Mandatory header
+#include "hwos.inc"
+#include "math.inc"
+#include "strings.inc"
 
-convert	CODE
 
 ;=============================================================================
+convert1	CODE
+;=============================================================================
 
+
+;-----------------------------------------------------------------------------
+; Print last two Digits or double-dots if zero - big Font
+;
 	global	output99DD_call
 output99DD_call:
 	tstfsz	lo							; value = 0 ?
 	bra		output99_call				; NO  - do normal output
 	movlw	" "							; YES - print a space
 	movwf	POSTINC2					;     - ...
-	bra		output99dd_cont				;     - continue with the double dots
+	bra		print_doubledots			;     - continue printing two dots
 
 
+;-----------------------------------------------------------------------------
+; Print last two Digits or double-dots if zero - small Font
+;
 	global	output99dd_call
 output99dd_call:
 	tstfsz	lo							; value = 0 ?
 	bra		output99_call				; NO  - do normal output
-output99dd_cont:
-	movlw	"."							; YES - print double dots
-	movwf	POSTINC2					;     - ...
+	bra		print_doubledots			; YES - continue printing two dots
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - Print two Dots
+;
+print_doubledots:
+	movlw	"."							; load a '.'
+	movwf	POSTINC2					; print 1st dot
+	movwf	POSTINC2					; print 2nd dot
+	bra		output_common_finish		; clean-up and return
+
+
+;-----------------------------------------------------------------------------
+; Print last Digit from a 8 bit Integer (0-9)
+;
+	global	output9_call
+output9_call:
+	bsf		hide_digit2					; do not print digit 5, 4, 3 and 2
+	bra		output8_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Print only last two Digits from a 8 bit Integer, with leading zero (00-99)
+;
+	global	output99x_call
+output99x_call:
+	bsf		leading_zeros				; print leading zeros
+	;bra	output99_call				; continue with output99_call
+
+
+;-----------------------------------------------------------------------------
+; Print last two Digits from a 8 bit Integer (0-99)
+;
+	global	output99_call
+output99_call:
+	bsf		hide_digit3					; do not print digit 5, 4 and 3
+	;bra	output8_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Print 8 bit Integer (0-255)
+;
+	global	output256_call
+output256_call:
+	;bra	output8_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - common Part for Printing 8 Bit Integers
+;
+output8_common:
+	bcf		output_overflow				; clear overflow flag
+	movff	lo,bin_lo					; copy value to show
+	rcall	convert_bin8bcd				; compute bcd_hi (1 digit) and bcd_lo (2 digits)
+	btfsc	hide_digit2					; shall hide digit 2 ?
+	bsf		hide_digit3					; YES - hide digit 3 then, too
+	bra		output_common_d3			; start printing with digit 3
+
+
+;-----------------------------------------------------------------------------
+; Print last four Digits from a 16 bit Value (0-9999)
+;
+	global	output9999_call
+output9999_call:
+	bsf		hide_digit5					; do not print digit 5
+	bra		output16_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Print last three Digits from a 16 bit Value (0-999)
+;
+	global	output999_call
+output999_call:
+	bsf		hide_digit4					; do not print digit 4 and 5
+	;bra	output16_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Print a full 16 bit Value (0-65535)
+;
+	global	output65535_call
+output65535_call:
+	;bra	output16_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - common Part for Printing 16 Bit Integers
+;
+output16_common:
+	bcf		output_overflow				; clear overflow flag
+	movff	lo,bin_lo					; copy value to show
+	movff	hi,bin_hi					; ...
+	rcall	convert_bin16bcd			; compute bcd_up (1 digit), bcd_hi (2 digits) and bcd_lo (2 digits)
+	btfsc	hide_digit2					; shall hide digit 2 ?
+	bsf		hide_digit3					; YES - hide digit 3 then, too
+	btfsc	hide_digit3					; shall hide digit 3 ?
+	bsf		hide_digit4					; YES - hide digit 4 then, too
+	btfsc	hide_digit4					; shall hide digit 4 ?
+	bsf		hide_digit5					; YES - hide digit 5 then, too
+	;bra	output_common_d5			; start printing with digit 5
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - common Part for Printing 8 and 16 Bit Integers
+;
+output_common_d5:
+	; digit 5
+	btfss	hide_digit5					; shall hide digit 5 ?
+	bra		output_common_d5p			; NO  - print digit 5
+	movf	bcd_up,W					; YES - get lower nibble (digit 5) into WREG
+	andlw	0x0F						;     - is it zero?
+	bnz		print_9999					;       NO  - print '9999'
+	bra		output_common_d4			;       YES - continue with digit 4
+output_common_d5p:
+	movf	bcd_up,W					; copy 5th digit to lower nibble of WREG
+	rcall	print_digit					; print the digit
+
+output_common_d4:
+	; between digit 5 and 4
+	btfsc	decimal_digit3				; shall print a decimal point in front of digit 3 ?
+	bsf		leading_zeros				; YES - allow printing of zeros now
+
+	; digit 4
+	btfss	hide_digit4					; shall hide digit 4 ?
+	bra		output_common_d4p			; NO  - print digit 4
+	swapf	bcd_hi,W					; YES - get upper nibble (digit 4) into WREG
+	andlw	0x0F						;     - is it zero?
+	bnz		print_999					;       NO  - print '999'
+	bra		output_common_d3			;       YES - continue with digit 3
+output_common_d4p:
+	swapf	bcd_hi,W					; copy 4th digit to lower nibble of WREG
+	rcall	print_digit					; print the digit
+
+output_common_d3:
+	; between digit 4 and 3
+	btfsc	decimal_digit3				; shall print a decimal point in front of digit 3 ?
+	rcall	print_decimal				; YES - print a decimal pint now
+	btfsc	decimal_digit2				; shall print a decimal point in front of digit 2 ?
+	bsf		leading_zeros				; YES - allow printing of zeros now
+	btfsc	omit_digit_2				; shall omit digits 2 and 1 ?
+	bsf		leading_zeros				; YES - allow printing of zeros now
+
+	; digit 3
+	btfss	hide_digit3					; shall hide digit 3 ?
+	bra		output_common_d3p			; NO  - print digit 3
+	movf	bcd_hi,W					; YES - get lower nibble (digit 3) into WREG
+	andlw	0x0F						;     - is it zero?
+	bnz		print_99					;       NO  - print '99'
+	bra		output_common_d2			;       YES - continue with digit 2
+output_common_d3p:
+	movf	bcd_hi,W					; copy 3rd digit to lower nibble of WREG
+	rcall	print_digit					; print the digit
+
+output_common_d2:
+	; between digit 3 and 2
+	btfsc	decimal_digit2				; shall print a decimal point in front of digit 2 ?
+	rcall	print_decimal				; YES - print a decimal pint now
+	btfsc	decimal_digit1				; shall print a decimal point in front of digit 1 ?
+	bsf		leading_zeros				; YES - allow printing of zeros now
+	btfsc	omit_digit_1				; shall omit digit 1 ?
+	bsf		leading_zeros				; YES - allow printing of zeros now
+
+	; digit 2
+	btfss	hide_digit2					; shall hide digit 2 ?
+	bra		output_common_d2p			; NO  - print digit 2
+	swapf	bcd_lo,W					; YES - get upper nibble (digit 2) into WREG
+	andlw	0x0F						;     - is it zero?
+	bnz		print_9						;       NO  - print '9'
+	bra		output_common_d1			;       YES - continue with digit 2
+output_common_d2p:
+	btfsc	omit_digit_2				; shall omit digit 2 ?
+	bra		output_common_finish		; YES - finish output
+	swapf	bcd_lo,W					; NO  - copy 2nd digit to lower nibble of WREG
+	rcall	print_digit					;     - print the digit
+
+output_common_d1:
+	; between digit 2 and 1
+	btfsc	decimal_digit1				; shall print a decimal point in front of digit 1 ?
+	rcall	print_decimal				; YES - print a decimal pint now
+	bsf		leading_zeros				; allow printing of zeros now
+
+	; digit 1
+	btfsc	omit_digit_1				; shall omit digit 1 ?
+	bra		output_common_finish		; YES - finish output
+	movf	bcd_lo,W					; NO  - copy 1st digit to lower nibble of WREG
+	rcall	print_digit					;     - print the digit
+
+output_common_finish:
+	clrf	INDF2						; place a terminator at the current buffer position
+	clrf	CVT_flags1					; clear output format command flags
+	clrf	CVT_flags2					; ...
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - print a Digit or a decimal Point
+;
+; Input:    lower nibble of WREG  BCD code of digit
+;           leading_zeros         =1: print (leading) zeros
+;           leftbind              =1: do not print leading spaces
+;
+print_digit:
+	andlw	0x0F						; keep only the lower nibble, is it zero?
+	bnz		print_digit_digit			; NO  - print in any case
+	btfsc	leading_zeros				; YES - printing of zeros allowed?
+	bra		print_digit_digit			;       YES - print a zero
+	btfsc	leftbind					;       NO  - shall print left-aligned?
+	return								;             YES - done
+	movlw	' '							;             NO  - load ASCII code of a space char
+	bra		print_digit_print			;                 - print it
+print_digit_digit:
+	bsf		leading_zeros				; allow printing of zeros now
+	addlw	'0'							; add ASCII code of '0' to BCD code to get final ASCII code
+print_digit_print:
+	movwf	POSTINC2					; print the digit or char
+	return								; done
+
+print_decimal:
+	movlw	'.'							; load ASCII code of a dot
+	bra		print_digit_print			; print it
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - print '9999' or '999' or '99' or '9'
+;
+print_9999:
+	movlw	'9'							; load a '9' digit
+	movwf	POSTINC2					; print digit 4
+print_999:
+	movlw	'9'							; load a '9' digit (for those embarked lately)
+	movwf	POSTINC2					; print digit 3
+print_99:
+	movlw	'9'							; load a '9' digit (for those embarked lately)
+	movwf	POSTINC2					; print digit 2
+print_9:
+	movlw	'9'							; load a '9' digit (for those embarked lately)
+	movwf	POSTINC2					; print digit 1
+	clrf	INDF2						; place a terminator at the current buffer position
+	clrf	CVT_flags1					; clear output format command flags
+	clrf	CVT_flags2					; ...
+	bsf		output_overflow				; set overflow flag
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Convert an 8 Bit Integer to BCD
+;
+; Input:  bin_lo         8 bit integer
+; Output: bcd_hi,bcd_lo  3 BCD digits
+;
+convert_bin8bcd:
+	clrf	bcd_lo						; clear result variables
+	clrf	bcd_hi						; ...
+	bsf		bcd_hi,0					; set loop counter to 8
+convert_bin8bcd_loop:
+	; get MSB bit from binary
+	rlcf	bin_lo,F					; shift-out MSB  to CARRY
+	; lower two BCDs
+	movf	bcd_lo,W					; get lower BCDs to WREG
+	addwfc	bcd_lo,W					; WREG = 2 * WREG + CARRY
+	daw									; decimal-adjust BCDs in WREG
+	movwf	bcd_lo						; copy back WREG to lower BCDs
+	; higher one BCD
+	rlcf	bcd_hi						; higher BCD = 2*(higher BCD) + CARRY (special version for 1 BCD only)
+	; loop control
+	bnc		convert_bin8bcd_loop		; all 8 bits done? NO  -> loop
+	return								;                  YES -> done
+
+
+;-----------------------------------------------------------------------------
+; Convert a 16 Bit Integer to BCD
+;
+; Input:  bin_hi,bin_lo         16 bit integer
+; Output: bcd_up,bcd_hi,bcd_lo   5 BCD digits
+;
+convert_bin16bcd:
+	clrf	bcd_lo						; clear result variables
+	clrf	bcd_hi						; ...
+	clrf	bcd_up						; ...
+	movlw	.16							; 16 bits to do
+	movwf	math_loop					; load loop counter
+convert_bin16bcd_loop:
+	; get MSB bit from binary
+	rlcf	bin_lo,F					; shift-out MSB  to CARRY
+	rlcf	bin_hi,F					; ...
+	; lower two BCDs
+	movf	bcd_lo,W					; get lower BCDs to WREG
+	addwfc	bcd_lo,W					; WREG = 2 * WREG + CARRY
+	daw									; decimal-adjust BCDs in WREG
+	movwf	bcd_lo						; copy back WREG to lower BCDs
+	; higher two BCDs
+	movf	bcd_hi,W					; repeat for higher BCDs
+	addwfc	bcd_hi,W					; ...
+	daw									; ...
+	movwf	bcd_hi						; ...
+	; upper one BCD
+;	movf	bcd_up,W					; repeat for upper BCD
+;	addwfc	bcd_up,W					; ...
+;	daw									; ...
+;	movwf	bcd_up						; ...
+	rlcf	bcd_up						; upper BCD = 2*(upper BCD) + CARRY (special version for 1 BCD only)
+	; loop control
+	decfsz	math_loop					; decrement bit counter, all done?
+	bra		convert_bin16bcd_loop		; NO  - loop
+	return								; YES - done
+
+
+;=============================================================================
+convert2	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Print Value in WREG as hex Number (00-FF)
+;
+	global	outputHEX_call
+outputHEX_call:
+	movwf	bin_lo						; make a backup
+	swapf	WREG,W						; swap nibbles to process upper nibble first
+	rcall	outputHEX_nibble			; print nibble as ASCII
+	movf	bin_lo,W					; recall backup
+outputHEX_nibble:
+	andlw	0x0F						; isolate lower nibble
+	addlw	+0x36						; add 0x36 so that numbers >= decimal 10 will become >= 0x40
+	btfss	WREG,6						; WREG >= 0x40 ?
+	addlw	-0x07						; NO - number is < 10, move back by offset between ASCII codes for 'A' and '9'
+	addlw	+0x01						; make final common move forward to align with ASCII code
+	movwf	POSTINC2					; write ASCII code to output buffer
+	clrf	INDF2						; place a terminator at the current buffer position
+	return								; done
+
+
+;=============================================================================
+convert3	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Convert signed 16 Bit to unsigned 16 Bit and put a '-' into the buffer if negative
+;
+; Input / Output: mpr:2
+;
+	global	convert_signed_16bit
+convert_signed_16bit:
+	bcf		neg_flag					; clear flag for negative number by default
+	btfss	hi,7						; negative number?
+	return								; NO  - done
+	bsf		neg_flag					; YES - set flag for negative number
+	comf	hi							;     - complement hi:lo
+	negf	lo							;     - ...
+	btfsc	STATUS,C					;     - ...
+	incf	hi							;     - ...
+	movlw	'-'							;     - print a minus sign
 	movwf	POSTINC2					;     - ...
 	return								;     - done
 
 
-	global	output99_call
-output99_call:
-	clrf	ignore_digits
-	incf	ignore_digits,F
-	clrf	cvt_temp4
-	;bra	output99
+;=============================================================================
+convert4	CODE
+;=============================================================================
 
 
-	global	output99
-output99:
-	movlw	d'99'
-	cpfslt	lo
-	movwf	lo							; limit to 99
-	movff	lo,cvt_temp_lo
-	clrf	cvt_temp_hi
-	bcf		pre_zero_flag				; do not display leading zeros
+;-----------------------------------------------------------------------------
+; Convert Pressure in [mbar] to Depth in [cm]
+;
+; Input:    mpr:2 pressure [mbar]
+; Output:   mpr:2 depth    [cm]
+; Destroys: up
+;
+	global	convert_pres_to_depth
+convert_pres_to_depth:
+	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
 
-LCD_val99_2:
-	movlw	.10							; 10
-	movwf	cvt_temp2
-	clrf	cvt_temp3
-	rcall	DEC2ASCII
+	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
 
-	movlw	.1							; 1
-	movwf	cvt_temp2
-	clrf	cvt_temp3
-	bsf		pre_zero_flag				; last figure, display zero (0)
-	rcall	DEC2ASCII
+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						; get salinity in [%]
+	clrf	xB+1						; ...
+	call	div32x16					; xC:4 = xC:4 / xB:2 with xA as remainder
+	MOVII	xC,mpr						; copy back result as depth in [cm]
 	return
 
-	global	output99x_call
-output99x_call:
-	clrf	ignore_digits
-	incf	ignore_digits,F
-	clrf	cvt_temp4
+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
+
+
+;=============================================================================
+convert5	CODE
+;=============================================================================
+
 
-	movlw	d'99'
-	cpfslt	lo
-	movwf	lo							; limit to 99
-	movff	lo,cvt_temp_lo
-	clrf	cvt_temp_hi
-	bsf		pre_zero_flag				; display leading zeros
-	bra		LCD_val99_2
+;-----------------------------------------------------------------------------
+; Convert  Depth in [cm] to Depth in [feet]
+;
+; Input:  mpr:2  depth in [cm]
+; Output: mpr:2  depth in [ft]
+;
+	global	convert_cm_to_feet
+convert_cm_to_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
 
 
-	global	output8_call
-output8_call:
-	clrf	ignore_digits
-	incf	ignore_digits,F
-	clrf	cvt_temp4
+;-----------------------------------------------------------------------------
+; Convert  Depth in [m] to Depth in [feet]
+;
+; Input:  lo     depth in [m]
+; Output: mpr:2  depth in [ft]
+;
+	global	convert_meter_to_feet
+convert_meter_to_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
 
-output8:
-	movff	lo,cvt_temp_lo
-	clrf	cvt_temp_hi
-	bcf		pre_zero_flag				; do not display leading zeros
-	movlw	.100						; 100
-	movwf	cvt_temp2
-	clrf	cvt_temp3
-	rcall	DEC2ASCII
-	bra		LCD_val99_2
+
+;-----------------------------------------------------------------------------
+; Helper Function to convert_cm_to_feet and convert_meter_to_feet
+;
+convert_common_to_feet:
+	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
+	return								; done
 
 
-	global	output16_4_call
-output16_4_call:						; limit to 9999
-	bsf		show_last4
-										; 9999 = 27 0F = [39][15]
-	movlw	.40
-	cpfslt	hi							; hi < 40 ?
-	bra		output16_4_call_2			; NO  - hi >= 40, do limit
-										; YES - hi <= 39
-	movlw	.39
-	cpfseq	hi							; hi = 39 ?
-	bra		output16_4_call_3			; NO  - hi < 39, no limit needed
-										; YES - hi = 39
-	movlw	.15
-	cpfslt	lo							; lo < 15
-	movwf	lo							; NO  - lo >= 15, set lo = 15
-										; YES - lo <= 14 or lo set to =15
-	bra		output16_4_call_3			;     - done
+;=============================================================================
+convert6	CODE
+;=============================================================================
+
 
-output16_4_call_2:						; set to 9999
-	MOVLI	.9999,mpr
-output16_4_call_3:
-	bra		output16_call
+;-----------------------------------------------------------------------------
+; Convert Temperature in Celsius to Fahrenheit
+;
+; Input:  mpr:2  temperature in [0.1 °C]
+; Output: mpr:2  temperature in [0.1 °F]
+;
+	global	convert_celsius_to_fahrenheit
+convert_celsius_to_fahrenheit:
+	MOVII	mpr,xA					; temperature in 1/10 of °C
+	ADDLI	.1000,xA				; add offset of 1000 to get out of any negative numbers
+									; adjust scaling: 1°C = 1.8°F:
+	MOVLI	.18,xB					; multiply with 18:
+	call	mult16x16				; ...
+	MOVLI	.10,xB					; divide by 10
+	call	div32x16				; ...
+	SUBLI	.1480,xC				; subtract above offset (1000 * 1.8 = 1800) and add Fahrenheit-Offset (32 * 10 = 320) => subtract 1480
+	MOVII	xC,mpr					; store result in mpr:2
+	return							; done
+
+
+;=============================================================================
+convert7	CODE
+;=============================================================================
 
 
-	global	output16_3_call
-	global	output16_call
-	global	output16
-output16_3_call:						; limit to 999
-	bsf		show_last3
-	; Limit to 3
-	movlw	.4
-	cpfslt	hi
-	bra		output16_3_call_2
-	movlw	.3
-	cpfseq	hi							; = 3 ?
-	bra		output16_3_call_3			; NO - done
-	movlw	.231						; limit to 231(+768=999...)
-	cpfslt	lo
-	movwf	lo
-	bra		output16_3_call_3			; done
-output16_3_call_2:						; set to .999
-	MOVLI	.999,mpr
-output16_3_call_3:
-output16_call:
-	clrf	ignore_digits
-	incf	ignore_digits,F
-	clrf	WREG
-output16:
-	movwf	cvt_temp4					; passed from output16dp macro, cleared by others.
-	bcf		all_zeros_flag				; do not display any zero from here unless there was at least one figure /zero
-	bsf		leading_zeros
-	tstfsz	cvt_temp4					; display leading zeros at all?
-	bcf		leading_zeros
-	bsf		DP_done2
-	tstfsz	cvt_temp4
-	bcf		DP_done2					; decimal point not yet set
-	movff	lo,cvt_temp_lo				; copy hi:lo to cvt_temp_hi:cvt_temp_lo
-	movff	hi,cvt_temp_hi				; ...
-	bcf		pre_zero_flag				; do not display leading zeros
-	movlw	b'00010000'					; 10000s
-	movwf	cvt_temp2
-	movlw	b'00100111'
-	movwf	cvt_temp3
-	btfsc	show_last3					; display only last three figures?
-	bra		output16_sk5
-	btfsc	show_last4					; display only last four figures?
-	bra		output16_sk5
-	rcall	DEC2ASCII					; NO - show all, here: 5th order digit
-
-output16_sk5:
-	bcf		show_last4
-	movlw	b'11101000'					; 1000s
-	movwf	cvt_temp2
-	movlw	b'00000011'
-	movwf	cvt_temp3
-	btfsc	DP_done2					; is there a decimal point at all?
-	bra		output16_2					; NO - use normal display mode
-
-	btfsc	all_zeros_flag				; display any zero from here
-	bra		output16_1					; there was a figure /zero already
-
-	bsf		pre_zero_flag				; display figure if zero?
-	decfsz	cvt_temp4,W
-	bcf		pre_zero_flag				; NO
+;-----------------------------------------------------------------------------
+; Convert Minutes to Hours and Minutes  / Seconds to Minutes and Seconds
+;
+; Input:   hi:lo  minutes  /  seconds
+; Output:  up:hi  hours    /  minutes 
+;             lo  minutes  /  seconds
+;
+; trashes xA, xB, xC
+;
+	global	convert_time
+convert_time:
+	movff	lo,xA+0					; copy hi:lo to xA
+	movff	hi,xA+1					; ...
+	movlw	d'60'					; set divisor to 60
+	movwf	xB+0					; write 60 to xB
+	clrf	xB+1					; ...
+	call	div16x16				; xC = xA / xB with xA as remainder
+	movff	xC+1,up					; result    is hours   / minutes, copy to up (high byte)
+	movff	xC+0,hi					; result    is hours   / minutes, copy to hi (low  byte)
+	movff	xA+0,lo					; remainder is minutes / seconds, copy to lo
+	return							; done
 
-output16_1:
-	btfsc	DP_done						; decimal point set already?
-	bsf		pre_zero_flag				; YES - so display the rest
-output16_2:
-	btfss	show_last3					; display only last three figures?
-	rcall	DEC2ASCII					; NO  - show all. Here: 4th order digit
-	bcf		show_last3					; YES - so display the rest
-	movlw	b'01100100'					; 100s
-	movwf	cvt_temp2
-	clrf	cvt_temp3
-	btfsc	ignore_digit3				; ignore 3rd-5th digit?
-	bra		output16_5					; YES - skip the rest
-	btfsc	DP_done2					; is there a decimal point at all?
-	bra		output16_3					; NO  - use normal display mode
-	btfsc	all_zeros_flag				; display any zero from here
-	bra		output16_2_1				; there was a figure /zero already
-	bsf		pre_zero_flag				; display figure if zero?
-	decfsz	cvt_temp4,W
-	bcf		pre_zero_flag				; NO
 
-output16_2_1:
-	btfsc	DP_done						; decimal point set already?
-	bsf		pre_zero_flag				; YES - so display the rest
-	btfsc	DP_done2					; is there a decimal point at all?
-	bsf		pre_zero_flag				; NO  - so display the rest
-output16_3:
-	rcall	DEC2ASCII					; 3th order digit...
-	movlw	b'00001010'					; 10s
-	movwf	cvt_temp2
-	clrf	cvt_temp3
-	btfsc	DP_done2
-	bra		output16_4
-	btfsc	all_zeros_flag				; display any zero from here
-	bra		output16_3_1				; there was a figure /zero already
-	bsf		pre_zero_flag
-	decfsz	cvt_temp4,W
-	bcf		pre_zero_flag
-
-output16_3_1:
-	btfsc	DP_done
-	bsf		pre_zero_flag
-	btfsc	DP_done2
-	bsf		pre_zero_flag
-output16_4:
-	btfsc	ignore_digit4				; ignore 4-5th digit?
-	bra		output16_5					; YES - skip the rest
-	rcall	DEC2ASCII					; 2nd order digit
-
-	movlw	b'00000001'					; 1s
-	movwf	cvt_temp2
-	clrf	cvt_temp3
-	bsf		pre_zero_flag
-	btfss	ignore_digit5				; ignore 5th digit?
-	rcall	DEC2ASCII					; 1st order digit
-	bcf		ignore_digit5				; YES - clear flag
-output16_5:
-	bcf		ignore_digit4				; clear flag
-	bcf		ignore_digit3				; clear flag
-	clrf	ignore_digits
-	incf	ignore_digits,F
-	bcf		DP_done
-	return								; done with convert.asm...
+;=============================================================================
+convert8	CODE
+;=============================================================================
 
 
-DEC2ASCII:
-	clrf	cvt_temp1					; converts into ASCII code
-DEC2ASCII_2:
-	movf	cvt_temp3,W
-	subwf	cvt_temp_hi,W
-	btfss	STATUS,C
-	bra		DEC2ASCII_4
-	bnz		DEC2ASCII_3
-	movf	cvt_temp2,W
-	subwf	cvt_temp_lo,W
-	btfss	STATUS,C
-	bra		DEC2ASCII_4
-DEC2ASCII_3:
-	movf	cvt_temp3,W
-	subwf	cvt_temp_hi,F
-	movf	cvt_temp2,W
-	subwf	cvt_temp_lo,F
-	btfss	STATUS,C
-	decf	cvt_temp_hi,F
-	incf	cvt_temp1,F
-	bsf		pre_zero_flag
-	bra		DEC2ASCII_2
-DEC2ASCII_4:
-	decfsz	ignore_digits,F
-	return
-	incf	ignore_digits,F				; so ignore_digits stays zero for the test above
-	movlw	'0'							; offset for ASCII-value
-	addwf	cvt_temp1,W
-	btfsc	pre_zero_flag				; is this a leading zero?
-	bra		DEC2ASCII_4_1				; NO
-	btfsc	leftbind
-	bra		DEC2ASCII_6
-	movlw	' '							; instead of leading zeros a space!
-	bra		DEC2ASCII_5
-DEC2ASCII_4_1:
-	bsf		all_zeros_flag				; display any zero from here
-DEC2ASCII_5:
-	movwf	POSTINC2
-DEC2ASCII_6:
-	decfsz	cvt_temp4,F					; set decimal point?
-	RETURN								; NO
-	movlw	"."							; YES
-	movwf	POSTINC2
-	bsf		DP_done
-	return
+;-----------------------------------------------------------------------------
+; Print full Date
+;
+; Input:     lo  year
+;            hi  month
+;            up  day
+;
+; Output format depends on value of option opt_dateformat:
+;         0: MM.DD.YY
+;         1: DD.MM.YY
+;         2: YY.MM.DD
+;
+; Destroyed: hy
+;
+	global	output_date
+output_date:
+	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: MM.DD.YY
+	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				; shall use format 1 ?
+	bra		TFT_convert_date_common	; NO  - use format 2: YY.MM.DD - can print directly
+									; YES - use format 1: DD.MM.YY
+	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:
+	call	output99x_call			; print lo (00-99)
+	PUTC	'.'						; print spacing dot
+	movff	hi,lo					; print hi (00-99)
+	call	output99x_call			; ...
+	PUTC	'.'						; print spacing dot
+	movff	up,lo					; print up (00-99)
+	call	output99x_call			; ...
+	return							; done
+
+
+;=============================================================================
+convert9	CODE
+;=============================================================================
 
 
-	global	outputHEX_call
-outputHEX_call:							; coverts 8 Bit integer into two hex digits
-	movwf	cvt_temp1					; copy byte to process from WREG to local temp
-	swapf	cvt_temp1,F					; swap nibbles to process upper nibble first
-	rcall	outputHEX_nibble			; print nibble as ASCII
-	swapf	cvt_temp1,F					; swap back to process lower nibble
-outputHEX_nibble:
-	movff	cvt_temp1,cvt_temp2			; create a working copy
-	movlw	0x0F						; mask for lower nibble
-	andwf	cvt_temp2,F					; isolate lower nibble
-	movlw	0x30						; offset from binary 0 to ASCII code for "0"
-	addwf	cvt_temp2,F					; add offset
-	movlw	0x39						; ASCII code for "9"
-	cpfsgt	cvt_temp2					; character code in cvt_temp2 pointing to something after "9"?
-	bra		outputHEX_1					; NO  - character code represents "0"..."9", can be printed
-	movlw	0x07						; YES - offset from ASCII code for character after "9" to character "A"
-	addwf	cvt_temp2,F					;     - add offset, character code now represents "A"..."F", can be printed now
-outputHEX_1:
-	movff	cvt_temp2,POSTINC2			; copy character code to output buffer
-	return
+;-----------------------------------------------------------------------------
+; Print Date by Month & Day
+;
+; Input:     hi  month
+;            up  day
+;
+; Output format depends on value of option opt_dateformat:
+;         0: MM.DD
+;         1: DD.MM
+;         2: MM.DD
+;
+; Destroyed: lo
+;
+	global	output_date_short
+output_date_short:
+	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:
+	call	output99x_call			; print lo (00-99)
+	PUTC	'.'						; print spacing dot
+	movff	hi,lo					; print hi (00-99)
+	call	output99x_call			; ...
+	return							; done
 
 
+;=============================================================================
+convert10	CODE
+;=============================================================================
+
+
+	global	output_secs_as_days_hours
+output_secs_as_days_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							; transfer result to 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
+	call	output99_call					; print days (0-99)
+	PUTC	"d"								; append unit
+	movff	xA+0,lo							; get   full hours
+	call	output99x_call					; print full hours (00-99)
+	PUTC	"h"								; append unit
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+
 	END
--- a/src/convert.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/convert.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File convert.inc                          combined next generation V3.04.2
+;   File convert.inc                          combined next generation V3.09.4l
 ;
 ;   Converts register values to string
 ;
@@ -11,53 +11,124 @@
 ;   2010-12-10 : [jDG] Optimize macro size
 
 
-	extern	output16_3_call
-output_16_3	macro				; displays only last three digits from a 16 bit value (0-999)
-	call	output16_3_call
-	endm
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;
+;          The output format of all 8 and 16 bit integer printing
+;          functions can be controlled with the following flags.
+;          After each printing, the flags are reset automatically.
+;
+;
+;   bsf leftbind        ; print left-aligned            (no leading spaces)
+;   bsf leading_zeros   ; print leading zeros
+;
+;   bsf hide_digit5     ; do not print digit  5      (clip output at  9999)
+;   bsf hide_digit4     ; do not print digits 5 - 4  (clip output at   999)
+;   bsf hide_digit3     ; do not print digits 5 - 3  (clip output at    99)
+;   bsf hide_digit2     ; do not print digits 5 - 2  (clip output at     9)
+;
+;   In case the output gets clipped, the flag 'output_overflow' will be set
+;
+;   bsf omit_digit_2    ; do not print digits 2 - 1  (show output as xxx--)
+;   bsf omit_digit_1    ; do not print digit      1  (show output as xxxx-)
+;
+;   bsf decimal_digit3  ; put a decimal point in front of digit 3  (xx.xxx)
+;   bsf decimal_digit2  ; put a decimal point in front of digit 2  (xxx.xx)
+;   bsf decimal_digit1  ; put a decimal point in front of digit 1  (xxxx.x)
+;
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-	extern	output16_4_call
-output_16_4	macro				; displays only last four digits from a 16 bit value (0-9999)
-	call	output16_4_call
+
+;-----------------------------------------------------------------------------
+;
+; Output Functions for 8 Bit Integers
+;
+; output_x: x is the max number that will be shown
+;
+; Input: mpr:1 (lo)
+;
+;-----------------------------------------------------------------------------
+
+output_9	macro				; print only last digit  (0-9)
+	extern	output9_call
+	call	output9_call
 	endm
 
-	extern	output16
-output_16dp	macro dp_position	; 16 bit with decimal point
-	movlw	dp_position
-	call	output16
-	endm
 
-	extern	output16_call
-output_16	macro				; 16 bit normal
-	call	output16_call
-	endm
-
-	extern	output8_call
-output_8	macro				; 8 bit normal
-	call	output8_call
-	endm
-
+output_99	macro				; print only 2 digits (0-99)
 	extern	output99_call
-output_99	macro				; displays only last two digits from a 8 bit value (0-99)
 	call	output99_call
 	endm
 
+output_99x	macro				; print only 2 digits with leading zero (00-99)
 	extern	output99x_call
-output_99x	macro				; displays only last two digits from a 8 bit value with leading zero (00-99)
 	call	output99x_call
 	endm
 
+output_99dd	macro				; print only 2 digits or double-dots if zero - variant for small font
 	extern	output99dd_call
-output_99dd	macro				; displays only last two digits from a 8 bit value, prints double-dots if zero - small fonts
 	call	output99dd_call
 	endm
 
+output_99DD	macro				; print only 2 digits or double-dots if zero - variant for big   font
 	extern	output99DD_call
-output_99DD	macro				; displays only last two digits from a 8 bit value, prints double-dots if zero - big   fonts
 	call	output99DD_call
 	endm
 
+output_256	macro				; print all 3 digits (0-255)
+	extern	output256_call
+	call	output256_call
+	endm
+
+output_hex	macro				; print in hex (00-FF), Attention: input is via WREG
 	extern	outputHEX_call
-output_hex	macro				; displays 8 bit integer in hex, input via WREG
 	call	outputHEX_call
 	endm
+
+
+;-----------------------------------------------------------------------------
+;
+; Output Functions for 16 Bit Integers
+;
+; output_x: x is the max number that will be shown
+;
+; Input: mpr:2 (lo,hi)
+;
+;-----------------------------------------------------------------------------
+
+output_65535 macro				; print all 5 digits       (0-65535)
+	extern	output65535_call
+	call	output65535_call
+	endm
+
+
+output_9999	macro				; print only last 4 digits (0-9999)
+	extern	output9999_call
+	call	output9999_call
+	endm
+
+output_999	macro				; print only last 3 digits (0-999)
+	extern	output999_call
+	call	output999_call
+	endm
+
+
+;-----------------------------------------------------------------------------
+;
+; Conversion Functions
+;
+;-----------------------------------------------------------------------------
+
+	extern	convert_pres_to_depth			; convert pressure in [mbar] to depth in [cm]
+	extern	convert_cm_to_feet				; convert depth    in [cm]   to depth in [feet]
+	extern	convert_meter_to_feet			; convert depth    in [m]    to depth in [feet]
+	extern	convert_celsius_to_fahrenheit	; convert temperature from celsius to fahrenheit
+	extern	convert_signed_16bit			; convert signed to unsigned 16bit, print '-' if negative
+	extern	convert_time					; convert minutes to hours:minutes or seconds to minutes:seconds
+
+	extern	output_date						; print date with day, month and year
+	extern	output_date_short				; print date with day and month only
+	extern	output_secs_as_days_hours		; print seconds as days and hours
+
+;-----------------------------------------------------------------------------
+
+
--- a/src/customview.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/customview.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File customview.asm                       combined next generation V3.08.8
+;   File customview.asm                     * combined next generation V3.09.5
 ;
 ;   Custom Views in Surface and Dive Mode
 ;
@@ -21,9 +21,10 @@
 #include "divemode.inc"
 #include "i2c.inc"
 #include "start.inc"
+#include "colorschemes.inc"
 
 
-	extern	gaslist_strcat_gas_cd
+	extern	gaslist_strcat_gas_PRODL
 	extern	char_I_model
 
  IFDEF _compass
@@ -31,19 +32,21 @@
 	extern	TFT_dive_compass_mask
  ENDIF
 
-#DEFINE num_premenu_items	.11		; overall number of pre-menu items
 
-custview	CODE
-
-;-----------------------------------------------------------------------------
+#DEFINE num_premenu_items	.12			; overall number of pre-menu items
+#DEFINE num_surface_cv		.10			; overall number of surface custom views
 
 
 ;=============================================================================
-; Jump table for the every-second tasks for the custom view area (dive mode)
+custview1	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Jump Table for the every-second Tasks for the Custom View Area (Dive Mode)
 ;
 ; Attention: the ordering must be in line with the init jump table and the
 ;            index numbers defined in hwos.inc!
-
+;
 	global	dive_customview_second
 dive_customview_second:
 	movf	active_customview,W			; get current view
@@ -107,33 +110,46 @@
  ENDIF
 	return								;  0: do nothing
 
+
+;=============================================================================
+custview2	CODE
+;=============================================================================
+
+
 ;-----------------------------------------------------------------------------
-
+; Show next Surface Custom View
+;
 	global	surf_customview_toggle
 surf_customview_toggle:
 	bcf		switch_right				; clear button event
-	incf	active_customview,F			; number of custom view to show
+	incf	active_customview,F			; set number of the next custom view to show
 
  IFDEF _compass
-	movlw	.6							; index of surface custom view compass
-	cpfseq	active_customview			; will compass be shown in custom view?
-	call	I2C_sleep_compass			; NO - stop compass
+	movlw	.6							; load index of surface custom view compass
+	cpfseq	active_customview			; will the compass be shown in custom view?
+	call	I2C_sleep_compass			; NO - can stop the compass to save on energy
  ENDIF
 
-	movlw	d'10'						; max number of custom views in surface mode
-	cpfsgt	active_customview			; max reached?
-	bra		surf_customview_mask		; NO  - show
+	movlw	num_surface_cv				; load number of custom views available
+	cpfsgt	active_customview			; beyond last view?
+	bra		surf_customview_mask		; NO  - show view
 	movlw	.1							; YES - wrap around to 1st view
 	movwf	active_customview			;     - ...
-	;bra	surf_customview_mask		;     - show
+	;bra	surf_customview_mask		;     - show view
 
 
+;-----------------------------------------------------------------------------
+; Show Surface Custom View
+;
 	global	surf_customview_mask
 surf_customview_mask:
+
+	; prepare output of custom view title
 	WIN_BOX_BLACK .50,surf_warning1_row-1, .0, surf_decotype_column-.1	; top, bottom, left, right
-	WIN_TINY  surf_customview_title_column,surf_customview_title_row	; set title position
-	WIN_COLOR color_greenish											; set title color
+	WIN_TINY   surf_customview_title_column,surf_customview_title_row	; set title position
+	FONT_COLOR color_greenish											; set title color
 
+	; jump table
 	movf	active_customview,W			; get custom view to show
 	movff	WREG,customview_surfmode	; save number for later recall
 	dcfsnz	WREG,F						; 1:
@@ -156,10 +172,15 @@
 	bra		surf_customview_init_view9	; sensor mV readings
 	dcfsnz	WREG,F						; 10:
 	bra		surf_customview_init_view10	; tank data
-	bra		surf_customview_init_view4	; default view after restart and loading of new firmware
+	bra		surf_customview_init_view4	; 0: default view after restart and loading of new firmware
 
+surf_cv_toggle_exit:
+	bcf		request_next_custview		; clear request flag
+	return								; done
 
-surf_customview_init_view1:				; view 1: OC Gas list
+	; ---- view 1: OC Gas list ----
+	;
+surf_customview_init_view1:
 	btfsc	FLAG_gauge_mode				; in gauge mode?
 	bra		surf_customview_toggle		; YES - not available in gauge mode, goto next view
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
@@ -175,12 +196,13 @@
 	STRCPY_TEXT_PRINT tDiveBailout		; (1) - title of custom view / CCR & pSCR mode
  ENDIF
 surf_customview_init_view1b:
-	call	TFT_standard_color			; set color
-	call	TFT_gaslist_surfmode		; show gas list
-	bra		customview_toggle_exit		; done
+	call	TFT_surf_cv_list_gas		; show gas list
+	bra		surf_cv_toggle_exit			; done
 
 
-surf_customview_init_view2:				; view 2: CCR / pSCR diluent list
+	; ---- view 2: CCR / pSCR diluent list ----
+	;
+surf_customview_init_view2:
  IFDEF _ccr_pscr
 	btfsc	FLAG_ccr_mode				; in CCR mode?
 	bra		surf_customview_init_view2a	; YES - (1)
@@ -189,168 +211,196 @@
 	bra		surf_customview_toggle		; NO  - not available if not in CCR or pSCR mode, goto next view
 surf_customview_init_view2a:
 	STRCPY_TEXT_PRINT tGaslistCC		; (1) - title of custom view
-	call	TFT_standard_color			;     - set color
-	call	TFT_dillist_surfmode		;     - show diluent list
-	bra		customview_toggle_exit		;     - done
+	call	TFT_surf_cv_list_dil		;     - show diluent list
+	bra		surf_cv_toggle_exit			;     - done
  ELSE
 	bra		surf_customview_toggle		; not available without CCR/pSCR mode compiled in, goto next view
  ENDIF
 
 
-surf_customview_init_view3:				; view 3: CC SP list
+	; ---- view 3: CC SP list ----
+	;
+surf_customview_init_view3:
  IFDEF _ccr_pscr
 	btfss	FLAG_ccr_mode				; in CCR mode?
 	bra		surf_customview_toggle		; NO  - not available if not in CCR mode, goto next view
 	STRCPY_TEXT_PRINT tFixedSetpoints	; YES - title of custom view
-	call	TFT_standard_color			;     - set color
-	call	TFT_splist_surfmode			;     - show setpoint list
-	bra		customview_toggle_exit		;     - done
+	call	TFT_surf_cv_list_sp			;     - show setpoint list
+	bra		surf_cv_toggle_exit			;     - done
  ELSE
 	bra		surf_customview_toggle		; not available without CCR/pSCR mode compiled in, goto next view
  ENDIF
 
 
-surf_customview_init_view9:				; view 9: sensor mV at the surface
- IFDEF _external_sensor
-	btfsc	FLAG_ccr_mode				; in CCR mode?
-	bra		surf_customview_init_view9a	; YES - (1)
-	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	bra		surf_customview_init_view9a	; YES - (1) 
-	bra		surf_customview_toggle		; NO  - not available if not in CCR or pSCR mode, goto next view
-surf_customview_init_view9a:
-	movff	opt_ccr_mode,WREG			; (1) - get SP mode (0: fixed SP, 1: Sensor, 2: auto SP)
-	sublw	.1							;     - opt_ccr_mode = 1 (sensor)?
-	bnz		surf_customview_toggle		;       NO  - goto next view
-	STRCPY_TEXT_PRINT tSensorMilliVolt	;       YES - title of custom view
-	call	TFT_standard_color			;           - set color
-	call	TFT_sensor_mV				;           - write sensor mV readings to screen 
-	bra		customview_toggle_exit		;           - done
- ELSE
-	bra		surf_customview_toggle		; not available without CCR/pSCR mode compiled in, goto next view
- ENDIF
+	; ---- view 4: custom text
+	;
+surf_customview_init_view4:
+	call	TFT_surf_cv_text			; show the custom text
+	bra		surf_cv_toggle_exit			; done
 
 
-surf_customview_init_view4:				; view 4: custom text
-	call	TFT_standard_color			; set color
-	call	TFT_custom_text				; show the custom text
-	bra		customview_toggle_exit		; done
-
-
-surf_customview_init_view5:				; view 5: tissue diagram
+	; ---- view 5: tissue diagram
+	;
+surf_customview_init_view5:
 	btfsc	FLAG_gauge_mode				; in gauge mode?
 	bra		surf_customview_toggle		; YES - not available in gauge mode, goto next view
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	bra		surf_customview_toggle		; YES - not available in apnoe mode, goto next view
-	call	TFT_standard_color			; set color
-	call	TFT_surface_tissues			; show tissue diagram
-	bra		customview_toggle_exit		; done
+	call	TFT_surf_cv_tissues			; show tissue diagram
+	bra		surf_cv_toggle_exit			; done
 
 
-surf_customview_init_view6:				; view 6: compass
+	; ---- view 6: compass
+	;
+surf_customview_init_view6:
  IFDEF _compass
 	call	I2C_init_compass			; start compass
 	call	TFT_surface_compass_mask	; show compass mask
-	bra		customview_toggle_exit		; done
+	bra		surf_cv_toggle_exit			; done
  ELSE
 	bra		surf_customview_toggle		; not available without compass compiled in, goto next view
  ENDIF
 
 
-surf_customview_init_view7:				; view 7: deco settings
+	; ---- view 7: deco settings ----
+	;
+surf_customview_init_view7:
 	btfsc	FLAG_gauge_mode				; in gauge mode?
 	bra		surf_customview_toggle		; YES - not available in gauge mode, goto next view
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	bra		surf_customview_toggle		; YES - not available in apnoe mode, goto next view
-	call	TFT_surface_decosettings	; show all deco settings
-	bra		customview_toggle_exit		; done
+	call	TFT_surf_cv_settings		; show all deco settings
+	bra		surf_cv_toggle_exit			; done
+
+
+	; ---- view 8: last dive info ----
+	;
+surf_customview_init_view8:
+	call	TFT_surf_cv_lastdive		; show last dive info
+	bra		surf_cv_toggle_exit			; done
 
 
-surf_customview_init_view8:				; view 8: last dive info
-	call	TFT_standard_color			; set color
-	call	TFT_surface_lastdive		; show last dive info
-	bra		customview_toggle_exit		; done
+	; ---- view 9: sensor mV at the surface ----
+	;
+surf_customview_init_view9:
+ IFDEF _external_sensor
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	bra		surf_customview_init_view9a	; YES - show view
+	btfsc	FLAG_pscr_mode				; NO  - in pSCR mode?
+	bra		surf_customview_init_view9a	;       YES - show view
+	bra		surf_customview_toggle		;       NO  - not available if not in CCR or pSCR mode, goto next view
+
+surf_customview_init_view9a:
+	movff	opt_ccr_mode,WREG			; get SP mode (0: fixed SP, 1: Sensor, 2: auto SP)
+	decfsz	WREG,W						; opt_ccr_mode = 1 (sensor)?
+	bra		surf_customview_toggle		; NO  - goto next view
+	STRCPY_TEXT_PRINT tSensorMilliVolt	; YES - title of custom view
+	call	TFT_imprint_surf_mV			;     - write sensor mV readings to screen 
+	bra		surf_cv_toggle_exit			;     - done
+ ELSE
+	bra		surf_customview_toggle		; not available without CCR/pSCR mode compiled in, goto next view
+ ENDIF
 
 
-surf_customview_init_view10:			; view 10: transmitter data / debug
+	; ---- view 10: transmitter data / debug ----
+	;
+surf_customview_init_view10:
  IFDEF _rx_functions
 	btfss	tr_functions_activated		; TR functions activated?
 	bra		surf_customview_toggle		; NO  - show next view in list
 	STRCAT_PRINT "ID     bar  Volt"		; YES - title of custom view (none language-dependent)
-	call	TFT_surface_tankdata		;     - show received data
-	bra		customview_toggle_exit		;     - done
+	call	TFT_surf_cv_tankdata		;     - show received data
+	bra		surf_cv_toggle_exit			;     - done
  ELSE
 	bra		surf_customview_toggle		; not available without RX functions compiled in, goto next view
  ENDIF
 
+
+;=============================================================================
+custview3	CODE
+;=============================================================================
+
+
 ;-----------------------------------------------------------------------------
-
+; Show next Pre-Menu Item / Clear the Pre-Menu
+;
 	global	menuview_toggle
-	global	menuview_toggle_reset
-menuview_toggle:						; show main menu or the pre-menu
+menuview_toggle:
 	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			; increment pre-menu item number
-	movlw	num_premenu_items			; get count of pre-menu items
-	cpfsgt	active_premenu				; max reached?
+	call	restart_timeout_time		; restart the timeout
+	bsf		dive_pre_menu				; flag that the pre-menu is shown
+menuview_next_item:
+	incf	active_premenu,F			; increment     pre-menu item number
+	movlw	num_premenu_items			; get number of pre-menu items
+	cpfsgt	active_premenu				; beyond last item?
 	bra		menuview_mask				; NO  - show item
-	;bra	menuview_toggle_reset		; YES - reset selector
-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
+	;bra	menuview_toggle_reset		; YES - reset to first item
+
+	global	menuview_toggle_reset
+menuview_toggle_reset:
+	clrf	active_premenu				; reset pre-menu item number
+	bcf		dive_pre_menu				; flag that the pre-menu is not shown anymore
+	;bra	menuview_mask				; clear last item from display
+
 menuview_mask:
 	WIN_BOX_BLACK dm_premenu_row, dm_premenu_bot, dm_premenu_col, dm_premenu_rgt ; top, bottom, left, right
-	tstfsz	active_premenu				; any pre-menu selected?
-	bra		menuview_items				; YES - display menu item
-	bcf		win_invert					; NO  - end inverse printing
-	btfss	FLAG_apnoe_mode				;     - in apnoe mode?
-	goto	TFT_show_temp_divemode		;       YES - restore temperature and done
-	goto	TFT_standard_color			;       NO  - done
+	btfsc	dive_pre_menu				; shall show pre-menu?
+	bra		menuview_show_item			; YES - show menu item
+	;bra	menuview_exit				; NO  - done with pre-menu
 
-menuview_items:
-	call	TFT_attention_color			; set color
+menuview_exit:
+	bcf		win_invert					; clear inverse printing
+	btfss	dive_pre_menu				; showing pre-menu?
+	goto	TFT_show_temp_divemode		; NO  - restore temperature display and return
+	return								; YES - done
+
+menuview_show_item:
+	WIN_SMALL dm_premenu_col,dm_premenu_row
+	FONT_COLOR_ATTENTION				; 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		;  1: gas change	(skipped if no better gas/dil cued)
 	dcfsnz	WREG,F
-	bra		menuview_view_divemenu		;  2: "Menu?"		(skipped in gauge and apnoe modes)
+	bra		menuview_view_ackn			;  2: "Ackn?"		(skipped if no active advice/attention/warning sign)
+	dcfsnz	WREG,F
+	bra		menuview_view_divemenu		;  3: "Menu?"		(skipped in gauge and apnoe modes)
 	dcfsnz	WREG,F
  IFDEF _cave_mode
-	bra		menuview_view_cavemenu		;  3: "Cave?"		(skipped if not in cave mode)
+	bra		menuview_view_cavemenu		;  4: "Cave?"		(skipped if not in cave mode)
  ELSE
-	bra		menuview_toggle				;  3: cave mode not implemented, go to next menu item
+	bra		menuview_next_item			;  4: cave mode not implemented, goto next item
  ENDIF
 	dcfsnz	WREG,F
-	bra		menuview_view_sim_quit		;  4: "Quit?"		(in simulation mode only)
+	bra		menuview_view_sim_quit		;  5: "Quit?"		(in simulation mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view_sim_down		;  5: "Sim down"	(in simulation mode only)
+	bra		menuview_view_sim_down		;  6: "Sim down"	(in simulation mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view_sim_up		;  6: "Sim up"		(in simulation mode only)
+	bra		menuview_view_sim_up		;  7: "Sim up"		(in simulation mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view_sim_time		;  7: "Sim+5'"		(in simulation mode only)
+	bra		menuview_view_sim_time		;  8: "Sim+5'"		(in simulation mode only)
 	dcfsnz	WREG,F
-	bra		menuview_view_apnoe_quit	;  8: "Quit?"		(in apnoe mode only)
+	bra		menuview_view_apnoe_quit	;  9: "Quit?"		(in apnoe mode only)
 	dcfsnz	WREG,F
-	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)
+	bra		menuview_view_gauge_reset	; 10: "Reset Avr"	(in gauge mode only)
 	dcfsnz	WREG,F
-	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
-	bcf		win_invert					; reset invert flag
-	return								; active pre-menu = 0, i.e. show nothing
+ IFDEF _compass
+	bra		menuview_view_course		; 11: "Course"		(only when compass is shown)
+ ELSE
+	bra		menuview_next_item			; 11: compass not implemented, goto next item
+ ENDIF
+	dcfsnz	WREG,F
+	bra		menuview_view_layout		; 12: "Layout"		(offer alternative layout, aka blind mode)
+	bra		menuview_exit				; catch illegal item number
+	; when adding or removing items, adjust the value num_premenu_items in the #DEFINE !
 
 
+	; --- item 1: gas change advice ---
+	;
 menuview_view_gaschange:
-	btfsc	request_gas_change			; last gas change request executed yet?
-	bra		menuview_toggle				; YES - call next option
+	btfsc	request_gas_change			; last gas change request already executed?
+	bra		menuview_next_item			; YES - goto next option
  IFDEF _ccr_pscr
 	btfsc	FLAG_oc_mode				; in OC mode?
 	bra		menuview_view_gaschange_OC	; YES
@@ -358,107 +408,147 @@
 	bra		menuview_view_gaschange_OC	; YES
 menuview_view_gaschange_DIL:
 	btfss	better_dil_available		; is the better diluent still available?
-	bra		menuview_toggle				; NO - call next option
+	bra		menuview_next_item			; NO - goto next item
 	movff	best_dil_number,PRODL		; number (1-5) of the "best diluent"
 	bsf		is_diluent_menu				; setting up diluents
-	bra		menuview_view_gaschange_com
- ENDIF
+	bra		menuview_view_gaschange_com	; continue with common part
+ ENDIF	; _ccr_pscr
 menuview_view_gaschange_OC:
 	btfss	better_gas_available		; is the better gas still available?
-	bra		menuview_toggle				; NO - call next option
-	movff	best_gas_number,PRODL		; number (1-5) of the "best gas"
-	bcf		is_diluent_menu				; setting up OC gases
+	bra		menuview_next_item			; NO  - goto next item
+	movff	best_gas_number,PRODL		; YES - number (1-5) of the "best gas"
+	bcf		is_diluent_menu				;     - setting up OC gases
 menuview_view_gaschange_com:
 	decf	PRODL,F						; (1-5) -> (0-4)
-	bsf		short_gas_descriptions		; use short version of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
+	bsf		short_gas_descriptions		; use short version of gaslist_strcat_gas_PRODL 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
+	call	gaslist_strcat_gas_PRODL	; append gas description of gas #PRODL (0-4) to current string
 	movlw	.5							; point to 6th character (5 chars are used for the gas/dil description)
 	movwf	FSR2L						; ...
-	STRCAT_PRINT "?"					; print question mark
+	PUTC_PRINT "?"						; append question and dump buffer to screen
 	bra		menuview_exit				; done
 
+	; ---- item 2: acknowledge ----
+	;
+menuview_view_ackn:
+	btfss	sign_shown					; advice, attention or warning sign shown?
+	bra		menuview_next_item			; NO  - goto next item
+	STRCAT_TEXT_PRINT tDiveAckn			; YES - print "Ackn?"
+	bra		menuview_exit				;     - done
+
+
+	; ---- item 3: dive menu ----
+	;
 menuview_view_divemenu:
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bra		menuview_toggle				; YES - goto next option
+	bra		menuview_next_item			; YES - goto next item
 	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
-	bra		menuview_toggle				;       YES - goto next option
+	bra		menuview_next_item			;       YES - goto next item
 	PUTC	"\xb7"						;       NO  - print '->' symbol
 	STRCAT_TEXT_PRINT tDivePreMenu		;           - print "Menu?"
 	bra		menuview_exit				;           - done
 
+
+	; ---- item 4: cave menu ----
+	;
  IFDEF _cave_mode
 menuview_view_cavemenu:
 	TSTOSS	opt_cave_mode				; cave mode switched on?
-	bra		menuview_toggle				; NO  - goto next option
+	bra		menuview_next_item			; NO  - goto next item
 	PUTC	"\xb7"						; YES - print '->' symbol
 	STRCAT_TEXT_PRINT tDivePreCave		;     - print "Cave?"
 	bra		menuview_exit				;     - done
- ENDIF
+ ENDIF	; _cave_mode
+
 
+	; ---- item 5: quit simulator ---
+	;
 menuview_view_sim_quit:
 	btfss	simulatormode				; in simulator mode?
-	bra		menuview_toggle				; NO  - goto next option
+	bra		menuview_next_item			; NO  - goto next item
 	STRCPY_TEXT_PRINT tQuitSim			; YES - print "Quit Simulation?"
 	bra		menuview_exit				;     - done
 
+
+	; ---- item 6: simulator - go down ----
+	;
 menuview_view_sim_down:
 	btfss	simulatormode				; in simulator mode?
-	bra		menuview_toggle				; NO - goto next option
+	bra		menuview_next_item			; NO - goto next item
 	STRCPY_PRINT "Sim\xb8"				; print down arrow for going down
 	bra		menuview_exit				; done
 
+
+	; ---- item 7: simulator - go up ----
+	;
 menuview_view_sim_up:
 	btfss	simulatormode				; in simulator mode?
-	bra		menuview_toggle				; NO  - goto next option
+	bra		menuview_next_item			; NO  - goto next item
 	STRCPY_PRINT "Sim\xb9"				; YES - print up arrow for going up
 	bra		menuview_exit				;     - done
 
+
+	; ---- item 8: simulator - advance time ----
+	;
 menuview_view_sim_time:
 	btfss	simulatormode				; in simulator mode?
-	bra		menuview_toggle				; NO  - goto next option
+	bra		menuview_next_item			; NO  - goto next item
 	btfsc	FLAG_gauge_mode				; YES - in gauge mode?
-	bra		menuview_toggle				;       YES - goto next option
+	bra		menuview_next_item			;       YES - goto next item
 	btfsc	FLAG_apnoe_mode				;       NO  - in apnoe mode?
-	bra		menuview_toggle				;             YES - goto next option
+	bra		menuview_next_item			;             YES - goto next item
 	STRCPY_PRINT "Sim+5'"				;             NO  - print "Sim+5'"
 	bra		menuview_exit				;                 - done
 
+
+	; ---- item 9: apnoe mode - quit ----
+	;
 menuview_view_apnoe_quit:
 	btfss	FLAG_apnoe_mode				; in apnoe mode?
-	bra		menuview_toggle				; NO  - goto next option
+	bra		menuview_next_item			; NO  - goto next option
 	btfss	apnoe_at_surface			; YES - at the surface?
-	bra		menuview_toggle				;       NO  - goto next option
+	bra		menuview_next_item			;       NO  - goto next item
 	STRCPY_TEXT_PRINT tQuitSim			;       YES - print "Quit Apnea mode?"
 	bra		menuview_exit				;           - done
 
+
+	; ---- item 10: gauge mode - reset average ----
+	;
 menuview_view_gauge_reset:
 	btfss	FLAG_gauge_mode				; in gauge mode?
-	bra		menuview_toggle				; NO  - goto next option
+	bra		menuview_next_item			; NO  - goto next item
 	STRCPY_TEXT_PRINT tResetAvg			; YES - print "Reset Avg."
 	bra		menuview_exit				;     - done
 
+
+	; ---- item 11: set bearing ----
+ IFDEF _compass
 menuview_view_course:
- IFDEF _compass
 	movlw	index_compass_dm			; index of compass view
 	cpfseq	active_customview			; in compass view?
-	bra		menuview_toggle				; NO  - goto next option
+	bra		menuview_next_item			; NO  - goto next item
 	STRCPY_TEXT_PRINT tSetHeading		; YES - print "Heading"
 	bra		menuview_exit				;     - done
- ELSE
-	bra		menuview_toggle				; not available without compass compiled in, goto next option
  ENDIF
 
+
+	; ---- item 12: switch layout ----
+	;
 menuview_view_layout:
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bra		menuview_toggle				; YES - goto next option
+	bra		menuview_next_item			; YES - goto next item
 	STRCPY_TEXT_PRINT tDiveLayout		; NO  - print "Layout"
 	bra		menuview_exit				;     - done
 
-;-----------------------------------------------------------------------------
+
+;=============================================================================
+custview4	CODE
+;=============================================================================
 
-; Initialize dive mode custom view
 
+;-----------------------------------------------------------------------------
+; Show a specific Dive Mode Custom View
+;
 	global	dive_customview_show
 dive_customview_show:
 	btfss	custom_view_locked			; custom view locked?
@@ -469,36 +559,42 @@
 	movwf	active_customview			; set the requested custom view
 	bra		dive_customview_callup		; call-up the custom view
 
+
+;-----------------------------------------------------------------------------
+; Show again last Dive Mode 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
 
+
+;-----------------------------------------------------------------------------
+; Show next Dive Mode Custom View
+;
 	global	dive_customview_toggle
 dive_customview_toggle:
 	incf	active_customview,F			; increment number of custom view to show
-	movlw	index_cv_dm_max				; highest index in use in dive mode custom view
-	cpfsgt	active_customview			; max reached?
+	movlw	index_cv_dm_max				; get highest index in use in dive mode custom view
+	cpfsgt	active_customview			; beyond last view?
 	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
 
+
+;-----------------------------------------------------------------------------
+; Show current Dive Mode 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
+	call	I2C_sleep_compass			; NO - stop compass to save on energy
 
-;----------------------------------------------------------------------------------
-; Jump table for initialization of the every-second tasks in custom view area (dive mode)
-;
-; Attention: the ordering must be in line with the every-second update jump table
-;            and the index numbers defined in hwos.inc!
-;
-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
+
+	; jump table
 	movf	active_customview,W			; get custom view to show
 	dcfsnz	WREG,F						;
 	bra		init_avr_stopwatch			;  1: average depth and stopwatch
@@ -523,131 +619,112 @@
 	dcfsnz	WREG,F						;
 	bra		init_CNS					; 11: CNS values
 	dcfsnz	WREG,F						;
-	bra		init_ppo2_ead_end_cns		; 12: ppO2, END/EAD and CNS
+	bra		init_ppo2_ead_end_cns		; 12: ppO2, END/EAD and CNS/gas density
 	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)
+	;bra	dive_cv_toggle_exit			;  0: no view (blank screen in custom view area)
+
+dive_cv_toggle_exit:
+	bcf		request_next_custview		; clear request flag
+	return								; done
 
 
-init_ppo2_sensors:
- IFDEF _external_sensor
-	bsf		trigger_temp_changed		; fake a change of the temperature to have the resettable dive time overwritten which was shown with the compass view
-	btfsc	FLAG_ccr_mode				; in CC mode?
-	bra		customview_init_view1a		; YES - (1)
-	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	bra		customview_init_view1a		; YES - (1)
-	bra		dive_customview_toggle		; NO to both, goto next view
-customview_init_view1a:
-	btfsc	analog_o2_input				; (1) - do we have an analog input?
-	bra		customview_init_view1b		;       YES - (2)
-	btfsc	s8_digital_avail			;       NO  - do we have a digital S8 interface?
-	bra		customview_init_view1b		;             YES - (2)
-	btfss	optical_input				;             NO  - do we have an optical input?
-	bra		dive_customview_toggle		;                   NO  - goto next view
-										;                   YES - (2)
-customview_init_view1b:
-	call	TFT_ppo2_sensors_mask		; (2) - mask for ppO2 sensors
-	call	TFT_ppo2_sensors			;     - data for ppO2 sensors
-	bra		customview_toggle_exit		;     - done
- ELSE
-	bra		dive_customview_toggle		; not available without external sensors, got next view
- ENDIF
-
+	; ---- view 1: average depth and stopwatch ----
+	;
 init_avr_stopwatch:
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	bra		dive_customview_toggle		; YES - goto next view
 	call	TFT_avr_stopwatch_mask		; NO  - mask for average depth and stopwatch
 	call	TFT_avr_stopwatch			;     - data for average depth and stopwatch
-	bra		customview_toggle_exit		;     - done
+	bra		dive_cv_toggle_exit			;     - done
+
 
-init_decoplan:
-	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 - goto next view
-	call	TFT_decoplan_mask			;       NO  - mask for deco plan
-	call	TFT_decoplan				;           - data for deco plan
-	bra		customview_toggle_exit		;           - done
-
-init_clock_batt_surfpress:
-	call	TFT_clock_batt_surfpress_mask	; mask for clock, battery and surface pressure
-	call	TFT_clock_batt_surfpress		; data for clock, battery and surface pressure
-	bra		customview_toggle_exit			; done
-
-init_TFT_dive_compass:					; compass
+	; ---- view 2: compass ----
+	;
+init_TFT_dive_compass:
  IFDEF _compass
 	call	I2C_init_compass			; start compass
-	call	TFT_dive_compass_mask		; show compass mask
-	bra		customview_toggle_exit		; done
+	call	TFT_dive_compass_mask		; mask for compass
+	bra		dive_cv_toggle_exit			; done
  ELSE
 	bra		dive_customview_toggle		; not available without compass compiled in, goto next view
  ENDIF
 
-init_pressures_SAC:						; tank pressure and SAC rate
+
+	; ---- view 3: ppO2 sensors ---
+	;
+init_ppo2_sensors:
+ IFDEF _external_sensor
+	bsf		trigger_temp_changed		; fake a change of the temperature to have the resettable dive time overwritten which was shown with the compass view
+	btfsc	FLAG_ccr_mode				; in CC mode?
+	bra		init_ppo2_sensors_1			; YES
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	bra		init_ppo2_sensors_1			; YES
+	bra		dive_customview_toggle		; NO to both, goto next view
+init_ppo2_sensors_1:
+	btfsc	ext_input_s8_ana			; do we have an S8/analog input?
+	bra		init_ppo2_sensors_2			; YES - show this view
+	btfsc	ext_input_optical			; NO  - do we have an optical input?
+	bra		init_ppo2_sensors_2			;       YES - show this view
+	bra		dive_customview_toggle		;       NO  - goto next view
+
+init_ppo2_sensors_2:
+	call	TFT_ppo2_sensors_mask		; mask for ppO2 sensors
+	call	TFT_ppo2_sensors			; data for ppO2 sensors
+	bra		dive_cv_toggle_exit			; done
+ ELSE
+	bra		dive_customview_toggle		; not available without external sensors, got next view
+ ENDIF
+
+	; ---- view 4: sensor check ----
+	;
+init_sensor_check:
+ IFDEF _ccr_pscr
+	btfss	FLAG_ccr_mode				; in CCR mode?
+	bra		dive_customview_toggle		; NO  - goto next view
+	call	TFT_sensor_check_mask		; YES - mask for sensor check
+	call	TFT_sensor_check			;     - data for sensor check
+	bra		dive_cv_toggle_exit			;     - done
+ ELSE
+	bra		dive_customview_toggle		; not available without CCR mode compiled in, goto next view
+ ENDIF
+
+
+	; ---- view 5: pSCR data ----
+	;
+init_pscr_info:
+ IFDEF _ccr_pscr
+	btfss	FLAG_pscr_mode				; in pSCR mode?
+	bra		dive_customview_toggle		; NO  - goto next view
+	call	TFT_pscr_info_mask			; YES - mask for pSCR info
+	call	TFT_pscr_info				;     - data for pSCR info
+	bra		dive_cv_toggle_exit			;     - done
+ ELSE
+	bra		dive_customview_toggle		; not available without CCR / pSCR mode, goto next view
+ ENDIF
+
+
+	; view 6: tank pressure and SAC rate ----
+	;
+init_pressures_SAC:
  IFDEF _rx_functions
 	btfss	tr_functions_activated		; TR functions activated?
 	bra		dive_customview_toggle		; NO  - goto next view
 	call	TFT_pressures_SAC_mask		; YES - mask for pressures and SAC
 	call	TFT_pressures_SAC			;     - data for pressures and SAC
-	bra		customview_toggle_exit		;     - done
+	bra		dive_cv_toggle_exit			;     - done
  ELSE
 	bra		dive_customview_toggle		; not available without RX functions, got next view
  ENDIF
 
-init_CNS:								; CNS at end of dive
-	btfsc	FLAG_gauge_mode				; in gauge mode?
-	bra		dive_customview_toggle		; YES - call next view
-	btfsc	FLAG_apnoe_mode				; NO  - in apnoe mode?
-	bra		dive_customview_toggle		;       YES - call next view
-	call	TFT_CNS_mask				;       NO  - mask for CNS values
-	call	TFT_CNS						;           - data for CNS values
-	bra		customview_toggle_exit		;           - done
 
-init_ceiling_GF_tissue:					; ceiling, tissues and current GF
-	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
-	call	TFT_ceiling_GF_tissue_mask	;       NO  - mask for ceiling, current GF and tissues
-	call	TFT_ceiling_GF_tissue		;           - data for ceiling, current GF and tissues
-	bra		customview_toggle_exit		;           - done
-
-init_sensor_check:						; sensor check
- IFDEF _ccr_pscr
-	btfss	FLAG_ccr_mode				; in CCR mode?
-	bra		dive_customview_toggle		; NO  - goto next view
-	call	TFT_sensor_check_mask		; YES - mask for sensor check
-	call	TFT_sensor_check			;     - data for sensor check
-	bra		customview_toggle_exit		;     - done
- ELSE
-	bra		dive_customview_toggle		; not available without CCR mode compiled in, goto next view
- ENDIF
-
-init_ppo2_ead_end_cns:					; ppO2, END/EAD and CNS
-	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 - goto next view
-	call	TFT_ppo2_ead_end_cns_mask	;       NO  - mask for ppO2, END/EAD and CNS
-	call	TFT_ppo2_ead_end_cns		;           - data for ppO2, END/EAD and CNS
-	bra		customview_toggle_exit		;           - done
-
-init_pscr_info:							; pSCR information
- IFDEF _ccr_pscr
-	btfss	FLAG_pscr_mode				; in pSCR mode?
-	bra		dive_customview_toggle		; NO  - goto next view
-	call	TFT_pscr_info_mask			; YES - mask for pSCR info
-	call	TFT_pscr_info				;     - data for pSCR info
-	bra		customview_toggle_exit		;     - done
- ELSE
-	bra		dive_customview_toggle		; not available without CCR / pSCR mode, goto next view
- ENDIF
-
-init_gas_needs_ascent:					; gas needs for ascent
+	; ---- view 7: gas needs ----
+	;
+init_gas_needs_ascent:
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	bra		dive_customview_toggle		; YES - goto next view
 	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
@@ -656,35 +733,94 @@
 	bra		dive_customview_toggle		;             NO  - goto next view
 	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
+	bra		dive_cv_toggle_exit			;                 - done
+
 
-init_cave_tts:							; cave mode data
+	; ---- view 8: cave mode TTS ----
+init_cave_tts:
  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
+	bra		dive_cv_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
+	; ---- view 9: deco plan ----
+	;
+init_decoplan:
+	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 - goto next view
+	call	TFT_decoplan_mask			;       NO  - mask for deco plan
+	call	TFT_decoplan				;           - data for deco plan
+	bra		dive_cv_toggle_exit			;           - done
+
+
+	; ---- view 10: ceiling, tissues and current GF
+	;
+init_ceiling_GF_tissue:
+	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
+	call	TFT_ceiling_GF_tissue_mask	;       NO  - mask for ceiling, current GF and tissues
+	call	TFT_ceiling_GF_tissue		;           - data for ceiling, current GF and tissues
+	bra		dive_cv_toggle_exit			;           - done
+
+
+	; ---- view 11: CNS values ----
+	;
+init_CNS:								; CNS at end of dive
+	btfsc	FLAG_gauge_mode				; in gauge mode?
+	bra		dive_customview_toggle		; YES - call next view
+	btfsc	FLAG_apnoe_mode				; NO  - in apnoe mode?
+	bra		dive_customview_toggle		;       YES - call next view
+	call	TFT_CNS_mask				;       NO  - mask for CNS values
+	call	TFT_CNS						;           - data for CNS values
+	bra		dive_cv_toggle_exit			;           - done
+
+
+	; ---- view 12: ppO2, END/EAD and CNS/gas density ----
+	;
+init_ppo2_ead_end_cns:					; 
+	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 - goto next view
+	call	TFT_ppo2_ead_end_cns_mask	;       NO  - mask for ppO2, END/EAD and CNS
+	call	TFT_ppo2_ead_end_cns		;           - data for ppO2, END/EAD and CNS
+	bra		dive_cv_toggle_exit			;           - done
+
+
+	; ---- view 13: clock, battery and surface pressure
+	;
+init_clock_batt_surfpress:
+	call	TFT_clock_batt_surfpress_mask	; mask for clock, battery and surface pressure
+	call	TFT_clock_batt_surfpress		; data for clock, battery and surface pressure
+	bra		dive_cv_toggle_exit				; done
+
+
+	; ---- view 14: GF factors
+	;
+init_gf_factors:
+	call	TFT_gf_factors_mask			; show GF factors
+	bra		dive_cv_toggle_exit			; done
+
+
+	; ---- view 15: cave waypoints ----
+	;
+init_cave_waypoints:
+ IFDEF _cave_mode
+	call	TFT_cave_waypoints			; show waypoint graphics
+	bra		dive_cv_toggle_exit			; done
+ ELSE
+	bra		dive_customview_toggle		; not available without cave mode, goto next view
+ ENDIF
 
 ;-----------------------------------------------------------------------------
 
--- a/src/divemenu_tree.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/divemenu_tree.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemenu_tree.asm                    combined next generation V3.08.8
+;   File divemenu_tree.asm                  * combined next generation V3.09.5
 ;
 ;   OSTC dive mode menu
 ;
@@ -9,52 +9,80 @@
 ; HISTORY
 ;   2013-02-02 : [mH] Made out of menu_tree.asm
 
-#include "hwos.inc"						; Mandatory header
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;
+;                                  ATTENTION
+;
+; All Calls made via the Menu Macros need to go to Addresses within 0x0xxxx !
+;
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+#include "hwos.inc"
+#include "shared_definitions.h"
 #include "menu_processor.inc"
-#include "shared_definitions.h"			; Mailbox from/to p2_deco.c
 #include "tft_outputs.inc"
 #include "customview.inc"
 #include "strings.inc"
 #include "calibrate.inc"
-
-	extern	timeout_divemode_menu2
-	extern	restart_deco_engine_wo_ceiling
-	extern	diveloop_menu_exit
+#include "gaslist.inc"
+#include "colorschemes.inc"
 
 
-dmenu_tree	CODE
+	extern	diveloop_menu_exit
+
+ IFDEF _cave_mode
+	extern	cavemode_turndive_check
+	extern	cavemode_waypoint_set_check
+	extern	cavemode_waypoint_out_check
+	extern	cavemode_waypoint_in_check
+ ENDIF
+
 
 ;=============================================================================
+dive_menu	CODE	0x02000				; needs to be at 0x0xxxx
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Return to Main Dive Mode Menu
 ;
-; Dive Mode Menu
-;
-
 do_return_main_divemenu:
 	call	menu_processor_double_pop	; drop exit line and back to last line
 	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_divemenu_common
+	bra		do_main_divemenu_common		; continue with common part
+
 
+;-----------------------------------------------------------------------------
+; Entry Point for Main Dive Mode Menu
+;
 	global	do_main_divemenu
 do_main_divemenu:
 	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						; ...
+	;bra	do_main_divemenu_common				; continue with common part
 
+
+;-----------------------------------------------------------------------------
+; Common Part for Main Dive Mode Menu, 1st Layer
+;
 do_main_divemenu_common:
  IFDEF _ccr_pscr
-	btfsc	FLAG_ccr_mode
-	bra		main_divemenu_loop			; goto CCR / pSCR Menu menu
-	btfsc	FLAG_pscr_mode
-	bra		main_divemenu_loop			; goto CCR / pSCR Menu menu
- ENDIF
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	bra		main_divemenu_loop			; YES - goto CCR / pSCR Menu menu
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	bra		main_divemenu_loop			; YES - goto CCR / pSCR Menu menu
+ ENDIF	; _ccr_pscr
 
 main_divemenu_OC:
  IFDEF _ccr_pscr
 	bcf		is_diluent_menu				; selecting OC gases ...
 	bcf		is_bailout_menu				; ... not for bailout reason
- ENDIF
+ ENDIF	; _ccr_pscr
 
  IFDEF _cave_mode
 	TSTOSS	opt_cave_mode				; cave mode switched on?
@@ -62,28 +90,25 @@
 	;bra	main_divemenu_OC_cave		; YES - use version with    cave mode entry
 
 main_divemenu_OC_cave:
-	MENU_BEGIN	tMainMenu,	.6
+	MENU_BEGIN_DIVE	.6
 		MENU_CALL		tDivemenu_Gaslist,	do_divemode_gaslist
 		MENU_CALL		tDivemenu_ResetAvg,	do_reset_average
-		MENU_DYNAMIC	label_do_toggle_gf,	do_toggle_gf
+		MENU_DYNAMIC	dyn_toggle_gf,		do_toggle_gf
 		MENU_CALL		tDivemenu_Marker,	do_set_marker
 		MENU_CALL		tCaveMode,			do_main_cavemenu
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
- ENDIF
+ ENDIF	; _cave_mode
 
 main_divemenu_OC_nocave:
-	MENU_BEGIN	tMainMenu,	.5
+	MENU_BEGIN_DIVE	.5
 		MENU_CALL		tDivemenu_Gaslist,	do_divemode_gaslist
 		MENU_CALL		tDivemenu_ResetAvg,	do_reset_average
-		MENU_DYNAMIC	label_do_toggle_gf,	do_toggle_gf
+		MENU_DYNAMIC	dyn_toggle_gf,		do_toggle_gf
 		MENU_CALL		tDivemenu_Marker,	do_set_marker
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
-
-;=============================================================================
-
  IFDEF _ccr_pscr
 
 main_divemenu_loop:
@@ -92,60 +117,95 @@
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
 	bra		main_divemenu_pscr			; YES - show pSCR menu
 
-	MENU_BEGIN	tMainMenu,	.6
+	MENU_BEGIN_DIVE	.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	label_do_toggle_gf,	do_toggle_gf
+		MENU_DYNAMIC	dyn_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)?
+	btfsc	ext_input_s8_ana			; do we have an S8/analog input (OSTC cR)?
 	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
-	btfsc	optical_input				; do we have an optical input (OSTC 3)?
+	btfsc	ext_input_optical			; do we have an optical input (OSTC 3)?
 	bra		main_divemenu_pscr_sensors	; YES - do menu with calibration
- ENDIF
+ ENDIF	; _external_sensor
 
 main_divemenu_pscr_no_sensors:
-	MENU_BEGIN	tMainMenu,	.6
+	MENU_BEGIN_DIVE	.6
 		MENU_CALL		tDiveBailout,		do_divemode_gaslist_bail
 		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	label_do_toggle_gf,	do_toggle_gf
+		MENU_DYNAMIC	dyn_toggle_gf,		do_toggle_gf
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
+ IFDEF _external_sensor
 main_divemenu_pscr_sensors:
- IFDEF _external_sensor
-	MENU_BEGIN	tMainMenu,	.6
+	MENU_BEGIN_DIVE	.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	label_do_toggle_gf,	do_toggle_gf
+		MENU_DYNAMIC	dyn_toggle_gf,		do_toggle_gf
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
  ENDIF	; _external_sensor
 
+
+;-----------------------------------------------------------------------------
+; Call Function - start Bailout Condition
+;
+do_divemode_gaslist_bail:
+	bcf		is_diluent_menu				; select OC gases
+	bsf		is_bailout_menu				; flag it is a bailout action
+	bra		do_divemode_gaslist			; continue with the gas menu for B/O gas selection
+
+
+;-----------------------------------------------------------------------------
+; Call Function - switch to calculated Setpoint (pSCR)
+;
+do_switch_sp_calc:
+	bcf		warn_det_sensors_lost		; clear fallback condition (revoke all sensors lost warning)
+	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			; continue with common part
+
  ENDIF	; _ccr_pscr
 
-;=============================================================================
+
+;-----------------------------------------------------------------------------
+; dynamic Title - toggle GF
+;
+dyn_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		dyn_toggle_gf_1				; NO  - print in disabled color
+	TSTOSS	opt_enable_aGF				; YES - aGF enabled?
+dyn_toggle_gf_1:
+	FONT_COLOR_DISABLED					;       NO  - print in disabled color
+	STRCAT_TEXT tDivemenu_ToggleGF		; output label
+	return								; done
 
 
+;-----------------------------------------------------------------------------
+; Sub-Menu: Toggle GFs
+;
 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_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
+	bra		do_abort_toggle_gf			; NO - do nothing and return
+	TSTOSS	opt_enable_aGF				; aGF enabled?
+	bra		do_abort_toggle_gf			; NO - do nothing and return
 	bsf		custom_view_locked			; lock custom view
 do_toggle_gf_1:
 	movlw	index_gf_factors			; get  number of GF factors custom view
@@ -154,40 +214,56 @@
 	movlw	.1							; set to first option in dive mode menu
 	movwf	menu_pos_cur				; ...
 
-	MENU_BEGIN	tDivemenu_ToggleGF,	.2
+	MENU_BEGIN_DIVE	.2
 		MENU_CALL		tDivemenu_ToggleGF,	do_toggle_gf_toggle
 		MENU_CALL		tExit,				do_exit_divemode_menu
 	MENU_END
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - abort toggle GF Sub-Menu
+;
+do_abort_toggle_gf:
+	call	menu_processor_pop			; drop selection from menu stack
+	bra		do_main_divemenu_common		; back to main menu
+
+
+;-----------------------------------------------------------------------------
+; Call Function - toggle GF <-> aGF
+;
 do_toggle_gf_toggle:
-	bsf		request_toggle_GF			; set request flag to have the deco engine restarted
+	bsf		request_toggle_GF			; request restart of the deco engine
 	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
 
 
+;-----------------------------------------------------------------------------
+; Sub-Menu: Reset average Depth & set Marker
+;
 do_reset_avg_set_mkr:
 	movlw	.1							; set to first option in dive mode menu
 	movwf	menu_pos_cur				; ...
 
-	MENU_BEGIN	tDivemenu_Avg_Mkr,	.3
+	MENU_BEGIN_DIVE	.3
 		MENU_CALL		tDivemenu_ResetAvg,	do_reset_average
 		MENU_CALL		tDivemenu_Marker,	do_set_marker
-		MENU_CALL		tBack,				do_return_main_divemenu
+		MENU_CALL		tBack,				do_return_main_divemenu		; return to main menu
 	MENU_END
 
 
+;-----------------------------------------------------------------------------
+; Call Function - reset average Depth
+;
 do_reset_average:
 	bsf		request_reset_avg			; request reset of resettable average depth and dive time
  IFDEF _min_depth_option
@@ -196,67 +272,22 @@
 	bra		do_exit_divemode_menu		; continue exiting the menu
 
 
+;-----------------------------------------------------------------------------
+; Call Function - set a Marker in the Dive Profile Recording
+;
 do_set_marker:
 	bsf		request_set_marker			; set request flag
 	bra		do_exit_divemode_menu		; continue exiting the menu
 
-;=============================================================================
 
- IFDEF _ccr_pscr
-
-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		; 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			; continue with common part
-
-
-do_switch_sp_calc:						; entry point when coming from switch to calculated ppO2 (pSCR)
-	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
-	movff	WREG,char_I_const_ppO2		; set setpoint to 0, this forces deco engine to take the computed ppO2
-	;bra	do_switch_sp_com			; continue with common part
-
-
-do_switch_sp_com:						; common part
-	bsf		event_occured				; set global   event byte
-	bsf		event_SP_change				; set setpoint event flag
-
-	; Clear some flags in case we were in bailout before...
-	bcf		bailout_mode				; end bailout mode
-	bcf		better_gas_available		; =1: a better gas is available and a gas change is advised in dive mode
-	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_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_gas_change			; initiate reconfiguration to loop mode on last diluent
-
-	bra		do_exit_divemode_menu		; continue exiting the menu
-
-
-do_divemode_gaslist_bail:				; entry point from CCR/pSCR to bailout to OC gases
-	bcf		is_diluent_menu				; select OC gases
-	bsf		is_bailout_menu				; flag it is a bailout action
-	;bra	do_divemode_gaslist
-
- ENDIF	; _ccr_pscr
-
-;=============================================================================
-
-do_divemode_gaslist:					; entry point for switching: OC -> gases, loop -> diluents
+;-----------------------------------------------------------------------------
+; Sub-Menu: Switch OC / Diluent Selection
+;
+do_divemode_gaslist:
  IFDEF _ccr_pscr
 	btfsc	bailout_mode				; in bailout mode?
 	bcf		is_diluent_menu				; YES - for safety reasons, redirect to selecting OC (bailout) gases
- ENDIF
+ ENDIF	; _ccr_pscr
 	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
@@ -264,7 +295,7 @@
  IFDEF _ccr_pscr
 	btfsc	is_diluent_menu				; in diluent selection?
 	movf	best_dil_number,W			; YES - overwrite with best diluent (1-5)
- ENDIF
+ ENDIF; _ccr_pscr
 	bnz		do_divemode_gaslist_1		; best gas/dil number  =   0 (none available) ?
 	movlw	.1							; YES - default to first gas/dil
 	btfsc	WREG,7						; best gas/dil number >= 128 (not computed yet) ?
@@ -272,88 +303,42 @@
 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_BEGIN_DIVE	.6
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_switch_gas
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_switch_gas
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_switch_gas
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_switch_gas
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_switch_gas
 		MENU_CALL		tDivemenu_LostGas,		do_lost_gas
 	MENU_END
 
 
-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
- ENDIF
-
-do_divemode_gaslist_more_common:
- IFDEF _helium
-	MENU_BEGIN	tGaslist,	.6
-		MENU_CALL		tO2Plus,				do_dive_pO2
-		MENU_CALL		tO2Minus,				do_dive_mO2
-		MENU_CALL		tHePlus,				do_dive_pHe
-		MENU_CALL		tHeMinus,				do_dive_mHe
-		MENU_DYNAMIC	gaslist_strcat_gas6,	do_switch_gas6
-		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		tExit,					do_exit_divemode_menu
-	MENU_END
- ENDIF
+;-----------------------------------------------------------------------------
+; dynamic Title - print full Gas Description
+;
+dyn_strcat_gas_prodl:
+	goto	gaslist_strcat_gas_PRODL	; code is hosted in gaslist.asm
 
 
-do_lost_gas:
-	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_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
-
-
-do_switch_gas6:
-	movlw	.6							; gas 6
-	movwf	menu_pos_cur				; transfer register for selected gas towards gas_switched_common
-	bsf		event_gas_change_gas6		; set flag for profile recording
-	;bra	do_switch_gas				; continue with common gas-switched code
-
-
+;-----------------------------------------------------------------------------
+; Call Function - initiate Gas Change (will also trigger restart of deco_engine)
+;
 do_switch_gas:
-	bsf		request_gas_change			; initiate gas change, will also trigger restart of deco_engine
+	bsf		request_gas_change			; request dive mode to do a gas change
  IFDEF _ccr_pscr
 	btfss	is_bailout_menu				; doing a bailout?
 	bra		do_switch_gas_1				; NO
 	bsf		bailout_mode				; YES - begin bailout mode
- ENDIF
+ ENDIF	; _ccr_pscr
  IFDEF _cave_mode
 	btfsc	cave_mode					;     - cave mode switched on?
 	bsf		request_turn_turn			;       YES - request to turn the dive
- ENDIF
+ ENDIF	; _cave_mode
  IFDEF _ccr_pscr
 do_switch_gas_1:
-	bcf		sp_fallback					; terminate fallback mode and get rid of its warning if applicable
+	bcf		warn_det_sensors_lost		; 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
+ ENDIF	; _ccr_pscr
 	; 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
@@ -366,17 +351,42 @@
 	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
+ ENDIF	; _cave_mode
+	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		; check for timeout and do some cleanup
-	clrf	STKPTR						; reset the stack
-	goto	diveloop_menu_exit			; back to the dive loop
+;-----------------------------------------------------------------------------
+; Sub-Menu: lost / staged Gas
+;
+do_lost_gas:
+	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_DIVE	.6
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_toggle_staged_lost
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_toggle_staged_lost
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_toggle_staged_lost
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_toggle_staged_lost
+		MENU_DYNAMIC	dyn_strcat_gas_prodl,	do_toggle_staged_lost
+		MENU_DYNAMIC	dyn_gas6_or_exit,		do_gas6_or_exit
+	MENU_END
 
 
+;-----------------------------------------------------------------------------
+; dynamic Title - print full Gas Description
+;
+;dyn_strcat_gas_prodl:
+;	goto	gaslist_strcat_gas_PRODL	; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; Call Function - toggle a Gas between available, lost and staged
+;
 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)
@@ -388,7 +398,7 @@
 	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
+ ENDIF	; _ccr_pscr
 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
@@ -431,99 +441,187 @@
 	bra		do_lost_gas_common			; back to the menu
 
 
-do_dive_pO2:
-	incf	gas6_O2_ratio,F				; increment O2 %
+;-----------------------------------------------------------------------------
+; dynamic Title - print Gas 6 Item or Exit Item
+;
+dyn_gas6_or_exit:
+	btfsc	gas6_or_EXIT				; shall print exit?
+	bra		dyn_gas6_or_exit_1			; YES - print exit  label
+	STRCAT_TEXT tGas6					; NO  - print gas 6 label
+	return								;     - done
+dyn_gas6_or_exit_1:
+	STRCAT_TEXT tExit					; print exit label
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Sub-Menu: Gas 6 / Menu-Exit
+;
+do_gas6_or_exit:
+	btfsc	gas6_or_EXIT						; shall exit?
+	bra		do_exit_divemode_menu				; YES - exit the menu
+	movlw	.1									; NO  - select first item
+	movwf	menu_pos_cur						;     - set cursor
+	movff	char_I_O2_ratio,opt_gas6_O2_ratio	;     - initialize gas6 with currently breathed gas - O2 ratio
  IFDEF _helium
-	movf	gas6_He_ratio,W				; get He %
-	addwf	gas6_O2_ratio,W				; add O2 %
+	movff	char_I_He_ratio,opt_gas6_He_ratio	;     - initialize gas6 with currently breathed gas - He ratio
  ELSE
-	movf	gas6_O2_ratio,W				; get O2 %
- ENDIF
-	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
+	clrf	WREG								;     - set gas6 helium to zero
+	movff	WREG,opt_gas6_He_ratio				;     - ...
+ ENDIF	; _helium
+	bsf		block_option_value					; suspend displaying of option values
 
 
-do_dive_mO2:
-	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  - value is valid
-	movwf	gas6_O2_ratio				; YES - set O2 % to minimum
-do_dive_mO2_done:
-	bra		do_divemode_gaslist_more_common
+ IFDEF _helium
+	MENU_BEGIN_DIVE .6
+		MENU_OPT_INCS	tO2Plus,				oGas6O2
+		MENU_OPT_DECS	tO2Minus,				oGas6O2
+		MENU_OPT_INCS	tHePlus,				oGas6He
+		MENU_OPT_DECS	tHeMinus,				oGas6He
+		MENU_DYNAMIC	dyn_show_gas6,			do_gas6_switch
+		MENU_CALL		tExit,					do_exit_divemode_menu
+	MENU_END
+ ELSE
+	MENU_BEGIN_DIVE .4
+		MENU_OPT_INCS	tO2Plus,				oGas6O2
+		MENU_OPT_DECS	tO2Minus,				oGas6O2
+		MENU_DYNAMIC	dyn_show_gas6,			do_gas6_switch
+		MENU_CALL		tExit,					do_exit_divemode_menu
+	MENU_END
+ ENDIF; _helium
 
-;=============================================================================
-
- IFDEF _helium
 
-do_dive_pHe:
-	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
+;-----------------------------------------------------------------------------
+; dynamic Title: show Gas 6 Mix
+;
+dyn_show_gas6:
+	STRCAT_TEXT tTakeGas				; print "take"
+	PUTC	" "							; print one space
+	movff	opt_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	opt_gas6_O2_ratio,lo		; gaslist_strcat_mix needs O2 ratio in lo
+ IFDEF _helium
+	movff	opt_gas6_He_ratio,hi		;                ... and He ratio in hi
+ ELSE
+	clrf	hi							;                ... and He ration will be zero
+ ENDIF	; _helium
+	goto	gaslist_strcat_mix			; print "Nxlo", "Txlo/hi", "Air" or "O2" and return
 
-do_dive_mHe:
-	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:
-	bra		do_divemode_gaslist_more_common
 
- ENDIF
+;-----------------------------------------------------------------------------
+; Call Function - switch to Gas 6
+;
+do_gas6_switch:
+	movlw	.6							; gas 6
+	movwf	menu_pos_cur				; transfer register for selected gas towards gas_switched_common
+	bsf		event_gas_change_gas6		; set flag for profile recording
+	bra		do_switch_gas				; continue with common gas-switched code
 
-;=============================================================================
 
  IFDEF _ccr_pscr
 
+;-----------------------------------------------------------------------------
+; Sub Menu - select Setpoint
+;
 do_divemode_splist:
 	bsf		short_gas_descriptions		; do not show "SP" etc.
 	movlw	.1							; default to first menu item
 	movff	opt_ccr_mode,lo				; get CCR mode (0: Fixed SP, 1: Sensor, 2: Auto SP)
 	dcfsnz	lo,F						; mode = sensor ?
 	movlw	.6							; YES - load menu item number for 'sensor'
-	btfsc	sp_fallback					; in fallback condition?
+	btfsc	warn_det_sensors_lost		; all sensors lost?
 	movlw	.1							; YES - revert to first menu item
 	movwf	menu_pos_cur				; set cursor position
 
-do_divemode_splist_common:
-
  IFDEF _external_sensor
-	btfsc	analog_o2_input				; do we have an analog or S8 digital input (OSTC cR)?
+	btfsc	ext_input_s8_ana			; do we have an S8/analog input (OSTC cR)?
 	bra		do_divemode_splist_sensor	; YES
-	btfsc	optical_input				; do we have an optical input (OSTC 3)?
+	btfsc	ext_input_optical			; do we have an optical input (OSTC 3)?
 	bra		do_divemode_splist_sensor	; YES
- ENDIF
+ ENDIF	; _external_sensor
 
 do_divemode_splist_no_sensor:
-	MENU_BEGIN	tGaslist, .5
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
+	MENU_BEGIN_DIVE	.5
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
 	MENU_END
 
 
  IFDEF _external_sensor
 
 do_divemode_splist_sensor:
-	MENU_BEGIN	tGaslist,	.6
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_switch_sp
+	MENU_BEGIN_DIVE	.6
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_switch_sp
 		MENU_CALL		tCCRSensor,					do_divemode_sensor
 	MENU_END
 
+ ENDIF	; _external_sensor
 
+
+;-----------------------------------------------------------------------------
+; dynamic Title - print Setpoint
+;
+dyn_strcat_setpoint_prodl:
+	goto	gaslist_strcat_setpoint_PRODL	; function is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; Call Function - switch to manually selected Setpoint (CCR)
+;
+do_switch_sp:
+	decf	menu_pos_cur,W				; 1-5 -> 0-4
+	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		warn_det_sensors_lost		; clear fallback condition (revoke all sensors lost 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			; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - common Part of Setpoint Switching
+;
+do_switch_sp_com:						; common part
+	bsf		event_occured				; set global   event byte
+	bsf		event_SP_change				; set setpoint event flag
+
+	; Clear some flags in case we were in bailout before...
+	bcf		bailout_mode				; end bailout mode
+	bcf		better_gas_available		; =1: a better gas is available and a gas change is advised in dive mode
+	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_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_gas_change			; initiate reconfiguration to loop mode on last diluent
+
+	bra		do_exit_divemode_menu		; continue exiting the menu
+
+
+ IFDEF _external_sensor
+
+
+;-----------------------------------------------------------------------------
+; Return to Sub Menu toggle Sensor Usage / select Sensors from Menu Action
+;
+do_return_divemode_sensor:
+	call	menu_processor_pop			; drop selection from menu stack
+	bra		do_return_divemode_common	; back to menu
+
+;-----------------------------------------------------------------------------
+; Sub Menu - toggle Sensor Usage / select Sensors
+;
 do_divemode_sensor:
 	movlw	index_ppo2_sensors			; number of ppO2 sensors custom view
 	movwf	active_customview			; set     the custom view number
@@ -531,8 +629,8 @@
 	movlw	.1							; set to 1st option: use sensors
 	movwf	menu_pos_cur				; ...
 
-do_return_divemode_sensor:
-	MENU_BEGIN	tGaslist,	.6
+do_return_divemode_common:
+	MENU_BEGIN_DIVE	.6
 		MENU_CALL		tDivemenu_UseSensor,	do_switch_sensor
 		MENU_CALL		tBack,					do_divemode_splist
 		MENU_CALL		tExit,					do_exit_divemode_menu
@@ -545,7 +643,7 @@
 	movlw	.1
 	movwf	menu_pos_cur				; set to 1st option: use calculated ppO2
 
-	MENU_BEGIN	tGaslist,	.6
+	MENU_BEGIN_DIVE	.6
 		MENU_CALL		tCalculated,			do_switch_sp_calc
 		MENU_CALL		tDivemenu_UseSensor,	do_switch_sensor
 		MENU_CALL		tExit,					do_exit_divemode_menu
@@ -554,41 +652,59 @@
 		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
+
+;-----------------------------------------------------------------------------
+; Call Function - switch to using Sensors
+;
+do_switch_sensor:
+	movlw	.1							; switch to sensor (0: fixed/ calculated SP, 1: Sensor, 2: AutoSP)
+	movff	WREG,opt_ccr_mode			; ...
 
+	; check for external HUD/ppO2 Monitor
+	btfss	ext_input_optical			; do we have an optical input?
+	bra		do_switch_sp_com			; NO  - continue with common part
+	btfsc	sensor1_active				; YES - process flags from HUD/ppO2 Monitor
+	bsf		use_O2_sensor1				;     - ...
+	btfsc	sensor2_active				;     - ...
+	bsf		use_O2_sensor2				;     - ...
+	btfsc	sensor3_active				;     - ...
+	bsf		use_O2_sensor3				;     - ...
+	bra		do_switch_sp_com			;     - continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Call Function - toggle Sensor Usage
+;
 do_toggle_sensor:
-	movff	menu_pos_cur,lo				; backup position
-	decf	menu_pos_cur,f				; 4, 5, 6 ->  3, 4, 5
-	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				;             = 
-	dcfsnz	menu_pos_cur				; 0, 1, 2 -> -1, 0, 1
-	btg		use_O2_sensor2				;                =
-	dcfsnz	menu_pos_cur				; -1,0, 1 -> -2,-1, 0
-	btg		use_O2_sensor3				;                   =
-	movff	lo,menu_pos_cur				; restore position
-	bra		do_return_divemode_sensor
+	movf	menu_pos_cur,W				; copy position to WREG
+	addlw	-.3							; skip first 3 menu items
+	dcfsnz	WREG						; cursor on item sensor 1 ?
+	btg		use_O2_sensor1				; YES - toggle sensor 1 state
+	dcfsnz	WREG						; cursor on item sensor 2 ?
+	btg		use_O2_sensor2				; YES - toggle sensor 2 state
+	dcfsnz	WREG						; cursor on item sensor 3 ?
+	btg		use_O2_sensor3				; YES - toggle sensor 3 state
+	bra		do_return_divemode_sensor	; back to same menu
 
  ENDIF	; _external_sensor
  ENDIF	; _ccr_pscr
 
-;=============================================================================
-;
-; Cave Mode Menu
-;
 
  IFDEF _cave_mode
 
+;-----------------------------------------------------------------------------
+; Return to Cave Mode Main Menu
+;
 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
 
+
+;-----------------------------------------------------------------------------
+; Cave Mode Main Menu
+;
 	global	do_main_cavemenu
 do_main_cavemenu:
 	bsf		custom_view_locked					; lock custom view
@@ -600,47 +716,123 @@
 	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.
+	;bra	do_main_cavemenu_common				; continue with common part
 
 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_BEGIN_DIVE	.6
+		MENU_DYNAMIC	dyn_waypoint_set,		do_waypoint_set			; 1
+		MENU_DYNAMIC	dyn_turndive_toggle,	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_DYNAMIC	dyn_waypoint_out,		do_waypoint_out			; 4
+		MENU_DYNAMIC	dyn_waypoint_in,		do_waypoint_in			; 5
 		MENU_CALL		tExit,					do_exit_divemode_menu	; 6
 	MENU_END
 
 
+;-------------------------------------------------------------------
+; dynamic Title - set a Waypoint
+;
+dyn_waypoint_set:
+	call	cavemode_waypoint_set_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	FONT_COLOR_DISABLED					; NO - switch to disabled color
+	STRCAT_TEXT tDivemenu_wp_set		; print label
+	return								; done
+
+
+;-------------------------------------------------------------------
+; dynamic Title - turn the Dive
+;
+dyn_turndive_toggle:
+	call	cavemode_turndive_check		; check if command is allowed
+	tstfsz	WREG						; command allowed?
+	FONT_COLOR_DISABLED					; NO - switch to disabled color
+	btfss	cave_mode					; cave mode switched on?
+	bra		dyn_turndive_toggle_1		; NO  - print turn dive label
+	btfss	dive_turned					; YES - dive turned?
+	bra		dyn_turndive_toggle_1		;       NO  - print turn dive label
+	STRCAT_TEXT tDivemenu_ContDive		;       YES - print continue dive label
+	return								;           - done
+dyn_turndive_toggle_1:
+	STRCAT_TEXT tDivemenu_TurnDive		; print turn dive label
+	return								; done
+
+
+;-------------------------------------------------------------------
+; dynamic Title - navigate one Waypoint outwards
+;
+dyn_waypoint_out:
+	call	cavemode_waypoint_out_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	FONT_COLOR_DISABLED					; NO - switch to disabled color
+	STRCAT_TEXT tDivemenu_wp_out		; print label
+	return								; done
+
+
+;-------------------------------------------------------------------
+; dynamic Title - navigate one Waypoint inwards
+;
+dyn_waypoint_in:
+	call	cavemode_waypoint_in_check	; check if command is allowed to execute
+	tstfsz	WREG						; command allowed?
+	FONT_COLOR_DISABLED					; NO - switch to disabled color
+	STRCAT_TEXT tDivemenu_wp_in			; print label
+	return								; done
+
+
+;-------------------------------------------------------------------
+; Call Function - set a Waypoint
+;
 do_waypoint_set:
 	bsf		request_waypoint_set		; set request flag
 	bra		do_return_main_cavemenu		; back to menu
 
+
+;-------------------------------------------------------------------
+; Call Function - turn the dive
+;
 do_turndive_toggle:
 	bsf		request_turn_toggle			; set request flag
 	bra		do_return_main_cavemenu		; back to menu
 
+
+;-------------------------------------------------------------------
+; Call Function - turn Cave Mode on/off
+;
 do_cavemode_toggle:
 	bsf		request_cave_toggle			; set request flag
 	bra		do_return_main_cavemenu		; back to menu
 
+
+;-------------------------------------------------------------------
+; Call Function - navigate one Waypoint outwards
+;
 do_waypoint_out:
 	bsf		request_waypoint_out		; set request flag
 	bra		do_return_main_cavemenu		; back to menu
 
+
+;-------------------------------------------------------------------
+; Call Function - navigate one Waypoint inwards
+;
 do_waypoint_in:
 	bsf		request_waypoint_in			; set request flag
 	bra		do_return_main_cavemenu		; back to menu
 
  ENDIF	; _cave_mode
 
-;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Call Function - leave the Menu
+;
+do_exit_divemode_menu:
+	bcf		block_option_value			; resume displaying of option values
+	goto	diveloop_menu_exit			; back to the dive loop
+
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/divemode.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/divemode.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemode.asm                         combined next generation V3.08.8
+;   File divemode.asm                       * combined next generation V3.09.5
 ;
 ;   Dive Mode
 ;
@@ -31,6 +31,7 @@
 	extern	do_line_menu
 	extern	do_main_divemenu
 	extern	menu_draw_lines_divemode
+	extern	menu_draw_cursor_dive
 	extern	init_recording_params
 	extern	option_check_and_store_all
 
@@ -42,6 +43,7 @@
 	extern	do_main_cavemenu
  ENDIF
 
+
 ;---- Private local Variables -------------------------------------------------
 
 	CBLOCK	local1						; max size is 16 Byte !!!
@@ -63,12 +65,10 @@
 	CBLOCK	local2						; max size is 16 Byte !!!
 		pressure_rel_accu_trip:4		; pressure accumulator for calculating the resettable average depth
 		pressure_rel_accu_total:4		; pressure accumulator for calculating the total dive average depth
-		xmitter_flags_stat				; pressure transmitter flags for status
-		xmitter_flags_mesg				; pressure transmitter flags for messages
 		ppO2_min:2						; used in search for best gas/dil: minimum ppO2 required
 		ppO2_max_default:2				; used in search for best gas/dil: default  maximum ppO2
 		ppO2_max_deco:2					; used in search for best gas/dil: deco     maximum ppO2
-	ENDC								; used: 16 byte, remaining: 0 byte ==> FULL
+	ENDC								; used: 14 byte, remaining: 2 byte
 
 
 ;---- Private local Flags ----------------------------------------------------
@@ -114,41 +114,25 @@
 ;										TFT_output_flags_4,7	; --- unused
 
 
-; Pressure Transmitter Status
-#DEFINE transmitter1_lost				xmitter_flags_stat,0	; =1: transmitter 1 lost               is an old message
-#DEFINE transmitter1_battery			xmitter_flags_stat,1	; =1: transmitter 1 battery low        is an old message
-#DEFINE transmitter1_pres_warn			xmitter_flags_stat,2	; =1: transmitter 1 pressure warning   is an old message
-#DEFINE transmitter1_pres_att			xmitter_flags_stat,3	; =1: transmitter 1 pressure attention is an old message
-#DEFINE transmitter2_lost				xmitter_flags_stat,4	; =1: transmitter 2 lost               is an old message
-#DEFINE transmitter2_battery			xmitter_flags_stat,5	; =1: transmitter 2 battery low        is an old message
-#DEFINE transmitter2_pres_warn			xmitter_flags_stat,6	; =1: transmitter 2 pressure warning   is an old message
-#DEFINE transmitter2_pres_att			xmitter_flags_stat,7	; =1: transmitter 2 pressure attention is an old message
-
-; Pressure Transmitter Messages
-#DEFINE pres_customview_shown			xmitter_flags_mesg,0	; =1: pressure readings custom view has been shown before
-#DEFINE show_transmitter_attention		xmitter_flags_mesg,1	; =1: show transmitter attention
-#DEFINE show_pres_warning				xmitter_flags_mesg,2	; =1: show transmitter pressure warning
-#DEFINE show_pres_attention				xmitter_flags_mesg,3	; =1: show transmitter pressure attention
-;										xmitter_flags_mesg,4	; --- unused
-;										xmitter_flags_mesg,5	; --- unused
-;										xmitter_flags_mesg,6	; --- unused
-;										xmitter_flags_mesg,7	; --- unused
-
 ; various Flags
 #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
+#DEFINE update_menu						DM_flags_local,1		; =1: redraw the dive menu
+#DEFINE FLAG_SP2_used					DM_flags_local,2		; =1: setpoint 2 has been auto-selected already
+#DEFINE FLAG_SP3_used					DM_flags_local,3		; =1: setpoint 3 has been auto-selected already
+#DEFINE FLAG_SP4_used					DM_flags_local,4		; =1: setpoint 4 has been auto-selected already
+#DEFINE FLAG_SP5_used					DM_flags_local,5		; =1: setpoint 5 has been auto-selected already
+;										DM_flags_local,6		; --- unused
 ;										DM_flags_local,7		; --- unused
 
 
-dmode	CODE
-
 ;=============================================================================
-
+dmode1	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Entry Point for Dive Mode
+;
 	global	diveloop
 diveloop:
 	clrf	STKPTR						; clear return addresses stack
@@ -170,83 +154,85 @@
 	clrf	DM_flags_message			; clear all flags for display control / messages
 	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
+	clrf	DM_flags_advc_det			; clear all flags for advices    detection
+	clrf	DM_flags_advc_ack			; clear all flags for advices    acknowledged
+
+	clrf	DM_flags_att1_det			; clear all flags for attentions detection
+	clrf	DM_flags_att2_det			; ...
+	clrf	DM_flags_att3_det			; ...
+
+	clrf	DM_flags_att1_ack			; clear all flags for attentions acknowledged
+	clrf	DM_flags_att2_ack			; ...
+	clrf	DM_flags_att3_ack			; ...
+
+	clrf	DM_flags_war1_det			; clear all flags for warnings   detection
+	clrf	DM_flags_war2_det			; ...
+
+	clrf	DM_flags_war1_ack			; clear all flags for warnings   acknowledged
+	clrf	DM_flags_war2_ack			; ...
+
+	clrf	DM_flags_shown1				; arm auto show-up of custom views
+	clrf	DM_flags_shown2				; ...
+	clrf	DM_flags_shown3				; ...
+
+	bcf		dive_main_menu				; clear dive main menu flag
+	bcf		dive_pre_menu				; clear dive  pre-menu flag
 
 	; reset local flags
 	clrf	TFT_output_flags_1			; clear all flags for TFT output phase 1
 	clrf	TFT_output_flags_2			; clear all flags for TFT output phase 2
 	clrf	TFT_output_flags_3			; clear all flags for TFT output phase 3
 	clrf	TFT_output_flags_4			; clear all flags for TFT output phase 4
-	clrf	xmitter_flags_stat			; clear all pressure transmitter status  flags
-	clrf	xmitter_flags_mesg			; clear all pressure transmitter message flags
 	clrf	DM_flags_local				; clear all the various other flags, too
 
-	; configure screen layout (all flags were cleared above)
-	TSTOSC	opt_layout					; alternative layout enabled?
-	bsf		alt_layout_active			; YES - start with alternative layout
-
-	; 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
+	call	diveloop_boot				; initialize dive mode
 
 	; startup tasks for all modes
-;	clrf	CCP1CON						; stop PWM
-;	bcf		PORTC,2						; pull PWM output to GND
-;	clrf	CCPR1L						; backlight off
 	call	TFT_boot					; initialize TFT (includes clear screen)
+	call	TFT_load_dive_color_pallet	; load dive color pallet
 	call	TFT_show_divemode_mask		; display static dive mode mask
 	call	TFT_Display_FadeIn			; dim up the display
 
-	; reload and redraw last custom view
-	movff	customview_divemode,active_customview
-	bsf		FLAG_TFT_customview_callup
-
+	; arm dive start timer
 	bcf		divetime_longer_1min		; the dive has just begun
 	btfsc	FLAG_apnoe_mode				; in apnea mode?
 	bsf		divetime_longer_1min		; YES - force dive to have lasted for longer than 1 minute already
 	btfsc	sensor_override_active		; in simulator mode?
 	bsf		divetime_longer_1min		; YES - force dive to have lasted for longer than 1 minute already
 
+	; initiate initial display outputs
 	bsf		trigger_pres_cur_changed	; flag that the pressures have changed to have all data...
 	bsf		trigger_pres_max_changed	; ... written to the display on the first output round
-
 	bsf		trigger_temp_changed		; flag that the temperature has changed to have the temperature ...
 										; ... written to the display on the first output round
-
 	bsf		new_deco_data_avail			; flag that new deco engine results are available to have the initial data ...
 										; ... written to the display on the first output round
 
-	; clear the resettable average depth
-	call	clear_resettable_average_depth
-
-;	; initial caching of new absolute and relative pressure, ISR-safe 2 byte copies
-;	SMOVII	pressure_abs,    pressure_abs_cached
-;	SMOVII	pressure_rel_cur,pressure_rel_cur_cached
-
-;	; initial transfer of absolute pressure to deco engine
-;	MOVII	pressure_abs_cached,int_I_pres_respiration
+	; initialize the resettable average depth
+	call	resettable_average_depth_init
+
+	; reload and redraw last custom view
+	movff	customview_divemode,active_customview
+	bsf		FLAG_TFT_customview_callup
 
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
 	bra		diveloop_1					; YES - done with initialization
 	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
 	bra		diveloop_1					;       YES - done with initialization
-	bsf		FLAG_TFT_display_ndl_mask	;       NO  - in deco mode then, display NDL mask
+	bsf		FLAG_TFT_display_ndl_mask	;       NO  - request initial display of NDL mask
 	bsf		FLAG_TFT_active_gas_divemode;           - request initial display of gas and setpoint
 
 diveloop_1:
 	btfsc	reset_timebase				; has the ISR confirmed reset of the timebase meanwhile?
-	bra		$-2							; NO - not yet, loop waiting for confirmation before entering the dive loop
-
+	bra		$-2							; NO  - not yet, loop waiting for confirmation before entering the dive loop
+	;bra	diveloop_loop				; YES - enter the dive loop
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode Mail Loop
+;
 diveloop_loop:
-	; ### the dive loop starts here ###
 	btfsc	trigger_full_second			; new 1/1 second?
 	bra		diveloop_loop_2				; YES - continue with tasks every 1/1 second
 	btfsc	trigger_half_second			; NO  - new 1/2 second?
@@ -343,9 +329,9 @@
 
  IFDEF _external_sensor
 	btfsc	FLAG_ccr_mode				; in CCR mode?
-	rcall	calc_deko_divemode_sensor	; YES - do sensor data acquisition if applicable
+	rcall	calc_deko_divemode_sensor	; YES - process sensor readings
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	rcall	calc_deko_divemode_sensor	; YES - do sensor data acquisition if applicable
+	rcall	calc_deko_divemode_sensor	; YES - process sensor readings
  ENDIF
 
  IFDEF _cave_mode
@@ -407,7 +393,7 @@
 	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
+	call	show_new_deco_data			; YES - set-up display update requests
 
 	btfsc	decostop_active				; in deco mode?
 	bsf		FLAG_TFT_display_deco		; YES - update deco stop depth & time every second because of depth-dependent color-coding
@@ -435,8 +421,8 @@
 
 diveloop_loop_10:
 	; common tasks every 1/1 second
-	rcall	timeout_divemode			; check for timeout condition
-	call	check_dive_modes			; test if depth still deeper than threshold
+	rcall	timeout_divemode			; check for timeout conditions
+	call	check_dive_modes_dive		; test if depth still deeper than threshold
 
 	btfsc	trigger_full_minute			; has next minute begun?
 	rcall	update_divemode60			; YES - update clock, etc.
@@ -451,18 +437,38 @@
 
 ; tasks every round, every mode
 diveloop_loop_11:
-	call	test_switches_divemode		; check switches in dive mode
-	bra		diveloop_loop_12
-
+	call	test_switches_divemode		; check switches, in case branch into menu processor
+	bra		diveloop_loop_12			; continue the dive loop
+
+
+	; **** jump-in when returning from menu processor ****
+	;
+	global	divemode_option_divemenu_return
+divemode_option_divemenu_return:
+	clrf	STKPTR						; reset the stack
+	call	menu_draw_cursor_dive		; show the cursor
+	bsf		dive_main_menu				; set main menu   is     shown now
+	clrf	active_premenu				; set pre-menu    is not shown any more
+	bcf		safety_stop_active			; set safety stop is not shown any more
+	movlw	divemode_timeout_mainmenu	; get timeout for main menu
+	call	restart_timeout_time		; restart the timeout
+	bra		diveloop_loop_12			; continue the dive loop
+
+
+	; **** jump-in when returning from dive mode menu ****
+	;
 	global	diveloop_menu_exit
-diveloop_menu_exit:						; jump-in from menu exit
-	bsf		FLAG_TFT_temperature		; restore temperature display or resettable dive time (was overwritten by menu)
+diveloop_menu_exit:
+	clrf	STKPTR						; reset the stack
+	call	divemenu_cleanup			; clean up menu area and restore dive data
+	;bra	diveloop_loop_12			; continue the dive loop
+
 
 diveloop_loop_12:
 	bsf		FLAG_TFT_active_gas_divemode; redraw gas and setpoint (eventually needed to restore the "Bailout" text)
 
 	btfsc	request_next_custview		; shall show next custom view?
-	call	dive_customview_toggle		; YES - show next custom view (and delete this flag)
+	call	dive_customview_toggle		; YES - show next custom view
 
 	btfsc	request_gas_change			; shall change gas?
 	call	gas_switch_common			; YES
@@ -471,7 +477,7 @@
 	call	gas_update_common			; YES
 
 	btfsc	request_toggle_GF			; shall toggle GF/aGF?
-	rcall	divemodemode_togglegf		; YES
+	call	divemodemode_togglegf		; YES
 
  IFDEF _cave_mode
 	btfsc	request_cave_off_turned		; shall switch cave mode off and set the dive as turned?
@@ -510,10 +516,76 @@
 	call	TFT_dump_screen_check		; YES - check if requested and do it
  ENDIF
 
-	bra		diveloop_loop				; loop in dive mode
-
-;--------------------------------------------------------------------------------------------------------
-
+	bra		diveloop_loop				; do next loop in dive mode
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode Tasks every 1/1 Minute
+;
+update_divemode60:
+	bcf		trigger_full_minute			; clear flag
+
+	call	get_battery_voltage			; get battery voltage
+	btfss	battery_low_condition		; battery low condition detected?
+	bra		update_divemode60_1			; NO  - skip next
+	movlw	d'7'						; YES - 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
+
+update_divemode60_1:
+	; 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	simulator_timeout_normal	; YES - set simulation timeout
+ IFDEF _cave_mode
+	TSTOSC	opt_cave_mode				;     - cave mode switched on?
+	movlw	simulator_timeout_cave		;       YES - replace with cave mode simulation timeout
+ ENDIF
+	cpfsgt	counted_divetime_mins+0		;     - timeout?
+	return								;       NO  - done
+ IFDEF _DEBUG
+	return								;       YES - but we do not care in debug mode...
+ ELSE
+	goto	divemode_option_sim_quit	;       YES - set depth to 0 m and return
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - set-up Display Update Requests
+;
+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_norm		; deco stops found?
+	bra		show_new_deco_data_deco		; YES - in deco
+	;bra	show_new_deco_data_ndl		; NO  - within NDL
+
+show_new_deco_data_ndl:					; within NDL
+	btfsc	decostop_active				; been in deco mode before?
+	bsf		FLAG_TFT_clear_deco_data	; YES - clear old deco data
+	btfsc	decostop_active				; been in deco mode before?
+	bsf		FLAG_TFT_display_ndl_mask	; YES - display NDL data mask
+	bcf		decostop_active				; clear flag for been in deco mode before
+	bsf		FLAG_TFT_display_ndl		; display NDL time
+	return								; done
+
+show_new_deco_data_deco:				; in deco
+	btfss	decostop_active				; been in deco mode before?
+	bsf		FLAG_TFT_clear_deco_data	; NO - clear old NDL data
+	btfss	decostop_active				; been in deco mode before?
+	bsf		FLAG_TFT_display_deco_mask	; NO - display deco data mask
+	bsf		decostop_active				; set flag for being in deco mode
+	bsf		FLAG_TFT_display_tts		; display TTS time (display of stop data is managed separately)
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - do all Phase 1 Display Outputs
+;
 TFT_output_1:								; every second - before deco calculations, all mode
 	btfsc	FLAG_TFT_clear_apnoe_surface	; shall clear apnoe mode surface data from screen?
 	call	TFT_clear_apnoe_surface			; YES - clear apnoe mode surface data from screen
@@ -537,6 +609,10 @@
 	clrf	TFT_output_flags_1				; mark all TFT updates done
 	return									; done
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - do all Phase 2 Display Outputs
+;
 TFT_output_2:								; every second - before deco calculations, deco modes only
 	btfsc	FLAG_TFT_divemode_mask			; shall re-draw mask?
 	call	TFT_show_divemode_mask			; YES - re-draw mask
@@ -549,6 +625,10 @@
 	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
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - do all Phase 3 Display Outputs
+;
 TFT_output_3:								; every second - after deco calculations, deco modes only
 	btfsc	FLAG_TFT_clear_deco_data		; shall clear deco data (NDL or stop & TTS)?
 	call	TFT_clear_deco_data				; YES - clear deco data (NDL or stop & TTS)
@@ -565,6 +645,10 @@
 	clrf	TFT_output_flags_3				; mark all TFT updates done
 	return									; done
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - do all Phase 4 Display Outputs
+;
 TFT_output_4:								; every second - after deco calculations, all modes
 	btfsc	FLAG_TFT_customview_callup		; shall show a custom view?
 	call	dive_customview_callup			; YES - show a custom view
@@ -583,8 +667,10 @@
 	clrf	TFT_output_flags_4				; mark all TFT updates done
 	return									; done
 
-;--------------------------------------------------------------------------------------------------------
-
+
+;-----------------------------------------------------------------------------
+; Apnoe Mode Tasks
+;
 divemode_apnoe_tasks:						; 1 sec. apnoe tasks
 	bsf		FLAG_TFT_apnoe_divetime			; show apnoe dive times (current/last dive and total)
 	btfsc	apnoe_at_surface				; at the surface?
@@ -606,6 +692,9 @@
 	;bra	apnoe_calc_maxdepth				; calculate overall max. depth and return
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - calculate Apnoe Mode overall maximum Depth
+;
 	global	apnoe_calc_maxdepth
 apnoe_calc_maxdepth:
 	MOVII	apnoe_max_pressure,     sub_a				; get max depth from all dives to far
@@ -616,10 +705,12 @@
 	MOVII	pressure_rel_max_cached,apnoe_max_pressure	; YES - store new overall max depth
 	return												;     - done
 
-	; --------------------------------------------------------------------------------------
-
-	; Manage and invoke the Deco Calculation Engine
-	; =============================================
+
+;-----------------------------------------------------------------------------
+; Manage and invoke the Deco Calculation Engine
+;
+callup_deco_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
@@ -631,32 +722,30 @@
 
 	; Deco Engine Calculation Schedules:
 	;
-	; Schedule	Dive Mode	Bailout	fTTS	Gas Needs	Plan	Deco Mode	Planning Modes
-	; ---------------------------------------------------------------------------------------------
+	; Schedule  Dive Mode  Bailout  fTTS   Gas Needs    Plan    Deco Mode  calculated Functions
+	; -----------------------------------------------------------------------------------------------------
 	;
-	; 1a)		OC			no		 no		(yes)		norm	OC						(gas needs)
-	;													alt		--			--
+	;   1a)        OC       no       no      (yes)      norm       OC      TTS, CNS, deco plan, (gas needs)
+	;                                                no alt plan
 	;
-	; 1b)		OC			no		 YES	(yes)		norm	OC			--
-	;													alt		OC			fTTS,		(gas needs)
+	;   1b)        OC       no       YES     (yes)      norm       OC      TTS,  CNS, deco plan
+	;                                                   alt        OC      fTTS, fCNS, (gas needs)
 	;
-	; 2a)		Loop		no		 no		 no			norm	Loop		--
-	;													alt		--			--
+	;   2a)       Loop      no       no       no        norm      Loop     TTS,  CNS, deco plan
+	;                                                no alt plan
 	;
-	; 2b)		Loop		no		 yes	 no			norm	Loop		--
-	;													alt		Loop		fTTS
+	;   2b)       Loop      no       yes      no        norm      Loop     TTS,  CNS, deco plan
+	;                                                   alt       Loop     fTTS, fCNS
 	;
-	; 2c)		Loop		no		(yes)	 YES		norm	Loop		--
-	;													alt		OC			gas needs,	(fTTS*)
+	;   2c)       Loop      no      (yes)     YES       norm      Loop     TTS,  CNS, deco plan
+	;                                                   alt        OC      fTTS*, fCNS*, gas needs      <- "what if" BAILOUT
 	;
-	; 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:
+	;   3)        Loop      YES      n/a     (yes)      norm       OC      TTS, deco plan, (gas needs)  <-   real    BAILOUT
+	;                                                no alt plan
+	; _____________________________________________________________________________________________________
+	; norm: normal plan, alt: alternative plan, (): optional, n/a: not applicable
+	; * the fTTS time is set to zero when in cave mode and the dive is in turned state
+
 
 	; 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
@@ -676,8 +765,9 @@
 	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:
 	bcf		lo,DECO_COMPLETED_ALT		; clear completion flag from alternative plan
  IFDEF _ccr_pscr
@@ -749,8 +839,9 @@
 	bsf		lo,DECO_START_NORM			; calculate a normal plan
 	bra		calc_deco_engine_start		; start deco engine
 
+
 	; ---- alternative plans ----
-
+	;
 calc_deco_engine_alt:
 	bcf		lo,DECO_COMPLETED_NORM		; clear completion flag from normal plan
  IFDEF _ccr_pscr
@@ -822,8 +913,9 @@
 	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
@@ -839,8 +931,10 @@
 
 calc_deco_engine_exec:
 ;	+++++++++++++++++++++++++++++++++++++
+	bsf		tmr5_preemtion_allowed		; grant  preemption allowance for timer 5 (deco engine)
 	call	deco_calc_hauptroutine		; invoke the deco engine (C-code)
 	banksel	common						; back to bank common
+	bcf		tmr5_preemtion_allowed		; revoke preemption allowance
 ;	+++++++++++++++++++++++++++++++++++++
 
  ifdef _debug_output
@@ -852,68 +946,48 @@
 	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
 
-	; 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_norm		; deco stops found?
-	bra		show_new_deco_data_deco		; YES - in deco
-	;bra	show_new_deco_data_ndl		; NO  - within NDL
-
-show_new_deco_data_ndl:					; within NDL
-	btfsc	decostop_active				; been in deco mode before?
-	bsf		FLAG_TFT_clear_deco_data	; YES - clear old deco data
-	btfsc	decostop_active				; been in deco mode before?
-	bsf		FLAG_TFT_display_ndl_mask	; YES - display NDL data mask
-	bcf		decostop_active				; clear flag for been in deco mode before
-	bsf		FLAG_TFT_display_ndl		; display NDL time
-	return
-
-show_new_deco_data_deco:				; in deco
-	btfss	decostop_active				; been in deco mode before?
-	bsf		FLAG_TFT_clear_deco_data	; NO - clear old deco data
-	btfss	decostop_active				; been in deco mode before?
-	bsf		FLAG_TFT_display_deco_mask	; NO - display deco data mask
-	bsf		decostop_active				; set flag for being in deco mode
-	bsf		FLAG_TFT_display_tts		; display TTS time (display or stop data is managed somewhere else)
-	return
-
-;=============================================================================
+	return								; done
+
 
  IFDEF _ccr_pscr
  IFDEF _external_sensor
 
+;-----------------------------------------------------------------------------
+; Process Sensor Readings
+;
 	global	calc_deko_divemode_sensor
 calc_deko_divemode_sensor:
-	; sensor acquisition code
-	btfss	s8_digital_avail				 ; do we have a digital S8 interface?
-	bra		calc_deko_divemode_sensor_analog ; NO  - check if we have an analog interface
-	btfss	trigger_S8_data_update			 ; YES - check if a new data frame was received
-	bra		calc_deko_divemode_sensor_common ;       NO  - use old values
-	bcf		trigger_S8_data_update			 ;       YES - clear update flag
-	call	compute_mvolts_for_all_sensors	 ;           - compute mV values from digital data
-	bra		calc_deko_divemode_sensor_common
-calc_deko_divemode_sensor_analog:
-	btfss	analog_o2_input					; do we have an analog input?
-	bra		calc_deko_divemode_sensor_opt	; NO  - check if we have an optical interface
-	call	get_analog_inputs				; YES - get the analog voltages and continue with the common part
-	bra		calc_deko_divemode_sensor_common
+	btfsc	ext_input_optical				; do we have an optical interface?
+	bra		calc_deko_divemode_sensor_opt	; YES - process received data
+	btfss	ext_input_s8_ana				; NO  - do we have a S8/analog interface?
+	return									;       NO  - nothing to do, done
+	TSTOSS	opt_s8_mode						;       YES - shall use S8 interface?
+	bra		calc_deko_divemode_sensor_ana	;           - NO  - use analog interface
+	;bra	calc_deko_divemode_sensor_s8	;             YES - use S8     interface
+
+calc_deko_divemode_sensor_s8:
+	btfss	trigger_S8_data_update			; new data frame available?
+	bra		calc_deko_divemode_sensor_common; NO  - use old values
+	bcf		trigger_S8_data_update			; YES - clear update flag
+	call	compute_mvolts_from_rawdata	;     - compute mV values from digital data
+	bra		calc_deko_divemode_sensor_common;     - continue with common part
+
 calc_deko_divemode_sensor_opt:
-	btfss	optical_input					; do we have an optical input?
-	return									; NO  - return (we have no sensors at all: not analog, not S8 and not optical)
-	btfss	sensor1_active					; YES - sensor1_ppO2, sensor2_ppO2 and sensor3_ppO2 are already filled in ISR
-	bcf		use_O2_sensor1					;       check HUD status data and eventually clear use_O2_sensorX
-	btfss	sensor2_active
-	bcf		use_O2_sensor2
-	btfss	sensor3_active
-	bcf		use_O2_sensor3
-	bra		calc_deko_divemode_sensor_A		; continue with calculating sensor average
+	; sensor1_ppO2, sensor2_ppO2 and sensor3_ppO2 are already filled in ISR
+	btfss	sensor1_active					; check HUD status data and eventually clear use_O2_sensorX
+	bcf		use_O2_sensor1					; ...
+	btfss	sensor2_active					; ...
+	bcf		use_O2_sensor2					; ...
+	btfss	sensor3_active					; ...
+	bcf		use_O2_sensor3					; ...
+	bra		check_sensor_avg				; continue with calculating sensor average
+
+calc_deko_divemode_sensor_ana:
+	call	get_analog_inputs				; get the analog voltages and continue with the common part
+	;bra	calc_deko_divemode_sensor_common; continue with common part
 
 calc_deko_divemode_sensor_common:
+
 	; Check each sensor if it is calibrated and if its mV value is within min_mv and max_mv limits.
 	; If     ok: compute o2_ppo2_sensorX = o2_mv_sensorX * opt_x_sX / 1000
 	; If not ok: reset   o2_ppo2_sensorX, reset use_O2_sensorX and show the customview 1 in case the sensor was ok before
@@ -921,181 +995,205 @@
 	; check sensor 1
 	btfss	sensor1_calibrated_ok		; check if sensor is usable at all
 	bra		check_sensor_1_fail			; NO  - handle it as failed
+	SMOVII	sensor1_mv,sub_a			; YES - load sensor mV value
+
 	; check min threshold
-	SMOVII	sensor1_mv,sub_a			; load sensor mV value
-	rcall	check_min_threshold
+	rcall	check_min_threshold			; check if sensor mV is outside minimum
 	btfsc	neg_flag					; check if result is negative, i.e. sensor_mv < min_mv
 	bra		check_sensor_1_fail			; YES - declare sensor as failed
+
 	; check max_threshold
-	rcall	check_max_threshold
+	rcall	check_max_threshold			; check if sensor mV is outside maximum
 	btfss	neg_flag					; check if result is negative, i.e. sensor_mv < max_mv
 	bra		check_sensor_1_fail			; NO  - declare sensor as failed
+
 	; check HUD data, if available
 	btfss	hud_connection_ok			; check if there is a HUD connected
 	bra		check_sensor_1_ok			; NO  - all checks done then and positive
 	btfss	sensor1_active				; YES - HUD status ok?
 	bra		check_sensor_1_fail			;       NO - HUD reports a fail
+
 check_sensor_1_ok:
 	; sensor1_ppO2 = sensor1_mv:2 * opt_x_s1:2 / 1000
-	SMOVII	sensor1_mv,xA
-	MOVII	opt_x_s1,  xB
-	rcall	compute_ppo2_helper
+	SMOVII	sensor1_mv,xA				; get sensor mV          into xA
+	MOVII	opt_x_s1,  xB				; get calibration factor into xB
+	rcall	compute_ppo2_helper			; compute ppO2
 	movff	xC+0,sensor1_ppO2			; result in 0.01 bar
+	bcf		attn_det_sensor1_lost		; clear attention
+	bcf		shown_sensor1_fail			; re-arm custom-view show-up
 	bra		check_sensor_2				; continue with next sensor
+
 check_sensor_1_fail:
-	clrf	WREG
-	movff	WREG,sensor1_ppO2			; set ppO2 reading to zero
-	btfss	use_O2_sensor1				; check if sensor was in use before
-	bra		check_sensor_1_fail_1		; NO  - no new news then
-	call	check_sensor_custview_helper; YES - show sensors custom view on further conditions met
-check_sensor_1_fail_1:
+	clrf	WREG						; set ppO2 reading to zero
+	movff	WREG,sensor1_ppO2			; ...
+	btfsc	use_O2_sensor1				; check if sensor is in use
+	bsf		attn_det_sensor1_lost		; YES - set an attention
 	bcf		use_O2_sensor1				; revoke sensor from usage
 
-check_sensor_2:							; check min_mv of sensor 2
+check_sensor_2:
+	; check sensor 2
 	btfss	sensor2_calibrated_ok		; check if sensor is usable at all
 	bra		check_sensor_2_fail			; NO  - handle it as failed
+	SMOVII	sensor2_mv,sub_a			; YES - load sensor mV value
+
 	; check min threshold
-	SMOVII	sensor2_mv,sub_a			; load sensor mV value
-	rcall	check_min_threshold
+	rcall	check_min_threshold			; check if sensor mV is outside minimum
 	btfsc	neg_flag					; check if result is negative, i.e. sensor_mv < min_mv
 	bra		check_sensor_2_fail			; YES - declare sensor as failed
+
 	; check max_threshold
-	rcall	check_max_threshold
+	rcall	check_max_threshold			; check if sensor mV is outside maximum
 	btfss	neg_flag					; check if result is nagative, i.e. sensor_mv < max_mv
 	bra		check_sensor_2_fail			; NO  - declare sensor as failed
+
 	; check HUD data, if available
 	btfss	hud_connection_ok			; check if there is a HUD connected
 	bra		check_sensor_2_ok			; NO  - all checks done then and positive
 	btfss	sensor2_active				; YES - HUD status ok?
 	bra		check_sensor_2_fail			;       NO - HUD reports a fail
+
 check_sensor_2_ok:
 	; sensor2_ppO2 = sensor2_mv:2 * opt_x_s2:2 / 1000
-	SMOVII	sensor2_mv,xA
-	MOVII	opt_x_s2,  xB
-	rcall	compute_ppo2_helper
+	SMOVII	sensor2_mv,xA				; get sensor mV          into xA
+	MOVII	opt_x_s2,  xB				; get calibration factor into xB
+	rcall	compute_ppo2_helper			; compute ppO2
 	movff	xC+0,sensor2_ppO2			; result in 0.01 bar
+	bcf		attn_det_sensor2_lost		; clear attention
+	bcf		shown_sensor2_fail			; re-arm custom-view show-up
 	bra		check_sensor_3				; continue with next sensor
+
 check_sensor_2_fail:
-	clrf	WREG
-	movff	WREG,sensor2_ppO2			; set ppO2 reading to zero
-	btfss	use_O2_sensor2				; check if sensor was in use before
-	bra		check_sensor_2_fail_1		; NO  - no new news then
-	call	check_sensor_custview_helper; YES - show sensors custom view on further conditions met
-check_sensor_2_fail_1:
+	clrf	WREG						; set ppO2 reading to zero
+	movff	WREG,sensor2_ppO2			; ...
+	btfsc	use_O2_sensor2				; check if sensor is in use
+	bsf		attn_det_sensor2_lost		; YES - set an attention
 	bcf		use_O2_sensor2				; revoke sensor from usage
 
-check_sensor_3:							; check min_mv of sensor 2
+check_sensor_3:
+	; check sensor 3
 	btfss	sensor3_calibrated_ok		; check if sensor is usable at all
 	bra		check_sensor_3_fail			; NO  - handle it as failed
+	SMOVII	sensor3_mv,sub_a			; YES - load sensor mV value
+
 	; check min threshold
-	SMOVII	sensor3_mv,sub_a			; load sensor mV value
-	rcall	check_min_threshold
+	rcall	check_min_threshold			; check if sensor mV is outside minimum
 	btfsc	neg_flag					; check if result is negative, i.e. sensor_mv < min_mv
 	bra		check_sensor_3_fail			; YES - declare sensor as failed
+
 	; check max threshold
-	rcall	check_max_threshold
+	rcall	check_max_threshold			; check if sensor mV is outside maximum
 	btfss	neg_flag					; check if result is negative, i.e. sensor_mv < max_mv
 	bra		check_sensor_3_fail			; NO  - declare sensor as failed
+
 	; check HUD data, if available
 	btfss	hud_connection_ok			; check if there is a HUD connected
 	bra		check_sensor_3_ok			; NO  - all checks done then and positive
 	btfss	sensor3_active				; YES - HUD status ok?
 	bra		check_sensor_3_fail			;       NO - HUD reports a fail
+
 check_sensor_3_ok:
 	; sensor3_ppO2 = sensor3_mv:2 * opt_x_s1:2 / 1000
-	SMOVII	sensor3_mv,xA
-	MOVII	opt_x_s3,  xB
-	rcall	compute_ppo2_helper
+	SMOVII	sensor3_mv,xA				; get sensor mV          into xA
+	MOVII	opt_x_s3,  xB				; get calibration factor into xB
+	rcall	compute_ppo2_helper			; compute ppO2
 	movff	xC+0,sensor3_ppO2			; result in 0.01 bar
-	bra		calc_deko_divemode_sensor_A	; continue with calculating sensor average
+	bcf		attn_det_sensor3_lost		; clear attention
+	bcf		shown_sensor3_fail			; re-arm custom-view show-up
+	bra		check_sensor_avg			; continue with calculating sensor average
+
 check_sensor_3_fail:
-	clrf	WREG
-	movff	WREG,sensor3_ppO2			; set ppO2 reading to zero
-	btfss	use_O2_sensor3				; check if sensor was in use before
-	bra		check_sensor_3_fail_1		; NO  - no new news then
-	call	check_sensor_custview_helper; YES - show sensors custom view on further conditions met
-check_sensor_3_fail_1:
+	clrf	WREG						; set ppO2 reading to zero
+	movff	WREG,sensor3_ppO2			; ...
+	btfsc	use_O2_sensor3				; check if sensor is in use
+	bsf		attn_det_sensor3_lost		; YES - set an attention
 	bcf		use_O2_sensor3				; revoke sensor from usage
 
-calc_deko_divemode_sensor_A:			; calculate sensor average
+check_sensor_avg:
+	; calculate sensor average
 	btfss	divemode					; in dive mode?
 	return								; NO - done here if not in dive mode
 
-	; compute sensor_setpoint = average of all o2_ppo2_sensorX of those sensors that have use_O2_sensorX == true
-	; sum up sensor values (in xA:2) and active sensors in (xB:2)
-	CLRI	xA
-	CLRI	xB
-divemode_setup_sensor_1_value:
-	btfss	use_O2_sensor1					; sensor 1 active?
-	bra		divemode_setup_sensor_2_value	; NO
-	movff	sensor1_ppO2,WREG
-	addwf	xA+0,F
-	movlw	.0
-	addwfc	xA+1,F							; add into xA:2
-	incf	xB+0,F							; add a sensor
-divemode_setup_sensor_2_value:
-	btfss	use_O2_sensor2					; sensor 2 active?
-	bra		divemode_setup_sensor_3_value	; NO
-	movff	sensor2_ppO2,WREG
-	addwf	xA+0,F
-	movlw	.0
-	addwfc	xA+1,F							; add into xA:2
-	incf	xB+0,F							; add a sensor
-divemode_setup_sensor_3_value:
-	btfss	use_O2_sensor3					; sensor 3 active?
-	bra		divemode_setup_sensor_mean		; NO
-	movff	sensor3_ppO2,WREG
-	addwf	xA+0,F
-	movlw	.0
-	addwfc	xA+1,F							; add into xA:2
-	incf	xB+0,F							; add a sensor
-
+	; compute sensor_setpoint = average of all o2_ppo2_sensorX of
+	; those sensors that have use_O2_sensorX == true
+
+	CLRI	xA							; clear sum of sensor values
+	CLRI	xB							; clear number of active sensors found
+
+check_sensor_avg_1:
+	btfss	use_O2_sensor1				; sensor 1 active?
+	bra		check_sensor_avg_2			; NO
+	movff	sensor1_ppO2,WREG			; YES - get ppO2
+	addwf	xA+0,F						;     - add into xA:2
+	movlw	.0							;     - ...
+	addwfc	xA+1,F						;     - ... 
+	incf	xB+0,F						;     - add a sensor
+
+check_sensor_avg_2:
+	btfss	use_O2_sensor2				; sensor 2 active?
+	bra		check_sensor_avg_3			; NO
+	movff	sensor2_ppO2,WREG			; YES - get ppO2
+	addwf	xA+0,F						;     - add into xA:2
+	movlw	.0							;     - ...
+	addwfc	xA+1,F						;     - ...
+	incf	xB+0,F						;     - add a sensor
+
+check_sensor_avg_3:
+	btfss	use_O2_sensor3				; sensor 3 active?
+	bra		check_sensor_avg_compute	; NO
+	movff	sensor3_ppO2,WREG			; YES - get ppO2
+	addwf	xA+0,F						;     - add into xA:2
+	movlw	.0							;     - ...
+	addwfc	xA+1,F						;     - ...
+	incf	xB+0,F						;      add a sensor
+
+check_sensor_avg_compute:
 	; divide sum of sensor values by number of active sensors found
-divemode_setup_sensor_mean:
-	clrf	xC+0							; set zero as default result
-	tstfsz	xB+0							; pending div/0 ?
-	call	div16x16						; NO - execute xC = xA / xB = summed ppO2 / number of sensors
-	movff	xC+0,sensor_setpoint			; copy result (or its default)
+	clrf	xC+0						; set zero as default result
+	tstfsz	xB+0						; pending div/0 ?
+	call	div16x16					; NO - execute xC = xA / xB = summed ppO2 / number of sensors
+	movff	xC+0,sensor_setpoint		; copy result (or its default)
 
 	; set default value for pSCR mode: 0 => let p2_deco.c compute the ppO2 based on current dil gas and depth
 	; will be overwritten later in case we are in sensor mode and have at least one usable sensor
-	clrf	WREG								; pre-load a zero
-	btfsc	FLAG_pscr_mode						; check if we are in pSCR mode
-	movff	WREG,char_I_const_ppO2				; YES - write 0 to char_I_const_ppo2,
-												;       it will be overwritten if we have a usable sensor reading
-	btfsc	bailout_mode						; check if we are in bailout
-	bra		calc_deko_divemode_sensor_V			; YES - no sensor data transfer to char_I_const_ppO2 in this case
-	movff	opt_ccr_mode,WREG					; NO  - get mode (0: Fixed SP, 1: Sensor, 2: Auto SP)
-	sublw	.1									;     - in sensor mode?
-	bnz		calc_deko_divemode_sensor_V			;       NO  - not in sensor mode - no transfer of sensor data to char_I_const_ppO2
-	tstfsz	xB+0								;       YES - check if we have found at least one usable sensor
-	bra		divemode_setup_sensor_mean1			;             YES - we have at least one usable sensor
-	bsf		sp_fallback							;             NO  - we have NO usable sensors -> initiate fallback
-	btfss	FLAG_ccr_mode						;                 - check if we are in CCR mode
-	bra		calc_deko_divemode_sensor_V			;                   NO  - continue with voting logic flags
-	movff	opt_setpoint_cbar+0,char_I_const_ppO2 ;                 YES - select fixed setpoint no. 1 for fallback
-	bra		calc_deko_divemode_sensor_V			;                       - continue with voting logic flags
+	clrf	WREG						; pre-load a zero
+	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
+	movff	WREG,char_I_const_ppO2		; YES - write 0 to char_I_const_ppo2,
+										;       it will be overwritten if we have a usable sensor reading
+	btfsc	bailout_mode				; check if we are in bailout
+	bra		check_sensor_vote			; YES - no sensor data transfer to char_I_const_ppO2 in this case
+	movff	opt_ccr_mode,WREG			; NO  - get mode (0: Fixed SP, 1: Sensor, 2: Auto SP)
+	sublw	.1							;     - in sensor mode?
+	bnz		check_sensor_vote			;       NO  - not in sensor mode - no transfer of sensor data to char_I_const_ppO2
+	tstfsz	xB+0						;       YES - check if we have found at least one usable sensor
+	bra		check_sensor_avg_use		;             YES - we have at least one usable sensor
+	bsf		warn_det_sensors_lost		;             NO  - we have NO usable sensors
+	btfsc	FLAG_ccr_mode				;                 - check if we are in CCR mode
+	movff	opt_setpoint_cbar+0,char_I_const_ppO2 ;         YES - select fixed setpoint no. 1 for fallback
+	bra		check_sensor_vote			;                       - continue with voting logic flags
+
+check_sensor_avg_use:
 	; we have at least one usable sensor with a ppO2 value > 0
-divemode_setup_sensor_mean1:
-	bcf		sp_fallback							; clear fallback condition
+	bcf		warn_det_sensors_lost				; clear warning
+	bcf		shown_sensors_lost					; re-arm custom view show-up
 	movff	sensor_setpoint,char_I_const_ppO2	; transfer average sensor value to p2_deco.c code
-	; vote sensors
-calc_deko_divemode_sensor_V:
-	bsf		voting_logic_sensor1
-	movff	sensor1_ppO2,lo
-	rcall	check_sensor_voting_helper
+
+check_sensor_vote:
+	; check if individual sensors agree with their average
+	bsf		voting_logic_sensor1		; default sensor to be within voting
+	movff	sensor1_ppO2,WREG			; get sensor's ppO2
+	rcall	check_sensor_voting_helper	; check if sensor is within +/- range around setpoint
 	tstfsz	WREG						; sensor within range (WREG = 0)?
 	bcf		voting_logic_sensor1		; NO - vote out this sensor
 
-	bsf		voting_logic_sensor2
-	movff	sensor2_ppO2,lo
-	rcall	check_sensor_voting_helper
+	bsf		voting_logic_sensor2		; default sensor to be within voting
+	movff	sensor2_ppO2,WREG			; get sensor's ppO2
+	rcall	check_sensor_voting_helper	; check if sensor is within +/- range around setpoint
 	tstfsz	WREG						; sensor within range (WREG = 0)?
 	bcf		voting_logic_sensor2		; NO - vote out this sensor
 
-	bsf		voting_logic_sensor3
-	movff	sensor3_ppO2,lo
-	rcall	check_sensor_voting_helper
+	bsf		voting_logic_sensor3		; default sensor to be within voting
+	movff	sensor3_ppO2,WREG			; get sensor's ppO2
+	rcall	check_sensor_voting_helper	; check if sensor is within +/- range around setpoint
 	tstfsz	WREG						; sensor within range (WREG = 0)?
 	bcf		voting_logic_sensor3		; NO - vote out this sensor
 
@@ -1105,13 +1203,14 @@
 	btfsc	FLAG_pscr_mode				; check if we are in pSCR mode
 	bra		check_warn_sensor_0			; YES - continue with further checks
 	bra		check_warn_sensor_done		; not in CCR and not in pSCR, so no warning
+
 check_warn_sensor_0:					; we are in CCR or pSCR mode
 	btfsc	bailout_mode				; check if we are in bailout
 	bra		check_warn_sensor_done		; YES - no warning in this case
 	movff	opt_ccr_mode,WREG			; get mode (0: Fixed SP, 1: Sensor, 2: Auto SP)
 	sublw	.1							; in sensor mode?
 	bnz		check_warn_sensor_done		; NO - not in sensor mode - no warning in this case
-	; check sensor 1
+
 check_warn_sensor_1:
 	btfss	sensor1_calibrated_ok		; check if sensor has a valid calibration
 	bra		check_warn_sensor_2			; NO  - sensor can not cause a warning then
@@ -1119,9 +1218,9 @@
 	bra		check_warn_sensor_2			;       NO  - sensor can not cause a warning then
 	btfsc	voting_logic_sensor1		;       YES - check if sensor value is within agreement range
 	bra		check_warn_sensor_2			;             YES - continue with next sensor
-	bcf		o2_sensors_agree			;             NO  - issue a warning
-	return
-	; check sensor 2
+	bsf		warn_det_sensors_div		;             NO  - sensors divergence
+	return								;                 - done
+
 check_warn_sensor_2:
 	btfss	sensor2_calibrated_ok		; check if sensor has a valid calibration
 	bra		check_warn_sensor_3			; NO  - sensor can not cause a warning then
@@ -1129,9 +1228,9 @@
 	bra		check_warn_sensor_3			;       NO  - sensor can not cause a warning then
 	btfsc	voting_logic_sensor2		;       YES - check if sensor value is within agreement range
 	bra		check_warn_sensor_3			;             YES - continue with next sensor
-	bcf		o2_sensors_agree			;             NO  - issue a warning
-	return
-	; check sensor 3
+	bsf		warn_det_sensors_div		;             NO  - sensors divergence
+	return								;                 - done
+
 check_warn_sensor_3:
 	btfss	sensor3_calibrated_ok		; check if sensor has a valid calibration
 	bra		check_warn_sensor_agree		; NO  - sensor can not cause a warning then
@@ -1139,85 +1238,104 @@
 	bra		check_warn_sensor_agree		;       NO  - sensor can not cause a warning then
 	btfsc	voting_logic_sensor3		;       YES - check if sensor value is within agreement range
 	bra		check_warn_sensor_agree		;             YES - continue with next sensor
-	bcf		o2_sensors_agree			;             NO  - issue a warning
-	return
-	; no need for a warning
+	bsf		warn_det_sensors_div		;             NO  - set warning
+	return								;                 - done
+
 check_warn_sensor_done:
 check_warn_sensor_agree:
-	bsf		o2_sensors_agree
-	return
-
+	bcf		warn_det_sensors_div		; clear warning
+	bcf		shown_sensors_diverg		; re-arm custom view show-up
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - check if sensor mV is outside minimum
+;
 check_min_threshold:
 	MOVLI	min_mv,sub_b				; load minimum mV value
 	goto	sub16						; sub_c = sensor_mv - min_mv (and return)
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - check if sensor mV is outside maximum
+;
 check_max_threshold:
 	MOVLI	max_mv,sub_b				; load maximum mV value
 	goto	sub16						; sub_c = sensor_mv - max_mv (and return)
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - compute ppO2 from sensor mV and calibration factor
+;
 compute_ppo2_helper:
 	call	mult16x16					; xC:4 = xA:2 * xB:2
-	MOVLI	.1000,xB
+	MOVLI	.1000,xB					; load scaling factor
 	call	div32x16					; xC:4 = xC:4 / xB:2 with xA as remainder
 	tstfsz	xC+1						; is the ppO2 higher than 2.55 bar?
 	setf	xC+0						; YES - set result to 255 aka 2.55 bar
-	return
-
-check_sensor_custview_helper:
-	btfss	divemode					; check if we are in dive mode
-	return								; NO  - not in dive mode, return
-	movff	opt_ccr_mode,WREG			; YES - =0: Fixed SP, =1: Sensor, =2: Auto SP
-	decfsz	WREG,W						;     - opt_ccr_mode = 1 (sensors)?
-	return								;       NO  - not using the sensors in the moment
-show_sensors_custview:
-	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
-
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - check if sensor is within +/- range around setpoint
+;
 check_sensor_voting_helper:
-	movf	lo,W
-	cpfsgt	sensor_setpoint
-	bra		check_sensor_voting_helper2		; lo < sensor_setpoint
-	; lo > sensor_setpoint
-	movf	lo,W
-	subwf	sensor_setpoint,W
-	movwf	lo
-check_sensor_voting_helper1:
-	movlw	sensor_voting_logic_threshold	; threshold in 0.01 bar
-	cpfsgt	lo
-	retlw	.0								; within range
-	retlw	.1								; out of range
-check_sensor_voting_helper2:
-	; lo < sensor_setpoint
-	movf	sensor_setpoint,W
-	subwf	lo,F
-	bra		check_sensor_voting_helper1
+	subwf	sensor_setpoint,W				; deviation = setpoint - sensor ppO2
+	btfsc	STATUS,N						; result negative?
+	negf	WREG,W							; YES - negate deviation
+	sublw	sensor_voting_logic_threshold	; WREG = threshold - deviation
+	btfss	STATUS,N						; result negative?
+	retlw	.0								; NO  - within range
+	retlw	.1								; YES - out of range
+
+;	cpfsgt	sensor_setpoint					; sensor ppO2 > setpoint?
+;	bra		check_sensor_voting_helper_2	; NO
+;	;bra	check_sensor_voting_helper_1	; YES
+;
+;check_sensor_voting_helper_1:
+;	subwf	sensor_setpoint,W				; WREG = setpoint - sensor ppO2
+;	bra		check_sensor_voting_helper_com	; continue with common part
+;
+;check_sensor_voting_helper_2:
+;	movwf	lo								; copy sensor ppO2 to lo
+;	movf	sensor_setpoint,W				; copy setpoint    to WREG
+;	subwf	lo,W							; WREG = sensor ppO2 - setpoint
+;	;bra	check_sensor_voting_helper_com	; continue with common part
+;
+;check_sensor_voting_helper_com:
+;	movwf	lo								; copy deviation to lo
+;	movlw	sensor_voting_logic_threshold	; load threshold in 0.01 bar
+;	cpfsgt	lo								; deviation > threshold ?
+;	retlw	.0								; NO  - within range
+;	retlw	.1								; YES - out of range
 
  ENDIF	; _external_sensor
  ENDIF	; _ccr_pscr
 
-;=============================================================================
-
-divemodemode_togglegf:
-	bcf		request_toggle_GF			; clear request flag
-	goto	restart_deco_engine			; restart the deco engine and return
-
-;=============================================================================
 
  IFDEF _cave_mode
 
+;-----------------------------------------------------------------------------
+; Cave Mode - on/off Switching
+;
 cavemode_toggle_onoff:
 	bcf		request_cave_toggle			; clear request flag
 	btg		cave_mode					; toggle the on/off state
 	return								; done
 
+
+;-----------------------------------------------------------------------------
+; Cave Mode - switch off and set Dive as turned
+;
 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)
 
 
+;-----------------------------------------------------------------------------
+; Cave Mode - check if 'turn dive' is allowed
+;
 	global	cavemode_turndive_check
 cavemode_turndive_check:
 	btfss	cave_mode					; cave mode switched on?
@@ -1229,6 +1347,10 @@
 	retlw	1							;             NO  - signal not allowed
 	retlw	0							;             YES - command is allowed
 
+
+;-----------------------------------------------------------------------------
+; Cave Mode - execute 'turn dive' toggle
+;
 cavemode_turndive_toggle:
 	bcf		request_turn_toggle			; clear request flag
 	rcall	cavemode_turndive_check		; check if command is allowed
@@ -1236,28 +1358,30 @@
 	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
-
+	bcf		dive_turned					;       YES - 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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - set the dive as turned
+;
 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)
-
-
+	bsf		dive_turned					;       NO  - set dive as turned
+	call	set_logbook_marker			;           - set a logbook marker
+	goto	write_backtrack_turnpoint	;           - write a turn-point waypoint and return
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - check if setting a Waypoint is allowed
+;
 	global	cavemode_waypoint_set_check
 cavemode_waypoint_set_check:
 	btfss	cave_mode					; cave mode switched on?
@@ -1271,6 +1395,10 @@
 	retlw	1							;                   NO  - command not allowed
 	retlw	0							;                   YES - command is  allowed
 
+
+;-----------------------------------------------------------------------------
+; Cave Mode - set a Waypoint
+;
 cavemode_waypoint_set:
 	bcf		request_waypoint_set		; clear request flag
 	rcall	cavemode_waypoint_set_check	; check if command is allowed to execute
@@ -1280,6 +1408,9 @@
 	goto	write_backtrack_waypoint	;     - execute command (and return)
 
 
+;-----------------------------------------------------------------------------
+; Cave Mode - check if stepping one Waypoint outwards is allowed
+;
 	global	cavemode_waypoint_out_check
 cavemode_waypoint_out_check:
 	btfss	cave_mode					; cave mode switched on?
@@ -1290,6 +1421,10 @@
 	retlw	1							;             YES - command not allowed
 	retlw	0							;             NO  - command is  allowed
 
+
+;-----------------------------------------------------------------------------
+; Cave Mode - step one Waypoint outwards
+;
 cavemode_waypoint_out:
 	bcf		request_waypoint_out		; clear request flag
 	rcall	cavemode_waypoint_out_check	; check if command is allowed to execute
@@ -1298,6 +1433,9 @@
 	goto	backtrack_waypoint_go_out	; YES - execute the command (and return)
 
 
+;-----------------------------------------------------------------------------
+; Cave Mode - check if stepping one Waypoint inwards is allowed
+;
 	global	cavemode_waypoint_in_check
 cavemode_waypoint_in_check:
 	btfss	cave_mode					; cave mode switched on?
@@ -1308,6 +1446,10 @@
 	retlw	1							;             YES - command not allowed
 	retlw	0							;             NO  - command is  allowed
 
+
+;-----------------------------------------------------------------------------
+; Cave Mode - step one Waypoint inwards
+;
 cavemode_waypoint_in:
 	bcf		request_waypoint_in			; clear request flag
 	rcall	cavemode_waypoint_in_check	; check if command is allowed to execute
@@ -1315,10 +1457,199 @@
 	return								; NO  - no further in possible, abort
 	goto	backtrack_waypoint_go_in	; YES - execute command (and return)
 
- ENDIF
-
-;=============================================================================
-
+
+;-----------------------------------------------------------------------------
+; Cave Mode - store current Delta Time
+;
+write_backtrack_deltatime:
+	rcall	setup_backtrack_index				; setup writing position
+	bra		write_backtrack_datum_deltatime		; store the current delta time (and return)
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - store a Backtracking Depth Data Set
+;
+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)
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - store a Waypoint
+;
+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)
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - store a Turn Point
+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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - append further Logging after current Waypoint
+;
+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)
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - execute stepping one Waypoint outwards
+;
+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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode - execute stepping one Waypoint inwards
+;
+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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode Helper Function - set up Index Position
+;
+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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode Helper Function - reset Time since last Depth Recording and store it
+;
+write_backtrack_datum_zerotime:
+	clrf	backtrack_deltatime					; reset the time elapsed since last depth recording
+	;bra	write_backtrack_datum_deltatime		; store the time
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode Helper Function - store 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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode Helper Function - store Depth
+;
+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 (protect time marker bit)
+	movwf	POSTINC1							; write the depth entry and increment the writing position index
+	return										; done
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode Helper Function - store Gas Availability Vector
+;
+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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode Helper Function - store a Waypoint Number
+;
+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
+
+
+;-----------------------------------------------------------------------------
+; Cave Mode Helper Function - store new writing position and check remaining storage capacity
+;
+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
+
+
+;-----------------------------------------------------------------------------
+; Calculate vertical Velocity
+;
 calc_velocity:							; called every two seconds
 	btfsc	velocity_active_num			; was velocity shown in last cycle?
 	bra		calc_velocity_1				; YES - always update if shown before
@@ -1362,8 +1693,9 @@
 	return								; done
 
 
-;=============================================================================
-
+;-----------------------------------------------------------------------------
+; Check and Memorize if Dive went into Deco & Deco Region
+;
 check_deco_states:
 	btfsc	deco_region					; been within the deco stops region before?
 	return								; YES - been in deco then before too, done
@@ -1378,8 +1710,10 @@
 	bsf		deco_region					;             YES - memorize to have entered the deco stops region
 	return								;           - done
 
-;=============================================================================
-
+
+;-----------------------------------------------------------------------------
+; Exercise Safety Stop Control
+;
 safety_stop_control:
 	TSTOSS	opt_safetystop				; safety stop enabled? (=1: show safety stop)
 	return								; NO  - done
@@ -1402,21 +1736,25 @@
 	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:
+	btfsc	neg_flag					; below threshold depth?
+	bra		safety_stop_control_chk		; NO  - check if above end threshold
+	;bra	safety_stop_reset			; YES - reset safety stop
+
+safety_stop_reset:
+	movff	opt_safety_stop_length,safety_stop_countdown	; rearm safety stop (load timer)
+	incf	safety_stop_countdown,F							; +1 because safety_stop_show decrements first
+	bsf		FLAG_TFT_safety_stop_clear						; request to clear safety stop
+	return													; done
+
+safety_stop_control_chk:
 	; above "opt_safety_stop_end"?
 	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:
+	bra		safety_stop_finish			; YES - finish with safety stop and return
+
 	; above "opt_safety_stop_start"?
 	movff	opt_safety_stop_start,WREG	; load safety stop start threshold [dm]
 	mullw	.10							; convert threshold from [dm] to [cm]
@@ -1426,60 +1764,108 @@
 	return								; NO  - pause safety stop
 	tstfsz	safety_stop_countdown		; YES - safety stop armed?
 	bsf		safety_stop_enabled			;       YES - enable safety stop
-	return								;       NO  - done
-
-
+	return								;     - done
+
+
+;-----------------------------------------------------------------------------
+; Show Safety Stop
+;
 safety_stop_show:
 	btfss	safety_stop_enabled			; safety stop enabled?
 	return								; NO  - done
 	dcfsnz	safety_stop_countdown,F		; YES - decrement remaining stop time, reached zero?
-	bra		safety_stop_finish			;       YES - finished with safety stop
+	bra		safety_stop_finish			;       YES - finished with safety stop and return
 	bsf		FLAG_TFT_safety_stop_show	;       NO  - request to show safety stop
 	return								;           - done
 
+
+;-----------------------------------------------------------------------------
+; Finish Safety Stop
+;
 safety_stop_finish:
-	clrf	safety_stop_countdown							; disarm safety stop
-	bcf		safety_stop_enabled								; disable safety stop
-	bsf		FLAG_TFT_safety_stop_clear						; request to clear safety stop
-	return													; done
-
-safety_stop_reset:
-	movff	opt_safety_stop_length,safety_stop_countdown	; arm safety stop (load timer)
-	incf	safety_stop_countdown,F							; +1 because safety_stop_show does decrement first
-	bsf		FLAG_TFT_safety_stop_clear						; request to clear safety stop
-	return													; done
-
-
-;=============================================================================
-
-timeout_menuview:
-	btfss	trigger_timeout				; timeout occurred?
-	return								; NO  - done
-	goto	menuview_toggle_reset		; YES - terminate the pre-menu and return
-
-timeout_divemode_menu:
-	btfss	trigger_timeout				; timeout occurred?
-	return								; NO  - done
-	;bra	timeout_divemode_menu2		; YES - clean up main menu and restore dive data
-
-	global	timeout_divemode_menu2
-timeout_divemode_menu2:					; jump-in point from divemenu_tree.asm
+	clrf	safety_stop_countdown		; disarm  safety stop
+	bcf		safety_stop_enabled			; disable safety stop
+	bsf		FLAG_TFT_safety_stop_clear	; request to clear safety stop
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Check for Timeouts (called by tasks every 1/1 second)
+;
+timeout_divemode:
+	btfss	dive_main_menu				; main dive menu shown?
+	bra		timeout_divemode_1			; NO  - skip
+	btfsc	trigger_timeout				; YES - timeout occurred?
+	rcall	divemenu_cleanup			;       YES - clean up main menu and restore dive data
+
+timeout_divemode_1:
+	btfss	dive_pre_menu				; pre-menu shown?
+	bra		timeout_divemode_2			; NO  - skip
+	btfsc	trigger_timeout				; YES - timeout occurred?
+	call	menuview_toggle_reset		;       YES - terminate the pre-menu
+
+timeout_divemode_2:
+	btfss	divetime_longer_1min		; does the dive already last for longer than one minute?
+	return								; NO  - suspend timeout
+
+	INCI	dive_timeout_timer			; increment timeout timer
+
+	btfsc	FLAG_apnoe_mode				; in apnoe mode?
+	bra		timeout_divemode_apnoe		; YES - use apnoe timeout
+
+ IFNDEF _DEBUG
+	btfsc	sensor_override_active		; in simulator mode?
+	bra		timeout_divemode_sim		; YES - use simulator timeout
+ ENDIF
+
+	movff	opt_diveTimeout,WREG		; get dive timeout in minutes into WREG
+	bra		timeout_divemode_com_min	; continue with common part for minutes
+
+timeout_divemode_apnoe:
+	movlw	apnoe_timeout				; get apnoe timeout in minutes into WREG
+	bra		timeout_divemode_com_min	; continue with common part for minutes
+
+timeout_divemode_sim:
+	MOVLI	simulator_timeout,sub_a		; get simulator timeout in seconds directly into sub_a
+	bra		timeout_divemode_com_sec	; continue with common part for seconds
+
+timeout_divemode_com_min:
+	mullw	.60							; multiply with 60 to convert minutes in WREG to seconds
+	MOVII	PRODL,sub_a					; copy resulting seconds to sub_a
+
+timeout_divemode_com_sec:
+	MOVII	dive_timeout_timer,sub_b	; copy current timeout timer value to sub_b
+	call	cmpU16						; check sub_a - sub_b
+	btfsc	neg_flag					; result negative, i.e. timeout?
+	bcf		divemode					; YES - terminate dive mode
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Clean up Dive Menu Area and restore Dive Data
+;
+divemenu_cleanup:
 	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
+	bra		divemenu_cleanup_1			; NO  - continue with redrawing the lower display
+	bcf		custom_view_locked			; YES - release locked
 	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
-	bsf		FLAG_TFT_temperature		; display temperature (or resettable dive time when in compass view)
+divemenu_cleanup_1:
+	bsf		FLAG_TFT_active_gas_divemode; request redraw of gas/setpoint/diluent
+	bsf		FLAG_TFT_temperature		; request redraw of temperature (or resettable dive)
 	bcf		better_gas_blinking			; stop better gas cue
 	bcf		better_dil_blinking			; stop better dil cue
-
+	;bra	request_redraw_NDL_deco_data; request redraw of NDL/deco data and return
+
+
+;-----------------------------------------------------------------------------
+; Request redraw of NDL/Deco Data
+;
 request_redraw_NDL_deco_data:
 	btfsc	FLAG_gauge_mode				; in gauge mode?
 	return								; YES - done
@@ -1498,348 +1884,146 @@
 	bsf		FLAG_TFT_display_ndl		; show NDL time
 	return								; done
 
-timeout_divemode:
-	btfsc	dive_main_menu				; main dive menu shown?
-	rcall	timeout_divemode_menu		; YES - check the timeout for it
-
-	btfsc	dive_options_menu			; pre-menu shown?
-	rcall	timeout_menuview			; YES - check the timeout for it
-
-	btfss	divetime_longer_1min		; does dive already last for longer than one minute?
-	return								; NO  - suspend timeout
-
-	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bra		timeout_divemode_apnoe		; YES - use apnoe timeout
-
- IFNDEF _DEBUG
-	btfsc	sensor_override_active		; in simulator mode?
-	bra		timeout_divemode_sim		; YES - use simulator timeout
-	;bra	timeout_divemode_dive		; NO  - use normal dive timeout
- ENDIF
-
-timeout_divemode_dive:
-	movff	opt_diveTimeout,WREG		; get dive timeout in minutes into WREG
-	;bra	timeout_divemode_com_min
-
-timeout_divemode_com_min:
-	mullw	.60							; multiply with 60 to convert minutes in WREG to seconds
-	MOVII	PRODL,sub_a					; copy resulting seconds to sub_a
-timeout_divemode_com_sec:
-	MOVII	dive_timeout_timer,sub_b	; copy current timeout timer value to sub_b
-	INCI	dive_timeout_timer			; increment timeout timer
-	call	cmpU16						; check sub_a - sub_b
-	btfsc	neg_flag					; result negative, i.e. timeout?
-	bcf		divemode					; YES - terminate dive mode
-	return								; done
-
-timeout_divemode_apnoe:
-	movlw	apnoe_timeout				; get apnoe timeout in minutes into WREG
-	bra		timeout_divemode_com_min	; continue with common part for minutes
-
-timeout_divemode_sim:
-	MOVLI	simulator_timeout,sub_a		; get simulator timeout in seconds directly into sub_a
-	bra		timeout_divemode_com_sec	; continue with common part for seconds
-
-
-update_divemode60:						; tasks every full minute
-	bcf		trigger_full_minute			; clear flag
-
-	call	get_battery_voltage			; get battery voltage
-	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	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 we do not care in debug mode...
- ELSE
-	bra		divemode_option_sim_quit	;       YES - set depth to 0 m and return
- ENDIF
-
-;=============================================================================
-
- IFDEF _cave_mode
-
-; ** 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
+
+;-----------------------------------------------------------------------------
+; Check if Dive Mode needs to be started (called from Surface Mode)
+;
+	global	check_dive_modes_surf
+check_dive_modes_surf:
+	SMOVII	pressure_rel_cur,sub_a			; ISR-safe 2 byte copy of current relative pressure to sub_a
+	bcf		divetime_longer_1min			; not diving when in surface mode
+	bra		check_dive_modes				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Check if Dive Mode needs to be finished (called from Dive Loop)
+;
+check_dive_modes_dive:
+	MOVII	pressure_rel_cur_cached,sub_a	; copy cached relative pressure to sub_a
+	;bra	check_dive_modes				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Check for Dive Mode Start/Finish - common Part
+;
+check_dive_modes:
+	btfss	high_altitude_mode					; in high altitude mode?
+	bra		check_dive_modes_norm				; NO  - use normal start-dive threshold
+	btfsc	divetime_longer_1min				; YES - diving since > one minute?
+	bra		check_dive_modes_norm				;       YES - this is a real dive -> use normal start-dive threshold
+	;bra	check_dive_modes_high				;       NO  - use hight-altitude start-dive threshold
+
+check_dive_modes_high:
+	; high altitude start/end dive thresholds
+	btfss	count_divetime						; dive time counting, i.e. already in the dive?
+	bra		check_dive_modes_high_start			; NO  - select start threshold
+	;bra	check_dive_modes_high_end			; YES - select end   threshold
+
+check_dive_modes_high_end:
+	MOVLI	dive_threshold_high_alt_end,sub_b	; load high altitude end threshold
+	bra		check_dive_modes_comm				; continue with common part
+
+check_dive_modes_high_start:
+	MOVLI	dive_threshold_high_alt_start,sub_b	; load high altitude start threshold
+	bra		check_dive_modes_comm				; continue with common part
+
+check_dive_modes_norm:
+	; normal altitude start/end dive thresholds
+	btfss	count_divetime						; dive time counting, i.e. already in the dive?
+	bra		check_dive_modes_norm_start			; NO  - select start threshold
+	;bra	check_dive_modes_norm_end			; YES - select end   threshold
+
+check_dive_modes_norm_end:
+	MOVLI	dive_threshold_norm_alt_end,sub_b	; load normal altitude end threshold
+	bra		check_dive_modes_comm				; continue with common part
+
+check_dive_modes_norm_start
+	MOVLI	dive_threshold_norm_alt_start,sub_b	; load normal altitude start threshold
+	;bra	check_dive_modes_comm				; continue with common part
+
+check_dive_modes_comm:
+	call	cmpU16								; sub_a - sub_b = pressure_rel_cur - start-dive threshold
+	btfsc	neg_flag							; pressure_rel_cur > dive_threshold, i.e. deeper than threshold?
+	bra		check_dive_modes_shallow			; NO  - shallower than threshold
+	btfsc	divetime_longer_1min				; YES - diving > one minute?
+	CLRI	dive_timeout_timer					;       YES - reset timeout counter
+	bsf		divemode							;     - set dive mode flag
+	bsf		count_divetime						;     - count dive time
+	return										;     - done
+
+check_dive_modes_shallow:
+	bcf		count_divetime						; stop counting dive time
+	btfss	divetime_longer_1min				; diving > one minute?
+	bcf		divemode							; NO  - quit dive mode as this was no real dive
 	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
-
-;=============================================================================
-
-	global	set_dive_modes
-set_dive_modes:
-	SMOVII	pressure_rel_cur,sub_a		; ISR-safe 2 byte copy of current relative pressure to sub_a
-	bra		set_dive_modes_1
-check_dive_modes:
-	MOVII	pressure_rel_cur_cached,sub_a; copy cached relative pressure to sub_a
-set_dive_modes_1:
-	btfss	high_altitude_mode			; in high altitude mode?
-	bra		set_dive_modes_norm			; NO  - use normal start-dive threshold
-	btfsc	divetime_longer_1min		; YES - dive lasted longer than one minute?
-	bra		set_dive_modes_norm			;       YES - this is a real dive -> use normal start-dive threshold
-	;bra	set_dive_modes_high			;       NO  - use hight-altitude start-dive threshold
-
-	; high altitude start/end dive thresholds
-set_dive_modes_high:
-	btfss	count_divetime				; dive time counting, i.e. already in the dive?
-	bra		set_dive_modes_high_start	; NO  - select start threshold
-	;bra	set_dive_modes_high_end		; YES - select end   threshold
-
-set_dive_modes_high_end:
-	MOVLI	dive_threshold_high_alt_end,sub_b
-	bra		set_dive_modes_comm
-
-set_dive_modes_high_start:
-	MOVLI	dive_threshold_high_alt_start,sub_b
-	bra		set_dive_modes_comm
-
-	; normal altitude start/end dive thresholds
-set_dive_modes_norm:
-	btfss	count_divetime				; dive time counting, i.e. already in the dive?
-	bra		set_dive_modes_norm_start	; NO  - select start threshold
-	;bra	set_dive_modes_norm_end		; YES - select end   threshold
-
-set_dive_modes_norm_end:
-	MOVLI	dive_threshold_norm_alt_end,sub_b
-	bra		set_dive_modes_comm
-
-set_dive_modes_norm_start
-	MOVLI	dive_threshold_norm_alt_start,sub_b
-	;bra	set_dive_modes_comm
-
-set_dive_modes_comm:
-	call	cmpU16						; sub_a - sub_b = pressure_rel_cur - start-dive threshold
-	btfsc	neg_flag					; pressure_rel_cur > dive_threshold, i.e. deeper than threshold?
-	bra		set_dive_modes_shallow		; NO  - shallower than threshold
-	btfsc	divetime_longer_1min		; YES - dive lasted longer than one minute?
-	CLRI	dive_timeout_timer			;       YES - reset timeout counter
-	bsf		divemode					;     - set dive mode flag
-	bsf		count_divetime				;     - count dive time
-	return								;     - done
-set_dive_modes_shallow:
-	bcf		count_divetime				; NO  - stop counting dive time
-	btfss	divetime_longer_1min		;     - dive lasted longer than one minute?
-	bcf		divemode					;       NO  - quit dive mode as this was no real dive
-	return								;       done
-
-
-set_powersafe:
-	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:
-	; prime the resettable average depth with 0
-	CLRI	pressure_rel_avg_trip
-	bra		reset_resettable_average_depth1
-
-reset_resettable_average_depth:
-	; clear reset-average request
-	bcf		request_reset_avg
-
-	; prime the resettable average depth with the current relative pressure (depth)
-	MOVII	pressure_rel_cur_cached,pressure_rel_avg_trip
-
-reset_resettable_average_depth1:
-	; clear the resettable depth accumulator
-	clrf	pressure_rel_accu_trip+0
-	clrf	pressure_rel_accu_trip+1
-	clrf	pressure_rel_accu_trip+2
-	clrf	pressure_rel_accu_trip+3
-
-	; clear the resettable time accumulator
-	CLRI	divesecs_avg_trip
-	return
-
-
+
+;-----------------------------------------------------------------------------
+; Initialize the resettable Depth and Timer
+;
+resettable_average_depth_init:
+	CLRI	pressure_rel_avg_trip							; prime the resettable average depth with 0
+	bra		resettable_average_depth_common					; clear pressure accumulator and timer
+
+
+;-----------------------------------------------------------------------------
+; Reset the resettable Depth and Timer
+;
+resettable_average_depth_reset:
+	bcf		request_reset_avg								; clear request
+	MOVII	pressure_rel_cur_cached,pressure_rel_avg_trip	; prime the resettable average depth
+															; with the current relative pressure (depth)
+	;bra	resettable_average_depth_common					; clear pressure accumulator and timer
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - common Part for resettable Depth and Timer init/reset
+;
+resettable_average_depth_common:
+	clrf	pressure_rel_accu_trip+0						; clear the resettable depth accumulator
+	clrf	pressure_rel_accu_trip+1						; ....
+	clrf	pressure_rel_accu_trip+2						; ....
+	clrf	pressure_rel_accu_trip+3						; ....
+	CLRI	divesecs_avg_trip								; clear the resettable time accumulator
+	return													; done
+
+
+;-----------------------------------------------------------------------------
+; Calculate Average Depth
+;
 calc_average_depth:
 	; 1. compute pressure_rel_cur_cached x 2, because this routine is called every 2nd second only
-
-	; copy current rel pressure to xB
-	MOVII	pressure_rel_cur_cached,xB
-
-	; multiply rel pressure x 2 (via shift left)
-	bcf		STATUS,C
-	rlcf	xB+0,F
-	rlcf	xB+1,F
+	MOVII	pressure_rel_cur_cached,xB		; copy current rel pressure to xB
+	bcf		STATUS,C						; multiply rel pressure x 2 (via shift left)
+	rlcf	xB+0,F							; ...
+	rlcf	xB+1,F							; ...
 
 	; 2a add (pressure_rel_cur_cached x 2) to the resettable depth accumulator
 	;    will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth)
-	movf	xB+0,W
-	addwf	pressure_rel_accu_trip+0,F
-	movf	xB+1,W
-	addwfc	pressure_rel_accu_trip+1,F
-	movlw	.0
-	addwfc	pressure_rel_accu_trip+2,F
-	addwfc	pressure_rel_accu_trip+3,F
+	movf	xB+0,W							; pressure_rel_accu_trip += xB
+	addwf	pressure_rel_accu_trip+0,F		; ...
+	movf	xB+1,W							; ...
+	addwfc	pressure_rel_accu_trip+1,F		; ...
+	movlw	.0								; ...
+	addwfc	pressure_rel_accu_trip+2,F		; ...
+	addwfc	pressure_rel_accu_trip+3,F		; ...
 
 	; 2b add (pressure_rel_cur_cached x 2) to the total depth accumulator
 	;    will work up to 9999 mbar * 60 * 60 * 24 = 863913600 mbar (24h @ 90 m depth)
-	movf	xB+0,W
-	addwf	pressure_rel_accu_total+0,F
-	movf	xB+1,W
-	addwfc	pressure_rel_accu_total+1,F
-	movlw	.0
-	addwfc	pressure_rel_accu_total+2,F
-	addwfc	pressure_rel_accu_total+3,F
+	movf	xB+0,W							; pressure_rel_accu_total += xB
+	addwf	pressure_rel_accu_total+0,F		; ...
+	movf	xB+1,W							; ...
+	addwfc	pressure_rel_accu_total+1,F		; ...
+	movlw	.0								; ...
+	addwfc	pressure_rel_accu_total+2,F		; ...
+	addwfc	pressure_rel_accu_total+3,F		; ...
 
 	; 3a compute the resettable average depth
-
-	; get the accumulated depth
-	movff	pressure_rel_accu_trip+0,xC+0
-	movff	pressure_rel_accu_trip+1,xC+1
-	movff	pressure_rel_accu_trip+2,xC+2
-	movff	pressure_rel_accu_trip+3,xC+3
-
-	; get the accumulated time
-	MOVII	divesecs_avg_trip,xB
+	movff	pressure_rel_accu_trip+0,xC+0	; get the accumulated depth
+	movff	pressure_rel_accu_trip+1,xC+1	; ...
+	movff	pressure_rel_accu_trip+2,xC+2	; ...
+	movff	pressure_rel_accu_trip+3,xC+3	; ...
+	MOVII	divesecs_avg_trip,xB			; get the accumulated time
 
 	; divide accumulated depth by accumulated time
 	call	div32x16						; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
@@ -1850,15 +2034,11 @@
 	return									; NO (e.g. too shallow)
 
 	; 3b compute the dive total average depth
-
-	; get accumulated depth
-	movff	pressure_rel_accu_total+0,xC+0
-	movff	pressure_rel_accu_total+1,xC+1
-	movff	pressure_rel_accu_total+2,xC+2
-	movff	pressure_rel_accu_total+3,xC+3
-
-	; get accumulated time
-	MOVII	divesecs_avg_total,xB
+	movff	pressure_rel_accu_total+0,xC+0	; get accumulated depth
+	movff	pressure_rel_accu_total+1,xC+1	; ...
+	movff	pressure_rel_accu_total+2,xC+2	; ...
+	movff	pressure_rel_accu_total+3,xC+3	; ...
+	MOVII	divesecs_avg_total,xB			; get accumulated time
 
 	; divide accumulated depth by accumulated time
 	call	div32x16						; xC:4 = xC:4 / xB:2 with xA as remainder
@@ -1867,7 +2047,7 @@
 	MOVII	xC,pressure_rel_avg_total		; total dive average depth
 
 	btfsc	request_reset_avg				; shall reset the resettable average depth?
-	rcall	reset_resettable_average_depth	; YES - reset the resettable average depth
+	rcall	resettable_average_depth_reset	; YES - reset the resettable average depth
 
 	TSTOSC	opt_2ndDepthDisp				; drawing average depth instead of max depth?
 	bsf		FLAG_TFT_depth_maximum			; YES - flag to update display
@@ -1878,16 +2058,19 @@
 	return									; done
 
 
-test_switches_divemode:						; checks switches in dive mode, called every second
+;-----------------------------------------------------------------------------
+; Check Switches, execute Pre-Menu Items  (called every second)
+;
+test_switches_divemode:
 	btfsc	dive_main_menu					; dive mode menu shown?
 	bra		test_switches_divemode_menu		; YES - use menu processor
 	btfsc	switch_left						; NO  - left button pressed?
-	goto	menuview_toggle					;       YES - menu or simulator tasks; and return...
+	goto	menuview_toggle					;       YES - step through pre-menu
 	btfss	switch_right					;       NO  - right button pressed?
 	return									;             NO  - done
 	bcf		switch_right					;             YES - clear button event
 	tstfsz	active_premenu					;                 - any pre-menu task selected?
-	bra		test_switches_divemode1			;                   YES - do option or menu tasks
+	bra		test_switches_divemode1			;                   YES - execute a pre-menu item
 	bsf		request_next_custview			;                   NO  - request next custom view
 	return									;                       - done
 
@@ -1895,96 +2078,333 @@
 	btfsc	switch_left						; left button pressed?
 	bra		test_switches_divemode_menu2	; YES - move cursor
 	btfsc	switch_right					; NO  - right button pressed?
-	bra		test_switches_divemode_menu3	;       YES - enter sub-menu or do something
+	bra		test_switches_divemode_menu3	;       YES - do a menu operation
 	btfss	update_menu						;       NO  - shall update the menu?
 	return									;             NO  - done
 	bcf		update_menu						;             YES - clear request
 	goto	menu_draw_lines_divemode		;                 - redraw the menu (to update color coding) and return
 
 test_switches_divemode_menu1:
-	clrf	menu_pos_cur
+	clrf	menu_pos_cur					; reset menu item number to zero
 test_switches_divemode_menu2:
-	bcf		switch_left
-	incf	menu_pos_cur,F
-	incf	menu_pos_max,W					; menu_pos_max + 1 -> WREG
-	cpfslt	menu_pos_cur					; > menu_pos_max ?
-	bra		test_switches_divemode_menu1	; YES - set to 1
-	call	TFT_show_menu_cursor_divemode	; update the cursor
+	bcf		switch_left						; clear left button event
+	incf	menu_pos_cur,F					; increment menu item number
+	incf	menu_pos_max,W					; get number of items + 1 into WREG
+	cpfslt	menu_pos_cur					; incremented item number > number of items ?
+	bra		test_switches_divemode_menu1	; YES - restart from first item
+	call	menu_draw_cursor_dive			; draw cursor at new position
 	movlw	divemode_timeout_mainmenu		; get timeout for main menu
-	call	reset_timeout_time				; reset timeout
-	return
-
-test_switches_divemode_menu3:				; enter sub-menu or do something
-	bcf		switch_right
-;	decf	menu_pos_cur,F					; menu_processor needs 0-5...
-	goto	do_line_menu					; Warning! trashes STKPTR and returns to diveloop_menu_exit
+	call	restart_timeout_time			; restart the timeout
+	return									; done
+
+test_switches_divemode_menu3:
+	bcf		switch_right					; clear right button event
+	goto	do_line_menu					; Warning! trashes STKPTR and returns to
+											;          divemode_option_divemenu_return
 
 test_switches_divemode1:
-	movlw	divemode_timeout_premenu	; get timeout for pre-menu
-	call	reset_timeout_time			; reset timeout
-	movff	active_premenu,WREG			; get number of active pre-menu
+	movlw	divemode_timeout_premenu		; get timeout for pre-menu
+	call	restart_timeout_time			; restart the timeout
+	movf	active_premenu,W				; get active pre-menu item
 	dcfsnz	WREG,F
-	bra		divemode_option_gaschange	;  1: 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_option_divemenu	;  2: enter dive mode menu
+	bra		divemode_option_ackn			;  2: acknowledge current advice, attention, or warning
+	dcfsnz	WREG,F
+	bra		divemode_option_divemenu		;  3: enter dive mode menu
 	dcfsnz	WREG,F
  IFDEF _cave_mode
-	bra		divemode_option_cavemenu	;  3: enter cave mode menu
+	bra		divemode_option_cavemenu		;  4: enter cave mode menu
  ELSE
-	return								;  3: (no cave mode compiled in)
+	return									;  4: (no cave mode compiled in)
+ ENDIF
+	dcfsnz	WREG,F
+	bra		divemode_option_sim_quit		;  5: quit simulator mode
+	dcfsnz	WREG,F
+	bra		divemode_option_sim_down		;  6: simulator mode - descent
+	dcfsnz	WREG,F
+	bra		divemode_option_sim_up			;  7: simulator mode - ascend
+	dcfsnz	WREG,F
+	bra		divemode_option_sim_time		;  8: simulator mode - +5 min
+	dcfsnz	WREG,F
+	bra		divemode_option_apnoe_quit		;  9: quit apnoe dive
+	dcfsnz	WREG,F
+	bra		divemode_option_gauge_reset		; 10: reset stopwatch and avg depth (gauge mode)
+	dcfsnz	WREG,F
+ IFDEF _compass
+	bra		divemode_option_course			; 11: set bearing
+ ELSE
+	return									; 11: (no compass compiled in)
  ENDIF
 	dcfsnz	WREG,F
-	bra		divemode_option_sim_quit	;  4: simulation - quit
-	dcfsnz	WREG,F
-	bra		divemode_option_sim_down	;  5: simulation - descent
-	dcfsnz	WREG,F
-	bra		divemode_option_sim_up		;  6: simulation - ascend
-	dcfsnz	WREG,F
-	bra		divemode_option_sim_time	;  7: simulation - +5 min
-	dcfsnz	WREG,F
-	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
+	bra		divemode_option_layout			; 12: switch layout
+	return									; catch illegal item number
+
+
+	; item  1: switch to the the "better gas" / "better diluent"
+	;
+divemode_option_gaschange:
+ IFDEF _ccr_pscr
+	btfsc	FLAG_oc_mode					; in OC mode?
+	bra		divemode_option_gaschange_oc	; YES
+	btfsc	bailout_mode					; in bailout?
+	bra		divemode_option_gaschange_oc	; YES
+
+	; in CCR/pSCR mode and not in bailout
+	movff	best_dil_number,menu_pos_cur	; select best diluent
+	bcf		better_dil_available			; clear flag immediately
+	bra		divemode_option_gaschange3		; continue with common part
+ ENDIF
+divemode_option_gaschange_oc:
+	movff	best_gas_number,menu_pos_cur	; select best gas
+	bcf		better_gas_available			; clear better gas cue
+
+divemode_option_gaschange3
+	bsf		request_gas_change				; request a gas/diluent change
+	goto	menuview_toggle_reset			; terminate the pre-menu (and return)
+
+
+	; item  2: acknowledge current advice, attention, or warning
+	;
+divemode_option_ackn:
+	btfss	sign_warning						; any warning active?
+	bra		divemode_option_ackn_attn			; NO  - check for active attentions
+	movff	DM_flags_war1_det,DM_flags_war1_ack	; YES - memorize active warnings as acknowledged
+	movff	DM_flags_war2_det,DM_flags_war2_ack	;     - ...
+	bra		divemode_option_ackn_common			;     - update screen
+
+divemode_option_ackn_attn:
+	btfss	sign_attention						; any attention active?
+	bra		divemode_option_ackn_advc			; NO  - must be active advice then
+	movff	DM_flags_att1_det,DM_flags_att1_ack	; YES - memorize active attentions as acknowledged
+	movff	DM_flags_att2_det,DM_flags_att2_ack	;     - ...
+	movff	DM_flags_att3_det,DM_flags_att3_ack	;     - ...
+	bra		divemode_option_ackn_common			;     - update screen
+
+divemode_option_ackn_advc:
+	movff	DM_flags_advc_det,DM_flags_advc_ack	; memorize active advices as acknowledged
+	;bra	divemode_option_ackn_common			; update screen
+
+divemode_option_ackn_common:
+	call	menuview_toggle_reset			; terminate pre-menu
+	call	divemode_check_sign				; compute if  the advice / attention / warning sign shall be shown
+	btfsc	FLAG_TFT_sign_show				; shall show  the advice / attention / warning sign?
+	goto	TFT_divemode_sign_show			; YES - show  sign and return
+	goto	TFT_divemode_sign_clear			; NO  - clear sign and return
+
+
+	; item  3: enter dive mode menu
+	;
+divemode_option_divemenu:
+	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_pre_menu					;     - set pre-menu as not shown anymore
+	goto	do_main_divemenu				;     - hand over to menu processor
+
+
+	; item  4: enter cave mode menu
+	;
+ IFDEF _cave_mode
+divemode_option_cavemenu:
+	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_pre_menu					;     - set pre-menu as not shown anymore
+	goto	do_main_cavemenu				;     - hand over to menu processor
+ ENDIF
+
+
+	; item  5: quit simulator mode
+	;
+divemode_option_sim_quit:
+	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
+	btfsc	FLAG_apnoe_mode					; in apnoe mode?
+	bcf		divemode						; YES - force end of dive mode
+	return									; done
+
+
+	; item  6: simulator mode - descent 1 meter
+	;
+divemode_option_sim_down:
+	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
+
+
+	; item  7: simulator mode - ascent 1 meter
+	;
+divemode_option_sim_up:
+	tstfsz	simulatormode_depth				; simulated depth > 0 ?
+	decf	simulatormode_depth,F			; YES - decrement simulated depth
+	return									; done
+
+
+	; item  8: simulator mode - +5 min
+	;
+divemode_option_sim_time:
+	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
+	bra		advance_time					; YES - advance time and return
+
+
+	; item  9: quit apnoe dive
+	;
+divemode_option_apnoe_quit:
+	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
+
+
+	; item 10: reset stopwatch and avg depth (gauge mode only)
+	;
+divemode_option_gauge_reset:
+	bsf		request_reset_avg				; request reset of average depth
+	goto	menuview_toggle_reset			; terminate pre-menu and return
+
+
+	; item 11: set bearing
+	;
  IFDEF _compass
-	bra		divemode_option_course		; 10: store heading
- ELSE
-	return								; 10: (no compass compiled in)
+divemode_option_course:
+	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
-	dcfsnz	WREG,F
-	bra		divemode_option_layout		; 11: switch layout
-	return
-
-
+
+
+	; item 12: switch layout
+	;
+divemode_option_layout:
+	call	menuview_toggle_reset		; terminate the pre-menu
+	call	TFT_ClearScreen				; clear the whole screen
+	btg		alt_layout_active			; toggle layout
+
+	bcf		depth_color_last			; set warning or attention on the depth   not shown
+	bcf		depth_inverse_last			; set depth displayed in inverse as       not shown
+	bcf		sign_shown					; set warning/attention/advice sign       not shown
+	bcf		velocity_active_num			; set numerical vertical velocity display not shown
+	bcf		velocity_active_vsi			; set vertical  vertical velocity display not shown
+	bcf		safety_stop_active			; set safety stop                         not shown
+
+	bsf		FLAG_TFT_divemode_mask		; request redraw of dive screen mask
+	bsf		FLAG_TFT_divetime			; request redraw of dive time
+	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_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
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - advance Time by 5 Minutes (Simulator Mode)
+;
+advance_time:
+	; advance tissues pressures and deco obligation by 5 minutes
+	movlw	.5								; + 5 minutes
+	movff	WREG,char_I_sim_advance_time	; copy to mailbox
+	call	restart_deco_engine				; condition deco engine to execute the +5 minutes
+
+	bcf		count_divetime					; stop dive time incrementing in ISR
+	ADDLI	.5,counted_divetime_mins		; add 5 minutes to counted_divetime_mins
+	ADDLI	.300,total_divetime_secs		; add 5 minutes (300 seconds) to total_divetime_secs
+	bsf		count_divetime					; continue dive time incrementing in ISR
+
+	ADDLI	.300,divesecs_avg_trip			; add 5 minutes (300 seconds) to resettable time accumulator
+	ADDLI	.300,divesecs_avg_total			; add 5 minutes (300 seconds) to total time accumulator
+
+	MOVII	pressure_rel_cur_cached,xB		; calculate 300 x depth in mbar (300 = 5 min * 60 sec/min)
+	MOVLI	.300,xA							; ...
+	call	mult16x16						; xC = xA * xB
+
+	movf	xC+0,W							; add to the resettable depth accumulator
+	addwf	pressure_rel_accu_trip+0,F		; ...
+	movf	xC+1,W							; ...
+	addwfc	pressure_rel_accu_trip+1,F		; ...
+	movf	xC+2,W							; ...
+	addwfc	pressure_rel_accu_trip+2,F		; ...
+	movf	xC+3,W							; ...
+	addwfc	pressure_rel_accu_trip+3,F		; ...
+
+	movf	xC+0,W							; add to the total depth accumulator
+	addwf	pressure_rel_accu_total+0,F		; ...
+	movf	xC+1,W							; ...
+	addwfc	pressure_rel_accu_total+1,F		; ...
+	movf	xC+2,W							; ...
+	addwfc	pressure_rel_accu_total+2,F		; ...
+	movf	xC+3,W							; ...
+	addwfc	pressure_rel_accu_total+3,F		; ...
+
+ IFDEF _cave_mode
+	; update backtracking data
+	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
+ ENDIF	; _cave_mode
+
+divemode_option_sim_time_exit:
+	return									; done (leaving option avail for repeated selection)
+
+
+;-----------------------------------------------------------------------------
+; Change Gas / Diluent
+;
 gas_switch_common:
-	bcf		request_gas_change			; clear request flag
+	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
-	bcf		request_back_to_loop		; YES - clear flag
-	movff	active_dil,menu_pos_cur		;     - reload last diluent
-	bra		gas_switched_common1		;     - continue with common part
+	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
+	bcf		request_back_to_loop			; YES - clear flag
+	movff	active_dil,menu_pos_cur			;     - reload last diluent
+	bra		gas_switched_common1			;     - continue with common part
  ENDIF
 gas_switched_common0:
-	tstfsz	menu_pos_cur				; menu_pos_cur = 0 ?
-	bra		gas_switched_common1		; NO  - valid gas
-	return								; YES - something went wrong, invalid gas, abort
+	tstfsz	menu_pos_cur					; menu_pos_cur = 0 ?
+	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-5)
+	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			; 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
+	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
+	call	setup_dil_registers				; set up real tissues  with WREG = diluent 1-6
+	call	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			; 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
+	call	setup_gas_registers				; set up real tissues  with WREG = gas 1-6
+	call	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
@@ -2004,6 +2424,9 @@
 	goto	restart_deco_engine_wo_ceiling	; abort running deco calculations and restart (and return)
 
 
+;-----------------------------------------------------------------------------
+; Reload the current Gas / Diluent
+;
 gas_update_common:
 	bcf		request_gas_update			; reset the request flag
 	movf	active_gas,W				; load WREG with currently used gas
@@ -2018,407 +2441,27 @@
 	bra		gas_switched_common_OC		; reload OC gases
  ENDIF
 
-; Code to pass all parameters to the C code
-
-	global	get_first_gas_to_WREG
-get_first_gas_to_WREG:					; gets first gas (1-5) into WREG
-	lfsr	FSR1,opt_gas_type			; load base address of the gas types
-	clrf	lo							; start with gas 0
-get_first_gas_to_WREG2:
-	movf	lo,W						; set index
-	movf	PLUSW1,W					; get type of gas (0=Disabled, 1=First, 2=Travel, 3=Deco)
-	sublw	.1							; is it of type First?
-	bz		get_first_gas_to_WREG3		; YES - found the First gas
-	incf	lo,F						; NO  - increment index
-	movlw	NUM_GAS+1					;     - get highest index+1
-	cpfseq	lo							;     - all gases checked?
-	bra		get_first_gas_to_WREG2		;       NO  - not yet
-	movlw	.1							;       YES - default to gas 1
-	movff	WREG,opt_gas_type+0			;           - force it to be of type First
-	return								;           - done
-get_first_gas_to_WREG3:
-	movf	lo,W						; copy index of gas found to be the First to WREG
-	incf	WREG,W						; turn index into gas number (0-4 -> 1-5)
-	return								; done
-
-;=============================================================================
-
- IFDEF _ccr_pscr
-
-	global	get_first_dil_to_WREG
-get_first_dil_to_WREG:					; gets first dil (1-5) into WREG
-	lfsr	FSR1,opt_dil_type			; load base address of the dil types
-	clrf	lo							; start with dil 0
-get_first_dil_to_WREG2:
-	movf	lo,W						; set index
-	movf	PLUSW1,W					; get type of Dil (0=Disabled, 1=First, 2=Normal)
-	sublw	.1							; is it of type First?
-	bz		get_first_dil_to_WREG3		; YES - found the First dil
-	incf	lo,F						; NO  - increment index
-	movlw	NUM_GAS+1					;     - get highest index+1
-	cpfseq	lo							;     - dils checked?
-	bra		get_first_dil_to_WREG2		;       NO  - not yet
-	movlw	.1							;       YES - default to dil 1
-	movff	WREG,opt_dil_type+0			;           - force it to be of type First
-	return								;           - done
-get_first_dil_to_WREG3:
-	movf	lo,W						; copy index of dil found to be the First to WREG
-	incf	WREG,W						; turn index into dil number (0-4 -> 1-5)
-	return								; done
-
- ENDIF
-
-;=============================================================================
-
-	global	deco_setup_oc_gases
-deco_setup_oc_gases:					; with currently breathed gas in WREG (1-5 or 6)
-	movff	char_O_deco_status,lo		; working copy of char_O_deco_status in bank common
-deco_setup_oc_gases_pre:				; entry point with lo preloaded
-	movff	WREG,char_I_current_gas_num	; set gas to start with when doing the deco calculations
-	;
-	; Memory Map:
-	; ---------------------------------------------------------------------------------
-	; opt_gas_O2_ratio		res NUM_GAS		|	char_I_deco_O2_ratio		res NUM_GAS
-	; opt_dil_O2_ratio		res NUM_GAS		|
-	; opt_gas_He_ratio		res NUM_GAS		|	char_I_deco_He_ratio		res NUM_GAS
-	; opt_dil_He_ratio		res NUM_GAS		|
-	; opt_gas_type			res NUM_GAS		|	char_I_deco_gas_type		res NUM_GAS
-	; opt_dil_type			res NUM_GAS		|
-	; opt_gas_change		res NUM_GAS		|	char_I_deco_gas_change		res NUM_GAS
-	; opt_dil_change		res NUM_GAS		|
-	;
-	lfsr	FSR2,char_I_deco_O2_ratio	; load FSR2 with base address of char_I_deco_O2_ratio
-										; FSR2 will step through all char_I_deco_... vars
-	lfsr	FSR1,opt_gas_O2_ratio		; load FSR1 with base address of opt_gas_O2_ratio
-	rcall	deco_setup_copy				; copy all OC O2 ratios
-	lfsr	FSR1,opt_gas_He_ratio		; load FSR1 with base address of opt_gas_He_ratio
-	rcall	deco_setup_copy				; copy all OC He ratios
-	lfsr	FSR1,opt_gas_type			; load FSR1 with base address of opt_gas_type
-	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 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
-
-;=============================================================================
-
- IFDEF _ccr_pscr
-
-	global	deco_setup_cc_diluents
-deco_setup_cc_diluents:					; with currently breathed diluent in WREG (1-5 or 6)
-	movff	char_O_deco_status,lo		; working copy of char_O_deco_status in bank common
-deco_setup_cc_diluents_pre:				; entry point with lo preloaded
-	btfsc	bailout_mode				; check if in bailout condition       | --------------- FOR SAFETY ONLY --------------
-	bra		deco_setup_oc_gases_pre		; YES - revert to setting up OC gases | This branch should never happen to be taken...
-	movff	WREG,char_I_current_gas_num	; NO  - set diluent to start with when doing the deco calculations
-	;
-	; Memory Map:
-	; ---------------------------------------------------------------------------------
-	; opt_gas_O2_ratio		res NUM_GAS		|
-	; opt_dil_O2_ratio		res NUM_GAS		|	char_I_deco_O2_ratio		res NUM_GAS
-	; opt_gas_He_ratio		res NUM_GAS		|
-	; opt_dil_He_ratio		res NUM_GAS		|	char_I_deco_He_ratio		res NUM_GAS
-	; opt_gas_type			res NUM_GAS		|
-	; opt_dil_type			res NUM_GAS		|	char_I_deco_gas_type		res NUM_GAS
-	; opt_gas_change		res NUM_GAS		|
-	; opt_dil_change		res NUM_GAS		|	char_I_deco_gas_change		res NUM_GAS
-	;
-	lfsr	FSR2,char_I_deco_O2_ratio	; load FSR2 with base address of char_I_deco_O2_ratio.
-										; FSR2 will step through all char_I_deco_... vars.
-	lfsr	FSR1,opt_dil_O2_ratio		; load FSR1 with base address of opt_dil_O2_ratio
-	rcall	deco_setup_copy				; copy all dil O2 ratios
-	lfsr	FSR1,opt_dil_He_ratio		; load FSR1 with base address of opt_dil_He_ratio
-	rcall	deco_setup_copy				; copy all dil He ratios
-	lfsr	FSR1,opt_dil_type			; load FSR1 with base address of opt_dil_type
-	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
+
+;-----------------------------------------------------------------------------
+; Toggle GF/aGF  (finalization)
+;
+divemodemode_togglegf:
+	bcf		request_toggle_GF			; clear request flag
+	goto	restart_deco_engine			; restart the deco engine and return
+
+
+;-----------------------------------------------------------------------------
+; Set a Marker in the Dive Profile
+;
+set_logbook_marker:
+	bcf		request_set_marker			; clear request flag
+	movlw	d'6'						; set type of alarm: manual marker
+	movwf	alarm_type					; copy to alarm register
+	bsf		event_occured				; set event flag
 	return								; done
 
- ENDIF
-
-;=============================================================================
-
-deco_setup_copy:
-	movlw	NUM_GAS						; load loop counter with number of gases (5)
-deco_setup_copy_loop:
-	movff	POSTINC1,POSTINC2			; copy from (FSR1) to (FSR2)
-	decfsz	WREG						; decrement loop counter and check if it became 0
-	bra		deco_setup_copy_loop		; NO  - not yet, loop
-	return								; YES - done
-
-
-	global	setup_gas_registers
-setup_gas_registers:					; with currently breathed gas in WREG (1-5 or 6)
-	movwf	active_gas					; set as current gas
-	movlw	.6
-	cpfseq	active_gas					; gas = gas6 ?
-	bra		setup_gas_registers_15		; NO - load gas 1-5
-	movff	gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine
- IFDEF _helium
-	movff	gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine
- ENDIF
-	movlw	.3							; declare gas6 as a deco gas
-	movff	WREG,char_I_current_gas_type; copy gas type to deco engine
-	movff	depth_meter,char_I_gas6_depth;set current depth as change depth
-	bra		setup_gas_registers_com		; continue with common part
-setup_gas_registers_15:
-	lfsr	FSR1,opt_gas_O2_ratio		; load base address of gas data
-	decf	active_gas,W				; set index to O2 ratio of current gas (1-5 -> 0-4)
-	movff	PLUSW1,char_I_O2_ratio		; copy         O2 ratio to deco engine
-	addlw	.10							; advance index from O2 ratio to He ratio
- IFDEF _helium
-	movff	PLUSW1,char_I_He_ratio		; copy         He ratio to deco engine
- ENDIF
-	addlw	.10							; advance index from He ratio to gas type
-	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 (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!)
-	return
-
-;=============================================================================
-
- IFDEF _ccr_pscr
-
-	global	setup_dil_registers
-setup_dil_registers:					; with currently breathed gas in WREG (1-5 or 6)
-	btfsc	bailout_mode				; check if in bailout condition                      | --------------- FOR SAFETY ONLY --------------
-	bra		setup_gas_registers			; revert to setting up OC gases in bailout condition | This branch should never happen to be taken...
-	movwf	active_dil					; set as current diluent
-	movlw	.6
-	cpfseq	active_dil					; diluent = gas6 ?
-	bra		setup_dil_registers_15		; NO - load diluent 1-5
-	movff	gas6_O2_ratio,char_I_O2_ratio ; copy gas6 O2 ratio to deco engine
- IFDEF _helium
-	movff	gas6_He_ratio,char_I_He_ratio ; copy gas6 H2 ratio to deco engine
- ENDIF
-	movlw	.2							; declare gas6 as a normal diluent
-	movff	WREG,char_I_current_gas_type; copy gas type to deco engine
-	movff	depth_meter,char_I_gas6_depth;set current depth as change depth
-	bra		setup_dil_registers_com		; continue with common part
-setup_dil_registers_15:
-	lfsr	FSR1,opt_dil_O2_ratio		; load base address of diluent data
-	decf	active_dil,W				; set index to O2 ratio of current diluent (1-5 -> 0-4)
-	movff	PLUSW1,char_I_O2_ratio		; copy         O2 ratio to deco engine
-	addlw	.10							; advance index from O2 ratio to He ratio
- IFDEF _helium
-	movff	PLUSW1,char_I_He_ratio		; copy         He ratio to deco engine
- ENDIF
-	addlw	.10							; advance index from He ratio to diluent type
-	movff	PLUSW1,char_I_current_gas_type ; copy diluent type (0=Disabled, 1=First, 2=Normal)
-setup_dil_registers_com:
-	movff	char_O_main_status,lo		; working copy of char_O_main_status in bank common
-	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_main_status		; bank safe write-back of char_O_main_status
-	movf	active_dil,W				; reload WREG with diluent 1-5 or 6 (important!)
-	return
-
- ENDIF
-
-;=============================================================================
-
-divemode_option_gaschange:				; switch to the "better gas" / "better diluent"
- IFDEF _ccr_pscr
-	btfsc	FLAG_oc_mode				; in OC mode?
-	bra		divemode_option_gaschange_oc; YES
-	btfsc	bailout_mode				; in bailout?
-	bra		divemode_option_gaschange_oc; YES
-divemode_option_gaschange_loop:			; in CCR/pSCR mode and not in bailout
-	movff	best_dil_number,menu_pos_cur; NO  - select best diluent
-	bcf		better_dil_available		;     - clear flag immediately
-	bra		divemode_option_gaschange3	;     - continue with common part
- ENDIF
-divemode_option_gaschange_oc:			; in OC or bailout
-	movff	best_gas_number,menu_pos_cur; select best gas
-	bcf		better_gas_available		; clear flag immediately
-divemode_option_gaschange3				; common part
-	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
-	bsf		dive_main_menu				; set main menu   is     shown now
-	movlw	divemode_timeout_mainmenu	; get timeout for main menu
-	call	reset_timeout_time			; reload timeout
-	goto	diveloop_menu_exit			; go back to dive loop (menu processor resets STKPTR!)
-
-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
-	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bcf		divemode					; YES - force end of dive mode
-	return								; done
-
-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_option_sim_up:					; minus 1 meter
-	tstfsz	simulatormode_depth			; simulated depth > 0 ?
-	decf	simulatormode_depth,F		; YES - decrement simulated depth
-	return								; done
-
-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
-
-	; advance tissues pressures and deco obligation by 5 minutes
-	movlw	.5							; + 5 minutes
-	movff	WREG,char_I_sim_advance_time; copy to mailbox
-	call	restart_deco_engine			; condition deco engine to execute the +5 minutes
-
-	; stop dive time incrementing in ISR
-	bcf		count_divetime
-
-	; add 5 minutes to counted_divetime_mins
-	ADDLI	.5,counted_divetime_mins
-
-	; add 5 minutes (300 seconds) to total_divetime_secs
-	ADDLI	.300,total_divetime_secs
-
-	; continue dive time incrementing in ISR
-	bsf		count_divetime
-
-	; add 5 minutes (300 seconds) to resettable time accumulator
-	ADDLI	.300,divesecs_avg_trip
-
-	; add 5 minutes (300 seconds) to total time accumulator
-	ADDLI	.300,divesecs_avg_total
-
-	; calculate 300 x depth in mbar (300 = 5 min * 60 sec/min)
-	MOVII	pressure_rel_cur_cached,xB
-	MOVLI	.300,xA
-	call	mult16x16					; xC = xA * xB
-
-	; add to the resettable depth accumulator
-	movf	xC+0,W
-	addwf	pressure_rel_accu_trip+0,F
-	movf	xC+1,W
-	addwfc	pressure_rel_accu_trip+1,F
-	movf	xC+2,W
-	addwfc	pressure_rel_accu_trip+2,F
-	movf	xC+3,W
-	addwfc	pressure_rel_accu_trip+3,F
-
-	; add to the total depth accumulator
-	movf	xC+0,W
-	addwf	pressure_rel_accu_total+0,F
-	movf	xC+1,W
-	addwfc	pressure_rel_accu_total+1,F
-	movf	xC+2,W
-	addwfc	pressure_rel_accu_total+2,F
-	movf	xC+3,W
-	addwfc	pressure_rel_accu_total+3,F
-
- IFDEF _cave_mode
-	; update backtracking data
-	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_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_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
-
-	bcf		depth_warn_att_last			; set warning or attention on the depth   not shown
-	bcf		depth_inverse_last			; set depth displayed in inverse as       not shown
-	bcf		sign_shown					; set warning/attention/advice sign       not shown
-	bcf		velocity_active_num			; set numerical vertical velocity display not shown
-	bcf		velocity_active_vsi			; set vertical  vertical velocity display not shown
-	bcf		safety_stop_active			; set safety stop                         not shown
-
-	bsf		FLAG_TFT_divemode_mask		; request redraw of dive screen mask
-	bsf		FLAG_TFT_divetime			; request redraw of dive time
-	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_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
-
-
-;=============================================================================
+
+;-----------------------------------------------------------------------------
 ; Find the best gas and diluent for the current depth
 ; and check if a gas/diluent change is to be advised.
 ;
@@ -2499,7 +2542,7 @@
 	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?
+	btfsc	warn_det_sensors_lost			; all sensors lost?
 	bra		check_gas_best_dil3				; YES - suppress better diluent prompt in this case
 	; not using the best gas - show better diluent hint whenever a better diluent is available
 	bsf		better_dil_available			; signal that a better diluent is available
@@ -2568,7 +2611,7 @@
 
 
 check_gas_best_common:						; with gas to be checked in check_gas_num (1-5)
-;											; and  current gas       in lo            (1-5)
+											; and  current gas       in lo            (1-5)
 	;
 	; Memory Map:
 	; ---------------------------------------------------------------------------------------
@@ -2669,17 +2712,18 @@
 	movff	check_gas_depth,best_gas_depth	;     - memorize its change depth
 	return									;     - done
 
-
-;=============================================================================
+ IFDEF _ccr_pscr
+
+
+;-----------------------------------------------------------------------------
 ; Check for Auto-SP
 ;
- IFDEF _ccr_pscr
-
-check_dive_autosp:						; check for Auto-SP
+check_dive_autosp:
 	movff	opt_ccr_mode,WREG			; =0: Fixed SP, =1: Sensor, =2: Auto SP
 	sublw	.2							; opt_ccr_mode = 2 (Auto SP)?
 	bz		check_dive_autosp2			; YES - check
 	return								; NO  - return for sensor or fixed mode
+
 check_dive_autosp2:
 	; check SP2
 	btfsc	FLAG_SP2_used				; SP 2 used so far?
@@ -2696,6 +2740,7 @@
 	movff	opt_setpoint_cbar+1,char_I_const_ppO2 ; YES - use SP
 	rcall	xmit_sp_set_flag			;     - send SP to external devices
 	bsf		FLAG_SP2_used				;     - set SP 2 used flag
+
 check_dive_autosp3:
 	; check SP3
 	btfsc	FLAG_SP3_used				; SP 3 used so far?
@@ -2712,6 +2757,7 @@
 	movff	opt_setpoint_cbar+2,char_I_const_ppO2 ; YES - use SP
 	rcall	xmit_sp_set_flag			;     - send SP to external devices
 	bsf		FLAG_SP3_used				;     - set SP 3 used flag
+
 check_dive_autosp4:
 	; check SP4
 	btfsc	FLAG_SP4_used				; SP 4 used so far?
@@ -2728,6 +2774,7 @@
 	movff	opt_setpoint_cbar+3,char_I_const_ppO2 ; YES - use SP
 	rcall	xmit_sp_set_flag			;     - send SP to external devices
 	bsf		FLAG_SP4_used				;     - set SP 4 used flag
+
 check_dive_autosp5:
 	; check SP5
 	btfsc	FLAG_SP5_used				; SP 5 used so far?
@@ -2744,9 +2791,14 @@
 	movff	opt_setpoint_cbar+4,char_I_const_ppO2 ; YES - use SP
 	rcall	xmit_sp_set_flag			;     - send SP to external devices
 	bsf		FLAG_SP5_used				;     - set SP 5 used flag
+
 check_dive_autosp6:
-	return
-
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - transmit new Setpoint to external Electronics and flag Change
+;
 xmit_sp_set_flag:
  IFDEF _external_sensor
 	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
@@ -2757,55 +2809,281 @@
 
  ENDIF	; _ccr_pscr
 
-;=============================================================================
-
-set_logbook_marker:
-	bcf		request_set_marker			; clear request flag
-	movlw	d'6'						; set type of alarm: manual marker
-	movwf	alarm_type					; copy to alarm register
-	bsf		event_occured				; set event flag
-	return
 
 ;=============================================================================
-; Setup everything to enter dive mode
+dmode2	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Setup everything to enter OC Dive Mode
 ;
 	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)
-	return
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - get first Gas (1-5) into WREG
+;
+	global	get_first_gas_to_WREG
+get_first_gas_to_WREG:
+	lfsr	FSR1,opt_gas_type			; load base address of the gas types
+	clrf	lo							; start with gas 0
+get_first_gas_to_WREG2:
+	movf	lo,W						; set index
+	movf	PLUSW1,W					; get type of gas (0=Disabled, 1=First, 2=Travel, 3=Deco)
+	sublw	.1							; is it of type First?
+	bz		get_first_gas_to_WREG3		; YES - found the First gas
+	incf	lo,F						; NO  - increment index
+	movlw	NUM_GAS+1					;     - get highest index+1
+	cpfseq	lo							;     - all gases checked?
+	bra		get_first_gas_to_WREG2		;       NO  - not yet
+	movlw	.1							;       YES - default to gas 1
+	movff	WREG,opt_gas_type+0			;           - force it to be of type First
+	return								;           - done
+get_first_gas_to_WREG3:
+	movf	lo,W						; copy index of gas found to be the First to WREG
+	incf	WREG,W						; turn index into gas number (0-4 -> 1-5)
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - load currently breathed Gas into Deco Engine
+;
+	global	setup_gas_registers
+setup_gas_registers:
+	movwf	active_gas						; set as current gas
+	movlw	.6								; gas = gas6 ?
+	cpfseq	active_gas						; ...
+	bra		setup_gas_registers_15			; NO - load gas 1-5
+
+	; load gas 6
+	movff	opt_gas6_O2_ratio,char_I_O2_ratio	; copy gas6 O2 ratio to deco engine
+ IFDEF _helium
+	movff	opt_gas6_He_ratio,char_I_He_ratio	; copy gas6 H2 ratio to deco engine
+ ENDIF
+	movlw	.3								; declare gas6 as a deco gas
+	movff	WREG,char_I_current_gas_type	; copy gas type to deco engine
+	movff	depth_meter,char_I_gas6_depth	;set current depth as change depth
+	bra		setup_gas_registers_com			; continue with common part
+
+setup_gas_registers_15:
+	lfsr	FSR1,opt_gas_O2_ratio			; load base address of gas data
+	decf	active_gas,W					; set index to O2 ratio of current gas (1-5 -> 0-4)
+	movff	PLUSW1,char_I_O2_ratio			; copy         O2 ratio to deco engine
+	addlw	.10								; advance index from O2 ratio to He ratio
+ IFDEF _helium
+	movff	PLUSW1,char_I_He_ratio			; copy         He ratio to deco engine
+ ENDIF
+	addlw	.10								; advance index from He ratio to gas type
+	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 (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!)
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - load OC Gases into Deco Engine (currently breathed gas in WREG)
+;
+	global	deco_setup_oc_gases
+deco_setup_oc_gases:
+	movff	char_O_deco_status,lo			; get working copy of char_O_deco_status in bank common
+deco_setup_oc_gases_pre:					; entry point with lo preloaded
+	movff	WREG,char_I_current_gas_num		; set gas to start with when doing the deco calculations
+	;
+	; Memory Map:
+	; ---------------------------------------------------------------------------------
+	; opt_gas_O2_ratio		res NUM_GAS		|	char_I_deco_O2_ratio		res NUM_GAS
+	; opt_dil_O2_ratio		res NUM_GAS		|
+	; opt_gas_He_ratio		res NUM_GAS		|	char_I_deco_He_ratio		res NUM_GAS
+	; opt_dil_He_ratio		res NUM_GAS		|
+	; opt_gas_type			res NUM_GAS		|	char_I_deco_gas_type		res NUM_GAS
+	; opt_dil_type			res NUM_GAS		|
+	; opt_gas_change		res NUM_GAS		|	char_I_deco_gas_change		res NUM_GAS
+	; opt_dil_change		res NUM_GAS		|
+	;
+	lfsr	FSR2,char_I_deco_O2_ratio		; load FSR2 with base address of char_I_deco_O2_ratio
+											; FSR2 will step through all char_I_deco_... vars
+	lfsr	FSR1,opt_gas_O2_ratio			; load FSR1 with base address of opt_gas_O2_ratio
+	rcall	deco_setup_copy					; copy all OC O2 ratios
+	lfsr	FSR1,opt_gas_He_ratio			; load FSR1 with base address of opt_gas_He_ratio
+	rcall	deco_setup_copy					; copy all OC He ratios
+	lfsr	FSR1,opt_gas_type				; load FSR1 with base address of opt_gas_type
+	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 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
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - dedicated Memory Copy
+deco_setup_copy:
+	movlw	NUM_GAS						; load loop counter with number of gases (5)
+deco_setup_copy_loop:
+	movff	POSTINC1,POSTINC2			; copy from (FSR1) to (FSR2)
+	decfsz	WREG						; decrement loop counter and check if it became 0
+	bra		deco_setup_copy_loop		; NO  - not yet, loop
+	return								; YES - done
+
 
 
  IFDEF _ccr_pscr
 
+;-----------------------------------------------------------------------------
+; Setup everything to enter CCR/pSCR Dive Mode - Part 1
+;
 	global	dive_boot_cc
 dive_boot_cc:
-	; 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)
-	return
-
-
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - get first Diluent (1-5) into WREG
+;
+	global	get_first_dil_to_WREG
+get_first_dil_to_WREG:					; gets first dil (1-5) into WREG
+	lfsr	FSR1,opt_dil_type			; load base address of the dil types
+	clrf	lo							; start with dil 0
+get_first_dil_to_WREG2:
+	movf	lo,W						; set index
+	movf	PLUSW1,W					; get type of Dil (0=Disabled, 1=First, 2=Normal)
+	sublw	.1							; is it of type First?
+	bz		get_first_dil_to_WREG3		; YES - found the First dil
+	incf	lo,F						; NO  - increment index
+	movlw	NUM_GAS+1					;     - get highest index+1
+	cpfseq	lo							;     - dils checked?
+	bra		get_first_dil_to_WREG2		;       NO  - not yet
+	movlw	.1							;       YES - default to dil 1
+	movff	WREG,opt_dil_type+0			;           - force it to be of type First
+	return								;           - done
+get_first_dil_to_WREG3:
+	movf	lo,W						; copy index of dil found to be the First to WREG
+	incf	WREG,W						; turn index into dil number (0-4 -> 1-5)
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - load currently breathed Diluent into Deco Engine
+;
+	global	setup_dil_registers
+setup_dil_registers:
+	btfsc	bailout_mode					; check if in bailout condition                      | --------------- FOR SAFETY ONLY --------------
+	bra		setup_gas_registers				; revert to setting up OC gases in bailout condition | This branch should never happen to be taken...
+	movwf	active_dil						; set as current diluent
+	movlw	.6								; diluent = gas6 ?
+	cpfseq	active_dil						; ...
+	bra		setup_dil_registers_15			; NO - load diluent 1-5
+
+	; load gas 6
+	movff	opt_gas6_O2_ratio,char_I_O2_ratio	; copy gas6 O2 ratio to deco engine
+ IFDEF _helium
+	movff	opt_gas6_He_ratio,char_I_He_ratio	; copy gas6 He ratio to deco engine
+ ENDIF
+	movlw	.2								; declare gas6 as a normal diluent
+	movff	WREG,char_I_current_gas_type	; copy gas type to deco engine
+	movff	depth_meter,char_I_gas6_depth	;set current depth as change depth
+	bra		setup_dil_registers_com			; continue with common part
+
+setup_dil_registers_15:
+	lfsr	FSR1,opt_dil_O2_ratio			; load base address of diluent data
+	decf	active_dil,W					; set index to O2 ratio of current diluent (1-5 -> 0-4)
+	movff	PLUSW1,char_I_O2_ratio			; copy         O2 ratio to deco engine
+	addlw	.10								; advance index from O2 ratio to He ratio
+ IFDEF _helium
+	movff	PLUSW1,char_I_He_ratio			; copy         He ratio to deco engine
+ ENDIF
+	addlw	.10								; advance index from He ratio to diluent type
+	movff	PLUSW1,char_I_current_gas_type	; copy diluent type (0=Disabled, 1=First, 2=Normal)
+setup_dil_registers_com:
+	movff	char_O_main_status,lo			; working copy of char_O_main_status in bank common
+	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_main_status			; bank safe write-back of char_O_main_status
+	movf	active_dil,W					; reload WREG with diluent 1-5 or 6 (important!)
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - load Diluents into Deco Engine (currently breathed dil in WREG)
+;
+	global	deco_setup_cc_diluents
+deco_setup_cc_diluents:
+	movff	char_O_deco_status,lo			; working copy of char_O_deco_status in bank common
+deco_setup_cc_diluents_pre:					; entry point with lo preloaded
+	btfsc	bailout_mode					; check if in bailout condition       | --------------- FOR SAFETY ONLY --------------
+	bra		deco_setup_oc_gases_pre			; YES - revert to setting up OC gases | This branch should never happen to be taken...
+	movff	WREG,char_I_current_gas_num		; NO  - set diluent to start with when doing the deco calculations
+	;
+	; Memory Map:
+	; ---------------------------------------------------------------------------------
+	; opt_gas_O2_ratio		res NUM_GAS		|
+	; opt_dil_O2_ratio		res NUM_GAS		|	char_I_deco_O2_ratio		res NUM_GAS
+	; opt_gas_He_ratio		res NUM_GAS		|
+	; opt_dil_He_ratio		res NUM_GAS		|	char_I_deco_He_ratio		res NUM_GAS
+	; opt_gas_type			res NUM_GAS		|
+	; opt_dil_type			res NUM_GAS		|	char_I_deco_gas_type		res NUM_GAS
+	; opt_gas_change		res NUM_GAS		|
+	; opt_dil_change		res NUM_GAS		|	char_I_deco_gas_change		res NUM_GAS
+	;
+	lfsr	FSR2,char_I_deco_O2_ratio		; load FSR2 with base address of char_I_deco_O2_ratio.
+											; FSR2 will step through all char_I_deco_... vars.
+	lfsr	FSR1,opt_dil_O2_ratio			; load FSR1 with base address of opt_dil_O2_ratio
+	rcall	deco_setup_copy					; copy all dil O2 ratios
+	lfsr	FSR1,opt_dil_He_ratio			; load FSR1 with base address of opt_dil_He_ratio
+	rcall	deco_setup_copy					; copy all dil He ratios
+	lfsr	FSR1,opt_dil_type				; load FSR1 with base address of opt_dil_type
+	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									; done
+
+
+;-----------------------------------------------------------------------------
+; Setup everything to enter CCR / pSCR Dive Mode - Part 2
+;
 dive_boot_cc_part2:
 	; revoke sensors from usage if they do not have a valid calibration
 	bsf		use_O2_sensor1
-	bsf		use_O2_sensor2
-	bsf		use_O2_sensor3
 	btfss	sensor1_calibrated_ok
 	bcf		use_O2_sensor1
+
+	bsf		use_O2_sensor2
 	btfss	sensor2_calibrated_ok
 	bcf		use_O2_sensor2
+
+	bsf		use_O2_sensor3
 	btfss	sensor3_calibrated_ok
 	bcf		use_O2_sensor3
 
  IFDEF _external_sensor
 	; check for external HUD/ppO2 Monitor
-	btfss	optical_input				; do we have an optical input?
+	btfss	ext_input_optical			; do we have an optical input?
 	bra		dive_boot_cc_part2_1		; NO
-	btfsc	sensor1_active				; YES - copy valid flags from HUD/ppO2 Monitor
+	btfsc	sensor1_active				; YES - process flags from HUD/ppO2 Monitor
 	bsf		use_O2_sensor1				;     - ...
 	btfsc	sensor2_active				;     - ...
 	bsf		use_O2_sensor2				;     - ...
@@ -2816,13 +3094,14 @@
 dive_boot_cc_part2_1:
 	; In pSCR mode, only settings 0 (calculated ppO2) and 1 (ppO2 from sensors) are defined.
 	; In case we still have 3 (auto SP) selected out of previous CCR mode, we reset to 0.
-	btfss	FLAG_pscr_mode
-	bra		dive_boot_cc_part2_2
-	movff	opt_ccr_mode,WREG			; =0: Fixed SP (CCR) / calculated SP (pSCR), =1: Sensor, =2: Auto SP
+	btfss	FLAG_pscr_mode				; in pSCR mode?
+	bra		dive_boot_cc_part2_2		; NO
+	movff	opt_ccr_mode,WREG			; YES - get mode (=0: Fixed SP (CCR) / calculated SP (pSCR), =1: Sensor, =2: Auto SP)
 	sublw	.2							; opt_ccr_mode = 1 (Auto SP)?
-	bnz		dive_boot_cc_part2_2
-	movlw	.0
-	movff	WREG,opt_ccr_mode
+	bnz		dive_boot_cc_part2_2		; NO  - ok
+	movlw	.0							; YES - revert to calculated SP
+	movff	WREG,opt_ccr_mode			; ...
+
 dive_boot_cc_part2_2:
 	bsf		event_SP_change				; set setpoint event flag
 
@@ -2832,33 +3111,50 @@
 	btfsc	FLAG_ccr_mode				; in CCR mode?
 	movff	opt_setpoint_cbar+0,WREG	; YES - get value of setpoint 1 into WREG
 	movff	WREG,char_I_const_ppO2		; write setpoint to deco engine
+
  IFDEF _external_sensor
 	call	transmit_setpoint			; transmit current setpoint from WREG (in cbar) to external electronics
-	goto	calc_deko_divemode_sensor	; read & process sensor data (and return)
+	goto	calc_deko_divemode_sensor	; process sensor readings and return
  ELSE
 	return								; done
  ENDIF
 
  ENDIF	; _ccr_pscr
 
+
 ;=============================================================================
-
+dmode3	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Initialize Dive Mode
+;
 diveloop_boot:
 	; do the basic initialization
-	call	restart_set_modes_and_flags
-
-	; stop accelerometer and compass
-	call	I2C_sleep_compass
+	call	restart_set_modes_and_flags	; basic settings depending on deco mode
+
+	; save on energy
+	call	I2C_sleep_compass			; stop accelerometer and compass
 
 	; do an early initialization of all deco engine output variables to
 	; avoid glitches in the display outputs during deco engine start-up
 	call	deco_init_output_vars;		; (C-code)
 	banksel	common						; back to bank common
 
+	; configure screen layout
+	TSTOSC	opt_layout					; alternative layout enabled?
+	bsf		alt_layout_active			; YES - start with alternative layout
+
+	; configure tissue graphics
+	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
+
 	; reset max relative pressure (max depth)
 	bsf		reset_max_pressure			; request ISR to reset the max pressure
 
-
  IFDEF _min_depth_option
 	; reset the resettable min/max relative pressure (trip-wise min/max depth)
 	bsf		reset_trip_pressure			; request ISR to reset the resettable min/max pressure
@@ -2907,14 +3203,14 @@
 	movff	lo,char_O_deco_status		; bank-safe copy back to deco engine
 
 	; disable "fast forward" function
-	movlw	.0
-	movff	WREG,char_I_sim_advance_time
+	movlw	.0							; set fast forward to zero
+	movff	WREG,char_I_sim_advance_time; ...
 
 	; write last stop depth to deco engine
 	movff	opt_last_stop,char_I_last_stop_depth
 
 	; initialize max depth for apnoe mode
-	CLRI	apnoe_max_pressure
+	CLRI	apnoe_max_pressure			; reset to zero
 
 	; reset minimum temperature, ISR-safe 2 byte copy
 	SMOVII	temperature_cur,temperature_min
@@ -2931,7 +3227,6 @@
 
 	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
 
@@ -2958,8 +3253,9 @@
 	bra		diveloop_boot_0				; NO  - skip TR function initialization
 
 	banksel	int_IO_pressure_value
-	clrf	WREG						; clear WREG
-	bsf		WREG,int_not_avail_flag		; set   WREG to coding for integer numbers -> data not available
+
+	clrf	WREG						; set WREG to coding for integer numbers -> data not available
+	bsf		WREG,int_not_avail_flag		; ...
 	clrf	int_IO_pressure_value+0		; clear   low  byte   of 1st pressure reading value
 	movwf	int_IO_pressure_value+1		; copy to high byte   of 1st pressure reading value
 	clrf	int_IO_pressure_value+2		; clear   low  byte   of 2nd pressure reading value
@@ -2991,18 +3287,18 @@
  ENDIF
 
 	btfsc	FLAG_oc_mode				; in OC mode?
-	rcall	dive_boot_oc				; YES - add OC mode settings
+	call	dive_boot_oc				; YES - add OC mode settings
 
  IFDEF _ccr_pscr
 	btfsc	FLAG_ccr_mode				; in CCR mode?
-	rcall	dive_boot_cc				; YES - add CC mode settings
+	call	dive_boot_cc				; YES - add CC mode settings
 	btfsc	FLAG_ccr_mode				; in CCR mode?
-	rcall	dive_boot_cc_part2			; YES - add CC sensor and SP settings
+	call	dive_boot_cc_part2			; YES - add CC sensor and SP settings
 
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	rcall	dive_boot_cc				; YES - add CC mode settings
+	call	dive_boot_cc				; YES - add CC mode settings
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	rcall	dive_boot_cc_part2			; YES - add CC sensor and SP settings
+	call	dive_boot_cc_part2			; YES - add CC sensor and SP settings
  ENDIF
 
 	bcf		bailout_mode				; not in bailout mode
@@ -3039,12 +3335,18 @@
 
 
 ;=============================================================================
-
+dmode4	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Check all Sorts of Parameters and issue Warnings and Attentions if applicable
+;
 divemode_check_warnings:
 	movlw	.1							; one message at a time in alternative layout
 	btfss	alt_layout_active			; in alternative layout?
 	movlw	.2							; NO - two messages at a time in normal layout
-	cpfsgt	message_counter				; more than one (alt layout) / 2 (normal layout) messages currently active?
+	cpfsgt	message_counter				; had more than 1 / 2 messages in the last round?
 	bra		divemode_check_warnings1	; NO  - update messages every second
 
 ;										; YES - update every 4 seconds:
@@ -3054,30 +3356,26 @@
 ;	return								;             NO  - no update in this cycle
 ;	;bra	divemode_check_warnings1	;             YES - update messages
 
-										; NO  - update every 2 seconds
+										; YES - update every 2 seconds
 	btfsc	timebase_1sec				;     - on even second?
 	return								;       NO  - done
 	;bra	divemode_check_warnings1	;       YES - update messages
 
 divemode_check_warnings1:
-	; start a new message collection cycle
-	bcf		message_advice				; clear flag for messages of level advice
-	bcf		message_attention			; clear flag for messages of level attention
-	bcf		message_warning				; clear flag for messages of level warning
 	clrf	message_counter				; clear message counter
 
 	; messages sorted by severity: highest severity warnings first, then attentions, advices and last info
 
 	; warnings for all modes
-	call	check_warn_battery			; check if the battery level should be displayed/warned
-	rcall	check_depth_limit			; check current depth against set depth limit
-	call	check_divetimeout			; check and show the dive mode timeout (not actually a warning)
+	call	check_battery				; check battery status
+	rcall	check_depth_limit			; check current depth
+	call	check_divetimeout			; check dive timeout
 
 	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bra		divemode_check_warnings2	; YES
+	bra		divemode_check_warnings2	; YES - skip deco mode checks
 
 	btfsc	FLAG_gauge_mode				; in gauge mode?
-	bra		divemode_check_warnings2	; YES
+	bra		divemode_check_warnings2	; YES - skip deco mode checks
 
 	; warnings applicable only in deco modes
 
@@ -3085,49 +3383,43 @@
 	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
+	rcall	check_display_ftts			; show  fTTS time (or cave mode cTTS)
+	rcall	check_ppO2					; check ppO2
 
  IFDEF _external_sensor
-	btfss	o2_sensors_agree			; are the sensor values within the threshold range?
-	rcall	check_warn_sensors_disagree	; NO  - do further evaluation
-	btfsc	o2_sensors_agree			; are the sensor values within the threshold range?
-	bcf		o2_sensors_warning			; YES - clear flag for a new warning
+	rcall	check_ext_sensors			; check external sensors
  ENDIF
 
 	rcall	check_outside				; check of ZHL16 model violation
 
- IFDEF _helium
-	rcall	check_IBCD					; check for IBCD attention or warning
- ENDIF
-
+ IFDEF _ccr_pscr
 	btfsc	FLAG_ccr_mode				; in CCR mode?
 	rcall	check_OC_gas_avail			; YES - check if a breathable OC (bailout) gas is available
 	btfsc	FLAG_pscr_mode				; in pSCR mode?
 	rcall	check_OC_gas_avail			; YES - check if a breathable OC (bailout) gas is available
+ ENDIF
 
 	btfsc	decostop_active				; in deco mode?
-	rcall	check_and_store_sat_violation; YES - sets warnings, if required
+	rcall	check_saturation			; YES - check tissue saturation
 
 	rcall	check_mbubbles				; check for micro bubbles
-	rcall	check_cns_violation			; check CNS value and display it, if required
-	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_cns_violation_now		; check current     CNS value
+	rcall	check_cns_violation_eod		; check end-of-dive CNS value (needs to be done after check_cns_violation_now)
+	rcall	check_gas_needs				; check for gas needs
+	rcall	check_gas_change			; check for diluent or gas change advice
+
+ IFDEF _ccr_pscr
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	rcall	check_gas_density			; YES - check gas density
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	rcall	check_gas_density			; YES - check gas density
+ ENDIF
 
 	btfsc	use_aGF						; using alternative GF factors?
-	rcall	warn_agf					; YES - show memo
-
-	btfsc	sp_fallback					; in fallback condition due to O2 sensor failure?
-	rcall	warn_fallback				; YES - show a warning
-
-	btfsc	better_dil_available		; is a better diluent available?
-	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 a gas change advice
+	rcall	remind_agf_in_use			; YES - show reminder
 
 divemode_check_warnings2:
+
  IFDEF _rx_functions
 	btfss	tr_functions_activated		; TR functions activated?
 	bra		divemode_check_warnings3	; NO  - skip
@@ -3136,17 +3428,11 @@
  ENDIF
 
 divemode_check_warnings3:
-	; Display / clear the advice, attention or warning icon
-	btfsc	message_advice				; any message of level advice?
-	bsf		FLAG_TFT_sign_show			; YES
-	btfsc	message_attention			; any message of level attention?
-	bsf		FLAG_TFT_sign_show			; YES
-	btfsc	message_warning				; any message of level warning?
-	bsf		FLAG_TFT_sign_show			; YES
-	btfss	FLAG_TFT_sign_show			; any message of above levels?
-	bsf		FLAG_TFT_sign_clear 		; NO - clear sign
-
-	; Increment message page number
+
+	; compute if an advice / attention / warning sign shall be shown
+	rcall	divemode_check_sign
+
+	; increment message page number
 	incf	message_page,F				; increment page number
 	bcf		STATUS,C					; clear carry bit
 	movf	message_page,W				; get page number into WREG
@@ -3155,107 +3441,215 @@
 	cpfsgt	message_counter				; number of actual messages > message capacity ?
 	clrf	message_page				; NO - all messages could be shown, restart from first page next time
 
-	; Clear both rows of messages if there is nothing to show at all
+	; clear both rows of messages if there is nothing to show at all
 	tstfsz	message_counter				; any message to show?
 	bra		divemode_check_warnings4	; YES - look if second row needs to be cleared
 	bsf		FLAG_TFT_message_clear_both	; NO  - request clearing of left-over messages
 	return								;     - done
 
 divemode_check_warnings4:
-	; Clear 2nd row of messages if there is nothing to show (on this page)
+	; clear 2nd row of messages if there is nothing to show (on this page)
 	btfss	message_2nd_row_used		; does the 2nd row contain a message?
 	bsf		FLAG_TFT_message_clear_2nd	; NO - set flag to clear the 2nd row
 	return								; done
 
+
 ;-----------------------------------------------------------------------------
-
-	global	check_warn_battery
-check_warn_battery:
+; Helper Function - check if an Advice / Attention / Warning Sign shall be shown
+;
+divemode_check_sign:
+	; clear sign flags
+	bcf		sign_advice					; clear flag for showing advice    sign
+	bcf		sign_attention				; clear flag for showing attention sign
+	bcf		sign_warning				; clear flag for showing warning   sign
+
+	; check for new advices
+	movf	DM_flags_advc_det,W			; get current advices
+	andwf	DM_flags_advc_ack,W			; keep only those acknowledgments that have current advices
+	movwf	DM_flags_advc_ack			; store updated acknowledgments
+	xorwf	DM_flags_advc_det,W			; find advices that have not been acknowledged yet
+	tstfsz	WREG						; any new advice?
+	bsf		sign_advice					; YES - set flag for showing advice sign
+
+	; check for new attentions (1)
+	movf	DM_flags_att1_det,W			; get current attentions
+	andwf	DM_flags_att1_ack,W			; keep only those acknowledgments that have current attentions
+	movwf	DM_flags_att1_ack			; store updated acknowledgments
+	xorwf	DM_flags_att1_det,W			; find attentions that have not been acknowledged yet
+	tstfsz	WREG						; any new attention?
+	bsf		sign_attention				; YES - set flag for showing attention sign
+
+	; check for new attentions (2)
+	movf	DM_flags_att2_det,W			; get current attentions
+	andwf	DM_flags_att2_ack,W			; keep only those acknowledgments that have current attentions
+	movwf	DM_flags_att2_ack			; store updated acknowledgments
+	xorwf	DM_flags_att2_det,W			; find attentions that have not been acknowledged yet
+	tstfsz	WREG						; any new attention?
+	bsf		sign_attention				; YES - set flag for showing attention sign
+
+	; check for new attentions (3)
+	movf	DM_flags_att3_det,W			; get current attentions
+	andwf	DM_flags_att3_ack,W			; keep only those acknowledgments that have current attentions
+	movwf	DM_flags_att3_ack			; store updated acknowledgments
+	xorwf	DM_flags_att3_det,W			; find attentions that have not been acknowledged yet
+	tstfsz	WREG						; any new attention?
+	bsf		sign_attention				; YES - set flag for showing attention sign
+
+	; check for new warnings (1)
+	movf	DM_flags_war1_det,W			; get current warnings
+	andwf	DM_flags_war1_ack,W			; keep only those acknowledgments that have current warnings
+	movwf	DM_flags_war1_ack			; store updated acknowledgments
+	xorwf	DM_flags_war1_det,W			; find warnings that have not been acknowledged yet
+	tstfsz	WREG						; any new warning?
+	bsf		sign_warning				; YES - set flag for showing warning sign
+
+	; check for new warnings (2)
+	movf	DM_flags_war2_det,W			; get current warnings
+	andwf	DM_flags_war2_ack,W			; keep only those acknowledgments that have current warnings
+	movwf	DM_flags_war2_ack			; store updated acknowledgments
+	xorwf	DM_flags_war2_det,W			; find warnings that have not been acknowledged yet
+	tstfsz	WREG						; any new warning?
+	bsf		sign_warning				; YES - set flag for showing warning sign
+
+	; show or clear the advice / attention / warning sign
+	btfsc	sign_advice					; shall show advice sign?
+	bsf		FLAG_TFT_sign_show			; YES - show sign
+	btfsc	sign_attention				; shall show attention sign?
+	bsf		FLAG_TFT_sign_show			; YES - show sign
+	btfsc	sign_warning				; shall show warning sign?
+	bsf		FLAG_TFT_sign_show			; YES - show sign
+	btfss	FLAG_TFT_sign_show			; shall show any sign?
+	bsf		FLAG_TFT_sign_clear			; NO  - then clear the sign
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Check Battery Power
+;
+	global	check_battery
+check_battery:
+	bcf		warn_det_batt_low			; clear warning for battery low
 	movlw	battery_show_level+1		; get threshold for showing battery level, incremented by 1
 	cpfslt	batt_percent				; battery percentage ok?
-	return								; YES - no display, no warning
-	; Display Battery, but warn?
-	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 warning message for battery low (battery percent) and return
-
-
+	return								; YES - done
+	btfsc	battery_low_condition		; NO  - battery low condition detected?
+	bsf		warn_det_batt_low			;       YES - set warning for battery low
+	movf	active_customview,W			;     - get current custom view
+	xorlw	index_clock_batt_surfpress	;     - battery shown in custom view?
+	bnz		check_battery_mesg			;       NO  - show message
+	return								;       YES - do not show twice, done
+
+check_battery_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_battery_percent	; show message for battery low (battery percent) and return
+
+
+;-----------------------------------------------------------------------------
+; Show Dive Timeout Counter if Dive Time is not counted
+;
 check_divetimeout:
 	btfsc	count_divetime				; is dive time counted?
-	return								; YES - do nothing
-	incf	message_counter,F			; increase counter
-	goto	TFT_divetimeout				; show timeout counter (and return)
-
-
+	return								; YES - nothing to do, done
+	incf	message_counter,F			; NO  - increase message counter
+	goto	TFT_message_divetimeout		;     - show timeout counter and return
+
+
+;-----------------------------------------------------------------------------
+; Check ppO2 of all Gases / Diluents in use
+;
 check_ppO2:
  IFDEF _ccr_pscr
-	btfsc	FLAG_oc_mode				; are we in OC mode?
+	; check if breathing from the loop
+	btfsc	FLAG_oc_mode				; in OC mode?
 	bra		check_ppO2_1				; YES - continue with breathed gas
 	btfsc	bailout_mode				; NO  - in bailout?
 	bra		check_ppO2_1				;       YES - continue with breathed gas
-	; CCR / pSCR mode - checks on pure diluent
+	; CCR / pSCR mode - check the pure diluent
+	bcf		warn_det_ppO2_diluent		; clear warning   for pure diluent ppO2
+	bcf		attn_det_ppo2_diluent		; clear attention for pure diluent ppO2
 	MOVII	int_O_pure_ppO2,mpr			; get value and attention/warning flags for the pure diluent
-	btfsc	hi,int_warning_flag			; is there a ppO2 low or high warning on the pure diluent?
-	rcall	check_ppO2_dw				; YES - show warning and return on next line
+	btfsc	hi,int_warning_flag			; ppO2 of the pure diluent in warning state?
+	bra		check_ppO2_dil_warn			; YES - show warning
 	btfsc	hi,int_attention_flag		; ppO2 of the pure diluent in attention state?
-	rcall	check_ppO2_da				; YES - show attention and return on next line
- ENDIF
-	; all modes - checks on breathed gas (OC or from loop)
+	bra		check_ppO2_dil_attn			; YES - show attention
+	bra		check_ppO2_1				; continue with checking breathed gas
+
+check_ppO2_dil_warn:
+	bsf		warn_det_ppO2_diluent		; set warning   for pure diluent ppO2
+	rcall	check_ppO2_show_mesg		; show ppO2 message
+	bra		check_ppO2_1				; continue with checking breathed gas
+
+check_ppO2_dil_attn:
+	bsf		attn_det_ppo2_diluent		; set attention for pure diluent ppO2
+	rcall	check_ppO2_show_mesg		; show ppO2 message
+	;bra	check_ppO2_1				; continue with checking breathed gas
+ ENDIF	; _ccr_pscr
+
 check_ppO2_1:
+	; all modes - check breathed gas (OC or loop)
+	bcf		attn_det_ppo2_breathed		; clear attention for breathed ppO2
+	bcf		warn_det_ppO2_breathed		; clear warning   for breathed ppO2
 	MOVII	int_O_breathed_ppO2,mpr		; get value and attention/warning flags for the breathed gas
 	btfsc	hi,int_attention_flag		; breathed ppO2 in attention state (when in loop mode, no attention will be generated)?
-	bra		check_ppo2_display_a		; YES - set attention flag and show ppO2
-	btfsc	hi,int_low_flag				; breathed ppO2 too low?
-	bra		check_ppO2_low				; YES - record the warning and show ppO2
-	btfsc	hi,int_high_flag			; breathed ppO2 too high?
-	bra		check_ppO2_high				; YES - record the warning and show ppO2
-	TSTOSS	opt_showppo2				; show ppO2 anyhow? (0 = no, 1 = show always)
-	return								; NO  - no warnings, no show - done
-	bra		check_ppO2_common_2			; YES - but only when in OC or bailout...
-check_ppO2_low:
+	bra		check_ppO2_breath_attn		; YES - set attention flag and show ppO2
+	btfsc	hi,int_low_flag				; NO  - breathed ppO2 too low?
+	bra		check_ppO2_breath_warn_low	;       YES - record the warning and show ppO2
+	btfsc	hi,int_high_flag			;       NO  - breathed ppO2 too high?
+	bra		check_ppO2_breath_warn_high	;             YES - record the warning and show ppO2
+	bra		check_ppO2_breath_ok		;             NO  - ppO2 is ok
+
+check_ppO2_breath_attn:
+	bsf		attn_det_ppo2_breathed		; set attention for breathed ppO2
+	bra		check_ppO2_show				; show ppO2 message
+
+check_ppO2_breath_warn_low:
 	movlw	d'4'						; set type of alarm (ppO2 low)
-	bra		check_ppO2_common			; continue with common part
-check_ppO2_high:
+	bra		check_ppO2_breath_common	; continue with common part
+
+check_ppO2_breath_warn_high:
 	movlw	d'5'						; set type of alarm (ppO2 high)
-check_ppO2_common:
+	;bra	check_ppO2_breath_common	; continue with common part
+
+check_ppO2_breath_common:
 	movwf	alarm_type					; copy alarm type to alarm register
-	bsf		event_occured				; set event   flag
-	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
+	bsf		event_occured				; set event flag
+	bsf		warn_det_ppO2_breathed		; set warning for breathed ppO2
+	bra		check_ppO2_show				; show ppO2 message
+
+check_ppO2_breath_ok:
+	TSTOSS	opt_showppo2				; shall always show ppO2 (0 = no, 1 = yes)
+	return								; NO  - done
+	;bra	check_ppO2_show				; YES - show ppO2 message
+
+check_ppO2_show:
  IFDEF _ccr_pscr
-	btfsc	bailout_mode				; are we in bailout mode?
-	bra		check_ppo2_display			; YES - show
- ENDIF
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		check_ppO2_show_1			; YES - show ppO2 message
+	btfsc	bailout_mode				; in bailout mode?
+	bra		check_ppO2_show_1			; YES - show ppO2 message
 	return								; NO  - in loop mode, ppO2 is already shown via setpoint display
-check_ppo2_display_a:
-	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?
-	bra		check_ppO2_b				; NO
-	return								; YES - do not show twice (in custom view and in warning area)
-check_ppO2_b:
-	movlw	index_pscr_info				; index of custom view with pSCR data
-	cpfseq	active_customview			; ppO2 shown?
-	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 for diluent ppO2
-check_ppO2_da:
-	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 warning message for breathed gas or diluent ppO2 and return
-
-
+ ENDIF
+check_ppO2_show_1:
+	movf	active_customview,W			; get current custom view
+	xorlw	index_ppo2_ead_end_cns		; ppO2 shown already via custom view?
+	bz		check_ppO2_done				; YES - done
+	movf	active_customview,W			; get current custom view (again)
+	xorlw	index_pscr_info				; ppO2 shown already via custom view?
+	bz		check_ppO2_done				; YES - done
+	;bra	check_ppO2_show_mesg		; NO  - show ppO2 message
+
+check_ppO2_show_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_ppo2			; show ppO2 message and return
+
+check_ppO2_done:
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Show fTTS Message
+;
 check_display_ftts:
  IFDEF _ccr_pscr
 	btfsc	bailout_mode				; in bailout mode?
@@ -3265,464 +3659,685 @@
 	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
+	bra		check_display_ftts_mesg		;       YES - show fTTS
 	return								;       NO  - no fTTS computed, done
-check_display_ftts_1:
+
+check_display_ftts_mesg:
 	incf	message_counter,F			; increase counter
-	goto	TFT_show_ftts				; show @+x time
-
-
-	global	check_cns_violation
-check_cns_violation:
-	; Check if CNS should be displayed
+	goto	TFT_message_ftts			; show @+x time
+
+
+;-----------------------------------------------------------------------------
+; check current CNS Value
+;
+	global	check_cns_violation_now
+check_cns_violation_now:
+	bcf		warn_det_cns_current		; clear warning   for CNS
+	bcf		attn_det_cns_current		; clear attention for CNS
 	movff	int_O_CNS_current+1,WREG	; get current CNS, high byte
 	btfsc	WREG,int_warning_flag		; warning flag set?
-	bra		check_cns_violation_1		; YES - issue warning
-	btfsc	WREG,int_attention_flag		; NO  - attention flag set?
-	bra		check_cns_violation_2		;       YES - issue attention
-	return								;       NO  - done
-check_cns_violation_1:
-	bsf		message_warning				; show warning   sign for CNS
-check_cns_violation_2:
-	bsf		message_attention			; show attention sign for CNS
+	bra		check_cns_violation_now_warn; YES - show a warning
+	btfsc	WREG,int_attention_flag		; attention flag set?
+	bra		check_cns_violation_now_attn; YES - show an attention
+	return								; NO  - done
+
+check_cns_violation_now_warn:
+	bsf		warn_det_cns_current		; set warning for CNS
+	bra		check_cns_violation_now_mesg; show message
+
+check_cns_violation_now_attn:
+	bsf		attn_det_cns_current		; set attention for CNS
+	;bra	check_cns_violation_now_mesg; show message
+
+check_cns_violation_now_mesg:
  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?
-	bra		check_cns_violation_3		; NO
-	return								; YES - do not show twice (in custom view and in warning area)
+	movf	active_customview,W			; get current custom view
+	xorlw	index_ppo2_ead_end_cns		; CNS shown?
+	bz		check_cns_violation_now_done; YES - done
  ENDIF
-check_cns_violation_3:
-	movlw	index_CNS					; index of custom view with CNS values
-	cpfseq	active_customview			; CNS shown?
-	bra		check_cns_violation_4		; NO
-	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 attention/warning message for CNS and return
-
-
-	global	check_eod_cns_violation		; check end-of-dive CNS values
-check_eod_cns_violation:
-	movff	int_O_CNS_current+1,WREG	; get current CNS, high byte
-	btfsc	WREG,int_warning_flag		; current CNS value in warning state?
-	return								; YES - inhibit end-of-dive warning if current CNS is already in warning
+	movf	active_customview,W			; get current custom view (again)
+	xorlw	index_CNS					; CNS shown?
+	bz		check_cns_violation_now_done; YES - done
+	incf	message_counter,F			; NO  - increase counter
+	goto	TFT_message_cns				;     - show message and return
+
+check_cns_violation_now_done:
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; check end-of-Dive CNS Value
+;
+	global	check_cns_violation_eod
+check_cns_violation_eod:
+	bcf		attn_det_cns_eod			; clear attention for end-of-dive CNS
+	btfsc	warn_det_cns_current		; current CNS value in warning state?
+	return								; YES - inhibit end-of-dive CNS checks if current CNS is already in warning
+	;bra	check_cns_violation_eod_norm; NO  - check normal plan
+
+check_cns_violation_eod_norm:
 	movff	int_O_CNS_norm+1,WREG		; get CNS at end of dive in normal plan, high byte
 	btfsc	WREG,int_invalid_flag		; flag for invalid value set?
-	bra		check_eod_cns_violation1	; YES - continue with checking the other CNS value
+	bra		check_cns_violation_eod_alt	; YES - continue with checking alternative plan
 	btfsc	WREG,int_warning_flag		; NO  - flag for warning set?
-	bra		check_eod_cns_violation2	;       YES - issue warning
-check_eod_cns_violation1:				;       NO  - continue with checking the other CNS value
+	bra		check_cns_violation_eod_warn;       YES - show message
+	;bra	check_cns_violation_eod_alt	;       NO  - check alternative plan
+
+check_cns_violation_eod_alt:
 	movff	int_O_CNS_alt+1,WREG		; get CNS at end of dive in alternative plan, high byte
 	btfsc	WREG,int_invalid_flag		; flag for invalid value set?
-	return								; YES - done with CNS checking
+	return								; YES - done
 	btfsc	WREG,int_warning_flag		; NO  - flag for warning set?
-	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 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			; show warning message for end-of-dive CNS and return
-
-
-	global	check_and_store_sat_violation
-check_and_store_sat_violation:
-	movff	int_O_lead_supersat+1,WREG		; get upper byte of leading tissue's supersaturation
-	btfss	WREG,int_warning_flag			; check if the warning flag is set
-	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					;     - 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 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 saturation
-	bsf		message_attention				; show attention sign for saturation
-	incf	message_counter,F				; increase counter
-	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
+	bra		check_cns_violation_eod_warn;       YES - show message
+	return								;       NO  - done
+
+check_cns_violation_eod_warn:
+	bsf		attn_det_cns_eod			; set attention(!) for end-of-dive CNS
+	movf	active_customview,W			; get current custom view
+	xorlw	index_CNS					; CNS shown?
+	bz		check_cns_violation_eod_done; YES - done
+	incf	message_counter,F			; NO  - increase message counter
+	goto	TFT_message_cns_eod			;     - show message for end-of-dive CNS and return
+
+check_cns_violation_eod_done:
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Check current Tissue Supersaturation
+;
+	global	check_saturation
+check_saturation:
+	bcf		attn_det_saturation			; clear attention for saturation
+	bcf		warn_det_saturation			; clear warning   for saturation
+	bcf		attn_det_ibcd				; clear attention for IBCD
+	movff	int_O_lead_supersat+1,WREG	; get upper byte of leading tissue's supersaturation
+	btfss	WREG,int_warning_flag		; warning flag set?
+	bra		check_saturation_1			; 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		warn_det_saturation			;     - set   warning
+	bra		check_saturation_mesg		;     - show saturation message
+
+check_saturation_1:
+	btfss	WREG,int_attention_flag		; attention flag set?
+	bra		check_saturation_2			; NO  - continue with checking for IBCD
+	bsf		attn_det_saturation			; YES - set   attention
+	bra		check_saturation_mesg		;     - show saturation message
+
+check_saturation_2:
+ IFDEF _helium
+	TSTOSS	opt_enable_IBCD				; IBCD warning activated?
+	bra		check_saturation_3			; NO  - continue with checking deco info
+	movff	char_O_deco_warnings,WREG	; YES - get the deco warnings vector
+	btfss	WREG,IBCD_warning			;     - IBCD warning flag set?
+	bra		check_saturation_3			;       NO  - continue with checking deco info
+	bsf		attn_det_ibcd				;       YES - set attention
+	bra		check_saturation_mesg		;           - show saturation message
+ ENDIF
+
+check_saturation_3:
+	btfss	divemode					; in dive mode?
+	return								; NO  - done
  IFDEF _ccr_pscr
-	btfsc	bailout_mode					; YES - in bailout mode?
-	return									;       YES - done, return (deco zone flag is not updated when in bailout mode)
+	btfsc	bailout_mode				; YES - in bailout mode?
+	return								;       YES - done (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
-	btfsc	use_aGF							;             YES - using alternative GF factors?
-	return									;                   YES - suppress deco zone info
-	btfsc	alt_layout_active				;                   NO  - in alternative layout?
-	return									;                         YES - suppress deco zone info
-	incf	message_counter,F				;                         NO  - increase counter
-	goto	TFT_info_deco					;                             - show deco info
-
-
+	movff	char_O_deco_info,WREG		;       NO  - get the deco info vector
+	btfss	WREG,deco_zone				;             deco zone flag set?
+	return								;             NO  - done
+	btfsc	use_aGF						;             YES - using alternative GF factors?
+	return								;                   YES - suppress deco zone info
+	btfsc	alt_layout_active			;                   NO  - in alternative layout?
+	return								;                         YES - suppress deco zone info
+	incf	message_counter,F			;                         NO  - increase message counter
+	goto	TFT_message_deco_info		;                             - show deco info and return
+
+check_saturation_mesg:
+ IFDEF _helium
+	btfss	attn_det_ibcd				; IBCD detected?
+	bra		check_saturation_mesg_1		; NO  - show saturation message
+	incf	message_counter,F			; YES - increase message counter
+	call	TFT_message_IBCD			;     - show IBCD message
+ ENDIF
+check_saturation_mesg_1:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_saturation		; show saturation message and return
+
+
+;-----------------------------------------------------------------------------
+; Check Depth Limit
+;
 check_depth_limit:
-	bcf		depth_limit_exceeded		; clear warning flag by default
+	bcf		warn_det_depth_limit		; clear warning by default
 	movff	opt_max_depth,WREG			; get depth limit
 	cpfsgt	depth_meter					; current depth > depth limit?
-	return								; NO
-	bsf		depth_limit_exceeded		; YES - set flag for depth limit exceeded
-	incf	message_counter,F			;     - increase counter
-	bsf		message_warning				;     - show warning sign    for depth
-	goto	TFT_warning_depth			;     - show warning message for depth
-
-
+	return								; NO  - done
+	bsf		warn_det_depth_limit		; YES - set warning
+	incf	message_counter,F			;     - increase message counter
+	goto	TFT_message_depth_limit		;     - show message
+
+
+;-----------------------------------------------------------------------------
+; Check Bühlmann Model Violation
+;
 check_outside:
+	bcf		warn_det_outside			; clear warning
+	bcf		attn_det_outside			; clear attention
 	movff	char_O_deco_warnings,WREG	; bank-safe copy of deco warnings
-	btfss	WREG,outside_warning_lock	; are we outside of the ZH-L16 model?
+	btfss	WREG,outside_warning		; currently outside the ZH-L16 model?
+	bra		check_outside_1				; NO
+	bsf		warn_det_outside			; YES - set warning
+	bra		check_outside_mesg			;     - show message
+
+check_outside_1:
+	btfss	WREG,outside_warning_lock	; had been outside of the ZH-L16 model?
 	return								; NO  - done
-	incf	message_counter,F			; YES - increase counter
-	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				;     - show warning sign for outside
-	goto	TFT_warning_outside			;     - show warning/attention message for outside and return
-
-
+	bsf		attn_det_outside			; YES - set attention
+	;bra	check_outside_mesg			;     - show message
+
+check_outside_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_outside			; show message and return
+
+
+;-----------------------------------------------------------------------------
+; Check raised Probability for Micro-Bubbles
+;
 	global	check_mbubbles
 check_mbubbles:
+	bcf		warn_det_microbubble		; clear warning
+	bcf		attn_det_microbubble		; clear attention
 	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
-	btfsc	WREG,mbubble_warning		; are we in micro bubbling zone right now?
-	bra		check_mbubbles_warn			; YES
-	btfss	WREG,mbubble_warning_lock	; were we in micro bubbling zone?
+	btfss	WREG,mbubble_warning		; currently in micro bubbling zone?
+	bra		check_mbubbles_1			; NO
+	bsf		warn_det_microbubble		; YES - set warning
+	bra		check_mbubbles_mesg			;     - show message
+
+check_mbubbles_1
+	btfss	WREG,mbubble_warning_lock	; had been in micro bubbling zone?
 	return								; NO  - done
-check_mbubble_att						; YES - attention level
-	incf	message_counter,F			; increase counter
-	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				; show warning sign    for micro bubbles
-	goto	TFT_warning_mbubbles		; show warning message for micro bubbles (and return)
+	bsf		attn_det_microbubble		; YES - set attention
+	;bra	check_mbubbles_mesg			;     - show message
+
+check_mbubbles_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_mbubbles		; show message and return
+
+
+ IFDEF _ccr_pscr
+;-----------------------------------------------------------------------------
+; Check Gas Density
+;
+check_gas_density:
+	TSTOSS	opt_gas_density_check		; shall check gas density?
+	return								; NO - done
+	bcf		warn_det_gas_density		; YES - clear attention for gas density by default
+	bcf		attn_det_gas_density		;     - clear warning   for gas density by default
+	movff	int_O_gas_density+1,WREG	;     - get upper byte of current gas density
+	btfsc	WREG,int_warning_flag		;     - warning flag set?
+	bra		check_gas_density_warn		;       YES - generate a warning
+	btfsc	WREG,int_attention_flag		;       NO  - attention flag set?
+	bra		check_gas_density_attn		;             YES - generate an attention
+	;bra	check_gas_density_ok		;             NO  - gas density ok
+
+check_gas_density_ok:
+	bcf		shown_gas_density_attn		; re-arm custom view show-up for warning
+	bcf		shown_gas_density_warn		; re-arm custom view show-up for attention
+	return								; done
+
+check_gas_density_warn:
+	bsf		warn_det_gas_density		; set warning
+	bcf		shown_gas_density_attn		; re-arm custom view show-up for attention
+	btfsc	shown_gas_density_warn		; has the custom view been shown before on warning level?
+	bra		check_gas_density_mesg		; YES - do not show the gas needs custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	bra		check_gas_density_mesg		;       YES - do not show it now
+	bsf		shown_gas_density_warn		;       NO  - set custom view as shown now
+	bra		check_gas_density_cv		;           - show gas needs custom view
+
+check_gas_density_attn:
+	bsf		attn_det_gas_density		; set attention
+	bcf		shown_gas_density_warn		; re-arm custom view show-up for warning
+	btfsc	shown_gas_density_attn		; has the custom view been shown before on attention level?
+	bra		check_gas_density_mesg		; YES - do not show the gas needs custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	bra		check_gas_density_mesg		;       YES - do not show it now
+	bsf		shown_gas_density_attn		;       NO  - set custom view as shown now
+	;bra	check_gas_density_cv		;           - show gas needs custom view
+
+check_gas_density_cv:
+	movlw	index_ppo2_ead_end_cns		; get  custom view number of gas density
+	call	dive_customview_show		; show custom view
+	;bra	check_gas_density_mesg		; show message
+
+check_gas_density_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_gas_density		; show gas density message and return
+
+
+;-----------------------------------------------------------------------------
+; Check if an OC Bailout Gas is available
+;
+check_OC_gas_avail:
+	bcf		warn_det_no_bo_gas			; clear warning by default
+	tstfsz	best_gas_number				; is a breathable OC (bailout) gas available?
+	return								; YES - a breathable gas is available, done
+	btfsc	bailout_mode				; NO  - in bailout?
+	return								;       YES - suppress warning, done
+	bsf		warn_det_no_bo_gas			;       NO  - set warning for no bailout gas
+	incf	message_counter,F			;           - increase message counter
+	goto	TFT_message_no_BO_gas		;           - show message and return
+
+ ENDIF	; _ccr_pscr
 
 
  IFDEF _cave_mode
 
+;-----------------------------------------------------------------------------
+; Check Cave Profile Storage Usage
+;
 check_cavemode:
+	bcf		warn_det_cave_shut_down		; clear warning   by default
+	bcf		attn_det_cave_shut_down		; clear attention by default
 	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
+	btfss	cave_mode					;       NO  - cave mode switched on?
+	return								;             NO  - do not show info
+	btfsc	alt_layout_active			;             YES - alternative layout active?
+	return								;                   YES - suppress info message
+	;bra	check_cavemode_mesg			;                   NO  - show cave mode active info
+
+check_cavemode_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_cave_mode		; show cave mode 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
+	btfss	cave_mode					; has the cave mode been switched on again meanwhile?
+	bsf		warn_det_cave_shut_down		; NO  - set warning level
 	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
+	bsf		attn_det_cave_shut_down		; YES - set attention level
+	bra		check_cavemode_mesg			; show message
 
 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
+	bsf		attn_det_cave_shut_down		; YES - set an attention
+	bra		check_cavemode_mesg			;     - show message
 
  ENDIF	; _cave_mode
 
 
-warn_agf:
-	incf	message_counter,F			; increase counter
-	goto	TFT_warning_agf				; show aGF reminder (and return)
-
-warn_fallback:
-	incf	message_counter,F			; increase counter
-	bsf		message_warning				; show warning sign    for fallback
-	goto	TFT_warning_fallback		; show warning message for fallback and return
-
-;=============================================================================
+;-----------------------------------------------------------------------------
+; Show aGF Reminder
+;
+remind_agf_in_use:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_agf				; show aGF reminder and return
+
+
+;-----------------------------------------------------------------------------
+; Check better Gas / Diluent Advice
+;
+check_gas_change:
+	bcf		advc_det_change_gas			; clear advice by default
+ IFDEF _ccr_pscr
+	btfsc	better_dil_available		; is a better diluent available?
+	bra		check_gas_change_mesg		; YES - show a gas change advice
+ ENDIF
+	btfsc	better_gas_available		; is a better gas     available?
+	bra		check_gas_change_mesg		; YES - show a gas change advice
+	return								; NO  - done
+
+check_gas_change_mesg:
+	bsf		advc_det_change_gas			; set advice
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_gas_change		; show advice and return
+
 
  IFDEF _rx_functions
 
+;-----------------------------------------------------------------------------
+; Check SAC and Swap-Tank Advice
+;
 check_tr_messages:
+	bcf		attn_det_sac_rate			; clear SAC attention by default
+	bcf		advc_det_switch_tank		; clear switch advice by default
 	btfss	count_divetime				; is the dive time counted, i.e. deeper than dive threshold?
-	return								; NO  - suppress messages
+	return								; NO  - suppress check
 	movff	int_O_SAC_measured+1,WREG	; YES - bank-safe copy of measured SAC rate
 	btfss	WREG,int_attention_flag		;     - attention flag set?
-	bra		check_tr_messages2			;       NO  - skip
+	bra		check_tr_messages_chk_swap	;       NO  - continue with checking for swap advice
 	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 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 attention message for SAC rate
-check_tr_messages2:
+	bra		check_tr_messages_chk_swap	;       NO  - continue with checking for swap advice
+	bsf		attn_det_sac_rate			;       YES - set attention for SAC rate
+	movf	active_customview,W			;           - get current custom view
+	xorlw	index_pressures_SAC			;           - SAC rate shown?
+	bz		check_tr_messages_chk_swap	;             YES - do not show twice, continue with swap advice
+	;bra	check_tr_messages_mesg_sac	;             NO  - show SAC message
+
+check_tr_messages_mesg_sac:
+	incf	message_counter,F			; increase message counter
+	call	TFT_message_sac				; show message for SAC rate
+	;bra	check_tr_messages_chk_swap	; continue with switch advice
+
+check_tr_messages_chk_swap:
 	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    for switching tanks
-	goto	TFT_advice_switch			;     - show advice message for switching tanks and return
-
+	return								; NO  - done
+	;bra	check_tr_messages_mesg_swap	; YES - show swap message
+
+check_tr_messages_mesg_swap:
+	bsf		advc_det_switch_tank		; set advice
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_switch_tanks	; show message for switching tanks and return
+
+
+;-----------------------------------------------------------------------------
+; Check Transmitter States
+;
 check_tr_functions:
-	clrf	xmitter_flags_mesg				; set all messages as not shown yet
-	movlw	index_pressures_SAC				; index of custom view pressure readings
-	cpfseq	active_customview				; pressure readings shown?
-	bra		check_tr_functions_tr1			; NO  - continue with checking transmitter 1
-	bsf		pres_customview_shown			; YES - suppress redraw by faking it has already been redrawn
-check_tr_functions_tr1:
+	; check transmitter 1
 	movff	char_I_pressure_stat+0,WREG		; get status of 1st pressure reading
 	rcall	check_tr_functions_helper1		; check for transmitter 1 lost
 	rcall	check_tr_functions_helper2		; check for transmitter 1 low battery
 	movff	int_IO_pressure_value+1,WREG	; get high byte of 1st pressure reading
 	rcall	check_tr_functions_helper3		; check for transmitter 1 pressure warning
 	rcall	check_tr_functions_helper4		; check for transmitter 1 pressure attention
-check_tr_functions_tr2:
+	; check transmitter 2
 	movff	char_I_pressure_stat+1,WREG		; get status of 2nd pressure reading
 	rcall	check_tr_functions_helper5		; check for transmitter 2 lost
 	rcall	check_tr_functions_helper6		; check for transmitter 2 low battery
 	movff	int_IO_pressure_value+3,WREG	; get high byte of 2nd pressure reading
 	rcall	check_tr_functions_helper7		; check for transmitter 2 pressure warning
 	rcall	check_tr_functions_helper8		; check for transmitter 2 pressure attention
-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 - 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 - show warning sign for pressure
-	incf	message_counter,F				;     - increase counter
-	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 - show attention sign for pressure
-	incf	message_counter,F				;     - increase counter
-	goto	TFT_attention_pres_reading		;     - show attention message for pressure reading and return
+
+	; results for transmitter
+	btfsc	attn_det_xmit1_bat				; do we have a transmitter 1 attention?
+	bra		check_tr_functions_xmitter_mesg	; YES - show transmitter message
+	btfsc	attn_det_xmit2_bat				; do we have a transmitter 2 attention?
+	bra		check_tr_functions_xmitter_mesg	; YES - show transmitter message
+check_tr_functions_1:
+	btfsc	warn_det_pressure1				; do we have a pressure 1 warning?
+	bra		check_tr_functions_pres_mesg	; YES - show pressure message
+	btfsc	warn_det_pressure2				; do we have a pressure 2 warning?
+	bra		check_tr_functions_pres_mesg	; YES - show pressure message
+	btfsc	attn_det_pressure1				; do we have a pressure 1 attention?
+	bra		check_tr_functions_pres_mesg	; YES - show pressure message
+	btfsc	attn_det_pressure2				; do we have a pressure 2 attention?
+	bra		check_tr_functions_pres_mesg	; YES - show pressure message
+	return									; done
+
+check_tr_functions_xmitter_mesg:
+	incf	message_counter,F				; increase message counter
+	call	TFT_message_transmitter			; show transmitter message
+	bra		check_tr_functions_1			; continue with pressure messages
+
+check_tr_functions_pres_mesg:
+	incf	message_counter,F				; increase message counter
+	goto	TFT_message_pressure			; show pressure message and return
 
 check_tr_functions_helper1:
 	btfsc	WREG,char_transmitter_lost		; transmitter 1 lost?
 	bra		check_tr_functions_helper1a		; YES - show transmitter attention message
-	bcf		transmitter1_lost				; NO  - clear flag for old lost attention
+	bcf		shown_xmit1_lost				; NO  - clear flag for old message
 	return									;     - done
 check_tr_functions_helper1a:
-;	bsf		show_transmitter_attention		; show transmitter attention
-	btfsc	transmitter1_lost				; is it a new message?
+	btfsc	shown_xmit1_lost				; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter1_lost				; YES - memorize it's an old message now
-	bra		check_tr_functions_show_cv		;     - show custom view
+	bsf		shown_xmit1_lost				; YES - memorize it's an old message now
+	rcall	check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_helper2:
 	btfsc	WREG,char_transmitter_low_bat	; transmitter 1 low battery?
 	bra		check_tr_functions_helper2a		; YES - show transmitter attention message
-	bcf		transmitter1_battery			; NO  - clear flag for old battery attention
+	bcf		shown_xmit1_battery				; NO  - clear flag for old message
+	bcf		attn_det_xmit1_bat				;     - clear transmitter 1 attention
 	return									;     - done
 check_tr_functions_helper2a:
-	bsf		show_transmitter_attention		; show transmitter attention
-	btfsc	transmitter1_battery			; is it a new message?
+	bsf		attn_det_xmit1_bat				; set transmitter 1 attention
+	btfsc	shown_xmit1_battery				; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter1_battery			; YES - memorize it's an old message now
-	bra		check_tr_functions_show_cv		;     - show custom view
+	bsf		shown_xmit1_battery				; YES - memorize it's an old message now
+	rcall	check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_helper3:
 	btfsc	WREG,int_warning_flag			; transmitter 1 pressure warning?
 	bra		check_tr_functions_helper3a		; YES - show pressure reading message as warning
-	bcf		transmitter1_pres_warn			; NO  - clear flag for old warning
+	bcf		shown_xmit1_pres_warn			; NO  - clear flag for old message
+	bcf		warn_det_pressure1				;     - clear pressure 1 warning
 	return									;     - done
 check_tr_functions_helper3a:
-	bsf		show_pres_warning				; show pressure warning
-	btfsc	transmitter1_pres_warn			; is it a new message?
+	bsf		warn_det_pressure1				; set pressure 1 warning
+	btfsc	shown_xmit1_pres_warn			; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter1_pres_warn			; YES - memorize it's an old message now
+	bsf		shown_xmit1_pres_warn			; YES - memorize it's an old message now
 	bra		check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_helper4:
 	btfsc	WREG,int_attention_flag			; transmitter 1 pressure attention?
 	bra		check_tr_functions_helper4a		; YES - show pressure reading message as attention
-	bcf		transmitter1_pres_att			; NO  - clear flag for old attention
+	bcf		shown_xmit1_pres_attn			; NO  - clear flag for old message
+	bcf		attn_det_pressure1				;     - clear pressure 1 attention
 	return									;     - done
 check_tr_functions_helper4a
-	bsf		show_pres_attention				; show pressure attention
-	btfsc	transmitter1_pres_att			; is it a new message?
+	bsf		attn_det_pressure1				; set pressure 1 attention
+	btfsc	shown_xmit1_pres_attn			; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter1_pres_att			; YES - memorize it's an old message now
+	bsf		shown_xmit1_pres_attn			; YES - memorize it's an old message now
 	bra		check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_helper5:
 	btfsc	WREG,char_transmitter_lost		; transmitter 2 lost?
 	bra		check_tr_functions_helper5a		; YES - show transmitter attention message
-	bcf		transmitter2_lost				; NO  - clear flag for old lost attention
+	bcf		shown_xmit2_lost				; NO  - clear flag for old lost message
 	return									;     - done
 check_tr_functions_helper5a:
-;	bsf		show_transmitter_attention		; show transmitter attention
-	btfsc	transmitter2_lost				; is it a new message?
+	btfsc	shown_xmit2_lost				; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter2_lost				; YES - memorize it's an old message now
+	bsf		shown_xmit2_lost				; YES - memorize it's an old message now
 	bra		check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_helper6:
 	btfsc	WREG,char_transmitter_low_bat	; transmitter 2 low battery?
 	bra		check_tr_functions_helper6a		; YES - show transmitter attention message
-	bcf		transmitter2_battery			; NO  - clear flag for old battery attention
+	bcf		shown_xmit2_battery				; NO  - clear flag for old battery message
+	bcf		attn_det_xmit2_bat				;     - clear transmitter 2 attention
 	return									;     - done
 check_tr_functions_helper6a:
-	bsf		show_transmitter_attention		; show transmitter attention
-	btfsc	transmitter2_battery			; is it a new message?
+	bsf		attn_det_xmit2_bat				; set transmitter 2 attention
+	btfsc	shown_xmit2_battery				; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter2_battery			; YES - memorize it's an old message now
+	bsf		shown_xmit2_battery				; YES - memorize it's an old message now
 	bra		check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_helper7:
 	btfsc	WREG,int_warning_flag			; transmitter 2 pressure warning?
 	bra		check_tr_functions_helper7a		; YES - show pressure reading message as warning
-	bcf		transmitter2_pres_warn			; NO  - clear flag for old warning
+	bcf		shown_xmit2_pres_warn			; NO  - clear flag for old message
+	bcf		warn_det_pressure2				;     - clear pressure 2 warning
 	return									;     - done
 check_tr_functions_helper7a:
-	bsf		show_pres_warning				; show pressure warning
-	btfsc	transmitter2_pres_warn			; is it a new message?
+	bsf		warn_det_pressure2				; set pressure 2 warning
+	btfsc	shown_xmit2_pres_warn			; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter2_pres_warn			; YES - memorize it's an old message now
+	bsf		shown_xmit2_pres_warn			; YES - memorize it's an old message now
 	bra		check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_helper8:
 	btfsc	WREG,int_attention_flag			; transmitter 2 pressure attention?
 	bra		check_tr_functions_helper8a		; YES - show pressure reading message as attention
-	bcf		transmitter2_pres_att			; NO  - clear flag for old attention
+	bcf		shown_xmit2_pres_attn			; NO  - clear flag for old message
+	bcf		attn_det_pressure2				;     - clear pressure 2 attention
 	return									;     - done
 check_tr_functions_helper8a
-	bsf		show_pres_attention				; show pressure attention
-	btfsc	transmitter2_pres_att			; is it a new message?
+	bsf		attn_det_pressure2				; set pressure 2 attention
+	btfsc	shown_xmit2_pres_attn			; is it a new message?
 	return									; NO  - do not show the pressure readings custom view again
-	bsf		transmitter2_pres_att			; YES - memorize it's an old message now
+	bsf		shown_xmit2_pres_attn			; YES - memorize it's an old message now
 	;bra	check_tr_functions_show_cv		;     - show custom view
 
 check_tr_functions_show_cv:
-	btfsc	pres_customview_shown			; is the pressure readings custom view not shown yet?
-	return									; NO  - already shown, 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
-
-;=============================================================================
-
+	btfsc	custom_view_locked				; NO  - custom view locked?
+	return									;       YES - do not show now
+	movlw	index_pressures_SAC				;       NO  - get  custom view number of pressure readings
+	goto	dive_customview_show			;           - show custom view and return
+
+ ENDIF	; _rx_functions
+
+
+;-----------------------------------------------------------------------------
+; Check Gas Needs
+;
 check_gas_needs:
-	banksel	int_O_gas_need_pres
+	bcf		attn_det_gas_needs			; clear attention by default
+	bcf		warn_det_gas_needs			; clear warning   by default
+	banksel	int_O_gas_need_pres			; switch to bank where int_O_gas_need_pres is stored
 	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
 	iorwf	int_O_gas_need_pres+5,W		; inclusive or with high byte from pres need of 3rd tank
 	iorwf	int_O_gas_need_pres+7,W		; inclusive or with high byte from pres need of 4th tank
 	iorwf	int_O_gas_need_pres+9,W		; inclusive or with high byte from pres need of 5th tank
-	banksel	common
-	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
+	banksel	common						; back to bank common
+	btfsc	WREG,int_invalid_flag		; any invalid flag set?
+	bra		check_gas_needs_ok			; YES - no further checking required
+	btfsc	WREG,int_warning_flag		; NO  - any gas with pres_need >= pres_fill ?
 	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_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
+	btfsc	WREG,int_attention_flag		;       NO  - any gas with pres_need >= pres_fill * threshold ?
+	bra		check_gas_needs_attn		;             YES - generate an attention
+	;bra	check_gas_needs_ok			;             NO  - gas needs ok
+
+check_gas_needs_ok:
+	bcf		shown_gas_needs_warn		; re-arm custom view show-up for warning
+	bcf		shown_gas_needs_attn		; re-arm custom view show-up for attention
+	return								; done
 
 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?
-	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?
-	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
-
-;=============================================================================
+	bsf		warn_det_gas_needs			; set warning
+	bcf		shown_gas_needs_attn		; re-arm custom view show-up for attention
+	btfsc	shown_gas_needs_warn		; has the custom view been shown before on warning level?
+	bra		check_gas_needs_mesg		; YES - do not show the gas needs custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	bra		check_gas_needs_mesg		;       YES - do not show it now
+	bsf		shown_gas_needs_warn		;       NO  - set custom view as shown now
+	bra		check_gas_needs_cv			;           - show gas needs custom view
+
+check_gas_needs_attn:
+	bsf		attn_det_gas_needs			; set attention
+	bcf		shown_gas_needs_warn		; re-arm custom view show-up for warning
+	btfsc	shown_gas_needs_attn		; has the custom view been shown before on attention level?
+	bra		check_gas_needs_mesg		; YES - do not show the gas needs custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	bra		check_gas_needs_mesg		;       YES - do not show it now
+	bsf		shown_gas_needs_attn		;       NO  - set custom view as shown now
+	;bra	check_gas_needs_cv			;           - show gas needs custom view
+
+check_gas_needs_cv:
+	movlw	index_gas_needs_ascent		; get  custom view number of gas needs
+	call	dive_customview_show		; show custom view
+	;bra	check_gas_needs_mesg		; show message
+
+check_gas_needs_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_gas_needs		; show message for gas needs and return
+
 
  IFDEF _external_sensor
 
-check_warn_sensors_disagree:
-	incf	message_counter,F			; increase counter
-	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 warning message for sensor disagree and return
-
- ENDIF
+;-----------------------------------------------------------------------------
+; Check external Sensors for Loss and Divergence
+;
+check_ext_sensors:
+	btfsc	warn_det_sensors_lost		; all sensors lost?
+	bra		check_ext_sensors_lost_all	; YES - show a warning and return
+
+	btfsc	attn_det_sensor1_lost		; sensor 1 lost?
+	rcall	check_ext_sensors_lost_1	; YES - show an attention
+
+	btfsc	attn_det_sensor2_lost		; sensor 2 lost?
+	rcall	check_ext_sensors_lost_2	; YES - show an attention
+
+	btfsc	attn_det_sensor3_lost		; sensor 3 lost?
+	rcall	check_ext_sensors_lost_3	; YES - show an attention
+
+	btfsc	warn_det_sensors_div		; sensor values divergence?
+	bra		check_ext_sensors_diverg	; YES - show a warning and return
+
+	return								; done
+
+check_ext_sensors_lost_all:
+	btfsc	shown_sensors_lost			; has the custom view been shown before?
+	bra		warn_sensors_lost_mesg		; YES - do not show the sensor custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	bra		warn_sensors_lost_mesg		;       YES - do not show it now
+	bsf		shown_sensors_lost			;       NO  - set it as shown now
+	movlw	index_ppo2_sensors			;           - get  custom view number of sensors
+	call	dive_customview_show		;           - show custom view
+	;bra	warn_sensors_lost_mesg		;           - show message
+
+warn_sensors_lost_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_fallback		; show message and return
+
+check_ext_sensors_lost_1:
+	btfsc	shown_sensor1_fail			; has the custom view been shown before for sensor 1?
+	return								; YES - do not show the sensor custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	return								;       YES - do not show it now
+	bsf		shown_sensor1_fail			;       NO  - set it as shown now
+	bra		check_ext_sensors_show_cv	;           - show sensor custom view
+
+check_ext_sensors_lost_2:
+	btfsc	shown_sensor2_fail			; has the custom view been shown before for sensor 2?
+	return								; YES - do not show the sensor custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	return								;       YES - do not show it now
+	bsf		shown_sensor2_fail			;       NO  - set it as shown now
+	bra		check_ext_sensors_show_cv	;           - show sensor custom view
+
+check_ext_sensors_lost_3:
+	btfsc	shown_sensor3_fail			; has the custom view been shown before for sensor 3?
+	return								; YES - do not show the sensor custom view again
+	btfsc	custom_view_locked			; NO  - custom view locked?
+	return								;       YES - do not show it now
+	bsf		shown_sensor3_fail			;       NO  - set it as shown now
+	;bra	check_ext_sensors_show_cv	;           - show sensor custom view
+
+check_ext_sensors_show_cv:
+	movlw	index_ppo2_sensors			; get  custom view number of sensors
+	goto	dive_customview_show		; show custom view and return
+
+check_ext_sensors_diverg:
+	btfsc	shown_sensors_diverg			; has the custom view been shown before for divergence?
+	bra		check_ext_sensors_diverg_mesg	; YES - do not show the sensor custom view again
+	btfsc	custom_view_locked				; NO  - custom view locked?
+	bra		check_ext_sensors_diverg_mesg	;       YES - do not show it now
+	bsf		shown_sensors_diverg			;       NO  - set it as shown now
+	movlw	index_ppo2_sensors				;           - get  custom view number of sensors
+	call	dive_customview_show			;           - show custom view
+	;bra	check_ext_sensors_diverg_mesg	;           - show message
+
+check_ext_sensors_diverg_mesg:
+	incf	message_counter,F			; increase message counter
+	goto	TFT_message_divergence		; show message and return
+
+ ENDIF	; _external_sensor
+
 
 ;=============================================================================
-
- IFDEF _helium
-
-check_IBCD:
-	TSTOSS	opt_enable_IBCD				; IBCD warning activated?
-	return								; NO  - done
-	movff	char_O_deco_warnings,WREG	; YES - get deco warnings vector
-	btfss	WREG,IBCD_warning			;       IBCD warning flag set?
-	return								;       NO  - return
-	incf	message_counter,F			;       YES - increase counter
-	goto	TFT_warning_IBCD			;             write warning to display
-
- ENDIF
-
+dmode5	CODE
 ;=============================================================================
 
-check_OC_gas_avail:
-	tstfsz	best_gas_number				; is a breathable OC (bailout) gas available?
-	return								; YES (>0) - a breathable gas is available
- 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		; show advice (and return)
-
-
+
+;-----------------------------------------------------------------------------
+; Restart the Deco Engine
+;
 	global	restart_deco_engine
 	global	restart_deco_engine_wo_ceiling
 restart_deco_engine:
@@ -3730,8 +4345,9 @@
 	bsf		int_O_ceiling+1,char_invalid_flag			; invalidate ceiling (int_O_ceiling has its invalid flag on a char's position!)
 
 restart_deco_engine_wo_ceiling:
-	banksel	char_O_deco_gas								; switch to bank where the shared "_O_" variables are stored
+	banksel	char_O_deco_gas								; switch to bank where the stops table is stored
 	bsf		char_O_deco_gas+0,char_invalid_flag			; invalidate deco data (stop table data)
+	banksel	int_O_NDL_norm								; switch to bank where the shared "_O_" variables are stored
 	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)
@@ -3742,7 +4358,7 @@
 	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
+	banksel	int_O_NDL_alt								; switch to bank where the shared "_O_" variables are stored
 	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)
@@ -3757,19 +4373,24 @@
 	banksel	common										; bank to bank common
 	bsf		new_deco_data_avail							; set flag for new NDL and deco data available to have the display updated
 
-	return
+	return												; done
+
 
 ;=============================================================================
-; Simulator Mode
+dmode6	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Start-up Simulator Mode
 ;
-	global	do_demo_divemode
-do_demo_divemode:
+	global	demo_divemode
+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 ?
+	btfsc	option_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					; restore tissue pressures and CNS value after finishing simulator use
@@ -3795,6 +4416,8 @@
 
 	; branch into dive mode
 	bsf		divemode						; activate  dive mode (to be done after simulator mode is activated)
-	goto	diveloop						; branch to dive mode code
+	goto	diveloop						; start dive mode
+
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/divemode.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/divemode.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File divemode.inc                         combined next generation V3.08.5
+;   File divemode.inc                       * combined next generation V3.09.4g
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -8,8 +8,9 @@
 ; HISTORY
 ;  2011-08-15 : [mH] moving from OSTC code
 
-	extern	set_dive_modes
+
 	extern	diveloop
+	extern	check_dive_modes_surf
 	extern	apnoe_calc_maxdepth
 	extern	check_gas_best
 	extern	setup_gas_registers
@@ -29,17 +30,24 @@
 ; row    = 0...239
 ; column = 0...159 (x2)
 
+
 ; Divemode has multiple layouts but basicly splits the screen into 3 rows:
 ;   - upper  content row: depth, max depth, dive time, etc.
 ;   - custom content row: selectable views
 ;   - bottom content row: temp, gas, ndl, tts, etc.
 
+
+;-----------------------------------------------------------------------------
 ; I. The upper content row (0-99)
+;-----------------------------------------------------------------------------
+
 ;    The top row is divided in 2 areas:
 ;    - header : holds the titles (mask)
 ;    - content: holds the values
 
-;******* upper content / header row *******
+
+;-----------------------------------------------------------------------------
+; Upper Content / Header Row
 
 #DEFINE dm_mask_depth_row						.0
 #DEFINE dm_mask_depth_column					.2
@@ -58,9 +66,11 @@
 ;   - max depth and warning messages
 ;   - dive time, apnea dive times and warning icon
 
-;******* upper content / content row / 1st col *******
 
-; GLOBAL
+;-----------------------------------------------------------------------------
+; Upper Content / Content Row / 1st Column
+
+; Global
 #DEFINE dm_offset								.14								;  14  start of content row
 
 ; Depth - full meters or feet
@@ -87,17 +97,18 @@
 
 ; ascend/descend rate - graphical display
 #DEFINE dm_velocity_graph_top					dm_offset+.10					;  24
-#DEFINE dm_velocity_graph_lft					dm_depth_rgt_large+.3			;  61		+2 / 61
+#DEFINE dm_velocity_graph_lft					dm_depth_rgt_large+.3			;  61
 #DEFINE dm_velocity_graph_bot					dm_velocity_graph_top+.70		;  94
-#DEFINE dm_velocity_graph_rgt					dm_upcnt_2ndcol-.3				;  72		-2 / 72
-#DEFINE dm_velocity_graph_width					.10								;  12		12
+#DEFINE dm_velocity_graph_rgt					dm_upcnt_2ndcol-.3				;  72
+#DEFINE dm_velocity_graph_width					.10								;  12
 
 
-;******* upper content / content row / 2nd col *******
+;-----------------------------------------------------------------------------
+; Upper Content / Content Row / 2nd Column
 
 ; Start column
-#DEFINE dm_upcnt_2ndcol							.74								;  74 - with vertical speed indicator enabled
-#DEFINE dm_upcnt_2ndcol_nvsi					.64								;  64 - with vertical speed indicator disabled
+#DEFINE dm_upcnt_2ndcol							.74								;  74 (vertical speed indicator  enabled)
+#DEFINE dm_upcnt_2ndcol_nvsi					.64								;  64 (vertical speed indicator disabled)
 
 ; max depth
 #DEFINE dm_max_depth_row						dm_offset						;  14
@@ -114,7 +125,7 @@
 
 ; Warning area (combined)
 #DEFINE dm_warning_row							dm_offset+.36					;  50
-#DEFINE dm_warning_column						dm_upcnt_2ndcol+.23				;  97	ex +.0
+#DEFINE dm_warning_column						dm_upcnt_2ndcol+.23				;  97
 #DEFINE dm_warning_bot							dm_warning_row+.49				;  99
 #DEFINE dm_warning_rgt							dm_warning_column+.62			; 136
 #DEFINE dm_warning_length						.9								;      total string length in number of characters
@@ -132,7 +143,8 @@
 #DEFINE dm_warning2_rgt							dm_warning_rgt					; 136
 
 
-;******* upper content / content row / 3rd col *******
+;-----------------------------------------------------------------------------
+; Upper Content / Content Row / 3rd Column
 
 ; Dive time
 #DEFINE dm_divetime_row							dm_offset						;  14
@@ -170,17 +182,22 @@
 #DEFINE dm_total_apnoe_text_row					dm_apnoe_total_divetime_row-.11	;  53
 #DEFINE dm_total_apnoe_text_col					.132							; 132
 
-; I. end of the upper content row. (0-99)
+
+;-----------------------------------------------------------------------------
+; End of the Upper Content Row (0-99)
 
 ; 1px space between the 1st and 2nd content rows
 #DEFINE dm_sep_1_2_row							dm_offset+.86					; 100
 
 
+;-----------------------------------------------------------------------------
 ; II. custom/selectable content row
+;-----------------------------------------------------------------------------
 
 ;   The custom view display area is: 101,163,0,159 (t,b,l,r), or 0,101->159,163
 
-;******* Custom View: Global *******
+;-----------------------------------------------------------------------------
+; Custom View: Global
 
 #DEFINE dm_customview_row						dm_offset+.87					; 101
 #DEFINE dm_customview_column					.0								;   0
@@ -188,7 +205,8 @@
 #DEFINE dm_customview_rgt						.159							; 159
 
 
-;******* Custom View: Avg depth, stopwatch and avg depth *******
+;-----------------------------------------------------------------------------
+; Custom View: avg Depth, Stopwatch and avg Depth
 
 #DEFINE dm_custom_avr_stop_title_row			dm_customview_row+.1			; 102
 #DEFINE dm_custom_avr_stop_row					dm_customview_row+.16			; 117
@@ -197,7 +215,8 @@
 #DEFINE dm_custom_avr_stop_column3				.118							; 118
 
 
-;******* Custom View: Decompressions stops *******
+;-----------------------------------------------------------------------------
+; Custom View: Decompressions Stops
 
 ; Title
 #DEFINE dm_custom_decoplan_title_row			dm_customview_row				; 101
@@ -222,7 +241,8 @@
 #DEFINE dm_cust_dstop_7th_stop_column			dm_cust_dstop_6th_stop_column	; 111
 
 
-;******* Custom View: Time, Battery, Surface Pressure *******
+;-----------------------------------------------------------------------------
+; Custom View: Time, Battery, Surface Pressure
 
 ; Clock
 #DEFINE dm_custom_clock_title_row				dm_customview_row+.1			; 102
@@ -231,8 +251,8 @@
 
 ; Battery
 #DEFINE dm_custom_battery_title_row				dm_customview_row+.1			; 102
-#DEFINE dm_custom_battery_volt_row				dm_customview_row+.16			; 117
-#DEFINE dm_custom_battery_percent_row			dm_custom_ead_row+.23			; 140
+#DEFINE dm_custom_battery_volt_row				dm_customview_row+.15			; 116
+#DEFINE dm_custom_battery_percent_row			dm_custom_ead_row+.21			; 138
 #DEFINE dm_custom_battery_column				.62								;  62
 
 ; Surface Pressure
@@ -241,7 +261,8 @@
 #DEFINE dm_custom_surfpres_column				.95								;  95
 
 
-;****** Custom View: ppO2, EAD/ENDS and CNS *******
+;-----------------------------------------------------------------------------
+; Custom View: ppO2, EAD/ENDS and CNS
 
 ; ppO2
 #DEFINE dm_custom_ppo2_title_row				dm_customview_row+.1			; 102
@@ -250,9 +271,9 @@
 
 ; EAD/END
 #DEFINE dm_custom_eadend_title_row				dm_customview_row+.1			; 102
-#DEFINE dm_custom_ead_row						dm_customview_row+.16			; 117
+#DEFINE dm_custom_ead_row						dm_customview_row+.14			; 115
 #DEFINE dm_custom_ead_column					.50								;  50
-#DEFINE dm_custom_end_row						dm_custom_ead_row+.23			; 140
+#DEFINE dm_custom_end_row						dm_custom_ead_row+.21			; 138
 #DEFINE dm_custom_end_column					dm_custom_ead_column			;  50
 
 ; CNS
@@ -261,7 +282,8 @@
 #DEFINE dm_custom_cns_column					.115							; 115
 
 
-;****** Custom View: tripple CNS *******
+;-----------------------------------------------------------------------------
+; Custom View: tripple CNS
 
 #DEFINE dm_custom_cns3_title_row				dm_customview_row+.1			; 102
 #DEFINE dm_custom_cns3_row						dm_customview_row+.16			; 117
@@ -270,7 +292,8 @@
 #DEFINE dm_custom_cns3_column3					.115							; 115
 
 
-;****** Custom View: Ceiling, Tissues, (current GF)
+;-----------------------------------------------------------------------------
+; Custom View: Ceiling, Tissues, (current GF)
 
 ; Ceiling
 #DEFINE dm_custom_ceiling_title_row				dm_customview_row+.1			; 102
@@ -294,7 +317,8 @@
 #DEFINE dm_custom_tissue_diagram_frame_spacing	.8								;   8
 
 
-;******* Custom View: GF-lo/hi, aGF-lo/hi, current GF value *******
+;-----------------------------------------------------------------------------
+; Custom View: GF-lo/hi, aGF-lo/hi, current GF Value
 
 ; Title
 #DEFINE dm_custom_gf_title_row					dm_customview_row+.1			; 102
@@ -304,17 +328,18 @@
 #DEFINE dm_custom_gf_column3					.95								;  95
 
 
-;******* Custom View: Compass *******
+;-----------------------------------------------------------------------------
+; Custom View: Compass
 
 ; Title
 #DEFINE dm_custom_compass_mask_row				dm_customview_row				; 101
 #DEFINE dm_custom_compass_mask_column			.65								;  65
 
 ; Head and arrows
-#DEFINE dm_custom_compass_head_row				dm_customview_row+.39			; 140
+#DEFINE dm_custom_compass_head_row				dm_customview_row+.37			; 138
 #DEFINE dm_custom_compass_head_column			.62								;  62
 #DEFINE dm_custom_compass_ldir_column			.5								;   5
-#DEFINE dm_custom_compass_rdir_column			.140							; 140
+#DEFINE dm_custom_compass_rdir_column			.138							; 138
 
 ; Ruler
 #DEFINE dm_custom_compass_graph_row				dm_customview_row				; 101
@@ -328,7 +353,8 @@
 #DEFINE dm_custom_compass_tick_bot_bot			dm_custom_compass_graph_row+.33	; 134
 
 
-;******* Custom View: O2 Sensor Values *******
+;-----------------------------------------------------------------------------
+; Custom View: O2 Sensor Values
 
 #DEFINE dm_custom_hud_title_row					dm_customview_row+.1			; 102
 #DEFINE dm_custom_hud_row						dm_customview_row+.16			; 117
@@ -337,17 +363,19 @@
 #DEFINE dm_custom_hud_sensor3_column			.118							; 118
 
 
-;******* Custom View: Gas Needs *******
+;-----------------------------------------------------------------------------
+; Custom View: Gas Needs
 
 #DEFINE dm_custom_gas_mask_row					dm_customview_row				; 101
 #DEFINE dm_custom_gas_row1						dm_customview_row+.14			; 115
 #DEFINE dm_custom_gas_row2						dm_customview_row+.37			; 138
-#DEFINE dm_custom_gas_column_title				.29								;  29
+#DEFINE dm_custom_gas_column_title				.20								;  20
 #DEFINE dm_custom_gas_column1					.5								;   5
 #DEFINE dm_custom_gas_column2					.85								;  85
 
 
-; ******* Custom View: Tank Pressures *******
+;-----------------------------------------------------------------------------
+; Custom View: Tank Pressures
 
 #DEFINE dm_custom_tankdata_mask_row				dm_customview_row+.1			; 102
 #DEFINE dm_custom_tankdata_row					dm_customview_row+.16			; 117
@@ -356,7 +384,8 @@
 #DEFINE dm_custom_tankdata_SAC_col				.56								;  56
 
 
-;******* Custom View: Sensor Check *******
+;-----------------------------------------------------------------------------
+; Custom View: Sensor Check
 
 #DEFINE dm_custom_s_check_title_row				dm_customview_row+.1			; 102
 #DEFINE dm_custom_s_check_row					dm_customview_row+.18			; 119
@@ -365,7 +394,8 @@
 #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,7 +403,8 @@
 #DEFINE dm_custom_pscr_ratio_column				.105							; 105
 
 
-;******* Custom View: cave TTS *******
+;-----------------------------------------------------------------------------
+; Custom View: cave TTS
 
 #DEFINE dm_custom_cave_title_row				dm_customview_row+.1			; 102
 #DEFINE dm_custom_cave_title_column1			.2								;   2
@@ -386,15 +417,18 @@
 #DEFINE dm_custom_cave_data_column3				.114							; 114
 
 
-
-; II. end of the custom content row (101-163)
+;-----------------------------------------------------------------------------
+; End of the Custom Content Row (101-163)
 
 ; 1px space between the 2nd and 3rd content rows
 #DEFINE dm_sep_2_3_row							dm_offset+.150					; 164
 
 
+;-----------------------------------------------------------------------------
 ; III. The 3rd content row contains temperature, active gas, NDL/TTS time,
-; simulator menu, active/dil gas, decostop, Apnea surface time and max depth
+;      simulator menu, active/dil gas, decostop, Apnea surface time and max depth
+;-----------------------------------------------------------------------------
+
 ;  The content row contains 2 columns:
 ;   - temperature, gas names
 ;   - NDL/TTS, DecoStop
@@ -405,7 +439,8 @@
 #DEFINE dm_3rdrow_rgt							.159							; 159
 
 
-;******* Bottom content / 1st col *******
+;-----------------------------------------------------------------------------
+; Bottom Content / 1st Column
 
 ; Temperature
 #DEFINE dm_temp_row								dm_3rdrow_top-.3				; 162
@@ -439,7 +474,9 @@
 #DEFINE dm_sign_bot_alt							dm_sign_row_alt+.38				; 231
 #DEFINE dm_sign_rgt_alt							dm_sign_col_alt+.22				;  74
 
-;******* Bottom content / 2nd col *******
+
+;-----------------------------------------------------------------------------
+; Bottom content / 2nd Column
 
 ; 1st Deco Stop
 #DEFINE dm_decostop_row_norm					dm_3rdrow_top					; 165
@@ -485,7 +522,8 @@
 #DEFINE dm_gassep_column						.78								;  78
 
 
-;******* Bottom content / Apnea mode *******
+;-----------------------------------------------------------------------------
+; Bottom Content / Apnea Mode
 
 #DEFINE dm_apnoe_last_max_depth_text_row		.192							; 192
 #DEFINE dm_apnoe_last_max_depth_text_col		.20								;  20
@@ -498,7 +536,9 @@
 #DEFINE dm_apnoe_surface_time_column			.80								;  80
 
 
-;******* Bottom content / Gauge mode *******
+;-----------------------------------------------------------------------------
+; Bottom content / Gauge mode
+
 #DEFINE dm_gauge_max_depth_text_row				.192
 #DEFINE dm_gauge_max_depth_text_col				.25
 #DEFINE dm_gauge_max_depth_row					.207
@@ -510,8 +550,9 @@
 #DEFINE dm_gauge_avg_depth_col					.85
 
 
-
-; IV. The last set of parameters is for the menus displayed in dive mode
+;-----------------------------------------------------------------------------
+; IV. The last set of parameters is for the menu displayed in dive mode
+;-----------------------------------------------------------------------------
 
 ; Divemode menu
 #DEFINE dm_menu_row								.164							; 164  upper row, the frame's top line is the separator
--- a/src/eeprom_rs232.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/eeprom_rs232.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File eeprom_rs232.asm                     combined next generation V3.08.8
+;   File eeprom_rs232.asm                   * combined next generation V3.09.4n
 ;
 ;   Internal EEPROM, RS232
 ;
@@ -21,20 +21,20 @@
 
 	extern	lt2942_charge_done
 
+
+;=============================================================================
+eeprom	CODE
+;=============================================================================
+
 ;-----------------------------------------------------------------------------
 ;
-;			for EEPROM Macros and Memory Map, see eeprom_rs232.inc
+; EEPROM Functions - for EEPROM Macros and Memory Map, see eeprom_rs232.inc
 ;
 ;-----------------------------------------------------------------------------
 
-ee_rs232	CODE
-
-;=============================================================================
-;   EEPROM Functions
-;=============================================================================
 
 ;-----------------------------------------------------------------------------
-; read from internal EEPROM
+; Read from internal EEPROM
 ;
 ; Input:   EEADRH:EEADR = EEPROM address
 ; Output:  EEDATA
@@ -42,13 +42,14 @@
 ;
 	global	read_eeprom
 read_eeprom:
-	bcf		EECON1,EEPGD					;
-	bcf		EECON1,CFGS						;
-	bsf		EECON1,RD						;
-	return
+	bcf		EECON1,EEPGD					; access data EEPROM
+	bcf		EECON1,CFGS						; ...
+	bsf		EECON1,RD						; initiate reading
+	return									; done
+
 
 ;-----------------------------------------------------------------------------
-; write into internal EEPROM
+; Write into internal EEPROM
 ;
 ; Input:   EEADRH:EEADR = EEPROM address
 ;          EEDATA = byte to write
@@ -56,10 +57,10 @@
 ;
 	global	write_eeprom
 write_eeprom:
-	bcf		EECON1,EEPGD					;
-	bcf		EECON1,CFGS						;
-	bsf		EECON1,WREN						;
-	bcf		INTCON,GIE						; disable interrupts for the next 5 instructions
+	bcf		EECON1,EEPGD					; access data EEPROM
+	bcf		EECON1,CFGS						; ...
+	bsf		EECON1,WREN						; enable writing
+	bcf		INTCON,GIE						; disable interrupts
 	movlw	0x55							; unlock sequence
 	movwf	EECON2							; ...
 	movlw	0xAA							; ...
@@ -67,13 +68,14 @@
 	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
+	bra		write_eeprom_loop				; NO  - loop waiting
+	bcf		EECON1,WREN						; YES - disable writing
+	bsf		INTCON,GIE						;     - re-enable interrupts 
+	return									;     - done
+
 
 ;-----------------------------------------------------------------------------
-; these 2 functions are meant to be used through the macros, see eeprom_rs232!
+; EEPROM read and write Functions to be used via Macros
 ;
 	global	eeprom_read_common
 eeprom_read_common:
@@ -97,44 +99,46 @@
 	bra		eeprom_write_common_loop		; NO  - loop
 	return									; YES - done
 
+
 ;-----------------------------------------------------------------------------
-; REad OSTC serial number
+; Read OSTC Serial Number
 ;
 	global	eeprom_serial_number_read
 eeprom_serial_number_read:
-	EEPROM_II_READ eeprom_ostc_serial,mpr
-	return
+	EEPROM_II_READ eeprom_ostc_serial,mpr	; read serial number
+	return									; done
+
 
 ;-----------------------------------------------------------------------------
-; Read and write dive number offset
+; Read and Write Dive Number Offset
 ;
 	global	eeprom_log_offset_read
 eeprom_log_offset_read:
-	EEPROM_II_READ	eeprom_log_offset,mpr
-	return
+	EEPROM_II_READ	eeprom_log_offset,mpr	; read log offset
+	return									; done
 
 	global	eeprom_log_offset_write
 eeprom_log_offset_write:
-	EEPROM_II_WRITE mpr,eeprom_log_offset
-	return
+	EEPROM_II_WRITE mpr,eeprom_log_offset	; write log-offset
+	return									; done
 
 
 ;-----------------------------------------------------------------------------
-; Read and write total number of dives
+; Read and Write total Number of Dives
 ;
 	global	eeprom_total_dives_read
 eeprom_total_dives_read:
-	EEPROM_II_READ	eeprom_num_dives,mpr
-	return
+	EEPROM_II_READ	eeprom_num_dives,mpr	; read total dives
+	return									; done
 
 	global	eeprom_total_dives_write
 eeprom_total_dives_write:
-	EEPROM_II_WRITE mpr,eeprom_num_dives
-	return
+	EEPROM_II_WRITE mpr,eeprom_num_dives	; write total dives
+	return									; done
 
 
 ;-----------------------------------------------------------------------------
-; Read and write the battery gauge and type
+; Read and Write the Battery Type and Gauge Reading
 ;
 	global	eeprom_battery_gauge_read
 eeprom_battery_gauge_read:
@@ -143,7 +147,7 @@
 	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
+	return													; done
 
 	global	eeprom_battery_gauge_write
 eeprom_battery_gauge_write:
@@ -152,16 +156,28 @@
 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
+	return													; done
 
 
 ;-----------------------------------------------------------------------------
-; Read and write the deco status
+; Memorize the Checksum of the Firmware in the update Storage
+;
+	global	eeprom_memorize_fw_checksum
+eeprom_memorize_fw_checksum:
+	EXT_FLASH_ADDR 0x3E000D									; address firmware ID at 0x3E000D
+	FLASH_CW_READ_0x40										; read    firmware ID to WREG
+	movff	WREG,buffer+.5									; append  firmware ID to checksum
+	EEPROM_RR_WRITE buffer,eeprom_fw_chksum_current,.6		; do a  6 byte write  to EEPROM
+	return													; done
+
+
+;-----------------------------------------------------------------------------
+; Read and Write the Deco Status
 ;
 	global	eeprom_deco_data_read
 eeprom_deco_data_read:
 
-	btfsc	RCON,POR												; was there a power outage ?
+	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
@@ -220,98 +236,115 @@
 	return															;   done
 
 
-
 ;=============================================================================
-;   RS232 Functions
+rs232	CODE
 ;=============================================================================
 
-	global	disable_ir_s8
-disable_ir_s8:
-	banksel	TXSTA2						; select bank for IO register access
-	clrf	TXSTA2
-	clrf	RCSTA2
-	banksel	common						; back to bank common
-	bcf		PIE3,RC2IE					; disable RC2 INT
-	bcf		ir_power					; IR off
-	bcf		mcp_power					; power-down instrumentation amp
-	bsf		s8_npower					; power-down S8 digital interface
-	bcf		s8_digital_avail			; digital S8 interface not available
-	return
+;-----------------------------------------------------------------------------
+;
+; RS232 Functions
+;
+;-----------------------------------------------------------------------------
 
 
-	global	enable_ir_s8
-enable_ir_s8:
+;-----------------------------------------------------------------------------
+; Switch-On the IR/S8 Port
+;
+	global	enable_ir_s8_analog
+enable_ir_s8_analog:
 	;initialize serial port2 (TRISG2)
-	btfsc	analog_o2_input				; do we have an analog input?
-	bra		enable_s8					; YES - search for S8 digital input
-										; NO  - start      IR digital input
-	banksel	BAUDCON2					;     - select bank for IO register access
-	movlw	b'00100000'					;     - BRG16=0, inverted for IR
-	movwf	BAUDCON2
-	movlw	b'00100000'					;     - BRGH=0, SYNC=0
-	movwf	TXSTA2
-	movlw	.102						;     - SPBRGH:SPBRG = .102 : 2403 BAUD @ 16 MHz
-	movwf	SPBRG2
-	clrf	SPBRGH2
-	movlw	b'10010000'
-	movwf	RCSTA2
-	banksel	common						;     - back to bank common
-	bsf		ir_power					;     - power-up IR
-	btfss	ir_power					;     - power-up confirmed?
-	bra		$-6							;       NO - loop and wait
-	bsf		PIE3,RC2IE					;     - enable RC2 INT
-	return								;     - done
+	btfsc	ext_input_s8_ana			; do we have an S8/analog input?
+	bra		enable_s8_analog			; YES - enable S8/analog  input
+	;bra	enable_ir					; NO  - enable IR digital input
 
-enable_s8:
+enable_ir:
+	banksel	BAUDCON2					; select bank for IO register access
+	movlw	b'00100000'					; speed generator configuration: BRG16=0, inverted for IR
+	movwf	BAUDCON2					; ...
+	movlw	b'00100000'					; TX configuration: BRGH=0, SYNC=0
+	movwf	TXSTA2						; ...
+	movlw	.102						; speed configuration: SPBRGH:SPBRG = .102 : 2403 BAUD @ 16 MHz
+	movwf	SPBRG2						; ...
+	clrf	SPBRGH2						; ...
+	movlw	b'10010000'					; RX configuration
+	movwf	RCSTA2						; ...
+	banksel	common						; back to bank common
+	bsf		ir_power					; power-up IR
+	btfss	ir_power					; power-up confirmed?
+	bra		$-6							; NO - loop and wait
+	bsf		PIE3,RC2IE					; enable RC2 INT
+	return								; done
+
+enable_s8_analog:
 	banksel	TXSTA2						; select bank for IO register access
 	clrf	TXSTA2						; reset UART 2 TX function
 	clrf	RCSTA2						; reset UART 2 RX function
 	banksel	common						; back to bank common
 
-	bsf		mcp_power					; power-up instrumentation amp (for analog AND digital)
+	bsf		mcp_power					; power-up instrumentation amp (used by S8 and analog input)
 	btfss	mcp_power					; power-up completed?
 	bra		$-4							; NO - loop
 
-	; toggle for digital/analog
+	; branch according to S8 / analog selection
 	TSTOSS	opt_s8_mode					; =0: analog, =1: digital RS232
-	bra		enable_s8_analog			; -> analog
+	bra		enable_analog				; -> analog
 
 	; configure S8 digital interface
 	bcf		s8_npower					; power S8 HUD (inverted via P-MOS transistor)
 	WAITMS	d'30'						; NO  - wait 30 ms
 	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
-	movwf	TXSTA2
-	movlw	.25							; SPBRGH:SPBRG = .25 : 9615 BAUD @ 16 MHz
-	movwf	SPBRG2
-	movlw	b'10010000'
-	movwf	RCSTA2
+	movlw	b'00000000'					; speed generator configuration: BRG16=0, normal for S8
+	movwf	BAUDCON2					; ...
+	movlw	b'00100000'					; TX configuration: BRGH=0, SYNC=0
+	movwf	TXSTA2						; ...
+	movlw	.25							; speed configuration: SPBRGH:SPBRG = .25 : 9615 BAUD @ 16 MHz
+	movwf	SPBRG2						; ...
+	movlw	b'10010000'					; RX configuration
+	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:
+enable_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
+	bsf		s8_npower					; power-down S8 digital interface
+	return								; done
 
 
-	global	ir_s8_wait_tx
-ir_s8_wait_tx:
+;-----------------------------------------------------------------------------
+; Shut-Down the IR/S8 Port
+;
+	global	disable_ir_s8_analog
+disable_ir_s8_analog:
 	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
+	clrf	TXSTA2						; shut down TX function
+	clrf	RCSTA2						; shut down RX function
+	banksel	common						; back to bank common
+	bcf		PIE3,RC2IE					; disable RC2 INT
+	bcf		ir_power					; power down IR receiver
+	bcf		mcp_power					; power-down instrumentation amp
+	bsf		s8_npower					; power-down S8 digital interface
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Send Byte in WREG via the IR/S8 Port
+;
+	global	ir_s8_tx_single
+ir_s8_tx_single:
+	banksel	TXSTA2						; UART 2 is outside of the access RAM
+	movwf	TXREG2						; transmit byte
+ir_s8_tx_single_loop:
+	btfss	TXSTA2,TRMT					; TX completed?
+	bra		ir_s8_tx_single_loop		; NO  - wait...
+	banksel	common						; YES - back to bank common
 	return								;     - done
 
+
 ;-----------------------------------------------------------------------------
-
+; Switch-On USB/BT Port
+;
 	global	enable_rs232
 enable_rs232:
 	call	request_speed_normal		; request CPU speed change to normal speed
@@ -324,21 +357,44 @@
 	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
+ IFNDEF _comm_debug
+	movlw	HIGH(.65536-rx_timeout*.32)	;     - define TMR5H initialization value for RX timeout (rx_timeout defined in hwos.inc)
+ ELSE
+	include	"math.inc"
+	movff	opt_comm_timeout,xA+0		;     - get timeout setting in multiples of 10 ms (opt_comm_timeout: 10 .. 200 x 10 ms)
+	clrf	xA+1						;     - ...
+	MOVLI	.320,xB						;     - multiply with 10 to get timeout in ms and 32 because tmr5 ticks 32x per ms
+	call	mult16x16					;     - xC = xA * xB = timer ticks to go until timeout
+	MOVII	xC,sub_b					;     - multiplication result is max. 64000
+	MOVLI	.65535,sub_a				;     - timer wraps around after 65535
+	call	subU16						;     - sub_c = sub_a - sub_b = start value for timer
+
+	movlw	.244						; safety maximum value for rx_timeout_tmr5h_load (minimum timeout interval)
+	cpfslt	sub_c+1						; result > safety value?
+	movwf	sub_c+1						; YES - revert to safety value
+
+	movf	sub_c+1,W					;     - keep only the upper byte as TMR5H initialization value for RX timeout
+ ENDIF
+	movwf	rx_timeout_tmr5h_load		;     - store for later use
 	return								;     - done
 
 
+;-----------------------------------------------------------------------------
+; Shut-Down USB/BT Port
+;
 	global	disable_rs232
 disable_rs232:
 	clrf	RCSTA1						; disable RX
 	clrf	TXSTA1						; disable TX
 	bcf		PORTC,6						; switch TX pin hard to GND
-	bsf		PORTE,0						; stop comm
+	bsf		PORTE,0						; power down BT chip
 	bcf		PORTJ,2						; /Reset (required for very old OSTC sport)
 	return
 
 
+;-----------------------------------------------------------------------------
+; Wait for last Byte to be sent out of USB/BT Port
+;
 	global	rs232_wait_tx				; ++++ do not touch WREG here! ++++
 rs232_wait_tx:
 	btfss	TXSTA1,TRMT					; last byte completely shifted out on TX pin?
@@ -350,36 +406,47 @@
 	return								;             YES - done
 
 
-										; ++++ make this code as fast as possible! ++++
-	global	rs232_get_byte				; ++++       do not touch WREG here!       ++++
-rs232_get_byte:
+;-----------------------------------------------------------------------------
+; Receive one Byte via the USB/BT Port
+;
+; ++++ make this code as fast as possible! ++++
+; ++++       do not touch WREG here!       ++++
+;
+	global	serial_rx_single
+serial_rx_single:
 	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
+	btfsc	PIR1,RCIF					; received a data byte? (bit is set on RX completion and reset on reading RCREG1)
+	return								; YES - done (fast path)
+	movff	rx_timeout_tmr5h_load,TMR5H	; NO  - 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:
+serial_rx_single_loop:
 	btfsc	PIR1,RCIF					; received a data byte?
-	return								; YES - done, received a byte
+	return								; YES - done
 	btfss	PIR5,TMR5IF					; NO  - timer overflow (timeout)?
-	bra		rs232_get_byte_loop			;       NO  - continue looping
-	;bra	rs232_rx_get_timeout		;       YES - give up
-
-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
+	bra		serial_rx_single_loop		;       NO  - continue waiting
+	;bra	serial_rx_timeout			;       YES - timeout
 
 
 ;-----------------------------------------------------------------------------
-; Send and Receive functions to be used through the macros
+; Helper Function: Timeout in serial_rx_single / serial_tx_steam
+;
+serial_rx_timeout:
+	bsf		rs232_rx_timeout			; set timeout flag
+	bcf		RCSTA1,CREN					; clear receiver status: disable RX,
+	bsf		RCSTA1,CREN					;               ... enable again RX
+	return								; done
+
 
-; send a range of 1-256 bytes from memory to the RS232 interface
+;-----------------------------------------------------------------------------
+; Send and Receive Functions to be used via Macros
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; Send a Range of 1-256 Bytes from Memory via the USB/BT Port
 ;
-	global	serial_tx_ram
-serial_tx_ram:
+	global	serial_tx_steam
+serial_tx_steam:
 	movwf	eeprom_loop					; initialize loop counter (eeprom variable used here)
 serial_tx_ram_loop:
 	rcall	rs232_wait_tx				; wait for completion of last transmit
@@ -389,37 +456,36 @@
 	return								; YES - done
 
 
-; receive a range of 1-256 byte from the RS232 interface and write them to memory
+;-----------------------------------------------------------------------------
+; Receive a Range of 1-256 Byte via the USB/BT Port and write them to Memory
+; ++++ make this code as fast as possible! ++++
 ;
-	global	serial_rx_stream_ram		; ++++ make this code as fast as possible! ++++
-serial_rx_stream_ram:
+	global	serial_rx_stream
+serial_rx_stream:
 	movwf	eeprom_loop					; initialize loop counter (eeprom variable used here)
-serial_rx_stream_ram_loop_1:
+serial_rx_stream_loop:
 	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
+	bra		serial_rx_stream_tmr		; NO  - enter receive loop with timeout
+	;bra	serial_rx_stream_received	; YES - copy to memory, tick counter, ...
+
+serial_rx_stream_received:
+	movff	RCREG1,POSTINC2				; copy received byte to memory
+	decfsz	eeprom_loop,F				; decrement loop counter, became zero?
+	bra		serial_rx_stream_loop		; NO  - await next byte
+	bcf		rs232_rx_timeout			; YES - clear timeout flag
+	return								;     - all bytes received, done
+
+serial_rx_stream_tmr:
+	movff	rx_timeout_tmr5h_load,TMR5H	; load TMR5 high with timeout value
+	clrf	TMR5L						; load TMR5 low  with a zero, writing to 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
+serial_rx_stream_tmr_loop:
+	btfsc	PIR1,RCIF					; received a data byte? (bit is set on RX complete and reset on reading RCREG1)
+	bra		serial_rx_stream_received	; YES - copy to memory, tick counter, ...
+	btfss	PIR5,TMR5IF					; NO  - timer overflow (timeout)?
+	bra		serial_rx_stream_tmr_loop	;       NO  - continue waiting
+	bra		serial_rx_timeout			;       YES - timeout
 
 ;-----------------------------------------------------------------------------
+
 	END
--- a/src/eeprom_rs232.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/eeprom_rs232.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File eeprom_rs232.inc                     combined next generation V3.08.8
+;   File eeprom_rs232.inc                   * combined next generation V3.09.4n
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -9,150 +9,6 @@
 ;  2011-08-03 : [mH] moving from OSTC code
 
 
-; --------------------------------------------------------------------------------------------
-;           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
-
 
 ; --------------------------------------------------------------------------------------------
 ;       EEPROM Defines
@@ -177,7 +33,8 @@
 #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_fw_chksum_current		0x012		;   6  checksum of the current firmware *)
+;										0x018		;   2  unused
 #DEFINE eeprom_options_storage			0x01A		; 486  backup storage for the options
 
 
@@ -201,37 +58,208 @@
 #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
+#DEFINE eeprom_fw_chksum_recovry		0x382		;   6  checksum of stored recovery firmware *)
+;										0x388		; 121  unused
+
+
+; *) 4 byte code checksum, 1 byte checksum of the checksum, 1 byte firmware ID
 
 
 
 ; --------------------------------------------------------------------------------------------
-;           Serial read & write Macros
+;
+;           EEPROM read & write Macros
+;
 ; --------------------------------------------------------------------------------------------
 
-; receive 1 byte and write to memory, in case of timeout the flag 'rs232_rx_timeout' will be set
+
+;-----------------------------------------------------------------------------
+; 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 need to 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 need to 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 need to 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 need to 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 need to 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 need to 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
+
+
+
+; --------------------------------------------------------------------------------------------
+;
+;           Serial Read & Write Macros
+;
+; --------------------------------------------------------------------------------------------
+
+
+;-----------------------------------------------------------------------------
+; Receive 1 Byte and write to Memory
+;
+; in case of a Timeout the Flag 'rs232_rx_timeout' will be set
 ;
 SERIAL_CC_RECEIVE	macro	mem_address
-	call	rs232_get_byte				; (try to) receive one byte
+	extern	serial_rx_single
+	call	serial_rx_single			; (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
+;-----------------------------------------------------------------------------
+; Stream a Range of Bytes to Memory
+;
+; in case of a 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
+SERIAL_RR_RECEIVE	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
+	extern	serial_rx_stream
+	call	serial_rx_stream
 	endm
 
 
-
-; send 1 byte literal
+;-----------------------------------------------------------------------------
+; Send 1 Byte Literal
 ;
 SERIAL_LC_SEND	macro	literal
 	call	rs232_wait_tx				; wait for completion of last transmit
@@ -240,7 +268,8 @@
 	endm
 
 
-; send 1 byte from memory
+;-----------------------------------------------------------------------------
+; Send 1 Byte from Memory
 ;
 ; mem_address: address:2 containing the source address in memory (bank safe)
 ;
@@ -250,16 +279,17 @@
 	endm
 
 
-; send a range of bytes from memory
+;-----------------------------------------------------------------------------
+; 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
+SERIAL_RR_SEND	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
+	extern	serial_tx_steam
+	call	serial_tx_steam
 	endm
 
 
@@ -297,16 +327,15 @@
 
 ; Serial - IR / S8
 
-	extern	enable_ir_s8
-	extern	disable_ir_s8
-	extern	ir_s8_wait_tx
+	extern	enable_ir_s8_analog
+	extern	disable_ir_s8_analog
+	extern	ir_s8_tx_single
 
 
 ; Serial - RS232 (USB / BT)
 
 	extern	enable_rs232
 	extern	disable_rs232
-	extern	rs232_get_byte
 	extern	rs232_wait_tx
 
 
--- a/src/external_flash.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/external_flash.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File external_flash.asm                   combined next generation V3.08.8
+;   File external_flash.asm                 * combined next generation V3.09.4e
 ;
 ;   External flash
 ;
@@ -13,92 +13,121 @@
 	#include "wait.inc"
 	#include "eeprom_rs232.inc"
 
+;=============================================================================
 ext_flash	CODE
-
 ;=============================================================================
 
-; 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 one with wrap-around at 0x400000 to 0x000000
+;
+ext_flash_inc_address_0x40_p1:
+	movlw	.1								; increment by 1
+	;bra	ext_flash_inc_address_0x40_exec	; execute incrementing
 
 
-; 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
+;-----------------------------------------------------------------------------
+; increase Flash Address by Value in WREG with wrap-around at 0x400000 to 0x000000
+;
+	global	ext_flash_inc_address_0x40_exec
+ext_flash_inc_address_0x40_exec:
+	clrf	ext_flash_address_limit			; | set wrap-around threshold to
+	bsf		ext_flash_address_limit,6		; | 0x40 without destroying WREG
 	bra		incf_ext_flash_address0_common	; continue with common part
 
 
-; 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 one with wrap-around at 0x200000 to 0x000000
+;
+ext_flash_inc_address_0x20_p1:
+	movlw	.1								; increment by one
+	;bra	ext_flash_inc_address_0x20_exec	; execute incrementing
 
 
-; 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:
-	clrf	ext_flash_rollover_threshold	; set wrap-around threshold without destroying WREG to ...
-	bsf		ext_flash_rollover_threshold,5	; ... 0x20
+;-----------------------------------------------------------------------------
+; increase Flash Address by Value in WREG with wrap-around at 0x200000 to 0x000000
+;
+	global	ext_flash_inc_address_0x20_exec
+ext_flash_inc_address_0x20_exec:
+	clrf	ext_flash_address_limit			; | set wrap-around threshold to
+	bsf		ext_flash_address_limit,5		; | 0x20 without destroying WREG
 	;bra	incf_ext_flash_address0_common	; continue with common part
 
 
+;-----------------------------------------------------------------------------
+; common Part for Flash Address Increasing
+;
 incf_ext_flash_address0_common:
-	bcf		address_wrap_around				; clear wrap-around flag
+	bcf		flash_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
+	movf	ext_flash_address_limit,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
+	bsf		flash_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
 
 
-; 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
+;-----------------------------------------------------------------------------
+; add 0x001000 to Flash Address, no Check for wrap-around
+;
+	global	ext_flash_inc_address_4kB
+ext_flash_inc_address_4kB:
+	movlw	0x10							; add 0x10 to high byte
+	addwf	ext_flash_address+1,F			; ...
+	movlw	0x00							; propagate carry to upper byte
+	addwfc	ext_flash_address+2,F			; ...
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; decrement Length Counter by 1
+;
+	global	ext_flash_dec_length_exec
+ext_flash_dec_length_exec:
+	movlw	.1								; decrement by 1
+	subwf	ext_flash_length_counter+0,F	; ...
 	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_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)
+;-----------------------------------------------------------------------------
+; read a Byte from Flash and increment Address with wrap-around at 0x20 / 0x40
+; returns in ext_flash_rw and WREG
+;
+	global	ext_flash_read_byte_0x40
+ext_flash_read_byte_0x40:
+	bsf		flash_wrap_around				; wrap-around at 0x400000
+	bra		ext_flash_read_byte_common		; continue with common part
 
+	global	ext_flash_read_byte_0x20
+ext_flash_read_byte_0x20:
+	bcf		flash_wrap_around				; wrap-around at 0x200000
+	;bra	ext_flash_read_byte_common		; continue with common part
 
-	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
+ext_flash_read_byte_common:
+	movlw	0x03							; prepare read command
+	rcall	shift_spi						; execute 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
+	movwf	ext_flash_rw					; copy byte read from WREG to ext_flash_rw
+	btfss	flash_wrap_around				; shall wrap-around at 0x40000 ?
+	bra		ext_flash_inc_address_0x20_p1	; NO  - increment address with wrap-around at 0x200000 and return
+	bra		ext_flash_inc_address_0x40_p1	; YES - increment address with wrap-around at 0x200000 and return
 
-; ----------------------------------------------------------------------------
-; read-range base functions
 
+;-----------------------------------------------------------------------------
+; Read-Range Base Functions - start reading
+;
 	global	ext_flash_read_block_start		; return data read in WREG
 ext_flash_read_block_start:
 	movlw	0x03							; set up  read command
@@ -107,50 +136,61 @@
 	bra		shift_spi						; shift the SPI to read data into WREG (and return)
 
 
+;-----------------------------------------------------------------------------
+; Read-Range Base Functions -  increment Address and read a Byte, wrap-around at 0x40
+;
 	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	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?
+	rcall	ext_flash_inc_address_0x40_p1	; increase address with wrap-around at 0x400000
+	btfss	flash_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
 
 
+;-----------------------------------------------------------------------------
+; Read-Range Base Functions - increment Address and read a Byte, wrap-around at 0x20
+;
+;	global	ext_flash_read_block_0x20		; return data read in WREG
+;ext_flash_read_block_0x20:
+;	rcall	ext_flash_inc_address_0x20_p1	; increase address with wrap-around at 0x200000
+;	btfss	flash_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
+
+
+;-----------------------------------------------------------------------------
+; Read-Range Base Functions - terminate reading
+;
 	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
+; read a Range of Bytes, to be used via 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
+	rcall	ext_flash_read_block_start		; read first byte from FLASH to WREG
 	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
+	rcall	shift_spi_loop_1				; read next  byte from FLASH to WREG
 ext_flash_read_range_loop_start:
-	movwf	POSTINC1						; write byte to memory
+	movwf	POSTINC1						; write      byte from WREG  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)
 
 
 ; ----------------------------------------------------------------------------
-; write-range base functions
-
+; Write-Range Base Functions - for use with SST26VF Chip only!
+;
 ext_flash_write_block_start:
+	movwf	ext_flash_rw					; copy byte to write from WREG to ext_flash_rw
 	bsf		flash_ncs						; set CS=1
 	movlw	0x06							; set up  WREN command
 	rcall	shift_spi						; execute WREN command
@@ -158,161 +198,182 @@
 	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
+	movf	ext_flash_rw,W					; get back 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-range function, to be used through macro
+; write a Range of Bytes, to be used via Macro
 ;
 	global	ext_flash_write_range
 ext_flash_write_range:
 	movwf	eeprom_loop						; load loop counter (eeprom variable used here)
 
-;	btfsc	flash_block_write				; does the FLASH support block-write?
-;	bra		ext_flash_write_range_block		; YES - write date via block operation
-;	;bra	ext_flash_write_range_seq		; NO  - write data via sequential single writes
+	btfsc	flash_block_write				; does the FLASH support block-write?
+	bra		ext_flash_write_range_block		; YES - write data in block      mode
+	;bra	ext_flash_write_range_seq		; NO  - write data in sequential mode
 
-ext_flash_write_range_seq:					; sequential write
-ext_flash_write_range_loop_s:
-	movff	POSTINC1,ext_flash_rw			; read  byte from     memory     to  ext_flash_rw
-	rcall	ext_flash_byte_write			; write byte from  ext_flash_rw  to     FLASH
-	rcall	incf_ext_flash_address_p1_0x40	; increase address with wrap-around at 0x400000
+	; sequential write
+ext_flash_write_range_seq:
+	bsf		flash_wait						; wait for flash writes to complete
+ext_flash_write_range_seq_loop:
+	movf	POSTINC1,W						; copy  byte from memory to WREG
+	rcall	ext_flash_byte_write_common_W	; write byte from WREG   to FLASH
+	rcall	ext_flash_inc_address_0x40_p1	; increase address with wrap-around at 0x400000
 	decfsz	eeprom_loop,F					; decrement loop counter, all done?
-	bra		ext_flash_write_range_loop_s	; NO  - continue loop
+	bra		ext_flash_write_range_seq_loop	; NO  - loop
 	return									; YES - done
 
-ext_flash_write_range_block:				; block write
-	movff	POSTINC1,ext_flash_rw			; read  first byte from memory
-	rcall	ext_flash_write_block_start		; write first byte to FLASH
+	; block write
+ext_flash_write_range_block:
+	movf	POSTINC1,W						; copy first byte from memory to WREG
+	rcall	ext_flash_write_block_start		; copy first byte from WREG   to FLASH
 	bra		ext_flash_write_range_loop_start; jump into loop
-ext_flash_write_range_loop_b:
-	movff	POSTINC1,ext_flash_rw			; read  next byte from memory
-	rcall	ext_flash_write_block			; write next byte to FLASH
+ext_flash_write_range_block_loop:
+	movf	POSTINC1,W						; copy next  byte from memory to WREG
+	rcall	ext_flash_write_block			; copy next  byte from WREG   to FLASH
 ext_flash_write_range_loop_start:
 	decfsz	eeprom_loop,F					; decrement loop counter, all done?
-	bra		ext_flash_write_range_loop_b	; 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
+	bra		ext_flash_write_range_block_loop; NO  - loop
+	rcall	ext_flash_write_block_stop		; YES - initiate FLASH write
+	clrf	ext_flash_address+0				;     - advance address to start of next block
+	infsnz	ext_flash_address+1,F			;     - ...
+	incf	ext_flash_address+2,F			;     - ...
+	return									;     - done
 
 
-	global	write_byte_ext_flash_plus_prof
-write_byte_ext_flash_plus_prof:
+;-----------------------------------------------------------------------------
+; write a Byte with wrap-around at 0x200000,
+; erase on entering new 4kB Block,
+; increment Dive Length Counter
+;
+	global	ext_flash_write_byte_0x20_incdc
+ext_flash_write_byte_0x20_incdc:
 	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
+	bra		write_byte_ext_flash_plus_nocnt1; continue with checking for begin of new block
 
 
-	global	write_byte_ext_flash_plus_nocnt
-write_byte_ext_flash_plus_nocnt:
+;-----------------------------------------------------------------------------
+; write a Byte with wrap-around at 0x200000,
+; erase on entering new 4kB Block
+; 
+	global	ext_flash_write_byte_0x20
+ext_flash_write_byte_0x20:
 	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
+write_byte_ext_flash_plus_nocnt1:
+	; check if at 1st byte of a 4kB block,
+	; if yes the block needs to be erased
+	; before new data can be written to it
+	tstfsz	ext_flash_address+0				; is the low byte of the address = 0x00 ?
+	bra		write_byte_ext_flash_plus_nodel1; NO  - not at 1st byte, can execute write
+	movf	ext_flash_address+1,W			; YES - get high byte of the address
+	andlw	0x0F							;     - keep only the lower nibble
+	tstfsz	WREG							;     - is the lower nibble = 0x0 ?
+	bra		write_byte_ext_flash_plus_nodel1;       NO  - not at 1st byte, can execute write
+	rcall	ext_flash_erase_4kB				;       YES - at 1st byte, erase 4kB block
 	bra		write_byte_ext_flash_plus_nodel1;           - execute write
 
 
-	global	write_byte_ext_flash_plus_nodel
-write_byte_ext_flash_plus_nodel:
+;-----------------------------------------------------------------------------
+; write a Byte with wrap-around at 0x200000
+; NO erase on entering new 4kB Block
+;
+	global	ext_flash_write_byte_0x20_nodel
+ext_flash_write_byte_0x20_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
+	bsf		flash_wait						; wait for flash write to complete
+	rcall	ext_flash_byte_write_common_F	; write the byte in ext_flash_rw
+	bra		ext_flash_inc_address_0x20_p1	; 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
+;-----------------------------------------------------------------------------
+; write a Byte without Wait (used by comm mode)
+;
+; time budget for flash to complete a write is ~86 us at 115200 Baud on serial
+;
+	global	ext_flash_write_byte_0x40_nowait
+ext_flash_write_byte_0x40_nowait:
 	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
+	rcall	ext_flash_byte_write_common_W	; write the byte in WREG
+	bra		ext_flash_inc_address_0x40_p1	; 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:
+;-----------------------------------------------------------------------------
+; internal common Write Functions W: WREG         -> FLASH(ext_flash_address)
+;                                 F: ext_flash_rw -> FLASH(ext_flash_address)
+;
+ext_flash_byte_write_common_W:
+	movwf	ext_flash_rw					; copy byte to write from WREG to ext_flash_rw
+ext_flash_byte_write_common_F:
 	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
+	movlw	0x02							; prepare 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
+	movf	ext_flash_rw,W					; get back 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
 
-; ----------------------------------------------------------------------------
 
+;-----------------------------------------------------------------------------
+; switch off Write-Protection
+;
 	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	shift_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x01							; WRSR command
-	rcall	shift_spi
-	movlw	b'00000000'						; new status
-	rcall	shift_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'00000000'						; prepare new status
+	rcall	shift_spi						; set     new status
+
 	; unlock new memory
-	movlw	0x06							; WREN command
-	rcall	shift_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x98							; ULBPR command
-	rcall	shift_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x06							; WREN command
-	rcall	shift_spi
-	bsf		flash_ncs						; CS=1
-	movlw	0x42							; WBPR command
-	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	0x98							; prepare ULBPR command
+	rcall	shift_spi						; execute ULBPR command
+	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_disable_prot_loop:
 	movlw	0x00							; prepare writing a zero
-	rcall	shift_spi						; execute write
+	rcall	shift_spi						; write a zero
 	decfsz	lo,F							; all bytes done?
 	bra		ext_flash_disable_prot_loop		; NO  - loop
 	bsf		flash_ncs						; YES - set CS=1
 	return									;     - done
 
 
+;-----------------------------------------------------------------------------
+; switch on Write-Protection
+;
 	global	ext_flash_enable_protection
 ext_flash_enable_protection:
 	; lock old memory
@@ -324,69 +385,104 @@
 	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	shift_spi
-;	bsf		flash_ncs						; CS=1
-;	movlw	0x8D							; LBPR command
-;	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	0x8D							; prepare LBPR command
+;	rcall	shift_spi						; execute LBPR command
 ;	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
+	rcall	shift_spi						; write a zero
 	decfsz	lo,F							; all bytes done?
 	bra		ext_flash_enable_prot_loop		; NO  - loop
 	bsf		flash_ncs						; YES - set CS=1
 	return									;     - done
 
-; ----------------------------------------------------------------------------
 
+;-----------------------------------------------------------------------------
+; erase complete Logbook
+;
 	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
-	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_erase_4kB				; erase 4kB block
-	rcall	ext_flash_add_4kB				; increase ext_flash_address:3 by 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
+	; set address to 0x000000 / prepare a 3 byte zero integer
+	CLRT	ext_flash_address
+
+	; clear logbook data in EPROM by writing all zeros
+	EEPROM_II_WRITE ext_flash_address,eeprom_num_dives		; reset the total number of dives
+	EEPROM_TT_WRITE ext_flash_address,eeprom_log_pointer	; reset pointer to begin of profile data
+
+	; erase logbook data in FLASH from 0x000000 - 0x2FFFFF = 3 MByte = 3 * 256 blocks * 4 kB/block
+
+	clrf	WREG							; erase 256 blocks per call
+	rcall	ext_flash_erase_range			; erase 1st bunch of 256 blocks
+	rcall	ext_flash_erase_range_loop		; erase 2nd bunch of 256 blocks
+	rcall	ext_flash_erase_range_loop		; erase 3rd bunch of 256 blocks
+	return									; done
 
 
-	global	ext_flash_erase_4kB				; erase a 4kB sector
+;-----------------------------------------------------------------------------
+; erase a Number of 4kB Blocks
+;
+	global	ext_flash_erase_range
+ext_flash_erase_range:
+	movwf	eeprom_loop						; initialize loop counter
+ext_flash_erase_range_loop:
+	rcall	ext_flash_erase_4kB				; erase one block
+	rcall	ext_flash_inc_address_4kB		; increase start address by 0x1000 (4kB)
+	btfsc	ext_flash_address+2,6			; reached 0x400000 ?
+	return									; YES - reached end of address range, done anyhow
+	decfsz	eeprom_loop,F					; NO  - decrement number of blocks to do, all blocks done?
+	bra		ext_flash_erase_range_loop		;       NO  - loop
+	return									;       YES - done, back to command loop
+
+
+;-----------------------------------------------------------------------------
+; erase one 4kB Block
+;
+	global	ext_flash_erase_4kB
 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
+	movlw	0x20							; prepare block erase command
+	rcall	shift_spi						; execute block 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
+;-----------------------------------------------------------------------------
+; read JEDEC IDs
+;
+	global	ext_flash_read_jedec
+ext_flash_read_jedec:
+	movlw	0x9F							; prepare JEDEC read command
+	rcall	shift_spi						; execute JEDEC read command
+	rcall	shift_spi						; shift the SPI to read the manufacturer ID into WREG
+	movwf	lo								; store                 the manufacturer ID in   lo
+	rcall	shift_spi						; shift the SPI to read the device type  ID into WREG
+	movwf	hi								; store                 the device type  ID in   hi
+	rcall	shift_spi						; shift the SPI to read the device model ID into WREG
+	movwf	up								; store                 the device model ID in   up
+	bsf		flash_ncs						; set CS=1
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; low level Functions - 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						; ...
@@ -395,7 +491,10 @@
 	movf	ext_flash_address+0,W			; ...
 	bra 	shift_spi						; ... and return
 
-; wait on write operation to complete
+
+;-----------------------------------------------------------------------------
+; low level Functions - wait for Completion of a Write Operation
+;
 ext_flash_wait_write:
 	bsf		flash_ncs						; set CS=1
 ;	WAITMS	d'1'							; TBE/TSE=25ms...
@@ -407,16 +506,14 @@
 	bra		ext_flash_wait_write			; YES - loop waiting
 	return									; NO  - done
 
-; add 0x001000 to flash address
-ext_flash_add_4kB:
-	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
 
-; shift the SPI bus for a combined write/read: WREG --->\      /---> WREG
-shift_spi:                                  ;          flash chip
+;-----------------------------------------------------------------------------
+; low level functions - shift the SPI Bus for a combined Write/Read
+;
+;      WREG --> write --->\      /---> read --> WREG
+;                        flash chip
+;
+shift_spi:
 	bcf		flash_ncs						; set CS=0
 shift_spi_loop_1:
 	bcf		SSP2STAT,WCOL					; clear flag
@@ -429,4 +526,100 @@
 	movf	SSP2BUF,W						; YES - copy received data to WREG
 	return									;     - done
 
+
+ IFDEF _firmware_recovery
+
+;-----------------------------------------------------------------------------
+; copy active Firmware to Backup Storage
+;
+	global	copy_fw_active_to_backup
+copy_fw_active_to_backup:
+	; erase FLASH for recovery firmware (120 kByte = 30 * 4 kByte)
+	rcall	ext_flash_to_recovery_fw				; set ext_flash_address to 0x3C0000
+	movlw	.30										; 30 blocks to do
+	rcall	ext_flash_erase_range					; erase #WREG 4kB blocks starting at ext_flash_address
+
+	; copy firmware (120 kByte = 2 x 240 x 256 byte)
+	rcall	ext_flash_to_productive_fw				; set ext_flash_address to 0x3E0000
+	clrf	hi										; flag in 1st round
+copy_fw_active_to_backup_loop1:
+	movlw	.240									; load loop counter
+	movwf	lo										; ...
+copy_fw_active_to_backup_loop2:
+	; read active firmware
+	bsf		ext_flash_address+2,1					; switch to productive firmware
+	lfsr	FSR1,buffer								; set start address in memory
+	movlw	low(.256)								; set size of range to read
+	rcall	ext_flash_read_range					; execute range-read (ext_flash_address NOT  incremented)
+	; write to backup storage
+	bcf		ext_flash_address+2,1					; switch to backup storage
+	lfsr	FSR1,buffer								; set start address in memory
+	movlw	low(.256)								; set size of range to write
+	rcall	ext_flash_write_range					; execute range-write (ext_flash_address GETS incremented)
+	; operate loop
+	decfsz	lo,F									; decrement loop counter, done?
+	bra		copy_fw_active_to_backup_loop2			; NO  - continue copying
+	tstfsz	hi										; YES - 2nd round finished?
+	return											;       YES - done
+	setf	hi										;       NO  - flag in 2nd round now
+	bra		copy_fw_active_to_backup_loop1			;           - start 2nd round
+
+
+;-----------------------------------------------------------------------------
+; copy Backup-Firmware to Update Storage
+;
+	global	copy_fw_backup_to_active
+copy_fw_backup_to_active:
+	; erase FLASH for productive firmware (120 kByte = 30 * 4 kByte)
+	rcall	ext_flash_to_productive_fw				; set ext_flash_address to 0x3E0000
+	movlw	.30										; 30 blocks to do
+	rcall	ext_flash_erase_range					; erase #WREG 4kB blocks starting at ext_flash_address
+
+	; copy firmware (120 kByte = 2 x 240 x 256 byte)
+	rcall	ext_flash_to_recovery_fw				; set ext_flash_address to 0x3C0000
+	clrf	hi										; flag in 1st round
+copy_fw_backup_to_active_loop1:
+	movlw	.240									; load loop counter
+	movwf	lo										; ...
+copy_fw_backup_to_active_loop2:
+	; read backup firmware
+	bcf		ext_flash_address+2,1					; switch to backup firmware
+	lfsr	FSR1,buffer								; set start address in memory
+	movlw	low(.256)								; set size of range to read
+	rcall	ext_flash_read_range					; execute range-read (ext_flash_address NOT  incremented)
+	; write to update storage
+	bsf		ext_flash_address+2,1					; switch to update storage
+	lfsr	FSR1,buffer								; set start address in memory
+	movlw	low(.256)								; set size of range to write
+	rcall	ext_flash_write_range					; execute range-write (ext_flash_address GETS incremented)
+	; operate loop
+	decfsz	lo,F									; decrement loop counter, done?
+	bra		copy_fw_backup_to_active_loop2			; NO  - continue copying
+	tstfsz	hi										; YES - 2nd round finished?
+	return											;       YES - done
+	setf	hi										;       NO  - flag in 2nd round now
+	bra		copy_fw_backup_to_active_loop1			;           - start 2nd round
+
+
+;-----------------------------------------------------------------------------
+; Helper Functions - point ext_flash_address to active / backup firmware storage
+;
+ext_flash_to_recovery_fw
+	movlw	0x3C									; 0x3C|
+	bra		ext_flash_common
+
+ext_flash_to_productive_fw:
+	movlw	0x3E									; 0x3E|
+	;bra	ext_flash_common
+
+ext_flash_common:
+	movwf	ext_flash_address+2						; ....|
+	clrf	ext_flash_address+1						; ....|00|
+	clrf	ext_flash_address+0						; .......|00
+	return
+
+ ENDIF
+
+;-----------------------------------------------------------------------------
+
 	END
--- a/src/external_flash.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/external_flash.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File external_flash.inc                   combined next generation V3.08.8
+;   File external_flash.inc                 * combined next generation V3.09.4e
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -14,29 +14,32 @@
 ; 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
+; 0x3C0000 - 0x3DDFFF  120 kB backup firmware
+; 0x3DE000 - 0x3DFFFF    8 kb unused
+; 0x3E0000 - 0x3FDFFF  120 kB firmware buffer
+; 0x3FE000 - 0x3FFFFF    8 kB reserved for factory use
 
 
 ; 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
+	extern	ext_flash_write_byte_0x20_incdc		; with increment of ext_flash_dive_counter
+	extern	ext_flash_write_byte_0x20			; standard flash write
+	extern	ext_flash_write_byte_0x20_nodel		; without delete on entering new page
 
 
 ; 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)
+	extern	ext_flash_write_byte_0x40_nowait	; 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_0x20			; subsequent read of next byte(s) with wrap-around at 0x200000
 	extern	ext_flash_read_block_stop			; terminate  read
 
 
 ; Erase:
-	extern	ext_flash_erase_4kB					; erase one 4 kB sector @ext_flash_address:3
+	extern	ext_flash_erase_4kB					; erase   one 4kB block  starting at ext_flash_address:3
+	extern	ext_flash_erase_range				; erase #WREG 4kB blocks starting at ext_flash_address:3
 	extern	erase_complete_logbook				; erase complete logbook (FLASH and EEPROM)
 
 
@@ -44,6 +47,16 @@
 	extern	ext_flash_enable_protection			; enable  write protection
 	extern	ext_flash_disable_protection		; disable write protection
 
+; Misc
+	extern	ext_flash_read_jedec				; read JEDEC IDs
+	extern	ext_flash_inc_address_4kB			; increment address by 0x001000, no check for wrap-around
+
+
+ IFDEF _firmware_recovery
+; Firmware Copying
+	extern	copy_fw_active_to_backup			; copy active firmware code to backup storage
+	extern	copy_fw_backup_to_active			; copy backup firmware code to update storage
+ ENDIF
 
 
 ;-----------------------------------------------------------------------------
@@ -51,48 +64,61 @@
 ;-----------------------------------------------------------------------------
 
 
-; read 1 byte from FLASH to WREG with address auto-increment and wrap-around at 0x200000
+; read 1 byte from FLASH to WREG with address 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
+	extern	ext_flash_read_byte_0x20
+	call	ext_flash_read_byte_0x20			; read from FLASH to WREG
 	endm
 
 
-; read 1 byte from FLASH to memory with address auto-increment and wrap-around at 0x200000
+; read 1 byte from FLASH to WREG with address increment and wrap-around at 0x400000
+;
+; the byte read is also copied to ext_flash_rw
 ;
-; mem_address: address:2 containing target address in memory
+FLASH_CW_READ_0x40	macro
+	extern	ext_flash_read_byte_0x40
+	call	ext_flash_read_byte_0x40			; read from FLASH to WREG
+	endm
+
+
+; read 1 byte from FLASH to memory with address increment and wrap-around at 0x200000
+;
+; mem_address: target address in memory, must be in current bank!
 ;
 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
+	extern	ext_flash_read_byte_0x20
+	call	ext_flash_read_byte_0x20			; read from FLASH to WREG
+	movwf	mem_address							; copy from WREG  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
+; mem_address: target address in memory, must be in current bank!
 ;
 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
+	extern	ext_flash_read_byte_0x20
+	call	ext_flash_read_byte_0x20			; read 1st byte from FLASH to WREG
+	movwf	mem_address+0						; copy 1st byte from WREG  to memory
+	call	ext_flash_read_byte_0x20			; read 2nd byte from FLASH to WREG
+	movwf	mem_address+1						; copy 2nd byte from WREG  to memory
 	endm
 
 
-; 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
+; read a range of data from FLASH to memory (destroys WREG, FSR1)
+;
 ; 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
+; Attention: function does NOT check for a wrap-around!
+;
+; -> flash_start is at ext_flash_address
+; -> ext_flash_address is NOT changed
+;
+FLASH_RR_READ		macro	memory_start, range
 	lfsr	FSR1,memory_start						; set start address in memory
 	movlw	low(range)								; set size of range to read
 	extern	ext_flash_read_range
@@ -100,29 +126,45 @@
 	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!
+; write a range of data from memory to FLASH (destroys WREG, FSR1)
+;
 ; 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
+; Attention: low(ext_flash_address) + range must be <= 256 !
+;
+; -> flash_start is at ext_flash_address
+; -> old flash chip: ext_flash_address is incremented according to range parameter
+; -> new flash chip: ext_flash_address is set to start of next 256 byte block
+;
+FLASH_RR_WRITE		macro	memory_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
+	movlw	low(range)								; set size of range to write
 	extern	ext_flash_write_range
 	call	ext_flash_write_range					; execute range-write
 	endm
 
 
+; set ext_flash_address to a given address
+;
+EXT_FLASH_ADDR	macro	address
+	movlw	LOW   (address         )
+	movwf	ext_flash_address+0
+	movlw	HIGH  (address & 0xFFFF)
+	movwf	ext_flash_address+1
+	movlw	UPPER (address         )
+	movwf	ext_flash_address+2
+	endm
+
+
 ; 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
+EXT_FLASH_INC_ADDRESS_0x40	macro	increment
+	movlw	increment
+	extern	ext_flash_inc_address_0x40_exec
+	call	ext_flash_inc_address_0x40_exec
 	endm
 
 
@@ -130,19 +172,16 @@
 ;
 ; 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
+EXT_FLASH_INC_ADDRESS_0x20	macro	increment
+	movlw	increment
+	extern	ext_flash_inc_address_0x20_exec
+	call	ext_flash_inc_address_0x20_exec
 	endm
 
 
-; decrement length count
-;
-; decrement: literal (1-255)
+; decrement length counter by 1
 ;
-ext_flash_dec_length			macro	decrement
-		movlw	decrement
-		extern	decf_ext_flash_length0
-		call	decf_ext_flash_length0
+EXT_FLASH_DEC_LENGTH		macro
+	extern	ext_flash_dec_length_exec
+	call	ext_flash_dec_length_exec
 	endm
--- a/src/gaslist.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/gaslist.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File gaslist.asm                          combined next generation V3.08.8
+;   File gaslist.asm                        * combined next generation V3.09.5
 ;
 ;   Managing OSTC gas list
 ;
@@ -18,462 +18,284 @@
 #include "shared_definitions.h"
 #include "wait.inc"
 #include "rx_ops.inc"
-
-
-	extern	convert_meter_to_feet
-	extern	tSetup_GasDepth
-	extern	tGasDisabled
-	extern	tDilDisabled
-	extern	tLiter
-	extern	tbar10
-	extern	tbar
+#include "colorschemes.inc"
 
- 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
-
-;-----------------------------------------------------------------------------
 
 ;=============================================================================
-; Helper Functions for divemenu_tree.asm
-;
-; These functions need to be placed in a different
-; file than where the MENU_DYNAMIC macros use them.
-
-;-----------------------------------------------------------------------------
-
-	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
-	decfsz	WREG,W						; aGF enabled?
-	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			; print in disabled color
-do_toggle_gf_label_2:
-	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
+gaslist1	CODE
+;=============================================================================
 
 ;-----------------------------------------------------------------------------
-
- IFDEF _cave_mode
-
-	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?
-	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
-
-	global	do_toggle_max_pres_diff_label
-do_toggle_max_pres_diff_label:
-	movff	opt_TR_mode,WREG			; get TR mode
-	xorlw	.2							; compare with 2 (ind.double)
-	tstfsz	WREG						; equal?
-	call	TFT_disabled_color			; NO - print in disabled color
-	STRCAT_TEXT tTrMaxDeltaP			; output label
-	movff	char_I_max_pres_diff,lo
-	output_99
-	STRCAT_TEXT	tbar					; " bar"
-	return
-
- ENDIF
-
-;-----------------------------------------------------------------------------
-
- IFDEF _ccr_pscr
-
-	global	gaslist_copy_dil_to_oc
-gaslist_copy_dil_to_oc:
+; Append Mix ("Nxlo", "Txlo/hi", "Air" or "O2") to current String
 ;
-;  Memory Map:
-;  -----------------------------------------
-;  opt_gas_O2_ratio				res 5
-;  opt_dil_O2_ratio				res 5
-;  opt_gas_He_ratio				res 5
-;  opt_dil_He_ratio				res 5
-;  opt_gas_type					res 5
-;  opt_dil_type					res 5
-;  opt_gas_change				res 5
-;  opt_dil_change				res 5
-;
-;  char_I_gas_avail_size		res 10
-;  char_I_gas_avail_pres		res 10
+; Input:  PRODL : gas/dil number (0..4)
+;         flag 'is_diluent_menu' for gas/dil selection
 ;
-	bcf		copying_dil					; default to copying a gas
-	movf	gaslist_gas,W				; copy current gas or diluent number to WREG
-	btfss	is_diluent_menu				; setting up diluents?
-	bra		gaslist_copy_dil_to_oc_1	; NO  - gaslist_gas is already pointing to an OC gas
-	addlw	-.5							; YES - subtract offset between diluents and gases
-	movwf	gaslist_gas					;     - let gaslist_gas point to the corresponding OC gas
-	bsf		copying_dil					;     - we are copying a diluent
-	bcf		is_diluent_menu				;     - pretend we are setting up OC gases
-gaslist_copy_dil_to_oc_1:
-	lfsr	FSR0,opt_dil_O2_ratio		; load base address of diluents settings, ASM variables
-	lfsr	FSR1,opt_gas_O2_ratio		; load base address of gas      settings, ASM variables
-	movff	PLUSW0,PLUSW1				; copy O2 ratio
-	addlw	.10							; add offset from O2 ratios to He ratios
-	movff	PLUSW0,PLUSW1				; copy He ratio
-	addlw	.10							; add offset from He ratios to types
-	movff	PLUSW0,PLUSW1				; copy type
-	addlw	.10							; add offset from type to change depth
-	movff	PLUSW0,PLUSW1				; copy change depth
-	addlw	-.30						; wind back to initial gas number
-	lfsr	FSR0,char_I_gas_avail_size+5; load base address of diluents settings, shared variables
-	lfsr	FSR1,char_I_gas_avail_size+0; load base address of gas      settings, shared variables
-	movff	PLUSW0,PLUSW1				; copy tank size
-	addlw	.10							; add offset from tank sizes to pressure budget
-	movff	PLUSW0,PLUSW1				; copy pressure budget
-	call	gaslist_cleanup_list		; make sure that there will be just one first gas
-	btfss	copying_dil					; are we copying a diluent?
-	return								; NO  - done
-	bsf		is_diluent_menu				; YES - restore to be setting up diluents
-	movlw	.5							;     - offset between OC gases and diluents
-	addwf	gaslist_gas,F				;     - let gaslist_gas point to the diluent again
-	WIN_BOX_BLACK .30,.239,.0,.159		;     - create some visual effect to show activity
-	WAITMS	.200						;     - pause for 200 ms
-	return								;     - done
-
- ENDIF
-
-;=============================================================================
-
-;=============================================================================
-; Append gas description to current string
-;
-; Input:  PRODL : gas number (0..4)
-;         FSR2  : Current string position
-; Output: Text appended into buffer pointed by FSR2
-
-	global	gaslist_strcat_gas
-	global	gaslist_strcat_gas_WREG
-gaslist_strcat_gas:						; entry point with gas/dil in PRODL (0-4) and flag 'is_diluent_menu' set accordingly
+	global	gaslist_strcat_mix_PRODL
+gaslist_strcat_mix_PRODL:
 	movff	PRODL,gaslist_gas			; get current menu item (0-4)
 	movlw	.5							; offset between gases and diluents
 	btfsc	is_diluent_menu				; setting up diluents?
 	addwf	gaslist_gas,F				; YES - add the offset
 	movf	gaslist_gas,W				; copy to WREG
-gaslist_strcat_gas_WREG:				; entry point with gas/dil in WREG (0-9)
+	;bra	gaslist_strcat_mix_WREG		; continue
+
+
+;-----------------------------------------------------------------------------
+; Append Mix ("Nxlo", "Txlo/hi", "Air" or "O2") to current String
+;
+; Input:  WREG : gas/dil number (0..9)
+;
+	global	gaslist_strcat_mix_WREG
+gaslist_strcat_mix_WREG:				; entry point with gas/dil in WREG (0-9)
 	lfsr	FSR1,opt_gas_O2_ratio		; load base address of opt_gas_O2_ratio
 	movff	PLUSW1,lo					; read O2 ratio
 	lfsr	FSR1,opt_gas_He_ratio		; load base address of opt_gas_He_ratio
 	movff	PLUSW1,hi					; read He ratio
-	goto	gaslist_show_mix			; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2, and RETURN
-
-
-;=============================================================================
-; Append current mix to current string (for dive mode)
-;
-; Input:  FSR2 : Current string position
-; Output: Text appended into buffer pointed by FSR2
-
-	global	gaslist_strcat_gas6
-gaslist_strcat_gas6:					; show current O2/He mix
-	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
- IFDEF _helium
-	movff	gas6_He_ratio,hi			;                ... and He ratio in hi
- ELSE
-	clrf	hi							;                ... and He ration will be zero
- ENDIF
-	goto	gaslist_show_mix			; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2, and return
-
-
-;=============================================================================
-; Helper functions for menu_tree
-
-	global	gaslist_GasDepth
-gaslist_GasDepth:
-	movf	gaslist_gas,W				; load gas/dil index into WREG (0-9)
-	lfsr	FSR1,opt_gas_change			; load base address of change depths
-	tstfsz	PLUSW1						; change depth = 0 ?
-	bra		gaslist_GasDepth_1			; NO
-	lfsr	FSR1,opt_gas_type			; YES - load base address of opt_gas_type
-	tstfsz	PLUSW1						;     - type = disabled ?
-	call	TFT_attention_color			;       NO  - print in attention color (yellow)
-gaslist_GasDepth_1:
-	STRCAT_TEXT tSetup_GasDepth
-	return
-
-
-	global	gaslist_show_type
-gaslist_show_type:
-	movf	gaslist_gas,W
-	lfsr	FSR1,opt_gas_type			; load base address of opt_gas_type
-	movff	PLUSW1,lo					; read gas type
-	STRCAT_TEXT tType
-	lfsr	FSR1,tGasDisabled			; load base address of gas type labels
-	btfsc	is_diluent_menu				; setting up diluents?
-	lfsr	FSR1,tDilDisabled			; YES - load base address of diluent type labels
-	movff	lo,WREG						; 0-3
-	rlncf	WREG						; x2
-	addwf	FSR1L,F						; adjust address pointer to required text
-	movlw	.0
-	addwfc	FSR1H,F
-	call	strcat_text					; copy label text
-	return
+	;bra	gaslist_strcat_mix			; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2, and RETURN
 
 
-	global	gaslist_toggle_type
-gaslist_toggle_type:
-	lfsr	FSR1,opt_gas_type			; load base address of opt_gas_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?
-	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
+;----------------------------------------------------------------------------
+; Append Mix ("Nxlo", "Txlo/hi", "Air" or "O2") to current String
+;
+; Input: lo  O2%
+;        hi  He%
+;
+; Includes capability to show trimix gases to be able to properly decode data
+; from logbook in case trimix dives are stored on an OSTC running the sport FW
+;
+	global	gaslist_strcat_mix
+gaslist_strcat_mix:
+	tstfsz	hi							; He=0?
+	bra		gaslist_strcat_mix_5		; NO - print a TX
+
+gaslist_strcat_mix_1:
+	movlw	.21							; air is 21% O2
+	cpfseq	lo							; Air ?
+	bra		gaslist_strcat_mix_2		; NO  - try next
+	STRCAT_TEXT tSelectAir				; YES - print "Air"
+	bra		gaslist_strcat_mix_4b		;     - continue
+
+gaslist_strcat_mix_2:
+	movlw	.100						; O2 is 100% O2
+	cpfseq	lo							; O2 ?
+	bra		gaslist_strcat_mix_3		; NO  - try next
+	STRCAT_TEXT tSelectO2				; YES - print "O2"
+	bra		gaslist_strcat_mix_4b		;     - continue
+
+gaslist_strcat_mix_3:
+	movlw	.21							; strange mix has no He and O2 < 21%
+	cpfslt	lo							; < Nx21 ?
+	bra		gaslist_strcat_mix_4		; NO  - try next
+	STRCAT_TEXT tGasErr					; YES - print "Err"
+	output_99							;     - print O2%
+	bra		gaslist_strcat_mix_4c		;     - continue
+
+gaslist_strcat_mix_4:
+	STRCAT_TEXT tSelectNx				; print "Nx"
+	output_99							; print O2%
+
+gaslist_strcat_mix_4b:
+	STRCAT	" "							; print a space
+
+gaslist_strcat_mix_4c:
+	btfsc	divemode					; in dive mode?
+	return								; YES - done
+	STRCAT	"  "						; NO  - add two spaces
+	return								;     - done
+
+gaslist_strcat_mix_5:
+	btfsc	divemode					; in dive mode?
+	bra		gaslist_strcat_mix_6		; YES - do short version
+	STRCAT_TEXT tSelectTx				; NO  - print "Tx"
+
+gaslist_strcat_mix_6:
+	output_99							; print O2%
+	PUTC	"/"							; print "/"
+	movff	hi,lo						; move He% into lo
+	output_99							; print He%
 	return								; done
 
-;=============================================================================
-
- IFDEF _ccr_pscr
-
-	global	gaslist_strcat_setpoint
-	global	gaslist_strcat_setpoint_0
-gaslist_strcat_setpoint:				; entry point with setpoint index in PRODL
-	movff	PRODL,gaslist_gas			; get current menu item (0-4)
-gaslist_strcat_setpoint_0:				; entry point with setpoint index in gaslist_gas
-	bsf		leftbind
-	btfsc	short_gas_descriptions		; shall use short versions of gaslist_strcat_setpoint?
-	bra		gaslist_strcat_setpoint2	; YES - use short version
-	STRCAT_TEXT tSP						; "SP"
-	incf	gaslist_gas,W				; (0-4) -> (1-5) into WREG
-	movwf	lo
-	output_8							; print SP number
-	bcf		leftbind
-	PUTC	":"
-gaslist_strcat_setpoint2:				; short version
-	btfsc	divemode
-	bra		gaslist_strcat_setpoint4	; no "*" in dive mode
-	movf	gaslist_gas,W				; (0-4) into WREG
-	bnz		gaslist_strcat_setpoint3	; SP index = 0 ?
-	PUTC	"*"							; YES - print *
-	bra		gaslist_strcat_setpoint4	;     - continue with cbar value
-gaslist_strcat_setpoint3:				; NO
-	PUTC	" "							;     - print a space
-gaslist_strcat_setpoint4:
-	movf	gaslist_gas,W				; (0-4) into WREG
-	lfsr	FSR1,opt_setpoint_cbar		; load base address of setpoint cbar values
-	movf	PLUSW1,W					; read cbar value
-	movwf	lo
-	clrf	hi
-	bsf		leftbind
-	output_16dp d'3'					; print as X.XX
-	btfsc	divemode					; in dive mode?
-	bra		gaslist_strcat_setpoint5	; YES - skip text in dive mode
-	STRCAT_TEXT tbar					; NO  - print "bar"
-gaslist_strcat_setpoint5:
-	PUTC	" "							; print a space
-	movf	gaslist_gas,W				; (0-4) into WREG
-	lfsr	FSR1,opt_setpoint_change	; load base address of switch depths
-	movff	PLUSW1,lo					; read switch depth into lo
-	bra		gaslist_strcat_depth		; print depth in meters or ft
-
- ENDIF	; _ccr_pscr
 
 ;----------------------------------------------------------------------------
-; Append gas description to current string
+; Append full Gas Description to current String
 ;
 ; Prints gas number, * if first, = if deco gas, gas composition and change depth,
 ; including fancy color-coding
 ;
 ; Input:  PRODL gas number (0..4)
-;         FSR2  current string position
-; Output: text appended to buffer pointed by FSR2
+;         flag 'is_diluent_menu' for gas/dil selection
 ;
 ; NOTE: used in the menu-tree for the MENU_CALLBACK entry
-
-	global	gaslist_strcat_gas_cd
-gaslist_strcat_gas_cd:					; entry point with gas in PRODL (0-4) and flag 'is_diluent_menu' set accordingly
+;
+	global	gaslist_strcat_gas_PRODL
+gaslist_strcat_gas_PRODL:
 	movff	PRODL,gaslist_gas			; get current menu item (0-4)
 	movlw	.5							; offset between gases and diluents
 	btfsc	is_diluent_menu				; dealing with diluents?
 	addwf	gaslist_gas,F				; YES - add the offset
-	;bra	gaslist_gastitle			; continue with gaslist_gastitle function
+	;bra	gaslist_strcat_gas			; continue with gaslist_strcat_gas 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							; 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			;     - continue
+;----------------------------------------------------------------------------
+; Append full Gas Description to current String
+;
+; Print gas number, * if first, = if deco gas, gas composition and change depth,
+; including fancy color-coding
+;
+; Input:  gaslist_gas gas/dil number (0..9)
+;
+; NOTE: used in the menu-tree for the MENU_CALLBACK entry
+;
+	global	gaslist_strcat_gas
+gaslist_strcat_gas:
+	btfsc	short_gas_descriptions		; shall use short versions of gaslist_strcat_gas_PRODL?
+	bra		gaslist_gastitle_short		; YES - use short version
+	incf	gaslist_gas,W				; NO  - (0-9) -> (1-10) into WREG
+	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
+	;bra	gaslist_gastitle_gas		;       YES - it's a gas
+
+gaslist_gastitle_gas:
+	STRCAT_TEXT tGas					; it's a gas
+	bra		gaslist_gastitle_gas_num	; continue
+
 gaslist_gastitle_dil:
 	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) again
-gaslist_gastitle0:
-	bsf		leftbind
-	output_8							; print gas/dil number (1-5)
-	bcf		leftbind
-	PUTC	":"
-gaslist_gastitle1:						; short version of gaslist_strcat_gas_cd
+
+gaslist_gastitle_gas_num:
+	output_9							; print gas/dil number (1-5)
+	PUTC	":"							; print ":"
+
+gaslist_gastitle_short:
 	btfsc	divemode					; in dive mode?
-	bra		gaslist_gastitle3			; YES - no "*" and "=" in front of gas composition, no highlighting for transmitters paired
+	bra		gaslist_gastitle_color_avail; YES - no "*" and "=" in front of gas composition, no highlighting for transmitters paired
 
  IFDEF _rx_functions
-	btfss	tr_functions_activated		; NO  - TR functions activated?
-	bra		gaslist_gastitle2			;       NO  - continue with gas type
-	lfsr	FSR1,opt_transmitter_id_1	;       YES - load base address of transmitter ID table
-	movf	gaslist_gas,W				;           - (0-4 for OC/Bailout, 5-9 for Diluents)
-	rlncf	WREG,W						;           - index x2 because IDs are 2 byte
-	tstfsz	PLUSW1						;           - transmitter ID low byte <> 0 ?
-	bsf		win_invert					;             YES - flag transmitter paired by inverting output
-	incf	WREG,W						;           - increment index
-	tstfsz	PLUSW1						;           - transmitter ID high byte <> 0 ?
-	bsf		win_invert					;             YES - flag transmitter paired by inverting output
- ENDIF
+	btfss	tr_functions_activated		; TR functions activated?
+	bra		gaslist_gastitle_type_1		; NO  - continue with gas type
+	lfsr	FSR1,opt_transmitter_id_1	; YES - load base address of transmitter ID table
+	movf	gaslist_gas,W				;     - (0-4 for gases, 5-9 for diluents)
+	rlncf	WREG,W						;     - index x2 because IDs are 2 byte
+	tstfsz	PLUSW1						;     - transmitter ID low byte <> 0 ?
+	bsf		win_invert					;       YES - flag transmitter paired by inverting output
+	incf	WREG,W						;     - increment index
+	tstfsz	PLUSW1						;     - transmitter ID high byte <> 0 ?
+	bsf		win_invert					;       YES - flag transmitter paired by inverting output
+ ENDIF	; _rx_functions
 
-gaslist_gastitle2:
-	rcall	gaslist_strcat_gas_type		; print "*" for first gas/dil, "=" for a deco gas or " " else
-gaslist_gastitle3:
-	call	TFT_standard_color
+gaslist_gastitle_type_1:
+	rcall	gaslist_strcat_gas_type		; print type marking ("*", "=", "X", ...)
+
+gaslist_gastitle_color_avail:
+	FONT_COLOR_MEMO						; default to standard color
 	btfsc	divemode					; in dive mode?
 	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
 	btfsc	WREG,gas_lost				; gas/dil lost?
-	bra		gaslist_gastitle3a			; YES - switch to disabled color
+	bra		gaslist_gastitle_not_avail	; YES - switch to disabled color and skip ppO2 check
 	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:
+	bra		gaslist_gastitle_not_avail	; YES - switch to disabled color and skip ppO2 check
+	bnz		gaslist_gastitle_color_ppo2	; type not disabled -> color code by ppO2
+	;bz		gaslist_gastitle_not_avail	; type     disabled -> switch to disabled color and skip ppO2 check
+
+gaslist_gastitle_not_avail:
+	FONT_COLOR_DISABLED					; switch to disabled color
+	bra		gaslist_gastitle_mix		; skip ppO2 check for disabled gases
+
+gaslist_gastitle_color_ppo2:
 	btfss	divemode					; in dive mode?
-	bra		gaslist_gastitle5			; NO  - no color-coding if not in dive mode
+	bra		gaslist_gastitle_mix		; 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
+	bra		gaslist_gastitle_mix		;       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:
+
+gaslist_gastitle_mix:
 	movf	gaslist_gas,W				; copy gas/dil index to WREG (0-9)
-	rcall	gaslist_strcat_gas_WREG		; print gas composition
+	rcall	gaslist_strcat_mix_WREG		; print gas composition
 	btfss	divemode					; in dive mode?
-	bra		gaslist_gastitle6			; NO  - continue printing a space
-	rcall	gaslist_strcat_gas_type		; YES - print "*" for first gas/dil, "=" for a deco gas, or a space else
-	bra		gaslist_gastitle7			;     - continue with change depth
-gaslist_gastitle6:
+	bra		gaslist_gastitle_no_type	; NO  - print no type marking
+	;bra	gaslist_gastitle_type_2		; YES - print    type marking
+
+gaslist_gastitle_type_2:
+	rcall	gaslist_strcat_gas_type		; print type marking ("*", "=", "X", ...)
+	bra		gaslist_gastitle_depth		; continue with change depth
+
+gaslist_gastitle_no_type:
 	PUTC	" "							; print a space
-gaslist_gastitle7:
+
+gaslist_gastitle_depth:
 	lfsr	FSR1,opt_gas_change			; load base address of change depths
 	movf	gaslist_gas,W				; load gas/dil index into WREG (0-9)
 	movff	PLUSW1,lo					; read change depth into lo
-gaslist_strcat_depth:					; entry point for general printing of depths with value in meters in lo
-	TSTOSS	opt_units					; check depth units
-	bra		gaslist_strcat_depth_metric	; 0 - use Meters
-gaslist_strcat_depth_imperial:			; 1 - use 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
-gaslist_strcat_depth_metric:
-;	PUTC	" "							; print a space
-;	output_99
-	output_8
-	STRCAT_TEXT tMeters					; "m"
-	return
+	;bra	gaslist_strcat_depth		; print depth and return
 
 
-; check for better gas
+;-----------------------------------------------------------------------------
+; Helper Function - print Depths in Meters or Feet
+;
+; input: lo  depth in meters
 ;
-gaslist_strcat_gas_better:				; color-code output if this is the best gas/diluent
-	btfss	better_gas_hint				; shall better gas hints be given?
-	return								; NO - return
-	movf	best_gas_number,W			; get best gas number into WREG
+gaslist_strcat_depth: 
+	TSTOSS	opt_units					; check depth units
+	bra		gaslist_strcat_depth_meter	; 0 - use Meters
+	;bra	gaslist_strcat_depth_feet	; 1 - use Feet
+
+gaslist_strcat_depth_feet:
+	call	convert_meter_to_feet		; convert value in lo from [m] to [feet]
+	output_999							; print depth (0-999)
+	STRCAT_TEXT tFeets					; append "ft"	REMARK: still one char to long for space available in dive mode menu!
+	return								; done
+
+gaslist_strcat_depth_meter:
+	output_256							; print 0-256
+	STRCAT_TEXT tMeters					; append "m"
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - color-code Output if this is the best Gas/Diluent
+;
+gaslist_strcat_gas_better:
+	btfss	better_gas_hint				; shall better gas cues be given?
+	return								; NO  - return
+	movf	best_gas_number,W			; YES - get best gas number into WREG
  IFDEF _ccr_pscr
-	btfsc	is_diluent_menu				; setting up diluents?
-	movf	best_dil_number,W			; YES - overwrite with best diluent number
- ENDIF
-	tstfsz	WREG						; is a best gas/dil available?
-	bra		gaslist_strcat_gas_better1	; YES - proceed
-	return								; NO  - return
+	btfsc	is_diluent_menu				;     - setting up diluents?
+	movf	best_dil_number,W			;       YES - replace with best diluent number
+ ENDIF	; _ccr_pscr
+	tstfsz	WREG						;     - is a best gas/dil available?
+	bra		gaslist_strcat_gas_better1	;       YES - proceed
+	return								;       NO  - done
+
 gaslist_strcat_gas_better1:
 	decf	WREG,W						; (1-5) -> (0-4)
 	btfsc	is_diluent_menu				; setting up diluents?
-	addlw	.5							; YES - add offset between gases and diluents (0-4) -> (5-9)
-	cpfseq	gaslist_gas					; compare with given gas/dil (0-4 for OC bailout gases, 5-9 for diluents)
-	return								; not equal - return
-	bsf		win_invert					;     equal - invert
-	movlw	color_green					;           - select green color (gas is something "good")
-	goto	TFT_set_color				;           - activate color and return
+	addlw	.5							; YES - add offset between gases and diluents (0-4) -> (5-9) to better gas number
+	cpfseq	gaslist_gas					; is the current gas/dil the best one?
+	return								; NO  - done
+	bsf		win_invert					; YES - print invert
+	FONT_COLOR color_green				;     - select green color (gas is something "good")
+	return								;     - done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - print      "*"     for   first    Gas/Dil
+;                         a down arrow for a Work     Gas/Dil
+;                              "="     for a Deco     Gas
+;                              " "     for a disabled Gas/Dil
+;                              "X"     for a lost     Gas/Dil
+;                              "S"     for a staged   Gas/Dil
+;
 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)
@@ -483,421 +305,49 @@
  IFDEF _cave_mode
 	btfsc	WREG,gas_staged				; gas set as staged?
 	bra		gaslist_strcat_gas_type_5	; YES - print staged marking
- ENDIF
+ ENDIF	; _cave_mode
 	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
+
 gaslist_strcat_gas_type_1:
 	decf	WREG,W						; decrement gas type (-2 for disabled, -1 for first,  0 for work/normal, 1 for deco)
 	bnz		gaslist_strcat_gas_type_2	; type = work? NO  - continue with checking for deco gas
 	PUTC	"\xb8"						;              YES - print down-arrow for a work gas
 	return								;                  - done
+
 gaslist_strcat_gas_type_2:
 	decf	WREG,W						; decrement gas type (-3 for disabled, -2 for first, -1 for work/normal, 0 for deco)
 	bnz		gaslist_strcat_gas_type_3	; type = deco? NO  - neither first nor deco
 	PUTC	"="							;              YES - print "=" for a deco gas
-	return								;                   - done
+	return								;                  - done
+
 gaslist_strcat_gas_type_3:
-	PUTC	" "							; neither first nor deco, print a space
+	PUTC	" "							; type = disabled, print a space
 	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
-
-
-;----------------------------------------------------------------------------
-; Housekeeping for the gas/dil settings, e.g. making sure there is one FIRST only
-;
-; Input:  gaslist_gas  last edited gas/dil (0-9)
-
-	global	gaslist_cleanup_list
-gaslist_cleanup_list:
-	lfsr	FSR1,opt_gas_type			; load base address of opt_gas_type
- IFDEF _ccr_pscr
-	movlw	.5							; offset between gases and diluents
-	btfsc	is_diluent_menu				; setting up diluents?
-	subwf	gaslist_gas,F				; YES - subtract offset from gaslist_gas: (5-9) -> (0-4)
- ENDIF
-gaslist_cleanup_list0:
-	bcf		ignore_last_edited_gas
-gaslist_cleanup_list1:
-	clrf	lo							; counter for number of "firsts" found
-	movlw	.5							; initialize hi as loop counter for checking 5 gases/diluents
-	movwf	hi
-gaslist_cleanup_list2:					; loop body
-	decf	hi,W						; WREG = current gas/dil (0-4)
- IFDEF _ccr_pscr
-	btfsc	is_diluent_menu				; setting up diluents?
-	addlw	.5							; YES - add offset from gases to diluents -> (5-9)
- ENDIF
-	movff	PLUSW1,WREG					; read type into WREG
-	decfsz	WREG						; is type = first (ex type code 1)?
-	bra		gaslist_cleanup_list3		; NO  - done with this gas/dil
-	incf	lo,F						; YES - increment number of "firsts" found
-	btfss	ignore_last_edited_gas		;     - shall we ignore the last edited gas/dil?
-	bra		gaslist_cleanup_list2b		;       NO  - continue remembering the "last first" gas/dil (do a shortcut)
-	decf	hi,W						;       YES - get the current gas/dil as (0-4)
-	cpfseq	gaslist_gas					;           - is this the last edited gas/dil?
-gaslist_cleanup_list2b:
-	movff	hi,up						;             (NO) - remember the last "first gas" found
-gaslist_cleanup_list3:
-	decfsz	hi,F						; decrement loop counter, did loop counter became 0?
-	bra		gaslist_cleanup_list2		; NO  - loop
-	tstfsz	lo							; YES - any first gas/dil at all?
-	bra		gaslist_cleanup_list4		;       YES - at least one first gas/dil existing
- IFDEF _ccr_pscr
-	btfsc	is_diluent_menu				;       NO  - setting up diluents?
-	lfsr	FSR1,opt_dil_type			;             YES - load base address of opt_gas_type
- ENDIF
-	movlw	.1							;           - load coding for first gas
-	movwf	INDF1						;           - make gas/dil 1 the first gas
-	return								;           - done
-gaslist_cleanup_list4:
-	movlw	.1							; total number of Firsts that should exist is 1
-	cpfsgt	lo							; more then one "first gas" found?
-	return								; NO  - done
-	decf	up,W						; YES - WREG = last found "first gas" - 1 (0-4)
-	cpfseq	gaslist_gas					;     - is this the last edited gas/dil?
-	bra		gaslist_cleanup_list4b		;       NO  - disable it
-	bsf		ignore_last_edited_gas		;       YES - do not disable last edited gas, search again but ignore the last edited gas
-	bra		gaslist_cleanup_list1		;           - loop until only one "first" is left over
-gaslist_cleanup_list4b:
- IFDEF _ccr_pscr
-	btfsc	is_diluent_menu				; setting up diluents?
-	addlw	.5							; YES - adjust offset
- ENDIF
-	clrf	PLUSW1						; disable gas
-	bra		gaslist_cleanup_list0		; redo from start until only one "first" is left over
-	return
+ ENDIF	; _cave_mode
 
 
 ;----------------------------------------------------------------------------
-; Tank Settings
-;
-; Input: char_I_gas_avail_size   size of the tank in liters
-;        char_I_gas_avail_pres   available pressure in multiples of 10 bar
-
-	global	gaslist_tank_size_pres
-gaslist_tank_size_pres:					; dynamic title: xx l, xx0 bar
-	lfsr	FSR1,char_I_gas_avail_size	; load base address of char_I_gas_avail_size
-	movf	gaslist_gas,W				; load index (0-9)
-	movff	PLUSW1,lo					; read char_I_gas_avail_size[WREG] into lo
-	lfsr	FSR1,char_I_gas_avail_pres	; load base address of char_I_gas_avail_pres
-	movff	PLUSW1,hi					; read char_I_gas_avail_pres[WREG] into hi
-	STRCAT	"     "						; print 5 leading spaces for alignment
-	output_8							; print tank size
-	STRCAT_TEXT tLiter					; print unit (" l")
-	movff	hi,lo						; copy fill pressure into lo
-	output_8							; print fill pressure (it is stored in multiples of 10 bar)
-	STRCAT_TEXT tbar10					; print unit ("0 bar")
-	return
-
-
-	global	gaslist_tank_size
-gaslist_tank_size:						; adjust char_I_gas_avail_size between min_tank_size and max_tank_size
-	lfsr	FSR1,char_I_gas_avail_size	; load base address of char_I_gas_avail_size
-	movf	gaslist_gas,W				; load index (0-9)
-	movff	PLUSW1,lo					; read char_I_gas_avail_size[WREG] into lo
-	incf	lo,F						; increment tank size by 1 liter
-	movlw	max_tank_size				; load max. allowed value into WREG
-	cpfsgt	lo							; tank size <= max value?
-	bra		gaslist_tank_size_1			; YES - new value can be used
-	movlw	min_tank_size				; NO  - wrap-around to min value
-	movwf	lo							;     - and write to lo
-gaslist_tank_size_1:
-	movf	gaslist_gas,W				; re-load index
-	movff	lo,PLUSW1					; write back tank size to char_I_gas_avail_size[WREG]
-	return
-
-
-	global	gaslist_tank_pres
-gaslist_tank_pres:						; adjust char_I_gas_avail_pres between 5(0) and 29(0) bar
-	lfsr	FSR1,char_I_gas_avail_pres	; load base address of char_I_gas_avail_pres
-	movf	gaslist_gas,W				; load index (0-9)
-	movff	PLUSW1,lo					; read char_I_gas_avail_pres[WREG] into lo
-	incf	lo,F						; increment fill press by by 1(0) bar
-	movlw	max_fill_press				; load max. allowed value into WREG
-	cpfsgt	lo							; press <= max value?
-	bra		gaslist_tank_pres_1			; YES - new value can be used
-	movlw	min_fill_press				; NO  - wrap-around to min value
-	movwf	lo							;     - and write to lo
-gaslist_tank_pres_1:
-	movf	gaslist_gas,W				; re-load index
-	movff	lo,PLUSW1					; write back tank size to char_I_gas_avail_pres[WREG]
-	return
-
-
-;=============================================================================
-
- IFDEF _rx_functions
-
-; Transmitter functions - ID
-;
-	global	gaslist_tank_id_pres
-gaslist_tank_id_pres:					; dynamic title: shows ID and pressure from transmitter with ID opt_transmitter_id[gaslist_gas]
-										;                When changing layout, adapt output position TFT_menu_tank_pres!
-	STRCAT	"  ID: "					; print header
-	; get ID							;
-	lfsr	FSR1,opt_transmitter_id_1	; load base address of opt_transmitter_id
-	movf	gaslist_gas,W				; load index (0-9)
-	rlncf	WREG,W						; multiply by 2 because IDs are 2 byte in size
-	movff	PLUSW1,lo					; copy opt_transmitter_id+0[gaslist_gas] to lo
-	incf	WREG,W						; increment index
-	movff	PLUSW1,hi					; copy opt_transmitter_id+1[gaslist_gas] to hi
-	; check if a transmitter is paired to this tank
-	tstfsz	hi							; high byte of ID <> 0 ?
-	bra		gaslist_tank_id_pres_1		; YES - a transmitter is paired to the tank
-	tstfsz	lo							; low  byte of ID <> 0 ?
-	bra		gaslist_tank_id_pres_1		; YES - a transmitter is paired to the tank
-	STRCAT	"----"						; NO  - no transmitter paired
-	bcf		imprint_xmitter_pres		;     - stop imprinting of transmitter pressure data
-	return								;     - done
-gaslist_tank_id_pres_1:					; YES - show ID
-	movf	hi,W						;     - copy high byte of ID to WREG
-	output_hex							;     - print it
-	movf	lo,W						;     - copy low  byte of ID to WREG
-	output_hex							;     - print it
-	bsf		imprint_xmitter_pres		;     - start imprinting of transmitter pressure data
-	return								;     - done
-
-
-; Transmitter functions - Pairing
-;
-	global	gaslist_tank_pairing
-gaslist_tank_pairing:
-	incf	pairing_slot,F				; goto next RX data slot
-	btfsc	pairing_slot,3				; slot = 8?
-	bra		gaslist_tank_pairing_none	; YES - offer unpairing
-	movf	pairing_slot,W				; NO  - copy slot to WREG
-	call	get_transmitter_id_by_slot	; WREG = slot (0-7) -> hi:lo = transmitter ID
-	tstfsz	hi							; transmitter found (probe on high byte)?
-	bra		gaslist_tank_pairing_common	; YES - select this transmitter
-	tstfsz	hi							; transmitter found (probe on low byte)?
-	bra		gaslist_tank_pairing_common	; YES - select this transmitter
-	bra		gaslist_tank_pairing		; NO  - try next slot
-gaslist_tank_pairing_common:
-	lfsr	FSR1,opt_transmitter_id_1	; load base address of opt_transmitter_id
-	movf	gaslist_gas,W				; load index into WREG (0-9)
-	rlncf	WREG,W						; multiply by 2 because IDs are 2 byte in size
-	movff	lo,PLUSW1					; copy lo to opt_transmitter_id+0[gaslist_gas]
-	incf	WREG,W						; increment index
-	movff	hi,PLUSW1					; copy hi to opt_transmitter_id+1[gaslist_gas]
-	return								; done
-gaslist_tank_pairing_none:
-	setf	pairing_slot				; prime slot number with 255 aka -1
-	clrf	hi							; adjust "no transmitter" ID
-	clrf	lo							; adjust "no transmitter" ID
-	bra		gaslist_tank_pairing_common	; continue with common part
-
- ENDIF
-
-;=============================================================================
-
-;----------------------------------------------------------------------------
-; Helper Functions for Menu Operations
-
-
-; Increment O2 ratio
-;
-	global	gaslist_pO2
-gaslist_pO2:
-	movf	gaslist_gas,W				; load index (0-9)
-	lfsr	FSR1,opt_gas_He_ratio		; load base address of opt_gas_He_ratio
-	movff	PLUSW1,hi					; read He ratio into hi
-	lfsr	FSR1,opt_gas_O2_ratio		; load base address of opt_gas_O2_ratio
-	movff	PLUSW1,lo					; read O2 ratio into lo
-
-	incf	lo,F						; O2++
-	movf	hi,W						; get He ratio into WREG
-	addwf	lo,W						; add O2 ratio to   WREG
-	movwf	up							; move sum He + O2 to up
-	movlw	.101						;
-	cpfslt	up							; O2 + He < 101?
-	decf	lo,F						; O2-- (revoke ++)
-	movf	gaslist_gas,W				; re-load index
-	movff	lo,PLUSW1					; write back O2 ratio to opt_gas_O2_ratio[WREG]
-	return
-
-
-; Decrement O2 ratio
-;
-	global	gaslist_mO2
-gaslist_mO2:
-	movf	gaslist_gas,W				; load index (0-9)
-	lfsr	FSR1,opt_gas_O2_ratio		; load base address of opt_gas_O2_ratio
-	movff	PLUSW1,lo					; read O2 ratio into lo
-
-	decf	lo,F						; O2--
-	movlw	gaslist_min_o2				; get minimum allowed O2 ratio
-	cpfslt	lo							; current O2 ratio below allowed minimum?
-	bra		gaslist_mO2_1				; NO
-	movwf	lo							; YES - copy minimum O2 ratio to lo
-gaslist_mO2_1:
-	movf	gaslist_gas,W				; re-load index
-	movff	lo,PLUSW1					; write back O2 ratio to opt_gas_O2_ratio[WREG]
-	return
-
-;=============================================================================
-
- IFDEF _helium
-
-; Increment He ratio
-;
-	global	gaslist_pHe
-gaslist_pHe:
-	movf	gaslist_gas,W				; load index (0-9)
-	lfsr	FSR1,opt_gas_O2_ratio		; load base address of opt_gas_O2_ratio
-	movff	PLUSW1,lo					; read O2 ratio into lo
-	lfsr	FSR1,opt_gas_He_ratio		; load base address of opt_gas_He_ratio
-	movff	PLUSW1,hi					; read He ratio into hi
-
-	incf	hi,F						; He++
-	movf	hi,W						; get He ratio into WREG
-	addwf	lo,W						; add O2 ratio to WREG
-	movwf	up							; move sum He + O2 to up
-	movlw	.101						;
-	cpfslt	up							; O2 + He < 101?
-	decf	hi,F						; He-- (revoke ++)
-	movf	gaslist_gas,W				; re-load index
-	movff	hi,PLUSW1					; write back He ratio to opt_gas_He_ratio[WREG]
-	return
-
-; Decrement He ratio
-;
-	global	gaslist_mHe
-gaslist_mHe:
-	movf	gaslist_gas,W				; load index (0-9)
-	lfsr	FSR1,opt_gas_He_ratio		; load base address of opt_gas_He_ratio
-	movff	PLUSW1,hi					; read He ratio into hi
-
-	decf	hi,F						; He--
-	bnn		gaslist_mHe_1				; He ratio negative?
-	clrf	hi							; YES - set He ratio to 0
-gaslist_mHe_1:
-	movf	gaslist_gas,W				; re-load index
-	movff	hi,PLUSW1					; write back He ratio to opt_gas_He_ratio[WREG]
-	return
-
- ENDIF	; _helium
-
-;=============================================================================
-
-; Increment switch depth
-;
-	global	gaslist_pDepth
-gaslist_pDepth:
-	lfsr	FSR1,opt_gas_change			; load base address of opt_gas_change
-	movf	gaslist_gas,W				; load index (0-4)
-	movff	PLUSW1,lo					; read switch depth into lo
-	incf	lo,F						; increment switch depth
-	movlw	gaslist_max_change_depth	; get max change depth
-	cpfsgt	lo							; above max change depth?
-	bra		gaslist_pDepth_1			; NO
-	movwf	lo							; YES - revert to max change depth
-gaslist_pDepth_1:
-	movf	gaslist_gas,W				; re-load index
-	movff	lo,PLUSW1					; write back switch depth
-	return
-
-
-; Decrement switch depth
-;
-	global	gaslist_mDepth
-gaslist_mDepth:
-	lfsr	FSR1,opt_gas_change			; load base address of opt_gas_change
-	movf	gaslist_gas,W				; load index (0-4)
-	movff	PLUSW1,lo					; read switch depth into lo
-	decf	lo,F						; decrement switch depth
-	btfsc	STATUS,N					; did depth became negative?
-	clrf	lo							; YES - reset to zero
-	movff	lo,PLUSW1					; write back switch depth
-	return
-
-;=============================================================================
-
- IFDEF _ccr_pscr
-
-; Increment setpoint
-;
-	global	gaslist_spplus
-gaslist_spplus:
-	movf	gaslist_gas,W
-	lfsr	FSR1,opt_setpoint_cbar
-	movff	PLUSW1,lo					; read setpoint
-	movlw	gaslist_sp_stepsize
-	addwf	lo,F
-	movlw	gaslist_sp_max
-	cpfsgt	lo
-	bra		gaslist_spplus2
-	movlw	gaslist_sp_min
-	movwf	lo
-gaslist_spplus2:
-	movf	gaslist_gas,W
-	movff	lo,PLUSW1					; write back setpoint
-	return
-
-
-; Increment setpoint switch depth
-;
-	global	gaslist_spdepthplus
-gaslist_spdepthplus:
-	movf	gaslist_gas,W				; get setpoint number (0-4)
-	bz		gaslist_spdepthplus2		; setpoint number = 0? YES - force depth to always be 0m
-	lfsr	FSR1,opt_setpoint_change	; load base address of opt_setpoint_change
-	movff	PLUSW1,lo					; read setpoint depth into lo
-	incf	lo,F						; increment depth
-	movlw	gaslist_max_change_depth	; get max. depth
-	cpfsgt	lo							; switch depth > max. depth?
-	bra		gaslist_spdepthplus_1		; NO
-	movwf	lo							; YES - copy to lo
-gaslist_spdepthplus_1:
-	movf	gaslist_gas,W				; re-load index
-	movff	lo,PLUSW1					; write back setpoint depth
-	return
-
-
-; Decrement set point switch depth
-;
-	global	gaslist_spdepthminus
-gaslist_spdepthminus:
-	movf	gaslist_gas,W				; get setpoint number (0-4)
-	bz		gaslist_spdepthminus2		; setpoint number = 0? YES - force depth to always be 0m
-	lfsr	FSR1,opt_setpoint_change	; load base address of opt_setpoint_change
-	movff	PLUSW1,lo					; read setpoint depth into lo
-	decf	lo,F						; decrement switch depth
-	btfsc	STATUS,N					; did depth became negative?
-	clrf	lo							; YES - reset to zero
-	movff	lo,PLUSW1					; write back setpoint depth
-	return
-
-
-; helper for increment/decrement setpoint switch depth
-;
-gaslist_spdepthplus2:
-gaslist_spdepthminus2:
-	movlw	.0
-	movff	WREG,opt_setpoint_change+0; hard reset to 0m
-	return
-
- ENDIF	; _ccr_pscr
-
-;=============================================================================
-
-
-;----------------------------------------------------------------------------
+; Helper Function:
 ; Compute MOD from O2 ratio and char_I_ppO2_max_work / char_I_ppO2_max_deco
 ; Compute MOD from O2 ratio and char_I_ppO2_max_deco
 ;
-; Input:  gaslist_gas                   = current gas index.
+; Input:  gaslist_gas                   = current gas index
 ;         opt_gas_O2_ratio[gaslist_gas] = current O2 ratio
 ; Output: WREG                          = MOD [m]
 ;
+	global gaslist_calc_mod
 gaslist_calc_mod:
 	lfsr	FSR1,opt_gas_type			; load base address of opt_gas_type
 	movf	gaslist_gas,W				; load index (0...9)
@@ -910,22 +360,169 @@
 	lfsr	FSR1,opt_gas_O2_ratio		; load base address of opt_gas_O2_ratio
 	movf	gaslist_gas,W				; load index (0...9)
 	movff	PLUSW1,xB+0					; read O2 ratio into xB+0
-	movf	xB+1,W						; copy ppO2 max into WREG
+	movf	xB+1,W						; copy ppO2 [cbar] max into WREG
 	clrf	xB+1						; clear xB+1 for div16x16 operation
 	mullw	.10							; multiply ppO2 max value with 10
 	MOVII	PROD,xA						; copy result to xA
 	call	div16x16					; xC = xA / xB with xA as remainder
-	movf	xC+0,W						; copy low  byte of the result to WREG
-	addlw	-.10						; subtract 10 cbar
+	movf	xC+0,W						; copy low byte of the result to WREG
+	addlw	-.10						; subtract 10 m to remove the 1 bar surface pressure
 	return								; return with final result [in meters] in WREG
 
-;----------------------------------------------------------------------------
+
+;=============================================================================
+gaslist2	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Clean up the Gas/Diluent Settings so that there is only one FIRST Gas/Diluent
+;
+; Input:  gaslist_gas  last edited gas/dil (0-9)
+;
+	global	gaslist_cleanup_list
+gaslist_cleanup_list:
+	lfsr	FSR1,opt_gas_type			; load base address of opt_gas_type
+
+ IFDEF _ccr_pscr
+	movlw	.5							; offset between gases and diluents
+	btfsc	is_diluent_menu				; setting up diluents?
+	subwf	gaslist_gas,F				; YES - subtract offset from gaslist_gas: (5-9) -> (0-4)
+ ENDIF	; _ccr_pscr
+
+gaslist_cleanup_list_loop_1:
+	bcf		ignore_last_edited_gas		; allow the last edited gas/dil to be found as a "first"
+
+gaslist_cleanup_list_loop_2:
+	clrf	lo							; clear number of "first" gases found
+	movlw	.5							; initialize hi as loop counter for checking 5 gases/diluents
+	movwf	hi							; ...
+
+gaslist_cleanup_list_loop_3:
+	decf	hi,W						; WREG = current gas/dil to check (4..0)
+
+ IFDEF _ccr_pscr
+	btfsc	is_diluent_menu				; setting up diluents?
+	addlw	.5							; YES - add offset from gases to diluents -> (9..5)
+ ENDIF	; _ccr_pscr
+
+	movff	PLUSW1,WREG					; read type into WREG
+	decfsz	WREG						; type = first ?
+	bra		gaslist_cleanup_1			; NO  - done with this gas/dil
+	incf	lo,F						; YES - increment number of "firsts" found
+	btfss	ignore_last_edited_gas		;     - shall the last edited gas/dil be skipped?
+	bra		gaslist_cleanup_set_first	;       NO  - set the currently checked gas/dil as last "first" found
+	decf	hi,W						;       YES - get the currently checked gas/dil (0..4)
+	cpfseq	gaslist_gas					;           - is  the currently checked gas/dil == the last edited gas/dil ?
+gaslist_cleanup_set_first:
+	movff	hi,up						;             (NO) - set current gas/dil as the last "first" found (1..5)
+
+gaslist_cleanup_1:
+	decfsz	hi,F						; decrement loop counter, did loop counter became 0?
+	bra		gaslist_cleanup_list_loop_3	; NO  - check next gas/dil
+	tstfsz	lo							; YES - any first gas/dil at all?
+	bra		gaslist_cleanup_list_2		;       YES - one or more "first" gas/dil found
+
+ IFDEF _ccr_pscr
+	btfsc	is_diluent_menu				;       NO  - setting up diluents?
+	lfsr	FSR1,opt_dil_type			;             YES - load base address of opt_gas_type
+ ENDIF	; _ccr_pscr
+
+	movlw	.1							;           - load coding for first gas
+	movwf	INDF1						;           - make gas/dil 1 the first gas
+	bsf		option_changed				;           - flag that the EEPROM needs to be updated
+	return								;           - done
+
+gaslist_cleanup_list_2:
+	movlw	.1							; total number of "first" gas/dil allowed is 1
+	cpfsgt	lo							; more than one "first" found?
+	return								; NO  - done
+	decf	up,W						; YES - get last found "first" (0-4)
+	cpfseq	gaslist_gas					;     - is  last found "first" == last edited gas/dil ?
+	bra		gaslist_cleanup_disable		;       NO  - disable it
+	bsf		ignore_last_edited_gas		;       YES - do not find the last edited gas/dil as "first" any more
+	bra		gaslist_cleanup_list_loop_2	;           - loop until only one "first" is left over
 
-; print ppO2 as x.xx for gas/diluent in gaslist_gas (0-9)
+gaslist_cleanup_disable:
+ IFDEF _ccr_pscr
+	btfsc	is_diluent_menu				; setting up diluents?
+	addlw	.5							; YES - adjust offset
+ ENDIF	; _ccr_pscr
+
+	clrf	PLUSW1						; disable the gas/dil
+	bsf		option_changed				; flag that the EEPROM needs to be updated
+	bra		gaslist_cleanup_list_loop_1	; redo from start until only one "first" is left over
+
+
+;=============================================================================
+gaslist3	CODE
+;=============================================================================
+
+ IFDEF _ccr_pscr
+
+;-----------------------------------------------------------------------------
+; Main Menu Item - print Setpoint by 'PRODL' (dynamic Title)
+;
+	global	gaslist_strcat_setpoint_PRODL
+gaslist_strcat_setpoint_PRODL:
+	movff	PRODL,gaslist_gas			; get current menu item (0-4)
+	;bra	gaslist_strcat_setpoint		; continue
+
+
+;-----------------------------------------------------------------------------
+; Main Menu Item - print Setpoint by 'gaslist_gas' (dynamic Title)
+;
+	global	gaslist_strcat_setpoint
+gaslist_strcat_setpoint:
+	btfsc	short_gas_descriptions		; shall use short version?
+	bra		gaslist_strcat_setpoint2	; YES - use short version
+	STRCAT_TEXT tSP						; "SP"
+	incf	gaslist_gas,W				; (0-4) -> (1-5) into WREG
+	movwf	lo							; copy to lo
+	output_9							; print SP number (0-9)
+	PUTC	":"							; ":"
+
+gaslist_strcat_setpoint2:
+	btfsc	divemode					; in dive mode?
+	bra		gaslist_strcat_setpoint4	; YES - do not add the "*" in dive mode
+	movf	gaslist_gas,W				; NO  - (0-4) into WREG
+	bnz		gaslist_strcat_setpoint3	;     - SP index = 0 ?
+	PUTC	"*"							;       YES - print *
+	bra		gaslist_strcat_setpoint4	;     - continue with cbar value
+
+gaslist_strcat_setpoint3:
+	PUTC	" "							; print a space
+
+gaslist_strcat_setpoint4:
+	movf	gaslist_gas,W				; (0-4) into WREG
+	lfsr	FSR1,opt_setpoint_cbar		; load base address of setpoint cbar values
+	movf	PLUSW1,W					; read cbar value
+	movwf	lo							; copy to lo
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_256							; print as x.xx
+	btfsc	divemode					; in dive mode?
+	bra		gaslist_strcat_setpoint5	; YES - skip text in dive mode
+	STRCAT_TEXT tbar					; NO  - print "bar"
+
+gaslist_strcat_setpoint5:
+	PUTC	" "							; print a space
+	movf	gaslist_gas,W				; (0-4) into WREG
+	lfsr	FSR1,opt_setpoint_change	; load base address of switch depths
+	movff	PLUSW1,lo					; read switch depth into lo
+	goto	gaslist_strcat_depth		; print depth (meters or ft)
+
+ ENDIF	; _ccr_pscr
+
+
+;=============================================================================
+gaslist4	CODE
+;=============================================================================
+
+;----------------------------------------------------------------------------
+; Main Menu Item - print ppO2 at Change Depth (dynamic Title)
 ;
 	global	gaslist_ppo2
 gaslist_ppo2:
-	STRCAT_TEXT tppO2					; ppO2:
+	STRCAT_TEXT tppO2					; print "ppO2:"
 	lfsr	FSR1,opt_gas_change			; load base address of opt_gas_change
 	movf	gaslist_gas,W				; load index (0-9)
 	movf	PLUSW1,W					; read change depth into WREG
@@ -938,59 +535,59 @@
 	clrf	xB+1						; clear xB+1
 	call	mult16x16					; calculate char_I_O2_ratio * (p_amb/10)
 	MOVII	xC,xA						; copy result to xA
-	movlw	d'100'						; load 100 to xB
-	movwf	xB+0
-	clrf	xB+1
+	MOVLI	.100,xB						; load 100    to xB
 	call	div16x16					; xC = xA / xB = (char_I_O2_ratio * p_amb/10)/100
 	; check for very high ppO2
 	tstfsz	xC+2						; xC+2 remains from mult16x16, xC+2 > 0 (-> ppO2 is > 6.55 bar) ?
-	bra		gaslist_ppo2_1				; YES - display a fixed max value
-	MOVII	xC,mpr						; copy result to hi:lo
-	bcf		ignore_digit4
-	bsf		leftbind
-	output_16dp d'3'					; print ppO2 as x.xx
-	STRCAT_TEXT tbar					; print "bar"
-	return
+	bra		gaslist_ppo2_2				; YES - display a fixed max value
+	PUTC	" "							; NO  - print a space
+	MOVII	xC,mpr						;     - copy result to hi:lo
+	bsf		leftbind					;     - print left-aligned
+	bsf		decimal_digit2				;     - place a decimal point in front of digit 2
+	output_999							;     - print ppO2 (0.00-655.35)
 gaslist_ppo2_1:
-	STRCAT	">6.6"
-	return
+	STRCAT_TEXT tbar					;     - print "bar"
+	return								;     - done
+
+gaslist_ppo2_2:
+	STRCAT	">6.55"						; print ">6.55"
+	bra		gaslist_ppo2_1				; append unit and return
 
 
-; print MOD and END for gas in gaslist_gas (0-9)
+;-----------------------------------------------------------------------------
+; Main Menu Item - print MOD and END for a Gas (dynamic Title)
 ;
 	global	gaslist_MOD_END
 gaslist_MOD_END:
 	STRCAT_TEXT tMOD					; print "MOD:"
-	rcall	gaslist_calc_mod			; compute MOD into WREG
+	call	gaslist_calc_mod			; compute MOD into WREG
 	movwf	lo							; copy result to lo
+	movwf	hi							; keep copy   in hi
 	call	gaslist_strcat_depth		; print depth in meters or feet as configured
 	PUTC	"/"							; print "/"
 	STRCAT_TEXT tEND					; print "END:"
-	rcall	gaslist_calc_mod			; compute MOD into WREG
+	movf	hi,W						; retrieve MOD
 	addlw	.10							; compute MOD = MOD + 10m
-	movwf	xB+0
-	clrf	xB+1
-	movlw	d'100'
-	movwf	xA+0
+	movwf	xB+0						; copy to xB
+	clrf	xB+1						; ...
+	MOVLI	.100,xA						; load 100 to xA
 	lfsr	FSR1,opt_gas_He_ratio		; load base address of opt_gas_He_ratio
 	movf	gaslist_gas,W				; load index (0...9)
-	movf	PLUSW1,W					; read He ration into WREG
-	subwf	xA+0,F						; xA+0 = 100 - He ratio in %
-	clrf	xA+1
-	call	mult16x16					; xA*xB=xC
-	MOVII	xC,xA
-	movlw	d'100'
-	movwf	xB+0
-	clrf	xB+1
+	movf	PLUSW1,W					; read He ratio into WREG
+	subwf	xA+0,F						; xA = 100 - He ratio in %
+	call	mult16x16					; xC = xA * xB
+	MOVII	xC,xA						; copy result to xA
+	MOVLI	.100,xB						; load 100 to xB
 	call	div16x16					; xC = xA / xB with xA as remainder
 	;									; xC:2 = ((MOD+10) * 100 - HE Value in %) / 100
 	movlw	d'10'						; subtract 10 m
 	subwf	xC+0,F						; ...
 	movff	xC+0,lo						; copy result to lo
-	bra		gaslist_strcat_depth		; print depth in meters or feet as configured and return
+	goto	gaslist_strcat_depth		; print depth and return
 
 
-; print change depth of gas in gaslist_gas (0-9), use warning color if > MOD
+;-----------------------------------------------------------------------------
+; Main Menu Item - print 'reset to MOD' (dynamic Title)
 ;
 	global	gaslist_reset_mod_title
 gaslist_reset_mod_title:
@@ -999,80 +596,22 @@
 	lfsr	FSR1,opt_gas_change			; load base address of opt_gas_change
 	movf	gaslist_gas,W				; load index (0-9)
 	movff	PLUSW1,hi					; read change depth into hi
-	rcall	gaslist_calc_mod			; compute MOD for ppO2 max work/deco dependent on gas type into WREG
+	call	gaslist_calc_mod			; compute MOD for ppO2 max work/deco dependent on gas type into WREG
 	movwf	lo							; copy (true) MOD   to lo
 	movf	hi,W						; copy change depth to WREG
 	cpfslt	lo							; change depth > MOD ?
-	bra		gaslist_strcat_depth		; NO  - print MOD from value in lo
-	call	TFT_attention_color			; YES - use attention color
-	rcall	gaslist_calc_mod_deco		;     - compute MOD for ppO2 max deco into WREG
+	bra		gaslist_reset_mod_title_exit; NO  - print MOD from value in lo
+	FONT_COLOR_ATTENTION				; YES - use attention color
+	call	gaslist_calc_mod_deco		;     - compute MOD for ppO2 max deco into WREG
 	movwf	up							;     - copy result to up
 	movf	hi,W						;     - copy change depth to WREG again
 	cpfslt	up							;     - change depth > MOD deco ?
-	bra		gaslist_strcat_depth		;       NO  - print MOD from value in lo, keeping attention color
-	call	TFT_warning_color			;       YES - switch to warning color
-	bra		gaslist_strcat_depth		;           - print MOD from value in lo
-
-
-; set change depth of gas in gaslist_gas (0-9) to its MOD
-;
-	global	gaslist_reset_mod
-gaslist_reset_mod:
-	rcall	gaslist_calc_mod			; compute MOD into WREG
-	movwf	lo							; copy result to lo
-	lfsr	FSR1,opt_gas_change			; load base address of opt_gas_change
-	movf	gaslist_gas,W				; load index (0-9)
-	movff	lo,PLUSW1					; write back new change depth
-	return
-
-;----------------------------------------------------------------------------
-; put "Nxlo", "Txlo/hi", "Air" or "O2" into postinc2
-;
-; Includes capability to show trimix gases to be able to properly decode data
-; from logbook in case trimix dives are stored on an OSTC running the sport FW.
+	bra		gaslist_reset_mod_title_exit;       NO  - print MOD from value in lo, keeping attention color
+	FONT_COLOR_WARNING					;       YES - switch to warning color
+	;bra	gaslist_reset_mod_title_exit;           - print MOD depth
 
-	global	gaslist_show_mix
-gaslist_show_mix:
-	tstfsz	hi							; He=0?
-	bra		gaslist_show_mix5			; NO - show a TX
-	movlw	.21
-	cpfseq	lo							; Air?
-	bra		gaslist_show_mix2			; NO
-	STRCAT_TEXT tSelectAir				; YES - show "Air"
-	bra		gaslist_show_mix4b
-gaslist_show_mix2:
-	movlw	.100
-	cpfseq	lo							; O2?
-	bra		gaslist_show_mix3			; NO
-	STRCAT_TEXT tSelectO2				; YES - show "O2"
-	bra		gaslist_show_mix4b
-gaslist_show_mix3:
-	movlw	.21
-	cpfslt	lo							; < Nx21?
-	bra		gaslist_show_mix4			; NO
-	STRCAT_TEXT tGasErr					; YES - show "Err"
-	output_99							; O2 ratio is still in "lo"
-	bra		gaslist_show_mix4c
-gaslist_show_mix4:
-	STRCAT_TEXT tSelectNx				; show "Nx"
-	output_99							; O2 ratio is still in "lo"
-gaslist_show_mix4b:
-	STRCAT	" "
-gaslist_show_mix4c:
-	btfsc	divemode					; in dive mode?
-	return								; YES
-	STRCAT	"  "
-	return
-gaslist_show_mix5:
-	btfsc	divemode
-	bra		gaslist_show_mix6
-	STRCAT_TEXT tSelectTx				; show "Tx"
-gaslist_show_mix6:
-	output_99							; O2 ratio is still in "lo"
-	PUTC	"/"
-	movff	hi,lo
-	output_99							; He ratio
-	return
+gaslist_reset_mod_title_exit:
+	goto	gaslist_strcat_depth		; print MOD depth and return
 
 ;-----------------------------------------------------------------------------
 
--- a/src/gaslist.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/gaslist.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File gaslist.inc                          combined next generation V3.08.7
+;   File gaslist.inc                        * combined next generation V3.09.4j
 ;
 ;   Interface to OSTC gas list management.
 ;
@@ -10,61 +10,21 @@
 ;   2011-08-11 : [jDG] Creation.
 
 	; Utils
-	extern	gaslist_strcat_gas
-	extern	gaslist_strcat_gas_WREG
-	extern	gaslist_strcat_gas_cd
-	extern	gaslist_show_mix				; put "Nxlo", "Txlo/hi", "Air" or "O2" into Postinc2
-	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
+	extern	gaslist_strcat_mix_PRODL		; append gas mix to buffer, gas number in PRODL
+	extern	gaslist_strcat_mix_WREG			; append gas mix to buffer, gas number in WREG
+	extern	gaslist_strcat_mix				; append gas mix to buffer, lo= O2%, hi= He%
+	extern	gaslist_strcat_gas_PRODL		; append full gas description to buffer by PRODL and dil flag
+	extern	gaslist_strcat_gas				; append full gas description to buffer by gaslist_gas
+	extern	gaslist_calc_mod				; calculate MOD in meters
+	extern	gaslist_cleanup_list			; make sure there is only one FIRST gas & diluent
 
-	; 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
-	extern	gaslist_strcat_setpoint
-	extern	gaslist_spplus
-	extern	gaslist_spdepthplus
-	extern	gaslist_spdepthminus
-	extern	gaslist_copy_dil_to_oc
+	extern	gaslist_strcat_setpoint_PRODL	; print setpoint data by number in PRODL
+	extern	gaslist_strcat_setpoint			; print setpoint data by number in gaslist_gas
  ENDIF
 
-	; 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
-
-	; RX Functions
- IFDEF _rx_functions
-	extern	gaslist_tank_id_pres
-	extern	gaslist_tank_pairing
-	extern	do_toggle_max_pres_diff_label
- ENDIF
+	; dynamic Titles
+	extern	gaslist_MOD_END					; print MOD and END
+	extern	gaslist_ppo2					; print ppO2 at Change Depth
+	extern	gaslist_reset_mod_title			; print 'reset to MOD' title
--- a/src/ghostwriter.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/ghostwriter.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File ghostwriter.asm                      combined next generation V3.08.8
+;   File ghostwriter.asm                    * combined next generation V3.09.4k
 ;
 ;   Ghostwriter (Log profile recorder)
 ;
@@ -19,13 +19,14 @@
 #include "divemode.inc"
 #include "rtc.inc"
 #include "logbook.inc"
+#include "convert.inc"
 
 
 	extern	deco_pull_tissues_from_vault
 
 
-; ----------------------------------------------------------------------------
-;  Macros - write PROFILE data to FLASH (all macros are bank-safe)
+;-----------------------------------------------------------------------------
+;  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
@@ -47,7 +48,7 @@
 	endm
 
 
-; ----------------------------------------------------------------------------
+;-----------------------------------------------------------------------------
 ;   private local Variables
 
 	CBLOCK	local3						; max size is 16 Byte !!!
@@ -62,11 +63,13 @@
 	ENDC								; used: 8 byte, remaining: 8 byte
 
 
-ghostwriter	CODE
-
+;=============================================================================
+ghostwrite1		CODE
 ;=============================================================================
 
-
+;-----------------------------------------------------------------------------
+; prepare Data Recording
+;
 	global	init_recording_params		; initialize profile recording parameters
 init_recording_params:
 	movlw	div_temperature				; get divisor for temperature storage
@@ -105,6 +108,13 @@
 	return
 
 
+;=============================================================================
+ghostwrite2		CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; sample and store a Set of Dive Data
+;
 	global	store_dive_data
 store_dive_data:
 	bcf		trigger_sample_divedata		; clear flag
@@ -143,7 +153,7 @@
 	decfsz	divisor_supersat,W			; check divisor if it will become 0, dump decremented value to WREG
 	bra		check_extended3				; NO  - skip
 	movlw	infolength_gf				; YES - get length of extra data
-	addwf	ProfileFlagByte,F			; add to ProfileFlagByte
+	addwf	ProfileFlagByte,F			;     - add to ProfileFlagByte
 check_extended3:
  IFDEF _external_sensor
 	decfsz	divisor_ppo2_sensors,W		; check divisor if it will become 0, dump decremented value to WREG
@@ -226,7 +236,7 @@
 	FLASH_CC_PROFILE ProfileFlagByte	; store ProfileFlagByte
 
 	btfss	event_occured				; global event flag set?
-	bra		store_dive_data4			; NO - no events to store
+	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
@@ -433,15 +443,18 @@
 ; 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
+	movf	POSTINC0,W						; get byte into WREG
+	call	ext_flash_write_byte_0x20_incdc	; write to external flash and increment ext_flash_dive_counter
+	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)
+	goto	ext_flash_write_byte_0x20_incdc	; write to external flash and increment ext_flash_dive_counter (and return)
 ;
 ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
+;-----------------------------------------------------------------------------
+; finish Dive Data Recording and write Header
+;
 	global	ghostwriter_end_dive
 ghostwriter_end_dive:
 	; save end-of-profile pointer for later storage in EEPROM
@@ -468,7 +481,7 @@
 
 	; 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
+	goto	ghostwriter_end_dive_common		; NO  - discard everything
 
  ifndef _DEBUG
 	; in DEBUG compile, write simulated dives to logbook
@@ -506,7 +519,8 @@
 	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)
+
+	;---- dive finished (and longer than one minute) -------------------------
 
 	; close profile recording
 	FLASH_LIT_PROFILE 0xFD					; write end-of-profile code, byte 1
@@ -515,23 +529,23 @@
 	; save end-of-profile pointer for later storage in header and EEPROM
 	MOVTT	ext_flash_address,ext_flash_log_pointer
 
-	; set to first address of profile data again to store dive length (number of recorded bytes)
-	rcall	ghostwriter_load_pointer
+	; go back again to start of profile data to store the profile length (number of recorded bytes)
+	call	ghostwriter_load_pointer
 
 	; skip internal "0xFA 0xFA #Divenumber:2 0xFA 0xFA" header, i.e. the first 6 bytes
-	ext_flash_inc_address_0x20 d'6'
+	EXT_FLASH_INC_ADDRESS_0x20 d'6'
 
-	; 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 dive length (NO ext_flash_length_counter increase, NO page delete)
+	movf	ext_flash_length_counter+0,W	; get length of profile data, low   byte
+	call	ext_flash_write_byte_0x20_nodel	; write to flash
+	movf	ext_flash_length_counter+1,W	; get length of profile data, high  byte
+	call	ext_flash_write_byte_0x20_nodel	; write to flash
+	movf	ext_flash_length_counter+2,W	; get length of profile data, upper byte
+	call	ext_flash_write_byte_0x20_nodel	; write to flash
 
 	; ... profile recording done
 
-	; read, increment, and store again total number of dives
+	; read, increment, and store updated 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
@@ -598,7 +612,7 @@
  ENDIF
 
 end_dive_gaslist_common:					; helper function for writing gas list entries
-;
+
 ;   Memory Map:
 ;   -------------------------
 ;   opt_gas_O2_ratio	res 5
@@ -609,7 +623,7 @@
 ;   opt_dil_type		res 5
 ;   opt_gas_change		res 5
 ;   opt_dil_change		res 5
-;
+
 	movlw	.5								; 5 gases to store
 	movwf	lo								; use lo as counter
 end_dive_gaslist_loop:
@@ -659,7 +673,7 @@
 	lfsr	FSR0,opt_setpoint_cbar			; base address of ppO2 values
 	lfsr	FSR1,opt_setpoint_change		; base address of change depths
 	lfsr	FSR2,header_buffer+index_sp1	; base address of setpoint data in header buffer
-	movlw	.5								; 5 setpoints (ppo2, depth) to be stored
+	movlw	.5								; 5 setpoints (ppO2, depth) to be stored
 	movwf	lo								; use lo as counter
 end_dive_sp_loop:
 	movff	POSTINC0,POSTINC2				; copy ppO2 value
@@ -763,17 +777,12 @@
 	MOVLI	0xFBFB,mpr
 	MOVII	mpr,header_buffer+index_header_stop
 
-	; compute start address of header data
+	; store header in the FLASH
 	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)
-
-	; 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
+	call	log_header_addr_by_index		; compute header start address
+	call	ext_flash_erase_4kB				; erase the FLASH 4 kB block where the header will be stored
+	FLASH_RR_WRITE header_buffer,.256		; write the header to the FLASH
 
 ghostwriter_end_dive_cleanup:
 	call	eeprom_deco_data_write			; update deco data in EEPROM
@@ -824,7 +833,7 @@
 
 
 ;-----------------------------------------------------------------------------
-; helper function for copying tissue pressures
+; Helper Function - copy Tissue Pressures
 ;
 copy_tissuepres_to_header:
 	movwf	eeprom_loop						; initialize loop counter (EEPROM var used here)
@@ -837,15 +846,23 @@
 	bra		copy_tissuepres_to_header_loop	; NO  - loop
 	return									; YES - done
 
-;-----------------------------------------------------------------------------
-; load ext_flash_address from EEPROM
-;
-ghostwriter_load_pointer:
-	EEPROM_TT_READ	eeprom_log_pointer,ext_flash_address
-	return
 
 ;-----------------------------------------------------------------------------
-; write short header with dive number into profile memory
+; Helper Function - 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
+
+
+;-----------------------------------------------------------------------------
+; start Dive Data Recording (write short Header with Dive Number)
 ;
 	global	ghostwriter_short_header
 ghostwriter_short_header:
@@ -863,7 +880,7 @@
 
 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
+	movlw	0xF0							; high byte: keep upper 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			; ...
@@ -890,26 +907,24 @@
 	FLASH_LIT_PROFILE 0xFA					; 2nd byte
 
 	; load total number of dives
-	call	eeprom_total_dives_read			; read total number of dives
+	call	eeprom_total_dives_read			; read total number of dives into mpr:2
 	incf	mpr+0,F							; increment low byte + 1
-	FLASH_II_PROFILE mpr
+	FLASH_II_PROFILE mpr					; write mpr:2 to FLASH
 
 	; 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
-	; - write_byte_ext_flash_plus_prof takes care of 4kB page switching
-	; - fixes an issue when we are at exactly 0xXXX000 here...
+	; Keep room for dive length ext_flash_length_counter:3 (stored at the end of the dive),
+	; writing 0xFF here is mandatory because 0xFF can be overwritten when closing the dive.
+	; The stored dive length counter itself is not part of the counted dive length.
 
-	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
+	setf	WREG							; write 0xFF
+	call	ext_flash_write_byte_0x20		; write to profile (no dive length increment)
+	setf	WREG							; write 0xFF
+	call	ext_flash_write_byte_0x20		; write to profile (no dive length increment)
+	setf	WREG							; write 0xFF
+	call	ext_flash_write_byte_0x20		; write to profile (no dive length increment)
 
 	; store sizes and sampling rates of recording datasets
 
@@ -958,19 +973,16 @@
  ENDIF
 	FLASH_WREG_PROFILE							; WREG -> profile in ext. flash
 
+	return										; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - load ext_flash_address from EEPROM
+;
+ghostwriter_load_pointer:
+	EEPROM_TT_READ	eeprom_log_pointer,ext_flash_address
 	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	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/hwos.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File hwos.asm                             combined next generation V3.08.8
+;   File hwos.asm                           * combined next generation V3.09.4e
 ;
 ;   Definition of the hwOS dive computer platform.
 ;
@@ -12,30 +12,32 @@
 
 ;=============================================================================
 
-#DEFINE ACCESS_RAM_VARS			; the access RAM variables are declared in this file
+#DEFINE INSIDE_HWOS_ASM
 
 #include "hwos.inc"
 #include "eeprom_rs232.inc"
 
-;----------------------------- CONFIG ----------------------------------------
-	CONFIG	RETEN   = OFF		; disabled - controlled by SRETEN bit
-	CONFIG	SOSCSEL = HIGH		; High Power SOSC circuit selected
-	CONFIG	XINST   = OFF		; code won't execute in extended mode
+;----------------------------- PIC Configuration -----------------------------
+;
+	CONFIG	RETEN   = OFF		; regulator power while in sleep mode controlled by SRETEN bit
+	CONFIG	SOSCSEL = HIGH		; high power SOSC circuit selected
+	CONFIG	XINST   = OFF		; extended instruction set disabled
 	CONFIG	FOSC    = INTIO2	; internal RC oscillator, no clock-out
-	CONFIG	PLLCFG  = OFF		;
-	CONFIG	IESO    = OFF		; disabled
-	CONFIG	PWRTEN  = OFF		; disabled, because incompatible with ICD3 (Ri-400)
-	CONFIG	BOREN   = ON		; controlled with SBOREN bit
-	CONFIG	BORV    = 2			; 2.0V
-	CONFIG	BORPWR  = MEDIUM	; BORMV set to medium power level
-	CONFIG	WDTEN   = ON		; WDT controlled by SWDTEN bit setting
-	CONFIG	WDTPS   = 128		; 1:128
-	CONFIG	RTCOSC  = SOSCREF	; RTCC uses SOSC
-	CONFIG	MCLRE   = ON		; MCLR Enabled, RG5 Disabled
-	CONFIG	CCP2MX  = PORTBE	; RE7 micro-controller mode/RB3-all other modes
+	CONFIG	PLLCFG  = OFF		; oscillator used directly
+	CONFIG	IESO    = OFF		; two-speed start-up disabled
+	CONFIG	PWRTEN  = OFF		; power-up timer disabled, because incompatible with ICD3 (Ri-400)
+	CONFIG	BOREN   = ON		; brown-out reset controlled with SBOREN bit
+	CONFIG	BORV    = 2			; brown-out reset voltage 2.0V
+	CONFIG	BORPWR  = MEDIUM	; brown-out monitoring set to medium power level
+	CONFIG	WDTEN   = ON		; watchdog timer enabled, controlled by SWDTEN bit
+	CONFIG	WDTPS   = 128		; watchdog timer post-scaler 1:128
+	CONFIG	RTCOSC  = SOSCREF	; RTCC uses SOSC as ref clock
+	CONFIG	MCLRE   = ON		; MCLR enabled, RG5 disabled
+	CONFIG	CCP2MX  = PORTBE	; ECCP2 muxed with RE7 (micro-controller mode) /RB3 (other modes)
 
 
 ;---------------------------- Bank0 ACCESS RAM -------------------------------
+;
 ac_ram		equ			0x000
 ac_ram		udata_acs	ac_ram				; access RAM data
 
@@ -94,12 +96,22 @@
 hud_status_byte					res 1		; HUD status byte, see definition of flags   | Attention: keep relative position
 hud_battery_mv					res 2		; hud/ppo2 monitor battery voltage in mV     | between these two variables!
 
+;---- Battery Management
+battery_capacity_internal		res 2		; for internal battery gauging
+battery_capacity				res 2		; for battery gauge IC
+battery_offset					res 2		; for battery gauge IC
+battery_type					res 1		; =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
+battery_accumulated_charge		res 2		; raw values in battery gauge IC
+battery_temperature				res 2		; battery temperature in 0.1 Kelvin
+gauge_status_byte				res 1		; gauge IC status byte
 
-; 28 byte user data
+
+
+; 40 byte user data
 ; 32 byte tmp  data placed by C compiler
 ; 20 byte variables placed by math library
 ; ==
-; 80 byte used, 16 byte free (96 byte total available)
+; 92 byte used, 4 byte free (96 byte total available)
 
 
 	global	HW_descriptor
@@ -129,24 +141,33 @@
 	global	simulatormode_depth
 	global	hud_status_byte
 	global	hud_battery_mv
+	global	battery_capacity_internal
+	global	battery_capacity
+	global	battery_offset
+	global	battery_type
+	global	battery_accumulated_charge
+	global	battery_temperature
+	global	gauge_status_byte
+
+
+;=============================================================================
+hwos1	CODE
+;=============================================================================
 
 ;-----------------------------------------------------------------------------
-
-hwos	CODE
-
-;=============================================================================
-
+; Master Initialization of Hardware Resources
+;
 	global	init_ostc
 init_ostc:
 
 ; Oscillator
 	banksel	common				; select bank common
-	movlw	b'01110010'
-	movwf	OSCCON				; 16 MHz INTOSC
-	movlw	b'00001000'
-	movwf	OSCCON2				; secondary oscillator running
-	movlw	b'00000000'
-	movwf	OSCTUNE				; 4x PLL disable (Bit 6) - only works with 8 or 16MHz (=32 or 64MHz)
+	movlw	b'01110010'			; select 16 MHz INTOSC
+	movwf	OSCCON				; ...
+	movlw	b'00001000'			; secondary oscillator running
+	movwf	OSCCON2				; ...
+	movlw	b'00000000'			; 4x PLL disable (Bit 6) - only works with 8 or 16MHz (=32 or 64MHz)
+	movwf	OSCTUNE				; ...
 
 	movlw	coding_speed_normal	; coding for normal CPU speed
 	movwf	cpu_speed_request	; store CPU shall run with normal speed
@@ -156,72 +177,74 @@
 	bcf		RCON,IPEN			; priority interrupts off
 
 	banksel	WDTCON
-	movlw	b'10000000'
-	movwf	WDTCON				; setup watchdog
+	movlw	b'10000000'			; setup watchdog
+	movwf	WDTCON				; ...
 
 
 ; I/O Ports
-	banksel	0xF16				; addresses, F16h through F5Fh, are also used by SFRs, but are not part of the access RAM
+	banksel	0xF16				; addresses F16h ... F5Fh are not part of the access RAM
+
 	clrf	REFOCON				; no reference oscillator active on REFO pin
 	clrf	ODCON1				; disable open drain capability
 	clrf	ODCON2				; disable open drain capability
 	clrf	ODCON3				; disable open drain capability
-	clrf	CM1CON				; disable
-	clrf	CM2CON				; disable
-	clrf	CM3CON				; disable
+	clrf	CM1CON				; disable comparator 1
+	clrf	CM2CON				; disable comparator 2
+	clrf	CM3CON				; disable comparator 3
 
-	movlw	b'11000000'			; ANSEL, AN7 and AN6 -> Analog inputs, PORTA is digital
-	movwf	ANCON0
-	movlw	b'00000111'			; ANSEL, AN8, AN9, AN10 -> Analog input
-	movwf	ANCON1
-	movlw	b'00000010'			; ANSEL, AN17 -> Analog input
-	movwf	ANCON2
-	banksel	common
+	movlw	b'11000000'			; ANSEL0: AN7, AN6       -> analog inputs, PORTA is digital
+	movwf	ANCON0				; ...
+	movlw	b'00000111'			; ANSEL1: AN8, AN9, AN10 -> analog input
+	movwf	ANCON1				; ...
+	movlw	b'00000010'			; ANSEL2: AN17           -> analog input
+	movwf	ANCON2				; ...
+
+	banksel	common				; back to bank common
 
 ;	movlw	b'00000000'			; 1= input -> Data TFT_high
-	clrf	TRISA
+	clrf	TRISA				; ...
 ;	movlw	b'00000000'			; init port
-	clrf	PORTA
+	clrf	PORTA				; ...
 
 	movlw	b'00000011'			; 1= input, (RB0, RB1) -> switches, RB2 -> Power_MCP, RB3 -> s8_npower, RB4 -> LED_green/rx_nreset, RB5 -> /TFT_POWER
-	movwf	TRISB
+	movwf	TRISB				; ...
 	movlw	b'00111000'			; init port, rx_nreset=1 -> hard reset RX
-	movwf	PORTB
+	movwf	PORTB				; ...
 
 	movlw	b'10011010'			; 1= input, (RC0, RC1) -> SOSC, RC2 -> TFT_LED_PWM, (RC3,RC4) -> I²C, RC5 -> MOSI_MS5541, (RC6, RC7) -> UART1
-	movwf	TRISC
+	movwf	TRISC				; ...
 ;	movlw	b'00000000'			; init port
-	clrf	PORTC
+	clrf	PORTC				; ...
 
 	movlw	b'00100000'			; 1= input, RD0 -> TFT_NCS, RD1 -> TFT_RS, RD2 -> TFT_NWR, RD3 -> TFT_RD, RD4 -> MOSI_Flash, RD5 -> MISO_Flash, RD6 -> CLK_Flash, RD7 -> TFT_NRESET
-	movwf	TRISD
+	movwf	TRISD				; ...
 ;	movlw	b'00000000'			; init port
-	clrf	PORTD
+	clrf	PORTD				; ...
 
 	movlw	b'00100000'			; 1= input, RE0 -> not_Power_BLE, RE1 -> Power_IR, RE2 -> CS_MCP, RE3 -> LED_blue, RE4 -> power_sw1, RE5 -> leave as input
-	movwf	TRISE
+	movwf	TRISE				; ...
 	movlw	b'00010001'			; init port
-	movwf	PORTE
+	movwf	PORTE				; ...
 
 	movlw	b'01111110'			; 1= input, (RF1, RF2, RF3, RF4, RF5) -> Analog
-	movwf	TRISF
+	movwf	TRISF				; ...
 ;	movlw	b'00000000'			; init port
-	clrf	PORTF
+	clrf	PORTF				; ...
 
 	movlw	b'00001110'			; 1= input, <7:6> not implemented, RG0 -> TX3_PIEZO_CFG, , RG1 -> TX2, RG2 -> RX2, RG3 -> AN17_RSSI, RG4 -> SOSC_OUT, RG5 -> /RESET
-	movwf	TRISG
+	movwf	TRISG				; ...
 	movlw	b'00000001'			; init port
-	movwf	PORTG
+	movwf	PORTG				; ...
 
 ;	movlw	b'00000000'			; 1= input -> Data TFT_low
-	clrf	TRISH
+	clrf	TRISH				; ...
 ;	movlw	b'00000000'			; init port
-	clrf	PORTH
+	clrf	PORTH				; ...
 
 	movlw	b'10011011'			; 1= input, RJ4 -> vusb_in, RJ5 -> power_sw2, RJ6 -> CLK_MS5541, RJ7 -> MISO_MS5541
-	movwf	TRISJ
+	movwf	TRISJ				; ...
 	movlw	b'00100000'			; init port
-	movwf	PORTJ
+	movwf	PORTJ				; ...
 
 
 ; disable Charger by default
@@ -229,51 +252,74 @@
 	bcf		charge_enable		; activate charging-inhibit signal
 
 
-; Timer 0
-	movlw	b'00000001'			; timer0 with 1:4 prescaler
-	movwf	T0CON
+; Timer 7 for 62.5 ms Interrupt (Sensor States)
+	banksel	0xF16				; addresses F16h...F5Fh are not part of the access RAM
+	clrf	T7GCON				; clear timer 7 gate control register
+	movlw	b'10001101'			; bit 7-6: 10 = clock source SOSC/SCLKI (with bit   3 = 1)
+								; bit 5-4: 00 = 1:1 prescaler
+								; bit   3:  1 = clock source SOSC/SCLKI (with bit 7-6 = 10)
+								; bit   2:  1 = DO NOT synchronize external clock input (else OSTC won't wake up from sleep!)
+								; bit   1:  0 = 2x 8 bit operation
+								; bit   0:  1 = timer enabled
+								; 32768 Hz clock source, 1:1 prescaler -> timer counts at 30.51757813 µs/bit
+	movwf	T7CON				; ...
+	movlw	.248				; load timer 7, high byte (8x256 ticks -> 62.5 ms)
+	movwf	TMR7H				; ...
+	clrf	TMR7L				; load timer 7, low  byte
 
 
-; Timer 1 - Button hold-down timer
-	movlw	b'10001100'			; 32768 Hz clock source, 1:1 prescaler -> ; 30.51757813 µs/bit in TMR1L:TMR1H
-	movwf	T1CON
+; Timer 0 - not used
+	movlw	b'00000001'			; timer0 stopped (1:4 prescaler)
+	movwf	T0CON				; ...
+
+
+; Timer 1 - Button hold-down Timer
+;	movlw	b'10001100'			; old setting
+	movlw	b'10001010'			; bit 7-6: 10 = clock source SOSC/SCLKI (with bit   3 = 1)
+								; bit 5-4: 00 = 1:1 prescaler
+								; bit   3:  1 = clock source SOSC/SCLKI (with bit 7-6 = 10)
+								; bit   2:  0 = synchronize external clock input
+								; bit   1:  1 = 16 bit operation
+								; bit   0:  0 = timer stopped
+								; 32768 Hz clock source, 1:1 prescaler -> timer counts at 30.51757813 µs/bit
+	movwf	T1CON				; ...
 
 
 ; RTCC
 	banksel	0xF16				; addresses, F16h through F5Fh, are also used by SFRs, but are not part of the access RAM
-	movlw	0x55
-	movwf	EECON2
-	movlw	0xAA
-	movwf	EECON2
-	bsf 	RTCCFG,RTCWREN		; unlock sequence for RTCWREN
-	bsf		RTCCFG,RTCPTR1
-	bsf		RTCCFG,RTCPTR0
+	movlw	0x55				; unlock sequence for RTCWREN
+	movwf	EECON2				; ...
+	movlw	0xAA				; ...
+	movwf	EECON2				; ...
+	bsf 	RTCCFG,RTCWREN		; unlock access to RTC
+	bsf		RTCCFG,RTCPTR1		; set pointer register to b'11'
+	bsf		RTCCFG,RTCPTR0		; ..
 	bsf		RTCCFG,RTCEN		; module enable
 	bsf		RTCCFG,RTCOE		; output enable
 	movlw	b'00000100'			; 32768 Hz SOCS on RTCC pin (PORTG,4) Bit7-5: pull-ups for Port D, E and J
-	movwf	PADCFG1
-	movlw	b'11000000'
-	movwf	ALRMCFG				; 1/2 second alarm
-	movlw	d'1'
-	movwf	ALRMRPT				; alarm repeat counter
-	movlw	0x55
-	movwf	EECON2
-	movlw	0xAA
-	movwf	EECON2
-	bcf		RTCCFG,RTCWREN		; lock sequence for RTCWREN
-	banksel	common
+	movwf	PADCFG1				; ...
+	movlw	b'11000000'			; 1/2 second alarm
+	movwf	ALRMCFG				; ...
+	movlw	d'1'				; select alarm repeat counter to 1
+	movwf	ALRMRPT				; ...
+	movlw	0x55				; unlock sequence for RTCWREN
+	movwf	EECON2				; ...
+	movlw	0xAA				; ...
+	movwf	EECON2				; ...
+	bcf		RTCCFG,RTCWREN		; lock access to RTC
+	banksel	common				; back to bank common
 
 
 ; A/D Converter
 	movlw	b'00011000'			; power off ADC, select AN6
-	movwf	ADCON0
+	movwf	ADCON0				; ...
 	movlw	b'00100000'			; 2.048V Vref+
-	movwf	ADCON1
+	movwf	ADCON1				; ...
 	movlw	b'10111010'			; right aligned, 20 x T_AD acquisition time, FOSC/32 -> max. 40 MHz device clock speed
-	movwf	ADCON2
+	movwf	ADCON2				; ...
 
 
-; serial Port 1 (TRISC6/7)
+; Serial Port 1 (TRISC6/7)
 	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)
@@ -287,131 +333,148 @@
 	bcf		PORTC,6				; tie TX output hard to GND
 
 
-; serial Port 2 (TRISG2) for IR/S8 digital interface
+; Serial Port 2 (TRISG2) for IR/S8 digital Interface
 ;
 ; - will be initialized by enable_ir_s8 (eeprom_rs232.asm) in case IR/S8 shall be available
 
 
 ; Timer 3 for IR-RX Timeout
  IFDEF _external_sensor
-	clrf	T3GCON				; reset Timer3 gate control register
-	movlw	b'10001101'			; not synced, 1:1 prescaler -> 2 seconds till overrun @ 32768 Hz,
-								;                          incrementing by 1 bit each 30.51757813 µs
-	movwf	T3CON
+	clrf	T3GCON				; clear Timer3 gate control register
+;	movlw	b'10001101'			; old value
+	movlw	b'10001011'			; bit 7-6: 10 = clock source SOSC/SCLKI (with bit   3 = 1)
+								; bit 5-4: 00 = 1:1 prescaler
+								; bit   3:  1 = clock source SOSC/SCLKI (with bit 7-6 = 10)
+								; bit   2:  0 = synchronize external clock input
+								; bit   1:  1 = 16 bit operation
+								; bit   0:  1 = timer enabled
+								; 32768 Hz clock source, 1:1 prescaler -> timer counts at 30.51757813 µs/bit
+	movwf	T3CON				; ...
  ENDIF
 
 
 ; SPI Module(s)
 ; SPI2: External Flash
-	movlw	b'00110000'
-	movwf	SSP2CON1
-;	movlw	b'00000000'
-	clrf	SSP2STAT
-								; -> 0.25 MHz Bit clock @  1 MHz mode (Eco)
-								; ->    4 MHz Bit clock @ 16 MHz mode (Normal)
-								; ->   16 MHz Bit clock @ 64 MHz mode (Fastest)
+	movlw	b'00110000'			; set up SPI module
+	movwf	SSP2CON1			; ...
+	clrf	SSP2STAT			; ...
+								; resulting bit clocks:  0.25 MHz @  1 MHz CPU clock (Eco)
+								;                        4.00 MHz @ 16 MHz CPU clock (Normal)
+								;                       16.00 MHz @ 64 MHz CPU clock (Fastest)
 
 
 ; MSSP1 Module: I2C Master
-	movlw	b'00101000'			; I2C master mode
-	movwf	SSP1CON1
-;	movlw	b'00000000'
-	clrf	SSP1CON2
-	movlw	0x9C
-	movwf	SSP1ADD				; 100kHz @ 64MHz Fosc
+	movlw	b'00101000'			; set up I2C to master mode
+	movwf	SSP1CON1			; ...
+	clrf	SSP1CON2			; ...
+	movlw	0x9C				; select speed 100kHz @ 64MHz Fosc
+	movwf	SSP1ADD				; ...
 
 
 ; PWM Module(s)
 ; PWM 1 for LED dimming
-	movlw	b'00001100'
-	movwf	CCP1CON
-	movlw	b'00000001'
-	movwf	PSTR1CON			; pulse steering disabled
-	movlw	d'254'
-	movwf	PR2					; period
+	movlw	b'00001100'			; set up PWM module
+	movwf	CCP1CON				; ...
+	movlw	b'00000001'			; pulse steering disabled
+	movwf	PSTR1CON			; ...
+	movlw	d'254'				; select period
+	movwf	PR2					; ...
 	; 255 is max brightness (300 mW)
-	clrf	CCPR1L				; duty cycle
-	clrf	CCPR1H				; duty cycle
-	movlw	T2CON_NORMAL
-	movwf	T2CON
-
-
-; Timer 5 for ISR-independent wait routines
-	clrf	T5GCON				; reset Timer5 gate control register
-	movlw	b'10001111'			; not synced, 16 bit mode, 1:1 prescaler -> 2 seconds till overrun @ 32768 Hz,
-	movwf	T5CON				;                                       incrementing by 1 bit each 30.51757813 µs
+	clrf	CCPR1L				; duty cycle, low  byte
+	clrf	CCPR1H				; duty cycle, high byte
+	movlw	T2CON_NORMAL		; set timer for normal dimming
+	movwf	T2CON				; ...
 
 
-	banksel	0xF16				; addresses F16h through F5Fh are also used by SFRs, but are not part of the access RAM
-
-; Timer 7 for 62.5 ms Interrupt (sensor states)
-	clrf	T7GCON				; reset Timer7 gate control register
-	movlw	b'10001101'			; 1:1 prescaler -> 2 seconds @ 32768 Hz, not synced
-	movwf	T7CON
-	clrf	TMR7L
-	movlw	.248
-	movwf	TMR7H				; -> rollover after 2048 cycles -> 62.5 ms
+; Timer 5 for ISR-independent Wait/Timeout
+	clrf	T5GCON				; clear Timer5 gate control register
+;	movlw	b'10001111'			; old value
+	movlw	b'10001011'			; bit 7-6: 10 = clock source SOSC/SCLKI (with bit   3 = 1)
+								; bit 5-4: 00 = 1:1 prescaler
+								; bit   3:  1 = clock source SOSC/SCLKI (with bit 7-6 = 10)
+								; bit   2:  0 = synchronize external clock input
+								; bit   1:  1 = 16 bit operation
+								; bit   0:  1 = timer enabled
+								; 32768 Hz clock source, 1:1 prescaler -> timer counts at 30.51757813 µs/bit
+	movwf	T5CON				; ...
 
 
-; turn off unused timers
-	movlw	b'11000000'
-	movwf	PMD0
+; turn off unused Timers
+	;banksel 0xF16				; addresses F16h...F5Fh are not part of the access RAM
+	movlw	b'11000000'			; disable ECCP3 and ECCP2
+	movwf	PMD0				; ...
  IFDEF _external_sensor
-	movlw	b'11010001'
+	movlw	b'11010001'			; disable PSP, CTMU, Timer 4 and EMB
  ELSE
-	movlw	b'11011001'			; includes turning off timer 3
+	movlw	b'11011001'			; disable PSP, CTMU, Timer 4, Timer 3 and EMB
  ENDIF
-	movwf	PMD1
-	movlw	b'11010111'
-	movwf	PMD2
-	movlw	b'11111111'
-	movwf	PMD3
+	movwf	PMD1				; ...
+	movlw	b'11010111'			; disable timer 10, timer 8, timer 6 and comparators 1-3
+	movwf	PMD2				; ...
+	movlw	b'11111111'			; disable CCP 4-10 and timer 12
+	movwf	PMD3				; ...
 
 
 ; turn off unused CTMU
-	clrf	CTMUCONH
-	clrf	CTMUCONL
-	clrf	CTMUICON
+	;banksel 0xF16				; addresses F16h...F5Fh are not part of the access RAM
+	clrf	CTMUCONH			; disable CTMU
+	clrf	CTMUCONL			; ...
+	clrf	CTMUICON			; ...
+
 
 	banksel	common
 
 
 ; Interrupts
-	movlw	b'11010000'
-	movwf	INTCON
-	movlw	b'00001000'			; Bit7=1: pull-up for PORTB disabled
-	movwf	INTCON2
-	movlw	b'00000000'
-	movwf	INTCON3
-	movlw	b'00000001'			; Bit0: TMR1
-	movwf	PIE1
-	movlw	b'00000010'			; Bit1: TMR3
-	movwf	PIE2
-	movlw	b'00000000'			; Bit1: TMR5
-	movwf	PIE5
-	movlw	b'00000001'			; Bit0: RTCC, Bit5: UART2 (Default OFF)
-	movwf	PIE3
-	movlw	b'00001000'			; Bit3: TMR7
-	movwf	PIE5
+	bcf		PIR5,TMR7IF			; if applicable clear timer 7 IRQ flag
 
-	bcf		active_reset_ostc_rx	; release RESET from RX circuitry
+	movlw	b'11010000'			; enable global IRQ, peripheral IRQ and external IRQ 0
+	movwf	INTCON				; ...
+	movlw	b'00001000'			; external IRQ 0 on falling edge, pull-up of PORTB by TRIS register
+	movwf	INTCON2				; ...
+	movlw	b'00000000'			; disable external IRQs 1,2,3
+	movwf	INTCON3				; ...
+	movlw	b'00000001'			; enable timer 1 IRQ
+	movwf	PIE1				; ...
+	movlw	b'00000010'			; enable timer 3 IRQ
+	movwf	PIE2				; ...
+	movlw	b'00000000'			; enable timer 5 IRQ
+	movwf	PIE5				; ...
+	movlw	b'00000001'			; enable RTCC IRQ
+	movwf	PIE3				; ...
+	movlw	b'00001000'			; enable timer 7 IRQ
+	movwf	PIE5				; ...
+
+; Release RESET from RX Circuitry
+	bcf		active_reset_ostc_rx
+
+; Power-up the Switches
 	;bra	power_up_switches
 
 
+;-----------------------------------------------------------------------------
+; Power-up the Switches
+;
 	global	power_up_switches
 power_up_switches:
 	bsf		power_sw1			; switch on power supply for switch 1
 	btfss	power_sw1			; power established?
 	bra		$-4					; NO - wait
+
 	bsf		power_sw2			; switch on power supply for switch 2
 	btfss	power_sw2			; power established?
 	bra		$-4					; NO - wait
 
-	return
+	return						; done
+
 
 ;=============================================================================
-; CPU speed change request functions
+hwos2	CODE
+;=============================================================================
 
+;-----------------------------------------------------------------------------
+; CPU Speed Change Requests
+;
 	global	request_speed_eco
 request_speed_eco:
 	movlw	coding_speed_eco		; load coding for eco speed
@@ -430,14 +493,19 @@
 	movwf	cpu_speed_request		; request ISR to change the CPU speed
 	return							; done
 
+
 ;=============================================================================
-; Backup the first 128 bytes from program memory to EEPROM
+hwos3	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Backup the first 128 bytes from program FLASH to EEPROM
 ;
 	global	backup_flash_page
 backup_flash_page:
 	banksel	common
 
-	; set start address in internal program memory
+	; set start address in internal program FLASH
 	movlw	0x00					; set 0x000000
 	movwf	TBLPTRL					; ...
 	movwf	TBLPTRH					; ...
@@ -450,22 +518,27 @@
 	movlw	.128					; copy 1 block = 128 byte
 	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
+	tblrd+*							; read one byte from program FLASH (with pre-increment)
+	movff	TABLAT,EEDATA			; transfer byte from program FLASH read to EEPROM write
 	call	write_eeprom			; execute   EEPROM write
 	incf	EEADR,F					; increment EEPROM address
 	decfsz	eeprom_loop,F			; all 128 byte done?
 	bra		backup_flash_loop		; NO  - loop
 	return							; YES - done
 
+
 ;=============================================================================
-; Restore the first 128 bytes from EEPROM to program memory
+hwos4	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Restore the first 128 bytes from EEPROM to program FLASH
 ;
 	global	restore_flash
 restore_flash:
 	banksel	common
 
-	;set start address in internal program memory
+	;set start address in internal program FLASH
 	movlw	0x00					; set 0x000000
 	movwf	TBLPTRL					; ...
 	movwf	TBLPTRH					; ...
@@ -483,8 +556,8 @@
 restore_flash_loop:
 	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)
+	movff	EEDATA,TABLAT			; transfer byte from EEPROM read to program FLASH write
+	tblwt+*							; execute program FLASH write (with pre-increment)
 	decfsz	eeprom_loop,F			; all 128 bytes done?
 	bra		restore_flash_loop		; NO  - loop
 	movlw	b'10000100'				; YES - setup   block write
@@ -502,8 +575,13 @@
 	nop								; ...
 	return							; done
 
+
 ;=============================================================================
-; Memory clear and move functions, to be used through macros
+hwos5	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Memory clear and move Functions, to be used via Macros
 ;
 	global	memory_clear
 memory_clear:
@@ -519,4 +597,27 @@
 	bra		memory_move				; NO  - loop
 	return							; YES - done
 
-	END
\ No newline at end of file
+
+;=============================================================================
+hwos6	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Read CPU Silicon Version
+;
+	global	get_cpu_version
+get_cpu_version:
+	movlw	0xFE					; select address 0x3FFFFE
+	movwf	TBLPTRL					; ...
+	movlw	0xFF					; ...
+	movwf	TBLPTRH					; ...
+	movlw	0x3F					; ...
+	movwf	TBLPTRU					; ...
+	TBLRD*+							; read DEVID1 byte
+	movlw	b'00011111'				; load mask for silicon version
+	andwf	TABLAT,W				; apply mask and store result in WREG 
+	return							; done
+
+;-----------------------------------------------------------------------------
+
+	END
--- a/src/hwos.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/hwos.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File hwos.inc                             combined next generation V3.08.8
+;   File hwos.inc                           * combined next generation V3.09.5
 ;
 ;   OSTC Platform Definitions
 ;
@@ -11,17 +11,21 @@
 ;=============================================================================
 
 
-; Hardware Configuration
+; ---- Hardware Configuration
 	LIST P=18F87K22							; compiler  settings, if changed change also: Configure -> SelectDevice in MPLAB
 #include "p18f87k22.inc"					; processor definitions
 #include "ports.inc"						; port map  definitions
 
 
-; Software Configuration
+; ---- Software Configuration
 #include "configuration.inc"				; OSTC hwOS configuration
 
 
-; Language Codes
+;-----------------------------------------------------------------------------
+; Settings, Limits, Thresholds, Encodings, etc.
+;-----------------------------------------------------------------------------
+
+; ---- Language Codes
 #DEFINE none					0			; no language selected
 #DEFINE en						1			; select English
 #DEFINE de						2			; select German
@@ -29,14 +33,18 @@
 #DEFINE it						4			; select Italian
 
 
-; Magic Cookie Definition
+; ---- Magic Cookie Definition
 #DEFINE comm_service_key		0xABCDEF	; simsalabim to establish comm service mode
 
 
-; Logo Address Vectors
+; ---- Scrolling Menu Support
+;#DEFINE scrolling_menu_enabled				; disabled
+
+
+; ---- Logo Address Vectors
 #DEFINE hw_logo_block			0x01E000	; color image data for heinrichsweikamp logo
-#DEFINE usb_ble_logo_1			0x01EEDE	; color image data for USB or BLE logo
-#DEFINE usb_ble_logo_2			0x01EA04	; color image data for USB or BLE logo, "+" bootloader
+#DEFINE comm_logo_1				0x01EEDE	; color image data for USB or BT logo
+#DEFINE comm_logo_2				0x01EA04	; color image data for BT logo, "+" bootloader
 
 
 ;-----------------------------EEPROM DATA ------------------------------------
@@ -46,13 +54,14 @@
 ;-----------------------------------------------------------------------------
 
 
-#DEFINE CCP1CON_VALUE					b'00001100'	; PWM1 for LED dimming
+; ---- PWM1 for LED dimming
+#DEFINE CCP1CON_VALUE					b'00001100'
 #DEFINE T2CON_ECO						b'01111110'
 #DEFINE T2CON_NORMAL					b'01111110'
 #DEFINE T2CON_FASTEST					b'01111110'
 
 
-; CPU speeds
+; ---- CPU speeds
 #DEFINE coding_speed_eco				.1			;  1 MHz = eco     speed
 #DEFINE coding_speed_normal				.2			; 16 MHz = normal  speed
 #DEFINE coding_speed_fastest			.4			; 64 MHz = fastest speed (32 MHz on OSTC Sport BLE)
@@ -62,7 +71,7 @@
 #DEFINE speed_is_fastest		cpu_speed_state,2	; =1: CPU is running at fastest speed
 
 
-; Divemode Custom View Indexes - Attention: these numbers need to be in line with the jump tables in customview.asm!
+; ---- 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
@@ -82,32 +91,13 @@
 #DEFINE index_cv_dm_max					.13			; highest index used in normal custom view rotation
 
 
-; Timing for button hold-down flags
+; ---- Timing for button hold-down flags
 #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.50 s
 
 
-; Color Definitions: 8 bit RGB b'RRRGGGBB'
-#DEFINE color_red						b'11100000'	; (7,0,0)
-#DEFINE color_dark_red					b'10000101'	; (4,1,1)
-#DEFINE color_violet					b'11101011'	; (7,2,3)
-#DEFINE color_blue						b'11000111'	; (6,1,3)
-#DEFINE color_green						b'00011100'	; (0,7,0)
-#DEFINE color_greenish					b'00111110'	; (1,7,2)
-#DEFINE color_dark_green				b'00111001'	; (1,6,1)
-#DEFINE color_yellow					b'11111101'	; (7,7,1)
-#DEFINE color_white						b'11111111'	; (7,7,3)
-#DEFINE color_black						b'00000000'	; (0,0,0)
-#DEFINE color_deepblue					b'00000010'	; (0,0,2)
-#DEFINE color_grey						b'11011111'	; (6,7,3)
-#DEFINE color_cyan						b'11011111'	; (6,7,3)
-#DEFINE color_lightblue					b'11011011'	; (6,7,3)
-#DEFINE color_orange					b'11111000'	; (7,6,0)
-#DEFINE color_pink						b'11111010'	; (7,6,2)
-
-
-; Font Sizes
+; ---- Font Sizes
 #DEFINE FT_TINY							.0			; aa_font16_block, full character set
 #DEFINE FT_SMALL						.1			; aa_font28_block, full character set
 #DEFINE FT_STANDARD						.2			; aa_font34_block, full character set
@@ -116,18 +106,19 @@
 #DEFINE FT_HUGE							.5			; aa_font92_block, only digits, / and .
 
 
-; External O2 cell input Parameters
+; ---- External O2 Sensors
 #DEFINE min_mv							.70			; =   7 mV
 #DEFINE max_mv							.2500		; = 250 mV
-#DEFINE ignore_mv						.3500		; = 350 mV (to suppress ghost readings for long, open cables)
+#DEFINE ignore_mv_above					.3500		; = 350 mV (to suppress ghost readings on long open cables)
+#DEFINE ignore_mv_below					.19			; = 1.9 mv (to suppress noise readings on      open cabled)
 
 
-; Profile Recording Parameters
-#DEFINE logbook_profile_version			0x24		; logbook recording format
+; ---- Profile Recording Parameters
+#DEFINE logbook_profile_version			0x40+0x24	; logbook recording format: internal (2 bit) + external (6 bit)
 #DEFINE samplingrate_apnoe				.1			; [seconds]
 
 
-; Profile Recording Rates - Attention: all Divisors must be < 16 !
+; ---- Profile Recording Rates - Attention: all Divisors must be < 16 !
 #DEFINE div_temperature					.6			; x sampling rate [s]
 #DEFINE div_deco						.6			; x sampling rate [s]
 #DEFINE div_gf							.12			; x sampling rate [s]
@@ -137,7 +128,7 @@
 #DEFINE div_tank						.12			; x sampling rate [s]
 
 
-; Profile Recording Data - Attention: Information Lengths must be < 16 !
+; ---- Profile Recording Data - Attention: Information Lengths must be < 16 !
 #DEFINE infolength_temperature			.2			; [byte]
 #DEFINE infolength_deco					.2			; [byte]
 #DEFINE infolength_gf					.1			; [byte]
@@ -147,12 +138,11 @@
 #DEFINE infolength_tank					.2			; [byte]
 
 
-; RX Functions
+; ---- RX Functions
 #DEFINE rx_packet_overdue_timeout		.120		; [seconds] timeout for pressure measurements becomming declared as outdated (max. 255)
 #DEFINE max_pres_diff_min				.5			; [bar] minimum selectable pressure difference for ind.double mode
 #DEFINE max_pres_diff_max				.50			; [bar] maximum selectable pressure difference for ind.double mode
 
-
  IFDEF _ccr_pscr
 #DEFINE tr_pres_options					.15			; number of options for pressure measurement source / with diluents
  ELSE
@@ -160,7 +150,7 @@
  ENDIF
 
 
-; Cave Mode 
+; ---- Cave Mode 
  IFDEF _cave_mode
 #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
@@ -168,46 +158,48 @@
  ENDIF
 
 
-; Gas Needs Settings
+; ---- Gas Needs Settings
 #DEFINE min_tank_size					.1			; [liter]
 #DEFINE max_tank_size					.40			; [liter]
 #DEFINE min_fill_press					.5			; [0 bar] value is in multiples of 10 bar
 #DEFINE max_fill_press					.29			; [0 bar] value is in multiples of 10 bar, no 300 bar due to too far beyond ideal gas laws
 
 
-; Timeouts for Menus
+; ---- Timeouts for Menus / Surface Mode
 #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
+
 
+; ---- Timeouts for Menus / Dive Mode
 #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
+; ---- RS232 Timeout
+#DEFINE rx_timeout						.400		; [ms] timeout for RS232 RX, needs to be multiple of 50 ms
 
 
-; Dive-End Timeouts
+; ---- End-of-Dive 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
+; ---- other Timeouts
 #DEFINE deep_sleep_10mins				.144		; [x 10mins] (24h in this example)
 
 
-; Surface Mode Thresholds and Limits
+; ---- Surface Mode Thresholds and Limits
 #DEFINE high_altitude_threshold			.880		; [mbar] ambient pressure at which to switch into high altitude mode
 #DEFINE max_surfpressure				.1030		; [mbar] maximum value for internal surface pressure
+#DEFINE pressure_noise_threshold		.10			; [mbar] deltaP threshold for start of fast display updating
+#DEFINE pressure_noise_lag_time			.6			; [1/4 secs] lag time of display updating after deltaP < threshold again
 
 
-; Dive Mode Thresholds and Limits
+
+; ---- Dive Mode Thresholds and Limits
 #DEFINE wake_up_from_sleep				.1160		; [mbar] absolute pressure at which to switch from sleep mode to surface / dive mode
 #DEFINE dive_threshold_norm_alt_start	 .125		; [mbar] relative pressure for normal altitude start-of-dive (equals depth in cm)
 #DEFINE dive_threshold_norm_alt_end		  .75		; [mbar] relative pressure for normal altitude   end-of-dive (equals depth in cm)
@@ -217,17 +209,17 @@
 #DEFINE deco_region_distance			   .2		; [m]    distance below first stop for the deco region to begin
 
 
-; Dive Mode Margins
+; ---- Dive Mode Margins
 #DEFINE ppO2_margin_on_max				.300		; [0.1 mbar] extra margin on ppO2 max values to compensate for surface pressures > 1000 hPa
 #DEFINE sensor_voting_logic_threshold	.10			; threshold in 0.01 bar
 
 
-; Gas and Dil types
+; ---- Gas and Dil types
 #DEFINE num_gas_types					.4			; Disabled, First, Normal, Deco
 #DEFINE num_dil_types					.3			; Disabled, First, Normal
 
 
-; ppO2 Limits
+; ---- 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
 #DEFINE ppo2_warning_low_highest		.21			; [cbar] maximum value for minimum ppO2 on OC
@@ -250,17 +242,19 @@
 #DEFINE ppo2_warning_deco_highest		.160		; [cbar] maximum value for maximum ppO2 in deco phase
  ENDIF
 
-; Salinity Limits
+
+; ---- 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
+
+; ---- Color-Code Parameters for the Dive Mode
 #DEFINE color_code_velocity_warn_high	.11			; [m/min]
 #DEFINE color_code_velocity_attn_high	.10			; [m/min]
 #DEFINE velocity_display_threshold		.3			; [m/min]
 
 
-; Simulator Parameters
+; ---- Simulator Parameters
 #DEFINE simulator_startdepth			.200		; [mbar] initial depth (relative pressure) when entering simulator mode
 #DEFINE simulator_descent_threshold		.50			; [mbar] remaining distance to target pressure when to slow down descent
 #DEFINE simulator_ascent_threshold		.50			; [mbar] remaining distance to target pressure when to slow down ascent
@@ -268,7 +262,7 @@
 #DEFINE simulator_ascent_rate			.2			; [mbar/0.125 sec] normal ascent  speed, 2 equals  9 m/min
 
 
-; Battery Thresholds
+; ---- Battery Thresholds
 #DEFINE max_battery_charge_temp			.3231		; [0.1 Kelvin] max allowed battery temperature during charging (equals 50°C)
 #DEFINE lithium_36v_empty				.2400		; [mV] Saft 3.6 V LS14500 AA - threshold for battery percent display
 #DEFINE lithium_36v_low					.2000		; [mV] Saft 3.6 V LS14500 AA - lowest  possible voltage, value must be higher than value of aa_15v_high!
@@ -279,21 +273,21 @@
 #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
+; ---- 3.6 Volt Battery Sensing Data Points at 70 mA Load
 #DEFINE lithium_36v_75					.3000		; [mV]
 #DEFINE lithium_36v_50					.2900		; [mV]
 #DEFINE lithium_36v_25					.2600		; [mV]
 #DEFINE lithium_36v_10					.2500		; [mV]
 
 
-; Capacity for 2.4 Ah Saft LS14500 and 0.8 Ah Panasonic UR14500P
+; ----  Capacity for 2.4 Ah Saft LS14500 and 0.8 Ah Panasonic UR14500P
 ; battery_gauge: 6 is nAs
 ; devide through 65536
 ;    a) devide through 364 -> result is in percent of a 2.4 Ah battery
 ; or b) devide through 121 -> result is in percent of a 0.8 Ah battery
 
 
-; internal Battery Gauging
+; ---- internal Battery Gauging
 #DEFINE capacity_saft_internal			.364
 #DEFINE capacity_panasonic_internal		.121
 
@@ -312,7 +306,7 @@
 #DEFINE offset_ur16650					.38477		; 65536-(2.3Ah/0.085mAh)
 
 
-; Power Consumption Values
+; ---- Power Consumption Values
 #DEFINE current_sleepmode				.31
 #DEFINE current_backlight_multi			.115		; * CCPR1L + current_backlight_offset (restricted to  <= 255)
 #DEFINE current_backlight_offset		.216
@@ -323,7 +317,7 @@
 #DEFINE current_compass					.28
 
 
-; Brightness Thresholds (between zero (off) and 255 (max. power consumption))
+; ---- Brightness Thresholds (between zero (off) and 255 (max. power consumption))
 #DEFINE ambient_light_max_high_36V		.170
 #DEFINE ambient_light_max_high_cr		.240
 #DEFINE ambient_light_max_high_15V		.140
@@ -334,15 +328,46 @@
 #DEFINE ambient_light_min_eco			.10			; must be the lowest value!
 
 
-; IR Link Timeout
+; ---- IR Link Timeout
 #DEFINE ir_timeout_value				.128		; in multiples of 62.5 ms
 
 
-; Setpoint Control
+; ---- Setpoint Control
 #DEFINE surface_sp						.50			; in cbar
 
 
-; Gas / Diluent Type & State
+; ---- 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		.140		; max. change depth [m]
+#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]
+#DEFINE tissue_graphics_options			.1			; tissue graphics "Pres+Sat" only available
+ ENDIF
+
+
+; ---- Setpoint list hard-coded Limits
+#DEFINE gaslist_sp_max					.160		; max. setpoint [cbar]
+#DEFINE gaslist_sp_min					.50			; min. setpoint [cbar]
+#DEFINE gaslist_sp_max_depth			.100		; max change depth [m]
+
+
+; ---- Compass Display
+#DEFINE compass_fast_treshold			.9			; show new heading instantly if angular difference > compass_fast_treshold, else show animated turning of compass rose
+#DEFINE compass_averaging				.10			; number of averaging cycles
+
+
+;-----------------------------------------------------------------------------
+; Bit Flags
+;-----------------------------------------------------------------------------
+
+; ---- 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)
@@ -352,36 +377,7 @@
 ;										.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
- ENDIF
-
-
-; Setpoint list hard-coded Limits
-#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
-#DEFINE compass_fast_treshold			.9			; show new heading instantly if angular difference > compass_fast_treshold, else show animated turning of compass rose
-#DEFINE compass_averaging				.10			; number of averaging cycles
-
-
-; Bit Flags for Communication with p2_deco.c - char_O_main_status
+; ---- Bit Flags for Communication with p2_deco.c - char_O_main_status
 #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
@@ -391,8 +387,7 @@
 #DEFINE DECO_MODE_LOOP_FLAG				.6			; =1: calculate real tissues in loop mode (CCR or pSCR)
 #DEFINE DECO_MODE_PSCR_FLAG				.7			; =1: calculate real tissues in pSCR mode (loop flag needs to be set, too)
 
-
-; Bit Flags for Communication with p2_deco.c - char_O_deco_status
+; ---- Bit Flags for Communication with p2_deco.c - char_O_deco_status
 #DEFINE DECO_START_NORM					.0			; =1: write: start calculation of a  normal      deco plan
 #DEFINE DECO_START_ALT					.1			; =1: write: start calculation of an alternative deco plan
 #DEFINE DECO_COMPLETED_NORM				.0			; =1: read:  calculation of a  normal      deco plan has completed
@@ -404,8 +399,7 @@
 ;       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)
 
-
-; Bit Flags for Communication with p2_deco.c - char_O_deco_warnings
+; ---- Bit Flags for Communication with p2_deco.c - char_O_deco_warnings
 #DEFINE IBCD_warning					.0			; =1: IBCD currently occuring
 #DEFINE IBCD_warning_lock				.1			; =1: IBCD occured durign the dive
 #DEFINE mbubble_warning					.2			; =1: microbubbles potentionally currently occuring
@@ -415,8 +409,7 @@
 #DEFINE outside_attention				.6			; =1: currently near to the limits of the ZHL-16 model
 #DEFINE deco_plan_incomplete			.7			; =1: internal error: deco calculation incomplete
 
-
-; Bit Flags for Communication with p2_deco.c - char_O_deco_info
+; ---- 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
 #DEFINE gas_needs_fTTS					.2			; =1: indicated gas needs are calculated in fTTS mode
@@ -426,14 +419,12 @@
 #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
+; ---- Bit Flags for Status on Variables of Type char
 #DEFINE char_transmitter_lost			.6
 #DEFINE char_invalid_flag				.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
@@ -447,6 +438,7 @@
 
 ;-----------------------------------------------------------------------------
 ; Timebase and Eventbase (stored in access RAM, set by the ISR, trigger flags to be cleared by the application)
+;-----------------------------------------------------------------------------
 
 #DEFINE timebase_0sec			timebase,0			; counting timebase, 1/2 sec bit
 #DEFINE timebase_1sec			timebase,1			; counting timebase,  1  sec bit
@@ -461,7 +453,7 @@
 #DEFINE trigger_timeout			 eventbase,1		; =1: timeout signal by timeout service
 #DEFINE trigger_sample_divedata	 eventbase,2		; =1: time to store a new sample
 #DEFINE trigger_S8_data_update	 eventbase,3		; =1: new S8 digital   data  are available
-#DEFINE trigger_pres_update		 eventbase,4		; =1: new pressure     value is  available
+;								 eventbase,4		; --- unused
 #DEFINE trigger_pres_cur_changed eventbase,5		; =1: current pressure value has changed
 #DEFINE trigger_pres_max_changed eventbase,6		; =1: maximum pressure value has changed
 #DEFINE trigger_temp_changed	 eventbase,7		; =1: temperature      value has changed
@@ -469,16 +461,17 @@
 
 ;-----------------------------------------------------------------------------
 ; Flags - stored in access RAM
+;-----------------------------------------------------------------------------
 
 ;---- Hardware - OSTC Model Descriptor (stored in access RAM, cleared & rebuilt in restart, to preserve compatibility with 3rd party tools DO NOT alter bit positions)
 #DEFINE battery_gauge_available	HW_descriptor,0		; =1: OSTC has rechargeable battery with battery management chip
 #DEFINE ambient_sensor			HW_descriptor,1		; =1: OSTC has an ambient light sensor
-#DEFINE analog_o2_input			HW_descriptor,2		; =1: OSTC has analog inputs and S8 digital
-#DEFINE optical_input			HW_descriptor,3		; =1: OSTC has an digital optical input
-#DEFINE ble_available			HW_descriptor,4		; =1: OSTC has an BLE module
+#DEFINE ext_input_s8_ana		HW_descriptor,2		; =1: OSTC has S8/analog input
+#DEFINE ext_input_optical		HW_descriptor,3		; =1: OSTC has optical   input
+#DEFINE ble_available			HW_descriptor,4		; =1: OSTC has an BT module
 #DEFINE ostc_rx_present			HW_descriptor,5		; =1: OSTC has RX module
 #DEFINE lv_core					HW_descriptor,6		; =1: OSTC has low-voltage core (2.7V)
-;								HW_descriptor,7		; --- reserved
+#DEFINE flash_block_write		HW_descriptor,7		; =1: OSTC has FLASH with block-write capability
 
 ;---- Hardware - OSTC Model Variants (stored in access RAM, NOT cleared in restart)
 #DEFINE screen_type1			HW_variants,0		; =1: display type 1, =0; display type 0
@@ -506,9 +499,9 @@
 #DEFINE cv_active				HW_flags_state2,1	; =1: constant voltage charging active (cR hardware only)
 #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
+#DEFINE battery_low_condition	HW_flags_state2,4	; =1: low battery condition detected
+#DEFINE flash_wrap_around		HW_flags_state2,5	; =1: address wrap-around control / signalling
+#DEFINE flash_wait				HW_flags_state2,6	; =1: wait for flash write operation to complete
 ;								HW_flags_state2,7	; --- unused
 
 
@@ -518,17 +511,17 @@
 #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 options_changed			OS_flags_persist,5	; =1: option values have been changed, EEPROM needs to be updated
+#DEFINE option_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
 
 
 ;---- Operating System - ISR Control 1 (stored in access RAM)
-#DEFINE reset_timebase			OS_flags_ISR1,0		; =1: request ISR to reset the timebase for the trigger flags
-#DEFINE reset_timeout			OS_flags_ISR1,1		; =1: request ISR to reset the timeout timer
-#DEFINE reset_max_pressure		OS_flags_ISR1,2		; =1: request ISR to reset the maximum pressure to zero
-#DEFINE reset_surface_interval	OS_flags_ISR1,3		; =1: request ISR to reset the surface interval to zero
-#DEFINE reset_trip_pressure		OS_flags_ISR1,4		; =1: request ISR to reset the resettable min/max pressure
+#DEFINE reset_timebase			OS_flags_ISR1,0		; =1: request ISR to reset  the timebase for the trigger flags
+#DEFINE restart_timeout			OS_flags_ISR1,1		; =1: request ISR to resart the timeout timer
+#DEFINE reset_max_pressure		OS_flags_ISR1,2		; =1: request ISR to reset  the maximum pressure to zero
+#DEFINE reset_surface_interval	OS_flags_ISR1,3		; =1: request ISR to reset  the surface interval to zero
+#DEFINE reset_trip_pressure		OS_flags_ISR1,4		; =1: request ISR to reset  the resettable min/max pressure
 #DEFINE block_rtc_access		OS_flags_ISR1,5		; =1: suspend the ISR from accessing the RTC
 #DEFINE block_battery_gauge		OS_flags_ISR1,6		; =1: suspend the ISR from updating the battery gauge
 #DEFINE block_sensor_interrupt	OS_flags_ISR1,7		; =1: suspend the ISR from executing sensor interrupts
@@ -538,7 +531,7 @@
 #DEFINE quit_simulatormode		OS_flags_ISR2,1		; =1: request ISR to quit the simulator mode
 #DEFINE count_divetime			OS_flags_ISR2,2		; =1: request ISR to count the dive time
 #DEFINE sensor_override_request	OS_flags_ISR2,3		; =1: request ISR to override the pressure sensor with a simulated depth
-;								OS_flags_ISR2,4		; --- unused
+#DEFINE tmr5_preemtion_allowed	OS_flags_ISR2,4		; =1: allow preemption of timeout counter
 ;								OS_flags_ISR2,5		; --- unused
 #DEFINE sensor_override_active	OS_flags_ISR2,6		; =1: ISR output:    switch to override-mode confirmed
 #DEFINE divetime_longer_1min	OS_flags_ISR2,7		; =1: ISR output:    dive time is >= one minute
@@ -549,7 +542,7 @@
 #DEFINE divemode				OM_flags_mode,1		; =1: in dive mode
 #DEFINE simulatormode			OM_flags_mode,2		; =1: in simulator mode
 #DEFINE high_altitude_mode		OM_flags_mode,3		; =1: unit was manually turned on with absolute pressure < 880 mbar
-#DEFINE s8_digital_avail		OM_flags_mode,4		; =1: S8 digital interface is available
+;								OM_flags_mode,4		; --- unused
 #DEFINE tr_functions_activated	OM_flags_mode,5		; =1: TR module is available and TR mode is <> off
 #DEFINE cold_start				OM_flags_mode,6		; =1: restart is entered from a cold start
  IFDEF _screendump
@@ -572,6 +565,7 @@
 
 ;-----------------------------------------------------------------------------
 ; Flags - stored in bank common
+;-----------------------------------------------------------------------------
 
 ;---- Dive Mode - Dive States
 #DEFINE use_aGF					DM_flags_state,0	; =1: use aGF, =0: use GF
@@ -590,7 +584,7 @@
 #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
-#DEFINE sp_fallback				DM_flags_sensor,6	; =1: fall-back to SP1 due to external O2 sensor failure
+;								DM_flags_sensor,6	; --- unused
 ;								DM_flags_sensor,7	; --- unused
 
 ;---- Dive Mode - User Requests / General
@@ -635,12 +629,12 @@
 
 #DEFINE cur_depth_greater_100m	DM_flags_layout2,0	; =1: current depth > 100 meters
 #DEFINE max_depth_greater_100m	DM_flags_layout2,1	; =1: max.    depth > 100 meters
-#DEFINE depth_attention			DM_flags_layout2,2	; =1: show depth in attention color
-#DEFINE depth_warning			DM_flags_layout2,3	; =1: show depth in warning   color
-#DEFINE depth_warn_att_last		DM_flags_layout2,4	; =1: last depth was shown in warning or attention color
+#DEFINE depth_color_attention	DM_flags_layout2,2	; =1: show depth in attention color
+#DEFINE depth_color_warning		DM_flags_layout2,3	; =1: show depth in warning   color
+#DEFINE depth_color_last		DM_flags_layout2,4	; =1: last depth was shown in warning or attention color
 #DEFINE depth_inverse_last		DM_flags_layout2,5	; =1: last depth was shown in inverse
-#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 gas_needs_mode_last		DM_flags_layout2,6	; =1: last gas needs were computed for cave mode, =0: vertical ascent
+#DEFINE tts_over_99_last		DM_flags_layout2,7	; =1: last TTS was > 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
@@ -652,16 +646,6 @@
 ;								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
-#DEFINE message_warning			DM_flags_message,2	; =1: a warning    is active in dive mode or surface mode
-#DEFINE message_2nd_row_used	DM_flags_message,3	; =1: the second row contains a warning/attention/advice
-#DEFINE sign_shown				DM_flags_message,4	; =1: the warning/attention/advice sign is shown
-#DEFINE gas_needs_attention		DM_flags_message,5	; =1: the gas needs  attention has been shown before
-#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, Depth
 #DEFINE better_gas_hint			DM_flags_gas_dil,0	; =1: mark a gas when it is a better gas
 #DEFINE color_code_gases		DM_flags_gas_dil,1	; =1: color code the gases by ppO2 & current depth
@@ -670,17 +654,117 @@
 #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
+;								DM_flags_gas_dil,7	; --- unused
+
+
+;---- Dive Mode - Display Control / Messages
+#DEFINE sign_shown				DM_flags_message,0	; =1: the warning/attention/advice sign is shown
+#DEFINE sign_advice				DM_flags_message,1	; =1: the sign shown is an advice    sign
+#DEFINE sign_attention			DM_flags_message,2	; =1: the sign shown is an attention sign
+#DEFINE sign_warning			DM_flags_message,3	; =1: the sign shown is a  warning   sign
+#DEFINE message_2nd_row_used	DM_flags_message,4	; =1: the second row contains a warning/attention/advice
+;								DM_flags_message,5	; --- unused
+;								DM_flags_message,6	; --- unused
+;								DM_flags_message,7	; --- unused
+
+
+;---- Dive Mode - Display Control / Advices
+#DEFINE advc_det_change_gas		DM_flags_advc_det,0	; =1: change gas  advice
+#DEFINE advc_det_switch_tank	DM_flags_advc_det,1	; =1: change tank advice
+;								DM_flags_advc_det,2	; --- unused
+;								DM_flags_advc_det,3	; --- unused
+;								DM_flags_advc_det,4	; --- unused
+;								DM_flags_advc_det,5	; --- unused
+;								DM_flags_advc_det,6	; --- unused
+;								DM_flags_advc_det,7	; --- unused
+
+
+;---- Dive Mode - Display Control / Attentions
+#DEFINE attn_det_gas_needs		DM_flags_att1_det,0	; =1: gas needs          attention threshold reached
+#DEFINE attn_det_ppo2_breathed	DM_flags_att1_det,1	; =1: breathed ppO2      attention threshold reached
+#DEFINE attn_det_ppo2_diluent	DM_flags_att1_det,2	; =1: diluent  ppO2      attention threshold reached
+#DEFINE attn_det_cns_current	DM_flags_att1_det,3	; =1: current  CNS       attention threshold reached
+#DEFINE attn_det_gas_density	DM_flags_att1_det,4	; =1: gas density        attention threshold reached
+#DEFINE attn_det_saturation		DM_flags_att1_det,5	; =1: tissue saturation  attention threshold reached
+#DEFINE attn_det_outside		DM_flags_att1_det,6	; =1: outside model      attention issued
+#DEFINE attn_det_microbubble	DM_flags_att1_det,7	; =1: µ-bubble           attention issued
+
+#DEFINE attn_det_sac_rate		DM_flags_att2_det,0	; =1: SAC rate           attention threshold reached
+#DEFINE attn_det_pressure1		DM_flags_att2_det,1	; =1: tank 1 pressure    attention threshold reached
+#DEFINE attn_det_pressure2		DM_flags_att2_det,2	; =1: tank 2 pressure    attention threshold reached
+#DEFINE attn_det_ibcd			DM_flags_att2_det,3	; =1: IBCD               attention issued
+#DEFINE attn_det_cave_shut_down	DM_flags_att2_det,4	; =1: cave mode shutdown attention issued
+#DEFINE attn_det_sensor1_lost	DM_flags_att2_det,5	; =1: sensor 1 lost      attention issued
+#DEFINE attn_det_sensor2_lost	DM_flags_att2_det,6	; =1: sensor 2 lost      attention issued
+#DEFINE attn_det_sensor3_lost	DM_flags_att2_det,7	; =1: sensor 3 lost      attention issued
+
+#DEFINE attn_det_xmit1_bat		DM_flags_att3_det,0	; =1: xmitter 1 low batt attention issued
+#DEFINE attn_det_xmit2_bat		DM_flags_att3_det,1	; =1: xmitter 2 low batt attention issued
+#DEFINE attn_det_cns_eod		DM_flags_att3_det,2	; =1: end-of-dive CNS    attention threshold reached
+;								DM_flags_att3_det,3	; --- unused
+;								DM_flags_att3_det,4	; --- unused
+;								DM_flags_att3_det,5	; --- unused
+;								DM_flags_att3_det,6	; --- unused
+;								DM_flags_att3_det,7	; --- unused
+
+;---- Dive Mode - Display Control / Warnings
+#DEFINE warn_det_gas_needs		DM_flags_war1_det,0	; =1: gas needs          warning threshold reached
+#DEFINE warn_det_ppO2_breathed	DM_flags_war1_det,1	; =1: breathed ppO2      warning threshold reached
+#DEFINE warn_det_ppO2_diluent	DM_flags_war1_det,2	; =1: diluent  ppO2      warning threshold reached
+#DEFINE warn_det_cns_current	DM_flags_war1_det,3	; =1: current  CNS       warning threshold reached
+#DEFINE warn_det_gas_density	DM_flags_war1_det,4	; =1: gas density        warning threshold reached
+#DEFINE warn_det_saturation		DM_flags_war1_det,5	; =1: tissue saturation  warning threshold reached
+#DEFINE warn_det_outside		DM_flags_war1_det,6	; =1: outside model      warning issued
+#DEFINE warn_det_microbubble	DM_flags_war1_det,7	; =1: µ-bubble           warning issued
+
+#DEFINE warn_det_cave_shut_down	DM_flags_war2_det,0	; =1: cave mode shutdown warning issued
+#DEFINE warn_det_pressure1		DM_flags_war2_det,1	; =1: tank pressure 1    warning threshold reached
+#DEFINE warn_det_pressure2		DM_flags_war2_det,2	; =1: tank pressure 2    warning threshold reached
+#DEFINE warn_det_batt_low		DM_flags_war2_det,3	; =1: battery low        warning issued
+#DEFINE warn_det_depth_limit	DM_flags_war2_det,4	; =1: depth limit        warning issued
+#DEFINE warn_det_sensors_lost	DM_flags_war2_det,5	; =1: sensors lost       warning issued
+#DEFINE warn_det_sensors_div	DM_flags_war2_det,6	; =1: sensors divergence warning issued
+#DEFINE warn_det_no_bo_gas		DM_flags_war2_det,7	; =1: no B/O gas avail   warning issued
+
+
+;---- Dive Mode - Display Control / Custom View automatic show-up
+#DEFINE shown_gas_needs_attn	DM_flags_shown1,0	; =1: gas needs attention has been shown before
+#DEFINE shown_gas_needs_warn	DM_flags_shown1,1	; =1: gas needs warning   has been shown before
+#DEFINE shown_sensors_diverg	DM_flags_shown1,2	; =1: sensor divergence   has been shown before
+#DEFINE shown_sensors_lost		DM_flags_shown1,3	; =1: sensor all lost     has been shown before
+#DEFINE shown_sensor1_fail		DM_flags_shown1,4	; =1: sensor 1 failure    has been shown before
+#DEFINE shown_sensor2_fail		DM_flags_shown1,5	; =1: sensor 2 failure    has been shown before
+#DEFINE shown_sensor3_fail		DM_flags_shown1,6	; =1: sensor 3 failure    has been shown before
+;								DM_flags_shown1,7	; --- unused
+
+#DEFINE shown_xmit1_lost		DM_flags_shown2,0	; =1: xmitter 1 lost      has been shown before
+#DEFINE shown_xmit1_battery		DM_flags_shown2,1	; =1: xmitter 1 batt low  has been shown before
+#DEFINE shown_xmit1_pres_warn	DM_flags_shown2,2	; =1: xmitter 1 pres warn has been shown before
+#DEFINE shown_xmit1_pres_attn	DM_flags_shown2,3	; =1: xmitter 1 pres attn has been shown before
+#DEFINE shown_xmit2_lost		DM_flags_shown2,4	; =1: xmitter 2 lost      has been shown before
+#DEFINE shown_xmit2_battery		DM_flags_shown2,5	; =1: xmitter 2 batt low  has been shown before
+#DEFINE shown_xmit2_pres_warn	DM_flags_shown2,6	; =1: xmitter 2 pres warn has been shown before
+#DEFINE shown_xmit2_pres_attn	DM_flags_shown2,7	; =1: xmitter 2 pres attn has been shown before
+
+#DEFINE shown_gas_density_attn	DM_flags_shown3,0	; =1: gas density atten.  has been shown before
+#DEFINE shown_gas_density_warn	DM_flags_shown3,1	; =1: gas density warning has been shown before
+;								DM_flags_shown3,2	; --- unused
+;								DM_flags_shown3,3	; --- unused
+;								DM_flags_shown3,4	; --- unused
+;								DM_flags_shown3,5	; --- unused
+;								DM_flags_shown3,6	; --- unused
+;								DM_flags_shown3,7	; --- unused
+
 
 ;---- Menu System - Control
-#DEFINE surfmode_menu			MS_flags_control,0	; =1: surface      menu is shown (i.e. returning from it)
-#DEFINE dive_options_menu		MS_flags_control,1	; =1: dive options menu is shown (e.g. "Menu?")
-#DEFINE dive_main_menu			MS_flags_control,2	; =1: dive mode    menu is shown (i.e. the "big" menu)
+#DEFINE surfmode_menu			MS_flags_control,0	; =1: surface   menu is shown (i.e. returning from it)
+#DEFINE dive_pre_menu			MS_flags_control,1	; =1: dive  pre-menu is shown (e.g. "Menu?")
+#DEFINE dive_main_menu			MS_flags_control,2	; =1: dive main menu is shown (i.e. the "big" menu)
 #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
 #DEFINE custom_view_locked		MS_flags_control,6	; =1: the custom view is locked (defer CV auto-popup)
-;								MS_flags_control,7	; --- unused
+#DEFINE option_stop_at_max		MS_flags_control,7	; =1: option increment will stop at max value (no wrap around)
 
 ;---- Menu System - Data Imprinting
 #DEFINE imprint_time_date		MS_flags_imprint,0	; =1: imprint current time & date
@@ -689,8 +773,8 @@
 #DEFINE imprint_xmitter_pres	MS_flags_imprint,3	; =1: imprint transmitter pressure data
 #DEFINE imprint_xmitter_ID		MS_flags_imprint,4	; =1: in transmitter-to-tank pairing menu
 #DEFINE imprint_surfmode_data	MS_flags_imprint,5	; =1: imprint surface mode data
-#DEFINE block_option_value		MS_flags_imprint,6	; =1: suspend display of option values
-;								MS_flags_imprint,7	; --- unused
+#DEFINE block_option_value		MS_flags_imprint,6	; =1: suspend displaying of option values
+#DEFINE short_gas_descriptions	MS_flags_imprint,7	; =1: use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
 
 
 ;---- Font & Image System
@@ -699,29 +783,30 @@
 #DEFINE aa_color_half			AA_flags,2			;     used by aa_wordprocessor
 #DEFINE aa_aux_flag				AA_flags,3			;     auxiliary flag for various purposes
 #DEFINE use_custom_colors		AA_flags,4			; =1: override default pixel colors, used by color_image
-;								AA_flags,5			; --- unused
+#DEFINE win_invert				AA_flags,5			; =1: print in inverse video
 ;								AA_flags,6			; --- unused
 ;								AA_flags,7			; --- unused
 
 
-;---- Convert and Display Functions (Control of numerical and other Output)
-#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		;     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
+;---- Convert Functions (Control of numerical Output)
+
+#DEFINE hide_digit5				CVT_flags1,0		; =1: do not print digit  5   (clip output at  9999)
+#DEFINE hide_digit4				CVT_flags1,1		; =1: do not print digits 5-4 (clip output at   999)
+#DEFINE hide_digit3				CVT_flags1,2		; =1: do not print digits 5-3 (clip output at    99)
+#DEFINE hide_digit2				CVT_flags1,3		; =1: do not print digits 5-2 (clip output at     9)
+#DEFINE omit_digit_1			CVT_flags1,4		; =1: do not print digit    1 (show output as xxxx-)
+#DEFINE omit_digit_2			CVT_flags1,5		; =1: do not print digits 2-1 (show output as xxx--)
 ;								CVT_flags1,6		; --- unused
 ;								CVT_flags1,7		; --- unused
 
-#DEFINE pre_zero_flag			CVT_flags2,0
-#DEFINE all_zeros_flag			CVT_flags2,1
-#DEFINE DP_done					CVT_flags2,2
-#DEFINE DP_done2				CVT_flags2,3
-#DEFINE show_last3				CVT_flags2,4
-#DEFINE leading_zeros			CVT_flags2,5
-#DEFINE show_last4				CVT_flags2,6
-#DEFINE neg_flag				CVT_flags2,7		; =1: result is negative
+#DEFINE decimal_digit1			CVT_flags2,0		; =1: put a decimal point in front of digit 1
+#DEFINE decimal_digit2			CVT_flags2,1		; =1: put a decimal point in front of digit 2
+#DEFINE decimal_digit3			CVT_flags2,2		; =1: put a decimal point in front of digit 3
+;								CVT_flags2,3		; --- unused
+#DEFINE leftbind				CVT_flags2,4		; =1: align output to the left (no leading spaces)
+#DEFINE leading_zeros			CVT_flags2,5		; =1: print leading zeros
+#DEFINE output_overflow			CVT_flags2,6		; =1: the printed number is clipped to 9999/999/99/9
+;								CVT_flags2,7		; --- unused
 
 
 ;---- Miscellaneous Flags
@@ -730,9 +815,10 @@
 #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
+#DEFINE option_value_ok			misc_flags,5		; =1: option value was checked to be within min/max limits
+#DEFINE aux_flag				misc_flags,6		;     local flag, used in various places
+#DEFINE neg_flag				misc_flags,7		; =1: result is negative
+
 
 ;---- HUD Status Byte (stored in access RAM)
 #DEFINE hud_connection_ok		hud_status_byte,0	; =1 HUD connection ok
@@ -745,10 +831,11 @@
 ;								hud_status_byte,7	; --- unused in stand-alone HUD
 
 
-;---------------------------- Macros ------------------------------------
+;-----------------------------------------------------------------------------
+; Macros 
+;-----------------------------------------------------------------------------
 
-
-; ---- options checking ----
+; ---- options checking
 
 TSTOSS	macro opt_reg				; TeST Option Skip next instruction if Set (not zero)
 	movff	opt_reg,EEDATA			; Attention: destroys EEDATA!
@@ -762,7 +849,7 @@
 	endm							;            command, do not let follow a macro!
 
 
-; ---- literal operations ----
+; ---- 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!
@@ -795,7 +882,7 @@
 	endm							;
 
 
-; ---- arithetics ----
+; ---- 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!
@@ -824,7 +911,7 @@
 	endm							;
 
 
-; ---- moves ----
+; ---- moves
 
 MOVCC	macro from,to				; MOVe     1 byte Char    (actually an alias for movff)
 	movff	from,to
@@ -850,7 +937,7 @@
 	endm
 
 
-; ---- ISR-safe moves ----
+; ---- ISR-safe moves
 
 SMOVII	macro from, to				; isr-Safe MOVe     2 byte Integer (version of MOVII for ISR-safe copying)
 	local	retry					;
@@ -900,7 +987,9 @@
 	endm							; NO  - done
 
 
-;---------------------------- C-Code Routines ----------------------------
+;-----------------------------------------------------------------------------
+; C-Code Routines
+;-----------------------------------------------------------------------------
 
 	extern	deco_calc_desaturation_time
 	extern	deco_calc_hauptroutine
@@ -913,11 +1002,13 @@
 	extern	deco_push_tissues_to_vault
 
 
-;---------------------------- Bank0 ACCESS RAM ------------------------------
+;-----------------------------------------------------------------------------
+; Bank0 ACCESS RAM
+;-----------------------------------------------------------------------------
 
 ; Variables located in the Access Bank are declared in hwos.asm
 
- ifndef ACCESS_RAM_VARS
+ ifndef INSIDE_HWOS_ASM
 
 	extern	HW_descriptor
 	extern	HW_variants
@@ -959,9 +1050,20 @@
 	extern	hud_status_byte
 	extern	hud_battery_mv
 
+	extern	battery_capacity_internal
+	extern	battery_capacity
+	extern	battery_offset
+	extern	battery_type
+	extern	battery_accumulated_charge
+	extern	battery_temperature
+	extern	gauge_status_byte
+
  endif	; ACCESS_RAM_VARS
 
-;---------------------------- Bank0 NORMAL RAM ------------------------------
+;-----------------------------------------------------------------------------
+; Bank0 NORMAL RAM
+;-----------------------------------------------------------------------------
+
 isr_backup	equ			0x060		; Alias for "banksel isr_backup"
 isr_backup	udata_ovr	isr_backup	; Bank 0 ISR data
 
@@ -1088,8 +1190,11 @@
 
 ; 143 byte used, 17 byte free
 
- 
-;---------------------------- Common DATA ------------------------------------
+
+;-----------------------------------------------------------------------------
+; Common DATA
+;-----------------------------------------------------------------------------
+
 common		equ			0x100		; Alias for "banksel common"
 common		udata_ovr	common		; Bank 1 general variables
 
@@ -1107,7 +1212,7 @@
 MS_flags_control				res 1		; menu system - control
 MS_flags_imprint				res 1		; menu system - data imprinting
 
-;---- Flags - Dive Mode (9 byte)
+;---- Flags - Dive Mode (21 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 / general
@@ -1117,14 +1222,26 @@
 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
+DM_flags_advc_det				res 1		; dive mode - advices    detected
+DM_flags_advc_ack				res 1		; dive mode - advices    acknowledged
+DM_flags_att1_det				res 1		; dive mode - attentions detected     (1)
+DM_flags_att2_det				res 1		; dive mode - attentions detected     (2)
+DM_flags_att3_det				res 1		; dive mode - attentions detected     (3)
+DM_flags_att1_ack				res 1		; dive mode - attentions acknowledged (1)
+DM_flags_att2_ack				res 1		; dive mode - attentions acknowledged (2)
+DM_flags_att3_ack				res 1		; dive mode - attentions acknowledged (3)
+DM_flags_war1_det				res 1		; dive mode - warnings   detected     (1)
+DM_flags_war2_det				res 1		; dive mode - warnings   detected     (2)
+DM_flags_war1_ack				res 1		; dive mode - warnings   acknowledged (1)
+DM_flags_war2_ack				res 1		; dive mode - warnings   acknowledged (2)
+DM_flags_shown1					res 1		; dive mode - custom views shown      (1)
+DM_flags_shown2					res 1		; dive mode - custom views shown      (2)
+DM_flags_shown3					res 1		; dive mode - custom views shown      (3)
 
 ;---- Miscellaneous Flags (1 byte)
 misc_flags						res 1
 
-;---- Interface to numerical Display Functions (1 byte)
-ignore_digits					res 1
-
-;---- Interface to Graphic Functions (12 byte)
+;---- Interface to Graphic Functions (11 byte)
 win_leftx2						res 1
 win_top							res 1
 win_width						res 2
@@ -1135,7 +1252,6 @@
 win_color3						res 1		; 3 byte color used for display 2
 win_color4						res 1		; 3 byte color used for display 2
 win_color5						res 1		; 3 byte color used for display 2
-win_font						res 1		; font size selector
 
 ;---- Interface to Math Functions (16 byte)
 divA							res 2
@@ -1160,6 +1276,7 @@
 message_page					res 1		; current message page number
 pairing_slot					res 1		; slot number, used in transmitter pairing
 
+
 ;---- 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
@@ -1191,16 +1308,10 @@
 ;---- Dive Mode / apnoe mode (2 byte)
 apnoe_max_pressure				res 2		; max depth over all dives in the series
 
-;---- Gas 6 Data (2 byte)
-gas6_O2_ratio					res 1		; gas 6 O2 ratio
- IFDEF _helium
-gas6_He_ratio					res 1		; gas 6 He ratio
- ENDIF
-
 ;---- Profile Recording (6 byte)
-alarm_type						res 1		;
-event_byte1						res 1		;
-event_byte2						res 1		;
+alarm_type						res 1		; alarm states recording
+event_byte1						res 1		; events recording
+event_byte2						res 1		; events recording
 CNS_start						res 2		; CNS value at beginning of dive
 
 ;---- External Flash (14 byte)
@@ -1209,27 +1320,28 @@
 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_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
-battery_capacity				res 2		; for battery gauge IC
-battery_offset					res 2		; for battery gauge IC
-battery_type					res 1		; =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
-battery_accumulated_charge		res 2		; raw values in battery gauge IC
-battery_temperature				res 2		; battery temperature in 0.1 Kelvin
-gauge_status_byte				res 1		; gauge IC status byte
+ext_flash_address_limit			res 1		; wrap-around threshold while address incrementing
 
 
-;========================= private Variables ===================================
-;        do not access from outside of the respective source files!
+;-------------------------------------------------------------------------------
+; private Variables - do not access from outside of the respective source files!
+;-------------------------------------------------------------------------------
 
-;---- aa_wordprocessor.asm and strings.asm
+;---- aa_wordprocessor.asm, strings.asm & Co.
 AA_flags						res 1		; various flags for aa_wordprocessor and strings
 aa_bitlen						res 1		; count of pixels when decoding bitmaps
 aa_start						res 2		; PROM pointer to start of encoded bitmap
 aa_end							res 2		; and end of it
 aa_temp							res 2		; current color, divided by 2 or 4
+font_color						res 1		; selected font color
+font_size						res 1		; selected font size
+pallet_color_mask				res 1		; pallet color - mask		| Attention:
+pallet_color_disabled			res 1		; pallet color - disabled	| do not change
+pallet_color_memo				res 1		; pallet color - memo		| the relative
+pallet_color_advice				res 1		; pallet color - advice		| position of
+pallet_color_attention			res 1		; pallet color - attention	| these vars!
+pallet_color_warning			res 1		; pallet color - warning	|
+
 
 ;--- adc_lightsensor.asm
 get_bat_volt_counter			res 1		; counter for reading the charger chip
@@ -1237,12 +1349,11 @@
 ;---- convert.asm
 CVT_flags1						res 1
 CVT_flags2						res 1
-cvt_temp1						res 1
-cvt_temp2						res 1
-cvt_temp3						res 1
-cvt_temp4						res 1
-cvt_temp_lo						res 1
-cvt_temp_hi						res 1
+bcd_lo							res 1
+bcd_hi							res 1
+bcd_up							res 1
+bin_lo							res 1
+bin_hi							res 1
 
 ;---- color_processor.asm
 overall_pixels					res 3		; used by color_processor.asm
@@ -1257,7 +1368,7 @@
 
 ;---- eeprom_rs232.asm
 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
+rx_timeout_tmr5h_load			res 1		; TMR5H load value for RS232 RX timeout
 
 ;---- i2c.asm
 i2c_temp1						res 1		; temporary data
@@ -1268,26 +1379,25 @@
 
 ;---- menu_processor.asm
 menustack_pointer				res 1		; pointer to menu stack
-menu_flags						res 1		; flags for menu entries
-menu_item						res 1		; index of the current item
-start_item						res 1		; index of the first item (scrolling)
-item_max						res 1		; number of items in menu
+menu_item_start					res 1		; index of the first   menu item (scrolling)
+menu_item_curr					res 1		; index of the current menu item (loop counter)
+menu_item_count					res 1		; total number of      menu items
 selected_item					res 1		; index of the current item
-value_type						res 1		; type for vertical menu
-dynamic_item					res 3		; callback address
-menu_block						res 3		; address of the menu block (i.e. item 0)
-menu_title						res 3		; text or procedure for dynamic menu
-menu_center						res 1		; centering for line menu
-proc_item						res 3		; address of the current procedure
-text_item						res 2		; address of the current text
+menu_title_addr					res 2		; address of the multi-lingual menu titel
+menu_item_data_start			res 3		; base address of the menu item data blocks
+menu_vertical_start				res 1		; vertical start position of 1st menu item
+item_type						res 1		; type of the menu item
+item_title_addr					res 2		; address of item title function or title text
+item_funct_addr					res 2		; address of item call  function or option definition data
+
 
 ;---- options.asm
-#DEFINE opt_definiton_bytes		.12			; | Attention: do not change the relative position of these vars!
+#DEFINE opt_definition_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_inc							res 1		; | increment value, also used for enum low  and low (pointer to default string)
+opt_min							res 1		; | minimum   value, also used for enum high and high(pointer to default string)
+opt_max							res 1		; | maximum   value, also used for               length(         default string)
 opt_default						res 1		; | default   value
 opt_unit						res 2		; | pointer to multi-lingual unit text
 opt_memory						res 2		; | pointer to memory position
@@ -1317,19 +1427,25 @@
 ;---- wait.asm
 wait_counter					res 1
 
+;---- tft_outputs.asm
+pressure_update_lag_counter		res 1		; lag time counter for fast surface pressure display updating
 
-; 201 byte used, 7 byte free (208 byte total)
+
+; 200 byte used, 8 byte free (208 byte total)
 
 
-;============================ LOCAL DATA ======================================
+;-----------------------------------------------------------------------------
+; LOCAL DATA 
+;-----------------------------------------------------------------------------
+
 ; Space for various overlayed local data from top-level applications,
 ; i.e. applications that never run in parallel to each other
-;
+
 ; --------------------- local Data Users --------------------------------------
 ;
 ;					-------------- Applications using ----------------------
 ;	Mode			local1				local2				local3
-; -----------------------------------------------------------------------------
+; --------------------------------------------------------------------------
 ;	sleepmode		sleepmode.asm		(unused)			(unused)
 ;	surfmode		surfmode.asm*		(unused)			(unused)
 ;	simulator		divemode.asm		divemode.asm		simulator.asm
@@ -1351,7 +1467,10 @@
 				res			0x10	; 16 Byte (0x1F0 ... 0x1FF)
 
 
-;---------------------------- Common2 DATA ------------------------------------
+;-----------------------------------------------------------------------------
+; Common2 DATA
+;-----------------------------------------------------------------------------
+
 common2		equ			0xA00		; Alias for "banksel common2"
 common2		udata_ovr	common2		; Bank 10 general variables
 
@@ -1444,34 +1563,38 @@
 time_last_2nd					res 2		; last pressure reading time       in seconds    |
  ENDIF
 
-
 ; 156 byte used, 100 byte free
 
 
-;----------------------- Bank 2 General Purpose Buffer 1 -----------------------
-; general purpose buffer no.1
-;
+;-----------------------------------------------------------------------------
+; Bank 2 General Purpose Buffer 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 11 General Purpose Buffer 2 ----------------------
-; general purpose buffer no. 2
+;-----------------------------------------------------------------------------
+; Bank 11 General Purpose Buffer 2
+;-----------------------------------------------------------------------------
+
+; NOTE: needs to be aligned with a bank (low(buffer)=0)
 ;
-; NOTE: needs to be aligned with a bank (low(buffer)=0)
-
 ; 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.
 
 #DEFINE buffer2					0xB00
 
 
-;---------------------- Bank 14 Options Table ---------------------------------
+;-----------------------------------------------------------------------------
+; Bank 14 Options Table
+;-----------------------------------------------------------------------------
+
 opt_table	equ			0xE00		; Alias for "banksel opt_table"
 opt_table	udata_ovr	opt_table	; Bank 14 options table
 
@@ -1485,7 +1608,11 @@
 opt_gas_change					res 5		; change depths for OC/Bailout gases                         |
 opt_dil_change					res 5		; change depths for diluents                                 |
 
-;---- Setpoints
+;---- Gas 6 Settings
+opt_gas6_O2_ratio				res 1		; gas 6 O2 ratio                           | ATTENTION: keep relative positioning
+opt_gas6_He_ratio				res 1		; gas 6 He ratio                           |            of these two variables!
+
+;---- Setpoints Settings
 opt_setpoint_cbar				res 5		; setpoints in cbar                        | ATTENTION: keep relative positioning
 opt_setpoint_change				res 5		; change depth for the setpoints in meter  |            of these two arrays!
 
@@ -1507,6 +1634,7 @@
 opt_language					res 1		; current language: 0=EN, 1=DE, 2=FR, 3=SP
 opt_units						res 1		; 0:m/°C, 1:ft/°F
 opt_dateformat					res 1		; =0:MMDDYY, =1:DDMMYY, =2:YYMMDD
+opt_dive_color_scheme			res 1		; dive mode color scheme selection
 opt_last_stop					res 1		; =3:3m, =4:4m, =5:5m, =6:6m
 opt_aGF_high					res 1		; alternative GF HIGH
 opt_aGF_low						res 1		; alternative GF LOW
@@ -1515,13 +1643,12 @@
 opt_enable_aGF					res 1		; =1: aGF can be selected underwater
 opt_compass_gain				res 1		; 0-7 (230LSB/Gauss to 1370LSB/Gaus)
 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_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)
-opt_x_s3						res 2		; calibration factor (Not stored in EEPROM)
+opt_x_s1						res 2		; calibration factor (not stored in EEPROM) | keep relative
+opt_x_s2						res 2		; calibration factor (not stored in EEPROM) | position!
+opt_x_s3						res 2		; calibration factor (not stored in EEPROM) |
 opt_sensor_fallback				res 1		; NOT USED ANY MORE, KEPT FOR COMPATIBILITY WITH EEPROM IMAGE
 opt_flip_screen					res 1		; =1: flip the screen
 opt_cR_button_left				res 1		; left button  sensitivity (cR hardware)
@@ -1555,6 +1682,10 @@
 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
+opt_gas_density_check			res 1		; =1: gas density is checked (effective in CCR / pSCR modes only)
+opt_comm_timeout				res 1		; comm RX timeout in multiples of 10 ms
+opt_fallback					res 1		; unused dummy option for compatibility with 3rd party tools
+opt_conservatism				res 1		; unused dummy option for compatibility with 3rd party tools
 
 ;---- RX Function Settings
 opt_transmitter_id_1			res 2		; 16 bit transmitter ID for Gas 1
@@ -1572,7 +1703,7 @@
 opt_TR_2nd_pres					res 1		; TR functions - 2nd pressure assignment
 opt_TR_Bail_pres				res 1		; TR functions - bailout pressure assignment
 
-; ==> 190 bytes used - 54 bytes free (244 usable bytes only in bank 14 as the upper 12
+; ==> 193 bytes used - 51 bytes free (244 usable bytes only in bank 14 as the upper 12
 ;                                     bytes are reserved for special function registers)
 
 ;-----------------------------------------------------------------------------
--- a/src/i2c.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/i2c.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File i2c.asm                              combined next generation V3.08.8
+;   File i2c.asm                            * combined next generation V3.09.4b
 ;
 ;   I2C Interface
 ;
@@ -48,31 +48,44 @@
 #include "hwos.inc"						; Mandatory header
 #include "wait.inc"
 #include "math.inc"
-#include "external_flash.inc"
 #include "eeprom_rs232.inc"
 
 
-i2c	CODE
-
+;=============================================================================
+i2c		CODE
 ;=============================================================================
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - send 1 Byte, wait for end of transmission and check ackn
+;
 I2C_TX:
-	movwf	SSP1BUF
-	rcall	WaitMSSP
-	bra		I2C_WaitforACK				; returns...
+	movwf	SSP1BUF						; put byte to be sent into TX buffer
+	rcall	WaitMSSP					; wait for TX to complete
+	bra		I2C_Check_ACK				; check for acknowledge by receiver and return
+
 
-I2C_TwoBytesRX_div16:					; get two bytes and divide lo:hi/16 (signed)
-	rcall	I2C_OneByteRX				; get one byte
-	movff	SSP1BUF,hi					; data byte
-	rcall	I2C_OneByteRX				; get one byte
-	movff	SSP1BUF,lo					; data byte
-I2C_TwoBytesRX_div16_2:					; divide lo:hi/16 (signed) only
+;-----------------------------------------------------------------------------
+; Helper Function - get two Bytes and divide hi:lo/16 (signed)
+;
+I2C_TwoBytesRX_div16:
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
+	movff	SSP1BUF,hi					; copy data byte to hi
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
+	movff	SSP1BUF,lo					; copy data byte to lo
+I2C_TwoBytesRX_div16_2:					; divide hi:lo/16 (signed) only
 	bcf		STATUS,C
 	btfsc	hi,7						; copy sign bit to carry
 	bsf		STATUS,C
 	rrcf	hi							; /2
 	rrcf	lo
-I2C_TwoBytesRX_div8_2:					; divide lo:hi/8 (signed) only
+	;bra	I2C_TwoBytesRX_div8			; continue dividing hi:lo/8 (signed)
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - divide hi:lo/8 (signed)
+;
+I2C_TwoBytesRX_div8:
 	bcf		STATUS,C
 	btfsc	hi,7						; copy sign bit to carry
 	bsf		STATUS,C
@@ -88,8 +101,12 @@
 	bsf		STATUS,C
 	rrcf	hi							; /16
 	rrcf	lo
-	return
+	return								; done
+
 
+;-----------------------------------------------------------------------------
+; Read Accelerometer
+;
 	global	I2C_RX_accelerometer
 I2C_RX_accelerometer:
 	btfsc	compass_type3					; compass3 ?
@@ -102,18 +119,17 @@
 
 I2C_RX_accelerometer_compass0:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x38						; address
-	rcall	I2C_TX
-	movlw	0x00
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
+	movlw	0x00						; ??
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,RSEN				; repeated start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x39						; address
-	rcall	I2C_TX
-
-	rcall	I2C_OneByteRX				; get status byte
-	movf	SSP1BUF,W
+	rcall	I2C_TX						; send byte
+	rcall	I2C_OneByteRX				; get  status byte
+	movf	SSP1BUF,W					; copy status byte to WREG
 
 	; Non-flipped screen:
 	; Chip orientation on the PCB requires
@@ -132,49 +148,52 @@
 	rcall	I2C_TwoBytesRX_div16		; get two bytes and divide /16 (signed)
 	btfsc	flip_screen					; 180° rotation?
 	bra		I2C_RX_accelerometer2		; YES
-	comf	hi							; 16 bit sign change
-	negf	lo
-	btfsc	STATUS,C					; carry to propagate?
-	incf	hi,F						; YES - do it
+	comf	hi							; NO  - 16 bit sign change
+	negf	lo							;     - ....
+	btfsc	STATUS,C					;     - carry to propagate?
+	incf	hi,F						;     - YES - do it
 I2C_RX_accelerometer2:
-	MOVII	mpr,accel_DX				; copy result
+	MOVII	mpr,accel_DX				; copy result to accel_DX
+
 	rcall	I2C_TwoBytesRX_div16		; get two bytes and divide /16 (signed)
 	btfsc	flip_screen					; 180° rotation?
 	bra		I2C_RX_accelerometer3		; YES
+	comf	hi							; NO  - 16 bit sign change
+	negf	lo							;     - ...
+	btfsc	STATUS,C					;     - carry to propagate?
+	incf	hi,F						;       YES - do it
+I2C_RX_accelerometer3:
+	MOVII	mpr,accel_DY				; copy result to accel_DY
+
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
+	movff	SSP1BUF,hi					; copy data byte to hi
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	; according to data sheet there should be no master acknowledge for the last byte (accel_DZ+0)...
+	movff	SSP1BUF,lo					; copy data byte to lo
+	rcall	I2C_TwoBytesRX_div16_2		; divide hi:lo/16 (signed)
 	comf	hi							; 16 bit sign change
-	negf	lo
+	negf	lo							; ...
 	btfsc	STATUS,C					; carry to propagate?
 	incf	hi,F						; YES - do it
-I2C_RX_accelerometer3:
-	MOVII	mpr,accel_DY				; copy result
-	rcall	I2C_OneByteRX				; get one byte
-	movff	SSP1BUF,hi					; data byte
-	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP
-; According to data sheet there should be no master Acknowledge for the last byte (accel_DZ+0)...
-	movff	SSP1BUF,lo					; data byte
+	MOVII	mpr,accel_DZ				; copy result to accel_DZ
+	bsf		SSP1CON2,PEN				; stop condition
+	bra		WaitMSSP					; wait for TX to complete and return
 
-	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
-	comf	hi							; 16 bit sign change
-	negf	lo
-	btfsc	STATUS,C					; carry to propagate?
-	incf	hi,F						; YES - do it
-	MOVII	mpr,accel_DZ				; copy result
-	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
 
 I2C_RX_accelerometer_compass1:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'10101000'					; 0x28 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3D						; address
-I2C_RX_accelerometer_compass1_xx:		; compass 2 and 3 continue here... 
-	rcall	I2C_TX
+
+I2C_RX_accelerometer_common:			; common part for compass 1,2 and 3
+	rcall	I2C_TX						; send byte
 
 	; Non-flipped screen:
 	; Chip orientation on the PCB requires
@@ -193,9 +212,9 @@
 	; z = -z
 
 	; Dump the accelerator data
-	rcall	I2C_OneByteRX
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; accel_DX+0
-	rcall	I2C_OneByteRX
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,hi					; accel_DX+1
 	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
 	btfss	compass_type2				; compass 2?
@@ -204,85 +223,91 @@
 	btfss	flip_screen					; 180° rotation?
 	bra		I2C_RX_accelerometer2_c1	; NO  - continue with normal compass1 routines for Y and Z
 	; flipped compass 2, negate x
-	comf	hi							; 16 bit sign change
-	negf	lo
-	btfsc	STATUS,C					; carry to propagate?
-	incf	hi,F						; YES - do it
-	bra		I2C_RX_accelerometer2_c1	; continue with normal compass1 routines for Y and Z
+	comf	hi							; YES - 16 bit sign change
+	negf	lo							;     - ...
+	btfsc	STATUS,C					;     - carry to propagate?
+	incf	hi,F						;       YES - do it
+	bra		I2C_RX_accelerometer2_c1	;     - continue with normal compass1 routines for Y and Z
 
 I2C_RX_accelerometer1_c1:
 	btfsc	flip_screen					; 180° rotation?
 	bra		I2C_RX_accelerometer2_c1	; YES
 	; non-flipped compass 1, negate x
-	comf	hi							; 16 bit sign change
-	negf	lo
-	btfsc	STATUS,C					; carry to propagate?
-	incf	hi,F						; YES - do it
+	comf	hi							; NO  - 16 bit sign change
+	negf	lo							;     - ...
+	btfsc	STATUS,C					;     - carry to propagate?
+	incf	hi,F						;       YES - do it
 I2C_RX_accelerometer2_c1:
 	; flipped compass 1, non-flipped compass 2
 	MOVII	mpr,accel_DX				; copy result
-	rcall	I2C_OneByteRX
-	movff	SSP1BUF,lo					; accel_DY+0
-	rcall	I2C_OneByteRX
-	movff	SSP1BUF,hi					; accel_DY+1
-
-	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
+	movff	SSP1BUF,lo					; copy accel_DY+0 to lo
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
+	movff	SSP1BUF,hi					; copy accel_DY+1 to hi
+	rcall	I2C_TwoBytesRX_div16_2		; divide hi:lo/16 (signed) only
 	btfsc	flip_screen					; 180° rotation?
 	bra		I2C_RX_accelerometer3_c1	; YES
-	comf	hi							; 16 bit sign change
-	negf	lo
-	btfsc	STATUS,C					; carry to propagate?
-	incf	hi,F						; YES - do it
+	comf	hi							; NO  - 16 bit sign change
+	negf	lo							;     - ...
+	btfsc	STATUS,C					;     - carry to propagate?
+	incf	hi,F						;       YES - do it
 I2C_RX_accelerometer3_c1:
 	MOVII	mpr,accel_DY				; copy result
-	rcall	I2C_OneByteRX
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; accel_DZ+0
-	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP
-; According to data sheet there should be no master Acknowledge for the last byte (accel_DZ+1)...
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	; according to data sheet there should be no master Acknowledge for the last byte (accel_DZ+1)...
 	movff	SSP1BUF,hi					; accel_DZ+1
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	rcall	I2C_TwoBytesRX_div16_2		; divide lo:hi/16 (signed) only
 	comf	hi							; 16 bit sign change for Z
-	negf	lo
+	negf	lo							; ...
 	btfsc	STATUS,C					; carry to propagate?
 	incf	hi,F						; YES - do it
 	MOVII	mpr,accel_DZ				; copy result
-	return
+	return								; done
+
 
 I2C_RX_accelerometer_compass2:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x32						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'10101000'					; 0x28 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x33						; address
-	bra		I2C_RX_accelerometer_compass1_xx
+	bra		I2C_RX_accelerometer_common	; continue with common part
 
 I2C_RX_accelerometer_compass3:
-	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP
+	bsf		SSP1CON2,SEN				; start condition
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3A						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x28						; 0x28 (OUT_X_L_A)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3B						; address
-	bra		I2C_RX_accelerometer_compass1_xx
-
-I2C_OneByteRX:
-	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP
-	bsf		SSP1CON2,ACKEN				; master acknowledge
-	bra		WaitMSSP					; ... and return
+	bra		I2C_RX_accelerometer_common	; continue with common part
 
 
 ;-----------------------------------------------------------------------------
+; Helper Function - receive 1 Byte with Acknowledge
+;
+I2C_OneByteRX:
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	bsf		SSP1CON2,ACKEN				; send master acknowledge
+	bra		WaitMSSP					; wait for TX to complete and return
+
+
+;-----------------------------------------------------------------------------
+; Read Compass
+;
  IFDEF _compass
 
 	global	I2C_RX_compass
@@ -297,19 +322,17 @@
 
 I2C_RX_compass0:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x03
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
+	movlw	0x03						; ??
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
-
-	bcf		PIR1,SSP1IF
+	rcall	WaitMSSP					; wait for TX to complete
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3D						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 
 	; Compass IC sends data in following order:
 	; x MSB
@@ -333,9 +356,9 @@
 	; z = z
 	; y = -x
 
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,compass_DY+1		; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,compass_DY+0		; data byte
 	btfsc	flip_screen					; 180° rotation?
 	bra		I2C_RX_compass0_2			; NO
@@ -346,17 +369,17 @@
 	incf	compass_DY+1,F				;       YES - do it
 	banksel	common
 I2C_RX_compass0_2:
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,compass_DZ+1		; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,compass_DZ+0		; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,compass_DX+1		; data byte
 	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movff	SSP1BUF,compass_DX+0		; data byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	btfss	flip_screen					; 180° rotation?
 	return								; NO  - done
 	banksel	compass_DX					; YES - flip X
@@ -364,27 +387,28 @@
 	negf	compass_DX+0
 	btfsc	STATUS,C					;     - carry to propagate?
 	incf	compass_DX+1,F				;       YES - do it
-	banksel	common
-	return
+	banksel	common						; back to bank common
+	return								; done
+
 
 I2C_RX_compass1:						; compass type 1
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'10001000'					; 0x08 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3D						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	;rcall	WaitMSSP					; TODO needed? (mH)
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,hi					; data byte
-	rcall	I2C_TwoBytesRX_div8_2
-	MOVII	mpr,compass_DX
+	rcall	I2C_TwoBytesRX_div8			; divide hi,lo by 8 (signed)
+	MOVII	mpr,compass_DX				; copy result
 	btfss	flip_screen					; 180° rotation?
 	bra		I2C_RX_compass1_1			; NO
 	banksel	compass_DX					; YES - flip X
@@ -394,240 +418,243 @@
 	incf	compass_DX+1,F				;       YES - do it
 	banksel	common
 I2C_RX_compass1_1:
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,hi					; data byte
-	rcall	I2C_TwoBytesRX_div8_2
+	rcall	I2C_TwoBytesRX_div8			; divide hi, lo by 8 (signed)
 	MOVII	mpr,compass_DY
 	btfss	flip_screen					; 180° rotation?
 	bra		I2C_RX_compass1_2			; NO
 	banksel	compass_DY					; YES - flip Y
 	comf	compass_DY+1				;     - 16 bit sign change
-	negf	compass_DY+0
+	negf	compass_DY+0				;     - ...
 	btfsc	STATUS,C					;     - carry to propagate?
 	incf	compass_DY+1,F				;       YES - do it
 	banksel	common
 I2C_RX_compass1_2:
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
 	bsf		SSP1CON2, RCEN				; Enable receive mode
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movff	SSP1BUF,hi					; data byte
-	rcall	I2C_TwoBytesRX_div8_2
-	MOVII	mpr,compass_DZ
+	rcall	I2C_TwoBytesRX_div8			; divide hi, lo by 8 (signed)
+	MOVII	mpr,compass_DZ				; copy result
 	bsf		SSP1CON2,PEN				; stop condition
 	bra		WaitMSSP					; ... and return
 
+
 I2C_RX_compass2:						; compass type 2
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0xE8						; 0x68 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3D						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 I2C_RX_compass2_xx:						; compass 3 joins in here
-;	rcall	WaitMSSP
-	rcall	I2C_OneByteRX				; get one byte
+;	rcall	WaitMSSP					; wait for TX to complete (not needed, as included in I2C_TX)
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,hi					; data byte
-;	rcall	I2C_TwoBytesRX_div8_2
+;	rcall	I2C_TwoBytesRX_div8			; divide hi, lo by 8 (signed)
 	btfsc	flip_screen					; 180° rotation?
 	bra		I2C_RX_compass2_1			; YES - do nothing with X
 										; NO  - flip X
 	comf	hi							;     - 16 bit sign change
-	negf	lo
+	negf	lo							;     - ...
 	btfsc	STATUS,C					;     - carry to propagate?
 	incf	hi,F						;       YES - do it
 I2C_RX_compass2_1:
 	MOVII	mpr,compass_DX
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,hi					; data byte
-;	rcall	I2C_TwoBytesRX_div8_2
+;	rcall	I2C_TwoBytesRX_div8			; divide hi, lo by 8 (signed)
 	btfss	flip_screen					; 180° rotation?
 	bra		I2C_RX_compass2_2			; NO  - do nothing with Y
 										; YES - flip Y
 	comf	hi							;     - 16 bit sign change
-	negf	lo
+	negf	lo							;     - ...
 	btfsc	STATUS,C					;     - carry to propagate?
 	incf	hi,F						;       YES - do it
 I2C_RX_compass2_2:
 	MOVII	mpr,compass_DY
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,lo					; data byte
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movff	SSP1BUF,hi					; data byte
-;	rcall	I2C_TwoBytesRX_div8_2
-	MOVII	mpr,compass_DZ
+;	rcall	I2C_TwoBytesRX_div8			; divide hi, lo by 8 (signed)
+	MOVII	mpr,compass_DZ				; copy result
 	bsf		SSP1CON2,PEN				; stop condition
 	bra		WaitMSSP					; ...and return
 
+
 I2C_RX_compass3:						; compass type 3
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0xA8						; 0x28 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,RSEN				; repeated start condition (!)
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3D						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bra		I2C_RX_compass2_xx			; join with compass 2 code
 
  ENDIF	; _compass
 
+
 ;-----------------------------------------------------------------------------
-
+; Initialize Compass / Accelerometer Chip
+;
 	global	I2C_init_compass
 I2C_init_compass:
-	bsf		compass_enabled
-	bcf		compass_type2
-	bcf		compass_type3
+	bsf		compass_enabled				; flag compass will be enabled
+	bcf		compass_type2				; clear in preparation of chip detection
+	bcf		compass_type3				; ...
 
 	; probe for compass 3
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3A						; address byte + write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	btfss	SSP1CON2,ACKSTAT			; ACK?
-	bsf		compass_type3				; YES - ACK was send, compass 3 present
+	rcall	WaitMSSP					; wait for TX to complete
+	btfss	SSP1CON2,ACKSTAT			; ACK received?
+	bsf		compass_type3				; YES - ACK was send, compass 3 found
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	btfsc	compass_type3				; compass 3 found?
 	bra		I2C_init_compass3			; YES - initialize compass 3
 
 	; probe for compass 2
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x32						; address byte + write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	btfss	SSP1CON2,ACKSTAT			; ACK?
-	bsf		compass_type2				; YES - ACK send, compass 2 present
+	rcall	WaitMSSP					; wait for TX to complete
+	btfss	SSP1CON2,ACKSTAT			; ACK received?
+	bsf		compass_type2				; YES - ACK send, compass 2 found
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	btfsc	compass_type2				; compass 2 found?
 	bra		I2C_init_compass2			; YES - initialize compass 2
 
 	; probe for compass 0 or 1
-	bsf		compass_type1				; set flag
+	bsf		compass_type1				; assume compass 1 by default
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x0F
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
+	movlw	0x0F						; ??
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
-	bcf		PIR1,SSP1IF
+	rcall	WaitMSSP					; wait for TX to complete
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3D						; address
-	rcall	I2C_TX
-	rcall	I2C_OneByteRX				; get one byte
+	rcall	I2C_TX						; send byte
+	rcall	I2C_OneByteRX				; receive 1 byte with acknowledge
 	movlw	0x49						; 0x49 = compass 1
-	cpfseq	SSP1BUF
-	bcf		compass_type1				; clear flag
+	cpfseq	SSP1BUF						; 0x49 received?
+	bcf		compass_type1				; NO - clear flag for compass 1
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	btfsc	compass_type1				; compass 1 found?
 	bra		I2C_init_compass1			; YES - initialize compass 1
 	;bra	I2C_init_compass0			; NO  - must be compass 0 then
 
+
 I2C_init_compass0:
 	; magnetic
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x00
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
+	movlw	0x00						; ??
+	rcall	I2C_TX						; send byte
 	movlw	b'01101000'					; ConfigA: 3 Hz, 8 samples averaged
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movff	opt_compass_gain,i2c_temp1	; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss)
-	swapf	i2c_temp1,F
-	comf	i2c_temp1,F
-	bcf		STATUS,C
-	rlcf	i2c_temp1
-	movf	i2c_temp1,W
-	clrf	i2c_temp1
-	rcall	I2C_TX
-	movlw	b'00000000'					; continuous mode
-	rcall	I2C_TX
+	swapf	i2c_temp1,F					;
+	comf	i2c_temp1,F					;
+	bcf		STATUS,C					;
+	rlcf	i2c_temp1					;
+	movf	i2c_temp1,W					;
+	rcall	I2C_TX						; send byte
+	movlw	b'00000000'					; select continuous mode
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall		WaitMSSP
-	
+	rcall	WaitMSSP					; wait for TX to complete
+
 	; accelerometer
 	rcall	I2C_sleep_accelerometer0	; registers can only be changed in standby mode
 
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x38						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x0E						; XYZ_DATA_CFG
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; high pass filter = 0, +/- 2 g range
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x38						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x2A						; CTRL_REG1
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 ;	movlw	b'00110000'					; CTRL_REG1: 160 ms data rate, standby mode
 	movlw	b'00110100'					; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000010'					; CTRL_REG2: high-res in active mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x38						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x2A						; CTRL_REG1
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 ;	movlw	b'00110001'					; CTRL_REG1: 160 ms data rate, active  mode
 	movlw	b'00110101'					; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
 
 
 I2C_init_compass1:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x9F						; 1F with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL0
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00101111'					; CTRL1 (6.25 Hz, BDU=0, x,y,z = ON)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'11000000'					; CTRL2 (50 Hz, +/- 2g)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL3
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL4
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'01100100'					; CTRL5 HIGH res, 6.25 Hz
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movff	opt_compass_gain,i2c_temp1	; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss)
 	movlw	b'01100000'					; CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss)
 	dcfsnz	i2c_temp1,F					; = 1?
@@ -644,98 +671,104 @@
 	movlw	b'00000000'					; YES - CTRL6 (+/-2 Gauss)
 	dcfsnz	i2c_temp1,F					; = 7?
 	movlw	b'00000000'					; YES - CTRL6 (+/-2 Gauss)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL7 Continuous Mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	bra	WaitMSSP					; (and return), no I2C_init_accelerometer1 needed (inits with magnetic sensor)
+	bra		WaitMSSP					; wait for TX to complete and return
+
+	; accelerometer initializes along with magnetic sensor
+
 
 I2C_init_compass2:
 	; magnetic
-	bsf		SSP1CON2,SEN	; Start condition
-	rcall	WaitMSSP
-	movlw	0x3C            ; address
-	rcall       I2C_TX
-	movlw	0xE0		; 0x60 with auto-increment (MSB=1)
-	rcall       I2C_TX
-	movlw	b'10000000'	; CFG_REG_A_M (10Hz, Continuous) 0x60 0x00
-	rcall       I2C_TX
-	movlw	b'00000011'	; CFG_REG_B_M (low-pass filter enabled) 0x61 (set pulse is released every 63 ODR)
-	rcall	I2C_TX
-	movlw	b'00010000'	; CFG_REG_C_M BDU=1 0x62 0x57
-	rcall	I2C_TX
-	bsf	SSP1CON2,PEN	; Stop condition
-	rcall	WaitMSSP
-	
+	bsf		SSP1CON2,SEN				; start condition
+	rcall	WaitMSSP					; wait for TX to complete
+	movlw	0x3C						; address
+	rcall	I2C_TX						; send byte
+	movlw	0xE0						; 0x60 with auto-increment (MSB=1)
+	rcall	I2C_TX						; send byte
+	movlw	b'10000000'					; CFG_REG_A_M (10Hz, Continuous) 0x60 0x00
+	rcall	I2C_TX						; send byte
+	movlw	b'00000011'					; CFG_REG_B_M (low-pass filter enabled) 0x61 (set pulse is released every 63 ODR)
+	rcall	I2C_TX						; send byte
+	movlw	b'00010000'					; CFG_REG_C_M BDU=1 0x62 0x57
+	rcall	I2C_TX						; send byte
+	bsf		SSP1CON2,PEN				; stop condition
+	rcall	WaitMSSP					; wait for TX to complete
+
 	; accelerometer
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x32						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x9F						; 1F with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; TEMP_CFG_REG_A (Temp sensor off)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00100111'					; CTRL_REG1_A (10Hz, x,y,z = ON)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG2_A
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG3_A
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00001000'					; CTRL_REG4_A (BDU=0, +/-2g, HR=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 ;	movlw	b'00000000'					; CTRL_REG5_A
-;	rcall	I2C_TX
+;	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
 
 
 I2C_init_compass3:
 	; magnetic
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0xA0						; 0x20 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'01110000'					; CTRL_REG1_M (10Hz) 0x20
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'01100000'					; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'01000000'					; CTRL_REG3_M (Continuous) 0x22
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG4_M (Z in Low-power mode) 0x23
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG5_M 0x24
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG5_M 0x24
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; Stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	;accelerometer
 	bsf	SSP1CON2,SEN					; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3A						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x20
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'10010111'					; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG2_A 0x21
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG3_A 0x22
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'11001100'					; CTRL_REG4_A 0x23
-	rcall	I2C_TX
-	bsf	SSP1CON2,PEN					; stop condition
-	bra	WaitMSSP						; (and return)
+	rcall	I2C_TX						; send byte
+	bsf		SSP1CON2,PEN				; stop condition
+	bra		WaitMSSP					; wait for TX to complete and return
 
 
+;-----------------------------------------------------------------------------
+; Deactivate Compass / Accelerometer
+;
 	global	I2C_sleep_compass
 I2C_sleep_compass:
 	btfss	compass_enabled				; compass active?
-	return								; NO - return
+	return								; NO - done
 	bcf		compass_enabled
 	btfsc	compass_type3				; compass 3 ?
 	bra		I2C_sleep_compass3			; YES
@@ -745,237 +778,270 @@
 	bra		I2C_sleep_compass1			; YES
 	;bra	I2C_sleep_compass0			; NO  - must be compass 0 then
 
+
 I2C_sleep_compass0:
 	; magnetic
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
-	movlw	0x00
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
+	movlw	0x00						; ??
+	rcall	I2C_TX						; send byte
 	movlw	b'01101000'					; ConfigA
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00100000'					; ConfigB
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000010'					; idle mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
-I2C_sleep_accelerometer0:   ;(needed)
+I2C_sleep_accelerometer0:
 	; accelerometer
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x38						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x2A						; CTRL_REG1
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; standby mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
+
 
 I2C_sleep_compass1:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x20						; CTRL_REG1
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; data for CTRL_REG1: acceleration sensor power-down mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x26						; CTRL_REG7
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000010'					; data for CTRL_REG7: magnetic sensor power-down mode
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; (And return) - no I2C_sleep_accelerometer1 required (sleeps with magnetic sensor)
+	bra		WaitMSSP					; wait for TX to complete and return
+
+	; accelerometer sleeps with magnetic sensor
 
 
 I2C_sleep_compass2:
 	; magnetic
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0xE0						; 0x60 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000011'					; CFG_REG_A_M    0x60 (idle mode))
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000100'					; CFG_REG_B_M    0x61 (set pulse is released only at power-on after PD condition)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'01010001'					; CFG_REG_C_M    0x62
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; INT_CTRL_REG_M 0x63
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	; accelerometer
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x32						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x9F						; 1F with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; TEMP_CFG_REG_A  0x1F (temp sensor off)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG1_A     0x20 (all off)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
+
 
 I2C_sleep_compass3:
 	; magnetic
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3C						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0xA2						; 0x22 with auto-increment (MSB=1)
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'01000010'					; CTRL_REG3_M (power-down) 0x22
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	; accelerometer
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x3A						; address
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	0x20
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	movlw	b'00000000'					; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20
-	rcall	I2C_TX
+	rcall	I2C_TX						; send byte
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
+
 
+;-----------------------------------------------------------------------------
+; Helper Function - wait for TX to complete
+;
 WaitMSSP:
-	decfsz	i2c_temp1,F					; check for timeout during I2C action
-	bra		WaitMSSP2
-	bra		I2CFail						; timeout occurred
+	clrf	i2c_temp1					; wait for max 256 loops
+WaitMSSP_loop:
+	decfsz	i2c_temp1,F					; decrement loop counter, timeout?
+	bra		WaitMSSP2					; NO
+	bra		I2CFail						; YES
 WaitMSSP2:
-	btfss	PIR1,SSP1IF
-	bra		WaitMSSP
-	clrf	i2c_temp1
-	bcf		PIR1,SSP1IF
-	return
+	btfss	PIR1,SSP1IF					; TX completed?
+	bra		WaitMSSP_loop				; NO  - loop
+	bcf		PIR1,SSP1IF					; YES - clear TX completion flag
+	return								;     - done
+
 
-I2C_WaitforACK:
+;-----------------------------------------------------------------------------
+; Helper Function - check for Acknowledge by Receiver
+;
+I2C_Check_ACK:
 	btfss	SSP1CON2,ACKSTAT			; ACK received from slave?
-	return								; YES
-I2CFail:								; NO
-	bsf		active_reset_ostc_rx		;    - reset RX circuitry (which may be the cause for the hang up)
-	rcall	I2CReset					;    - reset I2C
-	bcf		PIR1,SSP1IF					;    - 
-	clrf	i2c_temp1					;    - 
-	bsf		i2c_error_flag				;    - set error flag
-	bcf		active_reset_ostc_rx		;    - release reset from RX circuitry
-	return								;    - done
+	return								; YES - done
+	;bra	I2CFail						; NO  - do some clean up
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - clean up I2C Interface after missing Acknowledge
+;
+I2CFail:
+	bsf		active_reset_ostc_rx		; reset RX circuitry (which may be the cause for the hang up)
+	rcall	I2CReset					; reset I2C
+	bcf		PIR1,SSP1IF					; clear TX completion flag
+	bsf		i2c_error_flag				; set error flag
+	bcf		active_reset_ostc_rx		; release reset from RX circuitry
+	return								; done
 
-I2CReset:								; something went wrong (slave holds SDA low?)
-	clrf	SSP1CON1					; wake-up slave and reset entire module
-	clrf	SSP1CON2
-	clrf	SSP1STAT
-	bcf		TRISC,3						; SCL OUTPUT
-	bsf		TRISC,4						; SDA input
-	bcf		PORTC,3
-	movlw	d'9'
-	movwf	i2c_temp1					; clock-out 9 clock cycles manually
+
+;-----------------------------------------------------------------------------
+; Helper Function - Reset I2C Module
+;
+; recover in case something went wrong, i.g. slave holds SDA low
+;
+I2CReset:
+	clrf	SSP1CON1					; reset entire module
+	clrf	SSP1CON2					; ...
+	clrf	SSP1STAT					; ...
+	bcf		TRISC,3						; SCL as OUTPUT
+	bsf		TRISC,4						; SDA as input
+	bcf		PORTC,3						; SCL = 0
+	movlw	d'9'						; clock-out 9 clock cycles manually
+	movwf	i2c_temp1					; ...
 I2CReset_1:
 	bsf		PORTC,3						; SCL = 1
-	nop
-	nop
-	nop
-	nop
+	nop									; pause for 4 CPU cycles
+	nop									; ...
+	nop									; ...
+	nop									; ...
 	btfsc	PORTC,4						; SDA = 1 ?
-	bra		I2CReset_2					; YES - =1, SDA has been released from slave
+	bra		I2CReset_2					; YES - SDA has been released from slave
 	bcf		PORTC,3						; NO  - set SCL = 0
-	nop
-	nop
-	bcf		PORTC,3
-	nop
-	nop
-	decfsz	i2c_temp1,F
-	bra		I2CReset_1					; check for nine clock cycles
+	nop									;     - pause for 2 CPU cycles
+	nop									;     - ...
+	bcf		PORTC,3						;     - SCL = 0
+	nop									;     - pause for 2 CPU cycles
+	nop									;     - ...
+	decfsz	i2c_temp1,F					;     - clock counter, all cycles done?
+	bra		I2CReset_1					;       NO - loop
 I2CReset_2:
-	bsf		TRISC,3						; SCL Input
-	clrf	SSP1CON1					; setup I²C mode
-	WAITMS	d'10'						; reset-timeout for I2C devices
-	movlw	b'00000000'					; with slew rate control
-	movwf	SSP1STAT
-	movlw	b'00101000'
-	movwf	SSP1CON1
-	movlw	b'00000000'
-	movwf	SSP1CON2
-	movlw	0x9C
-	movwf	SSP1ADD
-	return
+	bsf		TRISC,3						; SCL as input
+	clrf	SSP1CON1					; setup I2C mode
+	WAITMS	d'10'						; wait 10 ms (reset-timeout for I2C devices)
+	movlw	b'00000000'					; enable slew rate control
+	movwf	SSP1STAT					; ...
+	movlw	b'00101000'					; configure I2C module
+	movwf	SSP1CON1					; ...
+	movlw	b'00000000'					; ...
+	movwf	SSP1CON2					; ...
+	movlw	0x9C						; ...
+	movwf	SSP1ADD						; ...
+	return								; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Initialize Gauge IC again after an UVLO Event
+;
 lt2942_init_again:
-	clrf	i2c_temp1
 	movlw	0x02									; point to accumulated charge registers
-	rcall	I2C_TX_GAUGE
+	rcall	I2C_TX_GAUGE							; send byte to the LT2942 gauge IC
 	movff	battery_accumulated_charge+1,SSP1BUF	; data byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP								; wait for TX to complete
+	rcall	I2C_Check_ACK							; check for acknowledge by receiver
 	movff	battery_accumulated_charge+0,SSP1BUF	; data byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP								; wait for TX to complete
+	rcall	I2C_Check_ACK							; check for acknowledge by receiver
 	bsf		SSP1CON2,PEN							; stop condition
-	rcall	WaitMSSP
-	MOVII	battery_accumulated_charge,sub_a
-	; and init again...
+	rcall	WaitMSSP								; wait for TX to complete
+	MOVII	battery_accumulated_charge,sub_a		; copy result to sub_a
+	;bra	lt2942_init								; and initialize again...
 
 
+;-----------------------------------------------------------------------------
+; Initialize Gauge IC
+;
 	global	lt2942_init
-lt2942_init:							; setup control register B
-	clrf	i2c_temp1
+lt2942_init:
 	movlw	0x01						; point to control reg B
-	rcall	I2C_TX_GAUGE
+	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
 	movlw	b'11111000'					; automatic conversion every two seconds
-	movff	WREG, SSP1BUF				; data byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	movff	WREG,SSP1BUF				; data byte										TODO: movwf ??
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
 
 
+;-----------------------------------------------------------------------------
+; Read Gauge IC - Status Register
+;
 	global	lt2942_get_status
-lt2942_get_status:						; read status register
+lt2942_get_status:
 	bcf		battery_gauge_available		; clear flag
-	clrf	i2c_temp1
 	movlw	0x00						; point to status register
-	rcall	I2C_TX_GAUGE
-	rcall	I2C_RX_GAUGE
-	movff	SSP1BUF,WREG
+	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
+	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
+	movff	SSP1BUF,WREG				; copy received byte to WREG
 	btfss	WREG,7						; 2942 found?
 	bsf		battery_gauge_available		; YES - set flag
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
 
 
+;-----------------------------------------------------------------------------
+; Read Gauge IC - Voltage
+;
 	global	lt2942_get_voltage
-lt2942_get_voltage:						; read battery voltage registers
-	clrf	i2c_temp1
+lt2942_get_voltage:
 	movlw	0x08						; point to voltage registers
-	rcall	I2C_TX_GAUGE
-	rcall	I2C_RX_GAUGE
+	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
+	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
 	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP
-	movff	SSP1BUF,xA+1
-	bsf		SSP1CON2, RCEN				; enable receive mode
-	rcall	WaitMSSP
-	movff	SSP1BUF,xA+0
+	rcall	WaitMSSP					; wait for TX to complete
+	movff	SSP1BUF,xA+1				; copy received byte to xA+1
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	movff	SSP1BUF,xA+0				; copy received byte to xA+0
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	; convert voltage from raw value to Volt
 	MOVLI	.6000,xB					; load conversion multiplicand into xB
@@ -986,23 +1052,25 @@
 
 	tstfsz	batt_voltage+1				; < 256 mV ?
 	return								; NO  - done
-	bra		lt2942_init					; YES - ... and return
+	bra		lt2942_init					; YES - initialize gauge and return
 
 
+;-----------------------------------------------------------------------------
+; Read Gauge IC - Temperature
+;
 	global	lt2942_get_temperature
 lt2942_get_temperature:					; read battery temperature
-	clrf	i2c_temp1
 	movlw	0x0C						; point to temperature register
-	call	I2C_TX_GAUGE
-	call	I2C_RX_GAUGE
+	call	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
+	call	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
 	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movff	SSP1BUF,xA+1				; store raw temperature, high byte
 	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movff	SSP1BUF,xA+0				; store raw temperature, low byte
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	; convert temperature from raw value to Kelvin
 	MOVLI	.6000,xB					; load conversion multiplicand into xB
@@ -1011,7 +1079,7 @@
 	movff	xC+2,battery_temperature+0	; divide by 65536 can easily be done by just taking the 3rd and 4th byte of the multiplication result
 	movff	xC+3,battery_temperature+1	; ...
 
-	; check if battery is charged right now
+	; check if battery is being charged right now
 	btfss	cc_active					; in CC charging mode?
 	return								; NO  - not charging, done
 
@@ -1025,262 +1093,291 @@
 	bsf		charge_disable				;     - set      charging-inhibit signal
 	bcf		charge_enable				;     - activate charging-inhibit signal
 	bsf		battery_overtemp			;     - flag that the battery charging over-temperature protection has tripped
-	return
+	return								;     - done
 
 
+;-----------------------------------------------------------------------------
+; Read Gauge IC - Read State of Charge
+;
 	global	lt2942_get_accumulated_charge
 lt2942_get_accumulated_charge:			; read accumulated charge and compute percent
-	clrf	i2c_temp1
 	movlw	0x00						; point to status register
-	rcall	I2C_TX_GAUGE
-	rcall	I2C_RX_GAUGE
+	rcall	I2C_TX_GAUGE				; send    byte to   the LT2942 gauge IC
+	rcall	I2C_RX_GAUGE				; receive byte from the LT2942 Gauge IC
 	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP
-	movff	SSP1BUF,gauge_status_byte
+	rcall	WaitMSSP					; wait for TX to complete
+	movff	SSP1BUF,gauge_status_byte	; copy received byte to gauge_status_byte
 
-	bsf		SSP1CON2, RCEN				; enable receive mode
-	rcall	WaitMSSP					; dummy read (control byte)
-	movf	SSP1BUF,W
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete					; dummy read (control byte)
+	movf	SSP1BUF,W					; dump to WREG
 	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
-	bsf		SSP1CON2, RCEN				; enable receive mode
-	rcall	WaitMSSP
-	movff	SSP1BUF,sub_a+1
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	movff	SSP1BUF,sub_a+1				; copy received byte to sub_a+1
 	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
-	bsf		SSP1CON2, RCEN				; enable receive mode
-	rcall	WaitMSSP
-	movff	SSP1BUF,sub_a+0
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	movff	SSP1BUF,sub_a+0				; copy received byte to sub_a+0
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	btfsc	gauge_status_byte,0			; UVLO event ?
-	rcall	lt2942_init_again			; YES
+	rcall	lt2942_init_again			; YES - do an re-initialization
 
 	MOVII	sub_a,battery_accumulated_charge	; save raw value
 
-	; Compute batt_percent
-	; (charge-battery_offset)/365
-	MOVII	battery_offset,sub_b
+	; Compute batt_percent = (charge - battery_offset) / 365
+	MOVII	battery_offset,sub_b		; get battery offset
 	call	subU16						; sub_c = sub_a - sub_b (with signed values)
-	clrf	batt_percent				; set to zero
+	clrf	batt_percent				; default batt_percent to zero
 	btfsc	neg_flag					; result negative?
 	bra		lt2942_set_to_zero_percent	; YES - keep LT2942 at zero percent and return
 
 	; > zero, set batt_percent properly
-	MOVII	sub_c,xA
-	MOVII	battery_capacity,xB
+	MOVII	sub_c,xA					; copy net charge to xA
+	MOVII	battery_capacity,xB			; get battery capacity into xB
 	call	div16x16					; xC = xA / xB with xA as remainder
-	movff	xC+0,batt_percent
+	movff	xC+0,batt_percent			; result is battery percentage
 	movlw	.100						; max. value is  100 %
 	cpfslt	batt_percent				; batt_percent < 100 % ?
 	movwf	batt_percent				; NO  - limit to 100 %
 	return								; done
 
 lt2942_set_to_zero_percent:
-	clrf	i2c_temp1
 	movlw	0x02						; point to accumulated charge registers
-	rcall	I2C_TX_GAUGE
-	movff	battery_offset+1,SSP1BUF
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
-	movff	battery_offset+0,SSP1BUF
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
+	movff	battery_offset+1,SSP1BUF	; send battery offset, high byte
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movff	battery_offset+0,SSP1BUF	; send battery offset, low  byte
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
 
 
+;-----------------------------------------------------------------------------
+; Read Gauge IC - Reset Accumulating Register to 0xFFFF
+;
 	global	lt2942_charge_done
-lt2942_charge_done:						; reset accumulating registers to 0xFFFF
-	clrf	i2c_temp1
+lt2942_charge_done:
 	movlw	0x02						; point to accumulated charge registers
-	rcall	I2C_TX_GAUGE
+	rcall	I2C_TX_GAUGE				; send byte to the LT2942 gauge IC
 	setf	SSP1BUF						; data byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	setf	SSP1BUF						; data byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
+
 
-I2C_TX_GAUGE:							; send a byte to the LT2942 gauge IC
-	movwf	i2c_temp2					; data byte
+;-----------------------------------------------------------------------------
+; Helper Function - send 1 Byte to the LT2942 Gauge IC
+;
+I2C_TX_GAUGE:
+	movwf	i2c_temp2					; save data byte to be sent
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	b'11001000'					; address byte + Write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
-	movf	i2c_temp2,W
-	bra		I2C_TX						; ... and return
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movf	i2c_temp2,W					; restore data byte to be sent
+	bra		I2C_TX						; send byte and return
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - receive 1 Byte from the LT2942 Gauge IC
+;
 I2C_RX_GAUGE:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	b'11001001'					; address byte + Read bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	bsf		SSP1CON2,RCEN				; enable receive mode
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for reception and return
+
+
+;-----------------------------------------------------------------------------
+; Reset Hardware and Software Battery Gauge
+;
+; called from comm.asm and menu_tree.asm
+;
+	global	reset_battery_gauge_and_lt2942
+reset_battery_gauge_and_lt2942:
+	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_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
-
+;-----------------------------------------------------------------------------
+; Reset Software Battery Gauge
+;
 	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
+reset_battery_gauge:
+	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
-;
+
  IFDEF _rx_functions
 
+;-----------------------------------------------------------------------------
+; OSTC TR - probe if TR Module available
+;
 	global	I2C_probe_OSTC_rx
 I2C_probe_OSTC_rx:
-	bcf		ostc_rx_present				; no TR module by default
+	bcf		ostc_rx_present				; default to no TR module available
 	clrf	WREG						; bank-safe set to zero of ...
 	movff	WREG,rx_firmware_cur_major	; ... current TR module firmware, major
 	movff	WREG,rx_firmware_cur_minor	; ... current TR module firmware, minor
 	movlw	.5							; max number of tries for detecting a TR module
-	movwf	hy							; initialize counter for tries
+	movwf	hy							; initialize loop counter for tries
 I2C_probe_OSTC_rx_1:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x50						; address byte + write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	btfss	SSP1CON2,ACKSTAT			; ACK received?
 	bsf		ostc_rx_present				; YES - TR module detected
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	btfss	ostc_rx_present				; was a TR module detected?
 	return								; NO  - done
-	WAITMS	.1
+
+	WAITMS	.1							; wait 1 ms
+
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x50						; address byte + write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
-	movlw	0x1B
-	movwf	SSP1BUF						; data byte (get firmware)
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
+	movlw	0x1B						; command: get firmware
+	movwf	SSP1BUF						; send command
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
-	WAITMS	.1
+	rcall	WaitMSSP					; wait for TX to complete
+
+	WAITMS	.1							; wait 1 ms
+
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x51						; address byte + Read bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movff	SSP1BUF,rx_firmware_cur_major ; store as firmware version, major
 	bsf		SSP1CON2,ACKEN				  ; master acknowledge
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	; last byte in read from RX circuity always with a NACK!
 	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movff	SSP1BUF,rx_firmware_cur_minor ; store as firmware version, minor
-	bsf		SSP1CON2,ACKDT
+	bsf		SSP1CON2,ACKDT				; set ACKDT flag
 	bsf		SSP1CON2,ACKEN				; master NOT acknowledge
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 
 	; wait for TR module becoming ready
-	movff	rx_firmware_cur_minor,i2c_temp1	; copy firmware version to bank common, minor
+	movff	rx_firmware_cur_minor,i2c_temp1	; copy minor firmware version to bank common
 	movlw	.147							; code for not ready, minor
 	cpfseq	i2c_temp1						; equal?
-	bra		I2C_probe_OSTC_rx_2				; NO  - TR module ready
-	movff	rx_firmware_cur_major,i2c_temp1 ; YES - copy firmware version to bank common, major
+	return									; NO  - TR module ready, done
+	movff	rx_firmware_cur_major,i2c_temp1 ; YES - copy major firmware version to bank common
 	movlw	.27								;     - code for not ready, major
 	cpfseq	i2c_temp1						;     - equal?
-	bra		I2C_probe_OSTC_rx_2				;       NO  - TR module ready
+	return									;       NO  - TR module ready, done
 	bsf		active_reset_ostc_rx			;       YES - apply reset to TR module
 	WAITMS	.5								;           - wait 5 ms
 	bcf		active_reset_ostc_rx			;           - release reset
 	WAITMS	.250							;           - wait for     250 ms
 	WAITMS	.250							;           - wait another 250 ms
-	clrf	i2c_temp1						;           - clean-up i2c_temp1
 	decfsz	hy,F							;           - decrement counter for number of tries, became zero?
 	bra		I2C_probe_OSTC_rx_1				;           - NO  - try again
 	bcf		ostc_rx_present					;           - YES - something is wrong, flag TR module as not available
-I2C_probe_OSTC_rx_2:
-	clrf	i2c_temp1						; clean-up i2c_temp1
-	return									; done
+	return									;                 - done
 
 
+;-----------------------------------------------------------------------------
+; OSTC TR - get Tank Data
+;
 	global	I2C_get_tankdata
 I2C_get_tankdata:
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x50						; address byte + write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	movlw	0x1E						; read buffer2 (48 bytes)
 	movwf	SSP1BUF						; data byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
-	WAITMS	.1
+	rcall	WaitMSSP					; wait for TX to complete
+
+	WAITMS	.1							; wait 1 ms
+
 	; read 48 bytes
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x51						; address byte + read bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	movlw	.47							; 47 with ACK + 1 w/o ACK
-	movwf	i2c_temp2
-	lfsr	FSR2,rx_buffer
+	movwf	i2c_temp2					; initialize loop counter
+	lfsr	FSR2,rx_buffer				; point to start of rx data buffer 
 I2C_get_tankdata_loop_read:
-	bsf		SSP1CON2, RCEN				; enable receive mode
-	rcall	WaitMSSP
-	movff	SSP1BUF,POSTINC2
-	bcf		SSP1CON2,ACKDT
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	movff	SSP1BUF,POSTINC2			; copy received byte to the rx buffer
+	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
 	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP
-	decfsz	i2c_temp2,F
-	bra		I2C_get_tankdata_loop_read
-	; 1 w/o ACK
-	bsf		SSP1CON2, RCEN				; enable receive mode
-	rcall	WaitMSSP
-	movff	SSP1BUF,POSTINC2
-	bsf		SSP1CON2,ACKDT
+	rcall	WaitMSSP					; wait for TX to complete
+	decfsz	i2c_temp2,F					; decrement loop counter, done?
+	bra		I2C_get_tankdata_loop_read	; NO  - loop
+	; read last byte without ACK
+	bsf		SSP1CON2,RCEN				; enable receive mode
+	rcall	WaitMSSP					; wait for TX to complete
+	movff	SSP1BUF,POSTINC2			; copy received byte to the rx buffer
+	bsf		SSP1CON2,ACKDT				; set ACKDT flag
 	bsf		SSP1CON2,ACKEN				; master NOT acknowledge
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
 	bsf		SSP1CON2,PEN				; stop condition
-	bra		WaitMSSP					; ... and return
+	bra		WaitMSSP					; wait for TX to complete and return
 
 
+;-----------------------------------------------------------------------------
+; OSTC TR - Firmware Update
+;
  IFDEF _rx_update
 
 	global	I2C_update_OSTC_rx
@@ -1292,73 +1389,73 @@
 	movwf	i2c_temp2					; ...
 	; address write
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x50						; address byte + write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	; write 64 bytes
 I2C_update_OSTC_loop:
 	TBLRD*+								; read a byte from program memory
 	movff	TABLAT,POSTINC2				; copy to send buffer
 	movff	TABLAT,SSP1BUF				; copy to I2C data buffer
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	decfsz	i2c_temp2,F					;decrement loop counter, became zero?
 	bra		I2C_update_OSTC_loop		; NO  - loop
 	bsf		SSP1CON2,PEN				; YES - stop condition
-	rcall	WaitMSSP					;     - wait for stop condition done
+	rcall	WaitMSSP					;     - wait for TX to complete
 	WAITMS	.1							;     - wait another 1 ms
 	; setup for read-back
 	lfsr	FSR2,buffer					; reset pointer to begin of send buffer
 	movlw	.63							; initialize loop counter: 63 byte with ACK + 1 w/o ACK
-	movwf	i2c_temp2
+	movwf	i2c_temp2					; ...
 	; address read-back
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x51						; address byte + read bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	; read-back 64 bytes
 I2C_update_OSTC_loop_read:
 	bsf		SSP1CON2,RCEN				; enable receive mode
-	rcall	WaitMSSP
-	movf	SSP1BUF,W
+	rcall	WaitMSSP					; wait for TX to complete
+	movf	SSP1BUF,W					; copy received byte to WREG
 	cpfseq	POSTINC2					; compare read-back byte with sent byte, equal?
 	bsf		i2c_error_flag				; NO  - not equal, set error flag
-	bcf		SSP1CON2,ACKDT
+	bcf		SSP1CON2,ACKDT				; reset ACKDT flag
 	bsf		SSP1CON2,ACKEN				; master acknowledge
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	decfsz	i2c_temp2,F					; decrement loop counter, became zero?
 	bra		I2C_update_OSTC_loop_read	; NO  - loop
 	; 1 w/o ACK
 	bsf		SSP1CON2, RCEN				; YES - enable receive mode
-	rcall	WaitMSSP					;     -
+	rcall	WaitMSSP					;     - wait for TX to complete
 	movf	SSP1BUF,W					;     - get 64th byte
 	cpfseq	POSTINC2					;     - compare read-back byte with sent byte, equal?
 	bsf		i2c_error_flag				;       NO  - not equal, set error flag
-	bsf		SSP1CON2,ACKDT				;     -
+	bsf		SSP1CON2,ACKDT				;     - set ACKDT flag
 	bsf		SSP1CON2,ACKEN				;     - master NOT acknowledge
-	rcall	WaitMSSP					;     -
+	rcall	WaitMSSP					;     - wait for TX to complete
 	bcf		SSP1CON2,ACKDT				;     - reset ACKDT flag
 	; stop
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	WAITMS	.1
 	; address commit
 	bsf		SSP1CON2,SEN				; start condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	movlw	0x50						; address byte + write bit
 	movwf	SSP1BUF						; control byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	movlw	0x1F						; write command
 	movwf	SSP1BUF						; data byte
-	rcall	WaitMSSP
-	rcall	I2C_WaitforACK
+	rcall	WaitMSSP					; wait for TX to complete
+	rcall	I2C_Check_ACK				; check for acknowledge by receiver
 	bsf		SSP1CON2,PEN				; stop condition
-	rcall	WaitMSSP
+	rcall	WaitMSSP					; wait for TX to complete
 	WAITMS	.5							; required waiting time
 	; error check
 	btfss	i2c_error_flag				; did an error occur?
@@ -1369,6 +1466,6 @@
 
  ENDIF	; _rx_functions
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/isr.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/isr.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File isr.asm                              combined next generation V3.08.8
+;   File isr.asm                            * combined next generation V3.09.5
 ;
 ;   INTERUPT subroutines
 ;
@@ -16,25 +16,21 @@
 
 	extern	restore_flash
 
+
 ;=============================================================================
-; Code to be placed at fixed position
+; Code to be placed at a fixed Position
 ;
 isr_high	CODE	0x0008				; high priority interrupts
-	bra		HighInt
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	bra		HighInt
-										; *** low priority interrupts are not used ***
-isr_low		CODE	0x00018				; low priority interrupts
-	retfie	FAST						; do an immediate return with restore of BSR, STATUS and WREG
+	bra		HighInt						; jump to ISR
+
+isr_low		CODE	0x00018				; low priority interrupts *** not used ***
+	retfie	FAST						; do an immediate return from IRQ
+;
+;=============================================================================
 
 
-;=============================================================================
-; Interrupt Dispatcher
+;-----------------------------------------------------------------------------
+; Interrupt Dispatcher Entry Point
 ;
 HighInt:
 	; initialize interrupt code
@@ -78,8 +74,8 @@
 	retfie	FAST						; return from interrupt restoring BSR, STATUS and WREG
 
 
-;=============================================================================
-; CPU speed adjustment
+;-----------------------------------------------------------------------------
+; CPU Speed Adjustment
 ;
 isr_adjust_speed:
 	movff	cpu_speed_request,cpu_speed_state	; acknowledge CPU speed request
@@ -125,22 +121,31 @@
 
 block_0_code_end:						; marker to find end of code in block 0 in linker report file
 
+
 ;=============================================================================
-; jump vector for the bootloader, placed at an appointed position here
+; Code to be placed at a fixed Position: Jump-Vector for the Bootloader
 ;
-isr_restore	CODE	0x00080				; restore first flash page from EEPROM
+restore		CODE	0x00080				; restore first flash page from EEPROM
+
 restore_flash_0x00080:
 	goto	restore_flash
+;
+;=============================================================================
+
 
 ;=============================================================================
-; routines for handling digital-attached external sensors
+isr_handler	CODE	0x00084
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Handle digitally-attached external Sensors
+;
+; take a byte received on IR/S8 link and slot it into the RX buffer
 ;
  IFDEF _external_sensor
 
-; Take a byte received on IR/S8 link and slot it into the RX buffer
-;
 isr_uart2:
-	bcf	PIR3,RC2IF					; Clear UART 2 interrupt flag
+	bcf		PIR3,RC2IF					; clear UART 2 interrupt flag
 	banksel	RCREG2						; RC*2 is outside access RAM
 	movff	RCREG2,isr_lo				; copy received byte to isr_lo
 	bcf		RCSTA2,CREN					; clear receiver status
@@ -156,46 +161,43 @@
 	MOVII	FSR0_backup,FSR0L			;     - restore FSR0
 	incf	ir_s8_counter,F				;     - increment number of received bytes by 1
 isr_uart2_1:
-	clrf	TMR3L						; reload timer 3
-	movlw	.253						; ...
+	movlw	.253						; reload timer 3, high byte
 	movwf	TMR3H						; ...
-	bsf		T3CON,TMR3ON				; (re)start timeout timer 3
-	return
+	clrf	TMR3L						; reload timer 3, low  byte
+	bsf		T3CON,TMR3ON				; restart timer
+	return								; done
 
 
-; Timeout on IR/S8 link: check the checksum and gather the received data
+;-----------------------------------------------------------------------------
+; Timeout on IR/S8 Link: check the Checksum and gather the received Data
 ;
 isr_timer3:
 	bcf		T3CON,TMR3ON				; stop timer 3
-	movlw	.15
+	movlw	.15							; a IR telegram has 15 bytes
 	cpfseq	ir_s8_counter				; got exactly 15 bytes?
 	bra		isr_timer3_1				; NO  - test for 16 bytes
 	bra		isr_timer3_ir				; YES - got 15 bytes, compute local checksum
 isr_timer3_1:
-	movlw	.16
+	movlw	.16							; a IR telegram may also have 16 bytes, with last byte 0x00
 	cpfseq	ir_s8_counter				; got exactly 16 bytes?
 	bra		isr_timer3_2				; NO  - test for 17 bytes
 	tstfsz	ir_s8_buffer+.15			; YES - last byte = 0x00 ?
-	bra		isr_timer3_exit				;       No  - exit
+	bra		isr_timer3_exit				;       NO  - exit
 	bra		isr_timer3_ir				;       YES - got 16 bytes, compute local checksum
 isr_timer3_2:
-	movlw	.17
+	movlw	.17							; a S8 telegram has 17 bytes
 	cpfseq	ir_s8_counter				; got exactly 17 bytes?
 	bra		isr_timer3_exit				; NO  - exit
 	bra		isr_timer3_s8				; YES - S8 data
 
-	; Process telegram received on IR link
+	; process telegram received on IR link
 isr_timer3_ir:
-	movlw	.12							; checksum shall be computed for 1st and next 12 bytes
+	movlw	.12							; compute checksum over 1st and next 12 bytes
 	rcall	compute_IR_S8_checksum		; compute checksum
-	movf	ir_s8_buffer+.13,W			; get low  byte of the received checksum
-	cpfseq	isr_mpr+0					;  =  low  byte of the calculated local checksum?
-	bra		isr_timer3_exit				; NO - exit
-	movf	ir_s8_buffer+.14,W			; get high byte of the received checksum
-	cpfseq	isr_mpr+1					;  =  high byte of the calculated local checksum?
-	bra		isr_timer3_exit				; NO - exit
-										; YES to both - received telegram valid, copy data
+	tstfsz	ir_s8_counter				; checksum ok?
+	bra		isr_timer3_exit				; NO - discard data
 
+	; copy received data to respective variables
 	movff	ir_s8_buffer+.1, hud_status_byte
 	movff	ir_s8_buffer+.2, sensor1_mv+0
 	movff	ir_s8_buffer+.3, sensor1_mv+1
@@ -212,27 +214,23 @@
 	bsf		hud_connection_ok			; set manually for hwHUD w/o the HUD module
 	bra		isr_timer3_reload			; reload timer and exit
 
-	; Process telegram received on S8 link
+	; process telegram received on S8 link
 isr_timer3_s8:
-	movlw	.14							; checksum shall be computed for 1st and next 14 bytes
+	movlw	.14							; compute checksum over 1st and next 14 bytes
 	rcall	compute_IR_S8_checksum		; compute checksum
+	tstfsz	ir_s8_counter				; checksum ok?
+	bra		isr_timer3_exit				; NO - discard data
 
-	movf	ir_s8_buffer+.15,W			; get low  byte of the received checksum
-	cpfseq	isr_mpr+0					;  =  low  byte of the calculated local checksum?
-	bra		isr_timer3_exit				; NO - exit
-	movf	ir_s8_buffer+.16,W			; get high byte of the received checksum
-	cpfseq	isr_mpr+1					;  =  high byte of the calculated local checksum?
-	bra		isr_timer3_exit				; NO - exit
-										; YES to both - received telegram valid, copy data
-	movff	ir_s8_buffer+.3, hud_status_byte
+	; copy received data to respective variables
+	movff	ir_s8_buffer+.3, hud_status_byte	; also sets hud_connection_ok flag
 	movff	ir_s8_buffer+.13,hud_battery_mv+0
 	movff	ir_s8_buffer+.14,hud_battery_mv+1
 
-	btfsc	trigger_S8_data_update		; last data already processed?
-	bra		isr_timer3_exit			; NO  - skip copying new results (And not reload the timeout)
+;	btfsc	trigger_S8_data_update		; last data already processed?
+;	bra		isr_timer3_exit				; NO  - skip copying new data (and not reload the timeout)
 	bsf		trigger_S8_data_update		; YES - set flag for new data available
 
-	;     - copy more data
+	; copy more received data to respective variables
 	movff	ir_s8_buffer+.4, s8_rawdata_sensor1+0
 	movff	ir_s8_buffer+.5, s8_rawdata_sensor1+1
 	movff	ir_s8_buffer+.6, s8_rawdata_sensor1+2
@@ -244,72 +242,84 @@
 	movff	ir_s8_buffer+.12,s8_rawdata_sensor3+2
 
 isr_timer3_reload:
-	movlw	ir_timeout_value			; in multiples of 62.5 ms
-	movwf	ir_s8_timeout				; reload timeout
+	movlw	ir_timeout_value			; get timeout value (in multiples of 62.5 ms)
+	movwf	ir_s8_timeout				; reload timeout counter
 isr_timer3_exit:
-	clrf	ir_s8_counter				; clear pointer
-	bcf		PIR2,TMR3IF					; clear flag
-	return
+	clrf	ir_s8_counter				; clear number of received bytes
+	bcf		PIR2,TMR3IF					; clear IRQ flag
+	return								; done
 
 
-; compute checksum on data in RX buffer
+;-----------------------------------------------------------------------------
+; Helper Function - Compute Checksum on Data in RX Buffer
 ;
 compute_IR_S8_checksum:
 	movwf	ir_s8_counter				; initialize loop counter from WREG
-	movff	ir_s8_buffer+0,isr_mpr+0	; initialize low byte of the local checksum with first byte in buffer
-	clrf	               isr_mpr+1	; clear the high byte of the local checksum
-	lfsr	FSR0,ir_s8_buffer			; load base address of the buffer
+	MOVII	FSR0L,FSR0_backup			; back-up FSR0
+	lfsr	FSR0,ir_s8_buffer			; load base address of the receive buffer
+	movff	POSTINC0,isr_mpr+0			; initialize low byte of the calculated checksum with first byte in buffer
+	clrf	         isr_mpr+1			; clear the high byte of the calculated checksum
 compute_IR_S8_checksum_loop:
-	movf	PREINC0,W					; get next byte
+	movf	POSTINC0,W					; read next byte
 	addwf	isr_mpr+0,F					; add it to the to checksum, low  byte
 	movlw	.0							; no explicit data to add to the high byte...
 	addwfc	isr_mpr+1,F					; ... besides the carry
-	decfsz	ir_s8_counter				; decrement number of bytes yet to do, all done?
+	decfsz	ir_s8_counter,F				; decrement number of bytes yet to do, all done?
 	bra		compute_IR_S8_checksum_loop	; NO  - loop
-	return								; YES - done
+	movf	POSTINC0,W					; YES - read     low  byte of the received   checksum
+	cpfseq	isr_mpr+0					;     - equal to low  byte of the calculated checksum?
+	incf	ir_s8_counter,F				;       NO - mark a checksum error
+	movf	POSTINC0,W					;     - read     high byte of the received   checksum
+	cpfseq	isr_mpr+1					;     - equal to high byte of the calculated checksum?
+	incf	ir_s8_counter,F				;       NO - mark a checksum error
+	MOVII	FSR0_backup,FSR0L			;     - restore FSR0
+	return								;     - done
 
  ENDIF	; _external_sensor
 
-;=============================================================================
 
-;=============================================================================
-; Tasks every 62.5 ms: buttons, dimming, pressure/temp sensor and CPU speed
+;-----------------------------------------------------------------------------
+; Tasks every 62.5 ms: Buttons, Dimming, Pressure/Temperature Sensor and CPU Speed
 ;
 isr_tmr7:
-	bcf		PIR5,TMR7IF					; clear flag
-	movlw	.248						; rollover after 248 cycles -> 62.5 ms
-	movff	WREG,TMR7H					; timer 7 is outside access RAM
+	bcf		PIE5,TMR7IE					; disable IRQs by TMR7
 
-	call	get_analog_switches			; get analog readings, CAUTION: returns in bank common
-	banksel	isr_backup					;back to ISR default bank
+	banksel	0xF16						; TMR7H/L are not part of the access RAM
+	movlw	.248						; reload timer 7, high byte (8x256 ticks -> 62.5 ms)
+	movwf	TMR7H						; ...                       (keep low byte running )
+
+	call	get_analog_switches			; get analog readings - bank-safe, but CAUTION: returns in bank common
+	banksel	isr_backup					; back to ISR default bank
 
-	btfss	INTCON3,INT1IE
-	bra		isr_tmr7_a
-	btfsc	analog_sw2_pressed
-	rcall	isr_switch_left				; get digital readings of left switch
+	btfss	INTCON3,INT1IE				; external IRQ 1 enabled?
+	bra		isr_tmr7_a					; NO  - skip next
+	btfsc	analog_sw2_pressed			; YES - analog switch 2 pressed?
+	rcall	isr_switch_left				;       NO - get digital readings of left switch
 isr_tmr7_a:
-	btfss	INTCON,INT0IE
-	bra		isr_tmr7_b
-	btfsc	analog_sw1_pressed
-	rcall	isr_switch_right			; get digital readings of right switch
+	btfss	INTCON,INT0IE				; external IRQ 0 enabled?
+	bra		isr_tmr7_b					; NO  - skip next
+	btfsc	analog_sw1_pressed			; YES - analog switch 1 pressed?
+	rcall	isr_switch_right			;       NO - get digital readings of right switch
 isr_tmr7_b:
 	btfss	block_sensor_interrupt		; sensor interrupts disabled?
 	bra		isr_tmr7_c					; NO  - continue
-	return								; YES - done
+	bra		sensor_int_state_exit		; YES - goto exit
 isr_tmr7_c:
 	movf	max_CCPR1L,W				; dim value
 	cpfseq	CCPR1L						; = current PWM value?
 	rcall	isr_dimm_tft				; NO - adjust until max_CCPR1L = CCPR1L
 
  IFDEF _external_sensor
-	decfsz	ir_s8_timeout,F				; IR / S8 digital data still valid?
-	bra		isr_tmr7_2					; YES - continue
-	movlw	ir_timeout_value			; NO  - get timer reload in multiples of 62.5 ms
-	movwf	ir_s8_timeout				;     - reload the timer
-	btfss	analog_o2_input				;     - analog input available?
-	bra		isr_tmr7_1a					;       NO  - clear data
-	btfss	s8_digital_avail			;       YES - S8 digital interface available?
+	decfsz	ir_s8_timeout,F				; decrement IR/S8 timeout counter, became zero?
+	bra		isr_tmr7_2					; NO  - continue
+	movlw	ir_timeout_value			; YES - get timeout value (in multiples of 62.5 ms)
+	movwf	ir_s8_timeout				;     - reload timeout timer
+	btfsc	ext_input_optical			;     - optical input in use?
+	bra		isr_tmr7_1a					;       YES - clear data
+	TSTOSS	opt_s8_mode					;       NO  - S8 input in use?
 	bra		isr_tmr7_2					;             NO  - must be analog interface in use, keep data
+	;bra	isr_tmr7_1a					;             YES - clear data
+
 isr_tmr7_1a:
 	clrf	hud_status_byte				; S8/IR timeout clears all analog input readings to zero -> fallback will be triggered when in sensor mode
 	CLRI	hud_battery_mv				; clear battery voltage
@@ -335,7 +345,7 @@
 
 isr_tmr7_2:
 	btfsc	block_sensor_interrupt				; sensor interrupts disabled?
-	return										; YES - abort
+	bra		sensor_int_state_exit				; YES - goto exit
 
 isr_sensor_state2:
 	btfss	sensor_state_counter,0				; every 1/4 second
@@ -383,19 +393,18 @@
 	call	get_temperature_start				; and start temperature integration (73.5 us)
 	call	calculate_compensation				; calculate temperature compensated pressure (27 us)
 
-; build average for pressure
+	; build average for pressure
 	bcf		STATUS,C							; clear carry bit
 	rrcf	pressure_abs_avg+1					; divide by 2
-	rrcf	pressure_abs_avg+0
+	rrcf	pressure_abs_avg+0					; ...
 	bcf		STATUS,C							; clear carry bit
 	rrcf	pressure_abs_avg+1					; divide by 2, again
-	rrcf	pressure_abs_avg+0
+	rrcf	pressure_abs_avg+0					; ...
 
-	; copy into result register and set update flag
-	MOVII	pressure_abs_avg,pressure_abs
-;	bsf		trigger_pres_update					; signal a pressure update
+	; export averaged pressure
+	MOVII	pressure_abs_avg,pressure_abs		; export result
 
-; build average for temperature
+	; build average for temperature
 	bcf		STATUS,C							; clear carry bit by default
 	btfsc	temperature_avg+1,7					; sign bit set?
 	bsf		STATUS,C							; YES - copy sign bit to carry bit
@@ -408,7 +417,7 @@
 	rrcf	temperature_avg+0					; ...
 	MOVII	temperature_avg,temperature_cur		; store final result
 
-; check for temperature change
+	; check for temperature change
 	movf	temperature_cur+0,W					; get current temperature, low  byte
 	cpfseq	temperature_last+0					; compare with last temperature, equal?
 	bra		isr_sensor_state2_2					; NO - temperature has changed
@@ -496,11 +505,9 @@
  ENDIF	; _min_depth_option
 	bra		sensor_int_state_exit					; done
 
-
 sensor_int_state1_plus_restart:
-	; clear average registers
-	CLRI	pressure_abs_avg
-	CLRI	temperature_avg
+	CLRI	pressure_abs_avg			; clear average register for pressure
+	CLRI	temperature_avg				; clear average register for temperature
 
 sensor_int_state1:
 	call	get_temperature_value		; state 1: get temperature...
@@ -513,9 +520,14 @@
 	call	calculate_compensation		; .. and calculate temperature compensated pressure (233 us)
 
 sensor_int_state_exit:
+	bcf		PIR5,TMR7IF					; clear IRQ flag
+	bsf		PIE5,TMR7IE					; re-enable IRQs by TMR7
 	bra		isr_adjust_speed			; set/restore CPU speed and return
 
 
+;-----------------------------------------------------------------------------
+; Helper Function for Display Dimming
+;
 isr_dimm_tft:							; adjust until max_CCPR1L = CCPR1L
 	btfsc	screen_type3				; screen type 3 ?
 	return								; YES - ignore, no dimming function with screen type 3
@@ -538,8 +550,8 @@
 	return								;     - done
 
 
-;=============================================================================
-; RTC interrupt on every 1/2 second
+;-----------------------------------------------------------------------------
+; RTC Interrupt (invoked every 0.5 Seconds)
 ;
 isr_rtcc:
 	bcf		PIR3,RTCCIF					; clear flag
@@ -571,7 +583,7 @@
 	movff	RTCVALL,rtc_secs			; read seconds in BCD
 	movff	RTCVALH,rtc_mins			; read minutes in BCD
 
-	; Convert BCD to DEC and set registers
+	; convert BCD to DEC and set registers
 	movf	rtc_mins,W
 	rcall	isr_rtcc_convert_BCD_DEC	; convert to decimal with result in WREG
 	movwf	rtc_mins
@@ -610,7 +622,7 @@
 
 	; reset the surface interval timers if requested
 	btfsc	reset_surface_interval		; shall reset both surface interval timers?
-	call	rst_surface_interval		; YES
+	rcall	rst_surface_interval		; YES
 
 	; reset the timebase if requested
 	btfss	reset_timebase				; shall reset the timebase?
@@ -662,54 +674,57 @@
 	bsf		trigger_full_hour			;     - set flag for a new hour has begun
 	return								;     - done
 
-
 	; increment overall OSTC uptime
 isr_update_uptime:
-	incf	uptime+0,F
-	clrf	WREG
-	addwfc	uptime+1,F
-	addwfc	uptime+2,F
-	addwfc	uptime+3,F
-	return
-
+	incf	uptime+0,F					; uptime++
+	clrf	WREG						; ...
+	addwfc	uptime+1,F					; ...
+	addwfc	uptime+2,F					; ...
+	addwfc	uptime+3,F					; ...
+	return								; done
 
 	; process the timeout timer
 isr_update_timeout:
-	btfsc	reset_timeout				; shall reset the timeout?
+	btfsc	restart_timeout				; shall restart the timeout?
 	bra		isr_update_timeout_1		; YES
 	tstfsz	isr_timeout_timer			; NO  - timeout timer already at zero?
-	decfsz	isr_timeout_timer			;       NO  - decrement timer, reached zero now?
+	decfsz	isr_timeout_timer,F			;       NO  - decrement timer, reached zero now?
 	return								;       YES / NO  - nothing further to do
 	bsf		trigger_timeout				;             YES - set timeout flag
 	return								;                 - done
 isr_update_timeout_1:
-	bcf		reset_timeout							; clear request flag
+	bcf		restart_timeout							; clear request flag
 	bcf		trigger_timeout							; clear pending timeout trigger, if any
 	movff	isr_timeout_reload,isr_timeout_timer	; reload timer
 	return											; done
 
-;=============================================================================
-; Calculate charge drawn from the battery
+
+;-----------------------------------------------------------------------------
+; Calculate Charge drawn from the Battery
 ;
 isr_battery_gauge:
 	btfsc	block_battery_gauge			; access to battery gauge suspended?
 	return								; YES - done
 	MOVLI	current_sleepmode,isr_mpr	; NO  - default to sleep mode with 100µA/3600 -> nAs
 	btfss	sleepmode					;     - in sleep mode?
-	rcall	isr_battery_gauge2			;       NO - compute current consumption value into isr_lo and isr_hi
-	movf	isr_mpr+0,W					;     - 48 bit add of isr_mpr:2 with battery_gauge:6
-	addwf	battery_gauge+0,F
-	movf	isr_mpr+1,W
-	addwfc	battery_gauge+1,F
-	clrf	WREG
-	addwfc	battery_gauge+2,F
-	addwfc	battery_gauge+3,F
-	addwfc	battery_gauge+4,F
-	addwfc	battery_gauge+5,F
-	return
+	rcall	isr_battery_gauge2			;       NO - compute current consumption into isr_lo and isr_hi
+	movf	isr_mpr+0,W					;     - 48 bit add of isr_mpr:2 to battery_gauge:6
+	addwf	battery_gauge+0,F			;     - ...
+	movf	isr_mpr+1,W					;     - ...
+	addwfc	battery_gauge+1,F			;     - ...
+	clrf	WREG						;     - ...
+	addwfc	battery_gauge+2,F			;     - ...
+	addwfc	battery_gauge+3,F			;     - ...
+	addwfc	battery_gauge+4,F			;     - ...
+	addwfc	battery_gauge+5,F			;     - ...
+	return								;     - done
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - compute current Consumption
+;
 isr_battery_gauge2:
-	; set consumption rate in nAs - nano Ampere per second
+	; Set consumption rate in nAs (nano Ampere x seconds)
 	; Example:
 	; MOVLI  .55556,isr_mpr    ; 0.2 Ah / 3600 seconds per hour * 1e9s = nAs
 	;
@@ -723,7 +738,7 @@
 	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
+	; add current for CPU and GPU
 	; cpu_speed_state = ECO     3.10 mA ->  861 nAs
 	;                 = NORMAL  5.50 mA -> 1528 nAs
 	;                 = FASTEST 8.04 mA -> 2233 nAs
@@ -747,11 +762,11 @@
 	bra		isr_battery_gauge7				; NO
 	ADDLI	current_compass,isr_mpr			; YES - add current_compass to isr_mpr
 isr_battery_gauge7:
-	return
+	return									; done
 
 
-;=============================================================================
-; Every second tasks while in dive mode
+;-----------------------------------------------------------------------------
+; Every Second Tasks while in Dive Mode
 ;
 isr_divemode_1sec:
 	decfsz	sampling_timer,F			; decrement sampling timer, became zero?
@@ -818,58 +833,62 @@
 	return								;           - done
 
 
-;=============================================================================
-; BCD to Binary conversion
+;-----------------------------------------------------------------------------
+; Helper Function - BCD to Binary conversion
+;
 ; Input   WREG = value in BCD
 ; Output  WREG = value in binary
 ;
 isr_rtcc_convert_BCD_DEC:
-	movwf	isr_lo
-	swapf	isr_lo, W
-	andlw	0x0F						; W = tens
-	rlncf	WREG, W						; W = 2 * tens
+	movwf	isr_lo						; copy BCD to isr_lo
+	swapf	isr_lo, W					; create swapped copy in WREG
+	andlw	0x0F						; keep only the tens
+	rlncf	WREG, W						; WREG = 2 * tens
 	subwf	isr_lo, F					; 16 * tens + ones - 2*tens
 	subwf	isr_lo, F					; 14 * tens + ones - 2*tens
 	subwf	isr_lo, W					; 12 * tens + ones - 2*tens
-	return
+	return								; done
 
 
-;=============================================================================
-; Check buttons
+;-----------------------------------------------------------------------------
+; Check Buttons
 ;
 isr_switch_right:
-	bcf		INTCON,INT0IE				; disable INT0
+	bcf		INTCON,INT0IE				; clear external interrupt 0
 	btfss	flip_screen					; 180° flipped?
-	bsf		switch_right				; set flag
+	bsf		switch_right				; NO  - set flag for right button
 	btfsc	flip_screen					; 180° flipped?
-	bsf		switch_left					; set flag
-	bra		isr_switch_common			; continue...
+	bsf		switch_left					; YES - set flag for left button
+	bra		isr_switch_common			; continue with common part
 
 isr_switch_left:
-	bcf		INTCON3,INT1IE				; disable INT1
+	bcf		INTCON3,INT1IE				; clear external interrupt 1
 	btfss	flip_screen					; 180° flipped?
-	bsf		switch_left					; set flag
+	bsf		switch_left					; NO  - set flag for left button
 	btfsc	flip_screen					; 180° flipped?
-	bsf		switch_right				; set flag
-	;bra	isr_switch_common			; continue...
+	bsf		switch_right				; YES - set flag for right button
+	;bra	isr_switch_common			; continue with common part
 
 isr_switch_common:
-	clrf	TMR1L						; load timer1 for first press
-	movlw	TMR1H_VALUE_FIRST			; in steps of 7.8125 ms
+	btfsc	tmr5_preemtion_allowed		; timer 5 preemption allowed?
+	bsf		PIR5,TMR5IF					; YES - preempt timer 5
+	movlw	TMR1H_VALUE_FIRST			; load timer 1 (in steps of 7.8125 ms)
 	movwf	TMR1H						; ...
+	clrf	TMR1L						; ...
 	bsf		T1CON,TMR1ON				; start timer 1
-	bcf		INTCON3,INT1IF				; clear flag
-	bcf		INTCON,INT0IF				; clear flag
-	return
+	bcf		INTCON3,INT1IF				; clear timer 1 IRQ request
+	bcf		INTCON,INT0IF				; clear timer 0 IRQ request
+	return								; done
 
 
-;=============================================================================
-; Button hold-down interrupt
+;-----------------------------------------------------------------------------
+; Button hold-down Interrupt
 ;
 timer1int:
-	bcf		PIR1,TMR1IF					; clear flag
-	bcf		INTCON,INT0IF				; clear flag
-	bcf		INTCON3,INT1IF				; clear flag
+	bcf		PIR1,TMR1IF					; clear timer 1 IRQ request
+	bcf		INTCON,INT0IF				; clear timer 0 IRQ request
+	bcf		INTCON3,INT1IF				; clear timer 1 IRQ request
+
 	; digital
 	btfss	switch_left1				; left button hold-down?
 	bra		timer1int_left				; YES
@@ -882,61 +901,60 @@
 	btfsc	analog_sw1_pressed			; right button hold-down?
 	bra		timer1int_right				; YES
 
-	; no button hold-down, stop Timer 1
+	; no button hold-down, stop timer 1
 	bcf		T1CON,TMR1ON				; stop timer 1
-	bsf		INTCON,INT0IE				; enable INT0
-	bsf		INTCON3,INT1IE				; enable INT1
+	bsf		INTCON,INT0IE				; enable INT0 IRQ
+	bsf		INTCON3,INT1IE				; enable INT1 IRQ
 	return
 
 timer1int_left:
 	btfss	flip_screen					; 180° flipped?
-	bsf		switch_left					; (re-)set flag
+	bsf		switch_left					; set flag for left button
 	btfsc	flip_screen					; 180° flipped?
-	bsf		switch_right				; (re-)set flag
+	bsf		switch_right				; set flag for right button
 	bra		timer1int_common			; continue
 
 timer1int_right:
 	btfss	flip_screen					; 180° flipped?
-	bsf		switch_right				; set flag
+	bsf		switch_right				; set flag for right button
 	btfsc	flip_screen					; 180° flipped?
-	bsf		switch_left					; (re-)set flag
+	bsf		switch_left					; set flag for left button
 	;bra	timer1int_common			; continue
 
-timer1int_common:						; load timer1 for next pressure
-	clrf	TMR1L						; clear timer, low byte
+timer1int_common:						; load timer 1 for next button press
 	movlw	TMR1H_VALUE_CONT			; default to surface mode value
 	btfsc	divemode					; in dive mode?
 	movlw	TMR1H_VALUE_CONT_DIVE		; YES - overwrite with dive mode value
 	movwf	TMR1H						; write value to timer, high byte
-	return								; return from timer1int with timer1 kept running
+	clrf	TMR1L						; write value to timer, low  byte (zero)
+	return								; done (timer1 kept running)
 
 
-;=============================================================================
-; Increment surface interval (counted in minutes and in seconds)
+;-----------------------------------------------------------------------------
+; Increment Surface Interval (counted in minutes and in seconds)
 ;
 ; int_O_desaturation_time is only computed while in start, surface mode,
 ; menue_tree or ghostwriter. So the ISR may clock surface_interval_mins
-; past the actual surface interval time. But TFT_surface_lastdive will
+; past the actual surface interval time. But TFT_surf_cv_lastdive will
 ; check int_O_desaturation_time and in case int_O_desaturation_time is
 ; zero it will not show surface_interval_mins but surface_interval_secs instead.
 ; Thus the glitch will remain invisible.
 ;
+inc_surface_interval_secs:							; called every second when not in dive mode
+	incf	surface_interval_secs+0,F				; increment the lowest byte
+	clrf	WREG									; clear WREG
+	addwfc	surface_interval_secs+1,F				; add carry from byte before, if it did wrap-around
+	addwfc	surface_interval_secs+2,F				; add carry from byte before, if it did wrap-around
+	addwfc	surface_interval_secs+3,F				; add carry from byte before, if it did wrap-around
+	return											; done
 
-inc_surface_interval_secs:						; called every second when not in dive mode
-	incf	surface_interval_secs+0,F			; increment the lowest byte
-	clrf	WREG								; clear WREG
-	addwfc	surface_interval_secs+1,F			; add carry from byte before, if it did wrap-around
-	addwfc	surface_interval_secs+2,F			; add carry from byte before, if it did wrap-around
-	addwfc	surface_interval_secs+3,F			; add carry from byte before, if it did wrap-around
-	return										; done
-
-inc_surface_interval_mins:						; called every minute when not in dive mode
-	movff	int_O_desaturation_time+0,isr_lo	; get desaturation time, low  byte
-	movff	int_O_desaturation_time+1,WREG		; get desaturation time, high byte
-	iorwf	isr_lo,W							; inclusive-or low & high byte, desaturation time = 0 ?
-	bz		clr_surface_interval_mins			; YES - reset surface interval minutes counter
-	INCI	surface_interval_mins				; NO  - increment surface interval
-	return										;     - done
+inc_surface_interval_mins:							; called every minute when not in dive mode
+	movff	int_O_desaturation_time+0,isr_lo		; get desaturation time, low  byte
+	movff	int_O_desaturation_time+1,WREG			; get desaturation time, high byte
+	iorwf	isr_lo,W								; inclusive-or low & high byte, desaturation time = 0 ?
+	bz		clr_surface_interval_mins				; YES - reset surface interval minutes counter
+	INCI	surface_interval_mins					; NO  - increment surface interval
+	return											;     - done
 
 rst_surface_interval:
 	bcf		reset_surface_interval					; reset request flag
@@ -955,7 +973,6 @@
 	clrf	surface_interval_mins+1					; reset surface interval (minutes), high byte
 	return											; done
 
-
-;=============================================================================
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/logbook.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/logbook.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File logbook.asm                          combined next generation V3.08.8
+;   File logbook.asm                        * combined next generation V3.09.5
 ;
 ;   Logbook
 ;
@@ -26,16 +26,17 @@
 #include "divemode.inc"
 #include "ghostwriter.inc"
 #include "rtc.inc"
+#include "gaslist.inc"
+#include "colorschemes.inc"
 
 #DEFINE inside_loogbook
 #include "logbook.inc"
 
 
-	extern	do_main_menu2
-	extern	gaslist_show_mix
+	extern	main_menu
 
 
-;---- Private local variables ------------------------------------------------
+;---- Private local Variables ------------------------------------------------
 
 	CBLOCK	local1						; max size is 16 byte !!!
 		count_temperature				; current sample count for temperature divisor
@@ -85,10 +86,7 @@
 	ENDC								; used: 16 byte, remaining: 0 byte => full
 
 
-	; Remarks: The variable gaslist_gas is "misused" here as a local variable,
-	;          because the storage space for local variables is fully used up.
-	;
-	;          This code includes decoding and displaying of log data for Trimix
+	; Remark:  This code includes decoding and displaying of log data for Trimix
 	;          and CCR/pSCR dives to make sure that if such dives are in the
 	;          logbook they will be displayed correctly.
 
@@ -192,16 +190,19 @@
 #DEFINE MBAR_column					log2_salinity_column
 
 
+;=============================================================================
 logbook		CODE
-
 ;=============================================================================
 
+;-----------------------------------------------------------------------------
+; Helper Function - show the Cursor
+;
 TFT_logbook_cursor:
 	WIN_BOX_BLACK .0, .239, logbook_list_left-.8, logbook_list_left-.1    ; top, bottom, left, right
 
 	WIN_LEFT logbook_list_left-.8					; set horizontal position
-	WIN_FONT FT_SMALL								; select small font
-	call	TFT_standard_color						; print in white color
+	FONT_SIZE  FT_SMALL								; set font size
+	FONT_COLOR_MEMO									; set font color
 	decf	menu_pos_cur,W							; get row number -1 into WREG
 	mullw	logbook_row_offset						; multiply with vertical offset between rows
 	movff	PRODL,win_top							; set vertical position
@@ -209,17 +210,19 @@
 	return											; done
 
 
-	global	logbook									; entry point coming from menu_tree.asm
+;-----------------------------------------------------------------------------
+; Entry Point coming from Surface Menu
+;
+	global	logbook
 logbook:
-	call	TFT_boot
-;	call	TFT_standard_color
+	call	TFT_boot								; initialize display
 
 	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
+	clrf	logbook_page_number						; clear # of current displayed page
+	clrf	logbook_divenumber						; clear # of dive in list during search
+	clrf	logbook_temp							; clear temps
+	clrf	logbook_temp_backup						; ...
 
 	movlw	logbook_row_number						; get number of dive entry rows per list
 	movwf	menu_pos_cur							; initialize cursor position to last entry
@@ -229,14 +232,13 @@
 	movwf	logbook_max_dive_counter				; copy to logbook_max_dive_counter
 	movwf	total_num_dives							; copy to total_num_dives, too
 
+logbook2:
 
-;-----------------------------------------------------------------------------
-; 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)
+	; 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)
+	;           - 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 - loop
@@ -244,12 +246,10 @@
 	; compute index for dive to show / goto previous dive
 	decf	logbook_max_dive_counter,F
 
-	; 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
-
 	; copy the first 22 byte of the header from FLASH to memory
-	FLASH_RR_READ mpr,header_buffer,.22
+	movf	logbook_max_dive_counter,W				; hand over header index in WREG
+	call	log_header_addr_by_index				; compute start address of the header
+	FLASH_RR_READ header_buffer,.22					; copy first 22 bytes of header from FLASH to memory
 
 	; check if there is a header
 	MOVCC	header_buffer+index_header_start,WREG	; read first byte of header
@@ -275,7 +275,7 @@
 logbook4:
 	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
+	call	display_listdive						; NO  - display dive summery on current list position
 	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
@@ -337,7 +337,7 @@
 exit_logbook:
 	bcf		switch_right							; clear pending button events
 	bcf		switch_left								; ...
-	goto	do_main_menu2							; jump-back to main menu (in menu_tree.asm)
+	goto	main_menu								; jump-back to main menu (in menu_tree.asm)
 
 display_profile_or_next:
 	movlw	logbook_row_number+.1					; get menu line were the next page item is
@@ -345,8 +345,9 @@
 	bra		display_profile							; NO  - show profile of selected dive
 	goto	next_logbook2							; YES - show next page
 
+
 ;-----------------------------------------------------------------------------
-; show graphical dive profile
+; show graphical Dive Profile
 ;
 display_profile:
 	bcf		bailout_mode							; clear event flag
@@ -361,11 +362,9 @@
 	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
+	; copy header from FLASH into memory 
+	call	log_header_addr_by_divenumber			; compute header start address from the dive number
+	FLASH_RR_READ header_buffer,.256				; copy complete header from FLASH to memory
 
 	; read the sampling rate
 	MOVCC	header_buffer+index_samplingrate,sampling_rate
@@ -373,8 +372,8 @@
 	; --- start drawing the dive profile page ---
 
 display_profile2:
-	call	TFT_boot
-	call	TFT_standard_color
+	call	TFT_boot								; initialize display
+	FONT_COLOR_MEMO									; set font color
 
 	; show dive number
 	call	logbook_show_divenumber					; show the dive number in medium font
@@ -382,13 +381,13 @@
 	; show date
 	WIN_SMALL logbook_date_column, logbook_date_row
 	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 ""
+	call	output_date								; print date
+	PRINT											; dump to screen
 
 	; 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)
+	call	TFT_print_decotype						; print deco mode (OC, CC, Gauge, Apnea or pSCR)
 													; also sets aux_flag in case the dive was done in a deco mode
 
 	; show time
@@ -398,12 +397,14 @@
 	PUTC	':'										; print spacing ":"
 	movff	hi,lo									; print minute
 	output_99x										; ...
-	STRCAT_PRINT ""									; display 1st row of details
+	PRINT											; print buffer as 1st row of details to screen
 
 	; get log format version
 	MOVCC	header_buffer+index_profile_version,lo	; read profile format version
-	movlw	0x24
-	cpfslt	lo										; < 0x24 ?
+	movlw	b'00111111'								; load mask for external part of the profile version
+	andwf	lo,F									; keep only the external part
+	movlw	0x24									; recorded external version < 0x24
+	cpfslt	lo										; ... ?
 	bra		log_skip_extra_icon						; YES -  skip end of dive icon
 
 	; print end of dive icon
@@ -470,31 +471,29 @@
 
 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)
-	STRCAT_TEXT_PRINT tFeets
-	bra		display_profile_offset4_common
+	PUTC	' '										; append a space
+	output_999										; print depth (0-999)
+	STRCAT_TEXT_PRINT tFeets						; append unit and dump to screen
+	bra		display_profile_offset4_common			; continue
 
 display_profile_offset4_metric:
-	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
+	bsf		omit_digit_1							; do not print 1st digit (no cm)
+	bsf		decimal_digit2							; place a decimal point in front of digit 2
+	output_65535									; print depth (0.0x-655.3x)
+	STRCAT_TEXT_PRINT tMeters						; append unit and dump to screen
+	;bra	display_profile_offset4_common			; continue
 
 display_profile_offset4_common:
 	WIN_SMALL log_divetime_mins_value_column,log_divetime_mins_value_row
-	bsf		leftbind
 
 	; show dive time minutes : seconds
 	MOVTT	header_buffer+index_divetime,mpr		; get   dive time
-	output_16										; print dive time minutes
+	bsf		leftbind								; print left-aligned
+	output_9999										; print dive time minutes (0-9999)
 	PUTC	'm'										; print "m" (minutes)
 	movff	up,lo									; print dive time seconds
 	output_99x										; dive time seconds
-	STRCAT_PRINT "s"								; print "s" (seconds)
+	PUTC_PRINT "s"									; append unit (seconds) and dump buffer to screen
 
 	; get minimum temperature (for later use)
 	MOVII	header_buffer+index_min_temp,logbook_min_tp
@@ -544,76 +543,80 @@
 	movwf	backup_color1							; keep copy of color for later restore
 	call	TFT_color_code_gas						; set color
 
+	; initialize flag for signaling when last sample set was read
+	bcf		end_of_profile
+
 	; set ext_flash_address to the begin of the profile data
 	MOVTT	header_buffer+index_profile_start_address,ext_flash_address
 
-	; skip the 0xFA 0xFA header of the profile data
-	ext_flash_inc_address_0x20 d'2'
+	; header start code sequence present?
+	FLASH_CW_READ_0x20								; get the 1st byte
+	xorlw	0xFA									; 1st byte = header start byte?
+	bnz		display_profile_no_profile_jump			; NO  - no profile data available, abort
 
-	; initialize flag for signaling when last sample set was read
-	bcf		end_of_profile
+	FLASH_CW_READ_0x20								; get the 2nd byte
+	xorlw	0xFA									; 2nd byte = header start byte?
+	bnz		display_profile_no_profile_jump			; NO  - no profile data available, abort
 
 	; 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
+	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							; WREG = total number of dives - number of dive to show - 1
 	cpfseq	lo										; number of dive in profile = number of dive to show?
+display_profile_no_profile_jump:
 	bra		display_profile_no_profile				; NO  - no profile data for this dive available
 	;bra	display_profile_show_profile			; YES - show profile
 
 display_profile_show_profile:
 
 	; skip high byte of dive number          1 byte
-	; skip second header code                2 byte
+	; skip second part of header start code  2 byte
 	; skip length of profile data            3 byte
-	; skip sampling rate in profile section  1 byte
+	; skip sampling rate in profile data     1 byte
 	; skip number of divisors                1 byte
 	;                                        ======
 	;        total number of bytes to skip = 8 byte
-	ext_flash_inc_address_0x20 d'8'
+
+	EXT_FLASH_INC_ADDRESS_0x20 d'8'					; skip next 8 bytes
 
 	; read divisor temp
-	ext_flash_inc_address_0x20 d'2'					; skip information type and length
-	FLASH_CW_READ_0x20								; read  temperature divisor
+	EXT_FLASH_INC_ADDRESS_0x20 d'2'					; skip information type and length
+	FLASH_CW_READ_0x20								; read  temperature divisor into WREG
 	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
+	EXT_FLASH_INC_ADDRESS_0x20 d'2'					; skip information type and length
+	FLASH_CW_READ_0x20								; read  deco divisor into WREG
 	movwf	divisor_deco							; store deco divisor
 	movwf	count_deco								; store to deco status counter, too
 
 	; read divisor GF
-	ext_flash_inc_address_0x20 d'2'					; skip information type and length
-	FLASH_CC_READ_0x20 divisor_gf						; store saturation divisor
+	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
+	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
+	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
+	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
+	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
+	;---- start drawing the profile ----------------
 
 	; 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	color_deepblue							; select color
+	WIN_FRAME_COLOR profile_top-1,profile_top+profile_height_pixels+1,profile_left-1,profile_left+profile_width_pixels+1
 
 	; draw depth grid
 	movlw	profile_top								; set top  position of plot area
@@ -627,7 +630,7 @@
 	clrf	win_width+1								; ...
 	bra		display_profile2_loline					; do not draw the 0 m line
 display_profile2_loop:
-	call	TFT_box									; draw the line
+	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
@@ -641,9 +644,9 @@
 	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
+	clrf	ul										; clear counter for depth readings
+	movlw	profile_width_pixels+profile_left-.1	; load loop counter
+	movwf	ex										; ...
 
 	movlw	profile_left+.1
 	movwf	logbook_pixel_x_pos						; here: used as column x2 (start at column 5)
@@ -653,9 +656,9 @@
 	movwf	logbook_last_tp							; initialize for temperature curve, too
 
 	movlw	LOW(-.100)								; initialize max temperature to -10.0 °C
-	movwf	logbook_max_tp+0
-	movlw	HIGH 0xFFFF & (-.100)
-	movwf	logbook_max_tp+1
+	movwf	logbook_max_tp+0						; ...
+	movlw	HIGH 0xFFFF & (-.100)					; ...
+	movwf	logbook_max_tp+1						; ...
 
 	setf	logbook_cur_tp+0						; initialize temperature to 0xFFFF = 'no data'
 	setf	logbook_cur_tp+1						; ...
@@ -680,7 +683,8 @@
 
 ;	INIT_PIXEL_WRITE logbook_pixel_x_pos			; pixel x2 (also sets standard color!)
 
-	; start profile plotting loop
+	;---- start profile plotting loop --------------
+
 	CLRI	logbook_sample_counter					; clear counter for amount of samples read so far
 
 profile_display_loop:
@@ -701,8 +705,7 @@
 	btfsc	end_of_profile							; end of profile data reached?
 	bra		profile_display_loop_done				; YES - skip all remaining pixels
 
-
-	;---- draw ceiling curve, if any ---------------------------------------------
+	;---- draw ceiling curve, if any ---------------
 
 	movf	divisor_deco,W							; get divisor, deco data logged?
 	bz		profile_display_skip_deco				; NO - skip
@@ -729,7 +732,7 @@
 
 profile_display_skip_deco:
 
-	;---- draw temperature curve, if any ---------------------------------------------
+	;---- draw temperature curve, if any -----------
 
 	movf	divisor_temperature,W					; get divisor, deco data logged?
 	bz		profile_display_skip_temp				; NO - skip
@@ -766,7 +769,7 @@
 	movff	xC+1,xC+0
 
 	movlw	color_orange							; select color for temperature curve
-	call	TFT_set_color							; set color
+	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
@@ -785,7 +788,7 @@
 
 profile_display_skip_temp:
 
-	;---- draw depth curve ---------------------------------------------------
+	;---- draw depth curve -------------------------
 
 	MOVII	y_scale,          xB					; divide pressure in mbar/pixel for row offset
 	MOVII	logbook_cur_depth,xA					; get current depth
@@ -796,7 +799,8 @@
 	movff	fill_between_rows,xC+0					; YES - ignore
 
 	movf	backup_color1,W							; copy gas number to WREG for color-coding
-	call	TFT_color_code_gas						; set color
+	call	TFT_color_code_gas						; get color for gas
+	call	TFT_set_color							; set drawing color
 
 	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)
@@ -805,7 +809,7 @@
 	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  - skip
@@ -828,11 +832,10 @@
 	movwf	win_leftx2
 
 	; print marker
-	movlw	color_orange
-	call	TFT_set_color
-	WIN_FONT FT_TINY
-	lfsr	FSR2,buffer
-	STRCPY_PRINT "m"
+	FONT_COLOR color_orange							; set font color
+	FONT_SIZE FT_TINY								; set font size
+	INIT_BUFFER										; initialize output buffer
+	STRCPY_PRINT "m"								; print a "m" (marker)
 
 	movlw	profile_left
 	movwf	win_leftx2
@@ -848,7 +851,7 @@
 
 profile_display_skip_marker:
 
-	;---- draw CNS curve, if any ---------------------------------------------
+	;---- draw CNS curve, if any -------------------
 
 	movf	divisor_cns,W							; get divisor, CNS logged?
 	bz		profile_display_skip_cns				; NO - skip
@@ -858,7 +861,7 @@
 
 profile_display_skip_cns:
 
-	;---- draw saturation curve, if any --------------------------------------
+	;---- draw saturation curve, if any ------------
 
 	movf	divisor_gf,W							; get divisor, saturation logged?
 	bz		profile_display_skip_gf					; NO - skip
@@ -868,9 +871,7 @@
 
 profile_display_skip_gf:
 
-	; all curves done
-	bra		profile_display_skip_loop1
-
+	;---- all curves done --------------------------
 
 profile_display_skip_loop1:
 	dcfsnz	profile_temp2+0,F						; decrement low byte of x-scaler, became zero?
@@ -883,26 +884,24 @@
 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?
+	decfsz	ex,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_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
+	FONT_COLOR color_pink							; YES - select pink color
+	WIN_TINY logbook_bailout_column,logbook_bailout_row;  - select font and position
+	STRCPY_TEXT_PRINT tDiveBailout					;     - print "Bailout" and dump to screen
 
 profile_display_gas6:
 	btfss	event_gas_change_gas6					; did a change to gas 6 occurred?
 	bra		profile_display_temperatures			; NO  - skip next
-	movlw	color_pink								; YES - select color
-	call	TFT_set_color							;     - set color
+	FONT_COLOR color_pink							; YES - select color
 	WIN_TINY logbook_bailout_column,logbook_bailout_row-.15
 	STRCPY_TEXT tGas								;     - print "Gas"
-	STRCAT_PRINT " 6!"								;     - print " 6!"
+	STRCAT_PRINT " 6!"								;     - append " 6!" and dump to screen
 
 profile_display_temperatures:
 	movff	logbook_min_temp_pos,win_top			; get Y position at lowest temperature
@@ -910,12 +909,10 @@
 	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
+	FONT_SIZE FT_TINY								; set font size
+	FONT_COLOR color_yellow							; set font color
 
 	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
@@ -923,66 +920,59 @@
 
 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
+	rcall	logbook_show_temp_imperial_out			; print temperature
 	; max temperature
-	movlw	.15
-	subwf	logbook_max_temp_pos,W
+	movlw	.15										; set position
+	subwf	logbook_max_temp_pos,W					; ...
 	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
-	call	convert_celsius_to_fahrenheit			; convert value in lo:hi from Celsius to Fahrenheit
-	output_16
-	bcf		ignore_digit5
-	STRCAT_TEXT_PRINT tLogTunitF
-	bra		logbook_show_gases
+	MOVII	logbook_max_tp,mpr						; get max temperature
+	rcall	logbook_show_temp_imperial_out			; print temperature
+	bra		logbook_show_gases						; continue
 
 logbook_show_temp_metric:
 	; 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
+	rcall	logbook_show_temp_metric_out			; print temperature
 	; max temperature
-	movlw	.15
-	subwf	logbook_max_temp_pos,W
+	movlw	.15										; set position
+	subwf	logbook_max_temp_pos,W					; ...
 	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
-	movlw	d'3'
-	movwf	ignore_digits
-	bsf		leftbind
-	output_16dp d'2'								; temperature
-	STRCAT_TEXT_PRINT tLogTunitC
-	bra		logbook_show_gases
+	MOVII	logbook_max_tp,mpr						; get max  temperature
+	rcall	logbook_show_temp_metric_out			; print temperature
+	bra		logbook_show_gases						; continue
+
+logbook_show_temp_imperial_out:
+	INIT_BUFFER										; initialize output buffer
+	call	convert_celsius_to_fahrenheit			; convert value in lo:hi from Celsius to Fahrenheit
+	bsf		leftbind								; print left-aligned
+	bsf		omit_digit_1							; full degrees only
+	output_9999										; print temperature (0x-999x)
+	STRCAT_TEXT_PRINT tLogTunitF					; add unit and dump to screen
+	return											; done
+
+logbook_show_temp_metric_out:
+	INIT_BUFFER										; initialize output buffer
+	call	convert_signed_16bit					; convert lo:hi into unsigned-short and add '-' to POSTINC2 if required
+	bsf		leftbind								; print left-aligned
+	bsf		decimal_digit1							; place a decimal point in front of the 1st digit
+	output_999										; print temperature (0.0-99.9)
+	STRCAT_TEXT_PRINT tLogTunitC					; add unit and dump to screen
+	return											; done
 
 
 display_profile_no_profile:
-	; print message "No Data anymore..."
+	; print "no profile anymore..." message
 	WIN_SMALL .4,.110								; set text size and position
-	call	TFT_disabled_color						; use the color for disabled things
+	FONT_COLOR_DISABLED								; use the color for disabled things
 	STRCPY_TEXT_PRINT tNoProfileData				; print message
 
-
 logbook_show_gases:
-	bcf		leftbind
-	call	TFT_standard_color
-
+	FONT_COLOR_MEMO									; back to standard color
 	btfss	aux_flag								; dive done in a deco mode?
 	bra		logbook_show_gases_done					; NO - don't show gases
 
 	; show gases
-	lfsr	FSR0,header_buffer+index_gas1			; load base address of gases
+	lfsr	FSR0,header_buffer+index_gas1			; load base address of the gases
 	bsf		log_show_gas_short						; do the short version of log_show_gas
-	bsf		leftbind
 
 	WIN_TINY log_gas_column1, log_gas_row
 	movlw	.1										; color for gas 1
@@ -1004,10 +994,7 @@
 	movlw	.5										; color for gas 5
 	call	log_show_gas
 
-	bcf		leftbind
-
 logbook_show_gases_done:
-
 	rcall	logbook_preloop_tasks					; clear timeout, some flags and set to Speed_eco
 display_profile_loop:
 	btfsc	switch_right							; right button pressed?
@@ -1018,8 +1005,8 @@
 	bra		display_profile_loop					;           - loop waiting for something to do
 
 
-;=============================================================================
-; Draw a vertical line between xC+1 and xC+0, at current X position
+;-----------------------------------------------------------------------------
+; Helper Function - draw a vertical line between xC+1 and xC+0 at current X position
 ;
 ; Note: should keep xC+0
 ; Note: ascending or descending !
@@ -1064,9 +1051,10 @@
 	bra		profile_display_fill_up
 	return											; fill_between_rows and xC+0 are untouched
 
-;=============================================================================
 
-
+;-----------------------------------------------------------------------------
+; read next Profile Data Set and plot Depth and Temperature
+;
 profile_view_get_depth:
 	INCI	logbook_sample_counter					; count read pixels
 
@@ -1076,14 +1064,14 @@
 	movf	logbook_sample_counter+1,W
 	cpfseq	vertical_interval+1
 	bra		profile_view_get_depth_no_line			; no need to draw a 10min line, continue
-	; draw a new 10min line here...
-	CLRI	logbook_sample_counter					; clear counting registers for next line
+
+	;---- 10 min vertical line ---------------------
 
-	; Vertical lines...
-	movlw	color_deepblue
-	call	TFT_set_color
-	movlw	profile_top+.1
-	movwf	win_top
+	CLRI	logbook_sample_counter					; clear counting registers for next line
+	movlw	color_deepblue							; select color
+	call	TFT_set_color							; set    color
+	movlw	profile_top+.1							; set top position
+	movwf	win_top									; ...
 	incf	logbook_pixel_x_pos,W					; draw one line to right to make sure it's the background of the profile
 	movwf	win_leftx2								; left border (0-159)
 	movlw	profile_height_pixels
@@ -1093,17 +1081,17 @@
 	call	half_horizontal_line					; inputs: win_top, win_leftx2, win_width, win_color1, win_color2
 
 profile_view_get_depth_no_line:
-	FLASH_II_READ_0x20 logbook_cur_depth				; read depth (2 bytes)
-	FLASH_CC_READ_0x20 gaslist_gas						; read Profile Flag Byte
+	FLASH_II_READ_0x20 logbook_cur_depth			; read depth (2 bytes)
+	FLASH_CC_READ_0x20 ul							; read Profile Flag Byte
 
 	bcf		event_occured							; clear flag by default
-	btfsc	gaslist_gas,7							; event recorded?
+	btfsc	ul,7									; event recorded?
 	bsf		event_occured							; YES - we also have an event byte
-	bcf		gaslist_gas,7							; clear event byte flag (if any)
+	bcf		ul,7									; clear event byte flag (if any)
 
-	; gaslist_gas now holds the number of additional bytes to ignore (0-127)
+	; ul now holds the number of additional bytes to ignore (0-127)
 
-	; check for end of profile
+	;---- 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
@@ -1116,14 +1104,15 @@
 	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 temperature if available AND divisor reached AND bytes available
+	;---- temperature ------------------------------
+
 	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							;           - ...
+	FLASH_II_READ_0x20 logbook_cur_tp				;       YES - read temperature (2 bytes)
+	decf	ul,F									;           - reduce counter twice
+	decf	ul,F									;           - ...
 	movff	divisor_temperature,count_temperature	;           - restart counter
 
 	; compute max temperature on the fly...
@@ -1143,37 +1132,41 @@
 profile_view_compute_max_temp:
 	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:
+
+	;---- deco ceiling -----------------------------
+
 	movf	divisor_deco,W
 	bz		profile_view_get_depth_no_deco
 	decf	count_deco,F
 	bnz		profile_view_get_depth_no_deco
 
-	FLASH_CC_READ_0x20 logbook_ceiling					; read the ceiling
-	decf	gaslist_gas,F							; reduce the counter
+	FLASH_CC_READ_0x20 logbook_ceiling				; read the ceiling
+	decf	ul,F									; reduce the counter
 	movff	divisor_deco,count_deco					; restart counter
-	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 ------------------
+	EXT_FLASH_INC_ADDRESS_0x20 d'1'					; skip the stop duration
+	decf	ul,F									; reduce the counter
 
 profile_view_get_depth_no_deco:
 	; then skip remaining bytes...
-	movf	gaslist_gas,W							; get number of additional bytes to ignore (0-127)
+	movf	ul,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
+	call	ext_flash_inc_address_0x20_exec			; YES - skip #WREG bytes
+	return											; done
+
 
+;-----------------------------------------------------------------------------
+; get Information about Event(s)
+;
 profile_view_get_depth_events:
 	clrf	event_byte2								; clear event byte 2
-	FLASH_CC_READ_0x20 event_byte1						; read  event byte 1
-	decf	gaslist_gas,F							; reduce counter
+	FLASH_CC_READ_0x20 event_byte1					; read  event byte 1
+	decf	ul,F									; reduce counter
 
 	btfss	event_byte1,7							; another event byte?
 	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
+	FLASH_CC_READ_0x20 event_byte2					; YES - read event byte 2
+	decf	ul,F									;     - reduce counter
 	bcf		event_byte1,7							;     - clear flag
 
 profile_no_second_eventbyte:
@@ -1188,8 +1181,8 @@
 	rcall	logbook_event2							; YES
 	; any alarm?
 	bcf		event_byte1,4							; clear bits already tested
-	bcf		event_byte1,5
-	bcf		event_byte1,6
+	bcf		event_byte1,5							; ...
+	bcf		event_byte1,6							; ...
 	movlw	.6										; coding for manual marker
 	cpfseq	event_byte1								; manual marker set?
 	return											; NO  - done
@@ -1197,20 +1190,20 @@
 	return											;     - done
 
 logbook_event4:										; stored gas changed
-	FLASH_CC_READ_0x20 backup_color1					; read gas number, to be used as color index
-	decf	gaslist_gas,F							; reduce counter
+	FLASH_CC_READ_0x20 backup_color1				; read gas number, to be used as color index
+	decf	ul,F									; reduce counter
 	call	TFT_color_code_gas						; change profile color according to gas number (still in WREG)
-	return
+	return											; done
 
 logbook_event1:										; gas 6 used
 	bsf		event_gas_change_gas6					; set event flag
 	movlw	.6										; use gas 6 color
 	movwf	backup_color1							; select color for gas 6
 	call	TFT_color_code_gas						; set profile color
-	ext_flash_inc_address_0x20 d'2'					; skip two bytes
-	decf	gaslist_gas,F							; reduce counter
-	decf	gaslist_gas,F							; reduce counter
-	return
+	EXT_FLASH_INC_ADDRESS_0x20 d'2'					; skip two bytes
+	decf	ul,F									; reduce counter
+	decf	ul,F									; reduce counter
+	return											; done
 
 logbook_event2:										; bailout
 	bsf		bailout_mode							; set flag
@@ -1218,14 +1211,14 @@
 	movlw	.6										; use Gas6 color
 	movwf	backup_color1
 	call	TFT_color_code_gas						; use gas 6 color
-	ext_flash_inc_address_0x20 d'2'					; skip two bytes
-	decf	gaslist_gas,F							; reduce counter
-	decf	gaslist_gas,F							; reduce counter
-	return
+	EXT_FLASH_INC_ADDRESS_0x20 d'2'					; skip two bytes
+	decf	ul,F									; reduce counter
+	decf	ul,F									; reduce counter
+	return											; done
 
 logbook_event3:										; setpoint change
-	ext_flash_inc_address_0x20 d'1'					; skip one byte
-	decf	gaslist_gas,F							; reduce counter
+	EXT_FLASH_INC_ADDRESS_0x20 d'1'					; skip one byte
+	decf	ul,F									; reduce counter
 	btfss	bailout_mode							; in bailout?
 	return											; NO  - done
 	movff	backup_color2,backup_color1				; YES - restore color
@@ -1233,10 +1226,12 @@
 	call	TFT_color_code_gas						;     - back to normal profile color
 	return											;     - done
 
-; ------------------------------------------------------------------------
 
+;-----------------------------------------------------------------------------
+; Helper Function - return to Dive List
+;
 exit_profileview:
-	clrf	gaslist_gas								; restore all registers to build same page again
+	clrf	ul										; restore all registers to build same page again
 	movff	logbook_divenumber_temp,logbook_divenumber
 	movff	logbook_max_dive_counter_temp,logbook_max_dive_counter
 	movff	logbook_temp_backup,logbook_temp
@@ -1247,8 +1242,12 @@
 	movlw	logbook_row_number
 	movwf	menu_pos_cur							; here: active row on current page
 	call	TFT_boot
-	goto	logbook2								; start search
+	goto	logbook2								; display dive headers
+
 
+;-----------------------------------------------------------------------------
+; Helper Function - show next Page
+;
 next_logbook2:
 	btfsc	all_dives_shown							; all shown?
 	goto	logbook									; YES
@@ -1258,13 +1257,17 @@
 	incf	logbook_page_number,F					; start new screen
 	bsf		keep_cursor_new_page					; keep cursor on "next page"
 	call	TFT_boot
-	goto	logbook2								; start search
+	goto	logbook2								; display dive headers
+
 
+;-----------------------------------------------------------------------------
+; Helper Function - move Cursor
+;
 next_logbook3:
 	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
+	bra		next_logbook3a							; NO  - ok, done
 	movlw	.1										; YES - reset to first line
 	movwf	menu_pos_cur							;     - ...
 	bra		next_logbook3b							;     - done
@@ -1281,38 +1284,41 @@
 	bsf		all_dives_shown							; NO - set flag to load first page again (full reset)
 
 next_logbook3b:
-	call	TFT_logbook_cursor
-	goto	logbook_loop_pre
+	call	TFT_logbook_cursor						; show the cursor
+	goto	logbook_loop_pre						; serve HMI
 
-; ------------------------------------------------------------------
-; list one dive
+
+;-----------------------------------------------------------------------------
+; Helper Function - display Dive Summery
 ;
 display_listdive:
 	bsf		logbook_page_not_empty					; flag page will not be empty
 	incf	menu_pos_max,F							; increment number of lines shown
 
-	lfsr	FSR2,buffer								; initialize output buffer
-	WIN_FONT FT_SMALL								; select font
+	FONT_SIZE FT_SMALL								; set font size
+	FONT_COLOR_MEMO									; set font color
 	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
+	INIT_BUFFER										; initialize output buffer
 
 	; 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									; print dive number
-	bcf		leftbind								; end left-alignment
+	bcf		leftbind								; make sure dive number is printed in 5 digit format
+	output_65535									; print dive number (0-65535)
+	movff	buffer+2,buffer+0						; drop first 2 digits
+	movff	buffer+3,buffer+1						; ...
+	movff	buffer+4,buffer+2						; ...
+	movlw	.3										; relocate buffer pointer
+	movwf	FSR2L									; ...
 
 	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
-
+	call	output_date_short						; print date (day and month)
 	PUTC	' '										; print a space char
 
 	; print dive depth
@@ -1325,48 +1331,47 @@
 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
+	output_999										; print depth (0-999)
 	STRCAT_TEXT tFeets1								; print unit label
 	bra		display_listdive3						; continue with common part
 
 display_listdive2_metric:
-	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
+	bsf		omit_digit_1							; do not print 1st digit (no cm)
+	bsf		decimal_digit2							; place a decimal point in front of digit 2
+	output_65535									; print depth (0.0x-655.3x)
 	STRCAT_TEXT tMeters								; print unit label
-	PUTC	' '										; print one space char
+	PUTC	' '										; append one space char
 	;bra	display_listdive3						; continue with common part
 
 	; print dive time
 display_listdive3:
 	MOVII	header_buffer+index_divetime,mpr		; get dive time (minutes only)
-	output_16_3										; print minutes (0-999 min)
+	output_999										; print minutes (0-999)
 	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
-
+	movlw	.21										; max string length is 21 chars
+	call	TFT_buffer_trim_length					; fill or cut buffer to correct length
+	PRINT											; dump to screen
 	return											; done
 
-; ------------------------------------------------------------------
 
+;-----------------------------------------------------------------------------
+; Helper Function - show Dive Number
+;
 logbook_show_divenumber:
 	WIN_MEDIUM	logbook_divenumer_column, logbook_divenumer_row
 	movf	divenumber,W							; log_compute_divenumber needs the list number
 	call	log_compute_divenumber					; compute dive number
-	bsf		leftbind
-	output_16										; show dive number
-	bcf		leftbind
-	STRCAT_PRINT ""									; finalize output
+	bsf		leftbind								; print left-aligned
+	output_65535									; show dive number
+	PRINT											; print buffer to screen
 	return											; done
 
 
 ;-----------------------------------------------------------------------------
 ;  1st Details Page after Profile: Dive Statistics
-
+;
 logbook_page1:										; show more info
-	rcall	log_details_header						; shows number, time/date and basic dive info
+	rcall	log_details_header						; show number, time/date and basic dive data
 
 	btfss	aux_flag								; dive done in a deco mode?
 	bra		logbook_page1_1							; NO
@@ -1380,28 +1385,26 @@
 
 logbook_decomodel_2:
 	; deco model GF version
-	STRCAT_PRINT "ZHL-16+GF"
-	WIN_SMALL .5,.90
-	STRCPY_TEXT tGF2
+	STRCAT_PRINT "ZH-L16+GF"						; print model label
+	WIN_SMALL .5,.90								; set position
+	STRCPY_TEXT tSD2								; print label
 	MOVII	header_buffer+index_gf_lo_hi,mpr		; get  GF factors
-	output_8										; print GF lo
-	STRCAT	"%/"
-	movff	hi,lo									; print GF hi
-	output_8										; ...
-	STRCAT_PRINT "%"
-	bra		logbook_cns
+	bra		logbook_decomodel_com					; continue with common part
 
 logbook_decomodel_1:
 	; deco model none-GF version
-	STRCAT_PRINT "ZH-L16"
-	WIN_SMALL .5,.90
+	STRCAT_PRINT "ZH-L16"							; print model label
+	WIN_SMALL .5,.90								; set position
+	STRCPY_TEXT tGF2								; print label
 	MOVII	header_buffer+index_factor_sat_desat,mpr; get both factors
-	output_8										; print saturation factor
+	;bra	logbook_decomodel_com					; continue with common part
+
+logbook_decomodel_com:
+	output_256										; print saturation factor
 	STRCAT	"%/"
 	movff	hi,lo									; print desaturation factor
-	output_8										; ...
-	STRCAT_PRINT "%"
-	;bra	logbook_cns
+	output_256										; ...
+	PUTC_PRINT "%"									; append unit and dump buffer to screen
 
 logbook_cns:
 	WIN_SMALL .5,.115
@@ -1409,13 +1412,13 @@
 	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
-	STRCAT	"->"
+	output_999										; print CNS % (0-999)
+	STRCAT	"->"									; print an arrow
 	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 "%"
+	output_999										; print CNS % (0-999)
+	PUTC_PRINT "%"									; append unit and dump buffer to screen
 
 logbook_page1_1:
 	WIN_SMALL .5,.140
@@ -1428,96 +1431,102 @@
 
 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
+	PUTC	' '										; addend a space
+	output_999										; print depth (0-999)
+	STRCAT_PRINT "ft"								; append unit and dump to screen
+	bra		logbook_page1_1_common					; continue
 
 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
+	bsf		decimal_digit2							; place a decimal point in front of digit 2
+	bsf		omit_digit_1							; do not print 1st digit
+	output_65535									; print depth (0.0x - 999.9x)
+	PUTC_PRINT "m"									; append unit and dump buffer to screen
+	;bra	logbook_page1_1_common					; continue
 
 logbook_page1_1_common:
 	btfss	aux_flag								; dive done in a deco mode?
 	bra		logbook_page1_2							; NO
 
 	; Salinity
-	WIN_SMALL .5,.165								; ex WIN_SMALL .5,.140
-	STRCPY_TEXT tDvSalinity2
-	bsf		leftbind
+	WIN_SMALL .5,.165								; set position
+	STRCPY_TEXT tDvSalinity2						; print label
 	MOVCC	header_buffer+index_salinity,lo			; read salinity
-	output_8
-	STRCAT_PRINT "%"
+	output_99										; print salinity (0-99, effectively 0-4 with leading space)
+	PUTC_PRINT "%"									; append unit and dump to screen
 
 	; Last deco
-	WIN_SMALL .5,.190
-	STRCPY_TEXT tLastDeco
+	WIN_SMALL .5,.190								; set position
+	STRCPY_TEXT tLastDeco							; print label
 	MOVCC	header_buffer+index_last_stop,lo		; read last stop depth
-	output_8
-	STRCAT_PRINT "m"
+	output_99										; print depth (0-99, effectively 0-6 with leading space)
+	PUTC_PRINT "m"									; append unit and dump to screen
 
 logbook_page1_2:
-	movlw	color_lightblue
-	call	TFT_set_color
-	WIN_FRAME_COLOR16 .63,.220,.2,.105				; top, bottom, left, right
+	movlw	color_lightblue							; select color
+	WIN_FRAME_COLOR .63,.220,.2,.105				; top, bottom, left, right
 
 	; Firmware
-	call	TFT_standard_color
-	WIN_SMALL .110,.65
-	STRCAT	"V:"
+	FONT_COLOR_MEMO									; set font color
+	WIN_SMALL .110,.65								; set output position
+	STRCAT	"V:"									; print "V:"
 	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 version (in 1 digit due to leftbind)
+	output_99										; print major version
 	PUTC	"."										; print "."
 	movff	hi,lo									; print minor version...
 	output_99x										; ... in 2 digit format
-	STRCAT_PRINT ""									; finalize output
+	PRINT											; print buffer to screen
 
+logbook_battery_hwos_tech:
+	; all hwos tech >= 2.15 also stored battery %
 	movf	up,W									; get major into WREG
 	xorlw	.3										; major == 3 ?
 	bz		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 %
+	bnz		logbook_battery_hwos_sport				;       NO  - check for hwos sport
 	movlw	.14										;       YES - check minor version
 	cpfsgt	lo										;           - minor > 14 ?
-	bra		logbook_battery_voltage					;             NO  - skip battery %
-	;bra	logbook_battery_percent					;             YES - show battery %
+	bra		logbook_battery_hwos_sport				;             NO  - check for hwos sport
+	bra		logbook_battery_percent					;             YES - show battery %
+
+logbook_battery_hwos_sport:
+	; all hwos_sport >= 10.34 also stored battery %
+	; check major again for .10 (for maintainability)
+	movf	up,W									; get major into WREG
+	xorlw	.10										; major == 10 ?
+	bnz		logbook_battery_voltage					; NO  - skip battery %
+	movlw	.33										; YES - check minor version
+	cpfsgt	lo										;     - minor > 33 ?
+	bra		logbook_battery_voltage					;       NO  - skip battery %
+	;bra	logbook_battery_percent					;       YES - show battery %
 
 	; Battery %
 logbook_battery_percent:
 	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
+	output_256										; print battery percent
+	PUTC_PRINT "%"									; append "%" and dump buffer to screen
 
 	; Battery Voltage
 logbook_battery_voltage:
-	WIN_SMALL .110,.90
-	STRCAT_PRINT "Batt:"
-	WIN_SMALL .110,.115
-	MOVII	header_buffer+index_battery_voltage,mpr	; get   battery voltage
-	output_16dp .2									; print battery voltage
-	STRCAT_PRINT "V"								; print unit (Volt)
+	WIN_SMALL .110,.90								; set position
+	STRCAT_PRINT "Batt:"							; print label
+	WIN_SMALL .110,.115								; set position
+	MOVII	header_buffer+index_battery_voltage,mpr	; get battery voltage
+	bsf		decimal_digit3							; place a decimal point in front of digit 3
+	output_9999										; print battery voltage (0.000-9.999)
+	PUTC_PRINT "V"									; append unit and dump buffer to screen
 
 	; Surface Pressure
 	MOVII	header_buffer+index_surface_press,mpr	; get surface pressure
 	WIN_SMALL .110,.165								; set output position
-	bsf		leftbind								; print without leading spaces
-	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
+	output_9999										; print surface pressure before dive (0-9999)
+	STRCAT_TEXT_PRINT tMBAR							; append unit and dump to screen
 
 	movlw	color_greenish							; select color
-	call	TFT_set_color							; ...
-	WIN_FRAME_COLOR16 .63,.220,.107,.159			; draw a frame with coordinates top, bottom, left, right
+	WIN_FRAME_COLOR .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
@@ -1537,30 +1546,19 @@
 
 ;-----------------------------------------------------------------------------
 ;  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
+	; skip this page for dives recorded with internal profile < 0x01
 
-	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
+	MOVCC	header_buffer+index_profile_version,WREG; read profile format version
+	andlw	b'11000000'								; keep only the internal part of the profile version
+	bnz		logbook_page2a							; show page 2 if internal version  > 0
+	bra		logbook_page3							; skip page 2 if internal version is 0
 
-; ################# to be removed later ##################################
-display_page2_betajump:
-; ########################################################################
+logbook_page2a:
 
-	rcall	log_details_header						; shows number, time/date and basic dive info
+	rcall	log_details_header						; show number, time/date and basic dive data
 
 	; basic configuration of tissue graphics
 	bsf		tissue_graphic_mode						; select logbook mode
@@ -1574,7 +1572,7 @@
 	bsf		tissue_graphic_gf						; YES - show GF lines
 
 	; draw the graphics
-	call	TFT_surface_tissues
+	call	TFT_surf_cv_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
@@ -1586,14 +1584,14 @@
 	; 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
+	call	output_date_short							; print date (day and month)
 	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
+	PRINT												; print buffer to screen
 
 
 	; draw a white frame around the time/date
@@ -1614,9 +1612,8 @@
 	; 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
+	output_256										; print percent value
+	PUTC_PRINT "%"									; append "%" and dump buffer to screen
 
 	; 3rd line: 
 	WIN_SMALL .100,.118
@@ -1625,9 +1622,8 @@
 	; 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
+	output_256										; print percent value
+	PUTC_PRINT "%"									; append "%" and dump buffer to screen
 
 	; 5th line: desaturation time label
 	WIN_SMALL .100,.168
@@ -1644,15 +1640,14 @@
 	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
+	PUTC_PRINT "m"									; append minutes mark and dump buffer to screen
 
 	; 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
+	WIN_FRAME_COLOR .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
+	rcall	logbook_preloop_tasks					; clear timeout and left-over button events
 display_details1b_loop:
 	btfsc	switch_right							; right button pressed?
 	bra		logbook_page3							; YES - show more info
@@ -1663,11 +1658,12 @@
 
 
 ;-----------------------------------------------------------------------------
-; helper function
+; Helper Function - clear Timeout and left-over Button Events
+;
 logbook_preloop_tasks:
 	movlw	CCP1CON_VALUE							; see hwos.inc
 	movwf	CCP1CON									; power-on backlight
-	call	TFT_standard_color						; revert to standard color
+	FONT_COLOR_MEMO									; revert font color to standard
 	call	reset_timeout_surfmode					; reset timeout
 	bcf		switch_left								; clear left-over left  button event
 	bcf		switch_right							; clear left-over right button event
@@ -1675,12 +1671,12 @@
 
 ;-----------------------------------------------------------------------------
 ; 3rd Details Page after Profile: Gases / Diluents
-
+;
 logbook_page3:
-	rcall	log_details_header						; shows number, time/date and basic dive info
+	rcall	log_details_header						; show number, time/date and basic dive data
+
 	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
 
 	WIN_SMALL .5,.90
 	movlw	.1										; color for gas 1
@@ -1703,8 +1699,8 @@
 	rcall	log_show_gas
 
 	; OC/CC gas list
-	WIN_SMALL .5,.65
-	WIN_COLOR color_greenish
+	WIN_SMALL .5,.65								; set title position
+	FONT_COLOR color_greenish						; set title color
 
 	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 ?
@@ -1714,9 +1710,8 @@
 logbook_page3a:
 	STRCPY_TEXT_PRINT tGaslist						; print OC title
 logbook_page3b:
-	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
+	movlw	color_lightblue							; select frame color
+	WIN_FRAME_COLOR .63,.220,.2,.114				; draw frame (top, bottom, left, right)
 
 	; handle HMI
 	rcall	logbook_preloop_tasks					; clear timeout, some flags and set to speed_eco
@@ -1731,34 +1726,33 @@
 
 ;-----------------------------------------------------------------------------
 ; 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
+	rcall	log_details_header						; show number, time/date and basic dive data
 
 	; 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
-	call	TFT_standard_color
-	WIN_SMALL .5,.90
-	rcall	  log_show_sp
-	WIN_SMALL .5,.115
-	rcall	  log_show_sp
-	WIN_SMALL .5,.140
-	rcall	  log_show_sp
-	WIN_SMALL .5,.165
-	rcall	  log_show_sp
-	WIN_SMALL .5,.190
-	rcall	  log_show_sp
+	WIN_SMALL .5,.65								; set title position
+	FONT_COLOR color_greenish						; set title color
+	STRCPY_TEXT_PRINT tFixedSetpoints				; print title
+	FONT_COLOR_MEMO									; set font color
+	WIN_SMALL .5,.90								; set position
+	rcall	  log_show_sp							; print setpoint data set
+	WIN_SMALL .5,.115								; set position
+	rcall	  log_show_sp							; print setpoint data set
+	WIN_SMALL .5,.140								; set position
+	rcall	  log_show_sp							; print setpoint data set
+	WIN_SMALL .5,.165								; set position
+	rcall	  log_show_sp							; print setpoint data set
+	WIN_SMALL .5,.190								; set position
+	rcall	  log_show_sp							; print setpoint data set
 
-	movlw	color_greenish
-	call	TFT_set_color
-	WIN_FRAME_COLOR16 .63,.220,.2,.112				; top, bottom, left, right
+	movlw	color_greenish							; select color for the frame
+	WIN_FRAME_COLOR .63,.220,.2,.112				; draw frame (top, bottom, left, right)
 
 	; handle HMI
 	rcall	logbook_preloop_tasks					; clear timeout, some flags and set to Speed_eco
@@ -1772,27 +1766,25 @@
 
 
 ;-----------------------------------------------------------------------------
-; Helper Functions
-
+; Helper Function - show Dive Number, Time/Date and basic Dive Data
+;
 log_details_header:
-	call	TFT_boot
-	call	TFT_standard_color
+	call	TFT_boot								; initialize display
+	FONT_COLOR_MEMO									; set font color
 
 	rcall	logbook_show_divenumber					; show the dive number in medium font
 
 	; show date and time in first row
 	WIN_SMALL .59,.10
 	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	output_date								; print date
+	PUTC	"-"										; print "-"
 	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
+	PRINT											; dump to screen
 
 	; show max depth and dive time
 	WIN_SMALL .5,.35
@@ -1805,32 +1797,33 @@
 
 logbook_page2_depth_imperial:
 	call	convert_cm_to_feet						; convert value in lo:hi from [cm] to [feet]
-	PUTC	' '
-	bcf		leftbind
-	output_16_3
-	STRCAT_TEXT tFeets
-	bra		logbook_page2_depth_common
+	PUTC	' '										; append a space
+	output_999										; print depth
+	STRCAT_TEXT tFeets								; append unit
+	bra		logbook_page2_depth_common				; continue
 
 logbook_page2_depth_metric:
-	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
+	bsf		omit_digit_1							; do not print 1st digit
+	bsf		decimal_digit2							; place a decimal point in front of digit 2
+	output_65535									; print depth (0.0x-655.3x)
+	STRCAT_TEXT tMeters								; append unit
+	;bra	logbook_page2_depth_common				; continue
 
 logbook_page2_depth_common:
 	STRCAT	" - "
 	MOVTT	header_buffer+index_divetime,mpr		; get dive time
-	bsf		leftbind
-	output_16										; print minutes
-	PUTC	"m"
+	bsf		leftbind								; print left-aligned
+	output_9999										; print minutes (0-9999)
+	PUTC	"m"										; append unit
 	movff	up,lo									; print seconds
 	output_99x										; ...
-	STRCAT_PRINT "s"
-	return
+	PUTC_PRINT "s"									; append unit and dump buffer to screen
+	return											; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - show Setpoint Data
+;
 log_show_sp:
 	; log point is set by caller
 	MOVCC	POSTINC0,lo								; copy set point    into lo
@@ -1838,11 +1831,11 @@
 
 	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'								; print setpoint x.xx
-	bcf		leftbind
-	STRCAT_TEXT tbar
-	PUTC	" "
+	bsf		leftbind								; print left-aligned
+	bsf		decimal_digit2							; place a decimal point in front of digit 2
+	output_999										; print setpoint (0.00-9.99)
+	STRCAT_TEXT tbar								; append unit
+	PUTC	" "										; append a space
 	movff	mpr+2,mpr+0								; restore change depth to lo
 
 	TSTOSS	opt_units								; 0=Meter, 1=Feet
@@ -1851,33 +1844,34 @@
 
 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
+	output_999										; print depth (0-999)
+	PUTC	" "										; append space
+	STRCAT_TEXT_PRINT tFeets						; append unit and dump to screen
+	return											; done
 
 log_show_sp_metric:
-	output_8
-	PUTC	" "
-	STRCAT_TEXT tMeters								; "m"
-	;bra	log_show_sp_common
-
-log_show_sp_common:
-	STRCAT_PRINT ""
-	return
+	output_256										; print depth (0-256)
+	PUTC	" "										; append space
+	STRCAT_TEXT_PRINT tMeters						; append unit and dump to screen
+	return											; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - show Gas Data
+;
 log_show_gas:										; show gas data
 	call	TFT_color_code_gas						; color the output (gas number is in WREG)
-	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								; read O2 fraction into lo
+	MOVCC	POSTINC0,hi								; read He fraction into hi
+	call	gaslist_strcat_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 - do short version
-	;bra	log_show_gas_long						; NO  - add gas types
+	MOVCC	POSTINC0,lo								; read change depth into lo
+	MOVCC	POSTINC0,hi								; read gas    type  into hi
+
+	btfss	log_show_gas_short						; shall do the short version?
+	bra		log_show_gas_long						; NO  - add gas types
+	PRINT											; YES - dump to screen
+	return											; done
 
 log_show_gas_long:
 	PUTC	" "										; put one space between gas composition and gas type marking
@@ -1901,26 +1895,26 @@
 log_show_gas_4:
 	PUTC	" "										; put one space between gas type marking and change depth
 
+	bsf		leftbind								; print left-aligned
 	TSTOSS	opt_units								; 0=Meter, 1=Feet
 	bra		log_show_gas_metric						; 0 - do metric
 	;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
+	output_999										; print depth (0-999)
+	STRCAT_TEXT_PRINT tFeets						; append unit and dump to screen
+	return											; done
 
 log_show_gas_metric:
-	output_8
-	STRCAT_TEXT tMeters								; "m"
-	;bra	log_show_gas_common
-
-log_show_gas_common:
-	STRCAT_PRINT ""
-	return
+	output_256										; print depth (0-255)
+	STRCAT_TEXT_PRINT tMeters						; append unit and dump to screen
+	return											; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - compute Dive Number
+;
 log_compute_divenumber:
 	movwf	mpr+2									; store current dive number in mpr+2
 	call	eeprom_log_offset_read					; read log offset into mpr+0 & +1
@@ -1951,10 +1945,11 @@
 	MOVII	sub_c,mpr								;     - copy result back to mpr
 	return											;     - done
 
-;----------------------------------------------------------------------------
-; Compute flash address for header data of a particular dive
+
+;-----------------------------------------------------------------------------
+; Helper Function - compute Flash Address of Header by Dive Number
 ;
-; Memory map in flash:
+; Memory Map in Flash:
 ;
 ; low(total number of dives) -> index -> start address    end address
 ; --------------------------------------------------------------------
@@ -1963,9 +1958,9 @@
 ;          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'
+	; compute dive index from of the dive number
 	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)
@@ -1973,23 +1968,24 @@
 	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
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - compute Flash Address of Header by Dive 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
+	movwf	lo										; copy index to lo
+	movlw	.16										; prepare a shift left by 4 bit -> multiply with 16
+	mulwf	lo										; shift left the index to create the offset
+	clrf	ext_flash_address+0						; clear    low   byte of the address
+	movf	PRODL,W									; get      low   byte of the offset
+	movwf	ext_flash_address+1						; store as high  byte of the address
+	movf	PRODH,W									; get      high  byte of the offset
+	addlw	0x20									; add 0x20
+	movwf	ext_flash_address+2						; store as upper byte of the address
+	return											; done
 
 ; ----------------------------------------------------------------
 
-	END
\ No newline at end of file
+	END
--- a/src/math.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/math.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File math.asm                             combined next generation V3.04.3
+;   File math.asm                           * combined next generation V3.09.4k
 ;
 ;   Math subroutines
 ;
@@ -12,28 +12,17 @@
 
 #include "hwos.inc"						; mandatory header
 
-math	CODE
 
 ;=============================================================================
+math1	CODE
+;=============================================================================
 
-	global	convert_time				; converts hi:lo in minutes to hours (up:hi) and minutes (lo)
-										; also usable for conversion of seconds to minutes and seconds
-										; trashes xA, xB, xC
-convert_time:
-	movff	lo,xA+0						; copy hi:lo to xA
-	movff	hi,xA+1						;
-	movlw	d'60'						; set divisor to 60
-	movwf	xB+0						; write 60 to xB
-	clrf	xB+1						; 
-	rcall	div16x16					; xC = xA / xB with xA as remainder
-	movff	xC+1,up						; result    is hours   / minutes, copy to up (high byte)
-	movff	xC+0,hi						; result    is hours   / minutes, copy to hi (low  byte)
-	movff	xA+0,lo						; remainder is minutes / seconds, copy to lo
-	return
-
-
-	global	div16						; divA:2 = divA:2 / 2^WREG
-										; trashes WREG
+;-----------------------------------------------------------------------------
+; Divide a 16 Bit Integer by a Power of 2:  divA:2 = divA:2 / 2^WREG
+;
+; trashes WREG
+;
+	global	div16
 div16:
 	bcf		STATUS,C					; clear carry
 	rrcf	divA+1						; rotate right high byte, carry into MSB, LSB into carry
@@ -43,8 +32,16 @@
 	return								; YES - done
 
 
-	global	mult16						; xA:2 = xA:2 * 2^WREG
-										; trashes WREG
+;=============================================================================
+math2	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Multiply a 16 bit Integer by a Power of 2:  xA:2 = xA:2 * 2^WREG
+;
+; trashes WREG
+;
+	global	mult16
 mult16:
 	bcf		STATUS,C					; clear carry
 	rlcf	divA+0,F					; rotate left low  byte, carry into LSB, MSB into carry
@@ -54,8 +51,16 @@
 	return								; YES - done
 
 
-	global	addU16						; ; sub_c:2 = sub_a:2 + sub_b:2	with USIGNED values
-										; trashes WREG
+;=============================================================================
+math3	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Add two UNSIGNED 16 bit Integers:  sub_c:2 = sub_a:2 + sub_b:2
+;
+; trashes WREG
+;
+	global	addU16
 addU16:
 	movf	sub_a+0,W					; get 1st summand (low  byte) to WREG
 	addwf	sub_b+0,W					; add 2nd summand (low  byte) and store result in WREG
@@ -66,9 +71,16 @@
 	return								; done
 
 
-	global	sub16						; sub_c:2 = sub_a:2 - sub_b:2   with SIGNED values
-										; sets neg_flag if result is < 0
-										; trashes WREG
+;=============================================================================
+math4	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Subtract two SIGNED 16 Bit Integers:  sub_c:2 = sub_a:2 - sub_b:2
+;
+; sets neg_flag if result is < 0, trashes WREG
+;
+	global	sub16
 sub16:
 	bcf		neg_flag					; clear flag which will indicate if result is negative
 	movf	sub_b+0,W					; get value to be subtracted, low byte
@@ -87,9 +99,16 @@
 	return								;     - done
 
 
-	global	subU16						; sub_c:2 = sub_a:2 - sub_b:2   with UNSIGNED values
-										; sets neg_flag if result is < 0
-										; trashes WREG
+;=============================================================================
+math5	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Subtract two UNSIGNED 16 Bit Integers:  sub_c:2 = sub_a:2 - sub_b:2
+;
+; sets neg_flag if result is < 0, trashes WREG
+;
+	global	subU16
 subU16:
 	bcf		neg_flag					; clear flag which will indicate if result is negative
 	movf	sub_b+0,W					; get value to be subtracted, low byte
@@ -108,9 +127,17 @@
 	return								;     - done
 
 
-	global	cmpU16						; sub_a:2 - sub_b:2	with UNSIGNED values
-										; sets neg_flag if result is < 0, but does not store result itself
-										; trashes WREG
+;=============================================================================
+math6	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Compare two UNSIGNED 16 Bit Integers:  sub_a:2 - sub_b:2
+;
+; sets neg_flag if result is < 0, trashes WREG
+; the subtraction result is not stored
+;
+	global	cmpU16
 cmpU16:
 	bcf		neg_flag					; clear flag which will indicate if result is negative
 	movf	sub_b+0,W					; get value to be subtracted, low byte
@@ -122,44 +149,61 @@
 	return								; done
 
 
-	global	mult16x16					; xC:4 = xA:2 * xB:2   with UNSIGNED values
-										; trashes PRODL, PRODH, WREG
+;=============================================================================
+math7	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Multiply two UNSIGNED 16 bit Integers:  xC:4 = xA:2 * xB:2
+;
+; trashes PRODL, PRODH, WREG
+;
+	global	mult16x16
 mult16x16:
 	clrf	xC+2						; clear the high-order bits
-	clrf	xC+3
-	;
+	clrf	xC+3						; ...
+
 	movf	xA+0,W						; do the "L" multiplication
 	mulwf	xB+0
 	movff	PRODL,xC+0					; copy result to xC
 	movff	PRODH,xC+1
-	;
+
 	movf	xA+0,W						; do the "I" multiplication
 	mulwf	xB+1
 	movf	PRODL,W						; get the product's low byte...
 	addwf	xC+1,F						; ... and add it to xC+1
 	movf	PRODH,W						; get the product's high byte...
 	addwfc	xC+2,F						; ... and add it to xC+2 obeying carry bit from xC+1
-	;
+
 	movf	xA+1,W						; do the "O" multiplication
 	mulwf	xB+0
-	movf	PRODL,W						;  get the product's low byte...
+	movf	PRODL,W						; get the product's low byte...
 	addwf	xC+1,F						; ... and add it to xC+1
 	movf	PRODH,W						; get the product's high byte...
 	addwfc	xC+2,F						; ... and add it to xC+2 obeying carry bit from xC+1
 	clrf	WREG						; clear WREG...
 	addwfc	xC+3,F						; ... add add it to xC+3 obeying carry bit from xC+2 (can only happen in "O" multiplication)
-	;
+
 	movf	xA+1,W						; do the "F" multiplication
 	mulwf	xB+1
-	movf	PRODL,W						;   get the product's low byte...
+	movf	PRODL,W						; get the product's low byte...
 	addwf	xC+2,F						; ... and add it to xC+2
 	movf	PRODH,W						; get the product's high byte...
 	addwfc	xC+3,F						; ... and add it to xC+3 obeying carry bit from xC+2
-	return
+
+	return								; done
 
 
-	global	div16x16					; xC:2 = xA:2 / xB:2 with xA as remainder
-										; trashes WREG
+;=============================================================================
+math8	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Divide two UNSIGNED 16 Bit Integers:  xC:2 = xA:2 / xB:2 with xA as remainder
+;
+; trashes WREG
+;
+	global	div16x16
 div16x16:
 	movlw		.16						; process 16 bits ...
 	movwf		math_loop				; ... initialize loop counter
@@ -193,8 +237,16 @@
 	return								; YES - done
 
 
-	global	div32x16					; xC:4 = xC:4 / xB:2 with xA as remainder
-										; trashes WREG
+;=============================================================================
+math9	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Divide a 32 Bit Integer by a 16 Bit Integer: xC:4 = xC:4 / xB:2 with xA as remainder
+;
+; trashes WREG
+;
+	global	div32x16
 div32x16:
 	movlw		.32						; process 32 bits ...
 	movwf		math_loop				; ... initialize loop counter
@@ -228,73 +280,99 @@
 	return								; YES - done
 
 
+;-----------------------------------------------------------------------------
+;
+; ISR math functions
+;
+;-----------------------------------------------------------------------------
+
+;=============================================================================
+math10	CODE
 ;=============================================================================
 
-; ISR math functions
-
-	global	isr_shift_C31				; 24 bit shift, repeated WREG times, dedicated to a specific usage:
-										; Because less than 8 bits are shifted and only C[2:1] is needed,
-										; we don't care what bit is inserted.
+;-----------------------------------------------------------------------------
+; 24 Bit Shift, repeated WREG Times, dedicated to a specific Usage
+;
+; Because less than 8 bits are shifted and only C[2:1] is needed,
+; we don't care what bit is inserted.
+;
+	global	isr_shift_C31
 isr_shift_C31:
 	rrcf	isr_xC+3,F					; shift three bytes
-	rrcf	isr_xC+2,F
-	rrcf	isr_xC+1,F
+	rrcf	isr_xC+2,F					; ...
+	rrcf	isr_xC+1,F					; ...
 	decfsz	WREG						; decrement loop counter, done?
 	bra		isr_shift_C31				; NO  - loop
 	return								; YES - done
 
 
-	global	isr_unsigned_mult16x16		; isr_xC = isr_xA * _isr_xB   with UNSIGNED values
-										; trashes PRODL, PRODH, WREG
+;=============================================================================
+math11	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Multiply two UNSIGNED 16 Bit Integers: isr_xC = isr_xA * isr_xB
+;
+; trashes PRODL, PRODH, WREG
+;
+	global	isr_unsigned_mult16x16
 isr_unsigned_mult16x16:
 	movf	isr_xA+0,W					; multiply a[0] * b[0]
-	mulwf	isr_xB+0
+	mulwf	isr_xB+0					; ...
 	movff	PRODL,isr_xC+0				; store product to c[1]:c[0]
-	movff	PRODH,isr_xC+1
-	;
+	movff	PRODH,isr_xC+1				; ...
+
 	movf	isr_xA+1,W					; multiply a[1] * b[1]
-	mulwf	isr_xB+1
+	mulwf	isr_xB+1					; ...
 	movff	PRODL, isr_xC+2				; store product to  c[3]:c[2]
-	movff	PRODH, isr_xC+3
-	;
+	movff	PRODH, isr_xC+3				; ...
+
 	movf	isr_xA+0,W					; multiply a[0] * b[1]
-	mulwf	isr_xB+1
+	mulwf	isr_xB+1					; ...
 	movf	PRODL,W						; add cross product to c[3]:c[2]:c[1]
-	addwf	isr_xC+1,F
-	movf	PRODH,W
+	addwf	isr_xC+1,F					; ...
+	movf	PRODH,W						; ...
 	addwfc	isr_xC+2,F					; propagate carry
-	clrf	WREG
-	addwfc	isr_xC+3,F					; propagate carry
-	;
+	clrf	WREG						; ...
+	addwfc	isr_xC+3,F					; ...
+
 	movf	isr_xA+1,W					; multiply a[1] * b[0]
-	mulwf	isr_xB+0
+	mulwf	isr_xB+0					; ...
 	movf	PRODL,W						; add cross product
-	addwf	isr_xC+1,F
-	movf	PRODH,W
+	addwf	isr_xC+1,F					; ...
+	movf	PRODH,W						; ...
 	addwfc	isr_xC+2,F					; propagate carry
-	clrf	WREG
-	addwfc	isr_xC+3,F					; propagate carry
-	return
+	clrf	WREG						; ...
+	addwfc	isr_xC+3,F					; ...
+	return								; done
 
 
-	global	isr_signed_mult16x16		; isr_xC = isr_xA * isr_xB   with SIGNED values
-										; trashes PRODL, PRODH, WREG
+;-----------------------------------------------------------------------------
+; Multiply two   SIGNED 16 Bit Integers: isr_xC = isr_xA * isr_xB
+;
+; trashes PRODL, PRODH, WREG
+;
+	global	isr_signed_mult16x16
 isr_signed_mult16x16:
-	rcall	isr_unsigned_mult16x16		; do an unsigned multiplication first
-	;									; manage sign extension of operand B
+	; do an unsigned multiplication first
+	rcall	isr_unsigned_mult16x16
+
+	; manage sign extension of operand B
 	btfss	isr_xB+1,7					; is B negative ?
 	bra		isr_signed_mult_checkA		; NO  - continue checking operand A
-	movf	isr_xA+0,W					; Yes - add -65536 * A
-	subwf	isr_xC+2,F
-	movf	isr_xA+1,W
-	subwfb	isr_xC+3,F
+	movf	isr_xA+0,W					; YES - add -65536 * A
+	subwf	isr_xC+2,F					;     - ...
+	movf	isr_xA+1,W					;     - ...
+	subwfb	isr_xC+3,F					;     - ...
 isr_signed_mult_checkA					; manage sign extension of operand B
 	btfss	isr_xA+1,7					; is A negative ?
 	return								; NO  - done
-	movf	isr_xB+0,W					; Yes - add -65536 * B
-	subwf	isr_xC+2,F
-	movf	isr_xB+1,W
-	subwfb	isr_xC+3,F
-	return
+	movf	isr_xB+0,W					; YES - add -65536 * B
+	subwf	isr_xC+2,F					;     - ...
+	movf	isr_xB+1,W					;     - ...
+	subwfb	isr_xC+3,F					;     - ...
+	return								;     - done
+
+;-----------------------------------------------------------------------------
 
 	END
\ No newline at end of file
--- a/src/math.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/math.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File math.inc                             combined next generation V3.08.8
+;   File math.inc                           * combined next generation V3.09.4k
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -8,45 +8,94 @@
 ; HISTORY
 ;  2011-08-03 : [mH] moving from OSTC code
 
-	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					SHIFT-RIGHT    with UNSIGNED values
+;-----------------------------------------------------------------------------
+; SHIFT-RIGHT    with UNSIGNED values
+;
+	extern	div16					; divA:2 = divA:2 / 2^WREG
 									; trashes WREG
 
-	extern	mult16					; divA:2 = divA:2 * 2^WREG					SHIFT-LEFT     with UNSIGNED values
+
+;-----------------------------------------------------------------------------
+; SHIFT-LEFT     with UNSIGNED values
+;
+	extern	mult16					; divA:2 = divA:2 * 2^WREG
 									; trashes WREG
 
-	extern	addU16					; sub_c:2 = sub_a:2 + sub_b:2				ADDITION       with UNSIGNED values
+
+;-----------------------------------------------------------------------------
+; ADDITION       with UNSIGNED values
+;
+	extern	addU16					; sub_c:2 = sub_a:2 + sub_b:2
 									; trashes WREG
 
-	extern	sub16					; sub_c:2 = sub_a:2 - sub_b:2				SUBTRACTION    with SIGNED   values
+
+;-----------------------------------------------------------------------------
+; SUBTRACTION    with SIGNED   values
+;
+	extern	sub16					; sub_c:2 = sub_a:2 - sub_b:2
 									; sets neg_flag if result is < 0
 									; trashes WREG
 
-	extern	subU16					; sub_c:2 = sub_a:2 - sub_b:2				SUBTRACTION    with UNSIGNED values
+
+;-----------------------------------------------------------------------------
+; SUBTRACTION    with UNSIGNED values
+;
+	extern	subU16					; sub_c:2 = sub_a:2 - sub_b:2
 									; sets neg_flag if result is < 0
 									; trashes WREG
 
-	extern	cmpU16					; trashed = sub_a:2 - sub_b:2				COMPARE        with UNSIGNED values
+
+;-----------------------------------------------------------------------------
+; COMPARE        with UNSIGNED values
+;
+	extern	cmpU16					; trashed = sub_a:2 - sub_b:2
 									; sets neg_flag if result is < 0, but does not store result itself
 									; trashes WREG
 
-	extern	mult16x16				; xC:4 = xA:2 * xB:2						MULTIPLICATION with UNSIGNED values
+
+;-----------------------------------------------------------------------------
+; MULTIPLICATION with UNSIGNED values
+;
+	extern	mult16x16				; xC:4 = xA:2 * xB:2
 									; trashes PRODL, PRODH, WREG
 
-	extern	div16x16				; xC:2 = xA:2 / xB:2 with xA as remainder	DIVISION       with UNSIGNED values
+
+;-----------------------------------------------------------------------------
+; DIVISION       with UNSIGNED values
+;
+	extern	div16x16				; xC:2 = xA:2 / xB:2 with xA as remainder
 									; trashes xB, WREG
 
-	extern	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder	DIVISION       with UNSIGNED values
+
+;-----------------------------------------------------------------------------
+; DIVISION       with UNSIGNED values
+;
+	extern	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder	
 									; trashes WREG
 
-	extern	isr_shift_C31			; 24 bit shift, repeated WREG times, dedicated to a specific usage
+
+;-----------------------------------------------------------------------------
+; Math Functions specific for Use by ISR
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; 24 bit shift, repeated WREG times, dedicated to a specific usage
+;
+	extern	isr_shift_C31
 
 
-	extern	isr_unsigned_mult16x16	; isr_xC = isr_xA * isr_xB		MULTIPLICATION with UNSIGNED values ** for ISR only **
+;-----------------------------------------------------------------------------
+; MULTIPLICATION with UNSIGNED values
+;
+	extern	isr_unsigned_mult16x16	; isr_xC = isr_xA * isr_xB
 									; trashes PRODL, PRODH, WREG
 
-	extern	isr_signed_mult16x16	; isr_xC = isr_xA * isr_xB		MULTIPLICATION with SIGNED   values ** for ISR only **
+
+;-----------------------------------------------------------------------------
+; MULTIPLICATION with SIGNED   values
+;
+	extern	isr_signed_mult16x16	; isr_xC = isr_xA * isr_xB
 									; trashes PRODL, PRODH, WREG
+
+;-----------------------------------------------------------------------------
\ No newline at end of file
--- a/src/mcp.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/mcp.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File mcp.asm                              combined next generation V3.06.1
+;   File mcp.asm                            * combined next generation V3.06.1
 ;
 ;   Basic routines for RX circuity
 ;
@@ -13,18 +13,23 @@
 #include "hwos.inc"
 #include "wait.inc"
 
-mcp	code
 
 ;=============================================================================
+mcp		code
+;=============================================================================
 
+
+;-----------------------------------------------------------------------------
+; Disable IR Receiver
+;
 	global	mcp_sleep
 mcp_sleep:
 	bcf		INTCON3,INT3IE			; disable INT3
-	bcf		mcp_power				; request IR receiver off
-	btfsc	mcp_power				; off confirmed?
+	bcf		mcp_power				; power down IR receiver
+	btfsc	mcp_power				; power drained down?
 	bra		$-6						; NO  - loop waiting
 	return							; YES - done
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/menu_processor.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/menu_processor.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File menu_processor.asm                   combined next generation V3.08.6
+;   File menu_processor.asm                 * combined next generation V3.09.5
 ;
 ;   Routines to handle all hwOS graphic/text menus.
 ;
@@ -24,139 +24,136 @@
 #include "i2c.inc"
 #include "rtc.inc"
 #include "wait.inc"
+#include "colorschemes.inc"
 
 
 ; NOTE: needs to be identical in .inc and .asm !
+;
 #define MENU_LINES_MAX			.7			; maximum number of lines per screen
-#define MENU_TITLE_FONT			WIN_STD		; font needs to contain lower and UPPER chars
-#define MENU_LINE_FONT			WIN_SMALL	; font needs to contain lower and UPPER chars
 #define MENU_LEFT				.20			; position of first menu item
-#define MENU_HEIGHT				.27			; spacing between menu lines
+#define MENU_HEIGHT_SURF		.27			; spacing between menu item in surface mode (pixel)
+#define MENU_HEIGHT_DIVE		.24			; spacing between menu item in surface mode (pixel)
 #define MENU_VCENTER			.125		; position on screen
-#define MENU_LINE_MAX_LENGTH	.20			; length in characters
-#define option_item				proc_item
+#define MAX_LINE_LENGTH_TITLE	.17			; max menu title length                   (characters)
+#define MAX_LINE_LENGTH_SURF	.20			; max menu item  length in surface   menu (characters)
+#define MAX_LINE_LENGTH_DIVE	.10			; max menu item  length in dive mode menu (characters)
+#define MENU_ITEM_DATA_SIZE		.4			; size of a menu item data block
 
-
-	extern	aa_wordprocessor
-	extern	option_inc
-	extern	option_draw
-	extern	TFT_clear_divemode_menu
-	extern	TFT_divemask_color
-	extern	rtc_set_rtc
-	extern	divemode_option_divemenu_return
-	extern	TFT_fillup_with_spaces
+; Alias for easier code reading
+#define option_addr				item_funct_addr
 
 
-menu_proc	CODE
-
-;=============================================================================
-; menu handler
-;
-; Input:    TBLPTR = addr of menu block
-
-	global	menu_processor
-menu_processor:
-;	btfss	divemode						; in dive mode?
-;	call	request_speed_fastest			; NO  - request CPU speed change to fastest speed
-	;---- Read menu block ------------------------------------------------
-	VARARGS_BEGIN							; read inline PROM data
-	clrf	STKPTR							; never return from here
-	VARARGS_GET8	item_max				; get number of items
-	VARARGS_GET8	menu_flags				; get flags
-	VARARGS_GET24	menu_title				; get pointer to menu title
-	VARARGS_GET8	menu_center				; vertical position
-	movff	TBLPTRL, menu_block+0			; save base address for menu_read_item
-	movff	TBLPTRH, menu_block+1			; ...
-	movff	TBLPTRU, menu_block+2			; ...
-	btfss	divemode						; in dive mode?
-	bra		menu_processor0					; NO
+	extern	option_adjust_group_member
+	extern	option_inc
+	extern	option_dec
+	extern	option_draw
 
-	; Required for menus with less entries than the calling menu but not so nice when setting up gas 6.... mH
-	movlw	.1
-	cpfsgt	menu_pos_cur					; only if menu_pos_cur = 1...
-	call	TFT_clear_divemode_menu			; ... clear the menu!
-	; Draw one frame around the dive mode menu
-	call	TFT_divemask_color
-	WIN_FRAME_COLOR16 dm_menu_row, dm_menu_lower, dm_menu_left ,dm_menu_right	; top, bottom, left, right
-	call	TFT_standard_color
-
-	bra		menu_processor1					; skip next code segment in dive mode
-
-menu_processor0:
-	;---- draw menu title ------------------------------------------------
-	clrf	CCP1CON							; stop PWM
-	bcf		PORTC,2							; pull PWM out to GND
-	call	TFT_ClearScreen
-	rcall	menu_processor_title
-	rcall	menu_processor_bottom_line
-
-menu_processor1:
-	WIN_FONT FT_SMALL
-
-	;---- Select menu type -----------------------------------------------
-	bra		menu_vertical
+	extern	rtc_set_rtc
+	extern	divemode_option_divemenu_return
 
 
 ;=============================================================================
-; draw menu bottom line
-;
-menu_processor_bottom_line:
-	;---- Draw bottom line -----------------------------------------------
-	TEXT_TINY .5,         .240-.16, tNext
-	TEXT_TINY .160-.6*.6, .240-.16, tEnter
-	goto	TFT_standard_color				; ...and return
+menu_proc	CODE
+;=============================================================================
 
-;=============================================================================
-; (re-)draw menu title
+
+;-----------------------------------------------------------------------------
+; Entry Point for Menu Processor, called by MENU_BEGIN Macros
 ;
-menu_processor_title:
-	WIN_BOX_BLACK   .2,.23,.0,.159			; clear menu title
-	MENU_TITLE_FONT .0, .2					; menu title positioning
-	btfss	menu_flags,0					; static or dynamic title?
-	bra		menu_processor_static_title		; static  title
-	rcall	menu_processor_call_title		; dynamic title - add gas, detail and color
-	bra		menu_processor_title_1
+	global	menu_processor
+menu_processor:
+	; read menu header
+	VARARGS_BEGIN							; load TBLPTR with start address of the menu header data
+	clrf	STKPTR							; never return from here
+
+	VARARGS_GET8	menu_item_count			; get number of items
+	VARARGS_GET8	menu_vertical_start		; get vertical start position of 1st menu item
+
+	movf	menu_vertical_start,W			; excite flags
+	bz		menu_processor_no_title			; no menu title text -> skip reading menu title text address
+
+	VARARGS_GET16	menu_title_addr			; get address of menu title text
+
+menu_processor_no_title:
 
-menu_processor_static_title:
-	movff	menu_title+0,FSR1L				; just copy string
-	movff	menu_title+1,FSR1H
-	call	strcpy_text
+	movff	TBLPTRL, menu_item_data_start+0	; store base address for menu_read_menu_item_data
+	movff	TBLPTRH, menu_item_data_start+1	; ...
+	movff	TBLPTRU, menu_item_data_start+2	; ...
+
+	btfss	divemode						; in dive mode?
+	bra		menu_processor_menu_title		; NO  - no frame in surface mode menu
+
+	; required for menus with less entries than the calling menu but not so nice when setting up gas 6.... mH
+	movlw	.1								; menu_pos_cur = 1 ?
+	cpfsgt	menu_pos_cur					; ...
+	call	TFT_clear_divemode_menu			; YES - clear the menu
+
+	; draw a frame around the dive mode menu
+	movf	pallet_color_mask,W				; get mask color into WREG
+	WIN_FRAME_COLOR dm_menu_row, dm_menu_lower, dm_menu_left ,dm_menu_right	; top, bottom, left, right
+	bra		menu_processor_menu_body		; the dive mode menu has no menu title and footer
 
-menu_processor_title_1:
-	WIN_COLOR color_greenish
-	movf	FSR2L,W							; get title length
-	mullw	.9								; convert to half pixels
-	bcf		STATUS,C						; clear carry
-	rrcf	PRODL							; /2
-	movf	PRODL,W							; back to WREG
-	sublw	.80								; 80 - width
-	movwf	win_leftx2						; aligned to center
-	movlw	.0								; string termination code
-	movff	WREG,buffer+.17					; limit to 17 chars (std font max.)
-	call	aa_wordprocessor
-	call	TFT_standard_color
-	return
+menu_processor_menu_title:
+	; prepare screen
+	clrf	CCP1CON							; stop PWM
+	bcf		PORTC,2							; fade out backlight
+	call	TFT_ClearScreen					; clear screen
+
+	; draw menu title
+	WIN_BOX_BLACK   .2,.23,.0,.159			; clear menu title area
+	WIN_STD .0, .2							; set menu title font and position
+	FONT_COLOR color_greenish				; set menu title font color
+	movff	menu_title_addr+0,FSR1L			; point to multi-lingual menu title text
+	movff	menu_title_addr+1,FSR1H			; ...
+	call	strcpy_text_FSR					; copy translated text into the buffer
+	movf	FSR2L,W							; get title text length
+	mullw	.9								; compute title length in pixels_x2
+	bcf		STATUS,C						; divide by 2
+	rrcf	PRODL							; ...
+	movf	PRODL,W							; get result into WREG
+	sublw	.80								; compute 80 (screen center position) - half title width in pixel_x2
+	movwf	win_leftx2						; set result as horizontal start position
+	movlw	MAX_LINE_LENGTH_TITLE			; load max allowed length of a menu title
+	movwf	FSR2L							; set buffer pointer to end of max length
+	clrf	INDF2							; terminate string          at max length
+	PRINT									; output menu title
 
-;=============================================================================
-; Call dynamic proc for menu title:
+	; draw footer line
+	FONT_COLOR_MEMO							; select default color
+	WIN_TINY   .5, .224						; tiny font, left position
+	STRCPY_TEXT_PRINT tNext					; print "Next"
+	WIN_TINY .124, .224						; tiny font, righ position
+	STRCPY_TEXT_PRINT tEnter				; print "Enter"
 
+menu_processor_menu_body:
+	FONT_SIZE FT_SMALL						; select font size
+	bra		menu_vertical					; draw the menu items
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - call Callback-Function to draw the Menu Item Title
+;
 menu_processor_call_title:
-	movff	menu_title+2,PCLATU				; execute computed goto
-	movff	menu_title+1,PCLATH
-	movf	menu_title+0,W
-	movwf	PCL
+	movff	menu_title_addr+2,PCLATU		; execute computed goto
+	movff	menu_title_addr+1,PCLATH		; ...
+	movf	menu_title_addr+0,W				; ...
+	movwf	PCL								; ...
 
-;=============================================================================
-; Restart with first icon/line selected
+
+;-----------------------------------------------------------------------------
+; Clear all memorized Menu Item Selections and restart with Cursor on first Item
 ;
 	global	menu_processor_reset
 menu_processor_reset:
-	clrf	menustack						; clear                 first stack position
-	clrf	menustack_pointer				; set stack pointer  to first stack position
-	clrf	selected_item					; set last menu item to first item
-	return
+	clrf	menustack						; clear                  first stack position
+	clrf	menustack_pointer				; set stack pointer   to first stack position
+	clrf	selected_item					; set cursor position to first menu item
+	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Pull / Double-Pull Cursor Position from Stack
+;
 	global	menu_processor_double_pop
 	global	menu_processor_pop
 menu_processor_double_pop:
@@ -167,300 +164,362 @@
 	clrf	menustack_pointer				; YES - reset stack pointer to first stack position
 	movf	menustack_pointer,W				; load stack pointer into WREG
 	lfsr	FSR2,menustack					; load base  address of menu stack
-	movff	PLUSW2,selected_item			; retrieve menu item from stack
+	movff	PLUSW2,selected_item			; retrieve cursor position from stack
 	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Push Cursor Position onto Stack
+;
 menu_processor_push:
 	lfsr	FSR2,menustack					; load base  address of menu stack
 	movf	menustack_pointer,W				; load stack pointer into WREG
-	movff	selected_item,PLUSW2			; save menu item to stack
+	movff	selected_item,PLUSW2			; save cursor position to stack
 	incf	menustack_pointer,W				; increment stack pointer, park result in WREG
 	btfss	WREG,3							; result < 8 ?
 	movwf	menustack_pointer				; YES - update stack pointer
-	clrf	selected_item					; set to first item in new menu
+	clrf	selected_item					; set cursor to first item in new menu
 	return									; done
 
 
-;---- Execute menu selection -------------------------------------------------
-do_menu_item:
-	bcf		switch_right					; clear left-over button event
-	movf	selected_item,W					; reread proc address from table
-	rcall	menu_read_item					; (destroys PROD)
-	movff	selected_item,PRODL				; pass along selected line
-	rcall	menu_processor_push				; remember where we got from (clears selected_item)
-	movff	proc_item+2,PCLATU				; then execute computed goto
-	movff	proc_item+1,PCLATH
-	movf	proc_item+0,W
-	movwf	PCL
+;-----------------------------------------------------------------------------
+; Helper Function - call Menu Item Function
+;
+menu_call_item_function:
+	bcf		switch_right					; clear button event
+	movf	selected_item,W					; copy current cursor position to WREG
+	rcall	menu_read_menu_item_data		; read item function address
+	movff	selected_item,PRODL				; pass cursor position (menu item number) to call function
+	rcall	menu_processor_push				; push current cursor position onto stack
+	clrf	                  PCLATU		; execute computed goto
+	movff	item_funct_addr+1,PCLATH		; ...
+	movf	item_funct_addr+0,W				; ...
+	movwf	                  PCL			; ...
 
-;=============================================================================
-; Get current item from table.
-;
-; Input  : Item number in WREG, menu_block.
-; Output : icon_large, text_item, proc_item 16bits pointers.
-; Trashed: PROD, WREG
+
+;-----------------------------------------------------------------------------
+; Read Menu Item Data
 ;
-menu_read_item:
-	mullw	.10								; 10 bytes per item
-	movf	PRODL,W							; then do a 24 bits add
-	addwf	menu_block+0,W					; with menu_block, and
-	movwf	TBLPTRL							; setup TBLPTR
-	movf	PRODH,W
-	addwfc	menu_block+1,W
-	movwf	TBLPTRH
-	movlw	0
-	addwfc	menu_block+2,W
-	movwf	TBLPTRU
-	VARARGS_GET8	value_type				; read 10 bytes of item data
-	VARARGS_GET24	dynamic_item
-	VARARGS_GET24	proc_item
-	VARARGS_GET8	WREG					; skip dummy byte
-	VARARGS_GET16	text_item
+menu_read_menu_item_data:
+	cpfsgt	menu_item_count					; selected menu item valid?				|| * Safety Check * to prevent any computed
+	clrf	WREG							; NO - change selection to first item	|| goto to an illegal random target address
+
+	mullw	MENU_ITEM_DATA_SIZE				; compute menu item data offset
+	movf	PRODL,W							; add offset to base address of menu data block and set up TBLPTR
+	addwf	menu_item_data_start+0,W		; ...
+	movwf	TBLPTRL							; ...
+	movf	PRODH,W							; ...
+	addwfc	menu_item_data_start+1,W		; ...
+	movwf	TBLPTRH							; ...
+	movlw	0								; ...
+	addwfc	menu_item_data_start+2,W		; ...
+	movwf	TBLPTRU							; ...
+
+	VARARGS_GET16	item_title_addr			; read address of item title function or title text             | with embedded
+	VARARGS_GET16	item_funct_addr			; read address of item call  function or option definition data | menu item type
 
-	return
+	movlw	.2								; probe for menu item type = OPTION
+	btfsc	item_funct_addr,0				; is type OPTION?
+	bra		menu_read_menu_item_data_1		; YES
+
+	movlw	.1								; probe for menu item type = MENU_CALL
+	btfsc	item_title_addr,0				; is type MENU_CALL?
+	bra		menu_read_menu_item_data_1		; YES
+
+	movlw	.0								; must be MENU_DYNAMIC
 
-;=============================================================================
-; Vertical menu - set of line/value to choose from,
-;                 entry point to update lines already shown
+menu_read_menu_item_data_1:
+	movwf	item_type						; store menu item type
+	bcf		item_title_addr+0,0				; strip menu item type encoding from addresses (reset to even addresses)
+	bcf		item_funct_addr+0,0				; ...
+
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Menu HMI Operation
 ;
 	global	menu_vertical
 menu_vertical:
-	rcall	menu_draw_lines					; always re-draw whole menu
-	movlw	CCP1CON_VALUE					; see hwos.inc
+	rcall	menu_draw_menu_items			; draw all menu items
+	movlw	CCP1CON_VALUE					; load PWM setting
 	btfss	divemode						; in dive mode?
 	movwf	CCP1CON							; NO - power-on backlight
 
-menu_vertical_1:
-	movf	selected_item,W					; copy current menu item selection to WREG
-	rcall	menu_read_item					; get current menu item data
-	movf	proc_item+0,W					; check if proc address is NULL
-	iorwf	proc_item+1,W
-	bz		next_line_menu					; YES - not selectable
-	btfss	divemode						; in dive mode?
-	rcall	menu_draw_selected_line			; NO
-	btfss	imprint_time_date				; currently imprinting the current time & date?
-	bra		menu_line_loop_pre1				; NO
-	btfss	switch_right					; YES - right button pressed, i.e. time or date changed?
-	bra		menu_line_loop_pre1				;       NO
-	call	TFT_show_time_date_menu_fast	;       YES - show a fast response on the screen (may momentarily show an illegal day/month combination)
-	call	rtc_set_rtc						;           - update time and date on RTC module (corrects illegal day/month combinations)
+menu_vertical_loop:
+	movf	selected_item,W					; get cursor position into WREG
+	rcall	menu_read_menu_item_data		; read menu item data
+	movf	item_funct_addr+0,W				; check if execute function call address is NULL
+	iorwf	item_funct_addr+1,W				; ...
+	bz		next_line_menu					; YES - not selectable, step cursor to next menu item
+	btfss	divemode						; NO  - in dive mode?
+	rcall	menu_draw_cursor_surf			;       NO  - draw the cursor (main menu style)
+	btfss	imprint_time_date				;     - currently imprinting the current time & date?
+	bra		menu_line_loop_pre1				;       NO  - skip
+	btfss	switch_right					;       YES - right button pressed, i.e. time or date changed?
+	bra		menu_line_loop_pre1				;             NO  - skip
+	call	TFT_imprint_time_date_fast		;             YES - show a fast response on the screen (may momentarily show an illegal day/month combination)
+	call	rtc_set_rtc						;                 - update time and date on RTC module (corrects illegal day/month combinations)
 
 menu_line_loop_pre1:
-	btfsc	imprint_color_schemes			; in the color scheme menu?
-	call	TFT_show_color_schemes			; YES - update the color schemes
-
-menu_line_loop_pre2:
 	bcf		switch_right					; clear left-over right button event
 	bcf		switch_left						; clear left-over left  button event
 
-menu_line_loop_pre3:
+menu_line_loop_pre2:
 	btfsc	divemode						; in dive mode?
 	goto	divemode_option_divemenu_return	; YES - return to it
-	;bra	menu_line_loop_surface			; NO  - proceed to surface mode dispatcher
+	call	reset_timeout_surfmode			; NO  - reset timeout
 
-; dispatcher for surface mode menus
-menu_line_loop_surface:
-	call	reset_timeout_surfmode			; reset timeout
 menu_line_loop:
-	call	housekeeping					; handle data imprinting, screen dump request, timeout and entering dive mode
-	btfsc	switch_right					; right button pressed?
-	bra		do_line_menu					; YES - type dependent
-	btfsc	switch_left						; left button pressed?
-	bra		next_line_menu					; YES - goto next item
-	bra		menu_line_loop					; NO to both - loop
+	call	housekeeping					;     - handle data imprinting, screen dump request, timeout and entering dive mode
+	btfsc	switch_right					;     - right button pressed?
+	bra		do_line_menu					;       YES - execute menu item function
+	btfss	switch_left						;       NO  - left button pressed?
+	bra		menu_line_loop					;             NO  - loop
+next_line_menu:								;             YES - step cursor to next menu item
+	bcf		switch_left						;                 - clear button event
+	incf	selected_item,F					;                 - increment cursor position to next item
+	movf	selected_item,W					;                 - copy new item number to WREG
+	cpfseq	menu_item_count					;                 - new item number beyond number of menu items?
+	bra		menu_vertical_loop				;                   NO  - redraw cursor
+	clrf	selected_item					;                   YES - reset cursor position to first item
+	bra		menu_vertical_loop				;                       - redraw cursor
 
 
-;---- Move to menu's next line
-next_line_menu:
-	bcf		switch_left						; clear button event
-	incf	selected_item,F					; select next item
-	movf	selected_item,W					; copy item number to WREG
-	cpfseq	item_max						; item number == max ?
-	bra		menu_vertical_1					; NO  - redraw cursor
-	clrf	selected_item					; YES - wrap-around to first item
-	bra		menu_vertical_1					; then redraw cursor
-
+;-----------------------------------------------------------------------------
+; Execute Menu Item Function
+;
 	global	do_line_menu
 do_line_menu:
-	decf	menu_pos_cur,W					; menu_processor needs 0-5
+	decf	menu_pos_cur,W					; get selected menu item (0-5) into WREG
 	btfsc	divemode						; in dive mode?
-	movwf	selected_item					; YES - set selected item from WREG
-	movf	selected_item,W					; read selected descriptor
-	rcall	menu_read_item
-	movf	value_type,W					; switch on data type
-	bz		menu_do_line_call				; CALL
-	dcfsnz	WREG
-	bra		menu_do_line_call				; STRING: do as call
-	dcfsnz	WREG
-	bra		menu_do_line_option				; OPTION
-	dcfsnz	WREG
-	bra		menu_do_line_call				; DYNAMIC: do as call
-	bra		menu_line_loop_pre3				; else do nothing
+	movwf	selected_item					; YES - take selected menu item from dive mode
+	movf	selected_item,W					; copy       selected menu item to WREG
+	rcall	menu_read_menu_item_data		; read menu item data
+	movf	item_type,W						; switch on menu item type
+	bz		menu_do_line_call				; -> 0: call (with dynamic title)
+	dcfsnz	WREG							;
+	bra		menu_do_line_call				; -> 1: call (with fixed   title)
+	dcfsnz	WREG							;
+	bra		menu_do_line_option				; -> 2: option
+	bra		menu_line_loop_pre2				; else do nothing
+
+menu_do_line_call:
+	rcall	menu_call_item_function			; push current cursor position onto stack and call menu item function
+	rcall	menu_processor_pop				; get back cursor position
+	bra		menu_vertical					; re-draw the menu
+
+menu_do_line_option:
+	movff	option_addr+0,FSR0L				; get address of option definition data
+	movff	option_addr+1,FSR0H				; ...
+	btfsc	option_addr+1,4					; shall stop at max value?
+	bsf		option_stop_at_max				; YES - set flag
+	btfsc	option_addr+1,6					; is the selected option an  option group member?
+	call	option_adjust_group_member		; YES -  adjust address to selected group member
+	btfss	option_addr+1,5					; shall increment?
+	call	option_inc						; YES - increment option value
+	btfsc	option_addr+1,5					; shall decrement?
+	call	option_dec						; YES - decrement option value
+	bcf		option_stop_at_max				; revert to default (= wrap-around after max value)
+	bra		menu_vertical					; re-draw the menu
+
+
+;-----------------------------------------------------------------------------
+; Draw all Menu Items
+;
+menu_draw_menu_items:
+	btfss	divemode						; in dive mode?
+	bra		menu_draw_lines_surfmode		; NO
+	;bra	menu_draw_lines_divemode		; YES
+
+	global	menu_draw_lines_divemode
+menu_draw_lines_divemode:
+	movlw	dm_menu_item1_row				; get row    position for 1st item
+	movwf	win_top							; set vertical  output position
+	movlw	dm_menu_item1_column			; get column position for 1st item
+	movwf	win_leftx2						; set horizontal output position
+	clrf	menu_item_start					; set first item in menu block as first item to draw
+	movff	menu_item_count,menu_pos_max	; copy number of item in menu block to menu_pos_max
+	bra		menu_draw_menu_items_common		; continue with common part
+
+menu_draw_lines_surfmode:
+	WIN_SMALL MENU_LEFT, 0					; initialize start position and font
+	movff	menu_vertical_start,win_top		; set vertical output position
+	clrf	menu_item_start					; set first item in menu block as first item to draw
+
+ IFDEF scrolling_menu_enabled
+	; does the menu have more than 7 item ?
+	movf	menu_item_count,W				; get number of menu items
+	addlw	-(MENU_LINES_MAX+1)				; more than 7 item?
+	bn		menu_draw_menu_items_common		; NO - continue with common part
+	movf	selected_item,W					; YES - compute first item to be drawn as current cursor position - 6
+	addlw	-(MENU_LINES_MAX-1)				;     - ...
+	btfsc	STATUS,N						;     - is this < 0 ?
+	clrf	WREG							;       YES - revert to starting from first item
+	movwf	menu_item_start					;     - set first item to be drawn
+ ENDIF	; scrolling_menu_enabled
+
+menu_draw_menu_items_common:
+	movff	menu_item_start,menu_item_curr	; initialize menu item counter
+	FONT_SIZE FT_SMALL						; set font size
+
+menu_draw_menu_items_loop:
+	FONT_COLOR_MEMO							; set default font color (may be changed by dynamic titles)
+	movf	menu_item_curr,W				; get menu item to draw
+	rcall	menu_read_menu_item_data		; read menu item data
+	movf	item_type,W						; switch on menu item type:
+	bz		 menu_draw_menu_item_dynamic 	; -> 0: call with dynamic title
+	dcfsnz	WREG							;
+	bra		menu_draw_menu_item_call		; -> 1: call with fixed   title
+	dcfsnz	WREG							;
+	bra		menu_draw_menu_item_option		; -> 2: option increment
+	bra		menu_draw_menu_item_print		; no output in case of illegal type
+
+menu_draw_menu_item_dynamic:
+
+	movf	item_title_addr+0,W				; check if call address is NULL
+	iorwf	item_title_addr+1,W				; ...
+	btfsc	STATUS,Z						; is null?
+	bra		menu_draw_menu_item_no_print	; YES - no printing on this menu line
+	INIT_BUFFER								; NO  - initialize buffer
+	movff	menu_item_curr,PRODL			;     - pass menu item position to call function
+	rcall	menu_text_call					;     - call dynamic title function
+	bra		menu_draw_menu_item_print		;     - print menu item
+
+menu_draw_menu_item_call:
+	movff	item_title_addr+0,FSR1L			; point to multi-lingual text
+	movff	item_title_addr+1,FSR1H			; ...
+	call	strcpy_text_FSR					; copy translated text to buffer
+	bra		menu_draw_menu_item_print		; print menu item
+
+menu_draw_menu_item_option:
+	movff	item_title_addr+0,FSR1L			; point to multi-lingual text
+	movff	item_title_addr+1,FSR1H			; ...
+	call	strcpy_text_FSR					; copy translated text to buffer
+	movff	option_addr+0,FSR0L				; hand over address of option definition data
+	movff	option_addr+1,FSR0H				; ...
+	btfsc	option_addr+1,6					; is the selected option an  option group member?
+	call	option_adjust_group_member		; YES -  adjust address to selected group member
+	btfss	block_option_value				; displaying of option value suspended?
+	call	option_draw						; NO - draw option value
+	;bra	menu_draw_menu_item_print		; print menu item
 
-;---- CALL
-menu_do_line_call:
-	rcall	do_menu_item					; same as icon menu: calculated goto
-	rcall	menu_processor_pop				; back to same line,
-	bra		menu_vertical					; then continue into menu...
+menu_draw_menu_item_print:
+	movlw	MAX_LINE_LENGTH_SURF			; load               maximum length for a surface   menu item
+	btfsc	divemode						; in dive mode?
+	movlw	MAX_LINE_LENGTH_DIVE			; YES - replace with maximum length for a dive mode menu item
+	call	TFT_buffer_trim_length			; fill up or cut buffer to max length
+	PRINT									; print menu item to screen
+	;bra	menu_draw_menu_item_no_print	; continue with after-print actions
+
+menu_draw_menu_item_no_print:
+	movlw	MENU_HEIGHT_SURF				; get menu items     vertical spacing for surface mode
+	btfsc	divemode						; in dive mode?
+	movlw	MENU_HEIGHT_DIVE				; YES - replace with vertical spacing for dive    mode
+
+	addwf	win_top,F						; adjust vertical output position
+	incf	menu_item_curr,F				; go to next menu item
+
+	btfss	divemode						; in dive mode?
+	bra		menu_draw_menu_item_surfmode	; NO
+	;bra	menu_draw_menu_item_divemode	; YES
+
+menu_draw_menu_item_divemode:
+	movlw	.3								; load a 3
+	cpfseq	menu_item_curr					; just done menu item 3 ?
+	bra		menu_draw_menu_item_common		; NO  - continue with common part
+	movlw	dm_menu_item4_row				; YES - set vertical   position for 2nd column
+	movff	WREG,win_top					;     - ...
+	movlw	dm_menu_item4_column			;     - set horizontal position for 2nd column
+	movff	WREG,win_leftx2					;     - ...
+	bra		menu_draw_menu_item_common		;     - continue with common part
+
+menu_draw_menu_item_surfmode:
+ IFDEF scrolling_menu_enabled
+	movf	menu_item_start,W				; get the number of the menu item that menu drawing started with
+	subwf	menu_item_curr,W				; compute how many item have been drawn already
+	xorlw	MENU_LINES_MAX					; compare with how max item fit the screen
+	btfsc	STATUS,Z						; screen full?
+	return									; YES - done
+	;bra	menu_draw_menu_item_common		; NO  - continue with common part
+ ENDIF	; scrolling_menu_enabled
+
+menu_draw_menu_item_common:
+	movf	menu_item_curr,W				; get current menu item
+	xorwf	menu_item_count,W				; compare with total number of menu items, more item to do?
+	bnz		menu_draw_menu_items_loop		; YES - loop
+	return									; NO  - done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - call Function for dynamic Title
+;
+menu_text_call:
+	clrf	                  PCLATU		; execute a computed goto
+	movff	item_title_addr+1,PCLATH		; ...
+	movf	item_title_addr+0,W				; ...
+	movwf	                  PCL			; ...
+
 
-;---- Call option specific increment subroutine
-menu_do_line_option:
-	movff	option_item+0,FSR0L				; get option handle
-	movff	option_item+1,FSR0H
-	call	option_inc						; increment
-	movff	selected_item,PRODL				; pass selection to callback
-	rcall	menu_text_call
-	bra		menu_vertical					; redraw all lines
+;-----------------------------------------------------------------------------
+; Draw the Cursor (Main Menu Style)
+;
+menu_draw_cursor_surf:
+	WIN_LEFT 	MENU_LEFT-8					; set horizontal  start of cursor column
+	WIN_WIDTH	.6							; set width             of cursor column
+	WIN_HEIGHT	.223						; set preliminary hight of cursor column
+
+	movf	menu_vertical_start,W			; get vertical    start of menu items
+	movwf	win_top							; set vertical    start of cursor column
+	subwf	win_height,F					; final hight = prelim.height - vertical start
+
+	clrf	WREG							; set color to black
+	BOX_COLOR								; clear cursor area
+
+	movf	menu_item_start,W				; get number of menu item that is on the first line
+	subwf	selected_item,W					; compute line number of current menu item
+
+	mullw	MENU_HEIGHT_SURF				; multiply line number with vertical menu items spacing
+	movf	PRODL,W							; get computed vertical offset
+	addwf	menu_vertical_start,W			; add offset to vertical start position
+	movwf	win_top							; set final vertical position
+	bra		menu_draw_cursor_common			; print cursor and return
+
+
+;-----------------------------------------------------------------------------
+; Draw the Cursor (Dive Mode Style)
+;
+	global	menu_draw_cursor_dive
+menu_draw_cursor_dive:
+	; clear cursor areas
+	WIN_BOX_BLACK dm_menu_row+.1, dm_menu_lower-.1, dm_menu_item1_column-.8, dm_menu_item1_column-.1
+	WIN_BOX_BLACK dm_menu_row+.1, dm_menu_lower-.1, dm_menu_item4_column-.8, dm_menu_item4_column-.1
+
+	movlw	dm_menu_item1_column-.8			; load position of left column
+	btfsc	menu_pos_cur,2					; cursor at menu item 4..6 ?
+	movlw	dm_menu_item4_column-.8			; YES - replace with position of right column
+	movwf	win_leftx2						; set horizontal position
+
+	decf	menu_pos_cur,W					; get cursor position as 0..5 into WREG
+	btfsc	menu_pos_cur,2					; cursor at menu item 4..6 ?
+	addlw	-.3								; YES - subtract 3 to get line number in right column
+
+	mullw	MENU_HEIGHT_DIVE				; multiply line number with vertical menu items spacing
+	movf	PRODL,W							; get computed vertical offset
+	addlw	dm_menu_item1_row				; add offset to vertical start position
+	movwf	win_top							; set final vertical position
+	;bra	menu_draw_cursor_common			; print cursor and return
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - common Part of drawing the Cursor
+;
+menu_draw_cursor_common:
+	FONT_COLOR_MEMO							; set font color
+	FONT_SIZE FT_SMALL						; set font size
+	STRCPY_PRINT "\xb7"						; print cursor
+	return									; done
 
 ;-----------------------------------------------------------------------------
 
-	global	menu_draw_lines_divemode		; entry point for re-drawing of the menu to update color-coding of gases
-menu_draw_lines_divemode:
-	movlw	dm_menu_item1_row
-	movff	WREG,win_top
-	movlw	dm_menu_item1_column
-	movff	WREG,win_leftx2
-	clrf	start_item
-	movff	item_max,menu_pos_max			; copy item_max for dive mode cursor routine
-	bra		menu_draw_lines_2
-
-menu_draw_lines:
-	btfsc	divemode						; in dive mode?
-	bra		menu_draw_lines_divemode		; YES
-	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
-
-	; Does the menu have more than 6 lines ?
-	movf	item_max,W
-	addlw	-(MENU_LINES_MAX+1)				;
-	bnn		menu_draw_long_menu				; bra if >= 7
-	clrf	start_item
-	bra		menu_draw_lines_2
-
-menu_draw_long_menu:
-	movf	selected_item,W					; start at selected-6
-	addlw	-(MENU_LINES_MAX-1)
-	btfsc	STATUS,N						; is this < 0 ?
-	clrf	WREG							; YES - start from top instead
-	movwf	start_item
-
-menu_draw_lines_2:
-	movff	start_item, menu_item
-	WIN_FONT FT_SMALL						; set font size
-
-menu_draw_lines_1:
-	call	TFT_standard_color				; set default text color
-	movf	menu_item,W
-	rcall	menu_read_item
-	movf	value_type,W					; switch on data type
-	bz		menu_draw_line_call
-	dcfsnz	WREG
-	bra		menu_draw_line_string
-	dcfsnz	WREG
-	bra		menu_draw_line_option
-	dcfsnz	WREG
-	bra		menu_draw_line_dynamic
-	bra		menu_draw_line_none
-
-menu_draw_line_string:
-	movff	text_item+0,TBLPTRL				; read not-translated string from PROM
-	movff	text_item+1,TBLPTRH
-	call	strcpy_prom						; copy in buffer
-	bra		menu_draw_line_none
-
-menu_draw_line_call:
-	movff	text_item+0,FSR1L				; read string from PROM
-	movff	text_item+1,FSR1H
-	call	strcpy_text						; copy in buffer
-	bra		menu_draw_line_none
-
-menu_draw_line_option:
-	movff	text_item+0,FSR1L				; read string from PROM
-	movff	text_item+1,FSR1H
-	call	strcpy_text						; copy in buffer
-	movff	option_item+0,FSR0L				; retrieve option handle
-	movff	option_item+1,FSR0H
-	btfss	block_option_value				; display of option value suspended?
-	call	option_draw						; NO - draw option (do not do it when setting time or date)
-	bra		menu_draw_line_none
-
-menu_draw_line_dynamic:
-	lfsr	FSR2,buffer
-	movff	menu_item,PRODL					; pass item to callback
-	rcall	menu_text_call					; push return address
-	bra		menu_draw_line_none
-
-; Computed goto to pointer inside dynamic_item:
-menu_text_call:
-	movf	dynamic_item+0,W				; check if callback is NULL
-	iorwf	dynamic_item+1,W
-	iorwf	dynamic_item+2,W
-	btfsc	STATUS,Z
-	return									; YES - don't call it
-	movff	dynamic_item+2,PCLATU			; prepare...
-	movff	dynamic_item+1,PCLATH
-	movf	dynamic_item+0,W
-	movwf	PCL								; ...and jump
-
-menu_draw_line_none:
-	btfsc	divemode						; in dive mode?
-	bra		menu_draw_line_none_divemode	; YES
-	movlw	MENU_LINE_MAX_LENGTH
-	call	TFT_fillup_with_spaces			; fill up FSR2 with spaces (total string length in #WREG)
-	clrf	WREG
-	movff	WREG,buffer+MENU_LINE_MAX_LENGTH ; NO - make sure won't be longer than MENU_LINE_MAX_LENGTH ch
-	call	aa_wordprocessor
-	bcf		win_invert						; clear flag for inverted output by default
-	movlw	MENU_HEIGHT						; NO - move to next line
-	addwf	win_top,F
-	incf	menu_item,F						; inc loop counter
-	movf	start_item,W					; first line (scrolled)
-	subwf	menu_item,W						; current - first
-	xorlw	MENU_LINES_MAX					; get max number of lines
-	btfsc	STATUS,Z						; already done max number of lines?
-	return									; YES
-menu_draw_line_none2:
-	movf	menu_item,W						; done item_max lines?
-	xorwf	item_max,W
-	btfss	STATUS,Z
-	bra		menu_draw_lines_1				; NO - loop...
-	return
-
-menu_draw_line_none_divemode:
-	movlw	.10
-	call	TFT_fillup_with_spaces			; fill up FSR2 with spaces (total string length in #WREG)
-	clrf	WREG
-	movff	WREG,buffer+.10
-	call	aa_wordprocessor				; draw the line
-	bcf		win_invert						; reset invert flag
-	movlw	.24								; dive mode menu spacing
-	addwf	win_top,F
-	incf	menu_item,F						; inc loop counter
-	movlw	.3
-	cpfseq	menu_item						; at position 4?
-	bra		menu_draw_line_none2			; NO
-	movlw	dm_menu_item4_row
-	movff	WREG,win_top					; reset row
-	movlw	dm_menu_item4_column
-	movff	WREG,win_leftx2					; new column
-	bra		menu_draw_line_none2			; done
-
-;-----------------------------------------------------------------------------
-; draw cursor
-menu_draw_selected_line:
-	WIN_BOX_BLACK .34,.221,MENU_LEFT-8,MENU_LEFT-2 ; clear left column
-	call	TFT_standard_color
-	WIN_SMALL MENU_LEFT-8, 0				; arrow symbol only in small font
-	movf	start_item,W					; first line (scrolled)
-	subwf	selected_item,W					; selected - first
-	mullw	MENU_HEIGHT						; 30 pixel by line
-	movf	PRODL,W							; result
-	addwf	menu_center,W					; added to first line
-	movwf	win_top							; and stored to position
-	STRCPY_PRINT "\xb7"						; print cursor
-	return
-
-	END
\ No newline at end of file
+	END
--- a/src/menu_processor.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/menu_processor.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File menu_processor.asm                   combined next generation V3.0.4b
+;   File menu_processor.inc                 * combined next generation V3.09.5
 ;
 ;   Routines to handle all OSTC graphic/text menus.
 ;
@@ -9,87 +9,316 @@
 ; HISTORY
 ;   2011-05-30 : [jDG] Creation.
 
-	; restart menu-system from first icon/line
-	extern	menu_processor_reset
+
 
-	; recall last (automatically) saved icon/line when returning from submenu
-	extern	menu_processor_pop
-	extern	menu_processor_double_pop
+; Menu Parameters
+; NOTE: needs to be identical in .inc and .asm files!
+;
+#define MENU_LINES_MAX_SURF	.7			; max number of lines per screen
+#define MENU_LINES_MAX_DIVE	.6			; max number of lines per dive mode menu
+#define MENU_HEIGHT_SURF	.27			; spacing between menu items in surface mode (pixel)
+#define MENU_VCENTER		.125		; vertical center position of menu items
 
-	; execute the menu block
-	extern	menu_processor
+
+; Menu Processor Functions
+;
+	extern	menu_processor_reset		; push current  menu item (cursor position) to   the stack
+	extern	menu_processor_pop			; pull current  menu item (cursor position) from the stack
+	extern	menu_processor_double_pop	; pull previous menu item (cursor position) from the stack
+
 
-;=============================================================================
-; Menus parameters
+; Encoding Format for Menu Item Types
+;
+; 1st word with code1  2nd word with code2  item_type  Type           Functionality
+; ------------------------------------------------------------------------------------------------------------------------
+; tttt tttt tttt ttt0  cccc cccc cccc ccc0      0      MENU_DYNAMIC   Call Item with dynamic Title
+; ~--~ tttt tttt ttt1  cccc cccc cccc ccc0      1      MENU_CALL      Call Item with fixed   Title (multi-lingual)
+; ~--~ tttt tttt ttt1  ~000 cccc cccc ccc1      2      MENU_OPT_INC   Option Increment with fixed multi-lingual Title
+; ~--~ tttt tttt ttt1  ~001 cccc cccc ccc1      2      MENU_OPT_INCS  as before, but stops at max value
+; ~--~ tttt tttt ttt1  ~011 cccc cccc ccc1      2      MENU_OPT_DECS  as before, but decrement (only stop at min avail)
+; ~--~ tttt tttt ttt1  ~100 cccc cccc ccc1      2      MENU_GRP_INC   Option Increment for an Option out of an Option Group
+; ~--~ tttt tttt ttt1  ~101 cccc cccc ccc1      2      MENU_GRP_INCS  as before, but stops at max value
+; ~--~ tttt tttt ttt1  ~111 cccc cccc ccc1      2      MENU_GRP_DECS  as before, but decrement (only stop at min avail)
+;
+;  t : Address Bits: title_func_addr or title_text_addr   |     Attention: title_func_addr and
+;  c : Address Bits: item_func_addr  or option_addr       | item_func_addr must be within 0x0xxxx
+;  - : unused, reads as zero
+;  ~ : unused, reads as one (part of the real program memory address shining through)
+; 0/1: fixed Bit Values making up Menu Item Type Encoding
+
+
 
-;NOTE: needs to be identical in .inc and .asm files!
-#define MENU_LINES_MAX		.7		; max number of lines per screen
-#define MENU_HEIGHT			.27		; spacing on screen
-#define MENU_VCENTER		.125	; position on screen
+;-----------------------------------------------------------------------------
+; Open a Dive Mode Menu Block
+;
+; nb_items         number of menu items that will follow
+;
+MENU_BEGIN_DIVE	MACRO nb_items
+
+items_target set nb_items
+items_count  set 0
 
-;=============================================================================
+	; check number of menu items
+	IF nb_items <= 0
+		Error "Zero items in menu ", x
+	ENDIF
+	IF nb_items > MENU_LINES_MAX_DIVE
+			Error "too many items in menu", x
+	ENDIF
+
+	; store code for menu execution
+	extern	menu_processor
+	call	menu_processor
+
+	; store menu header data
+	db	nb_items,				0x00					; number of items, encoding for no menu titel
+
+	ENDM
+
 
-COMMON_BEGIN_MENU	MACRO	dynamic, txt, nb_items
-		local	center
+;-----------------------------------------------------------------------------
+; Open a Surface Mode Menu Block with leading empty Item Lines
+;
+; title_text_addr  address of multi-lingual menu title text
+; offset           number of empty  menu items to  start with
+; nb_items         number of active menu items that will follow
+;
+MENU_BEGIN_OFFSET	MACRO title_text_addr, nb_items, offset
+
+items_target set nb_items
+items_count  set 0
 
-		If nb_items > MENU_LINES_MAX
-center		set MENU_VCENTER - (MENU_HEIGHT/2) * MENU_LINES_MAX
-		Else
-center		set MENU_VCENTER - (MENU_HEIGHT/2) * nb_items
-		Endif
+	; check number of menu items
+	IF nb_items <= 0
+		Error "Zero items in menu ", x
+	ENDIF
+	IFNDEF scrolling_menu_enabled
+		IF (nb_items + offset) > MENU_LINES_MAX_SURF
+			Error "too many items in menu", x
+		ENDIF
+	ENDIF
+
+	; compute vertical start position of 1st menu item
+	IF nb_items > MENU_LINES_MAX_SURF
+		local	vertical_start_pos = ( MENU_VCENTER - (MENU_HEIGHT_SURF/2) * MENU_LINES_MAX_SURF )
+	ELSE
+		local	vertical_start_pos = ( MENU_VCENTER - (MENU_HEIGHT_SURF/2) * nb_items ) + (MENU_HEIGHT_SURF/2 * offset)
+	ENDIF
+
+	; store code for menu execution
+	extern	title_text_addr			; 2 byte address of multi-lingual title text
+	extern	menu_processor
+	call	menu_processor
 
-		If nb_items <= 0
-			Error "Zero items in menu ", x
-		Endif
+	; store menu header data
+	db	nb_items,				vertical_start_pos		; number  of items, vertical start position 1st item
+	db	low(title_text_addr),	high(title_text_addr)	; address of multi-lingual title text
+
+	ENDM
+
+
+
+;-----------------------------------------------------------------------------
+; Open a Surface Mode Menu Block
+;
+; title_text_addr  address of multi-lingual menu title text
+; nb_items         number of active   menu items that will follow
+;
+MENU_BEGIN		MACRO title_text_addr, nb_items
+	MENU_BEGIN_OFFSET	title_text_addr, nb_items,0
+	endm
+
 
-		extern	txt
-		call	menu_processor
+;-----------------------------------------------------------------------------
+; Call Item with dynamic Title
+;
+; title_func_addr  address of the function to generate   the line title
+; item_func_addr   address of the function to be executed on line selection
+;
+MENU_DYNAMIC	MACRO title_func_addr, item_func_addr
+
+items_count set items_count+1
 
-		; Push 6 bytes of menu header data
-		db		nb_items,	dynamic
-		db		LOW(txt),	HIGH(txt)
-		db		UPPER(txt),	center
+	;extern	title_func_addr		; 2 byte address of dynamic title function
+	;extern	item_func_addr		; 2 byte address of item function
+
+	local	code1 = 0x0000		; dynamic title
+	local	code2 = 0x0000		; call function
+
+	db	low(title_func_addr + code1), high(title_func_addr + code1)
+	db	low(item_func_addr  + code2), high(item_func_addr  + code2)
+
 	ENDM
 
-;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Call Item with fixed multi-lingual Title
+;
+; title_text_addr  address of multi-lingual item text
+; item_func_addr   address of the function to be executed on line selection
+;
+MENU_CALL		MACRO title_text_addr, item_func_addr
 
-; Macro to generat (and check) menu vertical menu blocks with data.
+items_count set items_count+1
+
+	extern	title_text_addr		; 2 byte address of multi-lingual title text
+	;extern	item_func_addr		; 2 byte address of item function
 
-MENU_BEGIN			MACRO	menu_title, nb_items
-		COMMON_BEGIN_MENU	0, menu_title, nb_items
+	local	code1 = 0x0001		; static multi-lingual title
+	local	code2 = 0x0000		; call function
+
+	db	low(title_text_addr + code1), high(title_text_addr + code1)
+	db	low(item_func_addr  + code2), high(item_func_addr  + code2)
+
 	ENDM
 
-MENU_BEGIN_DYNAMIC	MACRO	title_proc, nb_items
-		COMMON_BEGIN_MENU	1, title_proc, nb_items
+
+;-----------------------------------------------------------------------------
+; Option Increment Item with fixed multi-lingual Title, wrap-around after max
+;
+; title_text_addr  address of multi-lingual item text
+; option_addr      address of option to be incremented on line selection
+;
+MENU_OPT_INC	MACRO title_text_addr, option_addr
+
+items_count set items_count+1
+
+	extern	title_text_addr		; 2 byte address of multi-lingual title text
+	extern	option_addr			; 2 byte address of option definition data
+
+	local	code1 = 0x0001		; static multi-lingual title
+	local	code2 = 0x0001		; option increment with wrap-around after max
+
+	db	low(title_text_addr + code1), high(title_text_addr + code1)
+	db	low(option_addr     + code2), high(option_addr     + code2)
+
+	ENDM
+
+
+;-----------------------------------------------------------------------------
+; Option Increment Item with fixed multi-lingual Title, stop at max value
+;
+; title_text_addr  address of multi-lingual item text
+; option_addr      address of option to be incremented on line selection
+;
+MENU_OPT_INCS	MACRO title_text_addr, option_addr
+
+items_count set items_count+1
+
+	extern	title_text_addr		; 2 byte address of multi-lingual title text
+	extern	option_addr			; 2 byte address of option definition data
+
+	local	code1 = 0x0001		; static multi-lingual title
+	local	code2 = 0x1001		; option increment with stop at max value
+
+	db	low(title_text_addr + code1), high(title_text_addr + code1)
+	db	low(option_addr     + code2), high(option_addr     + code2)
+
 	ENDM
 
-;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Option Increment Item for an Option out of an Option Group, with fixed multi-lingual Title
+;
+; title_text_addr  address of multi-lingual item text
+; option_addr      base address of the option group
+; gaslist_gas      offset of the selected option to be incremented within the group (normal variable)
+;
+MENU_GRP_INC	MACRO title_text_addr, option_addr
 
-; Submenu
+items_count set items_count+1
+
+	extern	title_text_addr		; 2 byte address of multi-lingual title text
+	extern	option_addr			; 2 byte address of option definition data
+
+	local	code1 = 0x0001		; static multi-lingual title
+	local	code2 = 0x4001		; option increment, group member, wrap-around after max value
+
+	db	low(title_text_addr + code1), high(title_text_addr + code1)
+	db	low(option_addr     + code2), high(option_addr     + code2)
 
-MENU_CALL			MACRO	txt, proc
-		extern	txt
-		db		0, 0,             0,             0
-		db		LOW(proc),     HIGH(proc),    UPPER(proc), 0
-		db		LOW(txt),      HIGH(txt)
-    ENDM
+	ENDM
+
+
+;-----------------------------------------------------------------------------
+; Option Increment Item for an Option out of an Option Group, with fixed multi-lingual Title
+;
+; title_text_addr  address of multi-lingual item text
+; option_addr      base address of the option group
+; gaslist_gas      offset of the selected option to be incremented within the group (normal variable)
+;
+MENU_GRP_INCS	MACRO title_text_addr, option_addr
 
-; Generic option menu
+items_count set items_count+1
+
+	extern	title_text_addr		; 2 byte address of multi-lingual title text
+	extern	option_addr			; 2 byte address of option definition data
 
-MENU_OPTION			MACRO	txt, option, callback
-		extern	txt
-		extern	option
-		db		2, LOW(callback), HIGH(callback), UPPER(callback)
-		db		   LOW(option),   HIGH(option),   UPPER(option),  0
-		db		   LOW(txt),      HIGH(txt)
+	local	code1 = 0x0001		; static multi-lingual title
+	local	code2 = 0x5001		; option increment, group member, stop at max value
+
+	db	low(title_text_addr + code1), high(title_text_addr + code1)
+	db	low(option_addr     + code2), high(option_addr     + code2)
+
 	ENDM
 
-MENU_DYNAMIC		MACRO	callback, proc
-		extern	callback
-		db		3, LOW(callback), HIGH(callback), UPPER(callback)
-		db		   LOW(proc),     HIGH(proc),     UPPER(proc),    0
-		db		   0,             0
+
+;-----------------------------------------------------------------------------
+; Option Decrement Item with fixed multi-lingual Title, stop at min value
+;
+; title_text_addr  address of multi-lingual item text
+; option_addr      address of option to be incremented on line selection
+;
+MENU_OPT_DECS	MACRO title_text_addr, option_addr
+
+items_count set items_count+1
+
+	extern	title_text_addr		; 2 byte address of multi-lingual title text
+	extern	option_addr			; 2 byte address of option definition data
+
+	local	code1 = 0x0001		; static multi-lingual title
+	local	code2 = 0x3001		; option decrement, stop at min value
+
+	db	low(title_text_addr + code1), high(title_text_addr + code1)
+	db	low(option_addr     + code2), high(option_addr     + code2)
+
 	ENDM
 
+
+;-----------------------------------------------------------------------------
+; Option Decrement Item for an Option out of an Option Group, with fixed multi-lingual Title
+;
+; title_text_addr  address of multi-lingual item text
+; option_addr      base address of the option group
+; gaslist_gas      offset of the selected option to be decremented within the group (normal variable)
+;
+MENU_GRP_DECS	MACRO title_text_addr, option_addr
+
+items_count set items_count+1
+
+	extern	title_text_addr		; 2 byte address of multi-lingual title text
+	extern	option_addr			; 2 byte address of option definition data
+
+	local	code1 = 0x0001		; static multi-lingual title
+	local	code2 = 0x7001		; option decrement, group member, stop at min value
+
+	db	low(title_text_addr + code1), high(title_text_addr + code1)
+	db	low(option_addr     + code2), high(option_addr     + code2)
+
+	ENDM
+
+
+;-----------------------------------------------------------------------------
+; Close a Menu Block
+;
 MENU_END	MACRO
+
+	IF items_count != items_target
+		Error "menu items count mismatch", x
+	ENDIF
+
 	ENDM
+
+
+;-----------------------------------------------------------------------------
+
--- a/src/menu_tree.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/menu_tree.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File menu_tree.asm                        next combined generation V3.08.8
+;   File menu_tree.asm                      * combined next generation V3.09.5
 ;
 ;   OSTC Surface Menus
 ;
@@ -9,711 +9,1427 @@
 ; HISTORY
 ;   2011-07-11 : [jDG] Creation.
 
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;
+;                                  ATTENTION
+;
+; All Calls made via the Menu Macros need to go to Addresses within 0x0xxxx !
+;
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
 #include "hwos.inc"						; mandatory header
+#include "shared_definitions.h"			; mailbox from/to p2_deco.c
 #include "gaslist.inc"
 #include "menu_processor.inc"
 #include "start.inc"
 #include "comm.inc"
-#include "logbook.inc"
 #include "tft.inc"
 #include "eeprom_rs232.inc"
 #include "external_flash.inc"
-#include "shared_definitions.h"			; mailbox from/to p2_deco.c
-#include "ghostwriter.inc"
 #include "adc_lightsensor.inc"
 #include "wait.inc"
 #include "i2c.inc"
 #include "calibrate.inc"
 #include "math.inc"
 #include "rtc.inc"
+#include "strings.inc"
+#include "tft_outputs.inc"
+#include "convert.inc"
+#include "colorschemes.inc"
 
 
-	extern	do_demo_divemode
-	extern	restart
+	extern	surfloop
+	extern	logbook
+	extern	demo_divemode
+	extern	demo_planner
+	extern	piezo_config
+	extern	comm_firmware_update_exec
+
 	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	surfloop
-	extern	oColorSetDive
+	extern	option_adjust_group_member
+	extern	option_inc
+	extern	option_dec
+	extern	option_draw
+
+	extern	get_cpu_version
 	extern	eeprom_deco_data_write
 
+
  IFDEF _ccr_pscr
 	extern	option_cleanup_oCCRMode
  ENDIF
 
  IFDEF _compass
-	extern	compass_calibration_loop
+	extern	compass_calibration
  ENDIF
 
-
-menu_tree	CODE
-
-;-----------------------------------------------------------------------------
+ IFDEF _rx_functions
+	extern	get_transmitter_id_by_slot
+ ENDIF
 
 
 ;=============================================================================
-; Main Menu
+surf_menu	CODE 0x01000				; needs to be at 0x0xxxx
+;=============================================================================
+
 
+;-----------------------------------------------------------------------------
+; Returning from a Menu Item
+;
 do_return_main_menu:
 	call	menu_processor_double_pop	; drop exit line and back to last line
-	bra		do_main_menu_common
+	bra		main_menu_common			; continue with menu
+
 
-	global	do_main_menu
-do_main_menu:
+;-----------------------------------------------------------------------------
+; Entry Point for Main Menu
+;
+	global	main_menu
+main_menu:
 	movff	active_customview,customview_surfmode	; save last custom view
 	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_menu_common:
+main_menu_common:
  IFDEF _ccr_pscr
 	MENU_BEGIN	tMainMenu, .7
-		MENU_CALL		tLogbook,					logbook
-		MENU_CALL		tGasSetup,					do_gas_menu
-		MENU_CALL		tCCRSetup,					do_ccr_menu
-		MENU_CALL		tDiveModeMenu,				do_divemode_menu
-		MENU_CALL		tSimulator,					do_simulator_menu
-		MENU_CALL		tSystSets,					do_settings_menu
+		MENU_CALL		tLogbook,					do_logbook
+		MENU_CALL		tGasSetup,					do_menu_gas
+		MENU_CALL		tCCRSetup,					do_menu_ccr
+		MENU_CALL		tDiveModeMenu,				do_menu_dive
+		MENU_CALL		tSimulator,					do_menu_simulator
+		MENU_CALL		tSystSets,					do_menu_settings
 		MENU_CALL		tExit,						do_restart
 	MENU_END
  ELSE
 	MENU_BEGIN	tMainMenu, .6
-		MENU_CALL		tLogbook,					logbook
-		MENU_CALL		tGasSetup,					do_gas_menu
-		MENU_CALL		tDiveModeMenu,				do_divemode_menu
-		MENU_CALL		tSimulator,					do_simulator_menu
-		MENU_CALL		tSystSets,					do_settings_menu
+		MENU_CALL		tLogbook,					do_logbook
+		MENU_CALL		tGasSetup,					do_menu_gas
+		MENU_CALL		tDiveModeMenu,				do_menu_dive
+		MENU_CALL		tSimulator,					do_menu_simulator
+		MENU_CALL		tSystSets,					do_menu_settings
 		MENU_CALL		tExit,						do_restart
 	MENU_END
- ENDIF
+ ENDIF	; _ccr_pscr
 
 
+;-----------------------------------------------------------------------------
+; Call Function - start Logbook
+;
+do_logbook:
+	goto	logbook						; code is hosted in logbook.asm
+
+
+;-----------------------------------------------------------------------------
+; Call Function - exit Menu
+;
 do_restart:
 	bsf		restart_fast				; skip logos and waits an restart
 	goto	restart						; restart into surface mode
 
-;=============================================================================
-; CCR Setup
 
  IFDEF _ccr_pscr
 
-do_return_ccr_menu:
+;-----------------------------------------------------------------------------
+; returning to CCR / pSCR Setup
+;
+do_return_menu_ccr:
 	call	menu_processor_double_pop	; drop exit line and back to last line
+	;bra	do_menu_ccr
 
-do_ccr_menu:
+
+;-----------------------------------------------------------------------------
+; CCR / pSCR Setup - 1st Level
+;
+do_menu_ccr:
 	call	option_cleanup_oCCRMode		; in pSCR mode, revert AutoSP (2) to calculated SP (0)
 
  IFDEF _external_sensor
+
 	bcf		imprint_sensor_mv			; stop imprinting of live O2 sensor mV data
-	btfsc	analog_o2_input
-	bra		do_ccr_menu_cR
- ENDIF
+	btfss	ext_input_s8_ana			; S8/analog sensor input available?
+	bra		do_menu_ccr_2				; NO  - do OSTC 2  menu
+	;bra	do_menu_ccr_cR				; YES - do OSTC cR menu
 
-	MENU_BEGIN	tCCRSetup, .5			; OSTC3 menu (and currently also the OSTC2 menu)
-		MENU_OPTION		tCCRMode,					oCCRMode,				0
-		MENU_CALL		tDiluentSetup,				do_diluent_setup
-		MENU_CALL		tFixedSetpoints,			do_fixed_setpoints
-		MENU_CALL		tMore,						do_ccr_menu_more
+do_menu_ccr_cR:							; OSTC cR menu
+	MENU_BEGIN	tCCRSetup, .6
+		MENU_OPT_INC	tCCRMode,					oCCRMode
+		MENU_CALL		tCalibrateMenu,				do_menu_calibrate
+		MENU_CALL		tDiluentSetup,				do_menu_diluent
+		MENU_CALL		tFixedSetpoints,			do_menu_setpoints
+		MENU_CALL		tMore,						do_menu_ccr_more
+		MENU_CALL		tBack,						do_return_main_menu
+	MENU_END
+
+ ENDIF	; _external_sensor
+
+do_menu_ccr_2:
+	MENU_BEGIN	tCCRSetup, .5			; OSTC 2 menu
+		MENU_OPT_INC	tCCRMode,					oCCRMode
+		MENU_CALL		tDiluentSetup,				do_menu_diluent
+		MENU_CALL		tFixedSetpoints,			do_menu_setpoints
+		MENU_CALL		tMore,						do_menu_ccr_more
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
 
+;-----------------------------------------------------------------------------
+; CCR / pSCR Setup - 2nd Level
+;
+do_menu_ccr_more:
  IFDEF _external_sensor
-
-do_ccr_menu_cR:							; cR menu
-	MENU_BEGIN	tCCRSetup, .6
-		MENU_OPTION		tCCRMode,					oCCRMode,				0
-		MENU_CALL		tCalibrateMenu,				do_calibrate_menu
-		MENU_CALL		tDiluentSetup,				do_diluent_setup
-		MENU_CALL		tFixedSetpoints,			do_fixed_setpoints
-		MENU_CALL		tMore,						do_ccr_menu_more
-		MENU_CALL		tBack,						do_return_main_menu
-	MENU_END
-
-
-do_calibrate_menu:
-	call	enable_ir_s8				; enable IR/S8-Port
-	bsf		imprint_sensor_mv			; start imprinting of live O2 sensor mV data
-
-do_calibrate_menu2:
-	MENU_BEGIN	tCalibrateMenu, .6
-		MENU_CALL		tDiveHudMask1,				0
-		MENU_CALL		tDiveHudMask2,				0
-		MENU_CALL		tDiveHudMask3,				0
-		MENU_OPTION		tCalibrationGas,			oCalGasO2,				0
-		MENU_CALL		tCalibrate,					do_calibrate_mix
-		MENU_CALL		tBack,						do_return_ccr_menu
-	MENU_END
-
-
-do_calibrate_mix:
-	call	calibrate_mix				; calibrate with opt_calibration_O2_ratio, also calibrate S8 HUD if connected
-	WAITMS	d'250'						; wait for HUD v3
-	movlw	.9
-	movff	WREG,customview_surfmode	; show sensor mV custom view after restart
-	bsf		restart_fast				; skip logos and waits an restart
-	goto	restart						; restart into surface mode
-
- ENDIF	; _external_sensor
-
-
-do_diluent_setup:
-	bsf		is_diluent_menu				; setting up diluents
-	bcf		short_gas_descriptions		; do not use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
-	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
-	call	gaslist_cleanup_list		; take care that only one gas can be first
-
-	MENU_BEGIN	tDiluentSetup, .6
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_CALL		tBack,						do_return_ccr_menu
-	MENU_END
-
-
-do_return_fixed_setpoints:
-	call	menu_processor_double_pop	; drop exit line and back to last line
-
-do_fixed_setpoints:
-	bcf		short_gas_descriptions		; =1: use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
-	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
-
-	MENU_BEGIN	tFixedSetpoints, .6
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_edit_sp_menu
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_edit_sp_menu
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_edit_sp_menu
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_edit_sp_menu
-		MENU_DYNAMIC	gaslist_strcat_setpoint,	do_edit_sp_menu
-		MENU_CALL		tBack,						do_return_ccr_menu
-	MENU_END
-
-
-do_edit_sp_menu:
-	movff	PRODL,gaslist_gas			; get menu item we came from (0-4)
-
-	MENU_BEGIN	tFixedSetpoints, .5
-		MENU_DYNAMIC	gaslist_strcat_setpoint_0,	0
-		MENU_CALL		tSPPlus,					gaslist_spplus
-		MENU_CALL		tDepthPlus,					gaslist_spdepthplus
-		MENU_CALL		tDepthMinus,				gaslist_spdepthminus
-		MENU_CALL		tBack,						do_return_fixed_setpoints
-	MENU_END
-
-
-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_BEGIN	tCCRSetup, .7			; CCR/pSCR more menu
+		MENU_OPT_INC	tS8Mode,					oS8Mode
+		MENU_OPT_INC	tCCmaxFracO2,				oCCmaxFracO2
+		MENU_OPT_INC	tDilppO2Check,				oDilppO2Check
+		MENU_OPT_INC	tGasDensityCheck,			oGasDensityCheck
+		MENU_OPT_INC	tPSCR_O2_drop,				oPSCR_drop
+		MENU_OPT_INC	tPSCR_lungratio,			oPSCR_lungratio
+		MENU_CALL		tBack,						do_return_menu_ccr
 	MENU_END
  ELSE
-	MENU_BEGIN	tCCRSetup, .5			; CCR/pSCR more menu
-		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_BEGIN	tCCRSetup, .6			; CCR/pSCR more menu
+		MENU_OPT_INC	tCCmaxFracO2,				oCCmaxFracO2
+		MENU_OPT_INC	tDilppO2Check,				oDilppO2Check
+		MENU_OPT_INC	tGasDensityCheck,			oGasDensityCheck
+		MENU_OPT_INC	tPSCR_O2_drop,				oPSCR_drop
+		MENU_OPT_INC	tPSCR_lungratio,			oPSCR_lungratio
+		MENU_CALL		tBack,						do_return_menu_ccr
 	MENU_END
  ENDIF	; _external_sensor
 
  ENDIF	; _ccr_pscr
 
-;=============================================================================
-; OC Gas Setup
+
+ IFDEF _external_sensor
+
+;-----------------------------------------------------------------------------
+; Calibration Menu
+;
+do_menu_calibrate:
+	call	enable_ir_s8_analog			; enable IR/S8/analog interface
+	bsf		imprint_sensor_mv			; start imprinting of live O2 sensor mV data
+
+	MENU_BEGIN	tCalibrateMenu, .6
+		MENU_CALL		tDiveHudMask1,				0					; data will be superimposed by housekeeping
+		MENU_CALL		tDiveHudMask2,				0					; ...
+		MENU_CALL		tDiveHudMask3,				0					; ...
+		MENU_OPT_INC	tCalibrationGas,			oCalGasO2
+		MENU_CALL		tCalibrate,					do_calibrate
+		MENU_CALL		tBack,						do_return_menu_ccr
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; Call Function - start Calibration, returns to Surface Mode
+;
+do_calibrate:
+	call	calibrate_mix				; calibrate with opt_calibration_O2_ratio, also calibrate S8 HUD if connected
+	WAITMS	d'250'						; wait for HUD v3
+	movlw	.9							; load index of sensor mV custom view
+	movff	WREG,customview_surfmode	; show this custom view when back in surface mode
+	bra		do_restart					; exit menu
+
+ ENDIF	; _external_sensor
+
+
+ IFDEF _ccr_pscr
+
+;-----------------------------------------------------------------------------
+; Diluent Setup
+;
+do_menu_diluent:
+	bsf		is_diluent_menu				; setting up diluents
+	bcf		short_gas_descriptions		; use long gas description format
+	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
+	call	gaslist_cleanup_list		; make sure there is only one gas being first
+
+	MENU_BEGIN	tDiluentSetup, .6
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_CALL		tBack,						do_return_menu_ccr
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show full Gas Description (just for info, active code is in other place)
+;
+;dyn_strcat_gas_PRODL:
+;	goto	gaslist_strcat_gas_PRODL	; code is hosted in gaslist.asm
+
 
-do_return_gas_menu:
+;-----------------------------------------------------------------------------
+; returning to Setpoint Setup
+;
+do_return_menu_setpoints:
+	call	menu_processor_double_pop	; drop exit line and back to last line
+	bcf		block_option_value			; resume displaying of option values
+	;bra	do_menu_setpoints			; continue
+
+
+;-----------------------------------------------------------------------------
+; Setpoint Setup - 1st Level
+;
+do_menu_setpoints:
+	bcf		short_gas_descriptions		;  use long gas description format
+	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
+
+	MENU_BEGIN	tFixedSetpoints, .6
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_menu_edit_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_menu_edit_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_menu_edit_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_menu_edit_sp
+		MENU_DYNAMIC	dyn_strcat_setpoint_prodl,	do_menu_edit_sp
+		MENU_CALL		tBack,						do_return_menu_ccr
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Setpoint Data
+;
+dyn_strcat_setpoint_prodl:
+	goto	gaslist_strcat_setpoint_PRODL ; function is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; Setpoint Setup - 2nd Level
+;
+do_menu_edit_sp:
+	movff	PRODL,gaslist_gas			; get menu item we came from (0-4)
+	bsf		block_option_value			; suspend displaying of option values
+
+	MENU_BEGIN	tFixedSetpoints, .5
+		MENU_DYNAMIC	dyn_strcat_setpoint,		0
+		MENU_GRP_INC	tSPPlus,					oSP1ppO2
+		MENU_GRP_INCS	tDepthPlus,					oSP1Depth
+		MENU_GRP_DECS	tDepthMinus,				oSP1Depth
+		MENU_CALL		tBack,						do_return_menu_setpoints
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Setpoint Data
+;
+dyn_strcat_setpoint:
+	goto	gaslist_strcat_setpoint		; function is hosted in gaslist.asm
+
+ ENDIF	; _ccr_pscr
+
+
+;-----------------------------------------------------------------------------
+; returning from Gas / Diluent Setup
+;
+do_return_menu_gas:
 	call	menu_processor_double_pop	; drop exit line and back to last line
 
  IFDEF _ccr_pscr
 	btfsc	is_diluent_menu				; return from setting up diluents?
-	bra		do_diluent_setup			; YES
+	bra		do_menu_diluent				; YES - continue with diluent menu
+	;bra	do_menu_gas					; NO  - continue with OC gas  menu
  ENDIF
 
-do_gas_menu:
+
+;-----------------------------------------------------------------------------
+; OC Gas Setup - 1st Level
+;
+do_menu_gas:
 	bcf		is_diluent_menu				; setting up OC gases
-	bcf		short_gas_descriptions		; do not use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
+	bcf		short_gas_descriptions		;  use long gas description format
 	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
-	call	gaslist_cleanup_list		; takes care that only one gas can be first
+	call	gaslist_cleanup_list		; make sure there is only one gas being first
 
 	MENU_BEGIN	tGaslist, .6
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
-		MENU_DYNAMIC	gaslist_strcat_gas_cd,		do_edit_gas_menu
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
+		MENU_DYNAMIC	dyn_strcat_gas_PRODL,		do_menu_edit_gas
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
 
-do_return_edit_gas_menu:
+;-----------------------------------------------------------------------------
+; dynamic Title - show full Gas Description
+;
+dyn_strcat_gas_PRODL:
+	goto	gaslist_strcat_gas_PRODL	; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; return to OC Gas Setup from Sub-Menu
+;
+do_return_menu_edit_gas:
  IFDEF _rx_functions
 	bcf		imprint_xmitter_pres		; stop imprinting of transmitter pressure data
 	bcf		imprint_xmitter_ID			; not in transmitter selection menu any more (back to normal timeout)
  ENDIF
-	call	menu_processor_double_pop	;  drop exit line and back to last line
-	bra		do_edit_gas_menu_common
+	call	menu_processor_double_pop	; drop exit line and back to last line
+	bcf		block_option_value			; resume displaying of option values
+	bra		do_menu_edit_gas_common		; continue with common part
+
 
-do_edit_gas_menu:
+;-----------------------------------------------------------------------------
+; OC Gas Setup - 2nd Level
+;
+do_menu_edit_gas:
 	movff	PRODL,gaslist_gas			; get menu item we came from (0-4)
 	movlw	.5							; offset between gases and diluents
 	btfsc	is_diluent_menu				; setting up diluents?
 	addwf	gaslist_gas,F				; YES - add the offset
 
-do_edit_gas_menu_common:
+do_menu_edit_gas_common:
 	MENU_BEGIN	tGasEdit, .7
-		MENU_DYNAMIC	gaslist_gastitle,			0
-		MENU_DYNAMIC	gaslist_MOD_END,			0
-		MENU_DYNAMIC	gaslist_show_type,			gaslist_toggle_type
-		MENU_CALL		tSetup_GasMix,				do_setup_mix_menu
-		MENU_DYNAMIC	gaslist_GasDepth,			do_setup_depth_menu
-		MENU_CALL		tSetup_Tank,				do_setup_tank_menu
-		MENU_CALL		tBack,						do_return_gas_menu
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_DYNAMIC	dyn_MOD_END,				0
+		MENU_GRP_INC	tType,						oGas1
+		MENU_CALL		tSetup_GasMix,				do_menu_gas_mix
+		MENU_DYNAMIC	dyn_show_depth,				do_menu_gas_depth
+		MENU_CALL		tSetup_Tank,				do_menu_gas_tank
+		MENU_CALL		tBack,						do_return_menu_gas
 	MENU_END
 
 
-do_setup_mix_menu:
+;-----------------------------------------------------------------------------
+; dynamic Title - show full Gas Description
+;
+dyn_gastitle:
+	goto	gaslist_strcat_gas			; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show MOD and END
+;
+dyn_MOD_END:
+	goto	gaslist_MOD_END				; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Change Depth
+;
+dyn_show_depth:
+	movf	gaslist_gas,W				; load gas/dil index into WREG (0-9)
+	lfsr	FSR1,opt_gas_change			; load base address of change depths
+	tstfsz	PLUSW1						; change depth = 0 ?
+	bra		dyn_show_depth_1			; NO  - print in normal color
+	lfsr	FSR1,opt_gas_type			; YES - load base address of opt_gas_type
+	tstfsz	PLUSW1						;     - type = disabled ?
+	FONT_COLOR_ATTENTION				;       NO  - print in attention color (yellow)
+dyn_show_depth_1:
+	STRCAT_TEXT tSetup_GasDepth			; print text
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; OC Gas Setup - 3rd Level - Mix
+;
+do_menu_gas_mix:
+	bsf		block_option_value			; suspend displaying of option values
+
  IFDEF _helium
 	MENU_BEGIN	tGasEdit, .7
-		MENU_DYNAMIC	gaslist_gastitle,			0
-		MENU_DYNAMIC	gaslist_MOD_END,			0
-		MENU_CALL		tO2Plus,					gaslist_pO2
-		MENU_CALL		tO2Minus,					gaslist_mO2
-		MENU_CALL		tHePlus,					gaslist_pHe
-		MENU_CALL		tHeMinus,					gaslist_mHe
-		MENU_CALL		tBack,						do_return_edit_gas_menu
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_DYNAMIC	dyn_MOD_END,				0
+		MENU_GRP_INCS	tO2Plus,					oGas1O2
+		MENU_GRP_DECS	tO2Minus,					oGas1O2
+		MENU_GRP_INCS	tHePlus,					oGas1He
+		MENU_GRP_DECS	tHeMinus,					oGas1He
+		MENU_CALL		tBack,						do_return_menu_edit_gas
 	MENU_END
  ELSE
 	MENU_BEGIN	tGasEdit, .5
-		MENU_DYNAMIC	gaslist_gastitle,			0
-		MENU_DYNAMIC	gaslist_MOD_END,			0
-		MENU_CALL		tO2Plus,					gaslist_pO2
-		MENU_CALL		tO2Minus,					gaslist_mO2
-		MENU_CALL		tBack,						do_return_edit_gas_menu
-	MENU_END
- ENDIF
-
-
-do_setup_tank_menu:
- IFDEF _rx_functions
-	TSTOSC	opt_TR_mode					; TR functions switched on?
-	bra		do_setup_tank_menu_rx		; YES
- ENDIF
-
- IFDEF _ccr_pscr
-	MENU_BEGIN	tSetup_Tank, .6
-		MENU_DYNAMIC	gaslist_gastitle,			0
-		MENU_DYNAMIC	gaslist_tank_size_pres,		0
-		MENU_CALL		tTankSize,					gaslist_tank_size
-		MENU_CALL		tTankUsablePress,			gaslist_tank_pres
-		MENU_CALL		tCopyDilToOC,				gaslist_copy_dil_to_oc
-		MENU_CALL		tBack,						do_return_edit_gas_menu
-	MENU_END
- ELSE
-	MENU_BEGIN	tSetup_Tank, .5
-		MENU_DYNAMIC	gaslist_gastitle,			0
-		MENU_DYNAMIC	gaslist_tank_size_pres,		0
-		MENU_CALL		tTankSize,					gaslist_tank_size
-		MENU_CALL		tTankUsablePress,			gaslist_tank_pres
-		MENU_CALL		tBack,						do_return_edit_gas_menu
-	MENU_END
- ENDIF
-
-
- IFDEF _rx_functions
-do_setup_tank_menu_rx:
-	setf	pairing_slot				; prime slot number with 255 aka -1, used in pairing function
-	bsf		imprint_xmitter_ID			; in transmitter selection menu (longer timeout)
-
-	MENU_BEGIN	tSetup_Tank, .7
-		MENU_DYNAMIC	gaslist_gastitle,			0
-		MENU_DYNAMIC	gaslist_tank_id_pres,		0					; when changing position, adopt TFT_menu_tank_pres!
-		MENU_DYNAMIC	gaslist_tank_size_pres,		0
-		MENU_CALL		tTankPairing,				gaslist_tank_pairing
-		MENU_CALL		tTankSize,					gaslist_tank_size
-		MENU_CALL		tTankUsablePress,			gaslist_tank_pres
-		MENU_CALL		tBack,						do_return_edit_gas_menu
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_DYNAMIC	dyn_MOD_END,				0
+		MENU_GRP_INCS	tO2Plus,					oGas1O2
+		MENU_GRP_DECS	tO2Minus,					oGas1O2
+		MENU_CALL		tBack,						do_return_menu_edit_gas
 	MENU_END
  ENDIF
 
 
-do_setup_depth_menu:
+;-----------------------------------------------------------------------------
+; OC Gas Setup - 3rd Level - Change Depth
+;
+do_menu_gas_depth:
+	bsf		block_option_value			; suspend displaying of option values
 
 	MENU_BEGIN	tGasEdit, .7
-		MENU_DYNAMIC	gaslist_gastitle,			0
-		MENU_DYNAMIC	gaslist_MOD_END,			0
-		MENU_DYNAMIC	gaslist_ppo2,				0					; ppO2 at change depth
-		MENU_CALL		tDepthPlus,					gaslist_pDepth
-		MENU_CALL		tDepthMinus,				gaslist_mDepth
-		MENU_DYNAMIC	gaslist_reset_mod_title,	gaslist_reset_mod
-		MENU_CALL		tBack,						do_return_edit_gas_menu
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_DYNAMIC	dyn_MOD_END,				0
+		MENU_DYNAMIC	dyn_ppo2,					0
+		MENU_GRP_INCS	tDepthPlus,					oGas1Depth
+		MENU_GRP_DECS	tDepthMinus,				oGas1Depth
+		MENU_DYNAMIC	dyn_reset_mod_title,		do_gas_depth_reset
+		MENU_CALL		tBack,						do_return_menu_edit_gas
 	MENU_END
 
 
-;=============================================================================
-; Simulator Menus
+;-----------------------------------------------------------------------------
+; dynamic Title - show Gas Description
+;
+;dyn_gastitle:
+;	goto	gaslist_strcat_gas			; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show MOD and END
+;
+;dyn_MOD_END:
+;	goto	gaslist_MOD_END				; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show ppO2 and Change Depth
+;
+dyn_ppo2:
+	goto	gaslist_ppo2				; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show 'Rest to MOD' Dialog
+;
+dyn_reset_mod_title:
+	goto	gaslist_reset_mod_title		; code is hosted in gaslist.asm
+
+
+;-----------------------------------------------------------------------------
+; Call Function - reset Change Depth to MOD
+;
+do_gas_depth_reset:
+	call	gaslist_calc_mod			; compute MOD, result in WREG
+	movwf	lo							; copy result to lo
+	lfsr	FSR1,opt_gas_change			; load base address of opt_gas_change
+	movf	gaslist_gas,W				; load index
+	movff	lo,PLUSW1					; update change depth
+	bsf		option_changed				; flag that EEPROM needs to be updated
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; OC Gas Setup - 3rd Level - Tank Setup
+;
+do_menu_gas_tank:
+ IFDEF _rx_functions
+	TSTOSC	opt_TR_mode					; TR functions switched on?
+	bra		do_menu_gas_tank_rx			; YES
+ ENDIF
+
+ IFDEF _ccr_pscr
+	MENU_BEGIN	tSetup_Tank, .5
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_GRP_INC	tTankSize,					oTankSizeOC1
+		MENU_GRP_INC	tTankUsablePress,			oTankPresOC1
+		MENU_CALL		tCopyDilToOC,				do_copy_dil_to_oc
+		MENU_CALL		tBack,						do_return_menu_edit_gas
+	MENU_END
+ ELSE
+	MENU_BEGIN	tSetup_Tank, .4
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_GRP_INC	tTankSize,					oTankSizeOC1
+		MENU_GRP_INC	tTankUsablePress,			oTankPresOC1
+		MENU_CALL		tBack,						do_return_menu_edit_gas
+	MENU_END
+ ENDIF	; _ccr_pscr
+
+
+ IFDEF _rx_functions
+do_menu_gas_tank_rx:
+	setf	pairing_slot				; prime slot number with 255 aka -1, used in pairing function
+	bsf		imprint_xmitter_ID			; in transmitter selection menu (longer timeout)
+
+ IFDEF _ccr_pscr
+	MENU_BEGIN	tSetup_Tank, .7
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_DYNAMIC	dyn_tank_id_pres,			0				; pressure will be superimposed by housekeeping
+		MENU_CALL		tTankPairing,				do_tank_pairing
+		MENU_GRP_INC	tTankSize,					oTankSizeOC1
+		MENU_GRP_INC	tTankUsablePress,			oTankPresOC1
+		MENU_CALL		tCopyDilToOC,				do_copy_dil_to_oc
+		MENU_CALL		tBack,						do_return_menu_edit_gas
+	MENU_END
+ ELSE
+	MENU_BEGIN	tSetup_Tank, .6
+		MENU_DYNAMIC	dyn_gastitle,				0
+		MENU_DYNAMIC	dyn_tank_id_pres,			0				; pressure will be superimposed by housekeeping
+		MENU_CALL		tTankPairing,				do_tank_pairing
+		MENU_GRP_INC	tTankSize,					oTankSizeOC1
+		MENU_GRP_INC	tTankUsablePress,			oTankPresOC1
+		MENU_CALL		tBack,						do_return_menu_edit_gas
+	MENU_END
+ ENDIF	; _ccr_pscr
+
 
-do_return_planner_menu:
+;-----------------------------------------------------------------------------
+; dynamic Title - show Transmitter ID
+;
+dyn_tank_id_pres:
+	STRCAT	"  ID: "					; print header
+	; get ID
+	lfsr	FSR1,opt_transmitter_id_1	; load base address of opt_transmitter_id
+	movf	gaslist_gas,W				; load index (0-9)
+	rlncf	WREG,W						; multiply by 2 because IDs are 2 byte in size
+	movff	PLUSW1,lo					; copy opt_transmitter_id+0[gaslist_gas] to lo
+	incf	WREG,W						; increment index
+	movff	PLUSW1,hi					; copy opt_transmitter_id+1[gaslist_gas] to hi
+	; check if a transmitter is paired to this tank
+	tstfsz	hi							; high byte of ID <> 0 ?
+	bra		dyn_tank_id_pres_1			; YES - a transmitter is paired to the tank
+	tstfsz	lo							; low  byte of ID <> 0 ?
+	bra		dyn_tank_id_pres_1			; YES - a transmitter is paired to the tank
+	STRCAT	"----"						; NO  - no transmitter paired
+	bcf		imprint_xmitter_pres		;     - stop imprinting of transmitter pressure data
+	return								;     - done
+dyn_tank_id_pres_1:						; show ID
+	movf	hi,W						; copy high byte of ID to WREG
+	output_hex							; print it
+	movf	lo,W						; copy low  byte of ID to WREG
+	output_hex							; print it
+	bsf		imprint_xmitter_pres		; start imprinting of transmitter pressure data
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Call Function - pair a Transmitter to a Tank
+;
+do_tank_pairing:
+	incf	pairing_slot,F				; goto next RX data slot
+	btfsc	pairing_slot,3				; slot = 8?
+	bra		do_tank_pairing_none		; YES - offer unpairing
+	movf	pairing_slot,W				; NO  - copy slot to WREG
+	call	get_transmitter_id_by_slot	; WREG = slot (0-7) -> hi:lo = transmitter ID
+	tstfsz	hi							; transmitter found (probe on high byte)?
+	bra		do_tank_pairing_common		; YES - select this transmitter
+	tstfsz	hi							; transmitter found (probe on low byte)?
+	bra		do_tank_pairing_common		; YES - select this transmitter
+	bra		do_tank_pairing				; NO  - try next slot
+do_tank_pairing_common:
+	lfsr	FSR1,opt_transmitter_id_1	; load base address of opt_transmitter_id
+	movf	gaslist_gas,W				; load index into WREG (0-9)
+	rlncf	WREG,W						; multiply by 2 because IDs are 2 byte in size
+	movff	lo,PLUSW1					; copy lo to opt_transmitter_id+0[gaslist_gas]
+	incf	WREG,W						; increment index
+	movff	hi,PLUSW1					; copy hi to opt_transmitter_id+1[gaslist_gas]
+	bsf		option_changed				; flag that EEPROM needs to be updated
+	return								; done
+do_tank_pairing_none:
+	setf	pairing_slot				; prime slot number with 255 aka -1
+	clrf	hi							; adjust "no transmitter" ID
+	clrf	lo							; adjust "no transmitter" ID
+	bra		do_tank_pairing_common		; continue with common part
+
+ ENDIF	; _rx_functions
+
+
+ IFDEF _ccr_pscr
+
+;-----------------------------------------------------------------------------
+; Call Function - copy Diluent Setup to OC Gases
+;
+do_copy_dil_to_oc:
+	bcf		copying_dil					; default to copying a gas
+	movf	gaslist_gas,W				; copy current gas or diluent number to WREG
+	btfss	is_diluent_menu				; setting up diluents?
+	bra		do_copy_dil_to_oc_1			; NO  - gaslist_gas is already pointing to an OC gas
+	addlw	-.5							; YES - subtract offset between diluents and gases
+	movwf	gaslist_gas					;     - let gaslist_gas point to the corresponding OC gas
+	bsf		copying_dil					;     - we are copying a diluent
+	bcf		is_diluent_menu				;     - pretend we are setting up OC gases
+do_copy_dil_to_oc_1:
+	lfsr	FSR0,opt_dil_O2_ratio		; load base address of diluents settings, ASM variables
+	lfsr	FSR1,opt_gas_O2_ratio		; load base address of gas      settings, ASM variables
+	movff	PLUSW0,PLUSW1				; copy O2 ratio
+	addlw	.10							; add offset from O2 ratios to He ratios
+	movff	PLUSW0,PLUSW1				; copy He ratio
+	addlw	.10							; add offset from He ratios to types
+	movff	PLUSW0,PLUSW1				; copy type
+	addlw	.10							; add offset from type to change depth
+	movff	PLUSW0,PLUSW1				; copy change depth
+	addlw	-.30						; wind back to initial gas number
+	lfsr	FSR0,char_I_gas_avail_size+5; load base address of diluents settings, shared variables
+	lfsr	FSR1,char_I_gas_avail_size+0; load base address of gas      settings, shared variables
+	movff	PLUSW0,PLUSW1				; copy tank size
+	addlw	.10							; add offset from tank sizes to pressure budget
+	movff	PLUSW0,PLUSW1				; copy pressure budget
+	call	gaslist_cleanup_list		; make sure there is only one gas being first
+	bsf		option_changed				; flag that EEPROM needs to be updated
+	btfss	copying_dil					; are we copying a diluent?
+	return								; NO  - done
+	bsf		is_diluent_menu				; YES - restore to be setting up diluents
+	movlw	.5							;     - offset between OC gases and diluents
+	addwf	gaslist_gas,F				;     - let gaslist_gas point to the diluent again
+	WIN_BOX_BLACK .30,.239,.0,.159		;     - create some visual effect to show activity
+	WAITMS	.200						;     - pause for 200 ms
+	return								;     - done
+
+ ENDIF	; _ccr_pscr
+
+
+;-----------------------------------------------------------------------------
+; return to Simulator (Deco Calculator) Menu from Sub-Menu
+;
+do_return_menu_simulator:
 	call	menu_processor_double_pop	; drop exit line and back to last line
-	bra		do_planner_common_1
+	bra		do_menu_simulator_common_2	; continue
+
 
-	global	do_return_demo_planner
-do_return_demo_planner:
+;-----------------------------------------------------------------------------
+; return to Simulator (Deco Calculator) Menu from Deco Calculator
+;
+	global	do_return_menu_simulator_planner
+do_return_menu_simulator_planner:
 	call	menu_processor_pop			; back to last line
-	bra		do_planner_common
+	bra		do_menu_simulator_common_1	; continue
+
 
-do_simulator_menu:
+;-----------------------------------------------------------------------------
+; Simulator (Deco Calculator) Menu
+;
+do_menu_simulator:
 	; reset planning parameters to default values
-	lfsr	FSR0,odiveInterval
-	call	option_reset
-	lfsr	FSR0,obottomTime
-	call	option_reset
-	lfsr	FSR0,obottomDepth
-	call	option_reset
-	lfsr	FSR0,oSimAGF
-	call	option_reset
+	lfsr	FSR0,odiveInterval			; surface interval
+	call	option_reset				; reset to default
+	lfsr	FSR0,obottomTime			; bottom time
+	call	option_reset				; reset to default
+	lfsr	FSR0,obottomDepth			; bottom depth
+	call	option_reset				; reset to default
+	lfsr	FSR0,oSimAGF				; GF/aGF
+	call	option_reset				; reset to default
 
  IFDEF _gas_contingency
-	; switch off gas contingency mode by default when entering the simulator menu
-	clrf	WREG
-	movff	WREG,opt_gas_contingency_sim
- ENDIF
+	lfsr	FSR0,oGasContingencySim		; gas contingency
+	call	option_reset				; reset to default (volatile option)
+ ENDIF	; _gas_contingency
 
-do_planner_common:
+do_menu_simulator_common_1:
 	call	restart_set_modes_and_flags	; initialize dive mode settings
-do_planner_common_1:
+
+do_menu_simulator_common_2:
+
+ IFDEF _ccr_pscr
+
 	movff	opt_dive_mode,WREG			; get dive mode: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR
-	dcfsnz	WREG,W						; subtract one, became zero?
-	bra		do_planner_common_ccr		; YES - use CCR version
+	decfsz	WREG,W						; subtract one, became zero?
+	bra		do_menu_simulator_common_oc	; NO  - use OC  version
+	;bra	do_menu_simulator_common_ccr; YES - use CCR version
 
+do_menu_simulator_common_ccr:
 	MENU_BEGIN	tSimulator, .7
-		MENU_OPTION		tIntvl,						odiveInterval,			0
-		MENU_OPTION		tBtDep,						obottomDepth,			0
+		MENU_OPT_INC	tIntvl,						odiveInterval
+		MENU_OPT_INC	tBtDep,						obottomDepth
 		MENU_CALL		tInter,						do_demo_divemode
-		MENU_OPTION		tBtTm,						obottomTime,			0
-		MENU_OPTION		tuseAGF,					oSimAGF,				0
+		MENU_OPT_INC	tBtTm,						obottomTime
+		MENU_CALL		tCalculatorSetup,			do_menu_simulator_more
 		MENU_CALL		tDeco,						do_demo_planner
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
-do_planner_common_ccr:
+ ENDIF	; _ccr_pscr
+
+do_menu_simulator_common_oc:
 	MENU_BEGIN	tSimulator, .7
-		MENU_OPTION		tIntvl,						odiveInterval,			0
-		MENU_OPTION		tBtDep,						obottomDepth,			0
+		MENU_OPT_INC	tIntvl,						odiveInterval
+		MENU_OPT_INC	tBtDep,						obottomDepth
 		MENU_CALL		tInter,						do_demo_divemode
-		MENU_OPTION		tBtTm,						obottomTime,			0
-		MENU_CALL		tCalculatorSetup,			do_planner_config
+		MENU_OPT_INC	tBtTm,						obottomTime
+		MENU_OPT_INC	tuseAGF,					oSimAGF
 		MENU_CALL		tDeco,						do_demo_planner
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
-do_planner_config:
+
+;-----------------------------------------------------------------------------
+; Call Function - start Simulator Mode
+;
+do_demo_divemode:
+	goto	demo_divemode				; code is hosted in divemode.asm
+
+
+;-----------------------------------------------------------------------------
+; Call Function - start Deco Calculator
+;
+do_demo_planner:
+	goto	demo_planner				; code is hosted in simulator.asm
+
+
+;-----------------------------------------------------------------------------
+; Simulator (Deco Calculator) Menu - 2nd Layer
+;
+do_menu_simulator_more:
  IFDEF _gas_contingency
 	MENU_BEGIN	tSimulator, .4
-		MENU_OPTION		tSelectSetpoint,			oSimSetpoint,			0
-		MENU_OPTION		tuseAGF,					oSimAGF,				0
-		MENU_OPTION		tGasContingencySim,			oGasContingencySim,		0
-		MENU_CALL		tBack,						do_return_planner_menu
+		MENU_OPT_INC	tSelectSetpoint,			oSimSetpoint
+		MENU_OPT_INC	tuseAGF,					oSimAGF
+		MENU_OPT_INC	tGasContingencySim,			oGasContingencySim
+		MENU_CALL		tBack,						do_return_menu_simulator
 	MENU_END
  ELSE
 	MENU_BEGIN	tSimulator, .3
-		MENU_OPTION		tSelectSetpoint,			oSimSetpoint,			0
-		MENU_OPTION		tuseAGF,					oSimAGF,				0
-		MENU_CALL		tBack,						do_return_planner_menu
+		MENU_OPT_INC	tSelectSetpoint,			oSimSetpoint
+		MENU_OPT_INC	tuseAGF,					oSimAGF
+		MENU_CALL		tBack,						do_return_menu_simulator
+	MENU_END
+ ENDIF	; _gas_contingency
+
+
+;-----------------------------------------------------------------------------
+; return to Dive Settings Menu from Sub-Menu
+;
+do_return_menu_dive:
+	call	menu_processor_double_pop	; drop exit line and back to last line
+	;bra	do_menu_dive			; continue
+
+;-----------------------------------------------------------------------------
+; Dive Settings Menu - 1st Layer
+;
+do_menu_dive:
+	MENU_BEGIN	tDiveModeMenu, .6
+		MENU_CALL		tDiveSetup,					do_menu_dive_dive		; dive setup
+		MENU_CALL		tDecoSetup,					do_menu_dive_deco		; deco setup
+		MENU_CALL		tSACSetup,					do_menu_dive_SAC		; SAC  setup
+		MENU_CALL		tppO2Setup,					do_menu_dive_ppO2		; ppO2 limits
+		MENU_CALL		tStopsSetup,				do_menu_dive_stops		; stops setup
+		MENU_CALL		tBack,						do_return_main_menu
+	MENU_END
+
+;-----------------------------------------------------------------------------
+; Dive Settings Menu - 2nd Layer - Dive Mode
+;
+do_menu_dive_dive:
+ IFDEF _cave_mode
+	MENU_BEGIN	tDiveModeMenu, .6
+		MENU_OPT_INC	tDvMode,					oDiveMode				; dive mode
+		MENU_OPT_INC	tCvMode,					oCaveMode				; cave mode
+		MENU_OPT_INC	tFTTSMenu,					oExtraTime				; fTTS/delay
+		MENU_OPT_INC	tTimeoutDive,				oDiveTimeout			; dive timeout
+		MENU_OPT_INC	tStoreApnoeDive,			oStoreApnoe				; store apnoe
+		MENU_CALL		tBack,						do_return_menu_dive
+	MENU_END
+ ELSE
+	MENU_BEGIN	tDiveModeMenu, .5
+		MENU_OPT_INC	tDvMode,					oDiveMode				; dive mode
+		MENU_OPT_INC	tFTTSMenu,					oExtraTime				; fTTS/delay
+		MENU_OPT_INC	tTimeoutDive,				oDiveTimeout			; dive timeout
+		MENU_OPT_INC	tStoreApnoeDive,			oStoreApnoe				; store apnoe
+		MENU_CALL		tBack,						do_return_menu_dive
 	MENU_END
  ENDIF
 
 
-;=============================================================================
-; Divemode Menu
+;-----------------------------------------------------------------------------
+; return to Dive Settings Menu from Sub-Menu
+;
+do_return_menu_dive_deco:
+	call	menu_processor_double_pop	; drop exit line and back to last line
+	;bra	do_menu_dive_deco				; continue
 
-do_return_divemode_menu:
-	call	menu_processor_double_pop	; drop exit line and back to last line
 
-do_divemode_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
+;-----------------------------------------------------------------------------
+; Dive Settings Menu - 2nd Layer - Deco Mode
+;
+do_menu_dive_deco:
+	MENU_BEGIN	tDecoSetup, .6
+		MENU_OPT_INC	tDkMode,					oDecoMode					; ZH-L16 /GF
+		MENU_OPT_INC	tSaturationMult,			osatmultgf					; saturation
+		MENU_OPT_INC	tDesaturationMult,			odesatmultgf				; desaturation
+		MENU_OPT_INC	tAltMode,					oAltMode					; altitude mode
+		MENU_CALL		tGFMenu,					do_menu_dive_deco_GF		; GF settings
+		MENU_CALL		tBack,						do_return_menu_dive
 	MENU_END
 
 
-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
+;-----------------------------------------------------------------------------
+; Dive Settings Menu - 3nd Layer - Deco Mode - GF Settings
+;
+do_menu_dive_deco_GF:
+	MENU_BEGIN	tGFMenu, .6
+		MENU_OPT_INC	tGF_low,					oGF_low						; GF  low
+		MENU_OPT_INC	tGF_high,					oGF_high					; GF  high
+		MENU_OPT_INC	taGFenable,					oEnable_aGF					; aGF selectable
+		MENU_OPT_INC	taGF_low,					oaGF_low					; aGF low
+		MENU_OPT_INC	taGF_high,					oaGF_high					; aGF high
+		MENU_CALL		tBack,						do_return_menu_dive_deco
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; Dive Settings Menu - 2nd Layer - SAC Setup
+;
+do_menu_dive_SAC:
+ IFDEF _gas_contingency
+	MENU_BEGIN	tSACSetup, .6
+		MENU_OPT_INC	tCalcGasNeeds,				oCalcAscGas					; calc.gas
+		MENU_OPT_INC	tGasContingencyDive,		oGasContingencyDive			; switch tank if used up
+		MENU_OPT_INC	tGasChangeTime,				oGasChangeTime				; gas change time
+		MENU_OPT_INC	tSetWorkSAC,				oWork_SAC					; work SAC
+		MENU_OPT_INC	tSetDecoSAC,				oDeco_SAC					; deco SAC
+		MENU_CALL		tBack,						do_return_menu_dive
 	MENU_END
  ELSE
-	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_BEGIN	tSACSetup, .5
+		MENU_OPT_INC	tCalcGasNeeds,				oCalcAscGas					; calc.gas
+		MENU_OPT_INC	tGasChangeTime,				oGasChangeTime				; gas change time
+		MENU_OPT_INC	tSetWorkSAC,				oWork_SAC					; work SAC
+		MENU_OPT_INC	tSetDecoSAC,				oDeco_SAC					; deco SAC
+		MENU_CALL		tBack,						do_return_menu_dive
 	MENU_END
  ENDIF
 
 
-do_return_deco_menu:
-	call	menu_processor_double_pop	; drop exit line and back to last line
-
-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_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_ppo2_menu:
+;-----------------------------------------------------------------------------
+; Dive Settings Menu - 2nd Layer - ppO2 Setup
+;
+do_menu_dive_ppO2:
  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_DYNAMIC	dyn_ppo2_max,				do_toggle_ppO2_max_work		; max work
+		MENU_DYNAMIC	dyn_ppo2_max_deco,			do_toggle_ppO2_max_deco		; max deco
+		MENU_DYNAMIC	dyn_ppo2_min,				do_toggle_ppO2_min			; min OC
+		MENU_DYNAMIC	dyn_ppo2_min_cc,			do_toggle_ppO2_min_cc		; min loop
+		MENU_OPT_INC	tIBCDwarning,				oEnable_IBCD				; IBCD warning
+		MENU_CALL		tBack,						do_return_menu_dive
 	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_DYNAMIC	dyn_ppo2_max,				do_toggle_ppO2_max_work		; max work
+		MENU_DYNAMIC	dyn_ppo2_max_deco,			do_toggle_ppO2_max_deco		; max deco
+		MENU_DYNAMIC	dyn_ppo2_min,				do_toggle_ppO2_min			; min OC
+		MENU_DYNAMIC	dyn_ppo2_min_cc,			do_toggle_ppO2_min_cc		; min loop
+		MENU_CALL		tBack,						do_return_menu_dive
 	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
+		MENU_DYNAMIC	dyn_ppo2_max,				do_toggle_ppO2_max_work		; max work
+		MENU_DYNAMIC	dyn_ppo2_max_deco,			do_toggle_ppO2_max_deco		; max deco
+		MENU_DYNAMIC	dyn_ppo2_min,				do_toggle_ppO2_min			; min OC
+		MENU_OPT_INC	tIBCDwarning,				oEnable_IBCD				; IBCD warning
+		MENU_CALL		tBack,						do_return_menu_dive
  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_DYNAMIC	dyn_ppo2_max,				do_toggle_ppO2_max_work		; max work
+		MENU_DYNAMIC	dyn_ppo2_max_deco,			do_toggle_ppO2_max_deco		; max deco
+		MENU_DYNAMIC	dyn_ppo2_min,				do_toggle_ppO2_min			; min OC
+		MENU_CALL		tBack,						do_return_menu_dive
 	MENU_END
  ENDIF	; _helium
  ENDIF	; _ccr_pscr
 
 
-do_stops_menu:
+;-----------------------------------------------------------------------------
+; dynamic Title - show maximum ppO2 - Work
+;
+dyn_ppo2_max:
+	STRCAT_TEXT tPPO2Max				; print text
+	movff	char_I_ppO2_max_work,lo		; get value
+	movlw	ppo2_warning_high_default	; load default
+	bra		dyn_ppo2_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show maximum ppO2 - Deco
+;
+dyn_ppo2_max_deco:
+	STRCAT_TEXT tPPO2DECO				; print text
+	movff	char_I_ppO2_max_deco,lo		; get value
+	movlw	ppo2_warning_deco_default	; load default
+	bra		dyn_ppo2_common				; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show minimum ppO2
+;
+dyn_ppo2_min:
+	STRCAT_TEXT tPPO2MIN				; print text
+	movff	char_I_ppO2_min,lo			; get value
+	movlw	ppo2_warning_low_default	; load default
+	bra		dyn_ppo2_common				; continue with common part
+
+
+ IFDEF _ccr_pscr
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show minimum ppO2 - Loop Modes
+;
+dyn_ppo2_min_cc:
+	STRCAT_TEXT tPPO2MINCC				; print text
+	movff	char_I_ppO2_min_loop,lo		; get value
+	movlw	ppo2_warning_loop_default	; load default
+	;bra	dyn_ppo2_common				; continue with common part
+
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; Helper Function to all show ppO2 dynamic Titles
+;
+dyn_ppo2_common:
+	movwf	up							; copy default to up
+	clrf	hi							; clear hi
+	bsf		leftbind					; print left-aligned
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_256							; print ppO2 as x.xx
+	STRCAT_TEXT tbar					; append unit
+	movf	up,W						; get default value into WREG
+	cpfseq	lo							; current value = default value ?
+	bra		divesets_ppo2_common2		; NO  - add an "*"
+	return								; YES - done
+divesets_ppo2_common2:
+	PUTC	"*"							; append a star
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Call Function - increment maximum ppO2 - Work
+;
+do_toggle_ppO2_max_work:				; add 0.1 bar
+	movff	char_I_ppO2_max_work,lo		; bank-safe copy
+	movlw	.10
+	addwf	lo,F
+	movlw	ppo2_warning_high_highest
+	cpfsgt	lo
+	bra		do_toggle_ppo2_max2
+	movlw	ppo2_warning_high_lowest
+	movwf	lo
+do_toggle_ppo2_max2:
+	movff	lo,char_I_ppO2_max_work
+	return
+
+
+;-----------------------------------------------------------------------------
+; Call Function - increment maximum ppO2 - Deco
+;
+do_toggle_ppO2_max_deco:				; add 0.1 bar
+	movff	char_I_ppO2_max_deco,lo		; bank-safe copy
+	movlw	.10
+	addwf	lo,F
+	movlw	ppo2_warning_deco_highest
+	cpfsgt	lo
+	bra		do_toggle_ppO2_max_deco2
+	movlw	ppo2_warning_deco_lowest
+	movwf	lo
+do_toggle_ppO2_max_deco2:
+	movff	lo,char_I_ppO2_max_deco
+	return
+
+
+;-----------------------------------------------------------------------------
+; Call Function - increment minimum ppO2
+;
+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
+	cpfsgt	lo
+	bra		do_toggle_ppO2_min2
+	movlw	ppo2_warning_low_lowest
+	movwf	lo
+do_toggle_ppO2_min2:
+	movff	lo,char_I_ppO2_min
+	return
+
+
+;-----------------------------------------------------------------------------
+; Call Function - increment minimum ppO2 - Loop Modes
+;
+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
+	cpfsgt	lo
+	bra		do_toggle_ppO2_min_cc2
+	movlw	ppo2_warning_loop_lowest
+	movwf	lo
+do_toggle_ppO2_min_cc2:
+	movff	lo,char_I_ppO2_min_loop
+	return
+
+
+;-----------------------------------------------------------------------------
+; Dive Settings Menu - 2nd Layer - Stops & Depth
+;
+do_menu_dive_stops:
 	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_OPT_INC	tSafetyStop,				oSafetyStop					; safety stop
+		MENU_OPT_INC	tExtendedStops,				oExtendedStops				; extended stops
+		MENU_OPT_INC	tLastDecostop,				oLastDeco					; last deco stop
+		MENU_OPT_INC	tDvSalinity,				oDiveSalinity				; salinity
+		MENU_OPT_INC	tDepthWarn,					oMaxDepth					; depth limit
+		MENU_CALL		tBack,						do_return_menu_dive
 	MENU_END
 
 
-do_GF_menu:
-	MENU_BEGIN	tGFMenu, .6
-		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
+;-----------------------------------------------------------------------------
+; return to Settings Menu from Sub-Sub-Menu
+;
+do_return_menu_settings_deeper:			; entry point for return from info menu 2
+	call	menu_processor_pop			; drop one more stack entry
+	;bra	do_return_menu_settings		; continue
 
 
-;=============================================================================
-; 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:
+;-----------------------------------------------------------------------------
+; return to Settings Menu from Sub-Menu
+;
+do_return_menu_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  - use version w/o TR
+	bra		do_menu_settings			; NO  - keep deactivated
 	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:
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 1st Layer
+;
+do_menu_settings:
  IFDEF _hwos_sport
-	bsf		ble_available				; for very old OSTC sport
+	bsf		ble_available				; required for very old OSTC sport
  ENDIF
-	btfsc	ble_available				; BLE available?
-	bra		do_settings_menu_ble		; YES
+	btfsc	ble_available				; BT available?
+	bra		do_menu_settings_bt			; YES - do BT menu
 
 	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		tSysSets,					do_syssets_menu
+		MENU_CALL		tInfoMenu,					do_menu_info
+		MENU_CALL		tSetTimeDate,				do_menu_date_time
+		MENU_CALL		tDispSets,					do_menu_dispsets
+		MENU_CALL		tSysSets,					do_menu_syssets
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
-
-do_settings_menu_ble:
+do_menu_settings_bt:
  IFDEF _rx_functions
 	btfss	ostc_rx_present				; TR model and TR activated?
-	bra		do_settings_menu_noRX		; NO
+	bra		do_menu_settings_noRX		; NO
 
 	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		tSysSets,					do_syssets_menu
+		MENU_CALL		tInfoMenu,					do_menu_info
+		MENU_CALL		tBleTitle,					do_comm_mode_bt
+		MENU_CALL		tTrSettings,				do_menu_settings_TR
+		MENU_CALL		tSetTimeDate,				do_menu_date_time
+		MENU_CALL		tDispSets,					do_menu_dispsets
+		MENU_CALL		tSysSets,					do_menu_syssets
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
  ENDIF
 
-do_settings_menu_noRX:
+do_menu_settings_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		tInfoMenu,					do_menu_info
+		MENU_CALL		tBleTitle,					do_comm_mode_bt
+		MENU_CALL		tSetTimeDate,				do_menu_date_time
+		MENU_CALL		tDispSets,					do_menu_dispsets
+		MENU_CALL		tSysSets,					do_menu_syssets
 		MENU_CALL		tBack,						do_return_main_menu
 	MENU_END
 
 
-do_info_menu:
+;-----------------------------------------------------------------------------
+; Call Function - start Communication Mode (BT)
+;
+do_comm_mode_bt:
+	goto	comm_mode_bt				; code hosted in comm.asm
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 2nd Layer - System Infos - Page 1
+;
+do_menu_info:
  IFDEF _rx_functions
 	btfss	ostc_rx_present				; TR model?
-	bra		do_info_menu_noRX			; NO
+	bra		do_menu_info_noRX			; NO
 
 	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_fw_cration_date,	0
-		MENU_DYNAMIC	info_menu_firmware_rx,		0
-		MENU_DYNAMIC	info_menu_total_dives,		0
-		MENU_CALL		tMore,						do_info_menu2
+		MENU_DYNAMIC	dyn_show_uptime,			0
+		MENU_DYNAMIC	dyn_show_serial,			0
+		MENU_DYNAMIC	dyn_show_firmware_ostc,		0
+		MENU_DYNAMIC	dyn_show_fw_creation_date,	0
+		MENU_DYNAMIC	dyn_show_firmware_rx,		0
+		MENU_DYNAMIC	dyn_show_total_dives,		0
+		MENU_CALL		tMore,						do_menu_info2
 	MENU_END
  ENDIF
 
-do_info_menu_noRX:
+do_menu_info_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_DYNAMIC	dyn_show_uptime,			0
+		MENU_DYNAMIC	dyn_show_serial,			0
+		MENU_DYNAMIC	dyn_show_firmware_ostc,		0
+		MENU_DYNAMIC	dyn_show_fw_creation_date,	0
+		MENU_DYNAMIC	dyn_show_total_dives,		0
+		MENU_CALL		tMore,						do_menu_info2
 	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
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Uptime
+;
+dyn_show_uptime:
+	STRCAT_TEXT tUptime					; print title
+	SMOVQQ	uptime,xC					; ISR-safe copy of uptime:4 to xC:4
+	goto	output_secs_as_days_hours	; print seconds as days and hours and return
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Uptime
+;
+dyn_show_serial:
+	STRCAT_TEXT tSerial					; print title
+	goto	TFT_cat_serial				; print serial number and return
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Firmware Version
+;
+dyn_show_firmware_ostc:
+	STRCAT_TEXT tFirmware				; print title
+	call	TFT_cat_firmware			; print firmware version
+	PUTC	" "							; print a dot
+	goto	TFT_cat_beta_short			; print beta/release state and return
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Firmware creation Date
+;
+dyn_show_fw_creation_date:
+	STRCAT_TEXT tFirmwareDate			; print title
+	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
+	goto	output_date					; print date and return
 
 
  IFDEF _rx_functions
 
-do_settings_menu_TR:
+;-----------------------------------------------------------------------------
+; dynamic Title - show RX Firmware Version  (also used by start.asm)
+;
+	global	dyn_show_firmware_rx
+dyn_show_firmware_rx:
+	STRCAT_TEXT tFirmware_rx			; print title
+	movff	rx_firmware_cur_major,lo	; get major version
+	bsf		leftbind					; print left-aligned
+	output_99							; print major (0-99)
+	PUTC	'.'							; print a dot
+	movff	rx_firmware_cur_minor,lo	; get minor
+	output_99x							; print minor (00-99)
+	return								; done
+
+ ENDIF	; _rx_functions
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show total Number of Dives
+;
+dyn_show_total_dives:
+	STRCAT_TEXT tTotalDives				; print title
+	call	eeprom_total_dives_read		; read total number of dives
+	bsf		leftbind					; print left-aligned
+	output_65535						; print number of total dives (0-65535)
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 2nd Layer - System Infos - Page 2
+;
+do_menu_info2:
+ IFNDEF _comm_debug
+	MENU_BEGIN	tInfoMenu, .5
+		MENU_DYNAMIC	dyn_show_battery_volts,		0
+		MENU_DYNAMIC	dyn_show_config,			0
+		MENU_DYNAMIC	dyn_show_sensor_calib,		0
+		MENU_DYNAMIC	dyn_show_sensor_offset,		0
+		MENU_CALL		tBack,						do_return_menu_settings_deeper
+	MENU_END
+ ELSE
+	MENU_BEGIN	tInfoMenu, .6
+		MENU_DYNAMIC	dyn_show_battery_volts,		0
+		MENU_DYNAMIC	dyn_show_config,			0
+		MENU_DYNAMIC	dyn_show_sensor_calib,		0
+		MENU_DYNAMIC	dyn_show_sensor_offset,		0
+		MENU_OPT_INC	tCommTimeout,				oCommTimeout
+		MENU_CALL		tBack,						do_return_menu_settings_deeper
+	MENU_END
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Battery Volts and Type
+;
+dyn_show_battery_volts:
+	STRCAT_TEXT tBatteryV				; print text
+	MOVII	batt_voltage,mpr			; get battery voltage
+	bsf		decimal_digit3				; place a decimal point in front of digit 3
+	bsf		omit_digit_1				; do not print 1st digit
+	output_9999							; print as x.yy-
+	STRCAT	" V(T"						; append fix legend
+	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_9							; print battery type code (0-9)
+	PUTC	")"							; append fix legend
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Hardware / Software Configuration
+;
+dyn_show_config:
+	STRCAT_TEXT tHardware				; print  text
+	call	I2C_init_compass			; start compass to get compass configuration
+	movf	HW_descriptor,W				; copy hardware descriptor to WREG
+	output_hex							; print as hex
+	movf	HW_variants,W				; copy hardware variants   to WREG
+	output_hex							; print as hex
+	PUTC	"-"							; print a separator
+	movlw	FW_CONF						; get firmware configuration
+	output_hex							; print as hex
+	call	get_cpu_version				; get CPU version
+	output_hex							; print as hex
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Pressure Sensor Calibration Data C1 and C5
+;
+dyn_show_sensor_calib:
+	STRCAT_TEXT tSensorC				; 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
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - show Pressure Sensor Offset Setting
+;
+dyn_show_sensor_offset:
+	STRCAT_TEXT tSensorD				; print  label
+	movff	opt_pressure_adjust,lo		; get pressure sensor offset
+	movf	lo,F						; excite flags
+	bz		dyn_show_sensor_offset_zero	; sensor offset = 0
+	bn		dyn_show_sensor_offset_neg	; sensor offset < 0
+	;bnn	dyn_show_sensor_offset_pos	; sensor offset > 0
+dyn_show_sensor_offset_pos:
+	PUTC	"+"							; print plus sign
+	bra		dyn_show_sensor_offset_com	; continue with common part
+dyn_show_sensor_offset_zero:
+	PUTC	" "							; print a space
+	bra		dyn_show_sensor_offset_com	; continue with common part
+dyn_show_sensor_offset_neg:
+	PUTC	"-"							; print a minus sign
+	negf	lo							; negate lo
+	;bra	dyn_show_sensor_offset_com	; continue with common part
+dyn_show_sensor_offset_com:
+	PUTC	" "							; print a space
+	bsf		leftbind					; print left-aligned
+	output_99							; print value (0-99)
+	PUTC	" "							; print a space
+	STRCAT_TEXT tMBAR					; print unit
+	return								; done
+
+
+ IFDEF _rx_functions
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 2nd Layer - TR Settings
+;
+do_menu_settings_TR:
 	movff	opt_dive_mode,WREG			; get dive mode: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR
 	incf	WREG,W						; add 1
 	dcfsnz	WREG,W						; subtract one, became zero?
-	bra		do_settings_menu_TR_MaxDelta; YES - OC
+	bra		do_menu_settings_TR_MaxDelta; YES - OC
+	dcfsnz	WREG,W						; subtract one, became zero?
+	bra		do_menu_settings_TR_BailPres; YES - CCR
 	dcfsnz	WREG,W						; subtract one, became zero?
-	bra		do_settings_menu_TR_BailPres; YES - CCR
+	bra		do_menu_settings_TR_MaxDelta; YES - Gauge
 	dcfsnz	WREG,W						; subtract one, became zero?
-	bra		do_settings_menu_TR_MaxDelta; YES - Gauge
+	bra		do_menu_settings_TR_abort	; YES - Apnea, abort
 	dcfsnz	WREG,W						; subtract one, became zero?
-	bra		do_settings_menu_TR_abort	; YES - Apnea, abort
-	dcfsnz	WREG,W						; subtract one, became zero?
-	bra		do_settings_menu_TR_both	; YES - pSCR
-do_settings_menu_TR_abort:
-	call	menu_processor_pop			; drop last menu selection
-	bra		do_settings_menu			; back to last menu
+	bra		do_menu_settings_TR_both	; YES - pSCR
+
+do_menu_settings_TR_abort:
+	call	menu_processor_pop			; drop button press
+	bra		do_menu_settings			; back to same menu
 
-do_settings_menu_TR_MaxDelta:			; menu with oTrMaxDeltaPres
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - TR Settings - Sidemount Mode
+;
+do_menu_settings_TR_MaxDelta:			; menu with oTrMaxDeltaPres
 	MENU_BEGIN	tTrSettings, .5
-		MENU_OPTION		tTrMode,					oTrMode,				0
-		MENU_OPTION		tTr1stPres,					oTr1stPres,				0
-		MENU_OPTION		tTr2ndPres,					oTr2ndPres,				0
-		MENU_DYNAMIC	do_toggle_max_pres_diff_label,do_toggle_max_pres_diff
-		MENU_CALL		tBack,						do_return_settings
-	MENU_END
-
-do_settings_menu_TR_BailPres:			; menu with oTrBailPres
-	MENU_BEGIN	tTrSettings, .5
-		MENU_OPTION		tTrMode,					oTrMode,				0
-		MENU_OPTION		tTr1stPres,					oTr1stPres,				0
-		MENU_OPTION		tTr2ndPres,					oTr2ndPres,				0
-		MENU_OPTION		tTrBailPres,				oTrBailPres,			0
-		MENU_CALL		tBack,						do_return_settings
-	MENU_END
-
-do_settings_menu_TR_both:				; menu with oTrBailPres and oTrMaxDeltaPres
-	MENU_BEGIN	tTrSettings, .6
-		MENU_OPTION		tTrMode,					oTrMode,				0
-		MENU_OPTION		tTr1stPres,					oTr1stPres,				0
-		MENU_OPTION		tTr2ndPres,					oTr2ndPres,				0
-		MENU_OPTION		tTrBailPres,				oTrBailPres,			0
-		MENU_DYNAMIC	do_toggle_max_pres_diff_label,do_toggle_max_pres_diff
-		MENU_CALL		tBack,						do_return_settings
+		MENU_OPT_INC	tTrMode,					oTrMode
+		MENU_OPT_INC	tTr1stPres,					oTr1stPres
+		MENU_OPT_INC	tTr2ndPres,					oTr2ndPres
+		MENU_DYNAMIC	dyn_toggle_max_pres_diff,	do_toggle_max_pres_diff
+		MENU_CALL		tBack,						do_return_menu_settings
 	MENU_END
 
 
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - TR Settings - CCR Mode
+;
+do_menu_settings_TR_BailPres:			; menu with oTrBailPres
+	MENU_BEGIN	tTrSettings, .5
+		MENU_OPT_INC	tTrMode,					oTrMode
+		MENU_OPT_INC	tTr1stPres,					oTr1stPres
+		MENU_OPT_INC	tTr2ndPres,					oTr2ndPres
+		MENU_OPT_INC	tTrBailPres,				oTrBailPres
+		MENU_CALL		tBack,						do_return_menu_settings
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - TR Settings - pSCR Mode
+;
+do_menu_settings_TR_both:				; menu with oTrBailPres and oTrMaxDeltaPres
+	MENU_BEGIN	tTrSettings, .6
+		MENU_OPT_INC	tTrMode,					oTrMode
+		MENU_OPT_INC	tTr1stPres,					oTr1stPres
+		MENU_OPT_INC	tTr2ndPres,					oTr2ndPres
+		MENU_OPT_INC	tTrBailPres,				oTrBailPres
+		MENU_DYNAMIC	dyn_toggle_max_pres_diff,	do_toggle_max_pres_diff
+		MENU_CALL		tBack,						do_return_menu_settings
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - max. Delta Pressure for Swap Tanks Advice
+;
+dyn_toggle_max_pres_diff:
+	movff	opt_TR_mode,WREG			; get TR mode
+	xorlw	.2							; compare with 2 (ind.double)
+	tstfsz	WREG						; equal?
+	FONT_COLOR_DISABLED					; NO - print in disabled color
+	STRCAT_TEXT tTrMaxDeltaP			; output label
+	movff	char_I_max_pres_diff,lo		; get configured deltaP
+	output_99							; print deltaP (0-99)
+	STRCAT_TEXT tbar					; append " bar"
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Call Function - adjust max. Delta Pressure for Swap Tanks Advice
+;
 do_toggle_max_pres_diff:				; add 5 bar, with hard-coded max.
 	movff	char_I_max_pres_diff,lo		; get current value
 	movlw	.5							; load increment
@@ -730,250 +1446,341 @@
  ENDIF	; _rx_functions
 
 
-do_return_settings_more_deeper:			; entry point for returns from reset sub-menu
-	call	menu_processor_pop			; drop one more stack entry
-
-do_return_settings_more:
+;-----------------------------------------------------------------------------
+; return to Settings Menu from Sub-Menu
+;
+do_return_menu_date_time:
 	call	menu_processor_double_pop	; drop exit line and back to last line
 
-do_syssets_menu:
-	btfsc	battery_gauge_available		; piezo buttons available?
-	bra		do_syssets_menu_piezo		; YES
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 2nd Layer - set Time & Date
+;
+do_menu_date_time:
+	bsf		imprint_time_date			; start imprinting current time & date
+	bcf		block_option_value			; resume displaying of option values
+
+	MENU_BEGIN	tSetTimeDate, .4
+		MENU_CALL		tSetTime,					do_menu_set_time
+		MENU_CALL		tSetDate,					do_menu_set_date
+		MENU_OPT_INC	tDateFormat,				oDateFormat
+		MENU_CALL		tBack,						do_return_menu_settings
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - set Time & Date - set Time
+;
+do_menu_set_time:
+	bsf		block_option_value			; suspend displaying of option values
+
+	MENU_BEGIN	tSetTime, .4
+		MENU_OPT_INC	tSetHours,					oSetHours
+		MENU_OPT_INC	tSetMinutes,				oSetMinutes
+		MENU_OPT_INC	tSetSeconds,				oClearSeconds
+		MENU_CALL		tBack,						do_return_menu_date_time
+	MENU_END
+
 
- IFDEF _compass
-	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 !
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - set Time & Date - set Date
+;
+do_menu_set_date:
+	bsf		block_option_value			; suspend displaying of option values
+
+	MENU_BEGIN	tSetDate, .4
+		MENU_OPT_INC	tSetDay,					oSetDay
+		MENU_OPT_INC	tSetMonth,					oSetMonth
+		MENU_OPT_INC	tSetYear,					oSetYear
+		MENU_CALL		tBack,						do_return_menu_date_time
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; return to Display Settings from Sub-Menu
+;
+do_return_dispsets_menu:
+	bcf		imprint_color_schemes		; deactivate color schemes demonstration
+	call	menu_processor_double_pop	; drop exit line and back to last line
+	;bra	do_menu_dispsets			; continue
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 2nd Layer - Display Settings - Page 1
+;
+do_menu_dispsets:
+ IF _language_2!=none
+	MENU_BEGIN	tDispSets, .7
+		MENU_OPT_INC	tBright,					oBrightness
+		MENU_OPT_INC	tLayout,					oLayout
+		MENU_OPT_INC	tUnits,						oUnits
+		MENU_OPT_INC	tLanguage,					oLanguage
+		MENU_OPT_INC	tFlip,						oFlipScreen
+		MENU_CALL		tColorScheme,				do_menu_color_scheme
+		MENU_CALL		tMore,						do_menu_dispsets_more
 	MENU_END
  ELSE
-	MENU_BEGIN	tSystSets, .3													; see above
-		MENU_CALL		tLogOffset,					do_log_offset_menu			;
-		MENU_CALL		tResetMenu,					do_reset_menu				;
-		MENU_CALL		tBack,						do_return_settings			;
+	MENU_BEGIN	tDispSets, .6
+		MENU_OPT_INC	tBright,					oBrightness
+		MENU_OPT_INC	tLayout,					oLayout
+		MENU_OPT_INC	tUnits,						oUnits
+		MENU_OPT_INC	tFlip,						oFlipScreen
+		MENU_CALL		tColorScheme,				do_menu_color_scheme
+		MENU_CALL		tMore,						do_menu_dispsets_more
 	MENU_END
- ENDIF	; _compass
+ ENDIF
 
 
-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
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - Display Settings - Color Schemes
+;
+do_menu_color_scheme:
+	bsf		imprint_color_schemes		; activate color schemes demonstration
+
+	; menu with 4 leading empty menu lines to give space for the color scheme imprinting
+	MENU_BEGIN_OFFSET	tColorScheme, .2, .4
+		MENU_OPT_INC	tColorSetDive,				oColorSetDive
+		MENU_CALL		tBack,						do_return_dispsets_menu
+	MENU_END
+
 
-do_syssets_menu_piezo:
- IFDEF _compass
-	MENU_BEGIN	tSystSets, .6
-		MENU_CALL		tCompassMenu,				do_compass_menu				; see above
-		MENU_CALL		tLogOffset,					do_log_offset_menu			;
-		MENU_DYNAMIC	info_menu_total_dives,		0
-		MENU_CALL		tResetMenu,					do_reset_menu				;
-		MENU_CALL		tPiezo,						do_settings_piezo_menu		;
-		MENU_CALL		tBack,						do_return_settings			;
+;-----------------------------------------------------------------------------
+; Settings Menu - 2nd Layer - Display Settings - Page 2
+;
+do_menu_dispsets_more:
+ IFDEF _helium
+	MENU_BEGIN	tDispSets, .7
+		MENU_OPT_INC	tVSIgraph,					oVSIgraph
+		MENU_OPT_INC	tVSItext2,					oVSItext
+		MENU_OPT_INC	tShowppO2,					oShowppO2
+		MENU_OPT_INC	tDepthWarning,				oDepthWarn
+		MENU_OPT_INC	t2ndDepth,					o2ndDepthDisp
+		MENU_OPT_INC	tTissueGraphics,			oTissueGraphics
+		MENU_CALL		tBack,						do_return_menu_settings_deeper
 	MENU_END
  ELSE
-	MENU_BEGIN	tSystSets, .5
-		MENU_CALL		tLogOffset,					do_log_offset_menu			; see above
-		MENU_DYNAMIC	info_menu_total_dives,		0
-		MENU_CALL		tResetMenu,					do_reset_menu				;
-		MENU_CALL		tPiezo,						do_settings_piezo_menu		;
-		MENU_CALL		tBack,						do_return_settings			;
+	MENU_BEGIN	tDispSets, .6
+		MENU_OPT_INC	tVSIgraph,					oVSIgraph
+		MENU_OPT_INC	tVSItext2,					oVSItext
+		MENU_OPT_INC	tShowppO2,					oShowppO2
+		MENU_OPT_INC	tDepthWarning,				oDepthWarn
+		MENU_OPT_INC	t2ndDepth,					o2ndDepthDisp
+		MENU_CALL		tBack,						do_return_menu_settings_deeper
 	MENU_END
  ENDIF
 
 
-do_settings_piezo_menu:
-	; Menu with features only available in piezo button hardware
-	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_syssets_menu_piezo
+;-----------------------------------------------------------------------------
+; return to System Settings Menu from Sub-Sub-Menu
+;
+do_return_menu_syssets_more_more:		; entry point for returns from reset sub-menu
+	call	menu_processor_pop			; drop one more stack entry
+	;bra	do_return_menu_syssets_more	; continue
+
+
+;-----------------------------------------------------------------------------
+; return to System Settings Menu from Sub-Menu
+;
+do_return_menu_syssets_more:
+	call	menu_processor_double_pop	; drop exit line and back to last line
+	bra		do_menu_syssets				; continue
+
+
+;-----------------------------------------------------------------------------
+; return to System Settings Menu from Piezo-Sub-Menu
+;
+do_return_menu_syssets_piezo:
+	call	menu_processor_double_pop	; drop exit line and back to last line
+	call	TFT_ClearScreen				; clear the screen
+	call	piezo_config				; configure buttons
+	;bra	do_menu_syssets				; continue
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 2nd Layer - System Settings
+;
+do_menu_syssets:
+	btfsc	battery_gauge_available		; piezo buttons available?
+	bra		do_menu_syssets_piezo		; YES
+
+ IFDEF _compass
+	MENU_BEGIN	tSystSets, .4													; All MENU_CALLs in this menu
+		MENU_CALL		tCompassMenu,				do_menu_compass				; need to stay together on this
+		MENU_CALL		tLogOffset,					do_menu_log_offset			; menu level in order to not
+		MENU_CALL		tResetMenu,					do_menu_reset				; mess up the menu stack on doing
+		MENU_CALL		tBack,						do_return_menu_settings		; the do_return_menu_settings !
 	MENU_END
+ ELSE
+	MENU_BEGIN	tSystSets, .3													; see above
+		MENU_CALL		tLogOffset,					do_menu_log_offset			;
+		MENU_CALL		tResetMenu,					do_menu_reset				;
+		MENU_CALL		tBack,						do_return_menu_settings		;
+	MENU_END
+ ENDIF	; _compass
+
+do_menu_syssets_piezo:
+ IFDEF _compass
+	MENU_BEGIN	tSystSets, .5
+		MENU_CALL		tCompassMenu,				do_menu_compass				; see above
+		MENU_CALL		tLogOffset,					do_menu_log_offset			;
+		MENU_CALL		tResetMenu,					do_menu_reset				;
+		MENU_CALL		tPiezo,						do_menu_piezo				;
+		MENU_CALL		tBack,						do_return_menu_settings		;
+	MENU_END
+ ELSE
+	MENU_BEGIN	tSystSets, .4
+		MENU_CALL		tLogOffset,					do_menu_log_offset			; see above
+		MENU_CALL		tResetMenu,					do_menu_reset				;
+		MENU_CALL		tPiezo,						do_menu_piezo				;
+		MENU_CALL		tBack,						do_return_menu_settings		;
+	MENU_END
+ ENDIF
 
 
  IFDEF _compass
 
-do_compass_menu:
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - System Settings - Compass
+;
+do_menu_compass:
 	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
-		MENU_DYNAMIC	menu_cal_y,					0
-		MENU_DYNAMIC	menu_cal_z,					0
-		MENU_CALL		tBack,						do_return_settings_more
+		MENU_CALL		tCompassCalibration,		do_compass_calibration
+;		MENU_OPT_INC	tCompassGain,				oCompassGain
+		MENU_DYNAMIC	dyn_compass_cal_x,			0
+		MENU_DYNAMIC	dyn_compass_cal_y,			0
+		MENU_DYNAMIC	dyn_compass_cal_z,			0
+		MENU_CALL		tBack,						do_return_menu_syssets_more
 	MENU_END
 
+
+;-----------------------------------------------------------------------------
+; Call Function - start Compass Calibration
+;
+do_compass_calibration:
+	goto	compass_calibration			; code hosted in compass_ops.asm
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - Calibration Value X
+;
+dyn_compass_cal_x:
+	STRCAT_TEXT tCalX					; print label
+	lfsr	FSR0,compass_CX_f			; address calibration value X
+	bra		dyn_compass_cal_common		; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - Calibration Value Y
+;
+dyn_compass_cal_y:
+	STRCAT_TEXT tCalY					; print label
+	lfsr	FSR0,compass_CY_f			; address calibration value Y
+	bra		dyn_compass_cal_common		; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - Calibration Value Z
+;
+dyn_compass_cal_z:
+	STRCAT_TEXT tCalZ					; print label
+	lfsr	FSR0,compass_CZ_f			; address calibration value Z
+	;bra	dyn_compass_cal_common		; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Helper Function to dynamic Titles - Calibration Value
+;
+dyn_compass_cal_common:
+	movff	POSTINC0,lo					; read calibration value, low  byte
+	movff	POSTINC0,hi					; read calibration value, high byte
+	PUTC	':'							; print ":"
+	PUTC	' '							; print a space
+	call	convert_signed_16bit		; convert lo:hi into signed-short and adds '-' to POSTINC2 if required
+	btfsc	neg_flag					; value negative?
+	bra		dyn_compass_cal_common_1	; YES - print value
+	PUTC	'+'							; NO  - add a plus sign
+dyn_compass_cal_common_1:
+	output_65535						; print value
+	return								; done
+
  ENDIF	; _compass
 
 
-;=============================================================================
-; Reset and confirmation menu
-
-do_reset_menu:
-	MENU_BEGIN	tResetMenu, .6
-		MENU_CALL		tBack,						do_return_settings_more
-		MENU_CALL		tReboot,					do_reset_menu_reboot	; confirm
-		MENU_CALL		tResetDeco,					do_reset_menu_deco		; confirm
-		MENU_CALL		tResetSettings,				do_reset_menu_settings	; confirm
-		MENU_CALL		tResetLogbook,				do_reset_menu_logbook	; confirm
-		MENU_CALL		tResetBattery,				do_new_battery_menu		; confirm
-	MENU_END
-
-do_reset_menu_reboot:
-	MENU_BEGIN	tResetMenu2, .2
-		MENU_CALL		tAbort,						do_return_settings_more_deeper
-		MENU_CALL		tReboot,					do_reboot				; reboot (cold start)
-	MENU_END
-
-do_reset_menu_deco:
-	MENU_BEGIN	tResetMenu2, .2
-		MENU_CALL		tAbort,						do_return_settings_more_deeper
-		MENU_CALL		tResetDeco,					do_reset_deco			; reset deco and return to main reset menu
-	MENU_END
-
-do_reset_menu_settings:
-	MENU_BEGIN	tResetMenu2, .2
-		MENU_CALL		tAbort,						do_return_settings_more_deeper
-		MENU_CALL		tResetSettings,				do_reset_settings		; reset all settings and go to surface mode
-	MENU_END
-
-do_reset_menu_logbook:
-	MENU_BEGIN	tResetMenu2, .2
-		MENU_CALL		tAbort,						do_return_settings_more_deeper
-		MENU_CALL		tResetLogbook,				do_reset_logbook		; reset logbook and return to main reset menu
-	MENU_END
-
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - System Settings - Logbook Offset
+;
+do_menu_log_offset:
 
-do_reset_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	eeprom_deco_data_write		; store updated deco data into EEPROM
-	bra		do_return_settings_more_deeper
-
-
-do_reset_settings:
-	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
+	clrf	WREG						; select an initial step size of 1
+	movff	WREG,opt_logoffset_step		; bank-safe write to option variable (volatile option)
 
-do_reboot:
-	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
-
-do_date_time_menu:
-	bsf		imprint_time_date			; start imprinting current time & date
-	bcf		block_option_value			; allow display of option values again
-
-	MENU_BEGIN	tSetTimeDate, .4
-		MENU_CALL		tSetTime,					do_time_menu
-		MENU_CALL		tSetDate,					do_date_menu
-		MENU_OPTION		tDateFormat,				oDateFormat,			0
-		MENU_CALL		tBack,						do_return_settings
+	MENU_BEGIN	tLogOffset, .5
+		MENU_DYNAMIC	dyn_logoffset_show_value,	0
+		MENU_OPT_INC	tLogOffStepSize,			oLogOffsetStep
+		MENU_CALL		tLogOffsetplus,				do_log_offset_plus
+		MENU_CALL		tLogOffsetminus,			do_log_offset_minus
+		MENU_CALL		tBack,						do_return_menu_syssets_more
 	MENU_END
 
 
-do_date_menu:
-	bsf		block_option_value			; suspend display of option values
-
-	MENU_BEGIN	tSetDate, .4
-		MENU_OPTION		tSetDay,					oSetDay,				0
-		MENU_OPTION		tSetMonth,					oSetMonth,				0
-		MENU_OPTION		tSetYear,					oSetYear,				0
-		MENU_CALL		tBack,						do_return_date_time_menu
-	MENU_END
-
-
-do_time_menu:
-	bsf		block_option_value			; suspend display of option values
-
-	MENU_BEGIN	tSetTime, .4
-		MENU_OPTION		tSetHours,					oSetHours,				0
-		MENU_OPTION		tSetMinutes,				oSetMinutes,			0
-		MENU_OPTION		tSetSeconds,				oClearSeconds,			0
-		MENU_CALL		tBack,						do_return_date_time_menu
-	MENU_END
+;-----------------------------------------------------------------------------
+; dynamic Title - show Logbook Offset
+;
+dyn_logoffset_show_value:
+	STRCPY_TEXT tLogOffsetValue			; print "Offset" in selected language
+	call	eeprom_log_offset_read		; read  offset into lo:hi
+	output_9999							; print offset (0-9999)
+	return								; no "_PRINT" here...
 
 
-do_toggle_ppo2_max_work:				; add 0.1 bar
-	movff	char_I_ppO2_max_work,lo		; bank-safe copy
-	movlw	.10
-	addwf	lo,F
-	movlw	ppo2_warning_high_highest
-	cpfsgt	lo
-	bra		do_toggle_ppo2_max2
-	movlw	ppo2_warning_high_lowest
-	movwf	lo
-do_toggle_ppo2_max2:
-	movff	lo,char_I_ppO2_max_work
-	return
-
-do_toggle_ppo2_max_deco:				; add 0.1 bar
-	movff	char_I_ppO2_max_deco,lo		; bank-safe copy
-	movlw	.10
-	addwf	lo,F
-	movlw	ppo2_warning_deco_highest
-	cpfsgt	lo
-	bra		do_toggle_ppo2_max_deco2
-	movlw	ppo2_warning_deco_lowest
-	movwf	lo
-do_toggle_ppo2_max_deco2:
-	movff	lo,char_I_ppO2_max_deco
-	return
-
-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
-	cpfsgt	lo
-	bra		do_toggle_ppo2_min2
-	movlw	ppo2_warning_low_lowest
-	movwf	lo
-do_toggle_ppo2_min2:
-	movff	lo,char_I_ppO2_min
-	return
-
-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
-	cpfsgt	lo
-	bra		do_toggle_ppo2_min_cc2
-	movlw	ppo2_warning_loop_lowest
-	movwf	lo
-do_toggle_ppo2_min_cc2:
-	movff	lo,char_I_ppO2_min_loop
-	return
+;-----------------------------------------------------------------------------
+; Call Function - increment Logbook Offset
+;
+do_log_offset_plus:
+	rcall	do_logoffset_common			; load current offset and step size
+	; add step size to current offset
+	movf	mpr+2,W						; get step size, low  byte
+	addwf	mpr+0,F						; add to offset, low  byte
+	movf	mpr+3,W						; get step size, high byte
+	addwfc	mpr+1,F						; add to offset, high byte, considering carry flag
+	; check if new offset is within limit
+	MOVLI	.9999,sub_a					; load max limit  into sub_a
+	MOVII	mpr,  sub_b					; copy new offset into sub_b
+	call	cmpU16						; compute sub_a - sub_b, setting neg_flag if result becomes negative
+	btfss	neg_flag					; neg_flag set, i.e. new offset > 9999 ?
+	bra		do_logoffset_exit			; NO  - store offset and return
+	MOVLI	.9999,mpr					; YES - limit offset to 9999
+	bra		do_logoffset_exit			;     - store offset and return
 
 
-	; Logbook offset sub-menu
-do_log_offset_menu:
-
-	clrf	WREG						; select an initial step size of 1
-	movff	WREG,opt_logoffset_step		; bank-safe write to option variable
-
-	MENU_BEGIN	tLogOffset, .5
-		MENU_DYNAMIC	TFT_LogOffset,				0
-		MENU_OPTION		tLogOffStepSize,			oLogOffsetStep,				0
-		MENU_CALL		tLogOffsetplus,				do_logoffset_plus
-		MENU_CALL		tLogOffsetminus,			do_logoffset_minus
-		MENU_CALL		tBack,						do_return_settings_more
-	MENU_END
+;-----------------------------------------------------------------------------
+; Call Function - decrement Logbook Offset
+;
+do_log_offset_minus:
+	rcall	do_logoffset_common			; load current offset and step size
+	; subtract step size from current offset
+	movf	mpr+2,W						; get step size,        low  byte
+	subwf	mpr+0,F						; subtract from offset, low byte
+	movf	mpr+3,W						; get step size,        high byte
+	subwfb	mpr+1,F						; subtract from offset, high byte, considering borrow flag
+	; check if new offset is within limit
+	btfsc	STATUS,C					; borrow to propagate (B == /CARRY) ?
+	bra		do_logoffset_exit			; NO  - result >= 0, store and return
+	;bra	do_logoffset_reset			; YES - revert offset to 0
 
 
+;-----------------------------------------------------------------------------
+; Helper Functions - Logbook Offset Reset & Write-Back
+;
+do_logoffset_reset:
+	CLRI	mpr							; set   offset to 0
+do_logoffset_exit:
+	goto	eeprom_log_offset_write		; store offset and return
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - compute Step Size
+;
 do_logoffset_common:
 	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
@@ -991,126 +1798,252 @@
 	movwf	mpr+2						;     - copy to step size, low  byte
 	dcfsnz	ul,F						; ul--, did ul became 0, i.e. step size = 100 ?
 	return								; YES - done
-	movlw	LOW .1000					; NO  - set a step size of 1000, low byte
-	movwf	mpr+2						;     - copy to step size,      low  byte
+	movlw	LOW .1000					; NO  - set a step size of 1000, low  byte
+	movwf	mpr+2						;     - copy to step size,       low  byte
 	movlw	HIGH .1000					;     - set a step size of 1000, high byte
 	movwf	mpr+3						;     - copy to step size,       high byte
 	return								;     - done
 
-do_logoffset_plus:
-	rcall	do_logoffset_common			; load current offset and step size
-	; add step size to current offset
-	movf	mpr+2,W						; get step size, low  byte
-	addwf	mpr+0,F						; add to offset, low  byte
-	movf	mpr+3,W						; get step size, high byte
-	addwfc	mpr+1,F						; add to offset, high byte, considering carry flag
-	; check if new offset is within limit
-	MOVLI	.9999,sub_a					; load max limit  into sub_a
-	MOVII	mpr,  sub_b					; copy new offset into sub_b
-	call	cmpU16						; compute sub_a - sub_b, setting neg_flag if result becomes negative
-	btfss	neg_flag					; neg_flag set, i.e. new offset > 9999 ?
-	bra		do_logoffset_exit			; NO  - store offset and return
-	MOVLI	.9999,mpr					; YES - limit offset to 9999
-	bra		do_logoffset_exit			;     - store offset and return
 
-do_logoffset_minus:
-	rcall	do_logoffset_common			; load current offset and step size
-	; subtract step size from current offset
-	movf	mpr+2,W						; get step size,        low  byte
-	subwf	mpr+0,F						; subtract from offset, low byte
-	movf	mpr+3,W						; get step size,        high byte
-	subwfb	mpr+1,F						; subtract from offset, high byte, considering borrow flag
-	; check if new offset is within limit
-	btfsc	STATUS,C					; borrow to propagate (B == /CARRY) ?
-	bra		do_logoffset_exit			; NO  - result >= 0, store and return
-do_logoffset_reset:
-	CLRI	mpr							; YES - revert offset to 0
-	;bra	do_logoffset_exit			;     - store offset and return
-
-do_logoffset_exit:
-	goto	eeprom_log_offset_write		; store offset and return
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - System Settings - adjust Piezo Buttons
+;
+do_menu_piezo:
+	MENU_BEGIN	tPiezo, .3
+		MENU_OPT_INC	tButtonleft,				ocR_button_left				; left  button sensitivity
+		MENU_OPT_INC	tButtonright,				ocR_button_right			; right button sensitivity
+		MENU_CALL		tBack,						do_return_menu_syssets_piezo
+	MENU_END
 
 
-do_return_dispsets_menu:
-	bcf		imprint_color_schemes		; not in color schemes menu any more
-	call	menu_processor_double_pop	; drop exit line and back to last line
+;-----------------------------------------------------------------------------
+; Settings Menu - 3rd Layer - System Settings - Reset Menus
+;
+do_menu_reset:
+	MENU_BEGIN	tResetMenu, .6
+		MENU_CALL		tBack,						do_return_menu_syssets_more
+		MENU_CALL		tReboot,					do_menu_reset_reboot	; confirm
+		MENU_CALL		tResetDeco,					do_menu_reset_deco		; confirm
+		MENU_CALL		tResetSettings,				do_menu_reset_settings	; confirm
+		MENU_CALL		tResetLogbook,				do_menu_reset_logbook	; confirm
+		MENU_CALL		tResetBattery,				do_menu_reset_battery	; confirm
+	MENU_END
 
-do_dispsets_menu:
- 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		tFlip,						oFlipScreen,			0
-		MENU_CALL		tColorScheme,				do_color_scheme
-		MENU_CALL		tMore,						do_dispsets_menu_more
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 4th Layer - System Settings - Reset - Reboot / FW Recovery
+;
+do_menu_reset_reboot:
+ IFDEF _firmware_recovery
+	MENU_BEGIN	tResetMenu2, .4
+		MENU_CALL		tAbort,						do_return_menu_syssets_more_more
+		MENU_CALL		tRebootCurFirmware,			do_reboot				; reboot  current firmware
+		MENU_DYNAMIC	dyn_menu_fw_backup,			do_firmware_backup		; backup  current firmware
+		MENU_DYNAMIC	dyn_menu_fw_restore,		do_firmware_restore		; restore backup  firmware
 	MENU_END
  ELSE
-	MENU_BEGIN	tDispSets, .6
-		MENU_OPTION		tBright,					oBrightness,			0
-		MENU_OPTION		tLayout,					oLayout,				0
-		MENU_OPTION		tUnits,						oUnits,					0
-		MENU_OPTION		tFlip,						oFlipScreen,			0
-		MENU_CALL		tColorScheme,				do_color_scheme
-		MENU_CALL		tMore,						do_dispsets_menu_more
+	MENU_BEGIN	tResetMenu2, .2
+		MENU_CALL		tAbort,						do_return_menu_syssets_more_more
+		MENU_CALL		tReboot,					do_reboot				; reboot (cold start)
 	MENU_END
  ENDIF
 
 
-do_dispsets_menu_more:
- IFDEF _helium
-	MENU_BEGIN	tDispSets, .7
-		MENU_OPTION		tVSIgraph,					oVSIgraph,				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_settings_deeper
-	MENU_END
- ELSE
-	MENU_BEGIN	tDispSets, .6
-		MENU_OPTION		tVSIgraph,					oVSIgraph,				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_settings_deeper
-	MENU_END
+;-----------------------------------------------------------------------------
+; Call Function - Reboot
+;
+do_reboot:
+	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	option_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
+
+
+ IFDEF _firmware_recovery
+
+;-----------------------------------------------------------------------------
+; dynamic Title - Firmware Backup Option
+;
+dyn_menu_fw_backup:
+	EEPROM_CC_READ eeprom_fw_chksum_current+.5,WREG		; read     stored  FW ID
+	xorlw	FW_ID										; XOR with current FW ID, equal?
+	bnz		dyn_menu_fw_backup_unable					; NO  - unable to make a backup
+	STRCPY_TEXT tBackupFirmware							; YES - print "Backup current Firmware"
+	return												;     - done
+dyn_menu_fw_backup_unable:
+	STRCPY	"-------"									; print dashes
+	return												; done
+
+
+;-----------------------------------------------------------------------------
+; dynamic Title - Firmware Restore Option
+;
+dyn_menu_fw_restore:
+	STRCPY_TEXT tRecoverFirmware		; print "Recover"
+	PUTC	" "							; add a space
+	PUTC	"V"							; add a V for Version
+	movlw	0x3C						; address firmware version in backup storage at 0x3C000A
+	movwf	ext_flash_address+2			; ...
+	clrf	ext_flash_address+1			; ...
+	movlw	0x0A						; ...
+	movwf	ext_flash_address+0			; ...
+	FLASH_RR_READ mpr,.3				; read backup firmware version (lo: major, hi: minor, up: beta)
+	infsnz	lo,W						; major = 0xFF ?
+	bra		dyn_menu_fw_restore_inop	; YES - no version to show
+	bsf		leftbind					; NO  - print left-aligned
+	output_99							;     - print major (0-99)
+	PUTC	'.'							;     - add a dot
+	movff	hi,lo						;     - get minor
+	output_99x							;     - print minor (00-99)
+	PUTC	' '							;     - add a space
+	movff	up,lo						;     - get beta/release
+	tstfsz	lo							;    -  release version?
+	bra		dyn_menu_fw_restore_beta	;     - NO  - beta
+	STRCAT	"Rel."						;     - YES - append "Rel(ease)"
+	return								;           - done
+dyn_menu_fw_restore_beta:
+	PUTC	'B'							; append "B(eta)"
+	bsf		leftbind					; print left-aligned
+	output_256							; print beta version (0-255)
+	return								; done
+dyn_menu_fw_restore_inop:
+	STRCAT	"--.--"						; no recovery firmware available
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Call Function - backup Firmware
+;
+do_firmware_backup:
+	EEPROM_CC_READ eeprom_fw_chksum_current+.5,WREG		; read     stored  FW ID
+	xorlw	FW_ID										; XOR with current FW ID, equal?
+	bnz		do_firmware_abort							; NO  - abort
+	call	TFT_ClearScreen								; YES - clear the screen
+	WIN_SMALL .0, .100									;     - set position
+	STRCPY_TEXT_PRINT tBackingUp						;     - print "backing up..."
+	call	copy_fw_active_to_backup					;     - copy 0x3Exxxx -> 0x3Cxxxx
+	EEPROM_RR_READ  eeprom_fw_chksum_current,buffer,.6	;     - retrieve checksum of current  firmware
+	EEPROM_RR_WRITE buffer,eeprom_fw_chksum_recovry,.6	;     - store as checksum of recovery firmware
+	bra		do_return_menu_syssets_more_more			;     - done
+
+
+;-----------------------------------------------------------------------------
+; Call Function - restore Firmware
+;
+do_firmware_restore:
+	EXT_FLASH_ADDR 0x3C000A								; address firmware version in backup storage at 0x3C000A
+	FLASH_CW_READ_0x40									; read backup firmware major version into WREG
+	infsnz	WREG										; major = 0xFF ?
+	bra		do_firmware_abort							; YES - abort, no firmware available for restoration
+	call	TFT_ClearScreen								; NO  - clear the screen
+	WIN_SMALL .0, .100									;     - set position
+	STRCPY_TEXT_PRINT tRestoring						;     - print "restoring..."
+	call	copy_fw_backup_to_active					;     - copy 0x3Cxxxx -> 0x3Exxxx
+	EEPROM_RR_READ  eeprom_fw_chksum_recovry,buffer,.6	;     - retrieve checksum of recovery firmware
+	EEPROM_RR_WRITE buffer,eeprom_fw_chksum_current,.6	;     - store as checksum of current  firmware (to be)
+	goto	comm_firmware_update_exec					;     - initiate firmware update
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - back to same menu
+;
+do_firmware_abort:
+	call	menu_processor_pop							; back to last line
+	bra		do_menu_reset_reboot						; back to same menu
+
  ENDIF
 
 
-do_color_scheme:
-	bsf		imprint_color_schemes		; in color schemes menu
+;-----------------------------------------------------------------------------
+; Settings Menu - 4th Layer - System Settings - Reset - Reset Deco
+;
+do_menu_reset_deco:
+	MENU_BEGIN	tResetMenu2, .2
+		MENU_CALL		tAbort,						do_return_menu_syssets_more_more
+		MENU_CALL		tResetDeco,					do_reset_deco			; reset deco and return to main reset menu
+	MENU_END
+
 
-	MENU_BEGIN	tColorScheme, .2
-		MENU_OPTION		tColorSetDive,				oColorSetDive,			0
-		MENU_CALL		tBack,						do_return_dispsets_menu
+;-----------------------------------------------------------------------------
+; Call Function - Reset Deco
+;
+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	eeprom_deco_data_write		; store updated deco data into EEPROM
+	bra		do_return_menu_syssets_more_more
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 4th Layer - System Settings - Reset - Reset Settings
+;
+do_menu_reset_settings:
+	MENU_BEGIN	tResetMenu2, .2
+		MENU_CALL		tAbort,						do_return_menu_syssets_more_more
+		MENU_CALL		tResetSettings,				do_reset_settings		; reset all settings and go to surface mode
 	MENU_END
 
 
-;=============================================================================
+;-----------------------------------------------------------------------------
+; Call Function - Reset Settings
+;
+do_reset_settings:
+	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_new_battery_menu:
-	MENU_BEGIN	tNewBattTitle, .2
-		MENU_CALL		tAbort,						do_return_settings_more_deeper
-		MENU_CALL		tYes,						do_new_battery_select_1
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 4th Layer - System Settings - Reset - Reset Logbook
+;
+do_menu_reset_logbook:
+	MENU_BEGIN	tResetMenu2, .2
+		MENU_CALL		tAbort,						do_return_menu_syssets_more_more
+		MENU_CALL		tResetLogbook,				do_reset_logbook		; reset logbook and return to main reset menu
 	MENU_END
 
 
-	global	do_new_battery_select
-do_new_battery_select:
+;-----------------------------------------------------------------------------
+; Call Function - Reset Logbook
+;
+do_reset_logbook:
+	call	erase_complete_logbook		; erase complete logbook
+	bra		do_return_menu_syssets_more_more
+
+
+;-----------------------------------------------------------------------------
+; Settings Menu - 4th Layer - System Settings - Reset - Reset Battery
+;
+do_menu_reset_battery:
+	MENU_BEGIN	tNewBattTitle, .2
+		MENU_CALL		tAbort,						do_return_menu_syssets_more_more
+		MENU_CALL		tYes,						do_new_battery_select
+	MENU_END
+
+
+;-----------------------------------------------------------------------------
+; Entry Point for Battery Selection after Power-Outage
+;
+	global	new_battery_select
+new_battery_select:
 	call	TFT_boot					; initialize TFT (includes clear screen)
 	call	TFT_Display_FadeIn			; dim up the display
 	call	menu_processor_reset		; reset menu stack
+	;bra	do_new_battery_select		; enter menu system
 
-do_new_battery_select_1:
-	; make sure to reset battery percentage
-	movlw	.100
-	movwf	batt_percent				; set battery level to full
 
-	; default (in cases of timeout or USB): use old battery
+;-----------------------------------------------------------------------------
+; Settings Menu - 5th Layer - System Settings - Reset - Reset - Battery Selection
+;
+do_new_battery_select:
+	movlw	.100						; set battery level to full
+	movwf	batt_percent				; ...
+										; default (in cases of timeout or USB) to use old battery:
 	call	eeprom_battery_gauge_read	; retrieve stored battery gauge value from EEPROM
 
  IFDEF _screendump
@@ -1131,7 +2064,6 @@
 	; 0x02:                           ambient sensor                   ---> OSTC Sport (USB model)   YES    NO     1.5V  3.6V disposable  3.6V rechargeable
 	; 0x52: BLE                   and ambient sensor and low volt core ---> OSTC Sport (BLE model)   YES    NO     1.5V  3.6V disposable  3.6V rechargeable
 
-
 	movlw	0x11						; OSTC 2 (old model)
 	cpfseq	HW_descriptor
 	bra		$+4
@@ -1145,73 +2077,151 @@
 	movlw	0x33						; OSTC 2 TR
 	cpfseq	HW_descriptor
 	bra		$+4
-	bra		use_16650_battery
+	bra		do_use_16650_battery
 
-;	movlw	0xXX						; OSTC 2 (new model)							TODO: define signature
+;	movlw	0xXX						; OSTC 2 (new model)			TODO: define signature
 ;	cpfseq	HW_descriptor
 ;	bra		$+4
-;	bra		use_16650_battery
+;	bra		do_use_16650_battery
 
-	movlw	0x13						; OSTC Plus										TODO: and OSTC 2 new model as of now
+	movlw	0x13						; OSTC Plus						TODO: and OSTC 2 new model as of now
 	cpfseq	HW_descriptor
 	bra		$+4
-	bra		menu_new_battery_AA_charger
+	bra		do_menu_new_battery_AA_charger
 
 	; movlw	0x0A						; OSTC 3 (USB model)
 	; cpfseq	HW_descriptor
 	; bra		$+4
-	; bra		menu_new_battery_AA_no_charger
+	; bra		do_menu_new_battery_AA_no_charge
 
 	; movlw	0x1A						; OSTC 3 (BLE model)
 	; cpfseq	HW_descriptor
 	; bra		$+4
-	; bra		menu_new_battery_AA_no_charger
+	; bra		do_menu_new_battery_AA_no_charge
 
 	; movlw	0x02						; OSTC Sport (USB model)
 	; cpfseq	HW_descriptor
 	; bra		$+4
-	; bra		menu_new_battery_AA_no_charger
+	; bra		do_menu_new_battery_AA_no_charge
 
 	; movlw	0x52						; OSTC Sport (BLE model)
 	; cpfseq	HW_descriptor
 	; bra		$+4
-	; bra		menu_new_battery_AA_no_charger
+	; bra		do_menu_new_battery_AA_no_charge
 
-	bra		menu_new_battery_AA_no_charger	; any other model
+	bra		do_menu_new_battery_AA_no_charge	; any other model
 
 
+;-----------------------------------------------------------------------------
+; return from confirm 3.6 V rechargeable
+;
 do_return_menu_new_bat_AA_chrg:
-	call	menu_processor_double_pop	; drop exit line and back to last line
+	call	menu_processor_double_pop		; drop exit line and back to last line
+	;bra	do_menu_new_battery_AA_charger	; continue
 
-	; OSTC Plus (charging function)																TODO: and OSTC 2 new model as of now
-menu_new_battery_AA_charger:
+;-----------------------------------------------------------------------------
+; Battery Selection for OSTC Plus (charging function)								TODO: and OSTC 2 new model as of now
+;
+do_menu_new_battery_AA_charger:
 	MENU_BEGIN	tNewBattTitle, .4
-		MENU_CALL		tNewBattOld,				use_old_batteries
-		MENU_CALL		tNewBattNew15,				use_new_15V_batteries	; not rechargeable
-;		MENU_CALL		tNewBattNew36,				use_36V_disposable		; not rechargeable  -> not allowed any more !!!
-		MENU_CALL		tNewBattAccu,				pre_36V_rechargeable	; rechargeable      -> goto safety question
-		MENU_CALL		tNew16650,					use_16650_battery		; OSTC 2 new model	TODO: remove when OSTC 2 new model can be separated from Plus
+		MENU_CALL		tNewBattOld,				do_use_old_battery				; load data of old battery
+		MENU_CALL		tNewBattNew15,				do_use_15V_disposable			; not rechargeable
+;		MENU_CALL		tNewBattNew36,				do_use_36V_disposable			; not rechargeable  -> not allowed any more !!!
+		MENU_CALL		tNewBattAccu,				do_menu_new_battery_36V_charge	; rechargeable      -> goto safety question
+		MENU_CALL		tNew16650,					do_use_16650_battery			; OSTC 2 new model	TODO: remove when OSTC 2 new model can be separated from Plus
 	MENU_END
 
-pre_36V_rechargeable:
+
+;-----------------------------------------------------------------------------
+; Safety Question for 3.6 V rechargeable Battery
+;
+do_menu_new_battery_36V_charge:
 	MENU_BEGIN	tNewBattTitle, .5
 		MENU_CALL		tConfirmChargeable1,		0								; safety question, line 1
 		MENU_CALL		tConfirmChargeable2,		0								; safety question, line 2
 		MENU_CALL		tConfirmChargeable3,		0								; safety question, line 3
 		MENU_CALL		tNo,						do_return_menu_new_bat_AA_chrg	; NO  - go back
-		MENU_CALL		tYes,						use_37V_rechargeable			; YES - confirmed rechargeable
+		MENU_CALL		tYes,						do_use_36V_chargeable			; YES - confirmed rechargeable
 	MENU_END
 
-	; OSTC 3 and Sport (no charging function)
-menu_new_battery_AA_no_charger:
+
+;-----------------------------------------------------------------------------
+; Battery Selection for OSTC 3 and Sport (no charging function)
+;
+do_menu_new_battery_AA_no_charge:
 	MENU_BEGIN	tNewBattTitle, .4
-		MENU_CALL		tNewBattOld,				use_old_batteries
-		MENU_CALL		tNewBattNew15,				use_new_15V_batteries	; not rechargeable
-		MENU_CALL		tNewBattNew36,				use_36V_disposable		; not rechargeable
-		MENU_CALL		tNewBattAccu,				use_37V_rechargeable	; rechargeable
+		MENU_CALL		tNewBattOld,				do_use_old_battery				; load data of old battery
+		MENU_CALL		tNewBattNew15,				do_use_15V_disposable			; not rechargeable
+		MENU_CALL		tNewBattNew36,				do_use_36V_disposable			; not rechargeable
+		MENU_CALL		tNewBattAccu,				do_use_36V_chargeable			; rechargeable
 	MENU_END
 
 
+;-----------------------------------------------------------------------------
+; Call Function - keep old Battery
+;
+do_use_old_battery:
+	rcall	get_battery_data			; load data of old battery
+	goto	surfloop					; proceed to surface mode
+
+
+;-----------------------------------------------------------------------------
+; Call Function - new 1.5 V disposable
+;
+do_use_15V_disposable:
+	rcall	setup_new_15v
+	bra		use_batt_exit
+
+
+;-----------------------------------------------------------------------------
+; Call Function - new 3.6 V disposable
+;
+do_use_36V_disposable:
+	rcall	setup_new_saft
+	bra		use_batt_exit
+
+
+;-----------------------------------------------------------------------------
+; Call Function - new 3.6 V rechargeable
+;
+do_use_36V_chargeable:
+	rcall	setup_new_panasonic
+	call	reset_battery_gauge
+	bra		use_batt_exit_1
+
+
+;-----------------------------------------------------------------------------
+; Call Function - build-in 16650
+;
+do_use_16650_battery:
+	rcall	setup_new_16650
+	bra		use_batt_exit
+
+
+;-----------------------------------------------------------------------------
+; Call Function - build-in 18650
+;
+use_18650_battery:
+	rcall	setup_new_18650
+	;bra	use_batt_exit
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - finish Battery Selection
+;
+use_batt_exit:
+	call	reset_battery_gauge_and_lt2942	; reset battery hard- and software gauge
+
+use_batt_exit_1:
+ IFNDEF _screendump
+	bcf		comm_mode_disabled				; re-enable COMM mode again
+ ENDIF
+	goto	surfloop						; exit to surface mode
+
+
+;-----------------------------------------------------------------------------
+; Migrate Battery Selection from Firmwares prior 2.09
+;
 	global	use_old_prior_209
 use_old_prior_209:
 	EEPROM_CC_READ eeprom_battery_type,WREG	; read battery type from EEPROM
@@ -1225,11 +2235,9 @@
 	return									;     - done
 
 
-use_old_batteries:
-	rcall	get_battery_data			; load data of old battery
-	goto	surfloop					; proceed to surface loop
-
-
+;-----------------------------------------------------------------------------
+; Retrieve Battery Selection from EEPROM
+;
 	global	get_battery_data
 get_battery_data:
 	call	eeprom_battery_gauge_read	; retrieve stored battery gauge value from EEPROM
@@ -1253,6 +2261,9 @@
 	return								; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Functions - configure Battery Types
+
 	; disposable 1.5 Volt Alkaline
 setup_new_15v:
 	bsf		charge_disable				; set      charging-inhibit signal
@@ -1307,36 +2318,6 @@
 	movwf	battery_type
 	return
 
-
-use_new_15V_batteries:
-	rcall	setup_new_15v
-	bra		use_batt_exit
-
-use_36V_disposable:
-	rcall	setup_new_saft
-	bra		use_batt_exit
-
-use_37V_rechargeable:
-	rcall	setup_new_panasonic
-	call	reset_battery_gauge
-	bra		use_batt_exit_1
-
-use_16650_battery:
-	rcall	setup_new_16650
-	bra		use_batt_exit
-
-use_18650_battery:
-	rcall	setup_new_18650
-	;bra	use_batt_exit
-
-use_batt_exit:
-	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
- ENDIF
-	goto	surfloop					; jump to surface loop
-
 ;-----------------------------------------------------------------------------
 
 	END
--- a/src/ms5541.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/ms5541.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,8 +1,8 @@
 ;=============================================================================
 ;
-;   File ms5541.asm                           combined next generation V3.8.6
+;   File ms5541.asm                          * combined next generation V3.9.4f
 ;
-;   Sensor subroutines
+;   Sensor Subroutines
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
 ;=============================================================================
@@ -15,15 +15,19 @@
 
 ms5541	CODE
 
-;=============================================================================
+
 ; Expose internal variables to ease debug
 	global	D1, D2
 	global	C1, C2, C3, C4, C5, C6
 	global	xdT, xdT2, OFF, SENS, pressure_abs_avg, temperature_avg
 
-;=============================================================================
 
-	global calculate_compensation		; called from ISR and from sleep mode, returns in bank isr_data
+;-----------------------------------------------------------------------------
+; Convert Temperature & Pressure raw Values to compensated Values
+;
+; called from ISR and from sleep mode, returns in bank isr_data
+;
+	global calculate_compensation
 calculate_compensation:
 	banksel	isr_backup					; select bank ISR data
 
@@ -51,125 +55,112 @@
 
 	; dT >= 0: divide by 8, i.e. 3 shifts rights
 	; dT <  0: divide by 2, i.e. 1 shifts rights
-	movlw	.3
-	btfss	xdT+1,7						 ; was dT negative ?
-	movlw	.1
+	movlw	.3							; 3 shifts by default
+	btfss	xdT+1,7						; was dT negative ?
+	movlw	.1							; YES - replace by 1 shift
 calc_loop_1:
-	bcf		STATUS,C					; dT^2 is positive, so injected zeros
-	rrcf	isr_xC+1,F
-	rrcf	isr_xC+0,F
-	decfsz	WREG
-	bra		calc_loop_1
+	bcf		STATUS,C					; dT^2 is positive, so injecte zeros
+	rrcf	isr_xC+1,F					; shift right high byte
+	rrcf	isr_xC+0,F					; shift right low  byte
+	decfsz	WREG						; decrement loop counter, all shifts done?
+	bra		calc_loop_1					; NO  - loop
 
 	movf	isr_xC+0,W					; dT2 = dT - (dT/128)*(dT/128)/(2 ...or... 8)
-	subwf	xdT+0,W
-	movwf	xdT2+0
-	movf	isr_xC+1,W
-	subwfb	xdT+1,W
-	movwf	xdT2+1
+	subwf	xdT+0,W						; ...
+	movwf	xdT2+0						; ...
+	movf	isr_xC+1,W					; ...
+	subwfb	xdT+1,W						; ...
+	movwf	xdT2+1						; ...
 
 	; calculate OFF = C2 + ((C4-250)*dT2)/2^12 + 10000 (range +9.246 .. +18.887)
 	MOVII	C4,  isr_xA					; C4 - 250 --> A
 	MOVII	xdT2,isr_xB					; dT2      --> B
-	call	isr_signed_mult16x16
+	call	isr_signed_mult16x16		; C = A*B
 
 	movlw	.12-.8						; a 12 bit shift = 1 byte + 4 bits
-	call	isr_shift_C31
+	call	isr_shift_C31				; special shift
 
 	movlw	LOW(.10000)					; add 10000
-	addwf	isr_xC+1,F
-	movlw	HIGH(.10000)
-	addwfc	isr_xC+2,F
+	addwf	isr_xC+1,F					; ...
+	movlw	HIGH(.10000)				; ...
+	addwfc	isr_xC+2,F					; ...
 
 	movf	C2+0,W						; add C2 and store result in OFF
-	addwf	isr_xC+1,W
-	movwf	OFF+0
-	movf	C2+1,W
-	addwfc	isr_xC+2,W
-	movwf	OFF+1
+	addwf	isr_xC+1,W					; ...
+	movwf	OFF+0						; ...
+	movf	C2+1,W						; ...
+	addwfc	isr_xC+2,W					; ...
+	movwf	OFF+1						; ...
 
 	; calculate SENS = C1/2 + ((C3+200)*dT)/2^13 + 3000
 	movlw	LOW(.200)					; C3+200 --> A
-	addwf	C3+0,W
-	movwf	isr_xA+0
-	movlw	HIGH(.200)
-	addwfc	C3+1,W
-	movwf	isr_xA+1
+	addwf	C3+0,W						; ...
+	movwf	isr_xA+0					; ...
+	movlw	HIGH(.200)					; ...
+	addwfc	C3+1,W						; ...
+	movwf	isr_xA+1					; ...
 										; B still contains dT2
-	call	isr_signed_mult16x16		; A*B --> C
+	call	isr_signed_mult16x16		; C = A*B
 	movlw	.13-.8						; A 13 bit shift = 1 byte + 5 bits
-	call	isr_shift_C31
+	call	isr_shift_C31				; special shift
 
 	bcf		STATUS,C					; SENS = C1 / 2
-	rrcf	C1+1,W
-	movwf	SENS+1
-	rrcf	C1+0,W
-	movwf	SENS+0
+	rrcf	C1+1,W						; ...
+	movwf	SENS+1						; ...
+	rrcf	C1+0,W						; ...
+	movwf	SENS+0						; ...
 
 	movlw	LOW(.3000)					; add 3000
-	addwf	isr_xC+1,F
-	movlw	HIGH(.3000)
-	addwfc	isr_xC+2,F
+	addwf	isr_xC+1,F					; ...
+	movlw	HIGH(.3000)					; ...
+	addwfc	isr_xC+2,F					; ...
 
 	movf	isr_xC+1,W					; and sum into SENS
-	addwf	SENS+0,F
-	movf	isr_xC+2,W
-	addwfc	SENS+1,F
+	addwf	SENS+0,F					; ...
+	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)
 	movf	OFF+0,W						; d1-off --> a
-	subwf	D1+0,W
-	movwf	isr_xA+0
-	movf	OFF+1,W
-	subwfb	D1+1,W
-	movwf	isr_xA+1
+	subwf	D1+0,W						; ...
+	movwf	isr_xA+0					; ...
+	movf	OFF+1,W						; ...
+	subwfb	D1+1,W						; ...
+	movwf	isr_xA+1					; ...
 
-	MOVII	SENS,isr_xB					; sens --> b
-	call	isr_signed_mult16x16
-	movlw	.13
+	MOVII	SENS,isr_xB					; sens --> B
+	call	isr_signed_mult16x16		; C = A*B
+	movlw	.13							; 12 * 256 = 3328
 	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
+	bra		isr_shift_ms5541_common		;     - continue
 isr_shift_ms5541_30:
 	movlw	.11-.8						; MS5541-30:    11 bit shift = 1 byte + 3 bits
 isr_shift_ms5541_common:
-	call	isr_shift_C31
+	call	isr_shift_C31				; special shift
 	movlw	LOW  .1000					; add 1000
-	addwf	isr_xC+1,F
-	movlw	HIGH .1000
-	addwfc	isr_xC+2,F
+	addwf	isr_xC+1,F					; ...
+	movlw	HIGH .1000					; ...
+	addwfc	isr_xC+2,F					; ...
 
 	; add opt_pressure_adjust to result (SIGNED!)
-	movff	opt_pressure_adjust,isr_xC+0; get adjustment value (signed)
-	movf	isr_xC+0,F					; excite flags, opt_pressure_adjust = 0 ?
-	bz		calc_compensation_1			; YES - skip pressure adjustment
-	btfss	isr_xC+0,7					; NO  - opt_pressure_adjust < 0 ?
-	bra		pressure_extra_add			;       NO  - add offset
-	;bra	pressure_extra_sub			;       YES - subtract offset
-
-pressure_extra_sub:
-	comf	isr_xC+0,F					; complement opt_pressure_adjust
-	incf	isr_xC+0,F					; ...
-	movlw	.22							; check for max. of 20 mbar
-	cpfslt	isr_xC+0					; opt_pressure_adjust < 21 mbar ?
-	clrf	isr_xC+0					; NO - reset opt_pressure_adjust to zero
-	movf	isr_xC+0,W					; get opt_pressure_adjust to WREG
-	subwf	isr_xC+1,F					; pressure value -= opt_pressure_adjust, low  byte
-	movlw	.0							; pressure value -= opt_pressure_adjust, high byte
-	subwfb	isr_xC+2,F					; ...
-	bra		calc_compensation_1			; continue with checking for simulator mode
-
-pressure_extra_add:
-	movlw	.21							; check for max. of 20 mbar
-	cpfslt	isr_xC+0					; opt_pressure_adjust < 21 mbar ?
-	clrf	isr_xC+0					; NO - reset opt_pressure_adjust to zero
-	movf	isr_xC+0,W					; get opt_pressure_adjust to WREG
+	clrf	isr_xC+0					; prepare high byte for adjustment
+	movff	opt_pressure_adjust,WREG	; get     low  byte for adjustment (signed)
+	movf	WREG,W						; excite flags
+	bz		calc_compensation_1			; opt_pressure_adjust = 0 -> skip adjustment
+	btfss	STATUS,N					; opt_pressure_adjust < 0 ?
+	bra		calc_compensation_adjust	; NO  - positive
+	negf	WREG						; YES - negate opt_pressure_adjust for limit check
+	setf	isr_xC+0					;     - adopt high byte for adjustment
+calc_compensation_adjust:
+	addlw	-.21						; limit is 20 mbar, subtract 21
+	bnn		calc_compensation_1			; result not negative -> skip adjustment
+	movff	opt_pressure_adjust,WREG	; get opt_pressure_adjust,               low  byte
 	addwf	isr_xC+1,F					; pressure value += opt_pressure_adjust, low  byte
-	movlw	.0							; pressure value += opt_pressure_adjust, high byte
-	addwfc	isr_xC+2,F					; ...
-	;bra	calc_compensation_1			; continue with checking for simulator mode
+	movf	isr_xC+0,W					; get adjustment,                        high byte
+	addwfc	isr_xC+2,F					; pressure value += opt_pressure_adjust, high byte
 
 calc_compensation_1:
 	bcf		sensor_override_active		; clear sensor override active flag by default
@@ -270,145 +261,160 @@
 
 	; calculate temp = 200 + dT*(C6+100)/2^11
 	movlw	LOW(.100)					; C6 + 100 --> A
-	addwf	C6+0,W
-	movwf	isr_xA+0
-	movlw	HIGH(.100)
-	addwfc	C6+1,W
-	movwf	isr_xA+1
+	addwf	C6+0,W						; ...
+	movwf	isr_xA+0					; ...
+	movlw	HIGH(.100)					; ...
+	addwfc	C6+1,W						; ...
+	movwf	isr_xA+1					; ...
 
 	MOVII	xdT2,isr_xB					; dT2 --> B
 	call	isr_signed_mult16x16		; A*B
 	movlw	.11-.8						; a 12 bit shift = 1 byte + 3 bits
-	call	isr_shift_C31
+	call	isr_shift_C31				; special shift
 
 	movlw	LOW(.200)					; add 200
-	addwf	isr_xC+1,F
-	movlw	HIGH(.200)
-	addwfc	isr_xC+2,F
+	addwf	isr_xC+1,F					; ...
+	movlw	HIGH(.200)					; ...
+	addwfc	isr_xC+2,F					; ...
 
 	; add opt_temperature_adjust to result (SIGNED!)
-	movff	opt_temperature_adjust,isr_xC+0
-
-	btfss	isr_xC+0,7					; < 0 ?
-	bra		temperature_extra_add		; NO
-	comf	isr_xC+0,F					; YES
-	incf	isr_xC+0,F
-	movlw	.22							; check for max. of 2.0°C
-	cpfslt	isr_xC+0
-	clrf	isr_xC+0
-	movf	isr_xC+0,W					; subtract
-	subwf	isr_xC+1,F
-	movlw	.0
-	subwfb	isr_xC+2,F
-	bra		temperature_extra_common
+	clrf	isr_xC+0					; prepare high byte for adjustment
+	movff	opt_temperature_adjust,WREG	; get     low  byte for adjustment (signed)
+	movf	WREG,W						; excite flags
+	bz		calc_temperature_add_avg	; opt_temperature_adjust = 0 -> skip adjustment
+	btfss	STATUS,N					; opt_temperature_adjust < 0 ?
+	bra		calc_temperature_adjust		; NO  - positive
+	negf	WREG						; YES - negate opt_temperature_adjust for limit check
+	setf	isr_xC+0					;     - adopt high byte for adjustment
+calc_temperature_adjust:
+	addlw	-.21						; limit is 2.0°C, subtract 21 (scaling is 0.1°C)
+	bnn		calc_temperature_add_avg	; result not negative -> skip adjustment
+	movff	opt_temperature_adjust,WREG	; get opt_temperature_adjust,                  low  byte
+	addwf	isr_xC+1,F					; temperature value += opt_temperature_adjust, low  byte
+	movf	isr_xC+0,W					; get adjustment                               high byte
+	addwfc	isr_xC+2,F					; temperature value += opt_temperature_adjust, high byte
 
-temperature_extra_add:
-	movlw	.21							; check for max. of 2.0°C
-	cpfslt	isr_xC+0
-	clrf	isr_xC+0
-	movf	isr_xC+0,W					; add
-	addwf	isr_xC+1,F
-	movlw	.0
-	addwfc	isr_xC+2,F
+calc_temperature_add_avg:
+	movf	isr_xC+1,W					; copy current temperature to WREG,       low  byte
+	addwf	temperature_avg+0,F			; temperature_avg += current temperature, low  byte
+	movf	isr_xC+2,W					; copy current temperature to WREG,       high byte
+	addwfc	temperature_avg+1,F			; temperature_avg += current temperature, high byte
+	return								; done
+
 
-temperature_extra_common:
-	movf	isr_xC+1,W
-	addwf	temperature_avg+0,F
-	movf	isr_xC+2,W
-	addwfc	temperature_avg+1,F
-
+;-----------------------------------------------------------------------------
+; Start Pressure Measurement
+;
+; called from ISR and sleep mode, needs to be called in bank isr_backup
+;
+	global	get_pressure_start
+get_pressure_start:
+	rcall	reset_MS5541				; reset the chip
+	movlw	b'10100000'					; +3*high as start and 1+low as stop
+	movwf	dbuffer						; ....
+	movlw	d'12'						; send start command
+	rcall	send_data_MS5541			; ...
 	return								; done
 
-;=============================================================================
 
-	global	get_pressure_start			; called from ISR and sleep mode, needs to be called bank isr_backup
-get_pressure_start:
-	rcall	reset_MS5541
-	movlw	b'10100000'					; +3*high as start and 1+low as stop
-	movwf	dbuffer
-	movlw	d'12'
-	rcall	send_data_MS5541
-	return
-
-	global get_pressure_value			; called from ISR and sleep mode, needs to be called bank isr_backup
+;-----------------------------------------------------------------------------
+; Read Pressure Measurement Result
+;
+; called from ISR and sleep mode, needs to be called in bank isr_backup
+;
+	global get_pressure_value
 get_pressure_value:
 	btfsc	MS5541_miso					; conversion done?
-	return								; NO - done
-	rcall	get_2bytes_MS5541
-	movff	dMSB,D1+1
-	movff	dLSB,D1+0
-	return
-
-;=============================================================================
-
-	global	get_temperature_start		; called from ISR and sleep mode, needs to be called in bank isr_backup
-get_temperature_start:
-	rcall	reset_MS5541
-	movlw	b'10010000'					; +3*high as start and 1+low as stop
-	movwf	dbuffer
-	movlw	d'12'
-	rcall	send_data_MS5541
-	return
+	return								; NO  - abort
+	rcall	get_2bytes_MS5541			; YES - read result
+	movff	dMSB,D1+1					; copy result to D1, high byte first
+	movff	dLSB,D1+0					; ...                low  byte second
+	return								; done
 
 
-	global	get_temperature_value		; called from ISR and sleep mode, needs to be called in bank isr_backup
+;-----------------------------------------------------------------------------
+; Start Temperature Measurement
+;
+; called from ISR and sleep mode, needs to be called in bank isr_backup
+;
+	global	get_temperature_start
+get_temperature_start:
+	rcall	reset_MS5541				; reset chip
+	movlw	b'10010000'					; +3*high as start and 1+low as stop
+	movwf	dbuffer						; ...
+	movlw	d'12'						; send start command
+	rcall	send_data_MS5541			; ...
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Read Pressure Measurement Result
+;
+; called from ISR and sleep mode, needs to be called in bank isr_backup
+;
+	global	get_temperature_value
 get_temperature_value:
 	btfsc	MS5541_miso					; conversion done?
 	return								; NO - done
-	rcall	get_2bytes_MS5541
-	movff	dMSB,D2+1
-	movff	dLSB,D2+0
-	return
+	rcall	get_2bytes_MS5541			; YES - read result
+	movff	dMSB,D2+1					; copy result to D2, high byte first
+	movff	dLSB,D2+0					; ...                low  byte second
+	return								; done
+
 
-;=============================================================================
-
-	global	get_calibration_data		; called by start, returns in bank common
+;-----------------------------------------------------------------------------
+; Retrieve Calibration Data
+;
+; called by start, returns in bank common
+;
+	global	get_calibration_data
 get_calibration_data:
 	banksel	isr_backup					; select bank ISR data
 	bsf		block_sensor_interrupt		; disable sensor interrupts
 
-	rcall	reset_MS5541
+	rcall	reset_MS5541				; reset chip
+
 	movlw	b'01010100'					; +3*high as start and 1+low as stop
-	movwf	dbuffer
-	movlw	d'13'
-	rcall	send_data_MS5541
-	rcall	get_2bytes_MS5541
-	movff	dMSB,ir_s8_buffer+1
-	movff	dLSB,ir_s8_buffer+0
+	movwf	dbuffer						; ...
+	movlw	d'13'						; send command
+	rcall	send_data_MS5541			; ...
+	rcall	get_2bytes_MS5541			; read result
+	movff	dMSB,ir_s8_buffer+1			; copy result, high byte first
+	movff	dLSB,ir_s8_buffer+0			; copy result, low  byte second
 
 	movlw	b'01011000'					; +3*high as start and 1+low as stop
-	movwf	dbuffer
-	movlw	d'13'
-	rcall	send_data_MS5541
-	rcall	get_2bytes_MS5541
-	movff	dMSB,ir_s8_buffer+3
-	movff	dLSB,ir_s8_buffer+2
+	movwf	dbuffer						; ...
+	movlw	d'13'						; send command
+	rcall	send_data_MS5541			; ...
+	rcall	get_2bytes_MS5541			; read result
+	movff	dMSB,ir_s8_buffer+3			; copy result, high byte first
+	movff	dLSB,ir_s8_buffer+2			; copy result, low  byte second
 
 	movlw	b'01100100'					; +3*high as start and 1+low as stop
-	movwf	dbuffer
-	movlw	d'13'
-	rcall	send_data_MS5541
-	rcall	get_2bytes_MS5541
-	movff	dMSB,ir_s8_buffer+5
-	movff	dLSB,ir_s8_buffer+4
+	movwf	dbuffer						; ...
+	movlw	d'13'						; send command
+	rcall	send_data_MS5541			; ...
+	rcall	get_2bytes_MS5541			; read result
+	movff	dMSB,ir_s8_buffer+5			; copy result, high byte first
+	movff	dLSB,ir_s8_buffer+4			; copy result, low  byte second
 
 	movlw	b'01101000'					; +3*high as start and 1+low as stop
-	movwf	dbuffer
-	movlw	d'13'
-	rcall	send_data_MS5541
-	rcall	get_2bytes_MS5541
-	movff	dMSB,ir_s8_buffer+7
-	movff	dLSB,ir_s8_buffer+6
+	movwf	dbuffer						; ...
+	movlw	d'13'						; send command
+	rcall	send_data_MS5541			; ...
+	rcall	get_2bytes_MS5541			; read result
+	movff	dMSB,ir_s8_buffer+7			; copy result, high byte first
+	movff	dLSB,ir_s8_buffer+6			; copy result, low  byte second
 
-	; calculate C1 (16Bit)
-	movff	ir_s8_buffer+1, C1+1
+	; calculate C1 (16 Bit)
+	movff	ir_s8_buffer+1,C1+1
 	bcf		STATUS,C
 	rrcf	C1+1
 	bcf		STATUS,C
 	rrcf	C1+1
 	bcf		STATUS,C
 	rrcf	C1+1
-	movff	ir_s8_buffer+0, C1+0
+	movff	ir_s8_buffer+0,C1+0
 	bsf		STATUS,C
 	btfss	ir_s8_buffer+1,0
 	bcf		STATUS,C
@@ -422,7 +428,7 @@
 	bcf		STATUS,C
 	rrcf	C1+0
 
-	; calculate C2 (16Bit)
+	; calculate C2 (16 Bit)
 	movff	ir_s8_buffer+2, C2+0
 	bsf		STATUS,C
 	btfss	ir_s8_buffer+3,0
@@ -469,7 +475,7 @@
 	bcf		STATUS,C
 	rrcf	C2+1
 
-	; calculate C3 (16Bit)
+	; calculate C3 (16 Bit)
 	movff	ir_s8_buffer+5,C3+0
 	bsf		STATUS,C
 	btfss	ir_s8_buffer+4,7
@@ -485,7 +491,7 @@
 	btfsc	ir_s8_buffer+5,6
 	bsf		C3+1,0
 
-	; calculate C4 (16Bit)
+	; calculate C4 (16 Bit)
 	movff	ir_s8_buffer+7,C4+0
 	bsf		STATUS,C
 	btfss	ir_s8_buffer+6,7
@@ -503,7 +509,7 @@
 	addwfc	C4+1,W
 	movwf	C4+1
 
-	; calculate C5 (16Bit)
+	; calculate C5 (16 Bit)
 	movff	ir_s8_buffer+4,C5+0
 	bcf		C5+0,6
 	btfsc	ir_s8_buffer+2,0
@@ -544,13 +550,16 @@
 	banksel	common						; back to bank common
 	return								; done
 
-;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Helper Function - Reset Chip
+;
 reset_MS5541_one:
-	bsf		MS5541_mosi
+	bsf		MS5541_mosi					; set MOSI
 	bra		send_clk_pulse				; send one high-low sequence on MS5541_clk and return
 
 reset_MS5541_zero:
-	bcf		MS5541_mosi
+	bcf		MS5541_mosi					; clear MOSI
 	bra		send_clk_pulse				; send one high-low sequence on MS5541_clk and return
 
 reset_MS5541:
@@ -578,77 +587,95 @@
 	return
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - read 2 Byte from Chip
+;
 get_2bytes_MS5541:
-	movlw	d'8'
-	movwf	clock_count
-	rcall	recieve_loop
-	movff	dbuffer,dMSB
-	movlw	d'8'
-	movwf	clock_count
-	rcall	recieve_loop
-	movff	dbuffer,dLSB
+	movlw	d'8'						; load counter for 8 bit
+	movwf	clock_count					; ...
+	rcall	recieve_loop				; receive 8 bits
+	movff	dbuffer,dMSB				; store result
+	movlw	d'8'						; load counter for 8 bit
+	movwf	clock_count					; ...
+	rcall	recieve_loop				; receive 8 bits
+	movff	dbuffer,dLSB				; store result
 	bra		send_clk_pulse				; send one high-low sequence on MS5541_clk and return
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - read 1 Bit from Chip
+;
 recieve_loop:
 	rcall	send_clk_pulse				; send one high-low sequence on MS5541_clk
-	btfss	MS5541_miso					; MSB first
-	bcf		STATUS,C
-	btfsc	MS5541_miso					; MSB first
-	bsf		STATUS,C
-	rlcf	dbuffer,F
-	decfsz	clock_count,F
-	bra		recieve_loop
-	return
+	btfss	MS5541_miso					; read bit = 1 ? (MSB first)
+	bcf		STATUS,C					; NO - clear carry bit
+	btfsc	MS5541_miso					; read bit = 0 ? (MSB first)
+	bsf		STATUS,C					; NO - set   carry bit
+	rlcf	dbuffer,F					; shift buffer
+	decfsz	clock_count,F				; decrement counter, became zero?
+	bra		recieve_loop				; NO  - loop
+	return								; YES - done
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - send a Clock Pulse
+;
 send_clk_pulse:
-	bsf		MS5541_clk
+	bsf		MS5541_clk					; set clock
 	nop
 	nop
 	nop
 	nop
 	nop
 	nop
-	bcf		MS5541_clk
+	bcf		MS5541_clk					; release clock
 	nop
 	nop
 	nop
 	nop
-	return
+	return								; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - send a Command
+;
 send_data_MS5541:
 	movwf	clock_count					; from WREG
 	; send three start bits first
-	bcf		MS5541_clk
-	nop
-	nop
-	bsf		MS5541_mosi
-	movlw	d'3'
-	subwf	clock_count,F				; total bit counter
+	bcf		MS5541_clk					; revoke clock
+	nop									; wait
+	nop									; wait
+	bsf		MS5541_mosi					; set MOSI
+	movlw	d'3'						; compute total bit counter
+	subwf	clock_count,F				; ...
 	rcall	send_clk_pulse				; send one high-low sequence on MS5541_clk
 	rcall	send_clk_pulse				; send one high-low sequence on MS5541_clk
 	rcall	send_clk_pulse				; send one high-low sequence on MS5541_clk
-send_data_MS5541_loop:					; now send 8 bits from dbuffer and fill-up with zeros
-	bcf		MS5541_clk
-	nop
-	nop
-	btfss	dbuffer,7					; MSB first
-	bcf		MS5541_mosi
-	btfsc	dbuffer,7					; MSB first
-	bsf		MS5541_mosi
-	bsf		MS5541_clk
-	bcf		STATUS,C
-	rlcf	dbuffer,F
-	nop
-	nop
+
+send_data_MS5541_loop:
+	; now send 8 bits from dbuffer and fill-up with zeros
+	bcf		MS5541_clk					; revoke clock
+	nop									; wait
+	nop									; wait
+	btfss	dbuffer,7					; bit = 1 ? (MSB first)
+	bcf		MS5541_mosi					; NO  - clear MOSI
+	btfsc	dbuffer,7					; bit = 0 ? (MSB first)
+	bsf		MS5541_mosi					; NO  - set   MOSI
+	bsf		MS5541_clk					; set clock
+	bcf		STATUS,C					; clear carry bit
+	rlcf	dbuffer,F					; shift data byte
+	nop									; wait
+	nop									; wait
 ;	nop
 ;	nop
 ;	nop
 ;	nop
 ;	bcf		MS5541_clk
-	decfsz	clock_count,F
-	bra		send_data_MS5541_loop
-	bcf		MS5541_clk
-	return
+	decfsz	clock_count,F				; decrement bit counter, became zero?
+	bra		send_data_MS5541_loop		; NO  - loop
+	bcf		MS5541_clk					; YES - revoke clock
+	return								;     - done
 
-	END
\ No newline at end of file
+;-----------------------------------------------------------------------------
+
+	END
--- a/src/option_table.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/option_table.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File option_table.asm                     combined next generation V3.08.8
+;   File option_table.asm                   * combined next generation V3.09.4j
 ;
 ;   The Option Table
 ;
@@ -10,13 +10,12 @@
 ;   2014-08-03 : mH creation
 ;
 
-#include "hwos.inc"                    ; Mandatory Header
-#include "eeprom_rs232.inc"
+#include "hwos.inc"
+
 
 ;=============================================================================
-; Options Tables
-
-option_table	CODE 0x00700	; keep in lower page!
+option_table CODE 0x08000  ; ! DO NOT CHANGE - Option Table must fit 0x08xxx !
+;=============================================================================
 
 
 OPTION_UINT8	MACRO lbl, min, max, default, unit, eeprom, serial, register
@@ -73,7 +72,7 @@
 		extern	tValue
 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
+		db	max-1, default				; value  : max, default
 		dw	.0, register, eeprom		; pointer: (no unit), variable, EEPROM
 		ENDM
 
@@ -82,14 +81,14 @@
 		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
+		db	.2-1, default				; value  : max, default
 		dw	.0, register, eeprom		; pointer: (no unit), variable, EEPROM
 		ENDM
 
 OPTION_STRING	MACRO lbl, stringlength, defText, eeprom, serial, register
 		global	lbl
 lbl:	db	.2, serial					; type   : 2 = STRING
-		db	LOW(defText), HIGH(defText)	; value  : pointer to string
+		db	LOW(defText), HIGH(defText)	; value  : pointer to default text
 		db	stringlength, .0			; value  : length, (no default)
 		dw	.0, register, eeprom		; pointer: (no unit), variable, EEPROM
 		ENDM
@@ -116,6 +115,10 @@
 	extern	char_I_gas_density_att, char_I_gas_density_warn
 	extern	char_I_dil_check
 
+ IFDEF _comm_debug
+	extern	tCommTimeoutU
+ ENDIF
+
 #DEFINE nounit		0x0000	; no unit text associated
 #DEFINE volatile	0xFFFF	; not stored in EEPROM
 #DEFINE nocomm		0x00	; not accessible via RS232
@@ -170,54 +173,101 @@
 	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_ENUM8    oDil1,           num_dil_types,                                .1,      tGasDisabled,    0x05D,  nocomm,  opt_dil_type+0				; diluent type: 0=Disabled, 1=First, 2=Normal
+	OPTION_ENUM8    oDil2,           num_dil_types,                                .0,      tGasDisabled,    0x05E,  nocomm,  opt_dil_type+1
+	OPTION_ENUM8    oDil3,           num_dil_types,                                .0,      tGasDisabled,    0x05F,  nocomm,  opt_dil_type+2
+	OPTION_ENUM8    oDil4,           num_dil_types,                                .0,      tGasDisabled,    0x060,  nocomm,  opt_dil_type+3
+	OPTION_ENUM8    oDil5,           num_dil_types,                                .0,      tGasDisabled,    0x061,  nocomm,  opt_dil_type+4
+
+	OPTION_UINT8    oGas1O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x03A,  0xFA,    opt_gas_O2_ratio+0			; O2 % of gas 1
+	OPTION_UINT8    oGas2O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x03C,  0xFA,    opt_gas_O2_ratio+1
+	OPTION_UINT8    oGas3O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x03E,  0xFA,    opt_gas_O2_ratio+2
+	OPTION_UINT8    oGas4O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x040,  0xFA,    opt_gas_O2_ratio+3
+	OPTION_UINT8    oGas5O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x042,  0xFA,    opt_gas_O2_ratio+4			; O2 % of gas 5
+	OPTION_UINT8    oDil1O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x049,  0xFA,    opt_dil_O2_ratio+0			; O2 % of diluent 1
+	OPTION_UINT8    oDil2O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x04B,  0xFA,    opt_dil_O2_ratio+1
+	OPTION_UINT8    oDil3O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x04D,  0xFA,    opt_dil_O2_ratio+2
+	OPTION_UINT8    oDil4O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x04F,  0xFA,    opt_dil_O2_ratio+3
+	OPTION_UINT8    oDil5O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,        0x051,  0xFA,    opt_dil_O2_ratio+4			; O2 % of diluent 5
+	OPTION_UINT8    oGas1He,             .0,            gaslist_max_He,            .0,      tPercent,        0x03B,  0xFB,    opt_gas_He_ratio+0			; He % of gas 1
+	OPTION_UINT8    oGas2He,             .0,            gaslist_max_He,            .0,      tPercent,        0x03D,  0xFB,    opt_gas_He_ratio+1
+	OPTION_UINT8    oGas3He,             .0,            gaslist_max_He,            .0,      tPercent,        0x03F,  0xFB,    opt_gas_He_ratio+2
+	OPTION_UINT8    oGas4He,             .0,            gaslist_max_He,            .0,      tPercent,        0x041,  0xFB,    opt_gas_He_ratio+3
+	OPTION_UINT8    oGas5He,             .0,            gaslist_max_He,            .0,      tPercent,        0x043,  0xFB,    opt_gas_He_ratio+4			; He % of gas 5
+	OPTION_UINT8    oDil1He,             .0,            gaslist_max_He,            .0,      tPercent,        0x04A,  0xFB,    opt_dil_He_ratio+0			; He % of diluent 1
+	OPTION_UINT8    oDil2He,             .0,            gaslist_max_He,            .0,      tPercent,        0x04C,  0xFB,    opt_dil_He_ratio+1
+	OPTION_UINT8    oDil3He,             .0,            gaslist_max_He,            .0,      tPercent,        0x04E,  0xFB,    opt_dil_He_ratio+2
+	OPTION_UINT8    oDil4He,             .0,            gaslist_max_He,            .0,      tPercent,        0x050,  0xFB,    opt_dil_He_ratio+3
+	OPTION_UINT8    oDil5He,             .0,            gaslist_max_He,            .0,      tPercent,        0x052,  0xFB,    opt_dil_He_ratio+4			; He % of diluent 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
 
+	OPTION_UINT8    oTankSizeOC1,    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    oTankSizeOC2,    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    oTankSizeOC3,    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    oTankSizeOC4,    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    oTankSizeOC5,    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    oTankSizeDil1,   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    oTankSizeDil2,   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    oTankSizeDil3,   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    oTankSizeDil4,   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    oTankSizeDil5,   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    oTankPresOC1,    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    oTankPresOC2,    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    oTankPresOC3,    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    oTankPresOC4,    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    oTankPresOC5,    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    oTankPresDil1,   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    oTankPresDil2,   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    oTankPresDil3,   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    oTankPresDil4,   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    oTankPresDil5,   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_UINT8p10 oSP1ppO2,        gaslist_sp_min,    gaslist_sp_max,           .70,      tbar,            0x053,  nocomm,  opt_setpoint_cbar+0			; ppO2 of setpoint 1
+	OPTION_UINT8p10 oSP2ppO2,        gaslist_sp_min,    gaslist_sp_max,           .90,      tbar,            0x054,  nocomm,  opt_setpoint_cbar+1			; ppO2 of setpoint 2
+	OPTION_UINT8p10 oSP3ppO2,        gaslist_sp_min,    gaslist_sp_max,          .100,      tbar,            0x055,  nocomm,  opt_setpoint_cbar+2			; ...
+	OPTION_UINT8p10 oSP4ppO2,        gaslist_sp_min,    gaslist_sp_max,          .120,      tbar,            0x056,  nocomm,  opt_setpoint_cbar+3			; ...
+	OPTION_UINT8p10 oSP5ppO2,        gaslist_sp_min,    gaslist_sp_max,          .140,      tbar,            0x057,  nocomm,  opt_setpoint_cbar+4			; ppO2 of setpoint 5
+
+	OPTION_UINT8d   oSP1Depth,           .0,                   .0,                 .0,      tMeters,         0x058,  nocomm,  opt_setpoint_change+0			; change depth of setpoint 1 (forced to 0 in code)
+	OPTION_UINT8d   oSP2Depth,           .0,            gaslist_sp_max_depth,      .0,      tMeters,         0x059,  nocomm,  opt_setpoint_change+1			; change depth of setpoint 2
+	OPTION_UINT8d   oSP3Depth,           .0,            gaslist_sp_max_depth,      .0,      tMeters,         0x05A,  nocomm,  opt_setpoint_change+2			; ...
+	OPTION_UINT8d   oSP4Depth,           .0,            gaslist_sp_max_depth,      .0,      tMeters,         0x05B,  nocomm,  opt_setpoint_change+3			; ...
+	OPTION_UINT8d   oSP5Depth,           .0,            gaslist_sp_max_depth,      .0,      tMeters,         0x05C,  nocomm,  opt_setpoint_change+4			; change depth of setpoint 5
+
+	OPTION_UINT8    oXmittID01L,         .0,                 .255,                 .0,      nounit,          0x0D2,    0x60,  opt_transmitter_id_1+0		; ID of transmitter for gas 1 (LOW)
+	OPTION_UINT8    oXmittID01H,         .0,                 .255,                 .0,      nounit,          0x0D3,    0x61,  opt_transmitter_id_1+1		; ID of transmitter for gas 1 (HIGH)
+	OPTION_UINT8    oXmittID02L,         .0,                 .255,                 .0,      nounit,          0x0D4,    0x62,  opt_transmitter_id_2+0		; ID of transmitter for gas 2 (LOW)
+	OPTION_UINT8    oXmittID02H,         .0,                 .255,                 .0,      nounit,          0x0D5,    0x63,  opt_transmitter_id_2+1		; ID of transmitter for gas 2 (HIGH)
+	OPTION_UINT8    oXmittID03L,         .0,                 .255,                 .0,      nounit,          0x0D6,    0x64,  opt_transmitter_id_3+0		; ID of transmitter for gas 3 (LOW)
+	OPTION_UINT8    oXmittID03H,         .0,                 .255,                 .0,      nounit,          0x0D7,    0x65,  opt_transmitter_id_3+1		; ID of transmitter for gas 3 (HIGH)
+	OPTION_UINT8    oXmittID04L,         .0,                 .255,                 .0,      nounit,          0x0D8,    0x66,  opt_transmitter_id_4+0		; ID of transmitter for gas 4 (LOW)
+	OPTION_UINT8    oXmittID04H,         .0,                 .255,                 .0,      nounit,          0x0D9,    0x67,  opt_transmitter_id_4+1		; ID of transmitter for gas 4 (HIGH)
+	OPTION_UINT8    oXmittID05L,         .0,                 .255,                 .0,      nounit,          0x0DA,    0x68,  opt_transmitter_id_5+0		; ID of transmitter for gas 5 (LOW)
+	OPTION_UINT8    oXmittID05H,         .0,                 .255,                 .0,      nounit,          0x0DB,    0x69,  opt_transmitter_id_5+1		; ID of transmitter for gas 5 (HIGH)
+	OPTION_UINT8    oXmittID06L,         .0,                 .255,                 .0,      nounit,          0x0DC,    0x6A,  opt_transmitter_id_6+0		; ID of transmitter for dil 1 (LOW)
+	OPTION_UINT8    oXmittID06H,         .0,                 .255,                 .0,      nounit,          0x0DD,    0x6B,  opt_transmitter_id_6+1		; ID of transmitter for dil 1 (HIGH)
+	OPTION_UINT8    oXmittID07L,         .0,                 .255,                 .0,      nounit,          0x0DE,    0x6C,  opt_transmitter_id_7+0		; ID of transmitter for dil 2 (LOW)
+	OPTION_UINT8    oXmittID07H,         .0,                 .255,                 .0,      nounit,          0x0DF,    0x6D,  opt_transmitter_id_7+1		; ID of transmitter for dil 2 (HIGH)
+	OPTION_UINT8    oXmittID08L,         .0,                 .255,                 .0,      nounit,          0x0E0,    0x6E,  opt_transmitter_id_8+0		; ID of transmitter for dil 3 (LOW)
+	OPTION_UINT8    oXmittID08H,         .0,                 .255,                 .0,      nounit,          0x0E1,    0x6F,  opt_transmitter_id_8+1		; ID of transmitter for dil 3 (HIGH)
+	OPTION_UINT8    oXmittID09L,         .0,                 .255,                 .0,      nounit,          0x0E2,    0x70,  opt_transmitter_id_9+0		; ID of transmitter for dil 4 (LOW)
+	OPTION_UINT8    oXmittID09H,         .0,                 .255,                 .0,      nounit,          0x0E3,    0x71,  opt_transmitter_id_9+1		; ID of transmitter for dil 4 (HIGH)
+	OPTION_UINT8    oXmittID10L,         .0,                 .255,                 .0,      nounit,          0x0E4,    0x72,  opt_transmitter_id_10+0		; ID of transmitter for dil 5 (LOW)
+	OPTION_UINT8    oXmittID10H,         .0,                 .255,                 .0,      nounit,          0x0E5,    0x73,  opt_transmitter_id_10+1		; ID of transmitter for dil 5 (HIGH)
+
 	; opt_name from 85 to 145
-	OPTION_STRING    oName,          opt_name_length,                                       tDefName,        0x067,  nocomm,  opt_name						; custom text on surface screen
+	OPTION_STRING   oName,           opt_name_length,                                       tDefName,        0x067,  nocomm,  opt_name						; custom text on surface screen
 
 	; Misc
 	OPTION_ENUM8    oColorSetDive,       .4,                                       .0,      tColorSetName0,  0x0A4,    0x31,  opt_dive_color_scheme			; color scheme dive mode
@@ -228,7 +278,7 @@
 	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    oWork_SAC,           .5,                  .80,                .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
@@ -245,16 +295,6 @@
 	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
@@ -264,36 +304,6 @@
 	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
@@ -317,14 +327,14 @@
 	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
+	OPTION_BOOL     oGasDensityCheck,                                              .1,                       0x107,    0x92,  opt_gas_density_check			; gas density is checked (effective in CCR / pSCR modes only)
 
 	;	+---------------------------------------------------------------------------------------------------------------------------------------------+
 	;   |  .                                                                                                                                          |
 	;	| /|\                                                                                                                                         |
 	;	|  |  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) |
+	;	|  |  EEPROM address  min: 0x012, max: 0x1FF, last used: 0x107, spare: 0x0B7-0x0B9, 0x0F5-0x0F6, disused: 0x0A8, 0x0CE                        |
+	;	|  |  serial address  min:  0x20, max:  0xF9, last used:  0x92, spare: 0x83, 0x84 (0xFA - 0xFE are reserved for internal use)                 |
 	;	+---------------------------------------------------------------------------------------------------------------------------------------------+
 
 	; ppO2 warnings, sorted by ppO2 levels
@@ -335,24 +345,38 @@
 
 
 	; 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				; ...
+	OPTION_UINT8    oGas6O2,         gaslist_min_o2,    gaslist_max_o2,           .21,      tPercent,     volatile,    0xFA,  opt_gas6_O2_ratio				; O2 % of gas 6
+	OPTION_UINT8    oGas6He,             .0,            gaslist_max_He,            .0,      tPercent,     volatile,    0xFB,  opt_gas6_He_ratio				; He % of gas 6
+	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				; ...
+
+	OPTION_UINT8    oFallback,           .0,                 .255,                 .0,      nounit,       volatile,    0x38,  opt_fallback					; unused dummy option for compatibility with 3rd party tools
+	OPTION_UINT8    oConservatism,       .0,                 .255,                 .0,      nounit,       volatile,    0x47,  opt_conservatism				; unused dummy option for compatibility with 3rd party tools
+
 
  IFDEF _gas_contingency
 	OPTION_BOOL     oGasContingencySim,                                            .0,                   volatile,   nocomm,  opt_gas_contingency_sim		; =1: deco calculator: switch to alternative gas if best gas is depleted
  ENDIF
 
+ IFDEF _comm_debug
+	OPTION_UINT8p5  oCommTimeout,       .10,                 .200,     rx_timeout/.10,     tCommTimeoutU, volatile, nocomm,  opt_comm_timeout				; comm RX timeout in multiples of 10 ms
+ ENDIF
+
+;-----------------------------------------------------------------------------
+
 	global	option_table_end
 option_table_end:
 	OPTION_END		; end of option table - important: DO NOT OMIT THIS MACRO!
 
+;-----------------------------------------------------------------------------
+
 	END
--- a/src/options.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/options.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File options.asm                          next combined generation V3.08.8
+;   File options.asm                        * next combined generation V3.09.4n
 ;
 ;   Manage all options data.
 ;
@@ -25,10 +25,64 @@
 	extern	option_table_begin,option_table_end
 	extern	convert_meter_to_feet
 
-options		CODE
 
 ;=============================================================================
-; Reset all options to factory defaults (in memory only)
+options1	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Adjust Address in FSR0 to an Option within an Option Group
+;
+; INPUT:  FSR0        = base address of the option group
+;         gaslist_gas = offset of the selected option within the group
+; OUTPUT: FSR0        = pointing to selected option
+;
+	global	option_adjust_group_member
+option_adjust_group_member:
+	movf	gaslist_gas,W					; get       offset in number of options
+	mullw	opt_definition_bytes			; calculate offset in number of bytes
+	movf	PRODL,W							; get number of bytes, low  byte
+	addwf	FSR0L,F							; add to FSR0,         low  byte
+	movf	PRODH,W							; get number of bytes, high byte
+	addwfc	FSR0H,F							; add to FSR0,         high byte
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Read the Option Definition
+;
+; INPUT:  FSR0 = option handle
+; OUTPUT: FSR1 = address of variable.
+; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
+;
+option_read_definition:
+	; option_table_begin is at 0x0|80|00
+	clrf	TBLPTRU							; TBLPRT upper = 0x00
+	movlw	HIGH(option_table_begin)		; TBLPRT high  = 0x80
+	iorwf	FSR0H,W							;              + 0x0H from FSR0H
+	movwf	TBLPTRH							;            set 0x8H
+	movff	FSR0L,TBLPTRL					; TBLPRT low   = 0xLL from FSR0L
+	; copy option definition from program to data memory
+	lfsr	FSR1,opt_type					; load FSR1 with base address of option definition buffer
+	movlw	opt_definition_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
+
+
+;-----------------------------------------------------------------------------
+; Reset all Options to Factory Defaults
 ;
 ; INPUT:  none
 ; OUTPUT: none
@@ -58,87 +112,74 @@
 	return									; YES - done
 
 
-;=============================================================================
-; Reset an option to its default value
+;-----------------------------------------------------------------------------
+; Reset an Option to its default Value
+;
 ; INPUT:  FSR0 = option handle
-; OUTPUT: none
+; OUTPUT: option value set to default value
+;         option_repaired flag set
+;         option_changed flag set if not a volatile option
 ; TRASH:  TBLPTR, TABLAT, WREG, FSR1, FSR2
 ;
 	global	option_reset					; reset option value to default
 option_reset:
 	; read type, default and register from table
 	rcall	option_read_definition			; read option definition
+	btfss	opt_eeprom_bank,7				; volatile option?
+	bsf		option_changed					; NO  - flag that EEPROM needs to be updated
+	;bra	option_init_loaded				; continue initializing the option value
 
-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
+
+;-----------------------------------------------------------------------------
+; Reset an Option to its default Value
+;
+; INPUT:  opt_* option definition vars initialized
+; OUTPUT: option value set to default value
+; TRASH:  TBLPTR, TABLAT, WREG, FSR1, FSR2
+;
+option_init_loaded:
 	movf	opt_type,W						; get option type
 	xorlw	.2								; type = STRING ?
-	bz		opt_reset_string				; YES - string copy
+	bz		opt_init_loaded_string			; YES - string copy
 	movff	opt_default,INDF1				; NO  - 1 byte copy
 	return									;     - done
 
-opt_reset_string:
+opt_init_loaded_string:
+	movff	TBLPTRL,mpr+0					; back-up TBLPTR
+	movff	TBLPTRH,mpr+1					; ...
+	movff	TBLPTRU,mpr+2					; ...
+
 	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,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_inc,FSR1L					; get pointer to multi-lingual default text (stored in opt_inc:opt_min)
+	movff	opt_min,FSR1H					; ...
+	call	strcat_text_FSR					; copy translated text to FSR2, hence string option
+
 	movff	mpr+0,TBLPTRL					; restore TBLPTR
 	movff	mpr+1,TBLPTRH					; ...
 	movff	mpr+2,TBLPTRU					; ...
+
 	return									; done
 
 
-;=============================================================================
-; Read option definition
-; INPUT:  FSR0 = option handle
-; OUTPUT: FSR1 = address of variable.
-; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
+;-----------------------------------------------------------------------------
+; Check one Option and reset its Value if it is out of its min/max Limits
 ;
-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
-
-
-;=============================================================================
-; 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
+; INPUT:  opt_* vars loaded, FSR1 pointing to option value
+;         hi    value to be checked for validity
+; OUTPUT: option_value_ok set/not set
 ; TRASH:  WREG
 ;
+	global	option_check_loaded
 option_check_loaded:
 	; switch on type
+	bsf		option_value_ok					; set result to ok by default
 	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
+	return									; type 2: STRING - nothing to check
 	;bra	option_check_uint8				; type 3: INT8
 
 option_check_uint8:
@@ -148,104 +189,117 @@
 
 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
+	cpfsgt	hi								; option value > (minimum permissible value - 1) ?
+	bra		option_check_nok				; NO  - value not ok
 	;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
+	return									; highest permissible value is 255, skip check, done
+	cpfslt	hi								; option value < (highest permissible value + 1) ?
+	bra		option_check_nok				; NO  - value not ok
+	return									; YES - value ok, done
 
-option_check_string:
-	return									; nothing to check with strings
+option_check_nok:
+	bcf		option_value_ok					; flag option value is invalid
+	return									; done
 
 
-;=============================================================================
-; Check and store all option values in EEPROM
+;-----------------------------------------------------------------------------
+; Check and store all Option Values to EEPROM
 ;
 	global	option_check_and_store_all
 option_check_and_store_all:
-	bcf		PIR3,RC2IE						; disable EUSART interrupts
+	bcf		PIR3,RC2IE						; disable EUSART interrupts								TODO: why???
+	call	option_crosschecks				; do some crosschecks between option values
+	;bra	option_store_all				; continue storing all option values to EEPROM
+
 
-	;---- save option version
+;-----------------------------------------------------------------------------
+; Store all Option Values to EEPROM
+;
+option_store_all:
+	;---- invalidate option version while updating
+	CLRI	mpr									; set options version number to zero
+	EEPROM_II_WRITE mpr,eeprom_options_version	; store options version number in EEPROM
+
+	;---- check and store 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 store 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
+
+	;---- store 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
-
-	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
+	bcf		option_changed					; no pending EEPROM updates any more
+	return									; done
 
 
-;=============================================================================
-; Check and store an option value in EEPROM
+;-----------------------------------------------------------------------------
+; Check and store one Option Value to 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
+	movff	INDF1,hi						; check current option value
+	rcall	option_check_loaded				; check value for validity
+	btfss	option_value_ok					; value ok (strings are always 'valid') ?
+	movff	opt_default,INDF1				; NO  - set value to default
+	;bra	option_store_loaded				; continue storing value
 
-option_save_loaded_checked:
+
+;-----------------------------------------------------------------------------
+; Store one Option Value to EEPROM
+;
+	global	option_store_loaded
+option_store_loaded:
 	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
+	return									; NO  - volatile option or illegal address, done/abort
 	tstfsz	opt_eeprom_bank					; YES - bank = 0 ?
-	bra		option_save_execute				;       NO  - address is valid
+	bra		option_store_execute			;       NO  - address is valid in any case
 	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
+	return									;             NO  - illegal address, done
+	;bra	option_store_execute			;             YES - address is valid
 
-option_save_execute:
+option_store_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 = 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
+	bz		option_store_exec_string		; YES - store string of bytes
+	;bnz	option_store_exec_byte			; NO  - store single    byte
 
-option_save_string:
-	movff	POSTINC1,EEDATA					; copy a character from the option value to the EEPROM write register
+option_store_exec_byte:
+	call	read_eeprom						; read stored value
+	movf	EEDATA,W						; copy stored value to WREG
+	xorwf	INDF1,W							; xor with current value
+	btfsc	STATUS,Z						; equal?
+	return									; YES - no need to write to EEPROM, done
+	movff	INDF1,EEDATA					; NO  - copy current option value to EEPROM write register
+	goto	write_eeprom					;     - execute write and return
+
+option_store_exec_string:
 	btfss	EEADRH,1						; current EEPROM address < 512 ?
-	call	write_eeprom					; YES  - execute write
+	rcall	option_store_exec_byte			; YES - store one byte from the string
+	movf	POSTINC1,W						; increment FSR1   address by a dummy read
 	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
+	bra		option_store_exec_string		; NO  - loop
 	return									; YES - done
 
 
-;=============================================================================
-; Restore and check all option values from EEPROM
+;-----------------------------------------------------------------------------
+; Restore all Option Values from EEPROM and check them
 ;
-	global	option_restore_and_check_all	; restore options from EEPROM
+	global	option_restore_and_check_all
 option_restore_and_check_all:
 	;---- Read option version from EEPROM
 	EEPROM_II_READ	eeprom_options_version,mpr
@@ -264,15 +318,20 @@
 	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
+
+	bcf		option_changed					; clear flag
+	call	option_crosschecks				; do some crosschecks between option values
+	btfsc	option_changed					; found and corrected errors?
+	bra		option_store_all				; YES - write back corrected data to EEPROM
+	return									; NO  - 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
+;-----------------------------------------------------------------------------
+; Restore one Option Value from EEPROM and check it
 ;
 	global	option_restore_and_check
 option_restore_and_check:
@@ -281,12 +340,12 @@
 	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
+	bra		option_init_loaded				; NO  - volatile option or illegal address, initialize to default
 	tstfsz	opt_eeprom_bank					; YES - bank = 0 ?
-	bra		option_restore_execute			;       NO  - address is valid
+	bra		option_restore_execute			;       NO  - address is valid in any case
 	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_init_loaded				;             NO  - illegal address, initialize to default
 	;bra	option_restore_execute			;             YES - address is valid
 
 option_restore_execute:
@@ -295,28 +354,31 @@
 
 	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
+	bz		option_restore_exec_string		; YES - special handling
+	call	read_eeprom						; NO  - execute   EEPROM read
+	movff	EEDATA,INDF1					;     - copy from EEPROM read register to option variable
+	movff	EEDATA,hi						;     - check loaded option value
+	rcall	option_check_loaded				;     - check if option value is within min/max limits
+	btfsc	option_value_ok					;     - option value ok (strings will always be 'ok') ?
+	return									;       YES  - done
+	movff	opt_default,INDF1				;       NO   - set option value to default
+	movff	INDF1,EEDATA					;            - copy repaired value to EEPROM write register
+	goto	write_eeprom					;            - execute write and return
 
-option_restore_string:
+option_restore_exec_string:
 	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
+	bra		option_restore_exec_string		; NO  - loop
 	return									; YES - done (nothing to check with strings)
 
 
 
-;=============================================================================
-; Read an option value via RS232
+;-----------------------------------------------------------------------------
+; Read an Option Value via serial Index
+;
 ; INPUT:  lo   = serial index
 ; OUTPUT: hi   = option value
 ;         WREG =0: option found and value valid, =1: option not found
@@ -332,15 +394,16 @@
 	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
+	retlw	.1								;       YES - option not found, abort
 
 option_read_serial_execute:
 	movff	INDF1,hi						; read option value into hi
-	retlw	.0								; done, option found
+	retlw	.0								; done
 
 
-;=============================================================================
-; Write an option value via RS232
+;-----------------------------------------------------------------------------
+; Write an Option Value via serial Index
+;
 ; INPUT:  lo   = serial index
 ;         hi   = option value
 ; OUTPUT: WREG =0: option found and value valid, =1: option not found, =2: value not valid
@@ -356,52 +419,59 @@
 	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
+	retlw	.1								;       YES - option not found, abort
 
 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
+	rcall	option_check_loaded				; check if new value is valid
+	btfss	option_value_ok					; value valid?
+	retlw	.2								; NO  - value not valid, abort
+	movff	hi,INDF1						; YES - take new value
+	btfss	opt_eeprom_bank,7				;     - volatile option?
+	bsf		option_changed					;       NO  - flag that EEPROM needs to be updated
+	retlw	.0								;     - done
 
 
-;=============================================================================
-; Increment an option value based on type and min/max boundary
+;-----------------------------------------------------------------------------
+; Increment an Option Value based on Type and min/max Boundary
+;
 ; INPUT:  FSR0 = option handle
-; OUTPUT: none
+; OUTPUT: incremented option value
 ; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
 ;
-	global	option_inc						; increment FSR0 option
+	global	option_inc
 option_inc:
 	; read type, default and register from table
 	rcall	option_read_definition
 
-	bsf		options_changed					; flag that EEPROM needs to be updated
+	btfss	opt_eeprom_bank,7				; volatile option?
+	bsf		option_changed					; NO  - flag that EEPROM needs to be updated
 
 	; switch on type
 	movf	opt_type,W						; get option type
-	bz		option_inc_uint8				; type 0: INT8
+	bz		option_inc_uint8				; type 0: UINT8
 	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
+	return									; type 2: STRING - no inc function defined
+	dcfsnz	WREG							; decrement
+	bra		option_inc_uint8				; type 3: UINT8 as meters or feet
+	return									; unknown, do nothing
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - increment UINT8, wrap-around or stop at option max
+;
 option_inc_uint8:
 	movf	INDF1,W							; get option value
 	addwf	opt_inc,W						; add increment
-	cpfslt	opt_max							; max < option value ?
+	cpfslt	opt_max							; option value > max ?
 	bra		option_inc_uint8_0				; NO  - new option value ok
-	movf	opt_min,W						; YES - reset to min value
+	movf	opt_min,W						; YES - reset to min value by default
+	btfsc	option_stop_at_max				;     - shall the option value stop at max?
+	movf	opt_max,W						;       YES - keep at max value
 option_inc_uint8_0:
 	movwf	INDF1							; store new value
+	; do cross-checks with other option values
 option_inc_uint8_1:
 	; now some rather crude hack into this routine to make CCR calibration more convenient:
 	movlw	0x37							; serial ID of option CalGasO2
@@ -416,7 +486,9 @@
 	movlw	.95								;             YES - advance it to 95
 	movwf	INDF1							;                 - store it
 	return
+
 option_inc_uint8_2:
+	; check GF low <= GF high
 	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
@@ -425,7 +497,9 @@
 	return									; NO  - setting ok, done
 	movff	opt_min,INDF1					; YES - wrap around to minimum value
 	return									;     - done
+
 option_inc_uint8_3:
+	; check GF high >= GF low
 	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
@@ -434,7 +508,9 @@
 	return									; NO  - setting ok, done
 	movwf	INDF1							; YES - rise GF high to GF low
 	return									;     - done
+
 option_inc_uint8_4:
+	; check aGF low <= aGF high
 	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
@@ -443,7 +519,9 @@
 	return									; NO  - setting ok, done
 	movff	opt_min,INDF1					; YES - wrap around to minimum value
 	return									;     - done
+
 option_inc_uint8_5:
+	; check aGF high >= aGF low
 	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
@@ -452,19 +530,60 @@
 	return									; NO  - setting ok, done
 	movwf	INDF1							; YES - rise GF high to GF low
 	return									;     - done
+
 option_inc_uint8_6:
+	; progressive increment for char_I_SAC_work
+	movlw	0x3C							; serial ID of option char_I_SAC_work
+	cpfseq	opt_serial						; editing char_I_SAC_work right now?
+	bra		option_inc_uint8_7				; NO  - check next option
+	movlw	.40								; YES - set threshold for incrementing in steps of 2
+	cpfsgt	INDF1							;     - option value > threshold ?
+	return									;       NO  - done
+	incf	INDF1,F							;       YES - increment one more time
+	return									;           - done
+
+option_inc_uint8_7:
+ IFDEF _helium
+	; check O2% + He% <= 100%
+	movlw	0xFA							; serial ID of O2% options
+	cpfseq	opt_serial						; editing a O2% right now?
+	bra		option_inc_uint8_7a				; NO  - check for He%
+	movlw	.2*NUM_GAS						; YES - load offset between O2% and He% for gas/dil 1-5
+	btfsc	opt_eeprom_bank,7				;     - volatile option?
+	movlw	.1								;       YES - load offset between O2% and He% for gas 6
+	bra		option_inc_uint8_7b				;       continue with common part
+option_inc_uint8_7a:
+	movlw	0xFB							; serial ID of He% options
+	cpfseq	opt_serial						; editing a He% right now?
+	bra		option_inc_uint8_8				; NO  - check next option
+	movlw	-.2*NUM_GAS						; YES - load offset between He% and O2% for gas/dil 1-5
+	btfsc	opt_eeprom_bank,7				;     - volatile option?
+	movlw	-.1								;       YES - load offset between He% and O2% for gas 6
+option_inc_uint8_7b:
+	movff	PLUSW1,hi						;     - copy complementing gas % to hi
+	movf	INDF1,W							;     - copy primary       gas % to WREG
+	addwf	hi,F							;     - hi = O2% + He%
+	movlw	.101							;     - load max allowed sum + 1
+	cpfslt	hi								;     - O2% + He% < 101 ?
+	decf	INDF1,F							;       NO - decrement primary gas% again
+ ENDIF	; _helium
+
+option_inc_uint8_8
+	; add more cross-checks with other option values here
 	return									; all done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - increment ENUM, will wrap-around on exceeding option max
+;
 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
-
+	incf	INDF1,W							; get incremented option value
+	cpfslt	opt_max							; option value > max?
+	bra		option_inc_enum8_0				; NO  - new option value ok
+	clrf	WREG							; YES - reset to 1st option value
+option_inc_enum8_0:
+	movwf	INDF1							; store new value
+	; do cross-checks with other option values
 option_inc_enum8_1:
  IFDEF _ccr_pscr
 	; now some rather crude hack into this routine to unify CCR & pSCR mode setting
@@ -472,9 +591,9 @@
 	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?
+	btfsc	ext_input_s8_ana				; YES - S8/analog input available?
 	bra		option_inc_enum8_1a				;       YES - setting 'sensor' allowed
-	btfsc	optical_input					;       does hosting OSTC have an optical interface?
+	btfsc	ext_input_optical				;     - optical interface available?
 	bra		option_inc_enum8_1a				;       YES - setting 'sensor' allowed
  ENDIF	; _external_sensor
 	movf	INDF1,W							;       NO to both - get mode (=0: fixed SP, =1: Sensor, =2: AutoSP)
@@ -497,7 +616,7 @@
 	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 ?
+	;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	;           - ...
@@ -590,57 +709,208 @@
  ENDIF	; _gas_contingency
 
 option_inc_enum8_6:
-	return
-
-
-option_inc_string:							; no editing available
+	; add more cross-checks with other option values here
 	return
 
 
+;-----------------------------------------------------------------------------
+; Decrement an Option Value based on Type and min/max Boundary
+;
+; INPUT:  FSR0 = option handle
+; OUTPUT: decremented option value
+; TRASH:  TBLPTR, TABLAT, WREG, FSR0, FSR1
+;
+	global	option_dec
+option_dec:
+	; read type, default and register from table
+	rcall	option_read_definition
+
+	btfss	opt_eeprom_bank,7				; volatile option?
+	bsf		option_changed					; NO  - flag that EEPROM needs to be updated
+
+	; switch on type
+	movf	opt_type,W						; get option type
+	bz		option_dec_uint8				; type 0: UINT8
+	dcfsnz	WREG							; decrement
+	bra		option_dec_enum8				; type 1: ENUM
+	dcfsnz	WREG							; decrement
+	return									; type 2: STRING  - no dec function defined
+	dcfsnz	WREG							; decrement
+	bra		option_dec_uint8				; type 3: UINT8 as meters or feet
+	return									; unknown, do nothing
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - decrement UINT8, will stop on reaching option min
+;
+option_dec_uint8:
+	movf	INDF1,W							; get option value
+	bsf		STATUS,C						; set carry (= clear borrow)
+	subfwb	opt_inc,W						; subtract increment
+	bnc		option_dec_uint8_reset			; under-run? -> reset
+	cpfsgt	opt_min							; option value < min ?
+	bra		option_dec_uint8_0				; NO  - new option value ok
+option_dec_uint8_reset:
+	movf	opt_min,W						; YES - reset to min value
+option_dec_uint8_0:
+	movwf	INDF1							; store new value
+	; add cross-checks with other option values here
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - decrement ENUM, will stop on reaching first option value
+;
+option_dec_enum8:
+	tstfsz	INDF1							; option value = 0 ?
+	decf	INDF1,F							; NO - decrement value
+option_dec_enum8_0:
+	; add cross-checks with other option values here
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Draw an Option Value
+;
+	global	option_draw
+option_draw:
+	; read type, default and register from table
+	rcall	option_read_definition
+
+	; switch on type
+	movf	opt_type,W						; get option type
+	bz		option_draw_uint8				; type0 = INT8
+	dcfsnz	WREG
+	bra		option_draw_enum8				; type1 = ENUM
+	dcfsnz	WREG
+	bra		option_draw_string				; type2 = string
+	dcfsnz	WREG
+	bra		option_draw_uint8_depth			; type3 = INT8 as meters or feet
+	return									; unknown, do nothing
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - draw a String
+;
+option_draw_string:
+	movff	POSTINC1,POSTINC2				; copy one character
+	decfsz	opt_max							; decrement remaining string length, became zero?
+	bra		option_draw_string				; NO  - loop
+	return									; YES - done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - draw an INT with automatic display in meters or feet
+;
+option_draw_uint8_depth:
+	TSTOSS	opt_units						; using metric units (0=m, 1=ft)?
+	bra		option_draw_uint8				; YES - handle with standard output
+	movff	INDF1,lo						; NO  - imperial, get value to lo
+	call	convert_meter_to_feet			;     - convert value in lo from meter to feet
+;	bsf		leftbind						;     - print with left alignment
+	output_999								;     - print depth (0-999)
+	STRCAT_TEXT	tFeets						;     - append unit and dump to screen
+	bra		option_draw_uint8_common		;     - continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - draw an INT
+;
+option_draw_uint8:
+	movff	INDF1,lo						; get option value
+
+	movlw	.99								; load a 99
+	cpfsgt	opt_max							; max value > 99 ?
+	bsf		hide_digit3						; NO - do not show digit 3
+	movlw	.9								; load a 9
+	cpfsgt	opt_max							; max value > 9 ?
+	bsf		hide_digit2						; NO  - do not show digit 2
+
+	output_256								; print option value
+
+	movf	opt_unit+0,W					; is there a unit to append?
+	iorwf	opt_unit+1,W					; ...
+	bz		option_draw_uint8_common		; NO  - continue with common part
+	movff	opt_unit+0,FSR1L				; YES - pointer to multi-lingual unit text
+	movff	opt_unit+1,FSR1H				;     - ...
+	call	strcat_text_FSR					;     - append unit text to buffer
+	;bra	option_draw_uint8_common		;     - continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - common Part for INT
+;
+option_draw_uint8_common:
+	movf	opt_default,W					; get default value
+	cpfseq	lo								; compare with current value, equal?
+	bra		option_draw_uint8_common_1		; NO  - not default, add *
+	return									; YES - default, done
+option_draw_uint8_common_1:
+	PUTC	"*"								; print "*"
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - draw an ENUM (set of translated strings)
+;
+option_draw_enum8:
+	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 FSR1
+	movlw	.0								; propagate carry...
+	addwfc	opt_min,W						; ...
+	movwf	FSR1H							; ...into FSR1
+	call	strcat_text_FSR					; print text
+	movf	opt_default,W					; get default value
+	cpfseq	lo								; compare with memorized current value, equal?
+	bra		option_draw_enum8_1				; NO  - not default, add *
+	return									; YES - default, done
+option_draw_enum8_1:
+	PUTC	"*"								; print "*"
+	return									; done
+
+
+;=============================================================================
+options2	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Check and Resolve some Interdependencies among Option Values
+;
+option_crosschecks:
+	bsf		is_diluent_menu					; setup checking diluents
+	call	gaslist_cleanup_list			; check and correct multiple or none First diluents
+
+	bcf		is_diluent_menu					; setup checking gases
+	call	gaslist_cleanup_list			; check and correct multiple or none First gases
+
+	rcall	option_cleanup_GF				; check and correct GFlow <= GFhigh
+
  IFNDEF _gauge_mode
-option_cleanup_gauge:
-	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
-	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
-
+	rcall	option_cleanup_gauge			; check and correct gauge mode
+ ENDIF	; _gauge_mode
 
  IFDEF _ccr_pscr
-	global	option_cleanup_oCCRMode
-	global	option_cleanup_oCCRMode_pSCR
-	global	option_cleanup_oCCRMode_CCR
-option_cleanup_oCCRMode:					; in pSCR mode, revert AutoSP (2) to calculated SP (0), in pSCR and CCR revert Sensor to fixed SP if no sensor interface available
-	movff	opt_dive_mode,WREG				; get dive mode into WREG (0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR)
-	xorlw	.4								; in pSCR mode?
-	bnz		option_cleanup_oCCRMode_CCR		; NO  - check if sensor is available on hosting OSTC
-option_cleanup_oCCRMode_pSCR:				; jump-in from start.asm if known to be in pSCR mode
-	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		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?
-	return									; YES - setting 'sensor' allowed
-	btfsc	optical_input					; does hosting OSTC have an optical interface?
-	return									; YES - setting 'sensor' allowed
- ENDIF
-	movff	opt_ccr_mode,WREG				; NO to both - get CCR mode
-	xorlw	.1								;            - coding for sensor
-	tstfsz	WREG							;            - CCR mode = sensor?
-	return									;              NO  - setting allowed
-	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		options_changed					;                  - flag that EEPROM needs to be updated
-	return									;                  - done
+	rcall	option_cleanup_oCCRMode			; check and correct CCR / pSCR mode
  ENDIF	; _ccr_pscr
 
+ IFDEF _helium
+	rcall	option_cleanup_sum_O2_He		; check and correct O2% + He% <= 100  +++
+ ENDIF	; _helium
 
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Check and correct GFs so that GF_high >= GF_low
+;
 option_cleanup_GF:
 	; cleanup normal GF
 	movff	opt_GF_high,WREG				; copy normal GF high to WREG
@@ -654,7 +924,7 @@
 	movwf	mpr								;       YES - correct GF low to 100%
 option_cleanup_GF_1:
 	movff	mpr,opt_GF_low					; store corrected GF low
-	bsf		options_changed					; flag that EEPROM needs to be updated
+	bsf		option_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
@@ -668,93 +938,86 @@
 	movwf	mpr								;       YES - correct GF low to 100%
 option_cleanup_GF_3:
 	movff	mpr,opt_aGF_low					; store corrected GF low
-	bsf		options_changed					; flag that EEPROM needs to be updated
+	bsf		option_changed					; flag that EEPROM needs to be updated
 option_cleanup_GF_4:
 	return									; done
 
-
-;=============================================================================
-; Strcat option into FSR2 buffer
+;-----------------------------------------------------------------------------
+; Check and correct Dive Mode if Gauge Mode is not allowed
 ;
-	global	option_draw						; STRCAT FRS0 option
-option_draw:
-	; read type, default and register from table
-	rcall	option_read_definition
-
-	; switch on type
-	movf	opt_type,W						; get option type
-	bz		option_draw_uint8				; type0 = INT8
-	dcfsnz	WREG
-	bra		option_draw_enum8				; type1 = ENUM
-	dcfsnz	WREG
-	bra		option_draw_string				; type2 = string
-	dcfsnz	WREG
-	bra		option_draw_uint8_depth			; type3 = INT8 with automatic display in meters or feet
-	return									; unknown, do nothing
-
-option_draw_string:
-	movff	POSTINC1,POSTINC2
-	decfsz	opt_max
-	bra		option_draw_string
-	return
-
-option_draw_uint8_depth:
-	TSTOSS	opt_units						; using metric units (0=m, 1=ft)?
-	bra		option_draw_uint8				; YES - handle with standard output
-	movff	INDF1,lo						; NO  - imperial, get value to lo
-	call	convert_meter_to_feet			;     - convert value in lo from meter to feet
-	bsf		leftbind						;     - print with left alignment
-	output_16_3								;     - display only last three digits from a 16 bit value (0-999)
-	bcf		leftbind						;     - back to normal alignment
-	STRCAT_TEXT	tFeets						;     - print unit
-	bra		option_draw_uint8_common		;     - continue with common part
-
-option_draw_uint8:
-	movff	INDF1,lo						; draw value
-	bsf		leftbind
-	output_8
-	bcf		leftbind
-	clrf	INDF2							; make sure to close string
-	movf	opt_unit+0,W					; is there a unit to append?
-	iorwf	opt_unit+1,W
-	rcall	option_draw_unit				; YES
-option_draw_uint8_common:
-	movf	opt_default,W					; get default value
-	cpfseq	lo								; compare with current value, equal?
-	bra		option_draw_uint8_2				; NO  - not default, add *
-	return									; YES - default, done
-option_draw_uint8_2:
-	PUTC	"*"								; print "*"
+ IFNDEF _gauge_mode
+option_cleanup_gauge:
+	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
+	movff	WREG,opt_dive_mode				; YES - setting not allowed, WREG is zero -> reset to OC mode
+	bsf		option_changed					;     - flag that EEPROM needs to be updated
+option_cleanup_gauge_1:
 	return									; done
-
-option_draw_unit:
-	movff	opt_unit+0,FSR1L
-	movff	opt_unit+1,FSR1H
-	goto	strcat_text
+ ENDIF	; _gauge_mode
 
 
-;---- Draw an enumerated value (set of translated strings)
-option_draw_enum8:
-	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 FSR1
-	movlw	.0								; propagate carry...
-	addwfc	opt_min,W						; ...
-	movwf	FSR1H							; ...into FSR1
-	call	strcat_text						; print text
-	movf	opt_default,W					; get default value
-	cpfseq	lo								; compare with memorized current value, equal?
-	bra		option_draw_enum8_1				; NO  - not default, add *
-	return									; YES - default, done
-option_draw_enum8_1:
-	PUTC	"*"								; print "*"
-	return									; done
+;-----------------------------------------------------------------------------
+; Check and correct AutoSP and external Sensor Settings dependent on Modes
+;
+ IFDEF _ccr_pscr
+	global	option_cleanup_oCCRMode
+	global	option_cleanup_oCCRMode_pSCR
+	global	option_cleanup_oCCRMode_CCR
+option_cleanup_oCCRMode:					; in pSCR mode, revert AutoSP (2) to calculated SP (0), in pSCR and CCR revert Sensor to fixed SP if no sensor interface available
+	movff	opt_dive_mode,WREG				; get dive mode into WREG (0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR)
+	xorlw	.4								; in pSCR mode?
+	bnz		option_cleanup_oCCRMode_CCR		; NO  - check if sensor is available on hosting OSTC
+option_cleanup_oCCRMode_pSCR:				; jump-in from start.asm if known to be in pSCR mode
+	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_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	ext_input_s8_ana				; S8/analog interface available?
+	return									; YES - setting 'sensor' allowed
+	btfsc	ext_input_optical				; does hosting OSTC have an optical interface?
+	return									; YES - setting 'sensor' allowed
+ ENDIF	; _external_sensor
+	movff	opt_ccr_mode,WREG				; NO to both - get CCR mode
+	xorlw	.1								;            - coding for sensor
+	tstfsz	WREG							;            - CCR mode = sensor?
+	return									;              NO  - setting allowed
+	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_changed					;                  - flag that EEPROM needs to be updated
+	return									;                  - done
+ ENDIF	; _ccr_pscr
+
+
+;-----------------------------------------------------------------------------
+; Check and correct that O2% + He% <= 100%
+;
+ IFDEF _helium
+option_cleanup_sum_O2_He:
+	lfsr	FSR0,opt_gas_He_ratio-1		; load (base address of He% array - 1) because of PREINC
+	movlw	2*NUM_GAS					; load loop counter
+	movwf	lo							; ...
+option_cleanup_sum_loop:
+	movff	PREINC1,up					; get He ratio
+	movlw	-2*NUM_GAS					; address O2 ratio
+	movff	PLUSW0,hi					; get O2 ratio
+	movlw	.100						; load WREG with 100%
+	bsf		STATUS,C					; set carry = clear borrow
+	subfwb	hi,W						; subtract O2% from WREG
+	subfwb	up,W						; subtract He% from WREG
+	btfsc	STATUS,C					; result negative?
+	bra		option_cleanup_sum_loop_1	; NO  - sum valid
+	clrf	INDF1						; YES - heal by setting He% to zero
+	bsf		option_changed				; flag that EEPROM needs to be updated
+option_cleanup_sum_loop_1:
+	decfsz	lo							; decrement loop counter, all done?
+	bra		option_cleanup_sum_loop		; NO  - loop
+	return								; YES - done
+ ENDIF	; _helium
+
 
 ;-----------------------------------------------------------------------------
 
--- a/src/p2_deco.c	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/p2_deco.c	Tue Apr 28 17:34:31 2020 +0200
@@ -1,5 +1,5 @@
 // ***************************************************************************
-// p2_deco.c                                  combined next generation V3.08.8
+// p2_deco.c                                  combined next generation V3.09.4
 //
 //  Created on: 12.05.2009
 //  Author: heinrichs weikamp, contributions by Ralph Lembcke and others
@@ -819,8 +819,9 @@
 
 
 // p2deco code moved from 0x0D000 to 0x0C000 in v.108
+//             moved from 0x0C000 to 0x0B000 in v3.09
 #ifndef UNIX
-#	pragma code p2_deco = 0x0C000
+#	pragma code p2_deco = 0x0B000
 #endif
 
 
@@ -1926,7 +1927,7 @@
 		ppHe = 0.0;
 	}
 
-#ifdef _helium
+#ifdef _ccr_pscr
 	// calculating real tissues?
 	if( tissue_increment & TISSUE_SELECTOR )
 	{
@@ -1935,13 +1936,13 @@
 		// compute gas density of current mix in multiples of 0.01 grams per liter
 		int_O_gas_density = (unsigned int)( 17.9 * ppHe + 125.1 * ppN2 + 142.8 * ppO2 );
 
-		// convert gas density into a 8 bit integer
+		// convert gas density into an 8 bit integer, scaling 0.1 grams per liter
 		temp = (unsigned char)( (int_O_gas_density + 9) / 10 );
 
 		// limit to display max and set warning or attention flag
-		     if( temp > 99                      ) int_O_gas_density  = 999 | INT_FLAG_WARNING;
-		else if( temp > char_I_gas_density_warn ) int_O_gas_density |=       INT_FLAG_WARNING;
-		else if( temp > char_I_gas_density_att  ) int_O_gas_density |=       INT_FLAG_ATTENTION;
+		     if( temp >  99                      ) int_O_gas_density  = 999 | INT_FLAG_WARNING;
+		else if( temp >= char_I_gas_density_warn ) int_O_gas_density |=       INT_FLAG_WARNING;
+		else if( temp >= char_I_gas_density_att  ) int_O_gas_density |=       INT_FLAG_ATTENTION;
 	}
 #endif
 }
--- a/src/rtc.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/rtc.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File rtc.asm                              combined next generation V3.08.8
+;   File rtc.asm                            * combined next generation V3.09.4k
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -10,11 +10,17 @@
 
 #include "hwos.inc"
 #include "math.inc"
+#include "convert.inc"
 
-rtc		CODE
 
 ;=============================================================================
+rtc1	CODE
+;=============================================================================
 
+
+;-----------------------------------------------------------------------------
+; Initialize RTC to Firmware creation Date
+;
 	global	rtc_init
 rtc_init:
 	banksel	isr_backup				; select bank ISR data
@@ -32,6 +38,10 @@
 	movwf	rtc_latched_year		; ...
 	;bra	rtc_set_rtc				; set the real time clock
 
+
+;-----------------------------------------------------------------------------
+; Set new Time & Date
+;
 	global	rtc_set_rtc
 rtc_set_rtc:
 	banksel	isr_backup				; select bank ISR data
@@ -105,14 +115,17 @@
 	return							; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - convert from decimal to BCD
+;
 rtc_dec2bcd:
 	banksel	common					; switch to bank common
 	movwf	lo						; input in decimal
 	setf	hi						; 10s
 rtc_dec2bcd2:
 	incf	hi,F					; count 10's
-	movlw	d'10'
-	subwf	lo,F
+	movlw	d'10'					; ...
+	subwf	lo,F					; ...
 	btfss	STATUS,N				; result negative?
 	bra		rtc_dec2bcd2			; NO  - loop
 	movlw	d'10'					; YES - 
@@ -123,8 +136,13 @@
 	return							;     - done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - check Validity of Day according to Month
+;
 ; 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
 	btfsc	rtc_latched_year,0		; is the year an even year?
@@ -165,9 +183,16 @@
 	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
+;=============================================================================
+rtc2	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; 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)!
+; Attention:
+; This code works for a maximum of 1439 minutes to add (23 hours, 59 minutes)!
 ;
 	global	rtc_add_minutes
 rtc_add_minutes:
@@ -198,7 +223,7 @@
 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
+	call	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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rx_firmware-1-40.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -0,0 +1,172 @@
+;=============================================================================
+;
+;   File rx_firmware.inc                      combined next generation V3.09.4f
+;
+;   Firmware for the RX Co-Processor
+;
+;   Copyright (c) 2019, HeinrichsWeikamp, all rights reserved.
+;=============================================================================
+
+
+; version of the RX firmware below
+#define rx_firmware_major	.1
+#define rx_firmware_minor	.40
+
+; http://srecord.sourceforge.net/
+        DB      0xF7,0xEF,0x05,0xF0,0x00,0x00,0x00,0x00,0x03,0xD0,0x00,0x00
+        DB      0x00,0x00,0x00,0x00,0x01,0x01,0xF3,0xCF,0x60,0xF0,0xF4,0xCF
+        DB      0x61,0xF0,0x7E,0xB0,0x87,0xD8,0xF0,0xB2,0xC8,0xD8,0x7B,0xB0
+        DB      0x0E,0xD8,0x01,0x01,0x9E,0xB0,0xBF,0xD8,0x9E,0xB2,0xB0,0xD8
+        DB      0xA1,0xB2,0xB7,0xD8,0xF2,0xB2,0xF2,0x92,0x61,0xC0,0xF4,0xFF
+        DB      0x60,0xC0,0xF3,0xFF,0x11,0x00,0x0F,0x01,0x4F,0x6B,0x50,0x6B
+        DB      0x01,0x01,0x7B,0x90,0x5E,0xCF,0x3D,0xF1,0x5E,0xCF,0x40,0xF1
+        DB      0xD8,0x90,0x40,0x33,0x3F,0x51,0x40,0x27,0x02,0x8D,0xA0,0x0E
+        DB      0x7D,0xB0,0x06,0x51,0x40,0x61,0x02,0x9D,0xD8,0x90,0x3D,0x31
+        DB      0x3F,0x6F,0x02,0xAD,0x82,0x94,0x02,0xBD,0x82,0x84,0x40,0xC1
+        DB      0x73,0xFF,0x0F,0x01,0x51,0xB5,0x12,0x00,0x01,0x01,0x02,0xAD
+        DB      0x06,0xD0,0x41,0x2B,0x40,0x51,0x45,0x27,0x00,0x0E,0x46,0x23
+        DB      0x12,0x00,0x42,0x2B,0x2B,0x0E,0x41,0x61,0x12,0xD0,0x0A,0x0E
+        DB      0x42,0x61,0x03,0xD0,0x05,0x0E,0x41,0x61,0x05,0xD0,0x41,0x6B
+        DB      0x42,0x6B,0x45,0x6B,0x46,0x6B,0x12,0x00,0x42,0x51,0x41,0x27
+        DB      0x2B,0x0E,0x41,0x61,0x02,0xD0,0x42,0x6B,0x12,0x00,0x41,0xC1
+        DB      0x06,0xF1,0x70,0x0E,0x4E,0x6F,0x17,0x0E,0x4F,0x6F,0x45,0xC1
+        DB      0x4C,0xF1,0x46,0xC1,0x4D,0xF1,0x92,0xEC,0x07,0xF0,0x49,0xB1
+        DB      0xE6,0xD7,0x45,0xC1,0x47,0xF1,0x46,0xC1,0x48,0xF1,0x45,0x6B
+        DB      0x46,0x6B,0x0F,0x01,0x53,0x6B,0xAF,0x0E,0x52,0x6F,0x26,0x0E
+        DB      0x51,0x6F,0x01,0x01,0x7E,0x90,0x02,0xEE,0x00,0xF0,0x7D,0x80
+        DB      0x0C,0x6B,0x0F,0x6B,0x08,0x0E,0x0D,0x6F,0x10,0x0E,0x10,0x6F
+        DB      0x05,0x0E,0x11,0x6F,0x41,0x6B,0x42,0x6B,0x47,0xC1,0x19,0xF1
+        DB      0x48,0xC1,0x1A,0xF1,0x06,0xC1,0x1B,0xF1,0x1C,0x6B,0x6B,0xEC
+        DB      0x07,0xF0,0x05,0x0E,0x15,0x27,0x15,0xC1,0x06,0xF1,0x12,0x00
+        DB      0x0F,0x01,0xFB,0x0E,0x52,0x6F,0x05,0x0E,0x51,0x6F,0x01,0x01
+        DB      0x7E,0x90,0x05,0x0E,0x10,0x65,0x06,0xD0,0x0D,0x0E,0x10,0x61
+        DB      0x03,0xD0,0x80,0x7C,0x02,0xBD,0x0F,0x2B,0x10,0x2F,0x12,0x00
+        DB      0x10,0x0E,0x10,0x6F,0x02,0x0E,0xD8,0x80,0x0F,0x65,0xD8,0x90
+        DB      0x0E,0x37,0x0C,0x67,0x07,0xD0,0x0E,0xB1,0x05,0xD0,0x0F,0x01
+        DB      0x51,0x95,0x01,0x01,0x7D,0x90,0x12,0x00,0x0F,0x6B,0x0C,0x2B
+        DB      0x0D,0x2F,0x12,0x00,0x08,0x0E,0x0D,0x6F,0x0E,0xC1,0xEE,0xFF
+        DB      0x11,0x2F,0x12,0x00,0x0F,0x01,0x51,0x95,0x01,0x01,0x7D,0x90
+        DB      0x02,0x85,0x12,0x00,0x9E,0x92,0x01,0x01,0x2B,0x2B,0x3E,0x0E
+        DB      0x2B,0x65,0x12,0x00,0x2B,0x6B,0x02,0x87,0x12,0x00,0x01,0x01
+        DB      0xA0,0x92,0xA1,0x92,0x12,0x00,0x01,0x01,0x9E,0x90,0x9D,0x90
+        DB      0x12,0x00,0x01,0x01,0xF0,0x92,0x12,0x00,0x12,0xEE,0x10,0xF0
+        DB      0x00,0xC3,0xE6,0xFF,0x10,0xC3,0xE6,0xFF,0x20,0xC3,0xE6,0xFF
+        DB      0x30,0xC3,0xE6,0xFF,0x40,0xC3,0xE6,0xFF,0x50,0xC3,0xE6,0xFF
+        DB      0x01,0xC3,0xE6,0xFF,0x11,0xC3,0xE6,0xFF,0x21,0xC3,0xE6,0xFF
+        DB      0x31,0xC3,0xE6,0xFF,0x41,0xC3,0xE6,0xFF,0x51,0xC3,0xE6,0xFF
+        DB      0x02,0xC3,0xE6,0xFF,0x12,0xC3,0xE6,0xFF,0x22,0xC3,0xE6,0xFF
+        DB      0x32,0xC3,0xE6,0xFF,0x42,0xC3,0xE6,0xFF,0x52,0xC3,0xE6,0xFF
+        DB      0x02,0x99,0x12,0x00,0x03,0x01,0x50,0x67,0x50,0x2B,0x51,0x67
+        DB      0x51,0x2B,0x52,0x67,0x52,0x2B,0x53,0x67,0x53,0x2B,0x54,0x67
+        DB      0x54,0x2B,0x55,0x67,0x55,0x2B,0x56,0x67,0x56,0x2B,0x13,0xEE
+        DB      0x00,0xF0,0x00,0x0E,0x0F,0xD8,0x01,0x0E,0x0D,0xD8,0x02,0x0E
+        DB      0x0B,0xD8,0x03,0x0E,0x09,0xD8,0x04,0x0E,0x07,0xD8,0x05,0x0E
+        DB      0x05,0xD8,0x06,0x0E,0x03,0xD8,0x01,0x01,0x02,0x89,0x12,0x00
+        DB      0x60,0x6F,0x50,0x0F,0xE3,0xCF,0x61,0xF3,0xF0,0x0E,0x61,0x63
+        DB      0x12,0x00,0x60,0x51,0xE3,0x6A,0x10,0x0E,0x60,0x25,0xE3,0x6A
+        DB      0x20,0x0E,0x60,0x25,0xE3,0x6A,0x30,0x0E,0x60,0x25,0xE3,0x6A
+        DB      0x40,0x0E,0x60,0x25,0xE3,0x6A,0x50,0x0E,0x60,0x25,0xE3,0x6A
+        DB      0x12,0x00,0x01,0x01,0x00,0xC2,0x2D,0xF1,0x01,0xC2,0x2E,0xF1
+        DB      0x02,0xC2,0x2F,0xF1,0x03,0xC2,0x30,0xF1,0x04,0xC2,0x31,0xF1
+        DB      0x02,0x95,0x32,0x6B,0x33,0x6B,0x34,0x6B,0x35,0x6B,0x36,0x6B
+        DB      0x37,0x6B,0x2D,0xBF,0x33,0x8B,0x2D,0xBD,0x33,0x89,0x2D,0xBB
+        DB      0x33,0x87,0x2D,0xB9,0x33,0x85,0x2D,0xB7,0x33,0x83,0x2D,0xB5
+        DB      0x33,0x81,0x2D,0xB3,0x34,0x8F,0x2D,0xB1,0x34,0x8D,0x2E,0xBF
+        DB      0x34,0x8B,0x2E,0xBD,0x34,0x89,0x2E,0xBB,0x34,0x87,0x2E,0xB9
+        DB      0x34,0x85,0x2E,0xB7,0x34,0x83,0x2E,0xB5,0x34,0x81,0x33,0xC1
+        DB      0x38,0xF1,0x38,0x9B,0x38,0x67,0x01,0xD0,0x00,0xD0,0x04,0x0E
+        DB      0x38,0x6F,0x11,0xEE,0x2D,0xF0,0x50,0x6B,0xE6,0x50,0x50,0x1B
+        DB      0x08,0x0E,0x51,0x6F,0xD8,0x90,0x50,0x37,0x85,0x0E,0xD8,0xB0
+        DB      0x50,0x1B,0x51,0x2F,0xF9,0xD7,0x38,0x2F,0xF3,0xD7,0x31,0x51
+        DB      0x50,0x63,0x12,0x00,0x2E,0xB3,0x35,0x87,0x2E,0xB1,0x35,0x85
+        DB      0x2F,0xBF,0x35,0x83,0x2F,0xBD,0x35,0x81,0x2F,0xBB,0x36,0x8F
+        DB      0x2F,0xB9,0x36,0x8D,0x2F,0xB7,0x36,0x8B,0x2F,0xB5,0x36,0x89
+        DB      0x2F,0xB3,0x36,0x87,0x2F,0xB1,0x36,0x85,0x30,0xBF,0x36,0x83
+        DB      0x30,0xBD,0x36,0x81,0x00,0x0E,0x36,0x63,0x05,0xD0,0x0C,0x0E
+        DB      0x35,0x63,0x02,0xD0,0x36,0x6B,0x35,0x6B,0xE4,0x0E,0x21,0x6F
+        DB      0x0C,0x0E,0x22,0x6F,0x36,0xC1,0x1F,0xF1,0x35,0xC1,0x20,0xF1
+        DB      0x5C,0xEC,0x07,0xF0,0x02,0xB1,0x01,0xD0,0x12,0x00,0x30,0xBB
+        DB      0x37,0x8B,0x30,0xB9,0x37,0x89,0x30,0xB7,0x37,0x87,0x30,0xB5
+        DB      0x37,0x85,0x30,0xB3,0x37,0x83,0x30,0xB1,0x37,0x81,0x38,0x6B
+        DB      0x13,0xEE,0x00,0xF0,0x23,0xEE,0x10,0xF0,0x33,0x51,0xE6,0x62
+        DB      0x1E,0xD0,0x34,0x51,0xDE,0x62,0x1C,0xD0,0x13,0xEE,0x00,0xF0
+        DB      0x38,0x51,0x33,0xC1,0xE3,0xFF,0x13,0xEE,0x10,0xF0,0x34,0xC1
+        DB      0xE3,0xFF,0x13,0xEE,0x20,0xF0,0x35,0xC1,0xE3,0xFF,0x13,0xEE
+        DB      0x30,0xF0,0x36,0xC1,0xE3,0xFF,0x13,0xEE,0x40,0xF0,0x37,0xC1
+        DB      0xE3,0xFF,0x13,0xEE,0x50,0xF0,0xE3,0x6A,0xE3,0x2A,0x02,0x89
+        DB      0x12,0x00,0xDE,0x50,0x38,0x2B,0x06,0x0E,0x38,0x63,0xDA,0xD7
+        DB      0x38,0x6B,0x13,0xEE,0x50,0xF0,0xE6,0x66,0x01,0xD0,0xDA,0xD7
+        DB      0x38,0x2B,0x06,0x0E,0x38,0x63,0xF9,0xD7,0x12,0x00,0x95,0xD8
+        DB      0x5C,0xD8,0x27,0x6B,0x80,0x88,0x80,0xA8,0xFD,0xD7,0x02,0x9B
+        DB      0x2B,0x6B,0x12,0xEE,0x00,0xF0,0xE6,0x6A,0x0F,0x0E,0xE2,0x62
+        DB      0xFC,0xD7,0x01,0x01,0x9E,0xB6,0xF1,0xD8,0x02,0xBB,0xED,0xD7
+        DB      0x02,0xB9,0xD0,0xDE,0x02,0xB5,0x31,0xDF,0x02,0xB7,0x02,0xD8
+        DB      0x04,0x00,0xF4,0xD7,0x02,0x97,0x29,0x4B,0x2A,0x2B,0xEE,0xDE
+        DB      0x81,0xB0,0x06,0xD8,0x81,0xA0,0x3B,0x6B,0x28,0x2F,0x12,0x00
+        DB      0x06,0xD8,0x12,0x00,0x01,0x01,0x3B,0x2B,0x1E,0x0E,0x3B,0x63
+        DB      0x12,0x00,0x3B,0x6B,0xF2,0x6A,0xF0,0x6A,0x9D,0x6A,0x80,0x0E
+        DB      0xF1,0x6E,0xCD,0x6A,0xB1,0x6A,0x0F,0x01,0x42,0x6B,0x41,0x6B
+        DB      0x01,0x01,0x00,0x00,0x00,0x00,0x80,0x98,0x80,0xB8,0xFD,0xD7
+        DB      0x2A,0x6B,0x29,0x6B,0x9E,0x96,0x03,0x00,0x00,0x00,0x81,0xB0
+        DB      0xFB,0xD7,0x00,0x00,0x80,0x88,0x80,0xA8,0xFD,0xD7,0xCD,0x6A
+        DB      0x82,0x0E,0xB1,0x6E,0x13,0xEE,0x00,0xF0,0xE6,0x6A,0x04,0x0E
+        DB      0xE2,0x62,0xFC,0xD7,0x0F,0x01,0x42,0x6B,0xE0,0x0E,0x41,0x6F
+        DB      0x01,0x01,0xC0,0x0E,0xF2,0x6E,0xF1,0x6A,0x10,0x0E,0xF0,0x6E
+        DB      0x02,0x0E,0x9D,0x6E,0x12,0x00,0xF2,0x9E,0x23,0x97,0x06,0x69
+        DB      0x04,0x6B,0x06,0x2F,0x02,0xD0,0x9B,0x6A,0x1C,0xD0,0xB2,0x6A
+        DB      0xB1,0x80,0x03,0x6B,0xA1,0x92,0xB3,0x68,0xFC,0x0E,0xB2,0x6E
+        DB      0x03,0x2B,0xA1,0xA2,0xFD,0xD7,0x03,0x51,0x7A,0x08,0xD8,0xA0
+        DB      0x01,0xD0,0x07,0xD0,0xFF,0x08,0x01,0x08,0xD8,0xB0,0x09,0xD0
+        DB      0x04,0x07,0x0D,0xD8,0xE6,0xD7,0x01,0x08,0xD8,0xB0,0x03,0xD0
+        DB      0x04,0x2B,0x07,0xD8,0xE0,0xD7,0x04,0xC1,0x3C,0xF1,0x82,0x0E
+        DB      0xB1,0x6E,0xF2,0x8E,0x12,0x00,0x04,0xC1,0x05,0xF1,0x05,0x9F
+        DB      0x05,0x9D,0x05,0xC1,0x9B,0xFF,0x14,0x0E,0x05,0x6F,0x04,0x00
+        DB      0xFF,0xEC,0x02,0xF0,0x05,0x2F,0xFB,0xD7,0x12,0x00,0x0F,0x01
+        DB      0x72,0x0E,0xD3,0x6E,0xD2,0x6A,0x9B,0x6A,0xD1,0x80,0x0C,0x0E
+        DB      0x92,0x6E,0x05,0x0E,0x93,0x6E,0x59,0x0E,0x94,0x6E,0x0F,0x01
+        DB      0x04,0x0E,0x38,0x6F,0x39,0x6B,0x3A,0x6B,0x0F,0x01,0x3F,0x6B
+        DB      0x9B,0x0E,0x3E,0x6F,0x0E,0x0E,0x3D,0x6F,0x0F,0x01,0x04,0x0E
+        DB      0x61,0x6E,0x0F,0x01,0x80,0x6A,0x81,0x6A,0x82,0x6A,0xD5,0x6A
+        DB      0xCD,0x6A,0xCC,0x6A,0x7F,0x0E,0xBA,0x6E,0x82,0x0E,0xB1,0x6E
+        DB      0xB4,0x6A,0x0F,0x01,0x51,0x6B,0x0F,0x01,0x01,0x0E,0x4E,0x6F
+        DB      0x4D,0x6B,0x0F,0x01,0x04,0x0E,0x4A,0x6F,0x0F,0x01,0x42,0x6B
+        DB      0xE0,0x0E,0x41,0x6F,0x16,0x0E,0x40,0x6F,0x01,0x01,0xC2,0x6A
+        DB      0xAC,0x6A,0xAB,0x6A,0xB8,0x6A,0xAF,0x6A,0xB0,0x6A,0x24,0x0E
+        DB      0x72,0x6E,0x80,0x0E,0x71,0x6E,0x08,0x0E,0x70,0x6E,0x22,0x0E
+        DB      0x75,0x6E,0x76,0x6A,0x50,0x0E,0xC8,0x6E,0xC7,0x6A,0x26,0x0E
+        DB      0xC6,0x6E,0x08,0x0E,0xC5,0x6E,0xCB,0x6A,0xCA,0x68,0xC6,0x88
+        DB      0x23,0x6B,0x26,0x6B,0x9E,0x96,0x0F,0x01,0x92,0x0E,0x49,0x6F
+        DB      0x0F,0x01,0x07,0x0E,0x5D,0x6F,0x0F,0x01,0x01,0x0E,0x5A,0x6F
+        DB      0x0F,0x01,0x5C,0x6B,0x0F,0x01,0x5B,0x6B,0x0F,0x01,0xC0,0x0E
+        DB      0xF2,0x6E,0xF1,0x6A,0xF0,0x6A,0x02,0x0E,0x9D,0x6E,0xA0,0x6A
+        DB      0xA3,0x6A,0x01,0x0E,0x7A,0x6E,0x01,0x01,0x12,0x00,0x9E,0x96
+        DB      0x0F,0x0E,0x28,0x6F,0xC9,0xCF,0x24,0xF1,0xC7,0xB4,0x16,0xD0
+        DB      0xC7,0xAA,0x11,0xD0,0x23,0x6B,0x1B,0x0E,0x24,0x63,0x02,0xD0
+        DB      0x23,0x81,0x0B,0xD0,0x1E,0x0E,0x24,0x63,0x02,0xD0,0x23,0x83
+        DB      0x06,0xD0,0x2E,0x0E,0x24,0x63,0x02,0xD0,0x23,0x85,0x01,0xD0
+        DB      0x00,0xD0,0x9E,0x96,0xC6,0x88,0x12,0x00,0x23,0xB1,0x1C,0xD0
+        DB      0x23,0xB3,0x08,0xD0,0x23,0xB5,0x14,0xD0,0xFF,0x0E,0x24,0xD8
+        DB      0x00,0xD0,0x9E,0x96,0xC6,0x88,0x12,0x00,0x23,0x93,0x12,0xEE
+        DB      0x10,0xF0,0x30,0x0E,0x03,0x6F,0xE6,0x50,0x19,0xD8,0x02,0xBB
+        DB      0x15,0xD0,0xC5,0xBC,0xF2,0xD7,0x03,0x2F,0xF8,0xD7,0xEF,0xD7
+        DB      0x23,0x95,0x12,0xEE,0x40,0xF0,0xF1,0xD7,0x23,0x91,0x01,0x0E
+        DB      0x0B,0xD8,0x02,0xBB,0x07,0xD0,0xC5,0xBC,0xE4,0xD7,0x28,0x0E
+        DB      0x05,0xD8,0x02,0xBB,0x01,0xD0,0xDF,0xD7,0x23,0x6B,0xDD,0xD7
+        DB      0xC9,0x6E,0xC6,0x88,0x04,0xD0,0xC6,0x88,0x02,0xD8,0xC9,0x50
+        DB      0x12,0x00,0x27,0x6B,0x9E,0xB6,0x0B,0xD0,0x9E,0xB6,0x09,0xD0
+        DB      0x9E,0xB6,0x07,0xD0,0x9E,0xB6,0x05,0xD0,0x27,0x2F,0x01,0xD0
+        DB      0x04,0xD0,0x9E,0xA6,0xFE,0xD7,0x9E,0x96,0x12,0x00,0x02,0x8B
+        DB      0x9E,0x96,0x12,0x00,0x02,0x91,0x21,0x51,0x1F,0x5D,0x1D,0x6F
+        DB      0x22,0x51,0x20,0x59,0x1E,0x6F,0xD8,0xB0,0x12,0x00,0x02,0x81
+        DB      0x1E,0x1F,0x1D,0x6D,0xD8,0xB0,0x1E,0x2B,0x12,0x00,0x15,0x6B
+        DB      0x16,0x6B,0x1B,0x51,0x1C,0x11,0xD8,0xB4,0xFF,0x0C,0x01,0x0E
+        DB      0x14,0x6F,0x1C,0xBF,0x05,0xD0,0x14,0x2B,0xD8,0x90,0x1B,0x37
+        DB      0x1C,0x37,0xF9,0xD7,0xD8,0x90,0x15,0x37,0x16,0x37,0x1B,0x51
+        DB      0x19,0x5F,0x1C,0x51,0xD8,0xA0,0x1C,0x29,0x1A,0x5F,0xD8,0xB0
+        DB      0x05,0xD0,0x1B,0x51,0x19,0x27,0x1C,0x51,0x1A,0x23,0x01,0xD0
+        DB      0x15,0x81,0x14,0x07,0xD8,0xB4,0x12,0x00,0xD8,0x90,0x1C,0x33
+        DB      0x1B,0x33,0xE8,0xD7,0x49,0x91,0x4E,0x51,0x4C,0x5D,0x4A,0x6F
+        DB      0x4F,0x51,0x4D,0x59,0x4B,0x6F,0xD8,0xB0,0x12,0x00,0x49,0x81
+        DB      0x4B,0x1F,0x4A,0x6D,0xD8,0xB0,0x4B,0x2B,0x12,0x00,0xFF,0xFF
+
+
--- a/src/rx_firmware.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/rx_firmware.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File rx_firmware.asm                      combined next generation V3.03.5
+;   File rx_firmware.asm                      combined next generation V3.09.4f
 ;
 ;   Firmware for the RX Co-Processor
 ;
@@ -11,29 +11,29 @@
 #include "hwos.inc"						; mandatory header
 
 
-rx_firmware_storage	code	0x18000
+;=============================================================================
+rx_firmware_storage		code	0x18000
+;=============================================================================
 
-;-----------------------------------------------------------------------------
 
  IFDEF _rx_update
 
 	global	rx_firmware_storage
 rx_firmware_storage:
 
-;#include	"rx_firmware-1-33.inc"
-;#include	"rx_firmware-1-37.inc"
-;#include	"rx_firmware-1-38.inc"
-#include	"rx_firmware-1-39.inc"
-
+#include	"rx_firmware-1-40.inc"
 
 	global	rx_firmware_new_major
-	global	rx_firmware_new_minor
 rx_firmware_new_major:
 	retlw	rx_firmware_major			; defined in firmware include file
+
+	global	rx_firmware_new_minor
 rx_firmware_new_minor:
 	retlw	rx_firmware_minor			; defined in firmware include file
 
 
  ENDIF	; _rx_update
 
+;-----------------------------------------------------------------------------
+
 	END
--- a/src/rx_ops.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/rx_ops.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File rx_ops.asm                           combined next generation V3.03.8
+;   File rx_ops.asm                         * combined next generation V3.09.4f
 ;
 ;   RX (Tank Pressure Transmitter) Routines.
 ;
@@ -13,7 +13,6 @@
 #include "math.inc"
 #include "wait.inc"
 
-;=============================================================================
 
  IFDEF _rx_functions
 
@@ -36,8 +35,8 @@
 #DEFINE time_accu_target_CCR		.180; [s] target time accumulator filling level in CCR mode
 
 
-rx_ops	CODE
-
+;=============================================================================
+rx_ops1		CODE
 ;=============================================================================
 
 
@@ -106,6 +105,10 @@
 	movff	ex,char_I_pressure_stat+1	; copy status data
 	return
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - set pressure data to not available
+;
 get_pressure_readings_H1:
 	clrf	lo							; set pressure to 0 (low  byte)
 	clrf	hi							; set pressure to 0 (high byte)
@@ -116,6 +119,10 @@
 
 
  IFDEF _ccr_pscr
+
+;-----------------------------------------------------------------------------
+; Helper Function - pre-process Measurement Selection
+;
 get_pressure_readings_H2:
 	movlw	.11
 	subwf	ul,F
@@ -147,9 +154,13 @@
 	movlw	.1
 	movwf	ul							; ul >= 15 -> should not happen, default to ul = 1
 	return
- ENDIF	;  _ccr_pscr
+
+ ENDIF	; _ccr_pscr
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - get Transmitter ID
+;
 get_pressure_readings_H3:
 	lfsr	FSR1,opt_transmitter_id_1	; load base address of transmitter ID array
 	decf	ul,W						; (1-10) -> (0-9)
@@ -509,6 +520,9 @@
 	return
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - do an Accumulator Reduction
+;
 calc_pres_drop_reduce_accus:
 	; subtract 1 second from the time accumulator: time_accu (divA) -= 1 (only the low byte needs to be processed)
 	decf	divA+0,F					; decrement low byte of time_accu
@@ -530,6 +544,10 @@
 	clrf	mpr+3						;     - clear pressure accumulator, highest byte
 	return								;     - done
 
+
+;-----------------------------------------------------------------------------
+; Helper Function - reset everything
+;
 calc_pres_drop_reset:
 	; store the current gas as the last gas
 	movlw	offset_FSR1_gas__last		; load index of            last gas
@@ -547,6 +565,12 @@
 	movlw	offset_FSR1_time_last+1		; load index of last pressure time, high byte
 	clrf	PLUSW1						; clear         last pressure time, high byte
 
+	;bra	calc_pres_drop_restart
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - reset both Accumulators and set average Pressure drop to not available
+;
 calc_pres_drop_restart:
 	; clear pressure accumulator - FSR0 was left pointing to address of highest byte
 	clrf	POSTDEC0					; clear pressure accumulator, highest byte
@@ -569,7 +593,7 @@
 
 
 ;-----------------------------------------------------------------------------
-; set up SAC calculation dependent on TR mode
+; Set-up SAC Calculation dependent on TR Mode
 ;
 	global	configure_sac_calculation
 configure_sac_calculation:
@@ -612,20 +636,23 @@
 	return
 
 
-;-----------------------------------------------------------------------------
-; Update TR module
-;
+;=============================================================================
+rx_ops2		CODE
+;=============================================================================
 
  IFDEF _rx_update
 
+;-----------------------------------------------------------------------------
+; Update TR module
+;
 	global	update_tr_module
 update_tr_module:
 	movlw	LOW   rx_firmware_storage	; setup program memory read for embedded TR firmware
-	movwf	TBLPTRL
-	movlw	HIGH  rx_firmware_storage
-	movwf	TBLPTRH
-	movlw	UPPER rx_firmware_storage
-	movwf	TBLPTRU
+	movwf	TBLPTRL						; ...
+	movlw	HIGH  rx_firmware_storage	; ...
+	movwf	TBLPTRH						; ...
+	movlw	UPPER rx_firmware_storage	; ...
+	movwf	TBLPTRU						; ...
 
 	bsf		active_reset_ostc_rx		; apply a reset to the RX co-processor
 	WAITMS	.200						; wait 200 ms
@@ -640,7 +667,7 @@
 update_tr_module_loop:					; (loop 64 times)
 	call	I2C_update_OSTC_rx			; send a batch of 64 bytes to the RX co-processor
 	tstfsz	WREG						; WREG = 0, i.e. data sent successfully?
-	bra		update_tr_module_fail		; NO - transfer error, abort
+	bra		update_tr_module_fail		; NO  - transfer error, abort
 	decfsz	lo,F						; YES - decrement loop counter, became zero?
 	bra		update_tr_module_loop		;       NO  - loop
 	bra		update_tr_module_done		;       YES - transfer complete & successful
@@ -652,28 +679,23 @@
 
 update_tr_module_done:
 	bsf		INTCON,GIE					; re-enable interrupts
-
-	call	wait_1s						; wait (up to)        1 second
-	call	wait_1s						; wait (another full) 1 second
-
+	WAITS	.1							; wait 1 second
 	bsf		active_reset_ostc_rx		; apply a reset to the RX co-processor
 	WAITMS	.200						; wait 200 ms
 	bcf		active_reset_ostc_rx		; release reset
-	call	wait_1s						; wait (up to)        1 second
-	call	wait_1s						; wait (another full) 1 second
-	call	wait_1s						; wait (another full) 1 second
+	WAITS	.2							; wait 2 seconds
 
 	call	I2C_probe_OSTC_rx			; check if RX co-processor is alive, will set ostc_rx_present if so (1st try)
 	btfsc	ostc_rx_present				; RX co-processor up & running?
 	return								; YES
-	call	wait_1s						; NO  - wait (up to) 1 second
+	WAITS	.1							; NO  - wait 1 second
 	call	I2C_probe_OSTC_rx			;     - give it a 2nd try
-	return								;     - finally done (whatever result on 2nd tray)
+	return								;     - finally done (whatever result on 2nd try)
 
  ENDIF	; _rx_update
 
-;=============================================================================
-
  ENDIF	; _rx_functions
 
+;-----------------------------------------------------------------------------
+
 	END
--- a/src/simulator.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/simulator.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File simulator.asm                        combined next generation V3.08.8
+;   File simulator.asm                      * combined next generation V3.09.5
 ;
 ;   Deco Calculator
 ;
@@ -23,14 +23,14 @@
 #include "gaslist.inc"
 #include "surfmode.inc"
 #include "wait.inc"
+#include "colorschemes.inc"
 
 
 	extern deco_push_tissues_to_vault
 	extern deco_calc_dive_interval
 	extern deco_calc_hauptroutine
 	extern deco_pull_tissues_from_vault
-	extern TFT_decotype_logbook
-	extern do_return_demo_planner
+	extern do_return_menu_simulator_planner
 	extern convert_meter_to_feet
 	extern dive_boot_oc
 	extern get_first_gas_to_WREG
@@ -68,15 +68,25 @@
 ;									decoplan_flags,7	; --- unused
 
 
-simulator	CODE
+;---- Macro for easier Code Writing ------------------------------------------
 
-;-----------------------------------------------------------------------------
+; print a multi-lingual text at position horizontal x, vertical y in tiny font
+TEXT_SMALL macro x, y, txt
+	WIN_SMALL x,y
+	STRCPY_TEXT_PRINT txt
+	endm
+
 
 ;=============================================================================
-; Deco Calculator Main Function
+simulator	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Entry Point for Deco Calculator
 ;
-	global	do_demo_planner
-do_demo_planner:
+	global	demo_planner
+demo_planner:
 	btfsc	FLAG_gauge_mode					; in gauge mode?
 	bra		do_demo_planner_exit			; YES - abort
 	btfsc	FLAG_apnoe_mode					; in apnea mode?
@@ -85,8 +95,7 @@
 	clrf	decoplan_flags					; clear all local flags
 	bsf		simulatormode					; activate simulator mode
 	bsf		reset_timebase					; request ISR to reset the timebase
-;	btfsc	reset_timebase					; has the ISR confirmed reset of the timebase?
-;	bra		$-2								; NO - not yet, loop waiting for the ISR
+
 	call	deco_push_tissues_to_vault		; back-up the state of the real tissues (C-code)
 	banksel	common							; back to bank common
 
@@ -98,6 +107,7 @@
 	rcall	deco_results					; NO - show results
 
 	movff	simulator_time,char_I_dive_interval	; get the deco calculator runtime
+
 	call	deco_pull_tissues_from_vault	; restore the status of the real tissues (C-code)
 	call	deco_calc_dive_interval			; catch up with tissue desaturation      (C-code)
 	call	deco_calc_desaturation_time		; calculate desaturation and no-fly/no-altitude time after catch-up (C-code)
@@ -106,8 +116,6 @@
 	bcf		switch_left						; clear left button event (may be left over from abort/exit)
 	bcf		simulatormode					; terminate simulator mode
 	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
 
 	btfsc	divemode						; shall go into dive mode?
 	goto	restart							; YES - goto restart which will dispatch further on to dive mode
@@ -119,15 +127,16 @@
 	goto	sleeploop						;     - goto sleep mode
 
 do_demo_planner_exit:
-	goto	do_return_demo_planner			; return to simulator menu
+	goto	do_return_menu_simulator_planner; return to simulator menu
 
 
-;=============================================================================
-; Calculate the Deco Plan
+;-----------------------------------------------------------------------------
+; Helper Function - Calculate the Deco Plan
 ;
 deco_calculate:
 	call	request_speed_fastest			; request CPU speed change to fastest speed
 	call	TFT_ClearScreen					; clear screen to show that calculator is starting up
+	FONT_COLOR_MEMO							; select default text color
 
 	; initialization of the deco engine
 	btfsc	update_surface_pressure			; is there a pending surface pressure update?
@@ -196,13 +205,11 @@
 
 deco_calculate_0_error:
 	call	request_speed_normal			; request switch back to normal speed
-	WIN_COLOR	color_red					; select color for error message
+	FONT_COLOR	color_red					; select color for error message
 	TEXT_SMALL	.0,  .80, tNoBottomGas1		; print            error message, line 1
 	TEXT_SMALL	.0, .105, tNoBottomGas2		; print            error message, line 2
 	bsf		decoplan_abort					; set abort flag
-	call	wait_1s							; wait up to a full second
-	call	wait_1s							; wait       a full second
-	call	wait_1s							; wait another full second
+	WAITS	.2								; wait 2 seconds
 	bcf		switch_left						; clear potential button event
 	return									; return to deco calculator main function
 
@@ -272,9 +279,11 @@
 
 	; show that the deco calculation is in progress
 	call		TFT_ClearScreen				; clear screen from last results
-	WIN_COLOR	color_lightblue				; select color for abort label
+
+	FONT_COLOR	color_lightblue				; select color for abort label
 	TEXT_SMALL	.1,.215, tAbort				; print abort label
-	WIN_COLOR	color_white					; select color for title and progress outputs
+
+	FONT_COLOR	color_white					; select color for title and progress outputs
 	TEXT_SMALL	.0, .40, tCalculating		; print "Calculating..."
 
 	; calculate the surface interval
@@ -295,8 +304,8 @@
 
 	; invoke the deco engine once to condition the real tissues
 	; to their pressure state at the end of the bottom segment
-	call	deco_calc_hauptroutine			; (C-code)
-	banksel	common
+	call	deco_calc_hauptroutine			; invoke the deco engine (C-code)
+	banksel	common							; back to bank common
 
  IFDEF _ccr_pscr
 	; conditional switch to bailout mode
@@ -335,13 +344,13 @@
 
 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)
+	output_999								; print depth reached
+	STRCAT_TEXT tFeets						; append unit and dump to screen
 	bra		deco_calculate_loop_0
 
 deco_calculate_loop_metric:
-	output_8								; print depth reached (in meters)
-	STRCAT_TEXT tMeters						; print unit (meters)
+	output_256								; print depth reached (in meters)
+	STRCAT_TEXT tMeters						; append unit and dump to screen
 	;bra	deco_calculate_loop_0			; continue
 
 deco_calculate_loop_0:
@@ -366,7 +375,7 @@
 
 
 ;-----------------------------------------------------------------------------
-; Draw a stop of the deco plan (simulator or dive)
+; Helper Function - draw one Stop of the Deco Plan
 ; Inputs:  lo      = depth
 ;          hi      = minutes
 ;          win_top = line to draw on screen.
@@ -382,7 +391,7 @@
 	movff	PLUSW2,WREG						; get current gas and copy it to WREG for color-coding
 	call	TFT_color_code_gas				; set output color dependent on gas (1-5)
 
-	lfsr	FSR2,buffer						; set up output buffer
+	INIT_BUFFER								; initialize output buffer
 
 	TSTOSS	opt_units						; 0=Meter, 1=Feet
 	bra		deco_plan_show_nstd_stop_metric	; 0 - do metric
@@ -390,24 +399,23 @@
 	movff	hi,ul							; back-up hi (minutes)
 	WIN_LEFT .80
 	call	convert_meter_to_feet			; convert value in lo from meters to feet
-	output_16_3								; limit output to 0...999
+	output_999								; limit output to 0...999
 	STRCAT_PRINT "ft"
 	movff	ul,hi							; restore hi (minutes)
 	bra		deco_plan_show_nstd_stop_common
 
 deco_plan_show_nstd_stop_metric:
-	WIN_LEFT .85
-	output_8								; outputs into postinc2
-	STRCAT_PRINT "m"
+	WIN_LEFT .85							; set position
+	output_256								; print depth
+	PUTC_PRINT "m"							; append unit and dump buffer to screen
 
 deco_plan_show_nstd_stop_common:
-
 	; print duration
-	WIN_LEFT .135
-	lfsr	FSR2,buffer
-	movff	hi,lo
+	WIN_LEFT .135							; set position
+	INIT_BUFFER								; initialize buffer
+	movff	hi,lo							; get stop time
 	output_99dd								; stop entries are 99 minutes at max., prints double dots if duration is zero
-	STRCAT_PRINT "'"
+	PUTC_PRINT "'"							; append unit and dump buffer to screen
 
 	; draw the bar graph used for deco stops (lo = minutes)
 	incf	win_top,F
@@ -418,22 +426,22 @@
 	MOVLI	.16,win_width					; column max width
 	incf	lo,W							; add 1 for a minimum visible active bargraph area
 	movwf	win_bargraph					; set width of the active bargraph area
-	call	TFT_box							; draw bargraph
+	BOX										; draw bargraph
 
 	; restore win_top
-	call	TFT_standard_color
+	FONT_COLOR_MEMO							; set font color
 	decf	win_top,F						; restore win_top
-	return
+	return									; done
 
 
 ;-----------------------------------------------------------------------------
-; Display the deco plan (simulator)
+; Helper Function - Display the Deco Plan results Page
+;
 ; Inputs: char_O_deco_table (array of stop times, in minutes)
 ;         decoplan_page = page number.
 ;
 deco_results_page:
-	bcf		win_invert						; reset invert flag
-	WIN_COLOR color_greenish
+	FONT_COLOR color_greenish
  IFDEF _ccr_pscr
 	btfss	bailout_mode					; bailout results?
 	bra		deco_results_page_1				; NO
@@ -447,25 +455,24 @@
 	btfsc	WREG,deco_stops_norm			; are there deco stops?
 	bra		deco_plan_show_1				; YES
 
-	;---- no deco --------------------------------------------------------
-	call	TFT_standard_color
-	TEXT_SMALL .80, .25, tNoDeco
+	;---- no deco
+	FONT_COLOR_MEMO							; set color
+	TEXT_SMALL .80, .25, tNoDeco			; print "no Deco"
 
-	; output of remaining NDL time
+	; show remaining NDL time
 	WIN_SMALL .80, .50						; same line as bottom time
-	PUTC	"+"
+	PUTC	"+"								; print a plus
 	movff	int_O_NDL_norm+0,lo				; get NDL time in normal plan
-	bsf		leftbind
-	output_8
-	bcf		leftbind
-	PUTC	"'"
-	PUTC	" "
-	STRCAT_TEXT_PRINT tNDLleft				; "NDL"
+	bsf		leftbind						; align to the left
+	output_256								; print time (0-255)
+	PUTC	"'"								; append unit
+	PUTC	" "								; append a space
+	STRCAT_TEXT_PRINT tNDLleft				; append "NDL" and dump to screen
 
 	bsf		decoplan_last_stop_shown
 	return
 
-	;---- deco stops ---------------------------------------------------------
+	;---- deco stops
 deco_plan_show_1:
 	lfsr	FSR0,char_O_deco_depth			; initialize indexed addressing
 	lfsr	FSR1,char_O_deco_time			; ...
@@ -495,11 +502,11 @@
 	bz		deco_plan_show_99				; depth == 0 -> done
 
 	; display the stop line
-	rcall	deco_plan_show_stop
+	rcall	deco_plan_show_stop				; draw one stop of the deco plan
 
 	; next
-	movlw	.24
-	addwf	win_top,F						; row: += 24
+	movlw	.24								; row: += 24
+	addwf	win_top,F						; ...
 	incf	decoplan_index,F				; local index += 1
 	incf	decoplan_gindex,F				; global index += 1
 
@@ -509,46 +516,47 @@
 	bra		deco_plan_show_2				; NO - loop
 
 	; check if next stop is end-of-list?
-	movf	decoplan_gindex,W
+	movf	decoplan_gindex,W				; get index
 	movf	PLUSW0,W						; char_O_deco_depth[decoplan_gindex]
 	bz		deco_plan_show_99				; end of list
 
-	call	TFT_standard_color
-	WIN_SMALL .135,.212
-	STRCAT_PRINT ">>>"
-	return
+	WIN_SMALL .135,.212						; set output position
+	FONT_COLOR_MEMO							; set font color
+	STRCAT_PRINT ">>>"						; show cue for next page
+	return									; done
 
 deco_plan_show_99:
 	bsf		decoplan_last_stop_shown		; nothing more in table to display
-	call	TFT_standard_color
-	return
+	FONT_COLOR_MEMO							; set font color
+	return									; done
 
-;=============================================================================
+
+;-----------------------------------------------------------------------------
 ; Show Deco Calculation Results
 ;
 deco_results:
-	call	TFT_ClearScreen
-	call	TFT_standard_color
+	call	TFT_ClearScreen							; clear the screen
+	FONT_COLOR_MEMO									; set font color
 
 	; print interval
-	WIN_SMALL .0,.25
-	STRCPY	"Int. :"
-	movff	opt_surface_interval,lo
-	output_8
-	STRCAT_PRINT "'"
+	WIN_SMALL .0,.25								; set position
+	STRCPY	"Int. :"								; print label
+	movff	opt_surface_interval,lo					; get   value
+	output_256										; print value
+	PUTC_PRINT "'"									; append unit and dump buffer to screen
 
 	; print bottom time
-	WIN_SMALL .0,.50
-	STRCPY_TEXT tBtTm_short
-	movff	char_I_bottom_time,lo
-	output_8
-	STRCAT_PRINT "'"
+	WIN_SMALL .0,.50								; set position
+	STRCPY_TEXT tBtTm_short							; print label
+	movff	char_I_bottom_time,lo					; get   value
+	output_256										; print value
+	PUTC_PRINT "'"									; append unit and dump buffer to screen
 
 	; print bottom depth
-	WIN_SMALL .0,.75
-	STRCPY_TEXT tDepth
-	PUTC	":"
-	movff	char_I_bottom_depth,lo
+	WIN_SMALL .0,.75								; set position
+	STRCPY_TEXT tDepth								; print label
+	PUTC	":"										; append ":"
+	movff	char_I_bottom_depth,lo					; get   value
 
 	TSTOSS	opt_units								; check depth units
 	bra		deco_results_metric						; 0 - use Meters
@@ -556,58 +564,55 @@
 
 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)
+	output_999										; print depth reached
+	STRCAT_TEXT tFeets								; print unit and dump to screen
 	bra		deco_results_0							; continue
 
 deco_results_metric:
-	output_8										; print depth reached (in meters)
-	STRCAT_TEXT tMeters								; print unit (meters)
+	output_256										; print depth reached
+	STRCAT_TEXT tMeters								; print unit and dump to screen
 	;bra	deco_results_0							; continue
 
 deco_results_0:
-	STRCAT_PRINT ""									; finalize bottom depth output
+	PRINT											; finalize bottom depth output
 
 	; print warnings or sat/dsat factors
-	WIN_SMALL .0,.105
+	WIN_SMALL .0,.105								; set position for label
 
 	; check for stop table overflow
 	btfss	decoplan_warnings,deco_plan_incomplete	; check if deco plan is incomplete
 	bra		deco_results_0a							; NO  - skip
 
 	; display overflow warning
-	call	TFT_warning_color						; YES - show overflow warning
-	STRCAT_PRINT "incomplete"						; max 10 characters
+	FONT_COLOR_WARNING								; select warning color
+	STRCAT_PRINT "incomplete"						; show warning (max 10 characters)
 	bra		deco_results_m1							; skip displaying sat/dsat factors
 
 deco_results_0a:
-
  IFDEF _helium
 	; check for IBCD warning
 	btfss	decoplan_warnings,IBCD_warning_lock		; check if we have a locked IBCD warning
 	bra		deco_results_2b							; NO  - skip
 
 	; display IBCD warning
-	call	TFT_attention_color						; YES - show IBCD warning
+	FONT_COLOR_ATTENTION							; select attention color
 	STRCAT_PRINT "IBCD!"							; max 10 characters
 	bra		deco_results_m1							; skip displaying sat/dsat factors
  ENDIF
 
 deco_results_2b:
-
 	; display Sat/Desat factors --> omitted if there were warnings
-	STRCAT_PRINT "SD:"
-	WIN_SMALL .25,.105
-	movff	char_I_saturation_multiplier,lo
-	output_8
-	STRCAT	"/"
-	movff	char_I_desaturation_multiplier,lo
-	output_8
-	STRCAT_PRINT ""
+	STRCAT_PRINT "SD:"								; print label
+	WIN_SMALL .25,.105								; set position for values
+	movff	char_I_saturation_multiplier,lo			; get   1st value
+	output_256										; print 1st value
+	STRCAT	"/"										; print "/"
+	movff	char_I_desaturation_multiplier,lo		; get   2nd value
+	output_256										; print 2nd value
+	PRINT											; dump to screen
 
 deco_results_m1:
-
-	call	TFT_standard_color				; clean-up from warnings
+	FONT_COLOR_MEMO							; revert font color
 
 	; get model
 	movff	char_I_model,WREG				; 0: straight Buhlmann, 1: with GF
@@ -615,38 +620,34 @@
 	bz		deco_results_m2					; NO
 
 	; display GF low/high factors
-	WIN_SMALL .0,.130
-	STRCAT_PRINT "GF:"
-	WIN_SMALL .25,.130
-	movff	char_I_GF_Low_percentage,lo
-	output_8
-	STRCAT	"/"
-	movff	char_I_GF_High_percentage,lo
-	output_8
-	STRCAT_PRINT ""
+	WIN_SMALL .0,.130						; set position for label
+	STRCAT_PRINT "GF:"						; print label
+	WIN_SMALL .25,.130						; set position for values
+	movff	char_I_GF_Low_percentage,lo		; get   1st value
+	output_256								; print 1st value
+	STRCAT	"/"								; print "/"
+	movff	char_I_GF_High_percentage,lo	; get   2nd value
+	output_256								; print value
+	PRINT									; dump to screen
 
 deco_results_m2:
-
 	; display deco mode
-	WIN_SMALL .0,.155
-	lfsr	FSR2,buffer
+	WIN_SMALL .0,.155						; set position
+	INIT_BUFFER								; load buffer base address
 	movff	opt_dive_mode,lo				; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR
-	call	TFT_decotype_logbook
+	call	TFT_print_decotype				; print deco type (OC, CCR)
 
  IFDEF _ccr_pscr
 	btfss	FLAG_ccr_mode					; current dive mode = CCR ?
-	bra		deco_results_2c					; NO - skip
-	WIN_SMALL .25,.155
-	STRCPY	"SP:"							; output setpoint used for calculation
-	movff	opt_sim_setpoint_number,lo
-	bsf		leftbind
-	output_8
-	bcf		leftbind
-	STRCAT_PRINT ""
+	bra		deco_results_2c					; NO  - skip
+	WIN_SMALL .25,.155						; YES - set position
+	STRCPY	"SP:"							;     - print label
+	movff	opt_sim_setpoint_number,lo		;     - get setpoint used for calculation
+	output_9								;     - print setpoint number (0-9)
+	PRINT									;     - dump to screen
  ENDIF
 
 deco_results_2c:
-
 	btfss	FLAG_oc_mode					; current dive mode = OC ?
 	bra		deco_results_2d					; NO  - skip
 	TSTOSS	opt_ext_stops					; YES - extended stops activated?
@@ -657,31 +658,28 @@
 deco_results_2d:
 
 	; display TTS result
-	WIN_SMALL .0,.180
-	STRCPY_TEXT tTTS
-	STRCAT	": "
-	MOVII	int_O_TTS_norm,mpr
-	bsf		leftbind
-	output_16
-	bcf		leftbind
-	STRCAT_PRINT "'"
+	WIN_SMALL .0,.180						; position
+	STRCPY_TEXT tTTS						; print label
+	STRCAT	": "							; append ": "
+	MOVII	int_O_TTS_norm,mpr				; get TTS value
+	bsf		leftbind						; print left-aligned
+	output_999								; print TTS (0-999)
+	PUTC_PRINT "'"							; append unit and dump to screen
 
 	; display CNS result
-	WIN_TOP	.205
-	STRCPY_TEXT tCNS2						; "CNS:"
+	WIN_TOP	.205							; position
+	STRCPY_TEXT tCNS2						; print label
 	MOVII	real_CNS,mpr					; recall real CNS from before simulated dive
 	call	TFT_color_code_cns				; color-code CNS output
-	bsf		leftbind
-	output_16_3								; limit to 999 and display only (0-999)
-	bcf		leftbind
+	bsf		leftbind						; print left-aligned
+	output_999								; limit to 999 and display only (0-999)
 	STRCAT	"%\x92"							; "->"
 	MOVII	int_O_CNS_norm,mpr				; get CNS at end of simulated dive in normal plan
 	call	TFT_color_code_cns				; color-code CNS output
-	bsf		leftbind
-	output_16_3								; limit to 999 and display only (0-999)
-	bcf		leftbind
-	STRCAT_PRINT "%"
-	call	TFT_standard_color
+	bsf		leftbind						; print left-aligned
+	output_999								; limit to 999 and display only (0-999)
+	PUTC_PRINT "%"							; append unit and print everything to screen
+	FONT_COLOR_MEMO							; back to standard color
 
 	; loop through deco plan pages
 deco_results_1:
@@ -734,7 +732,6 @@
 	movlw	.25								; output row is 25 (fixed offset set here) + n*25 (line increment, see below)
 	movwf	output_row						; set fixed vertical offset for output row
 	WIN_LEFT .80							; set column
-	call	TFT_standard_color
 	clrf	gas_index						; initialize gas counter
 	bcf		is_diluent_menu					; working on OC gases
 
@@ -745,16 +742,17 @@
 	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						; 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
-	bcf		divemode						; cleanup above
-
 	movlw	.25								; spacing between outputs
 	addwf	output_row,F					; increase row position
 	movff	output_row,win_top				; set      row position
 
+	INIT_BUFFER								; initialize output buffer
+
+	bsf		short_gas_descriptions			; configure gaslist_strcat_gas output format
+	bsf		divemode						; configure gaslist_strcat_gas output format
+	call	gaslist_strcat_mix_PRODL		; write "Nxlo", "Txlo/hi", "Air" or "O2" into output buffer
+	bcf		divemode						; revoke dive mode
+
 	movff	POSTINC0,lo						; read gas volume low  byte
 	movff	POSTINC0,hi						;                 high byte
 
@@ -763,14 +761,6 @@
 	btfsc	decoplan_pressures_shown		; results in bar?
 	bra		deco_results_gas_volumes_1		; YES
 
-	; output of gas needs in liter
-	movf	lo,W							; check if hi:lo = 65535: copy low byte to WREG
-	andwf	hi,W							; and do a bitwise AND with the high byte
-	incfsz	WREG							; add 1, result zero now?
-	bra		deco_results_gas_volumes_2		; NO  - print volume
-	STRCAT_PRINT ">65500"					; YES - print ">65500"
-	bra		deco_results_gas_volumes_3		;     - continue checking if all gases are shown
-
 	; output of gas needs in bar
 deco_results_gas_volumes_1:
 	btfsc	hi,int_high_flag				; overflow in result?
@@ -785,19 +775,20 @@
 
 deco_results_gas_volumes_2:
 	PUTC	":"								; print ":"
-	output_16								; print 16 bit number
+	output_9999								; print volume or bar (0-9999)
 	movlw	'>'								; load coding of ">" sign into WREG
-	btfsc	decoplan_overflow				; overflow in result?
-	movff	WREG,buffer+.7					; YES - place ">" before number
-	STRCAT_PRINT ""							; finalize output
-	bcf		win_invert						; back to none-inverse printing
+	btfsc	decoplan_overflow				; overflow in pressure value?
+	movff	WREG,buffer+.7					; YES - place ">" in front of pressure value
+	btfsc	output_overflow					; overflow in output?
+	movff	WREG,buffer+.6					; YES - place ">" in front of volume   value
+	PRINT									; dump to screen
 
 deco_results_gas_volumes_3:
 	movlw	NUM_GAS							; 5 gases to show
 	cpfseq	gas_index						; all gases shown?
 	bra		deco_results_gas_loop			; NO - loop
 
-	WIN_COLOR color_greenish				; set color
+	FONT_COLOR color_greenish				; set color
 	TEXT_SMALL .80,.01,tGasUsage			; "Gas Usage"
 
 	btfsc	decoplan_pressures_shown		; results shown in bar?
@@ -809,7 +800,6 @@
 	TEXT_SMALL .120,.25,tbar				; " bar" (with leading space)
 
 deco_results_gas_volumes_5:
-	call	TFT_standard_color				; revert to standard color
 	call	reset_timeout_surfmode			; reset timeout
 	bcf		switch_right					; clear left-over right button event
 	bcf		switch_left						; clear left-over left  button event
@@ -834,5 +824,6 @@
 	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
 
+;-----------------------------------------------------------------------------
 
-	END
\ No newline at end of file
+	END
--- a/src/sleepmode.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/sleepmode.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File sleepmode.asm                        combined next generation V3.08.8
+;   File sleepmode.asm                      * combined next generation V3.09.4n
 ;
 ;   Sleep Mode
 ;
@@ -56,10 +56,14 @@
 ;							sm_flags,7	; unused
 
 
+;=============================================================================
 slmode	CODE
-
 ;==============================================================================
 
+
+;-----------------------------------------------------------------------------
+; Entry Point for Sleep Mode
+;
 	global	sleeploop
 sleeploop:
 	clrf	STKPTR							; clear return addresses stack
@@ -75,7 +79,7 @@
 	bsf		sleepmode						; flag being in sleep mode
 	bsf		block_sensor_interrupt			; suspend ISR from executing sensor interrupts
 
-	call	disable_ir_s8					; power-down IR/S8 interrupts
+	call	disable_ir_s8_analog			; power-down IR/S8/analog interface
 	call	mcp_sleep						; power-down RX power supply
 
 	clrf	ADCON0							; power-down ADC module
@@ -85,9 +89,8 @@
 	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 ?
+	btfsc	option_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
 
@@ -106,18 +109,18 @@
 	btfss	sleepmode						; shall terminate sleep mode?
 	bra		sleeploop_exit					; YES
 
-	rcall	sleepmode_sleep					; wait at least 35 ms (every 62.5 ms timer7 wakeup)
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
 
 	btfss	deep_sleep						; shall enter deep sleep?
 	bra		sleeploop_loop					; NO  - remain in normal sleep loop
 	;bra	deepsleep_pre					; YES - enter     deep   sleep loop
 
 deepsleep_pre:
-	bcf		PIE1,0							; disable timer 1 interrupt
-	bcf		PIE2,1							; disable timer 2 interrupt
-	bcf		PIE5,3							; disable timer 7 interrupt
-	bcf		INTCON,4						; disable INT0    interrupt
-	bcf		INTCON3,3						; disable INT1    interrupt
+	bcf		PIE1,TMR1IE						; disable timer 1 interrupt
+	bcf		PIE2,TMR3IE						; disable timer 2 interrupt
+	bcf		PIE5,TMR7IE						; disable timer 7 interrupt
+	bcf		INTCON, INT0IE					; disable INT0    interrupt
+	bcf		INTCON3,INT1IE					; disable INT1    interrupt
 
 	bcf		power_sw1						; power-down switch 1
 	bcf		power_sw2						; power-down switch 2
@@ -135,7 +138,7 @@
 	btfsc	trigger_full_second				; one second in deep sleep?
 	rcall	one_sec_sleep					; YES - check switches, check pressure sensor, etc.
 
-	rcall	sleepmode_sleep					; wait at least 35 ms (every 62.5 ms timer7 wakeup)
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
 
 	btfss	sleepmode						; shall leave sleep mode?
 	bcf		deep_sleep						; YES - leave deep sleep mode then, too
@@ -149,15 +152,14 @@
 	call	power_up_switches				; turn on    the analog switches
 	rcall	init_avg_switches				; initialize the averaging system
 
-	bsf		PIE1,0							; enable timer 1 interrupt
-	bsf		PIE2,1							; enable timer 2 interrupt
-	bsf		PIE5,3							; enable timer 7 interrupt
-	bsf		INTCON,4						; enable INT0    interrupt
-	bsf		INTCON3,3						; enable INT1    interrupt
+	bsf		PIE1,TMR1IE						; enable timer 1 interrupt
+	bsf		PIE2,TMR3IE						; enable timer 2 interrupt
+	bsf		PIE5,TMR7IE						; enable timer 7 interrupt
+	bsf		INTCON, INT0IE					; enable INT0    interrupt
+	bsf		INTCON3,INT1IE					; enable INT1    interrupt
 
 	bra		sleeploop_loop					; enter normal sleep loop
 
-
 sleeploop_exit:
 	bcf		switch_left						; eventually clear left  button event
 	bcf		switch_right					; eventually clear right button event
@@ -168,8 +170,10 @@
 	goto	restart							; restart
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Tasks every Second in Sleep Mode
+;
 one_sec_sleep:
-	; tasks every second in sleep mode
 	bcf		trigger_full_second				; clear trigger flag
 
 	btfsc	switch_left						; left switch pressed?
@@ -195,14 +199,14 @@
 	btfsc	charge_in_sleep					; YES - already showing charge screen?
 	bra		one_sec_sleep_1b				;       YES - only update data
 
-	bsf	charge_in_sleep
-	bcf	deep_sleep						; wake-up from deepsleep
+	bsf		charge_in_sleep
+	bcf		deep_sleep						; wake-up from deepsleep
 	call	TFT_boot						; initialize TFT (includes clear screen)
 	movlw	.32
 	movff	WREG,max_CCPR1L					; bank safe
 	call	TFT_Display_FadeIn				; dim up the display
 one_sec_sleep_1b:
-	call	TFT_batt_surfmode				; show battery type, voltage and color-coded percentage
+	call	TFT_surfmode_batt				; show battery type, voltage and color-coded percentage
 	bra		one_sec_sleep_2					; continue
 
 one_sec_sleep_1a:
@@ -230,6 +234,9 @@
 	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Tasks every 10 Seconds in Sleep Mode
+;
 ten_sec_sleep:
 	; tasks every 10 seconds in sleep mode
 	clrf	sm_timer_10sec					; clear timer
@@ -242,6 +249,9 @@
 	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Tasks every Minute in Sleep Mode
+;
 one_min_sleep:
 	; tasks every minute in sleep mode
 	bcf		trigger_full_minute				; clear flag
@@ -261,6 +271,9 @@
 	return									;     - done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Tasks every 10 Minutes in Sleep Mode
+;
 ten_min_sleep:
 	; tasks every 10 minutes in sleep mode
 	clrf	sm_timer_10min					; reset timer to 0
@@ -296,6 +309,9 @@
 	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Tasks every Hour in Sleep Mode
+;
 one_hour_sleep:
 	; tasks every hour in sleep mode mode
 	bcf		trigger_full_hour				; clear one hour flag
@@ -304,13 +320,16 @@
 	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Initialization of the Button Event Averaging System
+;
 init_avg_switches:
 	; pause 4 seconds using CPU sleep mode to conserve on battery
 	movlw	.4								; time to pause
 	movwf	loop_counter					; initialize loop counter
 	bcf		trigger_full_second				; clear 'one second elapsed' flag
 activate_switches_1:
-	rcall	sleepmode_sleep					; wait at least 35 ms (every 62.5 ms timer7 wakeup)
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
 	btfss	trigger_full_second				; did 1 second elapsed meanwhile?
 	bra		activate_switches_1				; NO  - loop
 	bcf		trigger_full_second				; YES - clear flag
@@ -327,17 +346,19 @@
 
 	; clear all button events that may have intermediately occurred
 	bcf		PIR1,TMR1IF						; clear button-hold-down timer
-	bcf		INTCON,INT0IF					; clear right button activity
+	bcf		INTCON, INT0IF					; clear right button activity
 	bcf		INTCON3,INT1IF					; clear left  button activity
 	bcf		analog_sw1_pressed				; clear analog switch 1 activity
 	bcf		analog_sw2_pressed				; clear analog switch 2 activity
 	bcf		switch_right					; clear right button event
 	bcf		switch_left						; clear left  button event
 
-	; done
-	return
+	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - Check for Change in Accelerometer Z-Axis
+;
 check_accelerometer:
 	rcall	deepsleep_get_accel				; read accelerometer into WREG
 	subwf	accel_reference,W				; reference value - accel_DZ+0 -> WREG
@@ -350,9 +371,12 @@
 	return									; done
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - read Accelerometer Z-Axis
+;
 deepsleep_get_accel:
 	call	I2C_init_compass				; start compass
-	rcall	sleepmode_sleep					; wait a little bit
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
 	call	I2C_RX_accelerometer			; read accelerometer
 	call	I2C_RX_accelerometer			; read accelerometer
 	call	I2C_sleep_compass				; shut down compass
@@ -360,7 +384,12 @@
 	return									; done
 
 
-pressuretest_sleep_fast:					; get pressure without averaging (faster to save some power in sleep mode)
+;-----------------------------------------------------------------------------
+; Helper Function - read Pressure without Averaging
+;
+; faster method to save some power in sleep mode
+;
+pressuretest_sleep_fast:
 	banksel	isr_backup						; select bank ISR data
 
 	CLRI	pressure_abs_avg				; clear pressure    average register
@@ -368,14 +397,14 @@
 
 	call	get_temperature_start			; start temperature integration (73.5 us)
 
-	rcall	sleepmode_sleep					; wait at least 35 ms (every 62.5 ms timer7 wakeup)
-	rcall	sleepmode_sleep					; wait at least 35 ms (every 62.5 ms timer7 wakeup)
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
 
 	call	get_temperature_value			; state 1: get temperature
 	call	get_pressure_start				; start pressure integration
 
-	rcall	sleepmode_sleep					; wait at least 35 ms (every 62.5 ms timer7 wakeup)
-	rcall	sleepmode_sleep					; wait at least 35 ms (every 62.5 ms timer7 wakeup)
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
+	rcall	sleepmode_sleep					; sleep for 62.5...125 ms
 
 	call	get_pressure_value				; state2: get pressure (51 us)
 	call	calculate_compensation			; calculate temperature compensated pressure (27 us)
@@ -386,29 +415,24 @@
 	return
 
 
+;-----------------------------------------------------------------------------
+; Helper Function - sleep for 62.5...125 ms
+;
 sleepmode_sleep:
-	movff	BSR,BSR_backup					; backup BSR
-
-	banksel	common
+	movff	BSR,BSR_backup					; backup current bank selection
+	banksel	common							; switch to bank common
 	btfsc	charge_in_sleep					; already showing charge screen?
-	bra		sleepmode_sleepwalk				; YES - skip the actual sleep (But wait)
-
-;	banksel	T7GCON							; switch bank, T7* is outside access RAM
-;	clrf	T7GCON							; reset timer7 gate control register
-;	movlw	b'10001101'						; 1:1 prescaler -> 2 seconds @ 32768 Hz, not synced
-;	movwf	T7CON
-	sleep
-	sleep
-;	clrf	T7GCON							; reset timer7 gate control register
-;	movlw	b'10001001'						; 1:1 prescaler ->  2 seconds @ 32768 Hz, synced
-;	movwf	T7CON
+	bra		sleepmode_sleepwalk				; YES - skip the actual sleep (but wait)
+	sleep									; NO  - put CPU into sleep (wakes up by timer 7 IRQ)
+	sleep									;     - put CPU into sleep again
 sleepmode_sleep_1:
-	movff	BSR_backup,BSR					; restore BSR
-	return
-
+	movff	BSR_backup,BSR					; restore bank selection
+	return									; done
 
 sleepmode_sleepwalk:
-	WAITMS	d'65'
-	bra		sleepmode_sleep_1
+	WAITMS	d'65'							; wait 65 ms
+	bra		sleepmode_sleep_1				; continue with common part
 
- END
\ No newline at end of file
+;-----------------------------------------------------------------------------
+
+ END
--- a/src/start.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/start.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File start.asm                            combined next generation V3.09.1 fix
+;   File start.asm                          * combined next generation V3.09.5
 ;
 ;   Startup subroutines
 ;
@@ -36,7 +36,7 @@
 	extern	option_check_and_store
 	extern	option_reset
 	extern	rtc_init
-	extern	do_new_battery_select
+	extern	new_battery_select
 	extern	get_battery_data
 	extern	use_old_prior_209
 	extern	get_first_gas_to_WREG
@@ -59,29 +59,49 @@
  IFDEF _rx_update
 	extern	rx_firmware_new_major
 	extern	rx_firmware_new_minor
+	extern	dyn_show_firmware_rx
  ENDIF
 
-;-----------------------------------------------------------------------------
-
 
 ;=============================================================================
-; Reset Vector: entry point on device wake-up and hard reset
+; Reset Vector: Entry Point on Device Wake-up and hard Reset
 ;
 reset_v		CODE 0x00000
 	goto	0x1FF00							; jump to bootloader
 
 start_v		CODE 0x00004					; jump to application (cold-)start
 	goto	start
-
+;
 ;=============================================================================
 
-boot	CODE
 
 ;=============================================================================
-; Entry point after cold start
+; Firmware Identification
+;
+fingerprint	CODE 0x0000A
+	db	fw_version_major,		fw_version_minor		; major,         minor
+	db	fw_version_beta,		FW_ID					; beta/release,  firmware ID
+	db	firmware_creation_year,	firmware_creation_month	; creation year, month
+	db	firmware_creation_day,	FW_CONF 				; creation day,  firmware configuration
+	db	0x00,					0x00					; reserved for future use
+	db	0x00,					0x00					; reserved for future use
+	db	0x00,					0x00					; reserved for future use
+;
+;=============================================================================
+
+
+;=============================================================================
+boot1	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+;
+; Entry Point after cold Start
 ;
 	global	start
 start:
+
 	; clear RAM banks 0-14
 	lfsr	FSR0,0x000						; load start address into FSR0
 	movlw	0x0F							; load end   address into WREG (actually its high byte)
@@ -90,19 +110,19 @@
 	cpfseq	FSR0H							; has FSR0 reached begin of bank 15, i.e. banks 0-14 done?
 	bra		start_clear_rambank				; NO - loop
 
-	; initialize hardware (ports, timers, interrupts, etc.)
+	; initialize averaging for analog buttons before IRQ gets enabled
+	movlw	.16								; set averaging span
+	movff	WREG,analog_counter				; write to counter (in bank isr_backup)
+
+	; initialize hardware (ports, timers) and start interrupts
 	call	init_ostc						; also selects bank common and sets CPU to normal speed
 
 	; flag that later restart origins from a cold start
 	bsf		cold_start
 
-	; initialize averaging for analog buttons
-	movlw	.16								; set averaging span
-	movff	WREG,analog_counter				; write to counter (in bank isr_backup)
-
 	; get button type from bootloader info
 	bsf		analog_switches					; assume analog buttons by default
-	movlw	0x7C							; address bootloader at 0x01F77C
+	movlw	0x7C							; set up read from 0x01F77C
 	movwf	TBLPTRL							; ...
 	movlw	0xF7							; ...
 	movwf	TBLPTRH							; ...
@@ -114,10 +134,14 @@
 	bcf		analog_switches					; NO - no analog buttons
 
 	; get screen type (2) from bootloader info
-	bsf		screen_type2
-	bsf		screen_type3
-	movlw	0x80
-	movwf	TBLPTRL							; only low byte adjustment needed, high and upper are still at 0x01F7xx
+	bsf		screen_type2					; set flags for later clear of the false one
+	bsf		screen_type3					; ...
+	movlw	0x80							; set up read from 0x01F780
+	movwf	TBLPTRL							; ...
+	;movlw	0xF7							; high and upper are still at 0x01F7xx
+	;movwf	TBLPTRH							; ...
+	;movlw	0x01							; ...
+	;movwf	TBLPTRU							; ...
 	TBLRD*+									; read configuration byte
 	movlw	0x83							; coding for screen type 2
 	cpfseq	TABLAT							; equal?
@@ -131,27 +155,21 @@
 
 	; initialize pressure sensor calibration
 	call	get_calibration_data			; get calibration data from pressure sensor
+
 	call	TFT_DisplayOff					; turn off display
-
-	; wait for calibration data to take effect
 	bsf		LEDr							; turn on red LED
 
-	; first pass, will not have valid temperature yet
-	call	wait_1s
-	call	wait_1s
-
-	; second pass - complete sensor initialization
-	call	wait_1s
-	call	wait_1s
+	; wait for valid temperature and pressure
+	WAITS	.3								; wait 3 seconds
 
 	; sensor calibration completed, first valid pressure value is available
-	bcf		LEDr							; turn off red LED again
+	bcf		LEDr							; turn off red LED
 
-	; load surface pressure into ISR
-	; initially needs to be done twice in order to shift the current absolute pressure through the
-	; 15 minutes sampling buffer into the reference buffer from where it is loaded by the ISR
-	rcall	sample_surface_pressure			; 1st pass
-	rcall	sample_surface_pressure			; 2nd pass
+	; initial loading of the surface pressure into the ISR
+	; needs to be done twice in order to shift the current absolute pressure through
+	; the sampling buffer into the reference buffer from where it is loaded by the ISR
+	call	sample_surface_pressure			; 1st pass
+	call	sample_surface_pressure			; 2nd pass
 
 	; wait until initial surface pressure value has been loaded into the ISR
 	btfsc	update_surface_pressure			; has the ISR confirmed loading of the surface pressure?
@@ -222,18 +240,18 @@
 	;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
+	call	TFT_message_fw_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
+	call	TFT_message_fw_update			; show firmware is updated 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
+;	; 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
@@ -241,23 +259,61 @@
 	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
-start_check_new_firmware_wait:
-	call	wait_1s							; wait <= 1 second
-	decfsz	WREG,W							; decrement loop counter, did it became zero?
-	bra		start_check_new_firmware_wait	; NO  - loop
-	;bra	restart							; YES - proceed with restart
+	WAITS	.5								; wait 5 second
+
+	goto	restart							; proceed with restart
 
 
 ;=============================================================================
-; Entry point after warm start
+boot2	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Sample and store the current Surface Pressure
+; Update ISR and Deco Engine with Pressure sampled on last Invocation
+;
+	global	sample_surface_pressure
+sample_surface_pressure:
+	; make sure the ISR does not read the surface pressure reference buffer while it is updated
+	bcf		update_surface_pressure			; cancel any pending load request
+
+	; propagate the surface pressure sampled on last invocation to the reference pressure buffer
+	MOVII	pressure_abs_sampled,pressure_abs_ref
+
+	; update surface pressure in the ISR
+	bsf		update_surface_pressure			; request ISR to update its surface pressure
+
+	; update surface pressure in the deco engine
+	MOVII	pressure_abs_ref,int_I_pres_surface
+
+	; sample current absolute pressure (ISR-safe 2 byte copy)
+	SMOVII	pressure_abs,pressure_abs_sampled
+
+	; limit sampled pressure to max allowed surface pressure
+	MOVLI	max_surfpressure,    sub_a		; load upper limit    into sub_a
+	MOVII	pressure_abs_sampled,sub_b		; copy sampled pressure to sub_b
+	call	cmpU16							; sub_a - sub_b = max_surfpressure - pressure_abs_sampled
+	btfss	neg_flag						; sampled pressure > max_surfpressure ?
+	return									; NO  - below limit, done
+	MOVII	sub_a,pressure_abs_sampled		; YES - limit to max_surfpressure (still stored in sub_a)
+	return									;     - done
+
+
+;=============================================================================
+boot3	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Entry Point for warm Start
 ;
 ; called on leaving sleep mode, surface menu, communication mode, and
-; when a start of a dive is detected in all modes except surface mode.
+; when a start of a dive is detected in all modes except surface mode
 ;
 	global	restart
 restart:
+
 	; for safety purpose only
 	banksel	common							; select bank common
 	clrf	STKPTR							; clear return addresses stack
@@ -271,7 +327,7 @@
 	; clear flag groups
 	clrf	HW_descriptor					; hardware - OSTC model descriptor
 	clrf	HW_flags_state1					; hardware - states
-	;										; do not clear HW_flags_state2 !
+	;										; 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
@@ -279,13 +335,13 @@
 	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
+	clrf	CVT_flags1						; control of numerical outputs 1
+	clrf	CVT_flags2						; control of numerical outputs 2
 
 	; 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
 	bsf		ambient_sensor					; set ambient light sensor as available by default
-	bsf		optical_input					; set optical input        as available by default
+	bsf		ext_input_optical				; set optical input        as available by default
 
 	call	lt2942_get_status				; check for gauge IC
 	btfss	battery_gauge_available			; OSTC 2, cR or TR?
@@ -293,7 +349,7 @@
 
 	; OSTC 2, cR or TR
 	call	lt2942_init						; initialize battery gauge IC
-	bcf		optical_input					; OSTC 2, cR and TR do not have an optical input
+	bcf		ext_input_optical				; OSTC 2, cR and TR do not have an optical input
 
 	banksel	ANCON0							; ANCON0 is outside access RAM
 	bcf		ANCON0,7						; AN7 digital input
@@ -311,21 +367,21 @@
 restart2:
  IFNDEF _hwos_sport
 	btfsc	vusb_in							; USB power detected?
-	bra		restart3						; YES - no BLE then
+	bra		restart3						; YES - no BT 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
+	bra		restart3						;       NO  - no BT then
  ENDIF
-	bsf		ble_available					;       YES - BLE available
+	bsf		ble_available					;       YES - BT available
 
 restart3:
-	bsf		PORTE,0							; power down BLE chip
-	btfsc	ble_available					; BLE available?
+	bsf		PORTE,0							; power down BT chip
+	btfsc	ble_available					; BT available?
 	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
+	bsf		ext_input_s8_ana				;       YES - it's a cR, S8/analog sensor input available
 
 restart4:
 	bsf		lv_core							; default to low voltage core
@@ -347,6 +403,17 @@
 restart4a:
 	bcf		lv_core							;       NO - no low voltage core then
 
+	; OSTC sport 2019 hardware does not have an optical input
+	btfsc	lv_core							; low voltage core?
+	bcf		ext_input_optical				; YES - no optical input available
+
+	; check FLASH for block-write capability
+	bsf		flash_block_write				; default to block-write capability available
+	call	ext_flash_read_jedec			; read JEDEC IDs
+	movlw	0x26							; device type 26h supports block-write
+	cpfseq	hi								; dive type = 26h ?
+	bcf		flash_block_write				; NO  - revoke capability
+
 
  IFDEF _rx_functions
 
@@ -391,7 +458,7 @@
 	btfss	ostc_rx_present					; data transfer successful and TR module up & running again?
 	bra		restart4c						; NO
 	STRCAT	"to "							; YES - print success message
-	call	TFT_print_firmware_rx			;     - print installed version
+	call	dyn_show_firmware_rx			;     - print installed version
 	STRCAT_PRINT " done"					;     - complete result message
 	bra		restart4d						;     - show message for a while
 
@@ -399,9 +466,7 @@
 	STRCAT_PRINT "failed"					; complete result message - failure
 
 restart4d:
-	call	wait_1s							; wait (up to)        1 second
-	call	wait_1s							; wait (another full) 1 second
-	call	wait_1s							; wait (another full) 1 second
+	WAITS	.3								; wait 3 seconds
 
  ENDIF	; _rx_update
 
@@ -417,7 +482,7 @@
 
 restart5:
 	; manage hardware
-	btfss	analog_o2_input					; OSTC with analog input?
+	btfss	ext_input_s8_ana				; OSTC with S8/analog input?
 	bsf		TRISB,3							; NO - shut down power supply for S8 bulkhead
 
 	btfss	battery_gauge_available			; OSTC with gauge IC?
@@ -429,14 +494,13 @@
 	call	get_battery_data				; YES - get last battery data
 
 	; 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 ?
+	btfsc	option_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
 
 	; set screen orientation
-	bcf		flip_screen						; set default screen orientation
+	bcf		flip_screen						; disable upside-down orientation by default
 	TSTOSC	opt_flip_screen					; shall show screen outputs upside down? (=1: flip the screen)
-	bsf		flip_screen						; YES - set upside-down orientation
+	bsf		flip_screen						; YES - enable upside-down orientation
 
 	; check if high-altitude mode is applicable
 	bcf		high_altitude_mode				; disable high altitude mode by default
@@ -455,39 +519,40 @@
 	banksel	common							;     - back to bank common
 
 restart6:
-	; the dive mode flag can not be set right after cold start, must have been in surface mode before
+	call	TFT_load_std_color_pallet	; load standard color pallet
 	btfsc	divemode						; shall enter dive mode?
-	goto	diveloop						; YES
-
-	btfsc	RCON,POR						; was this a power-on reset?
-	goto	surfloop						; NO  - enter surface mode
-	bsf		RCON,POR						; YES - acknowledge detection and re-arm detector
-	goto	do_new_battery_select			;     - prompt for battery selection, will proceed to surface mode
+	goto	diveloop						; YES - enter dive mode
+	btfsc	RCON,POR						; NO  - was this a power-on reset?
+	goto	surfloop						;       NO  - enter surface mode
+	bsf		RCON,POR						;       YES - acknowledge detection and re-arm detector
+	goto	new_battery_select				;           - prompt for battery selection, will proceed to surface mode
 
 
 ;=============================================================================
-; Setup all flags and parameters for dive mode and simulator computations
+boot4	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Setup of all Flags and Parameters for Dive Mode and Simulator Computations
 ;
 ; called from divemode.asm, menu_tree.asm and surfmode.asm
 ;
 	global	restart_set_modes_and_flags
 restart_set_modes_and_flags:
-	call	disable_ir_s8					; switch off IR/S8 digital interface by default (for all compile versions!)
+	call	disable_ir_s8_analog			; switch off IR/S8/analog interface by default (for all compile versions!)
 
  IFDEF _external_sensor
-	WAITMS	d'100'							; some delay to power down S8-HUD properly
+	WAITMS	d'100'							; wait 100 ms to S8-HUD powered down properly
  ENDIF
 
-	; setup sampling rate
+	; setup sampling rate for dice data recording
 	movlw	.2								; default to 2 seconds
-	movwf	sampling_rate					; write setting
-	TSTOSS	opt_sampling_rate				; check option: 1= 10s, 0= 2s
-	bra		restart_set_modes_and_flags1	; 0 - 2 seconds selected, done
+	TSTOSC	opt_sampling_rate				; check option: 0= 2s, 1= 10s
 	movlw	.10								; 1 - change to 10 seconds
-	movwf	sampling_rate					;   - write setting
+	movwf	sampling_rate					; store selection
 
-restart_set_modes_and_flags1:
-	clrf	DM_flags_deco					; clear all deco mode flags
+	; clear all deco mode flags
+	clrf	DM_flags_deco
 
 	; initialize active_gas and active_dil for surface mode pressure display
 	call	get_first_gas_to_WREG
@@ -507,10 +572,12 @@
 	movff	opt_desat_multiplier_non_gf,char_I_desaturation_multiplier	;     - ...
 
 restart_set_modes_and_flags2:
+
 	; configure GF settings, GF high is needed for color-coding the current GF (supersaturation) factor
 	movff	opt_GF_low, char_I_GF_Low_percentage
 	movff	opt_GF_high,char_I_GF_High_percentage
 
+	; dive mode specific setup
 	movff	opt_dive_mode,lo				; get dive mode: 0= OC, 1= CCR, 2= gauge, 3= apnea, 4= pSCR
 	tstfsz	lo								; OC?
 	bra		restart_set_modes_and_flags3	; NO
@@ -530,7 +597,7 @@
 	call	option_cleanup_oTrMode_CCR		;     - revert TR mode from 'ind.double' to 'on'
  ENDIF	; _rx_functions
  IFDEF _external_sensor
-	call	enable_ir_s8					;     - enable IR/S8 digital interface
+	call	enable_ir_s8_analog				;     - enable IR/S8/analog interface
  ENDIF	; _external_sensor
  ENDIF	; _ccr_pscr
 	return									;     - done
@@ -564,41 +631,11 @@
 	call	option_cleanup_oTrMode_no_CCR	;     - revert TR mode from 'CCR Dil+O2' to 'on'
  ENDIF	; _rx_functions
  IFDEF _external_sensor
-	call	enable_ir_s8					;     - enable IR/S8 digital interface
+	call	enable_ir_s8_analog				;     - enable IR/S8/analog interface
  ENDIF	; _external_sensor
  ENDIF	; _ccr_pscr
 	return									;     - done
 
-
-;=============================================================================
-; Sample and store the current surface pressure, update ISR and deco engine
-; with the surface pressure sampled on last invocation.
-;
-	global	sample_surface_pressure
-sample_surface_pressure:
-	; make sure the ISR does not read the surface pressure reference buffer while it is updated
-	bcf		update_surface_pressure			; cancel any pending load request
-
-	; propagate the surface pressure sampled on last invocation to the reference pressure buffer
-	MOVII	pressure_abs_sampled,pressure_abs_ref
-
-	; update surface pressure in the ISR
-	bsf		update_surface_pressure			; request ISR to update its surface pressure
+;-----------------------------------------------------------------------------
 
-	; update surface pressure in the deco engine
-	MOVII	pressure_abs_ref,int_I_pres_surface
-
-	; sample current absolute pressure (ISR-safe 2 byte copy)
-	SMOVII	pressure_abs,pressure_abs_sampled
-
-	; limit sampled pressure to max allowed surface pressure
-	MOVLI	max_surfpressure,    sub_a		; load upper limit    into sub_a
-	MOVII	pressure_abs_sampled,sub_b		; copy sampled pressure to sub_b
-	call	cmpU16							; sub_a - sub_b = max_surfpressure - pressure_abs_sampled
-	btfss	neg_flag						; sampled pressure > max_surfpressure ?
-	return									; NO  - below limit, done
-	MOVII	sub_a,pressure_abs_sampled		; YES - limit to max_surfpressure (still stored in sub_a)
-	return									;     - done
-
-
-	END
\ No newline at end of file
+	END
--- a/src/strings.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/strings.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File strings.asm                          combined next generation V3.03.5
+;   File strings.asm                        * combined next generation V3.09.4l
 ;
 ;   Implementation code various string functions.
 ;
@@ -15,218 +15,223 @@
 #include "varargs.inc"
 
 	extern	aa_wordprocessor
-
-strings	CODE
-
-;=============================================================================
-
-; Variants that call word_processor at the end
-	global	strcpy_block_print
-	global	strcat_block_print
-strcpy_block_print:
-	lfsr	FSR2,buffer
-strcat_block_print:
-	bsf		aa_aux_flag				; print afterwards
-	bra		strings_common
+	extern	text_1_base
+	extern	text_1_text
 
-; Variants that do not call word_processor at end
-	global	strcpy_block
-	global	strcat_block
-strcpy_block:
-	lfsr	FSR2,buffer
-strcat_block:
-	bcf		aa_aux_flag				; do not print afterwards
-	;bra	strings_common
-
-; Common part: append the string from PROM return address
-strings_common:
-	VARARGS_BEGIN
-		rcall	strcat_prom
-		VARARGS_ALIGN
-	VARARGS_END
-
-	btfss	aa_aux_flag				; shall we print?
-	return							; NO  - then return straight away
-	goto	aa_wordprocessor		; YES - print it...
+ IF _language_2 != none
+	extern	text_2_base
+	extern	text_2_text
+ ENDIF
 
 
 ;=============================================================================
-; Copy multi-lingual text from FSR1 12 bit pointer to buffer
-;
-; Input:   FSR1 = 12 bit pointer to multi-lingual text
-; Output:  FSR2 pointing to closing null byte in buffer
-; Trashed: TBLPTR, TABLAT
+strings		CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; to be used via Macro: Variants that call the Word Processor at the end
+;-----------------------------------------------------------------------------
 
-	global	strcpy_text
-strcpy_text:
-	rcall	text_get_tblptr
-	bra		strcpy_prom
+	global	strcpy_block_print
+	global	strcat_block_print
+strcpy_block_print:
+	lfsr	FSR2,buffer				; load pointer to buffer
+strcat_block_print:
+	bsf		aa_aux_flag				; call Word Processor
+	bra		strings_com_block_VARARG; continue with common part for VARARGS PROM texts
 
-; Copy and print multi-lingual text from FSR1 12 bit pointer to buffer
-;
-; Input:   FSR1 = 12 bit pointer to multi-lingual text
-; Output:  FSR2 pointing to closing null byte in buffer
-; Trashed: TBLPTR, TABLAT
 
 	global	strcpy_text_print
+	global	strcat_text_print
 strcpy_text_print:
-	rcall	text_get_tblptr
-	bra		strcpy_prom_print
-
-; Append multi-lingual text from FSR1 12 bit pointers to buffer at FRS2
-;
-; Input:   FSR1 = 12 bit pointer to multi-lingual text
-;          FSR2 = current position in buffer
-; Output:  FSR2 pointing to closing null byte in buffer
-; Trashed: TBLPTR, TABLAT
-
-	global	strcat_text
-strcat_text:
-	rcall	text_get_tblptr
-	bra		strcat_prom
-
-; Append and print multi-lingual text from FSR1 12 bit pointers to buffer at FRS2
-;
-; Input:   FSR1 = 12 bit pointer to multi-lingual text
-;          FSR2 = current position in buffer
-; Output:  FSR2 pointing to closing null byte in buffer
-; Trashed: TBLPTR, TABLAT
-
-	global	strcat_text_print
+	lfsr	FSR2,buffer				; load pointer to buffer
 strcat_text_print:
-	rcall	text_get_tblptr
-	bra		strcat_prom_print
+	bsf		aa_aux_flag				; call Word Processor
+	bra		strings_com_text_VARARG	; continue with common part for VARARGS multi-lingual texts
+
+
+	global	putc_print
+	global	print
+putc_print:
+	movwf	POSTINC2				; append the character to the string
+print:
+	bsf		aa_aux_flag				; call Word Processor
+	bra		strings_common_term		; append string terminator
+
+
+;-----------------------------------------------------------------------------
+; to be used via Macro: Variants that do not call the Word Processor at end
+;-----------------------------------------------------------------------------
+
+	global	strcpy_block
+	global	strcat_block
+strcpy_block:
+	lfsr	FSR2,buffer				; load pointer to buffer
+strcat_block:
+	bcf		aa_aux_flag				; do not call Word Processor
+	bra		strings_com_block_VARARG; continue with common part for VARARGS PROM texts
+
+
+	global	strcpy_text
+	global	strcat_text
+strcpy_text:
+	lfsr	FSR2,buffer				; load pointer to buffer
+strcat_text:
+	bcf		aa_aux_flag				; do not call Word Processor
+	bra		strings_com_text_VARARG	; continue with common part for VARARGS multi-lingual texts
+
 
-;=============================================================================
-; Get pointer to multilingual text in TBLPTR
+	global	strcpy_text_FSR
+	global	strcat_text_FSR
+strcpy_text_FSR:
+	lfsr	FSR2,buffer				; load pointer to buffer
+strcat_text_FSR:
+	bcf		aa_aux_flag				; do not call Word Processor
+	bra		strings_com_text_FSR	; continue with common part for FSR multi-lingual texts
+
+
+;-----------------------------------------------------------------------------
+; Common Parts for all above Functions
+;-----------------------------------------------------------------------------
+
+strings_com_block_VARARG:
+	VARARGS_BEGIN
+		rcall	strcat_prom			; append text to buffer
+		VARARGS_ALIGN				; word-align the table pointer
+	VARARGS_END
+	bra		strings_common_term		; continue with common part for all texts
+
+strings_com_text_VARARG:
+	VARARGS_BEGIN
+		rcall	text_get_fsr		; get pointer to multi-lingual text
+	VARARGS_END
+	;bra	strings_com_text_FSR	; continue with common part for FSR multi-lingual texts
+
+strings_com_text_FSR:
+	rcall	text_get_tblptr			; get pointer to translated text
+	rcall	strcat_prom				; append text to buffer
+	;bra	strings_common_term		; continue with common part for all texts
+
+strings_common_term:
+	clrf	INDF2					; append string terminator
+	btfss	aa_aux_flag				; shall call the Word Processor?
+	return							; NO  - done
+	goto	aa_wordprocessor		; YES - dump buffer to screen and return
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - get Pointer to multi-lingual Text into FSR1
 ;
-; Input:   FSR1         = 12 bit text handle
-;          opt_language = current language
-; Output:  TBLPTR       = 24 bit PROM address
+text_get_fsr:
+	tblrd*+							; get pointer, low  byte
+	movff	TABLAT,FSR1L			; store in FSR1L
+	tblrd*+							; get pointer, low  byte
+	movff	TABLAT,FSR1H			; store in FSR1H
+	return							; done
+
 
-	global	text_get_tblptr
+;-----------------------------------------------------------------------------
+; Helper Function - get Pointer to translated Text into TBLPTR
+;
+; Input:   FSR1         = pointer to multi-lingual text
+;          opt_language = selected language
+; Output:  TBLPTR       = 24 bit PROM address							0x09000  /  0x09400 -> problem
+;																		0x07000  /  0x07400 -> ok
 text_get_tblptr:
-	extern	text_1_base
-	movlw	UPPER(text_1_base)		; complete 12 bit address to 24 bit address
-	movwf	TBLPTRU
-	movlw	HIGH(text_1_base)
-	andlw	0xF0
-	iorwf	FSR1H,W
-	movwf	TBLPTRH
-	movff	FSR1L,TBLPTRL
+	; load TBLPTR with the index address of the selected text, expanded from 12 to 24 bit
+	movlw	UPPER(text_1_base)		; get address, upper byte  = 0x00 of   index base
+	movwf	TBLPTRU					; set TBLPTR,  upper byte to 0x00
+	movlw	HIGH(text_1_base)		; get address, high  byte  = 0x90 of   index base
+	iorwf	FSR1H,W					; add address, high  byte  = 0x0H from FSR1H
+	movwf	TBLPTRH					; set TBLPTR,  high  byte to 0x9H
+	movff	FSR1L,TBLPTRL			; set TBLPTR,  low   byte to 0xLL from FSR1L
 
- IF _language_2!=none
+ IF _language_2 != none
+	; adjust the index address in case language 2 is selected
 	movff	opt_language,WREG		; get language selection
-	bz		text_get_lang1			; 0: language 1
-	dcfsnz	WREG
-	bra		text_get_lang2			; 1: language 2
+	tstfsz	WREG					; language 2 selected ?
+	bsf		TBLPTRH,2				; YES - add offset (0x00400) between the index tables
  ENDIF
 
-text_get_lang1:						; read 2-byte pointer to string
-	tblrd*+
-	movff	TABLAT,WREG
-	tblrd*+
-	movff	WREG,TBLPTRL
-	movff	TABLAT,TBLPTRH
-	return
-
- IF _language_2!=none
-text_get_lang2:						; add offset for second language
-	extern	text_2_base
-	movlw	LOW(text_2_base)
-	addwf	TBLPTRL
-	movlw	HIGH(text_2_base)
-	addwfc	TBLPTRH
-	movlw	UPPER(text_2_base)
-	addwfc	TBLPTRU
+	; read the address of the translated text in 16 bit format
+	tblrd*+							; read   low  byte and buffer it in WREG
+	movff	TABLAT,WREG				; ...
+	tblrd*+							; read   high byte and keep   it in TABLAT
 
-	movlw	LOW(text_1_base)
-	subwf	TBLPTRL
-	movlw	HIGH(text_1_base)
-	subwfb	TBLPTRH
-	movlw	UPPER(text_1_base)
-	subwfb	TBLPTRU
-	bra		text_get_lang1
+	; load TBLPTR with the address of the translated text expanded to 24 bit
+	movff	WREG,  TBLPTRL			; set TBLPTR,  low   byte
+	movlw	UPPER(text_1_text)		; get address, upper byte of text table
+ IF _language_2 != none
+	btfsc	TBLPTRH,2				; using language 2?
+	movlw	UPPER(text_2_text)		; YES - get upper address of language 2
  ENDIF
+	movwf	TBLPTRU					; set TBLPTR,  upper byte
+	movff	TABLAT,TBLPTRH			; set TBLPTR,  high  byte
 
-;=============================================================================
-; Copy a null-terminated string from TBLPTR to buffer
-;
-; Input:   TBLPTR : string pointer into PROM
-; Output:  string in buffer, FSR2 pointing to the closing null byte
-;
-	global	strcpy_prom
-strcpy_prom:
-	lfsr	FSR2,buffer
-	;bra	strcat_prom
+	return							; done
+
 
-; Append a null-terminated string from TBLPTR to buffer
+;-----------------------------------------------------------------------------
+; Helper Function - append a null-terminated String from TBLPTR to Buffer
 ;
 ; Input:   TBLPTR : string pointer into PROM
 ;          FRS2   : current character position
 ; Output:  string in buffer, FSR2 pointing to the closing null byte
 ;
-	global	strcat_prom
 strcat_prom:
-	tblrd*+							; read a character from PROM
-	movf	TABLAT,W				; transfer character to   WREG
-	movwf	POSTINC2				; transfer character from WREG to output buffer and increment buffer pointer
-	bnz		strcat_prom				; last character = NULL ? NO  - loop
-	movf	POSTDEC2,W				;                         YES - step back one char
-	return							;                             - done
+	tblrd*+							; read one character from PROM
+	movf	TABLAT,W				; copy character to WREG
+	movwf	POSTINC2				; copy from WREG to buffer and increment buffer pointer
+									; was character = NULL ?
+	bnz		strcat_prom				; NO  - loop
+	movf	POSTDEC2,W				; YES - dummy read to step back buffer pointer by 1
+	return							;     - done
 
-;=============================================================================
-; Variant that calls word processor right-away...
 
-	global	strcpy_prom_print
-	global	strcat_prom_print
-strcpy_prom_print:
-	lfsr	FSR2,buffer
-strcat_prom_print:
-	rcall	strcat_prom
-	goto	aa_wordprocessor
-
-;=============================================================================
-
+;-----------------------------------------------------------------------------
+; to by used via Macro: set Font Size and Output Position in one Batch
+;
 	global	start_tiny_block
 start_tiny_block:
-	clrf	WREG
-	bra		start_common
+	movlw	.0						; set size encoding
+	bra		start_block_common		; start block
 
 	global	start_small_block
 start_small_block:
-	movlw	1
-	bra		start_common
+	movlw	.1						; set size encoding
+	bra		start_block_common		; start block
 
 	global	start_std_block
 start_std_block:
-	movlw	2
-	bra		start_common
+	movlw	.2						; set size encoding
+	bra		start_block_common		; start block
 
 	global	start_medium_block
 start_medium_block:
-	movlw	3
-	bra		start_common
+	movlw	.3						; set size encoding
+	bra		start_block_common		; start block
 
 	global	start_large_block
 start_large_block:
-	movlw	4
-	bra		start_common
+	movlw	.4						; set size encoding
+	bra		start_block_common		; start block
 
 	global	start_huge_block
 start_huge_block:
-	movlw	5
-	;bra	start_block_common
+	movlw	.5						; set size encoding
+	;bra	start_block_common		; start block
 
-
-start_common:
-	movff	WREG,win_font			; needs a bank-safe move here !
+start_block_common:
+	movff	WREG,font_size			; needs a bank-safe move here! (TODO: why?)
 
 	VARARGS_BEGIN
-		VARARGS_GET8	win_leftx2
-		VARARGS_GET8	win_top
+		VARARGS_GET8	win_leftx2	; get horizontal position
+		VARARGS_GET8	win_top		; get vertical position
 	VARARGS_END
-	lfsr	FSR2,buffer				; point to buffer
-	return
+
+	lfsr	FSR2,buffer				; initialize output buffer
+	return							; done
 
-	END
\ No newline at end of file
+;-----------------------------------------------------------------------------
+
+	END
--- a/src/strings.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/strings.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File strings.asm                          combined next generation V3.03.5
+;   File strings.inc                        * combined next generation V3.08.5
 ;
 ;   Implementation code various string functions
 ;
@@ -10,206 +10,199 @@
 ;   2010-12-02 : [jDG] Creation
 ;
 
-;=============================================================================
-; Copy a short embedded string to the start of the string buffer
-; Input  : string after macro name
-; Output : chars are copied to the start of the string buffer
-;          FSR2 points to the first unused char containing the NULL termination
-; Trashed: WREG, TBLPTR, TABLAT, PRODL
-; Note   : uses bank-safe calls only
+
+;-----------------------------------------------------------------------------
+; Initialize the Buffer
+;
+INIT_BUFFER	macro
+	lfsr	FSR2,buffer				; load FSR2 with base address of the buffer
+	endm
+
+
+;-----------------------------------------------------------------------------
+; Re-Initialize the Buffer 
 ;
-	extern	strcpy_block
-STRCPY macro string
-	call	strcpy_block
-	DB		string, 0
+REINIT_BUFFER macro
+	clrf	FSR2L					; reset the buffer pointer
+	endm
+
+
+;-----------------------------------------------------------------------------
+; Font Size Selection
+;
+FONT_SIZE	macro	font_size_input
+	movlw	font_size_input
+	movwf	font_size
+	endm
+
+
+;-----------------------------------------------------------------------------
+; Dump the Buffer to Screen
+;
+PRINT		macro
+	extern	print
+	call	print					; append terminator to buffer and print buffer
 	endm
 
-;=============================================================================
-; A variant of STRCPY that appends chars in the string buffer at the current
-; FSR2 pointer position
-; Input/Output/Trashed: see STRCPY
+
+;-----------------------------------------------------------------------------
+; Macros to print embedded (untranslated) Texts
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; Copy an embedded (untranslated) Text to the Buffer
 ;
-	extern	strcat_block
-STRCAT macro string
-	call	strcat_block
-	DB		string, 0
+STRCPY		macro string
+	extern	strcpy_block
+	call	strcpy_block			; copy text to buffer
+	DB		string, 0				; inline text with terminator
 	endm
 
-;=============================================================================
-; A variant of STRCAT when there is just on char to output
-; Input/Output/Trashed: see STRCPY
+
+;-----------------------------------------------------------------------------
+; Append an embedded (untranslated) Text to the Buffer
 ;
-PUTC macro	char
-	movlw	char
-	movwf	POSTINC2
+STRCAT		macro string
+	extern	strcat_block
+	call	strcat_block			; append text to buffer
+	DB		string, 0				; inline text with terminator
 	endm
 
-;=============================================================================
-; A variant of STRCPY that sends the string to the word processor afterwards
-; Input/Output: see STRCPY
-; Trashed     : see STRCPY + word_processor. In particular, switches RAM to Bank1
+
+;-----------------------------------------------------------------------------
+; Append a single Character to the Buffer
 ;
-	extern  strcpy_block_print
-STRCPY_PRINT macro string
-	call	strcpy_block_print
-	DB		string, 0
+PUTC		macro	char
+	movlw	char					; get character into WREG
+	movwf	POSTINC2				; append character to buffer
+	endm
+
+
+;-----------------------------------------------------------------------------
+; Append a single Character to the Buffer and dump the Buffer to Screen
+;
+PUTC_PRINT	macro	char
+	extern	putc_print
+	movlw	char					; get character into WREG
+	call	putc_print				; append charcator to buffer and print whole buffer
 	endm
 
-;=============================================================================
-; A variant of STRCAT that sends the string to the word processor afterwards
-; Input/Output: see STRCAT
-; Trashed     : see STRCPY + word_processor. In particular, switches RAM to Bank1
+
+;-----------------------------------------------------------------------------
+; Copy an embedded Text to the Start of the Buffer and dump the Buffer to Screen
 ;
-	extern	strcat_block_print
-STRCAT_PRINT macro string
-	call	strcat_block_print
-	DB		string, 0
+STRCPY_PRINT macro string
+	extern  strcpy_block_print
+	call	strcpy_block_print		; copy text to buffer and print whole buffer
+	DB		string, 0				; inline text with terminator
 	endm
 
-;=============================================================================
-; Subroutines to operate on strings from PROM code
+
+;-----------------------------------------------------------------------------
+; Append an embedded Text to the Content of the Buffer and dump the Buffer to Screen
 ;
-; Input  : TBLPTR : string pointer into PROM
-; Trashed: FSR1
-; Output : string in buffer, FSR2 pointer on the closing null byte
-
-	extern	strcpy_prom,       strcat_prom
-	extern	strcpy_prom_print, strcat_prom_print
-
-;=============================================================================
-; Subroutines and macros to operate on multilingual text
-;
-	extern	strcpy_text
-STRCPY_TEXT macro txt
-	extern	txt
-	lfsr	FSR1, txt
-	call	strcpy_text
+STRCAT_PRINT macro string
+	extern	strcat_block_print
+	call	strcat_block_print		; append text to buffer and print whole buffer
+	DB		string, 0				; inline text with terminator
 	endm
 
-	extern	strcpy_text_print
-STRCPY_TEXT_PRINT macro txt
+
+;-----------------------------------------------------------------------------
+; Functions for direct printing of multi-lingual Texts pointed to by FSR1
+;-----------------------------------------------------------------------------
+
+	extern	strcpy_text_FSR			; translate and copy   text to buffer
+	extern	strcat_text_FSR			; translate and append text to buffer
+
+
+;-----------------------------------------------------------------------------
+; Macros to print multi-lingual (translated) Texts
+;-----------------------------------------------------------------------------
+
+;-----------------------------------------------------------------------------
+; Copy a multi-lingual Text to the Start of the Buffer
+;
+STRCPY_TEXT	macro txt
+	extern	strcpy_text
 	extern	txt
-	lfsr	FSR1, txt
-	call	strcpy_text_print
-	endm
-
-	extern	strcat_text
-STRCAT_TEXT macro txt
-	extern	txt
-	lfsr	FSR1, txt
-	call	strcat_text
+	call	strcpy_text				; translate and copy text to buffer
+	DB		LOW(txt), HIGH(txt)
 	endm
 
-	extern	strcat_text_print
-STRCAT_TEXT_PRINT macro txt
+
+;-----------------------------------------------------------------------------
+; Append a multi-lingual Text to the Content of the Buffer
+;
+STRCAT_TEXT	macro txt
+	extern	strcat_text
 	extern	txt
-	lfsr	FSR1, txt
-	call	strcat_text_print
+	call	strcat_text				; translate and append text to buffer
+	DB		LOW(txt), HIGH(txt)
 	endm
 
-;=============================================================================
-; A shortcut for the macros WIN_TOP + WIN_LEFT + WIN_FONT
-; The idea is to replace a 4x6=24 bytes sequence by a more compact 6 bytes one.
+
+;-----------------------------------------------------------------------------
+; Copy a multi-lingual Text to the Start of the Buffer and dump the Buffer to Screen
+;
+STRCPY_TEXT_PRINT macro txt
+	extern	strcpy_text_print
+	extern	txt
+	call	strcpy_text_print		; translate and copy text to buffer, then dump buffer to screen
+	DB		LOW(txt), HIGH(txt)
+	endm
+
+
+;-----------------------------------------------------------------------------
+; Append a multi-lingual Text to the Content of the Buffer and dump the Buffer to Screen
 ;
-; Trashed: TBLPTR, TABLAT, WREG.
-; Note   : uses bank-safe calls only
-;
+STRCAT_TEXT_PRINT macro txt
+	extern	strcat_text_print
+	extern	txt
+	call	strcat_text_print		; translate and copy text to buffer, then dump buffer to screen
+	DB		LOW(txt), HIGH(txt)
+	endm
+
+
+;-----------------------------------------------------------------------------
+; Macros to set Font Size and Output Position in one Batch
+;-----------------------------------------------------------------------------
+
+WIN_TINY	macro x, y
 	extern	start_tiny_block
-WIN_TINY macro x, y
 	call	start_tiny_block
 	DB		x, y
 	endm
 
+WIN_SMALL	macro x, y
 	extern	start_small_block
-WIN_SMALL macro x, y
 	call	start_small_block
 	DB		x, y
 	endm
 
+WIN_STD		macro x, y
 	extern	start_std_block
-WIN_STD macro x, y
 	call	start_std_block
 	DB		x, y
 	endm
 
+WIN_MEDIUM	macro x, y
 	extern	start_medium_block
-WIN_MEDIUM macro x, y
 	call	start_medium_block
 	DB		x, y
 	endm
 
+WIN_LARGE	macro x, y
 	extern	start_large_block
-WIN_LARGE macro x, y
 	call	start_large_block
 	DB		x, y
 	endm
 
+WIN_HUGE	macro x, y
 	extern	start_huge_block
-WIN_HUGE macro x, y
 	call	start_huge_block
 	DB		x, y
 	endm
 
-;=============================================================================
-; Shortcuts for compact display programmings
-;
-TEXT_TINY macro x, y, txt
-	WIN_TINY x,y
-	STRCPY_TEXT_PRINT txt
-	endm
-
-TEXT_SMALL macro x, y, txt
-	WIN_SMALL x,y
-	STRCPY_TEXT_PRINT txt
-	endm
-
-TEXT_SMALL_INVERT macro x, y, txt
-	WIN_SMALL_INVERT x,y
-	STRCPY_TEXT_PRINT txt
-	endm
-
-TEXT_STD macro x, y, txt
-	WIN_STD x,y
-	STRCPY_TEXT_PRINT txt
-	endm
-
-TEXT_MEDIUM macro x, y, txt
-	WIN_MEDIUM x,y
-	STRCPY_TEXT_PRINT txt
-	endm
+;-----------------------------------------------------------------------------
 
-TEXT_LARGE macro x, y, txt
-	WIN_LARGE x,y
-	STRCPY_TEXT_PRINT txt
-	endm
-
-TEXT_HUGE macro x, y, txt
-	WIN_HUGE x,y
-	STRCPY_TEXT_PRINT txt
-	endm
-
-
-STRING_TINY macro x, y, string
-	WIN_SMALL x,y
-	STRCPY_PRINT string
-	endm
-
-STRING_SMALL macro x, y, string
-	WIN_SMALL x,y
-	STRCPY_PRINT string
-	endm
-
-STRING_MEDIUM macro x, y, string
-	WIN_MEDIUM x,y
-	STRCPY_PRINT string
-	endm
-
-STRING_LARGE macro x, y, string
-	WIN_LARGE x,y
-	STRCPY_PRINT string
-	endm
-
-STRING_HUGE macro x, y, string
-	WIN_HUGE x,y
-	STRCPY_PRINT string
-	endm
--- a/src/surfmode.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/surfmode.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File surfmode.asm                         next combined generation V3.08.8
+;   File surfmode.asm                       * next combined generation V3.09.5
 ;
 ;   Surface Mode
 ;
@@ -9,36 +9,36 @@
 ; HISTORY
 ; 2011-08-07 : [mH] moving from OSTC code
 
-#include "hwos.inc"					; Mandatory header
-#include "shared_definitions.h"		; Mailbox from/to p2_deco.c
+#include "hwos.inc"					; mandatory header
+#include "shared_definitions.h"		; mailbox from/to p2_deco.c
 #include "start.inc"
 #include "tft.inc"
 #include "tft_outputs.inc"
 #include "adc_lightsensor.inc"
-#include "menu_processor.inc"
 #include "strings.inc"
 #include "sleepmode.inc"
 #include "wait.inc"
-#include "external_flash.inc"
 #include "customview.inc"
 #include "divemode.inc"
-#include "mcp.inc"					; RX
 #include "i2c.inc"
 #include "comm.inc"
-#include "eeprom_rs232.inc"
+#include "colorschemes.inc"
+
+ IFDEF _rx_functions
+#include "rx_ops.inc"
+ ENDIF
+
+ IFDEF _external_sensor
 #include "calibrate.inc"
-#include "rx_ops.inc"
+ ENDIF
 
 
-	extern	do_main_menu
-	extern	check_cns_violation
-	extern	check_warn_battery
-	extern	check_and_store_sat_violation
+	extern	main_menu
+	extern	check_cns_violation_now
+	extern	check_battery
+	extern	check_saturation
 	extern	check_mbubbles
 
- IFDEF _osct_logo
-	extern	ostc_logo_block
- ENDIF
 
  IFDEF _compass
 	extern	TFT_surface_compass_heading
@@ -57,115 +57,108 @@
 #DEFINE view_row			.215
 #DEFINE view_column			.124
 
-
-sfmode	CODE
+;=============================================================================
+sfmode1		CODE
+;=============================================================================
 
-;=============================================================================
-; Boot tasks for all modes
+;-----------------------------------------------------------------------------
+; Entry Point for Surface Mode
 ;
 ; called after restart via the battery selection, after compass calibration,
 ; and via ghostwriter at the end of a dive
 ;
 	global	surfloop
 surfloop:
-	clrf	STKPTR					; clear return addresses stack
-;	clrf	CCP1CON					; stop PWM
-;	bcf		PORTC,2					; pull PWM output to GND
-;	clrf	CCPR1L					; backlight off
-	call	TFT_boot				; initialize TFT (includes clear screen)
+	clrf	STKPTR						; clear return addresses stack
+;	clrf	CCP1CON						; stop PWM
+;	bcf		PORTC,2						; pull PWM output to GND
+;	clrf	CCPR1L						; backlight off
+	call	TFT_boot					; initialize TFT (includes clear screen)
 
-	btfsc	restart_fast			; shall make a fast restart?
-	bra		surfloop_1				; YES
+	btfsc	restart_fast				; shall make a fast restart?
+	bra		surfloop_1					; YES
 
 	; show heinrichsweikamp logo
 	WIN_TOP  .40
 	WIN_LEFT .10
 	TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block
 
+	; set font color
+	FONT_COLOR color_white
+
 	; show textual OSTC logo
-	WIN_COLOR color_white
-	WIN_STD .30,.90					; column, row
-	STRCPY_PRINT "Open Source"		; show OSTC banner text, line 1
-	WIN_STD .20,.130				; column, row
-	STRCPY_PRINT "Tauch-Computer"	; show OSTC banner text, line 2
+	WIN_STD .30,.90						; column, row
+	STRCPY_PRINT "Open Source"			; show OSTC banner text, line 1
+	WIN_STD .20,.130					; column, row
+	STRCPY_PRINT "Tauch-Computer"		; show OSTC banner text, line 2
 
-	WIN_COLOR color_white
+	; show firmware version
 	WIN_SMALL .35,.180
-	PUTC	"v"						; print v
-	call	TFT_cat_firmware		; print  x.y
-	PUTC	" "						; print     _
-	call	TFT_cat_beta_release	; print      BetaZ or Release
-	STRCAT_PRINT ""					; finalize output
-	bcf		win_invert				; clean up eventual color-coding
-	call	TFT_standard_color		; ditto
-	call	TFT_Display_FadeIn		; dim up the display
+	PUTC	"v"							; print "v"
+	call	TFT_print_firmware			; print full firmware version (may change the font color)
+	call	TFT_Display_FadeIn			; dim up the display
 
 surfloop_1:
-	;---- Do all useful initializations that take time -----------------------
+
+	;---- do all useful initializations that take time -----------------------
 
 	; set deco mode flags
 	call	restart_set_modes_and_flags
 
-	bsf		trigger_pres_cur_changed; set flag to have pressure    written to display on first round of surface loop
-	bsf		trigger_temp_changed	; set flag to have temperature written to display on first round of surface loop
+	bsf		trigger_pres_cur_changed	; set flag to have pressure    written to display on first round of surface loop
+	bsf		trigger_temp_changed		; set flag to have temperature written to display on first round of surface loop
 
-	call	I2C_sleep_compass		; shut down compass
-
-	CLRT	ext_flash_address
-
+	call	I2C_sleep_compass			; shut down compass
 
  IFDEF _ccr_pscr
-	movlw	surface_sp				; load default surface setpoint (in cbar)
-	movff	WREG,char_I_const_ppO2	; store it as current setpoint
+	movlw	surface_sp					; load default surface setpoint (in cbar)
+	movff	WREG,char_I_const_ppO2		; store it as current setpoint
  ENDIF
 
  IFDEF _external_sensor
-	call	transmit_setpoint		; transmit current setpoint (in cbar) via S8 digital interface (currently disabled)
+	call	transmit_setpoint			; transmit current setpoint (in cbar) via S8 digital interface (currently disabled)
  ENDIF
 
-	bcf		surfmode_menu			; not in surface menu (any more)
-	bcf		compass_menu			; not in "set bearing" selection (any more)
+	bcf		surfmode_menu				; not in surface menu (any more)
+	bcf		compass_menu				; not in "set bearing" selection (any more)
 
-	bcf		switch_left				; clear intermediate button event since start/restart
-	bcf		switch_right			; clear intermediate button event since start/restart
+	bcf		switch_left					; clear intermediate button event since start/restart
+	bcf		switch_right				; clear intermediate button event since start/restart
 
-	btfsc	restart_fast			; shall make a fast restart?
-	bra		surfloop_2				; YES
+	btfsc	restart_fast				; shall make a fast restart?
+	bra		surfloop_2					; YES
 
 	call	deco_calc_desaturation_time	; calculate desaturation and no-fly/no-altitude time (C-code)
 	banksel	common						; back to bank common
 
-	call	wait_1s					; wait <= 1 second
-	call	wait_1s					; wait    1 second
-	call	wait_1s					; wait    1 second
+	WAITS	.2							; wait 2 seconds
 
-	;---- Fade to standard surface view --------------------------------------
+	;---- fade to standard surface view --------------------------------------
 
-	call	TFT_Display_FadeOut		; dim down display to black screen
-	call	TFT_ClearScreen			; clear screen
+	call	TFT_Display_FadeOut			; dim down display to black screen
+	call	TFT_ClearScreen				; clear screen
 
 surfloop_2:
-	WIN_TOP  .0
-	WIN_LEFT .0
-	WIN_FONT FT_SMALL
-	bcf		win_invert				; clear flag for inverted text
+
+	call	TFT_load_std_color_pallet	; load standard color pallet
+
+	;---- button functionalities ---------------------------------------------
 
-	; show button functionalities
-	WIN_COLOR			color_lightblue
-	WIN_SMALL			menu_pos_column,menu_pos_row
-	STRCPY_TEXT_PRINT	tMenu							; show "<Menu"
-	WIN_SMALL			view_column,view_row
-	STRCPY_TEXT_PRINT	tView							; show "View>"
-	call				TFT_standard_color
+	FONT_COLOR			color_lightblue					; set font color
+	WIN_SMALL			menu_pos_column,menu_pos_row	; set font size and output position
+	STRCPY_TEXT_PRINT	tMenu							; print "<Menu"
+	WIN_SMALL			view_column,view_row			; set font size and output position
+	STRCPY_TEXT_PRINT	tView							; print "View>"
 
 
-	;---- Logo in upper right corner -----------------------------------------
+	;---- logo in upper right corner -----------------------------------------
 
 	; show textual OSTC logo
-	WIN_COLOR color_white				; set text color to white
 	WIN_STD .100,.2						; set output position
+	FONT_COLOR color_white				; set text color to white
 	STRCPY_PRINT "OSTC"					; show "OSTC"
-	WIN_COLOR color_cyan				; set text color to cyan
+
+	FONT_COLOR color_cyan				; set text color to cyan
 	WIN_TINY .138,.2					; set output position
 	STRCPY_PRINT "hwOS"					; show "hwOS"
 	WIN_TINY .137,.14					; set output position
@@ -174,138 +167,77 @@
  ELSE
 	STRCPY_PRINT "tech"					; show "tech"
  ENDIF
+
+	; firmware version
 	WIN_TINY .100,.32					; set output position
-	call	TFT_show_firmware			; show firmware version
+	FONT_COLOR color_white				; set text color to white
+	call	TFT_print_firmware			; show firmware version (long format)
 
 
 	;---- fill screen --------------------------------------------------------
-	call	get_battery_voltage				; get battery voltage
-	call	TFT_batt_surfmode				; display battery voltage
-	call	TFT_time_surfmode				; display time
-	call	TFT_date_surfmode				; display date
-	call	TFT_pres_surfmode				; display surface pressure
-	call	TFT_temp_surfmode				; display temperature
-	call	TFT_decotype_surface			; display deco mode
 
-	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
+	call	get_battery_voltage			; get battery voltage
+	call	TFT_surfmode_batt			; show battery voltage
+	call	TFT_surfmode_time			; show time
+	call	TFT_surfmode_date			; show date
+	call	TFT_surfmode_pres			; show surface pressure
+	call	TFT_surfmode_temp			; show temperature
+	call	TFT_surfmode_decotype		; show deco mode
+
+	TSTOSS	opt_dive_mode				; in OC? (0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=pSCR)
+	call	TFT_surfmode_startgas		; 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
+	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
+	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
+	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
 
-	call	TFT_Display_FadeIn				; display resulting surface screen
+	call	TFT_Display_FadeIn			; show resulting surface screen
 
  IFDEF _screendump
-	btfsc	screen_dump_avail				; screen dump function enabled?
-	call	enable_rs232					; YES - activate RS232 (also sets CPU to normal speed)
+	btfsc	screen_dump_avail			; screen dump function enabled?
+	call	enable_rs232				; YES - activate RS232 (also sets CPU to normal speed)
  ENDIF
 
-	bcf		restart_fast					; clear flag for fast restart
-	bsf		imprint_surfmode_data			; start imprinting surface mode data
+	bcf		restart_fast				; clear flag for fast restart
+	bsf		imprint_surfmode_data		; start imprinting surface mode data
 
-	bcf		switch_left						; clear pending left  button event
-	bcf		switch_right					; clear pending right button event
+	bcf		switch_left					; clear pending left  button event
+	bcf		switch_right				; clear pending right button event
 
-	rcall	reset_timeout_surfmode			; reset timeout
+	rcall	reset_timeout_surfmode		; reset timeout
 
 surfloop_loop:
-;	call	TFT_debug_output				; optional debug output
+;	call	TFT_debug_output			; optional debug output
 
-	call	test_switches_surfmode			; check switches
+	call	test_switches_surfmode		; check switches
 
-	btfsc	request_next_custview			; shall show next custom view?
-	call	surf_customview_toggle			; YES - show next custom view (and clear this flag)
+	btfsc	request_next_custview		; shall show next custom view?
+	call	surf_customview_toggle		; YES - show next custom view (and clear this flag)
 
-	btfss	surfmode_menu					; shall enter surface menu?
-	bra		surfloop_loop_1					; NO
-	bcf		imprint_surfmode_data			; YES - stop imprinting surface mode data
-	goto	do_main_menu					;     - goto surface menu
+	btfss	surfmode_menu				; shall enter surface menu?
+	bra		surfloop_loop_1				; NO
+	bcf		imprint_surfmode_data		; YES - stop imprinting surface mode data
+	goto	main_menu					;     - goto surface menu
 
 surfloop_loop_1:
-	rcall	housekeeping					; handle data imprinting, screen dump request, timeout and entering dive mode
-	bra		surfloop_loop					; loop in surface mode
+	call	housekeeping				; handle data imprinting, screen dump request, timeout and entering dive mode
+	bra		surfloop_loop				; loop in surface mode
 
 
-surfmode_check_for_warnings:
-	clrf	message_counter					; clear message counter
-
-	; warnings for all modes
-	call	check_warn_battery				; check if the battery level should be displayed/warned
-
-	btfsc	FLAG_apnoe_mode					; done for Apnoe or Gauge mode
-	bra		surfmode_check_for_warnings2
-	btfsc	FLAG_gauge_mode					; done for Apnoe or Gauge mode
-	bra		surfmode_check_for_warnings2
-
-	; warnings only in deco modes
-	call	check_and_store_sat_violation	; check/show tissue saturation
-	call	check_cns_violation				; check/show CNS value
-	call	check_mbubbles					; check/show micro bubbles warning
-	movff	int_O_lead_supersat+1,WREG		; get upper byte of leading tissue's supersaturation
-	btfsc	WREG,int_warning_flag			; check if the warning flag is set
-	bra		surfmode_check_for_warnings2	; YES - outside model
-	rcall	surfmode_check_for_desat		; NO  - check/display desaturation time
-	rcall	surfmode_check_for_nofly		; NO  - check/display no-fly       time
-
-surfmode_check_for_warnings2:
-	; setup message page number
-	incf	message_page,F					; increment page number
-	bcf		STATUS,C						; clear carry bit
-	rlcf	message_page,W					; each page can take two messages
-	cpfsgt	message_counter					; number of actual messages > message capacity ?
-	clrf	message_page					; NO - all messages could be shown, restart from first page next time
-
-	; clear both rows if there is nothing to show at all
-	tstfsz	message_counter					; any message to show?
-	bra		surfmode_check_for_warnings3	; YES - look if second row needs to be cleared
-	goto	TFT_clear_message_window		; NO  - clear complete message area and return
-
-surfmode_check_for_warnings3:
-	; clear 2nd row of messages if there is nothing to show (on this page)
-	btfss	message_2nd_row_used			; does the 2nd row contain a message?
-	goto	TFT_clear_message_window_row2	; NO  - clear the 2nd row and return
-	return									; YES - done
-
-
-surfmode_check_for_desat:
-	banksel	int_O_desaturation_time
-	movf	int_O_desaturation_time+0,W
-	iorwf	int_O_desaturation_time+1,W
-	banksel	common							; back to bank common
-	bnz		surfmode_check_for_desat_1		; is the desat-time > 0 ?
-	return									; NO  - done
-surfmode_check_for_desat_1:
-	incf	message_counter,F				; YES - increase counter
-	call	TFT_desaturation_time			;     - show desaturation time
-	return									;     - done
-
-surfmode_check_for_nofly:
-	banksel	int_O_nofly_time
-	movf	int_O_nofly_time+0,W
-	iorwf	int_O_nofly_time+1,W
-	banksel	common							; back to bank common
-	bnz		surfmode_check_for_nofly_1		; is the nofly-time > 0 ?
-	return									; NO  - done
-surfmode_check_for_nofly_1:
-	incf	message_counter,F				; YES - increase counter
-	call	TFT_nofly_time					;     - show nofly-time
-	return									;     - done
-
-
-;=============================================================================
-
+;-----------------------------------------------------------------------------
+; Surface Mode HMI Operations
+;
 test_switches_surfmode:					; check buttons in surface mode
 	btfsc	switch_right				; right button pressed?
 	bra		test_switches_surfmode2		; YES
@@ -340,7 +272,7 @@
 	bra		test_switches_surfmode3a	; NO
 	btfsc	compass_menu				; YES - "set course" selection already shown?
 	bra		test_switches_surfmode3b	;       YES - remove it
-	call	TFT_surf_set_bearing		;       NO  - show it
+	call	TFT_surf_cv_compass_bearing		;       NO  - show it
 	return								;           - done
  ENDIF
 test_switches_surfmode3a:
@@ -356,50 +288,160 @@
  ENDIF
 
 
-	; handle data imprinting, screen dump request, timeout and entering dive mode
+;-----------------------------------------------------------------------------
+; Helper Function - Reset and Restart Timeout for Surface Mode
+;
+	global	reset_timeout_surfmode
+reset_timeout_surfmode:
+	movlw	surfmode_timeout_default	; load default timeout value
+	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
+	;bra	restart_timeout_time		; restart timeout
+
+	global	restart_timeout_time
+restart_timeout_time:					; entry point with timeout value in WREG
+	movwf	isr_timeout_reload			; copy WREG to isr_timeout_reload
+	bsf		restart_timeout				; request ISR to restart the timeout
+	bcf		trigger_timeout				; clear any pending timeout trigger
+	return								; done
+
+
+;=============================================================================
+sfmode2		CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Helper Function - Check all possible Surface Mode Warning Conditions
+;
+surfmode_check_warnings:
+	clrf	message_counter				; clear message counter
+
+	; warnings for all modes
+	call	check_battery				; check if the battery level should be displayed/warned
+
+	btfsc	FLAG_apnoe_mode				; done for Apnoe or Gauge mode
+	bra		surfmode_check_warnings2
+	btfsc	FLAG_gauge_mode				; done for Apnoe or Gauge mode
+	bra		surfmode_check_warnings2
+
+	; warnings only in deco modes
+	call	check_saturation			; check/show tissue saturation
+	call	check_cns_violation_now		; check/show current CNS value
+	call	check_mbubbles				; check/show micro bubbles
+	movff	int_O_lead_supersat+1,WREG	; get upper byte of leading tissue's supersaturation
+	btfsc	WREG,int_warning_flag		; check if the warning flag is set
+	bra		surfmode_check_warnings2	; YES - outside of the model
+	rcall	surfmode_check_for_desat	; NO  - check/show desaturation time
+	rcall	surfmode_check_for_nofly	;     - check/show no-fly       time
+
+surfmode_check_warnings2:
+	; setup message page number
+	incf	message_page,F				; increment page number
+	bcf		STATUS,C					; clear carry bit
+	rlcf	message_page,W				; each page can take two messages
+	cpfsgt	message_counter				; number of actual messages > message capacity ?
+	clrf	message_page				; NO - all messages could be shown, restart from first page next time
+
+	; clear both rows if there is nothing to show at all
+	tstfsz	message_counter				; any message to show?
+	bra		surfmode_check_warnings3	; YES - look if second row needs to be cleared
+	goto	TFT_clear_message_window	; NO  - clear complete message area and return
+
+surfmode_check_warnings3:
+	; clear 2nd row of messages if there is nothing to show (on this page)
+	btfss	message_2nd_row_used			; does the 2nd row contain a message?
+	goto	TFT_clear_message_window_row2	; NO  - clear the 2nd row and return
+	return									; YES - done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - check if still in Desaturation, if yes show a Message
+;
+surfmode_check_for_desat:
+	banksel	int_O_desaturation_time
+	movf	int_O_desaturation_time+0,W
+	iorwf	int_O_desaturation_time+1,W
+	banksel	common						; back to bank common
+	bnz		surfmode_check_for_desat_1	; is the desat-time > 0 ?
+	return								; NO  - done
+surfmode_check_for_desat_1:
+	incf	message_counter,F			; YES - increase counter
+	call	TFT_surf_mesg_desat		;     - show desaturation time
+	return								;     - done
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - check if still in no-fly, if yes show a Message
+;
+surfmode_check_for_nofly:
+	banksel	int_O_nofly_time
+	movf	int_O_nofly_time+0,W
+	iorwf	int_O_nofly_time+1,W
+	banksel	common						; back to bank common
+	bnz		surfmode_check_for_nofly_1	; is the nofly-time > 0 ?
+	return								; NO  - done
+surfmode_check_for_nofly_1:
+	incf	message_counter,F			; YES - increase counter
+	call	TFT_surf_mesg_nofly				;     - show nofly-time
+	return								;     - done
+
+
+;=============================================================================
+sfmode3		CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Data Imprinting, Screen Dump request, Timeout and Entering Dive Mode
+;
 	global	housekeeping
 housekeeping:
 	btfss	trigger_full_second			; new 1/1 second begun?
 	bra		housekeeping_1				; NO
 
-	; tasks any new second
+	;---- tasks any new second ---------
+
 	bcf		trigger_full_second			; YES - clear flag
 	call	get_battery_voltage			;     - get battery voltage
 
 	btfsc	imprint_time_date			;     - shall imprint the current time & date?
-	call	TFT_show_time_date_menu		;       YES - imprint time and date on display (copies running time to latch registers)
+	call	TFT_imprint_time_date		;       YES - imprint time and date on display (copies running time to latch registers)
+
+	btfsc	imprint_color_schemes		;     - shall imprint color scheme demo?
+	call	TFT_imprint_color_schemes	;       YES - update the color schemes
 
  IFDEF _rx_functions
 	btfsc	tr_functions_activated		;     - TR functions activated?
 	call	I2C_get_tankdata			;       YES - get new transmitter data
 
 	btfsc	imprint_xmitter_pres		;     - shall imprint transmitter ID and pressure?
-	call	TFT_menu_tank_pres			;       YES - imprint transmitter ID and pressure
+	call	TFT_imprint_tank_pres		;       YES - imprint transmitter ID and pressure
  ENDIF
 
 	btfss	imprint_surfmode_data		;     - shall imprint all surface mode data?
 	bra		housekeeping_0				;       NO
-	call	TFT_time_surfmode			;       YES - update displayed time
-	call	TFT_batt_surfmode			;           - update displayed battery voltage
+	call	TFT_surfmode_time			;       YES - update displayed time
+	call	TFT_surfmode_batt			;           - update displayed battery voltage
 	btfss	timebase_1sec,0				;           - on even second?
-	call	surfmode_check_for_warnings ;             YES - check for warnings and display/update them
+	call	surfmode_check_warnings		;             YES - check for warnings and display/update them
 
  IFDEF _rx_functions
 	btfss	tr_functions_activated		;           - TR functions activated?
 	bra		housekeeping_0				;             NO  - skip tank pressure part
 
 	call	get_pressure_readings		;             YES - get pressure readings
-	call	TFT_surface_tank_pres		;                 - update first gas/diluent pressure
+	call	TFT_surfmode_tankpres		;                 - update first gas/diluent pressure
 
 	movf	active_customview,W			;                 - get current custom view
 	xorlw	.10							;                 - coding of tank data custom view
 	btfsc	STATUS,Z					;                 - equal?
-	call	TFT_surface_tankdata		;                   YES - update tank data custom view
+	call	TFT_surf_cv_tankdata		;                   YES - update tank data custom view
  ENDIF
 
 housekeeping_0:
 	bsf		restart_fast				; default to doing a fast restart (no logos)
-	call	set_dive_modes				; check if dive mode needs to be entered, will set dive mode flag if yes
+	call	check_dive_modes_surf		; check if dive mode needs to be entered, will set dive mode flag if yes
 	btfsc	simulatormode				; in simulator mode?
 	bra		housekeeping_1				; YES - can't restart or go to sleep without prior cleanup
 	btfsc	divemode					; NO  - need to enter dive mode?
@@ -415,16 +457,17 @@
 	btfss	trigger_quarter_second		; new 1/4 second begun?
 	bra		housekeeping_2				; NO
 
-	; tasks any new 1/4 second
+	;---- tasks any new 1/4 second -----
+
 	bcf		trigger_quarter_second		; YES - clear flag
  IFDEF _external_sensor
 	btfsc	imprint_sensor_mv			;     - shall imprint sensor mV data?
-	call	TFT_menu_calibrate			;       YES - imprint sensor mV data
+	call	TFT_imprint_menu_mV			;       YES - imprint sensor mV data
  ENDIF	; _external_sensor
 	btfss	imprint_surfmode_data		;     - shall imprint all surface mode data?
 	bra		housekeeping_2				;       NO
 	btfsc	trigger_pres_cur_changed	;       YES - pressure changed?
-	call	TFT_pres_surfmode			;             YES - display surface pressure
+	call	TFT_surfmode_pres_fast		;             YES - display surface pressure, but only if change > threshold
 	bcf		trigger_pres_cur_changed	;           - clear flag (anyhow)
  IFDEF _compass
 	movf	active_customview,W			;           - get current custom view
@@ -438,50 +481,64 @@
 	btfsc	FLAG_pscr_mode				;           - in pSCR mode?
 	bra		housekeeping_1a				;             YES - handle sensors
 	bra		housekeeping_2				;             NO to both
+
 housekeeping_1a:						; handle sensors
 	movff	opt_ccr_mode,WREG			; =0: fixed SP, =1: sensor, =2: autoSP
 	decfsz	WREG						; opt_ccr_mode = 1 (sensor)?
 	bra		housekeeping_2				; NO  - skip sensor readings
 	call	calc_deko_divemode_sensor	; YES - read & calculate sensor data
-	call	TFT_surface_sensor			;     - update displayed sensor data
-	call	TFT_sensor_surface_warning	;     - show a down-arrow behind sensor readings when sensor is at end-of-life
+	call	TFT_imprint_surf_ppO2		;     - update displayed sensor data
+	call	TFT_imprint_surf_sensor_eol	;     - show a down-arrow behind sensor readings when sensor is at end-of-life
 	movf	active_customview,W			;     - get current custom view
 	xorlw	.9							;     - coding of sensor mV readings custom view
 	btfsc	STATUS,Z					;     - equal?
-	call	TFT_sensor_mV				;       YES - update mV readings
+	call	TFT_imprint_surf_mV			;       YES - update mV readings
  ENDIF	; _external_sensor
+
 housekeeping_2:
 	btfss	trigger_full_minute			; new 1/1 minute begun?
 	bra		housekeeping_3				; NO
 
-	; tasks any new minute
+	;---- tasks any new minute ---------
+
 	bcf		trigger_full_minute			; YES - clear flag
+
+	btfss	imprint_surfmode_data		;     - shall imprint all surface mode data?
+	bra		housekeeping_2a				;       NO
+	btfsc	trigger_pres_cur_changed	;       YES - pressure changed?
+	call	TFT_surfmode_pres			;             YES - display surface pressure
+	bcf		trigger_pres_cur_changed	;           - clear flag (anyhow)
+
+housekeeping_2a:
 	btfsc	simulatormode				;     - in simulator mode?
-	bra		housekeeping_2a				;       YES - real tissues are in the vault, skip desaturation calculations
+	bra		housekeeping_2b				;       YES - real tissues are in the vault, skip desaturation calculations
 	call	deco_calc_dive_interval_1min;       NO  - calculate 1 minute at surface conditions (C-code)
 	call	deco_calc_desaturation_time	;           - calculate desaturation and no-fly/no-altitude time (C-code)
 	banksel	common						;           - back to bank common
-housekeeping_2a:
+
+housekeeping_2b:
 	btfss	imprint_surfmode_data		;     - shall imprint all surface mode data?
 	bra		housekeeping_3				;       NO
-	call	TFT_date_surfmode			;       YES - update displayed date
+	call	TFT_surfmode_date			;       YES - update displayed date
 
 	btfsc	trigger_temp_changed		;           - temperature changed?
-	call	TFT_temp_surfmode			;             YES - display temperature
+	call	TFT_surfmode_temp			;             YES - display temperature
 	bcf		trigger_temp_changed		;           - clear flag (anyhow)
 
 	movf	active_customview,W			;           - get current custom view
 	xorlw	.5							;           - coding of tissue custom view
 	btfsc	STATUS,Z					;           - equal?
-	call	TFT_surface_tissues			;             YES - update tissue diagram
+	call	TFT_surf_cv_tissues			;             YES - update tissue diagram
 
 	movf	active_customview,W			;           - get current custom view
 	xorlw	.8							;           - coding of last dive info custom view
 	btfsc	STATUS,Z					;           - equal?
-	call	TFT_surface_lastdive		;             YES - update last dive infos
+	call	TFT_surf_cv_lastdive		;             YES - update last dive infos
 
 housekeeping_3:
-	; tasks any round
+
+	;---- tasks any round --------------
+
  IFDEF _screendump
 	btfsc	screen_dump_avail			; screen dump function enabled?
 	call	TFT_dump_screen_check		; YES - check if requested and do it
@@ -505,46 +562,6 @@
 	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
-	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
-	;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
-reset_timeout_time:						; entry point with timeout value in WREG
-	movwf	isr_timeout_reload			; copy WREG to isr_timeout_reload
-	bsf		reset_timeout				; request ISR to reset the timeout
-	bcf		trigger_timeout				; clear any pending timeout trigger
-	return								; done
-
 ;-----------------------------------------------------------------------------
 
 	END
--- a/src/surfmode.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/surfmode.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File surfmode.inc                           combined next generation V2.97
+;   File surfmode.inc                         combined next generation V3.09.4
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -11,7 +11,7 @@
 
 	extern surfloop
 	extern reset_timeout_surfmode
-	extern reset_timeout_time
+	extern restart_timeout_time
 	extern housekeeping
 
 
--- a/src/text_english.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/text_english.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_english.asm                     next combined generation V3.08.8
+;	File text_english.asm                     next combined generation V3.09.4k
 ;
 ;	English texts reference file.
 ;
@@ -41,12 +41,7 @@
 	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)
@@ -130,11 +125,8 @@
 	TCODE	tGasFirst,			"First"					; |      1: First
 	TCODE	tGasTravel,			"Work"					; |      2: Work (Travel, Bottom)
 	TCODE	tGasDeco,			"Deco"					; |      3: Deco
-	TCODE	tDilDisabled,		"Disabled"				; | Enum 0: Disabled
-	TCODE	tDilFirst,			"First"					; |      1: First
-	TCODE	tDilNorm,			"Normal"				; |      2: Normal
-	TCODE	tAir,				"Air  "					; Enum: values must follow (5 chars)
-	TCODE	tO2,				"O2   "					; tAir + 5
+	TCODE	tAir,				"Air  "					; | Enum: values must follow (5 chars)
+	TCODE	tO2,				"O2   "					; |       tAir + 5
 	TCODE	tO2Plus,			"O2 +"
 	TCODE	tO2Minus,			"O2 -"
  IFDEF _helium
@@ -149,7 +141,7 @@
 	TCODE	tDepthReset,		"Reset to MOD:"
 	TCODE	tSetup_GasMix,		"Setup Mix"
  IFDEF _ccr_pscr
-	TCODE	tSPPlus,			"ppO2+"					; pO2+
+	TCODE	tSPPlus,			"ppO2  +"				; Setpoint ppO2 +
 	TCODE	tSensorFallback,	"Fallback:"				; Fallback:
 	TCODE	tCalculated,		"calculated"			; calculated
 	TCODE	tppO2O2,			"ppO2(O2)"				; ppO2(O2)
@@ -163,7 +155,6 @@
 	TCODE	tCCRModeFixedSP,	" "						; target needed by option table
  ENDIF
 	TCODE	tSP,				"SP"					; SP (SetPoint)
-	TCODE	tppO2,				"ppO2:"					; ppO2:
 
 
 ; New batteries menu
@@ -192,11 +183,11 @@
 	TCODE	tUsbTitle,			"USB Mode"
 	TCODE	tBleTitle,			"Bluetooth Mode"
 	TCODE	tUsbStarting,		"Starting..."
-	TCODE	tUsbStartDone,		"Done."
-	TCODE	tUsbServiceMode,	"Service mode enabled"
+	TCODE	tUsbStartDone,		"done."
+	TCODE	tUsbServiceMode,	"Service Mode enabled"
 	TCODE	tUsbClosed,			"Port closed"
 	TCODE	tUsbExit,			"Exited"
-	TCODE	tUsbDownloadMode,	"Download mode enabled"
+	TCODE	tUsbDownloadMode,	"Download Mode enabled"
 	TCODE	tUsbLlBld,			"Low-level Bootloader"
 
 
@@ -239,7 +230,7 @@
 	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	tDepthWarn,			"Depth Warning:"		; Depth Warning (no space after ':' on purpose)
 	TCODE	tGasUsage,			"Gas Usage"				; Gas Usage
 	TCODE	tSetWorkSAC,		"SAC Work: "			; SAC Work: (space)
 	TCODE	tSetDecoSAC,		"SAC Deco: "			; SAC Deco: (space)
@@ -249,8 +240,8 @@
  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)
+	TCODE	tTankSize,			"Tank Size: "			; Tank Size
+	TCODE	tTankUsablePress,	"Turn Pres: "			; Tank Pressure Budget for Ascent (turn pressure)
 	TCODE	tLiter,				" l"					; Liter as l
 	TCODE	tLiterLong,			"Liter"					; Liter as Liter
 	TCODE	t2ndDecoPlanMenu,	"2nd Deco Plan"			; 2nd Deco Plan
@@ -258,6 +249,7 @@
  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	tGasDensityCheck,	".. Gas Density: "		; check Gas Density
 	TCODE	tPSCR_O2_drop,		"pSCR   O2 Drop: "		; pSCR O2 drop
 	TCODE	tPSCR_lungratio,	"... Lung Ratio: "		; pSCR lung ratio
 	TCODE	tCopyDilToOC,		"Copy Dil.-> OC"		; copy diluent settings to OC gas
@@ -303,7 +295,7 @@
 	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	tVSItext2,			".. adaptive : "		; adaptive 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)
@@ -326,17 +318,18 @@
 ; Setup menu
 	TCODE	tSystSets,			"Settings"				; System Settings
  IFDEF _compass
-	TCODE	tCompassMenu,		"Compass Calibration"
+	TCODE	tCompassMenu,		"Compass"				; Compass
+	TCODE	tCompassCalibration,"Calibration"			; Calibration
 	TCODE	tCompassGain,		"Compass Gain:"
-	TCODE	tCalX,				"Cal X:"				; Cal X
-	TCODE	tCalY,				"Cal Y:"				; Cal Y
-	TCODE	tCalZ,				"Cal Z:"				; Cal Z
+	TCODE	tCalX,				"Cal X"					; Cal X
+	TCODE	tCalY,				"Cal Y"					; Cal Y
+	TCODE	tCalZ,				"Cal Z"					; Cal Z
  ENDIF
 	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	tDefName,		"HW OSTC						     "
 	TCODE	tPiezo,				"Buttons"				; Buttons
 	TCODE	tButtonleft,		"Left  Button:"			; Left  Button
 	TCODE	tButtonright,		"Right Button:"			; Right Button
@@ -467,11 +460,16 @@
 	TCODE	tgaschange,			"Change?"				; better gas found
 	TCODE	tNeed,				"Need "					; gas need (5 chars)
 	TCODE	tBattery,			"Battery"				; Battery
+	TCODE	tSAT,				"Sat:"					; Sat:  (max 4 chars)
+	TCODE	tppO2,				"ppO2:"					; ppO2: (max 5 chars)
 
  IFDEF _helium
 	TCODE	tHe,				"He"					; He
-	TCODE	tIBCD,				"IBCD N2He"				; IBCD warning
-	TCODE	tGasDensity,		"G.Density"				; Gas Density
+	TCODE	tIBCD,				"IBCD N2He"				; IBCD warning (max. 9 chars)
+ ENDIF
+
+ IFDEF _ccr_pscr
+	TCODE	tGasDensity,		"G.Density"				; Gas Density  (max. 9 chars)
  ENDIF
 
  IFDEF _rx_functions
@@ -481,14 +479,12 @@
 	TCODE	tswap,				"Swap Tank"				; swap tank (max. 9 chars)
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tDiveHudMask1,		"Sensor 1"
 	TCODE	tDiveHudMask2,		"Sensor 2"
 	TCODE	tDiveHudMask3,		"Sensor 3"
 	TCODE	tSensorDisagree,	"Sensors<>"				; Sensors disagree Warning
  ENDIF
- ENDIF
 
  IFDEF _cave_mode
 	TCODE	tGasNeedsCaveMode,	"Gas Needs -CAVE-"		; title for gas needs custom view (cave mode)		| need to be
@@ -504,6 +500,7 @@
 
 
 ; Divemode menu
+	TCODE	tDiveAckn,			"Ackn?"					; Ackn?  (max. 5 chars)
 	TCODE	tDivePreMenu,		"Menu?"					; Menu?  (max. 5 chars)
 	TCODE	tDiveLayout,		"Layout"				; Layout (max. 6 chars)
  IFDEF _compass
@@ -520,7 +517,7 @@
 	TCODE	tCNS2,				"CNS: "
 	TCODE	tAVG,				"Avg: "
 	TCODE	tGF2,				"GF : "
-	TCODE	tSAT,				"Sat: "					; max  4 chars
+	TCODE	tSD2,				"S/D: "
 	TCODE	tDvSalinity2,		"Salinity :"			; max 11 chars
 	TCODE	tLastDeco,			"Last Deco:"			; max 11 chars
 	TCODE	tNoProfileData,		"no profile anymore..."	; max 21 chars
@@ -529,7 +526,8 @@
 	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
 
 ; other users
-	TCODE	tGF,				"GF:"
+	TCODE	tGF,				"GF:"					; GF Factors                (3 chars)
+	TCODE	tSD,				"S/D"					; Saturation / Desaturation (3 chars)
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -543,7 +541,11 @@
 
 
 ; Reset menu
+ IFDEF _firmware_recovery
+	TCODE	tReboot,			"Reboot/Backup"			; Reboot/Backup
+ ELSE
 	TCODE	tReboot,			"Reboot"				; Reboot
+ ENDIF
 	TCODE	tResetMenu2,		"Are you sure?"			; Are you sure?
 	TCODE	tAbort,				"Abort"					; Abort
 	TCODE	tResetSettings,		"Reset Settings"		; Reset Settings
@@ -551,6 +553,14 @@
 	TCODE	tResetBattery,		"Reset Battery"			; Reset Battery
 	TCODE	tResetLogbook,		"Reset Logbook"			; Reset Logbook
 
+ IFDEF _firmware_recovery
+	TCODE	tRebootCurFirmware,	"Reboot  current FW"	; Reboot current Firmware
+	TCODE	tBackupFirmware,	"Backup  current FW"	; Backup current Firmware
+	TCODE	tRecoverFirmware,	"Restore"				; Restore (version will be appended)
+	TCODE	tBackingUp,			"backing up..."			; backing up current firmware
+	TCODE	tRestoring,			"restoring..."			; restoring  backup  firmware
+ ENDIF
+
 
 ; Set Time Menu/Set Date Menu
 	TCODE	tSetHours,			"Set   Hours"			; Set   Hours
@@ -593,6 +603,13 @@
 	TCODE	tColorSetName3,		"Blue"					; Blue
 
 
+; Debug Stuff
+ IFDEF _comm_debug
+	TCODE	tCommTimeout,		"RX Timeout: "
+	TCODE	tCommTimeoutU,		"0 ms"
+ ENDIF
+
+
 ; Language selection
  IF _language_1==en
 	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
--- a/src/text_french.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/text_french.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_french.sm                       next combined generation V3.08.8
+;	File text_french.sm                       next combined generation V3.09.4k
 ;
 ;	French texts translation file.
 ;
@@ -12,8 +12,8 @@
 	TCODE	tYes,				"Oui"					; 1 Yes		|
 
  IFDEF _cave_mode
-	TCODE	tOff,				"off"					; OFF		| Enum group
-	TCODE	tOn,				"on"					; ON		|
+	TCODE	tOff,				"Non"					; OFF		| Enum group
+	TCODE	tOn,				"Oui"					; ON		|
  ELSE
 	TCODE	tOff,				" "						; needed for option table
  ENDIF
@@ -41,12 +41,7 @@
 	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)
@@ -79,25 +74,25 @@
 	TCODE	tSetDate,			"Réglage Date"			; Set 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	tSysSets,			"Préfér. Système"		; System  Settings
 	TCODE	tExit,				"Sortie"				; Exit
 	TCODE	tResetMenu,			"Menu RaZ"				; Reset Menu
-	TCODE	tDiveModeMenu,		"Menu Déco"				; Dive Setup
+	TCODE	tDiveModeMenu,		"Réglages Plongée"		; Dive Setup  Régl.Plongée
 
-	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	tDiveSetup,			"Config. Plongée"		; Dive Setup
+	TCODE	tDecoSetup,			"Config. Déco"			; Deco Setup
+	TCODE	tSACSetup,			"Config. Conso"			; SAC Setup
+	TCODE	tppO2Setup,			"Config. PpO2"			; ppO2 Setup
+	TCODE	tStopsSetup,		"Config. Paliers"		; Stops & Depths
 
 	TCODE	tInfoMenu,			"Informations"			; Information
  IFDEF _ccr_pscr
 	TCODE	tCCRSetup,			"Paramètres CCR"		; CCR Setup
-	TCODE	tDiluentSetup,		"Liste Diluant"			; Diluent Setup
+	TCODE	tDiluentSetup,		"Liste Diluants"		; Diluents Setup
  ENDIF
 	TCODE	tFixedSetpoints,	"Setpoints Fixes"		; Fixed Setpoints
 	TCODE	tBack,				"Retour"				; back
-	TCODE	tGas6,				"extra Gas"				; edit & select Gas 6
+	TCODE	tGas6,				"Gaz suppl"				; edit & select Gas 6
 
  IFDEF _rx_functions
 	TCODE	tTrSettings,		"Affich.Pression"		; Pressure Display
@@ -126,15 +121,12 @@
 	TCODE	tGaslistCC,			"Liste Gaz CC"			; CC Diluents
 	TCODE	tGasEdit,			"Préférence Gaz"		; Edit Gas
 	TCODE	tType,				"Type: "
-	TCODE	tGasDisabled,		"Désactivé"				; Disabled
-	TCODE	tGasFirst,			"Premier"				; First
-	TCODE	tGasTravel,			"Travail"				; Work (Travel, Bottom)
-	TCODE	tGasDeco,			"Déco"					; Deco
-	TCODE	tDilDisabled,		"Désactivé"				; Disabled
-	TCODE	tDilFirst,			"Premier"				; First
-	TCODE	tDilNorm,			"Normal"				; Normal
-	TCODE	tAir,				"Air  "					; Enum: values must follow (5 chars)
-	TCODE	tO2,				"O2   "					; tAir + 5
+	TCODE	tGasDisabled,		"Désactivé"				; | ENUM 0: Disabled
+	TCODE	tGasFirst,			"Premier"				; |      1: First
+	TCODE	tGasTravel,			"Travail"				; |      2: Work (Travel, Bottom)
+	TCODE	tGasDeco,			"Déco"					; |      3: Deco
+	TCODE	tAir,				"Air  "					; | ENUM: values must follow (5 chars)
+	TCODE	tO2,				"O2   "					; |       tAir + 5
 	TCODE	tO2Plus,			"O2 +"
 	TCODE	tO2Minus,			"O2 -"
  IFDEF _helium
@@ -144,12 +136,12 @@
 	TCODE	tMOD,				"MOD :"
 	TCODE	tEAD,				"EAD:"
 	TCODE	tSetup_GasDepth,	"Config. Changement"	; Change Depth
-	TCODE	tDepthPlus,			"Prof. +"
-	TCODE	tDepthMinus,		"Prof. -"
+	TCODE	tDepthPlus,			"Prof.+"
+	TCODE	tDepthMinus,		"Prof.-"
 	TCODE	tDepthReset,		"MOD par défaut:"
 	TCODE	tSetup_GasMix,		"Config. Gaz"			; Setup mix
  IFDEF _ccr_pscr
-	TCODE	tSPPlus,			"PpO2+"					; pO2+
+	TCODE	tSPPlus,			"PpO2 +"				; Setpoint ppO2 +
 	TCODE	tSensorFallback,	"Fallback:"				; Fallback:
 	TCODE	tCalculated,		"calculé"				; calculated
 	TCODE	tppO2O2,			"PpO2(O2)"				; ppO2(O2)
@@ -163,7 +155,6 @@
 	TCODE	tCCRModeFixedSP,	" "						; target needed by option table
  ENDIF
 	TCODE	tSP,				"SP"					; SP (SetPoint)
-	TCODE	tppO2,				"PpO2:"					; ppO2:
 
 
 ; New batteries menu
@@ -203,9 +194,9 @@
 ; Dive Settings
 	TCODE	tDvMode,			"Mode        : "		; Dive Mode
  IFDEF _cave_mode
-	TCODE	tCvMode,			"Cave        : "		; Cave Mode
+	TCODE	tCvMode,			"Spéléo      : "		; Cave Mode
  ENDIF
-	TCODE	tFTTSMenu,			"Future DTR  :"			; Future TTS
+	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!
@@ -217,40 +208,40 @@
 	TCODE	tDkMode,			"Modèle: ZH-L16"
 	TCODE	tZHL16,				" "
 	TCODE	tZHL16GF,			"+GF"
-	TCODE	tPPO2Max,			"Max Travail:"
-	TCODE	tPPO2DECO,			"Max Déco   :"
+	TCODE	tPPO2Max,			"Max Fond  : "
+	TCODE	tPPO2DECO,			"Max Déco  : "
  IFDEF _ccr_pscr
-	TCODE	tPPO2MIN,			"Min OC     :"
-	TCODE	tPPO2MINCC,			"Min Loop   :"
+	TCODE	tPPO2MIN,			"Min OC    : "
+	TCODE	tPPO2MINCC,			"Min Boucle: "
  ELSE
-	TCODE	tPPO2MIN,			"Min        :"
+	TCODE	tPPO2MIN,			"Min       : "
  ENDIF
 	TCODE	tDecoparameters,	"Paramètres Déco"
-	TCODE	tGF_low,			"GF  Bas :"
-	TCODE	tGF_high,			"GF  Haut:"
-	TCODE	tSaturationMult,	"Saturation  : "
-	TCODE	tDesaturationMult,	"Désaturation: "
+	TCODE	tGF_low,			"GF  Bas : "			; GF low
+	TCODE	tGF_high,			"GF  Haut: "			; GF high
+	TCODE	tSaturationMult,	"Saturation  : "		; Saturation
+	TCODE	tDesaturationMult,	"Désaturation: "		; Desaturation
 	TCODE	tGFMenu,			"Menu GF"				; GF Settings
-	TCODE	taGF_low,			"aGF Bas :"				; aGF Low
-	TCODE	taGF_high,			"aGF Haut:"				; aGF High
-	TCODE	taGFenable,			"aGF Possible:"			; aGF Selectable
+	TCODE	taGF_low,			"aGF Bas : "			; aGF Low
+	TCODE	taGF_high,			"aGF Haut: "			; aGF High
+	TCODE	taGFenable,			"aGF Possible: "		; aGF Selectable
 	TCODE	tDiveaGF_active,	"aGF Actif"				; using aGF
 	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	tLastDecostop,		"Dern.Palier : "		; last DecoStop Depth
+	TCODE	tDvSalinity,		"Salinité    : "		; Salinity
+	TCODE	tDepthWarn,			"Alerte Prof.:"			; Depth Warning (no space after ':' on purpose)
 	TCODE	tGasUsage,			"Usage Gaz"				; Gas Usage
-	TCODE	tSetWorkSAC,		"SAC Fond: "			; SAC Work: (space)
-	TCODE	tSetDecoSAC,		"SAC Déco: "			; SAC Deco: (space)
+	TCODE	tSetWorkSAC,		"L/mn Fond: "			; SAC Work: (space)
+	TCODE	tSetDecoSAC,		"L/mn 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
+	TCODE	tGasContingencyDive,"Echange Bloc  : "		; Swap on 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)
+	TCODE	tGasChangeTime,		"Tps Change Gaz: +"		; additional Gas Change Time
+	TCODE	tSetup_Tank,		"Config. Bloc"			; Setup Tank
+	TCODE	tTankSize,			"Volume Bloc: "			; Tank Size
+	TCODE	tTankUsablePress,	"Pression   : "			; Tank Pressure Budget for Ascent (turn pressure)
 	TCODE	tLiter,				" l"					; Liter as l
 	TCODE	tLiterLong,			"Litre"					; Liter as Liter
 	TCODE	t2ndDecoPlanMenu,	"2ème Plan Déco"		; 2nd Deco Plan
@@ -258,6 +249,7 @@
  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	tGasDensityCheck,	".. Gas Density: "		; check Gas Density
 	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
@@ -303,11 +295,11 @@
 	TCODE	tFlip,				"Pivoter l'écran:"		; Rotate Screen
 	TCODE	tColorScheme,		"Jeu de Couleurs"		; Colour Scheme
 	TCODE	tVSIgraph,			"Graph.Vitesse: "		; Speed Graph
-	TCODE	tVSItext2,			"Var.  Vitesse: "		; variable Speed
+	TCODE	tVSItext2,			"Vites.Variabl: "		; adaptive Speed
 	TCODE	tShowppO2,			"Afficher PpO2: "		; always show ppO2
-	TCODE	tDepthWarning,		"Prof. luire  : "		; Depth blinking
+	TCODE	tDepthWarning,		"Prof. Flash  : "		; Depth blinking
 	TCODE	t2ndDepth,			"Choix Prof:"			; 2nd Depth Display Content (11 chars max)
-	TCODE	tTissueGraphics,	"Dessin    :"			; Tissue Graphics
+	TCODE	tTissueGraphics,	"Graphique :"			; Tissue Graphics
 	TCODE	tIBCDwarning,		"Alerte CDI: "			; IBCD Warning
 
 	TCODE	tEco,				"Eco"					; eco     | ENUM group
@@ -326,17 +318,18 @@
 ; Setup Menu
 	TCODE	tSystSets,			"Réglages"				; System Settings
  IFDEF _compass
-	TCODE	tCompassMenu,		"Calibration Compas"	; Compass Calibration
+	TCODE	tCompassMenu,		"Compas"				; Compass
+	TCODE	tCompassCalibration,"Calibration"			; Calibration
 	TCODE	tCompassGain,		"Sensibilité:"			; Compass Gain:
-	TCODE	tCalX,				"Cal X:"				; Cal X
-	TCODE	tCalY,				"Cal Y:"				; Cal Y
-	TCODE	tCalZ,				"Cal Z:"				; Cal Z
+	TCODE	tCalX,				"Cal X"					; Cal X
+	TCODE	tCalY,				"Cal Y"					; Cal Y
+	TCODE	tCalZ,				"Cal Z"					; Cal Z
  ENDIF
 	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	tDefName,		"HW OSTC						     "
 	TCODE	tPiezo,				"Bouton"				; Buttons
 	TCODE	tButtonleft,		"Bouton gauche:"		; Left button
 	TCODE	tButtonright,		"Bouton droit :"		; Right button
@@ -372,10 +365,10 @@
 
 
 ; Decoplanner submenu
-	TCODE	tBtTm,				"Temps Fond:"			; Bot. Time: (10 chars)
+	TCODE	tBtTm,				"Temps Fond: "			; Bot. Time:
 	TCODE	tBtTm_short,		"Temps:"				; Bot. Time: (max. 6 chars)
-	TCODE	tBtDep,				"Prof. Max :"			; Max Depth: (10 chars)
-	TCODE	tIntvl,				"Intervalle:"			; Interval : (10 chars)
+	TCODE	tBtDep,				"Prof. Max : "			; Max Depth:
+	TCODE	tIntvl,				"Intervalle: "			; Interval :
 	TCODE	tCalculatorSetup,	"Réglage Ordinateur"	; Calculator Setup
 	TCODE	tDeco,				"Calcul Déco"			; Calculate Deco
 	TCODE	tDivePlan,			"Runtime"				; Dive Plan (max. 10 chars)
@@ -400,16 +393,16 @@
 
 ; Information menu
 	TCODE	tFirmware,			"Logiciel: "			; Firmware: (space)
-	TCODE	tFirmwareDate,		"created : "			; created : (space)  firmware creation date
+	TCODE	tFirmwareDate,		"M.a Jour: "			; created : (space)  firmware creation date
 	TCODE	tHardware,			"Hardware: "			; Hardware: (space)
 	TCODE	tSerial,			"N. Série: "			; Serial  : (space)
 	TCODE	tBatteryV,			"Batterie: "			; Battery : (space)
-	TCODE	tSensorC,			"Sensor  : "			; Sensor  : (space)
-	TCODE	tSensorD,			"Offset  : "			; Offset  : (space)
+	TCODE	tSensorC,			"Capteur : "			; Sensor  : (space)
+	TCODE	tSensorD,			"Décalage: "			; Offset  : (space)
 	TCODE	tUptime,			"Mise a Jour:"			; Uptime:
 
  IFDEF _rx_functions
-	TCODE	tFirmware_rx,		"RX Ver  : "			; RX Ver  : (space)
+	TCODE	tFirmware_rx,		"RX Ver. : "			; RX Version
  ENDIF
 
 
@@ -467,11 +460,16 @@
 	TCODE	tgaschange,			"Changer?"				; better gas found
 	TCODE	tNeed,				"Need "					; gas need (5 chars)
 	TCODE	tBattery,			"Batterie"				; Battery
+	TCODE	tSAT,				"Sat:"					; Sat:  (max 4 chars)
+	TCODE	tppO2,				"PpO2:"					; ppO2: (max 5 chars)
 
  IFDEF _helium
 	TCODE	tHe,				"He"					; He
-	TCODE	tIBCD,				"CDI N2He"				; IBCD warning
-	TCODE	tGasDensity,		"G.Density"				; Gas Density				## pending translation
+	TCODE	tIBCD,				"CDI N2He"				; IBCD warning  (max. 9 chars)
+ ENDIF
+
+ IFDEF _ccr_pscr
+	TCODE	tGasDensity,		"G.Density"				; Gas Density   (max. 9 chars)	## pending translation
  ENDIF
 
  IFDEF _rx_functions
@@ -481,20 +479,18 @@
 	TCODE	tswap,				"Bloc Ech."				; swap tank (max. 9 chars)
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tDiveHudMask1,		"Cell. 1"
 	TCODE	tDiveHudMask2,		"Cell. 2"
 	TCODE	tDiveHudMask3,		"Cell. 3"
 	TCODE	tSensorDisagree,	"Sensors<>"				; Sensors disagree Warning; Sensors disagree Warning
  ENDIF
- ENDIF
 
  IFDEF _cave_mode
 	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	tCaveMode,			"M.Spéléo"				; cave mode activated (max. 9 char)
+	TCODE	tCaveModeShutdown,	"X-Spél-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
@@ -504,6 +500,7 @@
 
 
 ; Divemode menu
+	TCODE	tDiveAckn,			"Conf?"					; Acknf?  (max. 5 chars) (Acknowledge)
 	TCODE	tDivePreMenu,		"Menu?"					; Menu?  (max. 5 chars)
 	TCODE	tDiveLayout,		"Affich"				; Layout (max. 6 chars)
  IFDEF _compass
@@ -520,7 +517,7 @@
 	TCODE	tCNS2,				"SNC: "
 	TCODE	tAVG,				"Moy: "
 	TCODE	tGF2,				"GF : "
-	TCODE	tSAT,				"Sat:"					; max  4 chars
+	TCODE	tSD2,				"S/D: "
 	TCODE	tDvSalinity2,		"Salinité  :"			; max 11 chars
 	TCODE	tLastDeco,			"Der.Palier:"			; max 11 chars
 	TCODE	tNoProfileData,		"no data anymore..."	; max 21 chars
@@ -529,7 +526,8 @@
 	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
 
 ; other users
-	TCODE	tGF,				"GF:"
+	TCODE	tGF,				"GF:"					; GF Factors                (3 chars)
+	TCODE	tSD,				"S/D"					; Saturation / Desaturation (3 chars)
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -543,7 +541,11 @@
 
 
 ; Reset menu
+ IFDEF _firmware_recovery
+	TCODE	tReboot,			"Redémarrage/Backup"	; Reboot/Backup
+ ELSE
 	TCODE	tReboot,			"Redémarrage"			; Reboot
+ ENDIF
 	TCODE	tResetMenu2,		"Confirmer?"			; Are You Sure?
 	TCODE	tAbort,				"Quitter"				; Abort
 	TCODE	tResetSettings,		"RaZ Paramètres"		; Reset Settings
@@ -551,6 +553,14 @@
 	TCODE	tResetBattery,		"RaZ Batterie"			; Reset Battery
 	TCODE	tResetLogbook,		"RaZ Carnet"			; Reset Logbook
 
+ IFDEF _firmware_recovery
+	TCODE	tRebootCurFirmware,	"Reboot  current FW"	; Reboot current Firmware
+	TCODE	tBackupFirmware,	"Backup  current FW"	; Backup current Firmware
+	TCODE	tRecoverFirmware,	"Restore"				; Restore (version will be appended)
+	TCODE	tBackingUp,			"backing up..."			; backing up current firmware
+	TCODE	tRestoring,			"restoring..."			; restoring  backup  firmware
+ ENDIF
+
 
 ; Set Time Menu/Set Date Menu
 	TCODE	tSetHours,			"Ajust. Heures"			; Set Hours
@@ -593,6 +603,13 @@
 	TCODE	tColorSetName3,		"Bleu"					; Blue
 
 
+; Debug Stuff
+ IFDEF _comm_debug
+	TCODE	tCommTimeout,		"Attente Cx: "
+	TCODE	tCommTimeoutU,		"0 ms"
+ ENDIF
+
+
 ; Language selection
  IF _language_1==en
 	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
--- a/src/text_german.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/text_german.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_german.asm                      next combined generation V3.08.8
+;	File text_german.asm                      next combined generation V3.09.4k
 ;
 ;	German texts translation file.
 ;
@@ -41,12 +41,7 @@
 	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)
@@ -82,7 +77,7 @@
 	TCODE	tSysSets,			"System"				; System  Settings
 	TCODE	tExit,				"Ende"					; Exit
 	TCODE	tResetMenu,			"Reset Menü"			; Reset Menu
-	TCODE	tDiveModeMenu,			"TG-Einstellungen"	; Dive Setup
+	TCODE	tDiveModeMenu,		"TG-Einstellungen"		; Dive Setup
 
 	TCODE	tDiveSetup,			"Tauchgang"				; Dive Setup
 	TCODE	tDecoSetup,			"Dekompression"			; Deco Setup
@@ -126,15 +121,12 @@
 	TCODE	tGaslistCC,			"CC Gas Liste"			; CC Diluents
 	TCODE	tGasEdit,			"Gas einstellen"
 	TCODE	tType,				"Type: "
-	TCODE	tGasDisabled,		"Deaktiviert"			; Disabled
-	TCODE	tGasFirst,			"Start"					; First
-	TCODE	tGasTravel,			"Arbeit"				; Work (Travel, Bottom)
-	TCODE	tGasDeco,			"Deko"					; Deco
-	TCODE	tDilDisabled,		"Deaktiviert"			; Disabled
-	TCODE	tDilFirst,			"Start"					; First
-	TCODE	tDilNorm,			"Normal"				; Normal
-	TCODE	tAir,				"Air  "					; Enum: values must follow (5 chars)
-	TCODE	tO2,				"O2   "					; tAir + 5
+	TCODE	tGasDisabled,		"Deaktiviert"			; | ENUM 1: Disabled
+	TCODE	tGasFirst,			"Start"					; |      2: First
+	TCODE	tGasTravel,			"Arbeit"				; |      3: Work (Travel, Bottom)
+	TCODE	tGasDeco,			"Deko"					; |      4: Deco
+	TCODE	tAir,				"Air  "					; | ENUM: values must follow (5 chars)
+	TCODE	tO2,				"O2   "					; |       tAir + 5
 	TCODE	tO2Plus,			"O2 +"
 	TCODE	tO2Minus,			"O2 -"
  IFDEF _helium
@@ -149,7 +141,7 @@
 	TCODE	tDepthReset,		"Reset auf MOD:"
 	TCODE	tSetup_GasMix,		"Mix  Einstellen"
  IFDEF _ccr_pscr
-	TCODE	tSPPlus,			"ppO2+"					; pO2+
+	TCODE	tSPPlus,			"ppO2  +"				; Setpoint ppO2 +
 	TCODE	tSensorFallback,	"Fallback:"				; Fallback:
 	TCODE	tCalculated,		"berechnet"				; calculated
 	TCODE	tppO2O2,			"ppO2(O2)"				; ppO2(O2)
@@ -163,7 +155,6 @@
 	TCODE	tCCRModeFixedSP,	" "						; target needed by option table
  ENDIF
 	TCODE	tSP,				"SP"					; SP (SetPoint)
-	TCODE	tppO2,				"ppO2:"					; ppO2:
 
 
 ; New batteries menu
@@ -239,7 +230,7 @@
 	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	tDepthWarn,			"Tiefenlimit:"			; Depth Warning (no space after ':' on purpose)
 	TCODE	tGasUsage,			"Gasbedarf"				; Gas Usage
 	TCODE	tSetWorkSAC,		"Arbeits-SAC:"			; SAC Work:
 	TCODE	tSetDecoSAC,		"Deko    SAC:"			; SAC Deco:
@@ -249,15 +240,16 @@
  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)
+	TCODE	tTankSize,			"Tank Größe : "			; Tank Size 
+	TCODE	tTankUsablePress,	"Umkehrdruck: "			; Tank Pressure Budget for Ascent (turn pressure)
 	TCODE	tLiter,				" l"					; Liter as l
 	TCODE	tLiterLong,			"Liter"					; Liter as Liter
 	TCODE	t2ndDecoPlanMenu,	"2.Deko Plan"			; 2nd Deco Plan
 
  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	tDilppO2Check,		"Prüfe Dil ppO2: "		; check ppO2 of the diluent against the setpoint
+	TCODE	tGasDensityCheck,	"..   Gasdichte: "		; check Gas Density
 	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
@@ -303,7 +295,7 @@
 	TCODE	tFlip,				"Anzeige drehen: "		; Rotate Screen
 	TCODE	tColorScheme,		"Farbschema"			; Colour Scheme
 	TCODE	tVSIgraph,			"Geschw.Grafik: "		; Speed Graph
-	TCODE	tVSItext2,			"Var.   Geschw: "		; variable Speed
+	TCODE	tVSItext2,			"...   adaptiv: "		; 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)
@@ -326,17 +318,18 @@
 ; Setup Menu
 	TCODE	tSystSets,			"Konfiguration"			; System Settings
  IFDEF _compass
-	TCODE	tCompassMenu,		"Kompass-Kalibrierung"	; Compass calibration
+	TCODE	tCompassMenu,		"Kompass"				; Compass
+	TCODE	tCompassCalibration,"Kalibrierung"			; Calibration
 	TCODE	tCompassGain,		"Empfindlichkeit:"		; Compass gain:
-	TCODE	tCalX,				"Kal. X:"				; Cal X
-	TCODE	tCalY,				"Kal. Y:"				; Cal Y
-	TCODE	tCalZ,				"Kal. Z:"				; Cal Z
+	TCODE	tCalX,				"Kal. X"				; Cal X
+	TCODE	tCalY,				"Kal. Y"				; Cal Y
+	TCODE	tCalZ,				"Kal. Z"				; Cal Z
  ENDIF
 	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						     "
 	TCODE	tPiezo,				"Taster"				; Buttons
 	TCODE	tButtonleft,		"Taster links :"		; Left button
 	TCODE	tButtonright,		"Taster rechts:"		; Right button
@@ -372,10 +365,10 @@
 
 
 ; Decoplanner submenu
-	TCODE	tBtTm,				"Grundzeit:"			; Bot. Time: (10 chars)
+	TCODE	tBtTm,				"Grundzeit  : "			; Bot. Time: (10 chars)
 	TCODE	tBtTm_short,		"Zeit :"				; Bot. Time: (max. 6 chars)
-	TCODE	tBtDep,				"Tiefe    :"			; Max Depth: (10 chars)
-	TCODE	tIntvl,				"Intervall:"			; Interval : (10 chars)
+	TCODE	tBtDep,				"Tiefe      : "			; Max Depth: (10 chars)
+	TCODE	tIntvl,				"Intervall  : "			; Interval : (10 chars)
 	TCODE	tCalculatorSetup,	"Deko Parameter"		; Calculator Setup
 	TCODE	tDeco,				"Deko Berechnung"		; Calculate Deco
 	TCODE	tDivePlan,			"Tauchplan"				; Dive Plan (max. 10 chars)
@@ -467,11 +460,16 @@
 	TCODE	tgaschange,			"wechseln?"				; better gas found
 	TCODE	tNeed,				"Bedf."					; gas need (5 chars)
 	TCODE	tBattery,			"Batterie"				; Battery
+	TCODE	tSAT,				"Sät:"					; Sat:  (max 4 chars)
+	TCODE	tppO2,				"ppO2:"					; ppO2: (max 5 chars)
 
  IFDEF _helium
 	TCODE	tHe,				"He"					; He
-	TCODE	tIBCD,				"IBCD N2He"				; IBCD warning
-	TCODE	tGasDensity,		"Gasdichte"				; Gas Density
+	TCODE	tIBCD,				"IBCD N2He"				; IBCD warning (max. 9 chars)
+ ENDIF
+
+ IFDEF _ccr_pscr
+	TCODE	tGasDensity,		"Gasdichte"				; Gas Density  (max. 9 chars)
  ENDIF
 
  IFDEF _rx_functions
@@ -481,29 +479,28 @@
 	TCODE	tswap,				"wechseln"				; switch tank (max. 9 chars)
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tDiveHudMask1,		"Sensor 1"
 	TCODE	tDiveHudMask2,		"Sensor 2"
 	TCODE	tDiveHudMask3,		"Sensor 3"
 	TCODE	tSensorDisagree,	"Sensoren!"				; Sensors disagree Warning
  ENDIF
- ENDIF
 
  IFDEF _cave_mode
-	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	tGasNeedsCaveMode,	"Gasbedarf -HÖHLE- "	; title for gas needs custom view (cave mode)		| need to be
+	TCODE	tGasNeedsAscent,	"Gasbedarf 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
+	TCODE	tGasNeedsAscent,	"Gasbedarf Aufstieg"	; title for gas needs custom view
  ENDIF
 
 
 ; Divemode menu
+	TCODE	tDiveAckn,			"Best?"					; Ackn?  (max. 5 chars)
 	TCODE	tDivePreMenu,		"Menü?"					; Menu?  (max. 5 chars)
 	TCODE	tDiveLayout,		"Layout"				; Layout (max. 6 chars)
  IFDEF _compass
@@ -520,7 +517,7 @@
 	TCODE	tCNS2,				"ZNS:"
 	TCODE	tAVG,				"Mit:"
 	TCODE	tGF2,				"GF :"
-	TCODE	tSAT,				"Sät:"					; max  4 chars
+	TCODE	tSD2,				"S/D: "
 	TCODE	tDvSalinity2,		"Salinität :"			; max 11 chars
 	TCODE	tLastDeco,			"Letzt.Stop:"			; max 11 chars
 	TCODE	tNoProfileData,		"keine Daten mehr..."	; max 21 chars
@@ -529,7 +526,8 @@
 	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
 
 ; other useser
-	TCODE	tGF,				"GF:"
+	TCODE	tGF,				"GF:"					; GF Factors                (3 chars)
+	TCODE	tSD,				"S/D"					; Saturation / Desaturation (3 chars)
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -543,7 +541,11 @@
 
 
 ; Reset menu
+ IFDEF _firmware_recovery
+	TCODE	tReboot,			"Neustart/Backup"		; Reboot/Backup
+ ELSE
 	TCODE	tReboot,			"Neu starten"			; Reboot
+ ENDIF
 	TCODE	tResetMenu2,		"Sind Sie sicher?"		; Are you sure?
 	TCODE	tAbort,				"Abbrechen"				; Abort
 	TCODE	tResetSettings,		"Reset Einstellungen"	; Reset Settings (max. 19 chars)
@@ -551,6 +553,14 @@
 	TCODE	tResetBattery,		"neue Batterie"			; Reset Battery
 	TCODE	tResetLogbook,		"Logbuch löschen"		; Reset Logbook
 
+ IFDEF _firmware_recovery
+	TCODE	tRebootCurFirmware,	"Reboot aktuelle FW"	; Reboot current Firmware
+	TCODE	tBackupFirmware,	"Backup aktuelle FW"	; Backup current Firmware
+	TCODE	tRecoverFirmware,	"lade  "				; Recover (version will be appended)
+	TCODE	tBackingUp,			"Sicherung läuft..."	; backing up current firmware
+	TCODE	tRestoring,			"Wiederherstellung..."	; restoring  backup  firmware
+ ENDIF
+
 
 ; Set Time Menu/Set Date Menu
 	TCODE	tSetHours,			"Stunden einst."		; Set Hours
@@ -593,6 +603,13 @@
 	TCODE	tColorSetName3,		"Blau"					; Blue
 
 
+; Debug Stuff
+ IFDEF _comm_debug
+	TCODE	tCommTimeout,		"RX Timeout: "
+	TCODE	tCommTimeoutU,		"0 ms"
+ ENDIF
+
+
 ; Language selection
  IF _language_1==en
 	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
--- a/src/text_italian.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/text_italian.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;	File text_italian.asm                     next combined generation V3.08.8
+;	File text_italian.asm                     next combined generation V3.09.4k
 ;
 ;	Italian texts translation file.
 ;
@@ -26,9 +26,9 @@
 	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
+	TCODE	tFTTSSurf,			"TTS Futuro :"			; Future TTS
+	TCODE	tLastDecostopSurf,	"UltimaTappa:"			; last deco stop surface custom view
+	TCODE	tDvSalinitySurf,	"Salinita'  :"			; Salinity
 
  IFDEF _external_sensor
 	TCODE	tSensorMilliVolt,	"Sensori mV"			; Sensors mV
@@ -41,12 +41,7 @@
 	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)
@@ -96,8 +91,8 @@
 	TCODE	tDiluentSetup,		"Imposta Diluente"		; Diluent Setup
  ENDIF
 	TCODE	tFixedSetpoints,	"Setpoints Fissi"		; Fixed Setpoints
-	TCODE	tBack,				"back"					; back
-	TCODE	tGas6,				"extra Gas"				; edit & select Gas 6
+	TCODE	tBack,				"indietro"					; back
+	TCODE	tGas6,				"Gas extra"				; edit & select Gas 6
 
  IFDEF _rx_functions
 	TCODE	tTrSettings,		"Display Press.ni"		; Pressure Display
@@ -126,15 +121,12 @@
 	TCODE	tGaslistCC,			"Lista Gas CC"			; CC Diluents
 	TCODE	tGasEdit,			"Modifica Gas"
 	TCODE	tType,				"Tipo: "
-	TCODE	tGasDisabled,		"Disabilitato"			; Disabled
-	TCODE	tGasFirst,			"Primo"					; First
-	TCODE	tGasTravel,			"Lavoro" 				; Work (Travel, Bottom) ("Viaggio")
-	TCODE	tGasDeco,			"Deco"					; Deco
-	TCODE	tDilDisabled,		"Disabilitato"			; Disabled
-	TCODE	tDilFirst,			"Primo"					; First
-	TCODE	tDilNorm,			"Normale"				; Normal
-	TCODE	tAir,				"Aria "					; Enum: values must follow (5 chars)
-	TCODE	tO2,				"O2   "					; tAir + 5
+	TCODE	tGasDisabled,		"Disabilitato"			; | ENUM 1: Disabled
+	TCODE	tGasFirst,			"Primo"					; |      2: First
+	TCODE	tGasTravel,			"Lavoro" 				; |      3: Work (Travel, Bottom) ("Viaggio")
+	TCODE	tGasDeco,			"Deco"					; |      4: Deco
+	TCODE	tAir,				"Aria "					; | ENUM: values must follow (5 chars)
+	TCODE	tO2,				"O2   "					; |       tAir + 5
 	TCODE	tO2Plus,			"O2 +"
 	TCODE	tO2Minus,			"O2 -"
  IFDEF _helium
@@ -149,7 +141,7 @@
 	TCODE	tDepthReset,		"Reset a MOD:"
 	TCODE	tSetup_GasMix,		"Cambia Gas"
  IFDEF _ccr_pscr
-	TCODE	tSPPlus,			"ppO2+"					; pO2+
+	TCODE	tSPPlus,			"ppO2 +"				; Setpoint ppO2 +
 	TCODE	tSensorFallback,	"Fallback:"				; Fallback:
 	TCODE	tCalculated,		"Calcolato"				; calculated
 	TCODE	tppO2O2,			"ppO2(O2)"				; ppO2(O2)
@@ -163,7 +155,6 @@
 	TCODE	tCCRModeFixedSP,	" "						; target needed by option table
  ENDIF
 	TCODE	tSP,				"SP"					; SP (SetPoint)
-	TCODE	tppO2,				"ppO2:"					; ppO2:
 
 
 ; New battery menu
@@ -239,8 +230,8 @@
 	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	tDepthWarn,			"Depth Warning :"		; Depth Warning (no space after ':' on purpose)
+	TCODE	tGasUsage,			"Utilizzo"			; Gas Usage
 	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
@@ -249,8 +240,8 @@
  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)
+	TCODE	tTankSize,			"Capac. Bomb.: "		; Tank Size
+	TCODE	tTankUsablePress,	"Press. X Ri.: "		; Tank Press Budget for Ascent (turn pressure)
 	TCODE	tLiter,				" l"					; Liter as l
 	TCODE	tLiterLong,			"Litri"					; Liter as Liter
 	TCODE	t2ndDecoPlanMenu,	"2o Piano Deco"			; 2nd Deco Plan
@@ -258,6 +249,7 @@
  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	tGasDensityCheck,	".. Gas Density: "		; check Gas Density
 	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
@@ -303,7 +295,7 @@
 	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	tVSItext2,			"...   adaptive : "		; adaptive 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)
@@ -326,17 +318,18 @@
 ; Setup Menu
 	TCODE	tSystSets,			"Impostazioni"			; System Settings
  IFDEF _compass
-	TCODE	tCompassMenu,		"Calibra Bussola"		; Compass calibration
+	TCODE	tCompassMenu,		"Bussola"				; Compass
+	TCODE	tCompassCalibration,"Calibra"				; Calibration
 	TCODE	tCompassGain,		"Suscettibilita:"		; Compass gain:
-	TCODE	tCalX,				"Cal X:"				; Cal X
-	TCODE	tCalY,				"Cal Y:"				; Cal Y
-	TCODE	tCalZ,				"Cal Z:"				; Cal Z
+	TCODE	tCalX,				"Cal X"					; Cal X
+	TCODE	tCalY,				"Cal Y"					; Cal Y
+	TCODE	tCalZ,				"Cal Z"					; Cal Z
  ENDIF
 	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	tDefName,		"HW OSTC						     "
 	TCODE	tPiezo,				"Bottone"				; Buttons
 	TCODE	tButtonleft,		"Bottone Sx:"			; Left  Button
 	TCODE	tButtonright,		"Bottone Dx:"			; Right Button
@@ -457,7 +450,7 @@
 	TCODE	tCNSfTTS,			"CNS fTTS"				;
 	TCODE	tCNSBO,				"CNS B/O"				;
 	TCODE	tCNSnow,			"CNS ora"				;
-	TCODE	tCNSeod,			"CNS finale"			;
+	TCODE	tCNSeod,			"CNS fin."			;
  IFDEF _cave_mode
 	TCODE	tCNScave,			"CNS Cave"				;
  ENDIF
@@ -467,11 +460,16 @@
 	TCODE	tgaschange,			"Cambio?"				; better gas found
 	TCODE	tNeed,				"Neces"					; gas need (5 chars)
 	TCODE	tBattery,			"Batteria"				; Battery
+	TCODE	tSAT,				"Sat:"					; Sat:  (max 4 chars)
+	TCODE	tppO2,				"ppO2:"					; ppO2: (max 5 chars)
 
  IFDEF _helium
 	TCODE	tHe,				"He"					; He
-	TCODE	tIBCD,				"IBCD N2He"				; IBCD warning
-	TCODE	tGasDensity,		"G.Density"				; Gas Density				## pending translation
+	TCODE	tIBCD,				"IBCD N2He"				; IBCD warning (max. 9 chars)
+ ENDIF
+
+ IFDEF _ccr_pscr
+	TCODE	tGasDensity,		"G.Density"				; Gas Density  (max. 9 chars)	## pending translation
  ENDIF
 
  IFDEF _rx_functions
@@ -481,14 +479,12 @@
 	TCODE	tswap,				"CambioGas"				; swap tank (max. 9 chars
  ENDIF
 
- IFDEF _ccr_pscr
  IFDEF _external_sensor
 	TCODE	tDiveHudMask1,		"Sensore1"
 	TCODE	tDiveHudMask2,		"Sensore2"
 	TCODE	tDiveHudMask3,		"Sensore3"
 	TCODE	tSensorDisagree,	"Sensori<>"				; Sensors disagree Warning
  ENDIF
- ENDIF
 
  IFDEF _cave_mode
 	TCODE	tGasNeedsCaveMode,	"Gas Necess.  -CAVE- "	; title for gas needs custom view (cave mode)		| need to be
@@ -504,6 +500,7 @@
 
 
 ; Divemode menu
+	TCODE	tDiveAckn,			"Ackn?"					; Ackn?  (max. 5 chars)
 	TCODE	tDivePreMenu,		"Menu?"					; Menu?  (max. 5 chars)
 	TCODE	tDiveLayout,		"Layout"				; Layout (max. 6 chars)
  IFDEF _compass
@@ -520,7 +517,7 @@
 	TCODE	tCNS2,				"CNS:"
 	TCODE	tAVG,				"Media:"
 	TCODE	tGF2,				"GF :"
-	TCODE	tSAT,				"Sat:"					; max  4 chars
+	TCODE	tSD2,				"S/D: "
 	TCODE	tDvSalinity2,		"Salinita':"			; max 11 chars
 	TCODE	tLastDeco,			"Ult.Tappa:"			; max 11 chars
 	TCODE	tNoProfileData,		"no data anymore..."	; max 21 chars
@@ -529,7 +526,8 @@
 	TCODE	tDesatTime,			"Desat:"				; amx  8 chars
 
 ; other users
-	TCODE	tGF,				"GF:"
+	TCODE	tGF,				"GF:"					; GF Factors                (3 chars)
+	TCODE	tSD,				"S/D"					; Saturation / Desaturation (3 chars)
 
 ; Logbook units
 	TCODE	tLogTunitC,			"°C"
@@ -543,7 +541,11 @@
 
 
 ; Reset menu
+ IFDEF _firmware_recovery
+	TCODE	tReboot,			"Riavvio/Backup"		; Reboot/Backup
+ ELSE
 	TCODE	tReboot,			"Riavvio"				; Reboot
+ ENDIF
 	TCODE	tResetMenu2,		"Sei sicuro?"			; Are you sure?
 	TCODE	tAbort,				"Annulla"				; Abort
 	TCODE	tResetSettings,		"Azzera Settaggi"		; Reset all
@@ -551,6 +553,14 @@
 	TCODE	tResetBattery,		"Azzera Batteria"		; Reset Battery
 	TCODE	tResetLogbook,		"Azzera Logbook"		; Reset Logbook
 
+ IFDEF _firmware_recovery
+	TCODE	tRebootCurFirmware,	"Reboot  current FW"	; Reboot current Firmware
+	TCODE	tBackupFirmware,	"Backup  current FW"	; Backup current Firmware
+	TCODE	tRecoverFirmware,	"Restore"				; Restore (version will be appended)
+	TCODE	tBackingUp,			"backing up..."			; backing up current firmware
+	TCODE	tRestoring,			"restoring..."			; restoring  backup  firmware
+ ENDIF
+
 
 ; Set Time Menu/Set Date Menu
 	TCODE	tSetHours,			"Imposta Ora"			; Set Hours
@@ -593,6 +603,13 @@
 	TCODE	tColorSetName3,		"Blu"					; Blue
 
 
+; Debug Stuff
+ IFDEF _comm_debug
+	TCODE	tCommTimeout,		"RX Timeout: "
+	TCODE	tCommTimeoutU,		"0 ms"
+ ENDIF
+
+
 ; Language selection
  IF _language_1==en
 	TCODE	tLang1,				"EN"					; tLang1 is 1st language, enum context
--- a/src/text_multilang.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/text_multilang.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File text_multilang.asm                    combined next generation V3.0.4
+;   File text_multilang.asm                 * combined next generation V3.09.4k
 ;
 ;   Implementation text in various selectable languages.
 ;
@@ -12,14 +12,34 @@
 #include "hwos.inc"
 #include "text_multilang.inc"
 
-; Because text are indexed by 12 bits values in FSR register, they can't
-; just be anywhere. It is safe to make them start at address 0xHHH000.
-texts	code	0x009000
+
+; Because multi-lingual texts are indexed using a FSR register and a FSR
+; register only holds 12 bit, the texts need to be aligned to a 4 kB block
+; in program memory. That is, they need to start at an address 0xXX000.
+
+
+
+; fast hack **ONLY** for **CHANGING** languages ( en / de / fr / it )
+
+#undefine _language_1
+#define   _language_1 fr
+;
+#undefine _language_2
+#define   _language_2 it
+
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; LANGUAGE 1
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 
 ;=============================================================================
+text_1_base	CODE 0x09000	;     ! DO NOT CHANGE !        *** Index Table ***
+;=============================================================================
+
 	global	text_1_base
 text_1_base:
-;---- PASS 1 : generate description block ------------------------------------
+
 tcode_idx	set		0
 LANG		set		0
 #define		TCODE	TCODE_1
@@ -49,7 +69,14 @@
 
 #undefine	TCODE
 
-;---- PASS 2 : generate text contents ----------------------------------------
+
+;=============================================================================
+text_1_text	CODE_PACK	;                                   *** Text Table ***
+;=============================================================================
+
+	global	text_1_text
+text_1_text:
+
 tcode_idx	set		0
 #define		TCODE	TCODE_2
 
@@ -73,13 +100,22 @@
 
 #undefine	TCODE
 
-;=============================================================================
+
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; LANGUAGE 2
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
- IF _language_2!=none
+ IF _language_2 != none
+
+
+;=============================================================================
+text_2_base	CODE 0x09400	;     ! DO NOT CHANGE !        *** Index Table ***
+;=============================================================================
 
 	global	text_2_base
 text_2_base:
-;---- PASS 1 : generate description block ------------------------------------
+
 tcode_idx	set		0
 LANG		set		1
 #define		TCODE	TCODE_1
@@ -109,7 +145,14 @@
 
 #undefine	TCODE
 
-;---- PASS 2 : generate text contents ----------------------------------------
+
+;=============================================================================
+text_2_text	CODE_PACK	;                                   *** Text Table ***
+;=============================================================================
+
+	global	text_2_text
+text_2_text:
+
 tcode_idx	set		0
 #define	TCODE	TCODE_2
 
@@ -133,8 +176,8 @@
 
 #undefine	TCODE
 
- ENDIF
+ ENDIF	; _language_2
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/text_multilang.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/text_multilang.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;    File text_multilang.inc                   combined next generation V3.0.1
+;    File text_multilang.inc                 * combined next generation V3.09.4j
 ;
 ;    Implementation of texts in various selectable languages
 ;
@@ -14,26 +14,13 @@
 ;	TCODE	tNo,	"Non"					; No
 ;	TCODE	tLogbk,	"Carnet de plongées"	; Logbook
 ;
-; Text direct usage:
-;	lfsr	FSR1,tYes						; load a 12 bit text index
-;	call	strcpy_text						; copy to string buffer
-;	PUTC	'/'								; place a single character into the text buffer
-;	lfsr	FSR1,tNo
-;	call	strcat_text_print				; append next text and call word processor to output all text to the screen
-;
-; RATIONALS:
-;  - The macro should define a label so that text files can be reordered
-;    to keep consistency while adding more options (and make translator life easier).
-;
-;  - The text positions is keept in menu blocks for the menu processor.
-;
-;  - library function take text number from the FSR1 register, because a
-;    lfsr instruction loads a 12 bit constant at once.
-;
-;=============================================================================
+; Text usage via is done via macros, see strings.inc
+
 
-; Pass 1: generate a jump table and define labels
-;
+;-----------------------------------------------------------------------------
+; Pass 1: generate Index Table and define Labels
+;-----------------------------------------------------------------------------
+
 TCODE_1 macro label, text
 tcode_idx set tcode_idx+1
 	If LANG == 0
@@ -44,55 +31,14 @@
 	endm
 
 
-; Pass 2: generates string table
-;
+;-----------------------------------------------------------------------------
+; Pass 2: generate String Table
+;-----------------------------------------------------------------------------
+
 TCODE_2 macro label, text
 tcode_idx set tcode_idx+1
 t#v(LANG)_#v(tcode_idx):
 	db		text, 0
 	endm
 
-
-;=============================================================================
-; strcpy_text : copy a multiling text into string buffer
-;
-; Input  : FSR1    text index
-; Output : Buffer  filled with the text
-;          FSR2    pointer to end of copied text (the null char)
-; Trashed: WREG
-
-	extern	strcpy_text
-
-
-;=============================================================================
-; strcpy_text_print : same as above, but calls word processor afterward
-;
-; Input  : FSR1    text index
-; Output : Buffer  filled with the text.
-;          FSR2    pointer to end of copied text (the null char)
-; Trashed: WREG
-
-	extern	strcpy_text_print
-
-
-;=============================================================================
-; strcat_text : append a multiling text to FSR2 pointer
-;
-; Input  : FSR1  text index
-;          FSR2  current position (in buffer)
-; Output : FSR2  pointer to end of copied text (the null char)
-; Trashed: WREG
-
-	extern	strcat_text
-
-
-;=============================================================================
-; strcat_text_print : aame as above, but calls word processor afterward
-;
-; Input  : FSR1  text index
-;          FSR2  current position (in buffer)
-; Output : FSR2  pointer to end of copied text (the null char)
-; Trashed: WREG
-
-	extern	strcat_text_print
-
+;-----------------------------------------------------------------------------
--- a/src/tft.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/tft.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File tft.asm                              combined next generation V3.08.8
+;   File tft.asm                              combined next generation V3.09.4n
 ;
 ;   low-level Display Outputs
 ;
@@ -12,11 +12,10 @@
 #include "hwos.inc"
 #include "wait.inc"
 #include "varargs.inc"
-#include "external_flash.inc"
 #include "tft_outputs.inc"
 #include "eeprom_rs232.inc"
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; Basic bit-level macros
 
 RD_H	macro
@@ -51,7 +50,7 @@
 		bcf tft_nwr,0
 		endm
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; Byte-level macros
 
 Index_out		macro low_b
@@ -66,10 +65,9 @@
 				rcall TFT_DataWrite
 				endm
 
-
+;=============================================================================
 tft		CODE
-
-;;=============================================================================
+;=============================================================================
 
 	global	TFT_ClearScreen
 TFT_ClearScreen:
@@ -222,8 +220,6 @@
 	bra		TFT_ClearScreen_display2_loop0
 
 
-;=============================================================================
-
 	global	TFT_DisplayOff
 TFT_DisplayOff:
 	bcf		lightsen_power  		; power-down light sensor
@@ -479,7 +475,6 @@
 	rcall	TFT_DataWrite			; write configuration
 	bra		display1_init_loop		; loop
 
-;=============================================================================
 
 	global	TFT_CmdWrite
 TFT_CmdWrite:
@@ -517,7 +512,7 @@
 ;	return
 
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; Smooth lighting-up of the display:
 ;
 ; Trashes: WREG, PRODL
@@ -525,14 +520,14 @@
 ;	clrf	CCPR1L					; backlight off
 ;	[draw splash screen]
 ;	call	TFT_DisplayFadeIn
-
+;
 	global	TFT_Display_FadeIn
 TFT_Display_FadeIn:
 	movlw	CCP1CON_VALUE			; get configuration
 	movwf	CCP1CON					; set configuration
 	bsf		tft_is_dimming			; TFT is dimming, ignore ambient sensor
 	btfsc	screen_type3
-	bra	TFT_Display_FadeIn_1
+	bra		TFT_Display_FadeIn_1
 	clrf	CCPR1L					; backlight off - to be sure
 	movff	max_CCPR1L,PRODL
 TFT_Display_FadeIn_0:
@@ -546,10 +541,10 @@
 	setf	CCPR1L
 	return
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; Smooth lighting-off of the display:
 ; Trashes: WREG, PRODL
-
+;
 	global	TFT_Display_FadeOut
 TFT_Display_FadeOut:
 	movff	max_CCPR1L,PRODL
@@ -565,8 +560,9 @@
 	clrf	CCPR1L
 	return
 
-;=============================================================================
-	; OLED brightness control
+;-----------------------------------------------------------------------------
+; OLED brightness control
+;
 TFT_display3_high:					; 0x01F8F8
 	movlw	LOW   (0x01F8F8         )
 	movwf	TBLPTRL
@@ -594,17 +590,18 @@
 	movwf	TBLPTRU
 	bra	display1_init_loop			; and return
 
-;=============================================================================
 
-	global	box_std_block, box_black_block, box_color_block
+;-----------------------------------------------------------------------------
+; colored (filled) Boxes
+;
+	global	box_std_block, box_black_block, box_color_block, box_color
 
 box_std_block:						; use white color
 	setf	WREG
-	bra		box_common
+	bra		box_color_block
 box_black_block:					; use black color
 	clrf	WREG
-box_common:
-box_color_block:
+box_color_block:					; use color from WREG
 	rcall	TFT_set_color
 	VARARGS_BEGIN
 	VARARGS_GET8 win_top
@@ -614,14 +611,20 @@
 	VARARGS_END
 	bra		TFT_box
 
-;-----------------------------------------------------------------------------
+box_color:							; use color from WREG and pre-set coordinates
+	rcall	TFT_set_color
+	bra		TFT_box
 
-	global	box_frame_std, box_frame_common, box_frame_color, box_frame_color16
 
-box_frame_std:
+;-----------------------------------------------------------------------------
+; colored Frames
+;
+	global	box_frame_std, box_frame_color
+
+box_frame_std:						; use white color
 	setf	WREG
+box_frame_color:					; use color from WREG
 	rcall	TFT_set_color
-box_frame_common:
 	VARARGS_BEGIN
 	VARARGS_GET8 win_top
 	VARARGS_GET8 win_height
@@ -629,31 +632,29 @@
 	VARARGS_GET8 win_width
 	VARARGS_END
 	bra		TFT_frame
-box_frame_color:
-	rcall	TFT_set_color
-box_frame_color16:
-	bra		box_frame_common
+
 
-;;=============================================================================
-;; Init for half_pixel_write
-;; Set column register on TFT device, and current color.
-;; Inputs: win_leftx2
-;; Outputs: win_color:2
-;; Trashed: WREG, PROD
-;
-;	global	init_pixel_write
-;init_pixel_write:
-;	movf	win_leftx2,W
-;	mullw	2
-;	rcall	pixel_write_col320		; start address vertical (.0 - .319)
-;	setf	WREG
-;	bra	TFT_set_color
+; ;-----------------------------------------------------------------------------
+; ; Init for half_pixel_write
+; ; Set column register on TFT device, and current color.
+; ; Inputs: win_leftx2
+; ; Outputs: win_color_1/_2
+; ; Trashed: WREG, PROD
+; ;
+; ;	global	init_pixel_write
+; ;init_pixel_write:
+; ;	movf	win_leftx2,W
+; ;	mullw	2
+; ;	rcall	pixel_write_col320		; start address vertical (.0 - .319)
+; ;	setf	WREG
+; ;	bra	TFT_set_color
+
 
 ;-----------------------------------------------------------------------------
-; Writes two half-pixels at position (win_top,win_leftx2)
-; Inputs: win_leftx2, win_top, win_color:2
+; Draw two half-pixels at position (win_top,win_leftx2)
+; Inputs: win_leftx2, win_top, win_color_1/_2
 ; Trashed: WREG, PROD
-
+;
 	global	pixel_write
 pixel_write:
 	movf	win_leftx2,W
@@ -726,10 +727,10 @@
 	bra		TFT_DataWrite_PROD		; and return...
 
 ;-----------------------------------------------------------------------------
-; Writes one half-pixel at position (win_top,win_leftx2).
-; Inputs: win_leftx2, win_top, win_color:2
+; Write one half-pixel at position (win_top,win_leftx2).
+; Inputs: win_leftx2, win_top, win_color_1/_2
 ; Trashed: WREG, PROD
-
+;
 	global	half_pixel_write
 half_pixel_write:
 	movf	win_top,W					; d'0' ... d'239'
@@ -817,10 +818,10 @@
 	return							; done
 
 ;-----------------------------------------------------------------------------
-; Writes a vertical line of half-pixel at position (win_top,win_leftx2,win_height).
-; Inputs: win_leftx2, win_top, win_height, win_color:2
+; Draw a vertical line of half-pixel at position (win_top,win_leftx2,win_height).
+; Inputs: win_leftx2, win_top, win_height, win_color_1/_2
 ; Trashed: WREG, PROD, TABLAT, TBLPTRL
-
+;
 	global	half_vertical_line
 half_vertical_line:
 	clrf	TABLAT					; loop index
@@ -844,10 +845,10 @@
 	bra		half_vertical_line_loop
 
 ;-----------------------------------------------------------------------------
-; Writes a horizontal line of half-pixel at position (win_top,win_leftx2,win_width).
-; Inputs: win_leftx2, win_top, win_width, win_color:2
+; Draw a horizontal line of half-pixel at position (win_top,win_leftx2,win_width).
+; Inputs: win_leftx2, win_top, win_width, win_color_1/_2
 ; Trashed: WREG, PROD, TABLAT, TBLPTRL
-
+;
 	global	half_horizontal_line
 half_horizontal_line:
 	clrf	TABLAT					; loop index
@@ -868,9 +869,8 @@
 
 
 ;-----------------------------------------------------------------------------
-; TFT Data Command via W
-
-	global	TFT_DataWrite_PROD
+; TFT Data Command
+;
 TFT_DataWrite_PROD:
 ;	RD_H								; keep high
 	RS_H								; data
@@ -928,35 +928,38 @@
 	clrf	TRISH					; port H as output
 	return
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; Output TFT Window Address commands
 ; Inputs : win_top, win_leftx2, win_height, win_width
 ; Output : PortA/PortH commands
 ; Trashed: PROD
-
+;
 	global	TFT_box_write
 TFT_box_write:
-	movf	win_leftx2,W						; compute left = 2 * leftx2 --> PROD
-	mullw	.2									; win_leftx2 x 2 -> PRODH:PRODL
+	movf	win_leftx2,W			; compute left = 2 * leftx2 --> PROD
+	mullw	.2						; win_leftx2 x 2 -> PRODH:PRODL
 
-	btfsc	screen_type2						; screen type 2 ?
-	bra		TFT_box_write_display2				; YES
-	btfsc	screen_type3						; screen type 3 ?
-	bra		TFT_box_write_display3				; YES
+	btfsc	screen_type2			; screen type 2 ?
+	bra		TFT_box_write_display2	; YES
+	btfsc	screen_type3			; screen type 3 ?
+	bra		TFT_box_write_display3	; YES
+	btfsc	screen_type1			; screen type 1 ?
+	bra		TFT_box_write_display1	; YES
 
-	global	TFT_box_write_16bit_win_left
-TFT_box_write_16bit_win_left:					; with column in PRODL:PRODH
-	btfsc	screen_type1						; screen type 1 ?
-	bra		TFT_box_write_16bit_win_left_d1		; YES
 	; screen type 0
-	btfsc	flip_screen							; 180° rotation?
-	bra		TFT_box_flip_H						; YES
-	bra		TFT_box_write_16bit_win_left_com	; NO
-TFT_box_write_16bit_win_left_d1:				; Display1
-	btfss	flip_screen							; 180° rotation?
-	bra		TFT_box_flip_H						; NO
-TFT_box_write_16bit_win_left_com:				; YES for screen type 1, NO for type 0
+TFT_box_write_display0:
+	btfsc	flip_screen				; 180° rotation?
+	bra		TFT_box_do_flip_H		; YES
+	bra		TFT_box_no_flip_H		; NO
+
+	; screen type 1
+TFT_box_write_display1:
+	btfss	flip_screen				; 180° rotation?
+	bra		TFT_box_do_flip_H		; NO
+	;bra	TFT_box_no_flip_H		; YES
+
 	;---- Normal horizontal window ---------------------------------------
+TFT_box_no_flip_H:
 	Index_out 0x52					; window vertical start address
 	rcall	TFT_DataWrite_PROD		; output left
 	Index_out 0x21					; frame memory vertical address
@@ -972,10 +975,10 @@
 
 	Index_out 0x53					; window vertical end address
 	rcall	TFT_DataWrite_PROD
-	bra		TFT_box_noflip_H
+	bra		TFT_box_common_H
 
 	;---- Flipped horizontal window --------------------------------------
-TFT_box_flip_H:
+TFT_box_do_flip_H:
 	; calculate new coordinate
 	movf	PRODL,W					; 16 bits 319 - PROD --> PROD
 	sublw	LOW  .319				; 319 - WREG --> WREG
@@ -1001,11 +1004,13 @@
 	Index_out 0x52					; window vertical end address
 	rcall	TFT_DataWrite_PROD
 
-TFT_box_noflip_H:
+TFT_box_common_H:
 	btfss	flip_screen				; 180° rotation ?
-	bra		TFT_box_noflip_V		; NO
+	bra		TFT_box_no_flip_V		; NO
+	;bra	TFT_box_do_flip_V		; YES
 
 	;---- Flipped vertical window -----------------------------------------
+TFT_box_do_flip_V:
 	; calculate new coordinate
 	movff	win_top,PRODH			; top --> PRODH (first byte)
 	movf	win_height,W
@@ -1025,8 +1030,8 @@
 	movf	PRODH,W
 	bra		TFT_DataWrite			; lower (and tick) and return
 
-TFT_box_noflip_V:
 	;---- Normal vertical window ----------------------------------------
+TFT_box_no_flip_V:
 	movff	win_top,PRODL
 	movf	win_height,W
 	addwf	PRODL,W
@@ -1120,7 +1125,7 @@
 	movf	win_width+1,W
 	addwfc	PRODH,F
 	decf	PRODL,F					; decrement result
-	btfss   STATUS,C
+	btfss	STATUS,C
 	decf	PRODH,F
 
 	Index_out	0x36				; write and the right border
@@ -1143,12 +1148,12 @@
 	bra		TFT_DataWrite_PROD		; and return...
 
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; TFT_frame : draw a frame around current box with current color
 ; Inputs:  win_top, win_leftx2, win_height, win_width, win_color1, win_color2
 ; Outputs: (none)
 ; Trashed: WREG, PROD, aa_start:2, aa_end:2
-
+;
 	global	TFT_frame
 TFT_frame:
 	movff	win_top,tft_save_top		; backup everything
@@ -1189,12 +1194,12 @@
 	movff	tft_save_width,win_width+0
 	return
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 ; TFT_box: fills current box with current color
 ; Inputs : win_top, win_leftx2, win_height, win_width, win_color1, win_color2
 ; Outputs: (none)
 ; Trashed: WREG, PROD
-
+;
 	global	TFT_box
 TFT_box:
 	;---- Define Window ------------------------------------------------------
@@ -1224,10 +1229,10 @@
 	bcf		INTCON,GIE
 	movff	win_color1,PORTA		; upper
 	movff	win_color2,PORTH		; lower
-	WR_L
-	WR_H							; tick
-	WR_L
-	WR_H							; tick
+	WR_L							; tick
+	WR_H							; ...
+	WR_L							; tick
+	WR_H							; ...
 	bsf		INTCON,GIE
 	decfsz	PRODL,F					; row loop finished ?
 	bra		TFT_box3				; NO - continue
@@ -1326,13 +1331,14 @@
 	setf	win_bargraph			; YES - reset bargraph mode
 	return
 
-;=============================================================================
-; Convert 8 bit RGB b'RRRGGGBB' into 16 bit RGB b'RRRRRGGGGGGBBBBB'
 
+;-----------------------------------------------------------------------------
+; Convert 8 bit RGB b'RRRGGGBB' into 16 bit RGB    b'RRRRRGGGGGGBBBBB'
+;                       WREG                       win_color1 win_color2
 	global	TFT_set_color
 TFT_set_color:
 	movwf	tft_temp1				; get 8 bit RGB b'RRRGGGBB' into tft_temp1...
-	movwf	tft_temp2				; ... and tft_temp2
+	movwf	tft_temp2				;                        ... and tft_temp2
 
 	; mask bit 7,6,5,4,3,2
 	movlw	b'00000011'
@@ -1467,7 +1473,7 @@
 	return
 
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
  IFDEF _screendump
 
@@ -1649,6 +1655,6 @@
 
  ENDIF	; _screendump
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
 	END
--- a/src/tft.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/tft.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File tft.inc                              combined next generation V3.03.7
+;   File tft.inc                            * combined next generation V3.09.4m
 ;
 ;   Declaring interfaces to the TFT screen and its Oxxx controler
 ;
@@ -9,165 +9,118 @@
 ; HISTORY
 ;  2011-05-24 : [jDG] Cleanups from initial Matthias code.
 
-;=============================================================================
-; TFT public subroutines
-;=============================================================================
-
-;-----------------------------------------------------------------------------
-; Write two half-pixels at position (win_top,win_leftx2)
-;
-; Inputs : win_leftx2, win_top, win_color:2
-; Outputs: (none)
-; Trashed: WREG, PROD
-
-	extern	pixel_write
-
-
-;-----------------------------------------------------------------------------
-; Write one half-pixel at position (win_top,win_leftx2)
-;
-; Inputs : win_leftx2, win_top, win_color:2
-; Outputs: (none)
-; Trashed: WREG, PROD
-
-	extern	half_pixel_write
-
 
 ;-----------------------------------------------------------------------------
-; Draw a frame around current box with current color
-; Inputs :  win_top, win_leftx2, win_height, win_width, win_color1, win_color2
-; Outputs: (none)
-; Trashed: WREG, PROD, aa_start:2, aa_end:2, win_leftx2, win_width:1
-
-	extern	TFT_frame
-
+; public Functions
 
-;-----------------------------------------------------------------------------
-	extern	TFT_DisplayOff					; power-off everything (needs a boot thereafter)
-	extern	TFT_boot						; initialize screen hardware
-	extern	TFT_Display_FadeIn				; smooth lighting  up
-	extern	TFT_Display_FadeOut				; smooth darkening down
-	extern	TFT_ClearScreen
-	extern	TFT_box_write
-	extern	TFT_box_write_16bit_win_left	; with column in PRODL:PRODH
-	extern	TFT_box
-	extern	TFT_DataWrite_PROD
-	extern	TFT_set_color
-;	extern	init_pixel_write
-	extern	pixel_write
-	extern	pixel_write_col320
-	extern	half_vertical_line
-	extern	half_horizontal_line
+	extern	TFT_DisplayOff			; power-off everything (needs a boot thereafter)
+	extern	TFT_boot				; initialize screen hardware
+	extern	TFT_Display_FadeIn		; smooth lighting  up
+	extern	TFT_Display_FadeOut		; smooth darkening down
+	extern	TFT_ClearScreen			; clear screen
+
+	extern	TFT_box_write			; send TFT window address
+	extern	TFT_set_color			; set output color
+;	extern	pixel_write				; draw two half-pixels at position         (win_top,win_leftx2 )
+	extern	pixel_write_col320		; draw two half-pixels at position         (win_top,PRODH:PRODL)
+	extern	half_vertical_line		; draw a vertical   line of half-pixels at (win_top,win_leftx2,win_height)
+	extern	half_horizontal_line	; draw a horizontal line of half-pixels at (win_top,win_leftx2,win_width)
 
  IFDEF _screendump
-	extern	TFT_dump_screen
-	extern	TFT_dump_screen_check
+	extern	TFT_dump_screen			; send a screenshot via the serial interface immediately
+	extern	TFT_dump_screen_check	; send a screenshot via the serial interface on command
  ENDIF
 
 
-;=============================================================================
-; Low level macros (for aa_wordprocessor and color_processor)
+;-----------------------------------------------------------------------------
+; low Level Macros (for aa_wordprocessor and color_processor)
 ;
+
+Index_out	macro	low_b
+	movlw	low_b
 	extern	TFT_CmdWrite
-Index_out		macro	low_b
-					movlw	low_b
-					call	TFT_CmdWrite
-				endm
+	call	TFT_CmdWrite
+	endm
 
 
-;=============================================================================
-; shortcuts for TFT_box and TFT_frame call sequences
-;
-	extern	box_frame_std, box_frame_common, box_frame_color, box_frame_color16
-	extern	box_std_block, box_black_block,  box_color_block
+;-----------------------------------------------------------------------------
+; colored Boxes
 
-; Erase a given screen area
-;
-WIN_BOX_BLACK	macro	top, bottom, left, right
-					call	box_black_block
-					db		top, (bottom)-(top)+1, left, (right)-(left)+1
-				endm
+WIN_BOX_BLACK	macro	top, bottom, left, right			; black box (erase scree area)
+	extern	box_black_block
+	call	box_black_block
+	db		top, (bottom)-(top)+1, left, (right)-(left)+1
+	endm
 
+WIN_BOX_STD		macro	top, bottom, left, right			; white box
+	extern	box_std_block
+	call	box_std_block
+	db		top, (bottom)-(top)+1, left, (right)-(left)+1
+	endm
 
-; Fill a given screen area with standard color (white)
-;
-WIN_BOX_STD		macro	top, bottom, left, right
-					call	box_std_block
-					db		top, (bottom)-(top)+1, left, (right)-(left)+1
-				endm
-
+WIN_BOX_COLOR	macro	top, bottom, left, right			; box with color from WREG
+	extern	box_color_block
+	call	box_color_block
+	db		top, (bottom)-(top)+1, left, (right)-(left)+1
+	endm
 
-; Fill a given screen area with color from WREG (8 bits rrrgggbb)
-;
-WIN_BOX_COLOR	macro	top, bottom, left, right
-					call	box_color_block
-					db		top, (bottom)-(top)+1, left, (right)-(left)+1
-				endm
+BOX_COLOR		macro				; box with color from WREG and pre-set coordinates
+	extern	box_color
+	call	box_color
+	endm
 
-; Draw a frame in standard color (white)
-;
-WIN_FRAME_STD	macro	top, bottom, left, right
-					call	box_frame_std
-					db		top, (bottom)-(top)+1, left, (right)-(left)+1
-				endm
+BOX				macro				; box with pre-set color and coordinates
+	extern	TFT_box
+	call	TFT_box
+	endm
 
 
-; Draw a frame with color from WREG (8 bits rrrgggbb)
-;
-WIN_FRAME_COLOR	macro	top, bottom, left, right
-					call	box_frame_color
-					db		top, (bottom)-(top)+1, left, (right)-(left)+1
-				endm
-
+;-----------------------------------------------------------------------------
+; colored Frames
 
-; Draw a frame with color from win_color (16 bits in TFT format)
-;
-WIN_FRAME_COLOR16 macro	top, bottom, left, right
-					call	box_frame_color16
-					db		top, (bottom)-(top)+1, left, (right)-(left)+1
-				endm
-
+WIN_FRAME_STD	macro	top, bottom, left, right			; white frame
+	extern	box_frame_std
+	call	box_frame_std
+	db		top, (bottom)-(top)+1, left, (right)-(left)+1
+	endm
 
-WIN_FONT		macro	win_font_input
-					movlw	win_font_input
-					movff	WREG,win_font
-				endm
-
-
-WIN_TOP			macro	win_top_input
-					movlw	win_top_input
-					movff	WREG,win_top
-				endm
+WIN_FRAME_COLOR	macro	top, bottom, left, right			; frame with color from WREG
+	extern	box_frame_color
+	call	box_frame_color
+	db		top, (bottom)-(top)+1, left, (right)-(left)+1
+	endm
 
 
-WIN_HEIGHT		macro	win_hight_input
-					movlw	win_hight_input
-					movff	WREG,win_height
-				endm
+;-----------------------------------------------------------------------------
+; set individual Coordinates
+
+WIN_TOP		macro	win_top_input
+	movlw	win_top_input
+	movwf	win_top
+	endm
 
 
-WIN_LEFT		macro	win_left_input
-					movlw	win_left_input
-					movff	WREG,win_leftx2
-				endm
+WIN_HEIGHT	macro	win_hight_input
+	movlw	win_hight_input
+	movwf	win_height
+	endm
 
 
-WIN_WIDTH		macro	win_width_input
-					movlw	win_width_input
-					movff	WREG,win_width
-				endm
+WIN_LEFT	macro	win_leftx2_input
+	movlw	win_leftx2_input
+	movwf	win_leftx2
+	endm
 
 
-WIN_COLOR		macro	win_color_input
-					movlw	win_color_input
-					call	TFT_set_color
-				endm
+WIN_WIDTH	macro	win_width_input
+	movlw	win_width_input
+	movwf	win_width
+	endm
 
-;=============================================================================
-; TFT_write_prom_image
+
+;-----------------------------------------------------------------------------
+; Paint an Image stored in Program Memory, Image referenced by a Label
 ;
-
-; image referenced by a label
 TFT_WRITE_PROM_IMAGE_BY_LABEL	macro	image_label
 		extern	image_label
 		movlw	LOW   (image_label)
@@ -180,7 +133,10 @@
 		call	color_image
 	endm
 
-; image referenced by an address
+
+;-----------------------------------------------------------------------------
+; Paint an Image stored in Program Memory, image referenced by an address
+;
 TFT_WRITE_PROM_IMAGE_BY_ADDR	macro	image_address
 		movlw	LOW   (image_address)
 		movwf	TBLPTRL
@@ -192,7 +148,10 @@
 		call	color_image
 	endm
 
-; custom colors referenced by label
+
+;-----------------------------------------------------------------------------
+; Load a Custom Color Palette (to be call before TFT_WRITE_PROM_IMAGE*)
+;
 TFT_WRITE_PROM_IMAGE_CUST_COLOR	macro	colors_label
 		movlw	LOW   (colors_label)
 		movwf	TBLPTRL
@@ -202,28 +161,34 @@
 		movwf	TBLPTRU
 		extern	get_colors
 		call	get_colors
-		bsf		use_custom_colors		; will suppress reading the colors that come with the image
+		bsf		use_custom_colors		; suppress the colors that come with the image
 	endm
 
 
-;=============================================================================
-; Macros to provide our own interface code
+
+;-----------------------------------------------------------------------------
+; Pixel Writing Macros
 ;
 
-PIXEL_WRITE			macro	colRegister,	rowRegister
-						movff	colRegister,win_leftx2
-						movff	rowRegister,win_top
-						call	pixel_write
-					endm
+PIXEL_WRITE			macro	colRegister, rowRegister
+	movff	colRegister,win_leftx2
+	movff	rowRegister,win_top
+	extern	pixel_write
+	call	pixel_write
+	endm
 
 
 ;INIT_PIXEL_WRITE	macro	colRegister
-;						movff	colRegister,win_leftx2
-;						call	init_pixel_write
-;					endm
+;	movff	colRegister,win_leftx2
+;	extern	init_pixel_write
+;	call	init_pixel_write
+;	endm
 
 
 HALF_PIXEL_WRITE	macro	rowRegister
-						movff	rowRegister,win_top
-						call	half_pixel_write
-					endm
+	movff	rowRegister,win_top
+	extern	half_pixel_write
+	call	half_pixel_write
+	endm
+
+;-----------------------------------------------------------------------------
--- a/src/tft_outputs.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/tft_outputs.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File tft_outputs.asm                      next combined generation V3.09.1 fix
+;   File tft_outputs.asm                    * combined next generation V3.09.5
 ;
 ;   high-level Display Outputs
 ;
@@ -21,23 +21,21 @@
 #include "adc_lightsensor.inc"
 #include "surfmode.inc"
 #include "divemode.inc"
-#include "external_flash.inc"
 #include "ghostwriter.inc"
 #include "customview.inc"
 #include "i2c.inc"
-#include "colorschemes.inc"
 #include "calibrate.inc"
 #include "gaslist.inc"
 #include "rx_ops.inc"
 #include "logbook.inc"
+#include "external_flash.inc"
+#include "colorschemes.inc"
 
 
 ;---- external Functions -----------------------------------------------------
 
-	extern	aa_wordprocessor
 	extern	get_first_gas_to_WREG
 
-
 ;---- external Texts ---------------------------------------------------------
 
 	extern	tFirmware
@@ -67,278 +65,299 @@
  ENDIF
 
 
-tft_out	CODE
+;=============================================================================
+pallet_table	CODE_PACK 0x09800		; must be at 0x***00
+;=============================================================================
+
+
+pallet_table:
+	;	mask			disabled			memo			advice			attention		warning			; pallet
+	;	---------------	-------------------	---------------	---------------	---------------	---------------	  --------
+	DB	color_green,	color_lightblue,	color_white,	color_green,	color_yellow,	color_red		; standard
+	DB	color_red,		color_dark_red,		color_orange,	color_green,	color_yellow,	color_red		; redish
+	DB	color_cyan,		color_dark_green,	color_green,	color_green,	color_yellow,	color_red		; greenish
+	DB	color_blue,		color_deepblue,		color_lightblue,color_green,	color_yellow,	color_red		; blueish
+
 
 ;=============================================================================
-
-	global	TFT_debug_output
-TFT_debug_output:
- ifndef _debug_output
-	return
- else
-	btfsc	alt_layout_active			; alternative layout active?
-	return								; YES - abort
-
-;	WIN_TINY .100,.30					; surface mode: fits under the textual logo in the upper right corner
-;	WIN_TINY  .35, .0					; dive    mode: fits to the right side of the depth label
-	WIN_TINY   .0, .0					; dive    mode: overwrites depth label
-	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
-	bra		TFT_debug_output_1
-	bcf		mpr+1,7
-	PUTC	"-"
-	bra		TFT_debug_output_2
-TFT_debug_output_1:
-	PUTC	" "
-TFT_debug_output_2:
-	output_16_3
-	PUTC	"."
-	MOVII	int_O_profiling_overrun_max,mpr		; max runtime
-	output_16_3
-	PUTC	"."
-	movff	char_O_profiling_overrun_phase,WREG	; calculation phase causing the max runtime
-	output_hex
-	PUTC	"."
-	movff	char_O_profiling_runs_norm,mpr		; runs/cycle normal plan
-	output_99
-	PUTC	"."
-	movff	char_O_profiling_runs_alt,mpr		; runs/cycle alternative plan
-	output_99
-	STRCAT_PRINT ""
-	return
- endif
+tft_out1	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; load standard Color Pallet
+;
+	global	TFT_load_std_color_pallet
+TFT_load_std_color_pallet:
+	clrf	WREG						; select standard pallet
+	bra		TFT_load_color_pallet		; load color pallet
+
+
+;-----------------------------------------------------------------------------
+; load Dive Mode Color Pallet
+;
+	global	TFT_load_dive_color_pallet
+TFT_load_dive_color_pallet:
+	movff	opt_dive_color_scheme,WREG	; get color scheme selection
+	;bra	TFT_load_color_pallet		; load color pallet
+
+
+	; Helper Function - load color pallet
+TFT_load_color_pallet:
+	mullw	.6							; 6 bytes per pallet, compute pallet offset
+
+	movf	PRODL,W						; get pallet offset,  low
+	movwf	TBLPTRL						; set table pointer,  low
+
+	movlw	HIGH  (pallet_table)		; get start of table, high
+	movwf	TBLPTRH						; set table pointer,  high
+
+	movlw	UPPER (pallet_table)		; get start of table, upper
+	movwf	TBLPTRU						; set table pointer,  upper
+
+	lfsr	FSR2,pallet_color_mask		; point to first color in pallet
+	movlw	.6							; initialize loop counter
+TFT_load_color_pallet_loop:
+	TBLRD*+								; read color
+	movff	TABLAT,POSTINC2				; copy color to pallet
+	decfsz	WREG						; decrement loop counter, reached zero?
+	bra		TFT_load_color_pallet_loop	; NO  - loop
+	return								; YES - done
 
 
 ;=============================================================================
-
-	global	TFT_divemask_color
-TFT_divemask_color:
-	movlw	color_green
-	btfsc	divemode					; in dive mode?
-	rcall	TFT_divemask_color_dive
-	bra		TFT_standard_color0
-
-TFT_divemask_color_dive:
-	movff	opt_dive_color_scheme,WREG	; 0-3
-	incf	WREG
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_mask1	;0
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_mask2	;1
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_mask3	;2
-	retlw	color_scheme_divemode_mask4	;3
-
-
-	global	TFT_memo_color
-TFT_memo_color:							; information, values within normal range, things without a need to react upon
-	movlw	color_white
-	bra		TFT_standard_color0
-TFT_memo_color_dive:
-	retlw	color_white
-
-	global	TFT_advice_color
-TFT_advice_color:						; advices to do something, but without essential need to actually do it
-	movlw	color_green
-	bra		TFT_standard_color0
-TFT_advice_color_dive:
-	retlw	color_green
-
-	global	TFT_attention_color			; important things to be aware of and things that are developing towards a warning
-TFT_attention_color:
-	movlw	color_yellow
-	bra		TFT_standard_color0
-TFT_attention_color_dive:
-	retlw	color_yellow
-
-	global	TFT_warning_color			; important things with immediate need to react upon
-TFT_warning_color:
-	movlw	color_red
-	bra		TFT_standard_color0
-TFT_warnings_color_dive:
-	retlw	color_red
-
-
-	global	TFT_disabled_color
-TFT_disabled_color:
-	movlw	color_lightblue
-	btfsc	divemode					; in dive mode?
-	rcall	TFT_disabled_color_dive		; YES
-	bra		TFT_standard_color0
-TFT_disabled_color_dive:
-	movff	opt_dive_color_scheme,WREG	; 0-3
-	incf	WREG
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_dis1	; 0
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_dis2	; 1
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_dis3	; 2
-	retlw	color_scheme_divemode_dis4	; 3
-
-
-	global	TFT_standard_color
-TFT_standard_color:
-	setf	WREG						; default white
-	btfsc	divemode					; in dive mode?
-	rcall	TFT_standard_color_dive
-	;bra	TFT_standard_color0
-TFT_standard_color0:
-	goto	TFT_set_color				; and return...
-
-
-TFT_standard_color_dive:
-	movff	opt_dive_color_scheme,WREG	; 0-3
-	incf	WREG
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_std1	; 0
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_std2	; 1
-	dcfsnz	WREG
-	retlw	color_scheme_divemode_std3	; 2
-	retlw	color_scheme_divemode_std4	; 3
-
-
-	global	TFT_color_code_tank_pres_sac
-TFT_color_code_tank_pres_sac:			; color-code a tank pressure or SAC rate, data in hi:lo
+tft_out2	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Color-Code a Tank Pressure or SAC Rate
+;
+; Input hi:lo pressure / SAC rate
+;
+TFT_color_code_pres_sac:
 	btfss	hi,int_not_avail_flag		; is the not-available flag set?
 	bra		TFT_color_code_tank_pres_1	; NO
 	bcf		hi,int_not_avail_flag		; YES - clear not-available flag
-TFT_color_code_tank_pres_0:				;       entry point for outdated flag
-	bcf		hi,int_outdated_flag		;       clear outdated  flag (it may be set)
-	bcf		hi,int_warning_flag			;       clear warning   flag (it may be set)
-	bcf		hi,int_attention_flag		;       clear attention flag (it may be set)
-	bra		TFT_disabled_color			;       set to disabled color and return
+TFT_color_code_tank_pres_0:				;     - entry point for outdated flag
+	bcf		hi,int_outdated_flag		;     - clear outdated  flag (it may be set)
+	bcf		hi,int_warning_flag			;     - clear warning   flag (it may be set)
+	bcf		hi,int_attention_flag		;     - clear attention flag (it may be set)
+	FONT_COLOR_DISABLED					;     - set to disabled color and return
+	return								;     - done
+
 TFT_color_code_tank_pres_1:
 	btfsc	hi,int_outdated_flag		; is the outdated flag set?
 	bra		TFT_color_code_tank_pres_0	; YES - handle alike with not-available flag
+	btfss	hi,int_warning_flag			; NO  - is the warning flag set?
+	bra		TFT_color_code_tank_pres_2	;       NO
+	bcf		hi,int_attention_flag		;       YES - clear  attention flag (it may be set)
+	bcf		hi,int_warning_flag			;           - clear  warning flag
+	FONT_COLOR_WARNING					;           - select warning color
+	return								;           - done
+
 TFT_color_code_tank_pres_2:
-	btfss	hi,int_warning_flag			; is the warning flag set?
-	bra		TFT_color_code_tank_pres_3	; NO
-	bcf		hi,int_warning_flag			; YES - clear warning   flag
-	bcf		hi,int_attention_flag		;     - clear attention flag (it may be set)
-	bra		TFT_warning_color			;     - set to warning color and return
+	btfss	hi,int_attention_flag		; is the attention flag set?
+	bra		TFT_color_code_tank_pres_3	; NO  - set memo color and return
+	bcf		hi,int_attention_flag		; YES - clear attention flag
+	FONT_COLOR_ATTENTION				;     - set to attention color
+	return								;     - done
+
 TFT_color_code_tank_pres_3:
-	btfss	hi,int_attention_flag		; is the attention flag set?
-	bra		TFT_memo_color				; NO  - set to memo color and return
-	bcf		hi,int_attention_flag		; YES - clear attention flag
-	bra		TFT_attention_color			;     - set to attention color and return
-
-
+	FONT_COLOR_MEMO						; set to memo color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code a Gas by its ppO2
+;
+; Input hi                O2% of the gas
+;       pressure_abs_10   current absolute pressure / 10
+;
 	global	TFT_color_code_gaslist
-TFT_color_code_gaslist:					; color-code a gas (%O2 in hi) according to current absolute pressure
-; Check very high ppO2 manually
-	MOVII	pressure_abs_10,xA
-	movff	hi,xB+0
-	clrf	xB+1
+TFT_color_code_gaslist:
+	; check for very high ppO2
+	MOVII	pressure_abs_10,xA			; get absolute pressure / 10
+	movff	hi,xB+0						; get O2%
+	clrf	xB+1						; ...
 	call	mult16x16					; hi * absolute pressure / 10
-; Check if ppO2 > 6.55 bar
+	; check if ppO2 > 6.55 bar
 	tstfsz	xC+2						; char_I_O2_ratio * absolute pressure / 10 > 65536, i.e. ppO2 > 6.55 bar ?
-	bra		TFT_warning_color			; YES - warn in warning color
-; Check if ppO2 > 3.30 bar
-	btfsc	xC+1,7
-	bra		TFT_warning_color			; YES - warn in warning color
-; Check for low ppO2
-	MOVII	xC,sub_a
-	movff	char_I_ppO2_min,WREG
-	mullw	d'100'						; char_I_ppO2_min*100
-	MOVII	PRODL,sub_b
+	bra		TFT_color_code_gaslist_warn	; YES - set warning color and return
+
+	; check if ppO2 > 3.30 bar
+	btfsc	xC+1,7						; ppO2 > 3.30 bar ?
+	bra		TFT_color_code_gaslist_warn	; YES - set warning color and return
+
+	; check for low ppO2
+	MOVII	xC,sub_a					; get ppO2 of the gas
+	movff	char_I_ppO2_min,WREG		; get minimum ppO2
+	mullw	d'100'						; compute (minimum ppO2) * 100
+	MOVII	PRODL,sub_b					; copy result to sub_b
 	call	cmpU16						; compare (sub_a - sub_b)
 	btfsc	neg_flag					; lower than ppO2 min?
-	bra		TFT_warning_color			; YES - set warning color and return
-; Check for high ppO2
+	bra		TFT_color_code_gaslist_warn	; YES - set warning color and return
+
+	; check for high ppO2
 	movff	char_O_deco_info,WREG		; bank-safe copy of deco info vector
 	btfsc	WREG,deco_mode				; are we in deco?
 	bra		TFT_color_code_gaslist_deco	; YES - check against ppO2 max deco only
-										; NO  - check against ppO2 max travel/normal and deco
-; Check for ppO2 max travel/normal
+
+	; check for ppO2 max travel/normal
 	movff	char_I_ppO2_max_work,WREG	; ppo2 max during working phase
 	mullw	d'100'						; char_I_ppO2_max_work*100
 	ADDLI	ppO2_margin_on_max,PROD		; add ppO2 margin on max value to compensate for surface pressures > 1000 hPa
 	MOVII	PRODL,sub_b					; copy result to sub_b
 	call	cmpU16						; compare (sub_a - sub_b)
 	btfss	neg_flag					; higher than ppO2 max travel/deco?
-	rcall	TFT_attention_color			; YES - set attention color
-; Check for ppO2 max deco
+	FONT_COLOR_ATTENTION				; YES - set attention color
+	;bra	TFT_color_code_gaslist_deco ; continue checking against max deco
+
+	; check for ppO2 max deco
 TFT_color_code_gaslist_deco:
 	movff	char_I_ppO2_max_deco,WREG	; ppo2 max for deco
 	mullw	d'100'						; char_I_ppO2_max_deco * 100
 	ADDLI	ppO2_margin_on_max,PROD		; add ppO2 margin on max value to compensate for surface pressures > 1000 hPa
 	MOVII	PRODL,sub_b					; copy result to sub_b
 	call	cmpU16						; compare (sub_a - sub_b)
-	btfss	neg_flag					; higher than ppO2 max deco?
-	bra		TFT_warning_color			; YES - set warning color and return
-	return								; NO  - keep current color
-
-
-TFT_color_code_ceiling:					; color-code the ceiling depth
+	btfsc	neg_flag					; higher than ppO2 max deco?
+	return								; NO  - done
+	;bra	TFT_color_code_gaslist_warn	; YES - set warning color and return
+
+
+	; Helper Function - set waring color and return
+TFT_color_code_gaslist_warn:
+	FONT_COLOR_WARNING					; select warning color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code the Ceiling Depth
+;
+; Input mpr                      ceiling depth             [mbar]
+;       pressure_rel_cur_cached  current relative pressure [mbar]
+;
+TFT_color_code_ceiling:
+	; check for invalid
 	btfsc	hi,char_invalid_flag		; is the invalid flag set? (bit 7 here)
-	bra		TFT_color_code_ceiling_1	; YES - set disabled color
-	MOVII	pressure_rel_cur_cached,sub_a; NO - get current pressure to sub_a
-	MOVII	mpr,sub_b					;     - get ceiling to sub_b
-	call	cmpU16						;     - sub_a - sub_b = relative pressure [mbar] - int_O_ceiling [mbar]
-	btfss	neg_flag					;     - is current depth < ceiling (too shallow) ?
-	bra		TFT_memo_color				;       NO  - set to memo color and return
-	movff	char_O_deco_warnings,WREG	;       YES - bank-safe copy of deco warnings
-	btfsc	WREG,outside_warning		;           - are we currently outside of the ZH-L16 model?
-	bra		TFT_warning_color			;             YES - set to warnings  color and return
-	bra		TFT_attention_color			;             NO  - set to attention color and return
-TFT_color_code_ceiling_1:
+	bra		TFT_color_code_ceiling_dis	; YES - set to disabled color and return
+
+	; check for ceiling
+	MOVII	pressure_rel_cur_cached,sub_a;get current pressure to sub_a
+	MOVII	mpr,sub_b					; get ceiling to sub_b
+	call	cmpU16						; sub_a - sub_b = relative pressure [mbar] - int_O_ceiling [mbar]
+	btfss	neg_flag					; is current depth < ceiling (too shallow) ?
+	bra		TFT_color_code_ceiling_memo	; NO  - set to memo color and return
+
+	; check for outside
+	movff	char_O_deco_warnings,WREG	; bank-safe copy of deco warnings
+	btfss	WREG,outside_warning		; are we currently outside of the ZH-L16 model?
+	bra		TFT_color_code_ceiling_attn	; NO  - set to attention color and return
+	;bra	TFT_color_code_ceiling_warn	; YES - set to warnings  color and return
+
+
+	; Helper Functions - select color and return
+TFT_color_code_ceiling_warn:
+	FONT_COLOR_WARNING					; select color
+	return								; done
+
+TFT_color_code_ceiling_attn:
+	FONT_COLOR_ATTENTION				; select color
+	return								; done
+
+TFT_color_code_ceiling_memo:
+	FONT_COLOR_MEMO						; select color
+	return								; done
+
+TFT_color_code_ceiling_dis:
 	bcf		hi,char_invalid_flag		; clear the invalid flag (bit 7 here)
-	bra		TFT_disabled_color			; set to disabled color and return
-
-
-TFT_color_code_stop:					; color-code the stop depth: memo      color if below stop depth,
-										;                            attention color if above stop but below ceiling,
-										;                            warning   color if above stop and ceiling
-										;                            (ceiling depth is calculated using current GF)
+	FONT_COLOR_DISABLED					; select disabled color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code the Stop Depth
+;
+; memo      color if below stop depth,
+; attention color if above stop but below ceiling*,
+; warning   color if above stop and ceiling*
+;
+; Input: depth_meter       current depth
+;        lo                stop    depth
+;        char_O_deco_gas   deco data valid flag
+;
+; * the ceiling depth is calculated using current (interpolated) GF
+;
+TFT_color_code_stop:
+	; check for invalid
 	movff	char_O_deco_gas+0,WREG		; get flag for invalid deco data
 	btfsc	WREG,char_invalid_flag		; is the invalid flag set?
-	bra		TFT_disabled_color			; YES - set to disabled color and return
-	movff	char_O_deco_depth+0,WREG	; NO  - get depth of first stop in meters into WREG
-	subwf	depth_meter,W				;     - compute current depth - stop depth
-	btfsc	STATUS,C					;     - result negative?
-	bra		TFT_color_code_stop_1		;       NO  - not shallower than stop depth, check for ascent advice
-	MOVII	int_O_ceiling,sub_b			;       YES - get ceiling depth in mbar
-	btfsc	sub_b+1,char_invalid_flag	;           - is the invalid flag set? (bit 7 here)
-	bra		TFT_warning_color			;             YES - set to warning color and return
-	MOVII	pressure_rel_cur_cached,sub_a;            NO  - get current pressure
-	call	cmpU16						;                 - sub_a - sub_b = relative pressure - int_O_ceiling
-	btfsc	neg_flag					;                 - is ceiling > current depth?
-	bra		TFT_warning_color			;                   YES - set to warning   color and return
-	bra		TFT_attention_color			;                   NO  - set to attention color and return
+	bra		TFT_color_code_stop_dis		; YES - set to disabled color and return
+
+	; check for shallower than stop depth
+	movf	lo,W						; get depth of first stop in meters into WREG
+	subwf	depth_meter,W				; compute current depth - stop depth
+	btfsc	STATUS,C					; result negative?
+	bra		TFT_color_code_stop_1		; NO  - not shallower than stop depth, check for ascent advice
+	MOVII	int_O_ceiling,sub_b			; YES - get ceiling depth in mbar
+	btfsc	sub_b+1,char_invalid_flag	;     - is the invalid flag set? (bit 7 here)
+	bra		TFT_color_code_stop_warn	;       YES - select warning color and return
+	MOVII	pressure_rel_cur_cached,sub_a;      NO  - get current pressure
+	call	cmpU16						;           - sub_a - sub_b = relative pressure - int_O_ceiling
+	btfsc	neg_flag					;           - is ceiling > current depth?
+	bra		TFT_color_code_stop_warn	;             YES - set to warning   color and return
+	bra		TFT_color_code_stop_attn	;             NO  - set to attention color and return
+
+	; check for ascent advice
 TFT_color_code_stop_1:
-	movff	char_O_deco_depth+0,WREG	; get depth of first stop in meters into WREG
+	movf	lo,W						; get depth of first stop in meters into WREG
 	incf	WREG,W						; compute stop depth + 1 meter
 	subwf	depth_meter,W				; compute current depth - (first stop depth + 1 meter)
 	btfss	STATUS,C					; result negative?
-	bra		TFT_memo_color				; YES - within 1 meter of stop depth, use memo color
-	btfss	deco_region					; NO  - within deco stops region?
-	bra		TFT_memo_color				;       NO  - use memo color
-	bsf		win_invert					;       YES - give ascent advice, ...
-	bra		TFT_advice_color			;           - ... and return
-
-
+	bra		TFT_color_code_stop_memo	; YES - within 1 meter of stop depth, use memo color
+	btfsc	deco_region					; NO  - within deco stops region?
+	bra		TFT_color_code_stop_advc	;       YES - use advice color and return
+	;bra	TFT_color_code_stop_memo	;       NO  - use memo   color and return
+
+
+	; Helper Functions - select color and return
+TFT_color_code_stop_memo:
+	FONT_COLOR_MEMO						; select color
+	return								; done
+
+TFT_color_code_stop_advc:
+	FONT_COLOR_ADVICE					; select color
+	bsf		win_invert					; print in inverse
+	return								; done
+
+TFT_color_code_stop_attn:
+	FONT_COLOR_ATTENTION				; select color
+	return								; done
+
+TFT_color_code_stop_warn:
+	FONT_COLOR_WARNING					; select color
+	return								; done
+
+TFT_color_code_stop_dis:
+	FONT_COLOR_DISABLED					; select color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code the current Depth
+;
 TFT_color_code_depth:
 	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?
+	btfsc	warn_det_depth_limit		; YES - depth limit warning active?
 	bra		TFT_color_code_depth_warn	;       YES - set to warning color
-	bra		TFT_color_code_depth_mod	;       NO  - check depth against MOD and return...
+	bra		TFT_color_code_depth_mod	;       NO  - check depth against MOD
+
 TFT_color_code_depth_no_mod:
-	btfsc	depth_limit_exceeded		; NO  - deeper than depth limit?
-	bra		TFT_warning_color			;       YES - set to warning color and return
-	bra		TFT_memo_color				;       NO  - set to memo    color and return...
+	btfsc	warn_det_depth_limit		; depth limit warning active?
+	bra		TFT_color_code_depth_warn	; YES - set to warning color and return
+	bra		TFT_color_code_depth_memo	; NO  - set to memo    color and return...
+
 TFT_color_code_depth_mod:
  IFDEF _ccr_pscr
 	movff	opt_dive_mode,WREG			; get deco mode: 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR
@@ -346,290 +365,1002 @@
 	bra		TFT_color_code_depth_no_ccr	; NO  - continue checking for ppO2
 	btfss	bailout_mode				; YES - check if in bailout
 	bra		TFT_color_code_depth_outside;       NO  - continue checking for outside ZHL16 model
+	;bra	TFT_color_code_depth_no_ccr ;       YES - continue checking for ppO2
  ENDIF
+
 TFT_color_code_depth_no_ccr:
 	movff	int_O_breathed_ppO2+1,WREG	; get upper byte of currently breathed ppO2
 	btfsc	WREG,int_warning_flag		; is the warning flag set?
 	bra		TFT_color_code_depth_warn	; YES - animate in warning design
+	;bra	TFT_color_code_depth_outside; NO  - continue checking for outside ZHL16 model
+
 TFT_color_code_depth_outside:
 	movff	char_O_deco_warnings,WREG	; bank-safe copy of deco warnings
 	btfsc	WREG,outside_warning		; are we currently outside of the ZH-L16 model?
 	bra		TFT_color_code_depth_warn	; YES - activate  depth warning
-	bcf		depth_warning				; NO  - terminate depth warning
-	btfsc	WREG,outside_attention		;     - are we near to outside of the ZH-L16 model?
+	btfsc	WREG,outside_attention		; NO  - are we near to outside of the ZH-L16 model?
 	bra		TFT_color_code_depth_att	;       YES - activate  depth attention
-	bcf		depth_attention				;       NO  - terminate depth attention
-	bra		TFT_memo_color				;           - select memo color and return
+	;bra	TFT_color_code_depth_memo	;       NO  - select memo color and return
+
+
+	; Helper Functions - set colors and attention/warning flags
+TFT_color_code_depth_memo:
+	bcf		depth_color_warning			; terminate depth warning
+	bcf		depth_color_attention		; terminate depth attention
+	FONT_COLOR_MEMO						; select color
+	return								; done
+
 TFT_color_code_depth_warn:
-	bsf		depth_warning				; activate depth warning
-	bra		TFT_warning_color			; select warning color and return...
+	bsf		depth_color_warning			; activate  depth warning
+	bcf		depth_color_attention		; terminate depth attention
+	FONT_COLOR_WARNING					; select warning color
+	return								; done
+
 TFT_color_code_depth_att:
-	bsf		depth_attention				; activate depth attention
-	bra		TFT_attention_color			; select attention color and return...
-
-
+	bcf		depth_color_warning			; terminate depth warning
+	bsf		depth_color_attention		; activate  depth attention
+	FONT_COLOR_ATTENTION				; select attention
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code a CNS Value
+;
+; Input  hi:lo  CNS value [%]
+;
 	global	TFT_color_code_cns
-TFT_color_code_cns:						; color-code CNS values (CNS in hi:lo [%])
+TFT_color_code_cns:
 	btfss	hi,int_invalid_flag			; is the invalid flag set?
 	bra		TFT_color_code_cns_1		; NO
 	bcf		hi,int_invalid_flag			; YES - clear invalid flag
-	bcf		hi,int_warning_flag			;       clear warning   flag (it may be set)
-	bcf		hi,int_attention_flag		;       clear attention flag (it may be set)
-	bra		TFT_disabled_color			;       set to disabled color and return
+	bcf		hi,int_warning_flag			;     - clear warning   flag (it may be set)
+	bcf		hi,int_attention_flag		;     - clear attention flag (it may be set)
+	FONT_COLOR_DISABLED					;     - select disabled color
+	return								;     - done
+
 TFT_color_code_cns_1:
 	btfss	hi,int_warning_flag			; is the warning flag set?
 	bra		TFT_color_code_cns_2		; NO
 	bcf		hi,int_warning_flag			; YES - clear warning   flag
 	bcf		hi,int_attention_flag		;     - clear attention flag (it may be set)
-	bra		TFT_warning_color			;     - set to warning color and return
+	FONT_COLOR_WARNING					;     - select warning color
+	return								;     - done
+
 TFT_color_code_cns_2:
 	btfss	hi,int_attention_flag		; is the attention flag set?
-	bra		TFT_memo_color				; NO  - set to memo color and return
+	bra		TFT_color_code_cns_3		; NO  - select memo color
 	bcf		hi,int_attention_flag		; YES - clear attention flag
-	bra		TFT_attention_color			;     - set to attention color and return
-
-
-TFT_color_code_gf:
-	; with int_O_lead_supersat, the upper byte is solely used for the flags
-	; and not for the value, thus there is no need to clear the flags
+	FONT_COLOR_ATTENTION				;     - select attention color
+	return								;     - done
+
+TFT_color_code_cns_3:
+	FONT_COLOR_MEMO						; select memo color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code a Supersaturation Value
+;
+; Input  hi:lo  CNS value [%]
+;
+; with int_O_lead_supersat, the upper byte is solely used for the flags
+; and not for the value, thus there is no need to clear the flags
+;
+TFT_color_code_supersat:
+	movf	pallet_color_memo,W			; load memo color by default
+	btfsc	hi,int_attention_flag		; is the attention flag set?
+	movf	pallet_color_attention,W	; YES - replace by attention color
+	btfsc	hi,int_warning_flag			; is the warning flag set?
+	movf	pallet_color_warning,W		; YES - replace by warning   color
 	btfsc	hi,int_invalid_flag			; is the invalid flag set?
-	bra		TFT_disabled_color			; YES - set to disabled color and return
-	btfsc	hi,int_warning_flag			; NO  - is the warning flag set?
-	bra		TFT_warning_color			;       YES - set to warning color and return
-	btfsc	hi,int_attention_flag		;       NO  - is the attention flag set?
-	bra		TFT_attention_color			;             YES - set to attention color and return
-	bra		TFT_memo_color				;             NO  - set to memo      color and return
-
-
-TFT_color_code_ppo2:					; color-code ppO2 values (ppO2 in hi:lo [cbar]) by its warning flags
+	movf	pallet_color_disabled,W		; YES - replace by disabled  color
+	movwf	font_color					; set font color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code a ppO2 Value by its warning flags (16 bit)
+;
+; Input  hi:lo  ppO2 value [cbar]
+;
+TFT_color_code_ppo2:
 	btfss	hi,int_warning_flag			; is the warning flag set?
 	bra		TFT_color_code_ppo2_1		; NO
 	bcf		hi,int_warning_flag			; YES - clear warning flag
-	bcf		hi,int_attention_flag		;       clear attention    flag (it may be set)
-	bcf		hi,int_high_flag			;       clear high warning flag (it may be set)
-	bcf		hi,int_low_flag				;       clear low  warning flag (it may be set)
-	bra		TFT_warning_color			;       warn in warning color
+	bcf		hi,int_attention_flag		;     - clear attention    flag (it may be set)
+	bcf		hi,int_high_flag			;     - clear high warning flag (it may be set)
+	bcf		hi,int_low_flag				;     - clear low  warning flag (it may be set)
+	FONT_COLOR_WARNING					;     - select warning color
+	return								;     - done
+
 TFT_color_code_ppo2_1:
 	btfss	hi,int_attention_flag		; is the attention flag set?
 	bra		TFT_color_code_ppo2_2		; NO
 	bcf		hi,int_attention_flag		; YES - clear attention    flag (it may be set)
-	bcf		hi,int_high_flag			;       clear high warning flag (it may be set)
-	bcf		hi,int_low_flag				;       clear low  warning flag (it may be set)
-	bra		TFT_attention_color			;       set to attention color and return
+	bcf		hi,int_high_flag			;     - clear high warning flag (it may be set)
+	bcf		hi,int_low_flag				;     - clear low  warning flag (it may be set)
+	FONT_COLOR_ATTENTION				;     - select to attention color
+	return								;     - done
+
 TFT_color_code_ppo2_2:
 	bcf		hi,int_high_flag			; clear high warning flag (it may be set)
 	bcf		hi,int_low_flag				; clear low  warning flag (it may be set)
-	bra		TFT_memo_color				; set to memo color and return
-
-;=============================================================================
+	FONT_COLOR_MEMO						; select memo color
+	return								; done
+
 
  IFDEF _ccr_pscr
 
-TFT_color_code_ppo2_hud:				; color-code ppO2 values (ppO2 in --:lo [cbar]) by its value
+;-----------------------------------------------------------------------------
+; Color-Code a ppO2 Value by its warning flags (8 bit)
+;
+; Input  lo  ppO2 value [cbar]
+;
+TFT_color_code_ppo2_hud:
 	movff	char_O_deco_info,WREG		; get the deco info vector
-	btfss	WREG,deco_mode				; are we in deco?
+	btfss	WREG,deco_mode				; in deco?
 	bra		TFT_color_code_ppo2_hud_a	; NO  - load normal max value as threshold
-	movff	char_I_ppO2_max_deco,WREG	; YES - load deco value as threshold
-	bra		TFT_color_code_ppo2_hud_b
+	movff	char_I_ppO2_max_deco,WREG	; YES - load deco   max value as threshold
+	bra		TFT_color_code_ppo2_hud_b	; continue
+
 TFT_color_code_ppo2_hud_a:
 	movff	char_I_ppO2_max_work,WREG	; ppO2 max while in working phase
+	;bra	TFT_color_code_ppo2_hud_b	; continue
+
 TFT_color_code_ppo2_hud_b:
 	cpfsgt	lo							; lo > threshold?
 	bra		TFT_color_code_ppo2_hud1	; NO  - continue with checking for ppO2 low
-	bra		TFT_warning_color			; YES - set warning color and return
+	FONT_COLOR_WARNING					; YES - set warning color
+	return								;     - done
+
 TFT_color_code_ppo2_hud1:
 	movff	opt_dive_mode,WREG			; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR
-	decfsz	WREG,F						; now:  0=CC, 1=Gauge, 2=Apnea, 3=PSCR
-	bra		TFT_color_code_ppo2_hud_nocc; not CCR...
-	btfsc	bailout_mode
-	bra		TFT_color_code_ppo2_hud_nocc; is bailout, hence not loop mode...
-	movff	char_I_ppO2_min_loop,WREG	; ppO2 min loop mode color coding
-	bra		TFT_color_code_ppo2_hud_cont
+	decfsz	WREG,F						; in CCR mode?
+	bra		TFT_color_code_ppo2_hud_nocc; NO  - check with ppO2 min for OC mode
+	btfsc	bailout_mode				; YES - in bailout mode?
+	bra		TFT_color_code_ppo2_hud_nocc;       YES - check with ppO2 min for OC mode
+	movff	char_I_ppO2_min_loop,WREG	;       NO  - check with ppO2 min for loop mode
+	bra		TFT_color_code_ppo2_hud_com	;           - continue with common part
+
 TFT_color_code_ppo2_hud_nocc:
-	movff	char_I_ppO2_min,WREG		; PPO2 min for all other modes
-TFT_color_code_ppo2_hud_cont:
+	movff	char_I_ppO2_min,WREG		; get ppO2 min for all other modes
+	;bra	TFT_color_code_ppo2_hud_com	; continue with common part
+
+TFT_color_code_ppo2_hud_com:
 	cpfslt	lo							; lo < char_I_ppO2_min?
-	bra		TFT_memo_color				; NO  - set memo    color and return...
-	bra		TFT_warning_color			; Yes - set warning color and return
+	bra		TFT_color_code_ppo2_hud_com1; NO  - set memo    color
+	FONT_COLOR_WARNING					; YES - set warning color
+	return								;     - done
+
+TFT_color_code_ppo2_hud_com1:
+	FONT_COLOR_MEMO						; select memo color
+	return								; done
 
  ENDIF	; _ccr_pscr
 
+
+;-----------------------------------------------------------------------------
+; Color-Code the Battery Level
+;
+; Input  battery_low_condition  battery status flag
+;
+TFT_color_code_battery:
+	movf	pallet_color_memo,W			; get memo color by default
+	btfsc	battery_low_condition		; battery low condition detected?
+	movf	pallet_color_warning,W		; YES - switch to warning color
+	movwf	font_color					; set font color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Color-Code according to Gas Number
+;
+; Input  WREG  gas number
+;
+	global	TFT_color_code_gas
+TFT_color_code_gas:
+	movwf	up							; copy gas number (1-6) to up
+	movlw	color_white					; default color
+	dcfsnz	up,F						; gas 1 ?
+	movlw	color_white					; YES - color for gas 1
+	dcfsnz	up,F						; gas 2 ?
+	movlw	color_green					; YES - color for gas 2
+	dcfsnz	up,F						; gas 3 ?
+	movlw	color_red					; YSE - color for gas 3
+	dcfsnz	up,F						; gas 4 ?
+	movlw	color_yellow				; YES - color for gas 4
+	dcfsnz	up,F						; gas 5 ?
+	movlw	color_cyan					; YES - color for gas 5
+	dcfsnz	up,F						; gas 6 ?
+	movlw	color_pink					; YES - color for gas 6
+	movwf	font_color					; set color
+	return								; done
+
+
 ;=============================================================================
-
-TFT_color_code_battery:					; color-code the battery display, with battery percent in lo
+tft_out3	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - current Time
+;
+	global	TFT_surfmode_time
+TFT_surfmode_time:
+	WIN_SMALL surf_clock_column+.7,surf_clock_row
+	FONT_COLOR_MEMO						; set color
+	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
+	movff	rtc_latched_hour,lo			; get   hours
+	output_99							; print hours (0-99)
+	movlw	':'							; load a ":"
+	movff	rtc_latched_secs,lo			; get seconds
+	btfss	lo,0						; on even second?
+	movlw	' '							; NO - load a space char
+	movwf	POSTINC2					; print ":" or space char
+	movff	rtc_latched_mins,lo			; get   minutes
+	output_99x							; print minutes (00-99)
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - current Date
+;
+	global	TFT_surfmode_date
+TFT_surfmode_date:
+	WIN_SMALL	surf_date_column,surf_date_row
+	FONT_COLOR_MEMO						; set color
+	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
+	movff	rtc_latched_year, lo		; copy year  to lo
+	movff	rtc_latched_month,hi		; copy month to hi
+	movff	rtc_latched_day,  up		; copy day   to up
+	call	output_date					; print date
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - show Pressure, on condition deltaP > threshold
+;
+	global	TFT_surfmode_pres_fast
+TFT_surfmode_pres_fast:
+	SMOVII	pressure_abs,    sub_a		; ISR-safe 2 byte copy of current absolute pressure to sub_a
+	MOVII	pressure_abs_ref,sub_b		; standard 2 byte copy 10 min ago absolute pressure to sub_b
+	call	subU16						; sub_c = | sub_a - sub_b | = deltaP
+	tstfsz	sub_c+1						; deltaP > 255 mbar ?
+	bra		TFT_pres_surfmode_fast_1	; YES - show current pressure
+	movlw	pressure_noise_threshold+.1	; NO  - load noise suppression threshold
+	subwf	sub_c+0,W					;     - subtract threshold from deltaP
+	bc		TFT_pres_surfmode_fast_1	;     - result negative -> show current pressure
+	tstfsz	pressure_update_lag_counter	;     - still in lag time?
+	bra		TFT_pres_surfmode_fast_0	;       YES - continue updating the display
+	return								;       NO  - no display updates any more, done
+
+TFT_pres_surfmode_fast_0:
+	decf	pressure_update_lag_counter,F	; clock down lag time counter
+	bra		TFT_surfmode_pres				; update display
+
+TFT_pres_surfmode_fast_1:
+	movlw	pressure_noise_lag_time		; get    lag time
+	movwf	pressure_update_lag_counter	; re-set lag time counter
+	;bra	TFT_surfmode_pres			; update display
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - show Pressure (unconditional)
+;
+	global	TFT_surfmode_pres
+TFT_surfmode_pres:
+	; value
+	WIN_SMALL surf_press_column+.8,surf_press_row
+	FONT_COLOR_MEMO						; set color
+	SMOVII	pressure_abs,mpr			; get current pressure
+	FONT_COLOR_MEMO						; print in standard color
+	output_9999							; print (0-9999)
+	PRINT								; dump buffer to screen
+	; unit
+	WIN_SMALL	surf_press_column+(4+1)*8,surf_press_row
+	FONT_COLOR_MASK						; switch to mask color
+	STRCPY_TEXT_PRINT tMBAR				; print unit (hPa)
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - Temperature
+;
+	global	TFT_surfmode_temp
+TFT_surfmode_temp:
+	; unit
+	WIN_SMALL surf_temp_column+3*8,surf_temp_row
+	FONT_COLOR_MASK						; select mask color
+	TSTOSS	opt_units					; 0=°C, 1=°F
+	bra		TFT_temp_surfmode_metric	; 0: metric
+	;bra	TFT_temp_surfmode_imperial	; 1: imperial
+
+TFT_temp_surfmode_imperial:
+	STRCAT_TEXT tLogTunitF				; print "°F"
+	bra		TFT_temp_surfmode_common	; continue with common part
+
+TFT_temp_surfmode_metric:
+	STRCAT_TEXT tLogTunitC				; print "°C"
+	;bra	TFT_temp_surfmode_common	; continue with common part
+
+TFT_temp_surfmode_common:
+	PRINT								; dump the unit to screen
+
+	; value
+	WIN_SMALL surf_temp_column,surf_temp_row
+	bra		TFT_temp_common				; continue with common part
+
+
+	; Helper Function - common output for surface and dive mode temperature
+TFT_temp_common:
+	FONT_COLOR_MEMO						; set color
+	SMOVII	temperature_cur,mpr			; ISR-safe 2 byte copy of current temperature to hi:lo
+
+;	DEBUG CODE  -  manual override temp
+;	-----------------------------------
+;	MOVLI	0xFFF6,mpr		; - 1.0 °C
+;	MOVLI	0xFF9C,mpr		; -10.0 °C
+
+	TSTOSC	opt_units					; 0=°C, 1=°F
+	call	convert_celsius_to_fahrenheit;1 - convert value in lo:hi from Celsius to Fahrenheit
+	call	convert_signed_16bit		; convert lo:hi into signed-short and print '-' if negative
+	btfsc	neg_flag					; is the temperature negative?
+	bsf		hide_digit4					; YES - do not print digit 4
+	bsf		omit_digit_1				; do not print digit 1 (0.1°)
+	output_9999							; print temperature (0x-999x / 0x-99x if negative)
+
+	btfss	divemode					; in dive mode?
+	bra		TFT_temp_common_no_unit		; NO  - no unit to append
+	TSTOSS	opt_units					; YES - check unit type: 0=°C, 1=°F
+	bra		TFT_temp_common_metric		;       0 - metric
+	;bra	TFT_temp_common_imperial	;       1 - imperial
+
+TFT_temp_common_imperial:
+	STRCAT_TEXT_PRINT tLogTunitF		; append "°F" and dump to screen
+	return								; done
+
+TFT_temp_common_metric:
+	STRCAT_TEXT_PRINT tLogTunitC		; append "°C" and dump to screen
+	return								; done
+
+TFT_temp_common_no_unit:
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - Battery Status
+;
+	global	TFT_surfmode_batt
+TFT_surfmode_batt:
+	FONT_COLOR_MEMO						; set default color
+
+	; apply charging indicator and warnings
+	clrf	WREG						; default to no indication/warning
+	btfsc	cc_active					; charging in CC mode?
+	movlw	color_yellow				; YES - set output color to yellow
+	btfsc	cv_active					; charging in CV mode?
+	movlw	color_green					; YES - set output color to green
 	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
-
-
-	global	TFT_color_code_gas
-TFT_color_code_gas:						; color-code the output according to gas number (1-6) in WREG
-	movwf	up							; copy gas number (1-6) to up
-	movlw	color_white					; Default color
-	dcfsnz	up,F
-	movlw	color_white					; color for gas 1
-	dcfsnz	up,F
-	movlw	color_green					; color for gas 2
-	dcfsnz	up,F
-	movlw	color_red					; color for gas 3
-	dcfsnz	up,F
-	movlw	color_yellow				; color for gas 4
-	dcfsnz	up,F
-	movlw	color_cyan					; color for gas 5
-	dcfsnz	up,F
-	movlw	color_pink					; color for gas 6
-	goto	TFT_set_color				; set color...
-
-
-; ****************************************************************************
-
-	global	TFT_show_OC_startgas_surface
-TFT_show_OC_startgas_surface:			; show first gas and "OSTC2-like" active gases
-	; Show first gas
+	movf	pallet_color_warning,W		; YES - set output to warning color
+	btfsc	battery_overtemp			; battery over-temperature detector tripped?
+	movf	pallet_color_warning,W		; YES - set output to warning color
+	tstfsz	WREG						; any indicator or warning active?
+	bsf		win_invert					; YES - set output to inverse
+	tstfsz	WREG						; any indicator or warning active (asked again)?
+	movwf	font_color					; YES - change color
+
+	WIN_SMALL batt_percent_column+.2,batt_percent_row
+	movff	batt_percent,lo				; get   battery %
+	output_256							; print battery % (0-255)
+	STRCAT_PRINT "% "					; append unit with trailing space and dump to screen
+
+	WIN_TINY batt_voltage_column+.15,batt_voltage_row
+	FONT_COLOR_MEMO						; set color
+	movff	battery_type,lo				; get battery type
+	PUTC	"T"							; print "T"
+	output_9							; print battery type code (0-9)
+	PUTC	":"							; print ":"
+	MOVII	batt_voltage,mpr			; get battery voltage
+	bsf		omit_digit_2				; do not print 2nd and 1st digit
+	bsf		decimal_digit3				; place a decimal point in front of digit 3
+	output_9999							; print x.x--
+	PUTC_PRINT 'V'						; append unit and dump to screen
+	return								; done
+
+;update_battery_debug:
+;	FONT_COLOR_MEMO	
+;	WIN_TINY .70,.0
+;	movff	battery_gauge+5,xC+3
+;	movff	battery_gauge+4,xC+2
+;	movff	battery_gauge+3,xC+1
+;	movff	battery_gauge+2,xC+0
+;	; battery_gauge:6 is nAs
+;	; devide through 65536
+;	; devide through 152
+;	; Result is 0.01Ah in xC+1:xC+0
+;	MOVLI	.152,xB
+;	call	div32x16					; xC:4 = xC:4 / xB:2 with xA as remainder
+;	MOVII	xC,mpr
+;	bsf		leftbind
+;	output_65535
+;	STRCAT_PRINT "x.01Ah"
+;	return
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - Deco Mode  (0=OC, 1=CCR, 2=Gauge, 3=Apnoe, 4=pSCR)
+;
+	global	TFT_surfmode_decotype
+TFT_surfmode_decotype:
+	WIN_STD surf_decotype_column,surf_decotype_row
+	FONT_COLOR color_lightblue			; set font color
+	movff	opt_dive_mode,lo			; get deco mode 
+	tstfsz	lo							; in OC mode?
+	bra		TFT_decotype_surface_2		; NO
+	STRCAT_TEXT_PRINT tDvOC				; YES - print OC
+	return								;     - done
+
+TFT_decotype_surface_2:
+	decfsz	lo,F						; in CCR mode?
+	bra		TFT_decotype_surface_3		; NO
+ IFDEF _ccr_pscr
+	STRCAT_TEXT_PRINT tDvCC				; YES - print CCR
+
+	WIN_TINY surf_decotype_column+.18,surf_decotype_row+.12
+	FONT_COLOR_MEMO						;     - set color
+	movff	opt_ccr_mode,WREG			;     - ccr mode
+	tstfsz	WREG						;     - ccr_mode = 0 (FixedSP) ?
+	bra		TFT_surfmode_decotype_cc_var;       NO  - not fixed
+	;bra	TFT_surfmode_decotype_cc_fix;       YES - fixed
+
+TFT_surfmode_decotype_cc_fix:
+	STRCPY_TEXT tCCRModeFixedSP			; print "fixed SP"
+	bra		TFT_decotype_surface_cc_com	; continue
+
+TFT_surfmode_decotype_cc_var:
+	; Sensor or Auto SP mode
+	sublw	.2							; ccr_mode = 2 (Auto SP) ?
+	bz		TFT_decotype_surface_cc_auto; YES - AutoSP
+ IFDEF _external_sensor
+	STRCPY_TEXT tCCRModeSensor			; NO  - print "Sensor"
+	bra		TFT_decotype_surface_cc_com	;     - continue
+ ENDIF	; _external_sensor
+
+TFT_decotype_surface_cc_auto:
+	STRCPY_TEXT tCCRModeAutoSP			; print "Auto SP"
+	;bra	TFT_decotype_surface_cc_com	; continue
+
+TFT_decotype_surface_cc_com:
+	clrf	WREG						; load string terminator
+	movff	WREG,buffer+.8				; limit string length to 8
+	PRINT								; dump to screen
+	return								; done
+ ENDIF	; _ccr_pscr
+
+TFT_decotype_surface_3:
+	decfsz	lo,F						; in gauge mode?
+	bra		TFT_decotype_surface_4		; NO
+	STRCAT_TEXT_PRINT tDvGauge			; YES - print "Gauge"
+	return								;     - done
+
+TFT_decotype_surface_4:
+	decfsz	lo,F						; in apnea mode?
+	bra		TFT_decotype_surface_5		; NO
+	STRCAT_TEXT_PRINT tDvApnea			; YES - print "Apnoe"
+	return								;     - done
+
+TFT_decotype_surface_5:
+	STRCAT_TEXT_PRINT tDvPSCR			; print "pSCR"
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - small Gas List
+;
+	global	TFT_surfmode_startgas
+TFT_surfmode_startgas:
+	; FIRST gas
 	WIN_SMALL surf_decotype_column+.1,surf_decotype_row+.30
+	FONT_COLOR_MEMO						; set font color
 	call	get_first_gas_to_WREG		; get first gas (1-5) into WREG
 	decf	WREG,W						; 1-5 -> 0-4
-	movwf	PRODL
-	call	gaslist_strcat_gas			; input: PRODL : gas number (0..4), Output: Text appended into buffer pointed by FSR2.
-	STRCAT_PRINT ""
-	; Show boxes
-	WIN_TOP	 surf_decotype_row+.30+.25
+	movwf	PRODL						; copy to PRODL
+	call	gaslist_strcat_mix_PRODL	; print gas description
+	PRINT								; dump to screen
+
+	; show gases
+	WIN_TOP  surf_decotype_row+.30+.25	; set row position
+
+	; 1st gas
 	WIN_LEFT surf_decotype_boxes_left1+.1
-	rcall	TFT_disabled_color
 	movff	opt_gas_type+0,hi			; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	tstfsz	hi
-	rcall	TFT_standard_color
-	STRCPY_PRINT "1"
+	rcall	TFT_surfmode_startgas_helper; set font color
+	STRCPY_PRINT "1"					; print "1"
 	decfsz	hi,F						; Type = 1 (First)?
-	bra		DISP_active_gas_surfmode3	; NO - skip box
-	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left1, surf_decotype_boxes_left1+.8	;top, bottom, left, right
-DISP_active_gas_surfmode3:
-	rcall	TFT_disabled_color
+	bra		TFT_surfmode_startgas_2		; NO - skip box
+	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left1, surf_decotype_boxes_left1+.8
+
+	; 2nd gas
+TFT_surfmode_startgas_2:
+	WIN_LEFT surf_decotype_boxes_left2+.1
 	movff	opt_gas_type+1,hi			; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	tstfsz	hi
-	rcall	TFT_standard_color
-	WIN_LEFT surf_decotype_boxes_left2+.1
-	STRCPY_PRINT "2"
+	rcall	TFT_surfmode_startgas_helper; set font color
+	STRCPY_PRINT "2"					; print "2"
 	decfsz	hi,F						; Type = 1 (First)?
-	bra		DISP_active_gas_surfmode4	; NO - skip box
-	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left2, surf_decotype_boxes_left2+.8	;top, bottom, left, right
-DISP_active_gas_surfmode4:
-	rcall	TFT_disabled_color
+	bra		TFT_surfmode_startgas_3		; NO - skip box
+	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left2, surf_decotype_boxes_left2+.8
+
+	; 3rd gas
+TFT_surfmode_startgas_3:
+	WIN_LEFT surf_decotype_boxes_left3+.1
 	movff	opt_gas_type+2,hi			; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	tstfsz	hi
-	rcall	TFT_standard_color
-	WIN_LEFT surf_decotype_boxes_left3+.1
-	STRCPY_PRINT "3"
+	rcall	TFT_surfmode_startgas_helper; set font color
+	STRCPY_PRINT "3"					; print "3"
 	decfsz	hi,F						; Type = 1 (First)?
-	bra		DISP_active_gas_surfmode5	; NO - skip box
-	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left3, surf_decotype_boxes_left3+.8	;top, bottom, left, right
-DISP_active_gas_surfmode5:
-	rcall	TFT_disabled_color
+	bra		TFT_surfmode_startgas_4		; NO - skip box
+	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left3, surf_decotype_boxes_left3+.8
+
+	; 4th gas
+TFT_surfmode_startgas_4:
+	WIN_LEFT surf_decotype_boxes_left4+.1
 	movff	opt_gas_type+3,hi			; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	tstfsz	hi
-	rcall	TFT_standard_color
-	WIN_LEFT surf_decotype_boxes_left4+.1
-	STRCPY_PRINT "4"
+	rcall	TFT_surfmode_startgas_helper; set font color
+	STRCPY_PRINT "4"					; print "4"
 	decfsz	hi,F						; Type = 1 (First)?
-	bra		DISP_active_gas_surfmode6	; NO - skip box
-	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left4, surf_decotype_boxes_left4+.8	;top, bottom, left, right
-DISP_active_gas_surfmode6:
-	rcall	TFT_disabled_color
+	bra		TFT_surfmode_startgas_5		; NO - skip box
+	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left4, surf_decotype_boxes_left4+.8
+
+	; 5th gas
+TFT_surfmode_startgas_5:
+	WIN_LEFT surf_decotype_boxes_left5+.1
 	movff	opt_gas_type+4,hi			; 0=Disabled, 1=First, 2=Travel, 3=Deco
-	tstfsz	hi
-	rcall	TFT_standard_color
-	WIN_LEFT surf_decotype_boxes_left5+.1
-	STRCPY_PRINT "5"
-	rcall	TFT_standard_color			; reset color
+	rcall	TFT_surfmode_startgas_helper; set font color
+	STRCPY_PRINT "5"					; print "5"
 	decfsz	hi,F						; type = 1 (First)?
-	bra		DISP_active_gas_surfmode7	; NO - done
-	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left5, surf_decotype_boxes_left5+.8	;top, bottom, left, right
-DISP_active_gas_surfmode7:
+	return								; NO - done
+	WIN_FRAME_STD surf_decotype_boxes_top, surf_decotype_boxes_bottom, surf_decotype_boxes_left5, surf_decotype_boxes_left5+.8
+	return								; done
+
+
+	; Helper Function - set font color
+TFT_surfmode_startgas_helper:
+	movf	pallet_color_disabled,W
+	tstfsz	hi							; gas not disabled?
+	movf	pallet_color_memo,W			; YES - change to memo color
+	movwf	font_color					; set font color
+	return
+
+ IFDEF _rx_functions
+
+;-----------------------------------------------------------------------------
+; Surface Mode Screen - Tank Pressure Reading above Surface Pressure
+;
+	global	TFT_surfmode_tankpres
+TFT_surfmode_tankpres:
+	WIN_SMALL surf_decotype_column+.6,surf_decotype_row+.30+.47
+	movff	int_IO_pressure_value+0,lo	; copy pressure from 1st reading to hi:lo
+	movff	int_IO_pressure_value+1,hi	; ...
+	btfss	hi,int_not_avail_flag		; pressure reading 1 available?
+	bra		TFT_surface_tank_pres_0		; YES
+	movff	int_IO_pressure_value+2,lo	; NO - copy pressure from 2nd reading to hi:lo
+	movff	int_IO_pressure_value+3,hi	;    - ...
+	btfsc	hi,int_not_avail_flag		;    - pressure reading 2 available?
+	bra		TFT_surface_tank_pres_1		;      NO  - show not avail message
+
+TFT_surface_tank_pres_0:
+	call	TFT_color_code_pres_sac		; set output color according to flags
+	bsf		omit_digit_1				; do not print 1st digit (0.1 bar)
+	output_9999							; print (0x-999x)
+	PRINT								; dump to screen
+	bra		TFT_surface_tank_pres_2		; print unit
+
+TFT_surface_tank_pres_1:
+	FONT_COLOR_DISABLED					; select disabled color
+	STRCAT_PRINT " ---"					; output for no pressure data available
+
+TFT_surface_tank_pres_2:
+	WIN_SMALL surf_decotype_column+.38,surf_decotype_row+.30+.47
+	FONT_COLOR_MASK						; select mask color
+	STRCAT_PRINT "bar"					; can not use tbar because it has a leading space
+	return								; done
+
+ ENDIF	; _rx_functions
+
+
+;=============================================================================
+tft_out4	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Imprint the Color Schemes
+;
+	global	TFT_imprint_color_schemes
+TFT_imprint_color_schemes:
+	call	TFT_load_dive_color_pallet	; load dive mode color pallet
+
+	FONT_COLOR_MASK						; select mask color
+	WIN_TINY .12,.40					; print labels
+	STRCAT_TEXT_PRINT tDepth			; ...
+	WIN_TINY .62,.40					; ...
+	STRCAT_TEXT_PRINT tMaxDepth			; ...
+	WIN_TINY .122,.40					; ...
+	STRCAT_TEXT_PRINT tDivetime			; ...
+
+	FONT_COLOR_DISABLED					; select disabled color
+
+	; max. depth demo
+	WIN_MEDIUM .64,.54					; set font and position
+	movlw	.63							; load demo depth
+	movwf	lo							; ...
+	output_99							; print full meters (0-99)
+	PRINT								; dump to screen
+
+	WIN_SMALL .87,.66					; set font and position
+	PUTC	"."							; print ":"
+	movlw	.4							; load demo depth
+	movwf	lo							; ...
+	output_9							; print decimeters (0-9)
+	PRINT								; dump to screen
+
+	FONT_COLOR_MEMO						; select memo color
+
+	; depth demo
+	WIN_MEDIUM .3,.54					; set font and position
+	movlw	.17							; load a demo depth
+	movwf	lo							; ...
+	output_99							; print full meters (0-99)
+	PRINT								; dump to screen
+
+	WIN_SMALL .25,.66					; set font and position
+	PUTC	"."							; print ":"
+	movlw	.5							; load demo depth
+	movwf	lo							; ...
+	output_9							; print decimeters (0-9)
+	PRINT								; dump to screen
+
+	; dive time demo
+	WIN_MEDIUM .103, .54				; set font and position
+	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
+	movff	rtc_latched_mins,lo			; get   minutes
+	output_256							; print minutes (in 3 digits, 1st digit used as spacer)
+	PRINT								; dump to screen
+
+	WIN_SMALL .139, .66					; set font and position
+	PUTC	':'							; print ":"
+	movff	rtc_latched_secs,lo			; get   seconds
+	output_99x							; print seconds (00-99)
+	PRINT								; dump to screen
+
+	; messages demo
+	WIN_SMALL dm_warning1_column-.78, dm_warning1_row+.39+.12
+	FONT_COLOR_ADVICE					; select advice color
+	STRCPY_TEXT_PRINT tgaschange		; sample text "Change?"
+
+	WIN_SMALL dm_warning1_column, dm_warning1_row+.39
+	FONT_COLOR_ATTENTION				; select attention color
+	STRCPY_TEXT_PRINT tCNSeod			; sample text "CNS final"
+
+	WIN_SMALL dm_warning2_column, dm_warning2_row+.38
+	FONT_COLOR_WARNING					; select warning color
+	STRCPY_TEXT_PRINT tGasNeedsWarn		; sample text "Gas Needs"
+
+	call	TFT_load_std_color_pallet	; re-load standard color pallet
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Menu - Imprint Time & Date
+;
+	global	TFT_imprint_time_date
+TFT_imprint_time_date:
+	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of current date & time
+	;bra	TFT_imprint_time_date_fast	; continue
+
+
+;-----------------------------------------------------------------------------
+; Surface Menu - Imprint Time & Date - fast Updating
+;
+	global	TFT_imprint_time_date_fast
+TFT_imprint_time_date_fast:
+	WIN_SMALL .20,.40					; column, row - keep clear of the cursor area on the left!
+	FONT_COLOR_MEMO						; select color
+	movff	rtc_latched_hour,lo			; get   hours
+	output_99							; print hours (0-99)
+	PUTC	':'							; print ":"
+	movff	rtc_latched_mins,lo			; get   minutes
+	output_99x							; print minutes (00-99)
+	PUTC	':'							; print ":"
+	movff	rtc_latched_secs,lo			; get   seconds
+	output_99x							; print seconds (00-99)
+	STRCAT	"  "						; append two spaces
+	movff	rtc_latched_year, lo		; get date
+	movff	rtc_latched_month,hi		; ...
+	movff	rtc_latched_day,  up		; ...
+	call	output_date					; print date
+	PUTC_PRINT " "						; append a space and dump to screen
 	return								; done
 
 
-	global	TFT_show_color_schemes
-TFT_show_color_schemes:					; update the color schemes
-	bsf		divemode					; switch to dive mode
-	call	TFT_divemask_color
-	WIN_TINY .12,.40
-	STRCAT_TEXT_PRINT tDepth
-	WIN_TINY .62,.40
-	STRCAT_TEXT_PRINT tMaxDepth
-	WIN_TINY .122,.40
-	STRCAT_TEXT_PRINT tDivetime
-
-	; Show some demo screen
-
-	; Depth demo
-	call	TFT_memo_color
-	WIN_MEDIUM .3,.54
-	MOVLI	.5172,mpr
-	bsf		leftbind
-	bsf		ignore_digit4
-	output_16							; full meters in big font
-	bcf		leftbind
-	STRCAT_PRINT ""						; display full meters
-	WIN_SMALL .25,.66
-	MOVLI	.5172,mpr
-	PUTC	"."
-	movlw	d'4'
-	movwf	ignore_digits
-	bsf		ignore_digit5				; (flag will be cleared by output_16)
-	output_16dp d'0'					; .1m in SMALL font
-	STRCAT_PRINT ""						; display decimeters
-
-	; Max. Depth demo
-	WIN_MEDIUM .64,.54
-	bsf		ignore_digit4				; no 0.1 m
-	bsf		leftbind
-	MOVLI	.6349,mpr
-	output_16
-	STRCAT_PRINT ""						; display full meters
-	bcf		leftbind
-	; .1m in SMALL font
-	WIN_SMALL .87,.66
-	PUTC	"."
-	movlw	d'4'
-	movwf	ignore_digits
-	bsf		ignore_digit5				; (flag will be cleared by output_16)
-	bsf		leftbind
-	MOVLI	.6349,mpr
-	output_16dp d'0'
-	STRCAT_PRINT ""						; display decimeters
-	bcf		leftbind
-
-	; Divetime demo
-	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
-	movff	rtc_latched_mins,lo
-	clrf	hi
-	WIN_MEDIUM .103, .54
-	output_16_3							; limit to 999 and display only (0-999)
-	STRCAT_PRINT ""						; show minutes in large font
-	WIN_SMALL .139, .66					; left position for two sec figures
-	PUTC	':'
-	bsf		leftbind
-	movff	rtc_latched_secs,lo
-	output_99x
-	bcf		leftbind
-	STRCAT_PRINT ""						; show seconds in small font
-
-	bcf		divemode					; terminate dive mode again
-	return
-
-
+ IFDEF _external_sensor
+
+;-----------------------------------------------------------------------------
+; Surface Mode - Imprint ppO2 from Sensors
+;
+	global	TFT_imprint_surf_ppO2
+TFT_imprint_surf_ppO2:
+
+TFT_imprint_surf_ppO2_1:
+	WIN_SMALL surf_hud_sensor1_column,surf_hud_sensor1_row
+	btfsc	sensor1_calibrated_ok		; sensor calibrated?
+	bra		TFT_imprint_surf_ppO2_1a	; YES
+	btfsc	sensor1_active				; NO - valid HUD data for this sensor?
+	bra		TFT_imprint_surf_ppO2_1a	;      YES
+	rcall	TFT_imprint_surf_ppO2_h2	;      NO  - print dashes
+	bra		TFT_imprint_surf_ppO2_2		;          - continue with sensor 2
+TFT_imprint_surf_ppO2_1a:
+	movff	sensor1_ppO2,lo				; get ppO2
+	rcall	TFT_imprint_surf_ppO2_h1	; print ppO2
+
+TFT_imprint_surf_ppO2_2:
+	WIN_SMALL surf_hud_sensor2_column,surf_hud_sensor2_row
+	btfsc	sensor2_calibrated_ok		; sensor calibrated?
+	bra		TFT_imprint_surf_ppO2_2a	; YES
+	btfsc	sensor2_active				; NO  - valid HUD data for this sensor
+	bra		TFT_imprint_surf_ppO2_2a	;       YES
+	rcall	TFT_imprint_surf_ppO2_h2	;       NO  - print dashes
+	bra		TFT_imprint_surf_ppO2_3		;           - continue with sensor 3
+TFT_imprint_surf_ppO2_2a:
+	movff	sensor2_ppO2,lo				; get ppO2
+	rcall	TFT_imprint_surf_ppO2_h1	; print ppO2
+
+TFT_imprint_surf_ppO2_3:
+	WIN_SMALL surf_hud_sensor3_column,surf_hud_sensor3_row
+	btfsc	sensor3_calibrated_ok		; sensor calibrated?
+	bra		TFT_imprint_surf_ppO2_3a	; YES
+	btfsc	sensor3_active				; NO  - valid HUD data for this sensor
+	bra		TFT_imprint_surf_ppO2_3a	;       YES
+	bra		TFT_imprint_surf_ppO2_h2	;       NO  - print dashes and return
+	return								;           - done
+TFT_imprint_surf_ppO2_3a:
+	movff	sensor3_ppO2,lo				; get ppO2
+	;bra	TFT_imprint_surf_ppO2_h1	; print ppO2 and return
+
+TFT_imprint_surf_ppO2_h1:
+	call	TFT_color_code_ppo2_hud		; color-code with ppO2 [cbar] in lo
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_256							; print (0.00-2.55)
+	PRINT								; dump to screen
+	return								; done
+
+TFT_imprint_surf_ppO2_h2:
+	FONT_COLOR_MEMO						; select standard color
+	STRCPY_PRINT "--- "					; print dashes
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode - Imprint mV from Sensors
+;
+	global	TFT_imprint_surf_mV
+TFT_imprint_surf_mV:
+	FONT_COLOR_MEMO						; set font color
+
+	; sensor 1
+	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor1_row
+	SMOVII	sensor1_mv,mpr				; in 0.1mV steps
+	STRCAT	"1: "						; print number
+	rcall	TFT_sensor_mV_helper		; print mV
+
+	; sensor 2
+	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor2_row
+	SMOVII	sensor2_mv,mpr				; in 0.1mV steps
+	STRCAT	"2: "						; print number
+	rcall	TFT_sensor_mV_helper
+
+	; sensor 3
+	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor3_row
+	SMOVII	sensor3_mv,mpr				; in 0.1mV steps
+	STRCAT	"3: "						; print number
+	rcall	TFT_sensor_mV_helper		; print mV
+
+	; print sensor connection type
+	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor3_row+.24
+	btfsc	ext_input_optical			; optical input?
+	bra		TFT_sensor_mV_optical		; YES
+	TSTOSS	opt_s8_mode					; NO  - S8 input selected?
+	bra		TFT_sensor_mV_analog		;       NO  - analog input
+	;bra	TFT_sensor_mV_s8			;       YES - S8
+
+TFT_sensor_mV_s8:
+	STRCAT_PRINT	"Digital"			; print "Digital"
+	return								; done
+
+TFT_sensor_mV_optical:
+	STRCAT_PRINT	"Optical"			; print "Optical"
+	return								; done
+
+TFT_sensor_mV_analog:
+	STRCAT_PRINT	"Analog"			; print "analog"
+	return								; done
+
+
+	; Helper Function - print mV value
+TFT_sensor_mV_helper:
+	bsf		decimal_digit1				; place a decimal point in front of digit 1
+	output_9999							; print (0.0-999.9)
+	STRCAT_PRINT "mV "					; append unit and dump buffer to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode - Imprint End-of-Life from Sensors
+;
+; when opt_x_sx > 255 the sensor will just give 8 mV at a ppO2 of 0.21
+;
+	global	TFT_imprint_surf_sensor_eol
+TFT_imprint_surf_sensor_eol:
+	FONT_COLOR_WARNING					; set color
+
+TFT_imprint_surf_eol_1:
+	; sensor 1
+	btfss	sensor1_calibrated_ok		; valid calibration?
+	bra		TFT_imprint_surf_eol_2		; NO  - skip
+	movff	opt_x_s1+1,WREG				; YES - get high(opt_x_s1)
+	movf	WREG,W						;     - excite flags
+	bz		TFT_imprint_surf_eol_2		;     - opt_x_s1 > 255 -> the sensor is not too bad yet for a warning
+	WIN_SMALL surf_mV_sensor_status_column,surf_mV_sensor1_row-.5
+	STRCPY_PRINT "\xb8"					; mark sensor as being at end of lifetime
+
+TFT_imprint_surf_eol_2:
+	; sensor 2
+	btfss	sensor2_calibrated_ok		; valid calibration?
+	bra		TFT_imprint_surf_eol_3		; NO  - skip
+	movff	opt_x_s2+1,WREG				; YES - get high(opt_x_s2)
+	movf	WREG,W						;     - excite flags
+	bz		TFT_imprint_surf_eol_3		;     - opt_x_s2 > 255 -> the sensor is not too bad yet for a warning
+	WIN_SMALL surf_mV_sensor_status_column,surf_mV_sensor2_row-.5
+	STRCPY_PRINT "\xb8"					; mark sensor as being at end of lifetime
+
+TFT_imprint_surf_eol_3:
+	; sensor 3
+	btfss	sensor3_calibrated_ok		; valid calibration?
+	bra		TFT_imprint_surf_eol_4		; NO  - skip
+	movff	opt_x_s3+1,WREG				; YES - get high(opt_x_s3)
+	movf	WREG,W						;     - excite flags
+	bz		TFT_imprint_surf_eol_4		;     - opt_x_s3 > 255 -> the sensor is not too bad yet for a warning
+	WIN_SMALL surf_mV_sensor_status_column,surf_mV_sensor3_row-.5
+	STRCPY_PRINT "\xb8"					; mark sensor as being at end of lifetime
+
+TFT_imprint_surf_eol_4:
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Imprint Function for the Calibration Menu
+;
+	global	TFT_imprint_menu_mV
+TFT_imprint_menu_mV:
+	FONT_COLOR color_yellow				; show in yellow
+	rcall	TFT_sensor_mv_get			; get sensor mV values
+
+	; sensor 1
+	WIN_SMALL	surf_menu_sensor1_column,surf_menu2_sensor1_row
+	SMOVII	sensor1_mv,mpr				; in 0.1mV steps
+	rcall	TFT_imprint_menu_mV_helper	; print mV value
+
+	; sensor 2
+	WIN_SMALL	surf_menu_sensor2_column,surf_menu2_sensor2_row
+	SMOVII	sensor2_mv,mpr				; in 0.1mV steps
+	rcall	TFT_imprint_menu_mV_helper	; print mV value
+
+	; sensor 3
+	WIN_SMALL	surf_menu_sensor3_column,surf_menu2_sensor3_row
+	SMOVII	sensor3_mv,mpr				; in 0.1mV steps
+	rcall	TFT_imprint_menu_mV_helper	; print mV value
+
+	TSTOSS	opt_s8_mode					; =0: analog, =1: digital
+	return								; analog - done
+
+	; imprint HUD battery voltage
+	WIN_TINY .20,.209					; set position
+	STRCPY	"HUD Batt: "				; print label
+	SMOVII	hud_battery_mv,mpr			; get HUD battery voltage
+	bsf		decimal_digit3				; place a decimal point in front of digit 3
+	output_9999							; print (0.000-9.999)
+	PUTC_PRINT "V"						; append unit and dump buffer to screen
+	return								; done
+
+	; Helper Function - get sensor mV values
+TFT_sensor_mv_get:
+;	btfsc	ext_input_optical			; do we have an optical interface?
+;	return								; YES - optical interface delivers ready-to-use mV data, done
+	TSTOSS	opt_s8_mode					; NO  - S8 input selected?
+	bra		TFT_sensor_mv_get_ana		;       NO  - read analog inputs
+	;bra	TFT_sensor_mv_get_dig		;       YES - convert digitally received ppO2 into mV
+
+TFT_sensor_mv_get_dig:
+	btfss	trigger_S8_data_update		; new data frame received?
+	return								; NO  - use old values
+	bcf		trigger_S8_data_update		; YES - clear update flag
+	call	compute_mvolts_from_rawdata	;     - compute mV values from received raw data
+	return								;     - done
+
+TFT_sensor_mv_get_ana:
+	call	get_analog_inputs			; read mV values from analog inputs
+	return								; done
+
+
+	; Helper Function - print mV value
+TFT_imprint_menu_mV_helper:
+	bsf		decimal_digit1				; place a decimal point in front of digit 1 (no 0.1 mV)
+	output_9999							; print (0.0-999.9)
+	STRCAT_PRINT "mV"					; append unit and dump buffer to screen
+	return								; done
+
+ ENDIF	; _external_sensor
+
+
+ IFDEF _rx_functions
+;-----------------------------------------------------------------------------
+; Imprint Function for the Tank Setup Menu
+;
+	global	TFT_imprint_tank_pres
+TFT_imprint_tank_pres:
+	FONT_COLOR_MEMO						; set color
+	; get ID
+	lfsr	FSR1,opt_transmitter_id_1	; load base address of opt_transmitter_id
+	movf	gaslist_gas,W				; get current gas
+	rlncf	WREG,W						; multiply by 2 because IDs are 2 byte in size
+	movff	PLUSW1,lo					; copy opt_transmitter_id+0[gaslist_gas] to lo
+	incf	WREG,W						; increment index
+	movff	PLUSW1,hi					; copy opt_transmitter_id+1[gaslist_gas] to hi
+	; show pressure
+	WIN_SMALL .90, .61					; column, row (+/- 27 per row)
+	call	get_pres_by_transmitter_id	; get pressure into hi:lo
+	tstfsz	WREG						; do we have valid tank data (WREG=0) ?
+	bra		TFT_menu_tank_pres_1		; NO - transmitter not found
+	call	TFT_color_code_pres_sac		; set output color according to flags
+	bsf		omit_digit_1				; do not print 1st digit (0.1 bar)
+	output_9999							; print (0x-999x)
+	bra		TFT_menu_tank_pres_2
+TFT_menu_tank_pres_1:
+	FONT_COLOR_DISABLED					; select color
+	STRCAT	" ---"						; print dashes for no pressure data available
+TFT_menu_tank_pres_2:
+	STRCAT_TEXT_PRINT tbar				; print " bar"
+	return								; done
+
+ ENDIF	; _rx_functions
+
+
+;=============================================================================
+tft_out5	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - static Layout
+;
 	global	TFT_show_divemode_mask
 TFT_show_divemode_mask:										; display mask in dive mode
-	call	TFT_divemask_color								; set color
-
-	; depth
+	FONT_COLOR_MASK											; select color
+
+	; current depth
 	WIN_TINY dm_mask_depth_column,dm_mask_depth_row			; position for "Depth"
 	btfss	alt_layout_active								; alternative layout active?
 	bra		TFT_divemode_mask_depth_text					; NO
-	WIN_TINY dm_mask_depth_column_alt,dm_mask_depth_row		; YES - alternative position for "Depth"
+	btfsc	cur_depth_greater_100m							; YES - current depth >= 100 m?
+	bra		TFT_divemode_mask_max_avg						;       YES - skip depth label as it collides with depth number
+	WIN_TINY dm_mask_depth_column_alt,dm_mask_depth_row		;       NO  - set alternative position for "Depth"
 TFT_divemode_mask_depth_text:
 	STRCAT_TEXT_PRINT tDepth								; print "Depth"
 
+TFT_divemode_mask_max_avg:
 	; avg or max depth
 	btfsc	alt_layout_active								; alternative layout active?
 	bra		TFT_divemode_mask_avg_max_alt					; YES
@@ -663,510 +1394,33 @@
 TFT_divemode_mask_time_text:
 	STRCAT_TEXT_PRINT tDivetime								; print "Divetime"
 	btfss	FLAG_apnoe_mode									; in apnea mode?
-	bra		TFT_standard_color								; NO  - done
+	return													; NO  - done
 	WIN_TINY dm_total_apnoe_text_col,dm_total_apnoe_text_row; YES - set position
 	STRCPY_TEXT_PRINT tApnoeTotal							;     - print "Total"
-	bra		TFT_standard_color								;     - done
-
-;=========================================================================
-
-	global	TFT_velocity_show
-TFT_velocity_show:
-	rcall	TFT_memo_color				; set default color
-	btfsc	neg_flag_velocity			; descending?
-	rcall	TFT_velocity_set_color		; NO - set color for text dependent on speed and set threshold for VSI graph
-	rcall	TFT_velocity_num			; show the numerical VSI
-	TSTOSS	opt_vsigraph				; graphical VSI bar enabled?
-	bra		TFT_standard_color			; NO  - done
-	btfsc	neg_flag_velocity			; YES - in ascent?
-	bra		TFT_velocity_graph_show		;       YES - show  the graph
-	bra		TFT_velocity_graph_clear_1	;       NO  - clear the graph
-
-TFT_speed_table:
-	; use a depth-dependent ascent rate warning
-	; depth(ft):     <20 >20 >40 >60 >75 >88 >101 >115 >128 >144 >164
-	; speed(ft/min):  23  26  29  33  36  43   49   56   59   62   66
-	; depth(m):      <=6  >6 >12 >18 >23 >27  >31  >35  >39  >44  >50
-	; speed(m/min):    7   8   9  10  11  13   15   17   18   19   20 (warning)
-	; speed(m/min):    5   6   7   8   8  10   12   13   14   15   15 (attention)
-
-	; < depth (m), warning speed, attention speed, unused
-	DB  .6,.7,.5,.0
-	DB  .12,.8,.6,.0
-	DB  .18,.9,.7,.0
-	DB  .23,.10,.8,.0
-	DB  .27,.11,.8,.0
-	DB  .31,.13,.10,.0
-	DB  .35,.15,.12,.0
-	DB  .39,.17,.13,.0
-	DB  .44,.18,.14,.0
-	DB  .50,.19,.15,.0
-	DB  .200,.20,.15,.0
-
-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_vsitext						; 0=standard, 1=dynamic
-	bra		TFT_velocity_set_color_static	; static ascend rate limit
-
-	; point to speed table
-	movlw	LOW   (TFT_speed_table-.3)
-	movwf	TBLPTRL
-	movlw	HIGH  (TFT_speed_table-.3)
-	movwf	TBLPTRH
-	movlw	UPPER (TFT_speed_table-.3)
-	movwf	TBLPTRU
-
-TFT_velocity_set_color_next:
-	TBLRD*+									; 3 dummy reads
-	TBLRD*+
-	TBLRD*+
-	TBLRD*+									; get speed threshold
-	movf	depth_meter,W					; current depth in m
-	cpfsgt	TABLAT							; threshold > current depth ?
-	bra		TFT_velocity_set_color_next		; NO - try next
-
-	TBLRD*+									; get warning speed threshold
-	movf	TABLAT,W						; ...
-	movwf	divA+1							; copy for graph routine
-	cpfslt	divA+0							; actual vertical speed smaller than warning threshold?
-	bra		TFT_warning_color				; NO - set warning color (and return)
-	TBLRD*+									; get attention speed threshold
-	movf	TABLAT,W						; ...
-	cpfslt	divA+0							; actual vertical speed smaller than attention threshold?
-	bra		TFT_attention_color				; NO  - set attention color and return
-	bcf		aux_flag						; YES - don't show in alternative layout
-	bra		TFT_memo_color					;     - set memo color and return
-
-TFT_velocity_set_color_static:
-	movlw	color_code_velocity_warn_high	; threshold for warning in m/min
-	movwf	divA+1							; copy for graph routine
-	cpfslt	divA+0							; actual vertical speed smaller than warning threshold?
-	bra		TFT_warning_color				; NO - set warning color (and return)
-	movlw	color_code_velocity_attn_high	; threshold for attention in m/min
-	cpfslt	divA+0							; actual vertical speed smaller than attention threshold?
-	bra		TFT_attention_color				; NO  - set attention color and return
-	bcf		aux_flag						; YES - don't show in alternative layout
-	bra		TFT_memo_color					;     - set memo color and return
-
-TFT_velocity_num:
-	btfsc	alt_layout_active				; in alternative layout?
-	bra		TFT_velocity_num_alt			; YES
-											; NO  - set position
-	WIN_SMALL dm_velocity_text_col_norm, dm_velocity_text_row_norm
-TFT_velocity_num_com:
-	bsf		velocity_active_num				; set numerical velocity as shown
-	TSTOSS	opt_units						;     - 0=meter, 1=feet
-	bra		TFT_velocity_num_metric			;       0 - meter
-	;bra	TFT_velocity_num_imperial		;       1 - feet
-
-TFT_velocity_num_imperial:
-	movff	divA+0,WREG						; divA+0 = m/min
-	mullw	.100							; PROD   = mbar/min
-	MOVII	PRODL,mpr						; copy to hi:lo
-	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
-	btfsc	neg_flag_velocity				; ascending?
-	movlw	'+'								; YES - replace with coding for plus sign
-	movwf	POSTINC2						; put sign into output buffer
-	output_99								; print rate
-	STRCAT_TEXT tVelImperial				; print unit
-	bra		TFT_velocity_num_finish			; do finishing tasks
-
-TFT_velocity_num_metric:
-	movff	divA+0,lo						; divA+0 = m/min
-	movlw	'-'								; load coding for minus sign
-	btfsc	neg_flag_velocity				; ascending?
-	movlw	'+'								; YES - replace with coding for plus sign
-	movwf	POSTINC2						; put sign into output buffer
-	output_99								; print rate
-	STRCAT_TEXT tVelMetric					; print unit
-	;bra	TFT_velocity_num_finish			; do finishing tasks
-
-TFT_velocity_num_finish:
-	btfss	alt_layout_active				; in alternative layout?
-	bra		TFT_velocity_num_finish_1		; NO
-	movlw	"'"								; load encoding of minute sign
-	movff	WREG,buffer+4					; put it after m (meter) / f (feet)
-	clrf	WREG							; load string terminator
-	movff	WREG,buffer+5					; terminate string after minute sign
-TFT_velocity_num_finish_1:
-	STRCAT_PRINT ""							; finalize output
-	bcf		win_invert						; end inverse printing
-	return									; done
-
-TFT_velocity_num_alt:
-	btfsc	dive_main_menu					; is the dive mode menu shown?
-	return									; YES - abort
-	btfss	neg_flag_velocity				; NO  - in ascent?
-	bcf		aux_flag						;       NO  - clear aux flag
-	btfsc	aux_flag						;     - above attention or warning threshold?
-	bsf		win_invert						;       YES - print inverse
-											;     - set position
-	WIN_SMALL dm_velocity_text_col_alt, dm_velocity_text_row_alt
-	bra		TFT_velocity_num_com			;     - continue with common part
-
-
-TFT_velocity_graph_show:					; with speed in divA+0 (m/min)
-	btfsc	alt_layout_active				; in alternative layout?
-	bra		TFT_standard_color				; YES - done (not implemented)
-
-	btfsc	velocity_active_vsi				; was the graphical VSI shown before?
-	bra		TFT_velocity_graph_1			; YES - no need to redraw the framework box
-	bsf		velocity_active_vsi				; NO  - remember it is shown as of now
-											;     - draw the framework box
-	rcall	TFT_divemask_color_dive			;     - color -> WREG
-	WIN_FRAME_COLOR	dm_velocity_graph_top+.00, dm_velocity_graph_bot-.00, dm_velocity_graph_lft, dm_velocity_graph_rgt
-	rcall	TFT_divemask_color_dive			;     - color -> WREG
-	WIN_FRAME_COLOR	dm_velocity_graph_top+.10, dm_velocity_graph_bot-.10, dm_velocity_graph_lft, dm_velocity_graph_rgt
-	rcall	TFT_divemask_color_dive			;     - color -> WREG
-	WIN_FRAME_COLOR	dm_velocity_graph_top+.20, dm_velocity_graph_bot-.20, dm_velocity_graph_lft, dm_velocity_graph_rgt
-	rcall	TFT_divemask_color_dive			;     - color -> WREG
-	WIN_FRAME_COLOR	dm_velocity_graph_top+.30, dm_velocity_graph_bot-.30, dm_velocity_graph_lft, dm_velocity_graph_rgt
-
-TFT_velocity_graph_1:
-	movff	divA+0,hi						; copy ascend speed (in m/min) to hi
-	movff	divA+1,xA+0						; m/min for warning level (upper two blocks)
-	clrf	xA+1
-	MOVLI	.5,xB							; threshold for color warning (5 color normal + 2 color warning)
-	call	div16x16						; xC = xA / xB with xA as remainder
-	; xC+0 holds step size in m/min (e.g. =3 for 15m/min warning threshold)
-	movff	hi,xA+0							; velocity in m/min
-	clrf	xA+1
-	movff	xC+0,xB+0						; step size
-	clrf	xB+1
-	call	div16x16						; xC = xA / xB with xA as remainder
-
-	movff	xC+0,lo							; copy amount of segments to show to lo
-	incf	lo,F
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_0_fill
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_1_fill
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_2_fill
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_3_fill
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_4_fill
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_5_fill
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_6_fill
-	;bra	DISP_graph_vel_7_fill
-
-DISP_graph_vel_7_fill:
-	rcall	TFT_warnings_color_dive		; color -> WREG
-	WIN_BOX_COLOR dm_velocity_graph_top+.2,  dm_velocity_graph_top+.8,  dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_6_fill:
-	rcall	TFT_warnings_color_dive		; color -> WREG
-	WIN_BOX_COLOR dm_velocity_graph_top+.12, dm_velocity_graph_top+.18, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_5_fill:
-	rcall	TFT_attention_color_dive	; color -> WREG
-	WIN_BOX_COLOR dm_velocity_graph_top+.22, dm_velocity_graph_top+.28, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_4_fill:
-	rcall	TFT_standard_color_dive		; color -> WREG
-	WIN_BOX_COLOR dm_velocity_graph_top+.32, dm_velocity_graph_top+.38, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_3_fill:
-	rcall	TFT_standard_color_dive		; color -> WREG
-	WIN_BOX_COLOR dm_velocity_graph_top+.42, dm_velocity_graph_top+.48, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_2_fill:
-	rcall	TFT_standard_color_dive		; color -> WREG
-	WIN_BOX_COLOR dm_velocity_graph_top+.52, dm_velocity_graph_top+.58, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_1_fill:
-	rcall	TFT_standard_color_dive		; color -> WREG
-	WIN_BOX_COLOR dm_velocity_graph_top+.62, dm_velocity_graph_top+.68, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_0_fill:
-
-	movff	xC+0,lo							; copy amount of segments to show to lo
-	incf	lo,F
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_0_clear
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_1_clear
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_2_clear
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_3_clear
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_4_clear
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_5_clear
-	dcfsnz	lo,F
-	bra		DISP_graph_vel_6_clear
-	bra		DISP_graph_vel_7_clear
-
-DISP_graph_vel_0_clear:
-	WIN_BOX_BLACK dm_velocity_graph_top+.62, dm_velocity_graph_top+.68, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_1_clear:
-	WIN_BOX_BLACK dm_velocity_graph_top+.52, dm_velocity_graph_top+.58, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_2_clear:
-	WIN_BOX_BLACK dm_velocity_graph_top+.42, dm_velocity_graph_top+.48, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_3_clear:
-	WIN_BOX_BLACK dm_velocity_graph_top+.32, dm_velocity_graph_top+.38, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_4_clear:
-	WIN_BOX_BLACK dm_velocity_graph_top+.22, dm_velocity_graph_top+.28, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_5_clear:
-	WIN_BOX_BLACK dm_velocity_graph_top+.12, dm_velocity_graph_top+.18, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_6_clear:
-	WIN_BOX_BLACK dm_velocity_graph_top+.2,  dm_velocity_graph_top+.8,  dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
-DISP_graph_vel_7_clear:
-	bra		TFT_standard_color			; done
-
-
-	global	TFT_velocity_clear
-TFT_velocity_clear:
-	btfss	velocity_active_num			; was the numerical VSI shown in last cycle?
-	bra		TFT_velocity_clear_graph	; NO  - no need to clear it, continue with graphical VSI
-TFT_velocity_clear_num_1:
-	bcf		velocity_active_num			; YES - clear flag
-	btfsc	alt_layout_active			;     - in alternative layout?
-	bra		TFT_velocity_clear_num_alt	;       YES
-	;bra	TFT_velocity_clear_num_norm	;       NO
-
-TFT_velocity_clear_num_norm:			; clear normal numerical area
-	WIN_BOX_BLACK dm_velocity_text_row_norm, dm_velocity_text_bot_norm, dm_velocity_text_col_norm, dm_velocity_text_rgt_norm ; top, bottom, left, right
-	bra		TFT_velocity_clear_graph	; continue with graphical VSI
-
-TFT_velocity_clear_num_alt:				; clear alternative numerical area
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	bra		TFT_velocity_clear_graph	; YES - skip
-										; NO  - clear area
-	WIN_BOX_BLACK dm_velocity_text_row_alt,  dm_velocity_text_bot_alt,  dm_velocity_text_col_alt,  dm_velocity_text_rgt_alt  ; top, bottom, left, right
-	;bra	TFT_velocity_clear_graph	; continue with graphical VSI
-
-TFT_velocity_clear_graph:
-	btfss	velocity_active_vsi			; was the graphical VSI shown in last cycle?
-	bra		TFT_standard_color			; NO  - no need to clear it, done
-TFT_velocity_graph_clear_1:
-	bcf		velocity_active_vsi			; YES - clear flag
-	btfsc	alt_layout_active			;     - in alternative layout?
-	bra		TFT_standard_color			;       YES - not implemented
-	;bra	TFT_velocity_clear_graph_alt  ;     YES - code provision for future implementation
-	;bra	TFT_velocity_clear_graph_norm ;     NO
-
-TFT_velocity_clear_graph_norm			; clear normal graph area
-	WIN_BOX_BLACK dm_velocity_graph_top, dm_velocity_graph_bot, dm_velocity_graph_lft, dm_velocity_graph_rgt ; top, bottom, left, right
-	bra		TFT_standard_color			; done
-
-;=========================================================================
-
-	global	TFT_clear_divemode_menu
-TFT_clear_divemode_menu:
-	WIN_BOX_BLACK	dm_menu_row-.2, dm_menu_lower, dm_menu_left, dm_menu_right			; top, bottom, left, right - starts 2 pixel higher to completely wipe away the temperature display
-	return
-
-
-	global	TFT_clear_deco_data
-TFT_clear_deco_data:
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-										; NO  - clear deco data area (alternative stop depth makes upper-left most corner)
-	WIN_BOX_BLACK dm_decostop_row_alt_depth, dm_3rdrow_bot, dm_decostop_col_alt_depth, dm_3rdrow_rgt	; top, bottom, left, right
-	return								;     - done
-
-
+	return													;     - done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - NDL  Layout Add-on
+;
 	global	TFT_show_ndl_mask
 TFT_show_ndl_mask:
 	btfsc	dive_main_menu				; is the dive mode menu shown?
 	return								; YES - abort
-	call	TFT_divemask_color			; NO  - set text color
+	FONT_COLOR_MASK						; NO  - set color
 										;     - set position
 	WIN_STD dm_ndl_text_column, dm_ndl_text_row
 	STRCPY_TEXT_PRINT tNDL				;     - print "NDL"
 	btfss	deco_region					;     - was the dive within deco stops region?
-	bra		TFT_standard_color			;       NO  - done
+	return								;       NO  - done
 	btfsc	safety_stop_active			;       YES - safety stop shown?
-	bra		TFT_standard_color			;             YES - done
-TFT_show_slow_reminder:
-	call	TFT_attention_color			;             NO  - set color
-										;                 - set position
-	WIN_STD dm_safetystop_text_column+.5,dm_safetystop_text_row+.5
-	STRCPY_TEXT  tSlow					;                 - print "SLOW" reminder
-	STRCAT_PRINT 0x94					;                 - append an up-arrow
-	bra		TFT_standard_color			;                 - done
-
-
-	global	TFT_show_tts
-TFT_show_tts:
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-	call	TFT_memo_color				; NO  - default to memo color
-	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			;     - 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
-	MOVLI	.100,sub_b					;           - load 100 into sub_b
-	call	cmpU16						;           - sub_a - sub_b = TTS - 100
-	btfss	neg_flag					;           - TTS >= 100 ?
-	bra		TFT_display_tts_999			;             YES
-	;bra	TFT_display_tts_99			;             NO
-
-TFT_display_tts_99:
-	btfsc	tts_greater_99				; was TTS > 99 mins last time?
-	rcall	TFT_display_tts_clear		; YES - clear remains from TTS > 99
-										; set output position
-	WIN_MEDIUM dm_tts_value_col_99, dm_tts_value_row
-	output_99							; display 0...99
-	STRCAT_PRINT "'"					; print "'"
-	bcf		tts_greater_99				; last TTS shown was <= 99 mins
-	bra		TFT_standard_color			; done
-
-TFT_display_tts_999:					; set position
-	WIN_MEDIUM dm_tts_value_col_999, dm_tts_value_row
-	output_16_3							; display 0...999
-	STRCAT_PRINT ""						; finalize output (no "'" here - not enough space available)
-	bsf		tts_greater_99				; last TTS shown was > 99 mins
-	bra		TFT_standard_color			; done
-
-TFT_display_tts_999x:					; set position
-	WIN_MEDIUM dm_tts_value_col_999x, dm_tts_value_row
-	output_16_3							; display 0...999
-	STRCAT_PRINT "'"					; print "'"
-	bra		TFT_standard_color			; done
-
-TFT_display_tts_clear:					; clear remains from TTS > 99
-	WIN_BOX_BLACK dm_tts_value_row, dm_tts_value_row+.31, dm_tts_value_col_999, dm_tts_value_col_99 ; top, bottom, left, right
-	call	TFT_memo_color				; restore default memo color
-	movff	int_O_TTS_norm+1,WREG		; get the high byte of the TTS
-	btfsc	WREG,int_invalid_flag		; is the invalid flag set?
-	call	TFT_disabled_color			; YES - restore disabled color
-	return								; done
-
-
-	global	TFT_show_ndl
-TFT_show_ndl:
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-	movff	int_O_NDL_norm+0,lo			; NO  - 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?
-	bra		TFT_show_ndl_alt			;             YES - use alternative layout
-	;bra	TFT_show_ndl_norm			;             NO  - use normal layout
-
-TFT_show_ndl_norm:						; set position
-	WIN_MEDIUM dm_ndl_value_col_norm,dm_ndl_value_row_norm
-	rcall	TFT_show_ndl_set_color		; set color
-	output_8							; display 0...240
-TFT_show_ndl_exit_1:
-	STRCAT_PRINT "'"					; print minutes symbol
-TFT_show_ndl_exit_2:
-	goto	TFT_standard_color			; done
-
-TFT_show_ndl_alt:
-	btfsc	safety_stop_active			; is the safety stop active?
-	bra		TFT_show_ndl_alt_safety		; YES
-										; 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
-	rcall	TFT_show_ndl_set_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
-	rcall	TFT_show_ndl_set_color		; set color
-	PUTC	" "							; fill first digit position
-	output_99							; display 0...99
-	bra		TFT_show_ndl_exit_1			; print minutes symbol and done
-
-TFT_show_ndl_set_color:
-	movff	int_O_NDL_norm+1,lo			; get high byte of NDL time in normal plan
-	btfss	lo,int_invalid_flag			; is the invalid flag set?
-	goto	TFT_memo_color				; NO  - select memo     color and return
-	goto	TFT_disabled_color			; YES - select disabled color and return
-
-
-	global	TFT_divemode_sign_show
-TFT_divemode_sign_show:
-	btfsc	alt_layout_active			; alternative layout active?
-	bra		TFT_divemode_sign_show_alt	; YES
-	;bra	TFT_divemode_sign_show_norm	; NO
-
-TFT_divemode_sign_show_norm:
-	WIN_TOP  dm_sign_row_norm			; set row    position
-	WIN_LEFT dm_sign_col_norm			; set column position
-	bra		TFT_divemode_sign_show_com	; continue with common part
-
-TFT_divemode_sign_show_alt:
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-	btfsc	sign_shown					; NO  - sign already shown?
-	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  - 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
-	WIN_LEFT dm_sign_col_alt			;     - set column position
-	;bra	TFT_divemode_sign_show_com	;     - continue with common part
-
-TFT_divemode_sign_show_com:
-	bsf		sign_shown					; flag that the advice/attention/warning sign is shown
-	btfsc	message_warning				; do we have a warning?
-	bra		TFT_divemode_sign_show_warn	; YES - show warning  sign
-	btfsc	message_attention			; NO  - do we have an attention?
-	bra		TFT_divemode_sign_show_att	;       YES - show attention sign
-	btfsc	message_advice				;       NO  - do we have an advice message?
-	bra		TFT_divemode_sign_show_adv	;             YES - show advice sign
-	return								;             NO  - false alarm
-
-
-TFT_divemode_sign_color_warn:			; custom colors table for dive_warning2 icon - warning
-	db	.4, 0							; #colors, spare
-	dw	0x0000							; color 0x00: outside           black
-	dw	0xff80							; color 0x01: triangle          yellow
-	dw	0xff80							; color 0x02: exclamation mark  yellow
-	dw	0xf800							; color 0x03: inside            red
-
-TFT_divemode_sign_color_adv:			; custom colors table for dive_warning2 icon - advice
-	db	.4, 0							; #colors, spare
-	dw	0x0000							; color 0x00: outside           black
-	dw	0xffff							; color 0x01: triangle          white
-	dw	0xffff							; color 0x02: exclamation mark  white
-	dw	0x0780							; color 0x03: inside            green
-
-TFT_divemode_sign_show_warn:
-	TFT_WRITE_PROM_IMAGE_CUST_COLOR TFT_divemode_sign_color_warn; set custom colors for warning
-	TFT_WRITE_PROM_IMAGE_BY_LABEL   dive_warning2_block			; show sign
-	return														; done
-
-TFT_divemode_sign_show_att:
-	TFT_WRITE_PROM_IMAGE_BY_LABEL   dive_warning2_block			; show sign (with default colors)
-	return														; done
-
-TFT_divemode_sign_show_adv:
-	TFT_WRITE_PROM_IMAGE_CUST_COLOR TFT_divemode_sign_color_adv	; set custom colors for advice
-	TFT_WRITE_PROM_IMAGE_BY_LABEL   dive_warning2_block			; show sign
-	return														; done
-
-
-	global	TFT_divemode_sign_clear
-TFT_divemode_sign_clear:
-	btfss	sign_shown					; is the advice/attention/warning sign shown?
-	return								; NO  - done
-	bcf		sign_shown					; YES - clear advice/attention/warning sign area and its flag
-	btfsc	alt_layout_active			;     - alternative layout active?
-	bra		TFT_divemode_sign_clear_alt	;     - YES
-	;bra	TFT_divemode_sign_clear_norm;     - NO
-
-TFT_divemode_sign_clear_norm:
-	WIN_BOX_BLACK dm_sign_row_norm, dm_sign_bot_norm, dm_sign_col_norm, dm_sign_rgt_norm ; top, bottom, left, right
-	return								; done
-
-TFT_divemode_sign_clear_alt:
-	WIN_BOX_BLACK dm_sign_row_alt, dm_sign_bot_alt, dm_sign_col_alt, dm_sign_rgt_alt	 ; top, bottom, left, right
-	return								; done
-
-
+	return								;             YES - done
+	goto	TFT_show_slow_reminder		;             NO  - show "slow" reminder
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Deco Layout Add-on
+;
 	global	TFT_show_deco_mask
 TFT_show_deco_mask:
 	bcf		safety_stop_active			; flag safety stop is not shown any more	TODO: needed?
@@ -1177,2230 +1431,31 @@
 	;bra	TFT_show_deco_mask_norm		;       NO
 
 TFT_show_deco_mask_norm:
-	WIN_STD dm_tts_text_col_norm, dm_tts_text_row_norm	; set text position
-	bra		TFT_show_deco_mask_common					; continue with common part
+	WIN_STD dm_tts_text_col_norm, dm_tts_text_row_norm
+	bra		TFT_show_deco_mask_common	; continue with common part
 
 TFT_show_deco_mask_alt:
-	WIN_TINY dm_tts_text_col_alt, dm_tts_text_row_alt	; set text position
-	STRCPY	"Stop/"										; print "Stop/"
-	;bra	TFT_show_deco_mask_common					; continue with common part
+	WIN_TINY dm_tts_text_col_alt, dm_tts_text_row_alt
+	STRCPY	"Stop/"						; print "Stop/"
+	;bra	TFT_show_deco_mask_common	; continue with common part
 
 TFT_show_deco_mask_common:
-	call	TFT_divemask_color			; set text color
+	FONT_COLOR_MASK						; set color
 	STRCAT_TEXT_PRINT tTTS				; print "TTS"
-	bra		TFT_display_exit_1			; done
-
-
-TFT_display_deco_depth:					; output depth (stored in lo) to POSTINC2 with "m" or "ft"
-	TSTOSS	opt_units					; get unit (0=m, 1=ft)
-	bra		TFT_display_deco_depth_m	; 0 - meter
-	;bra	TFT_display_deco_depth_ft	; 1 - feet
-
-TFT_display_deco_depth_ft:
-	call	convert_meter_to_feet		; convert value in lo from meters to feet
-	output_16_3							; output stop depth (000-999)
-	return								; done
-
-TFT_display_deco_depth_m:
-	output_99							; output stop depth
-	STRCAT_TEXT tMeters					; print unit
 	return								; done
 
 
-	global	TFT_show_deco
-TFT_show_deco:
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-
-	call	TFT_color_code_stop			; color-code output
-	movff	char_O_deco_depth,lo		; get depth of first stop in meters
-
-	TSTOSC	opt_units					; get unit (0=m, 1=ft)
-	bra		TFT_show_deco_norm			; 1 - ft can only be displayed in normal layout due to space required for 3 digit depth
-
-	btfsc	alt_layout_active			; in alternative layout?
-	bra		TFT_show_deco_alt			; YES
-	;bra	TFT_show_deco_norm			; NO
-
-TFT_show_deco_norm:						; set position for combined depth and time
-	WIN_MEDIUM dm_decostop_col_norm, dm_decostop_row_norm
-	rcall	TFT_display_deco_depth		; output depth (stored in lo) to POSTINC2 with "m" or "ft"
-	PUTC	' '							; put a space char between depth and time
-	bra		TFT_display_deco_common		; continue with common part
-
-TFT_show_deco_alt:						; set position for depth
-	WIN_LARGE  dm_decostop_col_alt_depth, dm_decostop_row_alt_depth
-	output_99							; output stop depth (2 digits, usable for meters only)
-	STRCAT_PRINT ""						; finalize output
-										; set position for time
-	WIN_MEDIUM dm_decostop_col_alt_time,  dm_decostop_row_alt_time
-	call	TFT_memo_color				; back to memo color
-	bcf		win_invert					; back to non-inverted output
-	;bra	TFT_display_deco_common		; continue with common part
-
-TFT_display_deco_common:
-	movff	char_O_deco_time,lo			; get stop time of the first stop in minutes
-	output_99DD							; print minutes or double dots if null
-	STRCAT_PRINT "'"					; add minutes sign
-	bcf		win_invert					; back to non-inverted output
-TFT_display_exit_1:
-	goto	TFT_standard_color			; and return...
-
-
-	global	TFT_decoplan_mask			; mask for deco plan
-TFT_decoplan_mask:
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_decoplan_title_column, dm_custom_decoplan_title_row
-	STRCPY_TEXT_PRINT tDiveDecoplan
-	return
-
-
-	global	TFT_decoplan				; data for deco plan - stops 2 - 7 (stop 1 is shown in the main screen)
-TFT_decoplan:
-	lfsr	FSR0,char_O_deco_depth		; load base address of stops table
-	clrf	ex							; will be used for auxiliary flags
-	call	TFT_memo_color				; set default output color
-	movff	char_O_deco_gas+0,lo		; get flag for invalid deco data
-	btfsc	lo,char_invalid_flag		; is the invalid flag set?
-	call	TFT_disabled_color			; YES - set to disabled color
-	; 2nd stop
-	WIN_SMALL dm_cust_dstop_2nd_stop_column, dm_cust_dstop_2nd_stop_row
-	rcall	TFT_decoplan_helper
-	; 3rd stop
-	WIN_SMALL dm_cust_dstop_3rd_stop_column, dm_cust_dstop_3rd_stop_row
-	rcall	TFT_decoplan_helper
-	; 4th stop
-	bsf		ex,4						; flag we are on 4th screen position
-	WIN_SMALL dm_cust_dstop_4th_stop_column, dm_cust_dstop_4th_stop_row
-	rcall	TFT_decoplan_helper
-	bcf		ex,4						; clear 4th position flag again
-	; 5th stop
-	WIN_SMALL dm_cust_dstop_5th_stop_column, dm_cust_dstop_5th_stop_row
-	rcall	TFT_decoplan_helper
-	; 6th stop
-	WIN_SMALL dm_cust_dstop_6th_stop_column, dm_cust_dstop_6th_stop_row
-	rcall	TFT_decoplan_helper
-	; 7th stop
-	WIN_SMALL dm_cust_dstop_7th_stop_column, dm_cust_dstop_7th_stop_row
-	rcall	TFT_decoplan_helper
-	bra		TFT_display_exit_1			; set standard color and return...
-
-TFT_decoplan_helper:
-	btfsc	ex,0						; no more stops to show?
-	bra		TFT_decoplan_helper_1		; YES - skip checking next entry - it will be empty, too
-	movff	PREINC0,lo					; NO  - advance pointer to get the depth of the 2nd, 3rd, 4th, ... stop
-	tstfsz	lo							;       is the stop depth = 0, i.e. no stop entry?
-	bra		TFT_decoplan_helper_3		;       NO  - show stop data
-TFT_decoplan_helper_1:					; no more stop table entries
-	bsf		ex,0						; flag that there are no more stop table entries
-	btfss	ex,4						; are we on the 4th screen position?
-	bra		TFT_decoplan_helper_2		; NO  - normal handling on this position
-	btfsc	ex,1						; YES - special handling, has any stop been shown?
-	bra		TFT_decoplan_helper_2		;       YES - print normal blanking
-	STRCPY_PRINT "  ---- "				;       NO  - print a "no stops" indication (blanking potential previous content, too)
-	return
-TFT_decoplan_helper_2:					; no more stop table entries, blank potential previous content
-	STRCPY_PRINT "       "				; wipe screen position by printing 7 spaces
-	return
-TFT_decoplan_helper_3:
-	rcall	TFT_display_deco_depth		; output depth (stored in lo) to POSTINC2
-	PUTC	" "							; put a space char between depth and time
-	movlw	NUM_STOPS					; offset between arrays holding depths and durations
-	movff	PLUSW0,lo					; get duration of the current stop
-	output_99dd							; print duration, prints double dots if duration is zero
-	STRCAT_PRINT "'"					; append symbol for minutes and print to screen
-	bsf		ex,1						; flag that a stop was shown
-	return
-
-
-	global	TFT_safety_stop_clear
-TFT_safety_stop_clear:
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-	btfss	safety_stop_active			; NO  - is the safety stop shown?
-	return								;       NO  - done, nothing to do
-										;       YES - clear safety stop area
-	WIN_BOX_BLACK dm_safetystop_row, dm_safetystop_bot, dm_safetystop_text_column, dm_safetystop_rgt ; top, bottom, left, right
-	bcf		safety_stop_active			;           - safety stop not shown any more
-	btfsc	deco_region					;           - was the dive within deco stops region?
-	bra		TFT_show_slow_reminder		;             YES - show "SLOW" reminder
-	return								;             NO  - done
-
-
-	global	TFT_safety_stop_show
-TFT_safety_stop_show:
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-	btfsc	safety_stop_active			; NO  - is the safety stop shown already?
-	bra		TFT_safety_stop_show_time	;       YES - just update the time
-										;       NO  - clear area that may be polluted by alternative NDL
-	WIN_BOX_BLACK dm_safetystop_row, dm_tts_value_row, dm_ndl_value_col_alt, dm_safetystop_rgt ; top, bottom, left, right
-	call	TFT_divemask_color			;           - set color    for text
-	bsf		safety_stop_active			;           - flag safety stop is shown now
-										;           - set position for text
-	WIN_STD dm_safetystop_text_column, dm_safetystop_text_row
-	STRCPY_PRINT "Stop "				;           - print "Stop" with a trailing space to wipe away potential other remains
-TFT_safety_stop_show_time:
-	call	TFT_attention_color			; set color    for time
-										; set position for time
-	WIN_MEDIUM dm_safetystop_column, dm_safetystop_row
-	movff	safety_stop_countdown,lo	; get remaining time in seconds, low  byte, from safety stop timer
-	clrf	hi							; set remaining time in seconds, high byte, to zero
-	call	convert_time				; convert hi:lo in seconds to minutes (up:hi) and seconds (lo)
-	movff	lo,up						; save seconds in up
-	movff	hi,lo						; move minutes to lo
-	bsf		leftbind					; activate left-alignment
-	output_8							; print minutes
-	bcf		leftbind					; deactivate left-alignment
-	PUTC	':'							; print ":"
-	movff	up,lo						; move seconds to lo
-	output_99x							; print seconds (2 digits with leading zero)
-	STRCAT_PRINT ""						; finalize output
-	bra		TFT_display_exit_1			; done
-
-
-	global	TFT_avr_stopwatch_mask		; mask for average depth and stopwatch
-TFT_avr_stopwatch_mask:
-	call	TFT_divemask_color
-
- IFNDEF _min_depth_option
-
-	WIN_TINY dm_custom_avr_stop_column1+.2,dm_custom_avr_stop_title_row
-	TSTOSS	opt_2ndDepthDisp			; show avg depth instead of max depth in main screen?
-	bra		TFT_avr_stopwatch_mask_1	; NO  - draw avg depth in custom view then
-	btfss	alt_layout_active			; YES - in alternative layout?
-	bra		TFT_avr_stopwatch_mask_max	;       NO  - show max depth
-	;bra	TFT_avr_stopwatch_mask_avg	;       YES - show avg depth
-TFT_avr_stopwatch_mask_avg:
-	STRCPY_TEXT_PRINT tDiveTotalAvg		; mask for average depth
-	bra		TFT_avr_stopwatch_mask_2	; continue
-TFT_avr_stopwatch_mask_1:
-	btfss	alt_layout_active			; YES - in alternative layout?
-	bra		TFT_avr_stopwatch_mask_avg	;       NO  - show avg depth
-	;bra	TFT_avr_stopwatch_mask_max	;       YES - show max depth
-TFT_avr_stopwatch_mask_max:
-	STRCPY_TEXT_PRINT tMaxDepth			; mask for maximum depth
-	;bra	TFT_avr_stopwatch_mask_2	; continue
-TFT_avr_stopwatch_mask_2:
-	WIN_TINY dm_custom_avr_stop_column2+.3,dm_custom_avr_stop_title_row
-	STRCPY_TEXT_PRINT tDiveStopwatch
-	WIN_TINY dm_custom_avr_stop_column3-.8,dm_custom_avr_stop_title_row
-	STRCPY_TEXT_PRINT tDiveStopAvg
-	bra		TFT_display_exit_1
-
- ELSE
-
-	WIN_TINY dm_custom_avr_stop_column1+.2,dm_custom_avr_stop_title_row
-	STRCPY_PRINT "Max.Depth"
-	WIN_TINY dm_custom_avr_stop_column2+.3,dm_custom_avr_stop_title_row
-	STRCPY_PRINT "Avg.Depth"
-	WIN_TINY dm_custom_avr_stop_column3-.8,dm_custom_avr_stop_title_row
-	STRCPY_PRINT "Min.Depth"
-	bra		TFT_display_exit_1
-
- ENDIF
-
-
-	global	TFT_avr_stopwatch			; dive mode custom view: average depth and stopwatch
-TFT_avr_stopwatch:
-	call	TFT_memo_color
-
- IFNDEF _min_depth_option
-
-	; total average depth or max depth
-	WIN_MEDIUM dm_custom_avr_stop_column1,dm_custom_avr_stop_row
-	TSTOSS	opt_2ndDepthDisp			; show average depth instead of maximum depth in main screen?
-
-	bra		TFT_avr_stopwatch_1			; NO  - draw avg depth in custom view then
-	btfss	alt_layout_active			; YES - in alternative layout?
-	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 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 pressure into hi:lo
-	;bra	TFT_avr_stopwatch_2			; continue
-TFT_avr_stopwatch_2:
-	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_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
-	clrf	WREG
-	movff	WREG,buffer+.4				; limit string length to 4 = 3 digits + 1 half-size decimal dot
-TFT_update_avr_stopwatch2:
-	STRCAT_PRINT ""
-
-	; 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 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_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
-	clrf	WREG
-	movff	WREG,buffer+.4				; limit string length to 4 = 3 digits + 1 half-size decimal dot
-TFT_update_avr_stopwatch3:
-	STRCAT_PRINT ""						; finalize output
-
- ELSE
-
-	; 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	; 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	; 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	; get resettable minimum pressure
-	rcall	TFT_avr_stopwatch_helper
-
-	; done
-	bra		TFT_display_exit_2
-
-TFT_avr_stopwatch_helper:
-	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
-	movff	WREG,buffer+.5				; limit string length to 5 = 4 digits + 1 half-size decimal dot
-	STRCAT_PRINT ""
-	return
-
- ENDIF
-
-	; stopped dive time  (will also be used by compass custom view)
-	WIN_MEDIUM dm_custom_avr_stop_column2,dm_custom_avr_stop_row
-TFT_update_stopwatch:					; jump-in point for stopped dive time in compass custom view
-	MOVII	divesecs_avg_trip,mpr		; get the resettable dive time (stopwatch)
-	call	convert_time				; convert hi:lo in seconds to minutes (up:hi) and seconds (lo)
-	movlw	.100						; display layout will change if minutes become >= 100
-	cpfslt	hi							; minutes < 100 ?
-	bra		TFT_update_stopwatch_2		; NO  - display hours:minutes
-	bcf		aux_flag					; will print minutes : seconds
-TFT_update_stopwatch_1:
-	movf	hi,W						; exchange lo and hi
-	movff	lo,hi						; ...
-	movwf	lo							; ...
-	bcf		leftbind					; include leading spaces
-	output_99							; output minutes or hours ( 0 - 99)
-	movlw	":"							; load standard separator
-	btfsc	aux_flag					; will print hours : minutes ?
-	movlw	"'"							; YES - swap to alternative separator
-	movwf	POSTINC2					; print separator
-	movff	hi,lo						; restore lo
-	output_99x							; output seconds or minutes
-	movlw	.5
-	call	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	clrf	WREG
-	movff	WREG,buffer+.5				; limit to 5 chars
-	STRCAT_PRINT ""
-	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
-	call	convert_time				; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
-	bsf		aux_flag					; will print hours : minutes
-	bra		TFT_update_stopwatch_1
-
-
-	global	TFT_CNS_mask
-TFT_CNS_mask:
-	call	TFT_divemask_color
-	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_2				; YES - print fTTS label
-	btfsc	bailout_mode				; in bailout?
-	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_3				;     - continue with 3rd column
-TFT_CNS_mask_2:							; OC or bailout
-	STRCPY_TEXT_PRINT tCNSfTTS			; print fTTS label
-TFT_CNS_mask_3:
-	WIN_TINY dm_custom_cns3_column3, dm_custom_cns3_title_row
-	STRCPY_TEXT_PRINT tCNSnow			; print CNS now label
-	bra		TFT_display_exit_2
-
-
-	global	TFT_CNS
-TFT_CNS:
-	bsf		leftbind
-	; CNS at end of normal dive
-	WIN_STD dm_custom_cns3_column1+.3,dm_custom_cns3_row
-	MOVII	int_O_CNS_norm,mpr			; get CNS at end of dive in normal plan
-	call	TFT_color_code_cns
-	output_16_3							; output as xxx
-	STRCAT_PRINT "% "
-	; fTTS / Bailout CNS, if enabled
-	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_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%
-TFT_CNS_1:								; not in bailout, no volume calculation, and/or in OC mode
-	TSTOSS	char_I_extra_time			; fTTS extra time configured?
-	bra		TFT_CNS_3					; NO  - show "---"
-TFT_CNS_2:								; YES - show CNS%
-	MOVII	int_O_CNS_alt,mpr			; get CNS at end of dive in alternative plan
-	call	TFT_color_code_cns			; color-code the CNS value
-	output_16_3							; output as xxx
-	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:
-	; current CNS
-	WIN_STD dm_custom_cns3_column3+.3,dm_custom_cns3_row
-	MOVII	int_O_CNS_current,mpr		; get current CNS
-	call	TFT_color_code_cns
-	output_16_3							; output as xxx
-	STRCAT_PRINT "%"
-TFT_display_exit_2:
-	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
-
-;=============================================================================
-
- IFDEF _external_sensor
-
-	global	TFT_ppo2_sensors_mask		; mask for ppO2 sensors
-TFT_ppo2_sensors_mask:
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_hud_sensor1_column+.4,dm_custom_hud_title_row
-	STRCPY_TEXT_PRINT tDiveHudMask1
-	WIN_TINY dm_custom_hud_sensor2_column+.3,dm_custom_hud_title_row
-	STRCPY_TEXT_PRINT tDiveHudMask2
-	WIN_TINY dm_custom_hud_sensor3_column+.2,dm_custom_hud_title_row
-	STRCPY_TEXT_PRINT tDiveHudMask3
-	bra		TFT_display_exit_2
-
-
-	global	TFT_ppo2_sensors			; data for ppO2 sensors
-TFT_ppo2_sensors:
-;
-; Definition of the output:
-;
-;  sensorX       use        voting         o2
-; _calibrated    _O2       _logic        _ppo2          Output           Color
-;    _ok      _sensorX    _sensorX     _sensorX
-;-----------------------------------------------------------------------------------------------
-;    0          -/-          -/-            -/-         "----"           TFT_memo_color
-;    1           0           -/-            = 0         o2_ppo2_sensorX  TFT_attention_color
-;    1           0           -/-            > 0         o2_ppo2_sensorX  TFT_disabled_color
-;    1           1            0             -/-         o2_ppo2_sensorX  TFT_color_code_ppo2_hud + win_invert
-;    1           1            1             -/-         o2_ppo2_sensorX  TFT_color_code_ppo2_hud
-;
-	bsf		leftbind
-	; sensor 1
-	btfsc	sensor1_calibrated_ok		; valid calibration?
-	bra		TFT_update_hud1b			; YES
-	btfsc	sensor1_active				; valid HUD data for this sensor
-	bra		TFT_update_hud1b			; YES
-
-	; no valid calibration
-	WIN_STD dm_custom_hud_sensor1_column+.7, dm_custom_hud_row+.5
-	call	TFT_memo_color
-	STRCPY_PRINT "---"
-	bra		TFT_update_hud2a			; continue with sensor 2
-TFT_update_hud1b:
-	; sensor has a valid calibration
-	WIN_MEDIUM dm_custom_hud_sensor1_column,dm_custom_hud_row
-	movff	sensor1_ppO2,lo				; load ppO2 value into transfer storage for output
-	clrf	hi							; 
-	btfsc	use_O2_sensor1				; in use?
-	bra		TFT_update_hud1d			; YES
-	; valid calibration, but not in use
-	tstfsz	lo							; sensor value = 0?
-	bra		TFT_update_hud1c			; no
-	; valid calibration, not in use and value = 0
-	call	TFT_attention_color			; output in yellow
-	bra		TFT_update_hud1e
-TFT_update_hud1c:
-	; sensor has valid calibration, is not in use and has a value > 0
-	call	TFT_disabled_color			; output in light blue
-	bra		TFT_update_hud1e
-TFT_update_hud1d:
-	; sensor has valid calibration and is in use
-	call	TFT_color_code_ppo2_hud		; With ppO2 [cbar] in lo
-	btfsc	voting_logic_sensor1		; sensor value agrees with values of other sensors?
-	bra		TFT_update_hud1e			; YES
-	; valid calibration, in use, but value does not agree with other sensors
-	bsf		win_invert					; invert output
-TFT_update_hud1e:
-	; all coloring is set up now, let's write the value to the display!
-	output_16dp .3						; x.xx bar
-	STRCAT_PRINT ""
-	bcf		win_invert
-
-TFT_update_hud2a:						; sensor 2
-	btfsc	sensor2_calibrated_ok		; valid calibration?
-	bra		TFT_update_hud2b			; YES
-	btfsc	sensor2_active				; valid HUD data for this sensor
-	bra		TFT_update_hud2b			; YES
-	; no valid calibration
-	WIN_STD dm_custom_hud_sensor2_column+.7, dm_custom_hud_row+.5
-	call	TFT_memo_color
-	STRCPY_PRINT "---"
-	bra		TFT_update_hud3a			; continue with sensor 3
-TFT_update_hud2b:
-	; sensor has a valid calibration
-	WIN_MEDIUM dm_custom_hud_sensor2_column,dm_custom_hud_row
-	movff	sensor2_ppO2,lo				; load ppO2 value into transfer storage for output
-	clrf	hi							; 
-	btfsc	use_O2_sensor2				; in use?
-	bra		TFT_update_hud2d			; YES
-	; valid calibration, but not in use
-	tstfsz	lo							; sensor value = 0?
-	bra		TFT_update_hud2c			; NO
-	; valid calibration, not in use and value = 0
-	call	TFT_attention_color			; output in yellow
-	bra		TFT_update_hud2e
-TFT_update_hud2c:
-	; sensor has valid calibration, is not in use and has a value > 0
-	call	TFT_disabled_color			; output in light blue
-	bra		TFT_update_hud2e
-TFT_update_hud2d:
-	; sensor has valid calibration and is in use
-	call	TFT_color_code_ppo2_hud		; With ppO2 [cbar] in lo
-	btfsc	voting_logic_sensor2		; sensor value agrees with values of other sensors?
-	bra		TFT_update_hud2e			; YES
-	; valid calibration, in use, but value does not agree with other sensors
-	bsf		win_invert					; invert output
-TFT_update_hud2e:
-	; all coloring is set up now, let's write the value to the display!
-	output_16dp .3						; x.xx bar
-	STRCAT_PRINT ""
-	bcf		win_invert
-
-TFT_update_hud3a:						; sensor 3
-	btfsc	sensor3_calibrated_ok		; valid calibration?
-	bra		TFT_update_hud3b			; YES
-	btfsc	sensor3_active				; valid HUD data for this sensor
-	bra		TFT_update_hud3b			; YES
-	; no valid calibration
-	WIN_STD dm_custom_hud_sensor3_column+.7, dm_custom_hud_row+.5
-	call	TFT_memo_color
-	STRCPY_PRINT "---"
-	bra		TFT_update_hud4				; done
-TFT_update_hud3b:
-	; sensor has a valid calibration
-	WIN_MEDIUM dm_custom_hud_sensor3_column,dm_custom_hud_row
-	movff	sensor3_ppO2,lo				; load ppO2 value into transfer storage for output
-	clrf	hi							; 
-	btfsc	use_O2_sensor3				; in use?
-	bra		TFT_update_hud3d			; YES
-	; valid calibration, but not in use
-	tstfsz	lo							; sensor value = 0?
-	bra		TFT_update_hud3c			; NO
-	; valid calibration, not in use and value = 0
-	call	TFT_attention_color			; output in yellow
-	bra		TFT_update_hud3e
-TFT_update_hud3c:
-	; sensor has valid calibration, is not in use and has a value > 0
-	call	TFT_disabled_color			; output in light blue
-	bra		TFT_update_hud3e
-TFT_update_hud3d:
-	; sensor has valid calibration and is in use
-	call	TFT_color_code_ppo2_hud		; With ppO2 [cbar] in lo
-	btfsc	voting_logic_sensor3		; sensor value agrees with values other sensors?
-	bra		TFT_update_hud3e			; YES
-	; valid calibration, in use, but value does not agree with other sensors
-	bsf		win_invert					; invert output
-TFT_update_hud3e:
-	; all coloring is set up now, let's write the value to the display!
-	output_16dp .3						; x.xx bar
-	STRCAT_PRINT ""
-	bcf		win_invert
-
-TFT_update_hud4:						; closure
-	bra		TFT_display_exit_3
-
-
-	global	TFT_surface_sensor			; update O2 sensor data in surface mode
-TFT_surface_sensor:
-	bsf		leftbind
-	WIN_SMALL surf_hud_sensor1_column,surf_hud_sensor1_row
-	btfsc	sensor1_calibrated_ok
-	bra		TFT_surface_sensor1			; YES
-	btfsc	sensor1_active				; valid HUD data for this sensor
-	bra		TFT_surface_sensor1			; YES
-	call	TFT_standard_color
-	STRCPY_PRINT "--- "
-	bra		TFT_surface_sensor2			; skip sensor 1
-TFT_surface_sensor1:
-	movff	sensor1_ppO2,lo
-	call	TFT_color_code_ppo2_hud		; with ppO2 [cbar] in lo
-	clrf	hi
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	STRCAT_PRINT ""
-TFT_surface_sensor2:
-	WIN_SMALL surf_hud_sensor2_column,surf_hud_sensor2_row
-	btfsc	sensor2_calibrated_ok
-	bra		TFT_surface_sensor3			; YES
-	btfsc	sensor2_active				; valid HUD data for this sensor
-	bra		TFT_surface_sensor3			; YES
-	call	TFT_standard_color
-	STRCPY_PRINT "--- "
-	bra		TFT_surface_sensor4			; skip sensor 2
-TFT_surface_sensor3:
-	movff	sensor2_ppO2,lo
-	call	TFT_color_code_ppo2_hud		; with ppO2 [cbar] in lo
-	clrf	hi
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	STRCAT_PRINT ""
-TFT_surface_sensor4:
-	WIN_SMALL surf_hud_sensor3_column,surf_hud_sensor3_row
-	btfsc	sensor3_calibrated_ok
-	bra		TFT_surface_sensor5			; YES
-	btfsc	sensor3_active				; valid HUD data for this sensor
-	bra		TFT_surface_sensor5			; YES
-	call	TFT_standard_color
-	STRCPY_PRINT "--- "
-	bra		TFT_surface_sensor6			; skip sensor 3
-TFT_surface_sensor5:
-	movff	sensor3_ppO2,lo
-	call	TFT_color_code_ppo2_hud		; with ppO2 [cbar] in lo
-	clrf	hi
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	STRCAT_PRINT ""
-TFT_surface_sensor6:
-TFT_display_exit_3:
-	bcf		leftbind
-	goto	TFT_standard_color			; and return...
-
-
-	global	TFT_sensor_mV
-TFT_sensor_mV:
-	bsf		leftbind
-
-	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor1_row
-	SMOVII	sensor1_mv,mpr				; in 0.1mV steps
-	STRCAT	"1: "
-	rcall	TFT_sensor_mV_helper
-
-	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor2_row
-	SMOVII	sensor2_mv,mpr				; in 0.1mV steps
-	STRCAT	"2: "
-	rcall	TFT_sensor_mV_helper
-
-	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor3_row
-	SMOVII	sensor3_mv,mpr				; in 0.1mV steps
-	STRCAT	"3: "
-	rcall	TFT_sensor_mV_helper
-	bcf		leftbind
-	
-	WIN_SMALL surf_mV_sensor_column,surf_mV_sensor3_row+.24 ; 4th row
-	btfss	s8_digital_avail			;  do we have a digital S8 interface?
-	bra	TFT_sensor_mV_optical_analog
-	STRCAT_PRINT	"Digital"
-	bra		TFT_display_exit_3
-TFT_sensor_mV_optical_analog:
-	btfss	ir_power				;  do we have a optical digital interface?
-	bra	TFT_sensor_mV_analog
-	STRCAT_PRINT	"Optical"
-	bra		TFT_display_exit_3
-TFT_sensor_mV_analog:						; -> optical
-	STRCAT_PRINT	"Analog"
-	bra		TFT_display_exit_3
-
-TFT_sensor_mV_helper:
-	output_16dp .4						; xxx.y mV
-	STRCAT_PRINT "mV "
-	return
-
-
-	global	TFT_sensor_surface_warning
-TFT_sensor_surface_warning: 
-	call	TFT_warning_color
-	btfss	sensor1_calibrated_ok		; do not show end of lifetime arrow if sensor failed calibration at all
-	bra		TFT_sensor_mV2
-	movff	opt_x_s1+1,lo				; into bank1
-	movf	lo,W						; when opt_x_s1 > 255 the sensor will just give 8 mV at a ppO2 of 0.21 any more 
-	bz		TFT_sensor_mV2				; the sensor is not too bad yet for a warning 
-	WIN_SMALL surf_mV_sensor_status_column,surf_mV_sensor1_row-.5 
-	STRCPY_PRINT "\xb8"					; mark sensor as being at end of lifetime
-TFT_sensor_mV2:
-	btfss	sensor2_calibrated_ok		; do not show end of lifetime arrow if sensor failed calibration at all
-	bra		TFT_sensor_mV3
-	movff	opt_x_s2+1,lo				; into bank1
-	movf	lo,W						; when opt_x_s2 > 255 the sensor will just give 8 mV at a ppO2 of 0.21 any more 
-	bz		TFT_sensor_mV3				; the sensor is not too bad yet for a warning 
-	WIN_SMALL surf_mV_sensor_status_column,surf_mV_sensor2_row-.5 
-	STRCPY_PRINT "\xb8"					; mark sensor as being at end of lifetime 
-TFT_sensor_mV3:
-	btfss	sensor3_calibrated_ok		; do not show end of lifetime arrow if sensor failed calibration at all
-	bra		TFT_sensor_mV4
-	movff	opt_x_s3+1,lo				; into bank1
-	movf	lo,W						; when opt_x_s3 > 255 the sensor will just give 8 mV at a ppO2 of 0.21 any more 
-	bz		TFT_sensor_mV4				; the sensor is not too bad yet for a warning 
-	WIN_SMALL surf_mV_sensor_status_column,surf_mV_sensor3_row-.5
-	STRCPY_PRINT "\xb8"					; mark sensor as being at end of lifetime 
-TFT_sensor_mV4:
-	bra		TFT_display_exit_3
-
-
-	global	TFT_menu_calibrate
-TFT_menu_calibrate:						; update mV data in calibration menu
-	btfss	s8_digital_avail			; do we have a digital S8 interface?
-	bra		TFT_menu_calibrate_analog	; NO  - use analog
-	btfss	trigger_S8_data_update		; YES - new data frame received?
-	bra		TFT_menu_calibrate_common	;       NO  - use old values...
-	bcf		trigger_S8_data_update		;       YES - clear update flag
-	call	compute_mvolts_for_all_sensors ;        - compute mV values from received data frame
-	bra		TFT_menu_calibrate_common	;           - continue with common part
-TFT_menu_calibrate_analog:
-	call	get_analog_inputs			; read mV values from analog inputs
-TFT_menu_calibrate_common:
-	call	TFT_attention_color			; show in yellow
-	bsf		leftbind					; align to the left
-	WIN_SMALL	surf_menu_sensor1_column,surf_menu2_sensor1_row
-	SMOVII	sensor1_mv,mpr				; in 0.1mV steps
-	output_16dp .4						; xxx.y mV
-	STRCAT_PRINT "mV  "
-	WIN_SMALL	surf_menu_sensor2_column,surf_menu2_sensor2_row
-	SMOVII	sensor2_mv,mpr				; in 0.1mV steps
-	output_16dp .4						; xxx.y mV
-	STRCAT_PRINT "mV  "
-	WIN_SMALL	surf_menu_sensor3_column,surf_menu2_sensor3_row
-	SMOVII	sensor3_mv,mpr				; in 0.1mV steps
-	output_16dp .4						; xxx.y mV
-	STRCAT_PRINT "mV  "
-	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
-
-;=============================================================================
-
-	global	TFT_time_surfmode
-TFT_time_surfmode:
-	WIN_SMALL surf_clock_column+.7,surf_clock_row
-TFT_clock2:								; called from dive mode clock
-	call	TFT_standard_color
-	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
-	movff	rtc_latched_hour,lo
-	output_99
-	movlw	':'
-	movff	rtc_latched_secs,lo
-	btfss	lo,0						; blinking every second
-	movlw	' '
-	movwf	POSTINC2
-	movff	rtc_latched_mins,lo
-	output_99x
-	STRCAT_PRINT ""
-	return
-
-
-	global	TFT_show_time_date_menu
-	global	TFT_show_time_date_menu_fast
-TFT_show_time_date_menu:
-	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of current date & time
-TFT_show_time_date_menu_fast:
-	WIN_SMALL .20,.40					; column, row - keep clear of the cursor area on the left!
-	call	TFT_standard_color
-	movff	rtc_latched_hour,lo
-	output_99
-	PUTC	':'
-	movff	rtc_latched_mins,lo
-	output_99x
-	PUTC	':'
-	movff	rtc_latched_secs,lo
-	output_99x
-	STRCAT	"  "
-	movff	rtc_latched_year, lo
-	movff	rtc_latched_month,hi
-	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
-
-;=============================================================================
-
-	global	TFT_surface_decosettings	; show all deco settings
-TFT_surface_decosettings:
-	; Deco Mode
-	call	TFT_standard_color
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row
-	STRCAT_PRINT "ZH-L16"
-	movff	char_I_model,WREG
-	iorwf	WREG
-	bnz		TFT_surface_decosettings1
-	; Display ZH-L16 sat/desat model
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
-	lfsr	FSR2,buffer
-	movff	char_I_desaturation_multiplier,lo
-	bsf		leftbind
-	output_8
-	STRCAT	"%/"
-	movff	char_I_saturation_multiplier,lo
-	output_8
-	STRCAT_PRINT "%"
-	bra		TFT_surface_decosettings2
-	; Display ZH-L16-GF low/high model
-TFT_surface_decosettings1:
-	TEXT_SMALL surf_gaslist_column+.43,surf_gaslist_row,tZHL16GF
-	WIN_SMALL  surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
-	STRCPY_TEXT tGF						; GF:
-	movff	opt_GF_low,lo
-	output_99x
-	STRCAT	"/"
-	movff	opt_GF_high,lo
-	output_99x
-	STRCAT_PRINT ""
-TFT_surface_decosettings2:				; fTTS
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
-	STRCPY_TEXT tFTTSSurf
-	movff	char_I_extra_time,lo
-	bsf		leftbind
-	output_8
-	STRCAT_TEXT_PRINT tMinutes
-	; Last Stop
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)
-	STRCPY_TEXT tLastDecostopSurf
-	movff	opt_last_stop,lo
-	output_8
-	STRCAT_TEXT_PRINT tMeters
-	; Salinity
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
-	STRCPY_TEXT tDvSalinitySurf
-	movff	opt_salinity,lo
-	output_8
-	bcf		leftbind
-	STRCAT_TEXT_PRINT tPercent
-	return
-
-
-	global	TFT_divetimeout
-TFT_divetimeout:
-	call	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	call	TFT_memo_color
-	STRCPY	0x94						; "End of dive" symbol
-	movff	opt_diveTimeout,WREG		; in [min]
-	mullw	.60
-	MOVII	PRODL,             sub_a	; in seconds
-	MOVII	dive_timeout_timer,sub_b
-	call	subU16						; sub_c = sub_a - sub_b (with UNSIGNED values)
-	MOVII	sub_c,mpr
-	call	convert_time				; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
-	movf	hi,W						; swap lo and hi
-	movff	lo,hi						; ...
-	movwf	lo							; ...
-	output_99x
-	PUTC	':'
-	movff	hi,lo						; copy hi to lo
-	output_99x
-	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 ""
-	bcf		win_invert
-	return
-
-
-	global	TFT_show_ftts
-TFT_show_ftts:
-	call	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	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_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_6			; NO  - keep memo color
-	bcf		hi,int_invalid_flag			; YES - clear flag
-	call	TFT_disabled_color			;     - switch to disabled color
-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_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 ""						; finalize output
-	bcf		leftbind					; clear left alignment
-	goto	TFT_standard_color			; ...and return
-
-
 ;=============================================================================
-
-	global	TFT_temp_surfmode
-TFT_temp_surfmode:
-	call	TFT_divemask_color
-	WIN_SMALL surf_temp_column+3*8,surf_temp_row
-	TSTOSS	opt_units						; 0=°C, 1=°F
-	bra		TFT_temp_surfmode_metric
-	STRCAT_TEXT tLogTunitF					; °F
-	bra		TFT_temp_surfmode_common
-TFT_temp_surfmode_metric:
-	STRCAT_TEXT tLogTunitC					; °C
-TFT_temp_surfmode_common:
-	STRCAT_PRINT ""
-	WIN_SMALL surf_temp_column,surf_temp_row
-	call	TFT_memo_color
-	bra		TFT_temp_common
-
-
-	global	TFT_show_temp_divemode
-TFT_show_temp_divemode:
-	btfsc	dive_options_menu				; is the pre-menu shown?
-	return									; YES - abort
-	btfsc	dive_main_menu					; is the dive mode menu shown?
-	return									; YES - abort, no update of temperature now
-	btfsc	better_gas_blinking				; blinking better gas?
-	return									; YES - abort, no update of temperature now
-	btfsc	better_dil_blinking				; blinking better diluent?
-	return									; YES - abort, no update of temperature now
-
-	WIN_SMALL dm_temp_column,dm_temp_row	; set position
-	call	TFT_memo_color					; set color
-	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
-	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
-	call	convert_celsius_to_fahrenheit	; 1 - convert value in lo:hi from Celsius to Fahrenheit
-	rcall	TFT_convert_signed_16bit		; convert lo:hi into signed-short and adds '-' to POSTINC2 if required
-	btfsc	neg_flag						; is the temperature negative?
-	bra		TFT_temp_common_2				; YES - the minus sign has already been written
-	; temp is positive, is it less than 10°C ?
-	tstfsz	hi
-	bra		TFT_temp_common_1				; > 25.5°C, skip here
-	movlw	.100
-	cpfslt	lo
-	bra		TFT_temp_common_1				; > 10.0°C, skip here
-	bsf		leftbind
-	output_16dp d'4'						; x.y°C
-	bcf		leftbind
-	bra		TFT_temp_common_3				; done
-TFT_temp_common_1:
-	PUTC	" "								; NO  - write a space instead of the minus sign
-TFT_temp_common_2:
-	bsf		ignore_digit5					; ignore decimal (flag will be cleared by output_16)
-	output_16_3								; output 0-999 without decimal -> writes ' ' - 99
-	movff	buffer+2,lo						; get output from unit position
-	movlw	" "								; load code of the space character
-	cpfseq	lo								; is there a space sign on the unit position? (happens between +1 and -1)
-	bra		TFT_temp_common_3				; NO
-	movff	WREG,buffer+0					; YES - replace potential minus sign with a space (temps from -0.9° to -0.1° else would appear as '- 0')
-	movlw	"0"								; load code of the zero character
-	movff	WREG,buffer+2					; replace space with a zero
-TFT_temp_common_3:
-	btfss	divemode						; are we in dive mode?
-	bra		TFT_temp_common_5				; NO  - no unit to append
-	TSTOSS	opt_units						; YES - check unit type: 0=°C, 1=°F
-	bra		TFT_temp_common_4				; go metric
-	STRCAT_TEXT tLogTunitF					; append °F
-	bra		TFT_temp_common_5
-TFT_temp_common_4:
-	STRCAT_TEXT tLogTunitC					; append °C
-TFT_temp_common_5:
-	STRCAT_PRINT ""							; output to screen
-TFT_temp_common_6:
-	goto	TFT_standard_color				; done
-
-
-;=============================================================================
-
-	global	TFT_show_menu_cursor_divemode
-TFT_show_menu_cursor_divemode:
-	WIN_BOX_BLACK dm_menu_row+.1, dm_menu_lower-.1, dm_menu_item1_column-.8, dm_menu_item1_column-.1
-	WIN_BOX_BLACK dm_menu_row+.1, dm_menu_lower-.1, dm_menu_item4_column-.8, dm_menu_item4_column-.1
-	call	TFT_standard_color
-
-	movlw	dm_menu_item1_column-.8
-	btfsc	menu_pos_cur,2				; > 3 ?
-	movlw	dm_menu_item4_column-.8		; YES
-	movwf	win_leftx2
-
-	movff	menu_pos_cur,lo				; copy menu position
-	movlw	dm_menu_item6_row
-	dcfsnz	lo,F
-	movlw	dm_menu_item1_row
-	dcfsnz	lo,F
-	movlw	dm_menu_item2_row
-	dcfsnz	lo,F
-	movlw	dm_menu_item3_row
-	dcfsnz	lo,F
-	movlw	dm_menu_item4_row
-	dcfsnz	lo,F
-	movlw	dm_menu_item5_row
-	movwf	win_top
-	movlw	FT_SMALL
-	movwf	win_font
-	STRCPY_PRINT "\xb7"					; print cursor
-	return
-
-;=============================================================================
-
-	global	TFT_show_active_gas_divemode
-TFT_show_active_gas_divemode:			; display gas (OC) or setpoint/ppO2 & gas (CCR, pSCR)
-	btfsc	dive_main_menu				; is the dive mode menu shown?
-	return								; YES - abort
-	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	return								; YES - done
-	btfsc	FLAG_gauge_mode				; in gauge mode?
-	return								; YES - done
-
- IFDEF _ccr_pscr
-	btfsc	FLAG_oc_mode				; in OC mode?
-	bra		TFT_active_gas				; YES - show OC gas
-	;bra	TFT_active_sp				; NO  - show setpoint and diluent
-
-TFT_active_sp:
-	btfss	bailout_mode				; in bailout?
-	bra		TFT_active_sp_loop			; NO
-	;bra	TFT_active_sp_bailout		; YES
-
-TFT_active_sp_bailout:
-	WIN_SMALL dm_active_dil_column, dm_active_dil_row
-	call	TFT_attention_color			;     - set color
-	STRCPY_TEXT_PRINT tDiveBailout		;     - print "Bailout"
-	bra		TFT_active_gas				;     - continue showing OC bailout gas
-
-TFT_active_sp_loop:
-	MOVII	int_O_breathed_ppO2,mpr		; copy ppO2 [cbar] to hi:lo
-	call	TFT_color_code_ppo2			; color-code the output by the ppO2 of the loop gas mixture
-	btfss	timebase_1sec				; on even second?
-	bra		TFT_active_sp_print			; YES - print ppO2 with normal rendering
-	btfsc	sp_fallback					; NO  - check if in fallback condition
-	bra		TFT_active_sp_fallback		;       YES - process fallback case
-	movff	int_O_breathed_ppO2+1,WREG	;       NO  - get flags again (have been cleared in hi:lo by TFT_color_code_ppo2 meanwhile)
-	btfss	WREG,int_warning_flag		;             warning flag set?
-	bra		TFT_active_sp_print			;             NO  - ppO2 is ok, print ppO2 with normal rendering
-	bra		TFT_active_sp_invers		;             YES - print with inverse rendering
-TFT_active_sp_fallback:					; set up fallback case
-	call	TFT_attention_color			; set color to yellow
-TFT_active_sp_invers:					; blinking common part
-	bsf		win_invert					; print in inverse
-TFT_active_sp_print:					; set position
-	WIN_MEDIUM dm_active_gas_sp_value_col, dm_active_gas_sp_value_row
-	bsf		leftbind					; print left-aligned
-	output_16dp .3						; print ppO2 as x.xx
-	bcf		leftbind					; back to right alignment
-	STRCAT_PRINT ""						; finalize output
-	bcf		win_invert					; end inverse printing
-
-	btfsc	sign_shown					; advice/attention/warning sign shown?
-	bra		TFT_active_diluent			; YES - skip display of "bar" and loop mode
-
-	btfsc	velocity_active_vsi			; graphical vertical speed indicator shown?
-	bra		TFT_active_diluent			; YES - skip display of "bar" and loop mode
-
-TFT_active_sp_label:
-	WIN_STD dm_active_sp_label_col, dm_active_sp_label_row
-	call	TFT_memo_color				; select memo color
-	STRCAT	"bar"						; print "bar"
- IFDEF _external_sensor
-	movff	opt_ccr_mode,WREG			; get setpoint mode =0: Fixed SP, =1: Sensor, =2: Auto SP
-	sublw	.1							; opt_ccr_mode = 1 (Sensor) ?
-	bnz		TFT_active_sp_label_1		; NO  - skip
-	btfsc	alt_layout_active			; YES - in alternative layout?
-	bra		TFT_active_sp_label_1		;       YES - no space available for the "*"
-	PUTC	"*"							;       NO  - add "*"
-TFT_active_sp_label_1:
- ENDIF
-	STRCAT_PRINT ""						; finalize output
-
-TFT_active_loop_mode:
-	WIN_TINY dm_active_sp_label_col, dm_active_dil_row+.3
-	call	TFT_memo_color				; set memo color
-	btfsc	FLAG_ccr_mode				; in CCR mode?
-	bra		TFT_active_loop_mode_ccr	; YES - print CCR label
-	btfsc	FLAG_pscr_mode				; in pSCR mode?
-	bra		TFT_active_loop_mode_pscr	; YES - print pSCR label
-	bra		TFT_active_diluent			; NO  to both - should not happen
-TFT_active_loop_mode_ccr:
-	STRCPY_TEXT_PRINT tDvCCR			; print "CCR"
-	bra		TFT_active_diluent			; continue with diluent
-TFT_active_loop_mode_pscr:
-	STRCPY_TEXT_PRINT tDvPSCR			; print "pSCR"
-	;bra	TFT_active_diluent			; continue with diluent
-
-TFT_active_diluent:
-	MOVII	int_O_pure_ppO2,mpr			; get ppO2 [cbar] into hi:lo
-	call	TFT_color_code_ppo2			; color-code the output
-	btfss	better_dil_available		; better diluent available?
-	bra		TFT_active_diluent_show		; NO  - print in normal rendering
-	btg		better_dil_blinking			; YES - toggle blink bit...
-	btfss	better_dil_blinking			; blink now?
-	bra		TFT_active_diluent_show		; NO  - print in normal rendering
-	call	TFT_attention_color			; YES - print in yellow color
-	bsf		win_invert					;     - print in inverse
-TFT_active_diluent_show:
-	WIN_SMALL dm_active_dil_column, dm_active_dil_row
-	bra		TFT_active_dil_gas_common	; continue with common part
- ENDIF	; _ccr_pscr
-
-TFT_active_gas:
-	MOVII	int_O_breathed_ppO2,mpr		; copy ppO2 [cbar] into hi:lo
-	call	TFT_color_code_ppo2			; color-code the output
-	btfss	better_gas_available		; better gas available?
-	bra		TFT_active_gas_print		; NO  - print in normal rendering
-	btg		better_gas_blinking			; YES - toggle blink bit
-	btfss	better_gas_blinking			;       blink now?
-	bra		TFT_active_gas_print		;       NO  - print in normal rendering
-	call	TFT_attention_color			;       YES - blink in yellow
-	bsf		win_invert					;             print in inverse
-TFT_active_gas_print:
-	WIN_STD	dm_active_gas_sp_value_col, dm_active_sp_label_row
-TFT_active_dil_gas_common:
-	movff	char_I_O2_ratio,lo			; lo now stores O2 in %
- IFDEF _helium
-	movff	char_I_He_ratio,hi			; hi now stores He in %
- ELSE
-	clrf	hi							; set hi to zero (no He)
- ENDIF
-	call	gaslist_show_mix			; print "Nxlo", "Txlo/hi", "Air" or "O2"
-	STRCAT_PRINT ""						; finalize output
-	bcf		win_invert					; end inverse printing
-	goto	TFT_standard_color			; done
-
-;=============================================================================
-
-	global	TFT_decotype_surface
-TFT_decotype_surface:
-	WIN_STD	surf_decotype_column,surf_decotype_row
-	WIN_COLOR color_lightblue
-	movff	opt_dive_mode,lo				; 0=OC, 1=CCR, 2=Gauge, 3=Apnoe, 4=pSCR
-	tstfsz	lo								; in OC mode?
-	bra		TFT_decotype_surface_2			; NO
-TFT_decotype_surface_1:
-	STRCAT_TEXT_PRINT tDvOC					; OC
-	bra		TFT_display_decotype_exit
-TFT_decotype_surface_2:
-	decfsz	lo,F							; in CCR mode?
-	bra		TFT_decotype_surface_3			; NO
- IFDEF _ccr_pscr
-	STRCAT_TEXT_PRINT tDvCC					; YES
-	call	TFT_standard_color
-	WIN_TINY surf_decotype_column+.18,surf_decotype_row+.12
-	TSTOSS	opt_ccr_mode					; > 0, i.e. not Fixed SP ?
-	bra		TFT_display_decotype_cc_fixed	; NO - fixed then
- IFDEF _external_sensor
-	; Sensor or Auto SP mode
-	movff	opt_ccr_mode,WREG				; =0: Fixed SP, =1: Sensor, =2: Auto SP
-	sublw	.2								; mode = Auto SP ?
-	bz		TFT_display_decotype_cc_auto	; YES 
-	STRCPY_TEXT tCCRModeSensor				; NO  - Sensor
-	bra		TFT_display_decotype_cc_common	;
- ENDIF	; _external_sensor
-TFT_display_decotype_cc_auto:
-	STRCPY_TEXT tCCRModeAutoSP				; Auto SP
-	bra		TFT_display_decotype_cc_common
-TFT_display_decotype_cc_fixed:
-	STRCPY_TEXT tCCRModeFixedSP				; fixed SP
-TFT_display_decotype_cc_common:
-	clrf	WREG
-	movff	WREG,buffer+.8					; limit string length to 8
-	STRCAT_PRINT ""
-	bra		TFT_display_decotype_exit
- ENDIF	; _ccr_pscr
-TFT_decotype_surface_3:
-	decfsz	lo,F							; in gauge mode?
-	bra		TFT_decotype_surface_4			; NO
-TFT_decotype_surface_3_1:					; YES
-	STRCAT_TEXT_PRINT tDvGauge
-	bra		TFT_display_decotype_exit
-TFT_decotype_surface_4:
-	decfsz	lo,F							; in apnea mode?
-	bra		TFT_decotype_surface_5			; NO
-TFT_decotype_surface_4_1:					; YES
-	STRCAT_TEXT_PRINT tDvApnea
-	bra		TFT_display_decotype_exit
-TFT_decotype_surface_5:
-	STRCAT_TEXT_PRINT tDvPSCR				; last but not least: must be pSCR then
-TFT_display_decotype_exit:
-	goto	TFT_standard_color				; and return...
-
-
-	global	TFT_decotype_logbook
-TFT_decotype_logbook:						; used from logbook and from deco calculator (simulator.asm)
-	bsf		aux_flag						; default to dive with deco calculation
-	tstfsz	lo								; lo holds 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR, in OC mode?
-	bra		TFT_decotype_logbook_1_2		; NO
-	bra		TFT_decotype_surface_1			; YES - OC
-TFT_decotype_logbook_1_2:
-	decfsz	lo,F							; in CCR mode?
-	bra		TFT_decotype_logbook_1_3		; NO
-	STRCAT_TEXT_PRINT tDvCC					; YES - print "CCR"
-	bra		TFT_display_decotype_exit		;     - done
-TFT_decotype_logbook_1_3:
-	decfsz	lo,F							; in gauge mode?
-	bra		TFT_decotype_logbook_1_4		; NO
-	bcf		aux_flag						; YES - dive without deco data
-	bra		TFT_decotype_surface_3_1		;     - gauge
-TFT_decotype_logbook_1_4:
-	decfsz	lo,F							; in apnea mode?
-	bra		TFT_decotype_logbook_1_5		; NO
-	bcf		aux_flag						; YES - dive without deco data
-	bra		TFT_decotype_surface_4_1		;     - apnea
-TFT_decotype_logbook_1_5:
-	bra		TFT_decotype_surface_5			; last but not least: must be pSCR then
-
-;=============================================================================
-
- IFDEF _ccr_pscr
-
-	global	TFT_splist_surfmode			; show setpoint list
-TFT_splist_surfmode:
-	bsf		short_gas_descriptions		; use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
-	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
-	;SP 1
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row
-	clrf	PRODL
-	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
-	STRCAT_PRINT ""
-	;SP 2
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
-	movlw	.1
-	movwf	PRODL
-	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
-	STRCAT_PRINT ""
-	;SP 3
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
-	movlw	.2
-	movwf	PRODL
-	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
-	STRCAT_PRINT ""
-	;SP 4
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)
-	movlw	.3
-	movwf	PRODL
-	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
-	STRCAT_PRINT ""
-	;SP 5
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
-	movlw	.4
-	movwf	PRODL
-	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
-	STRCAT_PRINT ""
-	bcf		leftbind
-	return
-
- ENDIF
-
-;=============================================================================
-
-	global	TFT_gaslist_surfmode
-TFT_gaslist_surfmode:					; displays gas list
-	bsf		short_gas_descriptions		; use short versions of gaslist_strcat_gas_cd and gaslist_strcat_setpoint
-	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
-	;Gas 1
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row
-	clrf	PRODL
-	call	gaslist_strcat_gas_cd		; append gas description of gas #PRODL (0-4) to current string
-	STRCAT_PRINT ""
-	;Gas 2
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
-	movlw	.1
-	movwf	PRODL
-	call	gaslist_strcat_gas_cd		; append gas description of gas #PRODL (0-4) to current string
-	STRCAT_PRINT ""
-	;Gas 3
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
-	movlw	.2
-	movwf	PRODL
-	call	gaslist_strcat_gas_cd		; append gas description of gas #PRODL (0-4) to current string
-	STRCAT_PRINT ""
-	;Gas 4
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)
-	movlw	.3
-	movwf	PRODL
-	call	gaslist_strcat_gas_cd		; append gas description of gas #PRODL (0-4) to current string
-	STRCAT_PRINT ""
-	;Gas 5
-	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
-	movlw	.4
-	movwf	PRODL
-	call	gaslist_strcat_gas_cd		; append gas description of gas #PRODL (0-4) to current string
-	STRCAT_PRINT ""
-	bcf		leftbind
-	bcf		win_invert					; clear flag for inverted output
-	return
-
+tft_out6	CODE
 ;=============================================================================
 
- IFDEF _ccr_pscr
-
-	global	TFT_dillist_surfmode
-TFT_dillist_surfmode:					; displays diluent list
-	bsf		is_diluent_menu				; enable using diluents
-	rcall	TFT_gaslist_surfmode		; use OC gas routine
-	bcf		is_diluent_menu				; disable using diluents
-	return
-
- ENDIF
-
-;==================================================================
-
-	global	TFT_show_depth
-TFT_show_depth:
-	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
-
-	TSTOSS	opt_units					; 0=m, 1=ft ?
-	bra		TFT_depth_metric			; 0 - metric
-	;bra	TFT_depth_imperial			; 1 - imperial
-
-TFT_depth_imperial:
-	MOVLI	.30,sub_a					; display 0 ft if shallower than 30 cm
-	MOVII	mpr,sub_b
-	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_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
-	bra		TFT_depth_imperial_1		; continue with common part
-
-TFT_depth_metric:
-	; full meters
-	MOVLI	.9999,sub_a					; 9999 mbar = 99.99 m
-	MOVII	mpr,  sub_b					; current depth
-	call	cmpU16						; compare (sub_a - sub_b)
-	btfsc	neg_flag					; current depth < 100 meter ?
-	bra		TFT_depth_metric_100m		; NO  - current depth >= 100 meter
-
-	btfsc	cur_depth_greater_100m		; was the current depth >= 100 meter during last call?
-	rcall	TFT_depth_box_black			; YES - clear depth area
-	bcf		cur_depth_greater_100m		; current depth is now < 100 meter
-
-	MOVLI	.999,sub_a					; 999 mbar = 9.99 meter
-	MOVII	mpr, sub_b					; current depth
-	call	cmpU16						; compare (sub_a - sub_b)
-	movlw	' '							; load coding of a space char
-	btfss	neg_flag					; current depth < 10 meter ?
-	movwf	POSTINC2					; YES - print a leading space char
-
-	MOVLI	.99,sub_a					; 99 mbar = 99 cm
-	MOVII	mpr,sub_b					; current depth
-	call	cmpU16						; compare (sub_a - sub_b)
-	btfss	neg_flag					; current depth < 1 meter ?
-	bra		TFT_depth_metric_0m			; YES - (1)
-	bsf		ignore_digit4				; NO  - show depth in full meters, i.e. ignore digits 4 and 5
-	bsf		leftbind					;     - print left-aligned
-	output_16							;     - print depth
-	bcf		leftbind					;     - reset alignment
-	bra		TFT_depth_metric_com		;     - continue with common part
-TFT_depth_metric_0m:
-	STRCAT	"0"							; (1) - print a zero directly
-TFT_depth_metric_com:
-	STRCAT_PRINT ""						; finalize output
-
-	; decimeters
-	rcall	TFT_depth_position_dm		; set output position
-	PUTC	"."							; print a decimal point
-	MOVLI	.30,sub_a					; 30 mbar = 0.3 meter
-	MOVII	mpr,sub_b					; current depth
-	call	cmpU16						; compare (sub_a - sub_b)
-	btfss	neg_flag					; current depth < 0.3 meter ?
-	bra		depth_0_decimeter			; YES - (2)
-	movlw	d'4'						; NO  - omit leading digits holding the meters
-	movwf	ignore_digits				;     - ...
-	bsf		ignore_digit5				;     - omit last digit holding the centimeters
-	output_16dp d'0'					;     - print decimeters only
-	STRCAT_PRINT ""						;     - finalize output
-	bcf		win_invert					;     - reset invert flag
-	bra		TFT_depth_exit				;     - show target depth if in simulator mode and return
-depth_0_decimeter:
-	STRCAT_PRINT "0"					; (2) - print a zero directly and finalize output
-	bcf		win_invert					;     - reset invert flag
-	bra		TFT_depth_exit				;     - show target depth if in simulator mode and return
-
-TFT_depth_metric_100m:					; show full meters only
-	btfss	cur_depth_greater_100m		; was the current depth >= 100 meter during last call?
-	rcall	TFT_depth_box_black			; NO - clear depth area
-	bsf		cur_depth_greater_100m		; depth is >= 100 meter now
-	bsf		ignore_digit4				; show depth in full meters, i.e. ignore digits 4 and 5
-	bsf		leftbind					; print left-aligned
-	output_16							; print depth
-	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
-
-TFT_depth_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
-	btfsc	depth_warning				; NO  - do we have a depth warning now?
-	bra		TFT_depth_blink_new			;       YES - so we have a warning now but not previously
-	btfsc	depth_attention				;       NO  - do we have a depth attention now?
-	bra		TFT_depth_blink_new			;             YES - so we have attention now but not previously
-	bra		TFT_depth_blink_none		;             NO  - no warning in previous cycle, no warning now, reset all flags
-
-TFT_depth_blink_prev:
-	; we had a warning or attention in previous cycle, check if we still have a warning or attention
-	btfsc	depth_warning				; do we still have a warning?
-	bra		TFT_depth_blink_prev_1		; YES
-	btfsc	depth_attention				; NO  - do we still have an attention?
-	bra		TFT_depth_blink_prev_1		;       YES
-	; we had a warning or attention before, but not now any more - clear depth area from previous color
-	rcall	TFT_depth_box_black			;       NO  - clear depth area
-	;bra	TFT_depth_blink_none		;           - reset all flags
-
-TFT_depth_blink_none:
-	bcf		win_invert					; print non-inverted
-	bcf		depth_inverse_last			; memorize depth was printed in normal
-	bcf		depth_warn_att_last			; memorize there was no warning or attention
-	goto	TFT_memo_color				; select memo color and return
-
-TFT_depth_blink_prev_1:
-	; we had a warning or attention in previous cycle, and we still have a warning or attention
-	btfss	depth_inverse_last			; was the depth printed in inverse last time?
-	bra		TFT_depth_blink_set			; NO  - print in inverse now
-	bra		TFT_depth_blink_reset		; YES - print in normal  now
-
-TFT_depth_blink_new:
-	; we had no warning or attention in previous cycle, but now
-	bsf		depth_warn_att_last			; memorize that the depth had a warning or attention
-	;bra	TFT_depth_blink_set			; start with inverse display
-
-TFT_depth_blink_set:
-	; fill the area with respective color
-	call	TFT_attention_color_dive	; select attention color as default
-	btfsc	depth_warning				; do we have a warning?
-	call	TFT_warnings_color_dive		; YES - replace with warning color
-	rcall	TFT_depth_box_color			; color depth area
-	bsf		win_invert					; print in inverse
-	bsf		depth_inverse_last			; memorize depth was printed in inverse
-	return								; done
-
-TFT_depth_blink_reset:
-	; fill the area with black color
-	rcall	TFT_depth_box_black			; clear depth area
-	bcf		win_invert					; print non-inverted
-	bcf		depth_inverse_last			; memorize depth was printed in normal
-	return								; done
-
-
-TFT_depth_position_m_ft:
-	btfsc	alt_layout_active									; alternative layout active?
-	bra		TFT_depth_position_m_ft_alt							; YES - (1)
-	WIN_LARGE dm_depth_col_large,dm_depth_row_large				; NO  - normal layout
-	return														;     - done
-TFT_depth_position_m_ft_alt:
-	WIN_HUGE dm_depth_col_huge, dm_depth_row_huge				; (1) - alternative layout
-	return														;     - done
-
-TFT_depth_position_dm:
-	btfsc	alt_layout_active									; alternative layout active?
-	bra		TFT_depth_position_dm_alt							; YES - (1)
-	WIN_MEDIUM dm_depth_dm_col_medium, dm_depth_dm_row_medium	; NO  - normal layout
-	return														;     - done
-TFT_depth_position_dm_alt:
-	WIN_LARGE  dm_depth_dm_col_large,  dm_depth_dm_row_large	; (1) - alternative layout
-	return														;     - done
-
-TFT_depth_box_black:
-	clrf	WREG																				; select black color
-TFT_depth_box_color:
-	movff	win_color1,mpr+2																	; backup output color
-	movff	win_color2,mpr+3																	; ...
-	btfsc	alt_layout_active																	; alternative layout active?
-	bra		TFT_depth_box_alt																	; YES - (1)
-	WIN_BOX_COLOR dm_depth_row_large,dm_depth_bot_large,dm_depth_col_large,dm_depth_rgt_large	; NO  - top, bottom, left, right
-	bra		TFT_depth_box_exit																	;     - continue with common part
-TFT_depth_box_alt:
-	WIN_BOX_COLOR dm_mask_depth_row, dm_depth_bot_huge, dm_depth_col_huge, dm_depth_rgt_huge	; (1) - full meters area
-TFT_depth_box_exit:
-	movff	mpr+2,win_color1																	; restore output color
-	movff	mpr+3,win_color2																	; ...
-	return																						; done
-
-TFT_depth_exit:
-	btfss	alt_layout_active									; alternative layout active?
-	bra		TFT_depth_exit_1									; NO
-	btfsc	depth_inverse_last									; YES - was last output in inverse mode?
-	bra		TFT_depth_exit_1									;       YES
-	call	TFT_divemask_color									;       NO  - set color
-	WIN_TINY dm_mask_depth_column_alt,dm_mask_depth_row			;           - set position
-	STRCAT_TEXT_PRINT tDepth									;           - restore "Depth" title
-TFT_depth_exit_1:
-	btfss	sensor_override_active								; pressure sensor override active (simulator mode)?
-	goto	TFT_standard_color									; NO  - done
-	;bra	TFT_depth_target									; YES - show target depth
-
-TFT_depth_target:												; show simulated target depth
-	call	TFT_attention_color									; select attention color
-	TSTOSS	opt_units											; check unit selection (0=m or 1=ft)
-	bra		TFT_depth_target_metric								; 0 - metric
-	;bra	TFT_depth_target_imperial							; 1 - imperial
-
-TFT_depth_target_imperial:
-	btfsc	alt_layout_active									; alternative layout active?
-	bra		TFT_depth_target_imperial_alt						; YES
-	;bra	TFT_depth_target_imperial_norm						; NO
-
-TFT_depth_target_imperial_norm:
-	WIN_TINY dm_mask_depth_column+.40,dm_mask_depth_row			; position right of depth label
-	bra		TFT_depth_target_imperial_com						; continue with common part
-
-TFT_depth_target_imperial_alt:
-	WIN_TINY dm_mask_depth_column+.62,dm_mask_depth_row+.20		; position within last digit
-	;bra	TFT_depth_target_imperial_com						; continue with common part
-
-TFT_depth_target_imperial_com:
-	movff	simulatormode_depth,lo								; copy target depth to lo
-	call	convert_meter_to_feet								; convert value in lo from meters to feet
-	output_16_3													; display only last three digits from a 16 bit value (0-999)
-	STRCAT_PRINT "ft"											; finalize output
-	goto	TFT_standard_color									; done
-
-TFT_depth_target_metric:
-	btfsc	alt_layout_active									; alternative layout active?
-	bra		TFT_depth_target_metric_alt							; YES
-	;bra	TFT_depth_target_metric_norm						; NO
-
-TFT_depth_target_metric_norm:
-	WIN_TINY dm_mask_depth_column+.38,dm_mask_depth_row+.22		; position right of full meters, above decimal
-	bra		TFT_depth_target_metric_com							; continue with common part
-
-TFT_depth_target_metric_alt:
-	WIN_TINY dm_mask_depth_column+.65,dm_mask_depth_row+.20		; position right of full meters, above decimal
-	;bra	TFT_depth_target_metric_com							; continue with common part
-
-TFT_depth_target_metric_com:
-	movff	simulatormode_depth,lo								; copy target depth to lo
-	output_8													; display number
-	STRCAT_PRINT "m"											; finalize output
-	goto	TFT_standard_color									; done
-
-;=============================================================================
-
-	global	TFT_custom_text
-TFT_custom_text:					; show the custom text
-	lfsr	FSR0, opt_name			; source
-	WIN_SMALL surf_customtext_column,surf_customtext_row1 ; 1st row
-	rcall	TFT_custom_text_2		; show up to 12 chars and print
-	incfsz	lo,F					; was lo=255?
-	return							; NO - all done
-	lfsr	FSR0, opt_name+.12		; source
-	WIN_SMALL surf_customtext_column,surf_customtext_row2 ; 2nd row
-	rcall	TFT_custom_text_2		; show up to 12 chars and print
-	incfsz	lo,F					; was lo=255?
-	return							; NO - all done
-	lfsr	FSR0, opt_name+.24		; source
-	WIN_SMALL surf_customtext_column,surf_customtext_row3 ; 3rd row
-	rcall	TFT_custom_text_2		; show up to 12 chars and print
-	incfsz	lo,F					; was lo=255?
-	return							; NO - all done
-	lfsr	FSR0, opt_name+.36		; source
-	WIN_SMALL surf_customtext_column,surf_customtext_row4 ; 4th row
-	rcall	TFT_custom_text_2		; show up to 12 chars and print
-	incfsz	lo,F					; was lo=255?
-	return							; NO - all done
-	lfsr	FSR0, opt_name+.48		; source
-	WIN_SMALL surf_customtext_column,surf_customtext_row5 ; 5th row
-	;bra	TFT_custom_text_2		; show up to 12 chars, print and return...
-
-TFT_custom_text_2:
-	lfsr	FSR2, buffer			; destination
-	movlw	.12
-	movwf	lo						; length/line
-TFT_custom_text_3:
-	movf	POSTINC0,W				; get byte
-	bz		TFT_custom_text_4		; end if NULL
-	movwf	POSTINC2				; NO - copy
-	decfsz	lo,F					; max length reached ?
-	bra		TFT_custom_text_3		; NO - loop
-	setf	lo						; lo=255 -> more to come
-TFT_custom_text_4:
-	clrf	POSTINC2				; mark end of string
-	goto	aa_wordprocessor		; print and return
-
-
-;=============================================================================
-
-	global	TFT_pres_surfmode
-TFT_pres_surfmode:
-	WIN_SMALL surf_press_column+.8,surf_press_row
-	call	TFT_standard_color
-	SMOVII	pressure_abs,    sub_a				; make ISR-safe 2 byte copy of current absolute pressure to sub_a
-	MOVII	pressure_abs_ref,sub_b				; copy absolute pressure from 30 minutes ago to sub_b
-	MOVII	sub_a,mpr							; store current pressure also in hi:lo for output
-	call	subU16								; sub_c = sub_a - sub_b
-	btfsc	neg_flag							; pressure lower?
-	rcall	update_surf_press2					; YES - swap arguments
-	tstfsz	sub_c+1								; > 255 mbar difference?
-	bra		update_surf_press_common			; YES -  display
-	movlw	.11									; 10 mbar noise suppression margin
-	subwf	sub_c+0,W
-	btfsc	STATUS,C
-	bra		update_surf_press_common			; YES - display
-	MOVII	pressure_abs_ref,mpr				; NO  - overwrite with stable value
-update_surf_press_common:
-	output_16
-	; Show only 4 digits
-	movff	buffer+1,buffer+0
-	movff	buffer+2,buffer+1
-	movff	buffer+3,buffer+2
-	movff	buffer+4,buffer+3
-	movlw	0x00
-	movff	WREG,buffer+4
-	STRCAT_PRINT ""
-	call	TFT_divemask_color
-	WIN_SMALL	surf_press_column+(4+1)*8,surf_press_row
-	STRCPY_TEXT_PRINT tMBAR						; mbar (hPa)
-	return
-
-update_surf_press2:
-	MOVII	sub_a,sub_b
-	MOVII	pressure_abs_ref,sub_a
-	goto	subU16								; sub_c = sub_a - sub_b and return...
-
-;=============================================================================
-
-	global	TFT_batt_surfmode
-TFT_batt_surfmode:
-	; color-code according to battery percent
-	movff	batt_percent,lo
-	clrf	hi
-	call	TFT_color_code_battery
-
-	; set up charging indicator and temperature warning
-	clrf	WREG					; default to no indication/warning
-	btfsc	cc_active				; charging in CC mode?
-	movlw	color_yellow			; YES - set output color to yellow
-	btfsc	cv_active				; charging in CV mode?
-	movlw	color_green				; YES - set output color to green
-	btfsc	battery_overtemp		; battery over-temperature detector tripped?
-	movlw	color_red				; YES - set output color to red
-	tstfsz	WREG					; any indicator or warning active?
-	bsf		win_invert				; YES - set output to inverse
-	tstfsz	WREG					; any indicator or warning active (asked again)?
-	call	TFT_set_color			; YES - set color
-
-	WIN_SMALL batt_percent_column+.2,batt_percent_row
-	output_16_3						; display only last three digits from a 16 bit value (0-999)
-	STRCAT_PRINT "% "
-	bcf		win_invert
-	call	TFT_standard_color
-	WIN_TINY batt_voltage_column+.15,batt_voltage_row
-	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
-	PUTC	"T"
-	bsf		leftbind
-	output_8
-	PUTC	":"
-	MOVII	batt_voltage,mpr
-	output_16dp .2					; print as -x.yyy
-	bcf		leftbind
-	PUTC	'V'
-	movff	buffer+8,buffer+6
-	movlw	0x00
-	movff	WREG,buffer+7			; only "x.yV"
-	STRCAT_PRINT ""
-	return
-
-;update_battery_debug:
-;	call	TFT_standard_color
-;	WIN_TINY .70,.0
-;	movff	battery_gauge+5,xC+3
-;	movff	battery_gauge+4,xC+2
-;	movff	battery_gauge+3,xC+1
-;	movff	battery_gauge+2,xC+0
-;	; battery_gauge:6 is nAs
-;	; devide through 65536
-;	; devide through 152
-;	; Result is 0.01Ah in xC+1:xC+0
-;	MOVLI	.152,xB
-;	call	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder
-;	bsf		leftbind
-;	MOVII	xC,mpr
-;	output_16
-;	STRCAT_PRINT "x.01Ah"
-;	bcf		leftbind
-;	return
-
-;=============================================================================
-
-	global	TFT_convert_signed_16bit
-TFT_convert_signed_16bit:
-	bcf		neg_flag				; clear flag for negative number by default
-	btfss	hi,7					; negative number?
-	return							; NO  - done
-									; YES
-	bsf		neg_flag				; set flag for negative number
-	PUTC	'-'						; display a minus sign ("-")
-	comf	hi						; complement hi:lo
-	negf	lo
-	btfsc	STATUS,C
-	incf	hi
-	return							; done
-
-;=============================================================================
-; input: lo  year
-;        hi  month
-;        up  day
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show Dive Time
 ;
-; 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 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				; 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				; 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" 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
-
-;=============================================================================
-
-	global	TFT_date_surfmode
-TFT_date_surfmode:
-	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_year, lo
-	movff	rtc_latched_month,hi
-	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
-
-;=============================================================================
-
-	global	TFT_show_max_depth
-TFT_show_max_depth:
-	btfsc	alt_layout_active			; alternative layout active?
-	bra		TFT_show_max_depth_alt		; YES
-
-	WIN_MEDIUM dm_max_depth_column_nvsi, dm_max_depth_row
-	TSTOSS	opt_vsigraph				; graphical VSI bar enabled?
-	bra		TFT_show_max_depth_1		; NO  - keep position
-										; YES - adopt output position
-	WIN_MEDIUM dm_max_depth_column, dm_max_depth_row
-
-TFT_show_max_depth_1:
-	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bra		TFT_max_depth_apnoe			; YES - different handling in apnoe mode
-
-	TSTOSS	opt_2ndDepthDisp			; show average depth instead of max depth?
-	bra		TFT_max_depth_current		; NO  - show max depth
-	;bra	TFT_avg_depth_current		; YES - show avg depth
-
-TFT_avg_depth_current:
-	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 - 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 pressure
-	;bra	TFT_max_depth_common		; continue with common part
-
-TFT_max_depth_common:
-	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_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
-
-TFT_max_depth_metric:
-	MOVLI	.9999,sub_a					; 9999 mbar = 99.99 m
-	MOVII	mpr,  sub_b					; depth, also used to back-up hi:lo
-	call	cmpU16						; sub_a - sub_b = 99.99 - depth
-	btfsc	neg_flag					; depth < 100 meter ?
-	bra		TFT_max_depth_greater_100m	; NO  - greater   than 100 m
-	;bra	TFT_max_depth_shallower_100m; YES - shallower than 100 m
-
-TFT_max_depth_shallower_100m:
-	btfss	max_depth_greater_100m		; was depth >= 100 m during last call?
-	bra		TFT_max_depth_metric_show	; NO  - show depth
-	bcf		max_depth_greater_100m		; YES - clear flag, last depth shown now not > 99.84 m anymore
-	bra		TFT_max_depth_clear			;     - clear depth area
-
-TFT_max_depth_greater_100m:
-	btfsc	max_depth_greater_100m		; was depth >= 100 m during last call?
-	bra		TFT_max_depth_metric_show	; YES - show depth
-	bsf		max_depth_greater_100m		; NO  - set flag, last depth shown now > 99.84 m
-	;bra	TFT_max_depth_clear			;     - clear depth area
-
-TFT_max_depth_clear:
-	WIN_BOX_BLACK dm_max_depth_row, dm_max_depth_bot, dm_max_depth_column, dm_max_depth_rgt	; top, bottom, left, right
-	;bra	TFT_max_depth_metric_show
-
-TFT_max_depth_metric_show:
-	call	TFT_memo_color				; set output color
-	btfss	max_depth_greater_100m		; depth to show >= 100 m ?
-	bra		TFT_max_depth_metric_m_dm	; NO  - show meters and decimeters
-	bsf		ignore_digit4				; YES - crop decimeters and centimeters
-	bsf		leftbind					;     - print left-aligned
-	output_16							;     - print depth
-	bra		TFT_max_depth_finish		;     - finish output
-
-TFT_max_depth_metric_m_dm:
-	MOVLI	.999,sub_a					; load 9.99 meter
-	call	cmpU16						; sub_a - sub_b = 9.99 - depth
-	movlw	' '							; load a space character
-	btfss	neg_flag					; depth shallower than 10 meter ?
-	movwf	POSTINC2					; YES - add the space character
-	MOVLI	.99,sub_a					; load 0.99 m
-	call	cmpU16						; sub_a - sub_b = 0.99 m - depth
-	btfss	neg_flag					; depth shallower than  1 meter ?
-	bra		TFT_max_depth_metric_zero	; YES - manually display a zero
-	bsf		ignore_digit4				; NO  - crop decimeters and centimeters
-	bsf		leftbind					;     - align left
-	output_16							;     - display full meters
-	STRCAT_PRINT ""						;     - finalize output
-	bra		TFT_max_depth_metric_dm		;     - continue with decimeters
-
-TFT_max_depth_metric_zero:
-	STRCAT_PRINT "0"					; print a zero
-	;bra	TFT_max_depth_metric_dm		; continue with decimeters
-
-TFT_max_depth_metric_dm:
-	WIN_SMALL dm_max_depth_dm_column_nvsi, dm_max_depth_dm_row
-	TSTOSS	opt_vsigraph				; graphical VSI bar enabled?
-	bra		TFT_max_depth_metric_dm_1	; NO  - keep position
-										; YES - adopt position
-	WIN_SMALL dm_max_depth_dm_column, dm_max_depth_dm_row
-TFT_max_depth_metric_dm_1:
-	PUTC	"."							; print decimal point
-	MOVII	sub_b,mpr					; restore depth in hi:lo
-	movlw	d'4'						; crop leading 4 digits (don't show the full meters)
-	movwf	ignore_digits				; ...
-	bsf		ignore_digit5				; crop last digit (no centimeters, flag will be cleared by output_16)
-	bsf		leftbind					; print left-aligned
-	output_16dp d'0'					; print decimal
-TFT_max_depth_finish:
-	STRCAT_PRINT ""						; finalize output
-	bcf		leftbind					; back to default right alignment
-	goto	TFT_standard_color			; done
-
-
-TFT_show_max_depth_alt:
-	btfsc	FLAG_apnoe_mode				; in apnoe mode?
-	bra		TFT_show_apnoe_max_depth	; YES - use apnoe surface output also in alternative dive mode screen
-	btfsc	FLAG_gauge_mode				; NO  - in gauge mode?
-	bra		TFT_show_gauge_max_avg_depth;       YES - show both, max and avg depth
-	return								;       NO  - nothing to do
-
-TFT_show_gauge_max_avg_depth:
-	call	TFT_memo_color										; set color
-	WIN_MEDIUM dm_gauge_max_depth_col, dm_gauge_max_depth_row	; set position for max depth
-	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 pressure into hi:lo
-	bra		TFT_show_gauge_depth								; show avg depth and return
-
-
-	global	TFT_show_apnoe_max_depth
-TFT_show_apnoe_max_depth:
-	; title
-	WIN_TINY dm_apnoe_last_max_depth_text_col, dm_apnoe_last_max_depth_text_row
-	call	TFT_divemask_color
-	btfsc	alt_layout_active				; alternative layout active?
-	bra		TFT_show_apnoe_max_depth_alt	; YES
-	STRCPY_TEXT_PRINT tApnoeMax				; NO  - print "Last Descent"
-	bra		TFT_show_apnoe_max_depth_com	;     - continue with common part
-TFT_show_apnoe_max_depth_alt:
-	STRCPY_TEXT_PRINT tMaxDepth				; print "Max.Depth"
-TFT_show_apnoe_max_depth_com:
-	; value
-	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 pressure into hi:lo
-	;bra	TFT_show_gauge_depth			; show max depth and return
-
-TFT_show_gauge_depth:
-	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_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:
-	bsf		ignore_digit5					; do not display centimeters (flag will be cleared by output_16)
-	output_16dp d'3'
-	bra		TFT_max_depth_finish			; finish output
-
-;=============================================================================
-
 	global	TFT_show_divetime
 TFT_show_divetime:
-	call	TFT_memo_color					; set color
+	FONT_COLOR_MEMO							; set color
 	SMOVTT	counted_divetime_mins,mpr		; ISR-safe 3 byte copy of minutes:2 (mpr+1:mpr+0) and seconds (mpr+2)
 	btfsc	show_only_divemins				; shall suppress display of seconds?
 	bra		TFT_show_divetime_min_only		; YES - show minutes only
@@ -3435,8 +1490,8 @@
 	;bra	TFT_show_divetime_min_com		; continue with common part
 
 TFT_show_divetime_min_com:
-	output_99								; displays only last two digits from a 8 bit value (0-99)
-	STRCAT_PRINT ""							; finalize output
+	output_99								; print minutes (0-99)
+	PRINT									; dump buffer to screen
 
 	; show the seconds
 	btfsc	alt_layout_active				; in alternative layout?
@@ -3453,10 +1508,8 @@
 
 TFT_show_divetime_sec_com:
 	PUTC	':'								; print separator char
-	movff	mpr+2,lo						; copy seconds to lo
-	bsf		leftbind						; activate left-alignment
-	output_99x								; displays only last two figures from a 8 bit value with leading zero (00-99) 
-	bcf		leftbind						; deactivate left-alignment
+	movff	mpr+2,lo						; copy  seconds to lo
+	output_99x								; print seconds (00-99)
 	bra		TFT_divemins_exit				; continue with common part
 
 TFT_show_divetime_min_only:
@@ -3466,924 +1519,1652 @@
 
 TFT_show_divetime_min_only_norm:
 	WIN_MEDIUM dm_divetime_minonly_col_medium, dm_divetime_row
-	output_16_4								; print minutes (4 digits)
+	output_9999								; print minutes (0-9999)
 	bra		TFT_divemins_exit				; continue with common part
 
 TFT_show_divetime_min_only_alt:
 	WIN_LARGE  dm_divetime_minonly_col_large,  dm_divetime_row
-	output_16_3								; print minutes (3 digits)
+	output_999								; print minutes (0-999)
 	;bra	TFT_divemins_exit				; continue with common part
 
 TFT_divemins_exit:
-	STRCAT_PRINT ""							; finalize output
-	goto	TFT_standard_color				; and return...
-
-;=============================================================================
-
-	global	TFT_show_apnoe_surface
-TFT_show_apnoe_surface:
-	call	TFT_divemask_color
-	WIN_TINY dm_apnoe_surface_time_text_col, dm_apnoe_surface_time_text_row
-	STRCPY_TEXT_PRINT tApnoeSurface
-	call	TFT_memo_color
-	WIN_MEDIUM dm_apnoe_surface_time_column, dm_apnoe_surface_time_row
-	SMOVII	apnoe_surface_mins,mpr			; ISR-safe copy of minutes to lo and seconds to hi
-	output_8
-	PUTC	':'
-	movff	hi,lo							; copy seconds to lo
-	output_99x
-	bra		TFT_display_apnoe_exit			; and return...
-
-
-	global	TFT_show_apnoe_times
-TFT_show_apnoe_times:						; descent dive time
-	; current dive time
-	call	TFT_memo_color
-	WIN_MEDIUM dm_divetime_apnoe_col, dm_divetime_apnoe_row
-	SMOVII	apnoe_dive_mins,mpr				; ISR-safe copy of minutes to lo and seconds to hi
-	output_99								; display 0-99
-	STRCAT_PRINT ""							; show minutes
-	WIN_SMALL	dm_divetime_apnoe_secs_col, dm_divetime_apnoe_secs_row ; left position for two sec figures
-	PUTC	':'
-	bsf		leftbind
-	movff	hi,lo							; copy seconds to lo
-	output_99x
-	STRCAT_PRINT ""							; show seconds
-	; overall dive time
-	WIN_MEDIUM dm_apnoe_total_divetime_col, dm_apnoe_total_divetime_row
-	SMOVTT	counted_divetime_mins,mpr		; ISR-safe 3 byte copy of minutes:2 and seconds
-	clrf	hi
-	bcf		leftbind
-	output_16_3								; displays only last three figures from a 16 bit value (0-999)
-	STRCAT_PRINT ""							; show minutes in large font
-	WIN_SMALL dm_apnoe_total_divetime_secs_col, dm_apnoe_total_divetime_secs_row ; left position for two sec figures
-	PUTC	':'
-	bsf		leftbind
-	movff	up,lo							; copy minutes from up to lo
-	output_99x
-TFT_display_apnoe_exit:
-	STRCAT_PRINT ""
-	bcf		leftbind
-	goto	TFT_standard_color				; and return...
-
-
-	global	TFT_clear_apnoe_surface
-TFT_clear_apnoe_surface:
-	; clear surface data
-	WIN_BOX_BLACK dm_apnoe_last_max_depth_text_row, .239, dm_apnoe_last_max_depth_column, .159 ; top, bottom, left, right
-	goto	TFT_standard_color				; and return...
+	PRINT									; dump buffer to screen
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show current Depth
+;
+	global	TFT_show_depth
+TFT_show_depth:
+	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 for full meters/feet
+	TSTOSS	opt_units					; 0=m, 1=ft ?
+	bra		TFT_depth_metric			; 0 - metric
+	;bra	TFT_depth_imperial			; 1 - imperial
+
+TFT_depth_imperial:
+	MOVLI	.30,sub_a					; load depth threshold of 30 cm (for showing 0 if shallower)
+	MOVII	mpr,sub_b					; get current depth
+	call	cmpU16						; compute sub_a - sub_b = threshold - current depth
+	btfss	neg_flag					; shallower than 30 cm ?
+	bra		depth_0_feet				; YES - print a zero directly
+	call	convert_cm_to_feet			; NO  - convert value in hi:lo from [cm] to [feet]
+	output_999							;     - feet in large or huge font
+	PRINT								;     - dump to screen
+	bra		TFT_depth_exit				;     - do some cleanup and show target depth if in simulator mode
+
+depth_0_feet:
+	STRCAT_PRINT "  0"					; print a zero directly
+	bra		TFT_depth_exit				; do some cleanup and show target depth if in simulator mode
+
+TFT_depth_metric:
+	bsf		omit_digit_2				; print depth in full meters, i.e. do not print 2nd and 1st digit
+	output_9999							; test-print depth for range up to 99.9 meter (0xx-99xx)
+	btfsc	output_overflow				; did the printing clip, i.e. deeper than 99.9 meter?
+	bra		TFT_depth_metric_100m		; YES - print depth in full meters only
+
+	; depth in meters and decimeters
+	btfsc	cur_depth_greater_100m		; was the depth >= 100 meter during last call?
+	rcall	TFT_depth_box_black			; YES - clear depth area
+	bcf		cur_depth_greater_100m		; current depth is now < 100 meter
+	PRINT								; dump full meters to screen
+
+	btfsc	depth_inverse_last			; in inverse printing cycle?
+	bsf		win_invert					; YES - print inverse
+	rcall	TFT_depth_position_dm		; set output position for decimeters
+	MOVLI	.30,sub_a					; 30 mbar = 0.3 meter
+	MOVII	mpr,sub_b					; current depth
+	call	cmpU16						; compare (sub_a - sub_b)
+	btfss	neg_flag					; current depth < 0.3 meter ?
+	bra		depth_0_decimeter			; YES - print a zero
+	output_65535						; NO  - print full depth to buffer
+	REINIT_BUFFER						;     - re-initialize the output buffer
+	PUTC	"."							;     - print a decimal point
+	movff	buffer+3,POSTINC2			;     - get and print the decimeters
+	PRINT								;     - dump to screen
+	bra		TFT_depth_exit				;     - do some cleanup and show target depth if in simulator mode
+depth_0_decimeter:
+	STRCAT_PRINT ".0"					; print a zero directly and dump buffer to screen
+	bra		TFT_depth_exit				; do some cleanup and show target depth if in simulator mode
+
+TFT_depth_metric_100m:
+	; full meters only
+	btfss	cur_depth_greater_100m		; was the depth >= 100 meter during last call?
+	rcall	TFT_depth_box_black			; NO - clear depth area
+	bsf		cur_depth_greater_100m		; depth is >= 100 meter now
+	REINIT_BUFFER						; re-initialize the output buffer
+	bsf		omit_digit_2				; print depth in full meters, i.e. do not print 1st and 2nd digit
+	output_65535						; print depth for range >= 100 meter (0xx-655xx)
+	PRINT								; dump to screen
+	;bra	TFT_depth_exit				; do some cleanup and show target depth if in simulator mode
+
+TFT_depth_exit:
+	btfss	alt_layout_active			; alternative layout active?
+	bra		TFT_depth_exit_2			; NO
+	btfsc	depth_inverse_last			; YES - was last output in inverse mode?
+	bra		TFT_depth_exit_2			;       YES - do not restore "Depth" as it collides with depth number
+	btfsc	cur_depth_greater_100m		;       NO  - current depth >= 100 m?
+	bra		TFT_depth_exit_2			;             YES
+	;bra	TFT_depth_exit_1			;             NO
+
+TFT_depth_exit_1
+	WIN_TINY dm_mask_depth_column_alt,dm_mask_depth_row
+	FONT_COLOR_MASK						; set color
+	STRCAT_TEXT_PRINT tDepth			; restore "Depth" title
+
+TFT_depth_exit_2:
+	btfss	sensor_override_active		; pressure sensor override active (simulator mode)?
+	return								; NO  - done
+	bra		TFT_depth_target			; YES - show simulator target depth
+
+
+	; Helper Function - control animation (blinking)
+TFT_depth_blink:
+	TSTOSS	opt_depth_warn				; 0=standard, 1=blink
+	return								; standard, done
+	btfsc	depth_color_last			; was there a warning or attention on the depth in the previous cycle?
+	bra		TFT_depth_blink_prev		; YES
+	btfsc	depth_color_warning			; NO  - do we have a depth warning now?
+	bra		TFT_depth_blink_new			;       YES - so we have a warning now but not previously
+	btfsc	depth_color_attention		;       NO  - do we have a depth attention now?
+	bra		TFT_depth_blink_new			;             YES - so we have attention now but not previously
+	bra		TFT_depth_blink_none		;             NO  - no warning in previous cycle, no warning now, reset all flags
+
+TFT_depth_blink_prev:
+	; we had a warning or attention in previous cycle, check if we still have a warning or attention
+	btfsc	depth_color_warning			; do we still have a warning?
+	bra		TFT_depth_blink_prev_1		; YES
+	btfsc	depth_color_attention		; NO  - do we still have an attention?
+	bra		TFT_depth_blink_prev_1		;       YES
+	; we had a warning or attention before, but not now any more - clear depth area from previous color
+	rcall	TFT_depth_box_black			;       NO  - clear depth area
+	;bra	TFT_depth_blink_none		;           - reset all flags
+
+TFT_depth_blink_none:
+	bcf		depth_inverse_last			; memorize depth was printed in normal
+	bcf		depth_color_last			; memorize there was no warning or attention
+	FONT_COLOR_MEMO						; select memo color
+	return								; done
+
+TFT_depth_blink_prev_1:
+	; we had a warning or attention in previous cycle, and we still have a warning or attention
+	btfss	depth_inverse_last			; was the depth printed in inverse last time?
+	bra		TFT_depth_blink_set			; NO  - print in inverse now
+	bra		TFT_depth_blink_reset		; YES - print in normal  now
+
+TFT_depth_blink_new:
+	; we had no warning or attention in previous cycle, but now
+	bsf		depth_color_last			; memorize that the depth had a warning or attention
+	;bra	TFT_depth_blink_set			; start with inverse display
+
+TFT_depth_blink_set:
+	; fill the area with respective color
+	movf	pallet_color_attention,W	; select attention color as default
+	btfsc	depth_color_warning			; do we have a warning?
+	movf	pallet_color_warning,W		; YES - replace with warning color
+	rcall	TFT_depth_box_color			; color depth area with color in WREG
+	bsf		win_invert					; print in inverse
+	bsf		depth_inverse_last			; memorize depth was printed in inverse
+	return								; done
+
+TFT_depth_blink_reset:
+	; fill the area with black color
+	rcall	TFT_depth_box_black			; clear depth area
+	bcf		depth_inverse_last			; memorize depth was printed in normal
+	return								; done
+
+
+	; Helper Function - set output position for full meters/feet
+TFT_depth_position_m_ft:				; output position meters / feet
+	btfsc	alt_layout_active			; alternative layout active?
+	bra		TFT_depth_position_m_ft_alt	; YES
+	;bra	TFT_depth_position_m_ft_norm; NO
+
+TFT_depth_position_m_ft_norm:
+	WIN_LARGE dm_depth_col_large,dm_depth_row_large
+	return								; done
+
+TFT_depth_position_m_ft_alt:
+	WIN_HUGE dm_depth_col_huge, dm_depth_row_huge
+	return								; done
+
+
+	; Helper Function - set output position for decimeters
+TFT_depth_position_dm:					; output position decimeters
+	btfsc	alt_layout_active			; alternative layout active?
+	bra		TFT_depth_position_dm_alt	; YES
+	bra		TFT_depth_position_dm_norm	; NO
+
+TFT_depth_position_dm_norm:
+	WIN_MEDIUM dm_depth_dm_col_medium, dm_depth_dm_row_medium
+	return								; done
+TFT_depth_position_dm_alt:
+	WIN_LARGE  dm_depth_dm_col_large,  dm_depth_dm_row_large
+	return								; done
+
+
+	; Helper Function - clear depth area
+TFT_depth_box_black:
+	clrf	WREG						; select black color
+	;bra	TFT_depth_box_color			; continue with colored box
+
+
+	; Helper Function - color depth area with color in WREG
+TFT_depth_box_color:
+	btfsc	alt_layout_active			; alternative layout active?
+	bra		TFT_depth_box_alt			; YES
+	;bra	TFT_depth_box_norm			; NO
+
+TFT_depth_box_norm:
+	WIN_BOX_COLOR dm_depth_row_large,dm_depth_bot_large,dm_depth_col_large,dm_depth_rgt_large
+	return								; done
+
+TFT_depth_box_alt:
+	WIN_BOX_COLOR dm_mask_depth_row, dm_depth_bot_huge, dm_depth_col_huge, dm_depth_rgt_huge
+TFT_depth_box_exit:
+	return								; done
+
+
+	; Helper Function - show simulated target depth
+TFT_depth_target:
+	FONT_COLOR_ATTENTION					; select attention color
+	movff	simulatormode_depth,lo			; copy target depth to lo
+	TSTOSS	opt_units						; check unit selection (0=m or 1=ft)
+	bra		TFT_depth_target_metric			; 0 - metric
+	;bra	TFT_depth_target_imperial		; 1 - imperial
+
+TFT_depth_target_imperial:
+	btfsc	alt_layout_active				; alternative layout active?
+	bra		TFT_depth_target_imperial_alt	; YES
+	;bra	TFT_depth_target_imperial_norm	; NO
+
+TFT_depth_target_imperial_norm:
+	WIN_TINY dm_mask_depth_column+.40,dm_mask_depth_row		; position right of depth label
+	bra		TFT_depth_target_imperial_com					; continue with common part
+
+TFT_depth_target_imperial_alt:
+	WIN_TINY dm_mask_depth_column+.62,dm_mask_depth_row+.20	; position within last digit
+	;bra	TFT_depth_target_imperial_com					; continue with common part
+
+TFT_depth_target_imperial_com:
+	call	convert_meter_to_feet			; convert value in lo from meters to feet
+	output_999								; display only last three digits from a 16 bit value (0-999)
+	STRCAT_PRINT "ft"						; append unit and dump buffer to screen
+	return									; done
+
+TFT_depth_target_metric:
+	btfsc	alt_layout_active				; alternative layout active?
+	bra		TFT_depth_target_metric_alt		; YES
+	;bra	TFT_depth_target_metric_norm	; NO
+
+TFT_depth_target_metric_norm:
+	WIN_TINY dm_mask_depth_column+.38,dm_mask_depth_row+.22		; position right of full meters, above decimal
+	bra		TFT_depth_target_metric_com							; continue with common part
+
+TFT_depth_target_metric_alt:
+	WIN_TINY dm_mask_depth_column+.65,dm_mask_depth_row+.20		; position right of full meters, above decimal
+	;bra	TFT_depth_target_metric_com							; continue with common part
+
+TFT_depth_target_metric_com:
+	output_256								; display target depth (0-255)
+	PUTC_PRINT "m"							; append unit and dump to screen
+	return									; done
 
 
 ;-----------------------------------------------------------------------------
-; 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
-	movff	rtc_latched_day,lo		; get current day
-	movff	rtc_latched_month,hi	; get current month
-	movff	rtc_latched_year,up		; get current year
-	bsf		aux_flag				; set firmware as expired by default
-	movlw	firmware_expire_year	; start with checking year
-	cpfsgt	up						; current year > expiry year ?
-	bra		check_expiry_Y			; NO  - continue checks
-	return							; YES - expired
-check_expiry_Y:
-	cpfseq	up						; current year = expiry year ?
-	bra		check_expiry_ok			; NO  - must be < then, OK whatever month & day
-	movlw	firmware_expire_month	; YES - continue checking month
-	cpfsgt	hi						; current month > expiry month ?
-	bra		check_expiry_M			; NO  - continue checks
-	return							; YES - expired
-check_expiry_M:
-	cpfseq	hi						; current month = expiry month ?
-	bra		check_expiry_ok			; NO  - must be < then, OK whatever day
-	movlw	firmware_expire_day		; YES - continue checking day
-	cpfsgt	lo						; current day > expiry day ?
-	bra		check_expiry_ok			; NO  - must be <= then, OK
-	return							; YES - expired
-check_expiry_ok:
-	bcf		aux_flag
-	return
-
-;-----------------------------------------------------------------------------
-; append firmware BETA status to current string, including color-coding
-
-	global	TFT_cat_beta_release
-TFT_cat_beta_release:				; entry point for printing "Release" / "Beta #"
-	bsf		aux_flag
-	bra		TFT_cat_beta_common
-TFT_cat_beta_rel:					; entry point for printing "Rel." / "B. #"
-	bcf		aux_flag
-TFT_cat_beta_common:
- IFDEF _DEBUG
-	btfss	aux_flag				; shall show long version?
-	bra		TFT_cat_debug_short		; NO  - show short version
-	STRCAT	"DEBUG"					; YES - show long version
-	goto	TFT_warning_color		;     - set color
-TFT_cat_debug_short:
-	STRCAT	"DBG."					; show short version
-	goto	TFT_warning_color		; set color
- ELSE
-	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
-	btfss	aux_flag				; YES - shall show long version?
-	bra		TFT_cat_beta_2			;       NO  - show short version
-	rcall	check_expiry			;       YES - check  expiry date
-	btfsc	aux_flag				;           - within expiry date?
-	bra		TFT_cat_beta_4			;             NO  - give update cue
-	STRCAT	"Release"				;             YES - print "Release"
-	return							;                 - done
-TFT_cat_beta_1:
-	btfss	aux_flag				; shall show long  version?
-	bra		TFT_cat_beta_3			; NO  - show short version
-	STRCAT	"Beta "					; YES - show long  version
-TFT_cat_beta_1a:
-	bsf		leftbind
-	output_8						; print beta version number
-	bcf		leftbind
-	goto	TFT_attention_color		; and return
-TFT_cat_beta_2
-	STRCAT "Rel."					; short version for "Release"
-	return
-TFT_cat_beta_3
-	STRCAT "B."						; short version for "Beta"
-	bra		TFT_cat_beta_1a			; append beta version number
-TFT_cat_beta_4
-	STRCAT "update!"				; print update cue
-	goto	TFT_attention_color		; and return
- ENDIF	; ELSE / _DEBUG
-
-;-----------------------------------------------------------------------------
-; show firmware update message
+; Dive Mode - show maximum Depth
 ;
-; all text outputs are hard-coded since language switching
-; has not yet been initialized when this code is executed
-
-	global	show_fw_mesg_update
-	global	show_fw_mesg_kept
-show_fw_mesg_update:
-	call	TFT_standard_color
-	; show update message
-	WIN_SMALL .20,.100
-	STRCPY_PRINT "Update successful!"
-	; show firmware version
-	WIN_SMALL .20,.140
-	STRCPY	"New Firmware: "
-	bra		show_fw_mesg_common
-show_fw_mesg_kept:
-	call	TFT_standard_color
-	; show reboot message
-	WIN_SMALL .60,.100
-	STRCPY_PRINT "Reboot"
-	; show firmware version
-	WIN_SMALL .30,.140
-	STRCPY	"Firmware: "
-show_fw_mesg_common:
-	rcall	TFT_cat_firmware				; show firmware version x.y and color-code + invert if outdated
-	STRCAT_PRINT ""							; finalize output
-	bcf		win_invert						; back to normal (non inverted) output
-	; show firmware beta status
-	call	TFT_standard_color				; color to use if it is a release version
-	WIN_SMALL .60,.180
-	rcall	TFT_cat_beta_release			; show "Release" or "BETA" + issue
-	STRCAT_PRINT ""							; finalize output
-	goto	TFT_standard_color				; reset color and return
-
-;-----------------------------------------------------------------------------
-; show serial and firmware version for comm mode
-
-	global	TFT_show_serial_and_firmware
-	global	TFT_show_firmware
-TFT_show_serial_and_firmware:
-	STRCPY	"#"
-	call	TFT_cat_serial
-	STRCAT	" "
-	STRCAT	"v"
-TFT_show_firmware:
-	call	TFT_cat_firmware				; will set win_invert if outdated
-	STRCAT	" "
-	call	TFT_cat_beta_release
-	STRCAT_PRINT ""
-	bcf		win_invert						; clear win_invert
-	goto	TFT_standard_color				; ...and return
-
-;-----------------------------------------------------------------------------
-; For the Information menu: append total dives
-
-	global	info_menu_total_dives
-info_menu_total_dives:
-	lfsr	FSR1,tTotalDives				; locate text
-	call	strcat_text						; print  text
-TFT_cat_total_dives:
-	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
+	global	TFT_show_max_depth
+TFT_show_max_depth:
+	FONT_COLOR_MEMO						; select color
+	btfsc	alt_layout_active			; alternative layout active?
+	bra		TFT_show_max_depth_alt		; YES
+	;bra	TFT_show_max_depth_norm		; NO
+
+TFT_show_max_depth_norm:
+	WIN_MEDIUM dm_max_depth_column_nvsi, dm_max_depth_row
+	TSTOSS	opt_vsigraph								; graphical VSI bar enabled?
+	bra		TFT_show_max_depth_norm_1					; NO  - keep position
+	WIN_MEDIUM dm_max_depth_column, dm_max_depth_row	; YES - adopt output position
+
+TFT_show_max_depth_norm_1:
+	btfsc	FLAG_apnoe_mode				; in apnoe mode?
+	bra		TFT_max_depth_apnoe			; YES - different handling in apnoe mode
+	TSTOSS	opt_2ndDepthDisp			; NO  - show average depth instead of max depth?
+	bra		TFT_max_depth_current		;       NO  - show max depth
+	bra		TFT_avg_depth_current		;       YES - show avg depth
+
+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 - 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 pressure
+	bra		TFT_max_depth_common		; continue with common part
+
+TFT_avg_depth_current:
+	MOVII	pressure_rel_avg_total,mpr	; get total dive average pressure
+	;bra	TFT_max_depth_common		; continue with common part
+
+TFT_max_depth_common:
+	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:
+	bra		TFT_show_depth_helper_imperial
+
+TFT_max_depth_metric:
+	bsf		omit_digit_2				; print depth in full meters, i.e. do not print 2nd and 1st digit
+	output_9999							; test-print depth for range up to 99.9 meter (0xx-99xx)
+	btfsc	output_overflow				; did the printing clip, i.e. deeper than 99.9 meter?
+	bra		TFT_max_depth_metric_100m	; YES - print depth in full meters only
+	;bra	TFT_max_depth_metric_99m	; NO  - print depth in meters and decimeters
+
+TFT_max_depth_metric_99m:
+	; full meters
+	btfsc	max_depth_greater_100m		; was the depth >= 100 meter during last call?
+	rcall	TFT_max_depth_box_black		; NO - clear max depth area
+	bcf		max_depth_greater_100m		; current depth is now < 100 meter
+	PRINT								; dump full meters to screen
+	; decimeters
+	rcall	TFT_max_depth_metric_dm		; set output position for decimeters
+	output_65535						; print full depth to buffer
+	REINIT_BUFFER						; re-initialize the output buffer
+	PUTC	"."							; print a decimal point
+	movff	buffer+3,POSTINC2			; get and print the decimeters
+	PRINT								; dump to screen
+	return								; done
+
+TFT_max_depth_metric_100m:
+	; full meters only
+	btfss	max_depth_greater_100m		; was the depth >= 100 meter during last call?
+	rcall	TFT_max_depth_box_black		; NO - clear max depth area
+	bsf		max_depth_greater_100m		; depth is >= 100 meter now
+	REINIT_BUFFER						; re-initialize the output buffer
+	bsf		omit_digit_2				; print depth in full meters, i.e. do not print 1st and 2nd digit
+	output_65535						; print depth for range >= 100 meter (0xx-655xx)
+	PRINT								; dump to screen
+	return								; done
+
+TFT_show_max_depth_alt:
+	btfsc	FLAG_apnoe_mode				; in apnoe mode?
+	bra		TFT_show_apnoe_max_depth	; YES - use apnoe surface output also in alternative dive mode screen
+	btfss	FLAG_gauge_mode				; NO  - in gauge mode?
+	return								;       NO  - done
+	;bra	TFT_show_gauge_max_avg_depth;       YES
+
+TFT_show_gauge_max_avg_depth:
+	WIN_MEDIUM dm_gauge_max_depth_col, dm_gauge_max_depth_row	; set position for max depth
+	MOVII	pressure_rel_max_cached,mpr							; get max pressure into hi:lo
+	rcall	TFT_show_depth_helper								; print max depth
+	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 pressure into hi:lo
+	bra		TFT_show_depth_helper								; print avg depth and return
+
+
+	; Helper Function - clear max depth area
+TFT_max_depth_box_black:
+	WIN_BOX_BLACK dm_max_depth_row, dm_max_depth_bot, dm_max_depth_column, dm_max_depth_rgt
 	return									; done
 
-;-----------------------------------------------------------------------------
-; append firmware version to current string, including color-coding
-
-	global	TFT_cat_firmware
-TFT_cat_firmware:
-	movlw	fw_version_major
-	movwf	lo
-	bsf		leftbind
-	output_8								; print major in 1 or 2 digit format
-	PUTC	'.'
-	movlw	fw_version_minor
-	movwf	lo
-	output_99x								; print minor in two digit format
-	bcf		leftbind
-	rcall	check_expiry					; sets aux_flag if expired
-	btfss	aux_flag						; expired?
-	return									; NO
-	bsf		win_invert						; YES - print in inverse
-	goto	TFT_attention_color				;     - print in attention color (and return)
-
-;-----------------------------------------------------------------------------
-; For the Information menu: firmware version and creation date
-
-	global	info_menu_firmware
-info_menu_firmware:
-	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
+
+	; Helper Function - set output position for decimeters
+TFT_max_depth_metric_dm:
+	WIN_SMALL dm_max_depth_dm_column_nvsi, dm_max_depth_dm_row	; default position
+	TSTOSS	opt_vsigraph										; graphical VSI bar enabled?
+	return														; NO  - keep position
+	WIN_SMALL dm_max_depth_dm_column, dm_max_depth_dm_row		; YES - adopt position
+	return														; done
+
+
+	; Helper Function - print depth in mpr
+TFT_show_depth_helper:
+	call	convert_pres_to_depth			; convert pressure in [mbar] to depth in [cm]
+	TSTOSS	opt_units						; 0=m, 1=ft
+	bra		TFT_show_depth_helper_metric 	; 0 - metric
+	;bra	TFT_show_depth_helper_imperial	; 1 - imperial
+
+TFT_show_depth_helper_imperial:
+	call	convert_cm_to_feet				; convert value in hi:lo from [cm] to [feet]
+	output_999								; print depth (0-999)
+	PRINT									; dump to screen
 	return									; done
 
-;-----------------------------------------------------------------------------
-; For the Information menu: firmware version of the RX processor
-
- IFDEF _rx_functions
-
-	global	info_menu_firmware_rx
-	global	TFT_print_firmware_rx
-info_menu_firmware_rx:
-	lfsr	FSR1,tFirmware_rx
-	call	strcat_text
-TFT_print_firmware_rx:
-	movff	rx_firmware_cur_major,lo
-	bsf		leftbind
-	output_8
-	PUTC	'.'
-	movff	rx_firmware_cur_minor,lo
-	output_8
-	bcf		leftbind
-	return
-
- ENDIF
-
-;-----------------------------------------------------------------------------
-; For the Information menu: serial number
-
-	global	info_menu_serial
-	global	TFT_cat_serial
-info_menu_serial:
-	lfsr	FSR1,tSerial				; locate text
-	call	strcat_text					; print  text
-TFT_cat_serial:
-	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				; 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
+TFT_show_depth_helper_metric:
+	bsf		omit_digit_1					; do not print 1st digit
+	bsf		decimal_digit2					; place a decimal point in front of digit 2
+	output_65535							; print depth (0.0x-655.3x)
+	PRINT									; dump to screen
+	return									; done
 
 
 ;-----------------------------------------------------------------------------
-; For the Information menu: battery voltage
-
-	global	info_menu_battery_volts
-info_menu_battery_volts:
-	lfsr	FSR1,tBatteryV
-	call	strcat_text
-	MOVII	batt_voltage,mpr
-	bsf		leftbind
-	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
-	output_8
-	bcf		leftbind
-	PUTC	")"
-	return
+; Dive Mode - show maximum Depth - Apnoe Mode
+;
+	global	TFT_show_apnoe_max_depth
+TFT_show_apnoe_max_depth:
+	; title
+	WIN_TINY dm_apnoe_last_max_depth_text_col, dm_apnoe_last_max_depth_text_row
+	FONT_COLOR_MASK							; set color
+	btfsc	alt_layout_active				; alternative layout active?
+	bra		TFT_show_apnoe_max_depth_alt	; YES
+	;bra	TFT_show_apnoe_max_depth_norm	; NO
+
+TFT_show_apnoe_max_depth_norm:
+	STRCPY_TEXT_PRINT tApnoeMax				; print "Last Descent"
+	bra		TFT_show_apnoe_max_depth_com	; continue with common part
+
+TFT_show_apnoe_max_depth_alt:
+	STRCPY_TEXT_PRINT tMaxDepth				; print "Max.Depth"
+	;bra	TFT_show_apnoe_max_depth_com	; continue with common part
+
+TFT_show_apnoe_max_depth_com:
+	; value
+	WIN_MEDIUM	dm_apnoe_last_max_depth_column, dm_apnoe_last_max_depth_row
+	FONT_COLOR_MEMO							; select color
+	MOVII	pressure_rel_max_cached,mpr		; get max pressure into hi:lo
+	bra		TFT_show_depth_helper			; print max depth and return
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show Temperature
+;
+	global	TFT_show_temp_divemode
+TFT_show_temp_divemode:
+	btfsc	dive_pre_menu				; is the pre-menu shown?
+	return								; YES - abort
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort, no update of temperature now
+	btfsc	better_gas_blinking			; blinking better gas?
+	return								; YES - abort, no update of temperature now
+	btfsc	better_dil_blinking			; blinking better diluent?
+	return								; YES - abort, no update of temperature now
+
+	WIN_SMALL dm_temp_column,dm_temp_row; set position
+	FONT_COLOR_MEMO						; set color
+	movlw	index_compass_dm			; index of compass custom view
+	cpfseq	active_customview			; compass shown in custom view?
+	goto	TFT_temp_common				; NO  - continue with common part for temperature
+	goto	TFT_update_stopwatch		; YES - show resettable dive time instead of temperature
 
 
 ;-----------------------------------------------------------------------------
-; 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
+; Dive Mode - active Gas and Setpoint
+;
+	global	TFT_show_active_gas_divemode
+TFT_show_active_gas_divemode:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+	btfsc	FLAG_apnoe_mode				; in apnoe mode?
+	return								; YES - done
+	btfsc	FLAG_gauge_mode				; in gauge mode?
+	return								; YES - done
+
+ IFDEF _ccr_pscr
+
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		TFT_active_gas				; YES - show OC gas
+	btfss	bailout_mode				; NO  - in bailout?
+	bra		TFT_active_sp_loop			;       NO
+	;bra	TFT_active_sp_bailout		;       YES
+
+TFT_active_sp_bailout:
+	WIN_SMALL dm_active_dil_column, dm_active_dil_row
+	FONT_COLOR_ATTENTION				; set color
+	STRCPY_TEXT_PRINT tDiveBailout		; print "Bailout"
+	bra		TFT_active_gas				; continue showing OC bailout gas
+
+TFT_active_sp_loop:
+	MOVII	int_O_breathed_ppO2,mpr		; copy ppO2 [cbar] to hi:lo
+	call	TFT_color_code_ppo2			; color-code the output by the ppO2 of the loop gas mixture
+	btfss	timebase_1sec				; on even second?
+	bra		TFT_active_sp_print			; YES - print ppO2 with normal rendering
+	btfsc	warn_det_sensors_lost		; NO  - all sensors lost?
+	bra		TFT_active_sp_fallback		;       YES - process fallback case
+	movff	int_O_breathed_ppO2+1,WREG	;       NO  - get flags again (have been cleared in hi:lo by TFT_color_code_ppo2 meanwhile)
+	btfss	WREG,int_warning_flag		;             warning flag set?
+	bra		TFT_active_sp_print			;             NO  - ppO2 is ok, print ppO2 with normal rendering
+	bra		TFT_active_sp_invers		;             YES - print with inverse rendering
+TFT_active_sp_fallback:					; set up fallback case
+	FONT_COLOR_ATTENTION				; set color to attention
+TFT_active_sp_invers:
+	bsf		win_invert					; print in inverse
+TFT_active_sp_print:
+	WIN_MEDIUM dm_active_gas_sp_value_col, dm_active_gas_sp_value_row
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_999							; print ppO2 (0.00-9.99)
+	PRINT								; dump to screen
+
+	btfsc	sign_shown					; advice/attention/warning sign shown?
+	bra		TFT_active_diluent			; YES - do not overwrite in case of alternative layout
+
+	btfsc	velocity_active_vsi			; graphical vertical speed indicator shown?
+	bra		TFT_active_diluent			; YES - do not overwrite in case of alternative layout
+
+TFT_active_sp_label_1:
+	WIN_STD dm_active_sp_label_col, dm_active_sp_label_row
+	FONT_COLOR_MEMO						; select memo color
+	STRCAT	"bar"						; print "bar"
+
+ IFDEF _external_sensor
+
+	movff	opt_ccr_mode,WREG			; get setpoint mode =0: Fixed SP, =1: Sensor, =2: Auto SP
+	sublw	.1							; opt_ccr_mode = 1 (Sensor) ?
+	bnz		TFT_active_sp_label_2		; NO  - skip
+	btfsc	alt_layout_active			; YES - in alternative layout?
+	bra		TFT_active_sp_label_2		;       YES - no space available for the "*"
+	PUTC	"*"							;       NO  - append "*"
+
+ ENDIF
+
+TFT_active_sp_label_2:
+	PRINT								; dump buffer to screen
+
+TFT_active_loop_mode:
+	WIN_TINY dm_active_sp_label_col, dm_active_dil_row+.3
+	FONT_COLOR_MEMO						; set memo color
+	btfsc	FLAG_ccr_mode				; in CCR mode?
+	bra		TFT_active_loop_mode_ccr	; YES - print CCR label
+	btfsc	FLAG_pscr_mode				; in pSCR mode?
+	bra		TFT_active_loop_mode_pscr	; YES - print pSCR label
+	bra		TFT_active_diluent			; NO  to both - should not happen
+
+TFT_active_loop_mode_ccr:
+	STRCPY_TEXT_PRINT tDvCCR			; print "CCR"
+	bra		TFT_active_diluent			; continue with diluent
+
+TFT_active_loop_mode_pscr:
+	STRCPY_TEXT_PRINT tDvPSCR			; print "pSCR"
+	;bra	TFT_active_diluent			; continue with diluent
+
+TFT_active_diluent:
+	MOVII	int_O_pure_ppO2,mpr			; get ppO2 [cbar] into hi:lo
+	call	TFT_color_code_ppo2			; color-code the output
+	btfss	better_dil_available		; better diluent available?
+	bra		TFT_active_diluent_show		; NO  - print in normal rendering
+	btg		better_dil_blinking			; YES - toggle blink bit...
+	btfss	better_dil_blinking			;     - blink now?
+	bra		TFT_active_diluent_show		;       NO  - print in normal rendering
+	FONT_COLOR_ATTENTION				;       YES - print in attention color
+	bsf		win_invert					;           - print in inverse
+
+TFT_active_diluent_show:
+	WIN_SMALL dm_active_dil_column, dm_active_dil_row
+	bra		TFT_active_dil_gas_common	; continue with common part
+
+ ENDIF	; _ccr_pscr
+
+TFT_active_gas:
+	MOVII	int_O_breathed_ppO2,mpr		; copy ppO2 [cbar] into hi:lo
+	call	TFT_color_code_ppo2			; color-code the output
+	btfss	better_gas_available		; better gas available?
+	bra		TFT_active_gas_print		; NO  - print in normal rendering
+	btg		better_gas_blinking			; YES - toggle blink bit
+	btfss	better_gas_blinking			;       blink now?
+	bra		TFT_active_gas_print		;       NO  - print in normal rendering
+	FONT_COLOR_ATTENTION				;       YES - blink in attention color
+	bsf		win_invert					;             print in inverse
+
+TFT_active_gas_print:
+	WIN_STD	dm_active_gas_sp_value_col, dm_active_sp_label_row
+
+TFT_active_dil_gas_common:
+	movff	char_I_O2_ratio,lo			; lo now stores O2 in %
+ IFDEF _helium
+	movff	char_I_He_ratio,hi			; hi now stores He in %
+ ELSE
+	clrf	hi							; set hi to zero (no He)
+ ENDIF
+	call	gaslist_strcat_mix			; print "Nxlo", "Txlo/hi", "Air" or "O2"
+	PRINT								; dump to screen
 	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
+; Dive Mode - NDL Time
+;
+	global	TFT_show_ndl
+TFT_show_ndl:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+	MOVII	int_O_NDL_norm,mpr			; NO  - get NDL time in normal plan
+	rcall	TFT_show_ndl_tts_set_color	;     - set color
+	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?
+	bra		TFT_show_ndl_alt			;             YES - use alternative layout
+	;bra	TFT_show_ndl_norm			;             NO  - use normal layout
+
+TFT_show_ndl_norm:
+	WIN_MEDIUM dm_ndl_value_col_norm,dm_ndl_value_row_norm
+	output_256							; print NDL (0-255)
+	PUTC_PRINT "'"						; append unit and dump buffer to screen
+	return								; done
+
+TFT_show_ndl_alt:
+	btfsc	safety_stop_active			; is the safety stop active?
+	bra		TFT_show_ndl_alt_safety		; YES
+	;bra	TFT_show_ndl_alt_no_safety	; NO
+
+TFT_show_ndl_alt_no_safety:				; clear potential remains from NDL normal
+	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
+	output_99							; print NDL (0-99)
+	PRINT								; dump buffer to screen
+	return								; done
+
+TFT_show_ndl_alt_safety:
+	WIN_MEDIUM dm_ndl_value_col_norm,dm_ndl_value_row_norm
+	output_256							; print NDL (0-255)
+	PUTC_PRINT "'"						; append unit and dump buffer to screen
+	return								; done
+
+
+	; Helper Function - set color
+TFT_show_ndl_tts_set_color:
+	movf	pallet_color_memo,W			; load memo color as default
+	btfsc	mpr+1,int_invalid_flag		; is the invalid flag set?
+	movf	pallet_color_disabled,W		; YES - replace by disabled color
+	movwf	font_color					; set font color
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - TTS Time
+;
+	global	TFT_show_tts
+TFT_show_tts:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+	MOVII	int_O_TTS_norm,mpr			; NO  - get the TTS
+	rcall	TFT_show_ndl_tts_set_color	;     - color-code
+	bcf		hi,int_invalid_flag			;     - clear the invalid flag if applicable
+	btfsc	alt_layout_active			;     - in alternative layout?
+	bra		TFT_display_tts_alt			;       YES
+	;bra	TFT_display_tts_norm		;       NO
+
+TFT_display_tts_norm:
+	WIN_MEDIUM dm_tts_value_col_999x, dm_tts_value_row
+	output_999							; print (0...999)
+	PUTC_PRINT "'"						; append unit and dump buffer to screen
+	return								; done
+
+TFT_display_tts_alt:
+	output_99							; print TTS for range 0-99
+	btfsc	output_overflow				; does TTS fit into 0-99 ?
+	bra		TFT_display_tts_alt_999		; NO  - print in 999 format
+	;bra	TFT_display_tts_alt_99		; YES - print in  99 format
+
+TFT_display_tts_alt_99:
+	btfsc	tts_over_99_last			; was TTS > 99 last time?
+	rcall	TFT_display_tts_clear		; YES - clear remains from TTS > 99
+	WIN_MEDIUM dm_tts_value_col_99, dm_tts_value_row
+	output_99							; print TTS (0...99)
+	PUTC_PRINT "'"						; append unit and dump buffer to screen
+	return								; done
+
+TFT_display_tts_alt_999:
+	WIN_MEDIUM dm_tts_value_col_999, dm_tts_value_row
+	REINIT_BUFFER						; clear the buffer
+	output_999							; print (0...999), no space for unit
+	PRINT								; dump to screen
+	bsf		tts_over_99_last			; remember last TTS was > 99 mins
+	return								; done
+
+
+	; Helper Function - clear remains from TTS > 99
+TFT_display_tts_clear:					; clear remains from TTS > 99
+	WIN_BOX_BLACK dm_tts_value_row, dm_tts_value_row+.31, dm_tts_value_col_999, dm_tts_value_col_99 ; top, bottom, left, right
+	bcf		tts_over_99_last			; remember last TTS was NOT > 99 mins
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Deco Stop Time & Depth
+;
+	global	TFT_show_deco
+TFT_show_deco:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+
+	movff	char_O_deco_depth,lo		; get depth of first stop in meters
+	call	TFT_color_code_stop			; color-code output
+	TSTOSC	opt_units					; get unit (0=m, 1=ft)
+	bra		TFT_show_deco_norm			; 1 - ft can only be displayed in normal layout due to space required for 3 digit depth
+	btfsc	alt_layout_active			; 0 - in alternative layout?
+	bra		TFT_show_deco_alt			;     YES
+	;bra	TFT_show_deco_norm			;     NO  - combined depth and time
+
+TFT_show_deco_norm:
+	WIN_MEDIUM dm_decostop_col_norm, dm_decostop_row_norm
+	call	TFT_display_stop_depth		; print stop (depth in lo)
+	PUTC	' '							; put a space char between depth and time
+	bra		TFT_display_deco_common		; continue with common part
+
+TFT_show_deco_alt:
+	WIN_LARGE  dm_decostop_col_alt_depth, dm_decostop_row_alt_depth
+	output_99							; print stop depth (0-99)
+	PRINT								; dump buffer to screen
+	WIN_MEDIUM dm_decostop_col_alt_time,  dm_decostop_row_alt_time
+	FONT_COLOR_MEMO						; select memo color
+	;bra	TFT_display_deco_common		; continue with common part
+
+TFT_display_deco_common:
+	movff	char_O_deco_time,lo			; get stop time of the first stop in minutes
+	output_99DD							; print minutes or double dots if null
+	PUTC_PRINT "'"						; append unit and dump buffer to screen
+	return								; done
+
+
+;=============================================================================
+tft_out7	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Apnoe current and overall Dive Time
+;
+	global	TFT_show_apnoe_times
+TFT_show_apnoe_times:
+	; current dive time
+	FONT_COLOR_MEMO						; select color
+	WIN_MEDIUM dm_divetime_apnoe_col, dm_divetime_apnoe_row
+	SMOVII	apnoe_dive_mins,mpr			; ISR-safe copy of minutes to lo and seconds to hi
+	output_99							; print minutes (0-99)
+	PRINT								; dump to screen
+	WIN_SMALL	dm_divetime_apnoe_secs_col, dm_divetime_apnoe_secs_row
+	PUTC	':'							; print ":"
+	movff	hi,lo						; copy  seconds to lo
+	output_99x							; print seconds (00-99)
+	PRINT								; dump to screen
+	; overall dive time
+	WIN_MEDIUM dm_apnoe_total_divetime_col, dm_apnoe_total_divetime_row
+	SMOVTT	counted_divetime_mins,mpr	; ISR-safe 3 byte copy of minutes:2 and seconds
+	output_256							; minutes (0-256)
+	PRINT								; show minutes in large font
+	WIN_SMALL dm_apnoe_total_divetime_secs_col, dm_apnoe_total_divetime_secs_row ; left position for two sec figures
+	PUTC	':'							; print ":"
+	movff	up,lo						; copy seconds from up to lo
+	output_99x							; print seconds (00-99)
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show Apnoe Surface Time
+;
+	global	TFT_show_apnoe_surface
+TFT_show_apnoe_surface:
+	FONT_COLOR_MASK						; select mask color
+	WIN_TINY dm_apnoe_surface_time_text_col, dm_apnoe_surface_time_text_row
+	STRCPY_TEXT_PRINT tApnoeSurface		; print label
+	FONT_COLOR_MEMO						; select memo color
+	WIN_MEDIUM dm_apnoe_surface_time_column, dm_apnoe_surface_time_row
+	SMOVII	apnoe_surface_mins,mpr		; ISR-safe copy of minutes to lo and seconds to hi
+	output_256							; print minutes (0-255)
+	PUTC	':'							; print ":"
+	movff	hi,lo						; copy  seconds to lo
+	output_99x							; print seconds (00-99)
+	PRINT								; dump to screen
 	return								; done
 
 
 ;-----------------------------------------------------------------------------
-; For the Information menu: uptime
-
-	global	info_menu_uptime
-info_menu_uptime:
-	lfsr	FSR1,tUptime
-	call	strcat_text
-	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
-	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
-	bsf		leftbind
-	output_16
-	PUTC	"d"
-	movff	xA+0,lo						; full hours
-	output_8
-	PUTC	"h"
-	bcf		leftbind
+; Dive Mode - clear Apnoe Surface Time
+;
+	global	TFT_clear_apnoe_surface
+TFT_clear_apnoe_surface:
+	WIN_BOX_BLACK dm_apnoe_last_max_depth_text_row, .239, dm_apnoe_last_max_depth_column, .159
 	return								; done
 
+
+;=============================================================================
+tft_out8	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - clear Deco Data (NDL / Stop & TTS )
+;
+	global	TFT_clear_deco_data
+TFT_clear_deco_data:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES
+
+	WIN_BOX_BLACK dm_decostop_row_alt_depth, dm_3rdrow_bot, dm_decostop_col_alt_depth, dm_3rdrow_rgt	; top, bottom, left, right
+	return
+
+
 ;-----------------------------------------------------------------------------
-
- IFDEF _compass
-
-	global	menu_cal_x
-menu_cal_x:
-	lfsr	FSR0,compass_CX_f
-	lfsr	FSR1,tCalX
-	bra		menu_cal_common
-
-	global	menu_cal_y
-menu_cal_y:
-	lfsr	FSR0,compass_CY_f
-	lfsr	FSR1,tCalY
-	bra		menu_cal_common
-
-	global	menu_cal_z
-menu_cal_z:
-	lfsr	FSR0,compass_CZ_f
-	lfsr	FSR1,tCalZ
-	;bra	menu_cal_common
-
-menu_cal_common:
-	call	strcat_text
-	movff	POSTINC0,lo
-	movff	POSTINC0,hi
-	call	TFT_convert_signed_16bit	; convert lo:hi into signed-short and adds '-' to POSTINC2 if required
-	bsf		leftbind
-	output_16
-	bcf		leftbind
+; Dive Mode - clear Dive Mode Menu
+;
+; starts 2 pixel higher to completely wipe away the temperature display
+;
+	global	TFT_clear_divemode_menu
+TFT_clear_divemode_menu:
+	WIN_BOX_BLACK	dm_menu_row-.2, dm_menu_lower, dm_menu_left, dm_menu_right
 	return
 
- ENDIF	; _compass
+
+;=============================================================================
+VSI_table	CODE_PACK
+;=============================================================================
+
+VSI_table:
+
+	; use a depth-dependent ascent rate warning
+	; depth(ft):     <20 >20 >40 >60 >75 >88 >101 >115 >128 >144 >164
+	; speed(ft/min):  23  26  29  33  36  43   49   56   59   62   66
+	; depth(m):      <=6  >6 >12 >18 >23 >27  >31  >35  >39  >44  >50
+	; speed(m/min):    7   8   9  10  11  13   15   17   18   19   20 (warning)
+	; speed(m/min):    5   6   7   8   8  10   12   13   14   15   15 (attention)
+
+	; < depth (m), warning speed, attention speed
+	DB    .6, .7, .5
+	DB   .12, .8, .6
+	DB   .18, .9, .7
+	DB   .23,.10, .8
+	DB   .27,.11, .8
+	DB   .31,.13,.10
+	DB   .35,.15,.12
+	DB   .39,.17,.13
+	DB   .44,.18,.14
+	DB   .50,.19,.15
+	DB  .255,.20,.15
+
+
+;=============================================================================
+tft_out9	CODE
+;=============================================================================
 
 
 ;-----------------------------------------------------------------------------
-; ppO2 menu
-
-	global	divesets_ppo2_min
-divesets_ppo2_min:
-	lfsr	FSR1,tPPO2MIN
-	call	strcat_text
-	movff	char_I_ppO2_min,lo
-	movlw	ppo2_warning_low_default
-	bra		divesets_ppo2_common
-
-
- IFDEF _ccr_pscr
-
-	global	divesets_ppo2_min_cc
-divesets_ppo2_min_cc:
-	lfsr	FSR1,tPPO2MINCC
-	call	strcat_text
-	movff	char_I_ppO2_min_loop,lo
-	movlw	ppo2_warning_loop_default
-	bra		divesets_ppo2_common
-
- ENDIF
-
-	global	divesets_ppo2_max
-divesets_ppo2_max:
-	lfsr	FSR1,tPPO2Max
-	call	strcat_text
-	movff	char_I_ppO2_max_work,lo
-	movlw	ppo2_warning_high_default
-	bra		divesets_ppo2_common
-
-	global	divesets_ppo2_max_deco
-divesets_ppo2_max_deco:
-	lfsr	FSR1,tPPO2DECO
-	call	strcat_text
-	movff	char_I_ppO2_max_deco,lo
-	movlw	ppo2_warning_deco_default
-	;bra	divesets_ppo2_common
-
-divesets_ppo2_common:
-	movwf	up						; save default value
-	clrf	hi
-	bsf		leftbind
-	output_16dp d'3'
-	bcf		leftbind
-	lfsr	FSR1,tbar
-	call	strcat_text
-	movf	up,W					; default value
-	cpfseq	lo						; current value
-	bra		divesets_ppo2_common2	; not default, add *
-	return							; default, done
-divesets_ppo2_common2:
-	PUTC	"*"
-	return							; done
+; Dive Mode - show vertical Velocity
+;
+	global	TFT_velocity_show
+TFT_velocity_show:
+	FONT_COLOR_MEMO						; set default color
+	btfsc	neg_flag_velocity			; descending?
+	rcall	TFT_velocity_set_color		; NO - set color for text dependent on speed and set threshold for VSI graph
+	rcall	TFT_velocity_num			; show the numerical VSI
+	TSTOSS	opt_vsigraph				; graphical VSI bar enabled?
+	return								; NO  - done
+	btfss	neg_flag_velocity			; YES - in ascent?
+	bra		TFT_velocity_clear_graph	;       NO  - clear the graph
+	;bra	TFT_velocity_graph_show		;       YES - show  the graph
+
+TFT_velocity_graph_show:
+	btfsc	alt_layout_active			; in alternative layout?
+	return								; YES - done (not implemented)
+
+	btfsc	velocity_active_vsi			; was the graphical VSI shown before?
+	bra		TFT_velocity_graph_1		; YES - no need to redraw the framework box
+	bsf		velocity_active_vsi			; NO  - remember it is shown as of now
+										;     - draw the framework box
+	movf	pallet_color_mask,W			;     - color -> WREG
+	WIN_FRAME_COLOR	dm_velocity_graph_top+.00, dm_velocity_graph_bot-.00, dm_velocity_graph_lft, dm_velocity_graph_rgt
+	movf	pallet_color_mask,W			;     - color -> WREG
+	WIN_FRAME_COLOR	dm_velocity_graph_top+.10, dm_velocity_graph_bot-.10, dm_velocity_graph_lft, dm_velocity_graph_rgt
+	movf	pallet_color_mask,W			;     - color -> WREG
+	WIN_FRAME_COLOR	dm_velocity_graph_top+.20, dm_velocity_graph_bot-.20, dm_velocity_graph_lft, dm_velocity_graph_rgt
+	movf	pallet_color_mask,W			;     - color -> WREG
+	WIN_FRAME_COLOR	dm_velocity_graph_top+.30, dm_velocity_graph_bot-.30, dm_velocity_graph_lft, dm_velocity_graph_rgt
+
+TFT_velocity_graph_1:
+	movff	divA+0,hi					; copy ascend speed (in m/min) to hi
+	movff	divA+1,xA+0					; m/min for warning level (upper two blocks)
+	clrf	xA+1
+	MOVLI	.5,xB						; threshold for color warning (5 color normal + 2 color warning)
+	call	div16x16					; xC = xA / xB with xA as remainder
+	; xC+0 holds step size in m/min (e.g. =3 for 15m/min warning threshold)
+	movff	hi,xA+0						; velocity in m/min
+	clrf	xA+1						; ...
+	movff	xC+0,xB+0					; step size
+	clrf	xB+1						; ...
+	call	div16x16					; xC = xA / xB with xA as remainder
+	movff	xC+0,lo						; copy amount of segments to show to lo
+	incf	lo,F						; lo +=1
+	dcfsnz	lo,F						; lo = 1 ?
+	bra		DISP_graph_vel_0_fill		; YES - fill lowest  segment
+	dcfsnz	lo,F						; lo = 2 ?
+	bra		DISP_graph_vel_1_fill		; YES - fill lower 2 segments
+	dcfsnz	lo,F						; lo = 3 ?
+	bra		DISP_graph_vel_2_fill		; YES - fill lower 3 segments
+	dcfsnz	lo,F						; lo = 4 ?
+	bra		DISP_graph_vel_3_fill		; YES - fill lower 4 segments
+	dcfsnz	lo,F						; lo = 5 ?
+	bra		DISP_graph_vel_4_fill		; YES - fill lower 5 segments
+	dcfsnz	lo,F						; lo = 6 ?
+	bra		DISP_graph_vel_5_fill		; YES - fill lower 6 segments
+	dcfsnz	lo,F						; lo = 7 ?
+	bra		DISP_graph_vel_6_fill		; YES - fill lower 7 segments
+	;bra	DISP_graph_vel_7_fill		; YES - fill all     segments
+
+DISP_graph_vel_7_fill:
+	movf	pallet_color_warning,W
+	WIN_BOX_COLOR dm_velocity_graph_top+.2,  dm_velocity_graph_top+.8,  dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_6_fill:
+	movf	pallet_color_warning,W
+	WIN_BOX_COLOR dm_velocity_graph_top+.12, dm_velocity_graph_top+.18, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_5_fill:
+	movf	pallet_color_attention,W
+	WIN_BOX_COLOR dm_velocity_graph_top+.22, dm_velocity_graph_top+.28, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_4_fill:
+	movf	pallet_color_memo,W
+	WIN_BOX_COLOR dm_velocity_graph_top+.32, dm_velocity_graph_top+.38, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_3_fill:
+	movf	pallet_color_memo,W
+	WIN_BOX_COLOR dm_velocity_graph_top+.42, dm_velocity_graph_top+.48, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_2_fill:
+	movf	pallet_color_memo,W
+	WIN_BOX_COLOR dm_velocity_graph_top+.52, dm_velocity_graph_top+.58, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_1_fill:
+	movf	pallet_color_memo,W
+	WIN_BOX_COLOR dm_velocity_graph_top+.62, dm_velocity_graph_top+.68, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_0_fill:
+
+	movff	xC+0,lo						; copy amount of segments to show to lo
+	incf	lo,F						; lo += 1
+	dcfsnz	lo,F						; lo = 1 ?
+	bra		DISP_graph_vel_0_clear		; YES - clear upper 7 segments
+	dcfsnz	lo,F						; lo = 2 ?
+	bra		DISP_graph_vel_1_clear		; YES - clear upper 6 segments
+	dcfsnz	lo,F						; lo = 3 ?
+	bra		DISP_graph_vel_2_clear		; YES - clear upper 5 segments
+	dcfsnz	lo,F						; lo = 4 ?
+	bra		DISP_graph_vel_3_clear		; YES - clear upper 4 segments
+	dcfsnz	lo,F						; lo = 5 ?
+	bra		DISP_graph_vel_4_clear		; YES - clear upper 3 segments
+	dcfsnz	lo,F						; lo = 6 ?
+	bra		DISP_graph_vel_5_clear		; YES - clear upper 2 segments
+	dcfsnz	lo,F						; lo = 7 ?
+	bra		DISP_graph_vel_6_clear		; YES - clear upper 1 segments
+	bra		DISP_graph_vel_7_clear		; YES - clear no      segments
+
+DISP_graph_vel_0_clear:
+	WIN_BOX_BLACK dm_velocity_graph_top+.62, dm_velocity_graph_top+.68, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_1_clear:
+	WIN_BOX_BLACK dm_velocity_graph_top+.52, dm_velocity_graph_top+.58, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_2_clear:
+	WIN_BOX_BLACK dm_velocity_graph_top+.42, dm_velocity_graph_top+.48, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_3_clear:
+	WIN_BOX_BLACK dm_velocity_graph_top+.32, dm_velocity_graph_top+.38, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_4_clear:
+	WIN_BOX_BLACK dm_velocity_graph_top+.22, dm_velocity_graph_top+.28, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_5_clear:
+	WIN_BOX_BLACK dm_velocity_graph_top+.12, dm_velocity_graph_top+.18, dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_6_clear:
+	WIN_BOX_BLACK dm_velocity_graph_top+.2,  dm_velocity_graph_top+.8,  dm_velocity_graph_lft+.2, dm_velocity_graph_rgt-.2 ;top, bottom, left, right
+DISP_graph_vel_7_clear:
+	return								; done
+
+
+	; Helper Function - set color based on speed table or use static thresholds, with divA+0 = m/min
+TFT_velocity_set_color:
+	bsf		aux_flag						; for alternative layout: default is to show numerical VSI
+	; check if old/new ascend logic is used
+	TSTOSS	opt_vsitext						; 0=standard, 1=dynamic
+	bra		TFT_velocity_set_color_static	; 0 - static  ascend rate limit
+	;bra	TFT_velocity_set_color_dynamic	; 1 - dynamic ascend rate limit
+
+TFT_velocity_set_color_dynamic:
+	movlw	LOW   (VSI_table-.2)		; point to 2 entries ahead of the speed table
+	movwf	TBLPTRL						; ...
+	movlw	HIGH  (VSI_table-.2)		; ...
+	movwf	TBLPTRH						; ...
+	movlw	UPPER (VSI_table-.2)		; ...
+	movwf	TBLPTRU						; ...
+TFT_velocity_set_color_loop:
+	TBLRD*+								; consume waring    speed form last round
+	TBLRD*+								; consume attention speed form last round
+	TBLRD*+								; get table   depth
+	movf	depth_meter,W				; get current depth
+	cpfsgt	TABLAT						; table depth > current depth ?
+	bra		TFT_velocity_set_color_loop	; NO  - try next
+	TBLRD*+								; YES - read warning speed threshold
+	movf	TABLAT,W					;     - ...
+	movwf	divA+1						;     - copy to graph routine
+	cpfslt	divA+0						;     - actual vertical speed smaller than warning threshold?
+	bra		TFT_velocity_set_color_warn	;       NO - set warning color and return
+	TBLRD*+								;       YES - read attention speed threshold
+	movf	TABLAT,W					;           - ...
+	cpfslt	divA+0						;           - actual vertical speed smaller than attention threshold?
+	bra		TFT_velocity_set_color_attn	;             NO  - set attention color and return
+	bcf		aux_flag					;             YES - don't show in alternative layout
+	bra		TFT_velocity_set_color_memo	;                 - set memo color and return
+
+TFT_velocity_set_color_static:
+	movlw	color_code_velocity_warn_high	; get static threshold for warning in m/min
+	movwf	divA+1							; copy for graph routine
+	cpfslt	divA+0							; actual vertical speed smaller than warning threshold?
+	bra		TFT_velocity_set_color_warn		; NO  - set warning color and return
+	movlw	color_code_velocity_attn_high	; YES - get static threshold for attention in m/min
+	cpfslt	divA+0							;     - actual vertical speed smaller than attention threshold?
+	bra		TFT_velocity_set_color_attn		;       NO  - set attention color and return
+	bcf		aux_flag						;       YES - don't show in alternative layout
+	;bra	TFT_velocity_set_color_memo		;           - set memo color and return
+
+
+	; Helper Function - select color
+TFT_velocity_set_color_memo:
+	FONT_COLOR_MEMO						; select memo color
+	return								; done
+
+TFT_velocity_set_color_attn:
+	FONT_COLOR_ATTENTION				; select attention color
+	return								; done
+
+TFT_velocity_set_color_warn:
+	FONT_COLOR_WARNING					; select warning color
+	return								; done
+
+
+	; Helper Function - show the numerical VSI
+TFT_velocity_num:
+	btfsc	alt_layout_active			; in alternative layout?
+	bra		TFT_velocity_num_alt		; YES
+	;bra	TFT_velocity_num_norm		; NO
+
+TFT_velocity_num_norm:
+	WIN_SMALL dm_velocity_text_col_norm, dm_velocity_text_row_norm
+	bra		TFT_velocity_num_com		; continue with common part
+
+TFT_velocity_num_alt:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+	btfss	neg_flag_velocity			; NO  - in ascent?
+	bcf		aux_flag					;       NO  - clear aux flag
+	btfsc	aux_flag					;     - above attention or warning threshold?
+	bsf		win_invert					;       YES - print inverse
+	WIN_SMALL dm_velocity_text_col_alt, dm_velocity_text_row_alt
+	;bra	TFT_velocity_num_com		;     - continue with common part
+
+TFT_velocity_num_com:
+	bsf		velocity_active_num			; set numerical velocity as shown
+	TSTOSS	opt_units					; 0=meter, 1=feet
+	bra		TFT_velocity_num_metric		; 0 - meter
+	;bra	TFT_velocity_num_imperial	; 1 - feet
+
+TFT_velocity_num_imperial:
+	movff	divA+0,WREG					; divA+0 = m/min
+	mullw	.100						; PROD   = mbar/min
+	MOVII	PRODL,mpr					; copy to hi:lo
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
+	tstfsz	hi							; > 255 ?
+	setf	lo							; YES - set lo to 255
+	rcall	TFT_velocity_num_helper		; print vertical speed
+	STRCAT_TEXT tVelImperial			; print unit
+	bra		TFT_velocity_num_finish		; do finishing tasks
+
+TFT_velocity_num_metric:
+	movff	divA+0,lo					; divA+0 = m/min
+	rcall	TFT_velocity_num_helper		; print vertical speed
+	STRCAT_TEXT tVelMetric				; print unit
+	;bra	TFT_velocity_num_finish		; do finishing tasks
+
+TFT_velocity_num_finish:
+	btfss	alt_layout_active			; in alternative layout?
+	bra		TFT_velocity_num_finish_1	; NO
+	movlw	"'"							; load encoding of minute sign
+	movff	WREG,buffer+4				; put it after m (meter) / f (feet)
+	clrf	WREG						; load string terminator
+	movff	WREG,buffer+5				; terminate string after minute sign
+TFT_velocity_num_finish_1:
+	PRINT								; dump to screen
+	return								; done
+
+
+	; Helper Function - print vertical speed
+TFT_velocity_num_helper:
+	movlw	'-'							; load coding for minus sign
+	btfsc	neg_flag_velocity			; ascending?
+	movlw	'+'							; YES - replace with coding for plus sign
+	movwf	POSTINC2					; put sign into output buffer
+	output_99							; print rate (0-99)
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - clear vertical Velocity
+;
+	global	TFT_velocity_clear
+TFT_velocity_clear:
+	btfss	velocity_active_num			; was the numerical VSI shown in last cycle?
+	bra		TFT_velocity_check_graph	; NO  - no need to clear it, continue with graphical VSI
+	;bra	TFT_velocity_clear_num		; YES
+
+TFT_velocity_clear_num:
+	bcf		velocity_active_num			; clear flag
+	btfsc	alt_layout_active			; in alternative layout?
+	bra		TFT_velocity_clear_num_alt	; YES
+	;bra	TFT_velocity_clear_num_norm	; NO
+
+TFT_velocity_clear_num_norm:			; clear normal numerical area
+	WIN_BOX_BLACK dm_velocity_text_row_norm, dm_velocity_text_bot_norm, dm_velocity_text_col_norm, dm_velocity_text_rgt_norm
+	bra		TFT_velocity_check_graph	; continue with graphical VSI
+
+TFT_velocity_clear_num_alt:				; clear alternative numerical area
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	bra		TFT_velocity_check_graph	; YES - skip
+	WIN_BOX_BLACK dm_velocity_text_row_alt,  dm_velocity_text_bot_alt,  dm_velocity_text_col_alt,  dm_velocity_text_rgt_alt
+	;bra	TFT_velocity_check_graph	; continue with graphical VSI
+
+TFT_velocity_check_graph:
+	btfss	velocity_active_vsi			; was the graphical VSI shown in last cycle?
+	return								; NO  - no need to clear it, done
+	;bra	TFT_velocity_clear_graph	; YES - clear it
+
+TFT_velocity_clear_graph:
+	bcf		velocity_active_vsi			; clear flag
+	btfsc	alt_layout_active			; in alternative layout?
+	return								; YES - done (not implemented)
+	WIN_BOX_BLACK dm_velocity_graph_top, dm_velocity_graph_bot, dm_velocity_graph_lft, dm_velocity_graph_rgt
+	return								; done
+
 
 ;=============================================================================
-
+tft_out10	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show Sign
+;
+	global	TFT_divemode_sign_show
+TFT_divemode_sign_show:
+	btfsc	alt_layout_active			; alternative layout active?
+	bra		TFT_divemode_sign_show_alt	; YES
+	;bra	TFT_divemode_sign_show_norm	; NO
+
+TFT_divemode_sign_show_norm:
+	WIN_TOP  dm_sign_row_norm			; set row    position
+	WIN_LEFT dm_sign_col_norm			; set column position
+	bra		TFT_divemode_sign_show_com	; continue with common part
+
+TFT_divemode_sign_show_alt:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+	btfsc	sign_shown					; NO  - sign already shown?
+	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  - 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
+	WIN_LEFT dm_sign_col_alt			;     - set column position
+	;bra	TFT_divemode_sign_show_com	;     - continue with common part
+
+TFT_divemode_sign_show_com:
+	bsf		sign_shown					; flag sign is shown
+	btfsc	sign_warning				; shall show warning sign?
+	bra		TFT_divemode_sign_show_warn	; YES - show warning sign
+	btfsc	sign_attention				; NO  - shall show attention sign?
+	bra		TFT_divemode_sign_show_att	;       YES - show attention sign
+	btfsc	sign_advice					;       NO  - shall show advice sign?
+	bra		TFT_divemode_sign_show_adv	;             YES - show advice sign
+	return								;             NO  - false alarm
+
+TFT_divemode_sign_color_warn:			; custom colors table for dive_warning2 icon - warning
+	db	.4, 0							; #colors, spare
+	dw	0x0000							; color 0x00: outside           black
+	dw	0xff80							; color 0x01: triangle          yellow
+	dw	0xff80							; color 0x02: exclamation mark  yellow
+	dw	0xf800							; color 0x03: inside            red
+
+TFT_divemode_sign_color_adv:			; custom colors table for dive_warning2 icon - advice
+	db	.4, 0							; #colors, spare
+	dw	0x0000							; color 0x00: outside           black
+	dw	0xffff							; color 0x01: triangle          white
+	dw	0xffff							; color 0x02: exclamation mark  white
+	dw	0x0780							; color 0x03: inside            green
+
+TFT_divemode_sign_show_warn:
+	TFT_WRITE_PROM_IMAGE_CUST_COLOR TFT_divemode_sign_color_warn; set custom colors for warning
+	TFT_WRITE_PROM_IMAGE_BY_LABEL   dive_warning2_block			; show sign
+	return														; done
+
+TFT_divemode_sign_show_att:
+	TFT_WRITE_PROM_IMAGE_BY_LABEL   dive_warning2_block			; show sign (with default colors)
+	return														; done
+
+TFT_divemode_sign_show_adv:
+	TFT_WRITE_PROM_IMAGE_CUST_COLOR TFT_divemode_sign_color_adv	; set custom colors for advice
+	TFT_WRITE_PROM_IMAGE_BY_LABEL   dive_warning2_block			; show sign
+	return														; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show Sign
+;
+	global	TFT_divemode_sign_clear
+TFT_divemode_sign_clear:
+	btfss	sign_shown					; is the advice/attention/warning sign shown?
+	return								; NO  - done
+	bcf		sign_shown					; YES - clear flag
+	btfsc	alt_layout_active			;     - alternative layout active?
+	bra		TFT_divemode_sign_clear_alt	;     - YES
+	;bra	TFT_divemode_sign_clear_norm;     - NO
+
+TFT_divemode_sign_clear_norm:
+	WIN_BOX_BLACK dm_sign_row_norm, dm_sign_bot_norm, dm_sign_col_norm, dm_sign_rgt_norm
+	return								; done
+
+TFT_divemode_sign_clear_alt:
+	WIN_BOX_BLACK dm_sign_row_alt, dm_sign_bot_alt, dm_sign_col_alt, dm_sign_rgt_alt
+	return								; done
+
+
+;=============================================================================
+tft_out11	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show Safety Stop
+;
+	global	TFT_safety_stop_show
+TFT_safety_stop_show:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+	btfsc	safety_stop_active			; NO  - is the safety stop shown already?
+	bra		TFT_safety_stop_show_time	;       YES - just update the time
+										;       NO  - clear area that may be polluted by alternative NDL
+	WIN_BOX_BLACK dm_safetystop_row, dm_tts_value_row, dm_ndl_value_col_alt, dm_safetystop_rgt ; top, bottom, left, right
+	bsf		safety_stop_active			;           - flag safety stop is shown now
+	WIN_STD dm_safetystop_text_column, dm_safetystop_text_row
+	FONT_COLOR_MASK						;           - set color
+	STRCPY_PRINT "Stop "				;           - print "Stop" with a trailing space to wipe away potential other remains
+
+TFT_safety_stop_show_time:
+	WIN_MEDIUM dm_safetystop_column, dm_safetystop_row
+	FONT_COLOR_ATTENTION				; set color
+	movff	safety_stop_countdown,lo	; get remaining time in seconds, low  byte, from safety stop timer
+	clrf	hi							; set remaining time in seconds, high byte, to zero
+	call	convert_time				; convert hi:lo in seconds to minutes (up:hi) and seconds (lo)
+	movff	lo,up						; save seconds in up
+	movff	hi,lo						; move minutes to lo
+	output_9							; print minutes (0-9)
+	PUTC	':'							; print ":"
+	movff	up,lo						; move seconds to lo
+	output_99x							; print seconds (00-99)
+	PRINT								; dump buffer to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - clear Safety Stop
+;
+	global	TFT_safety_stop_clear
+TFT_safety_stop_clear:
+	btfsc	dive_main_menu				; is the dive mode menu shown?
+	return								; YES - abort
+	btfss	safety_stop_active			; NO  - is the safety stop shown?
+	return								;       NO  - done, nothing to do
+										;       YES - clear safety stop area
+	WIN_BOX_BLACK dm_safetystop_row, dm_safetystop_bot, dm_safetystop_text_column, dm_safetystop_rgt ; top, bottom, left, right
+	bcf		safety_stop_active			;           - safety stop not shown any more
+	btfss	deco_region					;           - was the dive within deco stops region?
+	return								;             NO  - done
+	;bra	TFT_show_slow_reminder		;             YES - show "SLOW" reminder
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - show "slow" Reminder
+;
+TFT_show_slow_reminder:
+	WIN_STD dm_safetystop_text_column+.5,dm_safetystop_text_row+.5
+	FONT_COLOR_ATTENTION				; set color
+	STRCPY_TEXT  tSlow					; print "SLOW" reminder
+	STRCAT_PRINT 0x94					; append an up-arrow
+	return								; done
+
+
+;=============================================================================
+tft_out12	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; clear complete Message Window
+;
 	global	TFT_clear_message_window
 TFT_clear_message_window:
-	btfss	divemode							; in dive mode?
-	bra		TFT_clear_message_window_surf		; NO  - clear surface mode area
-	;bra	TFT_clear_message_window_dive		; YES - clear dive    mode area
+	btfss	divemode						; in dive mode?
+	bra		TFT_clear_message_window_surf	; NO  - clear surface mode area
+	;bra	TFT_clear_message_window_dive	; YES - clear dive    mode area
 
 TFT_clear_message_window_dive:
-	btfsc	alt_layout_active					; in alternative layout?
-	bra		TFT_clear_message_window_dive_2		; YES - clear dive mode area, 2nd  row only
-												; NO  - clear dive mode area, both rows
-	WIN_BOX_BLACK dm_warning_row, dm_warning_bot, dm_warning_column, dm_warning_rgt		; top, bottom, left, right
-	return										;           - done
+	btfsc	alt_layout_active				; in alternative layout?
+	bra		TFT_clear_message_window_dive_2	; YES - clear dive mode area, 2nd  row only
+
+	WIN_BOX_BLACK dm_warning_row, dm_warning_bot, dm_warning_column, dm_warning_rgt
+	return									; done
 
 TFT_clear_message_window_surf:
 	WIN_BOX_BLACK surf_warning1_row, surf_warning2_row+.24, surf_warning1_column, surf_warning1_column+.76	; top, bottom, left, right
-	return										; done
-
-
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; clear 2nd Line of Message Window
+;
 	global	TFT_clear_message_window_row2
 TFT_clear_message_window_row2:
-	btfss	divemode							; in dive mode?
-	bra		TFT_clear_message_window_surf_2		; NO  - clear surface mode area, 2nd row only
-	;bra	TFT_clear_message_window_dive_2		; YES - clear dive    mode area, 2nd row only
+	bcf		message_2nd_row_used			; 2nd row is cleared
+	btfss	divemode						; in dive mode?
+	bra		TFT_clear_message_window_surf_2	; NO  - clear surface mode area, 2nd row only
+	;bra	TFT_clear_message_window_dive_2	; YES - clear dive    mode area, 2nd row only
 
 TFT_clear_message_window_dive_2:
-	WIN_BOX_BLACK dm_warning2_row, dm_warning2_bot, dm_warning2_column, dm_warning2_rgt	; top, bottom, left, right
-	bcf		message_2nd_row_used				;     - 2nd row is clear now
-	return										;     - done
+	WIN_BOX_BLACK dm_warning2_row, dm_warning2_bot, dm_warning2_column, dm_warning2_rgt
+	return									; done
 
 TFT_clear_message_window_surf_2:
 	WIN_BOX_BLACK surf_warning2_row, surf_warning2_row+.24, surf_warning2_column, surf_warning2_column+.76	; top, bottom, left, right
-	bcf		message_2nd_row_used				; 2nd row is clear now
-	return										; done
-
-
-	global	TFT_fillup_with_spaces
-TFT_fillup_with_spaces:					; fill up FSR2 with spaces (total string length in #WREG)
-	movwf	lo							; save max. string length into lo
-	movf	FSR2L,W						; get current string length
-	subwf	lo,F						; lo-WREG
-	btfsc	STATUS,N					; longer then #lo already?
-	return								; YES - done
-	tstfsz	lo							; zero?
-	bra		TFT_fillup_with_spaces2		; NO
-	return								; YES - done
-TFT_fillup_with_spaces2:
-	PUTC	" "							; add one space
-	decfsz	lo,F						; all done?
-	bra		TFT_fillup_with_spaces2		; NO  - loop
-	return								; YES - done
-
-;=============================================================================
-
-	global	TFT_desaturation_time
-TFT_desaturation_time:
-	rcall	TFT_set_message_window		; set row and column for the message
+	return									; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode - Message - Desaturation
+;
+	global	TFT_surf_mesg_desat
+TFT_surf_mesg_desat:
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	call	TFT_memo_color
-	STRCPY	"Desat:"
-	MOVII	int_O_desaturation_time,mpr
-	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_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 ""
-	return
-
-
-	global	TFT_nofly_time
-TFT_nofly_time:
-	rcall	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	call	TFT_memo_color
-	movff	char_I_altitude_wait,WREG
-	tstfsz	WREG
-	bra		TFT_nofly_time_1
-	STRCPY	"NoFly:"
-	bra		TFT_nofly_time_2
-TFT_nofly_time_1:
-	STRCPY	"NoAlt:"
-TFT_nofly_time_2:
-	MOVII	int_O_nofly_time,mpr
-	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_99x							; hours
-	PUTC	':'
-	movff	hi,lo						; minutes
-	output_99x
-	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 ""
-	return
-
-;=============================================================================
-
-	global	TFT_warning_agf
-TFT_warning_agf:
-	rcall	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	call	TFT_attention_color
-	STRCPY_TEXT tDiveaGF_active			; "aGF!"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-
-	global	TFT_warning_fallback
-TFT_warning_fallback:					; show fallback warning
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	FONT_COLOR_MEMO						; select color
+	STRCPY	"Desat:"					; print label
+	MOVII	int_O_desaturation_time,mpr	; get desaturation time in minutes
+	bra		TFT_dsat_nofly_common		; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode - Message - No-Fly / NO-Altitude
+;
+	global	TFT_surf_mesg_nofly
+TFT_surf_mesg_nofly:
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	call	TFT_warning_color
-	STRCPY_TEXT tDiveFallback			; "Fallback!"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-;=============================================================================
-
- IFDEF _rx_functions
-
-	global	TFT_advice_switch
-TFT_advice_switch:
-	rcall	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	call	TFT_advice_color
-	STRCPY_TEXT tswap					; "Swap Tank"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-	global	TFT_attention_transmitter
-TFT_attention_transmitter:
-	rcall	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	call	TFT_attention_color
-	STRCPY_TEXT tTransmitter			; "P.Transm."
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-	global	TFT_attention_pres_reading
-	global	TFT_warning_pres_reading
-TFT_attention_pres_reading:				; entry point for attention
-	call	TFT_attention_color			; use attention color
-	bra		TFT_common_pres_reading		; continue with common code
-TFT_warning_pres_reading:				; entry point for warning
-	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 row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	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)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-	global	TFT_attention_sac
-TFT_attention_sac:
-	rcall	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	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
-	STRCAT	": "						; ": "
-	output_16_3							; print as xxx
-	PUTC	" "							; print a dummy char to have string termination at the correct place
-	movff	buffer+.7,buffer+.8			; move decimal digit one position to the right
-	movlw	"."							; load coding of a decimal point
-	movff	WREG,buffer+.7				; place it before decimal digit
-	STRCAT_PRINT ""						; dump buffer to screen
-	bra		TFT_warn_att_info_exit		; and return...
-
- ENDIF	; _rx_functions
-
-;=============================================================================
-
-	global	TFT_info_deco
-TFT_info_deco							; show info when decompression obligation is steady or decreasing
-	rcall	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	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
-	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...
-
-;=============================================================================
-
- IFDEF _cave_mode
-
-	global	TFT_info_cave_mode
-TFT_info_cave_mode:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	FONT_COLOR_MEMO						; select color
+	movff	char_I_altitude_wait,WREG	; get mode
+	tstfsz	WREG						; mode = altitude?
+	bra		TFT_nofly_time_alt			; YES
+	;bra	TFT_nofly_time_fly			; NO
+
+TFT_nofly_time_fly:
+	STRCPY	"NoFly:"					; print no-fly label
+	bra		TFT_nofly_time_com			; continue
+
+TFT_nofly_time_alt:
+	STRCPY	"NoAlt:"					; print no-altitude label
+	;bra	TFT_nofly_time_com			; continue
+
+TFT_nofly_time_com:
+	MOVII	int_O_nofly_time,mpr		; get no-fly time in minutes
+	;bra	TFT_dsat_nofly_common		; continue with common part
+
+
+	; Helper Function - common part for TFT_surf_mesg_desat and TFT_surf_mesg_nofly
+TFT_dsat_nofly_common:
+	call	convert_time				; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
+	movff	lo,up						; backup lo
+	movff	hi,lo						; get   hours into lo
+	output_99							; print hours (0-99)
+	PUTC	':'							; print ":"
+	movff	up,lo						; get   minutes into lo
+	output_99x							; print minutes (00-99)
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - fTTS
+;
+	global	TFT_message_ftts
+TFT_message_ftts:
+	call	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO  - skip message in this cycle
-	call	TFT_memo_color				; YES - set memo color
-	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  - 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  - skip message in this cycle
-	call	TFT_warning_color			; YES - set warning color
-	;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...
-
+
+ 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
+	bsf		leftbind					; print left-aligned
+	output_99							; print waypoint number (0-99)
+	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
-
-;=============================================================================
-
-	global	TFT_warning_saturation
-TFT_warning_saturation
-	rcall	TFT_set_message_window		; set row and column for the message
+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_4:
+	movff	char_I_extra_time,lo		; get   fTTS delay time
+	output_9							; print fTTS delay time (0-9)
+	PUTC	":"							; print ":"
+TFT_display_ftts_5:
+	MOVII	int_O_TTS_alt,mpr			; get alternative TTS
+	FONT_COLOR_MEMO						; set memo color
+	btfss	hi,int_invalid_flag			; is the invalid flag set?
+	bra		TFT_display_ftts_6			; NO  - keep memo color
+	bcf		hi,int_invalid_flag			; YES - clear flag
+	FONT_COLOR_DISABLED					;     - switch to disabled color
+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 ?
+	FONT_COLOR_ADVICE					;       YES - set to advice color (green)
+TFT_display_ftts_7:
+	bsf		leftbind					; print left-aligned
+	output_999							; print ascent time (0-999)
+	PUTC	"'"							; print minutes symbol
+	bra		TFT_message_close			; finalize message output
+TFT_display_ftts_8:
+	STRCAT	"---"						; print "---" for not computed
+	bra		TFT_message_close			; finalize message output
+TFT_display_ftts_9:
+	STRCAT_TEXT tNDL					; print "NDL"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - ppO2
+;
+	global	TFT_message_ppo2
+TFT_message_ppo2:
+	call	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	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
-	STRCPY_TEXT tSAT					; print "Sat:"
-	PUTC	" "							; add a space to align the output with other warnings' outputs
-	bsf		leftbind
-	output_8							; print value of lo only, int_O_lead_supersat is limited to 255
-	PUTC	"%"
-	movlw	dm_warning_length			; dive mode string length
-	btfss	divemode					; in dive mode?
-	movlw	surf_warning_length			; NO - use surface string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bcf		leftbind
-	bcf		win_invert
-TFT_warn_att_info_exit:
-	goto	TFT_standard_color			; and return...
-
-
-	global	TFT_warning_mbubbles
-TFT_warning_mbubbles:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	call	TFT_color_code_ppo2			; color-code output
+
+	btfsc	bailout_mode				; in bailout?
+	bra		TFT_display_diluent_oc		; YES - bailout (OC)
+	btfsc	FLAG_ccr_mode				; NO  - in CCR mode?
+	bra		TFT_display_diluent_ccr		;       YES - CCR
+	btfsc	FLAG_pscr_mode				;       NO  - in pSCR mode?
+	bra		TFT_display_diluent_pscr	;             YES - pSCR
+	;bra	TFT_display_diluent_oc		;             NO  - OC
+
+TFT_display_diluent_oc:
+	STRCPY_TEXT tppO2					; bailout or OC mode, print "ppO2:"
+	bra		TFT_display_diluent_comm	; continue with ppO2 value
+
+TFT_display_diluent_ccr:
+	STRCPY_TEXT tdil					; print "Dil:"
+	bra		TFT_display_diluent_comm	; continue with ppO2 value
+
+TFT_display_diluent_pscr:
+	STRCPY_TEXT tmix					; YES - print "Mix:"
+	;bra	TFT_display_diluent_comm	;     - continue with ppO2 value
+
+TFT_display_diluent_comm:
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_999							; print ppO2 (0.00-9.99)
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Battery
+;
+	global	TFT_message_battery_percent
+TFT_message_battery_percent:
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	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 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
-	btfss	divemode					; in dive mode?
-	movlw	surf_warning_length			; NO  - use surface string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-
-	global	TFT_warning_outside
-TFT_warning_outside:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	call	TFT_color_code_battery		; color-code according to battery_low_condition flag
+	STRCPY	"Batt:"						; print "Batt:"
+	bsf		leftbind					; print left-aligned
+	movff	batt_percent,lo				; get   battery % 
+	output_256							; print battery % (0-255)
+	PUTC	"%"							; print "%"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - current CNS
+;
+	global	TFT_message_cns
+TFT_message_cns:
+	call	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	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?
-	call	TFT_warning_color			; YES - reconfigure to warning color
-	STRCPY	"X-ZHL16-X"
-	movlw	dm_warning_length			; dive mode string length
-	btfss	divemode					; in dive mode?
-	movlw	surf_warning_length			; NO  - use surface string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-
-	global	TFT_warning_depth
-TFT_warning_depth:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	MOVII	int_O_CNS_current,mpr		; get current CNS
+	call	TFT_color_code_cns			; color-code CNS output
+	STRCPY_TEXT tCNS					; CNS:
+	bsf		leftbind					; print left-aligned
+	output_999							; print (0-999)
+	PUTC	"%"							; append unit
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - End-of-Dive CNS
+;
+	global	TFT_message_cns_eod
+TFT_message_cns_eod:
+	call	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	call	TFT_warning_color
-	STRCPY_TEXT tMaxDepth				; "max.Depth"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-
-	global	TFT_warning_gas_needs
-TFT_warning_gas_needs:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	FONT_COLOR_WARNING					; switch to warnings (red) text color
+	STRCPY_TEXT tCNSeod					; end-of-dive CNS warning text
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Saturation
+;
+	global	TFT_message_saturation
+TFT_message_saturation
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO  - skip message in this cycle
-	call	TFT_warning_color			; YES - set warning color
-	bra		TFT_warning_gas_needs_com	;     - continue with common part
-
-	global	TFT_attention_gas_needs
-TFT_attention_gas_needs:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	MOVII	int_O_lead_supersat,mpr		; get leading tissue's supersaturation
+	call	TFT_color_code_supersat		; color-code output
+	STRCPY_TEXT tSAT					; print "Sat:"
+	PUTC	" "							; add a space to align the output with other warnings' outputs
+	bsf		leftbind					; print left-aligned
+	output_256							; print value of lo only, int_O_lead_supersat is limited to 255
+	PUTC	"%"							; print "%"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - alternative GF
+;
+	global	TFT_message_agf
+TFT_message_agf:
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO  - skip message in this cycle
-	call	TFT_attention_color			; YES - set attention color
-	;bra	TFT_warning_gas_needs_com	;     - continue with common part
-
-TFT_warning_gas_needs_com:
-	STRCPY_TEXT tGasNeedsWarn			; print "Gas Needs"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""						; finalize output
-	bra		TFT_warn_att_info_exit		; and return...
-
-;=============================================================================
-
- IFDEF _helium
-
-	global	TFT_warning_IBCD
-TFT_warning_IBCD:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	FONT_COLOR_ATTENTION				; set attention color
+	STRCPY_TEXT tDiveaGF_active			; print "aGF!"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Dive Timeout
+;
+	global	TFT_message_divetimeout
+TFT_message_divetimeout:
+	call	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
 	return								; NO - skip message in this cycle
-	call	TFT_attention_color			; select attention color as default
-	STRCPY_TEXT tIBCD					; "IBCD N2He"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
- ENDIF
-
-;=============================================================================
-
-	global	TFT_warning_no_BO_gas
-TFT_warning_no_BO_gas:
-	rcall	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	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
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""						; finalize output
-	bra		TFT_warn_att_info_exit		; and return...
-
-
-	global	TFT_advice_gas_change
-TFT_advice_gas_change:
-	rcall	TFT_set_message_window		; set row and column for the message
+
+	FONT_COLOR_MEMO						; select color
+	STRCPY	0x94						; "End of dive" symbol (up-arrow)
+	movff	opt_diveTimeout,WREG		; get timeout in minutes
+	mullw	.60							; get timeout in seconds
+	MOVII	PRODL,             sub_a	; calculate timeout - elapsed time = countdown
+	MOVII	dive_timeout_timer,sub_b	; ...
+	call	subU16						; ...
+	MOVII	sub_c,mpr					; transfer to mpr
+	call	convert_time				; convert hi:lo in seconds to minutes (up:hi) and seconds (lo)
+	movff	lo,up						; back-up lo
+	movff	hi,lo						; get   minutes
+	output_99							; print minutes (0-99)
+	PUTC	':'							; print ":"
+	movff	up,lo						; get   seconds
+	output_99x							; print seconds (00-99)
+	movlw	dm_warning_length			; get dive mode string length
+	rcall	TFT_buffer_trim_length		; fill / cut buffer to target length
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Gas Needs
+;
+	global	TFT_message_gas_needs
+TFT_message_gas_needs:
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	call	TFT_advice_color			; set advice color
-	STRCPY_TEXT tgaschange				; "Change?"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
-;=============================================================================
-
- IFDEF _external_sensor
-
-	global	TFT_warning_sensor_disagree
-TFT_warning_sensor_disagree:
-	rcall	TFT_set_message_window		; set row and column for the message
+	return								; NO  - skip message in this cycle
+
+	btfsc	attn_det_gas_needs			; attention?
+	FONT_COLOR_ATTENTION				; YES - set attention color
+	btfsc	warn_det_gas_needs			; warning?
+	FONT_COLOR_WARNING					; YES - set warning color
+	STRCPY_TEXT tGasNeedsWarn			; print "Gas Needs"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Gas Change
+;
+	global	TFT_message_gas_change
+TFT_message_gas_change:
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	call	TFT_warning_color
-	STRCPY_TEXT tSensorDisagree			; "Sensors<>"
-	movlw	dm_warning_length			; dive mode string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""
-	bra		TFT_warn_att_info_exit		; and return...
-
- ENDIF	; _external_sensor
-
-;=============================================================================
-
-TFT_set_message_window:						; sets the row and column for the current message
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_ADVICE					; set advice color
+	STRCPY_TEXT tgaschange				; print "Change?"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - no Bailout Gas
+;
+	global	TFT_message_no_BO_gas
+TFT_message_no_BO_gas:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_WARNING					; set warning color
+	STRCPY_TEXT tnoBOgas				; print "-B/O-Gas-"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Message - open Message
+;
+; sets the row and column for the current message
+;
+TFT_message_open:
 	; ignore warning (now)?
 	decf	message_counter,W				; load (message counter - 1) into WREG
 	bcf		STATUS,C						; clear carry bit
@@ -4397,618 +3178,523 @@
 
 ; Dive Mode
 TFT_set_message_window_dm:
-	btfsc	alt_layout_active							; in alternative layout?
-	bra		TFT_set_message_window_dm_row2				; YES - alternative layout only uses 2nd row
-	btfss	message_counter,0							; NO  - is the message number uneven?
-	bra		TFT_set_message_window_dm_row2				;       NO  - use 2nd row
-	;bra	TFT_set_message_window_dm_row1				;       YES - use 1st row
+	btfsc	alt_layout_active				; in alternative layout?
+	bra		TFT_set_message_window_dm_row2	; YES - alternative layout only uses 2nd row
+	btfss	message_counter,0				; NO  - is the message number uneven?
+	bra		TFT_set_message_window_dm_row2	;       NO  - use 2nd row
+	;bra	TFT_set_message_window_dm_row1	;       YES - use 1st row
 
 TFT_set_message_window_dm_row1:
-	WIN_SMALL dm_warning1_column, dm_warning1_row		; set output position
-	bcf		message_2nd_row_used						; flag that the 2nd does not contain a message yet
-	retlw	.0											; show in this cycle (message window is defined)
+	WIN_SMALL dm_warning1_column, dm_warning1_row
+	bcf		message_2nd_row_used			; flag that the 2nd does not contain a message yet
+	retlw	.0								; show in this cycle (message window is defined)
 
 TFT_set_message_window_dm_row2:
-	WIN_SMALL dm_warning2_column, dm_warning2_row		; set output position
-	bsf		message_2nd_row_used						; flag that the 2nd row contains a message now
-	retlw	.0											; show in this cycle (message window is defined)
+	WIN_SMALL dm_warning2_column, dm_warning2_row
+	bsf		message_2nd_row_used			; flag that the 2nd row contains a message now
+	retlw	.0								; show in this cycle (message window is defined)
 
 ; Surface Mode
 TFT_set_message_window_sf:
-	btfss	message_counter,0							; is the message counter uneven?
-	bra		TFT_set_message_window_sf_row2				; NO  - use 2nd row
-	;bra	TFT_set_message_window_sf_row1				; YES - use 1st row
+	btfss	message_counter,0				; is the message counter uneven?
+	bra		TFT_set_message_window_sf_row2	; NO  - use 2nd row
+	;bra	TFT_set_message_window_sf_row1	; YES - use 1st row
 
 TFT_set_message_window_sf_row1:
-	WIN_SMALL surf_warning1_column,surf_warning1_row	; set output position
-	bcf		message_2nd_row_used						; flag that the 2nd row does not contain a message yet
-	retlw	.0											; show in this cycle (message window is defined)
+	WIN_SMALL surf_warning1_column,surf_warning1_row
+	bcf		message_2nd_row_used			; flag that the 2nd row does not contain a message yet
+	retlw	.0								; show in this cycle (message window is defined)
 
 TFT_set_message_window_sf_row2:
-	WIN_SMALL surf_warning2_column,surf_warning2_row	; set output position
-	bsf		message_2nd_row_used						; flag that the 2nd row contains a message now
-	retlw	.0											; show in this cycle (message window is defined)
-
-
-	global	TFT_msg_batt_percent_divemode
-TFT_msg_batt_percent_divemode:
-	rcall	TFT_set_message_window		; set row and column for the message
+	WIN_SMALL surf_warning2_column,surf_warning2_row
+	bsf		message_2nd_row_used			; flag that the 2nd row contains a message now
+	retlw	.0								; show in this cycle (message window is defined)
+
+
+;-----------------------------------------------------------------------------
+; Message - fill to a given Length, or cut if too long
+;
+; Input: buffer  message
+;        WREG    max length
+;
+	global	TFT_buffer_trim_length
+TFT_buffer_trim_length:
+	movwf	lo							; copy max.   string length to lo
+	movf	FSR2L,W						; get current string length to WREG
+	subwf	lo,F						; lo = max length - current length
+	bn		TFT_fillup_with_spaces_cut	; string too long        -> cut string at max length
+	bnz		TFT_fillup_with_spaces_apnd	; string too short       -> append spaces and string terminator
+	bra		TFT_fillup_with_spaces_term	; string at exact length -> append            string terminator
+
+TFT_fillup_with_spaces_apnd:
+	PUTC	" "							; add one space
+	decfsz	lo,F						; all spaces done?
+	bra		TFT_fillup_with_spaces_apnd	; NO  - loop
+	bra		TFT_fillup_with_spaces_term	; YES - append string terminator
+
+TFT_fillup_with_spaces_cut:
+	movf	lo,W						; get over-length (as negative number) into WREG
+	addwf	FSR2L,F						; set back buffer pointer to end of max length
+	;bra	TFT_fillup_with_spaces_term	; append string terminator
+
+TFT_fillup_with_spaces_term:
+	clrf	INDF2						; append string terminator
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Message - close Message
+;
+TFT_message_close:
+	movlw	surf_warning_length			; get surface string length
+	btfsc	divemode					; in dive mode?
+	movlw	dm_warning_length			; YES - replace by dive mode string length
+	rcall	TFT_buffer_trim_length		; fill / cut buffer to target length
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Micro-Bubbles
+;
+	global	TFT_message_mbubbles
+TFT_message_mbubbles:
+	rcall	TFT_message_open			; set row and column for the message
 	tstfsz	WREG						; is there room for the message?
-	return								; NO - skip message in this cycle
-	movff	batt_percent,lo				; get battery percent
-	call	TFT_color_code_battery		; color-code battery percent
-	STRCPY	"Batt:"
-	bsf		leftbind
-	output_8
-	bcf		leftbind
-	PUTC	"%"
-	movlw	dm_warning_length			; dive mode string length
-	btfss	divemode					; in dive mode?
-	movlw	surf_warning_length			; NO - use surface string length
-	rcall	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in #WREG)
-	STRCAT_PRINT ""
-	bcf		win_invert
-	bra		TFT_custview_exit1			; and return...
-
-
-	global	TFT_gf_factors_mask			; mask for GF factors
-TFT_gf_factors_mask:
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_gf_column1,dm_custom_gf_title_row
-	STRCPY_TEXT_PRINT tGFactors
-	WIN_TINY dm_custom_gf_column3,dm_custom_gf_title_row
-	STRCPY_TEXT_PRINT taGFactors
-	; Show GF (static)
-	call	TFT_disabled_color			; default to disabled color
-	btfss	use_aGF						; shall use alternative GF factors?
-	call	TFT_memo_color				; NO - switch to memo color
-	WIN_STD	dm_custom_gf_column1, dm_custom_gf_row
-	bsf		leftbind
-	movff	opt_GF_low,lo				; get   normal GF low
-	output_8							; print normal GF low
-	PUTC	"/"							; print "/"
-	movff	opt_GF_high,lo				; get   normal GF high
-	output_8							; print normal GF high
-	STRCAT_PRINT ""						; finish output
-	; Show aGF (static)
-	call	TFT_memo_color				; default to memo color
-	TSTOSS	opt_enable_aGF				; are alternative GF factors enabled?
-	bra		TFT_gf_factors_mask_3		; NO  - show "---" and return
-										; YES - show aGF and which one is active
-	WIN_STD	dm_custom_gf_column2, dm_custom_gf_row
-	btfss	use_aGF						; shall use aGF?
-	bra		TFT_gf_factors_mask_1		; NO   - print "<- "
-	STRCPY_PRINT " ->"					; YES  - print " ->"
-	bra		TFT_gf_factors_mask_2		;      - continue with common part
-TFT_gf_factors_mask_1:
-	STRCPY_PRINT "<- "					; (NO) - print "<- "
-TFT_gf_factors_mask_2:					; common part
-	btfss	use_aGF						; shall use aGF?
-	call	TFT_disabled_color			; NO - switch to disabled color
-	WIN_STD	dm_custom_gf_column3, dm_custom_gf_row
-	movff	opt_aGF_low,lo				; get aGF low
-	output_8							; print 
-	PUTC	"/"							; print "/"
-	movff	opt_aGF_high,lo				; get aGF high
-	output_8							; print
-	STRCAT_PRINT ""						; finish output
-	bra		TFT_custview_exit1			; done
-TFT_gf_factors_mask_3:
-	WIN_STD	dm_custom_gf_column3+.10, dm_custom_gf_row
-	STRCPY_PRINT "---"
-	bra		TFT_custview_exit1			; done
-
-
-	global	TFT_ceiling_GF_tissue_mask	; mask for ceiling, current GF and tissues
-TFT_ceiling_GF_tissue_mask:
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_ceiling_column+.2,dm_custom_ceiling_title_row
-	STRCPY_TEXT_PRINT tCeiling
-	WIN_TINY dm_custom_tissue_title_column, dm_custom_tissue_title_row
-	STRCPY_TEXT_PRINT tDiveTissues
-	WIN_TINY dm_custom_gf_column1+.5, dm_custom_gf_title_row
-	STRCPY_TEXT_PRINT tGFInfo
-	bra		TFT_custview_exit1			; and return...
-
-
-	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			; 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_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:
-	STRCAT_PRINT " "
-	; Show tissue diagram
-	call	TFT_dive_tissues			; show tissue pressure diagram
-	; Show current supersaturation
-	WIN_MEDIUM dm_custom_clock_column+.3, dm_custom_gf_row
-	MOVII	int_O_lead_supersat,mpr		; bank-safe copy of leading tissue's supersaturation
-	call	TFT_color_code_gf			; color-code output
-	output_8							; need to print lo only, int_O_lead_supersat value is limited to 255
-	STRCAT_PRINT ""
-	WIN_STD	dm_custom_clock_column+.40, dm_custom_gf_row+.5
-	STRCAT_PRINT "%"					; % is printed in color set by TFT_color_code_gf, too
-TFT_custview_exit1:
-	bcf		leftbind
-	goto	TFT_standard_color			; and return...
-
-
-	global	TFT_clock_batt_surfpress_mask ; mask for clock, battery and surface pressure
-TFT_clock_batt_surfpress_mask:
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_clock_column, dm_custom_clock_title_row
-	STRCPY_TEXT_PRINT tTime				; "Time"
-	WIN_TINY dm_custom_battery_column, dm_custom_battery_title_row
-	STRCPY_TEXT_PRINT tBattery			; "Battery"
-	WIN_TINY dm_custom_surfpres_column+.8, dm_custom_surfpres_title_row
-	STRCPY_TEXT_PRINT tSurface			; "Surface"
-	; Show configured Surface Pressure (done in mask, because it's static during the dive)
-	call	TFT_standard_color
-	WIN_SMALL dm_custom_surfpres_column, dm_custom_surfpres_row
-	MOVII	pressure_surf,mpr
-	output_16
-	PUTC	' '
-	STRCAT_TEXT_PRINT tMBAR				; mbar (hPa)
-	bra		TFT_custview_exit1			; and return...
-
-
-	global	TFT_clock_batt_surfpress	; data for clock, battery and surface pressure
-TFT_clock_batt_surfpress:
-	; Update Clock
-	WIN_SMALL dm_custom_clock_column, dm_custom_clock_row
-	call	TFT_standard_color
-	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
-	movff	rtc_latched_hour,lo
-	output_99
-	PUTC	':'
-	movff	rtc_latched_mins,lo
-	output_99x
-	PUTC	":"
-	movff	rtc_latched_secs,lo
-	output_99x
-	STRCAT_PRINT ""
-	; Show Battery Volt
-	call	TFT_memo_color
-	WIN_SMALL dm_custom_battery_column, dm_custom_battery_volt_row
-	MOVII	batt_voltage,mpr
-	bsf		leftbind
-	output_16dp .2						; print as -x.yyy
-	PUTC	'V'
-	movff	buffer+5,buffer+4
-	movlw	0x00
-	movff	WREG,buffer+5				; only "x.yzV"
-	STRCAT_PRINT ""
-	; Show Battery Percent
-	WIN_SMALL dm_custom_battery_column+.7, dm_custom_battery_percent_row
-	movff	batt_percent,lo				; get battery percent
-	call	TFT_color_code_battery		; color-code battery percent
-	output_8
-	STRCAT	"% "
-	movlw	0x00
-	movff	WREG,buffer+4				; only "xxx%"
-	STRCAT_PRINT ""
-	; Surface pressure is shown in mask because it is static
-	bra		TFT_custview_exit1			; and return...
-
-;=============================================================================
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_ATTENTION				; set attention color as default
+	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
+	btfsc	WREG,mbubble_warning		; currently in the micro bubbles zone?
+	FONT_COLOR_WARNING					; YES - reconfigure to warning color
+	STRCPY_TEXT tMicroBubbles			; print message text
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Outside Buhlmann Model
+;
+	global	TFT_message_outside
+TFT_message_outside:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_ATTENTION				; set attention color
+	movff	char_O_deco_warnings,WREG	; bank-safe copy for deco warnings
+	btfsc	WREG,outside_warning		; currently outside the ZH-L16 model?
+	FONT_COLOR_WARNING					; YES - reconfigure to warning color
+	STRCPY	"X-ZHL16-X"					; print message text
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Depth Limit
+;
+	global	TFT_message_depth_limit
+TFT_message_depth_limit:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_WARNING					; set warning color
+	STRCPY_TEXT tMaxDepth				; print "max.Depth"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Deco Info
+;
+	global	TFT_message_deco_info
+TFT_message_deco_info
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_ADVICE					; actually it is a memo, but we break the rules here and display in advice color (green)
+	STRCPY_TEXT tDecoInfo				; write "Deco Zone"
+	bra		TFT_message_close			; finalize message output
+
+
+ IFDEF _helium
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - IBCD
+;
+	global	TFT_message_IBCD
+TFT_message_IBCD:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_ATTENTION				; set attention color
+	STRCPY_TEXT tIBCD					; Print "IBCD N2He"
+	bra		TFT_message_close			; finalize message output
+
+ ENDIF	; _helium
 
  IFDEF _ccr_pscr
 
-	global	TFT_pscr_info_mask			; mask for pSCR info
-TFT_pscr_info_mask:
-	rcall	TFT_show_ppo2_mask
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_pscr_drop_column, dm_custom_pscr_title_row
-	STRCPY_TEXT_PRINT tPSCR_O2_drop
-	WIN_TINY dm_custom_pscr_ratio_column, dm_custom_pscr_title_row
-	STRCPY_TEXT_PRINT tPSCR_lungratio
-	bra		TFT_custview_exit1			; and return...
-
-
-	global	TFT_pscr_info				; data for pSCR info
-TFT_pscr_info:
-	;show ppO2
-	WIN_MEDIUM dm_custom_ppo2_column,dm_custom_ppo2_row
-	MOVII	int_O_pSCR_ppO2,mpr			; copy pSCR ppO2 to hi:lo
-	call	TFT_color_code_ppo2			; color-code output
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	STRCAT_PRINT ""
-	; Show drop
-	WIN_STD dm_custom_pscr_drop_column+.11,dm_custom_pscr_row
-	call	TFT_memo_color
-	movff	char_I_PSCR_drop,lo
-	bsf		leftbind
-	output_8
-	STRCAT_PRINT "%"
-	; Show lung ratio
-	WIN_STD dm_custom_pscr_ratio_column+.5,dm_custom_pscr_row
-	movff	char_I_PSCR_lungratio,lo
-	bsf		leftbind
-	STRCPY	"1/"
-	output_8
-	STRCAT_PRINT ""
-	bra		TFT_custview_exit1			; and return...
-
- ENDIF	; _ccr_psrc
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Gas Density
+;
+	global	TFT_message_gas_density
+TFT_message_gas_density:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	btfsc	attn_det_gas_density		; on attention level?
+	FONT_COLOR_ATTENTION				; YES - set attention color
+	btfsc	warn_det_gas_density		; on warning level?
+	FONT_COLOR_WARNING					; YES set warning color
+	STRCPY_TEXT tGasDensity				; print "G.Density"
+	bra		TFT_message_close			; finalize message output
+
+ ENDIF	; _ccr_pscr
+
+ IFDEF _external_sensor
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Sensor ppO2 Divergence
+;
+	global	TFT_message_divergence
+TFT_message_divergence:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_WARNING					; set warning color
+	STRCPY_TEXT tSensorDisagree			; print "Sensors<>"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Fallback
+;
+	global	TFT_message_fallback
+TFT_message_fallback:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_WARNING					; set warning color
+	STRCPY_TEXT tDiveFallback			; print "Fallback!"
+	bra		TFT_message_close			; finalize message output
+
+ ENDIF	; _external_sensor
+
+ IFDEF _rx_functions
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - TR - Transmitter
+;
+	global	TFT_message_transmitter
+TFT_message_transmitter:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_ATTENTION				; set attention color
+	STRCPY_TEXT tTransmitter			; print "P.Transm."
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - TR - Pressure
+;
+	global	TFT_message_pressure
+TFT_message_pressure:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	btfsc	attn_det_pressure1			; on attention level - pressure 1 ?
+	FONT_COLOR_ATTENTION				; YES - set attention color
+	btfsc	attn_det_pressure2			; on attention level - pressure 2 ?
+	FONT_COLOR_ATTENTION				; YES - set attention color
+	btfsc	warn_det_pressure1			; on warning   level - pressure 1 ?
+	FONT_COLOR_WARNING					; YES - set warning color
+	btfsc	warn_det_pressure2			; on warning   level - pressure 2 ?
+	FONT_COLOR_WARNING					; YES - set warning color
+	STRCPY_TEXT tPressure				; print "Tank Pres"
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - TR - SAC
+;
+	global	TFT_message_sac
+TFT_message_sac:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	MOVII	int_O_SAC_measured,mpr		; copy measured SAC rate to hi:lo
+	call	TFT_color_code_pres_sac		; color-code the output
+	STRCPY_TEXT tSAC					; print "SAC" (needs to be exactly 3 chars long)
+	STRCAT	": "						; print ": "
+	bsf		decimal_digit1				; place a decimal point in front of digit 1
+	output_999							; print (0.0-99.9)
+	bra		TFT_message_close			; finalize message output
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - TR - switch Tank Advice
+;
+	global	TFT_message_switch_tanks
+TFT_message_switch_tanks:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	FONT_COLOR_ADVICE					; set advice color
+	STRCPY_TEXT tswap					; print "Swap Tank"
+	bra		TFT_message_close			; finalize message output
+
+ ENDIF	; _rx_functions
+
+ IFDEF _cave_mode
+ 
+;-----------------------------------------------------------------------------
+; Dive Mode - Message - Cave Mode
+;
+	global	TFT_message_cave_mode
+TFT_message_cave_mode:
+	rcall	TFT_message_open			; set row and column for the message
+	tstfsz	WREG						; is there room for the message?
+	return								; NO  - skip message in this cycle
+
+	btfss	attn_det_cave_shut_down		; on attention level?
+	bra		TFT_message_cave_mode_1		; NO
+	FONT_COLOR_ATTENTION				; YES - select attention color
+	bra		TFT_message_cave_mode_sd	;     - print shutdown message
+
+TFT_message_cave_mode_1:
+	btfss	warn_det_cave_shut_down		; on warning level?
+	bra		TFT_message_cave_mode_info	; NO
+	FONT_COLOR_WARNING					; YES - select warning color
+	;bra	TFT_message_cave_mode_sd	;     - print shutdown message
+
+TFT_message_cave_mode_sd:
+	STRCPY_TEXT tCaveModeShutdown		; print "X-Cave-X"
+	bra		TFT_message_close			; finalize message output
+
+TFT_message_cave_mode_info:
+	FONT_COLOR_MEMO						; set memo color
+	bsf		win_invert					; print in inverse
+	STRCPY_TEXT tCaveMode				; write "Cave Mode"
+	bra		TFT_message_close			; finalize message output
+
+ ENDIF	; _cave_mode
+
 
 ;=============================================================================
-
-	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
-	movff	char_O_deco_info,WREG		; get the deco info vector
-	btfss	WREG,gas_needs_cave			; are the gas needs calculated for cave mode?
-	bra		TFT_gas_needs_mask_ascent_1	; NO  - show as direct ascent needs
-	bsf		gas_needs_mode_last			; YES - remember last results were for cave mode
-	STRCPY_TEXT tGasNeedsCaveMode		;     - "Gas Needs Cave Mode"
-	bra		TFT_gas_needs_mask_ascent_2
-TFT_gas_needs_mask_ascent_1:
-	bcf		gas_needs_mode_last			; remember last results were for direct ascent
-	STRCPY_TEXT tGasNeedsAscent			; "Gas Needs Ascent"
-TFT_gas_needs_mask_ascent_2:
- 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				; 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?
-	bra		TFT_gas_needs_ascent_1		; NO  - continue below...
-	btfsc	gas_needs_mode_last			; YES - were the last results calculated for cave mode?
-	bra		TFT_gas_needs_ascent_3		;       YES - mask still valid
-	bra		TFT_gas_needs_ascent_2		;       NO  - redraw mask
-TFT_gas_needs_ascent_1:
-	btfss	gas_needs_mode_last			; NO  - were the last results calculated for direct ascent?
-	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_mask			; redraw mask
-TFT_gas_needs_ascent_3:
- ENDIF
-	clrf	up							; initialize gas index (0-4)
-	WIN_SMALL dm_custom_gas_column1+.5,dm_custom_gas_row1
-	rcall	TFT_gas_needs_helper
-	WIN_SMALL dm_custom_gas_column1+.5,dm_custom_gas_row2
-	rcall	TFT_gas_needs_helper
-	WIN_SMALL dm_custom_gas_column2+.5,dm_custom_gas_row1
-	rcall	TFT_gas_needs_helper
-	WIN_SMALL dm_custom_gas_column2+.5,dm_custom_gas_row2
-	rcall	TFT_gas_needs_helper
-	bra		TFT_custview_exit2			; and return...
-
-TFT_gas_needs_helper:
-	call	TFT_memo_color
-	movlw	.5							; number of gases
-	cpfslt	up							; check if all gases have been processed
-	bra		TFT_gas_needs_helper_1		; YES - clear display area
-	movf	up,W						; NO  - get gas number and check if need of that gas is > 0
-	rlncf	WREG,W						; multiply by 2
-	incf	WREG,W						; add 1 to address high byte
-	lfsr	FSR1,int_O_gas_need_pres	; load base of gas needs in pressure
-	movff	PLUSW1,hi					; read HIGH(int_O_gas_need_pres[up])
-	btfss	hi,int_is_zero				; check flag for pres_need == 0
-	bra		TFT_gas_needs_helper_2		; NO  - print gas type and pressure needed
-	incf	up,F						; YES - increment to next gas...
-	bra		TFT_gas_needs_helper		; ...and try the next gas
-TFT_gas_needs_helper_1:					; no gases to show anymore, clear display area from potential remains of last invocation
-	STRCAT_PRINT "  ----   "			; overwrite outdated stuff if screen position is not needed
-	return
-TFT_gas_needs_helper_2:					; output gas type and pressure needed
-	movf	up,W						; get gas number (0-4) to WREG
-	lfsr	FSR1,opt_gas_O2_ratio		; read opt_gas_O2_ratio[WREG]
-	movff	PLUSW1,lo					; copy result to lo
-	lfsr	FSR1,opt_gas_He_ratio		; read opt_gas_He_ratio[WREG]
-	movff	PLUSW1,hi					; copy result to hi
-	call	gaslist_show_mix			; print "Air", "O2", "21/35", etc.
-	PUTC	':'							; ":"
-	movf	up,W						; get gas number (0-4) to WREG
-	rlncf	WREG,W						; multiply by 2
-	lfsr	FSR1,int_O_gas_need_pres	; load base of gas needs in pressure
-	movff	PLUSW1,lo					; read LOW(int_O_gas_need_pres[up])
-	incf	WREG,W						; add 1 to address high byte
-	movff	PLUSW1,hi					; read HIGH(int_O_gas_need_pres[up])
-	btfsc	hi,int_attention_flag		; check if attention flag is set (pres_need > pres_fill * threshold)
-	call	TFT_attention_color			; YES - print gas need in attention color
-	btfsc	hi,int_warning_flag			; check if warning   flag is set (pres_need > pres_fill)
-	call	TFT_warning_color			; YES - print gas need in warning color
-	movff	int_O_gas_need_pres+1,WREG	; get HIGH(int_O_gas_need_pres[0]) which holds flag for invalid data
-	btfsc	WREG,int_invalid_flag		; check if invalid data flag is set
-	call	TFT_disabled_color			; YES - print gas need in disabled color
-	bcf		hi,int_attention_flag		; clear flag for attention
-	bcf		hi,int_warning_flag			; clear flag for warning
-	bcf		hi,int_high_flag			; clear flag for > 999 bar
-	bcf		hi,int_invalid_flag			; clear flag for invalid data (will actually only be set with 1st gas)
-	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
-	return								; done
-
-
-	global	TFT_show_ppo2_mask			; helper function for several custom views
-TFT_show_ppo2_mask:
-	call	TFT_divemask_color
- IFDEF _ccr_pscr
-	btfss	FLAG_ccr_mode				; in CCR mode?
-	bra		TFT_mask_ppo2a				; NO  - continue checking for pSCR and OC
-	btfsc	bailout_mode				; YES - in bailout?
-	bra		TFT_mask_ppo2b				;       YES
-	WIN_TINY dm_custom_ppo2_column-.2,dm_custom_ppo2_title_row	; tuned position for longer text (-8 = on leftmost edge of display)
-	STRCPY_TEXT_PRINT tppO2Dil			;       NO  - print "ppO2(Dil)"
-	bra		TFT_custview_exit2			;           - and return...
-TFT_mask_ppo2a:
-	btfss	FLAG_pscr_mode				; in pSCR mode?
-	bra		TFT_mask_ppo2b				; NO  - continue with OC mode (or bailout)
-	btfsc	bailout_mode				; YES - in bailout?
-	bra		TFT_mask_ppo2b				;       YES
-	WIN_TINY dm_custom_ppo2_column-.2,dm_custom_ppo2_title_row	; tuned position for longer text (-8 = on leftmost edge of display)
-	STRCPY_TEXT_PRINT tppO2Mix			;       NO  - print "ppO2(Mix)"
-	bra		TFT_custview_exit2			;           - and return...
- ENDIF
-TFT_mask_ppo2b:							; OC mode or bailout
-	WIN_TINY dm_custom_ppo2_column-.2, dm_custom_ppo2_title_row	; normal position
-	STRCPY_TEXT_PRINT tppO2				; in all other modes
-	bra		TFT_custview_exit2			; and return...
-
-
-	global TFT_ppo2_ead_end_cns_mask	; mask for ppO2, END/EAD and CNS / gas density
-TFT_ppo2_ead_end_cns_mask:
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_ppo2_column-.2, dm_custom_ppo2_title_row
-	STRCPY_TEXT_PRINT tppO2
-	WIN_TINY dm_custom_ead_column,     dm_custom_eadend_title_row
-	STRCPY_TEXT_PRINT tDiveEAD_END
- IFDEF _helium
-	WIN_TINY dm_custom_cns_column-.5,  dm_custom_eadend_title_row
-	STRCPY_TEXT_PRINT tGasDensity
- ELSE
-	WIN_TINY dm_custom_cns_column,     dm_custom_cns_title_row
-	STRCPY_TEXT_PRINT tCNS2
- ENDIF
-	bra		TFT_custview_exit2			; and return...
-
-
-	global	TFT_ppo2_ead_end_cns		; data for ppO2, END/EAD and CNS / gas density
-TFT_ppo2_ead_end_cns:
-	; Show ppO2
-	WIN_MEDIUM dm_custom_ppo2_column, dm_custom_ppo2_row
-	MOVII	int_O_breathed_ppO2,mpr		; copy ppO2 of the currently breathed gas to hi:lo
-	call	TFT_color_code_ppo2			; color-code output
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	STRCAT_PRINT ""
-	call	TFT_standard_color
-	; Show END/EAD
-	WIN_SMALL	dm_custom_ead_column, dm_custom_ead_row
-	STRCPY_TEXT tEAD					; EAD:
-	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:
-	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
-	MOVII	int_O_gas_density,mpr		; get current gas density
-	call	TFT_color_code_cns_1		; color-code output
-	bsf		leftbind					; print left-aligned
-	movlw	.2							; suppress first and second digit
-	movwf	ignore_digits				; ...
-	output_16dp .2						; print as -x.yyy
-	bcf		leftbind					; back to normal alignment
-	STRCAT_PRINT	""					; finalize output
- ELSE
-	; Show CNS
-	WIN_STD	dm_custom_cns_column+.3, dm_custom_cns_row
-	MOVII	int_O_CNS_current,mpr		; get current CNS
-	call	TFT_color_code_cns			; color-code CNS output
-	bsf		leftbind
-	output_16_3							; displays only 0...999
-	bcf		leftbind
-	STRCAT_PRINT "%"
- ENDIF
-TFT_custview_exit2:
-	goto	TFT_standard_color			; and return...
-
-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	; 0: meter
-	;bra	TFT_end_ead_common_imperial	; 1: feet
-
-TFT_end_ead_common_imperial:
-	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:
-	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:
-	STRCAT_PRINT ""						; finalize output
-	return								; done
-
+tft_out13	CODE
 ;=============================================================================
 
- IFDEF _ccr_pscr
-
-	global	TFT_sensor_check_mask		; mask for sensor check
-TFT_sensor_check_mask:
-	call	TFT_divemask_color
-	WIN_TINY dm_custom_s_check_title_column, dm_custom_s_check_title_row
-	STRCPY_TEXT_PRINT tSensorCheck
-	WIN_TINY dm_custom_ppO2_column, dm_custom_s_check_title_row
-	STRCPY_TEXT_PRINT tppO2O2
-	WIN_TINY dm_custom_ppDil_column, dm_custom_s_check_title_row
-	STRCPY_TEXT_PRINT tppO2Dil
-	bra		TFT_sensor_check_exit		; and return...
-
-
-	global	TFT_sensor_check			; data for sensor check
-TFT_sensor_check:
-	; Show ppO2 of O2 in this depth
-	WIN_MEDIUM dm_custom_ppO2_column, dm_custom_s_check_row
-	MOVII	int_O_O2_ppO2,mpr			; copy ppO2 of pure O2 to hi:lo
-	call	TFT_color_code_ppo2			; color-code output
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	STRCAT_PRINT ""
-	; Show ppO2 of the diluent in this depth
-	WIN_MEDIUM	dm_custom_ppDil_column, dm_custom_s_check_row
-	MOVII	int_O_pure_ppO2,mpr			; copy ppO2 of pure gas to hi:lo
-	call	TFT_color_code_ppo2			; color-code output
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	STRCAT_PRINT ""
-TFT_sensor_check_exit:
-	bra		TFT_custview_exit2			; and return...
-
- ENDIF	; _ccr_pscr
-
-;=============================================================================
-
-	global	TFT_surface_lastdive
-TFT_surface_lastdive:
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - Last Dive Summery
+;
+	global	TFT_surf_cv_lastdive
+TFT_surf_cv_lastdive:
+	FONT_COLOR_MEMO						; set color
+
 	WIN_TINY surf_gaslist_column,surf_gaslist_row+.5
-	STRCAT_TEXT_PRINT	tLastDive			; "Last Dive:"
+	STRCAT_TEXT_PRINT	tLastDive		; "Last Dive:"
+
 	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)+.5
-	STRCAT_TEXT_PRINT	tDivetime			; "Divetime:"
+	STRCAT_TEXT_PRINT	tDivetime		; "Divetime:"
+
 	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)+.5
-	STRCAT_TEXT_PRINT	tMaxDepth			; "Max.Depth"
+	STRCAT_TEXT_PRINT	tMaxDepth		; "Max.Depth"
+
 	WIN_TINY surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)+.5
-	STRCAT_TEXT_PRINT	tAvgDepth			; "Average"
+	STRCAT_TEXT_PRINT	tAvgDepth		; "Average"
 
 	WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row
-	SMOVII	int_O_desaturation_time,mpr		; ISR-safe copy of the desaturation time
-	movf	mpr+0,W							; get low byte into WREG
-	iorwf	mpr+1,W							; inclusive-or with high byte, check if desaturation time is zero
-	bz		TFT_surface_lastdive_1			; YES - show last dive time
-											; NO  - show surface interval
-	SMOVII	surface_interval_mins,mpr		;     - ISR-safe copy of surface interval in minutes
-	call	convert_time					;     - convert hi:lo in minutes to hours (up:hi) and minutes (lo)
-	movf	hi,W							;     - swap hi and lo
-	movff	lo,hi							;       ...
-	movwf	lo								;       ...
-	bsf		leftbind						;
-	output_99x								;
-	PUTC	'h'								;
-	movff	hi,lo							;
-	output_99x								;
-	STRCAT_PRINT "m "						;
-	bra		TFT_surface_lastdive_2			;
+	SMOVII	int_O_desaturation_time,mpr	; ISR-safe copy of the desaturation time
+	movf	mpr+0,W						; get low byte into WREG
+	iorwf	mpr+1,W						; inclusive-or with high byte, check if desaturation time is zero
+	bz		TFT_surface_lastdive_2		; YES - show last dive time
+	;bra	TFT_surface_lastdive_1		; NO  - show surface interval
+
 TFT_surface_lastdive_1:
-	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
+	; surface interval
+	SMOVII	surface_interval_mins,mpr	; ISR-safe copy of surface interval in minutes
+	call	convert_time				; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
+	movff	lo,up						; back-up low
+	movff	hi,lo						; get    hours
+	output_99							; print  hours (0-99)
+	PUTC	'h'							; append hours unit
+	movff	up,lo						; get    minutes
+	output_99x							; print  minutes (00-99)
+	PUTC_PRINT "m"						; append minutes unit and dump to screen
+	bra		TFT_surface_lastdive_com	; continue
+
 TFT_surface_lastdive_2:
+	; last dive time
+	SMOVQQ	surface_interval_secs,xC	; ISR-safe copy of surface_interval_secs:4 to xC:4
+	call	output_secs_as_days_hours	; print seconds as days and hours
+	PRINT								; dump to screen
+	;bra	TFT_surface_lastdive_com	; continue
+
+TFT_surface_lastdive_com:
+	; last dive duration
 	WIN_SMALL surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.1)
-	MOVII	lastdive_duration,mpr			; get duration of last dive, minutes
-	bsf		leftbind						; print without leading spaces
-	output_16								; dive time minutes
-	PUTC	":"								;
-	movff	lastdive_duration+2,lo			; get duration of last dive, seconds
-	output_99x								; print seconds
-	rcall	TFT_surface_common				; finalize output
-TFT_surface_lastdive_3:
+	MOVII	lastdive_duration,mpr		; get duration of last dive, minutes
+	output_999							; print minutes
+	PUTC	":"							; print ":"
+	movff	lastdive_duration+2,lo		; get duration of last dive, seconds
+	output_99x							; print seconds
+	PRINT								; dump to screen
+
+	; last dive max depth
 	WIN_SMALL	surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.2)
-	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
-	rcall	TFT_surface_imperial			; 1 - imperial
-	bra		TFT_surface_lastdive_4			;   - continue
-TFT_surface_lastdive_metric:
-	rcall	TFT_surface_metric				; print depth in meters
-TFT_surface_lastdive_4:
+	MOVII	lastdive_maxdepth,mpr		; get max depth of last dive
+	rcall	TFT_surface_lastdive_depth	; print depth
+
+	; average depth
 	WIN_SMALL	surf_gaslist_column+.48,surf_gaslist_row+(surf_gaslist_spacing*.3)
-	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_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
-	return									; done
-
-;=============================================================================
-
-	global	TFT_surface_tissues
-TFT_surface_tissues:						; show tissue diagram in surface mode
+	MOVII	lastdive_avgdepth,mpr		; get avg depth of last dive
+	;bra	TFT_surface_lastdive_depth	; print depth and return
+
+	; Helper Function - print depth
+TFT_surface_lastdive_depth:
+	TSTOSS	opt_units					; 0=Meter, 1=Feet
+	bra		TFT_surface_lastdive_m		; 0 - metric
+	;bra	TFT_surface_lastdive_ft		; 1 - imperial
+
+TFT_surface_lastdive_ft:
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
+	output_999							; print (0-999)
+	STRCAT_TEXT tFeets1					; "ft"
+	PRINT								; dump to screen
+	return								; done
+
+TFT_surface_lastdive_m:
+	bsf		omit_digit_1				; do not print 1st digit
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_65535						; print (0.0x-655.3x)
+	STRCAT_TEXT tMeters					; "m"
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - OC Gas List
+;
+	global	TFT_surf_cv_list_gas
+TFT_surf_cv_list_gas:
+	clrf	WREG						; do OC gases (0-4)
+	;bra	TFT_surf_cv_list_gas_common ; continue with common part
+
+	; common list for OC gases and diluents
+TFT_surf_cv_list_gas_common:
+	movwf	gaslist_gas					; set first gas/dil to show
+	FONT_COLOR_MEMO						; set color
+
+	bsf		short_gas_descriptions		; use short versions of gaslist_strcat_gas and gaslist_strcat_setpoint
+	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
+
+	; Gas 1
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row
+	call	gaslist_strcat_gas			; print gas description
+	PRINT								; dump to screen
+
+	; Gas 2
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
+	incf	gaslist_gas,F				; select next gas/dil
+	call	gaslist_strcat_gas			; print gas description
+	PRINT								; dump to screen
+
+	; Gas 3
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
+	incf	gaslist_gas,F				; select next gas/dil
+	call	gaslist_strcat_gas			; print gas description
+	PRINT								; dump to screen
+
+	; Gas 4
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)
+	incf	gaslist_gas,F				; select next gas/dil
+	call	gaslist_strcat_gas			; print gas description
+	PRINT								; dump to screen
+
+	; Gas 5
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
+	incf	gaslist_gas,F				; select next gas/dil
+	call	gaslist_strcat_gas			; print gas description
+	PRINT								; dump to screen
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - Custom Text
+;
+	global	TFT_surf_cv_text
+TFT_surf_cv_text:
+	FONT_COLOR_MEMO						; set color
+
+	; 1st row
+	WIN_SMALL surf_customtext_column,surf_customtext_row1
+	MOVRR	opt_name+ .0,buffer,.12		; copy 1st 12 chars to output buffer
+	PRINT								; dump to screen
+
+	; 2nd row
+	WIN_SMALL surf_customtext_column,surf_customtext_row2
+	MOVRR	opt_name+.12,buffer,.12		; copy 2nd 12 chars to output buffer
+	PRINT								; dump to screen
+
+	; 3rd row
+	WIN_SMALL surf_customtext_column,surf_customtext_row3
+	MOVRR	opt_name+.24,buffer,.12		; copy 3rd 12 chars to output buffer
+	PRINT								; dump to screen
+
+	; 4th row
+	WIN_SMALL surf_customtext_column,surf_customtext_row4
+	MOVRR	opt_name+.36,buffer,.12		; copy 4th 12 chars to output buffer
+	PRINT								; dump to screen
+
+	; 5th row
+	WIN_SMALL surf_customtext_column,surf_customtext_row5
+	MOVRR	opt_name+.48,buffer,.12		; copy 5th 12 chars to output buffer
+	PRINT								; dump to screen
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - Tissue Graphics
+;
+	global	TFT_surf_cv_tissues
+TFT_surf_cv_tissues:
 
 	; draw outer frame
 	WIN_FRAME_STD surf_tissue_diagram_top, surf_tissue_diagram_bottom, surf_tissue_diagram_left, surf_tissue_diagram_right
 
-	;---- draw labels ---------------------------------	;
-
-	call	TFT_standard_color
+	; draw labels
+	FONT_COLOR_MEMO						; set color
 	WIN_SMALL surf_tissue_N2_column,surf_tissue_N2_row
  IFDEF _helium
-	btfss	tissue_graphic_layout			; shall N2 and He?
-	bra		TFT_surface_tissues_1			; NO  - print "Tissues"
-	STRCPY_TEXT_PRINT tN2					; YES - 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"
+	STRCPY_TEXT_PRINT tDiveTissues		; print "Tissues"
 
 TFT_surface_tissues_2:
-	;---- draw scale ----------------------------------	;
-	movlw	color_deepblue
-	call	TFT_set_color
+	; draw scale
 
 SCALELINE	macro	x
-	WIN_FRAME_COLOR16 surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,surf_tissue_diagram_left+.4+x,surf_tissue_diagram_left+.4+x
+	movlw	color_deepblue
+	WIN_FRAME_COLOR surf_tissue_diagram_top+.23,surf_tissue_diagram_bottom-.4,surf_tissue_diagram_left+.4+x,surf_tissue_diagram_left+.4+x
 	endm
 
 	SCALELINE  .0
@@ -5023,626 +3709,237 @@
 	SCALELINE .72
 	SCALELINE .80
 
-	;---- common initialization for Tissue Pressures and Saturation ----------
+	; common initialization for tissue pressures and saturation
 	movlw	.1
-	movwf	win_height									; hight of the bargraph (0-239)
-	movlw	surf_tissue_diagram_left+.4					; left start position for N2 bars
-	movwf	win_leftx2									; column left (0-159)
-	movlw	surf_tissue_diagram_right-surf_tissue_diagram_left-.4	; get max width for N2 bars (78 pixel)
-	movwf	win_width+0									; set width of the bar box
-	clrf	win_width+1									; ...
-	movlw	color_white									; color for tissues not exceeding surface max pressure
-	movwf	ex											; store in ex
-	movlw	color_red									; color for tissues exceeding surface max pressure
-	movwf	ul											; store in ul
-	bcf		aux_flag									; draw tissue pressures by default
-
-	;---- Draw combined or N2 Tissue Pressures---------	;
-	lfsr	FSR2,char_O_tissue_pressure					; load base address of combined pressures by default
+	movwf	win_height							; hight of the bargraph (0-239)
+	movlw	surf_tissue_diagram_left+.4			; left start position for N2 bars
+	movwf	win_leftx2							; column left (0-159)
+	movlw	surf_tissue_diagram_right-surf_tissue_diagram_left-.4 ; get max width for N2 bars (78 pixel)
+	movwf	win_width+0							; set width of the bar box
+	clrf	win_width+1							; ...
+	movlw	color_white							; color for tissues not exceeding surface max pressure
+	movwf	ex									; store in ex
+	movlw	color_red							; color for tissues exceeding surface max pressure
+	movwf	ul									; store in ul
+	bcf		aux_flag							; draw tissue pressures by default
+
+	; draw combined or N2 tissue pressures
+	lfsr	FSR2,char_O_tissue_pressure			; load base address of combined pressures by default
  IFDEF _helium
-	btfsc	tissue_graphic_layout						; shall show N2+He ?
-	lfsr	FSR2,char_O_tissue_pres_N2					; YES - replace with 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
+	movwf	lo									; tissue counter, 16 tissues
+	clrf	hi									; row    counter
 TFT_surf_tissues_N2_loop:
-	movlw	surf_tissue_diagram_top+.23					; surface mode top start position N2
-	rcall	TFT_surf_tissues_bargraph					; show one tissue
-	movlw	.2											; bargraph spacing
-	addwf	hi,F										; increment row counter
-	decfsz	lo,F										; decrement tissue counter, done?
-	bra		TFT_surf_tissues_N2_loop					; NO - loop
+	movlw	surf_tissue_diagram_top+.23			; surface mode top start position N2
+	rcall	TFT_surf_tissues_bargraph			; show one tissue
+	movlw	.2									; bargraph spacing
+	addwf	hi,F								; increment row counter
+	decfsz	lo,F								; decrement tissue counter, done?
+	bra		TFT_surf_tissues_N2_loop			; NO - loop
  IFDEF _helium
-	btfsc	tissue_graphic_layout						; shall show N2+He ?
-	bra		TFT_surface_tissues_3						; YES - 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 ---------------------	;
+	; 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
-	movlw	color_grey									; color for tissue saturation
-	movwf	ex											; store in ex
-;	movlw	color_yellow								; 2nd color is not used by tissue saturation
-;	movwf	ul											; ...
-	bsf		aux_flag									; draw tissue saturation
+	movwf	lo									; tissue counter, 16 tissues
+	clrf	hi									; row    counter
+	movlw	color_grey							; color for tissue saturation
+	movwf	ex									; store in ex
+;	movlw	color_yellow						; 2nd color is not used by tissue saturation
+;	movwf	ul									; ...
+	bsf		aux_flag							; draw tissue saturation
 TFT_surf_tissues_sat_loop:
-	movlw	surf_tissue_diagram_top+.23+.57				; surface mode top start position saturations
-	rcall	TFT_surf_tissues_bargraph					; draw tissue bargraph
-	movlw	.2											; bargraph spacing
-	addwf	hi,F										; increment row counter
-	decfsz	lo,F										; decrement tissue counter, done?
-	bra		TFT_surf_tissues_sat_loop					; NO - loop
-
-	;---- common Part for vertical lines--------------- ;
-	movlw	surf_tissue_diagram_top+.23+.57				; get top position
-	movwf	win_top										; set top position (0-239)
-	movlw	.30											; get hight
-	movwf	win_height									; set height
-	movlw	.1											; get width
-	movwf	win_width+0									; set width, low  byte
-	clrf	win_width+1									; set width, high byte
-
-	;---- Print 100% Line -----------------------------	;
-	movlw	surf_tissue_diagram_left+.4+.64				; get left position
-	movwf	win_leftx2									; set left position (0-159)
-	movlw	color_red									; color for 100% line
-	call	TFT_set_color								; set color
-	call	TFT_box										; draw line
+	movlw	surf_tissue_diagram_top+.23+.57		; surface mode top start position saturations
+	rcall	TFT_surf_tissues_bargraph			; draw tissue bargraph
+	movlw	.2									; bargraph spacing
+	addwf	hi,F								; increment row counter
+	decfsz	lo,F								; decrement tissue counter, done?
+	bra		TFT_surf_tissues_sat_loop			; NO - loop
+
+	; common part for vertical lines
+	movlw	surf_tissue_diagram_top+.23+.57		; get top position
+	movwf	win_top								; set top position (0-239)
+	movlw	.30									; get hight
+	movwf	win_height							; set height
+	movlw	.1									; get width
+	movwf	win_width+0							; set width, low  byte
+	clrf	win_width+1							; set width, high byte
+
+	; print 100% line
+	movlw	surf_tissue_diagram_left+.4+.64		; get left position
+	movwf	win_leftx2							; set left position (0-159)
+	movlw	color_red							; color for 100% line
+	BOX_COLOR									; draw the line
 
 	; 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
-	movlw	color_green									; color for 100% line
-	call	TFT_set_color								; set color
-	call	TFT_box										; draw line
-
-	;---- Print GF high Line --------------------------	;
-	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
-	movlw	color_yellow								; color for 100% line
-	call	TFT_set_color								; set color
-	call	TFT_box										; draw line
-	bra		TFT_surface_tissues_4						; continue with CNS
+	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
+	movlw	color_green							; color for GF low line
+	BOX_COLOR									; draw the line
+
+	; print GF high line
+	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
+	movlw	color_yellow						; color for GF high line
+	BOX_COLOR									; draw the line
+	bra		TFT_surface_tissues_4				; continue with CNS
 
  IFDEF _helium
 TFT_surface_tissues_3:
-	;---- Draw He Tissue Pressures---------------------	;
-	movlw	surf_tissue_diagram_left+.4+.16				; start position for He bars
-	movwf	win_leftx2									; column left (0-159)
-	movlw	surf_tissue_diagram_right-surf_tissue_diagram_left-.4-.16	; max width for He bars
-	movwf	win_width+0									; set total width of the bar box
-	clrf	win_width+1									; ...
-	lfsr	FSR2,char_O_tissue_pres_He					; load base address of He pressures
+	; draw He tissue pressures
+	movlw	surf_tissue_diagram_left+.4+.16		; start position for He bars
+	movwf	win_leftx2							; column left (0-159)
+	movlw	surf_tissue_diagram_right-surf_tissue_diagram_left-.4-.16 ; max width for He bars
+	movwf	win_width+0							; set total width of the bar box
+	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
+	movwf	lo									; tissue counter, 16 tissues
+	clrf	hi									; row    counter
 TFT_surf_tissues_He_loop:
-	movlw	surf_tissue_diagram_top+.23+.57				; surface mode top start position He
-	rcall	TFT_surf_tissues_bargraph					; show one tissue
-	movlw	.2											; bargraph spacing
-	addwf	hi,F										; increment row counter
-	decfsz	lo,F										; decrement tissue counter, done?
-	bra		TFT_surf_tissues_He_loop					; NO - loop
+	movlw	surf_tissue_diagram_top+.23+.57		; surface mode top start position He
+	rcall	TFT_surf_tissues_bargraph			; show one tissue
+	movlw	.2									; bargraph spacing
+	addwf	hi,F								; increment row counter
+	decfsz	lo,F								; decrement tissue counter, done?
+	bra		TFT_surf_tissues_He_loop			; NO - loop
  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
-	call	TFT_color_code_cns							; color-code CNS value
-	STRCPY_TEXT tCNS2									; "CNS:"
-	bsf		leftbind
-	output_16_3											; display only 0...999
-	bcf		leftbind
-	STRCAT_PRINT "%"
-	goto	TFT_standard_color							; and return...
-
+	btfss	tissue_graphic_cns			; shall show CNS value?
+	return								; NO  - done
+
+	; draw CNS% in-between tissue bars
+	WIN_SMALL surf_tissue_He_column+.22,surf_tissue_He_row
+	MOVII	int_O_CNS_current,mpr		; get current CNS
+	call	TFT_color_code_cns			; color-code CNS value
+	STRCPY_TEXT tCNS2					; "CNS: "
+	bsf		leftbind					; print left-aligned
+	output_999							; print (0-999)
+	PUTC_PRINT "%"						; append unit and dump to screen
+	return								; done
+
+
+	; Helper Function - draw a bargraph
 TFT_surf_tissues_bargraph:
-	addwf	hi,W										; add row number to start position
-	movwf	win_top										; set as row top (0-239)
-	movff	POSTINC2,up									; get tissue value
-	movf	ex,W										; default color
-	btfsc	up,7										; check if flag in bit 7 is set
-	movf	ul,W										; YES - switch to 2nd color
-	call	TFT_set_color								; set bargraph bar color
-	bcf		up,7										; clear flag bit
-	btfss	aux_flag									; drawing saturations?
-	rlncf	up,F										; NO - multiply with 2 (previously cleared bit 7 will be rotated to bit 0)
-	incf	up,W										; add 1 for a minimum visible bar (He-bars could be invisible else-wise)
-	movwf	win_bargraph								; set length of the bargraph
-	goto	TFT_box										; draw bargraph and return
-
-
-;=============================================================================
-; Draw saturation graph in dive mode custom view
+	addwf	hi,W						; add row number to start position
+	movwf	win_top						; set as row top (0-239)
+	movff	POSTINC2,up					; get tissue value
+	movf	ex,W						; default color
+	btfsc	up,7						; check if flag in bit 7 is set
+	movf	ul,W						; YES - switch to 2nd color
+	bcf		up,7						; clear flag bit
+	btfss	aux_flag					; drawing saturations?
+	rlncf	up,F						; NO - multiply with 2 (previously cleared bit 7 will be rotated to bit 0)
+	movff	up,win_bargraph				; set length of the bargraph
+	incf	win_bargraph,F				; add 1 for a minimum visible bar (He-bars could be invisible else-wise)
+	BOX_COLOR							; draw bargraph with color in WREG
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - Tissue Graphics
 ;
-TFT_dive_tissues:
-
-	;---- 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)
-	movlw	dm_custom_tissue_diagram_left+.3			; get dive mode left start position
-	movwf	win_leftx2									; set column left (0-159)
-	movlw	.159-dm_custom_tissue_diagram_left-.4		; get max width
-	movwf	win_width+0									; set width (low byte)
-	clrf	win_width+1									; high byte of with is always zero
-	movlw	color_cyan									; color for tissues with decreasing pressure
-	movwf	ex											; store in ex
-	movlw	color_orange								; color for tissues with increasing pressure
-	movwf	ul											; store in ul
-
-	;---- Draw combined or N2 Tissue Pressures --------	;
-	lfsr	FSR2,char_O_tissue_pressure					; load base address of combined pressures by default
- IFDEF _helium
-	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
-	clrf	hi											; row    counter
-TFT_dive_tissues_N2_loop:
-	movlw	dm_custom_tissue_diagram_top+.3				; dive mode top start position N2
-	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_N2_loop					; NO - loop
- IFDEF _helium
-	btfsc	tissue_graphic_layout						; shall show N2+He ?
-	bra		TFT_dive_tissues_3							; YES - show He tissue pressures
- ENDIF
-
-	;---- Draw Tissue Saturations ---------------------	;
-	lfsr	FSR2,char_O_tissue_saturation				; load base address of tissue supersaturation
-	movlw	d'16'
-	movwf	lo											; tissue counter, 16 tissues
-	clrf	hi											; row    counter
-	movlw	color_grey									; color for tissue saturation, alternative: color_lightblue
-	movwf	ex											; store in ex
-;	movlw	color_yellow								; 2nd color is not used by tissue saturation
-;	movwf	ul											; ...
-TFT_dive_tissues_sat_loop:
-	movlw	dm_custom_tissue_diagram_top+.3+.22			; dive mode top start position saturations
-	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_sat_loop					; NO - loop
-
-	;---- common Part for vertical lines---------------	;
-	movlw	dm_custom_tissue_diagram_top+.3+.22			; get top position
-	movwf	win_top										; set top position (0-239)
-	movlw	.15											; get hight
-	movwf	win_height									; set height
-	movlw	.1											; get width
-	movwf	win_width+0									; set width, low  byte
-	clrf	win_width+1									; set width, high byte
-
-	;---- Print 100% Line -----------------------------	;
-	movlw	dm_custom_tissue_diagram_left+.3+.33		; get left position
-	movwf	win_leftx2									; set left position (0-159)
-	movlw	color_red									; color for 100% line
-	call	TFT_set_color								; set color
-	call	TFT_box										; draw line
-
-	; 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 --------------------------	;
-	movlw	dm_custom_tissue_diagram_left+.3			; get left base position
-	movwf	win_leftx2									; set left base position (0-159)
-	movff	char_I_GF_Low_percentage,WREG				; get GF low in 0.01 %
-	mullw	.82											; multiply with 82
-	movf	PRODH,W										; divide   by   256 -> resulting scale factor is 82/256 = 0.3203125
-	addwf	win_leftx2,F								; add to base position
-	movlw	color_green									; color for 100% line
-	call	TFT_set_color								; set color
-	call	TFT_box										; draw line
-
-	;---- Print GF high Line --------------------------	;
-	movlw	dm_custom_tissue_diagram_left+.3			; get left base position
-	movwf	win_leftx2									; set left base position (0-159)
-	movff	char_I_GF_High_percentage,WREG				; get GF high in 0.01 %
-	mullw	.82											; multiply with 82
-	movf	PRODH,W										; divide   by   256 -> resulting scale factor is 82/256 = 0.3203125
-	addwf	win_leftx2,F								; add to base position
-	movlw	color_yellow								; color for 100% line
-	call	TFT_set_color								; set color
-	call	TFT_box										; draw line
-	bra		TFT_dive_tissues_4							; continue with number of leading tissue
-
- 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									; ...
-	movlw	d'16'
-	movwf	lo											; tissue counter, 16 tissues
-	clrf	hi											; row    counter
-TFT_dive_tissues_He_loop:
-	movlw	dm_custom_tissue_diagram_top+.3+.22			; dive mode top start position H2
-	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
- ENDIF
-
-TFT_dive_tissues_4:
-	;---- Print Number of leading Tissue --------------	; TODO: some flicker due to overwriting by tissue bars
-	movff	int_O_lead_supersat+0,WREG					; get current leading tissue's supersaturation (only low byte used for value)
-	tstfsz	WREG										; current supersaturation = 0 ?
-	bra		TFT_dive_tissues_5							; NO  - print number of leading tissue
-	movff	char_O_deco_info,WREG						; YES - get deco info vector
-	btfss	WREG,deco_ceiling							;     - do we have a ceiling obligation?
-	goto	TFT_standard_color							;       NO  - can ascent directly, don't print number, set standard color and return
-														;       YES - print number of leading tissue
-TFT_dive_tissues_5:
-	movff	char_O_lead_tissue,lo						; get number of leading tissue as 0-15
-	incf	lo,F										; adjust to 1-16
-	movlw	.10
-	cpfsgt	lo											; is it > 10 ?
-	bra		TFT_dive_tissues_6							; NO - will output a single digit number
-	; start position for a 2 digit number
-	WIN_TINY dm_custom_tissue_diagram_left+.32,dm_custom_tissue_diagram_top+.10
-	bra		TFT_dive_tissues_7
-TFT_dive_tissues_6:
-	; start position for a 1 digit number
-	WIN_TINY dm_custom_tissue_diagram_left+.32+.4,dm_custom_tissue_diagram_top+.10
-TFT_dive_tissues_7:
-	call	TFT_standard_color							; set output color
-	bsf		leftbind
-	output_8											; print number in left aligned, i.e. without leading zeros or spaces
-	bcf		leftbind
-	STRCAT_PRINT ""										; finalize output
-	return
-
-TFT_dive_tissues_bargraph:
-	addwf	hi,W										; add row number to start position
-	movwf	win_top										; set as row top (0-239)
-	movff	POSTINC2,up									; get tissue value
-	movf	ex,W										; default color
-	btfsc	up,7										; check if flag in bit 7 is set
-	movf	ul,W										; YES - switch to 2nd color
-	call	TFT_set_color								; set bargraph bar color
-	bcf		up,7										; clear flag  bit
-	bcf		STATUS,C									; clear carry bit
-	rrcf	up,F										; divide by 2
-	incf	up,W										; add a bit for a minimum visible bar
-	movwf	win_bargraph								; set bargraph bar length
-	goto	TFT_box										; draw bargraph and return
-
-;=============================================================================
-
-	global	TFT_show_cns
-TFT_show_cns:
-	call	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	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
-	bsf		leftbind
-	output_16_3							; displays only 0...999
-	bcf		leftbind
-	PUTC	"%"
-	movlw	dm_warning_length			; dive mode string length
-	btfss	divemode					; In dive mode?
-	movlw	surf_warning_length			; NO - use surface string length
-	call	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""
-	bcf		win_invert
-	bra		TFT_custview_exit3			; and return...
-
-
-	global	TFT_warning_eod_cns
-TFT_warning_eod_cns:
-	call	TFT_set_message_window		; set row and column for the message
-	tstfsz	WREG						; is there room for the message?
-	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
-	call	TFT_fillup_with_spaces		; fill up FSR2 with spaces (total string length in WREG)
-	STRCAT_PRINT ""
-	bra		TFT_custview_exit3			; and return...
-
-
-	global	TFT_show_ppo2_warning
-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 - skip message in this cycle
-	call	TFT_color_code_ppo2			; color-code output
-	btfsc	bailout_mode				; in bailout?
-	bra		TFT_display_diluent_2		; YES
-	btfss	FLAG_ccr_mode				; in CCR mode?
-	bra		TFT_display_diluent_1		; NO  - continue with pSCR or OC 
-	STRCPY_TEXT tdil					; YES - print "Dil:"
-	bra		TFT_display_diluent_3
-TFT_display_diluent_1:
-	btfss	FLAG_pscr_mode				; in pSCR mode?
-	bra		TFT_display_diluent_2		; NO  - continue with OC 
-	STRCPY_TEXT tmix					; YES - print "Mix:"
-	bra		TFT_display_diluent_3
-TFT_display_diluent_2:
-	STRCPY_TEXT tppO2					; bailout or OC mode, print "ppO2:"
-TFT_display_diluent_3:
-	bsf		leftbind
-	output_16dp .3						; x.xx bar
-	bcf		leftbind
-	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 ""
-TFT_custview_exit3:
-	goto	TFT_standard_color			; and return...
-
-
- IFDEF _compass
-
-	global	TFT_surf_set_bearing
-TFT_surf_set_bearing:
-	btfsc	compass_menu				; is the "set bearing" selection shown?
-	return								; YES - return
-	bsf		compass_menu				; NO  - set "set bearing" selection as shown
-	WIN_BOX_BLACK surf_compass_bear_row,surf_warning1_row-1, surf_compass_bear_column, surf_decotype_column-.1 ; top, bottom, left, right
-	WIN_SMALL surf_compass_bear_column,surf_compass_bear_row
-	WIN_COLOR color_yellow
-	bsf		win_invert
-	STRCPY_TEXT_PRINT tSetHeading		; 7 chars
-	bcf		win_invert
-	return
-
- ENDIF
-
-;=============================================================================
-
-	global	TFT_LogOffset
-TFT_LogOffset:
-	STRCPY_TEXT tLogOffsetValue			; print "Offset" in selected language
-	call	eeprom_log_offset_read		; read offset into lo:hi
-;	bsf		leftbind
-	output_16_4							; print offset in 4 digits
-;	bcf		leftbind
-	return								; no "_PRINT" here...
-
-;=============================================================================
-; RX Functions
+	global	TFT_surf_cv_settings
+TFT_surf_cv_settings:
+	; Deco Mode
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row
+	STRCAT_PRINT "ZH-L16"				; print fix part of model
+	movff	char_I_model,WREG			; get model
+	iorwf	WREG						; GF enabled?
+	bnz		TFT_surface_decosettings1	; YES
+	;bra	TFT_surface_decosettings0	; NO
+
+TFT_surface_decosettings0:
+	; Display ZH-L16 sat/desat model
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
+	STRCPY_TEXT tSD								; print label (S/D)
+	movff	char_I_saturation_multiplier,  lo	; get sat   mult.
+	movff	char_I_desaturation_multiplier,hi	; get desat mult.
+	bra		TFT_surface_decosettings_com		; continue with common part
+
+TFT_surface_decosettings1:
+	; Display ZH-L16-GF low/high model
+	WIN_SMALL surf_gaslist_column+.43,surf_gaslist_row
+	STRCPY_TEXT_PRINT tZHL16GF					; print GF label behind deco model label
+
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
+	STRCPY_TEXT tGF								; print label (GF:)
+	PUTC	' '									; print a space
+	movff	opt_GF_low, lo						; get GF low
+	movff	opt_GF_high,hi						; get GF high
+	;bra	TFT_surface_decosettings_com		; continue with common part
+
+TFT_surface_decosettings_com:
+	; percentage pair
+	output_256							; print (0-255)
+	STRCAT	"%/"						; print "%/"
+	movff	hi,lo						; get 2nd value
+	output_256							; print (0-255)
+	PUTC_PRINT "%"						; append unit and dump to screen
+
+	; fTTS
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
+	STRCPY_TEXT tFTTSSurf				; print label
+	movff	char_I_extra_time,lo		; get time
+	output_9							; print time (0-9)
+	STRCAT_TEXT_PRINT tMinutes			; append unit and dump to screen
+
+	; Last Stop
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)
+	STRCPY_TEXT tLastDecostopSurf		; print label
+	movff	opt_last_stop,lo			; get depth
+	output_9							; print depth (0-9)
+	STRCAT_TEXT_PRINT tMeters			; append unit and dump to screen
+
+	; Salinity
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
+	STRCPY_TEXT tDvSalinitySurf			; print label
+	movff	opt_salinity,lo				; get salinity
+	output_9							; print salinity (0-9)
+	STRCAT_TEXT_PRINT tPercent			; append unit and dump to screen
+
+	return								; done
+
 
  IFDEF _rx_functions
 
-	global	TFT_pressures_SAC_mask			; mask for pressures and SAC
-TFT_pressures_SAC_mask:
-	call	TFT_divemask_color
-	; pressure reading 1
-	WIN_TINY dm_custom_tankdata_pres1_col, dm_custom_tankdata_mask_row
-	movff	char_I_pressure_gas+0,WREG		; =0: disabled, =1..10: gases/dils
-	bcf		aux_flag						; selector for disabled / need set to disabled
-	call	TFT_pressures_SAC_mask_helper	; print gas composition or " ---" if disabled
-	; pressure reading 2
-	WIN_TINY dm_custom_tankdata_pres2_col, dm_custom_tankdata_mask_row
-	movff	char_I_pressure_gas+1,WREG		; =0: need to reading 1, =1..10: gases/dils
-	bsf		aux_flag						; selector for disabled / need set to need
-	call	TFT_pressures_SAC_mask_helper	; print gas composition or "Need " if 0
-	; SAC rate
-	WIN_TINY dm_custom_tankdata_SAC_col, dm_custom_tankdata_mask_row
-	STRCPY_TEXT tSAC						; "SAC
-	STRCAT	" ("							;      (
-	STRCAT_TEXT tLitersMinute				;       l/min
-	STRCAT_PRINT ")"						;            )"
-	bra		TFT_custview_exit3				; and return...
-
-TFT_pressures_SAC_mask_helper:
-	tstfsz	WREG							; pressure reading assigned?
-	bra		TFT_dive_tankdata_mask_helper_1	; YES - print gas composition
-	btfsc	aux_flag						; NO  - check auxiliary flag
-	bra		TFT_dive_tankdata_mask_helper_2	;       1 - print "Need "
-	STRCAT_PRINT "    ---"					;       0 - print "    ---"
-	return									;         - done
-TFT_dive_tankdata_mask_helper_1:
-	decf	WREG,W							; (1..10) -> (0..9)
-	bsf		short_gas_descriptions			; just "Air", "O2" or "xx/yy"
-	call	gaslist_strcat_gas_WREG			; print composition of gas/dil in WREG (0..9)
-	bra		TFT_dive_tankdata_mask_helper_3 ; finish with adding "(bar)"
-TFT_dive_tankdata_mask_helper_2:
-	STRCPY_TEXT tNeed						; "Need"
-TFT_dive_tankdata_mask_helper_3:
-	STRCAT_PRINT "(bar)"
-	return
-
-
-	global	TFT_pressures_SAC				; data for pressures and SAC
-TFT_pressures_SAC:
-	; check mode for second reading
-	bcf		aux_flag						; clear auxiliary flag by default (reading 2 is pressure)
-	movff	char_I_pressure_gas+1,WREG		; =0: need to reading 1, =1..10: gases/dils
-	addlw	.0								; dummy operation to set status register flags
-	btfsc	STATUS,Z						; gas selected = 0 (i.e. no 2nd pressure reading) ?
-	bsf		aux_flag						; YES - set auxiliary flag (display position of reading 2 shall show need to reading 1)
-	; get data of reading 1
-	movff	int_IO_pressure_value+0,lo		; copy pressure 1 to hi:lo
-	movff	int_IO_pressure_value+1,hi
-	movff	char_I_pressure_stat+0,ex		; copy status data
-	; pressure of reading 1
-	WIN_STD dm_custom_tankdata_pres1_col+.4,dm_custom_tankdata_row
-	rcall	TFT_pressures_SAC_helper_1		; print pressure if available, else " ---"
-	; battery status of reading 1
-	WIN_SMALL dm_custom_hud_sensor1_column+.4+.36,dm_custom_tankdata_row
-	rcall	TFT_pressures_SAC_helper_2		; print or clear down arrow as low bat indicator
-	; get data for reading 2
-	btfsc	aux_flag						; shall reading 2 show need to reading 1 ?
-	bra		TFT_pressures_SAC_1				; YES
-	movff	int_IO_pressure_value+2,lo		; NO  - copy pressure 2 to hi:lo
-	movff	int_IO_pressure_value+3,hi
-	movff	char_I_pressure_stat+1,ex		;     - copy status data
-	bra		TFT_pressures_SAC_2
-TFT_pressures_SAC_1:
-	MOVII	int_O_pressure_need,mpr			; YES - copy need to pressure 1 to hi:lo
-	clrf	ex								;     - set status data to 0
-TFT_pressures_SAC_2:
-	; pressure of reading 2
-	WIN_STD dm_custom_tankdata_pres2_col+.2,dm_custom_tankdata_row
-	rcall	TFT_pressures_SAC_helper_1		; print pressure if available, else " ---"
-	; battery status of reading 2
-	WIN_SMALL dm_custom_tankdata_pres2_col+.2+.36,dm_custom_tankdata_row
-	rcall	TFT_pressures_SAC_helper_2		; print or clear down arrow as low bat indicator
-	; SAC
-	WIN_STD dm_custom_tankdata_SAC_col+.6,dm_custom_tankdata_row
-	MOVII	int_O_SAC_measured,mpr			; copy measured SAC rate to hi:lo
-	btfsc	hi,int_not_avail_flag			; SAC rate available?
-	bra		TFT_pressures_SAC_4				; NO - print " --.-"
-	call	TFT_color_code_tank_pres_sac	; color-code the output
-	output_16_3								; print as xxx
-	PUTC	" "								; print a dummy char to have the string termination at the correct place
-	movff	buffer+.2,buffer+.3				; move the decimal digit one position to the right
-	movlw	"."								; load coding of a decimal point
-	movff	WREG,buffer+.2					; place it before decimal digit
-	movlw	" "								; load coding of a space character
-	movff	buffer+.1,up					; get the character in front of the decimal point
-	cpfseq	up								; is it a space?
-	bra		TFT_pressures_SAC_3				; NO  - continue
-	movlw	"0"								; YES - load coding of a zero
-	movff	WREG,buffer+.1					;     - place a zero in front of the decimal point
-TFT_pressures_SAC_3:
-	STRCAT_PRINT ""							; dump buffer to screen
-	bra		TFT_custview_exit3				; and return...
-TFT_pressures_SAC_4:
-	call	TFT_disabled_color
-	STRCAT_PRINT "--.-"						; output for no SAC data available
-	bra		TFT_custview_exit3				; and return...
-
-TFT_pressures_SAC_helper_1:
-	btfss	hi,int_not_avail_flag			; pressure available?
-	bra		TFT_pressures_SAC_helper_1a		; YES - print pressure
-	call	TFT_disabled_color				; NO  - use disabled color as default
-;	btfsc	ex,char_transmitter_lost		;     - transmitter lost?
-;	call	TFT_attention_color				;       YES - use attention color
-	STRCAT_PRINT " ---"						;     - print " ---"
-	return
-TFT_pressures_SAC_helper_1a:
-	btfsc	hi,int_warning_flag				; out of range (signaled by warning flag)?
-	bra		TFT_pressures_SAC_helper_1c		; YES - special treatment
-	call	TFT_color_code_tank_pres_sac	; NO  - color-code the output
-	bsf		ignore_digit5					;     - no 0.1 bar (flag will be cleared by output_16)
-	movf	lo,W							;
-	iorwf	hi,W							;     - pressure value = 0 ?
-	bnz		TFT_pressures_SAC_helper_1b		;       NO  - print value
-	STRCPY_PRINT "   0"						;       YES - print a zero manually
-	return									;           - done
-TFT_pressures_SAC_helper_1b:
-	output_16								; print hi:lo
-	STRCAT_PRINT ""							; dump buffer to screen
-	return									; done
-TFT_pressures_SAC_helper_1c:
-	call	TFT_color_code_tank_pres_sac	; color-code the output (clears all flags)
-	STRCPY_PRINT ">400"						; print ">400"
-	return									; done
-
-TFT_pressures_SAC_helper_2:
-	btfss	ex,char_transmitter_low_bat		; low battery flag set?
-	bra		TFT_pressures_SAC_helper_2a		; NO  - wipe out down arrow (low bat indicator)
-	call	TFT_attention_color				; YES - use attention color
-	STRCPY_PRINT "\xb8"						;     - print down arrow as bat low indication
-	return
-TFT_pressures_SAC_helper_2a:
-	STRCPY_PRINT " "						; wipe out down arrow (low bat indicator)
-	return
-
-
-	global	TFT_menu_tank_pres
-TFT_menu_tank_pres:							; imprinting function for main menu / tank setup
-	call	TFT_standard_color
-	; get ID
-	lfsr	FSR1,opt_transmitter_id_1		; load base address of opt_transmitter_id
-	movf	gaslist_gas,W					; get current gas
-	rlncf	WREG,W							; multiply by 2 because IDs are 2 byte in size
-	movff	PLUSW1,lo						; copy opt_transmitter_id+0[gaslist_gas] to lo
-	incf	WREG,W							; increment index
-	movff	PLUSW1,hi						; copy opt_transmitter_id+1[gaslist_gas] to hi
-	; show pressure
-	WIN_SMALL .90, .61						; column, row (+/- 27 per row)
-	call	get_pres_by_transmitter_id		; get pressure into hi:lo
-	tstfsz	WREG							; do we have valid tank data (WREG=0) ?
-	bra		TFT_menu_tank_pres_1			; NO - transmitter not found
-	call	TFT_color_code_tank_pres_sac	; set output color according to flags
-	bsf		ignore_digit5					; no 0.1 bar (flag will be cleared by output_16)
-	output_16
-	bra		TFT_menu_tank_pres_2
-TFT_menu_tank_pres_1:
-	call	TFT_disabled_color
-	STRCAT	" ---"							; output for no pressure data available
-TFT_menu_tank_pres_2:
-	STRCAT_TEXT_PRINT tbar					; " bar"
-	bra		TFT_custview_exit3				; and return...
-
-
-	global	TFT_surface_tank_pres
-TFT_surface_tank_pres:						; show pressure reading above surface pressure
-	WIN_SMALL surf_decotype_column+.6,surf_decotype_row+.30+.47
-	movff	int_IO_pressure_value+0,lo		; copy pressure from 1st reading to hi:lo
-	movff	int_IO_pressure_value+1,hi
-	btfss	hi,int_not_avail_flag			; pressure reading 1 available?
-	bra		TFT_surface_tank_pres_0			; YES
-	movff	int_IO_pressure_value+2,lo		; NO - copy pressure from 2nd reading to hi:lo
-	movff	int_IO_pressure_value+3,hi
-	btfsc	hi,int_not_avail_flag			;    - pressure reading 2 available?
-	bra		TFT_surface_tank_pres_1			;      NO  - show not avail message
-TFT_surface_tank_pres_0:					;      YES - show pressure
-	call	TFT_color_code_tank_pres_sac	; set output color according to flags
-	bsf		ignore_digit5					; no 0.1 bar (flag will be cleared by output_16)
-	output_16
-	STRCAT_PRINT ""
-	bra		TFT_surface_tank_pres_2
-TFT_surface_tank_pres_1:
-	call	TFT_disabled_color
-	STRCAT_PRINT " ---"						; output for no pressure data available
-TFT_surface_tank_pres_2:
-	WIN_SMALL surf_decotype_column+.38,surf_decotype_row+.30+.47
-	call	TFT_divemask_color
-	STRCAT_PRINT "bar"						; can not use tbar because it has a leading space
-	bra		TFT_custview_exit3				; and return...
-
-
-	global	TFT_surface_tankdata
-TFT_surface_tankdata:
-	lfsr	FSR1,rx_buffer					; load base address of RX buffer
-;	bra		TFT_surface_tankdata_debug		; comment in for +++ debug version +++
+;-----------------------------------------------------------------------------
+; Surface Custom View - TR - Tank Data
+;
+	global	TFT_surf_cv_tankdata
+TFT_surf_cv_tankdata:
+	lfsr	FSR1,rx_buffer				; load base address of RX buffer
+
+ IFNDEF _rx_functions_debug
+
 	WIN_SMALL surf_customtext_column,surf_customtext_row1
 	rcall	TFT_surface_tankdata_print
 	WIN_SMALL surf_customtext_column,surf_customtext_row2
@@ -5653,170 +3950,2130 @@
 	rcall	TFT_surface_tankdata_print
 	WIN_SMALL surf_customtext_column,surf_customtext_row5
 	rcall	TFT_surface_tankdata_print
-	return
-
-TFT_surface_tankdata_print:					; max 12 char
-	call	TFT_standard_color				; set color
-	movff	POSTINC1,hi						; ID high (+0)
-	movff	POSTINC1,lo						; ID low  (+1)
-	tstfsz	hi								; ID high = 0 ?
-	bra		TFT_surface_tankdata_print_1	; NO  - slot in use
-	tstfsz	lo								; ID low  = 0?
-	bra		TFT_surface_tankdata_print_1	; NO  - slot in use
-	STRCAT_PRINT "----        "				; YES - mark as unused and clear rest of line from previous remains
-	movf	POSTINC1,W						;     - dummy read (+2) to advance index
-	movf	POSTINC1,W						;     - dummy read (+3) to advance index
-	movf	POSTINC1,W						;     - dummy read (+4) to advance index
-	bra		TFT_surface_tankdata_print_3
+
+	return								; done
+
+
+	; Helper Function - print transmitter data (max 12 char)
+TFT_surface_tankdata_print:
+	FONT_COLOR_MEMO						; set color
+	movff	POSTINC1,hi					; get ID high (+0)
+	movff	POSTINC1,lo					; get ID low  (+1)
+	tstfsz	hi							; ID high = 0 ?
+	bra		TFT_surface_tankdata_print_1; NO  - slot in use
+	tstfsz	lo							; ID low  = 0?
+	bra		TFT_surface_tankdata_print_1; NO  - slot in use
+	STRCAT_PRINT "----        "			; YES - mark as unused and clear rest of line from previous remains
+	movf	POSTINC1,W					;     - dummy read (+2) to advance index
+	movf	POSTINC1,W					;     - dummy read (+3) to advance index
+	movf	POSTINC1,W					;     - dummy read (+4) to advance index
+	bra		TFT_surface_tankdata_print_3;     - one more dummy read and return
+
 TFT_surface_tankdata_print_1:
-	movf	hi,W							; copy ID high to WREG
-	output_hex								;                     2 chars
-	movf	lo,W							; copy ID low  to WREG
-	output_hex								;                     2 chars (4 in total)
-	movff	POSTINC1,hi						; pressure high (+2)
-	movff	POSTINC1,lo						; pressure low  (+3)
-	call	TFT_color_code_tank_pres_sac	; needed to clear the status flags before output
-	bsf		ignore_digit5					; no 0.1 bar (flag will be cleared by output_16)
-	output_16								;                     4 chars (8 in total)
-	PUTC	" "								;                     1 char  (9 in total)
-	movf	POSTINC1,W						; status (+4)
-	andlw	.7								; mask out battery voltage
-	bnz		TFT_surface_tankdata_2			; branch if battery is not completely drained
-	call	TFT_warning_color				; output in red
-	STRCAT_PRINT "XXX"						; "XXX" for low
-	bra		TFT_surface_tankdata_print_3
+	movf	hi,W						; copy ID high to WREG
+	output_hex							; print as hex        2 chars
+	movf	lo,W						; copy ID low  to WREG
+	output_hex							; print as hex        2 chars (4 in total)
+	movff	POSTINC1,hi					; get pressure high (+2)
+	movff	POSTINC1,lo					; get pressure low  (+3)
+	call	TFT_color_code_pres_sac		; needed to clear the status flags before output
+	bsf		omit_digit_1				; do not print 1st digit (0.1 bar)
+	output_65535						; print (0x-6553x)    4 chars (8 in total)
+	PUTC	" "							;                     1 char  (9 in total)
+	movf	POSTINC1,W					; get status (+4)
+	andlw	.7							; mask out battery voltage
+	bnz		TFT_surface_tankdata_2		; branch if battery is not completely drained
+	FONT_COLOR_WARNING					; output in red
+	STRCAT_PRINT "XXX"					; "XXX" for low
+	bra		TFT_surface_tankdata_print_3; one more dummy read and return
+
 TFT_surface_tankdata_2:
-	addlw	.28								; add offset of 2.8 Volt
-	movff	WREG,lo							;
-	output_99								;                     2 chars (11 in total)
-	PUTC	" "								; dummy char          1 char  (12 in total)
-	movff	buffer+.10,buffer+.11			; move decimal digit of battery voltage one position to the right
-	movlw	"."								; decimal point
-	movff	WREG,buffer+.10					; place it before decimal digit
-	STRCAT_PRINT ""							; print buffer to screen
+	addlw	.28							; add offset of 2.8 Volt
+	movff	WREG,lo						; copy to lo
+	bsf		decimal_digit1  			; put a decimal point in front of digit 1
+	output_99							; print voltage       2 chars (11 in total)
+	PUTC_PRINT " "						; dummy char          1 char  (12 in total)
+
 TFT_surface_tankdata_print_3:
-	movf	POSTINC1,W						; dummy read (+5) to advance index
-	return
-
-
-; TFT_surface_tankdata_debug:					; surface custom view debug output
-	; call	TFT_standard_color
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*0
-	; rcall	TFT_surface_tankdata_debug_print
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*1
-	; rcall	TFT_surface_tankdata_debug_print
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*2
-	; rcall	TFT_surface_tankdata_debug_print
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*3
-	; rcall	TFT_surface_tankdata_debug_print
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*4
-	; rcall	TFT_surface_tankdata_debug_print
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*5
-	; rcall	TFT_surface_tankdata_debug_print
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*6
-	; rcall	TFT_surface_tankdata_debug_print
-	; WIN_TINY surf_customtext_column,surf_customtext_row1+.14*7
-	; rcall	TFT_surface_tankdata_debug_print
-	; return
-
-; TFT_surface_tankdata_debug_print:
-	; movff	POSTINC1,hi					; ID high (+0)
-	; movff	POSTINC1,lo					; ID low  (+1)
-	; output_16
-	; PUTC	","
-	; movff	POSTINC1,hi					; pressure high (+2)
-	; movff	POSTINC1,lo					; pressure low  (+3)
-	; call	TFT_color_code_tank_pres_sac; needed to clear the status flags before output
-	; output_16
-	; PUTC	","
-	; movff	POSTINC1,lo					; status (+4)
-	; output_8
-	; PUTC	","
-	; movff	POSTINC1,lo					; date (+5)
-	; output_8
-	; STRCAT_PRINT ""
-	; return
-
+	movf	POSTINC1,W					; dummy read (+5) to advance index
+	return								; done
+
+ ELSE	; _rx_functions_debug
+
+TFT_surface_tankdata_debug:				; surface custom view debug output
+	FONT_COLOR_MEMO						; set color
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*0
+	rcall	TFT_surface_tankdata_debug_print
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*1
+	rcall	TFT_surface_tankdata_debug_print
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*2
+	rcall	TFT_surface_tankdata_debug_print
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*3
+	rcall	TFT_surface_tankdata_debug_print
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*4
+	rcall	TFT_surface_tankdata_debug_print
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*5
+	rcall	TFT_surface_tankdata_debug_print
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*6
+	rcall	TFT_surface_tankdata_debug_print
+	WIN_TINY surf_customtext_column,surf_customtext_row1+.14*7
+	rcall	TFT_surface_tankdata_debug_print
+	return								; done
+
+TFT_surface_tankdata_debug_print:
+	movff	POSTINC1,hi					; read ID high (+0)
+	output_hex							; print as hex
+	movff	POSTINC1,lo					; read ID low  (+1)
+	output_hex							; print as hex
+	PUTC	","							; print ","
+	movff	POSTINC1,hi					; read pressure high (+2)
+	movff	POSTINC1,lo					; read pressure low  (+3)
+	call	TFT_color_code_pres_sac		; needed to clear the status flags before output
+	bsf		decimal_digit1				; place a decimal point in front of digit 1 
+	output_9999							; print pressure (0.0-999.9)
+	PUTC	","							; print ","
+	movff	POSTINC1,lo					; read status (+4)
+	output_hex							; print as hex
+	PUTC	","							; print ","
+	movff	POSTINC1,lo					; read date   (+5)
+	output_256							; print (0-255)
+	PRINT								; dump to screen
+	return								; done
+
+ ENDIF	; _rx_functions_debug
  ENDIF	; _rx_functions
 
+ IFDEF _compass
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - Compass - "set Bearing Dialog"
+;
+	global	TFT_surf_cv_compass_bearing
+TFT_surf_cv_compass_bearing:
+	btfsc	compass_menu				; is the "set bearing" selection shown?
+	return								; YES - done
+	bsf		compass_menu				; NO  - set "set bearing" selection as shown
+	WIN_BOX_BLACK surf_compass_bear_row,surf_warning1_row-1, surf_compass_bear_column, surf_decotype_column-.1 ; top, bottom, left, right
+	WIN_SMALL surf_compass_bear_column,surf_compass_bear_row
+	FONT_COLOR color_yellow				; set color
+	bsf		win_invert					; print inverse
+	STRCPY_TEXT_PRINT tSetHeading		; 7 chars
+	return								; done
+
+ ENDIF	; _compass
+
+ IFDEF _ccr_pscr
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - Diluent List
+;
+	global	TFT_surf_cv_list_dil
+TFT_surf_cv_list_dil:
+	movlw	.5							; do diluents (5-9)
+	bra		TFT_surf_cv_list_gas_common ; continue with common part
+
+
+;-----------------------------------------------------------------------------
+; Surface Custom View - Setpoint List
+;
+	global	TFT_surf_cv_list_sp			; show setpoint list
+TFT_surf_cv_list_sp:
+	FONT_COLOR_MEMO						; set color
+	bsf		short_gas_descriptions		; use short versions of gaslist_strcat_gas_PRODL and gaslist_strcat_setpoint
+	bcf		better_gas_hint				; do not mark the best gas/diluent (to be used in dive mode only)
+
+	;SP 1
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row
+	clrf	gaslist_gas					; select SP 1
+	call	gaslist_strcat_setpoint		; show setpoint data
+	PRINT								; dump to screen
+
+	;SP 2
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.1)
+	incf	gaslist_gas,F				; select next SP
+	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
+	PRINT								; dump to screen
+
+	;SP 3
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.2)
+	incf	gaslist_gas,F				; select next SP
+	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
+	PRINT								; dump to screen
+
+	;SP 4
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.3)
+	incf	gaslist_gas,F				; select next SP
+	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
+	PRINT								; dump to screen
+
+	;SP 5
+	WIN_SMALL surf_gaslist_column,surf_gaslist_row+(surf_gaslist_spacing*.4)
+	incf	gaslist_gas,F				; select next SP
+	call	gaslist_strcat_setpoint		; show SP#+1 of PRODL#
+	PRINT								; dump to screen
+
+	return								; done
+
+ ENDIF	; _ccr_pscr
+
+
 ;=============================================================================
-
-	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					; get salinity in [%]
-	clrf	xB+1					; ...
-	call	div32x16				; xC:4 = xC:4 / xB:2 with xA as remainder
-	MOVII	xC,mpr					; copy back result as depth in [cm]
+tft_out14	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - AVR / Stopwatch - Mask
+;
+	global	TFT_avr_stopwatch_mask
+TFT_avr_stopwatch_mask:
+	FONT_COLOR_MASK						; select color
+
+ IFNDEF _min_depth_option
+
+	WIN_TINY dm_custom_avr_stop_column1+.2,dm_custom_avr_stop_title_row
+	TSTOSS	opt_2ndDepthDisp			; show avg depth instead of max depth in main screen?
+	bra		TFT_avr_stopwatch_mask_1	; NO  - draw avg depth in custom view then
+	btfss	alt_layout_active			; YES - in alternative layout?
+	bra		TFT_avr_stopwatch_mask_max	;       NO  - show max depth
+	;bra	TFT_avr_stopwatch_mask_avg	;       YES - show avg depth
+
+TFT_avr_stopwatch_mask_avg:
+	STRCPY_TEXT_PRINT tDiveTotalAvg		; mask for average depth
+	bra		TFT_avr_stopwatch_mask_2	; continue
+
+TFT_avr_stopwatch_mask_1:
+	btfss	alt_layout_active			; YES - in alternative layout?
+	bra		TFT_avr_stopwatch_mask_avg	;       NO  - show avg depth
+	;bra	TFT_avr_stopwatch_mask_max	;       YES - show max depth
+
+TFT_avr_stopwatch_mask_max:
+	STRCPY_TEXT_PRINT tMaxDepth			; mask for maximum depth
+	;bra	TFT_avr_stopwatch_mask_2	; continue
+
+TFT_avr_stopwatch_mask_2:
+	WIN_TINY dm_custom_avr_stop_column2+.3,dm_custom_avr_stop_title_row
+	STRCPY_TEXT_PRINT tDiveStopwatch	; print label
+
+	WIN_TINY dm_custom_avr_stop_column3-.8,dm_custom_avr_stop_title_row
+	STRCPY_TEXT_PRINT tDiveStopAvg		; print label
+
+	return								; done
+
+ ELSE
+
+	WIN_TINY dm_custom_avr_stop_column1+.2,dm_custom_avr_stop_title_row
+	STRCPY_PRINT "Max.Depth"			; print label
+
+	WIN_TINY dm_custom_avr_stop_column2+.3,dm_custom_avr_stop_title_row
+	STRCPY_PRINT "Avg.Depth"			; print label
+
+	WIN_TINY dm_custom_avr_stop_column3-.8,dm_custom_avr_stop_title_row
+	STRCPY_PRINT "Min.Depth"			; print label
+
+	return								; done
+
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - AVR / Stopwatch - Data
+;
+	global	TFT_avr_stopwatch
+TFT_avr_stopwatch:
+	FONT_COLOR_MEMO							; select color
+
+ IFNDEF _min_depth_option
+
+	; total average depth or max depth
+	WIN_MEDIUM dm_custom_avr_stop_column1,dm_custom_avr_stop_row
+	TSTOSS	opt_2ndDepthDisp				; show average depth instead of maximum depth in main screen?
+	bra		TFT_avr_stopwatch_1				; NO  - draw avg depth in custom view then
+	btfsc	alt_layout_active				; YES - in alternative layout?
+	bra		TFT_avr_stopwatch_avg			;       YES - show avg depth
+	bra		TFT_avr_stopwatch_max			;       NO  - show max depth
+
+TFT_avr_stopwatch_1:
+	btfsc	alt_layout_active				; YES - in alternative layout?
+	bra		TFT_avr_stopwatch_max			;       YES - show max depth
+	;bra	TFT_avr_stopwatch_avg			;       NO  - show avg depth
+
+TFT_avr_stopwatch_avg:
+	MOVII	pressure_rel_avg_total,mpr		; get total dive average pressure into hi:lo
+	bra		TFT_avr_stopwatch_2				; continue
+
+TFT_avr_stopwatch_max:
+	MOVII	pressure_rel_max_cached,mpr		; get maximum pressure into hi:lo
+	;bra	TFT_avr_stopwatch_2				; continue
+
+TFT_avr_stopwatch_2:
+	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
+	;bra	TFT_update_avr_stopwatch1_imp	; 1 - imperial
+
+TFT_update_avr_stopwatch1_imp:
+	call	convert_cm_to_feet				; convert value in hi:lo from [cm] to [feet]
+	output_999								; print (0-999)
+	PRINT									; dump to screen
+	bra		TFT_update_avr_stopwatch2		; continue
+
+TFT_update_avr_stopwatch1_metric:
+	rcall	TFT_update_avr_stopwatch_metric	; print metric depth
+	;bra	TFT_update_avr_stopwatch2		; continue
+
+TFT_update_avr_stopwatch2:
+	; 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 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
+	;bra	TFT_update_avr_stopwatch2_imp	; 1 - imperial
+
+TFT_update_avr_stopwatch2_imp:
+	call	convert_cm_to_feet				; convert value in hi:lo from [cm] to [feet]
+	output_999								; print (0-999)
+	PRINT									; dump to screen
+	bra		TFT_update_avr_stopwatch3		; continue
+
+TFT_update_avr_stopwatch2_metric:
+	rcall	TFT_update_avr_stopwatch_metric	; print metric depth
+	bra		TFT_update_avr_stopwatch3		; continue
+
+
+; Helper Function - print metric depth
+TFT_update_avr_stopwatch_metric:
+	bsf		leftbind					; print left-aligned
+	bsf		omit_digit_1				; do not print 1st digit (no cm)
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_65535						; print (0.0x-655.3x)
+	PUTC	" "							; wipe out remains from last output
+	clrf	WREG
+	movff	WREG,buffer+.4				; limit string length to 4 = 3 digits + 1 half-size decimal dot
+	PRINT								; dump to screen
+	return								; done
+
+ ELSE
+
+	; resettable maximum depth - needs ISR-safe copy!
+	WIN_MEDIUM dm_custom_avr_stop_column1,dm_custom_avr_stop_row
+	FONT_COLOR_MEMO						; select color
+	SMOVII	pressure_rel_max_trip,mpr	; get resettable maximum pressure
+	rcall	TFT_avr_stopwatch_helper	; print depth
+
+	; resettable average depth
+	WIN_MEDIUM dm_custom_avr_stop_column2-.1,dm_custom_avr_stop_row
+	FONT_COLOR_ATTENTION				; select color
+	MOVII	pressure_rel_avg_trip,mpr	; get resettable average pressure
+	rcall	TFT_avr_stopwatch_helper	; print depth
+
+	; resettable minimum depth - needs ISR safe copy!
+	WIN_MEDIUM dm_custom_avr_stop_column3-.12,dm_custom_avr_stop_row
+	FONT_COLOR_MEMO						; select color
+	SMOVII	pressure_rel_min_trip,mpr	; get resettable minimum pressure
+	rcall	TFT_avr_stopwatch_helper	; print depth
+
+	return								; done
+
+TFT_avr_stopwatch_helper:
+	call	convert_pres_to_depth		; convert pressure in [mbar] to depth in [cm]
+	bsf		leftbind					; print left-aligned
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_65535						; print (0.00-655.35)
+	PUTC	" "							; wipe out remains from last output
+	clrf	WREG						; load string terminator
+	movff	WREG,buffer+.5				; limit string length to 5 = 4 digits + 1 half-size decimal dot
+	PRINT								; dump to screen
+	return								; done
+
+ ENDIF
+
+TFT_update_avr_stopwatch3:
+	WIN_MEDIUM dm_custom_avr_stop_column2,dm_custom_avr_stop_row
+	;bra	TFT_update_stopwatch		; continue
+
+TFT_update_stopwatch:
+	; jump-in point for stopped dive time in compass custom view
+	MOVII	divesecs_avg_trip,mpr		; get the resettable dive time (stopwatch)
+	call	convert_time				; convert hi:lo in seconds to minutes (up:hi) and seconds (lo)
+	movlw	.100						; display layout will change if minutes become >= 100
+	cpfslt	hi							; minutes < 100 ?
+	bra		TFT_update_stopwatch_1		; NO  - display hours:minutes
+	bcf		aux_flag					; YES - will print minutes : seconds
+	bra		TFT_update_stopwatch_2		;     - continue
+
+TFT_update_stopwatch_1:
+	movff	hi,lo						; transfer minutes (low  byte) to lo
+	movff	up,hi						; transfer minutes (high byte) to hi
+	call	convert_time				; convert hi:lo in minutes to hours (up:hi) and minutes (lo)
+	bsf		aux_flag					; will print hours : minutes
+
+TFT_update_stopwatch_2:
+	movf	hi,W						; exchange lo and hi
+	movff	lo,hi						; ...
+	movwf	lo							; ...
+	output_99							; print minutes or hours (0 - 99)
+	movlw	":"							; load standard separator
+	btfsc	aux_flag					; will print hours : minutes ?
+	movlw	"'"							; YES - swap to alternative separator
+	movwf	POSTINC2					; print separator
+	movff	hi,lo						; restore lo
+	output_99x							; print seconds or minutes (00-99)
+	movlw	.5							; set target length
+	call	TFT_buffer_trim_length		; fill / cut buffer to target length
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Gas Needs - Mask
+;
+	global	TFT_gas_needs_mask
+TFT_gas_needs_mask:
+	WIN_TINY dm_custom_gas_column_title, dm_custom_gas_mask_row
+	FONT_COLOR_MASK						; select color
+
+ IFDEF _cave_mode
+
+	movff	char_O_deco_info,WREG		; get the deco info vector
+	btfss	WREG,gas_needs_cave			; are the gas needs calculated for cave mode?
+	bra		TFT_gas_needs_mask_ascent_1	; NO  - show as direct ascent needs
+	;bra	TFT_gas_needs_mask_ascent_0	; YES - show as cave   return needs
+
+TFT_gas_needs_mask_ascent_0:
+	bsf		gas_needs_mode_last			; remember last results were for cave mode
+	STRCPY_TEXT tGasNeedsCaveMode		; print "Gas Needs Cave Mode"
+	bra		TFT_gas_needs_mask_ascent_2	; continue
+
+TFT_gas_needs_mask_ascent_1:
+	bcf		gas_needs_mode_last			; remember last results were for direct ascent
+	STRCPY_TEXT tGasNeedsAscent			; "Gas Needs Ascent"
+	;bra	TFT_gas_needs_mask_ascent_2	; continue
+
+ ELSE
+
+	STRCPY_TEXT tGasNeedsAscent			; "Gas Needs Ascent"
+
+ ENDIF
+
+TFT_gas_needs_mask_ascent_2:
+	TSTOSS	char_I_extra_time			; fTTS enabled?
+	bra		TFT_gas_needs_mask_ascent_3	; NO  - continue
+	STRCAT	" fTTS"						; YES - append fTTS marking
+TFT_gas_needs_mask_ascent_3:
+	STRCAT_PRINT " (bar)"				; append " (bar)" and dump buffer to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Gas Needs - Data
+;
+; 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
+TFT_gas_needs:
+
+ 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?
+	bra		TFT_gas_needs_ascent_1		; NO  - continue below...
+	btfsc	gas_needs_mode_last			; YES - were the last results calculated for cave mode?
+	bra		TFT_gas_needs_ascent_3		;       YES - mask still valid
+	bra		TFT_gas_needs_ascent_2		;       NO  - redraw mask
+
+TFT_gas_needs_ascent_1:
+	btfss	gas_needs_mode_last			; NO  - were the last results calculated for direct ascent?
+	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_mask			; redraw mask
+	;bra	TFT_gas_needs_ascent_3		; continue
+
+ ENDIF
+
+TFT_gas_needs_ascent_3:
+	clrf	up												; initialize gas index (0-4)
+	WIN_SMALL dm_custom_gas_column1+.5,dm_custom_gas_row1	; set position
+	rcall	TFT_gas_needs_helper							; print need
+	WIN_SMALL dm_custom_gas_column1+.5,dm_custom_gas_row2	; set position
+	rcall	TFT_gas_needs_helper							; print need
+	WIN_SMALL dm_custom_gas_column2+.5,dm_custom_gas_row1	; set position
+	rcall	TFT_gas_needs_helper							; print need
+	WIN_SMALL dm_custom_gas_column2+.5,dm_custom_gas_row2	; set position
+	rcall	TFT_gas_needs_helper							; print need
+	return													; done
+
+
+	; Helper Function - print need for next gas
+TFT_gas_needs_helper:
+	FONT_COLOR_MEMO						; select default color
+	movlw	.5							; total number of gases
+	cpfslt	up							; check if all gases have been processed
+	bra		TFT_gas_needs_helper_1		; YES - clear display area
+	movf	up,W						; NO  - get gas number and check if need of that gas is > 0
+	rlncf	WREG,W						;     - multiply by 2
+	incf	WREG,W						;     - add 1 to address high byte
+	lfsr	FSR1,int_O_gas_need_pres	;     - load base of gas needs in pressure
+	movff	PLUSW1,hi					;     - read HIGH(int_O_gas_need_pres[up])
+	btfss	hi,int_is_zero				;     - check flag for pres_need == 0
+	bra		TFT_gas_needs_helper_2		;       NO  - print gas type and pressure needed
+	incf	up,F						;       YES - increment to next gas
+	bra		TFT_gas_needs_helper		;           - loop and try the next gas
+
+TFT_gas_needs_helper_1:	
+	; no gases to show anymore, clear display area from potential remains of last invocation
+	STRCAT_PRINT "  ----   "			; overwrite outdated stuff if screen position is not needed
+	return								; done
+
+TFT_gas_needs_helper_2:
+	; output gas type and pressure needed
+	movf	up,W						; get gas number (0-4) to WREG
+	lfsr	FSR1,opt_gas_O2_ratio		; read opt_gas_O2_ratio[WREG]
+	movff	PLUSW1,lo					; copy result to lo
+	lfsr	FSR1,opt_gas_He_ratio		; read opt_gas_He_ratio[WREG]
+	movff	PLUSW1,hi					; copy result to hi
+	call	gaslist_strcat_mix			; print "Air", "O2", "21/35", etc.
+	PUTC	':'							; print ":"
+	movf	up,W						; get gas number (0-4) to WREG
+	rlncf	WREG,W						; multiply by 2
+	lfsr	FSR1,int_O_gas_need_pres	; load base of gas needs in pressure
+	movff	PLUSW1,lo					; read LOW(int_O_gas_need_pres[up])
+	incf	WREG,W						; add 1 to address high byte
+	movff	PLUSW1,hi					; read HIGH(int_O_gas_need_pres[up])
+	btfsc	hi,int_attention_flag		; check if attention flag is set (pres_need > pres_fill * threshold)
+	FONT_COLOR_ATTENTION				; YES - print gas need in attention color
+	btfsc	hi,int_warning_flag			; check if warning   flag is set (pres_need > pres_fill)
+	FONT_COLOR_WARNING					; YES - print gas need in warning color
+	movff	int_O_gas_need_pres+1,WREG	; get HIGH(int_O_gas_need_pres[0]) which holds flag for invalid data
+	btfsc	WREG,int_invalid_flag		; check if invalid data flag is set
+	FONT_COLOR_DISABLED					; YES - print gas need in disabled color
+	bcf		hi,int_attention_flag		; clear flag for attention
+	bcf		hi,int_warning_flag			; clear flag for warning
+	bcf		hi,int_high_flag			; clear flag for > 999 bar
+	bcf		hi,int_invalid_flag			; clear flag for invalid data (will actually only be set with 1st gas)
+	output_999							; print (0-999)
+	PUTC_PRINT " "						; add a space to overwrite any potential remains of earlier outputs and dump buffer to screen
+	incf	up,F						; increment to next gas
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Deco Plan - Mask
+;
+	global	TFT_decoplan_mask			; mask for deco plan
+TFT_decoplan_mask:
+	WIN_TINY dm_custom_decoplan_title_column, dm_custom_decoplan_title_row
+	FONT_COLOR_MASK						; select color
+	STRCPY_TEXT_PRINT tDiveDecoplan		; print label
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Deco Plan - Data
+;
+	global	TFT_decoplan
+TFT_decoplan:
+	lfsr	FSR0,char_O_deco_depth		; load base address of stops table
+	clrf	ex							; will be used for auxiliary flags
+	FONT_COLOR_MEMO						; set default output color
+	movff	char_O_deco_gas+0,lo		; get flag for invalid deco data
+	btfsc	lo,char_invalid_flag		; is the invalid flag set?
+	FONT_COLOR_DISABLED					; YES - set to disabled color
+	; 2nd stop
+	WIN_SMALL dm_cust_dstop_2nd_stop_column, dm_cust_dstop_2nd_stop_row
+	rcall	TFT_decoplan_helper			; show stop data
+	; 3rd stop
+	WIN_SMALL dm_cust_dstop_3rd_stop_column, dm_cust_dstop_3rd_stop_row
+	rcall	TFT_decoplan_helper			; show stop data
+	; 4th stop
+	bsf		ex,4						; flag we are on 4th screen position
+	WIN_SMALL dm_cust_dstop_4th_stop_column, dm_cust_dstop_4th_stop_row
+	rcall	TFT_decoplan_helper			; show stop data
+	bcf		ex,4						; clear 4th position flag again
+	; 5th stop
+	WIN_SMALL dm_cust_dstop_5th_stop_column, dm_cust_dstop_5th_stop_row
+	rcall	TFT_decoplan_helper			; show stop data
+	; 6th stop
+	WIN_SMALL dm_cust_dstop_6th_stop_column, dm_cust_dstop_6th_stop_row
+	rcall	TFT_decoplan_helper			; show stop data
+	; 7th stop
+	WIN_SMALL dm_cust_dstop_7th_stop_column, dm_cust_dstop_7th_stop_row
+	rcall	TFT_decoplan_helper			; show stop data
+	return								; done
+
+
+	; Helper Function - show stop data
+TFT_decoplan_helper:
+	btfsc	ex,0						; no more stops to show?
+	bra		TFT_decoplan_helper_1		; YES - skip checking next entry - it will be empty, too
+	movff	PREINC0,lo					; NO  - advance pointer to get the depth of the 2nd, 3rd, 4th, ... stop
+	tstfsz	lo							;       is the stop depth = 0, i.e. no stop entry?
+	bra		TFT_decoplan_helper_3		;       NO  - show stop data
+
+TFT_decoplan_helper_1:					; no more stop table entries
+	bsf		ex,0						; flag that there are no more stop table entries
+	btfss	ex,4						; are we on the 4th screen position?
+	bra		TFT_decoplan_helper_2		; NO  - normal handling on this position
+	btfsc	ex,1						; YES - special handling, has any stop been shown?
+	bra		TFT_decoplan_helper_2		;       YES - print normal blanking
+	STRCPY_PRINT "  ---- "				;       NO  - print a "no stops" indication (blanking potential previous content, too)
+	return								;            done
+
+TFT_decoplan_helper_2:					; no more stop table entries, blank potential previous content
+	STRCPY_PRINT "       "				; wipe screen position by printing 7 spaces
+	return								; done
+
+TFT_decoplan_helper_3:
+	rcall	TFT_display_stop_depth		; print stop depth (depth in lo)
+	PUTC	" "							; put a space char between depth and time
+	movlw	NUM_STOPS					; offset between arrays holding depths and durations
+	movff	PLUSW0,lo					; get duration of the current stop
+	output_99dd							; print duration, prints double dots if duration is zero
+	PUTC_PRINT "'"						; append unit and dump buffer to screen
+	bsf		ex,1						; flag that a stop was shown
+	return								; done
+
+
+	; Helper Function - print stop depth
+TFT_display_stop_depth:					; print depth (stored in lo)
+	TSTOSS	opt_units					; get unit (0=m, 1=ft)
+	bra		TFT_display_stop_depth_m	; 0 - meter
+	;bra	TFT_display_stop_depth_ft	; 1 - feet
+
+TFT_display_stop_depth_ft:
+	call	convert_meter_to_feet		; convert value in lo from meters to feet
+	output_999							; output stop depth (0-999)
+	return								; done
+
+TFT_display_stop_depth_m:
+	output_99							; output stop depth (0-99)
+	STRCAT_TEXT tMeters					; append unit
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Ceiling, Supersaturation & Tissues - Mask
+;
+	global	TFT_ceiling_GF_tissue_mask
+TFT_ceiling_GF_tissue_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_ceiling_column+.2,dm_custom_ceiling_title_row
+	STRCPY_TEXT_PRINT tCeiling			; print label
+
+	WIN_TINY dm_custom_tissue_title_column, dm_custom_tissue_title_row
+	STRCPY_TEXT_PRINT tDiveTissues		; print label
+
+	WIN_TINY dm_custom_gf_column1+.5, dm_custom_gf_title_row
+	STRCPY_TEXT_PRINT tGFInfo			; print label
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Ceiling, Supersaturation & Tissues - Data
+;
+	global	TFT_ceiling_GF_tissue
+TFT_ceiling_GF_tissue:
+	WIN_MEDIUM dm_custom_ceiling_column,dm_custom_ceiling_row
+	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_GF_tissue_metric	; 0 - meter
+	;bra	TFT_ceiling_GF_tissue_imperial	; 1 - feet
+
+TFT_ceiling_GF_tissue_imperial:
+	call	convert_cm_to_feet			; convert value in hi:lo from [cm] to [feet]
+	output_999							; print (0-999)
+	bra		TFT_ceiling_GF_tissue0		; continue
+
+TFT_ceiling_GF_tissue_metric:
+	bsf		omit_digit_1				; do not print 1st digit
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	bsf		leftbind					; print left-aligned
+	output_65535						; print (xxx.x-)
+	bra		TFT_ceiling_GF_tissue0		; continue
+
+TFT_ceiling_GF_tissue0:
+	PUTC_PRINT " "						; append a space and dump to screen
+	; show tissue diagram
+	rcall	TFT_dive_tissues			; show tissue pressure diagram
+	; show current supersaturation
+	WIN_MEDIUM dm_custom_clock_column+.3, dm_custom_gf_row
+	MOVII	int_O_lead_supersat,mpr		; bank-safe copy of leading tissue's supersaturation
+	call	TFT_color_code_supersat		; color-code output
+	output_256							; need to print lo only, int_O_lead_supersat value is limited to 255
+	PRINT								; dump to screen
+	WIN_STD	dm_custom_clock_column+.40, dm_custom_gf_row+.5
+	PUTC_PRINT "%"						; print "%" and dump to screen
+	return								; done
+
+
+	;-------------------------------------------------------------------------
+	; Draw saturation graph in dive mode custom view
+	;
+TFT_dive_tissues:
+	; draw outer frame
+	movf	pallet_color_memo,W					; get color into WREG
+	WIN_FRAME_COLOR 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)
+	movlw	dm_custom_tissue_diagram_left+.3	; get dive mode left start position
+	movwf	win_leftx2							; set column left (0-159)
+	movlw	.159-dm_custom_tissue_diagram_left-.4 ; get max width
+	movwf	win_width+0							; set width (low byte)
+	clrf	win_width+1							; high byte of with is always zero
+	movlw	color_cyan							; color for tissues with decreasing pressure
+	movwf	ex									; store in ex
+	movlw	color_orange						; color for tissues with increasing pressure
+	movwf	ul									; store in ul
+
+	; draw combined or N2 tissue pressures
+	lfsr	FSR2,char_O_tissue_pressure			; load base address of combined pressures by default
+ IFDEF _helium
+	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
+	clrf	hi									; row    counter
+TFT_dive_tissues_N2_loop:
+	movlw	dm_custom_tissue_diagram_top+.3		; dive mode top start position N2
+	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_N2_loop			; NO - loop
+ IFDEF _helium
+	btfsc	tissue_graphic_layout				; shall show N2+He ?
+	bra		TFT_dive_tissues_3					; YES - show He tissue pressures
+ ENDIF
+
+	; draw tissue saturations
+	lfsr	FSR2,char_O_tissue_saturation		; load base address of tissue supersaturation
+	movlw	d'16'
+	movwf	lo									; tissue counter, 16 tissues
+	clrf	hi									; row    counter
+	movlw	color_grey							; color for tissue saturation, alternative: color_lightblue
+	movwf	ex									; store in ex
+;	movlw	color_yellow						; 2nd color is not used by tissue saturation
+;	movwf	ul									; ...
+TFT_dive_tissues_sat_loop:
+	movlw	dm_custom_tissue_diagram_top+.25	; dive mode top start position saturations
+	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_sat_loop			; NO - loop
+
+	; common part for vertical lines
+	movlw	dm_custom_tissue_diagram_top+.25	; get top position
+	movwf	win_top								; set top position (0-239)
+	movlw	.15									; get hight
+	movwf	win_height							; set height
+	movlw	.1									; get width
+	movwf	win_width+0							; set width, low  byte
+	clrf	win_width+1							; set width, high byte
+
+	; print 100% line
+	movlw	dm_custom_tissue_diagram_left+.36	; get left position
+	movwf	win_leftx2							; set left position (0-159)
+	movlw	color_red							; color for 100% line
+	BOX_COLOR									; draw line
+
+	; 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
+	movlw	dm_custom_tissue_diagram_left+.3	; get left base position
+	movwf	win_leftx2							; set left base position (0-159)
+	movff	char_I_GF_Low_percentage,WREG		; get GF low in 0.01 %
+	mullw	.82									; multiply with 82
+	movf	PRODH,W								; divide   by   256 -> resulting scale factor is 82/256 = 0.3203125
+	addwf	win_leftx2,F						; add to base position
+	movlw	color_green							; color for GF low line
+	BOX_COLOR									; draw line
+
+	; print GF high line
+	movlw	dm_custom_tissue_diagram_left+.3	; get left base position
+	movwf	win_leftx2							; set left base position (0-159)
+	movff	char_I_GF_High_percentage,WREG		; get GF high in 0.01 %
+	mullw	.82									; multiply with 82
+	movf	PRODH,W								; divide   by   256 -> resulting scale factor is 82/256 = 0.3203125
+	addwf	win_leftx2,F						; add to base position
+	movlw	color_yellow						; color for GF high line
+	BOX_COLOR									; draw line
+
+ 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+.7	; get dive mode left start position for He bars
+	movwf	win_leftx2							; set column left (0-159)
+	movlw	.159-dm_custom_tissue_diagram_left-.8 ; get max width for He bars
+	movwf	win_width+0							; set width (low byte)
+	clrf	win_width+1							; ...
+	movlw	d'16'
+	movwf	lo									; tissue counter, 16 tissues
+	clrf	hi									; row    counter
+TFT_dive_tissues_He_loop:
+	movlw	dm_custom_tissue_diagram_top+.25	; dive mode top start position H2
+	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
+ ENDIF
+
+TFT_dive_tissues_4:
+	; print number of leading tissue	; TODO: some flicker due to overwriting by tissue bars
+	movff	int_O_lead_supersat+0,WREG	; get current leading tissue's supersaturation (only low byte used for value)
+	tstfsz	WREG						; current supersaturation = 0 ?
+	bra		TFT_dive_tissues_5			; NO  - print number of leading tissue
+	movff	char_O_deco_info,WREG		; YES - get deco info vector
+	btfss	WREG,deco_ceiling			;     - do we have a ceiling obligation?
+	return								;       NO  - can ascent directly, don't print number, set standard color and return
+										;       YES - print number of leading tissue
+TFT_dive_tissues_5:
+	movff	char_O_lead_tissue,lo		; get number of leading tissue as 0-15
+	incf	lo,F						; adjust to 1-16
+	movlw	.10
+	cpfsgt	lo							; is it > 10 ?
+	bra		TFT_dive_tissues_6			; NO - will output a single digit number
+	; start position for a 2 digit number
+	WIN_TINY dm_custom_tissue_diagram_left+.32,dm_custom_tissue_diagram_top+.10
+	bra		TFT_dive_tissues_7
+TFT_dive_tissues_6:
+	; start position for a 1 digit number
+	WIN_TINY dm_custom_tissue_diagram_left+.32+.4,dm_custom_tissue_diagram_top+.10
+TFT_dive_tissues_7:
+	FONT_COLOR_MEMO						; set output color
+	bsf		leftbind					; print left-aligned
+	output_99							; print tissue number (0-99)
+	PRINT								; dump buffer to screen
+	return								; done
+
+
+	; Helper Function - draw a bargraph
+TFT_dive_tissues_bargraph:
+	addwf	hi,W						; add row number to start position
+	movwf	win_top						; set as row top (0-239)
+	movff	POSTINC2,up					; get tissue value
+	movf	ex,W						; default color
+	btfsc	up,7						; check if flag in bit 7 is set
+	movf	ul,W						; YES - switch to 2nd color
+	bcf		up,7						; clear flag  bit
+	bcf		STATUS,C					; clear carry bit
+	rrcf	up,F						; divide by 2
+	movff	up,win_bargraph				; set bargraph length
+	incf	win_bargraph,F				; add a bit for a minimum visible bar
+	BOX_COLOR							; draw bargraph
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - CNS - Mask
+;
+	global	TFT_CNS_mask
+TFT_CNS_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_cns3_column1, dm_custom_cns3_title_row
+	STRCPY_TEXT_PRINT tCNSsurf			; print label
+
+	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_col2			; NO
+	STRCPY_TEXT_PRINT tCNScave			; YES - print cave TTS label
+	bra		TFT_CNS_mask_col3			;     - continue with 3rd column
+ ENDIF
+
+TFT_CNS_mask_col2:
+	btfsc	FLAG_oc_mode				; in OC mode?
+	bra		TFT_CNS_mask_ftts			; YES - print fTTS label
+	btfsc	bailout_mode				; NO  - in bailout?
+	bra		TFT_CNS_mask_ftts			;       YES - print fTTS label (label will be printed, but a fTTS will actually not be calculated)
+	TSTOSS	opt_calc_gasvolume			;       NO  - bailout volume calculation requested?
+	bra		TFT_CNS_mask_ftts			;             NO  - print fTTS label
+	;bra	TFT_CNS_mask_bo				;             YES - print bailout label
+
+TFT_CNS_mask_bo:
+	STRCPY_TEXT_PRINT tCNSBO			; print bailout label
+	bra		TFT_CNS_mask_col3			; continue with 3rd column
+
+TFT_CNS_mask_ftts:
+	STRCPY_TEXT_PRINT tCNSfTTS			; print fTTS label
+	;bra	TFT_CNS_mask_col3			; continue with 3rd column
+
+TFT_CNS_mask_col3:
+	WIN_TINY dm_custom_cns3_column3, dm_custom_cns3_title_row
+	STRCPY_TEXT_PRINT tCNSnow			; print CNS now label
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - CNS - Data
+;
+	global	TFT_CNS
+TFT_CNS:
+	; CNS at end of normal dive
+	WIN_STD dm_custom_cns3_column1+.3,dm_custom_cns3_row
+	MOVII	int_O_CNS_norm,mpr			; get CNS at end of dive in normal plan
+	call	TFT_color_code_cns			; color-code the CNS value
+	bsf		leftbind					; print left-aligned
+	output_999							; print (0-999)
+	STRCAT_PRINT "% "					; append unit and trailing space and dump to screen
+	; fTTS / Bailout CNS, if enabled
+	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_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%
+	;bra	TFT_CNS_1					;             YES - continue checking fTTS extra time
+
+TFT_CNS_1:
+	; not in bailout, no volume calculation, and/or in OC mode
+	TSTOSS	char_I_extra_time			; fTTS extra time configured?
+	bra		TFT_CNS_3					; NO  - show "---"
+	;bra	TFT_CNS_2					; YES - show CNS%
+
+TFT_CNS_2:
+	MOVII	int_O_CNS_alt,mpr			; get CNS at end of dive in alternative plan
+	call	TFT_color_code_cns			; color-code the CNS value
+	bsf		leftbind					; print left-aligned
+	output_999							; print (0-999)
+	STRCAT_PRINT "% "					; append unit and trailing space and dump to screen
+	bra		TFT_CNS_4					; continue
+
+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:
+	FONT_COLOR_MEMO						; select color
+	STRCPY_PRINT "---  "				; print non-avail symbol
+	;bra	TFT_CNS_4					; continue
+
+TFT_CNS_4:
+	; current CNS
+	WIN_STD dm_custom_cns3_column3+.3,dm_custom_cns3_row
+	MOVII	int_O_CNS_current,mpr		; get current CNS
+	call	TFT_color_code_cns			; color-code the CNS value
+	bsf		leftbind					; print left-aligned
+	output_999							; print (0-999)
+	PUTC_PRINT "%"						; append unit and dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - ppO2, EAD/END & Gas Density - Mask
+;
+	global TFT_ppo2_ead_end_cns_mask
+TFT_ppo2_ead_end_cns_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_ppo2_column-.2,dm_custom_ppo2_title_row
+	STRCPY_TEXT_PRINT tppO2				; print label
+
+	WIN_TINY dm_custom_ead_column,dm_custom_eadend_title_row
+	STRCPY_TEXT_PRINT tDiveEAD_END		; print label
+
+ IFDEF _ccr_pscr
+	WIN_TINY dm_custom_cns_column-.5,dm_custom_eadend_title_row
+	STRCPY_TEXT_PRINT tGasDensity		; print label
+ ELSE
+	WIN_TINY dm_custom_cns_column,dm_custom_cns_title_row
+	STRCPY_TEXT_PRINT tCNS2				; print label
+ ENDIF
+
+	return								; done
+
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - ppO2, EAD/END & Gas Density - Data
+;
+	global	TFT_ppo2_ead_end_cns
+TFT_ppo2_ead_end_cns:
+	; show ppO2
+	WIN_MEDIUM dm_custom_ppo2_column, dm_custom_ppo2_row
+	MOVII	int_O_breathed_ppO2,mpr		; copy ppO2 of the currently breathed gas to hi:lo
+	call	TFT_color_code_ppo2			; color-code output
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_999							; print ppO2 (0.00-9.99)
+	PRINT								; dump to screen
+	; show END/EAD
+	FONT_COLOR_MEMO						; select color
+	WIN_SMALL	dm_custom_ead_column, dm_custom_ead_row
+	STRCPY_TEXT tEAD					; print "EAD:"
+	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					; print "END:"
+	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
+	MOVII	int_O_gas_density,mpr		; get current gas density
+	call	TFT_color_code_cns			; color-code output
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_999							; print (0.00-9.99)
+	PRINT								; dump to screen
+ ELSE
+	; show CNS
+	WIN_STD	dm_custom_cns_column+.3, dm_custom_cns_row
+	MOVII	int_O_CNS_current,mpr		; get current CNS
+	call	TFT_color_code_cns			; color-code CNS output
+	bsf		leftbind					; print left-aligned
+	output_999							; print (0-999)
+	PUTC_PRINT "%"						; append unit and dump buffer to screen
+ ENDIF
+	return								; done
+
+
+	; Helper Function - convert to depth, print and limit to 8 chars
+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	; 0: meter
+	;bra	TFT_end_ead_common_imperial	; 1: feet
+
+TFT_end_ead_common_imperial:
+	call	convert_cm_to_feet			; convert depth in [cm] to depth in [feet]
+	output_999							; print (0-999)
+	PRINT								; dump buffer to screen
+	return								; done
+
+TFT_end_ead_common_metric:
+	bsf		omit_digit_2				; do not print 2nd and 1st digit
+	output_65535						; print (0xx-655xx)
+	PUTC_PRINT 'm'						; append unit and dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - GF Factors (Mask only)
+;
+	global	TFT_gf_factors_mask
+TFT_gf_factors_mask:
+	FONT_COLOR_MASK						; select color
+
+	; show labels
+	WIN_TINY dm_custom_gf_column1,dm_custom_gf_title_row
+	STRCPY_TEXT_PRINT tGFactors
+	WIN_TINY dm_custom_gf_column3,dm_custom_gf_title_row
+	STRCPY_TEXT_PRINT taGFactors
+
+	; show GF (static)
+	WIN_STD	dm_custom_gf_column1, dm_custom_gf_row
+	FONT_COLOR_DISABLED					; default to disabled color
+	btfss	use_aGF						; shall use alternative GF factors?
+	FONT_COLOR_MEMO						; NO - switch to memo color
+	movff	opt_GF_low, lo				; get   normal GF low
+	movff	opt_GF_high,hi				; get   normal GF high
+	rcall	TFT_gf_factors_mask_helper	; print GFs
+
+	; show aGF (static)
+	FONT_COLOR_MEMO						; select memo color
+	TSTOSS	opt_enable_aGF				; are alternative GF factors enabled?
+	bra		TFT_gf_factors_mask_3		; NO  - show "---" and return
+	; bra	TFT_gf_factors_mask_0		; YES - show arrow
+
+TFT_gf_factors_mask_0:
+	WIN_STD	dm_custom_gf_column2, dm_custom_gf_row
+	btfss	use_aGF						; shall use aGF?
+	bra		TFT_gf_factors_mask_1L		; NO   - print "<- "
+	;bra	TFT_gf_factors_mask_1R		; YES  - print " ->"
+
+TFT_gf_factors_mask_1R:
+	STRCPY_PRINT " ->"					; print " ->"
+	bra		TFT_gf_factors_mask_2		; continue
+
+TFT_gf_factors_mask_1L:
+	STRCPY_PRINT "<- "					; print "<- "
+	;bra	TFT_gf_factors_mask_2		; continue
+
+TFT_gf_factors_mask_2:
+	WIN_STD	dm_custom_gf_column3, dm_custom_gf_row
+	;FONT_COLOR_MEMO						; select memo color (still selected)
+	btfss	use_aGF						; shall use aGF?
+	FONT_COLOR_DISABLED					; NO - switch to disabled color
+	movff	opt_aGF_low, lo				; get aGF low
+	movff	opt_aGF_high,hi				; get aGF high
+	rcall	TFT_gf_factors_mask_helper	; print GFs
+	return								; done
+
+TFT_gf_factors_mask_3:
+	WIN_STD	dm_custom_gf_column3+.10, dm_custom_gf_row
+	STRCPY_PRINT "---"					; print not-avail symbol
+	return								; done
+
+	; Helper Function - print GF pair
+TFT_gf_factors_mask_helper:
+	output_256							; print GF low  (0-255)
+	PUTC	"/"							; print "/"
+	movff	hi,lo						; get   GF high
+	output_256							; print GF high (0-255)
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Clock, Battery & Surface Pressure - Mask
+;
+	global	TFT_clock_batt_surfpress_mask
+TFT_clock_batt_surfpress_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_clock_column, dm_custom_clock_title_row
+	STRCPY_TEXT_PRINT tTime				; "Time"
+
+	WIN_TINY dm_custom_battery_column, dm_custom_battery_title_row
+	STRCPY_TEXT_PRINT tBattery			; "Battery"
+
+	WIN_TINY dm_custom_surfpres_column+.8, dm_custom_surfpres_title_row
+	STRCPY_TEXT_PRINT tSurface			; "Surface"
+
+	; show configured surface pressure (done in mask, because it's static during the dive)
+	WIN_SMALL dm_custom_surfpres_column, dm_custom_surfpres_row
+	FONT_COLOR_MEMO						; select color
+	MOVII	pressure_surf,mpr			; get surface pressure
+	output_65535						; print (5 digits, first one used as spacer)
+	PUTC	' '							; print a space
+	STRCAT_TEXT_PRINT tMBAR				; append unit and dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Clock, Battery & Surface Pressure - Data
+;
+	global	TFT_clock_batt_surfpress
+TFT_clock_batt_surfpress:
+	; update clock
+	WIN_SMALL dm_custom_clock_column, dm_custom_clock_row
+	FONT_COLOR_MEMO						; select color
+	SMOVSS	rtc_year,rtc_latched_year	; ISR-safe 6 byte copy of date and time
+	movff	rtc_latched_hour,lo			; get   hours
+	output_99							; print hours (0-99)
+	PUTC	':'							; print ":"
+	movff	rtc_latched_mins,lo			; get   minutes
+	output_99x							; print minutes (00-99)
+	PUTC	":"							; print ":"
+	movff	rtc_latched_secs,lo			; get   seconds
+	output_99x							; print seconds (00-99)
+	PRINT								; dump to screen
+
+	; show battery voltage
+	WIN_SMALL dm_custom_battery_column, dm_custom_battery_volt_row
+	;FONT_COLOR_MEMO						; select color
+	MOVII	batt_voltage,mpr			; get voltage
+	bsf		decimal_digit3				; place a decimal point in front of digit 3
+	bsf		omit_digit_1				; do not print 1st digit 
+	output_9999							; print voltage (0.00x-9.99x)
+	PUTC_PRINT 'V'						; append unit and dump to screen
+
+	; show battery percent
+	WIN_SMALL dm_custom_battery_column+.7, dm_custom_battery_percent_row
+	call	TFT_color_code_battery		; color-code according to battery_low_condition flag
+	movff	batt_percent,lo				; get   battery %
+	output_256							; print battery % (0-999)
+	PUTC_PRINT "%"						; append unit and dump to screen
+
+	; surface pressure is shown via the mask because it is static
+	return								; done
+
+
+ IFDEF _ccr_pscr
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Sensor Check - Mask
+;
+	global	TFT_sensor_check_mask
+TFT_sensor_check_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_s_check_title_column, dm_custom_s_check_title_row
+	STRCPY_TEXT_PRINT tSensorCheck		; print label
+
+	WIN_TINY dm_custom_ppO2_column, dm_custom_s_check_title_row
+	STRCPY_TEXT_PRINT tppO2O2			; print label
+
+	WIN_TINY dm_custom_ppDil_column, dm_custom_s_check_title_row
+	STRCPY_TEXT_PRINT tppO2Dil			; print label
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Sensor Check - Data
+;
+	global	TFT_sensor_check
+TFT_sensor_check:
+	; show ppO2 of O2 in this depth
+	WIN_MEDIUM dm_custom_ppO2_column, dm_custom_s_check_row
+	MOVII	int_O_O2_ppO2,mpr			; copy ppO2 of pure O2 to hi:lo
+	rcall	TFT_sensor_check_helper		; print ppO2
+	; show ppO2 of the diluent in this depth
+	WIN_MEDIUM	dm_custom_ppDil_column, dm_custom_s_check_row
+	MOVII	int_O_pure_ppO2,mpr			; copy ppO2 of pure gas to hi:lo
+	rcall	TFT_sensor_check_helper		; print ppO2
+	return								; done
+
+TFT_sensor_check_helper:
+	call	TFT_color_code_ppo2			; color-code output
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_999							; print ppO2 (0.00-9.99)
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - pSCR Info - Mask
+;
+	global	TFT_pscr_info_mask
+TFT_pscr_info_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_pscr_drop_column, dm_custom_pscr_title_row
+	STRCPY_TEXT_PRINT tPSCR_O2_drop		; print label
+
+	WIN_TINY dm_custom_pscr_ratio_column, dm_custom_pscr_title_row
+	STRCPY_TEXT_PRINT tPSCR_lungratio	; print label
+
+	WIN_TINY dm_custom_ppo2_column-.2,dm_custom_ppo2_title_row
+	btfsc	bailout_mode				; in bailout?
+	bra		TFT_pscr_info_mask_2		; YES
+	;bra	TFT_pscr_info_mask_1		; NO
+
+TFT_pscr_info_mask_1:
+	STRCPY_TEXT_PRINT tppO2Mix			; print "ppO2(Mix)"
+	return								; done
+
+TFT_pscr_info_mask_2:
+	STRCPY_TEXT_PRINT tppO2				; print "ppO2"
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - pSCR Info - Data
+;
+	global	TFT_pscr_info
+TFT_pscr_info:
+	;show ppO2
+	WIN_MEDIUM dm_custom_ppo2_column,dm_custom_ppo2_row
+	MOVII	int_O_pSCR_ppO2,mpr			; copy pSCR ppO2 to hi:lo
+	call	TFT_color_code_ppo2			; color-code output
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_999							; print ppO2 (0.00-9-99)
+	PRINT								; dump to screen
+	; show drop
+	WIN_STD dm_custom_pscr_drop_column+.11,dm_custom_pscr_row
+	FONT_COLOR_MEMO						; select color
+	movff	char_I_PSCR_drop,lo			; get   drop
+	output_99							; print drop (0-99)
+	PUTC_PRINT "%"						; append unit and dump to screen
+	; show lung ratio
+	WIN_STD	dm_custom_pscr_ratio_column+.5,dm_custom_pscr_row
+	;FONT_COLOR_MEMO						; select color
+	movff	char_I_PSCR_lungratio,lo	; get ratio
+	STRCPY	"1/"						; print "1/"
+	bsf		leftbind					; print left-aligned
+	output_256							; print ratio number (0-256)
+	PRINT								; dump to screen
+	return								; done
+
+ ENDIF	; _ccr_psrc
+
+ IFDEF _external_sensor
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Sensor ppO2 - Mask
+;
+	global	TFT_ppo2_sensors_mask
+TFT_ppo2_sensors_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_hud_sensor1_column+.4,dm_custom_hud_title_row
+	STRCPY_TEXT_PRINT tDiveHudMask1		; print label
+
+	WIN_TINY dm_custom_hud_sensor2_column+.3,dm_custom_hud_title_row
+	STRCPY_TEXT_PRINT tDiveHudMask2		; print label
+
+	WIN_TINY dm_custom_hud_sensor3_column+.2,dm_custom_hud_title_row
+	STRCPY_TEXT_PRINT tDiveHudMask3		; print label
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Sensor ppO2 - Data
+;
+; Definition of the output:
+;
+;  sensorX       use        voting         o2
+; _calibrated    _O2       _logic        _ppo2          Output           Color
+;    _ok      _sensorX    _sensorX     _sensorX
+;-----------------------------------------------------------------------------------------------
+;    0          -/-          -/-            -/-         "----"           memo
+;    1           0           -/-            = 0         o2_ppo2_sensorX  attention
+;    1           0           -/-            > 0         o2_ppo2_sensorX  disabled
+;    1           1            0             -/-         o2_ppo2_sensorX  TFT_color_code_ppo2_hud + win_invert
+;    1           1            1             -/-         o2_ppo2_sensorX  TFT_color_code_ppo2_hud
+;
+	global	TFT_ppo2_sensors
+TFT_ppo2_sensors:
+
+	; sensor 1
+TFT_ppo2_sensors_1:
+	btfsc	sensor1_calibrated_ok		; valid calibration?
+	bra		TFT_ppo2_sensors_1b			; YES
+	btfsc	sensor1_active				; NO - valid HUD data for this sensor?
+	bra		TFT_ppo2_sensors_1b			;      YES
+	;bra	TFT_ppo2_sensors_1a			;      NO
+
+TFT_ppo2_sensors_1a:
+	; no valid calibration
+	WIN_STD dm_custom_hud_sensor1_column+.7, dm_custom_hud_row+.5
+	FONT_COLOR_MEMO						; set color
+	STRCPY_PRINT "---"					; print dashes
+	bra		TFT_ppo2_sensors_2			; continue with sensor 2
+
+TFT_ppo2_sensors_1b:
+	; sensor has a valid calibration
+	WIN_MEDIUM dm_custom_hud_sensor1_column,dm_custom_hud_row
+	movff	sensor1_ppO2,lo				; load ppO2 value into transfer storage for output
+	btfsc	use_O2_sensor1				; in use?
+	bra		TFT_ppo2_sensors_1d			; YES
+	tstfsz	lo							; NO  - sensor value = 0 ?
+	bra		TFT_ppo2_sensors_1c			;       NO
+	FONT_COLOR_ATTENTION				;       YES - set attention color
+	bra		TFT_ppo2_sensors_1e			;           - print ppO2 value
+
+TFT_ppo2_sensors_1c:
+	; sensor has valid calibration, is not in use and has a value > 0
+	FONT_COLOR_DISABLED					; set disabled color
+	bra		TFT_ppo2_sensors_1e			; print ppO2 value
+
+TFT_ppo2_sensors_1d:
+	; sensor has valid calibration and is in use
+	call	TFT_color_code_ppo2_hud		; color-code with ppO2 [cbar] in lo
+	btfsc	voting_logic_sensor1		; sensor value agrees with values of other sensors?
+	bra		TFT_ppo2_sensors_1e			; YES
+	bsf		win_invert					; NO  - invert output
+	;bra	TFT_ppo2_sensors_1e			; print ppO2 value
+
+TFT_ppo2_sensors_1e:
+	; all coloring is set up now, let's write the value to the display!
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_256							; print (0.00-2.55)
+	PRINT								; dump to screen
+
+	; sensor 2
+TFT_ppo2_sensors_2:
+	btfsc	sensor2_calibrated_ok		; valid calibration?
+	bra		TFT_ppo2_sensors_2b			; YES
+	btfsc	sensor2_active				; NO  - valid HUD data for this sensor?
+	bra		TFT_ppo2_sensors_2b			;       YES
+	;bra	TFT_ppo2_sensors_2a			;       NO
+
+TFT_ppo2_sensors_2a:
+	; no valid calibration
+	WIN_STD dm_custom_hud_sensor2_column+.7, dm_custom_hud_row+.5
+	FONT_COLOR_MEMO						; set color
+	STRCPY_PRINT "---"					; print dashes
+	bra		TFT_ppo2_sensors_3			; continue with sensor 3
+
+TFT_ppo2_sensors_2b:
+	; sensor has a valid calibration
+	WIN_MEDIUM dm_custom_hud_sensor2_column,dm_custom_hud_row
+	movff	sensor2_ppO2,lo				; load ppO2 value into transfer storage for output
+	btfsc	use_O2_sensor2				; in use?
+	bra		TFT_ppo2_sensors_2d			; YES
+	tstfsz	lo							; NO  - sensor value = 0?
+	bra		TFT_ppo2_sensors_2c			;       NO
+	FONT_COLOR_ATTENTION				;       YES - print in attention color
+	bra		TFT_ppo2_sensors_2e			;           - print ppO2 value
+
+TFT_ppo2_sensors_2c:
+	; sensor has valid calibration, is not in use and has a value > 0
+	FONT_COLOR_DISABLED					; output in light blue
+	bra		TFT_ppo2_sensors_2e			; print ppO2 value
+
+TFT_ppo2_sensors_2d:
+	; sensor has valid calibration and is in use
+	call	TFT_color_code_ppo2_hud		; color-code with ppO2 [cbar] in lo
+	btfsc	voting_logic_sensor2		; sensor value agrees with values of other sensors?
+	bra		TFT_ppo2_sensors_2e			; YES
+	bsf		win_invert					; NO  - invert output
+	;bra	TFT_ppo2_sensors_2e			;     - print ppO2 value
+
+TFT_ppo2_sensors_2e:
+	; all coloring is set up now, let's write the value to the display!
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_256							; print (0.00-2.55)
+	PRINT								; dump to screen
+
+	; sensor 3
+TFT_ppo2_sensors_3:
+	btfsc	sensor3_calibrated_ok		; valid calibration?
+	bra		TFT_ppo2_sensors_3b			; YES
+	btfsc	sensor3_active				; NO - valid HUD data for this sensor?
+	bra		TFT_ppo2_sensors_3b			;      YES
+	;bra	TFT_ppo2_sensors_3a			;      NO
+
+TFT_ppo2_sensors_3a:
+	WIN_STD dm_custom_hud_sensor3_column+.7, dm_custom_hud_row+.5
+	FONT_COLOR_MEMO						; set color
+	STRCPY_PRINT "---"					; print dashes
+	bra		TFT_ppo2_sensors_4			; done
+
+TFT_ppo2_sensors_3b:
+	; sensor has a valid calibration
+	WIN_MEDIUM dm_custom_hud_sensor3_column,dm_custom_hud_row
+	movff	sensor3_ppO2,lo				; load ppO2 value into transfer storage for output
+	btfsc	use_O2_sensor3				; in use?
+	bra		TFT_ppo2_sensors_3d			; YES
+	tstfsz	lo							; NO  - sensor value = 0?
+	bra		TFT_ppo2_sensors_3c			;       NO
+	FONT_COLOR_ATTENTION				;       YES - print in attention color
+	bra		TFT_ppo2_sensors_3e			;           - print ppO2 value
+
+TFT_ppo2_sensors_3c:
+	; sensor has valid calibration, is not in use and has a value > 0
+	FONT_COLOR_DISABLED					; print in disabled color
+	bra		TFT_ppo2_sensors_3e			; print ppO2 value
+
+TFT_ppo2_sensors_3d:
+	; sensor has valid calibration and is in use
+	call	TFT_color_code_ppo2_hud		; color-code with ppO2 [cbar] in lo
+	btfsc	voting_logic_sensor3		; sensor value agrees with values other sensors?
+	bra		TFT_ppo2_sensors_3e			; YES
+	bsf		win_invert					; NO  - invert output
+	;bra	TFT_ppo2_sensors_3e			;     - print ppO2 value
+
+TFT_ppo2_sensors_3e:
+	; all coloring is set up now, let's write the value to the display!
+	bsf		decimal_digit2				; place a decimal point in front of digit 2
+	output_256							; print (0.00-2.55)
+	PRINT								; dump to screen
+
+TFT_ppo2_sensors_4:
+	return								; done
+
+ ENDIF	; _external_sensor
+
+ IFDEF _rx_functions
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Pressures & SAC - Mask
+;
+	global	TFT_pressures_SAC_mask
+TFT_pressures_SAC_mask:
+	FONT_COLOR_MASK						; select color
+
+	; pressure reading 1
+	WIN_TINY dm_custom_tankdata_pres1_col, dm_custom_tankdata_mask_row
+	movff	char_I_pressure_gas+0,WREG	; =0: disabled, =1..10: gases/dils
+	bcf		aux_flag					; selector for disabled / need set to disabled
+	rcall	TFT_pressures_SAC_mask_h1	; print gas composition or " ---" if disabled
+
+	; pressure reading 2
+	WIN_TINY dm_custom_tankdata_pres2_col, dm_custom_tankdata_mask_row
+	movff	char_I_pressure_gas+1,WREG	; =0: need to reading 1, =1..10: gases/dils
+	bsf		aux_flag					; selector for disabled / need set to need
+	rcall	TFT_pressures_SAC_mask_h1	; print gas composition or "Need " if 0
+
+	; SAC rate
+	WIN_TINY dm_custom_tankdata_SAC_col, dm_custom_tankdata_mask_row
+	STRCPY_TEXT tSAC					; "SAC
+	STRCAT	" ("						;      (
+	STRCAT_TEXT tLitersMinute			;       l/min
+	PUTC_PRINT ")"						;            )"
+	return								; done
+
+
+	; Helper Function - print gas composition or " ---" if disabled
+TFT_pressures_SAC_mask_h1:
+	tstfsz	WREG						; pressure reading assigned?
+	bra		TFT_pressures_SAC_mask_h2	; YES - print gas composition
+	btfsc	aux_flag					; NO  - check auxiliary flag
+	bra		TFT_pressures_SAC_mask_h3	;       1 - print "Need "
+	STRCAT_PRINT "    ---"				;       0 - print "    ---"
+	return								;         - done
+
+TFT_pressures_SAC_mask_h2:
+	decf	WREG,W						; (1..10) -> (0..9)
+	bsf		short_gas_descriptions		; just "Air", "O2" or "xx/yy"
+	call	gaslist_strcat_mix_WREG		; print composition of gas/dil in WREG (0..9)
+	bra		TFT_pressures_SAC_mask_h4	; finish with adding "(bar)"
+
+TFT_pressures_SAC_mask_h3:
+	STRCPY_TEXT tNeed					; "Need"
+	;bra	TFT_pressures_SAC_mask_h4 ; finish with adding "(bar)"
+
+TFT_pressures_SAC_mask_h4:
+	STRCAT_PRINT "(bar)"				; print "(bar)"
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Pressures & SAC - Data
+;
+	global	TFT_pressures_SAC
+TFT_pressures_SAC:
+	; check mode for second reading
+	bcf		aux_flag					; clear auxiliary flag by default (reading 2 is pressure)
+	movff	char_I_pressure_gas+1,WREG	; =0: need to reading 1, =1..10: gases/dils
+	addlw	.0							; dummy operation to set status register flags
+	btfsc	STATUS,Z					; gas selected = 0 (i.e. no 2nd pressure reading) ?
+	bsf		aux_flag					; YES - set auxiliary flag (display position of reading 2 shall show need to reading 1)
+	; get data of reading 1
+	movff	int_IO_pressure_value+0,lo	; copy pressure 1 to hi:lo
+	movff	int_IO_pressure_value+1,hi	; ...
+	movff	char_I_pressure_stat+0,ex	; copy status data
+	; pressure of reading 1
+	WIN_STD dm_custom_tankdata_pres1_col+.4,dm_custom_tankdata_row
+	rcall	TFT_pressures_SAC_helper_1	; print pressure if available, else " ---"
+	; battery status of reading 1
+	WIN_SMALL dm_custom_hud_sensor1_column+.4+.36,dm_custom_tankdata_row
+	rcall	TFT_pressures_SAC_helper_2	; print or clear down arrow as low bat indicator
+	; get data for reading 2
+	btfsc	aux_flag					; shall reading 2 show need to reading 1 ?
+	bra		TFT_pressures_SAC_1			; YES
+	movff	int_IO_pressure_value+2,lo	; NO  - copy pressure 2 to hi:lo
+	movff	int_IO_pressure_value+3,hi	;     - ...
+	movff	char_I_pressure_stat+1,ex	;     - copy status data
+	bra		TFT_pressures_SAC_2			;     - continue
+
+TFT_pressures_SAC_1:
+	MOVII	int_O_pressure_need,mpr		; copy need to pressure 1 to hi:lo
+	clrf	ex							; set status data to 0
+	bra		TFT_pressures_SAC_2			; continue
+
+TFT_pressures_SAC_2:
+	; pressure of reading 2
+	WIN_STD dm_custom_tankdata_pres2_col+.2,dm_custom_tankdata_row
+	rcall	TFT_pressures_SAC_helper_1	; print pressure if available, else " ---"
+	; battery status of reading 2
+	WIN_SMALL dm_custom_tankdata_pres2_col+.2+.36,dm_custom_tankdata_row
+	rcall	TFT_pressures_SAC_helper_2	; print or clear down arrow as low bat indicator
+
+TFT_pressures_SAC_3:
+	; SAC
+	WIN_STD dm_custom_tankdata_SAC_col+.6,dm_custom_tankdata_row
+	MOVII	int_O_SAC_measured,mpr		; copy measured SAC rate to hi:lo
+	btfsc	hi,int_not_avail_flag		; SAC rate available?
+	bra		TFT_pressures_SAC_4			; NO - print " --.-"
+	call	TFT_color_code_pres_sac		; color-code the output
+	bsf		decimal_digit1				; place a decimal point in front of digit 1
+	output_999							; print (0.0-99.9)
+	PRINT								; dump to screen
+	return								; done
+
+TFT_pressures_SAC_4:
+	FONT_COLOR_DISABLED					; set color
+	STRCAT_PRINT "--.-"					; output for no SAC data available
+	return								; done
+
+
+	; Helper Function - print pressure if available, else " ---"
+TFT_pressures_SAC_helper_1:
+	btfss	hi,int_not_avail_flag		; pressure available?
+	bra		TFT_pressures_SAC_helper_1a	; YES - print pressure
+	FONT_COLOR_DISABLED					; NO  - use disabled color as default
+;	btfsc	ex,char_transmitter_lost	;     - transmitter lost?
+;	FONT_COLOR_ATTENTION				;       YES - use attention color
+	STRCAT_PRINT " ---"					;     - print " ---"
 	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
+TFT_pressures_SAC_helper_1a:
+	btfsc	hi,int_warning_flag			; out of range (signaled by warning flag)?
+	bra		TFT_pressures_SAC_helper_1c	; YES - special treatment
+	call	TFT_color_code_pres_sac		; NO  - color-code the output
+	PUTC	' '							;     - add a space
+	bsf		omit_digit_1				;     - do not print 1st digit (0.1 bar)
+	output_999							;     - print pressure (0x-999x)
+	PRINT								;     - dump buffer to screen
+	return								;     - done
+
+TFT_pressures_SAC_helper_1c:
+	call	TFT_color_code_pres_sac		; color-code the output
+	STRCPY_PRINT ">400"					; print ">400"
+	return								; done
+
+
+	; Helper Function - print or clear down arrow as low bat indicator
+TFT_pressures_SAC_helper_2:
+	btfss	ex,char_transmitter_low_bat	; low battery flag set?
+	bra		TFT_pressures_SAC_helper_2b	; NO  - clear down arrow (low bat indicator)
+	;bra	TFT_pressures_SAC_helper_2a	; YES - show  down arrow (low bat indicator)
+
+TFT_pressures_SAC_helper_2a:
+	FONT_COLOR_ATTENTION				; use attention color
+	STRCPY_PRINT "\xb8"					; print down arrow as bat low indication
+	return								; done
+
+TFT_pressures_SAC_helper_2b:
+	STRCPY_PRINT " "					; wipe out down arrow (low bat indicator)
+	return								; done
+
+ ENDIF _rx_functions
+
+ IFDEF _cave_mode
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Cave Mode TTS, total Stops and Run Time - Mask
+;
+
+	global	TFT_cave_tts_mask
+TFT_cave_tts_mask:
+	FONT_COLOR_MASK						; select color
+
+	WIN_TINY dm_custom_cave_title_column1,dm_custom_cave_title_row
+	STRCPY_TEXT_PRINT tCaveStops		; print label
+
+	WIN_TINY dm_custom_cave_title_column2,dm_custom_cave_title_row
+	STRCPY_TEXT_PRINT tCaveTTS			; print label
+
+	WIN_TINY dm_custom_cave_title_column3,dm_custom_cave_title_row
+	STRCPY_TEXT_PRINT tCaveRuntime		; print label
+
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Cave Mode TTS, total Stops and Run Time - Data
+;
+	global	TFT_cave_tts
+TFT_cave_tts:
+	; total time of all stops
+	WIN_MEDIUM dm_custom_cave_data_column1,dm_custom_cave_data_row
+	FONT_COLOR_MEMO						; 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
+	FONT_COLOR_DISABLED					;       YES - switch to disabled color
+	bra		TFT_cave_1b					;           - print dashes
+
+TFT_cave_1a:
+	btfsc	mpr+1,int_invalid_flag		; stops time invalid?
+	FONT_COLOR_DISABLED					; 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_999							; print (0-999)
+	PUTC_PRINT "'"						; append unit and dump to screen
+	bra		TFT_cave_2					; continue
+
+TFT_cave_1b:
+	STRCAT_PRINT ",-,-,-,"				; print 3 dashes (',' produces a half-width space)
+	;bra	TFT_cave_2					; continue
+
+TFT_cave_2:
+	; cave TTS
+	WIN_MEDIUM dm_custom_cave_data_column2,dm_custom_cave_data_row		; column 60
+	FONT_COLOR_MEMO						; 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
+	FONT_COLOR_DISABLED					;       YES - switch to disabled color
+	bra		TFT_cave_2b					;           - print dashes
+
+TFT_cave_2a:
+	btfsc	mpr+1,int_invalid_flag		; TTS invalid?
+	FONT_COLOR_DISABLED					; YES - switch to disabled color
+	bcf		mpr+1,int_invalid_flag		; clear invalid flag if applicable
+	output_999							; print (0-999)
+	PUTC_PRINT "'"						; append unit and dump to screen
+	bra		TFT_cave_3					; continue
+
+TFT_cave_2b:
+	STRCAT_PRINT ",-,-,-,"				; print 3 dashes (',' produces a half-width space)
+	;bra	TFT_cave_3					; continue
+
+TFT_cave_3:
+	; estimated total runtime
+	WIN_MEDIUM dm_custom_cave_data_column3,dm_custom_cave_data_row
+	;									; 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_999							;           - print (0-999)
+	PUTC_PRINT "'"						;           - append unit and dump to screen
+	return								;           - done
+
+TFT_cave_3b:
+	STRCAT_PRINT ",-,-,-,"				; print 3 dashes (',' produces a half-width space)
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; Dive Custom View - Cave Mode Waypoints
+;
+	global	TFT_cave_waypoints
+TFT_cave_waypoints:
+	; arrow
+	WIN_TINY .70,dm_custom_cave_title_row
+	FONT_COLOR_ATTENTION				; select color
+	btfss	cave_mode					; cave mode switched on?
+	bra		TFT_cave_waypoints_3		; NO  - do not show any marker (any more)
+	btfsc	dive_turned					; YES - dive turned?
+	bra		TFT_cave_waypoints_2		;       YES - print marker in the middle
+	;bra	TFT_cave_waypoints_1		;       NO  - print marker on right side
+
+TFT_cave_waypoints_1:
+	movlw	.12							; start with 12 space chars
+	call	TFT_buffer_trim_length		; fill / cut buffer to target length
+	;bra	TFT_cave_waypoints_2		; continue
+
+TFT_cave_waypoints_2:
+	STRCAT	"<====="					; print marker symbol
+	;bra	TFT_cave_waypoints_3		; continue
+
+TFT_cave_waypoints_3:
+	movlw	.18							; set overall number of chars
+	call	TFT_buffer_trim_length		; fill / cut buffer to target length
+	PRINT								; dump buffer to screen
+	; waypoint band
+	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
+	FONT_COLOR_ATTENTION				;     - select attention color
+	PUTC	" "							;     - print 2 space chars
+	PUTC	" "							;     - ...
+	STRCAT_TEXT tCaveMode				;     - print "Cave Mode"
+	PUTC	" "							;     - print 1 space char
+	STRCAT_TEXT tOff					;     - print "off"
+	movlw	.17							;     - set max number of chars
+	call	TFT_buffer_trim_length		;     - fill / cut buffer to target length
+	PRINT								;     - dump buffer to screen
+	return								;     - done
+
+TFT_cave_waypoints_4:
+	WIN_MEDIUM .0,dm_custom_cave_data_row; start in column 0
+	FONT_COLOR_MEMO						; select default color
+	tstfsz	DM_flags_cavereq			; any pending cave mode requests?
+	FONT_COLOR_DISABLED					; 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
+	;bra	TFT_cave_waypoints_6		; continue with next section
+
+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 dump buffer to screen
+	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
+	;bra	TFT_cave_waypoints_10		; continue with next section
+
+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
+	PRINT								;           - dump buffer to screen
+	return								;           - done
+
+TFT_cave_waypoints_11:
+	STRCAT_PRINT "---|,"				; print end-of-line symbol and dump buffer to screen
+	return								; done
+
+ ENDIF	; _cave_mode
+
 
 ;=============================================================================
-
-	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
-
-
-	global	convert_meter_to_feet
-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 [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
-
-	return
-
-;=============================================================================	
-
-	global	convert_celsius_to_fahrenheit	; convert value in hi:lo from Celsius to Fahrenheit
-convert_celsius_to_fahrenheit:		; convert value in lo:hi from Celsius to Fahrenheit
-	MOVII	mpr,xA					; temperature in 1/10 of °C
-	ADDLI	.1000,xA				; add offset of 1000 to get out of any negative numbers
-									; adjust scaling: 1°C = 1.8°F:
-	MOVLI	.18,xB					; multiply with 18:
-	call	mult16x16				; ...
-	MOVLI	.10,xB					; divide by 10
-	call	div32x16				; ...
-	SUBLI	.1480,xC				; remove offset: subtract above offset of 1000 * 1.8 = 1800 now and add 320 => subtract 1480
-	MOVII	xC,mpr					; store result in hi:lo
-	return
+tft_out15	CODE
+;=============================================================================
+
+
+;-----------------------------------------------------------------------------
+; Helper Function - check if firmware is within expiry period
+;
+; Output:  aux_flag set if not
+;
+check_expiry:
+	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
+	bsf		aux_flag					; set firmware as expired by default
+	movlw	firmware_expire_year		; start with checking year
+	cpfsgt	up							; current year > expiry year ?
+	bra		check_expiry_Y				; NO  - continue checks
+	return								; YES - expired
+
+check_expiry_Y:
+	cpfseq	up							; current year = expiry year ?
+	bra		check_expiry_ok				; NO  - must be < then, OK whatever month & day
+	movlw	firmware_expire_month		; YES - continue checking month
+	cpfsgt	hi							; current month > expiry month ?
+	bra		check_expiry_M				; NO  - continue checks
+	return								; YES - expired
+
+check_expiry_M:
+	cpfseq	hi							; current month = expiry month ?
+	bra		check_expiry_ok				; NO  - must be < then, OK whatever day
+	movlw	firmware_expire_day			; YES - continue checking day
+	cpfsgt	lo							; current day > expiry day ?
+	bra		check_expiry_ok				; NO  - must be <= then, OK
+	return								; YES - expired
+
+check_expiry_ok:
+	bcf		aux_flag					; not expired
+	return								; done 
+
+
+;-----------------------------------------------------------------------------
+; show Firmware updated Message
+;
+; Attention:
+; Pallet colors and language switching are not
+; available yet, all text outputs are hard-coded!
+;
+	global	TFT_message_fw_update
+TFT_message_fw_update:
+	FONT_COLOR_STANDARD					; set color
+
+	; show update message
+	WIN_SMALL .20,.100					; set position
+	STRCPY_PRINT "Update successful!"	; print message
+
+	; show firmware version
+	WIN_SMALL .20,.140					; set position
+	STRCPY	"New Firmware: "			; print message
+
+	bra		TFT_message_fw_common		; show firmware version
+
+
+;-----------------------------------------------------------------------------
+; show Firmware kept Message
+;
+; Attention:
+; Pallet colors and language switching are not
+; available yet, all text outputs are hard-coded!
+;
+	global	TFT_message_fw_kept
+TFT_message_fw_kept:
+	FONT_COLOR_STANDARD					; set color
+
+	; show reboot message
+	WIN_SMALL .60,.100					; set position
+	STRCPY_PRINT "Reboot"				; print message
+
+	; show firmware version
+	WIN_SMALL .30,.140					; set position
+	STRCPY	"Firmware: "				; print message
+
+	;bra	TFT_message_fw_common		; show firmware version
+
+
+	; Helper Function - show firmware version x.y and color-code + invert if outdated
+TFT_message_fw_common:
+	rcall	TFT_cat_firmware			; append major/minor and color-code on expiry
+	PRINT								; dump to screen
+	; show firmware beta status
+	WIN_SMALL .60,.180
+	FONT_COLOR_STANDARD					; set default color for a release version
+	rcall	TFT_cat_beta_long			; show "Release" or "BETA" + issue
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; append Firmware Version to current String, including color-coding on expiry
+;
+	global	TFT_cat_firmware
+TFT_cat_firmware:
+	movlw	fw_version_major			; get major
+	movwf	lo							; ...
+	bsf		leftbind					; print left-aligned
+	output_99							; print major (0-99)
+	PUTC	'.'							; print a dot
+	movlw	fw_version_minor			; get minor
+	movwf	lo							; ...
+	output_99x							; print minor in two digit format
+	rcall	check_expiry				; check if firmware is expired
+	btfss	aux_flag					; expired?
+	return								; NO
+	bsf		win_invert					; YES - print in inverse
+	FONT_COLOR color_yellow				;     - print in yellow
+	return								;     - done
+
+
+;-----------------------------------------------------------------------------
+; append Firmware BETA Status to current String, including color-coding on BETA
+;
+	global	TFT_cat_beta_long
+TFT_cat_beta_long:
+	bsf		aux_flag					; do long version
+	bra		TFT_cat_beta_common			; continue with common part
+
+	global	TFT_cat_beta_short
+TFT_cat_beta_short:
+	bcf		aux_flag					; do short version
+	;bra	TFT_cat_beta_common			; continue with common part
+
+TFT_cat_beta_common:
+
+ IFDEF _DEBUG
+
+	FONT_COLOR color_red				; set color
+	btfss	aux_flag					; shall show long version?
+	bra		TFT_cat_debug_short			; NO  - show short version
+	;bra	TFT_cat_debug_long			; YES - show long  version
+
+TFT_cat_debug_long:
+	STRCAT	"DEBUG"						; print long  debug
+	return								; done
+
+TFT_cat_debug_short:
+	STRCAT	"DBG."						; print short debug
+	return								; done
+
+ ELSE
+
+	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_com			; NO  - must be beta version then
+	btfss	aux_flag					; YES - shall show long version?
+	bra		TFT_cat_beta_rel_short		;       NO  - show short version
+	rcall	check_expiry				;       YES - check  expiry date
+	btfsc	aux_flag					;           - within expiry date?
+	bra		TFT_cat_beta_update			;             NO  - give update cue
+	;bra	TFT_cat_beta_rel_long		;             YES - "Release"
+
+TFT_cat_beta_rel_long:
+	STRCAT	"Release"					; print long "Release"
+	return								; done
+
+TFT_cat_beta_rel_short:
+	STRCAT "Rel."						; print short "Release"
+	return								; done
+
+TFT_cat_beta_com:
+	FONT_COLOR color_yellow				; set color
+	btfss	aux_flag					; shall show long  version?
+	bra		TFT_cat_beta_short_exec		; NO  - show short version
+	;bra	TFT_cat_beta_long_exec		; YES - show long  version
+
+TFT_cat_beta_long_exec:
+	STRCAT	"Beta "						; print long "Beta"
+	bra		TFT_cat_beta_version		; print version
+
+TFT_cat_beta_short_exec:
+	STRCAT "B."							; print short "Beta"
+	;bra	TFT_cat_beta_version		; append beta version number
+
+TFT_cat_beta_version:
+	bsf		leftbind					; print left-aligned
+	output_256							; print beta version number (0-255)
+	return								; done
+
+TFT_cat_beta_update:
+	FONT_COLOR color_yellow
+	STRCAT "update!"					; print update cue
+	return								; done
+
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; append Serial Number to to current String
+;
+	global	TFT_cat_serial
+TFT_cat_serial:
+	call	eeprom_serial_number_read	; read OSTC serial number
+	bsf		leftbind					; print left-aligned
+	output_65535						; print serial number
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; print Serial Number and Firmware Version (used by comm mode)
+;
+	global	TFT_print_serial_and_firmware
+TFT_print_serial_and_firmware:
+	STRCPY	"#"							; print "#"
+	rcall	TFT_cat_serial				; print serial number
+	STRCAT	" "							; print a space
+	STRCAT	"v"							; print a "v" (version)
+	;bra	TFT_print_firmware			; print firmware version
+
+
+;-----------------------------------------------------------------------------
+; print Firmware Version
+;
+	global	TFT_print_firmware
+TFT_print_firmware:
+	rcall	TFT_cat_firmware			; print firmware major/minor, will set win_invert if outdated
+	STRCAT	" "							; print a space
+	rcall	TFT_cat_beta_long			; print release/beta and update notification if expired
+	PRINT								; dump to screen
+	return								; done
+
+
+;-----------------------------------------------------------------------------
+; print Deco Type (OC, CCR, ...)
+;
+; Input: lo  deco type number:  0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR
+;
+	global	TFT_print_decotype
+TFT_print_decotype:
+	bsf		aux_flag					; default to dive with deco calculation (used by logbook)
+	incf	lo,W						; WREG = lo + 1
+TFT_print_decotype_1
+	decfsz	WREG,W						; in OC mode?
+	bra		TFT_print_decotype_2		; NO  - try next
+	STRCAT_TEXT_PRINT tDvOC				; YES - print "OC"
+	return								;     - done
+TFT_print_decotype_2:
+	decfsz	WREG,W						; in CCR mode?
+	bra		TFT_print_decotype_3		; NO  - try next
+	STRCAT_TEXT_PRINT tDvCC				; YES - print "CCR"
+	return								;     - done
+TFT_print_decotype_3:
+	decfsz	WREG,W						; in gauge mode?
+	bra		TFT_print_decotype_4		; NO  - try next
+	bcf		aux_flag					; YES - dive without deco data
+	STRCAT_TEXT_PRINT tDvGauge			;     - Print "Gauge"
+	return								;     - done
+TFT_print_decotype_4:
+	decfsz	WREG,W						; in apnea mode?
+	bra		TFT_print_decotype_5		; NO  - try next
+	bcf		aux_flag					; YES - dive without deco data
+	STRCAT_TEXT_PRINT tDvApnea			;     - print "Apnoe"
+	return								;     - done
+TFT_print_decotype_5:
+	STRCAT_TEXT_PRINT tDvPSCR			; print "pSCR"
+	return								; done
+
 
 ;=============================================================================
-
-	END
\ No newline at end of file
+tft_out16	CODE
+;=============================================================================
+
+
+	global	TFT_debug_output
+TFT_debug_output:
+
+ IFNDEF _debug_output
+
+	return										; do nothing
+
+ ELSE
+
+	btfsc	alt_layout_active					; alternative layout active?
+	return										; YES - abort
+
+;	WIN_TINY .100,.30							; surface mode: fits under the textual logo in the upper right corner
+;	WIN_TINY  .35, .0							; dive    mode: fits to the right side of the depth label
+	WIN_TINY   .0, .		0					; dive    mode: overwrites depth label
+	FONT_COLOR_MEMO								; set color
+
+	; deco engine scheduling performance
+	MOVII	int_O_profiling_overrun,mpr			; runtime +/- versus target
+	btfss	mpr+1,7								; overrun?
+	bra		TFT_debug_output_1					; YES
+	bcf		mpr+1,7								; NO - clear flag
+	PUTC	"-"									;    - print a minus
+	bra		TFT_debug_output_2					;    - continue
+TFT_debug_output_1:
+	PUTC	" "									; print a space instead of the minus
+TFT_debug_output_2:
+	output_999									; print time (0-999)
+	PUTC	"."									; print a dot as separator
+	MOVII	int_O_profiling_overrun_max,mpr		; get max runtime so far
+	output_999									; print (0-999)
+	PUTC	"."									; print a dot as separator
+	movff	char_O_profiling_overrun_phase,WREG	; get calculation phase causing the max runtime
+	output_hex									; print a hex
+	PUTC	"."									; print a dot as separator
+	movff	char_O_profiling_runs_norm,mpr		; get runs/cycle normal plan
+	output_99									; print (0-99)
+	PUTC	"."									; print a dot as separator
+	movff	char_O_profiling_runs_alt,mpr		; get runs/cycle alternative plan
+	output_99									; print (0-99)
+	PRINT										; dump to screen
+	return										; done
+
+ ENDIF	; _debug_output
+
+;-----------------------------------------------------------------------------
+
+	END
--- a/src/tft_outputs.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/tft_outputs.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File tft_outputs.inc                      next combined generation V3.08.8
+;   File tft_outputs.inc                    * combined next generation V3.09.5
 ;
 ;
 ;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
@@ -8,112 +8,154 @@
 ; HISTORY
 ;  2011-08-07 : [mH] moving from OSTC code
 
+
+;-----------------------------------------------------------------------------
 ; Surface Mode
-	extern	TFT_surface_lastdive
-	extern	TFT_show_OC_startgas_surface		; first gas and "OSTC2-like" active gases
-	extern	TFT_time_surfmode
-	extern	TFT_date_surfmode
-	extern	TFT_desaturation_time
-	extern	TFT_nofly_time
-	extern	TFT_gaslist_surfmode
-	extern	TFT_pres_surfmode
-	extern	TFT_temp_surfmode					; current temperature (common core with divemode temp)
-	extern	TFT_batt_surfmode
-	extern	TFT_decotype_surface
-	extern	TFT_decotype_logbook				; used from logbook
-	extern	TFT_custom_text						; the custom text
-	extern	TFT_surface_tissues					; tissue diagram in surface mode
-	extern	TFT_surface_decosettings			; all deco settings
-	extern	show_fw_mesg_update					; firmware is updated message
-	extern	show_fw_mesg_kept					; firmware is kept    message
-	extern	TFT_cat_serial						; add serial           to current string
-	extern	TFT_cat_firmware					; add firmware version to current string
-	extern	TFT_cat_beta_release				; add beta/release     to current string
+
+	extern	TFT_surfmode_time					; current time
+	extern	TFT_surfmode_date					; current date
+	extern	TFT_surfmode_pres					; print current pressure, unconditional
+	extern	TFT_surfmode_pres_fast				; print current pressure, but only if change > threshold
+	extern	TFT_surfmode_temp					; current temperature (common core with divemode temp)
+	extern	TFT_surfmode_batt					; battery status      (also used in sleep mode)
+	extern	TFT_surfmode_decotype				; deco mode (OC, CCR, ...)
+	extern	TFT_surfmode_startgas				; first gas and "OSTC2-like" active gases
+
+ IFDEF _rx_functions
+	extern	TFT_surfmode_tankpres				; tank data for surface mode screen
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
+; Surface Mode Custom Views
+
+	extern	TFT_surf_cv_lastdive				; last dive summery
+	extern	TFT_surf_cv_list_gas				; OC gases list
+	extern	TFT_surf_cv_text					; the custom text
+	extern	TFT_surf_cv_tissues					; tissue diagram (also used by logbook)
+	extern	TFT_surf_cv_settings				; all deco settings
+
+ IFDEF _rx_functions
+	extern	TFT_surf_cv_tankdata				; show the tank pressure data in surface customview
+ ENDIF
 
  IFDEF _compass
-	extern	TFT_surf_set_bearing
+	extern	TFT_surf_cv_compass_bearing			; "set bearing" dialog
  ENDIF
 
  IFDEF _ccr_pscr
-	extern	TFT_dillist_surfmode
-	extern	TFT_splist_surfmode					; setpoint list
+	extern	TFT_surf_cv_list_dil				; diluents list
+	extern	TFT_surf_cv_list_sp					; setpoint list
  ENDIF
 
+
+;-----------------------------------------------------------------------------
+; Surface Mode Messages
+
+	extern	TFT_surf_mesg_desat					; desaturation time
+	extern	TFT_surf_mesg_nofly					; no-fly/alt   time
+
+
+;-----------------------------------------------------------------------------
+; Imprints called by Housekeeping
+
+	extern	TFT_imprint_time_date				; imprint current     time and date
+	extern	TFT_imprint_time_date_fast			; imprint last cahced time and date
+	extern	TFT_imprint_color_schemes			; imprint color schemes (animated dive time)
+
  IFDEF _external_sensor
-	extern	TFT_menu_calibrate					; update mV data in menu
-	extern	TFT_surface_sensor					; update sensor data in surface mode
-	extern	TFT_sensor_surface_warning			; sensor end-of-lifetime symbol
+	extern	TFT_imprint_menu_mV					; imprint sensor data in menu    mode - mv
+	extern	TFT_imprint_surf_ppO2				; imprint sensor data in surface mode - ppO2
+	extern	TFT_imprint_surf_mV					; imprint sensor data in surface mode - mV
+	extern	TFT_imprint_surf_sensor_eol			; imprint sensor data in surface mode - end of life
+ ENDIF
+
+ IFDEF _rx_functions
+	extern	TFT_imprint_tank_pres				; imprint tank data in tank setup menu
  ENDIF
 
 
-; Menu
-	extern	TFT_LogOffset
-	extern	TFT_show_color_schemes				; update the color schemes
-	extern	TFT_show_time_date_menu
-	extern	TFT_show_time_date_menu_fast
-	extern	TFT_show_serial_and_firmware
-	extern	TFT_show_firmware
-	extern	info_menu_total_dives
-
+;-----------------------------------------------------------------------------
 ; Dive Mode
-	extern	TFT_show_cns
-	extern	TFT_show_divetime
-	extern	TFT_show_depth
-	extern	TFT_show_max_depth
-	extern	TFT_show_temp_divemode					; current temperature (common core with surface temp)
-	extern	TFT_show_active_gas_divemode			; active gas and setpoint
-	extern	TFT_show_divemode_mask
-	extern	TFT_show_menu_cursor_divemode			; the divemode cursor
-	extern	TFT_show_ndl_mask
-	extern	TFT_show_ndl
-	extern	TFT_show_tts
-	extern	TFT_show_deco_mask
-	extern	TFT_show_deco
-	extern	TFT_divemode_sign_show
-	extern	TFT_divemode_sign_clear
-	extern	TFT_velocity_show
-	extern	TFT_velocity_clear
-	extern	TFT_show_ppo2_mask
-	extern	TFT_show_ppo2_warning
-	extern	TFT_msg_batt_percent_divemode
-	extern	TFT_show_apnoe_times
-	extern	TFT_clear_apnoe_surface
-	extern	TFT_show_apnoe_surface
-	extern	TFT_show_apnoe_max_depth
-	extern	TFT_show_ftts
+
+	extern	TFT_show_divemode_mask				; show  static layout
+	extern	TFT_show_ndl_mask					; show  NDL    layout add-on
+	extern	TFT_show_deco_mask					; show  deco   layout add-on
+
+	extern	TFT_show_divetime					; show  dive time
+	extern	TFT_show_depth						; show  current depth
+	extern	TFT_show_max_depth					; show  maximum depth
+	extern	TFT_show_apnoe_max_depth			; show  maximum depth - apnoe mode
+	extern	TFT_show_temp_divemode				; show  temperature (common core with surface temp)
+	extern	TFT_show_active_gas_divemode		; show  active gas and setpoint
+	extern	TFT_show_ndl						; show  NDL time
+	extern	TFT_show_tts						; show  TTS time
+	extern	TFT_show_deco						; show  deco stop data
+
+	extern	TFT_show_apnoe_times				; show  apnoe current and overall time
+	extern	TFT_show_apnoe_surface				; show  apnoe surface mode data
+	extern	TFT_clear_apnoe_surface				; clear apnoe surface data
+
+	extern	TFT_clear_deco_data					; clear deco data (NDL or stop & TTS)
 	extern	TFT_clear_divemode_menu				; clear the divemode menu
-	extern	TFT_clear_message_window
-	extern	TFT_clear_message_window_row2
-	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_velocity_show					; show  vertical velocity
+	extern	TFT_velocity_clear					; clear vertical velocity
+
+	extern	TFT_divemode_sign_show				; show  sign
+	extern	TFT_divemode_sign_clear				; clear sign
+
+	extern	TFT_safety_stop_show				; show  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
-	extern	TFT_attention_gas_needs
-	extern	TFT_advice_gas_change
-	extern	TFT_warning_no_BO_gas
-	extern	TFT_warning_eod_cns
-	extern	TFT_warning_mbubbles
-	extern	TFT_warning_outside
-	extern	TFT_warning_depth
-	extern	TFT_info_deco
+
+
+;-----------------------------------------------------------------------------
+; Dive Mode Mesages
+
+	extern	TFT_message_ftts					; fTTS
+	extern	TFT_message_ppo2					; ppO2
+	extern	TFT_message_battery_percent			; battery
+	extern	TFT_message_cns						; current     CNS
+	extern	TFT_message_cns_eod					; end-of-dive CNS
+	extern	TFT_message_saturation				; Saturation
+	extern	TFT_message_agf						; aGF is selected
+	extern	TFT_message_divetimeout				; dive timeout counter
+	extern	TFT_message_gas_needs				; gas needs
+	extern	TFT_message_gas_change				; gas change advice
+	extern	TFT_message_no_BO_gas				; no bailout gas available
+	extern	TFT_message_mbubbles				; mico-bubbles
+	extern	TFT_message_outside					; outside of the model
+	extern	TFT_message_depth_limit				; depth limit exceeded
+	extern	TFT_message_deco_info				; decompression zone
 
  IFDEF _helium
-	extern	TFT_warning_IBCD
+	extern	TFT_message_IBCD					; INCD
+ ENDIF
+
+ IFDEF _ccr_pscr
+	extern	TFT_message_gas_density				; gas density
  ENDIF
 
  IFDEF _external_sensor
-	extern	TFT_warning_sensor_disagree
+	extern	TFT_message_divergence				; sensor ppO2 divergence
+	extern	TFT_message_fallback				; show fallback warning
  ENDIF
 
-; Date
-	extern	TFT_convert_date					; print day, month and year
-	extern	TFT_convert_date_short				; print day and month
+ IFDEF _rx_functions
+	extern	TFT_message_transmitter				; transmitter
+	extern	TFT_message_pressure				; pressure reading
+	extern	TFT_message_sac						; SAC
+	extern	TFT_message_switch_tanks			; switch advice for ind.double mode
+ ENDIF
 
+ IFDEF _cave_mode
+	extern	TFT_message_cave_mode				; cave mode status
+ ENDIF
+
+
+;-----------------------------------------------------------------------------
 ; 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_mask					; mask for gas needs ascent
@@ -127,7 +169,7 @@
 	extern	TFT_ppo2_ead_end_cns_mask			; mask for ppO2, END/EAD and CNS / gas density
 	extern	TFT_ppo2_ead_end_cns				; data for ppO2, END/EAD and CNS / gas density
 	extern	TFT_gf_factors_mask					; mask for GF factors
-;	extern										; data for GF factors (none)
+;	extern										; data for GF factors (not existing)
 	extern	TFT_clock_batt_surfpress_mask		; mask for clock, battery and surface pressure
 	extern	TFT_clock_batt_surfpress			; data for clock, battery and surface pressure
 
@@ -143,61 +185,61 @@
 	extern	TFT_ppo2_sensors					; data for ppO2 sensors
  ENDIF
 
+ IFDEF _rx_functions
+	extern	TFT_pressures_SAC_mask				; mask for pressures and SAC
+	extern	TFT_pressures_SAC					; data for pressures and SAC
+ 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
-
- IFDEF _external_sensor
-	extern	TFT_sensor_mV
+	extern	TFT_cave_waypoints					; data for cave mode waypoints (no mask function)
  ENDIF
 
 
-; Color-coding
-	extern	TFT_standard_color
-	extern	TFT_disabled_color
-	extern	TFT_memo_color
-	extern	TFT_advice_color
-	extern	TFT_attention_color
-	extern	TFT_warning_color
-	extern	TFT_divemask_color
+;-----------------------------------------------------------------------------
+; Font Color Selection - pallet-based Colors
+
+	extern	TFT_load_std_color_pallet			; load standard color pallet
+	extern	TFT_load_dive_color_pallet			; load dive     color pallet
+
 
-	extern	TFT_color_code_gas
-	extern	TFT_color_code_gaslist
-	extern	TFT_color_code_cns
-	extern	TFT_color_code_tank_pres_sac
+;-----------------------------------------------------------------------------
+; Color-Coding
 
-; 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
-
-; Debug output
-	extern	TFT_debug_output
+	extern	TFT_color_code_gas					; color-code by gas number (1-6) in WREG
+	extern	TFT_color_code_gaslist				; color-code by gas O2% (in hi) and absolute pressure
+	extern	TFT_color_code_cns					; color-code CNS value
 
 
- IFDEF _rx_functions
-	extern	TFT_pressures_SAC_mask				; mask for pressures and SAC
-	extern	TFT_pressures_SAC					; data for pressures and SAC
-	extern	TFT_menu_tank_pres					; update tank data when in tank setup menu
-	extern	TFT_surface_tank_pres				; update tank data when in surface mode
-	extern	TFT_surface_tankdata				; show the tank pressure data in surface customview
-	extern	TFT_attention_transmitter			; show attention for transmitter
-	extern	TFT_attention_pres_reading			; show attention for pressure reading
-	extern	TFT_warning_pres_reading			; show warning   for pressure reading
-	extern	TFT_attention_sac					; show attention for SAC
-	extern	TFT_advice_switch					; show switch advice for ind.double mode
-	extern	TFT_print_firmware_rx				; show rx firmware version
- ENDIF
+;-----------------------------------------------------------------------------
+; Append / Print Firmware Data etc.
+
+	extern	TFT_cat_firmware					; append firmware version to output buffer
+	extern	TFT_cat_beta_long					; append beta/release     to output buffer (long  format)
+	extern	TFT_cat_beta_short					; append beta/release     to output buffer (short format)
+	extern	TFT_cat_serial						; append serial number    to output buffer
+
+	extern	TFT_print_serial_and_firmware		; print serial number and full firmware
+	extern	TFT_print_firmware					; print firmware and beta/release status
+	extern	TFT_print_decotype					; print OC,CCR,... (used by logbook & simulator)
+
+	extern	TFT_message_fw_update				; firmware is updated message
+	extern	TFT_message_fw_kept					; firmware is kept    message
+
 
- IFDEF _cave_mode
-	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
+
+;-----------------------------------------------------------------------------
+; Message System
+
+	extern	TFT_buffer_trim_length				; fill or trim output buffer to a given length
+	extern	TFT_clear_message_window			; clear all messages
+	extern	TFT_clear_message_window_row2		; clear only 2nd message
+
+
+;-----------------------------------------------------------------------------
+; Debug output
+
+	extern	TFT_debug_output					; used for scheduling performance, etc.
+
+;-----------------------------------------------------------------------------
--- a/src/varargs.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/varargs.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;    File varargs.inc                          combined next generation V3.0.1
+;    File varargs.inc                        * combined next generation V3.0.1
 ;
 ;    Utilities to pass multiple arguments in compact code stream.
 ;
@@ -10,53 +10,67 @@
 ;  2011-05-27 : [jDG] Creation.
 ;
 
+
+;-----------------------------------------------------------------------------
+; Prepare reading inline Data: set Table Pointer to the Beginn of the inline Data
+;
 VARARGS_BEGIN macro
-	movff	TOSL, TBLPTRL
-	movff	TOSH, TBLPTRH
-	movff	TOSU, TBLPTRU
+	movff	TOSL, TBLPTRL			; copy program counter address to table pointer
+	movff	TOSH, TBLPTRH			; ...
+	movff	TOSU, TBLPTRU			; ...
 	endm
 
-VARARGS_GET8 macro register
-	tblrd*+
-	movff	TABLAT, register
+
+;-----------------------------------------------------------------------------
+; Read 1 Byte of inline Data
+;
+VARARGS_GET8 macro  register
+	tblrd*+							; read 1 byte from program memory
+	movff	TABLAT, register		; store to register
 	endm
 
+
+;-----------------------------------------------------------------------------
+; Read 2 Bytes of inline Data
+;
 VARARGS_GET16 macro register
-	tblrd*+
-	movff	TABLAT, register+0
-	tblrd*+
-	movff	TABLAT, register+1
+	tblrd*+							; read 1st byte from program memory
+	movff	TABLAT, register+0		; store to register
+	tblrd*+							; read 2nd byte from program memory
+	movff	TABLAT, register+1		; store to register
 	endm
 
+
+;-----------------------------------------------------------------------------
+; Read 3 Bytes of inline Data
+;
 VARARGS_GET24 macro register
-	tblrd*+
-	movff	TABLAT, register+0
-	tblrd*+
-	movff	TABLAT, register+1
-	tblrd*+
-	movff	TABLAT, register+2
+	tblrd*+							; read 1st byte from program memory
+	movff	TABLAT, register+0		; store to register
+	tblrd*+							; read 2nd byte from program memory
+	movff	TABLAT, register+1		; store to register
+	tblrd*+							; read 3rd byte from program memory
+	movff	TABLAT, register+2		; store to register
 	endm
 
+
+;-----------------------------------------------------------------------------
+; Align Table Pointer to an even Address
+;
 VARARGS_ALIGN macro
-	local	no_tblptr_align
-
-	btfss	TBLPTRL,0
-	bra		no_tblptr_align
-	incf	TBLPTRL
-	movlw	0
-	addwfc	TBLPTRH
-	addwfc	TBLPTRU
-no_tblptr_align:
+	btfsc	TBLPTRL,0				; table pointer pointing to an even address?
+	tblrd*+							; NO  - do a dummy read to advance to next even address
 	endm
 
+
+;-----------------------------------------------------------------------------
+; End reading inline Data: set Return Address behind End of the inline Data
+;
 VARARGS_END macro
-	; compute string length (modulo 256):
-	movf	TOSL,W
-	subwf	TBLPTRL,W
-
-	; then 24 bit add to return address
-	addwf	TOSL,F
-	movlw	0			; clear WREG, but keep carry
-	addwfc	TOSH,F
-	addwfc	TOSU,F
+	movf	TOSL,W					; compute how may inline bytes have been read
+	subwf	TBLPTRL,W				; WREG = (TBLPTRL - TOSL) modulo 256
+	addwf	TOSL,F					; advance the return address by this number
+	movlw	0						; ...
+	addwfc	TOSH,F					; ...
+	addwfc	TOSU,F					; ...
 	endm
--- a/src/wait.asm	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/wait.asm	Tue Apr 28 17:34:31 2020 +0200
@@ -1,6 +1,6 @@
 ;=============================================================================
 ;
-;   File wait.asm                             combined next generation V3.02.1
+;   File wait.asm                           * combined next generation V3.09.4
 ;
 ;   Wait routines
 ;
@@ -13,14 +13,16 @@
 
 #include "hwos.inc"
 
-wait	CODE
 
 
-; =============================================================================
-; WAIT 1 second
-; Warning: Do not use for time critical routines - can be between 0 and 1 sec!
-; =============================================================================
+;=============================================================================
+wait1	CODE
+;=============================================================================
 
+;-----------------------------------------------------------------------------
+; Wait 1 Second
+; Warning: do not use for time critical routines - can be between 0 and 1 sec!
+;
 	global	wait_1s
 wait_1s:
 	bcf		trigger_full_second	; clear any left-over trigger
@@ -29,11 +31,32 @@
 	return						; YES - done
 
 
-; =============================================================================
-; WAIT for multiples of 1 Millisecond
+;=============================================================================
+wait2	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Wait for a Multiple of 1 Second
+; Warning: do not use for time critical routines - can be up to 1 sec longer!
+;
+	global	WAITSX
+WAITSX:
+	bcf		trigger_full_second	; clear any left-over trigger
+	btfss	trigger_full_second	; did a new trigger occurred?
+	bra		$-2					; NO  - loop
+	decfsz	WREG,W				; YES - count down loop counter, became zero?
+	bra		WAITSX				;       NO  - loop
+	return						;       YES - done
+
+
+;=============================================================================
+wait3	CODE
+;=============================================================================
+
+;-----------------------------------------------------------------------------
+; Wait for a Multiple of 1 Millisecond
 ; Remark: not exact: 1.008 ms +/- 30.5 µs + worst case ISR latency
-; =============================================================================
-
+;
 	global	WAITMSX
 WAITMSX:
 	movwf	wait_counter		; store number of milliseconds to wait
@@ -49,6 +72,6 @@
 	bra		WAITMSX2			;       NO  - repeat outer loop
 	return						;       YES - done
 
-;=============================================================================
+;-----------------------------------------------------------------------------
 
 	END
\ No newline at end of file
--- a/src/wait.inc	Thu Mar 05 15:06:14 2020 +0100
+++ b/src/wait.inc	Tue Apr 28 17:34:31 2020 +0200
@@ -13,13 +13,23 @@
 
 ;=============================================================================
 
+
+	extern	wait_1s
+
+
+WAITS	macro	s_to_wait
+	movlw	s_to_wait+1
+	extern	WAITSX
+	call	WAITSX
+	endm
+
+
 WAITMS	macro	ms_to_wait
 	movlw	ms_to_wait
 	extern	WAITMSX
 	call	WAITMSX
 	endm
 
-	extern	wait_1s
 
 ; asm routines in hwos.asm
 	extern	request_speed_eco			; SPEED_ECO:      1 MHz