comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 711:f555590f1419

minor cleanups for CNS/NOAA bugfix.
author JeanDo <jd.gascuel@free.fr>
date Thu, 09 May 2013 00:26:41 +0200
parents d36f060e8203
children c498d6972087 8466932a2fcf
comparison
equal deleted inserted replaced
710:d36f060e8203 711:f555590f1419
85 // 2012/02/25: [jDG] Looking for a more stable LOW grad factor reference. 85 // 2012/02/25: [jDG] Looking for a more stable LOW grad factor reference.
86 // 2012/09/10: [mH] Fill char_O_deco_time_for_log for logbook write 86 // 2012/09/10: [mH] Fill char_O_deco_time_for_log for logbook write
87 // 2012/10/05: [jDG] Better deco_gas_volumes accuracy (average depth, switch between stop). 87 // 2012/10/05: [jDG] Better deco_gas_volumes accuracy (average depth, switch between stop).
88 // 2013/03/05: [jDG] Should vault low_depth too. 88 // 2013/03/05: [jDG] Should vault low_depth too.
89 // 2013/03/05: [jDG] Wrobell remark: ascent_to_first_stop works better with finer steps (2sec). 89 // 2013/03/05: [jDG] Wrobell remark: ascent_to_first_stop works better with finer steps (2sec).
90 // 2013/05/08: [jDG] A. Salm remark: NOAA tables for CNS are in ATA, not bar.
90 // 91 //
91 // TODO: 92 // TODO:
92 // + Allow to abort MD2 calculation (have to restart next time). 93 // + Allow to abort MD2 calculation (have to restart next time).
93 // 94 //
94 // Literature: 95 // Literature:
172 // Simulation context: used to predict ascent. 173 // Simulation context: used to predict ascent.
173 unsigned char sim_lead_tissue_no; // Leading compatiment number. 174 unsigned char sim_lead_tissue_no; // Leading compatiment number.
174 float sim_lead_tissue_limit; // Buhlmann tolerated pressure. 175 float sim_lead_tissue_limit; // Buhlmann tolerated pressure.
175 176
176 // Real context: what we are doing now. 177 // Real context: what we are doing now.
177 static float calc_lead_tissue_limit; // 178 static float calc_lead_tissue_limit; //
178 179
179 static unsigned char internal_deco_time[NUM_STOPS]; 180 static unsigned char internal_deco_time[NUM_STOPS];
180 static unsigned char internal_deco_depth[NUM_STOPS]; 181 static unsigned char internal_deco_depth[NUM_STOPS];
181 182
182 static float cns_vault; 183 static float cns_vault;
208 static float var_He_ht; // Half-time for current N2 tissue. 209 static float var_He_ht; // Half-time for current N2 tissue.
209 210
210 static float pres_diluent; // new in v.101 211 static float pres_diluent; // new in v.101
211 static float const_ppO2; // new in v.101 212 static float const_ppO2; // new in v.101
212 213
213 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch. 214 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch.
214 static unsigned char sim_gas_last_used; // Number of last used gas, to detected a gas switch. 215 static unsigned char sim_gas_last_used; // Number of last used gas, to detected a gas switch.
215 static unsigned short sim_gas_delay; // Time of gas-switch-stop ends [min on dive]. 216 static unsigned short sim_gas_delay; // Time of gas-switch-stop ends [min on dive].
216 static unsigned short sim_dive_mins; // Simulated dive time. 217 static unsigned short sim_dive_mins; // Simulated dive time.
217 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. 218 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio.
218 static float calc_He_ratio; // Simulated (switched) helium ratio. 219 static float calc_He_ratio; // Simulated (switched) helium ratio.
219 static float CNS_fraction; // new in v.101 220 static float CNS_fraction; // new in v.101
343 LFSR 1,C_STACK 344 LFSR 1,C_STACK
344 MOVLW 0xCC 345 MOVLW 0xCC
345 loop: MOVWF POSTINC1,0 346 loop: MOVWF POSTINC1,0
346 TSTFSZ FSR1L,0 347 TSTFSZ FSR1L,0
347 BRA loop 348 BRA loop
348 349
349 LFSR 1,C_STACK 350 LFSR 1,C_STACK
350 LFSR 2,C_STACK 351 LFSR 2,C_STACK
351 _endasm 352 _endasm
352 } 353 }
353 # else 354 # else
399 #endif 400 #endif
400 } 401 }
401 402
402 ////////////////////////////////////////////////////////////////////////////// 403 //////////////////////////////////////////////////////////////////////////////
403 // read buhlmann tables A and B for compatriment ci 404 // read buhlmann tables A and B for compatriment ci
404 // 405 //
405 static void read_buhlmann_coefficients(void) 406 static void read_buhlmann_coefficients(void)
406 { 407 {
407 #ifndef CROSS_COMPILE 408 #ifndef CROSS_COMPILE
408 // Note: we don't use far rom pointer, because the 409 // Note: we don't use far rom pointer, because the
409 // 24 bits is too complex, hence we have to set 410 // 24 bits is too complex, hence we have to set
480 } 481 }
481 } 482 }
482 483
483 ////////////////////////////////////////////////////////////////////////////// 484 //////////////////////////////////////////////////////////////////////////////
484 // read buhlmann tables for compatriment ci 485 // read buhlmann tables for compatriment ci
485 // 486 //
486 static void read_buhlmann_ht(void) 487 static void read_buhlmann_ht(void)
487 { 488 {
488 489
489 #ifndef CROSS_COMPILE 490 #ifndef CROSS_COMPILE
490 // Note: we don't use far rom pointer, because the 491 // Note: we don't use far rom pointer, because the
500 assert( ci < NUM_COMP ); 501 assert( ci < NUM_COMP );
501 { 502 {
502 overlay rom const float* ptr = &buhlmann_ht[2*ci]; 503 overlay rom const float* ptr = &buhlmann_ht[2*ci];
503 var_N2_ht = *ptr++; 504 var_N2_ht = *ptr++;
504 var_He_ht = *ptr++; 505 var_He_ht = *ptr++;
505 } 506 }
506 507
507 assert( 4.0 <= var_N2_ht && var_N2_ht <= 635.0 ); 508 assert( 4.0 <= var_N2_ht && var_N2_ht <= 635.0 );
508 assert( 1.5099 <= var_He_ht && var_He_ht <= 240.03 ); 509 assert( 1.5099 <= var_He_ht && var_He_ht <= 240.03 );
509 } 510 }
510 511
538 // Recompute leading gas limit, at current depth: 539 // Recompute leading gas limit, at current depth:
539 overlay float depth = (temp_deco - pres_surface) * BAR_TO_METER; 540 overlay float depth = (temp_deco - pres_surface) * BAR_TO_METER;
540 541
541 // At most, ascent 1 minute, at 10m/min == 10.0 m. 542 // At most, ascent 1 minute, at 10m/min == 10.0 m.
542 overlay float min_depth = (depth > 10.0) ? (depth - 10.0) : 0.0; 543 overlay float min_depth = (depth > 10.0) ? (depth - 10.0) : 0.0;
543 544
544 // Do we need to stop at current depth ? 545 // Do we need to stop at current depth ?
545 overlay unsigned char need_stop = 0; 546 overlay unsigned char need_stop = 0;
546 547
547 assert( depth >= -0.2 ); // Allow for 200mbar of weather change. 548 assert( depth >= -0.2 ); // Allow for 200mbar of weather change.
548 549
549 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ 550 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------
550 if( char_I_deco_model != 0 ) 551 if( char_I_deco_model != 0 )
551 { 552 {
552 overlay unsigned char first_stop = 0; 553 overlay unsigned char first_stop = 0;
553 overlay float p; 554 overlay float p;
554 555
555 sim_limit( GF_low ); 556 sim_limit( GF_low );
556 p = sim_lead_tissue_limit - pres_surface; 557 p = sim_lead_tissue_limit - pres_surface;
594 next_stop = 0; 595 next_stop = 0;
595 else if( first_stop == 6 ) 596 else if( first_stop == 6 )
596 next_stop = char_I_depth_last_deco; 597 next_stop = char_I_depth_last_deco;
597 else 598 else
598 next_stop = first_stop - 3; // Index of next (upper) stop. 599 next_stop = first_stop - 3; // Index of next (upper) stop.
599 600
600 // Total preassure at the new stop candidate: 601 // Total preassure at the new stop candidate:
601 p = next_stop * METER_TO_BAR 602 p = next_stop * METER_TO_BAR
602 + pres_surface; 603 + pres_surface;
603 604
604 // Recompute limit for this new stop: 605 // Recompute limit for this new stop:
605 if( !low_depth || next_stop > low_depth ) 606 if( !low_depth || next_stop > low_depth )
606 sim_limit( GF_low ); 607 sim_limit( GF_low );
607 else 608 else
614 // Else, validate that stop and loop... 615 // Else, validate that stop and loop...
615 first_stop = next_stop; 616 first_stop = next_stop;
616 } 617 }
617 618
618 no_deco_stop: 619 no_deco_stop:
619 temp_depth_limit = min_depth; 620 temp_depth_limit = min_depth;
620 goto done; 621 goto done;
621 622
622 deco_stop_found: 623 deco_stop_found:
623 // next stop is the last validated depth found, aka first_stop 624 // next stop is the last validated depth found, aka first_stop
624 need_stop = 1; // Hit. 625 need_stop = 1; // Hit.
625 temp_depth_limit = first_stop; // Stop depth, in meter. 626 temp_depth_limit = first_stop; // Stop depth, in meter.
626 627
627 done: 628 done:
628 ; 629 ;
629 } 630 }
630 else //---- ZH-L16 model ------------------------------------------------- 631 else //---- ZH-L16 model -------------------------------------------------
631 { 632 {
632 overlay float pres_gradient; 633 overlay float pres_gradient;
633 634
634 // Original model 635 // Original model
635 // optimized in v.101 636 // optimized in v.101
636 // char_I_depth_last_deco included in v.101 637 // char_I_depth_last_deco included in v.101
637 638
638 // Compute sim_lead_tissue_limit too, but just once. 639 // Compute sim_lead_tissue_limit too, but just once.
639 sim_limit(1.0); 640 sim_limit(1.0);
640 641
641 pres_gradient = sim_lead_tissue_limit - pres_surface; 642 pres_gradient = sim_lead_tissue_limit - pres_surface;
642 if (pres_gradient >= 0) 643 if (pres_gradient >= 0)
643 { 644 {
644 pres_gradient *= BAR_TO_METER/3; // Bar --> stop number; 645 pres_gradient *= BAR_TO_METER/3; // Bar --> stop number;
645 temp_depth_limit = 3 * (short) (pres_gradient + 0.99); // --> metre : depth for deco 646 temp_depth_limit = 3 * (short) (pres_gradient + 0.99); // --> metre : depth for deco
646 need_stop = 1; // Hit. 647 need_stop = 1; // Hit.
647 648
648 // Implement last stop at 4m/5m/6m... 649 // Implement last stop at 4m/5m/6m...
649 if( temp_depth_limit == 3 ) 650 if( temp_depth_limit == 3 )
650 temp_depth_limit = char_I_depth_last_deco; 651 temp_depth_limit = char_I_depth_last_deco;
651 } 652 }
652 else 653 else
653 temp_depth_limit = 0; 654 temp_depth_limit = 0;
654 } 655 }
655 656
656 //---- Check gas change -------------------------------------------------- 657 //---- Check gas change --------------------------------------------------
657 need_stop |= gas_switch_deepest(); // Update temp_depth_limit if there is a change, 658 need_stop |= gas_switch_deepest(); // Update temp_depth_limit if there is a change,
658 659
659 return need_stop; 660 return need_stop;
666 // while computing the next set. 667 // while computing the next set.
667 // 668 //
668 static void copy_deco_table(void) 669 static void copy_deco_table(void)
669 { 670 {
670 // Copy depth of the first (deepest) stop, because when reversing 671 // Copy depth of the first (deepest) stop, because when reversing
671 // order, it will be hard to find... 672 // order, it will be hard to find...
672 char_O_first_deco_depth = internal_deco_depth[0] & 0x7F; 673 char_O_first_deco_depth = internal_deco_depth[0] & 0x7F;
673 char_O_first_deco_time = internal_deco_time [0]; 674 char_O_first_deco_time = internal_deco_time [0];
674 675
675 if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------ 676 if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------
676 { 677 {
742 static void temp_tissue_safety(void) 743 static void temp_tissue_safety(void)
743 { 744 {
744 assert( 0.0 < float_desaturation_multiplier && float_desaturation_multiplier <= 1.0 ); 745 assert( 0.0 < float_desaturation_multiplier && float_desaturation_multiplier <= 1.0 );
745 assert( 1.0 <= float_saturation_multiplier && float_saturation_multiplier <= 2.0 ); 746 assert( 1.0 <= float_saturation_multiplier && float_saturation_multiplier <= 2.0 );
746 747
747 if( char_I_deco_model == 0 ) 748 if( char_I_deco_model == 0 )
748 { 749 {
749 if( temp_tissue < 0.0 ) 750 if( temp_tissue < 0.0 )
750 temp_tissue *= float_desaturation_multiplier; 751 temp_tissue *= float_desaturation_multiplier;
751 else 752 else
752 temp_tissue *= float_saturation_multiplier; 753 temp_tissue *= float_saturation_multiplier;
753 } 754 }
754 } 755 }
755 756
756 ////////////////////////////////////////////////////////////////////////////// 757 //////////////////////////////////////////////////////////////////////////////
757 ////////////////////////////////////////////////////////////////////////////// 758 //////////////////////////////////////////////////////////////////////////////
758 // ** THE JUMP-IN CODE ** 759 // ** THE JUMP-IN CODE **
793 // 794 //
794 void deco_calc_tissue(void) 795 void deco_calc_tissue(void)
795 { 796 {
796 RESET_C_STACK 797 RESET_C_STACK
797 calc_hauptroutine_update_tissues(); 798 calc_hauptroutine_update_tissues();
798 } 799 }
799 800
800 ////////////////////////////////////////////////////////////////////////////// 801 //////////////////////////////////////////////////////////////////////////////
801 802
802 void deco_calc_wo_deco_step_1_min(void) 803 void deco_calc_wo_deco_step_1_min(void)
803 { 804 {
814 calc_dive_interval(); 815 calc_dive_interval();
815 } 816 }
816 817
817 ////////////////////////////////////////////////////////////////////////////// 818 //////////////////////////////////////////////////////////////////////////////
818 // Find current gas in the list (if any). 819 // Find current gas in the list (if any).
819 // 820 //
820 // Input: char_I_current_gas = 1..6 821 // Input: char_I_current_gas = 1..6
821 // 822 //
822 // Output: sim_gas_last_depth = 0..5, temp_depth_limit. 823 // Output: sim_gas_last_depth = 0..5, temp_depth_limit.
823 // 824 //
824 static void gas_switch_find_current(void) 825 static void gas_switch_find_current(void)
838 sim_gas_last_used = 0; // Gas 6 = manual set 839 sim_gas_last_used = 0; // Gas 6 = manual set
839 } 840 }
840 841
841 ////////////////////////////////////////////////////////////////////////////// 842 //////////////////////////////////////////////////////////////////////////////
842 // Find deepest available gas. 843 // Find deepest available gas.
843 // 844 //
844 // Input: temp_depth_limit, 845 // Input: temp_depth_limit,
845 // deco_gas_change[] 846 // deco_gas_change[]
846 // sim_gas_delay, sim_gas_depth_used, sim_dive_mins. 847 // sim_gas_delay, sim_gas_depth_used, sim_dive_mins.
847 // 848 //
848 // RETURNS TRUE if a stop is needed for gas switch. 849 // RETURNS TRUE if a stop is needed for gas switch.
911 return 0; 912 return 0;
912 } 913 }
913 914
914 ////////////////////////////////////////////////////////////////////////////// 915 //////////////////////////////////////////////////////////////////////////////
915 // Calculate gas switches 916 // Calculate gas switches
916 // 917 //
917 // 918 //
918 // Input: N2_ratio, He_ratio. 919 // Input: N2_ratio, He_ratio.
919 // sim_gas_last_used 920 // sim_gas_last_used
920 // 921 //
921 // Output: calc_N2_ratio, calc_He_ratio 922 // Output: calc_N2_ratio, calc_He_ratio
925 assert( sim_gas_last_used <= NUM_GAS ); 926 assert( sim_gas_last_used <= NUM_GAS );
926 927
927 if( sim_gas_last_used == 0 ) // Gas6 = manualy set gas. 928 if( sim_gas_last_used == 0 ) // Gas6 = manualy set gas.
928 { 929 {
929 calc_N2_ratio = N2_ratio; 930 calc_N2_ratio = N2_ratio;
930 calc_He_ratio = He_ratio; 931 calc_He_ratio = He_ratio;
931 } 932 }
932 else 933 else
933 { 934 {
934 calc_N2_ratio = char_I_deco_N2_ratio[sim_gas_last_used-1] * 0.01; 935 calc_N2_ratio = char_I_deco_N2_ratio[sim_gas_last_used-1] * 0.01;
935 calc_He_ratio = char_I_deco_He_ratio[sim_gas_last_used-1] * 0.01; 936 calc_He_ratio = char_I_deco_He_ratio[sim_gas_last_used-1] * 0.01;
936 } 937 }
937 938
938 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); 939 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 );
939 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); 940 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 );
940 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); 941 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 );
959 if( deco_diluent > pres_surface ) 960 if( deco_diluent > pres_surface )
960 deco_diluent += float_deco_distance; 961 deco_diluent += float_deco_distance;
961 962
962 //---- CCR mode : deco gas switch ? -------------------------------------- 963 //---- CCR mode : deco gas switch ? --------------------------------------
963 if( char_I_const_ppO2 != 0 ) 964 if( char_I_const_ppO2 != 0 )
964 { 965 {
965 // In CCR mode, use calc_XX_ratio instead of XX_ratio. 966 // In CCR mode, use calc_XX_ratio instead of XX_ratio.
966 // Note: PPO2 and ratios are known outside the lumbs, so there is no 967 // Note: PPO2 and ratios are known outside the lumbs, so there is no
967 // ppWater in the equations below: 968 // ppWater in the equations below:
968 deco_diluent -= const_ppO2; 969 deco_diluent -= const_ppO2;
969 deco_diluent /= calc_N2_ratio + calc_He_ratio; 970 deco_diluent /= calc_N2_ratio + calc_He_ratio;
970 971
971 if (deco_diluent > temp_deco) 972 if (deco_diluent > temp_deco)
972 deco_diluent = temp_deco; 973 deco_diluent = temp_deco;
973 } 974 }
974 975
975 if( deco_diluent > ppWater ) 976 if( deco_diluent > ppWater )
976 { 977 {
977 ppN2 = calc_N2_ratio * (deco_diluent - ppWater); 978 ppN2 = calc_N2_ratio * (deco_diluent - ppWater);
978 ppHe = calc_He_ratio * (deco_diluent - ppWater); 979 ppHe = calc_He_ratio * (deco_diluent - ppWater);
995 // Note: fixed N2_ratio for standard air. 996 // Note: fixed N2_ratio for standard air.
996 // 997 //
997 static void clear_tissue(void) 998 static void clear_tissue(void)
998 { 999 {
999 overlay float p; 1000 overlay float p;
1000 flag_in_divemode = 0; 1001 flag_in_divemode = 0;
1001 1002
1002 // Kludge: the 0.0002 of 0.7902 are missing with standard air. 1003 // Kludge: the 0.0002 of 0.7902 are missing with standard air.
1003 N2_ratio = 0.7902; 1004 N2_ratio = 0.7902;
1004 pres_respiration = int_I_pres_respiration * 0.001; 1005 pres_respiration = int_I_pres_respiration * 0.001;
1005 1006
1006 p = N2_ratio * (pres_respiration - ppWater); 1007 p = N2_ratio * (pres_respiration - ppWater);
1007 for(ci=0; ci<NUM_COMP; ci++) 1008 for(ci=0; ci<NUM_COMP; ci++)
1008 { 1009 {
1009 // cycle through the 16 Bühlmann N2 tissues 1010 // cycle through the 16 Bühlmann N2 tissues
1010 pres_tissue_N2[ci] = p; 1011 pres_tissue_N2[ci] = p;
1044 // 6 = ascent to first stop (same as 2), except continue to 7 1045 // 6 = ascent to first stop (same as 2), except continue to 7
1045 // 7 = same as 1, except loop to 7. 1046 // 7 = same as 1, except loop to 7.
1046 // 1047 //
1047 static void calc_hauptroutine(void) 1048 static void calc_hauptroutine(void)
1048 { 1049 {
1049 static unsigned char backup_gas_used = 0; 1050 static unsigned char backup_gas_used = 0;
1050 static unsigned char backup_gas_depth = 0; 1051 static unsigned char backup_gas_depth = 0;
1051 static unsigned char backup_gas_delay = 0; 1052 static unsigned char backup_gas_delay = 0;
1052 1053
1053 calc_hauptroutine_data_input(); 1054 calc_hauptroutine_data_input();
1054 1055
1055 calc_hauptroutine_update_tissues(); 1056 calc_hauptroutine_update_tissues();
1056 calc_gradient_factor(); 1057 calc_gradient_factor();
1057 1058
1058 // toggle between calculation for nullzeit (bottom time), 1059 // toggle between calculation for nullzeit (bottom time),
1059 // deco stops 1060 // deco stops
1060 // and more deco stops (continue) 1061 // and more deco stops (continue)
1061 switch( char_O_deco_status ) 1062 switch( char_O_deco_status )
1062 { 1063 {
1063 case 3: //---- At surface: start a new dive ------------------------------ 1064 case 3: //---- At surface: start a new dive ------------------------------
1064 clear_deco_table(); 1065 clear_deco_table();
1065 copy_deco_table(); 1066 copy_deco_table();
1066 int_O_ascenttime = 0; // Reset DTR. 1067 int_O_ascenttime = 0; // Reset DTR.
1067 int_O_extra_ascenttime = 0; 1068 int_O_extra_ascenttime = 0;
1068 char_O_nullzeit = 0; // Reset bottom time. 1069 char_O_nullzeit = 0; // Reset bottom time.
1069 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. 1070 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration.
1070 1071
1071 // Values that should be reset just once for the full real dive. 1072 // Values that should be reset just once for the full real dive.
1072 // This is used to record the lowest stop for the whole dive, 1073 // This is used to record the lowest stop for the whole dive,
1073 // Including ACCROSS all simulated ascent. 1074 // Including ACCROSS all simulated ascent.
1084 case 0: //---- bottom time ----------------------------------------------- 1085 case 0: //---- bottom time -----------------------------------------------
1085 default: 1086 default:
1086 gas_switch_find_current(); // Lookup for current gas & time. 1087 gas_switch_find_current(); // Lookup for current gas & time.
1087 gas_switch_set(); // setup calc_ratio's 1088 gas_switch_set(); // setup calc_ratio's
1088 1089
1089 calc_nullzeit(); 1090 calc_nullzeit();
1090 if( char_O_nullzeit > 0 ) // Some NDL time left ? 1091 if( char_O_nullzeit > 0 ) // Some NDL time left ?
1091 { 1092 {
1092 char_O_deco_status = 0; // YES: recalc ndl next time. 1093 char_O_deco_status = 0; // YES: recalc ndl next time.
1093 clear_deco_table(); // Also clear stops ! 1094 clear_deco_table(); // Also clear stops !
1094 copy_deco_table(); 1095 copy_deco_table();
1095 char_O_deco_last_stop = 0; // And last stop (OSTC menu anim) 1096 char_O_deco_last_stop = 0; // And last stop (OSTC menu anim)
1096 } 1097 }
1097 else 1098 else
1098 char_O_deco_status = 2; // NO: calc ascent next time. 1099 char_O_deco_status = 2; // NO: calc ascent next time.
1099 break; 1100 break;
1100 1101
1101 case 2: //---- Simulate ascent to first stop ----------------------------- 1102 case 2: //---- Simulate ascent to first stop -----------------------------
1102 case 6: // @+5min variation 1103 case 6: // @+5min variation
1103 // Check proposed gas at begin of ascent simulation 1104 // Check proposed gas at begin of ascent simulation
1104 sim_dive_mins = int_I_divemins; // Init current time. 1105 sim_dive_mins = int_I_divemins; // Init current time.
1105 1106
1106 gas_switch_find_current(); // Lookup for current gas & time. 1107 gas_switch_find_current(); // Lookup for current gas & time.
1107 gas_switch_set(); // setup calc_ratio's 1108 gas_switch_set(); // setup calc_ratio's
1108 1109
1109 backup_gas_used = sim_gas_last_used; // And save for later simu steps. 1110 backup_gas_used = sim_gas_last_used; // And save for later simu steps.
1110 backup_gas_depth = sim_gas_last_depth; // And save for later simu steps. 1111 backup_gas_depth = sim_gas_last_depth; // And save for later simu steps.
1111 backup_gas_delay = sim_gas_delay; 1112 backup_gas_delay = sim_gas_delay;
1112 1113
1113 sim_ascent_to_first_stop(); 1114 sim_ascent_to_first_stop();
1114 1115
1115 // Calc stops next time (deco or gas switch). 1116 // Calc stops next time (deco or gas switch).
1116 char_O_deco_status = 1 | ( char_O_deco_status & 4 ); 1117 char_O_deco_status = 1 | ( char_O_deco_status & 4 );
1117 break; 1118 break;
1118 1119
1119 case 1: //---- Simulate stops -------------------------------------------- 1120 case 1: //---- Simulate stops --------------------------------------------
1120 case 5: // @+5 variation. 1121 case 5: // @+5 variation.
1121 calc_hauptroutine_calc_deco(); 1122 calc_hauptroutine_calc_deco();
1122 1123
1123 // If simulation is finished, restore the GF low reference, so that 1124 // If simulation is finished, restore the GF low reference, so that
1124 // next ascent simulation is done from the current depth: 1125 // next ascent simulation is done from the current depth:
1125 if( (char_O_deco_status & 3) == 0 ) 1126 if( (char_O_deco_status & 3) == 0 )
1126 { 1127 {
1127 sim_gas_last_used = backup_gas_used; 1128 sim_gas_last_used = backup_gas_used;
1128 sim_gas_last_depth = backup_gas_depth; 1129 sim_gas_last_depth = backup_gas_depth;
1129 sim_gas_delay = backup_gas_delay; 1130 sim_gas_delay = backup_gas_delay;
1130 } 1131 }
1131 break; 1132 break;
1132 } 1133 }
1133 1134
1134 } 1135 }
1135 1136
1136 ////////////////////////////////////////////////////////////////////////////// 1137 //////////////////////////////////////////////////////////////////////////////
1137 // calc_hauptroutine_data_input 1138 // calc_hauptroutine_data_input
1141 // 1142 //
1142 void calc_hauptroutine_data_input(void) 1143 void calc_hauptroutine_data_input(void)
1143 { 1144 {
1144 overlay short int_temp; 1145 overlay short int_temp;
1145 overlay unsigned char g; 1146 overlay unsigned char g;
1146 1147
1147 pres_respiration = int_I_pres_respiration * 0.001; 1148 pres_respiration = int_I_pres_respiration * 0.001;
1148 pres_surface = int_I_pres_surface * 0.001; 1149 pres_surface = int_I_pres_surface * 0.001;
1149 N2_ratio = char_I_N2_ratio * 0.01; 1150 N2_ratio = char_I_N2_ratio * 0.01;
1150 He_ratio = char_I_He_ratio * 0.01; 1151 He_ratio = char_I_He_ratio * 0.01;
1151 float_deco_distance = char_I_deco_distance * 0.01; // Get offset is in mbar. 1152 float_deco_distance = char_I_deco_distance * 0.01; // Get offset is in mbar.
1152 1153
1153 // ____________________________________________________ 1154 // ____________________________________________________
1154 // 1155 //
1155 // _____________ G A S _ C H A N G E S ________________ 1156 // _____________ G A S _ C H A N G E S ________________
1156 // ____________________________________________________ 1157 // ____________________________________________________
1157 1158
1158 // Keep a margin of 150mbar = 1.50m 1159 // Keep a margin of 150mbar = 1.50m
1159 int_temp = (int_I_pres_respiration - int_I_pres_surface) 1160 int_temp = (int_I_pres_respiration - int_I_pres_surface)
1160 + MBAR_REACH_GASCHANGE_AUTO_CHANGE_OFF; 1161 + MBAR_REACH_GASCHANGE_AUTO_CHANGE_OFF;
1161 1162
1162 // Gas are selectable if we did not pass the change depth by more than 1.50m: 1163 // Gas are selectable if we did not pass the change depth by more than 1.50m:
1163 for(g=0; g < NUM_GAS; ++g) 1164 for(g=0; g < NUM_GAS; ++g)
1164 { 1165 {
1165 deco_gas_change[g] = 0; 1166 deco_gas_change[g] = 0;
1166 if(char_I_deco_gas_change[g]) 1167 if(char_I_deco_gas_change[g])
1167 if( int_temp > 100 *(short)char_I_deco_gas_change[g] ) 1168 if( int_temp > 100 *(short)char_I_deco_gas_change[g] )
1168 deco_gas_change[g] = char_I_deco_gas_change[g]; 1169 deco_gas_change[g] = char_I_deco_gas_change[g];
1169 } 1170 }
1170 1171
1171 const_ppO2 = char_I_const_ppO2 * 0.01; 1172 const_ppO2 = char_I_const_ppO2 * 0.01;
1172 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01; 1173 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01;
1173 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; 1174 float_saturation_multiplier = char_I_saturation_multiplier * 0.01;
1184 assert( 0.00 <= N2_ratio && N2_ratio <= 1.00 ); 1185 assert( 0.00 <= N2_ratio && N2_ratio <= 1.00 );
1185 assert( 0.00 <= He_ratio && He_ratio <= 1.00 ); 1186 assert( 0.00 <= He_ratio && He_ratio <= 1.00 );
1186 assert( (N2_ratio + He_ratio) <= 0.95 ); 1187 assert( (N2_ratio + He_ratio) <= 0.95 );
1187 assert( 0.800 < pres_respiration && pres_respiration < 14.0 ); 1188 assert( 0.800 < pres_respiration && pres_respiration < 14.0 );
1188 1189
1189 pres_diluent = pres_respiration; 1190 pres_diluent = pres_respiration;
1190 if( char_I_const_ppO2 != 0 ) // new in v.101 1191 if( char_I_const_ppO2 != 0 ) // new in v.101
1191 { 1192 {
1192 overlay float flush_ppO2 = pres_respiration * (1.0 - N2_ratio - He_ratio); 1193 overlay float flush_ppO2 = pres_respiration * (1.0 - N2_ratio - He_ratio);
1193 1194
1194 pres_diluent -= const_ppO2; // new in v.101 1195 pres_diluent -= const_ppO2; // new in v.101
1195 pres_diluent /= N2_ratio + He_ratio; // new in v.101 1196 pres_diluent /= N2_ratio + He_ratio; // new in v.101
1196 if( pres_diluent < 0.0 ) 1197 if( pres_diluent < 0.0 )
1197 pres_diluent = 0.0; 1198 pres_diluent = 0.0;
1198 if( pres_diluent > pres_respiration ) // new in v.101 1199 if( pres_diluent > pres_respiration ) // new in v.101
1199 pres_diluent = pres_respiration; // new in v.101 1200 pres_diluent = pres_respiration; // new in v.101
1200 1201
1201 char_O_diluent = (unsigned char)(pres_diluent/pres_respiration*100.0 + 0.5); 1202 char_O_diluent = (unsigned char)(pres_diluent/pres_respiration*100.0 + 0.5);
1202 1203
1203 if( flush_ppO2 > 2.545) flush_ppO2 = 2.55; 1204 if( flush_ppO2 > 2.545) flush_ppO2 = 2.55;
1204 if( flush_ppO2 < 0.0 ) flush_ppO2 = 0.0; 1205 if( flush_ppO2 < 0.0 ) flush_ppO2 = 0.0;
1205 char_O_flush_ppO2 = (unsigned char)(flush_ppO2*100.0 + 0.5); 1206 char_O_flush_ppO2 = (unsigned char)(flush_ppO2*100.0 + 0.5);
1206 } 1207 }
1207 1208
1208 if( pres_diluent > ppWater ) // new in v.101 1209 if( pres_diluent > ppWater ) // new in v.101
1209 { 1210 {
1210 overlay float EAD, END; 1211 overlay float EAD, END;
1211 1212
1212 ppN2 = N2_ratio * (pres_diluent - ppWater); // changed in v.101 1213 ppN2 = N2_ratio * (pres_diluent - ppWater); // changed in v.101
1213 ppHe = He_ratio * (pres_diluent - ppWater); // changed in v.101 1214 ppHe = He_ratio * (pres_diluent - ppWater); // changed in v.101
1214 1215
1215 // EAD : Equivalent Air Dive. Equivalent depth for the same N2 level 1216 // EAD : Equivalent Air Dive. Equivalent depth for the same N2 level
1216 // with plain air. 1217 // with plain air.
1217 // ppN2 = 79% * (P_EAD - ppWater) 1218 // ppN2 = 79% * (P_EAD - ppWater)
1218 // EAD = (P_EAD - Psurface) * 10 1219 // EAD = (P_EAD - Psurface) * 10
1219 // ie: EAD = (ppN2 / 0.7902 + ppWater -Psurface) * 10 1220 // ie: EAD = (ppN2 / 0.7902 + ppWater -Psurface) * 10
1220 EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * BAR_TO_METER; 1221 EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * BAR_TO_METER;
1221 if( EAD < 0.0 || EAD > 245.5 ) EAD = 0.0; 1222 if( EAD < 0.0 || EAD > 245.5 ) EAD = 0.0;
1222 char_O_EAD = (unsigned char)(EAD + 0.5); 1223 char_O_EAD = (unsigned char)(EAD + 0.5);
1223 1224
1224 // END : Equivalent Narcotic Dive. 1225 // END : Equivalent Narcotic Dive.
1225 // Here we count O2 as narcotic too. Hence everything but helium (has a narcosis factor of 1226 // Here we count O2 as narcotic too. Hence everything but helium (has a narcosis factor of
1226 // 0.23 btw). Hence the formula becomes: 1227 // 0.23 btw). Hence the formula becomes:
1227 // END * BarPerMeter * (1.0 - 0.0) - ppWater + Psurface == Pambient - ppHe - ppWater 1228 // END * BarPerMeter * (1.0 - 0.0) - ppWater + Psurface == Pambient - ppHe - ppWater
1228 // ie: END = (Pambient - ppHe - Psurface) * BAR_TO_METER 1229 // ie: END = (Pambient - ppHe - Psurface) * BAR_TO_METER
1229 // 1230 //
1230 // Source cited: 1231 // Source cited:
1231 // The Physiology and Medicine of Diving by Peter Bennett and David Elliott, 1232 // The Physiology and Medicine of Diving by Peter Bennett and David Elliott,
1232 // 4th edition, 1993, W.B.Saunders Company Ltd, London. 1233 // 4th edition, 1993, W.B.Saunders Company Ltd, London.
1233 END = (pres_respiration - ppHe - pres_surface) * BAR_TO_METER; 1234 END = (pres_respiration - ppHe - pres_surface) * BAR_TO_METER;
1234 if( END < 0.0 || END > 245.5 ) END = 0.0; 1235 if( END < 0.0 || END > 245.5 ) END = 0.0;
1235 char_O_END = (unsigned char)(END + 0.5); 1236 char_O_END = (unsigned char)(END + 0.5);
1236 } 1237 }
1237 else // new in v.101 1238 else // new in v.101
1238 { 1239 {
1239 ppN2 = 0.0; // new in v.101 1240 ppN2 = 0.0; // new in v.101
1240 ppHe = 0.0; // new in v.101 1241 ppHe = 0.0; // new in v.101
1241 char_O_EAD = char_O_END = 0; 1242 char_O_EAD = char_O_END = 0;
1242 } 1243 }
1243 1244
1244 if(!char_I_step_is_1min) 1245 if(!char_I_step_is_1min)
1245 calc_tissue(0); 1246 calc_tissue(0);
1246 else 1247 else
1247 calc_tissue(1); 1248 calc_tissue(1);
1248 1249
1249 // Calc limit for surface, ie. GF_high. 1250 // Calc limit for surface, ie. GF_high.
1250 calc_limit(); 1251 calc_limit();
1251 1252
1252 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000); 1253 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000);
1253 int_O_gtissue_press = (short)((pres_tissue_N2[char_O_gtissue_no] + pres_tissue_He[char_O_gtissue_no]) * 1000); 1254 int_O_gtissue_press = (short)((pres_tissue_N2[char_O_gtissue_no] + pres_tissue_He[char_O_gtissue_no]) * 1000);
1254 } 1255 }
1255 1256
1256 1257
1257 ////////////////////////////////////////////////////////////////////////////// 1258 //////////////////////////////////////////////////////////////////////////////
1258 // Compute stops. 1259 // Compute stops.
1259 // 1260 //
1260 // Note: because this can be very long, break on 16 iterations, and set state 1261 // Note: because this can be very long, break on 16 iterations, and set state
1261 // to 0 when finished, or to 1 when needing to continue. 1262 // to 0 when finished, or to 1 when needing to continue.
1262 // Note: because each iteration might be very long too (~ 66 ms in 1.84beta), 1263 // Note: because each iteration might be very long too (~ 66 ms in 1.84beta),
1263 // break the loop when total time > 512msec. 1264 // break the loop when total time > 512msec.
1264 // 1265 //
1265 void calc_hauptroutine_calc_deco(void) 1266 void calc_hauptroutine_calc_deco(void)
1266 { 1267 {
1267 overlay unsigned char loop; 1268 overlay unsigned char loop;
1268 1269
1269 for(loop = 0; loop < 16; ++loop) 1270 for(loop = 0; loop < 16; ++loop)
1270 { 1271 {
1271 // Limit loops to 512ms, using the RTC timer 3: 1272 // Limit loops to 512ms, using the RTC timer 3:
1272 if( tmr3() & (512*32) ) 1273 if( tmr3() & (512*32) )
1273 break; 1274 break;
1274 1275
1275 // Do not ascent while doing a gas switch ? 1276 // Do not ascent while doing a gas switch ?
1276 if( sim_gas_delay <= sim_dive_mins ) 1277 if( sim_gas_delay <= sim_dive_mins )
1277 { 1278 {
1278 if( calc_nextdecodepth() ) 1279 if( calc_nextdecodepth() )
1279 { 1280 {
1280 if( temp_depth_limit == 0 ) 1281 if( temp_depth_limit == 0 )
1281 goto Surface; 1282 goto Surface;
1282 1283
1283 //---- We hit a stop at temp_depth_limit --------------------- 1284 //---- We hit a stop at temp_depth_limit ---------------------
1284 temp_deco = temp_depth_limit * METER_TO_BAR // Convert to relative bar, 1285 temp_deco = temp_depth_limit * METER_TO_BAR // Convert to relative bar,
1285 + pres_surface; // To absolute. 1286 + pres_surface; // To absolute.
1286 if( !update_deco_table() ) // Adds a one minute stops. 1287 if( !update_deco_table() ) // Adds a one minute stops.
1287 goto Surface; // Deco table full: abort... 1288 goto Surface; // Deco table full: abort...
1288 } 1289 }
1289 else 1290 else
1290 { 1291 {
1294 //---- Finish computations once surface is reached ----------- 1295 //---- Finish computations once surface is reached -----------
1295 if( temp_deco <= pres_surface ) 1296 if( temp_deco <= pres_surface )
1296 { 1297 {
1297 Surface: 1298 Surface:
1298 if( char_O_deco_status == 1 ) // Don't in @+5min variant. 1299 if( char_O_deco_status == 1 ) // Don't in @+5min variant.
1299 copy_deco_table(); 1300 copy_deco_table();
1300 1301
1301 calc_ascenttime(); 1302 calc_ascenttime();
1302 char_O_deco_status = 0; // calc nullzeit next time. 1303 char_O_deco_status = 0; // calc nullzeit next time.
1303 char_O_deco_last_stop = 0; // Surface reached (to animate menu) 1304 char_O_deco_last_stop = 0; // Surface reached (to animate menu)
1304 return; 1305 return;
1305 } 1306 }
1306 } 1307 }
1307 } 1308 }
1308 else 1309 else
1309 { 1310 {
1314 } 1315 }
1315 1316
1316 //---- Then update tissue -------------------------------------------- 1317 //---- Then update tissue --------------------------------------------
1317 sim_dive_mins++; // Advance simulated time by 1 minute. 1318 sim_dive_mins++; // Advance simulated time by 1 minute.
1318 gas_switch_set(); // Apply any simulated gas change, once validated. 1319 gas_switch_set(); // Apply any simulated gas change, once validated.
1319 sim_alveolar_presures(); // Updates ppN2 and ppHe. 1320 sim_alveolar_presures(); // Updates ppN2 and ppHe.
1320 sim_tissue(1); // Simulate compartiments for 1 minute. 1321 sim_tissue(1); // Simulate compartiments for 1 minute.
1321 } 1322 }
1322 1323
1323 // Surface not reached, need more stops... for menu animation. 1324 // Surface not reached, need more stops... for menu animation.
1324 char_O_deco_last_stop = temp_depth_limit; // Reached depth. 1325 char_O_deco_last_stop = temp_depth_limit; // Reached depth.
1325 } 1326 }
1326 1327
1327 ////////////////////////////////////////////////////////////////////////////// 1328 //////////////////////////////////////////////////////////////////////////////
1328 // Simulation ascention to first deco stop. 1329 // Simulation ascention to first deco stop.
1341 overlay unsigned char fast = 1; // 1min or 2sec steps. 1342 overlay unsigned char fast = 1; // 1min or 2sec steps.
1342 1343
1343 update_startvalues(); 1344 update_startvalues();
1344 clear_deco_table(); 1345 clear_deco_table();
1345 1346
1346 temp_deco = pres_respiration; // Starts from current real depth. 1347 temp_deco = pres_respiration; // Starts from current real depth.
1347 1348
1348 // Are we doing the special @+5min variation ? 1349 // Are we doing the special @+5min variation ?
1349 if(char_O_deco_status & 4) 1350 if(char_O_deco_status & 4)
1350 sim_extra_time(); 1351 sim_extra_time();
1351 1352
1352 // Do we have a gas switch going on ? 1353 // Do we have a gas switch going on ?
1353 if( sim_gas_delay > sim_dive_mins ) 1354 if( sim_gas_delay > sim_dive_mins )
1354 return; 1355 return;
1355 1356
1356 //---- Loop until first stop, gas switch, or surface is reached ---------- 1357 //---- Loop until first stop, gas switch, or surface is reached ----------
1357 for(;;) 1358 for(;;)
1358 { 1359 {
1359 overlay float old_deco = temp_deco; // Pamb backup (bars) 1360 overlay float old_deco = temp_deco; // Pamb backup (bars)
1360 1361
1361 // Try ascending 1 full minute (fast) or 2sec (!fast): 1362 // Try ascending 1 full minute (fast) or 2sec (!fast):
1362 if( fast ) 1363 if( fast )
1363 temp_deco -= 10*METER_TO_BAR; // 1 min, at 10m/min. ~ 1bar. 1364 temp_deco -= 10*METER_TO_BAR; // 1 min, at 10m/min. ~ 1bar.
1405 1406
1406 if( fast ) 1407 if( fast )
1407 sim_dive_mins++; // Advance simulated time by 1 minute. 1408 sim_dive_mins++; // Advance simulated time by 1 minute.
1408 sim_alveolar_presures(); // temp_deco --> ppN2/ppHe 1409 sim_alveolar_presures(); // temp_deco --> ppN2/ppHe
1409 sim_tissue(fast); // and update tissues for 1 min. 1410 sim_tissue(fast); // and update tissues for 1 min.
1410 } 1411 }
1411 } 1412 }
1412 1413
1413 ////////////////////////////////////////////////////////////////////////////// 1414 //////////////////////////////////////////////////////////////////////////////
1414 // Simulation extra time at the current depth. 1415 // Simulation extra time at the current depth.
1415 // 1416 //
1417 void sim_extra_time(void) 1418 void sim_extra_time(void)
1418 { 1419 {
1419 overlay unsigned char extra = read_custom_function(58); 1420 overlay unsigned char extra = read_custom_function(58);
1420 do { 1421 do {
1421 sim_dive_mins++; // Advance simulated time by 1 minute. 1422 sim_dive_mins++; // Advance simulated time by 1 minute.
1422 sim_tissue(1); // and update tissues for 1 min. 1423 sim_tissue(1); // and update tissues for 1 min.
1423 } while( --extra != 0 ); 1424 } while( --extra != 0 );
1424 } 1425 }
1425 1426
1426 ////////////////////////////////////////////////////////////////////////////// 1427 //////////////////////////////////////////////////////////////////////////////
1427 // calc_tissue 1428 // calc_tissue
1524 overlay unsigned char ndl; 1525 overlay unsigned char ndl;
1525 overlay unsigned char period = 10; 1526 overlay unsigned char period = 10;
1526 1527
1527 read_buhlmann_coefficients(); 1528 read_buhlmann_coefficients();
1528 read_buhlmann_times(2); // Starts with a 10min period. 1529 read_buhlmann_times(2); // Starts with a 10min period.
1529 1530
1530 //---- Simulate for that tissue -------------------------------------- 1531 //---- Simulate for that tissue --------------------------------------
1531 // NOTE: No need to simulate for longuer than the already found NDL. 1532 // NOTE: No need to simulate for longuer than the already found NDL.
1532 for(ndl=0; ndl<char_O_nullzeit;) 1533 for(ndl=0; ndl<char_O_nullzeit;)
1533 { 1534 {
1534 //---- Compute updated mix M-value at surface 1535 //---- Compute updated mix M-value at surface
1597 { 1598 {
1598 overlay unsigned char x; 1599 overlay unsigned char x;
1599 overlay unsigned short sum; 1600 overlay unsigned short sum;
1600 1601
1601 // + 0.7 to count 1 minute ascent time from 3 metre to surface 1602 // + 0.7 to count 1 minute ascent time from 3 metre to surface
1602 overlay float ascent = pres_respiration - pres_surface + 0.7; 1603 overlay float ascent = pres_respiration - pres_surface + 0.7;
1603 if (ascent < 0.0) 1604 if (ascent < 0.0)
1604 ascent = 0.0; 1605 ascent = 0.0;
1605 sum = (unsigned short)(ascent + 0.99); 1606 sum = (unsigned short)(ascent + 0.99);
1606 1607
1607 for(x=0; x<NUM_STOPS && internal_deco_depth[x]; x++) 1608 for(x=0; x<NUM_STOPS && internal_deco_depth[x]; x++)
1621 void update_startvalues(void) 1622 void update_startvalues(void)
1622 { 1623 {
1623 overlay unsigned char x; 1624 overlay unsigned char x;
1624 1625
1625 // Start ascent simulation with current tissue partial pressures. 1626 // Start ascent simulation with current tissue partial pressures.
1626 for(x=0; x<NUM_COMP; x++) 1627 for(x=0; x<NUM_COMP; x++)
1627 { 1628 {
1628 sim_pres_tissue_N2[x] = pres_tissue_N2[x]; 1629 sim_pres_tissue_N2[x] = pres_tissue_N2[x];
1629 sim_pres_tissue_He[x] = pres_tissue_He[x]; 1630 sim_pres_tissue_He[x] = pres_tissue_He[x];
1630 } 1631 }
1631 1632
1632 // No leading tissue (yet) for this ascent simulation. 1633 // No leading tissue (yet) for this ascent simulation.
1633 sim_lead_tissue_limit = 0.0; 1634 sim_lead_tissue_limit = 0.0;
1634 sim_lead_tissue_no = 255; 1635 sim_lead_tissue_no = 255;
1635 } 1636 }
1653 1654
1654 // N2 1655 // N2
1655 temp_tissue = (ppN2 - sim_pres_tissue_N2[ci]) * var_N2_e; 1656 temp_tissue = (ppN2 - sim_pres_tissue_N2[ci]) * var_N2_e;
1656 temp_tissue_safety(); 1657 temp_tissue_safety();
1657 sim_pres_tissue_N2[ci] += temp_tissue; 1658 sim_pres_tissue_N2[ci] += temp_tissue;
1658 1659
1659 // He 1660 // He
1660 temp_tissue = (ppHe - sim_pres_tissue_He[ci]) * var_He_e; 1661 temp_tissue = (ppHe - sim_pres_tissue_He[ci]) * var_He_e;
1661 temp_tissue_safety(); 1662 temp_tissue_safety();
1662 sim_pres_tissue_He[ci] += temp_tissue; 1663 sim_pres_tissue_He[ci] += temp_tissue;
1663 } 1664 }
1692 // Note: the correction factor depends both on GF and b, 1693 // Note: the correction factor depends both on GF and b,
1693 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%), 1694 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%),
1694 // so that can change who is the leading gas... 1695 // so that can change who is the leading gas...
1695 // Note: Also depends of the GF_current... 1696 // Note: Also depends of the GF_current...
1696 if( char_I_deco_model != 0 ) 1697 if( char_I_deco_model != 0 )
1697 p = ( p - var_N2_a * GF_current) 1698 p = ( p - var_N2_a * GF_current)
1698 / (GF_current / var_N2_b + 1.0 - GF_current); 1699 / (GF_current / var_N2_b + 1.0 - GF_current);
1699 else 1700 else
1700 p = (p - var_N2_a) * var_N2_b; 1701 p = (p - var_N2_a) * var_N2_b;
1701 1702
1702 if( p > sim_lead_tissue_limit ) 1703 if( p > sim_lead_tissue_limit )
1749 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) ); 1750 assert( !internal_deco_depth[x] || temp_depth_limit <= (internal_deco_depth[x]& 0x7F) );
1750 1751
1751 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit ) 1752 if( (internal_deco_depth[x] & 0x7F) == temp_depth_limit )
1752 { 1753 {
1753 // Do not overflow (max 255') 1754 // Do not overflow (max 255')
1754 if( internal_deco_time[x] < 255 ) 1755 if( internal_deco_time[x] < 255 )
1755 { 1756 {
1756 internal_deco_time[x]++; 1757 internal_deco_time[x]++;
1757 return 1; 1758 return 1;
1758 } 1759 }
1759 // But store extra in the next stop... 1760 // But store extra in the next stop...
1789 overlay float He = pres_tissue_He[char_O_gtissue_no]; 1790 overlay float He = pres_tissue_He[char_O_gtissue_no];
1790 1791
1791 assert( char_O_gtissue_no < NUM_COMP ); 1792 assert( char_O_gtissue_no < NUM_COMP );
1792 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); 1793 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 );
1793 1794
1794 // tissue > respiration (currently off-gasing) 1795 // tissue > respiration (currently off-gasing)
1795 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium. 1796 // GF = 0% when respiration == tissue, ie. bubbles are at equilibrium.
1796 // GF = 100% when respiration == limit. 1797 // GF = 100% when respiration == limit.
1797 temp_tissue = N2 + He; 1798 temp_tissue = N2 + He;
1798 if( temp_tissue <= pres_respiration ) 1799 if( temp_tissue <= pres_respiration )
1799 gf = 0.0; 1800 gf = 0.0;
1800 else 1801 else
1801 { 1802 {
1802 overlay float limit = calc_lead_tissue_limit; 1803 overlay float limit = calc_lead_tissue_limit;
1803 // NOTE: in GF model, calc_lead_tissue_limit include already the 1804 // NOTE: in GF model, calc_lead_tissue_limit include already the
1804 // correction due to gradient factor. To compute the actual 1805 // correction due to gradient factor. To compute the actual
1811 var_N2_a = (var_N2_a * N2 + var_He_a * He) / temp_tissue; 1812 var_N2_a = (var_N2_a * N2 + var_He_a * He) / temp_tissue;
1812 var_N2_b = (var_N2_b * N2 + var_He_b * He) / temp_tissue; 1813 var_N2_b = (var_N2_b * N2 + var_He_b * He) / temp_tissue;
1813 limit = (temp_tissue - var_N2_a) * var_N2_b; 1814 limit = (temp_tissue - var_N2_a) * var_N2_b;
1814 } 1815 }
1815 1816
1816 gf = (temp_tissue - pres_respiration) 1817 gf = (temp_tissue - pres_respiration)
1817 / (temp_tissue - limit) 1818 / (temp_tissue - limit)
1818 * 100.0; 1819 * 100.0;
1819 if( gf > 254.5 ) gf = 255.0; 1820 if( gf > 254.5 ) gf = 255.0;
1820 if( gf < 0.0 ) gf = 0.0; 1821 if( gf < 0.0 ) gf = 0.0;
1821 } 1822 }
1822 char_O_gradient_factor = (unsigned char)(gf+0.5f); 1823 char_O_gradient_factor = (unsigned char)(gf+0.5f);
1823 1824
1824 if( char_I_deco_model != 0 ) // calculate relative gradient factor 1825 if( char_I_deco_model != 0 ) // calculate relative gradient factor
1825 { 1826 {
1826 overlay float rgf; 1827 overlay float rgf;
1827 1828
1828 if( low_depth < 3 ) 1829 if( low_depth < 3 )
1829 rgf = GF_high; 1830 rgf = GF_high;
1830 else 1831 else
1831 { 1832 {
1832 overlay float temp1 = low_depth * METER_TO_BAR; 1833 overlay float temp1 = low_depth * METER_TO_BAR;
1833 overlay float temp2 = pres_respiration - pres_surface; 1834 overlay float temp2 = pres_respiration - pres_surface;
1834 1835
1835 if (temp2 <= 0) 1836 if (temp2 <= 0)
1836 rgf = GF_high; 1837 rgf = GF_high;
1837 else if (temp2 >= temp1) 1838 else if (temp2 >= temp1)
1838 rgf = GF_low; 1839 rgf = GF_low;
1839 else 1840 else
1840 rgf = GF_low + (temp1 - temp2)/temp1*GF_delta; 1841 rgf = GF_low + (temp1 - temp2)/temp1*GF_delta;
1841 } 1842 }
1842 1843
1843 rgf = gf / rgf; // gf is already in percent 1844 rgf = gf / rgf; // gf is already in percent
1844 if( rgf < 0.0 ) rgf = 0.0; 1845 if( rgf < 0.0 ) rgf = 0.0;
1845 if( rgf > 254.5 ) rgf = 255.0; 1846 if( rgf > 254.5 ) rgf = 255.0;
1846 char_O_relative_gradient_GF = (unsigned char)(rgf+0.5f); 1847 char_O_relative_gradient_GF = (unsigned char)(rgf+0.5f);
1847 } // calc relative gradient factor 1848 } // calc relative gradient factor
1848 else 1849 else
1849 { 1850 {
1850 char_O_relative_gradient_GF = char_O_gradient_factor; 1851 char_O_relative_gradient_GF = char_O_gradient_factor;
1851 } 1852 }
1852 } 1853 }
1853 1854
1854 ////////////////////////////////////////////////////////////////////////////// 1855 //////////////////////////////////////////////////////////////////////////////
1855 // deco_calc_desaturation_time 1856 // deco_calc_desaturation_time
1856 // 1857 //
1891 temp2 = ppN2 - pres_tissue_N2[ci]; 1892 temp2 = ppN2 - pres_tissue_N2[ci];
1892 if (temp2 >= 0.0) 1893 if (temp2 >= 0.0)
1893 temp1 = 0.0; 1894 temp1 = 0.0;
1894 else 1895 else
1895 temp1 = temp1 / temp2; 1896 temp1 = temp1 / temp2;
1896 1897
1897 if( 0.0 < temp1 && temp1 < 1.0 ) 1898 if( 0.0 < temp1 && temp1 < 1.0 )
1898 { 1899 {
1899 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. 1900 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
1900 // minus because log is negative. 1901 // minus because log is negative.
1901 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary. 1902 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary.
1914 temp3 = 0.0; 1915 temp3 = 0.0;
1915 else 1916 else
1916 temp3 = - temp3 / pres_tissue_He[ci]; 1917 temp3 = - temp3 / pres_tissue_He[ci];
1917 1918
1918 if( 0.0 < temp3 && temp3 < 1.0 ) 1919 if( 0.0 < temp3 && temp3 < 1.0 )
1919 { 1920 {
1920 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary. 1921 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary.
1921 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. 1922 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
1922 // minus because log is negative 1923 // minus because log is negative
1923 temp4 = var_He_ht * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier 1924 temp4 = var_He_ht * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier
1924 } 1925 }
1925 else 1926 else
1926 { 1927 {
1927 temp3 = 0.0; 1928 temp3 = 0.0;
1928 temp4 = 0.0; 1929 temp4 = 0.0;
1929 } 1930 }
1930 1931
1931 // saturation_time (for flight) 1932 // saturation_time (for flight)
1932 if (temp4 > temp2) 1933 if (temp4 > temp2)
1933 desat_time = (unsigned short)temp4; 1934 desat_time = (unsigned short)temp4;
1934 else 1935 else
1935 desat_time = (unsigned short)temp2; 1936 desat_time = (unsigned short)temp2;
1936 1937
1937 if(desat_time > int_O_desaturation_time) 1938 if(desat_time > int_O_desaturation_time)
1938 int_O_desaturation_time = desat_time; 1939 int_O_desaturation_time = desat_time;
1939 1940
1940 // N2 saturation in multiples of halftime for display purposes 1941 // N2 saturation in multiples of halftime for display purposes
1941 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 1942 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8
1975 pres_respiration = pres_surface = int_I_pres_surface * 0.001; 1976 pres_respiration = pres_surface = int_I_pres_surface * 0.001;
1976 ppN2 = N2_ratio * (pres_respiration - ppWater); 1977 ppN2 = N2_ratio * (pres_respiration - ppWater);
1977 ppHe = 0.0; 1978 ppHe = 0.0;
1978 float_desaturation_multiplier = char_I_desaturation_multiplier * (0.01 * SURFACE_DESAT_FACTOR); 1979 float_desaturation_multiplier = char_I_desaturation_multiplier * (0.01 * SURFACE_DESAT_FACTOR);
1979 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; 1980 float_saturation_multiplier = char_I_saturation_multiplier * 0.01;
1980 1981
1981 calc_tissue(1); // update the pressure in the tissues N2/He in accordance with the new ambient pressure 1982 calc_tissue(1); // update the pressure in the tissues N2/He in accordance with the new ambient pressure
1982 1983
1983 clear_deco_table(); 1984 clear_deco_table();
1984 char_O_deco_status = 3; // surface new in v.102 : stays in surface state. 1985 char_O_deco_status = 3; // surface new in v.102 : stays in surface state.
1985 char_O_nullzeit = 0; 1986 char_O_nullzeit = 0;
1986 int_O_ascenttime = 0; 1987 int_O_ascenttime = 0;
1987 int_O_extra_ascenttime = 0; 1988 int_O_extra_ascenttime = 0;
2024 calc_tissue(2); // period = 10min. 2025 calc_tissue(2); // period = 10min.
2025 CNS_fraction = 0.92587471 * CNS_fraction; // Half-time = 90min: (1/2)^(1/9) 2026 CNS_fraction = 0.92587471 * CNS_fraction; // Half-time = 90min: (1/2)^(1/9)
2026 } 2027 }
2027 assert( 0.0 <= CNS_fraction && CNS_fraction <= 2.56 ); 2028 assert( 0.0 <= CNS_fraction && CNS_fraction <= 2.56 );
2028 char_O_CNS_fraction = (unsigned char)(CNS_fraction * 100.0 + 0.5); 2029 char_O_CNS_fraction = (unsigned char)(CNS_fraction * 100.0 + 0.5);
2029 2030
2030 //---- Restore model ----------------------------------------------------- 2031 //---- Restore model -----------------------------------------------------
2031 char_I_deco_model = backup_model; 2032 char_I_deco_model = backup_model;
2032 } 2033 }
2033 2034
2034 ////////////////////////////////////////////////////////////////////////////// 2035 //////////////////////////////////////////////////////////////////////////////
2045 overlay unsigned char md_buffer[16]; 2046 overlay unsigned char md_buffer[16];
2046 overlay unsigned char md_temp; 2047 overlay unsigned char md_temp;
2047 overlay unsigned short md_pointer; 2048 overlay unsigned short md_pointer;
2048 2049
2049 RESET_C_STACK 2050 RESET_C_STACK
2050 2051
2051 // init 2052 // init
2052 for(md_i=0;md_i<16;md_i++) 2053 for(md_i=0;md_i<16;md_i++)
2053 { 2054 {
2054 md_state[md_i] = 0; 2055 md_state[md_i] = 0;
2055 char_O_hash[md_i] = 0; 2056 char_O_hash[md_i] = 0;
2099 2100
2100 md_buffer[md_i] = md_temp; 2101 md_buffer[md_i] = md_temp;
2101 md_state[md_i+16] = md_temp; 2102 md_state[md_i+16] = md_temp;
2102 md_state[md_i+32] = (unsigned char)(md_temp ^ md_state[md_i]); 2103 md_state[md_i+32] = (unsigned char)(md_temp ^ md_state[md_i]);
2103 } // for md_i 16 2104 } // for md_i 16
2104 2105
2105 for (md_i=0;md_i<18;md_i++) 2106 for (md_i=0;md_i<18;md_i++)
2106 { 2107 {
2107 for (md_j=0;md_j<48;md_j++) 2108 for (md_j=0;md_j<48;md_j++)
2108 { 2109 {
2109 md_state[md_j] ^= md_pi_subst[md_t]; 2110 md_state[md_j] ^= md_pi_subst[md_t];
2110 md_t = md_state[md_j]; 2111 md_t = md_state[md_j];
2111 } // for md_j 48 2112 } // for md_j 48
2112 md_t = (unsigned char)(md_t+1); 2113 md_t = (unsigned char)(md_t+1);
2113 } // for md_i 18 2114 } // for md_i 18
2114 md_t = char_O_hash[15]; 2115 md_t = char_O_hash[15];
2115 2116
2116 for (md_i=0;md_i<16;md_i++) 2117 for (md_i=0;md_i<16;md_i++)
2117 { 2118 {
2118 char_O_hash[md_i] ^= md_pi_subst[(md_buffer[md_i] ^ md_t)]; 2119 char_O_hash[md_i] ^= md_pi_subst[(md_buffer[md_i] ^ md_t)];
2119 md_t = char_O_hash[md_i]; 2120 md_t = char_O_hash[md_i];
2120 } // for md_i 16 2121 } // for md_i 16
2143 // CNS_fraction : velue before period. 2144 // CNS_fraction : velue before period.
2144 // Output: CNS_fraction, char_O_CNS_fraction 2145 // Output: CNS_fraction, char_O_CNS_fraction
2145 // 2146 //
2146 void deco_calc_CNS_fraction(void) 2147 void deco_calc_CNS_fraction(void)
2147 { 2148 {
2148 overlay float time_factor = 1.0f; 2149 overlay float time_factor = 1.0f;
2149 RESET_C_STACK 2150 RESET_C_STACK
2150 2151
2151 assert( 0.0 <= CNS_fraction && CNS_fraction <= 2.56 ); 2152 assert( 0.0 <= CNS_fraction && CNS_fraction <= 2.56 );
2152 assert( char_I_actual_ppO2 > 15 ); 2153 assert( char_I_actual_ppO2 > 15 );
2153 2154
2159 // Don't increase CNS below 0.5 bar, but keep it steady. 2160 // Don't increase CNS below 0.5 bar, but keep it steady.
2160 if (char_I_actual_ppO2 < 50) 2161 if (char_I_actual_ppO2 < 50)
2161 ; // no changes 2162 ; // no changes
2162 //------------------------------------------------------------------------ 2163 //------------------------------------------------------------------------
2163 // Below (and including) 1.60 bar 2164 // Below (and including) 1.60 bar
2164 else if (char_I_actual_ppO2 < 60) 2165 else if (char_I_actual_ppO2 < 61)
2165 CNS_fraction += time_factor/(-533.07 * char_I_actual_ppO2 + 54000.0); 2166 CNS_fraction += time_factor/(-533.07 * char_I_actual_ppO2 + 54000.0);
2166 else if (char_I_actual_ppO2 < 70) 2167 else if (char_I_actual_ppO2 < 71)
2167 CNS_fraction += time_factor/(-444.22 * char_I_actual_ppO2 + 48600.0); 2168 CNS_fraction += time_factor/(-444.22 * char_I_actual_ppO2 + 48600.0);
2168 else if (char_I_actual_ppO2 < 80) 2169 else if (char_I_actual_ppO2 < 81)
2169 CNS_fraction += time_factor/(-355.38 * char_I_actual_ppO2 + 42300.0); 2170 CNS_fraction += time_factor/(-355.38 * char_I_actual_ppO2 + 42300.0);
2170 else if (char_I_actual_ppO2 < 90) 2171 else if (char_I_actual_ppO2 < 91)
2171 CNS_fraction += time_factor/(-266.53 * char_I_actual_ppO2 + 35100.0); 2172 CNS_fraction += time_factor/(-266.53 * char_I_actual_ppO2 + 35100.0);
2172 else if (char_I_actual_ppO2 < 110) 2173 else if (char_I_actual_ppO2 < 111)
2173 CNS_fraction += time_factor/(-177.69 * char_I_actual_ppO2 + 27000.0); 2174 CNS_fraction += time_factor/(-177.69 * char_I_actual_ppO2 + 27000.0);
2174 else if (char_I_actual_ppO2 < 150) 2175 else if (char_I_actual_ppO2 < 152)
2175 CNS_fraction += time_factor/( -88.84 * char_I_actual_ppO2 + 17100.0); 2176 CNS_fraction += time_factor/( -88.84 * char_I_actual_ppO2 + 17100.0);
2176 else if (char_I_actual_ppO2 < 165) 2177 else if (char_I_actual_ppO2 < 167)
2177 CNS_fraction += time_factor/(-222.11 * char_I_actual_ppO2 + 37350.0); 2178 CNS_fraction += time_factor/(-222.11 * char_I_actual_ppO2 + 37350.0);
2178 //------------------------------------------------------------------------ 2179 //------------------------------------------------------------------------
2179 // Arieli et all.(2002): Modeling pulmonary and CNS O2 toxicity: 2180 // Arieli et all.(2002): Modeling pulmonary and CNS O2 toxicity:
2180 // J Appl Physiol 92: 248–256, 2002, doi:10.1152/japplphysiol.00434.2001 2181 // J Appl Physiol 92: 248–256, 2002, doi:10.1152/japplphysiol.00434.2001
2181 // Formula (A1) based on value for 1.55 and c=20 2182 // Formula (A1) based on value for 1.55 and c=20
2182 // example calculation: Sqrt((1.7/1.55)^20)*0.000404 2183 // example calculation: Sqrt((1.7/1.55)^20)*0.000404
2183 else if (char_I_actual_ppO2 < 170) 2184 else if (char_I_actual_ppO2 < 172)
2184 CNS_fraction += time_factor*0.00102; 2185 CNS_fraction += time_factor*0.00102;
2185 else if (char_I_actual_ppO2 < 175) 2186 else if (char_I_actual_ppO2 < 177)
2186 CNS_fraction += time_factor*0.00136; 2187 CNS_fraction += time_factor*0.00136;
2187 else if (char_I_actual_ppO2 < 180) 2188 else if (char_I_actual_ppO2 < 182)
2188 CNS_fraction += time_factor*0.00180; 2189 CNS_fraction += time_factor*0.00180;
2189 else if (char_I_actual_ppO2 < 185) 2190 else if (char_I_actual_ppO2 < 187)
2190 CNS_fraction += time_factor*0.00237; 2191 CNS_fraction += time_factor*0.00237;
2191 else if (char_I_actual_ppO2 < 190) 2192 else if (char_I_actual_ppO2 < 192)
2192 CNS_fraction += time_factor*0.00310; 2193 CNS_fraction += time_factor*0.00310;
2193 else if (char_I_actual_ppO2 < 195) 2194 else if (char_I_actual_ppO2 < 198)
2194 CNS_fraction += time_factor*0.00401; 2195 CNS_fraction += time_factor*0.00401;
2195 else if (char_I_actual_ppO2 < 200) 2196 else if (char_I_actual_ppO2 < 203)
2196 CNS_fraction += time_factor*0.00517; 2197 CNS_fraction += time_factor*0.00517;
2197 else if (char_I_actual_ppO2 < 230) 2198 else if (char_I_actual_ppO2 < 233)
2198 CNS_fraction += time_factor*0.0209; 2199 CNS_fraction += time_factor*0.0209;
2199 else 2200 else
2200 CNS_fraction += time_factor*0.0482; // value for 2.5 2201 CNS_fraction += time_factor*0.0482; // value for 2.5
2201 2202
2202 if( CNS_fraction > 2.5 ) 2203 if( CNS_fraction > 2.5 )
2210 ////////////////////////////////////////////////////////////////////////////// 2211 //////////////////////////////////////////////////////////////////////////////
2211 // deco_calc_CNS_planning 2212 // deco_calc_CNS_planning
2212 // 2213 //
2213 // Compute CNS during predicted ascent. 2214 // Compute CNS during predicted ascent.
2214 // 2215 //
2215 // Note: Needs a call to deco_push_tissues_to_vault(), 2216 // Note: Needs a call to deco_push_tissues_to_vault(),
2216 // deco_pull_tissues_from_vault() to avoid trashing everything... 2217 // deco_pull_tissues_from_vault() to avoid trashing everything...
2217 // 2218 //
2218 // Input: CNS_fraction, char_O_deco_time[], char_O_deco_depth[] 2219 // Input: CNS_fraction, char_O_deco_time[], char_O_deco_depth[]
2219 // Output: CNS_fraction, char_O_CNS_fraction 2220 // Output: CNS_fraction, char_O_CNS_fraction
2220 // 2221 //
2235 backup_dive_mins = sim_dive_mins; 2236 backup_dive_mins = sim_dive_mins;
2236 backup_actual_ppO2 = char_I_actual_ppO2; 2237 backup_actual_ppO2 = char_I_actual_ppO2;
2237 2238
2238 // Uses 1min CNS period: 2239 // Uses 1min CNS period:
2239 char_I_step_is_1min = 1; 2240 char_I_step_is_1min = 1;
2240 2241
2241 //---- Retrieve bottom Gas used, and set variables. 2242 //---- Retrieve bottom Gas used, and set variables.
2242 sim_gas_last_used = char_I_first_gas; 2243 sim_gas_last_used = char_I_first_gas;
2243 sim_gas_last_depth = 0; // Surface gas marker. 2244 sim_gas_last_depth = 0; // Surface gas marker.
2244 gas_switch_set(); // Sets initial calc_N2/He_ratio 2245 gas_switch_set(); // Sets initial calc_N2/He_ratio
2245 2246
2291 { 2292 {
2292 time = char_O_deco_time[(NUM_STOPS-1)-i]; 2293 time = char_O_deco_time[(NUM_STOPS-1)-i];
2293 temp_depth_limit = char_O_deco_depth[(NUM_STOPS-1)-i]; 2294 temp_depth_limit = char_O_deco_depth[(NUM_STOPS-1)-i];
2294 } 2295 }
2295 if( time == 0 ) continue; 2296 if( time == 0 ) continue;
2296 2297
2297 //---- Gas Switch ? ---------------------------------------------- 2298 //---- Gas Switch ? ----------------------------------------------
2298 switch_gas = temp_depth_limit & 0x80; // Switch flag. 2299 switch_gas = temp_depth_limit & 0x80; // Switch flag.
2299 temp_depth_limit &= 0x7F; // True stop depth. 2300 temp_depth_limit &= 0x7F; // True stop depth.
2300 2301
2301 if( switch_gas ) 2302 if( switch_gas )
2325 sim_gas_last_depth = backup_gas_last_depth; 2326 sim_gas_last_depth = backup_gas_last_depth;
2326 sim_gas_last_used = backup_gas_last_used; 2327 sim_gas_last_used = backup_gas_last_used;
2327 sim_gas_delay = backup_gas_delay; 2328 sim_gas_delay = backup_gas_delay;
2328 sim_dive_mins = backup_dive_mins; 2329 sim_dive_mins = backup_dive_mins;
2329 char_I_actual_ppO2 = backup_actual_ppO2; 2330 char_I_actual_ppO2 = backup_actual_ppO2;
2330 } 2331 }
2331 2332
2332 ////////////////////////////////////////////////////////////////////////////// 2333 //////////////////////////////////////////////////////////////////////////////
2333 // deco_calc_CNS_decrease_15min 2334 // deco_calc_CNS_decrease_15min
2334 // 2335 //
2335 // new in v.101 2336 // new in v.101
2513 void deco_push_tissues_to_vault(void) 2514 void deco_push_tissues_to_vault(void)
2514 { 2515 {
2515 overlay unsigned char x; 2516 overlay unsigned char x;
2516 RESET_C_STACK 2517 RESET_C_STACK
2517 2518
2518 cns_vault = CNS_fraction; 2519 cns_vault = CNS_fraction;
2519 low_depth_vault = low_depth; 2520 low_depth_vault = low_depth;
2520 2521
2521 for (x=0;x<NUM_COMP;x++) 2522 for (x=0;x<NUM_COMP;x++)
2522 { 2523 {
2523 pres_tissue_N2_vault[x] = pres_tissue_N2[x]; 2524 pres_tissue_N2_vault[x] = pres_tissue_N2[x];
2524 pres_tissue_He_vault[x] = pres_tissue_He[x]; 2525 pres_tissue_He_vault[x] = pres_tissue_He[x];
2525 } 2526 }
2526 } 2527 }
2527 2528
2528 void deco_pull_tissues_from_vault(void) 2529 void deco_pull_tissues_from_vault(void)
2529 { 2530 {
2530 overlay unsigned char x; 2531 overlay unsigned char x;
2531 RESET_C_STACK 2532 RESET_C_STACK
2532 2533
2533 for (x=0; x<NUM_COMP; x++) 2534 for (x=0; x<NUM_COMP; x++)
2534 { 2535 {
2535 pres_tissue_N2[x] = pres_tissue_N2_vault[x]; 2536 pres_tissue_N2[x] = pres_tissue_N2_vault[x];
2536 pres_tissue_He[x] = pres_tissue_He_vault[x]; 2537 pres_tissue_He[x] = pres_tissue_He_vault[x];
2537 } 2538 }
2538 2539
2539 // Restore both CNS variable, too. 2540 // Restore both CNS variable, too.
2540 CNS_fraction = cns_vault; 2541 CNS_fraction = cns_vault;
2541 char_O_CNS_fraction = (unsigned char)(CNS_fraction * 100.0 + 0.5); 2542 char_O_CNS_fraction = (unsigned char)(CNS_fraction * 100.0 + 0.5);
2542 2543
2543 // GF history too: 2544 // GF history too: