diff src/divemode.asm @ 480:ad8acade5567

NEW: PSCR mode (Passive semi-closed rebreather)
author heinrichsweikamp
date Mon, 06 Feb 2017 16:26:36 +0100
parents c6f36c55b4f6
children c0ee33f1f399
line wrap: on
line diff
--- a/src/divemode.asm	Wed Feb 01 13:51:59 2017 +0100
+++ b/src/divemode.asm	Mon Feb 06 16:26:36 2017 +0100
@@ -226,7 +226,8 @@
 	return
 
 ; Calculate CNS
-    rcall   set_actual_ppo2             ; Set char_I_actual_ppO2
+    btfss   FLAG_pscr_mode		; in PSCR mode?
+    rcall   set_actual_ppo2             ; No, set char_I_actual_ppO2
     clrf    WREG
     movff   WREG,char_I_step_is_1min    ; Make sure to be in 2sec mode.
 	call	deco_calc_CNS_fraction		; calculate CNS
@@ -315,10 +316,43 @@
 	clrf	WREG
 	movff	WREG,char_I_step_is_1min    ; Force 2 second deco mode
 
+	movff	char_I_O2_ratio,lo_temp		; Backup original value for everything
+	movff	char_I_N2_ratio,hi_temp		; Backup original value for everything
+	
+	btfss	FLAG_pscr_mode
+	bra	calc_deko_divemode2a	    ; Non-PSCR modes...
+	
+	; in PSCR mode, compute fO2 into char_I_O2_ratio
+	call		compute_pscr_ppo2	; pSCR ppO2 into sub_c:2
+	movff		sub_c+0,xA+0
+	movff		sub_c+1,xA+1
+	movlw		LOW		.10
+	movwf		xB+0
+	movlw		HIGH	.10
+	movwf		xB+1
+	call		mult16x16		;xA*xB=xC	-> xC:4 = ppO2*10
+	SAFE_2BYTE_COPY amb_pressure, xB
+	call		div32x16	 	; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
+	; xC+0 has O2 in percent
+	movff	xC+0,char_I_O2_ratio
+
+	movff	char_I_He_ratio, wait_temp	; copy into bank1 register
+	bsf	STATUS,C			; Borrow bit
+	movlw	d'100'				; 100%
+	subfwb	wait_temp,W			; minus He
+	bsf	STATUS,C			; Borrow bit
+	subfwb	xC+0,W				; minus O2
+	movff	WREG, char_I_N2_ratio		; = N2!
+	
+calc_deko_divemode2a:
     clrf    TMR5L
     clrf    TMR5H                       ; 30,51757813µs/bit in TMR5L:TMR5H
 	call	deco_calc_hauptroutine		; calc_tissue
     movlb   .1
+    
+  	movff	lo_temp,char_I_O2_ratio		; Restore original value for everything
+	movff	hi_temp,char_I_N2_ratio		; Restore original value for everything
+
 
     movff   char_O_deco_status,WREG     ; Is a compute cycle finished ?
     iorwf   WREG,F
@@ -1677,18 +1711,39 @@
 
 
 check_ppO2:							    ; check current ppO2 and display warning if required
-    SAFE_2BYTE_COPY amb_pressure, xA
-	movlw	d'10'
-	movwf	xB+0
-	clrf	xB+1
-	call	div16x16				; xC=p_amb/10
+    btfss	FLAG_pscr_mode
+    bra			check_ppO2_non_pscr		; Non-PSCR modes...
+    	; in PSCR mode
+    call		compute_pscr_ppo2		; pSCR ppO2 into sub_c:2
+    movff		sub_c+0,xA+0
+    movff		sub_c+1,xA+1
+    movlw		d'100'
+    movwf		xB+0
+    clrf		xB+1
+    call		div16x16				; /100
+    tstfsz      xC+1                    ; Is ppO2 > 2.55bar ?
+    setf        xC+0                    ; yes: bound to 2.55... better than wrap around.
+    movff		xC+0,char_I_actual_ppO2	; copy last ppO2 to buffer register (for pSCR CNS)
+    clrf		xC+2
+    clrf		xC+3
+    movff		sub_c+0,xC+0
+    movff		sub_c+1,xC+1			; copy for comptibility
+    bra			check_ppO2_check
 
-	movff	xC+0,xA+0
-	movff	xC+1,xA+1
+check_ppO2_non_pscr:    
+    SAFE_2BYTE_COPY amb_pressure, xA
+    movlw	d'10'
+    movwf	xB+0
+    clrf	xB+1
+    call	div16x16				; xC=p_amb/10
+
+    movff	xC+0,xA+0
+    movff	xC+1,xA+1
     movff   char_I_O2_ratio,xB+0    ; =O2 ratio
-	clrf	xB+1
-	call	mult16x16               ; char_I_O2_ratio * p_amb/10
+    clrf	xB+1
+    call	mult16x16               ; char_I_O2_ratio * p_amb/10
 
+check_ppO2_check:
     ; Check very high ppO2 manually
 	tstfsz	xC+2				; char_I_O2_ratio * p_amb/10 > 65536, ppO2>6,55bar?
 	bra		check_ppO2_1		; Yes, display Value!