changeset 344:797e2ac42d24 ScreenDump

MERGE with 1.91 main trunk.
author JeanDo
date Sat, 21 May 2011 14:48:07 +0200
parents 6bdf80d7276c (current diff) d5240792be51 (diff)
children 8bb7c901743d
files code_part1/OSTC_code_asm_part1/MAIN.ASM code_part1/OSTC_code_asm_part1/altimeter.asm code_part1/OSTC_code_asm_part1/definitions.asm code_part1/OSTC_code_asm_part1/divemode.asm code_part1/OSTC_code_asm_part1/isr.asm code_part1/OSTC_code_asm_part1/simulator.asm code_part1/OSTC_code_asm_part1/start.asm code_part1/OSTC_code_asm_part1/surfmode.asm
diffstat 19 files changed, 506 insertions(+), 546 deletions(-) [+]
line wrap: on
line diff
--- a/code_part1/OSTC_code_asm_part1/MAIN.ASM	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/MAIN.ASM	Sat May 21 14:48:07 2011 +0200
@@ -82,6 +82,7 @@
 osct_asm	code
 #include    strings.inc
 
+#include	isr.asm				; Interrupt service routine (RTC&Sensor)
 #include	displaytext.asm		; sends texts to wordprocessor
 #include	math.asm			; mathematical functions
 #include 	wait.asm			; waitroutines
@@ -103,7 +104,6 @@
 #include	menu_ppO2.asm		; Constant ppO2 setup menu
 #include 	menu_battery.asm	; Submenu "Battery Info"
 #include	menu_gassetup.asm	; Menu "Gas Setup"
-#include	isr.asm				; Interrupt service routine (RTC&Sensor)
 #include	surfmode.asm		; Mainroutines for Surfacemode
 #include	divemode.asm		; Mainroutines for Divemode
 #include	divemode_menu.asm	; Underwater menu
--- a/code_part1/OSTC_code_asm_part1/adc_rtc.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/adc_rtc.asm	Sat May 21 14:48:07 2011 +0200
@@ -72,9 +72,9 @@
 	movwf	fatal_error_code		; Battery very low!
 	bsf		enter_error_sleep		; enter error routine
 
-get_battery_voltage3:	
-	movff	amb_pressure+0,sub_b+0	
-	movff	amb_pressure+1,sub_b+1
+get_battery_voltage3:
+    SAFE_2BYTE_COPY amb_pressure, sub_b
+
 	movlw	LOW		d'15001'			; must be lower then 15001mBar
 	movwf	sub_a+0
 	movlw	HIGH	d'15001'
@@ -136,9 +136,10 @@
 	write_int_eeprom	d'43'
 	movff	year,EEDATA
 	write_int_eeprom	d'44'
-	movff	temperature+0,EEDATA
+    SAFE_2BYTE_COPY temperature,lo
+	movff	lo,EEDATA
 	write_int_eeprom	d'45'
-	movff	temperature+1,EEDATA
+	movff	hi,EEDATA
 	write_int_eeprom	d'46'
 	; Reset charge statistics
 	clrf	EEDATA
@@ -150,9 +151,10 @@
 	write_int_eeprom	d'52'		; total complete cycles
 	write_int_eeprom	d'53'		; total complete cycles
 	; Reset temperature extremas
-	movff	temperature+0,EEDATA	; Reset mimimum extrema
+    SAFE_2BYTE_COPY temperature,lo
+	movff	lo,EEDATA	; Reset mimimum extrema
 	write_int_eeprom	d'54'
-	movff	temperature+1,EEDATA
+	movff	hi,EEDATA
 	write_int_eeprom	d'55'
 	movff	month,EEDATA
 	write_int_eeprom	d'56'
@@ -160,9 +162,9 @@
 	write_int_eeprom	d'57'
 	movff	year,EEDATA
 	write_int_eeprom	d'58'
-	movff	temperature+0,EEDATA	; Reset maximum extrema
+	movff	lo,EEDATA	; Reset maximum extrema
 	write_int_eeprom	d'59'
-	movff	temperature+1,EEDATA
+	movff   hi,EEDATA
 	write_int_eeprom	d'60'
 	movff	month,EEDATA
 	write_int_eeprom	d'61'
@@ -192,9 +194,10 @@
 	write_int_eeprom	d'43'
 	movff	year,EEDATA
 	write_int_eeprom	d'44'
-	movff	temperature+0,EEDATA
+    SAFE_2BYTE_COPY temperature,lo
+	movff	lo,EEDATA
 	write_int_eeprom	d'45'
-	movff	temperature+1,EEDATA
+	movff	hi,EEDATA
 	write_int_eeprom	d'46'
 	return
 
--- a/code_part1/OSTC_code_asm_part1/altimeter.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/altimeter.asm	Sat May 21 14:48:07 2011 +0200
@@ -55,8 +55,7 @@
         clrf    pressureSum+1
         clrf    pressureCount
 
-        movff   amb_pressure+0,pressureAvg+0    ; And init first average.
-        movff   amb_pressure+1,pressureAvg+1
+        SAFE_2BYTE_COPY amb_pressure, pressureAvg   ; And init first average.
 
         movlw   4                       ; And multiply AVG by 16 to be coherent.
 altimeter_reset_1:
@@ -73,9 +72,11 @@
 
 altimeter_1:
         ;---- Do a bank-safe 16bit summing -----------------------------------
-        movff   amb_pressure+0,WREG
+        SAFE_2BYTE_COPY amb_pressure, lo   ; And init first average.
+
+        movff   lo,WREG
         addwf   pressureSum+0,F
-        movff   amb_pressure+1,WREG
+        movff   hi,WREG
         addwfc  pressureSum+1,F
 
         incf    pressureCount           ; Increment count too.
--- a/code_part1/OSTC_code_asm_part1/definitions.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/definitions.asm	Sat May 21 14:48:07 2011 +0200
@@ -188,7 +188,6 @@
 ext_ee_temp2    res 1           ; External EEPROM Temp 2		used in I2C EEPROM
 
 isr1_temp       res 1           ; ISR temp variables
-isr3_temp       res 2
 
 timer1int_counter1  res 1       ;Timer 1 counter
 timer1int_counter2  res 1       ;Timer 1 counter
@@ -235,15 +234,16 @@
 OFF             res 2
 SENS            res 2
 
+amb_pressure_avg res 2          ; ambient pressure summing buffer[mBar]
 amb_pressure    res 2           ; ambient pressure [mBar]
 rel_pressure    res 2		    ; amb_pressure - surface pressure [mBar]
 max_pressure    res 2           ; Max. pressure for the dive [mBar]
 avr_rel_pressure res 2          ; Average rel. pressure (Average depth) for the dive [mBar], Resettable
 avr_rel_pressure_total res 2    ; Average rel. pressure (Average depth) for the dive [mBar], Non-Resettable
 last_pressure   res 2
+temperature_avg res 2           ; Temperature summing buffer.
 temperature     res 2
 last_temperature res 2
-temperature_temp res 2
 Dx              res 2
 
 last_surfpressure       res 2   ; Divemode
@@ -440,7 +440,7 @@
 #DEFINE	switch_left			flag6,3	;=1: left switch pressed
 #DEFINE	switch_right		flag6,4	;=1: right switch pressed
 #DEFINE	uart_settime		flag6,5	;=1: enter time sync routine
-#DEFINE	neg_temp			flag6,6	;=1: temperature below zero
+#DEFINE	FLAG_1              flag6,6	;=1: unused
 #DEFINE	twosecupdate		flag6,7	;=1: after any two seconds
 
 #DEFINE	dekostop_active			flag7,0	;=1: in deocompression mode
--- a/code_part1/OSTC_code_asm_part1/divemode.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/divemode.asm	Sat May 21 14:48:07 2011 +0200
@@ -416,8 +416,7 @@
 ;-----------------------------------------------------------------------------
 ; calculate ppO2 in 0.01Bar (e.g. 150 = 1.50 Bar ppO2)
 set_actual_ppo2:
-	movff		amb_pressure+0,xA+0     ; P_amb in milibar (1000 = 1.000 bar).
-	movff		amb_pressure+1,xA+1
+    SAFE_2BYTE_COPY amb_pressure, xA    ; P_amb in milibar (1000 = 1.000 bar).
 	movlw		d'10'
 	movwf		xB+0
 	clrf		xB+1
@@ -556,8 +555,8 @@
 ;-----------------------------------------------------------------------------
 
 divemode_prepare_flags_for_deco:
-	movff	amb_pressure+0,int_I_pres_respiration+0		; lo  and copy result to deco routine
-	movff	amb_pressure+1,int_I_pres_respiration+1		; hi
+    SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; copy result to deco routine
+
 	GETCUSTOM8	d'11'                           ; Saturation multiplier %
 	movff	WREG,char_I_saturation_multiplier
 	GETCUSTOM8	d'12'                           ; Desaturation multiplier %
@@ -593,9 +592,10 @@
 	incf_eeprom_address	d'47'				; Macro, that adds 8Bit to eeprom_address:2 with banking at 0x8000
 
 store_dive_data2:
-	movf	rel_pressure+0,W				; store depth with every sample
+    SAFE_2BYTE_COPY rel_pressure, lo
+	movf	lo,W				        ; store depth with every sample
 	call	write_external_eeprom
-	movf	rel_pressure+1,W
+	movf	hi,W
 	call	write_external_eeprom
 
 ;First, find out how many bytes will append to this sample....
@@ -810,9 +810,10 @@
 	return
 
 store_dive_temperature:
-	movf	temperature+0,W				; append temperature to current sample!
+    SAFE_2BYTE_COPY temperature,lo
+	movf	lo,W			            ; append temperature to current sample!
 	call	write_external_eeprom
-	movf	temperature+1,W
+	movf	hi,W
 	call	write_external_eeprom
 	GETCUSTOM8	d'21'
 	movwf	divisor_temperature			; Reload divisor from CF
@@ -823,12 +824,11 @@
 	bra		do_not_display_velocity			; display velocity only in divemode
 
 calc_velocity2:
-	movff	amb_pressure+0,sub_a+0
-	movff	amb_pressure+1,sub_a+1
+    SAFE_2BYTE_COPY amb_pressure, sub_a
 	movff	last_pressure+0,sub_b+0
 	movff	last_pressure+1,sub_b+1
-	movff	amb_pressure+0,last_pressure+0	; store old value for velocity
-	movff	amb_pressure+1,last_pressure+1
+	movff	sub_a+0,last_pressure+0	; store old value for velocity
+	movff	sub_a+1,last_pressure+1
 
 	call	sub16						; sub_c = amb_pressure - last_pressure
 
@@ -875,8 +875,7 @@
 	return
 
 check_ppO2_bail:						; In CC mode but bailout active!
