diff src/simulator.asm @ 0:11d4fc797f74

init
author heinrichsweikamp
date Wed, 24 Apr 2013 19:22:45 +0200
parents
children 150d07db6048
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator.asm	Wed Apr 24 19:22:45 2013 +0200
@@ -0,0 +1,675 @@
+;=============================================================================
+;
+;   File simulator.asm
+;
+;   Decoplan interface to C model code.
+;
+;   Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
+;=============================================================================
+; HISTORY
+;  2011-07-09 : [jDG] Creation...
+
+#include "ostc3.inc"					; Mandatory include.
+#include "convert.inc"                  ; output_*
+#include "shared_definitions.h"         ; Mailbox from/to p2_deco.c
+#include "strings.inc"                  ; STRCPY,...
+#include "tft.inc"                      ; WIN_LEFT,...
+#include "wait.inc"                     ; speed_*
+#include "start.inc"
+#include "divemode.inc"
+#include "math.inc"
+#include "eeprom_rs232.inc"
+
+gui     CODE
+
+    extern  deco_clear_tissue
+    extern  deco_push_tissues_to_vault
+    extern  deco_calc_dive_interval
+    extern  deco_calc_hauptroutine
+    extern  deco_calc_tissue
+    extern  deco_calc_CNS_fraction
+    extern  deco_calc_CNS_planning
+    extern  deco_pull_tissues_from_vault
+
+    extern  log_screendump_and_onesecond, logbook_preloop_tasks
+
+;---- Private temp variables -------------------------------------------------
+        CBLOCK  tmp+0x10                ; Reserved space for wordprocessor and convert
+            decoplan_index              ; within each page
+            decoplan_gindex             ; global index
+            decoplan_last               ; Depth of last stop (CF#29)
+            decoplan_max                ; Number of lines per page.
+            decoplan_flags              ; Various private flags.
+            decoplan_CNS:2              ; Backup CNS before vault restore
+            ; Reserved to tmp+0x1F...
+        ENDC
+#define decoplan_last_ceiling_shown   decoplan_flags,0
+
+;---- Demo decoplanner -------------------------------------------------------
+        global  do_demo_planner
+        extern  do_planner_menu
+
+do_demo_planner:
+        call    speed_fastest
+;        call    deco_reset              ; TODO: remove reset all Decodata
+        call    deco_planer
+        call    deco_show_plan
+        call    speed_eco
+        bcf     switch_right
+        bcf     switch_left
+        goto    do_planner_menu
+
+;=============================================================================
+; Pass all parameters to the C code
+;
+
+    global  get_first_dil_to_WREG
+get_first_dil_to_WREG:                  ; Gets first dil (0-4) into WREG
+        lfsr    FSR1,opt_dil_type       ; Point to dil types
+        clrf    lo                      ; start with Gas0
+        bra     get_first_gas_to_WREG2  ; Start
+
+    global  get_first_gas_to_WREG
+get_first_gas_to_WREG:                  ; Gets first gas (0-4) into WREG
+        lfsr    FSR1,opt_gas_type       ; Point to gas types
+        clrf    lo                      ; start with Gas0
+get_first_gas_to_WREG2:
+        movf    lo,W                    ;
+        movf    PLUSW1,W                ; Get Type of Gas #lo
+        sublw   .1                      ; it is = 1 (First Gas)
+        bz      get_first_gas_to_WREG3  ; Found the first gas!
+        incf    lo,F                    ; ++
+        movlw   NUM_GAS+1
+        cpfseq  lo                      ; All done?
+        bra     get_first_gas_to_WREG2  ; Not yet
+        retlw  .1                       ; No first gas found, use #1
+get_first_gas_to_WREG3:
+        movf    lo,W                    ; Put into Wreg
+        return                          ; Done
+
+        global  deco_setup
+deco_setup:
+        banksel char_I_step_is_1min     ; Select the right bank...
+        clrf    char_I_step_is_1min     ; Default to 2sec steps.
+
+        ; Fixed ambient surface pressure to 1bar.
+        movlw   LOW(.1000)
+        movwf   int_I_pres_surface+0
+        movwf   int_I_pres_respiration+0
+        movlw   HIGH(.1000)
+        movwf   int_I_pres_surface+1
+        movwf   int_I_pres_respiration+1
+    
+        clrf    int_I_divemins+0        ; Dive start
+        clrf    int_I_divemins+1
+
+        call    get_first_gas_to_WREG           ; Gets first gas (0-4) into WREG
+        movff   WREG,char_I_first_gas           ; Copy for compatibility
+        extern  setup_gas_registers
+        call    setup_gas_registers             ; With WREG=Gas 0-4, set current N2/He/O2 ratios.
+        extern  set_actual_ppo2
+        call    set_actual_ppo2                 ; Then configure char_I_actual_ppO2 (For CNS)
+
+        global	deco_setup_dive
+deco_setup_dive:						; Called from divemode
+        banksel common                  ; Bank1
+
+        btfss   FLAG_ccr_mode           ; =1: CCR mode (Fixed ppO2 or Sensor) active
+        rcall   deco_setup_oc_gases     ; Setup OC Gases
+        btfsc   FLAG_ccr_mode           ; =1: CCR mode (Fixed ppO2 or Sensor) active
+        rcall   deco_setup_cc_diluents  ; Setup CC Diluents
+        btfsc   is_bailout              ; =1: Bailout
+        rcall   deco_setup_oc_gases     ; Setup OC/Bailout Gases
+
+        movlw   deco_distance
+        movff   WREG,char_I_deco_distance
+        movff   opt_last_stop,char_I_depth_last_deco
+        movff   opt_GF_low,char_I_GF_Low_percentage
+        movff   opt_GF_high,char_I_GF_High_percentage
+        ;Overwrite GF if aGF is wanted
+        btfsc   use_agf                         ; =1: Use aGF
+        movff   opt_aGF_low,char_I_GF_Low_percentage
+        btfsc   use_agf                         ; =1: Use aGF        
+        movff   opt_aGF_high,char_I_GF_High_percentage
+        return
+
+deco_setup_cc_diluents:
+        movff   opt_dil_He_ratio+0,char_I_deco_He_ratio+0
+        movff   char_I_deco_He_ratio+0,lo
+        movff   opt_dil_O2_ratio+0,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+0
+        movff   opt_dil_type+0,WREG   ; 0=Disabled, 1=First, 2=Normal
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+0   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_dil_He_ratio+1,char_I_deco_He_ratio+1
+        movff   char_I_deco_He_ratio+1,lo
+        movff   opt_dil_O2_ratio+1,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+1
+        movff   opt_dil_type+1,WREG   ; 0=Disabled, 1=First, 2=Normal
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+1   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_dil_He_ratio+2,char_I_deco_He_ratio+2
+        movff   char_I_deco_He_ratio+2,lo
+        movff   opt_dil_O2_ratio+2,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+2
+        movff   opt_dil_type+2,WREG   ; 0=Disabled, 1=First, 2=Normal
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+2   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_dil_He_ratio+3,char_I_deco_He_ratio+3
+        movff   char_I_deco_He_ratio+3,lo
+        movff   opt_dil_O2_ratio+3,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+3
+        movff   opt_dil_type+3,WREG   ; 0=Disabled, 1=First, 2=Normal
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+3   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_dil_He_ratio+4,char_I_deco_He_ratio+4
+        movff   char_I_deco_He_ratio+4,lo
+        movff   opt_dil_O2_ratio+4,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+4
+        movff   opt_dil_type+4,WREG   ; 0=Disabled, 1=First, 2=Normal
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+4   ; Yes, clear char_I_deco_gas_change
+        return
+
+deco_setup_oc_gases:
+        movff   opt_gas_He_ratio+0,char_I_deco_He_ratio+0
+        movff   char_I_deco_He_ratio+0,lo
+        movff   opt_gas_O2_ratio+0,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+0
+        movff   opt_gas_type+0,WREG   ; 0=Disabled, 1=First, 2=Travel, 3=Deco
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+0   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_gas_He_ratio+1,char_I_deco_He_ratio+1
+        movff   char_I_deco_He_ratio+1,lo
+        movff   opt_gas_O2_ratio+1,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+1
+        movff   opt_gas_type+1,WREG   ; 0=Disabled, 1=First, 2=Travel, 3=Deco
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+1   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_gas_He_ratio+2,char_I_deco_He_ratio+2
+        movff   char_I_deco_He_ratio+2,lo
+        movff   opt_gas_O2_ratio+2,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+2
+        movff   opt_gas_type+2,WREG   ; 0=Disabled, 1=First, 2=Travel, 3=Deco
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+2   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_gas_He_ratio+3,char_I_deco_He_ratio+3
+        movff   char_I_deco_He_ratio+3,lo
+        movff   opt_gas_O2_ratio+3,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+3
+        movff   opt_gas_type+3,WREG   ; 0=Disabled, 1=First, 2=Travel, 3=Deco
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+3   ; Yes, clear char_I_deco_gas_change
+
+        movff   opt_gas_He_ratio+4,char_I_deco_He_ratio+4
+        movff   char_I_deco_He_ratio+4,lo
+        movff   opt_gas_O2_ratio+4,WREG
+        addwf   lo,W                  ; O2 + He -> WREG
+        sublw   .100                  ; 100 - (O2 + He) -> WREG
+        movff   WREG,char_I_deco_N2_ratio+4
+        movff   opt_gas_type+4,WREG   ; 0=Disabled, 1=First, 2=Travel, 3=Deco
+        tstfsz  WREG                  ; Disabled?
+        bra     $+4                   ; No
+        movff   WREG,char_I_deco_gas_change+4   ; Yes, clear char_I_deco_gas_change
+        return
+
+;=============================================================================
+; Reset decompression tissues
+; 
+        global  deco_reset
+deco_reset:
+        rcall   deco_setup              ; Setup all model parameters.
+        call    deco_clear_tissue       ; Set all tissues to Pamb * N2_ratio
+        call    deco_clear_CNS_fraction ; Reset CNS value.
+        banksel common                  ; Bank1
+        return
+
+;=============================================================================
+; Launch decoplanning
+; 
+    global  deco_planer
+deco_planer:
+        call    speed_fastest           ; Quick !
+        rcall   deco_setup              ; Setup all model parameters.
+        call    deco_push_tissues_to_vault
+        banksel common                  ; Bank1
+
+;---- Specific settings ------------------------------------------------------
+   
+        banksel char_O_deco_status      ; Bank 2
+        movlw   .3                      ; Start in surface state.
+        movwf   char_O_deco_status
+    
+        banksel char_I_step_is_1min     ; Bank 3
+        movlw   1
+        movwf   char_I_step_is_1min     ; Set 1min steps
+
+;---- Add delay at surface, if needed ----------------------------------------
+        tstfsz  char_I_dive_interval
+        call    deco_calc_dive_interval
+
+;---- Dive loop --------------------------------------------------------------
+
+        ; Compute dive ambiant conditions
+        banksel char_I_bottom_depth
+        movf    char_I_bottom_depth,W
+        mullw   .100
+        movlw   LOW(.1000)
+        addwf   PRODL,W
+        movwf   int_I_pres_respiration+0
+        movlw   HIGH(.1000)
+        addwfc  PRODH,W
+        movwf   int_I_pres_respiration+1
+
+        banksel int_I_divemins          ; Bank 4
+        clrf    int_I_divemins+0        ; Clear dive time
+        clrf    int_I_divemins+1
+
+        clrf    TMR5L
+        clrf    TMR5H                   ; 30,51757813µs/bit in TMR5L:TMR5H
+        call    deco_calc_hauptroutine  ; Reset + simulate first min.
+
+deco_planer_loop:
+        banksel int_I_divemins          ; Bank 3
+        incf    int_I_divemins,F        ; Done 1 min.
+        btg     LEDg
+    
+        movf    char_I_bottom_time,W    ; Finished ?
+        xorwf   int_I_divemins,W
+        bz      deco_planer_endloop     ; YES
+    
+        call	deco_calc_tissue	    ; JUST calc tissue (faster).
+        call	deco_calc_CNS_fraction  ; Also calculate CNS (in 1min loop)
+        bra     deco_planer_loop
+
+deco_planer_endloop:
+        banksel char_I_step_is_1min
+        clrf    char_I_step_is_1min     ; Back to 2sec loops
+
+;---- Wait until status reach zero -------------------------------------------
+deco_planer_finishing:
+        btg     LEDg
+        clrf    TMR5L
+        clrf    TMR5H                       ; 30,51757813µs/bit in TMR5L:TMR5H
+        call    deco_calc_hauptroutine  ; Simulate 2sec more
+
+        banksel char_O_deco_status      ; Bank 2
+        movf    char_O_deco_status,W
+        bz      deco_planer_finished
+        
+        bra     deco_planer_finishing
+
+deco_planer_finished:
+        call    deco_calc_CNS_planning
+        movff   int_O_CNS_fraction+0,decoplan_CNS+0
+        movff   int_O_CNS_fraction+1,decoplan_CNS+1
+        call    deco_pull_tissues_from_vault
+        bcf     LEDg
+        banksel common                  ; Bank1
+		movlw	b'00111000'				; 1:8 Prescaler -> 65,536ms@16MHz
+		movwf	T3CON
+        call    speed_normal
+        return
+
+;-----------------------------------------------------------------------------
+; Draw a stop of the deco plan (simulator or dive).
+; Inputs: lo      = depth. Range 3m...93m
+;                 + 80 if this is a switch-gas stop.
+;         up      = minutes. range 1'..240'.
+;         win_top = line to draw on screen.
+; Trashed: up, lo, win_height, win_leftx2, win_width, win_color*,
+;          WREG, PROD, TBLPTR TABLAT.
+;
+deco_plan_show_stop:
+        ;---- Print depth ----------------------------------------------------
+        btfss   lo,7                    ; Bit set ?
+        bra     deco_plan_show_std_stop  ; No : Just an usual stop.
+
+        TFT_ATTENTION_COLOR
+        bcf     lo,7                    ; and cleanup depth.
+        bra     deco_plan_show_nstd_stop
+
+deco_plan_show_std_stop:
+    	TFT_STD_COLOR
+
+deco_plan_show_nstd_stop:        
+	    lfsr	FSR2,buffer
+
+		TSTOSS  opt_units			; 0=Meters, 1=Feets
+		bra		deco_plan_show_nstd_stop_metric
+
+        WIN_LEFT .85
+		movf	lo,W					; lo = m
+		mullw	.100					; PRODL:PRODH = mbar
+		movff	PRODL,lo
+		movff	PRODH,hi
+; Convert with 334feet/100m to have 10ft, 20ft, 30ft stops...
+		movff	lo,xA+0
+		movff	hi,xA+1
+		movlw	LOW 	d'334'          ; 334feet/100m
+		movwf	xB+0
+		movlw	HIGH 	d'334'
+		movwf	xB+1
+		call	mult16x16			    ; xA*xB=xC (lo:hi * 328)
+		movlw	d'50'                   ; round up
+		addwf	xC+0,F
+		movlw	0
+		addwfc	xC+1,F
+		addwfc	xC+2,F
+		addwfc	xC+3,F
+		movlw	d'100'					
+		movwf	xB+0
+		clrf	xB+1
+		call	div32x16  			    ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
+		movff	xC+0,lo
+		movff	xC+1,hi				    ; restore lo and hi with updated value
+		bsf		leftbind
+		bsf		ignore_digit4			; Only full feet
+		output_16
+		STRCAT_PRINT	"ft "
+		bra		deco_plan_show_nstd_stop_common
+
+deco_plan_show_nstd_stop_metric:
+        WIN_LEFT .90
+	    bsf     leftbind
+	    output_8					    ; outputs into Postinc2!
+        STRCAT_PRINT 	"m "
+deco_plan_show_nstd_stop_common:
+        ;---- Print duration -------------------------------------------------
+	    WIN_LEFT	.135
+	    lfsr	FSR2,buffer
+	    
+	    movf    lo,W                    ; Swap up & lo
+	    movff   up,lo
+	    movwf   up
+
+	    output_8					    ; Allow up to 240'
+        STRCAT_PRINT "'  "              ; 1 to 3 chars for depth.
+
+	    movf    lo,W                    ; Swap back up & lo
+	    movff   up,lo
+	    movwf   up
+
+        ;---------------------------------------------------------------------
+        ; Draw the bar graph used for deco stops (decoplan in simulator or dive).
+        incf   win_top,F
+        movlw	.19
+        movwf   win_height
+        movlw	.118
+        movwf	win_leftx2    		    ; column left (0-159)
+        movlw	.16
+        movwf	win_width    		    ; column max width.
+
+        ; Draw used area (up = minutes):
+        movlw	.16                     ; Limit length (16min)
+        cpfslt	up
+        movwf	up
+        movff	up,win_bargraph         ; Active width, the rest is cleared.
+        call	TFT_box
+
+        ; Restore win_top
+	    TFT_STD_COLOR
+        decf    win_top,F               ; Restore win_top
+        return
+
+;-----------------------------------------------------------------------------
+; Clear unused area belw last stop
+; Inputs: win_top : last used area...
+deco_plan_show_clear_bottom:
+        movf    win_top,W               ; Get back from bank0
+        btfsc   divemode                ; In dive mode ?
+        sublw   .168                    ; Yes: bottom row in divemode
+        btfss   divemode                ; In dive mode ?
+        sublw   .240                    ; No: bottom row in planning
+        movwf   win_height
+
+        WIN_LEFT .85                    ; Full divemenu width
+        movlw   .160-.85+1
+        movwf   win_width
+
+        clrf    win_color1              ; Fill with black
+        clrf    win_color2
+
+        goto	TFT_box
+
+;-----------------------------------------------------------------------------
+; Display the decoplan (simulator or divemode).
+; Inputs: char_O_deco_table (array of stop times, in minutes)
+;         decoplan_page = page number.
+;
+deco_show_plan_page:
+        WIN_INVERT 0
+
+        ;---- Is there deco stops ? ------------------------------------------
+    	movff   char_O_first_deco_depth,WREG
+    	iorwf   WREG
+        bnz		deco_plan_show_1
+
+        ;---- No Deco --------------------------------------------------------
+    	TFT_STD_COLOR
+        TEXT_SMALL   .80, .0, tNoDeco
+        bsf     decoplan_last_ceiling_shown
+        return
+
+deco_plan_show_1:
+    	lfsr	FSR0,char_O_deco_depth  ; Initialize indexed addressing.
+	    lfsr	FSR1,char_O_deco_time
+
+        movlw   .8                      ; 8 lines/page in decoplan
+        btfsc   divemode
+        movlw   .6                      ; 6 lines/page in divemode.
+        movwf   decoplan_max
+
+        clrf    decoplan_index          ; Start with index = 0
+        clrf	win_top                 ; and row = 0
+
+        ; Read stop parameters, indexed by decoplan_index and decoplan_page
+        movf    decoplan_page,W         ; decoplan_gindex = 6*decoplan_page + decoplan_index
+        mulwf   decoplan_max
+        movf    decoplan_index,W
+        addwf   PRODL,W
+        movwf   decoplan_gindex         ; --> decoplan_gindex
+
+        bcf     decoplan_last_ceiling_shown   ; Not finished yet...
+
+deco_plan_show_2:
+        btfsc   decoplan_gindex,5       ; Reached table length (32) ?
+        bra     deco_plan_show_99       ; YES: finished...
+
+        ; Read stop parameters, indexed by decoplan_index
+        movf    decoplan_gindex,W       ; index
+    	movff	PLUSW1,up               ; char_O_deco_time [gindex] --> up
+	    movff	PLUSW0,lo               ; char_O_deco_depth[gindex]
+        movf    lo,W
+        bz      deco_plan_show_99       ; depth == 0 : finished.
+
+        ; Display the stop line
+    	rcall	deco_plan_show_stop
+
+        ; Next
+        movlw   .24
+        addwf   win_top,F               ; row: += 24
+	    incf	decoplan_index,F        ; local index += 1
+	    incf	decoplan_gindex,F       ; global index += 1
+
+        ; Max number of lines/page reached ?
+    	movf    decoplan_max,W          ; index+1 == max ?
+    	cpfseq	decoplan_index
+    	bra		deco_plan_show_2         ; NO: loop
+
+    	; Check if next stop if end-of-list ?
+    	movf    decoplan_gindex,W
+	    movf	PLUSW0,W                ; char_O_deco_depth[gindex]
+    	bz      deco_plan_show_99         ; End of list...
+
+        ; Display the message "more..."
+        rcall   deco_plan_show_clear_bottom  ; Clear from next line
+
+    	TFT_STD_COLOR
+        TEXT_SMALL .85, .240-.25, tMore
+        return
+
+deco_plan_show_99:
+        bsf		decoplan_last_ceiling_shown ; Nothing more in table to display.
+        rcall   deco_plan_show_clear_bottom ; Clear from next line
+        return
+
+;-----------------------------------------------------------------------------
+; Loop to show all pages of the decoplan (surfacemode)
+
+        global  deco_show_plan
+deco_show_plan:
+        clrf    decoplan_page
+        call    TFT_ClearScreen
+        WIN_COLOR   color_greenish
+        TEXT_SMALL  .1,.1, tDivePlan
+        TFT_STD_COLOR
+        WIN_LEFT    .0
+        
+        ;---- Display model
+        movff   char_I_deco_model,WREG
+        iorwf   WREG
+        bnz     deco_show_plan_m1
+        
+        ; Display ZH-L16 sat/desat model.
+        TEXT_SMALL  .0,.40,  tZHL16
+        WIN_TOP .65
+        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     deco_show_plan_m2
+
+        ; Display ZH-L16-GF low/high model.
+deco_show_plan_m1:
+        TEXT_SMALL  .0,.40,  tZHL16GF
+        WIN_TOP .65
+        lfsr    FSR2,buffer
+        movff   char_I_GF_Low_percentage,lo
+        output_99x
+        STRCAT  "%/"
+        movff   char_I_GF_High_percentage,lo
+        output_99x
+        STRCAT_PRINT  "%"
+        ;bra     deco_show_plan_m2
+
+deco_show_plan_m2:        
+        
+        ;---- Display TTS result
+        WIN_TOP     .165
+        STRCPY_TEXT tTTS
+        STRCAT  ": "
+
+        movff   int_O_ascenttime+0,lo
+        movff   int_O_ascenttime+1,hi
+        bsf     leftbind
+        output_16
+        STRCAT_PRINT "'"
+
+        ;---- Display CNS result
+        WIN_TOP     .190
+        STRCPY_TEXT tCNS
+        STRCAT  ": "
+        movff   int_O_CNS_fraction+0,lo
+        movff   int_O_CNS_fraction+1,hi
+        output_16_3
+        STRCAT  "%\x92"					; "->"
+        movff   decoplan_CNS+0,lo
+        movff   decoplan_CNS+1,hi
+        output_16_3
+        STRCAT_PRINT "%"
+       
+        ;---- Loop through pages
+deco_show_plan_1:
+        call    speed_normal
+        rcall   deco_show_plan_page
+        incf    decoplan_page,F
+
+        call    logbook_preloop_tasks
+deco_show_plan_2:
+        btfsc   switch_right
+        bra     deco_show_plan_3
+        btfsc   switch_left
+        bra     deco_show_plan_4
+        call    log_screendump_and_onesecond    ; Check if we need to make a screenshot and check for new second
+    	btfsc	sleepmode                       ; Timeout?
+        bra		deco_show_plan_4                ; Exit
+        bra     deco_show_plan_2
+
+deco_show_plan_3:
+        btfss   decoplan_last_ceiling_shown
+        bra     deco_show_plan_1
+
+deco_show_plan_4:
+        call    speed_normal            ; Display in fast mode.
+        return
+
+;=============================================================================
+;
+        global  do_demo_divemode
+do_demo_divemode:
+		extern	option_save_all
+		call	option_save_all			; Save all settings into EEPROM before starting simulation
+ 		call    deco_push_tissues_to_vault
+        banksel common                  ; Bank1
+
+		bsf		restore_deco_data		; Restore tissue and CNS after sim
+
+		bcf		pressure_refresh
+		btfss	pressure_refresh					; Wait for sensor
+		bra		$-2
+
+		bsf		simulatormode_active				; Set Flag
+		movlw	LOW			simulator_start_depth
+		movff	WREG,rel_pressure+0
+		movlw	HIGH		simulator_start_depth
+		movff	WREG,rel_pressure+1					; Set Depth
+
+		movlw	LOW			(simulator_start_depth+.1000)
+		movff	WREG,sim_pressure+0
+		movlw	HIGH		(simulator_start_depth+.1000)
+		movff	WREG,sim_pressure+1					; Set Depth
+
+		bsf		divemode
+		goto	diveloop							; Switch into Divemode!
+
+
+        END
\ No newline at end of file