changeset 169:e26f49674956

Merge decoplan display for both GF and Buhlmann models. + Add CF(54) to reverse deco plan display order. + Clean state machine to faster redisplay in divemode. Fix don't flip screen for soft emulation.
author JeanDo
date Wed, 26 Jan 2011 19:19:02 +0100
parents 494587193f5d
children 0f7ca37b1412
files code_part1/OSTC_code_asm_part1/changelog.txt code_part1/OSTC_code_asm_part1/definitions.asm code_part1/OSTC_code_asm_part1/divemode.asm code_part1/OSTC_code_asm_part1/divemode_menu.asm code_part1/OSTC_code_asm_part1/menu_reset.asm code_part1/OSTC_code_asm_part1/ms5535.asm code_part1/OSTC_code_asm_part1/pled_outputs.asm code_part1/OSTC_code_asm_part1/simulator.asm code_part1/OSTC_code_asm_part1/start.asm code_part1/OSTC_code_asm_part1/text_table.asm code_part1/OSTC_code_c_part2/p2_deco.c code_part1/OSTC_code_c_part2/p2_deco.o code_part1/OSTC_code_c_part2/shared_definitions.h
diffstat 13 files changed, 412 insertions(+), 572 deletions(-) [+]
line wrap: on
line diff
--- a/code_part1/OSTC_code_asm_part1/changelog.txt	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/changelog.txt	Wed Jan 26 19:19:02 2011 +0100
@@ -1,5 +1,8 @@
 New in 1.81 beta:
 BETA Version - Do NOT use for diving!
+CHANGE: ZH-L16 display all stops (up to 93m), as ZH-L16-GF mode.
+BUGFIX: Don't wrap TTS sum (still limit each stop display (not compute) to ~4h).
+NEW: CF54: Display shallowest stop first (decoplan and divemode).
 
 New in 1.80 Stable:
 Stable release
--- a/code_part1/OSTC_code_asm_part1/definitions.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/definitions.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -488,7 +488,7 @@
 
 #DEFINE	internal_eeprom_write2	flag13,0	;=1: start routine to access internal EEPROM BANK 1 via the UART
 #DEFINE	button_delay_done		flag13,1	;=1: Button was pressed for more then 500ms, start counting
-#DEFINE	multi_gf_display		flag13,2	;=1: Display the Multi-GF screen instead of normal divemode screen
+; free                          flag13,2	;=1: unused
 #DEFINE	deco_mode_changed		flag13,3	;=1: The Decomode was changes, show decomode description!
 #DEFINE	pled_velocity_display	flag13,4	;=1: Velocity is displayed 
 #DEFINE depth_greater_100m		flag13,5	;=1: Depth is greater then 100m
--- a/code_part1/OSTC_code_asm_part1/divemode.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/divemode.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -433,11 +433,7 @@
 	movlb	b'00000001'						; rambank 1 selected
 	ostc_debug	'C'		; Sends debug-information to screen if debugmode active
 
-	movff	char_O_deco_status,WREG
-	tstfsz	WREG                        ; deco_status=0 if decompression calculation done
-	return                              ; calculation not yet finished!
-
-	movff	char_O_array_decodepth+0,wait_temp	; copy ceiling to temp register
+	movff	char_O_first_deco_depth,wait_temp	; copy ceiling to temp register
 	tstfsz	wait_temp							; Ceiling<0m?
 	bra		calc_deko_divemode3					; Yes!
 
@@ -476,8 +472,8 @@
 	call	PLED_display_deko_mask				; clear nostop time, display decodata
 	bsf		dekostop_active						; Set flag
 
-	movff	char_O_array_decodepth+0,decodata+0	; ceiling
-	movff	char_O_array_decotime,decodata+1	; length of first stop in minues
+	movff	char_O_first_deco_depth,decodata+0	; ceiling
+	movff	char_O_first_deco_time,decodata+1	; length of first stop in minues
 
 	call	PLED_display_deko					; display decodata
 	return						
@@ -1682,5 +1678,4 @@
 	subfwb	EEDATA,F					; minus O2
 	movff	EEDATA, char_I_N2_ratio		; = N2!
 
-	bcf		multi_gf_display			; Do not display the multi-gf table screen
 	return
--- a/code_part1/OSTC_code_asm_part1/divemode_menu.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/divemode_menu.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -159,11 +159,11 @@
 	dcfsnz	menupos,F
 	bra		divemode_toggle_brightness	; Toggle OLED-Brightness
 	dcfsnz	menupos,F
-	bra		timeout_divemenu2			; Quit divemode menu
+	bra		timeout_divemenu2           ; Quit divemode menu
 	bra		timeout_divemenu2			; Quit divemode menu
 
 divemode_menu3:
-	movff	menupos3,temp1		; copy
+	movff	menupos3,temp1              ; copy
 	dcfsnz	temp1,F
 	bra		toggle_stopwatch			; Toggle Stopwatch/Average register
 	dcfsnz	temp1,F
@@ -177,9 +177,9 @@
 	bra		timeout_divemenu2			; Quit divemode menu
 
 set_marker:
-	movlw	d'6'				; Type of Alarm  (Manual Marker)
-	movwf	AlarmType			; Copy to Alarm Register
-	bsf		event_occured		; Set Event Flag
+	movlw	d'6'                        ; Type of Alarm  (Manual Marker)
+	movwf	AlarmType                   ; Copy to Alarm Register
+	bsf		event_occured               ; Set Event Flag
 	bra		timeout_divemenu2			; quit menu!
 
 toggle_stopwatch:
@@ -333,41 +333,23 @@
 	bsf		display_see_deco			; set flag
 	call	PLED_clear_divemode_menu	; Clear Menu
 	
-	read_int_eeprom	d'34'
-	movlw	d'3'
-	cpfsgt	EEDATA						; in multi-gf mode? Z16 GF OC=4 and Z16 GF CC=5
-	bra		divemenu_see_decoplan1		; No, standard ZH-L16
-
-	bsf		multi_gf_display			; Yes, display the multi-gf table screen
 	bcf		last_ceiling_gf_shown		; Clear flag
-
     clrf    decoplan_page               ; Starts on page 0
-	call	PLED_decoplan_gf			; Display the new screen
-	return
-	
-divemenu_see_decoplan1:	
-    movff	char_O_deco_status,WREG
-    tstfsz	WREG                        ; deco_status=0 if decompression calculation done
-    return                              ; calculation not yet finished!
-	
-	call	PLED_decoplan				; display the Decoplan
-	return
+    bra     divemenu_see_decoplan2_1
 
 divemenu_see_decoplan2:
-	btfsc	multi_gf_display			; Next Page in Multi-GF Screen?
-	bra		divemenu_see_decoplan2_nextgf	; Yes!
-; No, remove outputs!
-divemenu_see_decoplan2_0:
-	bcf		display_see_deco			; clear flag
-	bra		timeout_divemenu2			; quit menu!
-
-divemenu_see_decoplan2_nextgf:
 	incf	decoplan_page,F
 	btfsc	last_ceiling_gf_shown		; last ceiling shown?
 	bra		divemenu_see_decoplan2_0	; All done, clear and return
 
+divemenu_see_decoplan2_1:
 	clrf	timeout_counter3			; Clear timeout Divemode menu
-	bra		timeout_divemenu3x			; Display next page
+	call	PLED_decoplan   			; Display the new screen
+	return
+
+divemenu_see_decoplan2_0:
+	bcf		display_see_deco			; clear flag
+	bra		timeout_divemenu2			; quit menu!
 
 divemenu_set_xgas2:
 	dcfsnz	menupos,F
