comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 344:797e2ac42d24 ScreenDump

MERGE with 1.91 main trunk.
author JeanDo
date Sat, 21 May 2011 14:48:07 +0200
parents ecbbbd423e86
children b5b030c1ae7e
comparison
equal deleted inserted replaced
337:6bdf80d7276c 344:797e2ac42d24
75 // 2011/04/10: [jDG] Use timer TMR3 to limit loops in calc_hauptroutine_calc_deco(). 75 // 2011/04/10: [jDG] Use timer TMR3 to limit loops in calc_hauptroutine_calc_deco().
76 // 2011/04/15: [jDG] Store low_depth in 32bits (w/o rounding), for a better stability. 76 // 2011/04/15: [jDG] Store low_depth in 32bits (w/o rounding), for a better stability.
77 // 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for decoplanning. 77 // 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for decoplanning.
78 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor. 78 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor.
79 // 2011/05/02: [jDG] Added "Future TTS" function (CF58). 79 // 2011/05/02: [jDG] Added "Future TTS" function (CF58).
80 // 2011/05/17: [jDG] Various cleanups.
80 // 81 //
81 // TODO: 82 // TODO:
82 // + Allow to abort MD2 calculation (have to restart next time). 83 // + Allow to abort MD2 calculation (have to restart next time).
83 // 84 //
84 // Literature: 85 // Literature:
161 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure. 162 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure.
162 163
163 // Real context: what we are doing now. 164 // Real context: what we are doing now.
164 static float calc_lead_tissue_limit; // 165 static float calc_lead_tissue_limit; //
165 166
166 static unsigned char internal_deco_time[32]; 167 static unsigned char internal_deco_time[NUM_STOPS];
167 static unsigned char internal_deco_depth[32]; 168 static unsigned char internal_deco_depth[NUM_STOPS];
168 169
169 static float cns_vault; 170 static float cns_vault;
170 static float pres_tissue_vault[32]; 171 static float pres_tissue_N2_vault[NUM_COMP];
172 static float pres_tissue_He_vault[NUM_COMP];
171 173
172 //---- Bank 5 parameters ----------------------------------------------------- 174 //---- Bank 5 parameters -----------------------------------------------------
173 #pragma udata bank5=0x500 175 #pragma udata bank5=0x500
174 176
175 static unsigned char ci; 177 static unsigned char ci;
186 static float var_He_a; // Bühlmann a, for current He tissue. 188 static float var_He_a; // Bühlmann a, for current He tissue.
187 static float var_He_b; // Bühlmann b, for current He tissue. 189 static float var_He_b; // Bühlmann b, for current He tissue.
188 static float var_N2_e; // Exposition, for current N2 tissue. 190 static float var_N2_e; // Exposition, for current N2 tissue.
189 static float var_He_e; // Exposition, for current He tissue. 191 static float var_He_e; // Exposition, for current He tissue.
190 192
191 static float pres_diluent; // new in v.101 193 static float pres_diluent; // new in v.101
192 static float const_ppO2; // new in v.101 194 static float const_ppO2; // new in v.101
193 195
194 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch. 196 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch.
195 static unsigned char sim_gas_last_used; // Number of last used gas, to detected a gas switch. 197 static unsigned char sim_gas_last_used; // Number of last used gas, to detected a gas switch.
196 static unsigned short sim_gas_delay; // Time of gas-switch-stop ends [min on dive]. 198 static unsigned short sim_gas_delay; // Time of gas-switch-stop ends [min on dive].
197 static unsigned short sim_dive_mins; // Simulated dive time. 199 static unsigned short sim_dive_mins; // Simulated dive time.
198 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. 200 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio.
199 static float calc_He_ratio; // Simulated (switched) helium ratio. 201 static float calc_He_ratio; // Simulated (switched) helium ratio.
200 static float CNS_fraction; // new in v.101 202 static float CNS_fraction; // new in v.101
201 static float float_saturation_multiplier; // new in v.101 203 static float float_saturation_multiplier; // new in v.101
202 static float float_desaturation_multiplier; // new in v.101 204 static float float_desaturation_multiplier; // new in v.101
203 static float float_deco_distance; // new in v.101 205 static float float_deco_distance; // new in v.101
204 static char flag_in_divemode; // new in v.108 206 static char flag_in_divemode; // new in v.108
205 207
206 static unsigned char deco_gas_change[5]; // new in v.109 208 static unsigned char deco_gas_change[NUM_GAS]; // new in v.109
207 209
208 //---- Bank 6 parameters ----------------------------------------------------- 210 //---- Bank 6 parameters -----------------------------------------------------
209 #pragma udata bank6=0x600 211 #pragma udata bank6=0x600
210 212
211 float pres_tissue[32]; 213 float pres_tissue_N2[NUM_COMP];
214 float pres_tissue_He[NUM_COMP];
212 215
213 //---- Bank 7 parameters ----------------------------------------------------- 216 //---- Bank 7 parameters -----------------------------------------------------
214 #pragma udata bank7=0x700 217 #pragma udata bank7=0x700
215 218
216 float sim_pres_tissue[32]; // 32 floats = 128 bytes. 219 float sim_pres_tissue_N2[NUM_COMP]; // 32 floats = 128 bytes.
217 static float sim_pres_tissue_backup[32]; 220 float sim_pres_tissue_He[NUM_COMP]; // 32 floats = 128 bytes.
221 static float sim_pres_tissue_backup_N2[NUM_COMP];
222 static float sim_pres_tissue_backup_He[NUM_COMP];
218 223
219 //---- Bank 8 parameters ----------------------------------------------------- 224 //---- Bank 8 parameters -----------------------------------------------------
220 #pragma udata bank8=0x800 225 #pragma udata bank8=0x800
221 226
222 static char md_pi_subst[256]; 227 static char md_pi_subst[256];
326 //---- Setup some error (?) conditions ----------------------------------- 331 //---- Setup some error (?) conditions -----------------------------------
327 if(char_I_deco_model) 332 if(char_I_deco_model)
328 int_O_DBS_bitfield |= DBS_mode; 333 int_O_DBS_bitfield |= DBS_mode;
329 if(const_ppO2) 334 if(const_ppO2)
330 int_O_DBS_bitfield |= DBS_ppO2; 335 int_O_DBS_bitfield |= DBS_ppO2;
331 for(i = 16; i < 32; i++) 336 for(i = 0; i < NUM_COMP; i++)
332 if(pres_tissue[i]) 337 if(pres_tissue_He[i])
333 int_O_DBS_bitfield |= DBS_HE_sat; 338 int_O_DBS_bitfield |= DBS_HE_sat;
334 if(float_saturation_multiplier < 0.99) 339 if(float_saturation_multiplier < 0.99)
335 int_O_DBS_bitfield |= DBS_SAT2l; 340 int_O_DBS_bitfield |= DBS_SAT2l;
336 if(float_saturation_multiplier > 1.3) 341 if(float_saturation_multiplier > 1.3)
337 int_O_DBS_bitfield |= DBS_SAT2h; 342 int_O_DBS_bitfield |= DBS_SAT2h;
415 temp_DBS |= DBG_C_MODE; 420 temp_DBS |= DBG_C_MODE;
416 if(DBG_pres_surface != pres_surface) 421 if(DBG_pres_surface != pres_surface)
417 temp_DBS |= DBG_C_SURF; 422 temp_DBS |= DBG_C_SURF;
418 423
419 if( !DBS_HE_sat && !He_ratio) 424 if( !DBS_HE_sat && !He_ratio)
420 for(i = 16; i < 32; i++) 425 for(i = 0; i < NUM_COMP; i++)
421 if(pres_tissue[i]) 426 if(pres_tissue_He[i])
422 temp_DBS |= DBG_HEwoHE; 427 temp_DBS |= DBG_HEwoHE;
423 428
424 if( DBG_deco_gas_change != deco_gas_change[0] 429 if( DBG_deco_gas_change != deco_gas_change[0]
425 || DBG_deco_N2_ratio != char_I_deco_N2_ratio[0] 430 || DBG_deco_N2_ratio != char_I_deco_N2_ratio[0]
426 || DBG_deco_He_ratio != char_I_deco_He_ratio[0] ) 431 || DBG_deco_He_ratio != char_I_deco_He_ratio[0] )
547 ////////////////////////////////////////////////////////////////////////////// 552 //////////////////////////////////////////////////////////////////////////////
548 // read buhlmann tables A and B for compatriment ci 553 // read buhlmann tables A and B for compatriment ci
549 // 554 //
550 static void read_buhlmann_coefficients(void) 555 static void read_buhlmann_coefficients(void)
551 { 556 {
557
552 #ifndef CROSS_COMPILE 558 #ifndef CROSS_COMPILE
553 // Note: we don't use far rom pointer, because the 559 // Note: we don't use far rom pointer, because the
554 // 24 bits is to complex, hence we have to set 560 // 24 bits is too complex, hence we have to set
555 // the UPPER page ourself... 561 // the UPPER page ourself...
556 // --> Set zero if tables are moved to lower pages ! 562 // --> Set zero if tables are moved to lower pages !
557 _asm 563 _asm
558 movlw 1 564 movlw 1
559 movwf TBLPTRU,0 565 movwf TBLPTRU,0
560 _endasm 566 _endasm
561 #endif 567 #endif
562 568
563 assert( 0 <= ci && ci < 16 ); 569 assert( 0 <= ci && ci < NUM_COMP );
564 var_N2_a = buhlmann_a[ci]; 570
565 var_N2_b = buhlmann_b[ci]; 571 // Use an interleaved array (AoS) to access coefficients with a
566 var_He_a = (buhlmann_a+16)[ci]; 572 // single addressing.
567 var_He_b = (buhlmann_b+16)[ci]; 573 {
574 overlay rom const float* ptr = &buhlmann_ab[4*ci];
575 var_N2_a = *ptr++;
576 var_N2_b = *ptr++;
577 var_He_a = *ptr++;
578 var_He_b = *ptr++;
579 }
568 580
569 // Check reading consistency: 581 // Check reading consistency:
570 if( (var_N2_a < 0.231) 582 if( (var_N2_a < 0.231)
571 || (var_N2_a > 1.27) 583 || (var_N2_a > 1.27)
572 || (var_N2_b < 0.504) 584 || (var_N2_b < 0.504)
594 _asm 606 _asm
595 movlw 1 607 movlw 1
596 movwf TBLPTRU,0 608 movwf TBLPTRU,0
597 _endasm 609 _endasm
598 #endif 610 #endif
599 assert( 0 <= ci && ci < 16 ); 611
612 assert( 0 <= ci && ci < NUM_COMP );
600 613
601 // Integration intervals. 614 // Integration intervals.
602 switch(period) 615 switch(period)
603 { 616 {
604 case 0: //---- 2 sec ----------------------------------------------------- 617 case 0: //---- 2 sec -----------------------------------------------------
605 var_N2_e = e2secs[ci]; 618 {
606 var_He_e = (e2secs+16)[ci]; 619 overlay rom const float* ptr = &e2secs[2*ci];
620 var_N2_e = *ptr++;
621 var_He_e = *ptr++;
622 }
607 623
608 // Check reading consistency: 624 // Check reading consistency:
609 if( (var_N2_e < 0.0000363) 625 if( (var_N2_e < 0.0000363)
610 || (var_N2_e > 0.00577) 626 || (var_N2_e > 0.00577)
611 || (var_He_e < 0.0000961) 627 || (var_He_e < 0.0000961)
614 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; 630 int_O_DBG_pre_bitfield |= DBG_ZH16ERR;
615 631
616 break; 632 break;
617 633
618 case 1: //---- 1 min ----------------------------------------------------- 634 case 1: //---- 1 min -----------------------------------------------------
619 var_N2_e = e1min[ci]; 635 {
620 var_He_e = (e1min+16)[ci]; 636 overlay rom const float* ptr = &e1min[2*ci];
637 var_N2_e = *ptr++;
638 var_He_e = *ptr++;
639 }
621 640
622 // Check reading consistency: 641 // Check reading consistency:
623 if( (var_N2_e < 1.09E-3) 642 if( (var_N2_e < 1.09E-3)
624 || (var_N2_e > 0.1592) 643 || (var_N2_e > 0.1592)
625 || (var_He_e < 0.00288) 644 || (var_He_e < 0.00288)
628 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; 647 int_O_DBG_pre_bitfield |= DBG_ZH16ERR;
629 648
630 break; 649 break;
631 650
632 case 2: //---- 10 min ---------------------------------------------------- 651 case 2: //---- 10 min ----------------------------------------------------
633 var_N2_e = e10min[ci]; 652 {
634 var_He_e = (e10min+16)[ci]; 653 overlay rom const float* ptr = &e10min[2*ci];
654 var_N2_e = *ptr++;
655 var_He_e = *ptr++;
656 }
635 657
636 // Check reading consistency: 658 // Check reading consistency:
637 if( (var_N2_e < 0.01085) 659 if( (var_N2_e < 0.01085)
638 || (var_N2_e > 0.82323) 660 || (var_N2_e > 0.82323)
639 || (var_He_e < 0.02846) 661 || (var_He_e < 0.02846)
647 assert(0); // Never go there... 669 assert(0); // Never go there...
648 } 670 }
649 } 671 }
650 672
651 ////////////////////////////////////////////////////////////////////////////// 673 //////////////////////////////////////////////////////////////////////////////
652 // calc_next_decodepth_GF 674 // calc_nextdecodepth
653 // 675 //
654 // new in v.102 676 // new in v.102
655 // 677 //
656 // INPUT, changing during dive: 678 // INPUT, changing during dive:
657 // low_depth 679 // low_depth
831 if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------ 853 if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------
832 { 854 {
833 overlay unsigned char x, y; 855 overlay unsigned char x, y;
834 856
835 //---- First: search the first non-null depth 857 //---- First: search the first non-null depth
836 for(x=31; x != 0; --x) 858 for(x=(NUM_STOPS-1); x != 0; --x)
837 if( internal_deco_depth[x] != 0 ) break; 859 if( internal_deco_depth[x] != 0 ) break;
838 860
839 //---- Second: copy to output table (in reverse order) 861 //---- Second: copy to output table (in reverse order)
840 for(y=0; y<32; y++, --x) 862 for(y=0; y<NUM_STOPS; y++, --x)
841 { 863 {
842 char_O_deco_depth[y] = internal_deco_depth[x]; 864 char_O_deco_depth[y] = internal_deco_depth[x];
843 char_O_deco_time [y] = internal_deco_time [x]; 865 char_O_deco_time [y] = internal_deco_time [x];
844 866
845 // Stop only once the last transfer is done. 867 // Stop only once the last transfer is done.
846 if( x == 0 ) break; 868 if( x == 0 ) break;
847 } 869 }
848 870
849 //---- Third: fill table end with null 871 //---- Third: fill table end with null
850 for(y++; y<32; y++) 872 for(y++; y<NUM_STOPS; y++)
851 { 873 {
852 char_O_deco_time [y] = 0; 874 char_O_deco_time [y] = 0;
853 char_O_deco_depth[y] = 0; 875 char_O_deco_depth[y] = 0;
854 } 876 }
855 } 877 }
856 else //---- Straight copy ------------------------------------------------ 878 else //---- Straight copy ------------------------------------------------
857 { 879 {
858 overlay unsigned char x; 880 overlay unsigned char x;
859 881
860 for(x=0; x<32; x++) 882 for(x=0; x<NUM_STOPS; x++)
861 { 883 {
862 char_O_deco_depth[x] = internal_deco_depth[x]; 884 char_O_deco_depth[x] = internal_deco_depth[x];
863 char_O_deco_time [x] = internal_deco_time [x]; 885 char_O_deco_time [x] = internal_deco_time [x];
864 } 886 }
865 } 887 }
958 { 980 {
959 overlay unsigned char j; 981 overlay unsigned char j;
960 overlay unsigned char N2 = (unsigned char)(N2_ratio * 100 + 0.5); 982 overlay unsigned char N2 = (unsigned char)(N2_ratio * 100 + 0.5);
961 overlay unsigned char He = (unsigned char)(He_ratio * 100 + 0.5); 983 overlay unsigned char He = (unsigned char)(He_ratio * 100 + 0.5);
962 984
963 for(j=0; j<5; ++j) 985 for(j=0; j<NUM_GAS; ++j)
964 { 986 {
965 // Make sure to detect if we are already breathing some gas in 987 // Make sure to detect if we are already breathing some gas in
966 // the current list (happends when first gas do have a depth). 988 // the current list (happends when first gas do have a depth).
967 if( N2 == char_I_deco_N2_ratio[j] 989 if( N2 == char_I_deco_N2_ratio[j]
968 && He == char_I_deco_He_ratio[j] 990 && He == char_I_deco_He_ratio[j]
983 assert( depth < 130 ); 1005 assert( depth < 130 );
984 1006
985 // And if I'm above the last decostop (with the 3m margin) ? 1007 // And if I'm above the last decostop (with the 3m margin) ?
986 if( (sim_gas_last_depth-3) > depth ) 1008 if( (sim_gas_last_depth-3) > depth )
987 { 1009 {
988 for(j=0; j<5; ++j) 1010 for(j=0; j<NUM_GAS; ++j)
989 { 1011 {
990 // And If I am in the range of a valide stop ? 1012 // And If I am in the range of a valide stop ?
991 // (again, with the same 3m margin) 1013 // (again, with the same 3m margin)
992 if( char_I_deco_gas_change[j] 1014 if( char_I_deco_gas_change[j]
993 && depth <= char_I_deco_gas_change[j] 1015 && depth <= char_I_deco_gas_change[j]
1032 if (char_I_const_ppO2 == 0) 1054 if (char_I_const_ppO2 == 0)
1033 { 1055 {
1034 overlay unsigned char j; 1056 overlay unsigned char j;
1035 1057
1036 // Loop over all enabled gas, to find the deepest one, 1058 // Loop over all enabled gas, to find the deepest one,
1037 // above las gas, but below temp_depth_limit. 1059 // above last used gas, but below temp_depth_limit.
1038 for(j=0; j<5; ++j) 1060 for(j=0; j<NUM_GAS; ++j)
1039 { 1061 {
1040 // Gas not (yet) allowed ? Skip ! 1062 // Gas not (yet) allowed ? Skip !
1041 if( temp_depth_limit > deco_gas_change[j] ) 1063 if( temp_depth_limit > deco_gas_change[j] )
1042 continue; 1064 continue;
1043 1065
1090 // 1112 //
1091 // Output: calc_N2_ratio, calc_He_ratio 1113 // Output: calc_N2_ratio, calc_He_ratio
1092 // 1114 //
1093 static void gas_switch_set(void) 1115 static void gas_switch_set(void)
1094 { 1116 {
1095 assert( 0 <= sim_gas_last_used && sim_gas_last_used <= 5 ); 1117 assert( 0 <= sim_gas_last_used && sim_gas_last_used <= NUM_GAS );
1096 1118
1097 if( sim_gas_last_used == 0 ) 1119 if( sim_gas_last_used == 0 )
1098 { 1120 {
1099 calc_N2_ratio = N2_ratio; 1121 calc_N2_ratio = N2_ratio;
1100 calc_He_ratio = He_ratio; 1122 calc_He_ratio = He_ratio;
1175 1197
1176 // Kludge: the 0.0002 of 0.7902 are missing with standard air. 1198 // Kludge: the 0.0002 of 0.7902 are missing with standard air.
1177 N2_ratio = 0.7902; 1199 N2_ratio = 0.7902;
1178 pres_respiration = int_I_pres_respiration * 0.001; 1200 pres_respiration = int_I_pres_respiration * 0.001;
1179 1201
1180 for(ci=0; ci<16; ci++) 1202 for(ci=0; ci<NUM_COMP; ci++)
1181 { 1203 {
1182 // cycle through the 16 Bühlmann tissues 1204 // cycle through the 16 Bühlmann tissues
1183 overlay float p = N2_ratio * (pres_respiration - ppWater); 1205 overlay float p = N2_ratio * (pres_respiration - ppWater);
1184 pres_tissue[ci] = p; 1206 pres_tissue_N2[ci] = p;
1185 1207
1186 // cycle through the 16 Bühlmann tissues for Helium 1208 // cycle through the 16 Bühlmann tissues for Helium
1187 (pres_tissue+16)[ci] = 0.0; 1209 pres_tissue_He[ci] = 0.0;
1188 } // for 0 to 16 1210 } // for 0 to 15
1189 1211
1190 clear_deco_table(); 1212 clear_deco_table();
1191 char_O_deco_status = 0; 1213 char_O_deco_status = 0;
1192 char_O_nullzeit = 0; 1214 char_O_nullzeit = 0;
1193 int_O_ascenttime = 0; 1215 int_O_ascenttime = 0;
1444 1466
1445 // Calc limit for surface, ie. GF_high. 1467 // Calc limit for surface, ie. GF_high.
1446 calc_limit(); 1468 calc_limit();
1447 1469
1448 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000); 1470 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000);
1449 int_O_gtissue_press = (short)((pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]) * 1000); 1471 int_O_gtissue_press = (short)((pres_tissue_N2[char_O_gtissue_no] + pres_tissue_He[char_O_gtissue_no]) * 1000);
1450 1472
1451 // if guiding tissue can not be exposed to surface pressure immediately 1473 // if guiding tissue can not be exposed to surface pressure immediately
1452 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) 1474 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0)
1453 { 1475 {
1454 char_O_nullzeit = 0; // deco necessary 1476 char_O_nullzeit = 0; // deco necessary
1614 static void calc_tissue(PARAMETER unsigned char period) 1636 static void calc_tissue(PARAMETER unsigned char period)
1615 { 1637 {
1616 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m 1638 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m
1617 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m 1639 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m
1618 1640
1619 for (ci=0;ci<16;ci++) 1641 for (ci=0;ci<NUM_COMP;ci++)
1620 { 1642 {
1621 read_buhlmann_times(period); // 2 sec or 1 min period. 1643 read_buhlmann_times(period); // 2 sec or 1 min period.
1622 1644
1623 // N2 1645 // N2
1624 temp_tissue = (ppN2 - pres_tissue[ci]) * var_N2_e; 1646 temp_tissue = (ppN2 - pres_tissue_N2[ci]) * var_N2_e;
1625 temp_tissue_safety(); 1647 temp_tissue_safety();
1626 pres_tissue[ci] += temp_tissue; 1648 pres_tissue_N2[ci] += temp_tissue;
1627 1649
1628 // He 1650 // He
1629 temp_tissue = (ppHe - (pres_tissue+16)[ci]) * var_He_e; 1651 temp_tissue = (ppHe - pres_tissue_He[ci]) * var_He_e;
1630 temp_tissue_safety(); 1652 temp_tissue_safety();
1631 (pres_tissue+16)[ci] += temp_tissue; 1653 pres_tissue_He[ci] += temp_tissue;
1632 } 1654 }
1633 } 1655 }
1634 1656
1635 ////////////////////////////////////////////////////////////////////////////// 1657 //////////////////////////////////////////////////////////////////////////////
1636 // calc_limit 1658 // calc_limit
1640 static void calc_limit(void) 1662 static void calc_limit(void)
1641 { 1663 {
1642 char_O_gtissue_no = 255; 1664 char_O_gtissue_no = 255;
1643 calc_lead_tissue_limit = 0.0; 1665 calc_lead_tissue_limit = 0.0;
1644 1666
1645 for(ci=0; ci<16;ci++) 1667 for(ci=0; ci<NUM_COMP;ci++)
1646 { 1668 {
1647 overlay float N2 = pres_tissue[ci]; 1669 overlay float N2 = pres_tissue_N2[ci];
1648 overlay float He = (pres_tissue+16)[ci]; 1670 overlay float He = pres_tissue_He[ci];
1649 overlay float p = N2 + He; 1671 overlay float p = N2 + He;
1650 1672
1651 read_buhlmann_coefficients(); 1673 read_buhlmann_coefficients();
1652 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; 1674 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p;
1653 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; 1675 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p;
1673 char_O_gtissue_no = ci; 1695 char_O_gtissue_no = ci;
1674 calc_lead_tissue_limit = p; 1696 calc_lead_tissue_limit = p;
1675 } 1697 }
1676 } 1698 }
1677 1699
1678 assert( char_O_gtissue_no < 16 ); 1700 assert( char_O_gtissue_no < NUM_COMP );
1679 assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0); 1701 assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0);
1680 } 1702 }
1681 1703
1682 ////////////////////////////////////////////////////////////////////////////// 1704 //////////////////////////////////////////////////////////////////////////////
1683 // calc_nullzeit 1705 // calc_nullzeit
1726 // 1748 //
1727 void backup_sim_pres_tissue(void) 1749 void backup_sim_pres_tissue(void)
1728 { 1750 {
1729 overlay unsigned char x; 1751 overlay unsigned char x;
1730 1752
1731 for(x = 0; x<32; x++) 1753 for(x=0; x<NUM_COMP; x++)
1732 sim_pres_tissue_backup[x] = sim_pres_tissue[x]; 1754 {
1755 sim_pres_tissue_backup_N2[x] = sim_pres_tissue_N2[x];
1756 sim_pres_tissue_backup_He[x] = sim_pres_tissue_He[x];
1757 }
1733 } 1758 }
1734 1759
1735 ////////////////////////////////////////////////////////////////////////////// 1760 //////////////////////////////////////////////////////////////////////////////
1736 // restore_sim_pres_tissue 1761 // restore_sim_pres_tissue
1737 // 1762 //
1738 void restore_sim_pres_tissue(void) 1763 void restore_sim_pres_tissue(void)
1739 { 1764 {
1740 overlay unsigned char x; 1765 overlay unsigned char x;
1741 1766
1742 for(x = 0; x<32; x++) 1767 for(x=0; x<NUM_COMP; x++)
1743 sim_pres_tissue[x] = sim_pres_tissue_backup[x]; 1768 {
1769 sim_pres_tissue_N2[x] = sim_pres_tissue_backup_N2[x];
1770 sim_pres_tissue_He[x] = sim_pres_tissue_backup_He[x];
1771 }
1744 } 1772 }
1745 1773
1746 ////////////////////////////////////////////////////////////////////////////// 1774 //////////////////////////////////////////////////////////////////////////////
1747 // calc_ascenttime 1775 // calc_ascenttime
1748 // 1776 //
1759 overlay float ascent = pres_respiration - pres_surface + 0.7; 1787 overlay float ascent = pres_respiration - pres_surface + 0.7;
1760 if (ascent < 0.0) 1788 if (ascent < 0.0)
1761 ascent = 0.0; 1789 ascent = 0.0;
1762 sum = (unsigned short)(ascent + 0.99); 1790 sum = (unsigned short)(ascent + 0.99);
1763 1791
1764 for(x=0; x<32 && internal_deco_depth[x]; x++) 1792 for(x=0; x<NUM_STOPS && internal_deco_depth[x]; x++)
1765 sum += (unsigned short)internal_deco_time[x]; 1793 sum += (unsigned short)internal_deco_time[x];
1766 1794
1767 if( char_O_deco_status == 1 ) 1795 if( char_O_deco_status == 1 )
1768 int_O_ascenttime = sum; 1796 int_O_ascenttime = sum;
1769 else 1797 else
1778 void update_startvalues(void) 1806 void update_startvalues(void)
1779 { 1807 {
1780 overlay unsigned char x; 1808 overlay unsigned char x;
1781 1809
1782 // Start ascent simulation with current tissue partial pressures. 1810 // Start ascent simulation with current tissue partial pressures.
1783 for (x = 0;x<16;x++) 1811 for(x=0; x<NUM_COMP; x++)
1784 { 1812 {
1785 sim_pres_tissue[x] = pres_tissue[x]; 1813 sim_pres_tissue_N2[x] = pres_tissue_N2[x];
1786 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; 1814 sim_pres_tissue_He[x] = pres_tissue_He[x];
1787 } 1815 }
1788 1816
1789 // No leading tissue (yet) for this ascent simulation. 1817 // No leading tissue (yet) for this ascent simulation.
1790 sim_lead_tissue_limit = 0.0; 1818 sim_lead_tissue_limit = 0.0;
1791 sim_lead_tissue_no = 255; 1819 sim_lead_tissue_no = 255;
1802 static void sim_tissue(PARAMETER unsigned char period) 1830 static void sim_tissue(PARAMETER unsigned char period)
1803 { 1831 {
1804 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m 1832 assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m
1805 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m 1833 assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m
1806 1834
1807 for(ci=0; ci<16; ci++) 1835 for(ci=0; ci<NUM_COMP; ci++)
1808 { 1836 {
1809 read_buhlmann_times(period); // 1 or 10 minute(s) interval 1837 read_buhlmann_times(period); // 1 or 10 minute(s) interval
1810 1838
1811 // N2 1839 // N2
1812 temp_tissue = (ppN2 - sim_pres_tissue[ci]) * var_N2_e; 1840 temp_tissue = (ppN2 - sim_pres_tissue_N2[ci]) * var_N2_e;
1813 temp_tissue_safety(); 1841 temp_tissue_safety();
1814 sim_pres_tissue[ci] += temp_tissue; 1842 sim_pres_tissue_N2[ci] += temp_tissue;
1815 1843
1816 // He 1844 // He
1817 temp_tissue = (ppHe - (sim_pres_tissue+16)[ci]) * var_He_e; 1845 temp_tissue = (ppHe - sim_pres_tissue_He[ci]) * var_He_e;
1818 temp_tissue_safety(); 1846 temp_tissue_safety();
1819 (sim_pres_tissue+16)[ci] += temp_tissue; 1847 sim_pres_tissue_He[ci] += temp_tissue;
1820 } 1848 }
1821 } 1849 }
1822 1850
1823 ////////////////////////////////////////////////////////////////////////////// 1851 //////////////////////////////////////////////////////////////////////////////
1824 // sim_limit() 1852 // sim_limit()
1833 assert( 0.0 < GF_current && GF_current <= 1.0f); 1861 assert( 0.0 < GF_current && GF_current <= 1.0f);
1834 1862
1835 sim_lead_tissue_limit = 0.0; 1863 sim_lead_tissue_limit = 0.0;
1836 sim_lead_tissue_no = 0; // If no one is critic, keep first tissue. 1864 sim_lead_tissue_no = 0; // If no one is critic, keep first tissue.
1837 1865
1838 for(ci=0; ci<16; ci++) 1866 for(ci=0; ci<NUM_COMP; ci++)
1839 { 1867 {
1840 overlay float N2 = sim_pres_tissue[ci]; 1868 overlay float N2 = sim_pres_tissue_N2[ci];
1841 overlay float He = (sim_pres_tissue+16)[ci]; 1869 overlay float He = sim_pres_tissue_He[ci];
1842 overlay float p = N2 + He; 1870 overlay float p = N2 + He;
1843 1871
1844 read_buhlmann_coefficients(); 1872 read_buhlmann_coefficients();
1845 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; 1873 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p;
1846 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; 1874 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p;
1862 sim_lead_tissue_no = ci; 1890 sim_lead_tissue_no = ci;
1863 sim_lead_tissue_limit = p; 1891 sim_lead_tissue_limit = p;
1864 } 1892 }
1865 } // for ci 1893 } // for ci
1866 1894
1867 assert( sim_lead_tissue_no < 16 ); 1895 assert( sim_lead_tissue_no < NUM_COMP );
1868 assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 ); 1896 assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 );
1869 } 1897 }
1870 1898
1871 ////////////////////////////////////////////////////////////////////////////// 1899 //////////////////////////////////////////////////////////////////////////////
1872 // clear_deco_table 1900 // clear_deco_table
1875 // 1903 //
1876 static void clear_deco_table(void) 1904 static void clear_deco_table(void)
1877 { 1905 {
1878 overlay unsigned char x; 1906 overlay unsigned char x;
1879 1907
1880 for(x=0; x<32; ++x) 1908 for(x=0; x<NUM_STOPS; ++x)
1881 { 1909 {
1882 internal_deco_time [x] = 0; 1910 internal_deco_time [x] = 0;
1883 internal_deco_depth[x] = 0; 1911 internal_deco_depth[x] = 0;
1884 } 1912 }
1885 } 1913 }
1899 { 1927 {
1900 overlay unsigned char x; 1928 overlay unsigned char x;
1901 assert( temp_depth_limit < 128 ); // Can't be negativ (overflown). 1929 assert( temp_depth_limit < 128 ); // Can't be negativ (overflown).
1902 assert( temp_depth_limit > 0 ); // No stop at surface... 1930 assert( temp_depth_limit > 0 ); // No stop at surface...
1903 1931
1904 for(x=0; x<32; ++x) 1932 for(x=0; x<NUM_STOPS; ++x)
1905 { 1933 {
1906 // Make sure deco-stops are recorded in order: 1934 // Make sure deco-stops are recorded in order:
1907 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) ); 1935 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) );
1908 1936
1909 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit ) 1937 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit )
1940 // new code in v.102 1968 // new code in v.102
1941 // 1969 //
1942 static void calc_gradient_factor(void) 1970 static void calc_gradient_factor(void)
1943 { 1971 {
1944 overlay float gf; 1972 overlay float gf;
1945 overlay float N2 = pres_tissue[char_O_gtissue_no]; 1973 overlay float N2 = pres_tissue_N2[char_O_gtissue_no];
1946 overlay float He = (pres_tissue+16)[char_O_gtissue_no]; 1974 overlay float He = pres_tissue_He[char_O_gtissue_no];
1947 1975
1948 assert( char_O_gtissue_no < 16 ); 1976 assert( char_O_gtissue_no < NUM_COMP );
1949 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); 1977 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 );
1950 1978
1951 // tissue > respiration (currently off-gasing) 1979 // tissue > respiration (currently off-gasing)
1952 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium. 1980 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium.
1953 // GF = 100% when respiration == limit. 1981 // GF = 100% when respiration == limit.
2016 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier 2044 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier
2017 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31] 2045 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31]
2018 // 2046 //
2019 void deco_calc_desaturation_time(void) 2047 void deco_calc_desaturation_time(void)
2020 { 2048 {
2049 overlay rom const float *ptr;
2050
2021 RESET_C_STACK 2051 RESET_C_STACK
2022 2052
2023 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); 2053 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 );
2024 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); 2054 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 );
2025 2055
2038 pres_surface = int_I_pres_surface * 0.001; 2068 pres_surface = int_I_pres_surface * 0.001;
2039 ppN2 = N2_ratio * (pres_surface - ppWater); 2069 ppN2 = N2_ratio * (pres_surface - ppWater);
2040 int_O_desaturation_time = 0; 2070 int_O_desaturation_time = 0;
2041 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) 2071 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142)
2042 2072
2043 for (ci=0;ci<16;ci++) 2073 ptr = &buhlmann_ht[0];
2044 { 2074 for(ci=0; ci<NUM_COMP; ci++)
2075 {
2076 overlay float var_N2_halftime = *ptr++;
2077 overlay float var_He_halftime = *ptr++;
2045 overlay unsigned short desat_time; // For a particular compartiment, in min. 2078 overlay unsigned short desat_time; // For a particular compartiment, in min.
2046 overlay float temp1; 2079 overlay float temp1;
2047 overlay float temp2; 2080 overlay float temp2;
2048 overlay float temp3; 2081 overlay float temp3;
2049 overlay float temp4; 2082 overlay float temp4;
2050 2083
2084 assert( 4.0 <= var_N2_halftime && var_N2_halftime <= 635.0 );
2085 assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 );
2086
2051 // saturation_time (for flight) and N2_saturation in multiples of halftime 2087 // saturation_time (for flight) and N2_saturation in multiples of halftime
2052 // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time ) 2088 // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time )
2053 // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time ) 2089 // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time )
2054 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations 2090 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations
2055 // N2 2091 // N2
2056 temp1 = 1.05 * ppN2 - pres_tissue[ci]; 2092 temp1 = 1.05 * ppN2 - pres_tissue_N2[ci];
2057 temp2 = ppN2 - pres_tissue[ci]; 2093 temp2 = ppN2 - pres_tissue_N2[ci];
2058 if (temp2 >= 0.0) 2094 if (temp2 >= 0.0)
2059 { 2095 {
2060 temp1 = 0.0; 2096 temp1 = 0.0;
2061 temp2 = 0.0; 2097 temp2 = 0.0;
2062 } 2098 }
2063 else 2099 else
2064 temp1 = temp1 / temp2; 2100 temp1 = temp1 / temp2;
2065 if( 0.0 < temp1 && temp1 < 1.0 ) 2101 if( 0.0 < temp1 && temp1 < 1.0 )
2066 { 2102 {
2067 overlay float var_N2_halftime = buhlmann_ht[ci];
2068 assert( 4.0 <= var_N2_halftime && var_N2_halftime <= 635.0 );
2069
2070 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. 2103 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
2071 // minus because log is negative. 2104 // minus because log is negative.
2072 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary. 2105 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary.
2073 temp2 = var_N2_halftime * temp1 / float_desaturation_multiplier; // time necessary (in minutes ) for complete desaturation (see comment about 5 percent) , new in v.101: float_desaturation_multiplier 2106 temp2 = var_N2_halftime * temp1 / float_desaturation_multiplier; // time necessary (in minutes ) for complete desaturation (see comment about 5 percent) , new in v.101: float_desaturation_multiplier
2074 2107
2078 temp1 = 0.0; 2111 temp1 = 0.0;
2079 temp2 = 0.0; 2112 temp2 = 0.0;
2080 } 2113 }
2081 2114
2082 // He 2115 // He
2083 temp3 = 0.1 - (pres_tissue+16)[ci]; 2116 temp3 = 0.1 - pres_tissue_He[ci];
2084 if (temp3 >= 0.0) 2117 if (temp3 >= 0.0)
2085 { 2118 {
2086 temp3 = 0.0; 2119 temp3 = 0.0;
2087 temp4 = 0.0; 2120 temp4 = 0.0;
2088 } 2121 }
2089 else 2122 else
2090 temp3 = - temp3 / (pres_tissue+16)[ci]; 2123 temp3 = - temp3 / pres_tissue_He[ci];
2091 if( 0.0 < temp3 && temp3 < 1.0 ) 2124 if( 0.0 < temp3 && temp3 < 1.0 )
2092 { 2125 {
2093 overlay float var_He_halftime = (buhlmann_ht+16)[ci];
2094 assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 );
2095
2096 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary. 2126 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary.
2097 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. 2127 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
2098 // minus because log is negative 2128 // minus because log is negative
2099 temp4 = var_He_halftime * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier 2129 temp4 = var_He_halftime * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier
2100 } 2130 }
2112 2142
2113 if(desat_time > int_O_desaturation_time) 2143 if(desat_time > int_O_desaturation_time)
2114 int_O_desaturation_time = desat_time; 2144 int_O_desaturation_time = desat_time;
2115 2145
2116 // N2 saturation in multiples of halftime for display purposes 2146 // N2 saturation in multiples of halftime for display purposes
2117 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 2147 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8
2118 temp2 = temp2 + 80.0; // set center 2148 temp2 = temp2 + 80.0; // set center
2119 if (temp2 < 0.0) 2149 if (temp2 < 0.0)
2120 temp2 = 0.0; 2150 temp2 = 0.0;
2121 if (temp2 > 255.0) 2151 if (temp2 > 255.0)
2122 temp2 = 255.0; 2152 temp2 = 255.0;
2123 char_O_tissue_saturation[ci] = (char)temp2; 2153 char_O_tissue_N2_saturation[ci] = (char)temp2;
2124 2154
2125 // He saturation in multiples of halftime for display purposes 2155 // He saturation in multiples of halftime for display purposes
2126 temp4 = temp3 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 2156 temp4 = temp3 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8
2127 temp4 = temp4 + 80.0; // set center 2157 temp4 = temp4 + 80.0; // set center
2128 if (temp4 < 0.0) 2158 if (temp4 < 0.0)
2129 temp4 = 0.0; 2159 temp4 = 0.0;
2130 if (temp4 > 255.0) 2160 if (temp4 > 255.0)
2131 temp4 = 255.0; 2161 temp4 = 255.0;
2132 (char_O_tissue_saturation+16)[ci] = (char)temp4; 2162 char_O_tissue_He_saturation[ci] = (char)temp4;
2133 } // for 2163 } // for
2134 } 2164 }
2135 2165
2136 ////////////////////////////////////////////////////////////////////////////// 2166 //////////////////////////////////////////////////////////////////////////////
2137 // calc_wo_deco_step_1_min 2167 // calc_wo_deco_step_1_min
2159 ppN2 = N2_ratio * (pres_respiration - ppWater); // ppWater is the extra pressure in the body 2189 ppN2 = N2_ratio * (pres_respiration - ppWater); // ppWater is the extra pressure in the body
2160 ppHe = 0.0; 2190 ppHe = 0.0;
2161 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) 2191 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142)
2162 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; 2192 float_saturation_multiplier = char_I_saturation_multiplier * 0.01;
2163 2193
2164 calc_tissue(1); // update the pressure in the 32 tissues in accordance with the new ambient pressure 2194 calc_tissue(1); // update the pressure in the tissues N2/He in accordance with the new ambient pressure
2165 2195
2166 clear_deco_table(); 2196 clear_deco_table();
2167 char_O_deco_status = 3; // surface new in v.102 : stays in surface state. 2197 char_O_deco_status = 3; // surface new in v.102 : stays in surface state.
2168 char_O_nullzeit = 0; 2198 char_O_nullzeit = 0;
2169 int_O_ascenttime = 0; 2199 int_O_ascenttime = 0;
2404 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0) or bar/min. 2434 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0) or bar/min.
2405 // Output: int_O_gas_volumes[0..4] in litters * 0.1 2435 // Output: int_O_gas_volumes[0..4] in litters * 0.1
2406 // 2436 //
2407 void deco_gas_volumes(void) 2437 void deco_gas_volumes(void)
2408 { 2438 {
2409 overlay float volumes[5]; 2439 overlay float volumes[NUM_GAS];
2410 overlay float bottom_usage, ascent_usage; 2440 overlay float bottom_usage, ascent_usage;
2411 overlay unsigned char i, deepest_first; 2441 overlay unsigned char i, deepest_first;
2412 overlay unsigned char gas; 2442 overlay unsigned char gas;
2413 RESET_C_STACK 2443 RESET_C_STACK
2414 2444
2415 //---- initialize with bottom consumption -------------------------------- 2445 //---- initialize with bottom consumption --------------------------------
2416 for(i=0; i<5; ++i) // Nothing yet... 2446 for(i=0; i<NUM_GAS; ++i) // Nothing yet...
2417 volumes[i] = 0.0; 2447 volumes[i] = 0.0;
2418 2448
2419 assert(1 <= char_I_first_gas && char_I_first_gas <= 5); 2449 assert(1 <= char_I_first_gas && char_I_first_gas <= NUM_GAS);
2420 gas = char_I_first_gas - 1; 2450 gas = char_I_first_gas - 1;
2421 2451
2422 bottom_usage = read_custom_function(56) * 0.1; 2452 bottom_usage = read_custom_function(56) * 0.1;
2423 if( bottom_usage > 0.0 ) 2453 if( bottom_usage > 0.0 )
2424 volumes[gas] 2454 volumes[gas]
2444 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 // ascent time (min) 2474 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 // ascent time (min)
2445 * ascent_usage; // Consumption ( xxx / min @ 1 bar) 2475 * ascent_usage; // Consumption ( xxx / min @ 1 bar)
2446 else 2476 else
2447 volumes[gas] = 65535.0; 2477 volumes[gas] = 65535.0;
2448 2478
2449 for(i=0; i<32; ++i) 2479 for(i=0; i<NUM_STOPS; ++i)
2450 { 2480 {
2451 overlay unsigned char j; 2481 overlay unsigned char j;
2452 overlay unsigned char depth, time, ascent; 2482 overlay unsigned char depth, time, ascent;
2453 2483
2454 // Manage stops in reverse order (CF#54) 2484 // Manage stops in reverse order (CF#54)
2470 if( i < 31 ) 2500 if( i < 31 )
2471 ascent -= char_O_deco_depth[30-i] & 0x7F; 2501 ascent -= char_O_deco_depth[30-i] & 0x7F;
2472 } 2502 }
2473 2503
2474 // Gas switch depth ? 2504 // Gas switch depth ?
2475 for(j=0; j<5; ++j) 2505 for(j=0; j<NUM_GAS; ++j)
2476 { 2506 {
2477 if( depth <= char_I_deco_gas_change[j] ) 2507 if( depth <= char_I_deco_gas_change[j] )
2478 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) ) 2508 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) )
2479 gas = j; 2509 gas = j;
2480 } 2510 }
2492 else 2522 else
2493 volumes[gas] = 65535.0; 2523 volumes[gas] = 65535.0;
2494 } 2524 }
2495 2525
2496 //---- convert results for the ASM interface ----------------------------- 2526 //---- convert results for the ASM interface -----------------------------
2497 for(i=0; i<5; ++i) 2527 for(i=0; i<NUM_GAS; ++i)
2498 if( volumes[i] > 6553.4 ) 2528 if( volumes[i] > 6553.4 )
2499 int_O_gas_volumes[i] = 65535; 2529 int_O_gas_volumes[i] = 65535;
2500 else 2530 else
2501 int_O_gas_volumes[i] = (unsigned short)(volumes[i]*10.0 + 0.5); 2531 int_O_gas_volumes[i] = (unsigned short)(volumes[i]*10.0 + 0.5);
2502 } 2532 }
2507 { 2537 {
2508 overlay unsigned char x; 2538 overlay unsigned char x;
2509 RESET_C_STACK 2539 RESET_C_STACK
2510 2540
2511 cns_vault = CNS_fraction; 2541 cns_vault = CNS_fraction;
2512 for (x=0;x<32;x++) 2542 for (x=0;x<NUM_COMP;x++)
2513 pres_tissue_vault[x] = pres_tissue[x]; 2543 {
2544 pres_tissue_N2_vault[x] = pres_tissue_N2[x];
2545 pres_tissue_He_vault[x] = pres_tissue_He[x];
2546 }
2514 } 2547 }
2515 2548
2516 void deco_pull_tissues_from_vault(void) 2549 void deco_pull_tissues_from_vault(void)
2517 { 2550 {
2518 overlay unsigned char x; 2551 overlay unsigned char x;
2519 RESET_C_STACK 2552 RESET_C_STACK
2520 2553
2521 for (x=0;x<32;x++) 2554 for (x=0; x<NUM_COMP; x++)
2522 pres_tissue[x] = pres_tissue_vault[x]; 2555 {
2556 pres_tissue_N2[x] = pres_tissue_N2_vault[x];
2557 pres_tissue_He[x] = pres_tissue_He_vault[x];
2558 }
2523 2559
2524 // Restore both CNS variable, too. 2560 // Restore both CNS variable, too.
2525 CNS_fraction = cns_vault; 2561 CNS_fraction = cns_vault;
2526 char_O_CNS_fraction = (char)(CNS_fraction * 100.0 + 0.5); 2562 char_O_CNS_fraction = (char)(CNS_fraction * 100.0 + 0.5);
2527 } 2563 }