comparison code_part1/OSTC_code_c_part2/p2_deco_main - 090915a.c @ 0:96a35aeda5f2

Initial setup
author heinrichsweikamp
date Tue, 12 Jan 2010 15:05:59 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:96a35aeda5f2
1 /*
2 * p2_deco_main.c
3 *
4 * Created on: 31.08.2009
5 * Author: christian.w @ heinrichsweikamp.com
6 *
7 */
8
9 //#include <p2_deco_header_c_v102d.h>
10
11 // OSTC - diving computer code
12 // Copyright (C) 2009 HeinrichsWeikamp GbR
13
14 // This program is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23
24 // You should have received a copy of the GNU General Public License
25 // along with this program. If not, see <http://www.gnu.org/licenses/>.
26
27
28 // *****************************
29 // ** I N T R O D U C T I O N **
30 // *****************************
31 //
32 // OSTC
33 //
34 // code:
35 // p2_deco_main_c_v101.c
36 // part2 of the OSTC code
37 // code with constant O2 partial pressure routines
38 // under construction !!
39 //
40 // summary:
41 // decompression routines
42 // for the OSTC experimental project
43 // written by Christian Weikamp
44 // last revision __________
45 // comments added _________
46 //
47 // additional files:
48 // p2_tables_v100.romdata (other files)
49 // 18f4685_ostc_v100.lkr (linker script)
50 //
51 // history:
52 // 01/03/08 v100: first release candidate
53 // 03/13/08 v101: start of programming ppO2 code
54 // 03/13/25 v101a: backup of interrim version with ppO2 calculation
55 // 03/13/25 v101: open circuit gas change during deco
56 // 03/13/25 v101: CNS_fraction calculation
57 // 03/13/26 v101: optimization of tissue calc routines
58 // 07/xx/08 v102a: debug of bottom time routine
59 // 09/xx/08 v102d: Gradient Factor Model implemenation
60 // 10/10/08 v104: renamed to build v103 for v118 stable
61 // 10/14/08 v104: integration of temp_depth_last_deco for Gradient Model
62 // 03/31/090 v107: integration of FONT Incon24
63
64 //
65 // literature:
66 // B"uhlmann, Albert: Tauchmedizin; 4. Auflage;
67 // Schr"oder, Kai & Reith, Steffen; 2000; S"attigungsvorg"ange beim Tauchen, das Modell ZH-L16, Funktionsweise von Tauchcomputern; http://www.achim-und-kai.de/kai/tausim/saett_faq
68 // Morrison, Stuart; 2000; DIY DECOMPRESSION; http://www.lizardland.co.uk/DIYDeco.html
69 // Balthasar, Steffen; Dekompressionstheorie I: Neo Haldane Modelle; http://www.txfreak.de/dekompressionstheorie_1.pdf
70 // Baker, Erik C.; Clearing Up The Confusion About "Deep Stops"
71 // Baker, Erik C.; Understanding M-values; http://www.txfreak.de/understanding_m-values.pdf
72
73
74 // *********************
75 // ** I N C L U D E S **
76 // *********************
77 #include <p18f4685.h>
78 #include <math.h>
79
80 // ********************************
81 // ** C O N F I G U R A T I O N **
82 // ** for simulation without asm **
83 // ********************************
84 #pragma config OSC = IRCIO67
85 #pragma config FCMEN = OFF
86 #pragma config IESO = OFF
87 #pragma config PWRT = ON
88 #pragma config BOREN = OFF
89 #pragma config WDT = OFF
90 #pragma config WDTPS = 128
91 #pragma config MCLRE = ON
92 #pragma config LPT1OSC = OFF
93 #pragma config PBADEN = OFF
94 #pragma config DEBUG = OFF
95 #pragma config XINST = OFF
96 #pragma config LVP = OFF
97 #pragma config STVREN = OFF
98
99 // ****************************
100 // ** D E F I N E S **
101 // ** missing in p18f4685.h **
102 // ****************************
103 #define INT0IF 1
104 #define INT1IF 0
105 #define TMR1IF 0
106
107
108 # define DBG_c_gas 0b0000000000000001
109 # define DBG_c_ppO2 0b0000000000000010
110 # define DBG_RUN 0b0000000000000100
111 # define DBG_RESTART 0b0000000000001000
112
113 # define DBG_CdeSAT 0b0000000000010000
114 # define DBG_C_MODE 0b0000000000100000
115 # define DBG_C_SURF 0b0000000001000000
116 # define DBG_HEwoHE 0b0000000010000000
117
118 # define DBG_C_DPPO2 0b0000000100000000
119 # define DBG_C_DGAS 0b0000001000000000
120 # define DBG_C_DIST 0b0000010000000000
121 # define DBG_C_LAST 0b0000100000000000
122
123 # define DBG_C_GF 0b0001000000000000
124 # define DBG_ZH16ERR 0b0010000000000000
125 # define DBG_PHIGH 0b0100000000000000
126 # define DBG_PLOW 0b1000000000000000
127
128
129 # define DBS_mode 0b0000000000000001
130 # define DBS_ppO2 0b0000000000000010
131 # define DBS_HE_sat 0b0000000000000100
132 # define DBS_ppO2chg 0b0000000000001000
133
134 # define DBS_SAT2l 0b0000000000010000
135 # define DBS_SAT2h 0b0000000000100000
136 # define DBS_GFLOW2l 0b0000000001000000
137 # define DBS_GFLOW2h 0b0000000010000000
138
139 # define DBS_GFHGH2l 0b0000000100000000
140 # define DBS_GFHGH2h 0b0000001000000000
141 # define DBS_GASO22l 0b0000010000000000
142 # define DBS_GASO22h 0b0000100000000000
143
144 # define DBS_DIST2h 0b0001000000000000
145 # define DBS_LAST2h 0b0010000000000000
146 # define DBS_DECOO2l 0b0100000000000000
147 # define DBS_DECOO2h 0b1000000000000000
148
149
150 # define DBS2_PRES2h 0b0000000000000001
151 # define DBS2_PRES2l 0b0000000000000010
152 # define DBS2_SURF2l 0b0000000000000100
153 # define DBS2_SURF2h 0b0000000000001000
154
155 # define DBS2_DESAT2l 0b0000000000010000
156 # define DBS2_DESAT2h 0b0000000000100000
157 # define DBS2_GFDneg 0b0000000001000000
158 # define DBS2_ 0b000000000000000
159
160 # define DBS2_ 0b000000000000000
161 # define DBS2_ 0b000000000000000
162 # define DBS2_ 0b000000000000000
163 # define DBS2_ 0b000000000000000
164
165 // NDL_at_20mtr
166
167
168
169 // ***********************
170 // ** V A R I A B L E S **
171 // ***********************
172 // prefixes etc:
173 // _O_ = output for use in the assembler code
174 // _I_ = input from the assembler code for the c code
175 // char_ and int_ = used to identify output and input size
176 // var = variable (from b"uhlmann)
177 // pres = pressure
178 // gtissue = guiding tissue, the one limiting the ascent
179 // e2secs = exp of the b"uhlmann formula precalculated for a 2 second step
180 // e1min = same for 1 minute step
181 // sim = used in simulating the ascent to the surface
182 // nullzeit = remaining ground/bottom time for "no deco"
183 // hauptroutine = main
184
185 #define WP_FONT_SMALL_HEIGHT 24
186 #define WP_FONT_MEDIUM_HEIGHT 32
187 #define WP_FONT_LARGE_HEIGHT 58
188
189 #define oled_rw PORTA,2,0
190 #define oled_rs PORTE,0,0
191
192 #define U8 unsigned char
193 #define U16 unsigned int
194
195 // IO assembler
196 #pragma udata bank0a=0x060
197 volatile unsigned char wp_stringstore[26];
198 volatile U8 wp_color1;
199 volatile U8 wp_color2;
200 volatile U8 wp_top;
201 volatile U8 wp_leftx2;
202 volatile U8 wp_font;
203 volatile U8 wp_invert;
204 volatile U8 wp_temp_U8;
205 // internal C
206 #pragma udata bank0b=0x081
207 volatile U8 wp_txtptr;
208 volatile unsigned char wp_char;
209 volatile U8 wp_command;
210 volatile U16 wp_data_16bit;
211 volatile U8 wp_data_8bit_one;
212 volatile U8 wp_data_8bit_two;
213 volatile U16 wp_start;
214 volatile U16 wp_end;
215 volatile U16 wp_i;
216 volatile U8 wp_black;
217 // some spare
218 volatile U8 wp_debug_U8;
219
220 // asm only
221 #pragma udata bank0c=0x0D0
222 #define LENGTH_kf_bank0 48
223 volatile unsigned char keep_free_bank0[LENGTH_kf_bank0];
224
225
226 #pragma udata bank1=0x100
227 #define LENGTH_kf_bank1 256
228 volatile unsigned char keep_free_bank1[LENGTH_kf_bank1]; // used by the assembler code
229
230 #pragma udata bank2a=0x200
231 // output:
232 static unsigned int int_O_tissue_for_debug[32];
233 static unsigned int int_O_GF_spare____; // 0x240
234 static unsigned int int_O_GF_step; // 0x242
235 static unsigned int int_O_gtissue_limit; // 0x244
236 static unsigned int int_O_gtissue_press; // 0x246
237 static unsigned int int_O_limit_GF_low; // 0x248
238 static unsigned int int_O_gtissue_press_at_GF_low; // 0x24A
239 // 0x24C + 0x24D noch unbenutzt
240
241 #pragma udata bank2b=0x24E
242 static unsigned char char_O_GF_low_pointer; // 0x24E
243 static unsigned char char_O_actual_pointer; // 0x24F
244 #pragma udata bank2c=0x250
245 static unsigned char char_O_deco_table[32]; // 0x250
246 #pragma udata bank2d=0x270
247 static unsigned char char_I_table_deco_done[32];
248 #pragma udata bank2e=0x290
249 static unsigned int int_O_calc_tissue_call_counter; // 0x290
250 // internal:
251 unsigned char lock_GF_depth_list;
252 static float temp_limit;
253 static float GF_low;
254 static float GF_high;
255 static float GF_delta;
256 static float GF_temp;
257 static float GF_step;
258 static float GF_step2;
259 static float temp_pres_gtissue;
260 static float temp_pres_gtissue_diff;
261 static float temp_pres_gtissue_limit_GF_low;
262 static float temp_pres_gtissue_limit_GF_low_below_surface;
263 static unsigned int temp_depth_limit;
264 static unsigned char temp_decotime;
265 static unsigned char temp_gtissue_no;
266 static unsigned int temp_depth_last_deco; // new in v.101
267
268 static unsigned char temp_depth_GF_low_meter;
269 static unsigned char temp_depth_GF_low_number;
270 static unsigned char internal_deco_pointer;
271 static unsigned char internal_deco_table[32];
272 static float temp_pres_deco_GF_low;
273
274 static unsigned int debug_temp;
275
276
277 #pragma udata bank3a=0x300
278 static char output[32];
279 // used by the math routines
280 #pragma udata bank3b=0x380
281 volatile float pres_tissue_vault[32];
282 #pragma udata bank4a=0x400
283 // internal:
284 unsigned char ci ; // don't move - used in _asm routines - if moved then modify movlb commands
285 unsigned char x;
286 unsigned int main_i;
287 unsigned int int_temp;
288 unsigned int int_temp_decostatus;
289 static float pres_respiration;
290 static float pres_surface;
291 static float temp1;
292 static float temp2;
293 static float temp3;
294 static float temp4;
295 static float temp_deco;
296 static float temp_atem;
297 static float temp2_atem;
298 static float temp_tissue;
299 static float temp_surface;
300 static float N2_ratio;
301 static float He_ratio;
302 static float temp_ratio;
303 static float var_a;
304 static float var2_a;
305 static float var_b;
306 static float var2_b;
307 static float var_t05nc;
308 static float var2_t05nc;
309 static float var_e2secs;
310 static float var2_e2secs;
311 static float var_e1min;
312 static float var2_e1min;
313 static float var_halftimes;
314 static float var2_halftimes;
315 static float pres_gtissue_limit;
316 static float temp_pres_gtissue_limit;
317 static float actual_ppO2; // new in v.102
318 #pragma udata bank4b=0x480
319 static float pres_tissue[32];
320
321 #pragma udata bank5=0x500
322 // don't move positions in this bank, the registers are addressed directly from assembler code
323 // input:
324 static unsigned int int_I_pres_respiration; // 0x500
325 static unsigned int int_I_pres_surface; // 0x502
326 static unsigned int int_I_temp; // 0x504 new in v101
327 static unsigned char char_I_temp; // 0x506 new in v101
328 static unsigned char char_I_actual_ppO2; // 0x507
329 static unsigned int int_I_spare_3;
330 static unsigned int int_I_spare_4;
331 static unsigned int int_I_spare_5;
332 static unsigned int int_I_spare_6;
333 static unsigned char char_I_N2_ratio; // 0x510
334 static unsigned char char_I_He_ratio; // 0x511
335 static unsigned char char_I_saturation_multiplier; // for conservatism/safety values 1.0 (no conservatism) to 1.5 (50% faster saturation
336 static unsigned char char_I_desaturation_multiplier; // for conservatism/safety values 0.66 (50% slower desaturation) to 1.0 (no conservatism)// consveratism used in calc_tissue(), calc_tissue_step_1_min() and sim_tissue_1min()
337 static unsigned char char_I_GF_High_percentage; // 0x514 new in v.102
338 static unsigned char char_I_GF_Low_percentage; // 0x515 new in v.102
339 static unsigned char char_I_spare; // 0x516
340 static unsigned char char_I_deco_distance; // 0x517
341 static unsigned char char_I_const_ppO2; // 0x518 new in v.101
342 static unsigned char char_I_deco_ppO2_change; // 0x519 new in v.101
343 static unsigned char char_I_deco_ppO2; // 0x51A new in v.101
344 static unsigned char char_I_deco_gas_change; // 0x51B new in v.101
345 static unsigned char char_I_deco_N2_ratio; // 0x51C new in v.101
346 static unsigned char char_I_deco_He_ratio; // 0x51D new in v.101
347 static unsigned char char_I_depth_last_deco; // 0x51E new in v.101 unit: [m]
348 static unsigned char char_I_deco_model; // 0x51F new in v.102 ( 1 = MultiGraF, sonst Std. mit (de-)saturation_multiplier)
349 // output:
350 static unsigned int int_O_desaturation_time; // 0x520
351 static unsigned char char_O_nullzeit; // 0x522
352 static unsigned char char_O_deco_status; // 0x523
353 static unsigned char char_O_array_decotime[7]; // 0x524
354 static unsigned char char_O_array_decodepth[6]; // 0x52B
355 static unsigned char char_O_ascenttime; // 0x531
356 static unsigned char char_O_gradient_factor; // 0x532
357 static unsigned char char_O_tissue_saturation[32]; // 0x533
358 static unsigned char char_O_array_gradient_weighted[16]; // 0x553
359 static unsigned char char_O_gtissue_no; // 0x563
360 static unsigned char char_O_diluent; // 0x564 new in v.101
361 static unsigned char char_O_CNS_fraction; // 0x565 new in v.101
362 static unsigned char char_O_relative_gradient_GF; // 0x566 new in v.102
363
364 // internal:
365 static float pres_tissue_limit[16];
366 static float sim_pres_tissue_limit[16];
367 static float pres_diluent; // new in v.101
368 static float deco_diluent; // new in v.101
369 static float const_ppO2; // new in v.101
370 static float deco_ppO2_change; // new in v.101
371 static float deco_ppO2; // new in v.101
372
373
374
375 #pragma udata bank6=0x600
376 // internal:
377 static float sim_pres_tissue[32];
378 static float sim_pres_tissue_backup[32];
379
380 //#pragma udata bank7=0x700
381 //const unsigned char keep_free_bank7[256]; // used by the assembler code (DD font2display)
382
383 #pragma udata bank8=0x800
384 static char md_pi_subst[256];
385
386 #pragma udata bank9a=0x900
387 // output:
388 static char md_state[48]; // DONT MOVE !! // has to be at the beginning of bank 9 for the asm code!!!
389 #pragma udata bank9b=0x930
390 // output:
391 static unsigned int int_O_DBS_bitfield; // 0x930 new in v.108
392 static unsigned int int_O_DBS2_bitfield; // 0x932 new in v.108
393 static unsigned int int_O_DBG_pre_bitfield; // 0x934 new in v.108
394 static unsigned int int_O_DBG_post_bitfield; // 0x936 new in v.108
395 static char char_O_NDL_at_20mtr; // 0x938 new in v.108 // 0xFF == undefined, max. 254
396 // internal:
397 static char md_t;
398 static char md_buffer[16];
399 static char md_cksum[16];
400 static char md_i;
401 static char md_j;
402 static char md_temp;
403 static unsigned int md_pointer;
404 static float deco_N2_ratio; // new in v.101
405 static float deco_He_ratio; // new in v.101
406 static float calc_N2_ratio; // new in v.101
407 static float calc_He_ratio; // new in v.101
408 static float deco_gas_change; // new in v.101
409 static float CNS_fraction; // new in v.101
410 static float float_saturation_multiplier; // new in v.101
411 static float float_desaturation_multiplier; // new in v.101
412 static float float_deco_distance; // new in v.101
413 // internal, dbg:
414 static unsigned char DBG_char_I_deco_model; // new in v.108
415 static unsigned char DBG_char_I_depth_last_deco; // new in v.108
416 static float DBG_pres_surface; // new in v.108
417 static float DBG_GF_low; // new in v.108
418 static float DBG_GF_high; // new in v.108
419 static float DBG_const_ppO2; // new in v.108
420 static float DBG_deco_ppO2_change; // new in v.108
421 static float DBG_deco_ppO2; // new in v.108
422 static float DBG_deco_N2_ratio; // new in v.108
423 static float DBG_deco_He_ratio; // new in v.108
424 static float DBG_deco_gas_change; // new in v.108
425 static float DBG_float_saturation_multiplier; // new in v.108
426 static float DBG_float_desaturation_multiplier; // new in v.108
427 static float DBG_float_deco_distance; // new in v.108
428 static float DBG_deco_N2_ratio; // new in v.108
429 static float DBG_deco_He_ratio; // new in v.108
430 static float DBG_N2_ratio; // new in v.108
431 static float DBG_He_ratio; // new in v.108
432 static char flag_in_divemode; // new in v.108
433 static int int_dbg_i; // new in v.108
434 unsigned int temp_DBS;
435
436 // *************************
437 // ** P R O T O T Y P E S **
438 // *************************
439 void main_calc_hauptroutine(void);
440 void main_calc_without_deco(void);
441 void main_clear_tissue(void);
442 void main_calc_percentage(void);
443 void main_calc_wo_deco_step_1_min(void);
444 void main_debug(void);
445 void main_gradient_array(void);
446 void main_hash(void);
447
448 void calc_hauptroutine(void);
449 void calc_tissue(void);
450 void calc_nullzeit(void);
451 void backup_sim_pres_tissue(void);
452 void restore_sim_pres_tissue(void);
453
454 void calc_without_deco(void);
455 void clear_tissue(void);
456 void calc_ascenttime(void);
457 void update_startvalues(void);
458 void clear_decoarray(void);
459 void update_decoarray(void);
460 void sim_tissue_1min(void);
461 void sim_tissue_10min(void);
462 void calc_gradient_factor(void);
463 void calc_gradient_array_only(void);
464 void calc_desaturation_time(void);
465 void calc_wo_deco_step_1_min(void);
466 void calc_tissue_step_1_min(void);
467 void hash(void);
468 void clear_CNS_fraction(void);
469 void calc_CNS_fraction(void);
470 void calc_CNS_decrease_15min(void);
471 void calc_percentage(void);
472 void main(void);
473 void calc_hauptroutine_data_input(void);
474 void calc_hauptroutine_update_tissues(void);
475 void calc_hauptroutine_calc_deco(void);
476 void calc_hauptroutine_calc_ascend_to_deco(void);
477 void calc_nextdecodepth_GF(void);
478 void copy_deco_table_GF(void);
479 void clear_internal_deco_table_GF(void);
480 void update_internal_deco_table_GF(void);
481 void DD2_write(void);
482 void DD2_write_incon42(void);
483 void DD2_get_pointer_to_char(void);
484 void DD2_set_column(void);
485 void DD2_load_background(void);
486 void DD2_build_one_line_of_char(void);
487 void DD2_print_column(void);
488 void DD2_CmdWrite(void);
489 void DD2_DataWrite(void);
490 void push_tissues_to_vault(void);
491 void pull_tissues_from_vault(void);
492 void main_push_tissues_to_vault(void);
493 void main_pull_tissues_from_vault(void);
494 void wordprocessor(void);
495
496 // *******************************
497 // ** start **
498 // ** necessary for compilation **
499 // *******************************
500 #pragma romdata der_code = 0x0000
501 #pragma code der_start = 0x0000
502 void der_start(void)
503 {
504 _asm
505 goto main
506 _endasm
507 }
508
509 // ***********************************
510 // ** main code for simulation / **
511 // ** tests without assembler code **
512 // ** is NOT a part of the OSTC **
513 // ***********************************
514 #pragma code main = 0x9000
515 void main(void)
516 {
517 for(wp_temp_U8=0;wp_temp_U8<LENGTH_kf_bank0 - 1;wp_temp_U8++)
518 keep_free_bank0[wp_temp_U8] = 7;
519 keep_free_bank0[LENGTH_kf_bank0 - 1] = 7;
520
521 for(wp_temp_U8=0;wp_temp_U8<LENGTH_kf_bank1 - 1;wp_temp_U8++)
522 keep_free_bank1[wp_temp_U8] = 7;
523 keep_free_bank1[LENGTH_kf_bank1 - 1] = 7;
524
525 #if 1
526 // new main to test DR-5
527
528 wp_top = 10;
529 wp_leftx2 = 10;
530 wp_color1 = 255;
531 wp_color2 = 255;
532 wp_font = 0;
533 wp_invert = 0;
534 wp_stringstore[0] = ' ';
535 wp_stringstore[1] = '!';
536 wp_stringstore[2] = '"';
537 wp_stringstore[3] = ':';
538 wp_stringstore[4] = 0;
539 wordprocessor();
540
541 GF_low = 1.0;
542 GF_high = 1.0;
543
544 GF_temp = GF_low * GF_high;
545
546 clear_CNS_fraction();
547 //char_I_const_ppO2 = 100;
548 //for (main_i=0;main_i<255;main_i++)
549 //{
550 //calc_CNS_fraction();
551 //} //for
552
553
554
555
556 int_I_pres_respiration = 1000;//980;
557 int_I_pres_surface = 1000;//980;
558 char_I_N2_ratio = 39; //38;
559 char_I_He_ratio = 40; //50;
560 char_I_deco_distance = 0; // 10 = 1 meter
561 char_I_depth_last_deco = 3; // values below 3 (meter) are ignored
562
563 char_I_const_ppO2 = 0;
564 char_I_deco_ppO2_change = 0; // [dm] 10 = 1 meter
565 char_I_deco_ppO2 = 0;
566
567 char_I_deco_gas_change = 0; // [m] 1 = 1 meter
568 char_I_deco_N2_ratio = 0;
569 char_I_deco_He_ratio = 0;
570
571 //char_I_actual_ppO2; // 0x507
572 char_I_GF_High_percentage = 100; // 0x514 new in v.102
573 char_I_GF_Low_percentage = 100; // 0x515 new in v.102
574
575 char_I_saturation_multiplier = 110;
576 char_I_desaturation_multiplier = 90;
577
578 char_I_deco_model = 0;
579
580 main_clear_tissue();
581
582 int_I_pres_respiration = 1000 + int_I_pres_surface;
583 main_calc_wo_deco_step_1_min();
584 int_I_pres_respiration = 3000 + int_I_pres_surface;
585 main_calc_wo_deco_step_1_min();
586 int_I_pres_respiration = 5000 + int_I_pres_surface;
587 main_calc_wo_deco_step_1_min();
588
589 /*
590 int_I_pres_respiration = 6000 + int_I_pres_surface;
591 for (main_i=0;main_i<27;main_i++)
592 main_calc_wo_deco_step_1_min();
593 */
594
595 char_O_deco_status = 255;
596 while (char_O_deco_status)
597 main_calc_hauptroutine();
598 _asm
599 nop
600 _endasm
601
602 for (main_i=0;main_i<50;main_i++)
603 {
604 main_calc_hauptroutine();
605 }
606 int_I_pres_respiration = 10000;
607 for (main_i=0;main_i<1500;main_i++)
608 {
609 main_calc_hauptroutine();
610 }
611
612 _asm
613 nop
614 _endasm
615
616
617 int_I_pres_respiration = 3000;
618 for (main_i=0;main_i<150;main_i++)
619 {
620 calc_hauptroutine_data_input();
621 calc_hauptroutine_update_tissues();
622 } //for
623
624 update_startvalues();
625 clear_decoarray();
626 clear_internal_deco_table_GF();
627 calc_hauptroutine_calc_ascend_to_deco();
628 if (char_O_deco_status > 15) // can't go up to first deco, too deep to calculate in the given time slot
629 {
630 char_O_deco_status = 2;
631 // char_O_lock_depth_list = 255;
632 }
633 else
634 {
635 // char_O_lock_depth_list = lock_GF_depth_list;
636 calc_hauptroutine_calc_deco();
637 }
638 // build_debug_output();
639
640 _asm
641 nop
642 _endasm
643 while (char_O_deco_status == 1)
644 {
645 char_O_deco_status = 0;
646 // char_O_lock_depth_list = 255;
647 calc_hauptroutine_calc_deco();
648 // build_debug_output();
649 _asm
650 nop
651 _endasm
652 };
653 debug_temp = 60; // [mtr Aufstieg in 10 mtr/min (30steps'2sec/min]
654 int_I_pres_respiration = 9980;
655 for (main_i=0;main_i<debug_temp;main_i++)
656 {
657 int_I_pres_respiration = int_I_pres_respiration - 33;
658 calc_hauptroutine_data_input();
659 calc_hauptroutine_update_tissues();
660 int_I_pres_respiration = int_I_pres_respiration - 33;
661 calc_hauptroutine_data_input();
662 calc_hauptroutine_update_tissues();
663 int_I_pres_respiration = int_I_pres_respiration - 34;
664 calc_hauptroutine_data_input();
665 calc_hauptroutine_update_tissues();
666 } //for
667 _asm
668 nop
669 _endasm
670
671 update_startvalues();
672 clear_decoarray();
673 clear_internal_deco_table_GF();
674 calc_hauptroutine_calc_ascend_to_deco();
675 if (char_O_deco_status > 15) // can't go up to first deco, too deep to calculate in the given time slot
676 {
677 char_O_deco_status = 2;
678 // char_O_lock_depth_list = 255;
679 }
680 else
681 {
682 // char_O_lock_depth_list = lock_GF_depth_list;
683 calc_hauptroutine_calc_deco();
684 }
685 // build_debug_output();
686
687 _asm
688 nop
689 _endasm
690 while (char_O_deco_status == 1)
691 {
692 char_O_deco_status = 0;
693 // char_O_lock_depth_list = 255;
694 calc_hauptroutine_calc_deco();
695 // build_debug_output();
696 _asm
697 nop
698 _endasm
699 };
700 _asm
701 nop
702 _endasm
703 debug_temp = 60; // [mtr Aufstieg in 10 mtr/min (30steps'2sec/min]
704 int_I_pres_respiration = 9980;
705 debug_temp = debug_temp * 3;
706 for (main_i=0;main_i<debug_temp;main_i++)
707 {
708 calc_hauptroutine_data_input();
709 calc_hauptroutine_update_tissues();
710 } //for
711 _asm
712 nop
713 _endasm
714 #endif
715 // -----------------------
716
717 } // main
718
719 // ******************************************************
720 // ******************************************************
721 // ** THE FOLLOWING CODE HAS TO BE COPPIED TO THE OSTC **
722 // ******************************************************
723 // ******************************************************
724
725 // ***************
726 // ***************
727 // ** THE FONTS **
728 // ***************
729 // ***************
730 // all new for bigscreen
731
732 #pragma romdata font_data_large = 0x09A00
733 rom const rom U16 wp_large_data[] =
734 {
735 #include "ostc90.drx.txt"
736 };
737
738 #pragma romdata font_table_medium = 0x0A000
739 rom const rom U16 wp_medium_table[] =
740 {
741 #include "ostc48.tbl.txt" // length 0x22
742 };
743
744 #pragma romdata font_data_medium = 0x0A024
745 rom const rom U16 wp_medium_data[] =
746 {
747 #include "ostc48.drx.txt" // length 0x390
748 };
749
750 #pragma romdata font_table_small = 0x0A39A
751 rom const rom U16 wp_small_table[] =
752 {
753 #include "ostc28.tbl.txt"
754 };
755
756 #pragma romdata font_data_small = 0x0A484
757 rom const rom U16 wp_small_data[] =
758 {
759 #include "ostc28.drx.txt"
760 };
761
762 #pragma romdata font_table_large = 0x0BEE0
763 rom const rom U16 wp_large_table[] =
764 {
765 0x0000
766 //#include "ostc90.tbl.txt"
767 };
768
769 // ***********************
770 // ***********************
771 // ** THE SUBROUTINES 2 **
772 // ***********************
773 // ***********************
774 // all new in v.102
775 // moved from 0x0D000 to 0x0C000 in v.108
776
777 #pragma code subroutines2 = 0x0C000 // can be adapted to fit the romdata tables ahead
778
779 // -------------------------------
780 // DBS - debug on start of dive //
781 // -------------------------------
782 void create_dbs_set_dbg_and_ndl20mtr(void)
783 {
784 int_O_DBS_bitfield = 0;
785 int_O_DBS2_bitfield = 0;
786 if(int_O_DBG_pre_bitfield & DBG_RUN)
787 int_O_DBG_pre_bitfield = DBG_RESTART;
788 else
789 int_O_DBG_pre_bitfield = DBG_RUN;
790 int_O_DBG_post_bitfield = 0;
791 char_O_NDL_at_20mtr = 255;
792
793 DBG_N2_ratio = N2_ratio;
794 DBG_He_ratio = He_ratio;
795 DBG_char_I_deco_model = char_I_deco_model;
796 DBG_char_I_depth_last_deco = char_I_depth_last_deco;
797 DBG_pres_surface = pres_surface;
798 DBG_GF_low = GF_low;
799 DBG_GF_high = GF_high;
800 DBG_const_ppO2 = const_ppO2;
801 DBG_deco_ppO2_change = deco_ppO2_change;
802 DBG_deco_ppO2 = deco_ppO2;
803 DBG_deco_N2_ratio = deco_N2_ratio;
804 DBG_deco_He_ratio = deco_He_ratio;
805 DBG_deco_gas_change = deco_gas_change;
806 DBG_float_saturation_multiplier = float_saturation_multiplier;
807 DBG_float_desaturation_multiplier = float_desaturation_multiplier;
808 DBG_float_deco_distance = float_deco_distance;
809
810 if(char_I_deco_model)
811 int_O_DBS_bitfield |= DBS_mode;
812 if(const_ppO2)
813 int_O_DBS_bitfield |= DBS_ppO2;
814 for(int_dbg_i = 16; int_dbg_i < 32; int_dbg_i++)
815 if(pres_tissue[int_dbg_i])
816 int_O_DBS_bitfield |= DBS_HE_sat;
817 if(deco_ppO2_change)
818 int_O_DBS_bitfield |= DBS_ppO2chg;
819 if(float_saturation_multiplier < 0.99)
820 int_O_DBS_bitfield |= DBS_SAT2l;
821 if(float_saturation_multiplier > 1.3)
822 int_O_DBS_bitfield |= DBS_SAT2h;
823 if(GF_low < 0.19)
824 int_O_DBS_bitfield |= DBS_GFLOW2l;
825 if(GF_low > 1.01)
826 int_O_DBS_bitfield |= DBS_GFLOW2h;
827 if(GF_high < 0.6)
828 int_O_DBS_bitfield |= DBS_GFHGH2l;
829 if(GF_high > 1.01)
830 int_O_DBS_bitfield |= DBS_GFHGH2h;
831 if((N2_ratio + He_ratio) > 0.95)
832 int_O_DBS_bitfield |= DBS_GASO22l;
833 if((N2_ratio + He_ratio) < 0.05)
834 int_O_DBS_bitfield |= DBS_GASO22h;
835 if(float_deco_distance > 0.25)
836 int_O_DBS_bitfield |= DBS_DIST2h;
837 if(char_I_depth_last_deco > 8)
838 int_O_DBS_bitfield |= DBS_LAST2h;
839 if(DBG_deco_gas_change && ((deco_N2_ratio + deco_He_ratio) > 0.95))
840 int_O_DBS_bitfield |= DBS_DECOO2l;
841 if(DBG_deco_gas_change && ((deco_N2_ratio + deco_He_ratio) < 0.05))
842 int_O_DBS_bitfield |= DBS_DECOO2h;
843 if(pres_respiration > 3.0)
844 int_O_DBS2_bitfield |= DBS2_PRES2h;
845 if(pres_surface - pres_respiration > 0.2)
846 int_O_DBS2_bitfield |= DBS2_PRES2l;
847 if(pres_surface < 0.75)
848 int_O_DBS2_bitfield |= DBS2_SURF2l;
849 if(pres_surface > 1.11)
850 int_O_DBS2_bitfield |= DBS2_SURF2h;
851 if(float_desaturation_multiplier < 0.70)
852 int_O_DBS2_bitfield |= DBS2_DESAT2l;
853 if(float_desaturation_multiplier > 1.01)
854 int_O_DBS2_bitfield |= DBS2_DESAT2h;
855 if(GF_low > GF_high)
856 int_O_DBS2_bitfield |= DBS2_GFDneg;
857 }
858
859 // -------------------------------
860 // DBG - set DBG to end_of_dive //
861 // -------------------------------
862 void set_dbg_end_of_dive(void)
863 {
864 int_O_DBG_pre_bitfield &= (~DBG_RUN);
865 int_O_DBG_post_bitfield &= (~DBG_RUN);
866 }
867
868 // -------------------------------
869 // DBG - NDL at first 20 m. hit //
870 // -------------------------------
871 void check_ndl(void)
872 {
873 if((char_O_NDL_at_20mtr == -1) && (int_I_pres_respiration > 3000))
874 {
875 char_O_NDL_at_20mtr = char_O_nullzeit;
876 if(char_O_NDL_at_20mtr == 255)
877 char_O_NDL_at_20mtr == 254;
878 }
879 }
880
881 // -------------------------------
882 // DBG - multi main during dive //
883 // -------------------------------
884 void check_dbg(char is_post_check)
885 {
886 temp_DBS = 0;
887 if( (DBG_N2_ratio != N2_ratio) || (DBG_He_ratio != He_ratio) )
888 temp_DBS |= DBG_c_gas;
889 if(DBG_const_ppO2 != const_ppO2)
890 temp_DBS |= DBG_c_ppO2;
891 if((DBG_float_saturation_multiplier != float_saturation_multiplier) || (DBG_float_desaturation_multiplier != float_desaturation_multiplier))
892 temp_DBS |= DBG_CdeSAT;
893 if(DBG_char_I_deco_model != char_I_deco_model)
894 temp_DBS |= DBG_C_MODE;
895 if(DBG_pres_surface != pres_surface)
896 temp_DBS |= DBG_C_SURF;
897 if((!DBS_HE_sat) && (!He_ratio))
898 for(int_dbg_i = 16; int_dbg_i < 32; int_dbg_i++)
899 if(pres_tissue[int_dbg_i])
900 temp_DBS |= DBG_HEwoHE;
901 if(DBG_deco_ppO2 != deco_ppO2)
902 temp_DBS |= DBG_C_DPPO2;
903 if((DBG_deco_gas_change != deco_gas_change) || (DBG_deco_N2_ratio != deco_N2_ratio) || (DBG_deco_He_ratio != deco_He_ratio))
904 temp_DBS |= DBG_C_DGAS;
905 if(DBG_float_deco_distance != float_deco_distance)
906 temp_DBS |= DBG_C_DIST;
907 if(DBG_char_I_depth_last_deco != char_I_depth_last_deco)
908 temp_DBS |= DBG_C_LAST;
909 if((DBG_GF_low != GF_low) || (DBG_GF_high != GF_high))
910 temp_DBS |= DBG_C_GF;
911 if(pres_respiration > 13.0)
912 temp_DBS |= DBG_PHIGH;
913 if(pres_surface - pres_respiration > 0.2)
914 temp_DBS |= DBG_PLOW;
915 /*
916 if()
917 temp_DBS |= ;
918 if()
919 temp_DBS |= ;
920 */
921 if(is_post_check)
922 int_O_DBG_post_bitfield |= temp_DBS;
923 else
924 int_O_DBG_pre_bitfield |= temp_DBS;
925 }
926
927 // -------------------------------
928 // DBG - prior to calc. of dive //
929 // -------------------------------
930 void check_pre_dbg(void)
931 {
932 check_dbg(0);
933 }
934
935 // -------------------------------
936 // DBG - after decocalc of dive //
937 // -------------------------------
938 void check_post_dbg(void)
939 {
940 check_dbg(1);
941 }
942
943
944
945 // -------------------------
946 // calc_next_decodepth_GF //
947 // -------------------------
948 // new in v.102
949 void calc_nextdecodepth_GF(void)
950 {
951 // INPUT, changing during dive:
952 // temp_pres_gtissue_limit_GF_low
953 // temp_pres_gtissue_limit_GF_low_below_surface
954 // temp_pres_gtissue
955 // temp_pres_gtissue_diff
956 // lock_GF_depth_list
957
958 // INPUT, fixed during dive:
959 // pres_surface
960 // GF_delta
961 // GF_high
962 // GF_low
963 // temp_depth_last_deco
964 // float_deco_distance
965
966 // OUTPUT
967 // GF_step
968 // temp_deco
969 // temp_depth_limt
970 // lock_GF_depth_list
971
972 // USES
973 // temp1
974 // temp2
975 // int_temp
976
977 char_I_table_deco_done[0] = 0; // safety if changed somewhere else. Needed for exit
978 if (char_I_deco_model == 1)
979 {
980 if (lock_GF_depth_list == 0)
981 {
982 temp2 = temp_pres_gtissue_limit_GF_low_below_surface / 0.29985; // = ... / 99.95 / 0.003;
983 int_temp = (int) (temp2 + 0.99);
984 if (int_temp > 31)
985 int_temp = 31; // deepest deco at 93 meter (31 deco stops)
986 if (int_temp < 0)
987 int_temp = 0;
988 temp_depth_GF_low_number = int_temp;
989 temp_depth_GF_low_meter = 3 * temp_depth_GF_low_number;
990 temp2 = (float)temp_depth_GF_low_meter * 0.09995;
991 temp_pres_deco_GF_low = temp2 + float_deco_distance + pres_surface;
992 if (temp_depth_GF_low_number == 0)
993 GF_step = 0;
994 else
995 GF_step = GF_delta / (float)temp_depth_GF_low_number;
996 if (GF_step < 0)
997 GF_step = 0;
998 if (GF_step > GF_delta)
999 GF_step = GF_delta;
1000 int_O_GF_step = (int)(GF_step * 10000);
1001 int_O_limit_GF_low = (int)(temp_pres_deco_GF_low * 1000);
1002 int_O_gtissue_press_at_GF_low = (int)(temp_pres_gtissue * 1000);
1003 char_O_GF_low_pointer = temp_depth_GF_low_number;
1004 lock_GF_depth_list = 1;
1005 internal_deco_pointer = 0;
1006 }
1007 if (internal_deco_pointer == 0) // new run
1008 {
1009 internal_deco_pointer = temp_depth_GF_low_number;
1010 GF_temp = GF_high - ((float)internal_deco_pointer * GF_step);
1011 int_temp = char_I_table_deco_done[internal_deco_pointer];
1012 output[8] = int_temp;
1013 output[9] = 33;
1014 }
1015 else
1016 {
1017 int_temp = 1;
1018 }
1019 while (int_temp == 1)
1020 {
1021 int_temp = internal_deco_pointer - 1;
1022 if (int_temp == 1) // new in v104
1023 {
1024 temp2 = (float)(temp_depth_last_deco * int_temp) * 0.09995;
1025 GF_step2 = GF_step/3.0 * ((float)(6 - temp_depth_last_deco));
1026 }
1027 else
1028 if (int_temp == 0)
1029 {
1030 temp2 = 0.0;
1031 GF_step2 = GF_high - GF_temp;
1032 }
1033 else
1034 {
1035 temp2 = (float)(3 *int_temp) * 0.09995;
1036 GF_step2 = GF_step;
1037 }
1038 temp2 = temp2 + pres_surface; // next deco stop to be tested
1039 temp1 = ((GF_temp + GF_step2)* temp_pres_gtissue_diff) + temp_pres_gtissue; // upper limit (lowest pressure allowed) // changes GF_step2 in v104
1040 if (temp1 > temp2) // check if ascent to next deco stop is ok
1041 {
1042 int_temp = 0; // no
1043 }
1044 else
1045 {
1046 internal_deco_pointer = int_temp;
1047 GF_temp = GF_temp + GF_step2; // changed in v104
1048 int_temp = char_I_table_deco_done[internal_deco_pointer]; // yes and check for ascent to even next stop if deco_done is set
1049 }
1050 } // while
1051 if (internal_deco_pointer > 0)
1052 {
1053 temp2 = (float)(0.29985 * internal_deco_pointer);
1054 temp_deco = temp2 + float_deco_distance + pres_surface;
1055 if (internal_deco_pointer == 1) // new in v104
1056 temp_depth_limit = temp_depth_last_deco;
1057 else
1058 temp_depth_limit = 3 * internal_deco_pointer;
1059 if (output[9] == 33)
1060 {
1061 output[9] = internal_deco_pointer;
1062 output[10] = char_I_table_deco_done[internal_deco_pointer];
1063 output[12] = output[12] + 1;
1064 if (output[12] == 100)
1065 output[12] = 0;
1066 }
1067 }
1068 else // if (char_I_deco_model == 1)
1069 {
1070 temp_deco = pres_surface;
1071 temp_depth_limit = 0;
1072 }
1073 }
1074 else
1075 {
1076 // calc_nextdecodepth - original
1077 // optimized in v.101
1078 // depth_last_deco included in v.101
1079
1080 temp1 = temp_pres_gtissue_limit - pres_surface;
1081 if (temp1 >= 0)
1082 {
1083 temp1 = temp1 / 0.29985; // = temp1 / 99.95 / 0.003;
1084 temp_depth_limit = (int) (temp1 + 0.99);
1085 temp_depth_limit = 3 * temp_depth_limit; // depth for deco [m]
1086 if (temp_depth_limit == 0)
1087 temp_deco = pres_surface;
1088 else
1089 {
1090 if (temp_depth_limit < temp_depth_last_deco)
1091 temp_depth_limit = temp_depth_last_deco;
1092 temp1 = (float)temp_depth_limit * 0.09995;
1093 temp_deco = temp1 + float_deco_distance + pres_surface; // depth for deco [bar]
1094 } // if (temp_depth_limit == 0)
1095 } // if (temp1 >= 0)
1096 else
1097 {
1098 temp_deco = pres_surface;
1099 temp_depth_limit = 0;
1100 } // if (temp1 >= 0)
1101 } // calc_nextdecodepth original
1102 } // calc_nextdecodepth_GF
1103
1104
1105 #if 0
1106 void build_debug_output(void)
1107 {
1108 output[0] = 0; // not used in asm PLED output
1109 output[1] = (int) (GF_low * 100);
1110 output[2] = (int) (GF_high * 100);
1111 output[3] = (int) (GF_step * 100);
1112 output[4] = (int) temp_depth_GF_low_number;
1113 output[5] = (int) temp_depth_GF_low_meter;
1114 //output[6]
1115 output[7] = (int) internal_deco_pointer;
1116 //output[8] = char_I_table_deco_done[temp_depth_GF_low_number]
1117 //output[9] = internal_deco_pointer @ new run
1118 //output[10] = char_I_table_deco_done[internal_deco_pointer] @ new run
1119 output [11] = (int) (temp_pres_deco_GF_low * 10);
1120 } // build_debug_output
1121 #endif
1122
1123 // ---------------------
1124 // copy_deco_table_GF //
1125 // ---------------------
1126 // new in v.102
1127 void copy_deco_table_GF(void)
1128 {
1129 if (char_I_deco_model == 1)
1130 {
1131 int_temp = 32;
1132 for (ci=0;ci<int_temp;ci++)
1133 char_O_deco_table[ci] = internal_deco_table[ci];
1134 }
1135 } // copy_deco_table_GF
1136
1137
1138 // ------------------------------
1139 // clear_internal_deco_table_GF//
1140 // ------------------------------
1141 // new in v.102
1142 void clear_internal_deco_table_GF(void)
1143 {
1144 if (char_I_deco_model == 1)
1145 {
1146 for (ci=0;ci<32;ci++) // cycle through the 16 b"uhlmann tissues for Helium
1147 {
1148 internal_deco_table[ci] = 0;
1149 }
1150 }
1151 } // clear_internal_deco_table_GF
1152
1153
1154 // --------------------------------
1155 // update_internal_deco_table_GF //
1156 // --------------------------------
1157 // new in v.102
1158 void update_internal_deco_table_GF(void)
1159 {
1160 if ((char_I_deco_model == 1) && (internal_deco_table[internal_deco_pointer] < 255))
1161 internal_deco_table[internal_deco_pointer] = internal_deco_table[internal_deco_pointer] + 1;
1162 } // update_internal_deco_table_GF
1163
1164
1165 // ---------------------
1166 // temp_tissue_safety //
1167 // ---------------------
1168 // outsourced in v.102
1169 void temp_tissue_safety(void)
1170 {
1171 if (char_I_deco_model == 1)
1172 {
1173 }
1174 else
1175 {
1176 if (temp_tissue < 0.0)
1177 temp_tissue = temp_tissue * float_desaturation_multiplier;
1178 else
1179 temp_tissue = temp_tissue * float_saturation_multiplier;
1180 }
1181 } // temp_tissue_safety
1182
1183 // -----------
1184 // dd2 OLD //
1185 // -----------
1186 void DD2_write(void)
1187 {
1188 _asm
1189 nop
1190 _endasm
1191 }
1192 void DD2_write_incon42(void)
1193 {
1194 DD2_write();
1195 }
1196
1197 void DD2_write_incon24(void)
1198 {
1199 DD2_write();
1200 }
1201 void DD2_get_pointer_to_char(void)
1202 {
1203 DD2_write();
1204 }
1205 void DD2_set_column(void)
1206 {
1207 DD2_write();
1208 }
1209 void DD2_load_background(void)
1210 {
1211 DD2_write();
1212 }
1213 void DD2_build_one_line_of_char(void)
1214 {
1215 DD2_write();
1216 }
1217 void DD2_print_column(void)
1218 {
1219 DD2_write();
1220 }
1221 void DD2_CmdWrite(void)
1222 {
1223 DD2_write();
1224 }
1225 void DD2_DataWrite(void)
1226 {
1227 DD2_write();
1228 }
1229
1230 // **********************
1231 // **********************
1232 // ** THE JUMP-IN CODE **
1233 // ** for the asm code **
1234 // **********************
1235 // **********************
1236 #pragma code main_calc_hauptroutine = 0x10000
1237 void main_calc_hauptroutine(void)
1238 {
1239 calc_hauptroutine();
1240 int_O_desaturation_time = 65535;
1241 } // divemode
1242 #pragma code main_without_deco = 0x10020
1243 void main_calc_without_deco(void)
1244 {
1245 calc_without_deco();
1246 calc_desaturation_time();
1247 }
1248
1249 #pragma code main_clear_CNS_fraction = 0x10030
1250 void main_clear_CNS_fraction(void)
1251 {
1252 clear_CNS_fraction();
1253 }
1254
1255 #pragma code main_calc_CNS_decrease_15min = 0x10034
1256 void main_calc_CNS_decrease_15min(void)
1257 {
1258 calc_CNS_decrease_15min();
1259 }
1260
1261 #pragma code main_calc_percentage = 0x10038
1262 void main_calc_percentage (void)
1263 {
1264 calc_percentage();
1265 }
1266
1267 #pragma code main_clear_tissue = 0x10040
1268 void main_clear_tissue(void)
1269 {
1270 clear_tissue();
1271 char_I_depth_last_deco = 0; // for compatibility with v.101pre_no_last_deco
1272 }
1273
1274 #pragma code main_calc_CNS_fraction = 0x10050
1275 void main_calc_CNS_fraction(void)
1276 {
1277 calc_CNS_fraction();
1278 }
1279
1280 #pragma code main_calc_desaturation_time = 0x10060
1281 void main_calc_desaturation_time(void)
1282 {
1283 calc_desaturation_time();
1284 }
1285
1286 #pragma code main_calc_wo_deco_step_1_min = 0x10080
1287 void main_calc_wo_deco_step_1_min(void)
1288 {
1289 calc_wo_deco_step_1_min();
1290 char_O_deco_status = 3; // surface new in v.102 overwrites value of calc_wo_deco_step_1_min
1291 calc_desaturation_time();
1292 } // surface mode
1293
1294 #pragma code main_debug = 0x100A0
1295 void main_debug(void)
1296 {
1297 //debug();
1298 }
1299
1300 #pragma code main_DD2_write_incon42 = 0x100B0
1301 void main_DD2_write_incon42(void)
1302 {
1303 DD2_write_incon42();
1304 }
1305
1306 #pragma code main_DD2_write_incon24 = 0x100B4
1307 void main_DD2_write_incon24(void)
1308 {
1309 DD2_write_incon24();
1310 }
1311
1312 #pragma code main_wordprocessor = 0x100B8
1313 void main_wordprocessor(void)
1314 {
1315 wordprocessor();
1316 }
1317
1318 #pragma code main_gradient_array = 0x100C0
1319 void main_gradient_array(void)
1320 {
1321 calc_gradient_array_only();
1322 }
1323 #pragma code main_push_tissues = 0x100C4
1324 void main_push_tissues_to_vault(void)
1325 {
1326 push_tissues_to_vault();
1327 }
1328 #pragma code main_pull_tissues = 0x100C8
1329 void main_pull_tissues_from_vault(void)
1330 {
1331 pull_tissues_from_vault();
1332 }
1333
1334 #pragma code main_hash = 0x100E0
1335 void main_hash(void)
1336 {
1337 hash();
1338 }
1339
1340 // ***********************
1341 // ***********************
1342 // ** THE LOOKUP TABLES **
1343 // ***********************
1344 // ***********************
1345
1346 #pragma romdata tables = 0x10200
1347 #include <p2_tables.romdata> // new table for deco_main_v.101 (var_a modified)
1348
1349 #pragma romdata tables2 = 0x10600
1350 rom const rom unsigned int md_pi[] =
1351 {
1352 0x292E, 0x43C9, 0xA2D8, 0x7C01, 0x3D36, 0x54A1, 0xECF0, 0x0613
1353 , 0x62A7, 0x05F3, 0xC0C7, 0x738C, 0x9893, 0x2BD9, 0xBC4C, 0x82CA
1354 , 0x1E9B, 0x573C, 0xFDD4, 0xE016, 0x6742, 0x6F18, 0x8A17, 0xE512
1355 , 0xBE4E, 0xC4D6, 0xDA9E, 0xDE49, 0xA0FB, 0xF58E, 0xBB2F, 0xEE7A
1356 , 0xA968, 0x7991, 0x15B2, 0x073F, 0x94C2, 0x1089, 0x0B22, 0x5F21
1357 , 0x807F, 0x5D9A, 0x5A90, 0x3227, 0x353E, 0xCCE7, 0xBFF7, 0x9703
1358 , 0xFF19, 0x30B3, 0x48A5, 0xB5D1, 0xD75E, 0x922A, 0xAC56, 0xAAC6
1359 , 0x4FB8, 0x38D2, 0x96A4, 0x7DB6, 0x76FC, 0x6BE2, 0x9C74, 0x04F1
1360 , 0x459D, 0x7059, 0x6471, 0x8720, 0x865B, 0xCF65, 0xE62D, 0xA802
1361 , 0x1B60, 0x25AD, 0xAEB0, 0xB9F6, 0x1C46, 0x6169, 0x3440, 0x7E0F
1362 , 0x5547, 0xA323, 0xDD51, 0xAF3A, 0xC35C, 0xF9CE, 0xBAC5, 0xEA26
1363 , 0x2C53, 0x0D6E, 0x8528, 0x8409, 0xD3DF, 0xCDF4, 0x4181, 0x4D52
1364 , 0x6ADC, 0x37C8, 0x6CC1, 0xABFA, 0x24E1, 0x7B08, 0x0CBD, 0xB14A
1365 , 0x7888, 0x958B, 0xE363, 0xE86D, 0xE9CB, 0xD5FE, 0x3B00, 0x1D39
1366 , 0xF2EF, 0xB70E, 0x6658, 0xD0E4, 0xA677, 0x72F8, 0xEB75, 0x4B0A
1367 , 0x3144, 0x50B4, 0x8FED, 0x1F1A, 0xDB99, 0x8D33, 0x9F11, 0x8314
1368 };
1369
1370 // *********************
1371 // *********************
1372 // ** THE SUBROUTINES **
1373 // *********************
1374 // *********************
1375
1376 #pragma code subroutines = 0x10700 // can be adapted to fit the romdata tables ahead
1377
1378
1379 // ---------------
1380 // CLEAR tissue //
1381 // ---------------
1382 // optimized in v.101 (var_a)
1383
1384 void clear_tissue(void) // preload tissues with standard pressure for the given ambient pressure
1385 {
1386
1387 flag_in_divemode = 0;
1388 int_O_DBS_bitfield = 0;
1389 int_O_DBS2_bitfield = 0;
1390 int_O_DBG_pre_bitfield = 0;
1391 int_O_DBG_post_bitfield = 0;
1392 char_O_NDL_at_20mtr = 255;
1393
1394 _asm
1395 lfsr 1, 0x300 // C math routines shall use this variable bank
1396 movlw 0x01
1397 movwf TBLPTRU,0
1398 _endasm
1399
1400 // N2_ratio = (float)char_I_N2_ratio; // the 0.0002 of 0.7902 are missing with standard air
1401 N2_ratio = 0.7902; // N2_ratio / 100.0;
1402 pres_respiration = (float)int_I_pres_respiration / 1000.0;
1403 for (ci=0;ci<16;ci++) // cycle through the 16 b"uhlmann tissues
1404 {
1405 pres_tissue[ci] = N2_ratio * (pres_respiration - 0.0627) ;
1406 _asm
1407 movlw 0x02
1408 movwf TBLPTRH,0
1409 movlb 4 // fuer ci
1410 movf ci,0,1
1411 addwf ci,0,1
1412 addwf ci,0,1
1413 addwf ci,0,1
1414 addlw 0x80
1415 movwf TBLPTRL,0
1416 TBLRDPOSTINC
1417 movff TABLAT,var_a+1
1418 TBLRDPOSTINC
1419 movff TABLAT,var_a
1420 TBLRDPOSTINC
1421 movff TABLAT,var_a+3
1422 TBLRD
1423 movff TABLAT,var_a+2
1424 addlw 0x80
1425 movwf TBLPTRL,0
1426 incf TBLPTRH,1,0
1427 TBLRDPOSTINC
1428 movff TABLAT,var_b+1
1429 TBLRDPOSTINC
1430 movff TABLAT,var_b
1431 TBLRDPOSTINC
1432 movff TABLAT,var_b+3
1433 TBLRD
1434 movff TABLAT,var_b+2
1435 _endasm
1436
1437 pres_tissue_limit[ci] = (pres_tissue[ci] - var_a) * var_b ;
1438 // now update the guiding tissue
1439 if (pres_tissue_limit[ci] < 0)
1440 pres_tissue_limit[ci] = 0;
1441 } // for 0 to 16
1442
1443 for (ci=16;ci<32;ci++) // cycle through the 16 b"uhlmann tissues for Helium
1444 {
1445 pres_tissue[ci] = 0.0;
1446 } // for
1447
1448 clear_decoarray();
1449 char_O_deco_status = 0;
1450 char_O_nullzeit = 0;
1451 char_O_ascenttime = 0;
1452 char_O_gradient_factor = 0;
1453 char_O_relative_gradient_GF = 0;
1454 } // clear_tissue(void)
1455
1456
1457 // --------------------
1458 // calc_without_deco //
1459 // fixed N2_ratio ! //
1460 // --------------------
1461 // optimized in v.101 (float_..saturation_multiplier)
1462
1463 void calc_without_deco(void)
1464 {
1465 _asm
1466 lfsr 1, 0x300
1467 _endasm
1468 N2_ratio = 0.7902; // FIXED RATIO !! sum as stated in b"uhlmann
1469 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system
1470 pres_surface = (float)int_I_pres_surface / 1000.0;
1471 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body
1472 temp2_atem = 0.0;
1473 temp_surface = pres_surface; // the b"uhlmann formula using temp_surface does apply to the pressure without any inert ratio
1474 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0;
1475 float_saturation_multiplier = char_I_saturation_multiplier / 100.0;
1476
1477 calc_tissue(); // update the pressure in the 16 tissues in accordance with the new ambient pressure
1478
1479 clear_decoarray();
1480 char_O_deco_status = 0;
1481 char_O_nullzeit = 0;
1482 char_O_ascenttime = 0;
1483 calc_gradient_factor();
1484
1485 } // calc_without_deco
1486
1487
1488 // --------------------
1489 // calc_hauptroutine //
1490 // --------------------
1491 // this is the major code in dive mode
1492 // calculates:
1493 // the tissues,
1494 // the bottom time
1495 // and simulates the ascend with all deco stops
1496
1497 void calc_hauptroutine(void)
1498 {
1499 calc_hauptroutine_data_input();
1500
1501 if(!flag_in_divemode)
1502 {
1503 flag_in_divemode = 1;
1504 create_dbs_set_dbg_and_ndl20mtr();
1505 }
1506 else
1507 check_pre_dbg();
1508
1509 calc_hauptroutine_update_tissues();
1510 calc_gradient_factor();
1511
1512
1513 switch (char_O_deco_status) // toggle between calculation for nullzeit (bottom time), deco stops and more deco stops (continue)
1514 {
1515 case 0:
1516 update_startvalues();
1517 calc_nullzeit();
1518 check_ndl();
1519 char_O_deco_status = 255; // calc deco next time
1520 break;
1521 case 1:
1522 if (char_O_deco_status == 3)
1523 break;
1524 char_O_deco_status = 0;
1525 // char_O_lock_depth_list = 255;
1526 calc_hauptroutine_calc_deco();
1527 // build_debug_output();
1528 break;
1529 case 3: // new dive
1530 clear_decoarray();
1531 clear_internal_deco_table_GF();
1532 copy_deco_table_GF();
1533 internal_deco_pointer = 0;
1534 lock_GF_depth_list = 0;
1535 update_startvalues();
1536 calc_nextdecodepth_GF();
1537 char_O_deco_status = 0;
1538 break;
1539 default:
1540 update_startvalues();
1541 clear_decoarray();
1542 clear_internal_deco_table_GF();
1543 output[6] = 1;
1544 calc_hauptroutine_calc_ascend_to_deco();
1545 if (char_O_deco_status > 15) // can't go up to first deco, too deep to calculate in the given time slot
1546 {
1547 char_O_deco_status = 2;
1548 // char_O_lock_depth_list = 255;
1549 }
1550 else
1551 {
1552 // char_O_lock_depth_list = lock_GF_depth_list;
1553 calc_hauptroutine_calc_deco();
1554 }
1555 // build_debug_output();
1556 break;
1557 }
1558 calc_ascenttime();
1559 check_post_dbg();
1560 }
1561
1562 void calc_hauptroutine_data_input(void)
1563 {
1564 pres_respiration = (float)int_I_pres_respiration / 1000.0;
1565 pres_surface = (float)int_I_pres_surface / 1000.0;
1566
1567 N2_ratio = (float)char_I_N2_ratio / 100.0;; // the 0.0002 of 0.7902 are missing with standard air
1568 He_ratio = (float)char_I_He_ratio / 100.0;;
1569 deco_N2_ratio = (float)char_I_deco_N2_ratio / 100.0;
1570 deco_He_ratio = (float)char_I_deco_He_ratio / 100.0;
1571 float_deco_distance = (float)char_I_deco_distance / 100.0;
1572 if(char_I_deco_gas_change)
1573 {
1574 deco_gas_change = (float)char_I_deco_gas_change / 9.995 + pres_surface;
1575 deco_gas_change = deco_gas_change + float_deco_distance;
1576 }
1577 else
1578 deco_gas_change = 0;
1579 const_ppO2 = (float)char_I_const_ppO2 / 100.0;
1580 deco_ppO2_change = (float)char_I_deco_ppO2_change / 99.95 + pres_surface;
1581 deco_ppO2_change = deco_ppO2_change + float_deco_distance;
1582 deco_ppO2 = (float)char_I_deco_ppO2 / 100.0;
1583 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0;
1584 float_saturation_multiplier = char_I_saturation_multiplier / 100.0;
1585 GF_low = (float)char_I_GF_Low_percentage / 100.0;
1586 GF_high = (float)char_I_GF_High_percentage / 100.0;
1587 GF_delta = GF_high - GF_low;
1588
1589 temp2 = (pres_respiration - pres_surface) / 0.29985;
1590 int_temp = (int)(temp2);
1591 if (int_temp < 0)
1592 int_temp = 0;
1593 if (int_temp > 255)
1594 int_temp = 255;
1595 char_O_actual_pointer = int_temp;
1596
1597 temp_depth_last_deco = (int)char_I_depth_last_deco;
1598 }
1599
1600 void calc_hauptroutine_update_tissues(void)
1601 {
1602 int_O_calc_tissue_call_counter = int_O_calc_tissue_call_counter + 1;
1603 if (char_I_const_ppO2 == 0) // new in v.101
1604 pres_diluent = pres_respiration; // new in v.101
1605 else // new in v.101
1606 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101
1607 if (pres_diluent > pres_respiration) // new in v.101
1608 pres_diluent = pres_respiration; // new in v.101
1609 if (pres_diluent > 0.0627) // new in v.101
1610 {
1611 temp_atem = N2_ratio * (pres_diluent - 0.0627); // changed in v.101
1612 temp2_atem = He_ratio * (pres_diluent - 0.0627); // changed in v.101
1613 char_O_diluent = (char)(pres_diluent/pres_respiration*100.0);
1614 }
1615 else // new in v.101
1616 {
1617 temp_atem = 0.0; // new in v.101
1618 temp2_atem = 0.0; // new in v.101
1619 char_O_diluent = 0;
1620 }
1621 temp_surface = pres_surface;
1622 calc_tissue();
1623 int_O_gtissue_limit = (int)(pres_tissue_limit[char_O_gtissue_no] * 1000);
1624 int_O_gtissue_press = (int)((pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16]) * 1000);
1625 if (char_I_deco_model == 1)
1626 {
1627 temp1 = temp1 * GF_high;
1628 }
1629 else
1630 {
1631 temp1 = temp_surface;
1632 }
1633 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately
1634 {
1635 char_O_nullzeit = 0; // deco necessary
1636 char_O_deco_status = 255; // calculate deco skip nullzeit calculation
1637 }
1638 } // calc_hauptroutine_update_tissues
1639 void calc_hauptroutine_calc_deco(void)
1640 {
1641 do
1642 {
1643 int_temp_decostatus = 0;
1644 calc_nextdecodepth_GF();
1645 if (temp_depth_limit > 0)
1646 {
1647 if (char_I_const_ppO2 == 0) // new in v.101
1648 {
1649 deco_diluent = temp_deco; // new in v.101
1650 if (temp_deco > deco_gas_change)
1651 {
1652 calc_N2_ratio = N2_ratio;
1653 calc_He_ratio = He_ratio;
1654 }
1655 else
1656 {
1657 calc_N2_ratio = deco_N2_ratio;
1658 calc_He_ratio = deco_He_ratio;
1659 }
1660 }
1661 else // new in v.101
1662 {
1663 calc_N2_ratio = N2_ratio;
1664 calc_He_ratio = He_ratio;
1665 if (temp_deco > deco_ppO2_change)
1666 {
1667 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101
1668 }
1669 else
1670 {
1671 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); // new in v.101
1672 }
1673 }
1674 if (deco_diluent > temp_deco) // new in v.101
1675 deco_diluent = temp_deco; // new in v.101
1676 if (deco_diluent > 0.0627) // new in v.101
1677 {
1678 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); // changed in v.101
1679 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); // changed in v.101
1680 }
1681 else // new in v.101
1682 {
1683 temp_atem = 0.0; // new in v.101
1684 temp2_atem = 0.0; // new in v.101
1685 }
1686 sim_tissue_1min();
1687 update_internal_deco_table_GF();
1688 temp_decotime = 1;
1689 update_decoarray();
1690 char_O_deco_status = char_O_deco_status + 1;
1691 if (char_O_deco_status < 16)
1692 int_temp_decostatus = 1;
1693 }
1694 else // if (temp_depth_limit > 0)
1695 {
1696 char_O_deco_status = 0;
1697 }
1698 } while (int_temp_decostatus == 1);
1699 if (char_O_deco_status > 15)
1700 {
1701 char_O_deco_status = 1;
1702 }
1703 else
1704 {
1705 copy_deco_table_GF();
1706 char_O_deco_status = 0;
1707 }
1708 }
1709
1710 void calc_hauptroutine_calc_ascend_to_deco(void)
1711 {
1712 update_startvalues();
1713 char_O_deco_status = 0;
1714 temp_deco = pres_respiration;
1715 lock_GF_depth_list = 1; // new in v.102
1716 do // go up to first deco
1717 {
1718 int_temp_decostatus = 0;
1719 temp_deco = temp_deco - 1.0;
1720 if ( char_I_deco_model == 1) // new in v.102 , 4 = deep stops
1721 temp_limit = temp_pres_gtissue_limit_GF_low;
1722 else
1723 temp_limit = temp_pres_gtissue_limit;
1724 if ((temp_deco > temp_limit) && (temp_deco > pres_surface)) // changes in v.102
1725 {
1726 lock_GF_depth_list = 0; // new in v.102, distance to first stop > 10 mtr.
1727 output[6] = 0;
1728 if (char_I_const_ppO2 == 0) // new in v.101 // calculate at half of the ascent
1729 {
1730 deco_diluent = temp_deco + 0.5; // new in v.101
1731 if (temp_deco + 0.5 > deco_gas_change)
1732 {
1733 calc_N2_ratio = N2_ratio;
1734 calc_He_ratio = He_ratio;
1735 }
1736 else
1737 {
1738 calc_N2_ratio = deco_N2_ratio;
1739 calc_He_ratio = deco_He_ratio;
1740 }
1741 }
1742 else // new in v.101
1743 {
1744 calc_N2_ratio = N2_ratio;
1745 calc_He_ratio = He_ratio;
1746 if (temp_deco + 0.5 > deco_ppO2_change)
1747 deco_diluent = ((temp_deco + 0.5 - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 // calculate at half of the ascent
1748 else
1749 deco_diluent = ((temp_deco + 0.5 - deco_ppO2)/(N2_ratio + He_ratio)); // new in v.101 // calculate at half of the ascent
1750 if (deco_diluent > (temp_deco +0.5)) // new in v.101
1751 deco_diluent = temp_deco + 0.5; // new in v.101 // calculate at half of the ascent
1752 }
1753 if (deco_diluent > 0.0627) // new in v.101
1754 {
1755 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); // changed in v.101
1756 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); // changed in v.101
1757 }
1758 else // new in v.101
1759 {
1760 temp_atem = 0.0; // new in v.101
1761 temp2_atem = 0.0; // new in v.101
1762 }
1763 sim_tissue_1min();
1764 char_O_deco_status = char_O_deco_status + 1;
1765 if (char_O_deco_status < 16) // 16 is the limit of calculations for one time slot
1766 int_temp_decostatus = 1;
1767 }
1768 } while (int_temp_decostatus == 1);
1769 } // calc_hauptroutine_calc_ascend_to_deco
1770
1771 // --------------
1772 // calc_tissue //
1773 // --------------
1774 // optimized in v.101
1775
1776 void calc_tissue(void)
1777 {
1778 _asm
1779 lfsr 1, 0x300
1780 movlw 0x01
1781 movwf TBLPTRU,0
1782 _endasm
1783
1784 char_O_gtissue_no = 255;
1785 pres_gtissue_limit = 0.0;
1786
1787 for (ci=0;ci<16;ci++)
1788 {
1789 _asm
1790 movlw 0x02
1791 movwf TBLPTRH,0
1792 movlb 4 // fuer ci
1793 movf ci,0,1
1794 addwf ci,0,1
1795 addwf ci,0,1
1796 addwf ci,0,1
1797 movwf TBLPTRL,0
1798 TBLRDPOSTINC
1799 movff TABLAT,var_e2secs+1 // the order is confussing
1800 TBLRDPOSTINC
1801 movff TABLAT,var_e2secs // low byte first, high afterwards
1802 TBLRDPOSTINC
1803 movff TABLAT,var_e2secs+3
1804 TBLRD
1805 movff TABLAT,var_e2secs+2
1806 addlw 0x40
1807 movwf TBLPTRL,0
1808 TBLRDPOSTINC
1809 movff TABLAT,var2_e2secs+1
1810 TBLRDPOSTINC
1811 movff TABLAT,var2_e2secs
1812 TBLRDPOSTINC
1813 movff TABLAT,var2_e2secs+3
1814 TBLRD
1815 movff TABLAT,var2_e2secs+2
1816 addlw 0x40
1817 movwf TBLPTRL,0
1818 TBLRDPOSTINC
1819 movff TABLAT,var_a+1
1820 TBLRDPOSTINC
1821 movff TABLAT,var_a
1822 TBLRDPOSTINC
1823 movff TABLAT,var_a+3
1824 TBLRD
1825 movff TABLAT,var_a+2
1826 addlw 0x40
1827 movwf TBLPTRL,0
1828 TBLRDPOSTINC
1829 movff TABLAT,var2_a+1
1830 TBLRDPOSTINC
1831 movff TABLAT,var2_a
1832 TBLRDPOSTINC
1833 movff TABLAT,var2_a+3
1834 TBLRD
1835 movff TABLAT,var2_a+2
1836 addlw 0x40
1837 movwf TBLPTRL,0
1838 incf TBLPTRH,1,0
1839 TBLRDPOSTINC
1840 movff TABLAT,var_b+1
1841 TBLRDPOSTINC
1842 movff TABLAT,var_b
1843 TBLRDPOSTINC
1844 movff TABLAT,var_b+3
1845 TBLRD
1846 movff TABLAT,var_b+2
1847 addlw 0x40
1848 movwf TBLPTRL,0
1849 TBLRDPOSTINC
1850 movff TABLAT,var2_b+1
1851 TBLRDPOSTINC
1852 movff TABLAT,var2_b
1853 TBLRDPOSTINC
1854 movff TABLAT,var2_b+3
1855 TBLRD
1856 movff TABLAT,var2_b+2
1857 _endasm
1858 // the start values are the previous end values // write new values in temp
1859
1860 if( (var_e2secs < 0.0000363)
1861 || (var_e2secs > 0.00577)
1862 || (var2_e2secs < 0.0000961)
1863 || (var2_e2secs > 0.150)
1864 || (var_a < 0.231)
1865 || (var_a > 1.27)
1866 || (var_b < 0.504)
1867 || (var_b > 0.966)
1868 || (var2_a < 0.510)
1869 || (var2_a > 1.75)
1870 || (var2_b < 0.423)
1871 || (var2_b > 0.927)
1872 )
1873 int_O_DBG_pre_bitfield |= DBG_ZH16ERR;
1874
1875 // N2
1876 temp_tissue = (temp_atem - pres_tissue[ci]) * var_e2secs;
1877 temp_tissue_safety();
1878 pres_tissue[ci] = pres_tissue[ci] + temp_tissue;
1879
1880 // He
1881 temp_tissue = (temp2_atem - pres_tissue[ci+16]) * var2_e2secs;
1882 temp_tissue_safety();
1883 pres_tissue[ci+16] = pres_tissue[ci+16] + temp_tissue;
1884
1885 temp_tissue = pres_tissue[ci] + pres_tissue[ci+16];
1886
1887 var_a = (var_a * pres_tissue[ci] + var2_a * pres_tissue[ci+16]) / temp_tissue;
1888 var_b = (var_b * pres_tissue[ci] + var2_b * pres_tissue[ci+16]) / temp_tissue;
1889 pres_tissue_limit[ci] = (temp_tissue - var_a) * var_b;
1890 if (pres_tissue_limit[ci] < 0)
1891 pres_tissue_limit[ci] = 0;
1892 if (pres_tissue_limit[ci] > pres_gtissue_limit)
1893 {
1894 pres_gtissue_limit = pres_tissue_limit[ci];
1895 char_O_gtissue_no = ci;
1896 }//if
1897 } // for
1898 }//calc_tissue(void)
1899
1900 // ----------------
1901 // calc_nullzeit //
1902 // ----------------
1903 // calculates the remaining bottom time
1904
1905 // unchanged in v.101
1906
1907 void calc_nullzeit(void)
1908 {
1909 char_O_nullzeit = 0;
1910 int_temp = 1;
1911 do
1912 {
1913 backup_sim_pres_tissue();
1914 sim_tissue_10min();
1915 char_O_nullzeit = char_O_nullzeit + 10;
1916 int_temp = int_temp + 1;
1917 if (char_I_deco_model == 1)
1918 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue;
1919 else
1920 temp1 = temp_pres_gtissue_limit;
1921 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately
1922 int_temp = 255;
1923 } while (int_temp < 17);
1924 if (int_temp == 255)
1925 {
1926 restore_sim_pres_tissue();
1927 char_O_nullzeit = char_O_nullzeit - 10;
1928 } //if int_temp == 255]
1929 int_temp = 1;
1930 if (char_O_nullzeit < 60)
1931 {
1932 do
1933 {
1934 sim_tissue_1min();
1935 char_O_nullzeit = char_O_nullzeit + 1;
1936 int_temp = int_temp + 1; // new in v.102a
1937 if (char_I_deco_model == 1)
1938 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue;
1939 else
1940 temp1 = temp_pres_gtissue_limit;
1941 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately
1942 int_temp = 255;
1943 } while (int_temp < 10);
1944 if (int_temp == 255)
1945 char_O_nullzeit = char_O_nullzeit - 1;
1946 } // if char_O_nullzeit < 60
1947 } //calc_nullzeit
1948
1949 // -------------------------
1950 // backup_sim_pres_tissue //
1951 // -------------------------
1952 void backup_sim_pres_tissue(void)
1953 {
1954 for (x = 0;x<16;x++)
1955 {
1956 sim_pres_tissue_backup[x] = sim_pres_tissue[x];
1957 sim_pres_tissue_backup[x+16] = sim_pres_tissue[x+16];
1958 }
1959 } // backup_sim
1960
1961 // --------------------------
1962 // restore_sim_pres_tissue //
1963 // --------------------------
1964 void restore_sim_pres_tissue(void)
1965 {
1966 for (x = 0;x<16;x++)
1967 {
1968 sim_pres_tissue[x] = sim_pres_tissue_backup[x];
1969 sim_pres_tissue[x+16] = sim_pres_tissue_backup[x+16];
1970 }
1971 } // restore_sim
1972
1973 // ------------------
1974 // calc_ascenttime //
1975 // ------------------
1976
1977 void calc_ascenttime(void)
1978 {
1979 if (pres_respiration > pres_surface)
1980 {
1981 switch (char_O_deco_status)
1982 {
1983 case 2:
1984 char_O_ascenttime = 255;
1985 break;
1986 case 1:
1987 break;
1988 default:
1989 temp1 = pres_respiration - pres_surface + 0.6; // + 0.6 hence 1 minute ascent time from a depth of 4 meter on
1990 if (temp1 < 0)
1991 temp1 = 0;
1992 if (temp1 > 255)
1993 temp1 = 255;
1994 char_O_ascenttime = (char)temp1;
1995
1996 for(ci=0;ci<7;ci++)
1997 {
1998 x = char_O_ascenttime + char_O_array_decotime[ci];
1999 if (x < char_O_ascenttime)
2000 char_O_ascenttime = 255;
2001 else
2002 char_O_ascenttime = x;
2003 }
2004 }
2005 }
2006 else
2007 char_O_ascenttime = 0;
2008 } // calc_ascenttime()
2009
2010
2011 // ---------------------
2012 // update_startvalues //
2013 // ---------------------
2014 // updated in v.102
2015
2016 void update_startvalues(void)
2017 {
2018 temp_pres_gtissue_limit = pres_gtissue_limit;
2019 temp_pres_gtissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16];
2020 temp_pres_gtissue_diff = temp_pres_gtissue_limit - temp_pres_gtissue; // negative number
2021 temp_pres_gtissue_limit_GF_low = GF_low * temp_pres_gtissue_diff + temp_pres_gtissue;
2022 temp_pres_gtissue_limit_GF_low_below_surface = temp_pres_gtissue_limit_GF_low - pres_surface;
2023 if (temp_pres_gtissue_limit_GF_low_below_surface < 0)
2024 temp_pres_gtissue_limit_GF_low_below_surface = 0;
2025
2026 temp_gtissue_no = char_O_gtissue_no;
2027 for (x = 0;x<16;x++)
2028 {
2029 sim_pres_tissue[x] = pres_tissue[x];
2030 sim_pres_tissue[x+16] = pres_tissue[x+16];
2031 sim_pres_tissue_limit[x] = pres_tissue_limit[x];
2032 }
2033 } // update_startvalues
2034
2035
2036 // ------------------
2037 // sim_tissue_1min //
2038 // ------------------
2039 // optimized in v.101
2040
2041 void sim_tissue_1min(void)
2042 {
2043 temp_pres_gtissue_limit = 0.0;
2044 temp_gtissue_no = 255;
2045
2046 _asm
2047 lfsr 1, 0x300
2048 movlw 0x01
2049 movwf TBLPTRU,0
2050 _endasm
2051
2052
2053 for (ci=0;ci<16;ci++)
2054 {
2055 _asm
2056 movlw 0x02
2057 movwf TBLPTRH,0
2058 movlb 4 // fuer ci
2059 movf ci,0,1
2060 addwf ci,0,1
2061 addwf ci,0,1
2062 addwf ci,0,1
2063 addlw 0x80
2064 movwf TBLPTRL,0
2065 TBLRDPOSTINC
2066 movff TABLAT,var_a+1
2067 TBLRDPOSTINC
2068 movff TABLAT,var_a
2069 TBLRDPOSTINC
2070 movff TABLAT,var_a+3
2071 TBLRD
2072 movff TABLAT,var_a+2
2073 addlw 0x40
2074 movwf TBLPTRL,0
2075 TBLRDPOSTINC
2076 movff TABLAT,var2_a+1
2077 TBLRDPOSTINC
2078 movff TABLAT,var2_a
2079 TBLRDPOSTINC
2080 movff TABLAT,var2_a+3
2081 TBLRD
2082 movff TABLAT,var2_a+2
2083 addlw 0x40
2084 movwf TBLPTRL,0
2085 incf TBLPTRH,1,0
2086 TBLRDPOSTINC
2087 movff TABLAT,var_b+1
2088 TBLRDPOSTINC
2089 movff TABLAT,var_b
2090 TBLRDPOSTINC
2091 movff TABLAT,var_b+3
2092 TBLRD
2093 movff TABLAT,var_b+2
2094 addlw 0x40
2095 movwf TBLPTRL,0
2096 TBLRDPOSTINC
2097 movff TABLAT,var2_b+1
2098 TBLRDPOSTINC
2099 movff TABLAT,var2_b
2100 TBLRDPOSTINC
2101 movff TABLAT,var2_b+3
2102 TBLRD
2103 movff TABLAT,var2_b+2
2104 addlw 0xC0
2105 movwf TBLPTRL,0
2106 incf TBLPTRH,1,0
2107 TBLRDPOSTINC
2108 movff TABLAT,var_e1min+1
2109 TBLRDPOSTINC
2110 movff TABLAT,var_e1min
2111 TBLRDPOSTINC
2112 movff TABLAT,var_e1min+3
2113 TBLRD
2114 movff TABLAT,var_e1min+2
2115 addlw 0x40
2116 movwf TBLPTRL,0
2117 TBLRDPOSTINC
2118 movff TABLAT,var2_e1min+1
2119 TBLRDPOSTINC
2120 movff TABLAT,var2_e1min
2121 TBLRDPOSTINC
2122 movff TABLAT,var2_e1min+3
2123 TBLRD
2124 movff TABLAT,var2_e1min+2
2125 _endasm
2126 // N2
2127 temp_tissue = (temp_atem - sim_pres_tissue[ci]) * var_e1min;
2128 temp_tissue_safety();
2129 sim_pres_tissue[ci] = sim_pres_tissue[ci] + temp_tissue;
2130 // He
2131 temp_tissue = (temp2_atem - sim_pres_tissue[ci+16]) * var2_e1min;
2132 temp_tissue_safety();
2133 sim_pres_tissue[ci+16] = sim_pres_tissue[ci+16] + temp_tissue;
2134 // pressure limit
2135 temp_tissue = sim_pres_tissue[ci] + sim_pres_tissue[ci+16];
2136 var_a = (var_a * sim_pres_tissue[ci] + var2_a * sim_pres_tissue[ci+16]) / temp_tissue;
2137 var_b = (var_b * sim_pres_tissue[ci] + var2_b * sim_pres_tissue[ci+16]) / temp_tissue;
2138 sim_pres_tissue_limit[ci] = (temp_tissue - var_a) * var_b;
2139
2140 if (sim_pres_tissue_limit[ci] < 0)
2141 sim_pres_tissue_limit[ci] = 0;
2142 if (sim_pres_tissue_limit[ci] > temp_pres_gtissue_limit)
2143 {
2144 temp_pres_gtissue = temp_tissue;
2145 temp_pres_gtissue_limit = sim_pres_tissue_limit[ci];
2146 temp_gtissue_no = ci;
2147 }
2148 } // for
2149 temp_pres_gtissue_diff = temp_pres_gtissue_limit - temp_pres_gtissue;
2150 temp_pres_gtissue_limit_GF_low = GF_low * temp_pres_gtissue_diff + temp_pres_gtissue;
2151 temp_pres_gtissue_limit_GF_low_below_surface = temp_pres_gtissue_limit_GF_low - pres_surface;
2152 if (temp_pres_gtissue_limit_GF_low_below_surface < 0)
2153 temp_pres_gtissue_limit_GF_low_below_surface = 0;
2154 } //sim_tissue_1min()
2155
2156 //--------------------
2157 // sim_tissue_10min //
2158 //--------------------
2159
2160 // Attention!! uses var_e1min und var2_e1min to load 10min data !!!
2161 // is identical to sim_tissue_1min routine except for the different load of those variables
2162
2163 // optimized in v.101
2164
2165 void sim_tissue_10min(void)
2166 {
2167 temp_pres_gtissue_limit = 0.0;
2168 temp_gtissue_no = 255;
2169
2170 _asm
2171 lfsr 1, 0x300
2172 movlw 0x01
2173 movwf TBLPTRU,0
2174 _endasm
2175
2176 for (ci=0;ci<16;ci++)
2177 {
2178 _asm
2179 movlw 0x02
2180 movwf TBLPTRH,0
2181 movlb 4 // fuer ci
2182 movf ci,0,1
2183 addwf ci,0,1
2184 addwf ci,0,1
2185 addwf ci,0,1
2186 addlw 0x80
2187 movwf TBLPTRL,0
2188 TBLRDPOSTINC
2189 movff TABLAT,var_a+1
2190 TBLRDPOSTINC
2191 movff TABLAT,var_a
2192 TBLRDPOSTINC
2193 movff TABLAT,var_a+3
2194 TBLRD
2195 movff TABLAT,var_a+2
2196 addlw 0x40
2197 movwf TBLPTRL,0
2198 TBLRDPOSTINC
2199 movff TABLAT,var2_a+1
2200 TBLRDPOSTINC
2201 movff TABLAT,var2_a
2202 TBLRDPOSTINC
2203 movff TABLAT,var2_a+3
2204 TBLRD
2205 movff TABLAT,var2_a+2
2206 addlw 0x40
2207 movwf TBLPTRL,0
2208 incf TBLPTRH,1,0
2209 TBLRDPOSTINC
2210 movff TABLAT,var_b+1
2211 TBLRDPOSTINC
2212 movff TABLAT,var_b
2213 TBLRDPOSTINC
2214 movff TABLAT,var_b+3
2215 TBLRD
2216 movff TABLAT,var_b+2
2217 addlw 0x40
2218 movwf TBLPTRL,0
2219 TBLRDPOSTINC
2220 movff TABLAT,var2_b+1
2221 TBLRDPOSTINC
2222 movff TABLAT,var2_b
2223 TBLRDPOSTINC
2224 movff TABLAT,var2_b+3
2225 TBLRD
2226 movff TABLAT,var2_b+2
2227 addlw 0xC0 // different to 1 min
2228 movwf TBLPTRL,0
2229 incf TBLPTRH,1,0
2230 incf TBLPTRH,1,0 // different to 1 min
2231 TBLRDPOSTINC
2232 movff TABLAT,var_e1min+1
2233 TBLRDPOSTINC
2234 movff TABLAT,var_e1min
2235 TBLRDPOSTINC
2236 movff TABLAT,var_e1min+3
2237 TBLRD
2238 movff TABLAT,var_e1min+2
2239 addlw 0x40
2240 movwf TBLPTRL,0
2241 //incf TBLPTRH,1,0 // different to 1 min
2242 TBLRDPOSTINC
2243 movff TABLAT,var2_e1min+1
2244 TBLRDPOSTINC
2245 movff TABLAT,var2_e1min
2246 TBLRDPOSTINC
2247 movff TABLAT,var2_e1min+3
2248 TBLRD
2249 movff TABLAT,var2_e1min+2
2250 _endasm
2251 // N2
2252 temp_tissue = (temp_atem - sim_pres_tissue[ci]) * var_e1min;
2253 temp_tissue_safety();
2254 sim_pres_tissue[ci] = sim_pres_tissue[ci] + temp_tissue;
2255 // He
2256 temp_tissue = (temp2_atem - sim_pres_tissue[ci+16]) * var2_e1min;
2257 temp_tissue_safety();
2258 sim_pres_tissue[ci+16] = sim_pres_tissue[ci+16] + temp_tissue;
2259 // pressure limit
2260 temp_tissue = sim_pres_tissue[ci] + sim_pres_tissue[ci+16];
2261 var_a = (var_a * sim_pres_tissue[ci] + var2_a * sim_pres_tissue[ci+16]) / temp_tissue;
2262 var_b = (var_b * sim_pres_tissue[ci] + var2_b * sim_pres_tissue[ci+16]) / temp_tissue;
2263
2264 sim_pres_tissue_limit[ci] = (temp_tissue - var_a) * var_b;
2265 if (sim_pres_tissue_limit[ci] < 0)
2266 sim_pres_tissue_limit[ci] = 0;
2267 if (sim_pres_tissue_limit[ci] > temp_pres_gtissue_limit)
2268 {
2269 temp_pres_gtissue = temp_tissue;
2270 temp_pres_gtissue_limit = sim_pres_tissue_limit[ci];
2271 temp_gtissue_no = ci;
2272 }
2273 } // for
2274 temp_pres_gtissue_diff = temp_pres_gtissue_limit - temp_pres_gtissue; // negative number
2275 temp_pres_gtissue_limit_GF_low = GF_low * temp_pres_gtissue_diff + temp_pres_gtissue;
2276 temp_pres_gtissue_limit_GF_low_below_surface = temp_pres_gtissue_limit_GF_low - pres_surface;
2277 if (temp_pres_gtissue_limit_GF_low_below_surface < 0)
2278 temp_pres_gtissue_limit_GF_low_below_surface = 0;
2279 } //sim_tissue_10min()
2280
2281
2282 // ------------------
2283 // clear_decoarray //
2284 // ------------------
2285 // unchanged in v.101
2286
2287 void clear_decoarray(void)
2288 {
2289 char_O_array_decodepth[0] = 0;
2290 char_O_array_decodepth[1] = 0;
2291 char_O_array_decodepth[2] = 0;
2292 char_O_array_decodepth[3] = 0;
2293 char_O_array_decodepth[4] = 0;
2294 char_O_array_decodepth[5] = 0;
2295 char_O_array_decotime[0] = 0;
2296 char_O_array_decotime[1] = 0;
2297 char_O_array_decotime[2] = 0;
2298 char_O_array_decotime[3] = 0;
2299 char_O_array_decotime[4] = 0;
2300 char_O_array_decotime[5] = 0;
2301 char_O_array_decotime[6] = 0;
2302 } // clear_decoarray
2303
2304
2305 // -------------------
2306 // update_decoarray //
2307 // -------------------
2308 // unchanged in v.101
2309
2310 void update_decoarray()
2311 {
2312 x = 0;
2313 do
2314 {
2315 if (char_O_array_decodepth[x] == temp_depth_limit)
2316 {
2317 int_temp = char_O_array_decotime[x] + temp_decotime;
2318 if (int_temp < 0)
2319 int_temp = 0;
2320 if (int_temp > 240)
2321 int_temp = 240;
2322 char_O_array_decotime[x] = int_temp;
2323 x = 10; // exit
2324 } // if
2325 else
2326 {
2327 if (char_O_array_decodepth[x] == 0)
2328 {
2329 if (temp_depth_limit > 255)
2330 char_O_array_decodepth[x] = 255;
2331 else
2332 char_O_array_decodepth[x] = (char)temp_depth_limit;
2333 int_temp = char_O_array_decotime[x] + temp_decotime;
2334 if (int_temp > 240)
2335 char_O_array_decotime[x] = 240;
2336 else
2337 char_O_array_decotime[x] = (char)int_temp;
2338 x = 10; // exit
2339 } // if
2340 else
2341 x++;
2342 } // else
2343 } while (x<6);
2344 if (x == 6)
2345 {
2346 int_temp = char_O_array_decotime[6] + temp_decotime;
2347 if (int_temp > 220)
2348 char_O_array_decotime[6] = 220;
2349 else
2350 char_O_array_decotime[6] = (char)int_temp;
2351 } // if x == 6
2352 } // update_decoarray
2353
2354
2355 // -----------------------
2356 // calc_gradient_factor //
2357 // -----------------------
2358 // optimized in v.101 (var_a)
2359 // new code in v.102
2360
2361 void calc_gradient_factor(void)
2362 {
2363 // tissue > respiration (entsaettigungsvorgang)
2364 // gradient ist wieviel prozent an limit mit basis tissue
2365 // dh. 0% = respiration == tissue
2366 // dh. 100% = respiration == limit
2367 temp_tissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16];
2368 temp1 = temp_tissue - pres_respiration;
2369 temp2 = temp_tissue - pres_tissue_limit[char_O_gtissue_no]; // changed in v.102
2370 temp2 = temp1/temp2;
2371 temp2 = temp2 * 100; // displayed in percent
2372 if (temp2 < 0)
2373 temp2 = 0;
2374 if (temp2 > 255)
2375 temp2 = 255;
2376 if (temp1 < 0)
2377 char_O_gradient_factor = 0;
2378 else
2379 char_O_gradient_factor = (char)temp2;
2380
2381 temp3 = temp2;
2382
2383 if (char_I_deco_model == 1) // calculate relative gradient factor
2384 {
2385 temp1 = (float)temp_depth_GF_low_meter * 0.09995;
2386 temp2 = pres_respiration - pres_surface;
2387 if (temp2 <= 0)
2388 temp1 = GF_high;
2389 else
2390 if (temp2 >= temp1)
2391 temp1 = GF_low;
2392 else
2393 temp1 = GF_low + (temp1 - temp2)/temp1*GF_delta;
2394 if (temp_depth_GF_low_meter == 0)
2395 temp1 = GF_high;
2396 temp2 = temp3 / temp1; // temp3 is already in percent
2397 if (temp2 < 0)
2398 temp2 = 0;
2399 if (temp2 > 255)
2400 temp2 = 255;
2401 char_O_relative_gradient_GF = (char)temp2;
2402 } // calc relative gradient factor
2403 else
2404 {
2405 char_O_relative_gradient_GF = char_O_gradient_factor;
2406 }
2407 } // calc_gradient
2408
2409 // ---------------------------
2410 // calc_gradient_array_only //
2411 // ---------------------------
2412 // optimized in v.101 (var_a)
2413 // new code in v.102
2414
2415 void calc_gradient_array_only()
2416 {
2417 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system
2418 for (ci=0;ci<16;ci++)
2419 {
2420 temp_tissue = pres_tissue[ci] + pres_tissue[ci+16];
2421 temp1 = temp_tissue - pres_respiration;
2422 temp2 = temp_tissue - pres_tissue_limit[ci];
2423 temp2 = temp1/temp2;
2424 temp2 = temp2 * 200; // because of output in (Double-)percentage
2425 if (temp2 < 0)
2426 temp2 = 0;
2427 if (temp2 > 255)
2428 temp2 = 255;
2429 if (temp1 < 0)
2430 char_O_array_gradient_weighted[ci] = 0;
2431 else
2432 char_O_array_gradient_weighted[ci] = (char)temp2;
2433 } // for
2434 } // calc_gradient_array_only
2435
2436
2437 // -------------------------
2438 // calc_desaturation_time //
2439 // -------------------------
2440 // FIXED N2_ratio
2441 // unchanged in v.101
2442
2443 void calc_desaturation_time(void)
2444 {
2445 _asm
2446 lfsr 1, 0x300
2447 movlw 0x01
2448 movwf TBLPTRU,0
2449 _endasm
2450 N2_ratio = 0.7902; // FIXED sum as stated in b"uhlmann
2451 pres_surface = (float)int_I_pres_surface / 1000.0;
2452 temp_atem = N2_ratio * (pres_surface - 0.0627);
2453 int_O_desaturation_time = 0;
2454 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142)
2455
2456 for (ci=0;ci<16;ci++)
2457 {
2458 _asm
2459 movlw 0x04
2460 movwf TBLPTRH,0
2461 movlb 4 // fuer ci
2462 movf ci,0,1
2463 addwf ci,0,1
2464 addwf ci,0,1
2465 addwf ci,0,1
2466 addlw 0x80
2467 movwf TBLPTRL,0
2468 TBLRDPOSTINC
2469 movff TABLAT,var_halftimes+1
2470 TBLRDPOSTINC
2471 movff TABLAT,var_halftimes
2472 TBLRDPOSTINC
2473 movff TABLAT,var_halftimes+3
2474 TBLRD
2475 movff TABLAT,var_halftimes+2
2476 addlw 0x40
2477 movwf TBLPTRL,0
2478 TBLRDPOSTINC
2479 movff TABLAT,var2_halftimes+1
2480 TBLRDPOSTINC
2481 movff TABLAT,var2_halftimes
2482 TBLRDPOSTINC
2483 movff TABLAT,var2_halftimes+3
2484 TBLRD
2485 movff TABLAT,var2_halftimes+2
2486 _endasm
2487
2488 // saturation_time (for flight) and N2_saturation in multiples of halftime
2489 // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time )
2490 // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time )
2491 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and noFly calculations
2492 // N2
2493 temp1 = 1.05 * temp_atem;
2494 temp1 = temp1 - pres_tissue[ci];
2495 temp2 = temp_atem - pres_tissue[ci];
2496 if (temp2 >= 0.0)
2497 {
2498 temp1 = 0;
2499 temp2 = 0;
2500 }
2501 else
2502 temp1 = temp1 / temp2;
2503 if (temp1 > 0.0)
2504 {
2505 temp1 = log(1.0 - temp1);
2506 temp1 = temp1 / -0.6931; // temp1 is the multiples of half times necessary.
2507 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
2508 // minus because log is negative
2509 temp2 = var_halftimes * temp1 / float_desaturation_multiplier; // time necessary (in minutes ) for complete desaturation (see comment about 10 percent) , new in v.101: float_desaturation_multiplier
2510 }
2511 else
2512 {
2513 temp1 = 0;
2514 temp2 = 0;
2515 }
2516
2517 // He
2518 temp3 = 0.1 - pres_tissue[ci+16];
2519 if (temp3 >= 0.0)
2520 {
2521 temp3 = 0;
2522 temp4 = 0;
2523 }
2524 else
2525 temp3 = -1.0 * temp3 / pres_tissue[ci+16];
2526 if (temp3 > 0.0)
2527 {
2528 temp3 = log(1.0 - temp3);
2529 temp3 = temp3 / -0.6931; // temp1 is the multiples of half times necessary.
2530 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
2531 // minus because log is negative
2532 temp4 = var2_halftimes * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier
2533 }
2534 else
2535 {
2536 temp3 = 0;
2537 temp4 = 0;
2538 }
2539
2540 // saturation_time (for flight)
2541 if (temp4 > temp2)
2542 int_temp = (int)temp4;
2543 else
2544 int_temp = (int)temp2;
2545 if(int_temp > int_O_desaturation_time)
2546 int_O_desaturation_time = int_temp;
2547
2548 // N2 saturation in multiples of halftime for display purposes
2549 temp2 = temp1 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8
2550 temp2 = temp2 + 80.0; // set center
2551 if (temp2 < 0.0)
2552 temp2 = 0.0;
2553 if (temp2 > 255.0)
2554 temp2 = 255.0;
2555 char_O_tissue_saturation[ci] = (char)temp2;
2556 // He saturation in multiples of halftime for display purposes
2557 temp4 = temp3 * 20.0; // 0 = 1/8, 120 = 0, 249 = 8
2558 temp4 = temp4 + 80.0; // set center
2559 if (temp4 < 0.0)
2560 temp4 = 0.0;
2561 if (temp4 > 255.0)
2562 temp4 = 255.0;
2563 char_O_tissue_saturation[ci+16] = (char)temp4;
2564 } // for
2565 } // calc_desaturation_time
2566
2567
2568 // --------------------------
2569 // calc_wo_deco_step_1_min //
2570 // --------------------------
2571 // FIXED N2 Ratio
2572 // optimized in v.101 (...saturation_multiplier)
2573 // desaturation slowed down to 70,42%
2574
2575 void calc_wo_deco_step_1_min(void)
2576 {
2577 if(flag_in_divemode)
2578 {
2579 flag_in_divemode = 0;
2580 set_dbg_end_of_dive();
2581 }
2582 _asm
2583 lfsr 1, 0x300
2584 _endasm
2585 N2_ratio = 0.7902; // FIXED, sum lt. buehlmann
2586 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system
2587 pres_surface = (float)int_I_pres_surface / 1000.0;
2588 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body
2589 temp2_atem = 0.0;
2590 temp_surface = pres_surface; // the b"uhlmann formula using temp_surface does not use the N2_ratio
2591 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142)
2592 float_saturation_multiplier = char_I_saturation_multiplier / 100.0;
2593
2594 calc_tissue_step_1_min(); // update the pressure in the 16 tissues in accordance with the new ambient pressure
2595 clear_decoarray();
2596 char_O_deco_status = 0;
2597 char_O_nullzeit = 0;
2598 char_O_ascenttime = 0;
2599 calc_gradient_factor();
2600
2601 } // calc_wo_deco_step_1_min(void)
2602
2603
2604 // -------------------------
2605 // calc_tissue_step_1_min //
2606 // -------------------------
2607 // optimized in v.101
2608
2609 void calc_tissue_step_1_min(void)
2610 {
2611 _asm
2612 lfsr 1, 0x300
2613 movlw 0x01
2614 movwf TBLPTRU,0
2615 _endasm
2616
2617 char_O_gtissue_no = 255;
2618 pres_gtissue_limit = 0.0;
2619
2620 for (ci=0;ci<16;ci++)
2621 {
2622 _asm
2623 movlw 0x02
2624 movwf TBLPTRH,0
2625 movlb 4 // fuer ci
2626 movf ci,0,1
2627 addwf ci,0,1
2628 addwf ci,0,1
2629 addwf ci,0,1
2630 addlw 0x80
2631 movwf TBLPTRL,0
2632 TBLRDPOSTINC
2633 movff TABLAT,var_a+1
2634 TBLRDPOSTINC
2635 movff TABLAT,var_a
2636 TBLRDPOSTINC
2637 movff TABLAT,var_a+3
2638 TBLRD
2639 movff TABLAT,var_a+2
2640 addlw 0x40
2641 movwf TBLPTRL,0
2642 TBLRDPOSTINC
2643 movff TABLAT,var2_a+1
2644 TBLRDPOSTINC
2645 movff TABLAT,var2_a
2646 TBLRDPOSTINC
2647 movff TABLAT,var2_a+3
2648 TBLRD
2649 movff TABLAT,var2_a+2
2650 addlw 0x40
2651 movwf TBLPTRL,0
2652 incf TBLPTRH,1,0
2653 TBLRDPOSTINC
2654 movff TABLAT,var_b+1
2655 TBLRDPOSTINC
2656 movff TABLAT,var_b
2657 TBLRDPOSTINC
2658 movff TABLAT,var_b+3
2659 TBLRD
2660 movff TABLAT,var_b+2
2661 addlw 0x40
2662 movwf TBLPTRL,0
2663 TBLRDPOSTINC
2664 movff TABLAT,var2_b+1
2665 TBLRDPOSTINC
2666 movff TABLAT,var2_b
2667 TBLRDPOSTINC
2668 movff TABLAT,var2_b+3
2669 TBLRD
2670 movff TABLAT,var2_b+2
2671 addlw 0xC0
2672 movwf TBLPTRL,0
2673 incf TBLPTRH,1,0
2674 TBLRDPOSTINC
2675 movff TABLAT,var_e1min+1
2676 TBLRDPOSTINC
2677 movff TABLAT,var_e1min
2678 TBLRDPOSTINC
2679 movff TABLAT,var_e1min+3
2680 TBLRD
2681 movff TABLAT,var_e1min+2
2682 addlw 0x40
2683 movwf TBLPTRL,0
2684 TBLRDPOSTINC
2685 movff TABLAT,var2_e1min+1
2686 TBLRDPOSTINC
2687 movff TABLAT,var2_e1min
2688 TBLRDPOSTINC
2689 movff TABLAT,var2_e1min+3
2690 TBLRD
2691 movff TABLAT,var2_e1min+2
2692 _endasm
2693
2694 // N2 1 min
2695 temp_tissue = (temp_atem - pres_tissue[ci]) * var_e1min;
2696 temp_tissue_safety();
2697 pres_tissue[ci] = pres_tissue[ci] + temp_tissue;
2698
2699 // He 1 min
2700 temp_tissue = (temp2_atem - pres_tissue[ci+16]) * var2_e1min;
2701 temp_tissue_safety();
2702 pres_tissue[ci+16] = pres_tissue[ci+16] + temp_tissue;
2703
2704 temp_tissue = pres_tissue[ci] + pres_tissue[ci+16];
2705 var_a = (var_a * pres_tissue[ci] + var2_a * pres_tissue[ci+16]) / temp_tissue;
2706 var_b = (var_b * pres_tissue[ci] + var2_b * pres_tissue[ci+16]) / temp_tissue;
2707 pres_tissue_limit[ci] = (temp_tissue - var_a) * var_b;
2708 if (pres_tissue_limit[ci] < 0)
2709 pres_tissue_limit[ci] = 0;
2710 if (pres_tissue_limit[ci] > pres_gtissue_limit)
2711 {
2712 pres_gtissue_limit = pres_tissue_limit[ci];
2713 char_O_gtissue_no = ci;
2714 }//if
2715
2716 // gradient factor array for graphical display
2717 // display range is 0 to 250! in steps of 5 for 1 pixel
2718 // the display is divided in 6 blocks
2719 // -> double the gradient 100% = 200
2720 // tissue > respiration (entsaettigungsvorgang)
2721 // gradient ist wieviel prozent an limit von tissue aus
2722 // dh. 0% = respiration == tissue
2723 // dh. 100% = respiration == limit
2724 temp1 = temp_tissue - pres_respiration;
2725 temp2 = temp_tissue - pres_tissue_limit[ci]; // changed in v.102
2726 temp2 = temp1/temp2;
2727 temp2 = temp2 * 200; // because of output in (Double-)percentage
2728 if (temp2 < 0)
2729 temp2 = 0;
2730 if (temp2 > 255)
2731 temp2 = 255;
2732 if (temp1 < 0)
2733 char_O_array_gradient_weighted[ci] = 0;
2734 else
2735 char_O_array_gradient_weighted[ci] = (char)temp2;
2736
2737 } // for
2738 } // calc wo deco 1min
2739
2740 #if 0
2741 // --------
2742 // debug //
2743 // --------
2744 void debug(void)
2745 {
2746 for (ci=0;ci<32;ci++)
2747 {
2748 int_O_tissue_for_debug[ci] = (unsigned int)(pres_tissue[ci] *1000);
2749 }
2750 } // void debug(void)
2751 #endif
2752
2753 // ----------
2754 // md hash //
2755 // ----------
2756 void hash(void)
2757 {
2758 // init
2759 for (md_i=0;md_i<16;md_i++)
2760 {
2761 md_state[md_i] = 0;
2762 md_cksum[md_i] = 0;
2763 } // for md_i 16
2764
2765 _asm
2766 movlw 0x01
2767 movwf TBLPTRU,0
2768 movlw 0x06
2769 movwf TBLPTRH,0
2770 movlw 0x00
2771 movwf TBLPTRL,0
2772 _endasm
2773 for (md_i=0;md_i<127;md_i++)
2774 {
2775 _asm
2776 TBLRDPOSTINC
2777 movff TABLAT,md_temp
2778 _endasm
2779 md_pi_subst[md_i] = md_temp;
2780 } // for md_i 256
2781 _asm
2782 TBLRDPOSTINC
2783 movff TABLAT,md_temp
2784 _endasm
2785 md_pi_subst[127] = md_temp;
2786 for (md_i=0;md_i<127;md_i++)
2787 {
2788 _asm
2789 TBLRDPOSTINC
2790 movff TABLAT,md_temp
2791 _endasm
2792 md_pi_subst[md_i+128] = md_temp;
2793 } // for md_i 256
2794 _asm
2795 TBLRD
2796 movff TABLAT,md_temp
2797 _endasm
2798 md_pi_subst[255] = md_temp;
2799
2800 _asm
2801 movlw 0x00
2802 movwf TBLPTRU,0
2803 movlw 0x00
2804 movwf TBLPTRH,0
2805 movlw 0x00
2806 movwf TBLPTRL,0
2807 _endasm
2808 // cycle buffers
2809 for (md_pointer=0x0000;md_pointer<0x17f3;md_pointer++)
2810 {
2811 md_t = 0;
2812 for (md_i=0;md_i<16;md_i++)
2813 {
2814 if(md_pointer == 9)
2815 md_temp = md_cksum[md_i];
2816 else
2817 {
2818 _asm
2819 TBLRDPOSTINC
2820 movff TABLAT,md_temp
2821 _endasm
2822 } // else
2823 md_buffer[md_i] = md_temp;
2824 md_state[md_i+16] = md_buffer[md_i];
2825 md_state[md_i+32] = (unsigned char)(md_buffer[md_i] ^ md_state[md_i]);
2826 } // for md_i 16
2827
2828 for (md_i=0;md_i<18;md_i++)
2829 {
2830 for (md_j=0;md_j<48;md_j++)
2831 {
2832 md_state[md_j] = (unsigned char)(md_state[md_j] ^ md_pi_subst[md_t]);
2833 md_t = md_state[md_j];
2834 } // for md_j 48
2835 md_t = (unsigned char)(md_t+1);
2836 } // for md_i 18
2837 md_t = md_cksum[15];
2838
2839 for (md_i=0;md_i<16;md_i++)
2840 {
2841 md_cksum[md_i] = (unsigned char)(md_cksum[md_i] ^ md_pi_subst[(md_buffer[md_i] ^ md_t)]);
2842 md_t = md_cksum[md_i];
2843 } // for md_i 16
2844 } // for md_pointer
2845 } // void hash(void)
2846
2847 // ---------------------
2848 // clear_CNS_fraction //
2849 // ---------------------
2850 // new in v.101
2851
2852 void clear_CNS_fraction(void)
2853 {
2854 CNS_fraction = 0.0;
2855 char_O_CNS_fraction = 0;
2856 } // void clear_CNS_fraction(void)
2857
2858
2859 // --------------------
2860 // calc_CNS_fraction //
2861 // --------------------
2862 // new in v.101
2863 // optimized in v.102 : with new variables char_I_actual_ppO2 and actual_ppO2
2864
2865 // Input: char_I_actual_ppO2
2866 // Output: char_O_CNS_fraction
2867 // Uses and Updates: CNS_fraction
2868 // Uses: acutal_ppO2
2869
2870 void calc_CNS_fraction(void)
2871 {
2872 actual_ppO2 = (float)char_I_actual_ppO2 / 100.0;
2873
2874 if (char_I_actual_ppO2 < 50)
2875 CNS_fraction = CNS_fraction;// no changes
2876 else if (char_I_actual_ppO2 < 60)
2877 CNS_fraction = 1/(-54000.0 * actual_ppO2 + 54000.0) + CNS_fraction;
2878 else if (char_I_actual_ppO2 < 70)
2879 CNS_fraction = 1/(-45000.0 * actual_ppO2 + 48600.0) + CNS_fraction;
2880 else if (char_I_actual_ppO2 < 80)
2881 CNS_fraction = 1/(-36000.0 * actual_ppO2 + 42300.0) + CNS_fraction;
2882 else if (char_I_actual_ppO2 < 90)
2883 CNS_fraction = 1/(-27000.0 * actual_ppO2 + 35100.0) + CNS_fraction;
2884 else if (char_I_actual_ppO2 < 110)
2885 CNS_fraction = 1/(-18000.0 * actual_ppO2 + 27000.0) + CNS_fraction;
2886 else if (char_I_actual_ppO2 < 150)
2887 CNS_fraction = 1/(-9000.0 * actual_ppO2 + 17100.0) + CNS_fraction;
2888 else if (char_I_actual_ppO2 < 160)
2889 CNS_fraction = 1/(-22500.0 * actual_ppO2 + 37350.0) + CNS_fraction;
2890 else if (char_I_actual_ppO2 < 165)
2891 CNS_fraction = 0.000755 + CNS_fraction; // Arieli et all.(2002): Modeling pulmonary and CNS O2 toxicity... Formula (A1) based on value for 1.55 and c=20
2892 else if (char_I_actual_ppO2 < 170)
2893 CNS_fraction = 0.00102 + CNS_fraction; // example calculation: Sqrt((1.7/1.55)^20)*0.000404
2894 else if (char_I_actual_ppO2 < 175)
2895 CNS_fraction = 0.00136 + CNS_fraction;
2896 else if (char_I_actual_ppO2 < 180)
2897 CNS_fraction = 0.00180 + CNS_fraction;
2898 else if (char_I_actual_ppO2 < 185)
2899 CNS_fraction = 0.00237 + CNS_fraction;
2900 else if (char_I_actual_ppO2 < 190)
2901 CNS_fraction = 0.00310 + CNS_fraction;
2902 else if (char_I_actual_ppO2 < 195)
2903 CNS_fraction = 0.00401 + CNS_fraction;
2904 else if (char_I_actual_ppO2 < 200)
2905 CNS_fraction = 0.00517 + CNS_fraction;
2906 else if (char_I_actual_ppO2 < 230)
2907 CNS_fraction = 0.0209 + CNS_fraction;
2908 else
2909 CNS_fraction = 0.0482 + CNS_fraction; // value for 2.5
2910
2911 if (CNS_fraction > 2.5)
2912 CNS_fraction = 2.5;
2913 if (CNS_fraction < 0.0)
2914 CNS_fraction = 0.0;
2915 char_O_CNS_fraction = (char)((CNS_fraction + 0.005)* 100.0);
2916 } // void calc_CNS_fraction(void)
2917
2918 // --------------------------
2919 // calc_CNS_decrease_15min //
2920 // --------------------------
2921 // new in v.101
2922
2923 // calculates the half time of 90 minutes in 6 steps of 15 min
2924
2925 // Output: char_O_CNS_fraction
2926 // Uses and Updates: CNS_fraction
2927
2928 void calc_CNS_decrease_15min(void)
2929 {
2930 CNS_fraction = 0.890899 * CNS_fraction;
2931 char_O_CNS_fraction = (char)((CNS_fraction + 0.005)* 100.0);
2932 }// calc_CNS_decrease_15min(void)
2933
2934
2935 // ------------------
2936 // calc_percentage //
2937 // ------------------
2938 // new in v.101
2939
2940 // calculates int_I_temp * char_I_temp / 100
2941 // output is int_I_temp
2942
2943 void calc_percentage(void)
2944 {
2945 temp1 = (float)int_I_temp;
2946 temp2 = (float)char_I_temp / 100.0;
2947 temp3 = temp1 * temp2;
2948 int_I_temp = (int)temp3;
2949 }
2950 void push_tissues_to_vault(void)
2951 {
2952 for (ci=0;ci<32;ci++)
2953 pres_tissue_vault[ci] = pres_tissue[ci];
2954 }
2955 void pull_tissues_from_vault(void)
2956 {
2957 for (ci=0;ci<32;ci++)
2958 pres_tissue[ci] = pres_tissue_vault[ci];
2959 }
2960
2961 void wp_write_command(void)
2962 {
2963 _asm
2964 bcf oled_rs
2965 movff wp_command,PORTD
2966 bcf oled_rw
2967 bsf oled_rw
2968 _endasm
2969 }
2970
2971 void wp_write_data(void)
2972 {
2973 wp_data_8bit_one = wp_data_16bit >> 8;
2974 wp_data_8bit_two = wp_data_16bit;
2975 _asm
2976 bsf oled_rs
2977 movff wp_data_8bit_one,PORTD
2978 bcf oled_rw
2979 bsf oled_rw
2980 movff wp_data_8bit_two,PORTD
2981 bcf oled_rw
2982 bsf oled_rw
2983 _endasm
2984 }
2985
2986 void wp_write_black(void)
2987 {
2988 _asm
2989 movff wp_black,PORTD
2990 bcf oled_rw
2991 bsf oled_rw
2992 bcf oled_rw
2993 bsf oled_rw
2994 _endasm
2995 }
2996
2997 void wp_write_color(void)
2998 {
2999 _asm
3000 movff wp_color1,PORTD
3001 bcf oled_rw
3002 bsf oled_rw
3003 movff wp_color2,PORTD
3004 bcf oled_rw
3005 bsf oled_rw
3006 _endasm
3007 }
3008
3009 void wp_set_window(void)
3010 {
3011 // x axis start ( 0 - 319)
3012 wp_command = 0x35;
3013 wp_write_command();
3014 wp_data_16bit = ((U16)wp_leftx2) << 1;
3015 wp_write_data();
3016 // x axis end ( 0 - 319)
3017 wp_command = 0x36;
3018 wp_write_command();
3019 wp_data_16bit = 319;
3020 wp_write_data();
3021 // y axis start + end ( 0 - 239 )
3022 wp_command = 0x37;
3023 wp_write_command();
3024 // the bottom part
3025 wp_data_16bit = wp_top;
3026 if(wp_font == 2)
3027 wp_data_16bit += WP_FONT_LARGE_HEIGHT;
3028 else if(wp_font == 1)
3029 wp_data_16bit += WP_FONT_MEDIUM_HEIGHT;
3030 else
3031 wp_data_16bit += WP_FONT_SMALL_HEIGHT;
3032 wp_data_16bit--;
3033 if(wp_data_16bit > 239)
3034 wp_data_16bit = 239;
3035 // the top part
3036 wp_data_16bit |= ((U16)wp_top) << 8;
3037 // all together in one 16bit transfer
3038 wp_write_data();
3039
3040 // start
3041 wp_command = 0x20;
3042 wp_write_command();
3043 wp_data_16bit = wp_top;
3044 wp_write_data();
3045
3046 wp_command = 0x21;
3047 wp_write_command();
3048 wp_data_16bit = ((U16)wp_leftx2) << 1;
3049 wp_write_data();
3050 }
3051
3052 void wp_set_char_font_small(void)
3053 {
3054 // space is A1
3055 if (wp_char > 0x7E) // skip space between ~ and ¡
3056 wp_char -= 34;
3057
3058 if (wp_char == ' ')
3059 wp_char = 0xA1;
3060
3061 if((wp_char < '!') || (wp_char > 0xA1)) // font has 34 chars after ~ // ¾ + 4 chars limit to end of battery at the moment
3062 wp_char = 0x82; // ¤
3063
3064 wp_start = wp_small_table[wp_char - '!'];
3065 wp_end = wp_small_table[1 + wp_char - '!'];
3066 }
3067
3068 void wp_set_char_font_medium(void)
3069 {
3070 // space is 3E
3071 if (wp_char == 0x27) // 0x27 == '
3072 wp_char = 0x3B;
3073 if (wp_char == '"')
3074 wp_char = 0x3C;
3075 if (wp_char == 'm')
3076 wp_char = 0x3D;
3077 if (wp_char == ' ')
3078 wp_char = 0x3E;
3079
3080 if((wp_char < '.') || (wp_char > 0x3E))
3081 wp_char = 0x3E;
3082 wp_start = wp_medium_table[wp_char - '.'];
3083 wp_end = wp_medium_table[1 + wp_char - '.'];
3084 }
3085
3086 void wp_set_char_font_large(void)
3087 {
3088 // space is / = 0x2F
3089 if (wp_char == ' ')
3090 wp_char = 0x2F;
3091
3092 if((wp_char < '.') || (wp_char > '9'))
3093 wp_char = 0x2F;
3094 wp_start = wp_large_table[wp_char - '.'];
3095 wp_end = wp_large_table[1 + wp_char - '.'];
3096 }
3097
3098 void wordprocessor(void)
3099 {
3100 wp_set_window();
3101
3102 // access to GRAM
3103 wp_command = 0x22;
3104 wp_write_command();
3105 _asm
3106 bsf oled_rs
3107 _endasm
3108
3109 wp_txtptr = 0;
3110 wp_char = wp_stringstore[wp_txtptr];
3111
3112 while(wp_char)
3113 {
3114 if(wp_font == 2)
3115 wp_set_char_font_large();
3116 else if(wp_font == 1)
3117 wp_set_char_font_medium();
3118 else
3119 wp_set_char_font_small();
3120
3121 wp_black = 0;
3122
3123 for(wp_i = wp_start; wp_i<wp_end;wp_i++)
3124 {
3125 if(wp_font == 2)
3126 wp_data_16bit = wp_large_data[wp_i / 2];
3127 else if(wp_font == 1)
3128 wp_data_16bit = wp_medium_data[wp_i / 2];
3129 else
3130 wp_data_16bit = wp_small_data[wp_i / 2];
3131 if(wp_i & 1)
3132 wp_temp_U8 = wp_data_16bit & 0xFF;
3133 else
3134 wp_temp_U8 = wp_data_16bit >> 8;
3135 if((wp_temp_U8 & 128))
3136 {
3137 wp_temp_U8 -= 127;
3138 if(wp_invert)
3139 {
3140 while(wp_temp_U8 > 0)
3141 {
3142 wp_temp_U8--;
3143 wp_write_color();
3144 }
3145 }
3146 else
3147 {
3148 _asm
3149 movff wp_black,PORTD
3150 _endasm
3151 while(wp_temp_U8 > 0)
3152 {
3153 wp_temp_U8--;
3154 _asm
3155 bcf oled_rw
3156 bsf oled_rw
3157 bcf oled_rw
3158 bsf oled_rw
3159 _endasm
3160 }
3161 }
3162 }
3163 else
3164 {
3165 wp_temp_U8++;
3166 if(wp_invert)
3167 {
3168 _asm
3169 movff wp_black,PORTD
3170 _endasm
3171 while(wp_temp_U8 > 0)
3172 {
3173 wp_temp_U8--;
3174 _asm
3175 bcf oled_rw
3176 bsf oled_rw
3177 bcf oled_rw
3178 bsf oled_rw
3179 _endasm
3180 }
3181 }
3182 else
3183 {
3184 while(wp_temp_U8 > 0)
3185 {
3186 wp_temp_U8--;
3187 wp_write_color();
3188 }
3189 }
3190 }
3191 }
3192 wp_txtptr++;
3193 wp_char = wp_stringstore[wp_txtptr];
3194 }
3195 wp_command = 0x00;
3196 wp_write_command();
3197 wp_top = 0;
3198 wp_leftx2 = 0;
3199 wp_font = 0;
3200 wp_invert = 0;
3201 }
3202