@@ -593,25 +575,15 @@
 	
 	btfss	display_see_deco		; Is the decoplan active?
 	bra		timeout_divemenu1		; No, skip updating the decoplan
-
-	btfsc	multi_gf_display		; display the multi-gf table screen?
-	bra		timeout_divemenu3		; Yes...
-
-	movff	char_O_deco_status,WREG
-	tstfsz	WREG                        ; deco_status=0 if decompression calculation done
-	bra		timeout_divemenu1		; No, skip updating the decoplan
-	
-	call	PLED_decoplan			; update the Decoplan
+	bra		timeout_divemenu3	    ; Yes...
 	
 timeout_divemenu1:	
 	incf	timeout_counter3,F		; increase timeout_counter3
 	GETCUSTOM8	d'10'				; loads timeout_divemenu into WREG
 	cpfsgt	timeout_counter3		; ... longer then timeout_divemenu
 	return							; No!
+
 timeout_divemenu2:					; quit divemode menu
-;	btfss	multi_gf_display		; Was the Multi-GF Table displayed?
-;	bra		timeout_divemenu2a		; No, normal OLED rebuild
-
 ; Restore some outputs
 	clrf	decoplan_page           ; Page 0-1 of deco list
 	call	PLED_clear_divemode_menu; Clear dive mode menu
@@ -627,7 +599,6 @@
 	call	PLED_display_ndl_mask	;  Clear deco data, display nostop time
 
 timeout_divemenu2a:
-	bcf		multi_gf_display		; Do not display the multi-gf table screen
 	bcf		menubit
 	bcf		premenu					; Yes, clear flags and menu, display dive time and mask again
 	call	PLED_active_gas_divemode; Display gas, if required
@@ -643,15 +614,15 @@
 	bcf		switch_left				; and debounce switches
 	bcf		switch_right
 	return
-	
+
+; Re-Draw current page of decoplan (may have more stops)
 timeout_divemenu3:
-	movff	char_O_deco_status,WREG
-	tstfsz	WREG                        ; deco_status=0 if decompression calculation done
-	bra		timeout_divemenu1				; No, skip updating the decoplan
-timeout_divemenu3x:
-	call	PLED_decoplan_gf            ; Re-Draw Current page of GF Decoplan
+    movff   char_O_deco_status,WREG     ; Get last computation state (BANK safe)
+    iorwf   WREG                        ; Is it zero ?
+    btfsc   STATUS,Z
+	call	PLED_decoplan               ; Yes: new data available.
 	bra		timeout_divemenu1			; Check timeout
-	
+
 timeout_divemenu6:
 	; Update Simulator Mask
 	call	PLED_divemode_simulator_mask; Show mask
--- a/code_part1/OSTC_code_asm_part1/menu_reset.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/menu_reset.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -170,7 +170,7 @@
 	                
 	CF_DEFAULT    CF_BOOL,     	d'1',   0,      0 		; CF52 Show Tissue Graph in Divemode
 	CF_DEFAULT    CF_BOOL,	    d'0',   0,      0 		; CF53 Show Laeding Tissue in Divemode
-	CF_DEFAULT    CF_INT15,     0,      0,      0 		; UNUSED
+	CF_DEFAULT    CF_BOOL,      d'0',   0,      0 		; CF54 Display shalowest stop first
 	CF_DEFAULT    CF_INT15,     0,      0,      0 		; UNUSED
 	CF_DEFAULT    CF_INT15,     0,      0,      0 		; UNUSED
 	                
--- a/code_part1/OSTC_code_asm_part1/ms5535.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/ms5535.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -18,13 +18,18 @@
 ; routines for Intersema MS5535A, MS5541B and MS5541C
 ; history:
 ; 2005-09-26: Written by Matthias Heinrichs, info@heinrichsweikamp.com
-; 2008-08-21: MH last updated
+; 2008-08-21: MH last updated, with second order compensation.
 ; 2011-01-19: jDG Clean up using true signed arithmetics.
 ; known bugs:
 ; ToDo: 
 
-; with second order temperature compensation
+;=============================================================================
+; Expose internal variables, to ease debug:
+    global D1, D2
+    global C1, C2, C3, C4, C5
+    global xdT, xdT2, OFF, SENS, amb_pressure
 
+;=============================================================================
 calculate_compensation:
     ; calculate UT1 = 8*C5 + 10000 (u16 range 10.000 .. +42.760)
 	clrf	isr_xA+1
@@ -193,6 +198,7 @@
 calc_pos_temp:
 	return			                    ; Fertig mit allem
 
+;=============================================================================
 get_pressure_start:
 	rcall	reset_MS5535A
 	movlw	b'10100000'	;+3*high as start and 1+low as stop!
@@ -212,6 +218,7 @@
 #endif
 	return
 
+;=============================================================================
 get_temperature_start:
 	rcall	reset_MS5535A
 	movlw	b'10010000'	;+3*high as start and 1+low as stop!
@@ -226,20 +233,8 @@
 #endif
 	return
 
+;=============================================================================
 get_calibration_data:
-;	; read addional temperature correction from internal EEPROM 0x100
-;	bsf		no_sensor_int				; No sensor interupt!
-;	clrf	temperature_correction		; clear compensation value
-;	movlw	LOW		0x100
-;	movwf	EEADR
-;	movlw	HIGH	0x100
-;	movwf	EEADRH
-;	call	read_eeprom
-;	clrf	EEADRH						; Only 256Bytes used in normal program
-;	movlw	d'200'						; limit value
-;	cpfsgt	EEDATA						; EEDATA>200?
-;	movff	EEDATA, temperature_correction	; No, Store for compensation
-;	
 	rcall	reset_MS5535A
 	movlw	d'13'
 	movwf	clock_count
@@ -398,6 +393,7 @@
 	bcf		no_sensor_int		; enable sensor interrupts
 	return
 
+;=============================================================================
 reset_MS5535A_one:
 	bsf		sensor_SDO
 	nop
@@ -485,7 +481,6 @@
 	decfsz	clock_count,F
 	bra		recieve_loop
 	return
-	
 
 send_data_MS55535A:
 	; send three startbits first
--- a/code_part1/OSTC_code_asm_part1/pled_outputs.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/pled_outputs.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -143,8 +143,8 @@
 	cpfseq	lo					; =1?
 	bra		PLED_color_code_ceiling1	; No, Set to default color
 
-	movff	char_O_array_decodepth+0,lo	; Ceiling in m
-	decf	lo,F	; -1
+	movff	char_O_first_deco_depth,lo  ; Ceiling in m
+	decf	lo,F	                    ; -1
 	movff	rel_pressure+1,xA+1
 	movff	rel_pressure+0,xA+0
 	movlw	LOW		d'100'
@@ -455,13 +455,13 @@
 	WIN_TOP		.80
 	WIN_LEFT	.94
 	WIN_FONT 	FT_MEDIUM
-	WIN_INVERT	.0					; Init new Wordprocessor
-	PLED_color_code		warn_ceiling	; Color-code Output
+	WIN_INVERT	.0                      ; Init new Wordprocessor
+	PLED_color_code		warn_ceiling    ; Color-code Output
 	lfsr	FSR2,letter
-	movff	char_O_array_decodepth+0,lo		; Ceiling in m
+	movff	char_O_first_deco_depth,lo  ; Ceiling in m
 	output_99
 	PUTC    'm'