-	movff		amb_pressure+0,xA+0
-	movff		amb_pressure+1,xA+1
+    SAFE_2BYTE_COPY amb_pressure, xA
 	movlw		d'10'
 	movwf		xB+0
 	clrf		xB+1
@@ -964,9 +963,8 @@
 ;
 check_gas_change:					; Checks if a better gas should be selected (by user)
 	bcf		better_gas_available	;=1: A better gas is available and a gas change is advised in divemode
-	
-	movff	rel_pressure+0,xA+0			
-	movff	rel_pressure+1,xA+1
+
+    SAFE_2BYTE_COPY rel_pressure,xA
 	movlw	d'100'
 	movwf	xB+0
 	clrf	xB+1
@@ -1444,21 +1442,23 @@
 	btfsc	divemode
 	call	set_min_temp				; store min. temp if required
 
-	bcf		temp_changed			; Display temperature?
-	movf	temperature+0,W
+	bcf		temp_changed			    ; Display temperature?
+    SAFE_2BYTE_COPY temperature,lo
+	movf	lo,W
 	cpfseq	last_temperature+0
-	bsf		temp_changed			; Yes
-	movf	temperature+1,W
+	bsf		temp_changed			    ; Yes
+	movf	hi,W
 	cpfseq	last_temperature+1
-	bsf		temp_changed			; Yes
+	bsf		temp_changed			    ; Yes
 	btfsc	temp_changed	
-	call	PLED_temp_divemode		; Displays temperature
+	call	PLED_temp_divemode		    ; Displays temperature
 
 	bcf		pres_changed			; Display new depth?
-	movf	amb_pressure+0,W
+    SAFE_2BYTE_COPY amb_pressure, lo
+	movf	lo,W
 	cpfseq	last_pressure+0
 	bsf		pres_changed			; Yes
-	movf	amb_pressure+1,W
+	movf	hi,W
 	cpfseq	last_pressure+1
 	bsf		pres_changed			; Yes
 
@@ -1481,32 +1481,30 @@
 set_max_depth:
 	movff	max_pressure+0,sub_a+0
 	movff	max_pressure+1,sub_a+1
-	movff	rel_pressure+0,sub_b+0
-	movff	rel_pressure+1,sub_b+1
-	call	sub16						; sub_c = sub_a - sub_b
+    SAFE_2BYTE_COPY rel_pressure, sub_b
+	call	sub16               ; sub_c = sub_a - sub_b
 								; max_pressure<rel_pressure -> neg_flag=1
 								; rel_pressure<=max_pressure -> neg_flag=0
 	btfss	neg_flag	
 	return
 								;max_pressure<rel_pressure
-	movff	rel_pressure+0,max_pressure+0
-	movff	rel_pressure+1,max_pressure+1
+	movff	sub_b+0,max_pressure+0
+	movff	sub_b+1,max_pressure+1
 	call	PLED_max_pressure			; No, use normal max. depth
 	return
 
 set_min_temp:
 	movff	mintemp+0,sub_a+0
 	movff	mintemp+1,sub_a+1
-	movff	temperature+0,sub_b+0
-	movff	temperature+1,sub_b+1
-	call	sub16						; sub_c = sub_a - sub_b
+    SAFE_2BYTE_COPY temperature,sub_b
+	call	sub16				; sub_c = sub_a - sub_b
 								; mintemp<T -> neg_flag=1
 								; T<=mintemp -> neg_flag=0
 	btfsc	neg_flag	
 	return
 								;mintemp>=T
-	movff	temperature+0,mintemp+0
-	movff	temperature+1,mintemp+1
+	movff	sub_b+0,mintemp+0
+	movff	sub_b+1,mintemp+1
 	return
 
 set_dive_modes:
@@ -1518,10 +1516,9 @@
 	GETCUSTOM8	.0					; loads dive_threshold in WREG
 	movwf	sub_a+0					; dive_treshold is in cm
 	clrf	sub_a+1
-	movff	rel_pressure+0,sub_b+0
-	movff	rel_pressure+1,sub_b+1
+    SAFE_2BYTE_COPY rel_pressure, sub_b
 	call	sub16					; sub_c = sub_a - sub_b
-	
+
 	btfss	neg_flag	
 	bra		set_dive_modes2			; too shallow (rel_pressure<dive_threshold)
 
@@ -1542,8 +1539,7 @@
 	movwf	sub_a+1
 	movlw	LOW		d'1075'			; hard-wired 1075mBar threshold
 	movwf	sub_a+0
-	movff	rel_pressure+0,sub_b+0
-	movff	rel_pressure+1,sub_b+1
+    SAFE_2BYTE_COPY rel_pressure, sub_b
 	call	sub16					; sub_c = sub_a - sub_b
 	
 	btfss	neg_flag	
@@ -1581,8 +1577,7 @@
 	rcall	reset_average1			; Reset the resettable average depth
 
 	; 1. Add new 2xdepth to the Sum of depths registers
-	movff	rel_pressure+0,b0_lo
-	movff	rel_pressure+1,b0_hi	; Buffer...
+    SAFE_2BYTE_COPY rel_pressure, b0_lo	; Buffer...
 
 	movf	b0_lo,w
 	addwf	average_depth_hold+0,F
@@ -1737,8 +1732,7 @@
 	movff	WREG,int_I_pres_surface+1   ; HIGH copy surfacepressure to deco routine
 
 diveloop_boot_2:
-	movff	temperature+0,mintemp+0     ; Reset Min-Temp registers
-	movff	temperature+1,mintemp+1     ; Reset Min-Temp registers
+	SAFE_2BYTE_COPY	temperature,mintemp ; Reset Min-Temp registers
 
 ; Init profile recording parameters	
 	GETCUSTOM8	d'20'                   ; sample rate
--- a/code_part1/OSTC_code_asm_part1/isr.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/isr.asm	Sat May 21 14:48:07 2011 +0200
@@ -27,6 +27,27 @@
 ; flag pressure_refresh is set every 500ms 
 ; and provides accurate pressure (+/-1mBar stable) and temperature (0.1C stable)
 
+;=============================================================================
+; Copy a 16bit value from ISR modified registers to main registers.
+; 
+; Because the ISR can happend at any time, the read should be redone if bytes
+; changed inbetween.
+;
+; Trashes: WREG and TABLAT
+; NOTE: Destination might be in any bank, so be BANK SAFE.
+;
+SAFE_2BYTE_COPY MACRO  from, to
+        local   retry
+retry:
+        movff   from+1,WREG             ; High byte in W.
+        movff   WREG,to+1               ; and destination.
+        movff   from+0,to+0             ; Copy low byte.
+        movff   from+1,TABLAT           ; another bank-safe read.
+        xorwf   TABLAT,W                ; High byte changed ?
+        bnz     retry
+        ENDM
+
+;=============================================================================
 uartint:
 		btfsc	simulatormode_active		; are we in simulatormode?
 		bra		simulator_int				; Yes, reading is depth in m!
@@ -64,7 +85,6 @@
 		bra		uartint1					; No
 		bsf		uart_115200_bootloader		; Yes, set Flag
 
-
 uartint1:
 		movf	RCREG,w						; unload RCREG in stand-alone simulator mode
 		bcf		PIR1,RCIF					; Clear flag
@@ -88,6 +108,8 @@
 		movff	PRODH,sim_pressure+1
 		bra		uartint1					; exit uart int
 
+;=============================================================================
+
 switch_left_int:
 		bcf		INTCON,INT0IF				; Clear flag
 
@@ -135,7 +157,10 @@
 		clrf	TMR0H
 		clrf	TMR0L
 		return
-		
+
+;=============================================================================
+;
+
 timer1int:
 		bcf		PIR1,TMR1IF					; Clear flag
 
@@ -160,6 +185,25 @@
 		btfsc	sleepmode					; In sleepmode?
 		return								; Yes
 
