Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 169:e26f49674956
Merge decoplan display for both GF and Buhlmann models.
+ Add CF(54) to reverse deco plan display order.
+ Clean state machine to faster redisplay in divemode.
Fix don't flip screen for soft emulation.
author | JeanDo |
---|---|
date | Wed, 26 Jan 2011 19:19:02 +0100 |
parents | 494587193f5d |
children | 7f3e1bf588bc |
comparison
equal
deleted
inserted
replaced
168:494587193f5d | 169:e26f49674956 |
---|---|
63 // 05/23/10 v109: 5 gas changes & 1 min timer | 63 // 05/23/10 v109: 5 gas changes & 1 min timer |
64 // 07/13/10 v110: cns vault added | 64 // 07/13/10 v110: cns vault added |
65 // 12/25/10 v110: split in three files (deco.c, main.c, definitions.h) | 65 // 12/25/10 v110: split in three files (deco.c, main.c, definitions.h) |
66 // 2011/01/20: [jDG] Create a common file included in ASM and C code. | 66 // 2011/01/20: [jDG] Create a common file included in ASM and C code. |
67 // 2011/01/23: [jDG] Added read_custom_function(). | 67 // 2011/01/23: [jDG] Added read_custom_function(). |
68 // + Make int_O_ascenttime an int. | 68 // 2011/01/24: [jDG] Make ascenttime an int. No more overflow! |
69 // 2011/01/25: [jDG] Fusion deco array for both models. | |
70 // 2011/01/25: [jDG] Use CF(54) to reverse deco order. | |
69 // | 71 // |
70 // TODO: | 72 // TODO: |
71 // + Fusion deco array for both models. | |
72 // + Allow (CF) revesring stop order (while copying). | |
73 // + Allow (CF) delay for gas switch while predicting ascent. | 73 // + Allow (CF) delay for gas switch while predicting ascent. |
74 // + Allow to abort MD2 calculation (have to restart next time). | 74 // + Allow to abort MD2 calculation (have to restart next time). |
75 // | 75 // |
76 // Literature: | 76 // Literature: |
77 // B"uhlmann, Albert: Tauchmedizin; 4. Auflage; | 77 // B"uhlmann, Albert: Tauchmedizin; 4. Auflage; |
101 | 101 |
102 static void calc_without_deco(void); | 102 static void calc_without_deco(void); |
103 static void clear_tissue(void); | 103 static void clear_tissue(void); |
104 static void calc_ascenttime(void); | 104 static void calc_ascenttime(void); |
105 static void update_startvalues(void); | 105 static void update_startvalues(void); |
106 static void clear_decoarray(void); | 106 static void clear_deco_table(void); |
107 static void update_decoarray(void); | 107 static void update_deco_table(void); |
108 static void sim_tissue_1min(void); | 108 static void sim_tissue_1min(void); |
109 static void sim_tissue_10min(void); | 109 static void sim_tissue_10min(void); |
110 static void calc_gradient_factor(void); | 110 static void calc_gradient_factor(void); |
111 static void calc_wo_deco_step_1_min(void); | 111 static void calc_wo_deco_step_1_min(void); |
112 | 112 |
113 static void calc_hauptroutine_data_input(void); | 113 static void calc_hauptroutine_data_input(void); |
114 static void calc_hauptroutine_update_tissues(void); | 114 static void calc_hauptroutine_update_tissues(void); |
115 static void calc_hauptroutine_calc_deco(void); | 115 static void calc_hauptroutine_calc_deco(void); |
116 static void calc_hauptroutine_calc_ascend_to_deco(void); | 116 static void sim_ascent_to_first_stop(void); |
117 | 117 |
118 static void calc_nextdecodepth_GF(void); | 118 static void calc_nextdecodepth_GF(void); |
119 static void copy_deco_table_GF(void); | |
120 static void clear_internal_deco_table_GF(void); | |
121 static void update_internal_deco_table_GF(void); | |
122 | 119 |
123 // *********************************************** | 120 // *********************************************** |
124 // ** V A R I A B L E S D E F I N I T I O N S ** | 121 // ** V A R I A B L E S D E F I N I T I O N S ** |
125 // *********************************************** | 122 // *********************************************** |
126 | 123 |
147 static unsigned int temp_depth_last_deco; // new in v.101 | 144 static unsigned int temp_depth_last_deco; // new in v.101 |
148 | 145 |
149 static unsigned char temp_depth_GF_low_meter; | 146 static unsigned char temp_depth_GF_low_meter; |
150 static unsigned char internal_deco_pointer; | 147 static unsigned char internal_deco_pointer; |
151 | 148 |
152 static unsigned char internal_deco_table[32]; | 149 static unsigned char internal_deco_time[32]; |
153 | 150 static unsigned char internal_deco_depth[32]; |
154 static char output[32]; // used by the math routines | |
155 | 151 |
156 static float cns_vault; | 152 static float cns_vault; |
157 | |
158 static float pres_tissue_vault[32]; | 153 static float pres_tissue_vault[32]; |
159 | 154 |
160 //---- Bank 5 parameters ----------------------------------------------------- | 155 //---- Bank 5 parameters ----------------------------------------------------- |
161 #pragma udata bank5=0x500 | 156 #pragma udata bank5=0x500 |
162 | 157 |
163 static unsigned char ci; | 158 static unsigned char ci; |
164 static unsigned int int_temp_decostatus; | |
165 static float pres_respiration; | 159 static float pres_respiration; |
166 static float pres_surface; | 160 static float pres_surface; |
167 static float temp1; | 161 static float temp1; |
168 static float temp2; | 162 static float temp2; |
169 static float temp3; | 163 static float temp3; |
616 static void calc_nextdecodepth_GF(void) | 610 static void calc_nextdecodepth_GF(void) |
617 { | 611 { |
618 | 612 |
619 char_I_table_deco_done[0] = 0; // safety if changed somewhere else. Needed for exit | 613 char_I_table_deco_done[0] = 0; // safety if changed somewhere else. Needed for exit |
620 | 614 |
621 //---- ZH-L16 + Gradient factor model ------------------------------------ | 615 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ |
622 if (char_I_deco_model == 1) | 616 if (char_I_deco_model == 1) |
623 { | 617 { |
624 overlay float next_stop; // Next stop to test, in Bar. | 618 overlay float next_stop; // Next stop to test, in Bar. |
625 overlay float press_tol; // Upper limit (lower pressure) tolerated. | 619 overlay float press_tol; // Upper limit (lower pressure) tolerated. |
626 overlay int int_temp; | 620 overlay int int_temp; |
657 if (internal_deco_pointer == 0) // new run | 651 if (internal_deco_pointer == 0) // new run |
658 { | 652 { |
659 internal_deco_pointer = temp_depth_GF_low_number; | 653 internal_deco_pointer = temp_depth_GF_low_number; |
660 GF_temp = GF_high - ((float)internal_deco_pointer * GF_step); | 654 GF_temp = GF_high - ((float)internal_deco_pointer * GF_step); |
661 int_temp = char_I_table_deco_done[internal_deco_pointer]; | 655 int_temp = char_I_table_deco_done[internal_deco_pointer]; |
662 output[8] = int_temp; | |
663 output[9] = 33; | |
664 } | 656 } |
665 else | 657 else |
666 { | 658 { |
667 int_temp = 1; | 659 int_temp = 1; |
668 } | 660 } |
705 temp_deco = next_stop + float_deco_distance + pres_surface; | 697 temp_deco = next_stop + float_deco_distance + pres_surface; |
706 if (internal_deco_pointer == 1) // new in v104 | 698 if (internal_deco_pointer == 1) // new in v104 |
707 temp_depth_limit = temp_depth_last_deco; | 699 temp_depth_limit = temp_depth_last_deco; |
708 else | 700 else |
709 temp_depth_limit = 3 * internal_deco_pointer; | 701 temp_depth_limit = 3 * internal_deco_pointer; |
710 if (output[9] == 33) | |
711 { | |
712 output[9] = internal_deco_pointer; | |
713 output[10] = char_I_table_deco_done[internal_deco_pointer]; | |
714 output[12] = output[12] + 1; | |
715 if (output[12] == 100) | |
716 output[12] = 0; | |
717 } | |
718 } | 702 } |
719 else // if (char_I_deco_model == 1) | 703 else // if (char_I_deco_model == 1) |
720 { | 704 { |
721 temp_deco = pres_surface; | 705 temp_deco = pres_surface; |
722 temp_depth_limit = 0; | 706 temp_depth_limit = 0; |
751 } // if (pres_gradient >= 0) | 735 } // if (pres_gradient >= 0) |
752 } // calc_nextdecodepth original | 736 } // calc_nextdecodepth original |
753 } | 737 } |
754 | 738 |
755 ////////////////////////////////////////////////////////////////////////////// | 739 ////////////////////////////////////////////////////////////////////////////// |
756 // copy_deco_table_GF | 740 // copy_deco_table |
757 // | 741 // |
758 // new in v.102 | 742 // Buffer the stops, once computed, so we can continue to display them |
759 // | 743 // while computing the next set. |
760 static void copy_deco_table_GF(void) | 744 // |
761 { | 745 static void copy_deco_table(void) |
762 overlay unsigned char x; | 746 { |
763 | 747 // Copy depth of the first (deepest) stop, because when reversing |
764 if( char_I_deco_model == 1 ) | 748 // order, it will be hard to find... |
765 { | 749 char_O_first_deco_depth = internal_deco_depth[0]; |
766 for(x=0; x<32; x++) | 750 char_O_first_deco_time = internal_deco_time [0]; |
767 char_O_deco_table[x] = internal_deco_table[x]; | 751 |
768 } | 752 if( read_custom_function(54) & 1 ) //---- Should we reverse table ? ------ |
769 } | 753 { |
770 | 754 overlay unsigned char x, y; |
771 ////////////////////////////////////////////////////////////////////////////// | 755 |
772 // clear_internal_deco_table_GF | 756 //---- First: search the first non-null depth |
773 // | 757 for(x=31; x != 0; --x) |
774 // new in v.102 | 758 if( internal_deco_depth[x] != 0 ) break; |
775 // | 759 |
776 static void clear_internal_deco_table_GF(void) | 760 //---- Second: copy to output table (in reverse order) |
777 { | 761 for(y=0; y<32; y++, --x) |
778 if (char_I_deco_model == 1) | 762 { |
779 { | 763 char_O_deco_depth[y] = internal_deco_depth[x]; |
764 char_O_deco_time [y] = internal_deco_time [x]; | |
765 | |
766 // Stop only once the last transfer is done. | |
767 if( x == 0 ) break; | |
768 } | |
769 | |
770 //---- Third: fill table end with null | |
771 for(y++; y<32; y++) | |
772 { | |
773 char_O_deco_time [y] = 0; | |
774 char_O_deco_depth[y] = 0; | |
775 } | |
776 } | |
777 else //---- Straight copy ------------------------------------------------ | |
778 { | |
780 overlay unsigned char x; | 779 overlay unsigned char x; |
781 | 780 |
782 for(x=0;x<32;x++) // cycle through the 16 tissues for N2 and He | 781 for(x=0; x<32; x++) |
783 internal_deco_table[x] = 0; | 782 { |
784 } | 783 char_O_deco_depth[x] = internal_deco_depth[x]; |
785 } | 784 char_O_deco_time [x] = internal_deco_time [x]; |
786 | 785 } |
787 ////////////////////////////////////////////////////////////////////////////// | 786 } |
788 // update_internal_deco_table_GF | |
789 // | |
790 // new in v.102 | |
791 // | |
792 // Add one minute to the current stop (if lower than 255). | |
793 // | |
794 static void update_internal_deco_table_GF(void) | |
795 { | |
796 if ((char_I_deco_model == 1) && (internal_deco_table[internal_deco_pointer] < 255)) | |
797 internal_deco_table[internal_deco_pointer]++; | |
798 } | 787 } |
799 | 788 |
800 ////////////////////////////////////////////////////////////////////////////// | 789 ////////////////////////////////////////////////////////////////////////////// |
801 // temp_tissue_safety // | 790 // temp_tissue_safety // |
802 // | 791 // |
849 LFSR 2, C_STACK \ | 838 LFSR 2, C_STACK \ |
850 _endasm | 839 _endasm |
851 #endif | 840 #endif |
852 | 841 |
853 ////////////////////////////////////////////////////////////////////////////// | 842 ////////////////////////////////////////////////////////////////////////////// |
854 | 843 // Called every 2 seconds during diving. |
844 // update tissues every time. | |
845 // Every 6 seconds (or slower when TTS > 16): | |
846 // - update deco table (char_O_deco_time/depth) with new values. | |
847 // - update ascent time, | |
848 // - set status to zero (so we can check there is new results). | |
849 // | |
855 void deco_calc_hauptroutine(void) | 850 void deco_calc_hauptroutine(void) |
856 { | 851 { |
857 RESET_C_STACK | 852 RESET_C_STACK |
858 calc_hauptroutine(); | 853 calc_hauptroutine(); |
859 int_O_desaturation_time = 65535; | 854 int_O_desaturation_time = 65535; |
930 | 925 |
931 // cycle through the 16 b"uhlmann tissues for Helium | 926 // cycle through the 16 b"uhlmann tissues for Helium |
932 (pres_tissue+16)[ci] = 0.0; | 927 (pres_tissue+16)[ci] = 0.0; |
933 } // for 0 to 16 | 928 } // for 0 to 16 |
934 | 929 |
935 clear_decoarray(); | 930 clear_deco_table(); |
936 char_O_deco_status = 0; | 931 char_O_deco_status = 0; |
937 char_O_nullzeit = 0; | 932 char_O_nullzeit = 0; |
938 int_O_ascenttime = 0; | 933 int_O_ascenttime = 0; |
939 char_O_gradient_factor = 0; | 934 char_O_gradient_factor = 0; |
940 char_O_relative_gradient_GF = 0; | 935 char_O_relative_gradient_GF = 0; |
958 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; | 953 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; |
959 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 954 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; |
960 | 955 |
961 calc_tissue_2_secs(); // update the pressure in the 32 tissues in accordance with the new ambient pressure | 956 calc_tissue_2_secs(); // update the pressure in the 32 tissues in accordance with the new ambient pressure |
962 | 957 |
963 clear_decoarray(); | 958 clear_deco_table(); |
964 char_O_deco_status = 0; | 959 char_O_deco_status = 0; |
965 char_O_nullzeit = 0; | 960 char_O_nullzeit = 0; |
966 int_O_ascenttime = 0; | 961 int_O_ascenttime = 0; |
967 calc_gradient_factor(); | 962 calc_gradient_factor(); |
968 } | 963 } |
997 { | 992 { |
998 case 0: //---- bottom time ----------------------------------------------- | 993 case 0: //---- bottom time ----------------------------------------------- |
999 update_startvalues(); | 994 update_startvalues(); |
1000 calc_nullzeit(); | 995 calc_nullzeit(); |
1001 check_ndl(); | 996 check_ndl(); |
1002 char_O_deco_status = 255; // calc deco next time | 997 char_O_deco_status = 2; // calc ascent next time. |
1003 break; | 998 break; |
1004 | 999 |
1005 case 1: //---- ???? ------------------------------------------------------ | 1000 case 1: //---- Simulate stops -------------------------------------------- |
1006 char_O_deco_status = 0; | |
1007 calc_hauptroutine_calc_deco(); | 1001 calc_hauptroutine_calc_deco(); |
1008 break; | 1002 break; |
1009 | 1003 |
1010 case 3: //---- new dive -------------------------------------------------- | 1004 case 3: //---- At surface: start a new dive ------------------------------ |
1011 clear_decoarray(); | 1005 clear_deco_table(); |
1012 clear_internal_deco_table_GF(); | 1006 copy_deco_table(); |
1013 copy_deco_table_GF(); | |
1014 internal_deco_pointer = 0; | 1007 internal_deco_pointer = 0; |
1015 lock_GF_depth_list = 0; | 1008 lock_GF_depth_list = 0; |
1016 update_startvalues(); | 1009 update_startvalues(); |
1017 calc_nextdecodepth_GF(); | 1010 calc_nextdecodepth_GF(); |
1018 char_O_deco_status = 0; | 1011 char_O_deco_status = 0; // Calc nullzeit next time. |
1019 break; | 1012 break; |
1020 | 1013 |
1021 default: //---- Continue stops calculation ------------------------------- | 1014 case 2: //---- Simulate ascent to first stop ----------------------------- |
1022 update_startvalues(); | 1015 sim_ascent_to_first_stop(); |
1023 clear_decoarray(); | 1016 char_O_deco_status = 1; // Cacl stops next time. |
1024 clear_internal_deco_table_GF(); | |
1025 output[6] = 1; | |
1026 calc_hauptroutine_calc_ascend_to_deco(); | |
1027 | |
1028 // can't go up to first deco, too deep to calculate in the given time slot | |
1029 if (char_O_deco_status > 15) | |
1030 char_O_deco_status = 2; | |
1031 else | |
1032 calc_hauptroutine_calc_deco(); | |
1033 break; | 1017 break; |
1034 } | 1018 } |
1035 | 1019 |
1036 calc_ascenttime(); | |
1037 check_post_dbg(); | 1020 check_post_dbg(); |
1038 } | 1021 } |
1039 | 1022 |
1040 ////////////////////////////////////////////////////////////////////////////// | 1023 ////////////////////////////////////////////////////////////////////////////// |
1041 // calc_hauptroutine_data_input | 1024 // calc_hauptroutine_data_input |
1179 { | 1162 { |
1180 temp1 = temp1 * GF_high; | 1163 temp1 = temp1 * GF_high; |
1181 } | 1164 } |
1182 else | 1165 else |
1183 { | 1166 { |
1184 temp1 = temp_surface; | 1167 temp1 = temp_surface; |
1185 } | 1168 } |
1186 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately | 1169 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately |
1187 { | 1170 { |
1188 char_O_nullzeit = 0; // deco necessary | 1171 char_O_nullzeit = 0; // deco necessary |
1189 char_O_deco_status = 255; // calculate deco skip nullzeit calculation | 1172 char_O_deco_status = 2; // calculate ascent on next iteration. |
1190 } | 1173 } |
1191 } // calc_hauptroutine_update_tissues | 1174 } // calc_hauptroutine_update_tissues |
1192 | 1175 |
1193 ////////////////////////////////////////////////////////////////////////////// | 1176 ////////////////////////////////////////////////////////////////////////////// |
1194 | 1177 // Compute stops. |
1178 // | |
1179 // Note: because this can be very long, break on 16 iterations, and set state | |
1180 // to 0 when finished, or to 1 when needing to continue. | |
1181 // | |
1195 void calc_hauptroutine_calc_deco(void) | 1182 void calc_hauptroutine_calc_deco(void) |
1196 { | 1183 { |
1197 do | 1184 overlay unsigned char loop; |
1185 | |
1186 for(loop = 0; loop < 16; ++loop) | |
1198 { | 1187 { |
1199 int_temp_decostatus = 0; | |
1200 calc_nextdecodepth_GF(); | 1188 calc_nextdecodepth_GF(); |
1201 if (temp_depth_limit > 0) | 1189 |
1202 { | 1190 //---- Finish computations once surface is reached ------------------- |
1203 calc_N2_ratio = N2_ratio; | 1191 if( temp_depth_limit <= 0 ) |
1204 calc_He_ratio = He_ratio; | 1192 { |
1205 | 1193 copy_deco_table(); |
1206 if (char_I_const_ppO2 == 0) // new in v.101 | 1194 calc_ascenttime(); |
1207 { | 1195 char_O_deco_status = 0; // calc nullzeit next time. |
1208 deco_diluent = temp_deco; // new in v.101 | 1196 return; |
1209 | 1197 } |
1210 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) | 1198 |
1211 { | 1199 //---- Else, continue simulating the stops --------------------------- |
1212 calc_N2_ratio = deco_N2_ratio1; | 1200 calc_N2_ratio = N2_ratio; |
1213 calc_He_ratio = deco_He_ratio1; | 1201 calc_He_ratio = He_ratio; |
1214 } | 1202 |
1215 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) | 1203 if (char_I_const_ppO2 == 0) |
1216 { | 1204 { |
1217 calc_N2_ratio = deco_N2_ratio2; | 1205 deco_diluent = temp_deco; |
1218 calc_He_ratio = deco_He_ratio2; | 1206 |
1219 } | 1207 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) |
1220 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | |
1221 { | |
1222 calc_N2_ratio = deco_N2_ratio3; | |
1223 calc_He_ratio = deco_He_ratio3; | |
1224 } | |
1225 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | |
1226 { | |
1227 calc_N2_ratio = deco_N2_ratio4; | |
1228 calc_He_ratio = deco_He_ratio4; | |
1229 } | |
1230 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | |
1231 { | |
1232 calc_N2_ratio = deco_N2_ratio5; | |
1233 calc_He_ratio = deco_He_ratio5; | |
1234 } | |
1235 } | |
1236 else // new in v.101 | |
1237 { | |
1238 if (temp_deco > deco_ppO2_change) | |
1239 { | |
1240 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 | |
1241 } | |
1242 else | |
1243 { | |
1244 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); // new in v.101 | |
1245 } | |
1246 } | |
1247 if (deco_diluent > temp_deco) // new in v.101 | |
1248 deco_diluent = temp_deco; // new in v.101 | |
1249 if (deco_diluent > 0.0627) // new in v.101 | |
1250 { | 1208 { |
1251 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); // changed in v.101 | 1209 calc_N2_ratio = deco_N2_ratio1; |
1252 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); // changed in v.101 | 1210 calc_He_ratio = deco_He_ratio1; |
1253 } | 1211 } |
1254 else // new in v.101 | 1212 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) |
1255 { | 1213 { |
1256 temp_atem = 0.0; // new in v.101 | 1214 calc_N2_ratio = deco_N2_ratio2; |
1257 temp2_atem = 0.0; // new in v.101 | 1215 calc_He_ratio = deco_He_ratio2; |
1258 } | 1216 } |
1259 sim_tissue_1min(); | 1217 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) |
1260 update_internal_deco_table_GF(); | 1218 { |
1261 update_decoarray(); | 1219 calc_N2_ratio = deco_N2_ratio3; |
1262 char_O_deco_status = char_O_deco_status + 1; | 1220 calc_He_ratio = deco_He_ratio3; |
1263 if (char_O_deco_status < 16) | 1221 } |
1264 int_temp_decostatus = 1; | 1222 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) |
1265 } | 1223 { |
1266 else // if (temp_depth_limit > 0) | 1224 calc_N2_ratio = deco_N2_ratio4; |
1267 { | 1225 calc_He_ratio = deco_He_ratio4; |
1268 char_O_deco_status = 0; | 1226 } |
1269 } | 1227 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) |
1270 } while (int_temp_decostatus == 1); | 1228 { |
1271 | 1229 calc_N2_ratio = deco_N2_ratio5; |
1272 if (char_O_deco_status > 15) | 1230 calc_He_ratio = deco_He_ratio5; |
1273 { | 1231 } |
1274 char_O_deco_status = 1; | 1232 } |
1233 else | |
1234 { | |
1235 if (temp_deco > deco_ppO2_change) | |
1236 { | |
1237 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); | |
1238 } | |
1239 else | |
1240 { | |
1241 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); | |
1242 } | |
1243 } | |
1244 | |
1245 if (deco_diluent > temp_deco) // new in v.101 | |
1246 deco_diluent = temp_deco; // new in v.101 | |
1247 | |
1248 if (deco_diluent > 0.0627) // new in v.101 | |
1249 { | |
1250 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); // changed in v.101 | |
1251 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); // changed in v.101 | |
1252 } | |
1253 else // new in v.101 | |
1254 { | |
1255 temp_atem = 0.0; // new in v.101 | |
1256 temp2_atem = 0.0; // new in v.101 | |
1257 } | |
1258 | |
1259 sim_tissue_1min(); // Simulate compartiments for 1 minute. | |
1260 update_deco_table(); // Add one minute stops. | |
1275 } | 1261 } |
1276 else | 1262 |
1263 // Surface not reached, need more stops... | |
1264 char_O_deco_status = 1; // calc more stops next time. | |
1265 } | |
1266 | |
1267 ////////////////////////////////////////////////////////////////////////////// | |
1268 // Simulation ascention to first deco stop. | |
1269 // | |
1270 // Note: because we ascent with a constant speed (10m/mn, ie. 1bar/mn), | |
1271 // there is no need to break on more that 16 iterations | |
1272 // (or we are already in deep shit). | |
1273 // | |
1274 void sim_ascent_to_first_stop(void) | |
1275 { | |
1276 update_startvalues(); | |
1277 clear_deco_table(); | |
1278 | |
1279 temp_deco = pres_respiration; | |
1280 lock_GF_depth_list = 1; | |
1281 | |
1282 // Loop until first top or surface is reached. | |
1283 for(;;) | |
1277 { | 1284 { |
1278 copy_deco_table_GF(); | 1285 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. |
1279 char_O_deco_status = 0; | 1286 |
1280 } | 1287 if ( char_I_deco_model == 1) |
1281 } | |
1282 | |
1283 ////////////////////////////////////////////////////////////////////////////// | |
1284 | |
1285 void calc_hauptroutine_calc_ascend_to_deco(void) | |
1286 { | |
1287 update_startvalues(); | |
1288 char_O_deco_status = 0; | |
1289 temp_deco = pres_respiration; | |
1290 lock_GF_depth_list = 1; // new in v.102 | |
1291 do // go up to first deco | |
1292 { | |
1293 int_temp_decostatus = 0; | |
1294 temp_deco = temp_deco - 1.0; | |
1295 if ( char_I_deco_model == 1) // new in v.102 , 4 = deep stops | |
1296 temp_limit = temp_pres_gtissue_limit_GF_low; | 1288 temp_limit = temp_pres_gtissue_limit_GF_low; |
1297 else | 1289 else |
1298 temp_limit = temp_pres_gtissue_limit; | 1290 temp_limit = temp_pres_gtissue_limit; |
1299 if ((temp_deco > temp_limit) && (temp_deco > pres_surface)) // changes in v.102 | 1291 |
1300 { | 1292 // Did we hit the first stop ? |
1301 lock_GF_depth_list = 0; // new in v.102, distance to first stop > 10 mtr. | 1293 if( temp_deco <= temp_limit ) |
1302 output[6] = 0; | 1294 break; |
1303 temp_deco += 0.5; | 1295 |
1304 | 1296 // Or the surface ? |
1305 calc_N2_ratio = N2_ratio; | 1297 if( temp_deco <= pres_surface ) |
1306 calc_He_ratio = He_ratio; | 1298 break; |
1307 | 1299 |
1308 if (char_I_const_ppO2 == 0) // new in v.101 // calculate at half of the ascent | 1300 lock_GF_depth_list = 0; |
1309 { | 1301 temp_deco += 0.5; // Check gas change 5 meter below new depth. |
1310 deco_diluent = temp_deco; // new in v.101 | 1302 |
1311 | 1303 //---- Simulat gas switches, at half the ascent |
1312 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) | 1304 calc_N2_ratio = N2_ratio; |
1313 { | 1305 calc_He_ratio = He_ratio; |
1314 calc_N2_ratio = deco_N2_ratio1; | 1306 |
1315 calc_He_ratio = deco_He_ratio1; | 1307 if (char_I_const_ppO2 == 0) |
1316 } | 1308 { |
1317 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) | 1309 deco_diluent = temp_deco; |
1318 { | 1310 |
1319 calc_N2_ratio = deco_N2_ratio2; | 1311 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) |
1320 calc_He_ratio = deco_He_ratio2; | 1312 { |
1321 } | 1313 calc_N2_ratio = deco_N2_ratio1; |
1322 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | 1314 calc_He_ratio = deco_He_ratio1; |
1323 { | 1315 } |
1324 calc_N2_ratio = deco_N2_ratio3; | 1316 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) |
1325 calc_He_ratio = deco_He_ratio3; | 1317 { |
1326 } | 1318 calc_N2_ratio = deco_N2_ratio2; |
1327 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | 1319 calc_He_ratio = deco_He_ratio2; |
1328 { | 1320 } |
1329 calc_N2_ratio = deco_N2_ratio4; | 1321 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) |
1330 calc_He_ratio = deco_He_ratio4; | 1322 { |
1331 } | 1323 calc_N2_ratio = deco_N2_ratio3; |
1332 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | 1324 calc_He_ratio = deco_He_ratio3; |
1333 { | 1325 } |
1334 calc_N2_ratio = deco_N2_ratio5; | 1326 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) |
1335 calc_He_ratio = deco_He_ratio5; | 1327 { |
1336 } | 1328 calc_N2_ratio = deco_N2_ratio4; |
1337 } | 1329 calc_He_ratio = deco_He_ratio4; |
1338 else // new in v.101 | 1330 } |
1339 { | 1331 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) |
1340 if (temp_deco > deco_ppO2_change) | 1332 { |
1341 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 // calculate at half of the ascent | 1333 calc_N2_ratio = deco_N2_ratio5; |
1342 else | 1334 calc_He_ratio = deco_He_ratio5; |
1343 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); // new in v.101 // calculate at half of the ascent | 1335 } |
1344 if (deco_diluent > (temp_deco)) // new in v.101 | 1336 } |
1345 deco_diluent = temp_deco; // new in v.101 // calculate at half of the ascent | 1337 else |
1346 } | 1338 { |
1347 temp_deco -= 0.5; | 1339 if( temp_deco > deco_ppO2_change ) |
1348 if (deco_diluent > 0.0627) // new in v.101 | 1340 deco_diluent = (temp_deco - const_ppO2)/(N2_ratio + He_ratio); // calculate at half of the ascent |
1349 { | 1341 else |
1350 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); // changed in v.101 | 1342 deco_diluent = (temp_deco - deco_ppO2)/(N2_ratio + He_ratio); // calculate at half of the ascent |
1351 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); // changed in v.101 | 1343 if( deco_diluent > temp_deco ) |
1352 } | 1344 deco_diluent = temp_deco; |
1353 else // new in v.101 | 1345 } |
1354 { | 1346 |
1355 temp_atem = 0.0; // new in v.101 | 1347 temp_deco -= 0.5; // Back to new depth. |
1356 temp2_atem = 0.0; // new in v.101 | 1348 |
1357 } | 1349 if (deco_diluent > 0.0627) |
1358 sim_tissue_1min(); | 1350 { |
1359 char_O_deco_status = char_O_deco_status + 1; | 1351 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); |
1360 if (char_O_deco_status < 16) // 16 is the limit of calculations for one time slot | 1352 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); |
1361 int_temp_decostatus = 1; | 1353 } |
1362 } | 1354 else |
1363 } while (int_temp_decostatus == 1); | 1355 { |
1356 temp_atem = 0.0; | |
1357 temp2_atem = 0.0; | |
1358 } | |
1359 | |
1360 // Then simulate with the new gas pressures...s | |
1361 sim_tissue_1min(); | |
1362 } | |
1364 } | 1363 } |
1365 | 1364 |
1366 ////////////////////////////////////////////////////////////////////////////// | 1365 ////////////////////////////////////////////////////////////////////////////// |
1367 // calc_tissue | 1366 // calc_tissue |
1368 // | 1367 // |
1436 char_O_nullzeit = 0; | 1435 char_O_nullzeit = 0; |
1437 for(loop = 1; loop <= 17; loop++) | 1436 for(loop = 1; loop <= 17; loop++) |
1438 { | 1437 { |
1439 backup_sim_pres_tissue(); | 1438 backup_sim_pres_tissue(); |
1440 sim_tissue_10min(); | 1439 sim_tissue_10min(); |
1441 char_O_nullzeit = char_O_nullzeit + 10; | 1440 char_O_nullzeit += 10; |
1442 | 1441 |
1443 if (char_I_deco_model == 1) | 1442 if (char_I_deco_model == 1) |
1444 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue; | 1443 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue; |
1445 else | 1444 else |
1446 temp1 = temp_pres_gtissue_limit; | 1445 temp1 = temp_pres_gtissue_limit; |
1449 } | 1448 } |
1450 | 1449 |
1451 if (loop == 255) | 1450 if (loop == 255) |
1452 { | 1451 { |
1453 restore_sim_pres_tissue(); | 1452 restore_sim_pres_tissue(); |
1454 char_O_nullzeit = char_O_nullzeit - 10; | 1453 char_O_nullzeit -= 10; |
1455 } //if loop == 255] | 1454 } //if loop == 255 |
1456 | 1455 |
1457 if (char_O_nullzeit < 60) | 1456 if (char_O_nullzeit < 60) |
1458 { | 1457 { |
1459 for(loop=1; loop <= 10; loop++) | 1458 for(loop=1; loop <= 10; loop++) |
1460 { | 1459 { |
1495 } | 1494 } |
1496 | 1495 |
1497 ////////////////////////////////////////////////////////////////////////////// | 1496 ////////////////////////////////////////////////////////////////////////////// |
1498 // calc_ascenttime | 1497 // calc_ascenttime |
1499 // | 1498 // |
1500 void calc_ascenttime(void) | 1499 static void calc_ascenttime(void) |
1501 { | 1500 { |
1502 if (pres_respiration > pres_surface) | 1501 if (pres_respiration > pres_surface) |
1503 { | 1502 { |
1504 switch (char_O_deco_status) | 1503 overlay unsigned char x; |
1505 { | 1504 |
1506 case 2: | 1505 // + 0.6 to count 1 minute ascent time from 4 meter to surface |
1507 int_O_ascenttime = -1; | 1506 overlay float ascent = pres_respiration - pres_surface + 0.6; |
1508 break; | 1507 if (ascent < 0.0) |
1509 case 1: | 1508 ascent = 0.0; |
1510 break; | 1509 int_O_ascenttime = (unsigned int)ascent; |
1511 default: | 1510 |
1512 { | 1511 for(x=0; x<32 && internal_deco_depth[x]; x++) |
1513 // + 0.6 to count 1 minute ascent time from 4 meter to surface | 1512 int_O_ascenttime += (unsigned int)internal_deco_time[x]; |
1514 overlay float ascent = pres_respiration - pres_surface + 0.6; | |
1515 if (ascent < 0.0) | |
1516 ascent = 0.0; | |
1517 int_O_ascenttime = (unsigned int)ascent; | |
1518 | |
1519 if( char_I_deco_model == 0 ) //---- ZH-L16 model | |
1520 { | |
1521 overlay unsigned char x; | |
1522 for(x=0; x<7; x++) | |
1523 int_O_ascenttime += (unsigned int)char_O_array_decotime[x]; | |
1524 } | |
1525 else //---------------------------- ZH-L16-GF model | |
1526 { | |
1527 overlay unsigned char x; | |
1528 for(x=0; x<32; x++) | |
1529 int_O_ascenttime += (unsigned int)internal_deco_table[x]; | |
1530 } | |
1531 | |
1532 break; | |
1533 } | |
1534 } | |
1535 } | 1513 } |
1536 else | 1514 else |
1537 int_O_ascenttime = 0; | 1515 int_O_ascenttime = 0; |
1538 } | 1516 } |
1539 | 1517 |
1556 | 1534 |
1557 temp_gtissue_no = char_O_gtissue_no; | 1535 temp_gtissue_no = char_O_gtissue_no; |
1558 for (x = 0;x<16;x++) | 1536 for (x = 0;x<16;x++) |
1559 { | 1537 { |
1560 sim_pres_tissue[x] = pres_tissue[x]; | 1538 sim_pres_tissue[x] = pres_tissue[x]; |
1561 sim_pres_tissue[x+16] = pres_tissue[x+16]; | 1539 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; |
1562 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; | 1540 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; |
1563 } | 1541 } |
1564 } | 1542 } |
1565 | 1543 |
1566 ////////////////////////////////////////////////////////////////////////////// | 1544 ////////////////////////////////////////////////////////////////////////////// |
1630 { | 1608 { |
1631 sim_tissue(2); // 10 minutes period | 1609 sim_tissue(2); // 10 minutes period |
1632 } | 1610 } |
1633 | 1611 |
1634 ////////////////////////////////////////////////////////////////////////////// | 1612 ////////////////////////////////////////////////////////////////////////////// |
1635 // clear_decoarray | 1613 // clear_deco_table |
1636 // | 1614 // |
1637 // unchanged in v.101 | 1615 // unchanged in v.101 |
1638 // | 1616 // |
1639 static void clear_decoarray(void) | 1617 static void clear_deco_table(void) |
1640 { | 1618 { |
1641 overlay unsigned char x; | 1619 overlay unsigned char x; |
1642 | 1620 |
1643 for(x=0; x<6; ++x) | 1621 for(x=0; x<32; ++x) |
1644 { | 1622 { |
1645 char_O_array_decodepth[x] = 0; | 1623 internal_deco_time [x] = 0; |
1646 char_O_array_decotime [x] = 0; | 1624 internal_deco_depth[x] = 0; |
1647 } | 1625 } |
1648 char_O_array_decotime[6] = 0; | 1626 } |
1649 } | 1627 |
1650 | 1628 ////////////////////////////////////////////////////////////////////////////// |
1651 ////////////////////////////////////////////////////////////////////////////// | 1629 // update_deco_table |
1652 // update_decoarray | 1630 // |
1653 // | 1631 // Add 1 min to current stop. |
1654 // unchanged in v.101 | 1632 // |
1655 // | 1633 // Inputs: |
1656 static void update_decoarray() | 1634 // temp_depth_limit = stop's depth, in meters. |
1657 { | 1635 // In/Out: |
1658 overlay int stop_time; | 1636 // internal_deco_depth[] : depth (in meters) of each stops. |
1659 overlay unsigned char x = 0; | 1637 // internal_deco_time [] : time (in minutes) of each stops. |
1660 do | 1638 // |
1639 static void update_deco_table() | |
1640 { | |
1641 overlay unsigned char x; | |
1642 | |
1643 if( temp_depth_limit > 255 ) // Can't store stops at more than 255m. | |
1644 temp_depth_limit = 255; | |
1645 | |
1646 for(x=0; x<32; ++x) | |
1661 { | 1647 { |
1662 if (char_O_array_decodepth[x] == temp_depth_limit) | 1648 // Did we found the right stop ? |
1663 { | 1649 if( internal_deco_depth[x] == temp_depth_limit ) |
1664 stop_time = char_O_array_decotime[x] + 1; | 1650 { |
1665 if (stop_time < 0) | 1651 // Increment stop time, but do test overflow: |
1666 stop_time = 0; | 1652 overlay int stop_time = 1 + (int)internal_deco_time[x]; |
1667 if (stop_time > 240) | 1653 if( stop_time > 255 ) |
1668 stop_time = 240; | 1654 stop_time = 255; |
1669 char_O_array_decotime[x] = stop_time; | 1655 internal_deco_time[x] = stop_time; |
1670 x = 10; // exit | 1656 |
1671 } // if | 1657 // Done ! |
1672 else | 1658 return; |
1673 { | 1659 } |
1674 if (char_O_array_decodepth[x] == 0) | 1660 |
1675 { | 1661 if( internal_deco_depth[x] == 0 ) |
1676 if (temp_depth_limit > 255) | 1662 { |
1677 char_O_array_decodepth[x] = 255; | 1663 // Found a free position: initialise it. |
1678 else | 1664 internal_deco_depth[x] = (unsigned char)temp_depth_limit; |
1679 char_O_array_decodepth[x] = (char)temp_depth_limit; | 1665 internal_deco_time[x] = 1; |
1680 stop_time = char_O_array_decotime[x] + 1; | 1666 return; |
1681 if (stop_time > 240) | 1667 } |
1682 char_O_array_decotime[x] = 240; | 1668 } |
1683 else | 1669 |
1684 char_O_array_decotime[x] = (char)stop_time; | 1670 // Here, there is no space left for stops. |
1685 x = 10; // exit | 1671 // Ie. the first one starts at 3m*32 positions = 96m... |
1686 } // if | 1672 // Just do nothing with that... |
1687 else | |
1688 x++; | |
1689 } // else | |
1690 } while (x<6); | |
1691 if (x == 6) | |
1692 { | |
1693 stop_time = char_O_array_decotime[6] + 1; | |
1694 if (stop_time > 220) | |
1695 char_O_array_decotime[6] = 220; | |
1696 else | |
1697 char_O_array_decotime[6] = (char)stop_time; | |
1698 } // if x == 6 | |
1699 } | 1673 } |
1700 | 1674 |
1701 ////////////////////////////////////////////////////////////////////////////// | 1675 ////////////////////////////////////////////////////////////////////////////// |
1702 // calc_gradient_factor | 1676 // calc_gradient_factor |
1703 // | 1677 // |
1878 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) | 1852 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) |
1879 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 1853 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; |
1880 | 1854 |
1881 calc_tissue_1_min(); // update the pressure in the 32 tissues in accordance with the new ambient pressure | 1855 calc_tissue_1_min(); // update the pressure in the 32 tissues in accordance with the new ambient pressure |
1882 | 1856 |
1883 clear_decoarray(); | 1857 clear_deco_table(); |
1884 char_O_deco_status = 0; | 1858 char_O_deco_status = 0; |
1885 char_O_nullzeit = 0; | 1859 char_O_nullzeit = 0; |
1886 int_O_ascenttime = 0; | 1860 int_O_ascenttime = 0; |
1887 calc_gradient_factor(); | 1861 calc_gradient_factor(); |
1888 } | 1862 } |