-	movff	char_O_array_decotime,lo		; length of first stop in m
+	movff	char_O_first_deco_time,lo   ; length of first stop in m
 	output_99
 	STRCAT_PRINT "'"
 	WIN_FONT 	FT_SMALL
@@ -530,8 +530,8 @@
 	return
 
 PLED_display_velocity:
-	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
-	return							; Yes, No update and return!
+;	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
+;	return							; Yes, No update and return!
 
 	ostc_debug	'v'		; Sends debug-information to screen if debugmode active
 	WIN_TOP		.90
@@ -835,8 +835,8 @@
 	return
 
 PLED_temp_divemode:
-	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
-	return								; Yes, No update and return!
+;	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
+;	return								; Yes, No update and return!
 
 	ostc_debug	'u'		; Sends debug-information to screen if debugmode active
 
@@ -913,8 +913,8 @@
 	btfsc	FLAG_apnoe_mode				; Ignore in Apnoe mode
 	return
 
-	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
-	return								; Yes, No update and return!
+;	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
+;	return								; Yes, No update and return!
 
 	WIN_INVERT	.0					; Init new Wordprocessor	
 	call	PLED_active_gas_divemode_show	; Show gas (Non-Inverted in all cases)
@@ -2191,7 +2191,7 @@
 ;         win_top = line to draw on screen.
 ; Trashed: hi, lo, win_height, win_leftx2, win_width, win_color*,
 ;          WREG, PROD, TBLPTR TABLAT.
-
+;
 PLED_decoplan_show_stop:
         ;---- Print depth ----------------------------------------------------
         WIN_LEFT .100
@@ -2273,34 +2273,32 @@
 #define decoplan_last   apnoe_max_pressure  ; Depth of last stop (CF#29)
 #define decoplan_max    apnoe_max_pressure+1; Number of lines per page. 7 in planning, 5 in diving.
 
-PLED_decoplan_gf:
+PLED_decoplan:
         ostc_debug	'n'		; Sends debug-information to screen if debugmode active
 
         WIN_INVERT 0
 
         ;---- Is there deco stops ? ------------------------------------------
-    	lfsr	FSR1,char_O_deco_table
-    	movlw   .1
-    	movf    PLUSW1,W                ; char_O_deco_table[1] --> WREG
-        bnz		PLED_decoplan_gf_1
-        
+    	movff   char_O_first_deco_depth,WREG
+    	iorwf   WREG
+        bnz		PLED_decoplan_1
+
         ;---- No Deco --------------------------------------------------------
         call    PLED_standard_color
         DISPLAYTEXT	d'239'              ;"No Deco"
         bsf     last_ceiling_gf_shown
         return
 
-PLED_decoplan_gf_1:
-    	GETCUSTOM8	d'29'			    ; Last decostop depth, in m
-        movwf	decoplan_last		    ; --> decoplan_last
+PLED_decoplan_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
 
-        movlw   .1
-        movwf   decoplan_index          ; Start with index = 1
+        clrf   decoplan_index           ; Start with index = 0
         clrf	WREG
         movff	WREG,win_top            ; and row = 0
 
@@ -2313,29 +2311,16 @@
         
         bcf     last_ceiling_gf_shown   ; Not finished yet...
 
-PLED_decoplan_gf_2:
+PLED_decoplan_2:
         btfsc   decoplan_gindex,5       ; Reached table length (32) ?
