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)