Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 203:2d9af08ed0ac
BUGFIX Gas switch
+ To implement gas switch, the ascent engine have to know about dive duration.
author | JeanDo |
---|---|
date | Fri, 18 Feb 2011 00:23:51 +0100 |
parents | e5c484d59a91 |
children | 275befc5f39d |
comparison
equal
deleted
inserted
replaced
202:667700d09fff | 203:2d9af08ed0ac |
---|---|
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 // 2011/01/24: [jDG] Make ascenttime an int. No more overflow! | 68 // 2011/01/24: [jDG] Make ascenttime an short. No more overflow! |
69 // 2011/01/25: [jDG] Fusion deco array for both models. | 69 // 2011/01/25: [jDG] Fusion deco array for both models. |
70 // 2011/01/25: [jDG] Use CF(54) to reverse deco order. | 70 // 2011/01/25: [jDG] Use CF(54) to reverse deco order. |
71 // 2011/02/11: [jDG] Reworked gradient-factor implementation. | 71 // 2011/02/11: [jDG] Reworked gradient-factor implementation. |
72 // 2011/02/13: [jDG] CF55 for additional gas switch delay in decoplan. | 72 // 2011/02/13: [jDG] CF55 for additional gas switch delay in decoplan. |
73 // | 73 // |
130 static void calc_nextdecodepth(void); | 130 static void calc_nextdecodepth(void); |
131 | 131 |
132 //---- Bank 4 parameters ----------------------------------------------------- | 132 //---- Bank 4 parameters ----------------------------------------------------- |
133 #pragma udata bank4=0x400 | 133 #pragma udata bank4=0x400 |
134 | 134 |
135 static unsigned char low_depth; | |
136 static float temp_limit; | 135 static float temp_limit; |
137 static float GF_low; | 136 static float GF_low; |
138 static float GF_high; | 137 static float GF_high; |
139 static float GF_delta; | 138 static float GF_delta; |
140 static unsigned char low_depth; // Depth of deepest stop | 139 static unsigned char low_depth; // Depth of deepest stop |
179 static float const_ppO2; // new in v.101 | 178 static float const_ppO2; // new in v.101 |
180 static float deco_ppO2_change; // new in v.101 | 179 static float deco_ppO2_change; // new in v.101 |
181 static float deco_ppO2; // new in v.101 | 180 static float deco_ppO2; // new in v.101 |
182 | 181 |
183 static unsigned char sim_gas_last_used; // Last used gas, to detected a gas switch. | 182 static unsigned char sim_gas_last_used; // Last used gas, to detected a gas switch. |
184 static unsigned char sim_gas_delay; // Delay added for gas switch (count down) [min]. | 183 static unsigned short sim_gas_delay; // Time of gas-switch-stop ends [min on dive]. |
184 static unsigned short sim_dive_mins; // Simulated dive time. | |
185 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. | 185 static float calc_N2_ratio; // Simulated (switched) nitrogen ratio. |
186 static float calc_He_ratio; // Simulated (switched) helium ratio. | 186 static float calc_He_ratio; // Simulated (switched) helium ratio. |
187 static float CNS_fraction; // new in v.101 | 187 static float CNS_fraction; // new in v.101 |
188 static float float_saturation_multiplier; // new in v.101 | 188 static float float_saturation_multiplier; // new in v.101 |
189 static float float_desaturation_multiplier; // new in v.101 | 189 static float float_desaturation_multiplier; // new in v.101 |
256 #include "p2_tables.romdata" // new table for deco_main_v.101 (var_N2_a modified) | 256 #include "p2_tables.romdata" // new table for deco_main_v.101 (var_N2_a modified) |
257 | 257 |
258 // Magic table to compute the MD2 HASH | 258 // Magic table to compute the MD2 HASH |
259 // | 259 // |
260 #pragma romdata hash_tables = 0x017E00 // Address fixed by ASM access... | 260 #pragma romdata hash_tables = 0x017E00 // Address fixed by ASM access... |
261 rom const rom unsigned int md_pi[] = | 261 rom const rom unsigned short md_pi[] = |
262 { | 262 { |
263 0x292E, 0x43C9, 0xA2D8, 0x7C01, 0x3D36, 0x54A1, 0xECF0, 0x0613 | 263 0x292E, 0x43C9, 0xA2D8, 0x7C01, 0x3D36, 0x54A1, 0xECF0, 0x0613 |
264 , 0x62A7, 0x05F3, 0xC0C7, 0x738C, 0x9893, 0x2BD9, 0xBC4C, 0x82CA | 264 , 0x62A7, 0x05F3, 0xC0C7, 0x738C, 0x9893, 0x2BD9, 0xBC4C, 0x82CA |
265 , 0x1E9B, 0x573C, 0xFDD4, 0xE016, 0x6742, 0x6F18, 0x8A17, 0xE512 | 265 , 0x1E9B, 0x573C, 0xFDD4, 0xE016, 0x6742, 0x6F18, 0x8A17, 0xE512 |
266 , 0xBE4E, 0xC4D6, 0xDA9E, 0xDE49, 0xA0FB, 0xF58E, 0xBB2F, 0xEE7A | 266 , 0xBE4E, 0xC4D6, 0xDA9E, 0xDE49, 0xA0FB, 0xF58E, 0xBB2F, 0xEE7A |
403 ////////////////////////////////////////////////////////////////////////////// | 403 ////////////////////////////////////////////////////////////////////////////// |
404 // DBG - multi main during dive | 404 // DBG - multi main during dive |
405 // | 405 // |
406 static void check_dbg(PARAMETER char is_post_check) | 406 static void check_dbg(PARAMETER char is_post_check) |
407 { | 407 { |
408 overlay unsigned int temp_DBS = 0; | 408 overlay unsigned short temp_DBS = 0; |
409 overlay unsigned char i; // Local loop index. | 409 overlay unsigned char i; // Local loop index. |
410 | 410 |
411 if( (DBG_N2_ratio != N2_ratio) || (DBG_He_ratio != He_ratio) ) | 411 if( (DBG_N2_ratio != N2_ratio) || (DBG_He_ratio != He_ratio) ) |
412 temp_DBS |= DBG_c_gas; | 412 temp_DBS |= DBG_c_gas; |
413 if(DBG_const_ppO2 != const_ppO2) | 413 if(DBG_const_ppO2 != const_ppO2) |
471 ////////////////////////////////////////////////////////////////////////////// | 471 ////////////////////////////////////////////////////////////////////////////// |
472 /////////////////////// U T I L I T I E S ///////////////////////////////// | 472 /////////////////////// U T I L I T I E S ///////////////////////////////// |
473 ////////////////////////////////////////////////////////////////////////////// | 473 ////////////////////////////////////////////////////////////////////////////// |
474 ////////////////////////////////////////////////////////////////////////////// | 474 ////////////////////////////////////////////////////////////////////////////// |
475 | 475 |
476 static int read_custom_function(PARAMETER unsigned char cf) | 476 static short read_custom_function(PARAMETER unsigned char cf) |
477 { | 477 { |
478 #ifdef CROSS_COMPILE | 478 #ifdef CROSS_COMPILE |
479 extern unsigned short custom_functions[]; | 479 extern unsigned short custom_functions[]; |
480 return custom_functions[cf]; | 480 return custom_functions[cf]; |
481 #else | 481 #else |
608 if (char_I_deco_model == 1) | 608 if (char_I_deco_model == 1) |
609 { | 609 { |
610 // Recompute leading gas limit, at current depth: | 610 // Recompute leading gas limit, at current depth: |
611 overlay float depth = (temp_deco - pres_surface) / 0.09995; | 611 overlay float depth = (temp_deco - pres_surface) / 0.09995; |
612 assert( depth >= 0.0 ); | 612 assert( depth >= 0.0 ); |
613 assert( low_depth < 255 ); | |
613 | 614 |
614 if( depth > low_depth ) | 615 if( depth > low_depth ) |
615 sim_limit( GF_low ); | 616 sim_limit( GF_low ); |
616 else | 617 else |
617 sim_limit( GF_high - depth * locked_GF_step ); | 618 sim_limit( GF_high - depth * locked_GF_step ); |
618 | 619 |
619 // Stops are needed ? | 620 // Stops are needed ? |
620 if( sim_lead_tissue_limit > pres_surface ) | 621 if( sim_lead_tissue_limit > pres_surface ) |
621 { | 622 { |
622 // Deepest stop, in meter. | 623 // Deepest stop, in meter. |
623 overlay unsigned char first_stop = 3 * (int)(0.99 + (sim_lead_tissue_limit - pres_surface) / 0.29985); | 624 overlay unsigned char first_stop = 3 * (short)(0.99 + (sim_lead_tissue_limit - pres_surface) / 0.29985); |
624 assert( first_stop < 128 ); | 625 assert( first_stop < 128 ); |
625 | 626 |
626 // Apply correction for the first stop. | 627 // Apply correction for the first stop. |
627 if( first_stop == 3 ) // new in v104 | 628 if( first_stop == 3 ) // new in v104 |
628 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. | 629 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. |
690 | 691 |
691 pres_gradient = sim_lead_tissue_limit - pres_surface; | 692 pres_gradient = sim_lead_tissue_limit - pres_surface; |
692 if (pres_gradient >= 0) | 693 if (pres_gradient >= 0) |
693 { | 694 { |
694 pres_gradient /= 0.29985; // Bar --> stop number; | 695 pres_gradient /= 0.29985; // Bar --> stop number; |
695 temp_depth_limit = 3 * (int) (pres_gradient + 0.99); // --> meter : depth for deco | 696 temp_depth_limit = 3 * (short) (pres_gradient + 0.99); // --> meter : depth for deco |
696 if (temp_depth_limit == 0) // At surface ? | 697 if (temp_depth_limit == 0) // At surface ? |
697 temp_deco = pres_surface; | 698 temp_deco = pres_surface; |
698 else | 699 else |
699 { | 700 { |
700 if (temp_depth_limit < char_I_depth_last_deco) // Implement last stop at 4m/5m/6m... | 701 if (temp_depth_limit < char_I_depth_last_deco) // Implement last stop at 4m/5m/6m... |
871 // Calculate gas switches | 872 // Calculate gas switches |
872 // | 873 // |
873 // | 874 // |
874 void check_gas_switch(void) | 875 void check_gas_switch(void) |
875 { | 876 { |
876 overlay unsigned char temp_gas_switch = sim_gas_last_used; | 877 overlay unsigned char temp_gas_switch = 0; |
877 overlay float switch_deco; | 878 overlay float switch_deco; |
878 | 879 |
879 calc_N2_ratio = N2_ratio; | 880 calc_N2_ratio = N2_ratio; |
880 calc_He_ratio = He_ratio; | 881 calc_He_ratio = He_ratio; |
881 | 882 |
919 temp_gas_switch = 5; | 920 temp_gas_switch = 5; |
920 switch_deco = deco_gas_change5; | 921 switch_deco = deco_gas_change5; |
921 } | 922 } |
922 } | 923 } |
923 | 924 |
924 // Should detect gas switch only when gas do changes... | 925 // If there is a better gas available |
925 // sim_gas_last_used: used to detect just once in each ascent simu. | 926 if( temp_gas_switch ) |
926 // N2_ratio : used to detect when already breathing that gas. | 927 { |
927 if( sim_gas_last_used < temp_gas_switch | 928 // Should detect gas switch only when gas do changes... |
928 && (calc_N2_ratio != N2_ratio || calc_He_ratio != He_ratio)) | 929 // sim_gas_last_used: used to detect just once in each ascent simu. |
929 { | 930 // N2_ratio : used to detect when already breathing that gas. |
930 sim_gas_last_used = temp_gas_switch; | 931 if( sim_gas_last_used < temp_gas_switch |
931 sim_gas_delay = read_custom_function(55); | 932 && sim_gas_delay <= sim_dive_mins |
932 | 933 && (calc_N2_ratio != N2_ratio || calc_He_ratio != He_ratio)) |
933 // Apply depth correction ONLY if there delay is not null: | |
934 if( sim_gas_delay > 0 ) | |
935 { | 934 { |
936 temp_deco = switch_deco - float_deco_distance; | 935 sim_gas_last_used = temp_gas_switch; |
937 temp_depth_limit = (temp_deco - pres_surface) / 0.09985; | 936 sim_gas_delay = read_custom_function(55); |
937 | |
938 // Apply depth correction ONLY if CF#55 is not null: | |
939 if( sim_gas_delay > 0 ) | |
940 { | |
941 sim_gas_delay += sim_dive_mins; | |
942 temp_deco = switch_deco - float_deco_distance; | |
943 temp_depth_limit = (temp_deco - pres_surface) / 0.09985; | |
944 } | |
938 } | 945 } |
939 } | 946 } |
947 else | |
948 sim_gas_delay = 0; | |
940 | 949 |
941 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); | 950 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); |
942 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); | 951 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); |
943 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); | 952 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); |
944 } | 953 } |
1041 static void calc_hauptroutine(void) | 1050 static void calc_hauptroutine(void) |
1042 { | 1051 { |
1043 static float backup_GF_step; | 1052 static float backup_GF_step; |
1044 static unsigned char backup_low_depth; | 1053 static unsigned char backup_low_depth; |
1045 static unsigned char backup_gas_used; | 1054 static unsigned char backup_gas_used; |
1055 static unsigned char backup_gas_delay; | |
1046 | 1056 |
1047 calc_hauptroutine_data_input(); | 1057 calc_hauptroutine_data_input(); |
1048 | 1058 |
1049 if(!flag_in_divemode) | 1059 if(!flag_in_divemode) |
1050 { | 1060 { |
1071 | 1081 |
1072 // Values that should be reset just once for the full real dive | 1082 // Values that should be reset just once for the full real dive |
1073 // (not every time we simulate an ascent): | 1083 // (not every time we simulate an ascent): |
1074 low_depth = 0; // Reset GF history. | 1084 low_depth = 0; // Reset GF history. |
1075 backup_low_depth = 255; // backup is empty... | 1085 backup_low_depth = 255; // backup is empty... |
1076 | 1086 sim_gas_last_used = 0; // Reset gas switch history. |
1077 // No gas change (yet) for this ascent simulation. | 1087 sim_gas_delay = 0; |
1078 sim_gas_last_used = 0; | 1088 sim_dive_mins = 0; |
1079 break; | 1089 |
1090 break; | |
1080 | 1091 |
1081 case 0: //---- bottom time ----------------------------------------------- | 1092 case 0: //---- bottom time ----------------------------------------------- |
1082 calc_nullzeit(); | 1093 calc_nullzeit(); |
1083 check_ndl(); | 1094 check_ndl(); |
1084 char_O_deco_status = 2; // calc ascent next time. | 1095 char_O_deco_status = 2; // calc ascent next time. |
1087 case 2: //---- Simulate ascent to first stop ----------------------------- | 1098 case 2: //---- Simulate ascent to first stop ----------------------------- |
1088 // Backup ascention state, so the simulation won't polute the real | 1099 // Backup ascention state, so the simulation won't polute the real |
1089 // dive data. | 1100 // dive data. |
1090 backup_GF_step = locked_GF_step; | 1101 backup_GF_step = locked_GF_step; |
1091 backup_low_depth = low_depth; | 1102 backup_low_depth = low_depth; |
1092 backup_gas_used = sim_gas_last_used; | 1103 |
1104 // Check proposed gas at begin of ascent simulation | |
1105 temp_deco = pres_respiration; // Starts from current real depth. | |
1106 sim_dive_mins = int_I_divemins; // and time. | |
1107 check_gas_switch(); | |
1108 | |
1109 backup_gas_used = sim_gas_last_used;// And save for later simu steps. | |
1110 backup_gas_delay = sim_gas_delay; | |
1093 | 1111 |
1094 sim_ascent_to_first_stop(); | 1112 sim_ascent_to_first_stop(); |
1095 | 1113 |
1096 char_O_deco_status = 1; // Calc stops next time (deco or gas switch). | 1114 char_O_deco_status = 1; // Calc stops next time (deco or gas switch). |
1097 break; | 1115 break; |
1104 if( char_O_deco_status == 0 && backup_low_depth != 255) | 1122 if( char_O_deco_status == 0 && backup_low_depth != 255) |
1105 { | 1123 { |
1106 locked_GF_step = backup_GF_step; | 1124 locked_GF_step = backup_GF_step; |
1107 low_depth = backup_low_depth; | 1125 low_depth = backup_low_depth; |
1108 sim_gas_last_used = backup_gas_used; | 1126 sim_gas_last_used = backup_gas_used; |
1109 backup_low_depth = 255; | 1127 sim_gas_delay = backup_gas_delay; |
1128 | |
1129 backup_low_depth = 255; | |
1110 } | 1130 } |
1111 break; | 1131 break; |
1112 } | 1132 } |
1113 | 1133 |
1114 check_post_dbg(); | 1134 check_post_dbg(); |
1120 // Reset all C-code dive parameters from their ASM-code values. | 1140 // Reset all C-code dive parameters from their ASM-code values. |
1121 // Detect gas change condition. | 1141 // Detect gas change condition. |
1122 // | 1142 // |
1123 void calc_hauptroutine_data_input(void) | 1143 void calc_hauptroutine_data_input(void) |
1124 { | 1144 { |
1125 overlay int int_temp; | 1145 overlay short int_temp; |
1126 | 1146 |
1127 pres_respiration = int_I_pres_respiration * 0.001; | 1147 pres_respiration = int_I_pres_respiration * 0.001; |
1128 pres_surface = int_I_pres_surface * 0.001; | 1148 pres_surface = int_I_pres_surface * 0.001; |
1129 N2_ratio = char_I_N2_ratio * 0.01; | 1149 N2_ratio = char_I_N2_ratio * 0.01; |
1130 He_ratio = char_I_He_ratio * 0.01; | 1150 He_ratio = char_I_He_ratio * 0.01; |
1135 // ____________________________________________________ | 1155 // ____________________________________________________ |
1136 // | 1156 // |
1137 // _____________ G A S _ C H A N G E S ________________ | 1157 // _____________ G A S _ C H A N G E S ________________ |
1138 // ____________________________________________________ | 1158 // ____________________________________________________ |
1139 | 1159 |
1160 // Keep a marhin of 150mbar = 1.50m | |
1140 int_temp = (int_I_pres_respiration - int_I_pres_surface) + MBAR_REACH_GASCHANGE_AUTO_CHANGE_OFF; | 1161 int_temp = (int_I_pres_respiration - int_I_pres_surface) + MBAR_REACH_GASCHANGE_AUTO_CHANGE_OFF; |
1141 | 1162 |
1142 deco_gas_change1 = 0.0; | 1163 deco_gas_change1 = 0.0; |
1143 deco_gas_change2 = 0.0; | 1164 deco_gas_change2 = 0.0; |
1144 deco_gas_change3 = 0.0; | 1165 deco_gas_change3 = 0.0; |
1145 deco_gas_change4 = 0.0; | 1166 deco_gas_change4 = 0.0; |
1146 deco_gas_change5 = 0.0; | 1167 deco_gas_change5 = 0.0; |
1147 | 1168 |
1169 // Gas are selectable if we did not pass the change depth by more than 1.50m: | |
1148 if(char_I_deco_gas_change1) | 1170 if(char_I_deco_gas_change1) |
1149 { | 1171 { |
1150 overlay int int_temp2 = ((int)char_I_deco_gas_change1) * 100; | 1172 if( int_temp > 100 *(short)char_I_deco_gas_change1 ) |
1151 if(int_temp > int_temp2) | 1173 deco_gas_change1 = char_I_deco_gas_change1 / 9.995 |
1152 { | 1174 + pres_surface |
1153 deco_gas_change1 = (float)char_I_deco_gas_change1 / 9.995 + pres_surface; | 1175 + float_deco_distance; |
1154 deco_gas_change1 += float_deco_distance; | |
1155 } | |
1156 } | 1176 } |
1157 if(char_I_deco_gas_change2) | 1177 if(char_I_deco_gas_change2) |
1158 { | 1178 { |
1159 overlay int int_temp2 = ((int)char_I_deco_gas_change2) * 100; | 1179 if( int_temp > 100 *(short)char_I_deco_gas_change2 ) |
1160 if(int_temp > int_temp2) | 1180 deco_gas_change2 = char_I_deco_gas_change2 / 9.995 |
1161 { | 1181 + pres_surface |
1162 deco_gas_change2 = (float)char_I_deco_gas_change2 / 9.995 + pres_surface; | 1182 + float_deco_distance; |
1163 deco_gas_change2 += float_deco_distance; | |
1164 } | |
1165 } | 1183 } |
1166 if(char_I_deco_gas_change3) | 1184 if(char_I_deco_gas_change3) |
1167 { | 1185 { |
1168 overlay int int_temp2 = ((int)char_I_deco_gas_change3) * 100; | 1186 if( int_temp > 100 *(short)char_I_deco_gas_change3 ) |
1169 if(int_temp > int_temp2) | 1187 deco_gas_change3 = char_I_deco_gas_change3 / 9.995 |
1170 { | 1188 + pres_surface |
1171 deco_gas_change3 = (float)char_I_deco_gas_change3 / 9.995 + pres_surface; | 1189 + float_deco_distance; |
1172 deco_gas_change3 += float_deco_distance; | |
1173 } | |
1174 } | 1190 } |
1175 if(char_I_deco_gas_change4) | 1191 if(char_I_deco_gas_change4) |
1176 { | 1192 { |
1177 overlay int int_temp2 = ((int)char_I_deco_gas_change4) * 100; | 1193 if( int_temp > 100 *(short)char_I_deco_gas_change4 ) |
1178 if(int_temp > int_temp2) | 1194 deco_gas_change4 = char_I_deco_gas_change4 / 9.995 |
1179 { | 1195 + pres_surface |
1180 deco_gas_change4 = (float)char_I_deco_gas_change4 / 9.995 + pres_surface; | 1196 + float_deco_distance; |
1181 deco_gas_change4 += float_deco_distance; | |
1182 } | |
1183 } | 1197 } |
1184 if(char_I_deco_gas_change5) | 1198 if(char_I_deco_gas_change5) |
1185 { | 1199 { |
1186 overlay int int_temp2 = ((int)char_I_deco_gas_change5) * 100; | 1200 if( int_temp > 100 *(short)char_I_deco_gas_change5 ) |
1187 if(int_temp > int_temp2) | 1201 deco_gas_change5 = char_I_deco_gas_change5 / 9.995 |
1188 { | 1202 + pres_surface |
1189 deco_gas_change5 = (float)char_I_deco_gas_change5 / 9.995 + pres_surface; | 1203 + float_deco_distance; |
1190 deco_gas_change5 += float_deco_distance; | |
1191 } | |
1192 } | 1204 } |
1193 | 1205 |
1194 const_ppO2 = char_I_const_ppO2 * 0.01; | 1206 const_ppO2 = char_I_const_ppO2 * 0.01; |
1195 deco_ppO2_change = char_I_deco_ppO2_change / 99.95 | 1207 deco_ppO2_change = char_I_deco_ppO2_change / 99.95 |
1196 + pres_surface | 1208 + pres_surface |
1239 calc_tissue(1); | 1251 calc_tissue(1); |
1240 | 1252 |
1241 // Calc limit for surface, ie. GF_high. | 1253 // Calc limit for surface, ie. GF_high. |
1242 calc_limit(GF_high); | 1254 calc_limit(GF_high); |
1243 | 1255 |
1244 int_O_gtissue_limit = (int)(calc_lead_tissue_limit * 1000); | 1256 int_O_gtissue_limit = (short)(calc_lead_tissue_limit * 1000); |
1245 int_O_gtissue_press = (int)((pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]) * 1000); | 1257 int_O_gtissue_press = (short)((pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]) * 1000); |
1246 | 1258 |
1247 // if guiding tissue can not be exposed to surface pressure immediately | 1259 // if guiding tissue can not be exposed to surface pressure immediately |
1248 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) | 1260 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) |
1249 { | 1261 { |
1250 char_O_nullzeit = 0; // deco necessary | 1262 char_O_nullzeit = 0; // deco necessary |
1264 overlay unsigned char loop; | 1276 overlay unsigned char loop; |
1265 | 1277 |
1266 for(loop = 0; loop < 16; ++loop) | 1278 for(loop = 0; loop < 16; ++loop) |
1267 { | 1279 { |
1268 // Do not ascent while doing a gas switch. | 1280 // Do not ascent while doing a gas switch. |
1269 if( sim_gas_delay == 0 ) | 1281 if( sim_gas_delay <= sim_dive_mins ) |
1282 { | |
1270 calc_nextdecodepth(); | 1283 calc_nextdecodepth(); |
1271 | 1284 |
1272 //---- Finish computations once surface is reached ------------------- | 1285 //---- Finish computations once surface is reached --------------- |
1273 if( temp_depth_limit == 0 ) | 1286 if( temp_depth_limit == 0 ) |
1274 { | 1287 { |
1275 copy_deco_table(); | 1288 copy_deco_table(); |
1276 calc_ascenttime(); | 1289 calc_ascenttime(); |
1277 char_O_deco_status = 0; // calc nullzeit next time. | 1290 char_O_deco_status = 0; // calc nullzeit next time. |
1278 return; | 1291 return; |
1279 } | 1292 } |
1280 | 1293 |
1281 //---- Else, continue simulating the stops --------------------------- | 1294 //---- Else, continue simulating the stops ----------------------- |
1282 if( sim_gas_delay == 0 ) | |
1283 check_gas_switch(); // Calculate N2_ratio and He_ratio. | 1295 check_gas_switch(); // Calculate N2_ratio and He_ratio. |
1284 if( sim_gas_delay > 0 ) | 1296 } |
1285 sim_gas_delay--; | 1297 |
1286 | 1298 //---- Then update tissue and decoplan ------------------------------- |
1287 alveolar_presures(); // Updates ppN2 and ppHe. | 1299 sim_dive_mins++; // Advance simulated time by 1 minute. |
1288 | 1300 alveolar_presures(); // Updates ppN2 and ppHe. |
1289 sim_tissue(1); // Simulate compartiments for 1 minute. | 1301 sim_tissue(1); // Simulate compartiments for 1 minute. |
1290 update_deco_table(); // Add one minute stops. | 1302 update_deco_table(); // Add one minute stops. |
1291 } | 1303 } |
1292 | 1304 |
1293 // Surface not reached, need more stops... | 1305 // Surface not reached, need more stops... |
1306 update_startvalues(); | 1318 update_startvalues(); |
1307 clear_deco_table(); | 1319 clear_deco_table(); |
1308 | 1320 |
1309 temp_deco = pres_respiration; // Starts from current real depth. | 1321 temp_deco = pres_respiration; // Starts from current real depth. |
1310 | 1322 |
1311 // Loop until first top or surface is reached. | 1323 // Loop until first stop, gas switch, or surface is reached. |
1312 for(;;) | 1324 for(;;) |
1313 { | 1325 { |
1314 // Do not ascent while doing a gas switch. | 1326 // Do we have a gas switch going on ? |
1315 if( sim_gas_delay == 0 ) | 1327 if( sim_gas_delay > sim_dive_mins ) |
1316 temp_deco -= 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. | 1328 break; |
1329 | |
1330 // No: try ascending 1 full minute. | |
1331 temp_deco -= 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. | |
1332 | |
1333 // Did we reach surface ? | |
1334 if( temp_deco <= pres_surface ) | |
1335 { | |
1336 temp_deco = pres_surface; // Yes: finished ! | |
1337 break; | |
1338 } | |
1317 | 1339 |
1318 // Compute sim_lead_tissue_limit at GF_low (deepest stop). | 1340 // Compute sim_lead_tissue_limit at GF_low (deepest stop). |
1319 sim_limit(GF_low); | 1341 sim_limit(GF_low); |
1320 | 1342 |
1321 // Did we reach first stop ? | 1343 // Did we reach deepest remaining stop ? |
1322 if( temp_deco <= sim_lead_tissue_limit ) | 1344 if( temp_deco <= sim_lead_tissue_limit ) |
1323 { | 1345 { |
1324 temp_deco = sim_lead_tissue_limit; | 1346 temp_deco = sim_lead_tissue_limit; |
1325 break; // Return stop found ! | 1347 break; // Return stop found ! |
1326 } | 1348 } |
1327 | 1349 |
1328 // Next stop is surface ? | 1350 temp_deco += 0.5; // Check gas change 5 meter below new depth. |
1329 if( temp_deco <= pres_surface ) | |
1330 break; // Yes: finished ! | |
1331 | |
1332 //---- Simulat gas switches | |
1333 if( sim_gas_delay > 0 ) | |
1334 { | |
1335 sim_gas_delay--; // Decrement switch delay | |
1336 update_deco_table(); // And mark stop in table | |
1337 } | |
1338 else | |
1339 { | |
1340 temp_deco += 0.5; // Check gas change 5 meter below new depth. | |
1341 check_gas_switch(); | 1351 check_gas_switch(); |
1342 temp_deco -= 0.5; // Back to new depth. | 1352 temp_deco -= 0.5; // Back to new depth. |
1343 } | 1353 |
1344 | 1354 sim_dive_mins++; // Advance simulated time by 1 minute. |
1345 // Then simulate with the new gas pressures... (1min) | 1355 alveolar_presures(); // Calculate ppO2/ppHe at new depth. |
1346 alveolar_presures(); // Calculated at true depth ! | 1356 sim_tissue(1); // and update tissues for 1 min. |
1347 sim_tissue(1); | |
1348 } | 1357 } |
1358 | |
1359 // Always updates depth in meter, too: | |
1360 temp_depth_limit = (temp_deco - pres_surface) / 0.09985; | |
1349 } | 1361 } |
1350 | 1362 |
1351 ////////////////////////////////////////////////////////////////////////////// | 1363 ////////////////////////////////////////////////////////////////////////////// |
1352 // calc_tissue | 1364 // calc_tissue |
1353 // | 1365 // |
1424 // | 1436 // |
1425 // unchanged in v.101 | 1437 // unchanged in v.101 |
1426 // | 1438 // |
1427 static void calc_nullzeit(void) | 1439 static void calc_nullzeit(void) |
1428 { | 1440 { |
1429 overlay int loop; | 1441 overlay unsigned char loop; |
1430 update_startvalues(); | 1442 update_startvalues(); |
1431 | 1443 |
1432 char_O_nullzeit = 0; | 1444 char_O_nullzeit = 0; |
1433 for(loop = 1; loop <= 17; loop++) | 1445 for(loop = 1; loop <= 17; loop++) |
1434 { | 1446 { |
1492 | 1504 |
1493 // + 0.7 to count 1 minute ascent time from 3 meter to surface | 1505 // + 0.7 to count 1 minute ascent time from 3 meter to surface |
1494 overlay float ascent = pres_respiration - pres_surface + 0.7; | 1506 overlay float ascent = pres_respiration - pres_surface + 0.7; |
1495 if (ascent < 0.0) | 1507 if (ascent < 0.0) |
1496 ascent = 0.0; | 1508 ascent = 0.0; |
1497 int_O_ascenttime = (unsigned int)(ascent + 0.99); | 1509 int_O_ascenttime = (unsigned short)(ascent + 0.99); |
1498 | 1510 |
1499 for(x=0; x<32 && internal_deco_depth[x]; x++) | 1511 for(x=0; x<32 && internal_deco_depth[x]; x++) |
1500 int_O_ascenttime += (unsigned int)internal_deco_time[x]; | 1512 int_O_ascenttime += (unsigned short)internal_deco_time[x]; |
1501 } | 1513 } |
1502 else | 1514 else |
1503 int_O_ascenttime = 0; | 1515 int_O_ascenttime = 0; |
1504 } | 1516 } |
1505 | 1517 |
1721 // FIXED N2_ratio | 1733 // FIXED N2_ratio |
1722 // unchanged in v.101 | 1734 // unchanged in v.101 |
1723 // | 1735 // |
1724 void deco_calc_desaturation_time(void) | 1736 void deco_calc_desaturation_time(void) |
1725 { | 1737 { |
1726 overlay unsigned int desat_time; // For a particular compartiment, in min. | 1738 overlay unsigned short desat_time; // For a particular compartiment, in min. |
1727 overlay float temp1; | 1739 overlay float temp1; |
1728 overlay float temp2; | 1740 overlay float temp2; |
1729 overlay float temp3; | 1741 overlay float temp3; |
1730 overlay float temp4; | 1742 overlay float temp4; |
1731 RESET_C_STACK | 1743 RESET_C_STACK |
1793 temp4 = 0; | 1805 temp4 = 0; |
1794 } | 1806 } |
1795 | 1807 |
1796 // saturation_time (for flight) | 1808 // saturation_time (for flight) |
1797 if (temp4 > temp2) | 1809 if (temp4 > temp2) |
1798 desat_time = (unsigned int)temp4; | 1810 desat_time = (unsigned short)temp4; |
1799 else | 1811 else |
1800 desat_time = (unsigned int)temp2; | 1812 desat_time = (unsigned short)temp2; |
1801 if(desat_time > int_O_desaturation_time) | 1813 if(desat_time > int_O_desaturation_time) |
1802 int_O_desaturation_time = desat_time; | 1814 int_O_desaturation_time = desat_time; |
1803 | 1815 |
1804 // N2 saturation in multiples of halftime for display purposes | 1816 // N2 saturation in multiples of halftime for display purposes |
1805 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 | 1817 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8 |
1863 { | 1875 { |
1864 overlay unsigned char md_i, md_j; // Loop index. | 1876 overlay unsigned char md_i, md_j; // Loop index. |
1865 overlay unsigned char md_t; | 1877 overlay unsigned char md_t; |
1866 overlay unsigned char md_buffer[16]; | 1878 overlay unsigned char md_buffer[16]; |
1867 overlay unsigned char md_temp; | 1879 overlay unsigned char md_temp; |
1868 overlay unsigned int md_pointer; | 1880 overlay unsigned short md_pointer; |
1869 | 1881 |
1870 RESET_C_STACK | 1882 RESET_C_STACK |
1871 | 1883 |
1872 // init | 1884 // init |
1873 for(md_i=0;md_i<16;md_i++) | 1885 for(md_i=0;md_i<16;md_i++) |
2047 // Used to compute NoFly remaining time. | 2059 // Used to compute NoFly remaining time. |
2048 | 2060 |
2049 void deco_calc_percentage(void) | 2061 void deco_calc_percentage(void) |
2050 { | 2062 { |
2051 RESET_C_STACK | 2063 RESET_C_STACK |
2052 int_I_temp = (int)(int_I_temp * (char_I_temp / 100.0)); | 2064 int_I_temp = (short)(int_I_temp * (char_I_temp / 100.0)); |
2053 } | 2065 } |
2054 | 2066 |
2055 ////////////////////////////////////////////////////////////////////////////// | 2067 ////////////////////////////////////////////////////////////////////////////// |
2056 | 2068 |
2057 void deco_push_tissues_to_vault(void) | 2069 void deco_push_tissues_to_vault(void) |