-        bra     PLED_decoplan_gf_99     ; YES: finished...
-
-        ; Compute new depth
-        movf    decoplan_gindex,W       ; depth = 3 * (global index)
-        mullw   .3                      ; --> PROD
-        movf    decoplan_last,W         ; depth < decoplan_last (CF#29) ?
-        cpfslt  PRODL
-        movf    PRODL,W                 ; NO: take depth, else keep decoplan_last.
-        movwf   lo                      ; --> lo
-
-        ; Read deepest depth from other bank.
-        movff   char_O_array_decodepth,WREG
-        xorwf   lo,W                    ; This is last stop ?
-        btfsc   STATUS,Z
-        bsf     last_ceiling_gf_shown   ; YES: mark for latter...
-
-        ; Read stop duration
+        bra     PLED_decoplan_99        ; YES: finished...
+
+        ; Read stop parameters, indexed by decoplan_index
         movf    decoplan_gindex,W       ; index
-    	movff	PLUSW1,hi               ; char_O_deco_table[index] --> hi
-    	movf    hi,W                    ; time = zero ?
-    	bz      PLED_decoplan_gf_4      ; Do not display it: continue.
+    	movff	PLUSW1,hi               ; char_O_deco_time [gindex] --> hi
+	    movff	PLUSW0,lo               ; char_O_deco_depth[gindex]
+        movf    lo,W
+        bz      PLED_decoplan_99        ; depth == 0 : finished.
 
         ; Display the stop line
     	call	PLED_decoplan_show_stop
@@ -2345,22 +2330,18 @@
 	    addlw	.24
         movff   WREG,win_top
 	    incf	decoplan_index,F        ; local index += 1
-PLED_decoplan_gf_4:
 	    incf	decoplan_gindex,F       ; global index += 1
 
-        btfsc   last_ceiling_gf_shown   ; Last one done ?
-        bra     PLED_decoplan_gf_99     ; YES: finished...
-
         ; Max number of lines/page reached ?
-    	incf    decoplan_max,W          ; index+1 == max+1 ?
+    	movf    decoplan_max,W          ; index+1 == max ?
     	cpfseq	decoplan_index
-    	bra		PLED_decoplan_gf_2      ; NO: loop
+    	bra		PLED_decoplan_2         ; NO: loop
 
     	; Check if next stop if end-of-list ?
-    	movlw   .3                      ; Next stop is lo + 3m
-    	addwf   lo,W
-    	xorwf   decoplan_last,W         ; == last stop ?
-    	bz      PLED_decoplan_gf_99     ; End of list...
+    	movf    decoplan_gindex,W
+	    movff	PLUSW0,WREG             ; char_O_deco_depth[gindex]
+	    iorwf   WREG
+    	bz      PLED_decoplan_99        ; End of list...
 
         ; Display the message "more..."
         rcall   PLED_decoplan_clear_bottom  ; Clear from next line
@@ -2371,93 +2352,10 @@
         bcf		last_ceiling_gf_shown	; More page to display...
     	return
 
-PLED_decoplan_gf_99:
+PLED_decoplan_99:
         bsf		last_ceiling_gf_shown   ; Nothing more in table to display.
         rcall   PLED_decoplan_clear_bottom  ; Clear from next line
         return
-
-;-----------------------------------------------------------------------------
-; Display the decoplan (simulator or divemode) for ZH-L16 model
-PLED_decoplan:
-        ostc_debug	'n'		; Sends debug-information to screen if debugmode active
-        
-        WIN_INVERT 0
-
-        ;---- Is there deco information --------------------------------------
-    	lfsr	FSR0,char_O_array_decodepth
-	    lfsr	FSR1,char_O_array_decotime
-
-    	movf    INDF0,W
-        bnz		PLED_decoplan1
-        
-        ;---- No Deco --------------------------------------------------------
-        call    PLED_standard_color
-        DISPLAYTEXT	d'239'              ;"No Deco"
-        bsf     last_ceiling_gf_shown
-        return
-
-PLED_decoplan1:
-    	GETCUSTOM8	d'29'			    ; Last decostop depth, in m
-        movwf	decoplan_last		    ; --> decoplan_last
-
-        movlw   .6                      ; Max 6 lines in all modes.
-        movwf   decoplan_max
-        
-        clrf	decoplan_index          ; Starts with index = 0
-        clrf	WREG
-        movff	WREG,win_top            ; and row = 0
-
-PLED_decoplan2:
-        ; Read stop parameters, indexed by decoplan_index
-	    movf	decoplan_index,W
-	    movff	PLUSW0,lo               ; array_decodepth[index]
-	    movff	PLUSW1,hi               ; array_decotime[index]
-
-        ; 0 time == end-of-table.
-    	movf	hi,w
-    	bz      PLED_decoplan_0
-
-        call	PLED_decoplan_show_stop
-
-        movff   win_top,WREG            ; row += 24
-	    addlw	.24         
-        movff   WREG,win_top
-	    incf	decoplan_index,F        ; index += 1    
-
-        ; 6 Stops max...
-        movf    decoplan_max,W
-        cpfseq	decoplan_index
-        bra		PLED_decoplan2
-
-        ;---- Additional time in the decoplan ? ------------------------------
-        movf    decoplan_max,W          ; Read array_decotime[6]
-        movf    PLUSW1,W                ; set Z flag
-        movwf   lo                      ; and copy to lo
-        btfsc   STATUS,Z                ; Zero: nothing to add.
-        return
-        
-        WIN_LEFT .100
-        call    PLED_standard_color
-
-        STRCPY  "add:"
-        output_8
-        STRCAT_PRINT "'"
-        return
-
-PLED_decoplan_0:
-        ;---- Plan not finished to compute ? ---------------------------------
-	    decf	decoplan_index,W
-	    movf 	PLUSW0,W                ; array_decodepth[index-1]
-	    subwf   decoplan_last,W         ; == last stop depth ?
-	    bz      PLED_decoplan_99
-        
-        WIN_LEFT .100
-        call    PLED_standard_color
-        STRCPY_PRINT "..."
-
-PLED_decoplan_99:
-        return
-
 ;-----------------------------------------------------------------------------
 PLED_gas_list:
 	ostc_debug	'm'		; Sends debug-information to screen if debugmode active
@@ -2816,8 +2714,8 @@
 	return
 
 PLED_const_ppO2_value:
-	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
-	return								; Yes, No update and return!
+;	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
+;	return								; Yes, No update and return!
 
 	ostc_debug	'j'		; Sends debug-information to screen if debugmode active
 	
@@ -2973,8 +2871,8 @@
 	return
 
 PLED_display_cns:
-	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
-	return								; Yes, No update and return!
+;	btfsc	multi_gf_display			; Is the Multi-GF Table displayed?
+;	return								; Yes, No update and return!
 
 	btfsc	gauge_mode			; Do not display in gauge mode
 	 return
--- a/code_part1/OSTC_code_asm_part1/simulator.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/simulator.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -170,8 +170,9 @@
         call    PLED_standard_color
         
         STRCPY  "TTS: "
+        bsf		leftbind
+        output_16
         bcf		leftbind
-        output_16
         STRCAT_PRINT    "'"		
 simulator_decoplan_notts:
 
@@ -209,21 +210,17 @@
 	bra		simulator_show_decoplan2
 
 simulator_show_decoplan5:
-	btfsc	multi_gf_display			; Next Page in Multi-GF Screen?
-	bra		simulator_show_decoplan5_1	; Yes!
-simulator_show_decoplan5_0:
-
-	bcf		display_see_deco			; clear flag
-	bra		simulator_show_decoplan4	; Quit
-
-simulator_show_decoplan5_1:
 	incf	decoplan_page,F
 	btfsc	last_ceiling_gf_shown		; last ceiling shown?
 	bra		simulator_show_decoplan5_0	; All done, clear and return
 
-	call	PLED_decoplan_gf        	; Re-Draw Current page of GF Decoplan
+	call	PLED_decoplan               ; Re-Draw Current page of GF Decoplan
 	bra		simulator_show_decoplan1	
 
+simulator_show_decoplan5_0:
+	bcf		display_see_deco			; clear flag
+	bra		simulator_show_decoplan4	; Quit
+
 simulator_show_decoplan4:
 	movlw	d'5'
 	movwf	menupos
@@ -264,7 +261,7 @@
 	WIN_INVERT	.0
 
 simulator_calc_deco_loop1:
-	call	divemode_check_decogases			; Checks for decogases and sets the gases
+	call	divemode_check_decogases        ; Checks for decogases and sets the gases
 	call	divemode_prepare_flags_for_deco
 
 	call	deco_calc_hauptroutine		    ; calc_tissue
@@ -277,7 +274,7 @@
 	movlw	d'1'
 	movff	WREG,char_I_step_is_1min		; 1 minute mode
 
-	movlw	d'255'
+	movlw	d'2'
 	movff	WREG,char_O_deco_status			; Reset Deco module
 
 simulator_calc_deco_loop2:
@@ -299,7 +296,7 @@
 	movlw	d'0'
 	movff	WREG,char_I_step_is_1min		; 2 second deco mode
 
-	movlw	d'255'
+	movlw	d'2'
 	movff	WREG,char_O_deco_status			; Reset Deco module
 
 	bra		simulator_calc_deco2				; Not finished
--- a/code_part1/OSTC_code_asm_part1/start.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/start.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -149,14 +149,20 @@
 	clrf	flag14
 	clrf	flag15
 
-	bsf		flag1,0                 ; Should we set win_flip_screen ?
+    ; Should we set win_flip_screen ?
+	bsf		flag1,0                 ; Precondition to yes
 	clrf	EEADRH					; Reset EEADRH
 	read_int_eeprom	d'1'
 	movlw	.7
-	cpfsgt	EEDATA					; >2048?
+	cpfsgt	EEDATA					; serial > 2048 (Mk2n hardware) ?
 	bcf		flag1,0
+	incf    EEDATA,W                ; serial == 65535 (emulation) ?
+	btfsc   STATUS,Z
+	bcf     flag1,0
 	movff	flag1,win_flags			; store in Bank0 register
 	clrf	flag1					; Clear flag1 (again)
+	
+	; Should we disable sleep (hardware emulator)
 	movlw	.0
 	cpfsgt	EEDATA					; >256
 	bsf		nsm						; NO-SLEEP-MODE : for hardware debugging
--- a/code_part1/OSTC_code_asm_part1/text_table.asm	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_asm_part1/text_table.asm	Wed Jan 26 19:19:02 2011 +0100
@@ -591,7 +591,7 @@
 	DA	"Show Stopwatch }"		;173
 	DA	"ShowTissueGraph}"		;174
 	DA	"Show Lead.Tiss.}"		;175
-	DA	"not used       }"		;176
+	DA	"Shalow stop 1st}"		;176
 	DA	"not used       }"		;177
 	DA	"not used       }"		;178
 	DA	"not used       }"		;179
@@ -628,7 +628,7 @@
 	DA	"time and Desat.-   }"	;205		l=20		
 	DA	"time at all!       }"	;206		l=20	
 ; Const.ppO2 description
-	DA	"Decotype:ZH-L16 CC }"	;207		l=20
+	DA	"Decotype: ZH-L16 CC}"	;207		l=20
 	DA	"For (Semi-)Closed  }"	;208		l=20
 	DA	"Circuit rebreathers}"	;209		l=20
 	DA	"Configure the 3    }"	;210		l=20
--- a/code_part1/OSTC_code_c_part2/p2_deco.c	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_c_part2/p2_deco.c	Wed Jan 26 19:19:02 2011 +0100
@@ -65,11 +65,11 @@
 // 12/25/10 v110: split in three files (deco.c, main.c, definitions.h)
 // 2011/01/20: [jDG] Create a common file included in ASM and C code.
 // 2011/01/23: [jDG] Added read_custom_function().
-//  + Make int_O_ascenttime an int.
+// 2011/01/24: [jDG] Make ascenttime an int. No more overflow!
+// 2011/01/25: [jDG] Fusion deco array for both models.
+// 2011/01/25: [jDG] Use CF(54) to reverse deco order.
 //
 // TODO:
-//  + Fusion deco array for both models.
-//  + Allow (CF) revesring stop order (while copying).
 //  + Allow (CF) delay for gas switch while predicting ascent.
 //  + Allow to abort MD2 calculation (have to restart next time).
 //
@@ -103,8 +103,8 @@
 static void clear_tissue(void);
 static void calc_ascenttime(void);
 static void update_startvalues(void);
-static void clear_decoarray(void);
-static void update_decoarray(void);
+static void clear_deco_table(void);
+static void update_deco_table(void);
 static void sim_tissue_1min(void);
 static void sim_tissue_10min(void);
 static void calc_gradient_factor(void);
@@ -113,12 +113,9 @@
 static void calc_hauptroutine_data_input(void);
 static void calc_hauptroutine_update_tissues(void);
 static void calc_hauptroutine_calc_deco(void);
-static void calc_hauptroutine_calc_ascend_to_deco(void);
+static void sim_ascent_to_first_stop(void);
 
 static void calc_nextdecodepth_GF(void);
-static void copy_deco_table_GF(void);
-static void clear_internal_deco_table_GF(void);
-static void update_internal_deco_table_GF(void);
 
 // ***********************************************
 // ** V A R I A B L E S   D E F I N I T I O N S **
@@ -149,19 +146,16 @@
 static unsigned char	temp_depth_GF_low_meter;
 static unsigned char	internal_deco_pointer;
 
-static unsigned char	internal_deco_table[32];
-
-static char output[32];                 // used by the math routines
+static unsigned char	internal_deco_time[32];
+static unsigned char	internal_deco_depth[32];
 
 static float cns_vault;
-
 static float pres_tissue_vault[32];
 
 //---- Bank 5 parameters -----------------------------------------------------
 #pragma udata bank5=0x500
 
 static unsigned char	ci;
-static unsigned int 	int_temp_decostatus;
 static float 			pres_respiration;
 static float			pres_surface;
 static float			temp1;
@@ -618,7 +612,7 @@
 
 	char_I_table_deco_done[0] = 0; // safety if changed somewhere else. Needed for exit
 	
-	//---- ZH-L16 + Gradient factor model ------------------------------------
+	//---- ZH-L16 + GRADIENT FACTOR model ------------------------------------
 	if (char_I_deco_model == 1)
 	{
         overlay float next_stop;            // Next stop to test, in Bar.
@@ -659,8 +653,6 @@
 			internal_deco_pointer = temp_depth_GF_low_number;
 			GF_temp = GF_high - ((float)internal_deco_pointer * GF_step);
 			int_temp = char_I_table_deco_done[internal_deco_pointer];
-			output[8] = int_temp;
-			output[9] = 33;
 		}
 		else
 		{
@@ -707,14 +699,6 @@
 				temp_depth_limit = temp_depth_last_deco;
 			else
 				temp_depth_limit = 3 * internal_deco_pointer;
-			if (output[9] == 33)
-			{
-				output[9] = internal_deco_pointer;
-				output[10] = char_I_table_deco_done[internal_deco_pointer];
-				output[12] = output[12] + 1;
-				if (output[12] == 100)
-					output[12] = 0;
-			}
 		}
 		else	// 	if (char_I_deco_model == 1)
 		{
@@ -753,48 +737,53 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
-// copy_deco_table_GF
+// copy_deco_table
 //
-// new in v.102
+// Buffer the stops, once computed, so we can continue to display them
+// while computing the next set.
 //
-static void copy_deco_table_GF(void)
+static void copy_deco_table(void)
 {
-    overlay unsigned char x;
+    // Copy depth of the first (deepest) stop, because when reversing
+    // order, it will be hard to find...    
+    char_O_first_deco_depth = internal_deco_depth[0];
+    char_O_first_deco_time  = internal_deco_time [0];
+
+    if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------
+    {
+        overlay unsigned char x, y;
+
+        //---- First: search the first non-null depth
+        for(x=31; x != 0; --x)
+            if( internal_deco_depth[x] != 0 ) break;
 
-	if( char_I_deco_model == 1 )
-	{
-		for(x=0; x<32; x++)
-			char_O_deco_table[x] = internal_deco_table[x];
-	}
-}
+        //---- Second: copy to output table (in reverse order)
+        for(y=0; y<32; y++, --x)
+        {
+            char_O_deco_depth[y] = internal_deco_depth[x];
+            char_O_deco_time [y] = internal_deco_time [x];
+
+            // Stop only once the last transfer is done.
+            if( x == 0 ) break;
+        }
 
-//////////////////////////////////////////////////////////////////////////////
-// clear_internal_deco_table_GF
-//
-// new in v.102
-//
-static void clear_internal_deco_table_GF(void)
-{
-	if (char_I_deco_model == 1)
-	{
+        //---- Third: fill table end with null
+        for(y++; y<32; y++)
+        {
+            char_O_deco_time [y] = 0;
+            char_O_deco_depth[y] = 0;
+        }
+    }
+    else //---- Straight copy ------------------------------------------------
+    {
         overlay unsigned char x;
 
-		for(x=0;x<32;x++)  // cycle through the 16 tissues for N2 and He
-			internal_deco_table[x] = 0;
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// update_internal_deco_table_GF
-//
-// new in v.102
-//
-// Add one minute to the current stop (if lower than 255).
-//
-static void update_internal_deco_table_GF(void)
-{
-	if ((char_I_deco_model == 1) && (internal_deco_table[internal_deco_pointer] < 255))
-		internal_deco_table[internal_deco_pointer]++;
+        for(x=0; x<32; x++)
+        {
+            char_O_deco_depth[x] = internal_deco_depth[x];
+            char_O_deco_time [x] = internal_deco_time [x];
+        }
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -851,7 +840,13 @@
 #endif
 
 //////////////////////////////////////////////////////////////////////////////
-
+// Called every 2 seconds during diving.
+// update tissues every time.
+// Every 6 seconds (or slower when TTS > 16):
+//    - update deco table (char_O_deco_time/depth) with new values.
+//    - update ascent time,
+//    - set status to zero (so we can check there is new results).
+//
 void deco_calc_hauptroutine(void)
 {
     RESET_C_STACK
@@ -932,7 +927,7 @@
         (pres_tissue+16)[ci] = 0.0;
     } // for 0 to 16
 
-    clear_decoarray();
+    clear_deco_table();
     char_O_deco_status = 0;
     char_O_nullzeit = 0;
     int_O_ascenttime = 0;
@@ -960,7 +955,7 @@
     
     calc_tissue_2_secs();  // update the pressure in the 32 tissues in accordance with the new ambient pressure
     
-    clear_decoarray();
+    clear_deco_table();
     char_O_deco_status = 0;
     char_O_nullzeit = 0;
     int_O_ascenttime = 0;
@@ -999,41 +994,29 @@
     	update_startvalues();
     	calc_nullzeit();
     	check_ndl();
-    	char_O_deco_status = 255; // calc deco next time
+    	char_O_deco_status = 2; // calc ascent next time.
     	break;
-    
-    case 1: //---- ???? ------------------------------------------------------
-    	char_O_deco_status = 0;
+
+    case 1: //---- Simulate stops --------------------------------------------
     	calc_hauptroutine_calc_deco();
     	break;
-    
-    case 3: //---- new dive --------------------------------------------------
-    	clear_decoarray();
-    	clear_internal_deco_table_GF();
-    	copy_deco_table_GF();
+
+    case 3: //---- At surface: start a new dive ------------------------------
+    	clear_deco_table();
+    	copy_deco_table();
     	internal_deco_pointer = 0;
     	lock_GF_depth_list = 0;
     	update_startvalues();
     	calc_nextdecodepth_GF();
-    	char_O_deco_status = 0;
+    	char_O_deco_status = 0; // Calc nullzeit next time.
     	break;
-    
-    default: //---- Continue stops calculation -------------------------------
-    	update_startvalues();
-    	clear_decoarray();
-    	clear_internal_deco_table_GF();
-    	output[6] = 1;
-    	calc_hauptroutine_calc_ascend_to_deco();
-    	
-    	// can't go up to first deco, too deep to calculate in the given time slot
-        if (char_O_deco_status > 15)		
-    		char_O_deco_status = 2;
-        else
-    		calc_hauptroutine_calc_deco();
+
+    case 2: //---- Simulate ascent to first stop -----------------------------
+    	sim_ascent_to_first_stop();
+    	char_O_deco_status = 1;     // Cacl stops next time.
     	break;
 	}
 
-	calc_ascenttime();
 	check_post_dbg();
 }
 
@@ -1181,186 +1164,202 @@
  	}
 	else
 	{
-	temp1 = temp_surface;
+        temp1 = temp_surface;
 	}
 	if (pres_gtissue_limit > temp1 && char_O_deco_status == 0)  // if guiding tissue can not be exposed to surface pressure immediately
  	{
-  		char_O_nullzeit = 0; // deco necessary
-  		char_O_deco_status = 255; // calculate deco skip nullzeit calculation
+  		char_O_nullzeit = 0;    // deco necessary
+  		char_O_deco_status = 2; // calculate ascent on next iteration.
  	}
 } 		// calc_hauptroutine_update_tissues
 
 //////////////////////////////////////////////////////////////////////////////
-
+// Compute stops.
+// 
+// Note: because this can be very long, break on 16 iterations, and set state
+//       to 0 when finished, or to 1 when needing to continue.
+//
 void calc_hauptroutine_calc_deco(void)
 {
- 	do
+    overlay unsigned char loop;
+
+ 	for(loop = 0; loop < 16; ++loop)
   	{
-  		int_temp_decostatus = 0;
   		calc_nextdecodepth_GF();
-  		if (temp_depth_limit > 0)
-   		{
-  			calc_N2_ratio = N2_ratio;
-			calc_He_ratio = He_ratio;
 
-			if (char_I_const_ppO2 == 0)																// new in v.101
-	 		{
-     			deco_diluent = temp_deco;																// new in v.101
+        //---- Finish computations once surface is reached -------------------
+        if( temp_depth_limit <= 0 )
+      	{
+    		copy_deco_table();
+        	calc_ascenttime();
+    		char_O_deco_status = 0; // calc nullzeit next time.
+    		return;
+      	}
+
+        //---- Else, continue simulating the stops ---------------------------
+        calc_N2_ratio = N2_ratio;
+        calc_He_ratio = He_ratio;
+        
+        if (char_I_const_ppO2 == 0)
+        {
+        	deco_diluent = temp_deco;
 
-  				if(deco_gas_change1 && (temp_deco < deco_gas_change1))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio1;
-	 				calc_He_ratio = deco_He_ratio1;
-	 			}
-  				if(deco_gas_change2 && (temp_deco < deco_gas_change2))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio2;
-	 				calc_He_ratio = deco_He_ratio2;
-	 			}
-  				if(deco_gas_change3 && (temp_deco < deco_gas_change3))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio3;
-	 				calc_He_ratio = deco_He_ratio3;
-	 			}
-  				if(deco_gas_change4 && (temp_deco < deco_gas_change4))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio4;
-	 				calc_He_ratio = deco_He_ratio4;
-	 			}
-  				if(deco_gas_change5 && (temp_deco < deco_gas_change5))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio5;
-	 				calc_He_ratio = deco_He_ratio5;
-	 			}
-	 		}
-    		else																					// new in v.101
-	 		{
-	 			if (temp_deco > deco_ppO2_change)
-				{
-      				deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio));			// new in v.101
-				}
-	 			else
-				{
-      				deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio));			// new in v.101
-				}
-	 		}
-    		if (deco_diluent > temp_deco)															// new in v.101
-     			deco_diluent = temp_deco;																// new in v.101
- 			if (deco_diluent > 0.0627)																// new in v.101
+    		if(deco_gas_change1 && (temp_deco < deco_gas_change1))
+    		{
+        		calc_N2_ratio = deco_N2_ratio1;
+        		calc_He_ratio = deco_He_ratio1;
+        	}
+    		if(deco_gas_change2 && (temp_deco < deco_gas_change2))
+    		{
+        		calc_N2_ratio = deco_N2_ratio2;
+        		calc_He_ratio = deco_He_ratio2;
+        	}
+    		if(deco_gas_change3 && (temp_deco < deco_gas_change3))
+    		{
+        		calc_N2_ratio = deco_N2_ratio3;
+        		calc_He_ratio = deco_He_ratio3;
+        	}
+    		if(deco_gas_change4 && (temp_deco < deco_gas_change4))
+    		{
+        		calc_N2_ratio = deco_N2_ratio4;
+        		calc_He_ratio = deco_He_ratio4;
+        	}
+    		if(deco_gas_change5 && (temp_deco < deco_gas_change5))
     		{
-     			temp_atem = calc_N2_ratio * (deco_diluent - 0.0627);										// changed in v.101
-				temp2_atem = calc_He_ratio * (deco_diluent - 0.0627);										// changed in v.101
-    		}
-    		else																					// new in v.101
-    		{
-     			temp_atem = 0.0;																		// new in v.101
-     			temp2_atem = 0.0;																		// new in v.101
-    		}
-   			sim_tissue_1min();
-			update_internal_deco_table_GF();
-   			update_decoarray();
-   			char_O_deco_status = char_O_deco_status + 1;
-   			if (char_O_deco_status < 16)
-     			int_temp_decostatus = 1;
-   		}
-  		else // if (temp_depth_limit > 0)
-		{
-   		    char_O_deco_status = 0;
-		}
-	} while (int_temp_decostatus == 1);
+        		calc_N2_ratio = deco_N2_ratio5;
+        		calc_He_ratio = deco_He_ratio5;
+        	}
+        }
+        else
+       	{
+       		if (temp_deco > deco_ppO2_change)
+        	{
+                deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio));
+        	}
+       		else
+        	{
+                deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio));
+        	}
+      	}
 