+; Sensor interput do poll the presure/temperature sensor, download results,
+; compute compensations, and store results in various shared variables.
+;
+; Input:    interupt (every 62.5msec == 16Hz), sensor,
+;           last_surfpressure:2.
+;
+; Output:   amb_pressure:2,
+;           temperature:2,
+;           rel_pressure:2,
+;           and the pressure_refresh flag.
+;
+; NOTE: averaging (4 successive value, as recommended in the MS5535 datasheet)
+;       is done on private variables, to avoid trashing data while reading it
+;       from the main code.
+;
+; NOTE: Because there is no atomic 16bits load/stores, we need to check twice
+;       the read data is correct. Ie. SAFE_2BYTE_COPY is mandatory to get
+;       amb_pressure, temperature or rel_pressure
+;
 sensor_int:
 		btfsc		no_sensor_int			; No sensor interrupt (because it's addressed during sleep)
 		return						
@@ -195,25 +239,30 @@
 ;sensor_int2_plus_average:
 		rcall		sensor_int_state2
 sensor_int2_plus_average2:		
-		bcf			STATUS,C
-		rrcf		isr3_temp+1				; isr3_temp / 2
-		rrcf		isr3_temp+0
-		bcf			STATUS,C
-		rrcf		temperature_temp+1		; temperature_temp /2
-		rrcf		temperature_temp+0
+		bcf			STATUS,C            ; clear carry bit.
+		rrcf		amb_pressure_avg+1  ; amb_pressure sum / 2
+		rrcf		amb_pressure_avg+0
+		bcf			STATUS,C            ; clear carry bit, twice.
+		rrcf		amb_pressure_avg+1  ; amb_pressure sum / 4
+		rrcf		amb_pressure_avg+0
+
+		movff		amb_pressure_avg+1,amb_pressure+1	; copy into actual register
+		movff		amb_pressure_avg+0,amb_pressure+0
 
-		bcf			STATUS,C
-		rrcf		isr3_temp+1				; isr3_temp / 4
-		rrcf		isr3_temp+0
-		bcf			STATUS,C
-		rrcf		temperature_temp+1		; temperature_temp /4
-		rrcf		temperature_temp+0
-	
-		movff		isr3_temp+1,amb_pressure+1	; copy into actual register
-		movff		isr3_temp+0,amb_pressure+0
+        bcf			STATUS,C
+        btfsc       temperature_avg+1,7 ; Copy sign bit to carry
+        bsf         STATUS,C
+		rrcf		temperature_avg+1   ; Signed temperature /2
+		rrcf		temperature_avg+0
 
-		movff		temperature_temp+1,temperature+1
-		movff		temperature_temp+0,temperature+0
+        bcf			STATUS,C
+        btfsc       temperature_avg+1,7 ; Copy sign bit to carry
+        bsf         STATUS,C
+		rrcf		temperature_avg+1   ; Signed temperature /4
+		rrcf		temperature_avg+0
+
+		movff		temperature_avg+1,temperature+1
+		movff		temperature_avg+0,temperature+0
 
 		bsf			pressure_refresh 			; Set flag! Temp and pressure were updated!
 		clrf		timer1int_counter2			; Then reset State counter
@@ -228,7 +277,6 @@
 		movwf		last_surfpressure+1
 
 comp_air_pressure:
-		bcf			neg_flag				
 		movf		last_surfpressure+0,W		; compensate airpressure
 		subwf   	amb_pressure+0,W             
 		movwf   	rel_pressure+0				; rel_pressure stores depth!
@@ -242,13 +290,12 @@
 		clrf		rel_pressure+1				; e.g. when surface air pressure dropped during the dive
 		return
 
-
 sensor_int_state1_plus_restart:
-		bcf			pressure_refresh		; clear flags
-		clrf		isr3_temp+0				; pressure average registers
-		clrf		isr3_temp+1
-		clrf		temperature_temp+0
-		clrf		temperature_temp+1
+;;;		bcf			pressure_refresh    ; clear flags
+		clrf		amb_pressure_avg+0  ; pressure average registers
+		clrf		amb_pressure_avg+1
+		clrf		temperature_avg+0
+		clrf		temperature_avg+1
 
 sensor_int_state1:
 		call		get_temperature_value	; State 1: Get temperature
@@ -258,17 +305,9 @@
 sensor_int_state2:
 		call		get_pressure_value		; State2: Get pressure (51us)
 		call		get_temperature_start	; and start temperature integration (73,5us)
-		call		calculate_compensation	; calculate temperature compensated pressure (233us)
-		movf		amb_pressure+0,W
-		addwf		isr3_temp+0				; average pressure
-		movf		amb_pressure+1,W
-		addwfc		isr3_temp+1
-		movf		temperature+0,W
-		addwf		temperature_temp+0		; average temperature
-		movf		temperature+1,W
-		addwfc		temperature_temp+1
-		return		
+		goto		calculate_compensation	; calculate temperature compensated pressure (233us)
 
+;=============================================================================
 
 RTCisr:			
 		clrf		timer1int_counter1		; counts to 16 (one second / 62.5ms)
--- a/code_part1/OSTC_code_asm_part1/math.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/math.asm	Sat May 21 14:48:07 2011 +0200
@@ -53,23 +53,19 @@
 	movf   	sub_b+1, W              ; Get the Value to be Subbed
 	subwfb 	sub_a+1, W
 	movwf  	sub_c+1
+
 	btfsc	STATUS,C
 	return							; result positve
-;  sub_c = sub_a - sub_b
+
 	bsf		neg_flag				; result negative
-	movff	sub_c+0,sub_b+0
-	movff	sub_c+1,sub_b+1
-	setf	sub_a
-	setf	sub_a+1
-	movf   	sub_b+0, W             	;  Get Value to be subtracted
-	subwf  	sub_a+0, W             	;  Do the High Byte
-	movwf  	sub_c+0
-	movf   	sub_b+1, W               ;  Get the Value to be Subbed
-	subwfb  sub_a+1, W
-	movwf  	sub_c+1
+
+    comf    sub_c+1                 ; 16bit sign change.
+    negf    sub_c+0
+    btfsc   STATUS,C                ; Carry to propagate ?
+    incf    sub_c+1,F               ; YES: do it.
+
     return        
 
-
 mult16x16:		;xA*xB=xC
 	clrf    xC+2        	  ;  Clear the High-Order Bits
 	clrf    xC+3
--- a/code_part1/OSTC_code_asm_part1/menu_reset.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/menu_reset.asm	Sat May 21 14:48:07 2011 +0200
@@ -284,8 +284,7 @@
 ; reset deco data
 	call	PLED_ClearScreen
 	DISPLAYTEXT	.25					; "Reset..."
-	movff	amb_pressure+0,int_I_pres_respiration+0		; copy surface air pressure to deco routine
-	movff	amb_pressure+1,int_I_pres_respiration+1		
+    SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration	; copy surface air pressure to deco routine
 	call	deco_clear_tissue
 	movlb	b'00000001'				; RAM Bank1 selected
 	goto	restart					; done. quit to surfmode
@@ -303,8 +302,7 @@
 
 reset_start:
 ; reset deco data
-	movff	amb_pressure+0,int_I_pres_respiration+0		; copy surface air pressure to deco routine
-	movff	amb_pressure+1,int_I_pres_respiration+1		
+    SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration	; copy surface air pressure to deco routine
 	call	deco_clear_tissue
 	movlb	b'00000001'				; RAM Bank1 selected
 
--- a/code_part1/OSTC_code_asm_part1/ms5535.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/ms5535.asm	Sat May 21 14:48:07 2011 +0200
@@ -20,6 +20,9 @@
 ; 2005-09-26: Written by Matthias Heinrichs, info@heinrichsweikamp.com
 ; 2008-08-21: MH last updated, with second order compensation.
 ; 2011-01-19: jDG Clean up using true signed arithmetics.
+; 2011-05-19: jDG Avegaring temperature and amb_pressure in private variable,
+;                 Use signed 16bit value for temperature (compat with avg !).
+;
 ; known bugs:
 ; ToDo: 
 
@@ -27,7 +30,7 @@
 ; Expose internal variables, to ease debug:
     global D1, D2
     global C1, C2, C3, C4, C5, C6
-    global xdT, xdT2, OFF, SENS, amb_pressure, temperature
+    global xdT, xdT2, OFF, SENS, amb_pressure_avg, temperature_avg
 
 ;=============================================================================
 calculate_compensation:
@@ -151,20 +154,23 @@
     movlw   .12-.8                      ; a 12bit shift = 1 byte + 4 bits.
     call    isr_shift_C31
 
-    movlw   LOW(.1000)                  ; add 1000, and save into amb_pressure
-    addwf   isr_xC+1,W
-    movwf   amb_pressure+0
+    movlw   LOW(.1000)                  ; add 1000
+    addwf   isr_xC+1,F
     movlw   HIGH(.1000)
-    addwfc  isr_xC+2,W
-    movwf   amb_pressure+1
+    addwfc  isr_xC+2,F
 
 	btfss	simulatormode_active		; are we in simulator mode?
-	bra		calc_pressure_done			; no
+	bra		calc_compensation_2			; no
 
-	movff	sim_pressure+0,amb_pressure+0	; override readings with simulator values
-	movff	sim_pressure+1,amb_pressure+1
+	movff	sim_pressure+0,isr_xC+1	    ; override readings with simulator values
+	movff	sim_pressure+1,isr_xC+2
 	
-calc_pressure_done:
+calc_compensation_2:
+    movf    isr_xC+1,W                  ; Then sum_up to pressure averaging buffer.
+    addwf   amb_pressure_avg+0,F
+    movf    isr_xC+2,W
+    addwfc  amb_pressure_avg+1,F
+
     ; calculate temp = 200 + dT*(C6+100)/2^11
     movlw   LOW(.100)                   ; C6 + 100 --> A
     addwf   C6+0,W
@@ -179,23 +185,16 @@
     movlw   .11-.8                      ; A 12bit shift = 1 byte + 3 bits.
     call    isr_shift_C31
 
-    movlw   LOW(.200)                   ; Add 200, and save into temperature
-    addwf   isr_xC+1,W
-    movwf   temperature+0
+    movlw   LOW(.200)                   ; Add 200
+    addwf   isr_xC+1,F
     movlw   HIGH(.200)
-    addwfc  isr_xC+2,W
-    movwf   temperature+1
+    addwfc  isr_xC+2,F
 
-    bcf     neg_temp
-    bnn     calc_pos_temp               ; Is Temp° negativ ?
-    
-    bsf     neg_temp                    ; Yes: set flag and store -temp
-    comf    temperature+1
-    negf    temperature+0
-    btfsc   STATUS,C
-    incf    temperature+1
+    movf    isr_xC+1,W
+    addwf   temperature_avg+0,F
+    movf    isr_xC+2,W
+    addwfc  temperature_avg+1,F
 
-calc_pos_temp:
 	return			                    ; Fertig mit allem
 
 ;=============================================================================
--- a/code_part1/OSTC_code_asm_part1/pled_outputs.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/pled_outputs.asm	Sat May 21 14:48:07 2011 +0200
@@ -105,8 +105,7 @@
 
 PLED_color_code_gaslist:				; %O2 in "EEDATA"
 ; Check very high ppO2 manually
-	movff		amb_pressure+0,xA+0
-	movff		amb_pressure+1,xA+1
+    SAFE_2BYTE_COPY amb_pressure,xA
 	movlw		d'10'
 	movwf		xB+0
 	clrf		xB+1
@@ -143,8 +142,7 @@
 	cpfseq	lo					; =1?
 	bra		PLED_color_code_ceiling1	; No, Set to default color
 
-	movff	rel_pressure+1,hi
-	movff	rel_pressure+0,lo
+    SAFE_2BYTE_COPY rel_pressure, lo
 	call	adjust_depth_with_salinity			; computes salinity setting into lo:hi [mBar]
 	movff	hi,xA+1
 	movff	lo,xA+0
@@ -168,8 +166,7 @@
 PLED_color_code_depth:
 	movff	hi,hi_temp
 	movff	lo,lo_temp
-	movff	rel_pressure+1,hi
-	movff	rel_pressure+0,lo
+    SAFE_2BYTE_COPY rel_pressure, lo
 	call	adjust_depth_with_salinity			; computes salinity setting into lo:hi [mBar]
 	movff	lo,sub_a+0
 	movff	hi,sub_a+1
@@ -839,15 +836,13 @@
 	WIN_LEFT	.0
 	WIN_TOP		.177
 	STRCPY  "amb:"
-	movff	amb_pressure+0,lo
-	movff	amb_pressure+1,hi
+    SAFE_2BYTE_COPY amb_pressure, lo
 	output_16
 	call	word_processor
 	WIN_LEFT	.80
 	WIN_TOP		.177
 	STRCPY  "temp:"
-	movff	temperature+0,lo
-	movff	temperature+1,hi
+    SAFE_2BYTE_COPY temperature, lo
 	output_16
 	call	word_processor
 
@@ -948,20 +943,28 @@
 	
 PLED_temp_surfmode:
 	ostc_debug	'e'
-	movff	temperature+0,last_temperature+0
-	movff	temperature+1,last_temperature+1
+    SAFE_2BYTE_COPY    temperature, last_temperature
 	WIN_TOP		.100
 	WIN_LEFT	.1
 	WIN_FONT 	FT_SMALL
-	WIN_INVERT	.0					; Init new Wordprocessor
+	WIN_INVERT	.0                      ; Init new Wordprocessor
 	call	PLED_standard_color
 
+	movff	last_temperature+1,hi
+	movff	last_temperature+0,lo
 	lfsr	FSR2,letter
-	movlw	'-'
-	btfsc	neg_temp			; Show "-"?
-	movwf	POSTINC2			; Yes
-	movff	temperature+0,lo
-	movff	temperature+1,hi
+
+    btfss   hi,7                        ; Negative temperature ?
+    bra     PLED_temp_surfmode_1        ; No: continue
+
+	PUTC	'-'                         ; Display "-"
+
+    comf    hi                          ; Then, 16bit sign changes.
+    negf    lo
+    btfsc   STATUS,C
+    incf    hi
+
+PLED_temp_surfmode_1:
 	movlw	d'3'
 	movwf	ignore_digits
 	bsf		leftbind			; left orientated output
@@ -974,8 +977,7 @@
 	ostc_debug	'u'		; Sends debug-information to screen if debugmode active
 
 ; temperature
-	movff	temperature+0,last_temperature+0
-	movff	temperature+1,last_temperature+1
+    SAFE_2BYTE_COPY temperature, last_temperature
 
 	WIN_TOP		.216
 	WIN_LEFT	.50
@@ -983,12 +985,22 @@
 	WIN_INVERT	.0					; Init new Wordprocessor
 	call	PLED_standard_color
 
+	movff	last_temperature+1,hi
+	movff	last_temperature+0,lo
+
 	lfsr	FSR2,letter
-	movlw	'-'
-	btfsc	neg_temp			; Show "-"?
-	movwf	POSTINC2			; Yes
-	movff	temperature+0,lo
-	movff	temperature+1,hi
+
+    btfss   hi,7                        ; Negative temperature ?
+    bra     PLED_temp_divemode_1        ; No: continue
+
+	PUTC	'-'                         ; Display "-"
+
+    comf    hi                          ; Then, 16bit sign changes.
+    negf    lo
+    btfsc   STATUS,C
+    incf    hi
+
+PLED_temp_divemode_1:
 	movlw	d'3'
 	movwf	ignore_digits
 	bsf		leftbind			; left orientated output
@@ -1546,8 +1558,7 @@
 
 PLED_depth:
 	ostc_debug	'r'		; Sends debug-information to screen if debugmode active
-	movff	rel_pressure+1,hi
-	movff	rel_pressure+0,lo
+    SAFE_2BYTE_COPY rel_pressure, lo
 	call	adjust_depth_with_salinity			; computes salinity setting into lo:hi [mBar]
 
 	movlw	.039
@@ -1607,8 +1618,7 @@
 	WIN_LEFT	.40
 	PLED_color_code	warn_depth		; Color-code the output
 
-	movff	rel_pressure+1,hi
-	movff	rel_pressure+0,lo
+    SAFE_2BYTE_COPY rel_pressure, lo
 	call	adjust_depth_with_salinity			; computes salinity setting into lo:hi [mBar]
 	
 	STRCPY  "."
@@ -1759,8 +1769,7 @@
 	call	PLED_warnings_color		; Yes, display ambient pressure in red
 
 	lfsr	FSR2,letter
-	movff	amb_pressure+0,lo
-	movff	amb_pressure+1,hi
+    SAFE_2BYTE_COPY amb_pressure, lo
 	bsf		leftbind
 	output_16
 	bcf		leftbind
@@ -1994,7 +2003,7 @@
 
 	movlw	.039
 	cpfslt	hi
-		bra		maxdepth_greater_99_84mtr
+    bra		maxdepth_greater_99_84mtr
 
 ; Display normal "xx.y"
 	lfsr	FSR2,letter
@@ -2789,7 +2798,7 @@
 PLED_no_graph_grid:
     
     ;---- Draw N2 Tissues ----------------------------------------------------
-	lfsr	FSR2, char_O_tissue_saturation+.000	; N2
+	lfsr	FSR2, char_O_tissue_N2_saturation
 	movlw	d'16'
 	movwf	wait_temp                   ; 16 tissues
 	clrf	waitms_temp                 ; Row offset
@@ -2835,7 +2844,7 @@
 	bra		PLED_tissue_saturation_graph3
 
     ;---- Draw He Tissues ----------------------------------------------------
-	lfsr	FSR2, char_O_tissue_saturation+.016	; He
+	lfsr	FSR2, char_O_tissue_He_saturation
 	movlw	d'16'
 	movwf	wait_temp                   ; 16 tissues
 	clrf	waitms_temp                 ; Row offset
@@ -2895,13 +2904,9 @@
 
 	movff	char_O_gtissue_no,wait_temp			; used as temp
 
-	lfsr	FSR1,char_O_tissue_saturation+0
-	incf	wait_temp,F			; make 1-16 of 0-15
-
-PLED_tissue_saturation_graph4:		; point to leading tissue...
-	movff	POSTINC1,lo			; copy/overwrite to lo register
-	decfsz	wait_temp,F			; count until zero
-	bra		PLED_tissue_saturation_graph4	;loop
+	lfsr	FSR1,char_O_tissue_N2_saturation
+	movf	wait_temp,W			; W <- 0-15
+	movff	PLUSW1,lo			; lo <- FSR1[W]
 
 	WIN_TOP		.62
 	WIN_FONT	FT_SMALL
@@ -2984,8 +2989,8 @@
 
 PLED_const_ppO2_value2:				; Display SetPoint
 ;Show fixed SP value
-	movff		amb_pressure+0,xA+0
-	movff		amb_pressure+1,xA+1
+    SAFE_2BYTE_COPY amb_pressure, xA
+
 	movlw		d'10'
 	movwf		xB+0
 	clrf		xB+1
@@ -3005,8 +3010,7 @@
 
 PLED_const_ppO2_value1:
 	; char_I_const_ppO2 < ppO2[Diluent] -> Not physically possible! -> Display actual value!
-	movff		amb_pressure+0,xA+0
-	movff		amb_pressure+1,xA+1
+    SAFE_2BYTE_COPY amb_pressure, xA
 	movlw		d'10'
 	movwf		xB+0
 	clrf		xB+1
@@ -3230,12 +3234,9 @@
 
     STRCAT_PRINT  ") "
 
-	lfsr	FSR1,char_O_tissue_saturation+0
-	incf	wait_temp,F			; make 1-16 of 0-15
-PLED_show_leading_tissue3:		; point to leading tissue...
-	movff	POSTINC1,lo			; copy/overwrite to lo register
-	decfsz	wait_temp,F			; count until zero
-	bra		PLED_show_leading_tissue3	;loop
+	lfsr	FSR1,char_O_tissue_N2_saturation
+	movf	wait_temp,W			; W <- 0-15
+	movff	PLUSW1,lo			; lo <- FSR1[W]
 
 	WIN_LEFT	.95
 	WIN_TOP		.216
--- a/code_part1/OSTC_code_asm_part1/simulator.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/simulator.asm	Sat May 21 14:48:07 2011 +0200
@@ -132,8 +132,9 @@
 
 	movff	xC+0,sim_pressure+0
 	movff	xC+1,sim_pressure+1
-	
-	movff	sim_pressure+0,amb_pressure+0	; override readings with simulator values
+
+    ; This override is done in ISR too, but do it right now also:	
+	movff	sim_pressure+0,amb_pressure+0
 	movff	sim_pressure+1,amb_pressure+1
 
 	bcf		menubit2
@@ -348,7 +349,8 @@
 	DISPLAYTEXT	.12                     ; "Wait..."
 	WIN_INVERT	.0
 
-	movff	sim_pressure+0,amb_pressure+0	; override readings with simulator values
+    ; This override is done in ISR too, but do it right now also:	
+	movff	sim_pressure+0,amb_pressure+0
 	movff	sim_pressure+1,amb_pressure+1
 
 	call	divemode_check_decogases    ; Checks for decogases and sets the gases
--- a/code_part1/OSTC_code_asm_part1/sleepmode.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/sleepmode.asm	Sat May 21 14:48:07 2011 +0200
@@ -78,8 +78,7 @@
 	movlb	b'00000001'
 	movff	last_surfpressure_15min+0,last_surfpressure_30min+0	; save older airpressure
 	movff	last_surfpressure_15min+1,last_surfpressure_30min+1	; save older airpressure	
-	movff	amb_pressure+0,last_surfpressure_15min+0			; save new airpressure
-	movff	amb_pressure+1,last_surfpressure_15min+1			; save new airpressure
+    SAFE_2BYTE_COPY amb_pressure, last_surfpressure_15min		; save new airpressure
 
 	clrf	divemins+1				; reset counter
 	GETCUSTOM15	d'7'				; loads max_sufpressure into lo, hi
@@ -98,8 +97,7 @@
 
 onemin_sleep2:
 ;calc_deko_sleepmode:
-	movff	amb_pressure+0,int_I_pres_respiration+0		; LOW copy pressure to deco routine
-	movff	amb_pressure+1,int_I_pres_respiration+1		; HIGH
+    SAFE_2BYTE_COPY amb_pressure, int_I_pres_respiration ; LOW copy pressure to deco routine
 	GETCUSTOM8	d'11'				; Saturation multiplier %
 	movff	WREG,char_I_saturation_multiplier
 	GETCUSTOM8	d'12'				; Desaturation multiplier %
@@ -134,8 +132,7 @@
 	GETCUSTOM15	d'6'				; loads pressure threshold into lo,hi
 	movff	lo,sub_a+0				; power on if ambient pressure is greater threshold
 	movff	hi,sub_a+1	
-	movff	amb_pressure+0,sub_b+0
-	movff	amb_pressure+1,sub_b+1
+    SAFE_2BYTE_COPY amb_pressure, sub_b
 	call	sub16					; sub_c = sub_a - sub_b
 	bsf		sleepmode
 	btfsc	neg_flag				; Wake up from Sleep?
--- a/code_part1/OSTC_code_asm_part1/start.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/start.asm	Sat May 21 14:48:07 2011 +0200
@@ -67,12 +67,11 @@
 	call	pressuretest_sleep_fast	; Gets pressure without averaging (faster!)
 	bcf		sleepmode				; Normal mode again
 
-	movff	amb_pressure+0,last_surfpressure+0
-	movff	amb_pressure+1,last_surfpressure+1
-	movff	amb_pressure+0,last_surfpressure_15min+0
-	movff	amb_pressure+1,last_surfpressure_15min+1
-	movff	amb_pressure+0,last_surfpressure_30min+0
-	movff	amb_pressure+1,last_surfpressure_30min+1	; Rests all airpressure registers
+    SAFE_2BYTE_COPY amb_pressure, last_surfpressure
+	movff	last_surfpressure+0,last_surfpressure_15min+0
+	movff	last_surfpressure+1,last_surfpressure_15min+1
+	movff	last_surfpressure+0,last_surfpressure_30min+0
+	movff	last_surfpressure+1,last_surfpressure_30min+1	; Rests all airpressure registers
 
 ; Extra power-up reset (JeanDo)
 	ifdef	TESTING
@@ -91,10 +90,9 @@
 	movff	WREG,char_I_saturation_multiplier
 	GETCUSTOM8	d'12'					    ; Desaturation multiplier %
 	movff	WREG,char_I_desaturation_multiplier
-	movff	amb_pressure+0,int_I_pres_respiration+0 ; copy for deco routine
-	movff	amb_pressure+1,int_I_pres_respiration+1		
-	movff	amb_pressure+0,int_I_pres_surface+0     ; copy for desat routine
-	movff	amb_pressure+1,int_I_pres_surface+1		
+    SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; copy for deco routine
+	movff	int_I_pres_respiration+0,int_I_pres_surface+0     ; copy for desat routine
+	movff	int_I_pres_respiration+1,int_I_pres_surface+1		
 
 	call	deco_clear_tissue			    ;
 	call	deco_calc_desaturation_time     ; calculate desaturation time
--- a/code_part1/OSTC_code_asm_part1/surfmode.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/surfmode.asm	Sat May 21 14:48:07 2011 +0200
@@ -284,8 +284,7 @@
 	movwf	wait_temp						; Use as buffer
 	movff	wait_temp,char_I_N2_ratio		; No He at the Surface
 
-	movff	amb_pressure+0,int_I_pres_respiration+0		; copy surface air pressure to deco routine
-	movff	amb_pressure+1,int_I_pres_respiration+1		
+    SAFE_2BYTE_COPY amb_pressure,int_I_pres_respiration ; copy surface air pressure to deco routine
 	GETCUSTOM8	d'11'									; Saturation multiplier %
 	movff	WREG,char_I_saturation_multiplier
 	GETCUSTOM8	d'12'									; Desaturation multiplier %
--- a/code_part1/OSTC_code_asm_part1/temp_extrema.asm	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_asm_part1/temp_extrema.asm	Sat May 21 14:48:07 2011 +0200
@@ -28,15 +28,14 @@
 	movff	EEDATA,sub_b+0
 	read_int_eeprom d'55'
 	movff	EEDATA,sub_b+1
-	movff	temperature+0,sub_a+0
-	movff	temperature+1,sub_a+1
+	SAFE_2BYTE_COPY	temperature,sub_a
 	call	sub16					; sub_c = sub_a - sub_b
 	btfss	neg_flag				; new lowest temperature ?
 	bra		check_temp_extrema_high	
 	; Yes, store new value together with the date
-	movff	temperature+0,EEDATA
+	movff	sub_a+0,EEDATA
 	write_int_eeprom	d'54'
-	movff	temperature+1,EEDATA
+	movff	sub_a+1,EEDATA
 	write_int_eeprom	d'55'
 	movff	month,EEDATA
 	write_int_eeprom	d'56'
@@ -44,21 +43,22 @@
 	write_int_eeprom	d'57'
 	movff	year,EEDATA
 	write_int_eeprom	d'58'
+
 	; Now check high extrema
 check_temp_extrema_high:
 	read_int_eeprom d'59'			; get highest temperature so far
 	movff	EEDATA,sub_b+0
 	read_int_eeprom d'60'
 	movff	EEDATA,sub_b+1
-	movff	temperature+0,sub_a+0
-	movff	temperature+1,sub_a+1
+	SAFE_2BYTE_COPY	temperature,sub_a
 	call	sub16					; sub_c = sub_a - sub_b
 	btfsc	neg_flag				; new highest temperature ?
 	return							; no, quit!
+
 	; Yes, store new value together with the date
-	movff	temperature+0,EEDATA
+	movff	sub_a+0,EEDATA
 	write_int_eeprom	d'59'
-	movff	temperature+1,EEDATA
+	movff	sub_a+1,EEDATA
 	write_int_eeprom	d'60'
 	movff	month,EEDATA
 	write_int_eeprom	d'61'
--- a/code_part1/OSTC_code_c_part2/p2_deco.c	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_c_part2/p2_deco.c	Sat May 21 14:48:07 2011 +0200
@@ -77,6 +77,7 @@
 // 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for decoplanning.
 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor.
 // 2011/05/02: [jDG] Added "Future TTS" function (CF58).
+// 2011/05/17: [jDG] Various cleanups.
 //
 // TODO:
 //  + Allow to abort MD2 calculation (have to restart next time).
@@ -163,11 +164,12 @@
 // Real context: what we are doing now.
 static float			calc_lead_tissue_limit;     // 
 
-static unsigned char	internal_deco_time[32];
-static unsigned char	internal_deco_depth[32];
+static unsigned char	internal_deco_time[NUM_STOPS];
+static unsigned char	internal_deco_depth[NUM_STOPS];
 
 static float cns_vault;
-static float pres_tissue_vault[32];
+static float pres_tissue_N2_vault[NUM_COMP];
+static float pres_tissue_He_vault[NUM_COMP];
 
 //---- Bank 5 parameters -----------------------------------------------------
 #pragma udata bank5=0x500
@@ -188,8 +190,8 @@
 static float  			var_N2_e;       // Exposition, for current N2 tissue.
 static float  			var_He_e;       // Exposition, for current He tissue.
 
-static float            pres_diluent;               // new in v.101
-static float            const_ppO2;                 // new in v.101
+static float            pres_diluent;                   // new in v.101
+static float            const_ppO2;                     // new in v.101
 
 static unsigned char    sim_gas_last_depth;             // Depth of last used gas, to detected a gas switch. 
 static unsigned char    sim_gas_last_used;              // Number of last used gas, to detected a gas switch. 
@@ -200,21 +202,24 @@
 static float			CNS_fraction;			        // new in v.101
 static float			float_saturation_multiplier;    // new in v.101
 static float			float_desaturation_multiplier;  // new in v.101
-static float			float_deco_distance;	// new in v.101
-static char			    flag_in_divemode;		// new in v.108
+static float			float_deco_distance;            // new in v.101
+static char			    flag_in_divemode;		        // new in v.108
 
-static unsigned char    deco_gas_change[5];		// new in v.109
+static unsigned char    deco_gas_change[NUM_GAS];       // new in v.109
 
 //---- Bank 6 parameters -----------------------------------------------------
 #pragma udata bank6=0x600
 
-float  pres_tissue[32];
+float  pres_tissue_N2[NUM_COMP];
+float  pres_tissue_He[NUM_COMP];
 
 //---- Bank 7 parameters -----------------------------------------------------
 #pragma udata bank7=0x700
 
-float  sim_pres_tissue[32];                 // 32 floats = 128 bytes.
-static float  sim_pres_tissue_backup[32];
+float  sim_pres_tissue_N2[NUM_COMP];             // 32 floats = 128 bytes.
+float  sim_pres_tissue_He[NUM_COMP];             // 32 floats = 128 bytes.
+static float  sim_pres_tissue_backup_N2[NUM_COMP];
+static float  sim_pres_tissue_backup_He[NUM_COMP];
 
 //---- Bank 8 parameters -----------------------------------------------------
 #pragma udata bank8=0x800
@@ -328,8 +333,8 @@
 		int_O_DBS_bitfield |= DBS_mode;
 	if(const_ppO2)
 		int_O_DBS_bitfield |= DBS_ppO2;
-	for(i = 16; i < 32; i++)
-		if(pres_tissue[i])
+	for(i = 0; i < NUM_COMP; i++)
+		if(pres_tissue_He[i])
 			int_O_DBS_bitfield |= DBS_HE_sat;
 	if(float_saturation_multiplier < 0.99)
 		int_O_DBS_bitfield |= DBS_SAT2l;
@@ -417,8 +422,8 @@
 		temp_DBS |= DBG_C_SURF;
 
 	if( !DBS_HE_sat && !He_ratio)
-		for(i = 16; i < 32; i++)
-			if(pres_tissue[i])
+		for(i = 0; i < NUM_COMP; i++)
+			if(pres_tissue_He[i])
 				temp_DBS |= DBG_HEwoHE;
 
 	if( DBG_deco_gas_change != deco_gas_change[0]
@@ -549,9 +554,10 @@
 // 
 static void read_buhlmann_coefficients(void)
 {
+
 #ifndef CROSS_COMPILE
     // Note: we don't use far rom pointer, because the
-    //       24 bits is to complex, hence we have to set
+    //       24 bits is too complex, hence we have to set
     //       the UPPER page ourself...
     //       --> Set zero if tables are moved to lower pages !
     _asm
@@ -560,11 +566,17 @@
     _endasm
 #endif
 
-    assert( 0 <= ci && ci < 16 );
-    var_N2_a = buhlmann_a[ci];
-    var_N2_b = buhlmann_b[ci];
-    var_He_a = (buhlmann_a+16)[ci];
-    var_He_b = (buhlmann_b+16)[ci];
+    assert( 0 <= ci && ci < NUM_COMP );
+
+    // Use an interleaved array (AoS) to access coefficients with a
+    // single addressing.
+    {
+        overlay rom const float* ptr = &buhlmann_ab[4*ci];
+        var_N2_a = *ptr++;
+        var_N2_b = *ptr++;
+        var_He_a = *ptr++;
+        var_He_b = *ptr++;
+    }
 
     // Check reading consistency:
 	if(	(var_N2_a < 0.231)
@@ -596,14 +608,18 @@
         movwf TBLPTRU,0
     _endasm
 #endif
-    assert( 0 <= ci && ci < 16 );
+
+    assert( 0 <= ci && ci < NUM_COMP );
 
     // Integration intervals.
     switch(period)
     {
     case 0: //---- 2 sec -----------------------------------------------------
-        var_N2_e = e2secs[ci];
-        var_He_e = (e2secs+16)[ci];
+        {
+            overlay rom const float* ptr = &e2secs[2*ci];
+            var_N2_e = *ptr++;
+            var_He_e = *ptr++;
+        }
 
         // Check reading consistency:
     	if(	(var_N2_e < 0.0000363)
@@ -616,8 +632,11 @@
         break;
 
     case 1: //---- 1 min -----------------------------------------------------
-        var_N2_e = e1min[ci];
-        var_He_e = (e1min+16)[ci];
+       {
+            overlay rom const float* ptr = &e1min[2*ci];
+            var_N2_e = *ptr++;
+            var_He_e = *ptr++;
+        }
 
         // Check reading consistency:
     	if(	(var_N2_e < 1.09E-3)
@@ -630,8 +649,11 @@
         break;
 
     case 2: //---- 10 min ----------------------------------------------------
-        var_N2_e = e10min[ci];
-        var_He_e = (e10min+16)[ci];
+        {
+            overlay rom const float* ptr = &e10min[2*ci];
+            var_N2_e = *ptr++;
+            var_He_e = *ptr++;
+        }
 
         // Check reading consistency:
     	if(	(var_N2_e < 0.01085)
@@ -649,7 +671,7 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
-// calc_next_decodepth_GF
+// calc_nextdecodepth
 //
 // new in v.102
 //
@@ -833,11 +855,11 @@
         overlay unsigned char x, y;
 
         //---- First: search the first non-null depth
-        for(x=31; x != 0; --x)
+        for(x=(NUM_STOPS-1); x != 0; --x)
             if( internal_deco_depth[x] != 0 ) break;
 
         //---- Second: copy to output table (in reverse order)
-        for(y=0; y<32; y++, --x)
+        for(y=0; y<NUM_STOPS; y++, --x)
         {
             char_O_deco_depth[y] = internal_deco_depth[x];
             char_O_deco_time [y] = internal_deco_time [x];
@@ -847,7 +869,7 @@
         }
 
         //---- Third: fill table end with null
-        for(y++; y<32; y++)
+        for(y++; y<NUM_STOPS; y++)
         {
             char_O_deco_time [y] = 0;
             char_O_deco_depth[y] = 0;
@@ -857,7 +879,7 @@
     {
         overlay unsigned char x;
 
-        for(x=0; x<32; x++)
+        for(x=0; x<NUM_STOPS; x++)
         {
             char_O_deco_depth[x] = internal_deco_depth[x];
             char_O_deco_time [x] = internal_deco_time [x];
@@ -960,7 +982,7 @@
     overlay unsigned char N2 = (unsigned char)(N2_ratio * 100 + 0.5);
     overlay unsigned char He = (unsigned char)(He_ratio * 100 + 0.5);
 
-    for(j=0; j<5; ++j)
+    for(j=0; j<NUM_GAS; ++j)
     {
         // Make sure to detect if we are already breathing some gas in
         // the current list (happends when first gas do have a depth).
@@ -985,7 +1007,7 @@
         // And if I'm above the last decostop (with the 3m margin) ?
         if( (sim_gas_last_depth-3) > depth )
         {
-            for(j=0; j<5; ++j)
+            for(j=0; j<NUM_GAS; ++j)
             {
                 // And If I am in the range of a valide stop ?
                 // (again, with the same 3m margin)
@@ -1034,8 +1056,8 @@
         overlay unsigned char j;
 
         // Loop over all enabled gas, to find the deepest one,
-        // above las gas, but below temp_depth_limit.
-        for(j=0; j<5; ++j)
+        // above last used gas, but below temp_depth_limit.
+        for(j=0; j<NUM_GAS; ++j)
         {
             // Gas not (yet) allowed ? Skip !
             if( temp_depth_limit > deco_gas_change[j] )
@@ -1092,7 +1114,7 @@
 //
 static void gas_switch_set(void)
 {
-    assert( 0 <= sim_gas_last_used && sim_gas_last_used <= 5 );
+    assert( 0 <= sim_gas_last_used && sim_gas_last_used <= NUM_GAS );
 
     if( sim_gas_last_used == 0 )
     {
@@ -1177,15 +1199,15 @@
     N2_ratio = 0.7902;
     pres_respiration = int_I_pres_respiration * 0.001;
     
-    for(ci=0; ci<16; ci++)
+    for(ci=0; ci<NUM_COMP; ci++)
     {
         // cycle through the 16 Bühlmann tissues
         overlay float p = N2_ratio * (pres_respiration -  ppWater);
-        pres_tissue[ci] = p;
+        pres_tissue_N2[ci] = p;
 
         // cycle through the 16 Bühlmann tissues for Helium
-        (pres_tissue+16)[ci] = 0.0;
-    } // for 0 to 16
+        pres_tissue_He[ci] = 0.0;
+    } // for 0 to 15
 
     clear_deco_table();
     char_O_deco_status = 0;
@@ -1446,7 +1468,7 @@
     calc_limit();
 
  	int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000);
-	int_O_gtissue_press = (short)((pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]) * 1000);
+	int_O_gtissue_press = (short)((pres_tissue_N2[char_O_gtissue_no] + pres_tissue_He[char_O_gtissue_no]) * 1000);
 
     // if guiding tissue can not be exposed to surface pressure immediately
     if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0)  
@@ -1616,19 +1638,19 @@
     assert( 0.00 <= ppN2 && ppN2 < 11.2 );  // 80% N2 at 130m
     assert( 0.00 <= ppHe && ppHe < 12.6 );  // 90% He at 130m
 
-    for (ci=0;ci<16;ci++)
+    for (ci=0;ci<NUM_COMP;ci++)
     {
         read_buhlmann_times(period);        // 2 sec or 1 min period.
 
         // N2
-        temp_tissue = (ppN2 - pres_tissue[ci]) * var_N2_e;
+        temp_tissue = (ppN2 - pres_tissue_N2[ci]) * var_N2_e;
         temp_tissue_safety();
-        pres_tissue[ci] += temp_tissue;
+        pres_tissue_N2[ci] += temp_tissue;
 
         // He
-        temp_tissue = (ppHe - (pres_tissue+16)[ci]) * var_He_e;
+        temp_tissue = (ppHe - pres_tissue_He[ci]) * var_He_e;
         temp_tissue_safety();
-        (pres_tissue+16)[ci] += temp_tissue;
+        pres_tissue_He[ci] += temp_tissue;
     }
 }
 
@@ -1642,10 +1664,10 @@
     char_O_gtissue_no = 255;
     calc_lead_tissue_limit = 0.0;
 
-    for(ci=0; ci<16;ci++)
+    for(ci=0; ci<NUM_COMP;ci++)
     {
-        overlay float N2 = pres_tissue[ci];
-        overlay float He = (pres_tissue+16)[ci];
+        overlay float N2 = pres_tissue_N2[ci];
+        overlay float He = pres_tissue_He[ci];
         overlay float p = N2 + He;
 
         read_buhlmann_coefficients();
@@ -1675,7 +1697,7 @@
         }
     }
 
-    assert( char_O_gtissue_no < 16 );
+    assert( char_O_gtissue_no < NUM_COMP );
     assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0);
 }
 
@@ -1728,8 +1750,11 @@
 {
     overlay unsigned char x;
 
-    for(x = 0; x<32; x++)
-        sim_pres_tissue_backup[x] = sim_pres_tissue[x];
+    for(x=0; x<NUM_COMP; x++)
+    {
+        sim_pres_tissue_backup_N2[x] = sim_pres_tissue_N2[x];
+        sim_pres_tissue_backup_He[x] = sim_pres_tissue_He[x];
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1739,8 +1764,11 @@
 {
     overlay unsigned char x;
 
-    for(x = 0; x<32; x++)
-        sim_pres_tissue[x] = sim_pres_tissue_backup[x];
+    for(x=0; x<NUM_COMP; x++)
+    {
+        sim_pres_tissue_N2[x] = sim_pres_tissue_backup_N2[x];
+        sim_pres_tissue_He[x] = sim_pres_tissue_backup_He[x];
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1761,7 +1789,7 @@
         ascent = 0.0;
     sum = (unsigned short)(ascent + 0.99);
 
-    for(x=0; x<32 && internal_deco_depth[x]; x++)
+    for(x=0; x<NUM_STOPS && internal_deco_depth[x]; x++)
         sum += (unsigned short)internal_deco_time[x];
 
     if( char_O_deco_status == 1 )
@@ -1780,10 +1808,10 @@
     overlay unsigned char x;
 
     // Start ascent simulation with current tissue partial pressures.
-  	for (x = 0;x<16;x++)
+  	for(x=0; x<NUM_COMP; x++)
   	{
-   		sim_pres_tissue[x] = pres_tissue[x];
-   		(sim_pres_tissue+16)[x] = (pres_tissue+16)[x];
+   		sim_pres_tissue_N2[x] = pres_tissue_N2[x];
+   		sim_pres_tissue_He[x] = pres_tissue_He[x];
   	}
 
     // No leading tissue (yet) for this ascent simulation.
@@ -1804,19 +1832,19 @@
     assert( 0.00 <= ppN2 && ppN2 < 11.2 );  // 80% N2 at 130m
     assert( 0.00 <= ppHe && ppHe < 12.6 );  // 90% He at 130m
 
-    for(ci=0; ci<16; ci++)
+    for(ci=0; ci<NUM_COMP; ci++)
     {
         read_buhlmann_times(period);        // 1 or 10 minute(s) interval
 
         // N2
-        temp_tissue = (ppN2 - sim_pres_tissue[ci]) * var_N2_e;
+        temp_tissue = (ppN2 - sim_pres_tissue_N2[ci]) * var_N2_e;
         temp_tissue_safety();
-        sim_pres_tissue[ci] += temp_tissue;
+        sim_pres_tissue_N2[ci] += temp_tissue;
         
         // He
-        temp_tissue = (ppHe - (sim_pres_tissue+16)[ci]) * var_He_e;
+        temp_tissue = (ppHe - sim_pres_tissue_He[ci]) * var_He_e;
         temp_tissue_safety();
-        (sim_pres_tissue+16)[ci] += temp_tissue;
+        sim_pres_tissue_He[ci] += temp_tissue;
     }
 }
 
@@ -1835,10 +1863,10 @@
     sim_lead_tissue_limit = 0.0;
     sim_lead_tissue_no = 0;             // If no one is critic, keep first tissue.
 
-    for(ci=0; ci<16; ci++)
+    for(ci=0; ci<NUM_COMP; ci++)
     {
-        overlay float N2 = sim_pres_tissue[ci];
-        overlay float He = (sim_pres_tissue+16)[ci];
+        overlay float N2 = sim_pres_tissue_N2[ci];
+        overlay float He = sim_pres_tissue_He[ci];
         overlay float p = N2 + He;
 
         read_buhlmann_coefficients();
@@ -1864,7 +1892,7 @@
         }
     } // for ci
 
-    assert( sim_lead_tissue_no < 16 );
+    assert( sim_lead_tissue_no < NUM_COMP );
     assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 );
 }
 
@@ -1877,7 +1905,7 @@
 {
     overlay unsigned char x;
 
-    for(x=0; x<32; ++x)
+    for(x=0; x<NUM_STOPS; ++x)
     {
         internal_deco_time [x] = 0;
         internal_deco_depth[x] = 0;
@@ -1901,7 +1929,7 @@
     assert( temp_depth_limit < 128 );   // Can't be negativ (overflown).
     assert( temp_depth_limit > 0 );     // No stop at surface...
 
-    for(x=0; x<32; ++x)
+    for(x=0; x<NUM_STOPS; ++x)
     {
         // Make sure deco-stops are recorded in order:
         assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) );
@@ -1942,10 +1970,10 @@
 static void calc_gradient_factor(void)
 {
     overlay float gf;
-    overlay float N2 = pres_tissue[char_O_gtissue_no];
-    overlay float He = (pres_tissue+16)[char_O_gtissue_no];
+    overlay float N2 = pres_tissue_N2[char_O_gtissue_no];
+    overlay float He = pres_tissue_He[char_O_gtissue_no];
 
-    assert( char_O_gtissue_no < 16 );
+    assert( char_O_gtissue_no < NUM_COMP );
     assert( 0.800 <= pres_respiration && pres_respiration < 14.0 );
 
 	// tissue > respiration (currently off-gasing)
@@ -2018,6 +2046,8 @@
 //
 void deco_calc_desaturation_time(void)
 {
+    overlay rom const float *ptr;
+
     RESET_C_STACK
 
     assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 );
@@ -2040,21 +2070,27 @@
     int_O_desaturation_time = 0;
     float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101	(70,42%/100.=142)
 
-    for (ci=0;ci<16;ci++)
+    ptr = &buhlmann_ht[0];
+    for(ci=0; ci<NUM_COMP; ci++)
     {
+        overlay float var_N2_halftime = *ptr++;
+        overlay float var_He_halftime = *ptr++;
         overlay unsigned short desat_time;    // For a particular compartiment, in min.
         overlay float temp1;
         overlay float temp2;
         overlay float temp3;
         overlay float temp4;
-    
+
+        assert( 4.0    <= var_N2_halftime && var_N2_halftime <= 635.0 );
+        assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 );
+
         // saturation_time (for flight) and N2_saturation in multiples of halftime
         // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time )
         // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time )
         // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations
         // N2
-        temp1 = 1.05 * ppN2 - pres_tissue[ci];
-        temp2 = ppN2 - pres_tissue[ci];
+        temp1 = 1.05 * ppN2 - pres_tissue_N2[ci];
+        temp2 = ppN2 - pres_tissue_N2[ci];
         if (temp2 >= 0.0)
         {
             temp1 = 0.0;
@@ -2064,9 +2100,6 @@
             temp1 = temp1 / temp2;
         if( 0.0 < temp1 && temp1 < 1.0 )
         {
-            overlay float var_N2_halftime = buhlmann_ht[ci];
-            assert( 4.0 <= var_N2_halftime && var_N2_halftime <= 635.0 );
-
             // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
             // minus because log is negative.
             temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary.
@@ -2080,19 +2113,16 @@
         }
 
         // He
-        temp3 = 0.1 - (pres_tissue+16)[ci];
+        temp3 = 0.1 - pres_tissue_He[ci];
         if (temp3 >= 0.0)
         {
             temp3 = 0.0;
             temp4 = 0.0;
         }
         else
-            temp3 = - temp3 / (pres_tissue+16)[ci];
+            temp3 = - temp3 / pres_tissue_He[ci];
         if( 0.0 < temp3 && temp3 < 1.0 )
     	{
-            overlay float var_He_halftime = (buhlmann_ht+16)[ci];
-            assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 );
-
         	temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary.
         							 // 0.6931 is ln(2), because the math function log() calculates with a base of e  not 2 as requested.
         							 // minus because log is negative
@@ -2114,22 +2144,22 @@
             int_O_desaturation_time = desat_time;
 
         // N2 saturation in multiples of halftime for display purposes
-        temp2 = temp1 * 20.0;  // 0 = 1/8, 120 = 0, 249 = 8
-        temp2 = temp2 + 80.0; // set center
+        temp2 = temp1 * 20.0;   // 0 = 1/8, 120 = 0, 249 = 8
+        temp2 = temp2 + 80.0;   // set center
         if (temp2 < 0.0)
             temp2 = 0.0;
         if (temp2 > 255.0)
             temp2 = 255.0;
-        char_O_tissue_saturation[ci] = (char)temp2;
+        char_O_tissue_N2_saturation[ci] = (char)temp2;
 
         // He saturation in multiples of halftime for display purposes
-        temp4 = temp3 * 20.0;  // 0 = 1/8, 120 = 0, 249 = 8
-        temp4 = temp4 + 80.0; // set center
+        temp4 = temp3 * 20.0;   // 0 = 1/8, 120 = 0, 249 = 8
+        temp4 = temp4 + 80.0;   // set center
         if (temp4 < 0.0)
             temp4 = 0.0;
         if (temp4 > 255.0)
             temp4 = 255.0;
-        (char_O_tissue_saturation+16)[ci] = (char)temp4;
+        char_O_tissue_He_saturation[ci] = (char)temp4;
     } // for
 }
 
@@ -2161,7 +2191,7 @@
     float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101	(70,42%/100.=142)
     float_saturation_multiplier   = char_I_saturation_multiplier   * 0.01;
     
-    calc_tissue(1);  // update the pressure in the 32 tissues in accordance with the new ambient pressure
+    calc_tissue(1);  // update the pressure in the tissues N2/He in accordance with the new ambient pressure
     
     clear_deco_table();
     char_O_deco_status = 3;     // surface new in v.102 : stays in surface state.
@@ -2406,17 +2436,17 @@
 //
 void deco_gas_volumes(void)
 {
-    overlay float volumes[5];
+    overlay float volumes[NUM_GAS];
     overlay float bottom_usage, ascent_usage;
     overlay unsigned char i, deepest_first;
     overlay unsigned char gas;
     RESET_C_STACK
 
     //---- initialize with bottom consumption --------------------------------
-    for(i=0; i<5; ++i)                              // Nothing yet...
+    for(i=0; i<NUM_GAS; ++i)                            // Nothing yet...
         volumes[i] = 0.0;
 
-    assert(1 <= char_I_first_gas && char_I_first_gas <= 5);
+    assert(1 <= char_I_first_gas && char_I_first_gas <= NUM_GAS);
     gas = char_I_first_gas - 1;
 
     bottom_usage = read_custom_function(56) * 0.1;
@@ -2446,7 +2476,7 @@
     else
         volumes[gas] = 65535.0;
 
-    for(i=0; i<32; ++i)
+    for(i=0; i<NUM_STOPS; ++i)
     {
         overlay unsigned char j;
         overlay unsigned char depth, time, ascent;
@@ -2472,7 +2502,7 @@
         }
 
         // Gas switch depth ?
-        for(j=0; j<5; ++j)
+        for(j=0; j<NUM_GAS; ++j)
         {
             if( depth <= char_I_deco_gas_change[j] )
                 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) )
@@ -2494,7 +2524,7 @@
     }
 
     //---- convert results for the ASM interface -----------------------------
-    for(i=0; i<5; ++i)
+    for(i=0; i<NUM_GAS; ++i)
         if( volumes[i] > 6553.4 )
             int_O_gas_volumes[i] = 65535;
         else
@@ -2509,8 +2539,11 @@
     RESET_C_STACK
 
 	cns_vault = CNS_fraction;
-	for (x=0;x<32;x++)
-		pres_tissue_vault[x] = pres_tissue[x];
+	for (x=0;x<NUM_COMP;x++)
+    {
+		pres_tissue_N2_vault[x] = pres_tissue_N2[x];
+		pres_tissue_He_vault[x] = pres_tissue_He[x];
+    }
 }
 
 void deco_pull_tissues_from_vault(void)
@@ -2518,8 +2551,11 @@
     overlay unsigned char x;
     RESET_C_STACK
 
-	for (x=0;x<32;x++)
-		pres_tissue[x] = pres_tissue_vault[x];
+	for (x=0; x<NUM_COMP; x++)
+    {
+		pres_tissue_N2[x] = pres_tissue_N2_vault[x];
+		pres_tissue_He[x] = pres_tissue_He_vault[x];
+    }
     
     // Restore both CNS variable, too.
     CNS_fraction = cns_vault;
Binary file code_part1/OSTC_code_c_part2/p2_deco.o has changed
--- a/code_part1/OSTC_code_c_part2/p2_tables.romdata	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_c_part2/p2_tables.romdata	Sat May 21 14:48:07 2011 +0200
@@ -18,236 +18,117 @@
 // HISTORY
 // 2011-01-20: jDG Cleanup addressing.
 // 2011-02-13: jDG Correct some typos.
+// 2011-05-17: jDG Optimized using interleaved arrays.
 //
 // **************************************************************
 
-rom const float buhlmann_a[32] =
-{	// Data ZH-L16C, from Bühlmann Tauchmedizin 2002, option 1a (4mn)
-//---a for N2 ----------------------------------------------------------------
-	1.2599,
-	1.0000,
-	0.8618,
-	0.7562,
-	0.6200,
-	0.5043,
-	0.4410,
-	0.4000,
-	0.3750,
-	0.3500,
-	0.3295,
-	0.3065,
-	0.2835,
-	0.2610,
-	0.2480,
-	0.2327,
-//---- a of He ---------------------------------------------------------------
-	1.7424,
-	1.3830,
-	1.1919,
-	1.0458,
-	.9220,
-	.8205,
-	.7305,
-	.6502,
-	.5950,
-	.5545,
-	.5333,
-	.5189,
-	.5181,
-	.5176,
-	.5172,
-	.5119
+rom const float buhlmann_ab[] = {
+// Data ZH-L16C, from Bühlmann Tauchmedizin 2002, option 1a (4mn)
+// a for N2    b for N2     a of He     b for He
+	1.2599,     0.5050,     1.7424,     0.4245,
+	1.0000,     0.6514,     1.3830,     0.5747,
+	0.8618,     0.7222,     1.1919,     0.6527,
+	0.7562,     0.7825,     1.0458,     0.7223,
+	0.6200,     0.8126,     0.9220,     0.7582,
+	0.5043,     0.8434,     0.8205,     0.7957,
+	0.4410,     0.8693,     0.7305,     0.8279,
+	0.4000,     0.8910,     0.6502,     0.8553,
+	0.3750,     0.9092,     0.5950,     0.8757,
+	0.3500,     0.9222,     0.5545,     0.8903,
+	0.3295,     0.9319,     0.5333,     0.8997,
+	0.3065,     0.9403,     0.5189,     0.9073,
+	0.2835,     0.9477,     0.5181,     0.9122,
+	0.2610,     0.9544,     0.5176,     0.9171,
+	0.2480,     0.9602,     0.5172,     0.9217,
+	0.2327,     0.9653,     0.5119,     0.9267
 };
 
-rom const float buhlmann_b[] =
-{
-//---- b for N2 --------------------------------------------------------------
-	0.5050,
-	0.6514,
-	0.7222,
-	0.7825,
-	0.8126,
-	0.8434,
-	0.8693,
-	0.8910,
-	0.9092,
-	0.9222,
-	0.9319,
-	0.9403,
-	0.9477,
-	0.9544,
-	0.9602,
-	0.9653,
-//---- b for He --------------------------------------------------------------
-	0.4245,
-	0.5747,
-	0.6527,
-	0.7223,
-	0.7582,
-	0.7957,
-	0.8279,
-	0.8553,
-	0.8757,
-	0.8903,
-	0.8997,
-	0.9073,
-	0.9122,
-	0.9171,
-	0.9217,
-	0.9267
-};
-
-rom const float buhlmann_ht[] =
-{
-//---- N2 --------------------------------------------------------------------
-	4,			// Compartiment half-life, in minute, for nitrogen.
-	8,
-	12,
-	18,
-	27,
-	39,
-	55,
-	77,
-	109,
-	146,
-	187,
-	239,
-	305,
-	390,
-	498,
-	635,
-//---- He --------------------------------------------------------------------
-	1.51,		// Compartiment half-life, in minute, for helium.
-	3.02,
-	4.72,
-	6.99,
-	10.21,
-	14.48,
-	20.53,
-	29.11,
-	41.20,
-	55.19,
-	70.69,
-	90.34,
-	115.29,
-	147.42,
-	188.24,
-	240.03
+rom const float buhlmann_ht[] = {
+// Compartiment half-life, in minute
+//-- N2 ---- He ---------------------------------------------------------------------
+	4,	    1.51,
+	8,      3.02,
+	12,     4.72,
+	18,     6.99,
+	27,    10.21,
+	39,    14.48,
+	55,    20.53,
+	77,    29.11,
+	109,   41.20,
+	146,   55.19,
+	187,   70.69,
+	239,   90.34,
+	305,  115.29,
+	390,  147.42,
+	498,  188.24,
+	635,  240.03
 };
 
-rom const float e2secs[] =
-{ 
-//---- N2 --------------------------------------------------------------------
-	5.75958E-03,  // result of  1 - 2^(-1/(30sec*HT))
-	2.88395E-03,
-	1.92356E-03,
-    1.28278E-03,
-    8.55371E-04,
-    5.92258E-04,
-    4.20001E-04,
-    3.00019E-04,
-    2.11949E-04,
-    1.58240E-04,
-    1.23548E-04,
-    9.66686E-05,
-    7.57509E-05,
-    5.92416E-05,
-    4.63943E-05,
-    3.63850E-05,
-//---- He --------------------------------------------------------------------
-	1.51848E-02,
-    7.62144E-03,
-    4.88315E-03,
-    3.29997E-03,
-    2.26041E-03,
-    1.59437E-03,
-    1.12479E-03,
-    7.93395E-04,
-    5.60641E-04,
-    4.18555E-04,
-    3.26795E-04,
-    2.55722E-04,
-    2.00387E-04,
-    1.56716E-04,
-    1.22734E-04,
-    9.62538E-05
+rom const float e2secs[] = {
+// result of  1 - 2^(-1/(30sec*HT))
+//---- N2 ------------- He ------------
+	5.75958E-03,    1.51848E-02,  
+	2.88395E-03,    7.62144E-03,
+	1.92356E-03,    4.88315E-03,
+    1.28278E-03,    3.29997E-03,
+    8.55371E-04,    2.26041E-03,
+    5.92258E-04,    1.59437E-03,
+    4.20001E-04,    1.12479E-03,
+    3.00019E-04,    7.93395E-04,
+    2.11949E-04,    5.60641E-04,
+    1.58240E-04,    4.18555E-04,
+    1.23548E-04,    3.26795E-04,
+    9.66686E-05,    2.55722E-04,
+    7.57509E-05,    2.00387E-04,
+    5.92416E-05,    1.56716E-04,
+    4.63943E-05,    1.22734E-04,
+    3.63850E-05,    9.62538E-05
+//-------------------------------------
 };
 
-rom const float e1min[] =
-{
-//---- N2 --------------------------------------------------------------------
-	1.59104E-01,     	// Integration constant for 1 minute,
-    8.29960E-02,        // Ie. 1- 2^(-1/HT)
-    5.61257E-02,
-    3.77762E-02,
-    2.53454E-02,
-    1.76160E-02,
-    1.25236E-02,
-    8.96152E-03,
-    6.33897E-03,
-    4.73633E-03,
-    3.69981E-03,
-    2.89600E-03,
-    2.27003E-03,
-    1.77572E-03,
-    1.39089E-03,
-    1.09097E-03,
-//---- e 1min He -------------------------------------------------------------
-	3.68109E-01,
-	2.05084E-01,
-    1.36579E-01,
-    9.44046E-02,
-    6.56359E-02,
-    4.67416E-02,
-    3.31991E-02,
-    2.35301E-02,
-    1.66832E-02,
-    1.24808E-02,
-    9.75753E-03,
-    7.64329E-03,
-    5.99417E-03,
-    4.69082E-03,
-    3.67548E-03,
-    2.88359E-03
+rom const float e1min[] = {
+// Integration constant for 1 minute,
+// Ie. 1- 2^(-1/HT)
+//----- N2 --------- e 1min He --------
+	1.59104E-01,    3.68109E-01,  	
+    8.29960E-02,   	2.05084E-01,     
+    5.61257E-02,    1.36579E-01,
+    3.77762E-02,    9.44046E-02,
+    2.53454E-02,    6.56359E-02,
+    1.76160E-02,    4.67416E-02,
+    1.25236E-02,    3.31991E-02,
+    8.96152E-03,    2.35301E-02,
+    6.33897E-03,    1.66832E-02,
+    4.73633E-03,    1.24808E-02,
+    3.69981E-03,    9.75753E-03,
+    2.89600E-03,    7.64329E-03,
+    2.27003E-03,    5.99417E-03,
+    1.77572E-03,    4.69082E-03,
+    1.39089E-03,    3.67548E-03,
+    1.09097E-03,    2.88359E-03
+//-------------------------------------
 };
 
-rom const float e10min[] =
-{
-//---- N2 --------------------------------------------------------------------
+rom const float e10min[] = {
 // The 10 min Value in float notation:
 //  result of 1 - 2^(-10/ht)
-	8.23223E-01,			// 1 - 2^(-10/4.0)
-	5.79552E-01,
-    4.38769E-01,
-    3.19605E-01,
-    2.26416E-01,
-    1.62832E-01,
-    1.18409E-01,
-    8.60863E-02,
-    6.16117E-02,
-    4.63665E-02,
-    3.63881E-02,
-    2.85855E-02,
-    2.24698E-02,
-    1.76160E-02,
-    1.38222E-02,
-    1.08563E-02,
-//---- He --------------------------------------------------------------------
-	9.89851E-01,
-	8.99258E-01,
-    7.69737E-01,
-    6.29027E-01,
-    4.92821E-01,
-    3.80407E-01,
-    2.86538E-01,
-    2.11886E-01,
-    1.54849E-01,
-    1.18026E-01,
-    9.34005E-02,
-    7.38569E-02,
-    5.83504E-02,
-    4.59303E-02,
-    3.61528E-02,
-    2.84646E-02
+//---- N2 -------------- He -----------
+	8.23223E-01,    9.89851E-01,  
+	5.79552E-01,  	8.99258E-01,
+    4.38769E-01,    7.69737E-01,
+    3.19605E-01,    6.29027E-01,
+    2.26416E-01,    4.92821E-01,
+    1.62832E-01,    3.80407E-01,
+    1.18409E-01,    2.86538E-01,
+    8.60863E-02,    2.11886E-01,
+    6.16117E-02,    1.54849E-01,
+    4.63665E-02,    1.18026E-01,
+    3.63881E-02,    9.34005E-02,
+    2.85855E-02,    7.38569E-02,
+    2.24698E-02,    5.83504E-02,
+    1.76160E-02,    4.59303E-02,
+    1.38222E-02,    3.61528E-02,
+    1.08563E-02,    2.84646E-02
+//-------------------------------------
 };
 
--- a/code_part1/OSTC_code_c_part2/shared_definitions.h	Tue May 17 01:05:04 2011 +0200
+++ b/code_part1/OSTC_code_c_part2/shared_definitions.h	Sat May 21 14:48:07 2011 +0200
@@ -74,6 +74,21 @@
 bank2   udata_ovr  0x200
 #endif
 
+#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+    Define model dimensions.
+    NUM_COMP  is the number of compartiments in the Bühlmann ZH-L16 model, ie 16.
+    NUM_STOPS is the maximum number of stops computed by decoplanning. 
+              Note that the deapest stop is roughly limited to 3m * NUM_STOPS
+                   (this is assuming all stops up to the surface are used).
+              Note also that if the table overflow, extra stops are ignored,
+                   and not reported in TTS summing.
+    NUM_GAS   is the number of (potentially) active gas considered during
+              ascent simulation.
+#endif
+#define NUM_COMP    0x10
+#define NUM_STOPS   0x20
+#define NUM_GAS     5
+
 VAR_UINT  (int_O_gtissue_limit);
 VAR_UINT  (int_O_gtissue_press);
 VAR_UINT  (int_O_desaturation_time);       // 
@@ -94,10 +109,11 @@
 
 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_depth, NUM_STOPS);   // Fusionned decompression table:
+TAB_UCHAR (char_O_deco_time,  NUM_STOPS);   // Both ZH-L16 and L16-GF models.
 
-TAB_UCHAR (char_O_tissue_saturation, 0x20); // Compartiment desaturation time, in min.
+TAB_UCHAR (char_O_tissue_N2_saturation, NUM_COMP); // Nitrogen compartiment desaturation time, in min.
+TAB_UCHAR (char_O_tissue_He_saturation, NUM_COMP); // Helium compartiment desaturation time, in min.
 
 VAR_UINT  (int_O_DBS_bitfield);             // NOTE: 9 bytes dumped to divelog by store_dive_decodebug
 VAR_UINT  (int_O_DBS2_bitfield);
@@ -140,9 +156,9 @@
 VAR_UCHAR (char_I_bottom_depth);           // Bottom depth for planning (used in gas volume evaluation).
 VAR_UCHAR (char_I_bottom_time);            // Bottom time for planning (used in gas volume evaluation).
 
-TAB_UCHAR (char_I_deco_gas_change, 5);     // new in v.101
-TAB_UCHAR (char_I_deco_N2_ratio, 5);       // new in v.101
-TAB_UCHAR (char_I_deco_He_ratio, 5);       // new in v.101
+TAB_UCHAR (char_I_deco_gas_change,NUM_GAS);// new in v.101
+TAB_UCHAR (char_I_deco_N2_ratio, NUM_GAS); // new in v.101
+TAB_UCHAR (char_I_deco_He_ratio, NUM_GAS); // new in v.101
 
 #ifdef __18CXX
 //----------------------------------------------------------------------------