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 }