-	if (char_O_deco_status > 15)
-	{
-   		char_O_deco_status = 1;
+        if (deco_diluent > temp_deco)															// new in v.101
+        	deco_diluent = temp_deco;																// new in v.101
+
+        if (deco_diluent > 0.0627)																// new in v.101
+        {
+            temp_atem = calc_N2_ratio * (deco_diluent - 0.0627);										// changed in v.101
+            temp2_atem = calc_He_ratio * (deco_diluent - 0.0627);										// changed in v.101
+        }
+        else																					// new in v.101
+        {
+            temp_atem = 0.0;																		// new in v.101
+            temp2_atem = 0.0;																		// new in v.101
+        }
+
+        sim_tissue_1min();          // Simulate compartiments for 1 minute.
+        update_deco_table();        // Add one minute stops.
 	}
-  	else
-  	{
-		copy_deco_table_GF();
-		char_O_deco_status = 0;
-  	}
+
+	// Surface not reached, need more stops...
+    char_O_deco_status = 1; // calc more stops next time.
 }
 
 //////////////////////////////////////////////////////////////////////////////
-
-void calc_hauptroutine_calc_ascend_to_deco(void)
+// Simulation ascention to first deco stop.
+//
+// Note: because we ascent with a constant speed (10m/mn, ie. 1bar/mn),
+//       there is no need to break on more that 16 iterations
+//       (or we are already in deep shit).
+//
+void sim_ascent_to_first_stop(void)
 {
  	update_startvalues();
- 	char_O_deco_status = 0;
+    clear_deco_table();
+
    	temp_deco = pres_respiration;
- 	lock_GF_depth_list = 1; 																// new in v.102
- 	do								// go up to first deco
+ 	lock_GF_depth_list = 1;
+
+    // Loop until first top or surface is reached.
+ 	for(;;)
   	{
-  		int_temp_decostatus = 0;
-  		temp_deco = temp_deco - 1.0;
-  		if ( char_I_deco_model == 1)																// new in v.102 , 4 = deep stops
+  		temp_deco = temp_deco - 1.0;    // Ascent 1 min, at 10m/min. == 1bar/min.
+
+  		if ( char_I_deco_model == 1)
 			temp_limit = temp_pres_gtissue_limit_GF_low;
   		else
 			temp_limit = temp_pres_gtissue_limit;
-  		if ((temp_deco > temp_limit) && (temp_deco > pres_surface)) 								// changes in v.102
-   		{
-   			lock_GF_depth_list = 0; 																	// new in v.102, distance to first stop > 10 mtr.
-			output[6] = 0;
-	 		temp_deco += 0.5;
 
-	 		calc_N2_ratio = N2_ratio;
-			calc_He_ratio = He_ratio;
+        // Did we hit the first stop ?
+        if( temp_deco <= temp_limit )
+            break;
+        
+        // Or the surface ?
+        if( temp_deco <= pres_surface )
+            break;
+        
+		lock_GF_depth_list = 0;
+ 		temp_deco += 0.5;           // Check gas change 5 meter below new depth.
 
-			if (char_I_const_ppO2 == 0)																// new in v.101 // calculate at half of the ascent
-			{
-    			deco_diluent = temp_deco;															// new in v.101
+        //---- Simulat gas switches, at half the ascent
+ 		calc_N2_ratio = N2_ratio;
+		calc_He_ratio = He_ratio;
+
+		if (char_I_const_ppO2 == 0)
+		{
+			deco_diluent = temp_deco;
 
-  				if(deco_gas_change1 && (temp_deco < deco_gas_change1))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio1;
-	 				calc_He_ratio = deco_He_ratio1;
-	 			}
-  				if(deco_gas_change2 && (temp_deco < deco_gas_change2))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio2;
-	 				calc_He_ratio = deco_He_ratio2;
-	 			}
-  				if(deco_gas_change3 && (temp_deco < deco_gas_change3))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio3;
-	 				calc_He_ratio = deco_He_ratio3;
-	 			}
-  				if(deco_gas_change4 && (temp_deco < deco_gas_change4))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio4;
-	 				calc_He_ratio = deco_He_ratio4;
-	 			}
-  				if(deco_gas_change5 && (temp_deco < deco_gas_change5))
- 	 			{
-	 				calc_N2_ratio = deco_N2_ratio5;
-	 				calc_He_ratio = deco_He_ratio5;
-	 			}
-			}
-   			else																						// new in v.101
-			{
-				if (temp_deco > deco_ppO2_change)
- 					deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio));	// new in v.101 // calculate at half of the ascent
-				else
- 					deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio));	// new in v.101 // calculate at half of the ascent
-				if (deco_diluent > (temp_deco))															// new in v.101
- 					deco_diluent = temp_deco;															// new in v.101 // calculate at half of the ascent
-			}
-	 		temp_deco -= 0.5;
-   			if (deco_diluent > 0.0627)																// new in v.101
-    		{
-    			temp_atem = calc_N2_ratio * (deco_diluent - 0.0627);											// changed in v.101
-    			temp2_atem = calc_He_ratio * (deco_diluent - 0.0627);										// changed in v.101
-    		}
-   			else																						// new in v.101
-    		{
-    			temp_atem = 0.0;																		// new in v.101
-    			temp2_atem = 0.0;																		// new in v.101
-    		}
-   			sim_tissue_1min();
-   			char_O_deco_status = char_O_deco_status + 1;
-   			if (char_O_deco_status < 16)  // 16 is the limit of calculations for one time slot
-    			int_temp_decostatus = 1;
-   		}
-	} while (int_temp_decostatus == 1);
+ 				if(deco_gas_change1 && (temp_deco < deco_gas_change1))
+	 			{
+ 				calc_N2_ratio = deco_N2_ratio1;
+ 				calc_He_ratio = deco_He_ratio1;
+ 			}
+ 				if(deco_gas_change2 && (temp_deco < deco_gas_change2))
+	 			{
+ 				calc_N2_ratio = deco_N2_ratio2;
+ 				calc_He_ratio = deco_He_ratio2;
+ 			}
+ 				if(deco_gas_change3 && (temp_deco < deco_gas_change3))
+	 			{
+ 				calc_N2_ratio = deco_N2_ratio3;
+ 				calc_He_ratio = deco_He_ratio3;
+ 			}
+ 				if(deco_gas_change4 && (temp_deco < deco_gas_change4))
+	 			{
+ 				calc_N2_ratio = deco_N2_ratio4;
+ 				calc_He_ratio = deco_He_ratio4;
+ 			}
+ 				if(deco_gas_change5 && (temp_deco < deco_gas_change5))
+	 			{
+ 				calc_N2_ratio = deco_N2_ratio5;
+ 				calc_He_ratio = deco_He_ratio5;
+ 			}
+		}
+		else
+		{
+			if( temp_deco > deco_ppO2_change )
+					deco_diluent = (temp_deco - const_ppO2)/(N2_ratio + He_ratio);  // calculate at half of the ascent
+			else
+					deco_diluent = (temp_deco - deco_ppO2)/(N2_ratio + He_ratio);   // calculate at half of the ascent
+			if( deco_diluent > temp_deco )
+					deco_diluent = temp_deco;
+		}
+		
+ 		temp_deco -= 0.5;   // Back to new depth.
+
+		if (deco_diluent > 0.0627)
+		{
+			temp_atem = calc_N2_ratio * (deco_diluent - 0.0627);
+			temp2_atem = calc_He_ratio * (deco_diluent - 0.0627);
+		}
+		else
+		{
+			temp_atem = 0.0;
+			temp2_atem = 0.0;
+		}
+
+        // Then simulate with the new gas pressures...s
+		sim_tissue_1min();
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1438,7 +1437,7 @@
 	{
   		backup_sim_pres_tissue();
   		sim_tissue_10min();
-  		char_O_nullzeit = char_O_nullzeit + 10;
+  		char_O_nullzeit += 10;
 
 		if (char_I_deco_model == 1)
 			temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue;
@@ -1451,8 +1450,8 @@
  	if (loop == 255)
  	{
   		restore_sim_pres_tissue();
-  		char_O_nullzeit = char_O_nullzeit - 10;
- 	} //if loop == 255]
+  		char_O_nullzeit -= 10;
+ 	} //if loop == 255
 
  	if (char_O_nullzeit < 60)
  	{
@@ -1497,41 +1496,20 @@
 //////////////////////////////////////////////////////////////////////////////
 // calc_ascenttime
 //
-void calc_ascenttime(void)
+static void calc_ascenttime(void)
 {
     if (pres_respiration > pres_surface)
     {
-        switch (char_O_deco_status)
-        {
-        case 2:
-            int_O_ascenttime = -1;
-            break;
-        case 1:
-            break;
-        default:
-            {
-                // + 0.6 to count 1 minute ascent time from 4 meter to surface
-                overlay float ascent = pres_respiration - pres_surface + 0.6; 
-                if (ascent < 0.0)
-                    ascent = 0.0;
-                int_O_ascenttime = (unsigned int)ascent;
+        overlay unsigned char x;
 
-                if( char_I_deco_model == 0 ) //---- ZH-L16 model 
-                {
-                    overlay unsigned char x;
-                    for(x=0; x<7; x++)
-                        int_O_ascenttime += (unsigned int)char_O_array_decotime[x];
-                }
-                else //---------------------------- ZH-L16-GF model
-                {
-                    overlay unsigned char x;
-                    for(x=0; x<32; x++)
-                        int_O_ascenttime += (unsigned int)internal_deco_table[x];
-                }
+        // + 0.6 to count 1 minute ascent time from 4 meter to surface
+        overlay float ascent = pres_respiration - pres_surface + 0.6; 
+        if (ascent < 0.0)
+            ascent = 0.0;
+        int_O_ascenttime = (unsigned int)ascent;
 
-                break;
-            }
-        }
+        for(x=0; x<32 && internal_deco_depth[x]; x++)
+            int_O_ascenttime += (unsigned int)internal_deco_time[x];
     }
     else
         int_O_ascenttime = 0;
@@ -1558,7 +1536,7 @@
   	for (x = 0;x<16;x++)
   	{
    		sim_pres_tissue[x] = pres_tissue[x];
-   		sim_pres_tissue[x+16] = pres_tissue[x+16];
+   		(sim_pres_tissue+16)[x] = (pres_tissue+16)[x];
    		sim_pres_tissue_limit[x] = pres_tissue_limit[x];
   	}
 }
@@ -1632,70 +1610,66 @@
 }
         
 //////////////////////////////////////////////////////////////////////////////
-// clear_decoarray
-//
-// unchanged in v.101
-//
-static void clear_decoarray(void)
-{
-    overlay unsigned char x;
-
-    for(x=0; x<6; ++x)
-    {
-        char_O_array_decodepth[x] = 0;
-        char_O_array_decotime [x] = 0;
-    }
-    char_O_array_decotime[6] = 0;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// update_decoarray
+// clear_deco_table
 //
 // unchanged in v.101
 //
-static void update_decoarray()
+static void clear_deco_table(void)
 {
-    overlay int stop_time;
-	overlay unsigned char x = 0;
-	do
+    overlay unsigned char x;
+
+    for(x=0; x<32; ++x)
+    {
+        internal_deco_time [x] = 0;
+        internal_deco_depth[x] = 0;
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// update_deco_table
+//
+// Add 1 min to current stop.
+//
+// Inputs:
+//      temp_depth_limit = stop's depth, in meters.
+// In/Out:
+//      internal_deco_depth[] : depth (in meters) of each stops.
+//      internal_deco_time [] : time (in minutes) of each stops.
+//
+static void update_deco_table()
+{
+	overlay unsigned char x;
+
+	if( temp_depth_limit > 255 ) // Can't store stops at more than 255m.
+	    temp_depth_limit = 255;
+
+	for(x=0; x<32; ++x)
 	{
-		if (char_O_array_decodepth[x] == temp_depth_limit)
-		{
-			stop_time = char_O_array_decotime[x] + 1;
-			if (stop_time < 0)
-				stop_time = 0;
-			if (stop_time > 240)
-				stop_time = 240;
- 			char_O_array_decotime[x] = stop_time;
-			x = 10; // exit
-		} // if
-		else
- 		{
- 			if (char_O_array_decodepth[x] == 0)
-  			{
-  				if (temp_depth_limit > 255)
-   					char_O_array_decodepth[x] = 255;
-  				else
-   					char_O_array_decodepth[x] = (char)temp_depth_limit;
-  				stop_time = char_O_array_decotime[x] + 1;
-  				if (stop_time > 240)
-   					char_O_array_decotime[x] = 240;
-  				else
-   					char_O_array_decotime[x] = (char)stop_time;
-  				x = 10; // exit
-  			} // if
- 			else
-  				x++;
- 		} // else
-	} while (x<6);
-	if (x == 6)
- 	{
- 		stop_time = char_O_array_decotime[6] + 1;
- 		if (stop_time > 220)
-  			char_O_array_decotime[6] = 220;
- 		else
-  			char_O_array_decotime[6] = (char)stop_time;
- 	} // if x == 6
+    	// Did we found the right stop ?
+    	if( internal_deco_depth[x] == temp_depth_limit )
+    	{
+        	// Increment stop time, but do test overflow:
+        	overlay int stop_time = 1 + (int)internal_deco_time[x];
+        	if( stop_time > 255 )
+        	    stop_time = 255;
+            internal_deco_time[x] = stop_time;
+            
+            // Done !
+            return;
+        }
+        
+        if( internal_deco_depth[x] == 0 )
+        {
+            // Found a free position: initialise it.
+            internal_deco_depth[x] = (unsigned char)temp_depth_limit;
+            internal_deco_time[x]  = 1;
+            return;
+        }
+    }
+
+    // Here, there is no space left for stops. 
+    // Ie. the first one starts at 3m*32 positions = 96m...
+    // Just do nothing with that...
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1880,7 +1854,7 @@
     
     calc_tissue_1_min();  // update the pressure in the 32 tissues in accordance with the new ambient pressure
     
-    clear_decoarray();
+    clear_deco_table();
     char_O_deco_status = 0;
     char_O_nullzeit = 0;
     int_O_ascenttime = 0;
Binary file code_part1/OSTC_code_c_part2/p2_deco.o has changed
--- a/code_part1/OSTC_code_c_part2/shared_definitions.h	Tue Jan 25 01:02:35 2011 +0100
+++ b/code_part1/OSTC_code_c_part2/shared_definitions.h	Wed Jan 26 19:19:02 2011 +0100
@@ -94,10 +94,11 @@
 VAR_UCHAR (char_O_CNS_fraction);           // new in v.101
 VAR_UCHAR (char_O_relative_gradient_GF);   // new in v.102
 
-TAB_UCHAR (char_O_array_decotime, 7);      // Old-school decompression table (ZH-L16)
-TAB_UCHAR (char_O_array_decodepth, 6);     // 
+VAR_UCHAR (char_O_first_deco_depth);        // Depth of first stop.
+VAR_UCHAR (char_O_first_deco_time) ;        // Duration of first stop.
+TAB_UCHAR (char_O_deco_depth, 0x20);        // Fusionned decompression table:
+TAB_UCHAR (char_O_deco_time,  0x20);        // Both ZH-L16 and L16-GF models.
 
-TAB_UCHAR (char_O_deco_table, 0x20);        // New school decompression table (GF mode)
 TAB_UCHAR (char_O_tissue_saturation, 0x20); // Compartiment desaturation time, in min.
 
 VAR_UINT  (int_O_DBS_bitfield);