Mercurial > public > mk2
diff code_part1/OSTC_code_asm_part1/divemode.asm @ 0:96a35aeda5f2
Initial setup
author | heinrichsweikamp |
---|---|
date | Tue, 12 Jan 2010 15:05:59 +0100 |
parents | |
children | d11ef8dc4b2c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/code_part1/OSTC_code_asm_part1/divemode.asm Tue Jan 12 15:05:59 2010 +0100 @@ -0,0 +1,1544 @@ + +; OSTC - diving computer code +; Copyright (C) 2008 HeinrichsWeikamp GbR + +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. + +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +; You should have received a copy of the GNU General Public License +; along with this program. If not, see <http://www.gnu.org/licenses/>. + + +; Mainroutines for divemode +; written by: Matthias Heinrichs, info@heinrichsweikamp.com +; written: 10/01/05 +; last updated: 15/05/08 +; known bugs: +; ToDo: + +diveloop: + call diveloop_boot ; Boot tasks for all modes + +; Startup Tasks for all modes + ostc_debug 'R' ; Sends debug-information to screen if debugmode active + call PLED_ClearScreen ; clean up OLED + call PLED_divemode_mask ; Display mask + call PLED_active_gas_divemode ; Display gas, if required + call PLED_temp_divemode ; Displays temperature + + btfsc FLAG_apnoe_mode + bsf realdive ; Set Realdive flag in Apnoe mode + + btfsc gauge_mode + bra diveloop_loop ; Skip in gauge mode + btfsc FLAG_apnoe_mode + bra diveloop_loop ; Skip in apnoe mode + +; Startup Tasks for deco modes + call PLED_display_ndl_mask ; display "no stop" if not in gauge or apnoe mode + +diveloop_loop: ; The diveloop starts here + btfss onesecupdate ; tasks any new second + bra diveloop_loop2 + + btfsc gauge_mode ; Only in gauge mode + bra diveloop_loop1a ; One Second Tasks in Gauge mode + btfsc FLAG_apnoe_mode ; Only in apnoe mode + bra diveloop_loop1b ; One Second Tasks in Apnoe mode + btfsc FLAG_const_ppO2_mode ; only in const_ppO2_mode + bra diveloop_loop1c ; One Second Tasks in const_ppO2 mode + +; Tasks only for OC modes + call check_ppO2 ; check ppO2 and displays warning if required + call calc_deko_divemode ; calculate decompression and display result (any two seconds) + bra diveloop_loop1x ; Common Tasks + +; Tasks only for Gauge mode +diveloop_loop1a: + btfss premenu ; Is the divemode menu active? + call PLED_divemins ; display (new) divetime! + call timeout_divemode ; dive finished? This routine sets the required flags + + btfsc stopwatch_active ; =1: Show Average Depth instead of Temperature + call PLED_stopwatch_show ; Show stopwatch only in Average mode + + btfsc twosecupdate ; two seconds after the last call + bra diveloop_loop1a2 ; Common Tasks + + bsf twosecupdate ; Routines used in the "other second" + call calc_average_depth ; calculate average depth + + bra diveloop_loop1x ; Common Tasks + +diveloop_loop1a2: + bcf twosecupdate + bra diveloop_loop1x ; Common Tasks + +; Tasks only for Apnoe mode +diveloop_loop1b: + call divemode_apnoe_tasks ; 1 sec. Apnoe tasks + bra diveloop_loop1x ; Common Tasks + +; Tasks only for ppO2 mode +diveloop_loop1c: + call PLED_const_ppO2_value ; display const ppO2 setting in [Bar] + call calc_deko_divemode ; calculate decompression and display result (any two seconds) + bra diveloop_loop1x ; Common Tasks + +; Common Tasks for all modes +diveloop_loop1x: + call timeout_divemode ; dive finished? This routine sets the required flags + btfsc low_battery_state ; If battery is low, then... + call update_batt_voltage_divemode ; Display Battery Symbol/Voltage! + btfsc premenu ; is Menu? displayed? + call timeout_premenu_divemode ; No, so check for timeout premenu + btfsc menubit ; is the Dive mode menu displayed? + call timeout_divemenu ; Yes, so check for timeout divemenu + call set_leds_divemode ; Sets warnings, if required. Also Sets buzzer + btfsc enter_error_sleep ; Enter Fatal Error Routine? + goto fatal_error_sleep ; Yes (In Sleepmode_vxx.asm!) + + btfsc stopwatch_active ; =1: Show Average Depth instead of Temperature + call PLED_stopwatch_show ; Show stopwatch only in Average mode + + bcf onesecupdate ; one seconds update done + + GETCUSTOM8 d'38' ; Show seconds (=1?) + movwf lo + movlw d'1' + cpfseq lo ; =1? + bra diveloop_loop2 ; No, minutes only + bsf update_divetime ; Set Update flag + + +diveloop_loop2: + btfss update_divetime ; display new divetime? + bra diveloop_loop3 ; No + btfsc premenu ; Is the divemode menu active? + bra diveloop_loop2a ; Yes + call PLED_divemins ; Display (new) divetime! + btfsc FLAG_const_ppO2_mode ; only in const_ppO2_mode + call PLED_const_ppO2_value ; display const ppO2 setting in [Bar] + btfsc ppO2_show_value ; show ppO2? + call check_ppO2 ; check ppO2 and displays warning if required + +diveloop_loop2a: + bcf update_divetime ; clear flag + + +diveloop_loop3: + btfss menubit ; Divemode menu active? + call test_switches_divemode ; No, Check switches normal + + btfsc menubit ; Divemode menu active? + call test_switches_divemode_menu ; Yes, check switches divemode menu + + btfss divemode ; Dive finished? + bra end_dive ; Dive finished! + + btfsc pressure_refresh ; new pressure available? + call update_divemode1 ; Yes, display new depth + bcf pressure_refresh ; until new pressure is available + + btfsc oneminupdate ; one minute tasks + call update_divemode60 ; Update clock, etc. + + btfsc store_sample ; store new sample? + call store_dive_data ; Store profile data + + btfss menubit ; Sleep only with inactive menu... + sleep + + nop + bra diveloop_loop ; Loop the divemode + +timeout_premenu_divemode: + incf timeout_counter3,F ; Yes... + + GETCUSTOM8 d'4' ; loads premenu_timeout into WREG + cpfsgt timeout_counter3 ; ... longer then premenu_timeout + return ; No! + + bcf premenu ; Yes, so clear "Menu?" and clear pre_menu bit + call PLED_menu_clear ; Remove "Menu?" + return + +divemode_apnoe_tasks: ; 1 sec. Apnoe tasks + call PLED_display_apnoe_descent ; Show descent timer + + btfsc divemode2 ; Time running? + bra divemode_apnoe_tasks2 ; New descent, reset data if flag is set + + call PLED_display_apnoe_surface + incf apnoe_surface_secs,F + movlw d'60' + cpfseq apnoe_surface_secs + bra divemode_apnoe_tasks1 + clrf apnoe_surface_secs + incf apnoe_surface_mins,F + +divemode_apnoe_tasks1: + bcf FLAG_active_descent ; Clear flag + btfsc divemode2 ; Time running? + return ; Yes, return + + bsf FLAG_active_descent ; Set Flag + return + +divemode_apnoe_tasks2: + btfss FLAG_active_descent ; Are descending? + return ; No, We are at the surface + rcall apnoe_calc_maxdepth ; Yes! + +divemode_apnoe_tasks3: + call PLED_apnoe_clear_surface ; Clear Surface timer + + clrf apnoe_timeout_counter ; Delete timeout + clrf apnoe_surface_secs + clrf apnoe_surface_mins + clrf apnoe_secs + clrf apnoe_mins ; Reset Descent time + clrf max_pressure+0 + clrf max_pressure+1 ; Reset Max. Depth + bcf FLAG_active_descent ; Clear flag + return + +apnoe_calc_maxdepth: + movff apnoe_max_pressure+0,sub_a+0 + movff apnoe_max_pressure+1,sub_a+1 + movff max_pressure+0,sub_b+0 + movff max_pressure+1,sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + ; apnoe_max_pressure<max_pressure -> neg_flag=1 + ; max_pressure<=apnoe_max_pressure -> neg_flag=0 + btfss neg_flag + return + ;apnoe_max_pressure<max_pressure + movff max_pressure+0,apnoe_max_pressure+0 + movff max_pressure+1,apnoe_max_pressure+1 + return + +set_leds_divemode: + call clear_LEDy ; LEDy OFF + movff char_O_gradient_factor,lo ; gradient factor absolute + + GETCUSTOM8 d'14' ; threshold for LED warning + cpfslt lo ; + call warn_gf1 ; show warning, set flags + + btfsc ppO2_warn_value ; warn because of too high ppO2? + call set_LEDy ; Yes + + movff char_I_deco_model,lo + decfsz lo,W ; jump over return if char_I_deco_model == 1 + return + + movff char_O_relative_gradient_GF,lo ; gradient factor relative (GF model) + + GETCUSTOM8 d'14' ; threshold for LED warning + cpfslt lo ; + call warn_gf1 ; show warning, set flags + + btfsc ppO2_warn_value ; warn because of too high ppO2? + call set_LEDy ; Yes + + return + +warn_gf1: + call set_LEDy ; LED Yellow on + movlw d'2' ; Type of Alarm + movwf AlarmType ; Copy to Alarm Register + bsf event_occured ; Set Event Flag + return + +calc_deko_divemode: + btfsc twosecupdate ; two seconds after the last call + bra calc_deko_divemode2 ; Yes, calculate and display deco data ("first second") + + ; Routines used in the "other second" + + bsf twosecupdate ; No, but next second! + call calc_average_depth ; calculate average depth + call calc_velocity ; calculate vertical velocity and display if > threshold (every two seconds) + + ; calculate ppO2 in 0.1Bar (e.g. 150 = 1.50Bar ppO2) + movff amb_pressure+0,xA+0 + movff amb_pressure+1,xA+1 + movlw LOW d'10' + movwf xB+0 + movlw HIGH d'10' + clrf xB+1 + call div16x16 ; xC=p_amb/10 + movff xC+0,xA+0 + movff xC+1,xA+1 + movff char_I_O2_ratio,xB+0 + clrf xB+1 + call mult16x16 ; char_I_O2_ratio * p_amb/10 + movff xC+0,xA+0 + movff xC+1,xA+1 + movlw LOW d'100' + movwf xB+0 + movlw HIGH d'100' + clrf xB+1 + call div16x16 ; xC=(char_I_O2_ratio * p_amb/10)/100 + +; Copy ppO2 for CNS calculation + movff xC+0, char_I_actual_ppO2 ; copy last ppO2 to buffer register + btfsc FLAG_const_ppO2_mode ; do in const_ppO2_mode + movff char_I_const_ppO2, char_I_actual_ppO2 ; copy last ppO2 to buffer register + +; Calculate CNS + call main_calc_CNS_fraction ; calculate CNS + movlb b'00000001' ; rambank 1 selected + +; Check if CNS should be displayed + movff char_O_CNS_fraction,lo ; copy into bank1 + GETCUSTOM8 d'27' ; cns_display_high + subwf lo,W + btfsc STATUS,C + call PLED_display_cns ; Show CNS + +; Check for decompression gases if in decomode +divemode_check_decogases: ; CALLed from Simulator + btfss dekostop_active + bra reset_decompression_gases ; While in NDL, do not set deompression gas +; 1. Find active gas with deepest change depth < current depth +; 2. Set Decogas + + movff rel_pressure+0,xA+0 + movff rel_pressure+1,xA+1 + movlw d'100' + movwf xB+0 + clrf xB+1 + call div16x16 ; compute depth in full m -> result in xC+0 + clrf lo ; clear depth for comparison + +; check gas1 + read_int_eeprom d'27' ; read flag register + btfss EEDATA,0 ; check active flag + bra check_decogas2 ; skip inactive gases! + read_int_eeprom d'28' ; read gas_change_depth + movf xC+0,W ; load depth in m into WREG + cpfslt EEDATA ; gas_change_depth > current depth? + bra check_decogas2 ; W < EEDATA -> current depth lower then gas_change_depth + + movff EEDATA,lo ; deepest gas_change_depth in lo + movlw d'1' + movwf hi ; Decogas # in hi (1-5) + +check_decogas2: + read_int_eeprom d'27' ; read flag register + btfss EEDATA,1 ; check active flag + bra check_decogas3 ; skip inactive gases! + read_int_eeprom d'29' ; read gas_change_depth + movf xC+0,W ; load depth in m into WREG + cpfslt EEDATA ; gas_change_depth > current depth? + bra check_decogas3 ; W < EEDATA -> current depth lower then gas_change_depth + + read_int_eeprom d'29' ; read gas_change_depth + movf lo,W ; load current gas_change_depth into WREG + cpfsgt EEDATA ; last gas_change_depth > current gas_change_depth ? + bra check_decogas3 ; W < lo -> last gas_change_depth > current gas_change_depth + movff EEDATA,lo ; deepest gas_change_depth in lo + movlw d'2' + movwf hi ; Decogas # in hi (1-5) + +check_decogas3: + read_int_eeprom d'27' ; read flag register + btfss EEDATA,2 ; check active flag + bra check_decogas4 ; skip inactive gases! + read_int_eeprom d'30' ; read gas_change_depth + movf xC+0,W ; load depth in m into WREG + cpfslt EEDATA ; gas_change_depth > current depth? + bra check_decogas4 ; W < EEDATA -> current depth lower then gas_change_depth + + read_int_eeprom d'30' ; read gas_change_depth + movf lo,W ; load current gas_change_depth into WREG + cpfsgt EEDATA ; last gas_change_depth > current gas_change_depth ? + bra check_decogas4 ; W < lo -> last gas_change_depth > current gas_change_depth + movff EEDATA,lo ; deepest gas_change_depth in lo + movlw d'3' + movwf hi ; Decogas # in hi (1-5) + +check_decogas4: + read_int_eeprom d'27' ; read flag register + btfss EEDATA,3 ; check active flag + bra check_decogas5 ; skip inactive gases! + read_int_eeprom d'31' ; read gas_change_depth + movf xC+0,W ; load depth in m into WREG + cpfslt EEDATA ; gas_change_depth > current depth? + bra check_decogas5 ; W < EEDATA -> current depth lower then gas_change_depth + + read_int_eeprom d'31' ; read gas_change_depth + movf lo,W ; load current gas_change_depth into WREG + cpfsgt EEDATA ; last gas_change_depth > current gas_change_depth ? + bra check_decogas5 ; W < lo -> last gas_change_depth > current gas_change_depth + movff EEDATA,lo ; deepest gas_change_depth in lo + movlw d'4' + movwf hi ; Decogas # in hi (1-5) + +check_decogas5: + read_int_eeprom d'27' ; read flag register + btfss EEDATA,4 ; check active flag + bra check_decogas_done ; skip inactive gases! + read_int_eeprom d'32' ; read gas_change_depth + movf xC+0,W ; load depth in m into WREG + cpfslt EEDATA ; gas_change_depth > current depth? + bra check_decogas_done ; W < EEDATA -> current depth lower then gas_change_depth + + read_int_eeprom d'32' ; read gas_change_depth + movf lo,W ; load current gas_change_depth into WREG + cpfsgt EEDATA ; last gas_change_depth > current gas_change_depth ? + bra check_decogas_done ; W < lo -> last gas_change_depth > current gas_change_depth + movff EEDATA,lo ; deepest gas_change_depth in lo + movlw d'5' + movwf hi ; Decogas # in hi (1-5) + +check_decogas_done: + ostc_debug 'E' ; Sends debug-information to screen if debugmode active + + decf hi,F ; Gas 0-4 + movff lo, char_I_deco_gas_change ; copy change_depth + + movf hi,W ; Gas 0-4 + mullw d'4' + movf PRODL,W + addlw d'7' ; = address for He ratio + movwf EEADR + call read_eeprom ; Read He ratio + movff EEDATA,char_I_deco_He_ratio ; And copy into hold register + + + movf hi,W ; Gas 0-4 + mullw d'4' + movf PRODL,W + addlw d'6' ; = address for O2 ratio + movwf EEADR + call read_eeprom ; Read O2 ratio + + movff char_I_deco_He_ratio, wait_temp ; copy into bank1 register + bsf STATUS,C ; Borrow bit + movlw d'100' ; 100% + subfwb wait_temp,W ; minus He + bsf STATUS,C ; Borrow bit + subfwb EEDATA,F ; minus O2 + movff EEDATA, char_I_deco_N2_ratio ; = N2! + bra skip_decompression_gases + +reset_decompression_gases: ; reset the deco gas while in NDL + ostc_debug 'F' ; Sends debug-information to screen if debugmode active + clrf lo + movff lo, char_I_deco_gas_change ; clear + movff lo, char_I_deco_N2_ratio ; clear + movff lo, char_I_deco_He_ratio ; clear +skip_decompression_gases: +;call PLED_gaschange_DEBUG + return + +calc_deko_divemode2: + bcf twosecupdate + + btfsc gauge_mode ; ignore decompression calculation in gauge mode + return + btfsc FLAG_apnoe_mode ; ignore decompression calculation in apnoe mode + return + + ostc_debug 'B' ; Sends debug-information to screen if debugmode active + call divemode_prepare_flags_for_deco + call deco_main_calc_hauptroutine ; calc_tissue + movlb b'00000001' ; rambank 1 selected + ostc_debug 'C' ; Sends debug-information to screen if debugmode active + + movff char_O_deco_status,deco_status ; + tstfsz deco_status ; deco_status=0 if decompression calculation done + return ; calculation not yet finished! + + movff char_O_array_decodepth+0,wait_temp ; copy ceiling to temp register + tstfsz wait_temp ; Ceiling<0m? + bra calc_deko_divemode3 ; Yes! + + btfsc dekostop_active + call PLED_display_ndl_mask ; Clear deco data, display nostop time + bcf dekostop_active ; clear flag + + clrf decodata+0 ; for profile memory + movff char_O_nullzeit,decodata+1 ; nostop time + + call PLED_display_ndl ; display no deco limit + return + +divemode_prepare_flags_for_deco: + movff amb_pressure+0,int_I_pres_respiration+0 ; lo and copy result to deco routine + movff amb_pressure+1,int_I_pres_respiration+1 ; hi + GETCUSTOM8 d'11' ; Saturation multiplier % + movwf wait_temp + movff wait_temp,char_I_saturation_multiplier + GETCUSTOM8 d'12' ; Desaturation multiplier % + movwf wait_temp + movff wait_temp,char_I_desaturation_multiplier + GETCUSTOM8 d'16' ; Deco distance to decostop in 1/10 meter for simulation + movwf wait_temp + movff wait_temp,char_I_deco_distance + GETCUSTOM8 d'29' ; Depth Last Deco in meter for simulation + movwf wait_temp + movff wait_temp,char_I_depth_last_deco + call restart_set_modes_and_flags ; Sets decomode (char_I_deco_model) and flags (again) + return + +calc_deko_divemode3: + btfss dekostop_active + call PLED_display_deko_mask ; clear nostop time, display decodata + bsf dekostop_active ; Set flag + + movff char_O_array_decodepth+0,decodata+0 ; ceiling + movff char_O_array_decotime,decodata+1 ; length of first stop in minues + + call PLED_display_deko ; display decodata + return + +store_dive_data: ; CF20 seconds gone + bcf store_sample ; update only any CF20 seconds + bsf update_divetime ; update divemins every CF20 seconds + + call clear_LEDg ; LEDg off + + btfsc header_stored ; Header already stored? + bra store_dive_data2 ; Yes, store only profile data + bsf header_stored ; Store header + + movff eeprom_address+0, eeprom_header_address+0 ; store startposition + movff eeprom_address+1, eeprom_header_address+1 ; store startposition + +; shift address for header +; the header will be stored after the dive + incf_eeprom_address d'47' ; Macro, that adds 8Bit to eeprom_address:2 with banking at 0x8000 + +store_dive_data2: + movf rel_pressure+0,W ; store depth with every sample + call write_external_eeprom + movf rel_pressure+1,W + call write_external_eeprom + +;First, find out how many bytes will append to this sample.... + clrf ProfileFlagByte ; clear number of bytes to append + +; Check Extented informations + decfsz divisor_temperature,W ; Check divisor + bra check_extended1 + movlw d'2' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte +check_extended1: + decfsz divisor_deco,W ; Check divisor + bra check_extended2 + movlw d'2' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte +check_extended2: + decfsz divisor_tank,W ; Check divisor + bra check_extended3 + movlw d'2' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte +check_extended3: + decfsz divisor_ppo2,W ; Check divisor + bra check_extended4 + movlw d'3' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte +check_extended4: + decfsz divisor_deco_debug,W; Check divisor + bra check_extended5 + movlw d'9' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte +check_extended5: + decfsz divisor_nuy2,W ; Check divisor + bra check_extended6 + movlw d'0' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte +check_extended6: + +; Second, check global event flag + btfss event_occured ; Check global event flag + bra store_dive_data3 ; No Event + movlw d'1' + addwf ProfileFlagByte,F ; add one byte (The EventByte) + + clrf EventByte ; reset EventByte + + movf AlarmType,W ; Type of Alarm Bit 0-3 + addwf EventByte,F ; Copy to EventByte Bit 0-3 + clrf AlarmType ; Reset AlarmType + +; Third, check events and add aditional bytes + btfss manual_gas_changed ; Check flag + bra check_event1 + movlw d'2' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte + bsf EventByte,4 ; Also set Flag in EventByte! +check_event1: + btfss stored_gas_changed ; Check flag + bra check_event2 + movlw d'1' ; Information length + addwf ProfileFlagByte,F ; add to ProfileFlagByte + bsf EventByte,5 ; Also set Flag in EventByte! +check_event2: + bsf ProfileFlagByte,7 ; Set EventByte Flag in ProfileFlagByte + +store_dive_data3: + movf ProfileFlagByte,W ; finally, write ProfileFlagByte! + call write_external_eeprom + + btfss event_occured ; Check global event flag (again) + bra store_dive_data4 ; No Event + +; Store the EventByte + additional bytes now + movf EventByte,W + call write_external_eeprom + + btfss manual_gas_changed ; Check flag + bra store_dive_data3a + read_int_eeprom d'24' ; % O2 Gas6 + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'25' ; % He Gas6 + movf EEDATA,W + call write_external_eeprom + +store_dive_data3a: + btfss stored_gas_changed ; Check flag + bra store_dive_data3b + movf active_gas,W ; Store active gas + call write_external_eeprom + +store_dive_data3b: + +store_dive_data4: + bcf event_occured ; Clear the global event flag + bcf manual_gas_changed ; Clear all events + bcf stored_gas_changed ; Clear all events + +; Store extended informations + decfsz divisor_temperature,F ; Check divisor + bra store_extended1 + rcall store_dive_temperature +store_extended1: + decfsz divisor_deco,F ; Check divisor + bra store_extended2 + rcall store_dive_decodata +store_extended2: + decfsz divisor_tank,F ; Check divisor + bra store_extended3 + rcall store_dive_tankdata +store_extended3: + decfsz divisor_ppo2,F ; Check divisor + bra store_extended4 + rcall store_dive_ppo2 +store_extended4: + decfsz divisor_deco_debug,F; Check divisor + bra store_extended5 + rcall store_dive_decodebug +store_extended5: + decfsz divisor_nuy2,F ; Check divisor + bra store_extended6 + rcall store_dive_nuy2 +store_extended6: + +; The next block is required to take care of "store never" + btfsc divisor_temperature,7 ; Test highest Bit (Register must have been zero before the "decfsz" command!) + clrf divisor_temperature ; And clear register again, so it will never reach zero... + btfsc divisor_deco,7 ; Test highest Bit (Register must have been zero before the "decfsz" command!) + clrf divisor_deco ; And clear register again, so it will never reach zero... + btfsc divisor_tank,7 ; Test highest Bit (Register must have been zero before the "decfsz" command!) + clrf divisor_tank ; And clear register again, so it will never reach zero... + btfsc divisor_ppo2,7 ; Test highest Bit (Register must have been zero before the "decfsz" command!) + clrf divisor_ppo2 ; And clear register again, so it will never reach zero... + btfsc divisor_deco_debug,7 ; Test highest Bit (Register must have been zero before the "decfsz" command!) + clrf divisor_deco_debug ; And clear register again, so it will never reach zero... + btfsc divisor_nuy2,7 ; Test highest Bit (Register must have been zero before the "decfsz" command!) + clrf divisor_nuy2 ; And clear register again, so it will never reach zero... + + ostc_debug 'D' ; Sends debug-information to screen if debugmode active + return ; Done. + +store_dive_nuy2: + GETCUSTOM8 d'26' + movwf divisor_nuy2 ; Reload divisor from CF + return + +store_dive_decodebug: + movff 0x931,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x930,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x933,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x932,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x935,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x934,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x937,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x936,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + movff 0x938,divisor_deco_debug ; Used as temp + movf divisor_deco_debug,W ; copy to WREG + call write_external_eeprom ; Store in EEPROM + GETCUSTOM8 d'25' + movwf divisor_deco_debug ; Reload divisor from CF + return + +store_dive_ppo2: + movlw 0x00 ; Dummy + call write_external_eeprom + movlw 0x00 ; Dummy + call write_external_eeprom + movlw 0x00 ; Dummy + call write_external_eeprom + GETCUSTOM8 d'24' + movwf divisor_ppo2 ; Reload divisor from CF + return + +store_dive_tankdata: + movlw d'0' ; Dummy Tank1 + call write_external_eeprom + movlw d'0' ; Dummy Tank2 + call write_external_eeprom + GETCUSTOM8 d'23' + movwf divisor_tank ; Reload divisor from CF + return + +store_dive_decodata: + movf decodata+0,W ; =0:no stop dive, if in deco mode: ceiling in m + call write_external_eeprom + movf decodata+1,W ; no stop time of length of first stop + call write_external_eeprom + GETCUSTOM8 d'22' + movwf divisor_deco ; Reload divisor from CF + return + +store_dive_temperature: + movf temperature+0,W ; append temperature to current sample! + call write_external_eeprom + movf temperature+1,W + call write_external_eeprom + GETCUSTOM8 d'21' + movwf divisor_temperature ; Reload divisor from CF + return + +calc_velocity: ; called every two seconds + btfss divemode + bra do_not_display_velocity ; display velocity only in divemode + +calc_velocity2: + movff amb_pressure+0,sub_a+0 + movff amb_pressure+1,sub_a+1 + movff last_pressure+0,sub_b+0 + movff last_pressure+1,sub_b+1 + movff amb_pressure+0,last_pressure+0 ; store old value for velocity + movff amb_pressure+1,last_pressure+1 + + call sub16 ; sub_c = amb_pressure - last_pressure + + movff sub_c+0,xA+0 + movff sub_c+1,xA+1 + movlw d'39' ;77 when called every second.... + movwf xB+0 + clrf xB+1 + call mult16x16 ; differential pressure in mBar*77... + movff xC+0,divA+0 + movff xC+1,divA+1 + movlw d'7' + movwf divB + call div16 ; devided by 2^7 equals velocity in m/min + + movlw d'99' + cpfsgt divA + bra calc_velocity3 + movwf divA ; divA=99 + +calc_velocity3: + + GETCUSTOM8 d'5' ; threshold for display vertical velocity + subwf divA+0,W ; + + btfss STATUS,C + bra do_not_display_velocity + +update_velocity: + bsf display_velocity + call PLED_display_velocity + return + +do_not_display_velocity: + btfss display_velocity ; Velocity was not displayed, do not delete + return + + bcf display_velocity ; Velocity was displayed, delete velocity now + call PLED_display_velocity_clear + return + +check_ppO2: ; check current ppO2 and display warning if required + btfsc FLAG_const_ppO2_mode ; ignore in ppO2 mode.... + return + + movff amb_pressure+0,xA+0 + movff amb_pressure+1,xA+1 + movlw d'10' + movwf xB+0 + clrf xB+1 + call div16x16 ; xC=p_amb/10 + movff xC+0,xA+0 + movff xC+1,xA+1 + movff char_I_O2_ratio,xB+0 + clrf xB+1 + call mult16x16 ; char_I_O2_ratio * p_amb/10 + +; Check if ppO2 should be displayed + movff xC+0,sub_b+0 + movff xC+1,sub_b+1 + GETCUSTOM8 d'19' ; ppo2_display_high + mullw d'100' ; ppo2_display_high*100 + movff PRODL,sub_a+0 + movff PRODH,sub_a+1 + call sub16 + bcf ppO2_show_value ; clear flag + btfsc neg_flag + bsf ppO2_show_value ; set flag if required + +;check if we are within our warning thresholds! + bcf ppO2_warn_value ; clear flag + movff xC+0,sub_b+0 + movff xC+1,sub_b+1 + GETCUSTOM8 d'18' ; ppo2_warning_high + mullw d'100' ; ppo2_warning_high*100 + movff PRODL,sub_a+0 + movff PRODH,sub_a+1 + call sub16 + btfss neg_flag + bra check_ppO2_0 ; Not too high + + bsf ppO2_warn_value ; set flag + movlw d'5' ; Type of Alarm + movwf AlarmType ; Copy to Alarm Register + bsf event_occured ; Set Event Flag + +check_ppO2_0: + movff xC+0,sub_b+0 + movff xC+1,sub_b+1 + GETCUSTOM8 d'17' ; ppo2_warning_low + mullw d'100' ; ppo2_warning_low*100 + movff PRODL,sub_a+0 + movff PRODH,sub_a+1 + call sub16 + btfsc neg_flag + bra check_ppO2_1 ; Not too low + + bsf ppO2_warn_value ; set flag + bsf ppO2_show_value ; show ppO2 if below threshold! + movlw d'4' ; Type of Alarm + movwf AlarmType ; Copy to Alarm Register + bsf event_occured ; Set Event Flag + +check_ppO2_1: + btfsc ppO2_show_value ; show value? + bra check_ppO2_2 ; yes! + + btfss ppO2_display_active ; is the value displayed? + bra check_ppO2_3 ; No, so clear not required + + call PLED_show_ppO2_clear; Clear ppO2 value + bcf ppO2_display_active ; clear flag + bra check_ppO2_3 ; done + +check_ppO2_2: + call PLED_show_ppO2 ; Display ppO2 (stored in xC) + bsf ppO2_display_active ; Set flag + +check_ppO2_3: + return ; done + + +calculate_noflytime: + ; calculate nofly time + movff int_O_desaturation_time+0,xA+0 + movff int_O_desaturation_time+1,xA+1 + tstfsz xA+0 ; Desat=0? + bra calculate_noflytime2 + tstfsz xA+1 ; Desat=0? + bra calculate_noflytime2 + ; Desaturation time = zero + movlw d'1' + movwf nofly_time+0 ; Clear nofly time + clrf nofly_time+1 ; Clear nofly time + bcf nofly_active ; Clear flag + return + +calculate_noflytime2: + movff xA+0,int_I_temp+0 + movff xA+1,int_I_temp+1 + GETCUSTOM8 .13 ; nofly_time_ratio + movwf xB+0 + movff xB,char_I_temp + ostc_debug 'K' ; Sends debug-information to screen if debugmode active + call main_calc_percentage + movlb b'00000001' ; select ram bank 1 + ostc_debug 'L' ; Sends debug-information to screen if debugmode active + movff int_I_temp+0,xA+0 + movff int_I_temp+1,xA+1 + tstfsz xA+0 ; Desat=0? + bra calculate_noflytime_2_final + tstfsz xA+1 ; Desat=0? + bra calculate_noflytime_2_final + ; noflytime = zero + movlw d'1' + movwf nofly_time+0 ; Clear nofly time + clrf nofly_time+1 ; Clear nofly time + bcf nofly_active ; Clear flag + return +calculate_noflytime_2_final: + movff xA+0,nofly_time+0 + movff xA+1,nofly_time+1 + bsf nofly_active ; Set flag + return + +end_dive: + btfss realdive ; dive longer then one minute + goto end_dive_common ; No, discard everything + + ; Dive finished (and longer then one minute or Apnoe timeout occured) + + btfsc FLAG_apnoe_mode ; Calc max. depth (again) for very short apnoe dives + rcall apnoe_calc_maxdepth + + ; calculate desaturation time + movff last_surfpressure_30min+0,int_I_pres_respiration+0 ; copy surface air pressure to deco routine + movff last_surfpressure_30min+1,int_I_pres_respiration+1 ; 30min old values + + GETCUSTOM8 d'12' ; Desaturation multiplier % + movwf wait_temp + movff wait_temp,char_I_desaturation_multiplier + + ostc_debug 'G' ; Sends debug-information to screen if debugmode active + call deco_main_calc_desaturation_time ; calculate desaturation time + movlb b'00000001' ; select ram bank 1 + rcall calculate_noflytime ; Calc NoFly time + ostc_debug 'H' ; Sends debug-information to screen if debugmode active + ; store header and ... + movlw 0xFD ; .... End-of-Profile Bytes + call write_external_eeprom + movlw 0xFD + call write_external_eeprom + movlw 0xFE ; This positon will be overwritten for the next profile + call write_external_eeprom ; and is required to find the newest dive after a firmware reset + + movff eeprom_header_address+0, eeprom_address+0 ; set header adress + movff eeprom_header_address+1, eeprom_address+1 ; write header + + movlw 0xFA ; Header start + call write_external_eeprom + movlw 0xFA + call write_external_eeprom + movlw logbook_profile_version ; Defined in definitions_vxyy.asm + call write_external_eeprom + movf month,W ; Date + call write_external_eeprom + movf day,W + call write_external_eeprom + movf year,W + call write_external_eeprom + movf hours,W ; End of dive time + call write_external_eeprom + movf mins,W + call write_external_eeprom + + btfss FLAG_apnoe_mode ; Store apnoe max or normal max (Which is only max from the last descent) + bra end_dive1 ; Store normal depth + + movff apnoe_max_pressure+0,lo + movff apnoe_max_pressure+1,hi + call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mBar] + movff lo,apnoe_max_pressure+0 + movff hi,apnoe_max_pressure+1 + + movf apnoe_max_pressure+0,W ; Max. depth + call write_external_eeprom + movf apnoe_max_pressure+1,W + call write_external_eeprom + bra end_dive2 ; skip + +end_dive1: + movff max_pressure+0,lo + movff max_pressure+1,hi + call adjust_depth_with_salinity ; computes salinity setting into lo:hi [mBar] + movff lo,max_pressure+0 + movff hi,max_pressure+1 + + movf max_pressure+0,W ; Max. depth + call write_external_eeprom + movf max_pressure+1,W + call write_external_eeprom + +end_dive2: + movf divemins+0,W ; divetime minutes + call write_external_eeprom + movf divemins+1,W + call write_external_eeprom + movf divesecs,W ; divetime seconds + call write_external_eeprom + movf mintemp+0,W ; minimum temperature + call write_external_eeprom + movf mintemp+1,W + call write_external_eeprom + movf last_surfpressure_30min+0,W ; airpressure before dive + call write_external_eeprom + movf last_surfpressure_30min+1,W + call write_external_eeprom + movff int_O_desaturation_time+0,lo ; + movff int_O_desaturation_time+1,hi + movf lo,W ; desaturation time in minutes + call write_external_eeprom + movf hi,W ; + call write_external_eeprom + + ; Gases.... + read_int_eeprom d'6' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'7' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + + read_int_eeprom d'10' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'11' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + + read_int_eeprom d'14' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'15' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + + read_int_eeprom d'18' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'19' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + + read_int_eeprom d'22' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'23' ; Read byte (stored in EEDATA) + movf EEDATA,W + call write_external_eeprom + + read_int_eeprom d'24' ; % O2 Gas6 + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'25' ; % He Gas6 + movf EEDATA,W + call write_external_eeprom + read_int_eeprom d'33' ; start gas + movf EEDATA,W + call write_external_eeprom + + movlw softwareversion_x ; Firmware version + call write_external_eeprom + movlw softwareversion_y + call write_external_eeprom + movf batt_voltage+0,W ; Battery voltage + call write_external_eeprom + movf batt_voltage+1,W + call write_external_eeprom + + GETCUSTOM8 d'20' ; sampling rate in WREG + btfsc FLAG_apnoe_mode ; Apnoe mode? + movlw d'1' ; Apnoe sampling rate + call write_external_eeprom + + movlw d'2' ; information size temperature + movwf temp1 ; copy to bits 0-3 + swapf temp1,F ; swap nibbels 0-3 with 4-7 + GETCUSTOM8 d'21' ; Divisor temperature + addwf temp1,W ; copy to bits 0-3, result in WREG + call write_external_eeprom + + movlw d'2' ; information size deco + movwf temp1 ; copy to bits 0-3 + swapf temp1,F ; swap nibbels 0-3 with 4-7 + GETCUSTOM8 d'22' ; Divisor deco + addwf temp1,W ; copy to bits 0-3, result in WREG + call write_external_eeprom + + movlw d'2' ; information size tank + movwf temp1 ; copy to bits 0-3 + swapf temp1,F ; swap nibbels 0-3 with 4-7 + GETCUSTOM8 d'23' ; Divisor Tank + addwf temp1,W ; copy to bits 0-3, result in WREG + call write_external_eeprom + + movlw d'3' ; information size pp02 + movwf temp1 ; copy to bits 0-3 + swapf temp1,F ; swap nibbels 0-3 with 4-7 + GETCUSTOM8 d'24' ; Divisor pp02 + addwf temp1,W ; copy to bits 0-3, result in WREG + call write_external_eeprom + + movlw d'9' ; information size Decodebug + movwf temp1 ; copy to bits 0-3 + swapf temp1,F ; swap nibbels 0-3 with 4-7 + GETCUSTOM8 d'25' ; Divisor Decodebug + addwf temp1,W ; copy to bits 0-3, result in WREG + call write_external_eeprom + + movlw d'0' ; information size nuy2 + movwf temp1 ; copy to bits 0-3 + swapf temp1,F ; swap nibbels 0-3 with 4-7 + GETCUSTOM8 d'26' ; Divisor nuy2 + addwf temp1,W ; copy to bits 0-3, result in WREG + call write_external_eeprom + + read_int_eeprom d'26' ; Read Salinity from EEPROM + movf EEDATA,W + call write_external_eeprom ; Store Salinity to Dive + + movlw d'0' ; Spare + call write_external_eeprom + + movlw 0xFB ; Header stop + call write_external_eeprom + movlw 0xFB + call write_external_eeprom + + ; Increase total dive counter + read_int_eeprom d'2' ; Read byte (stored in EEDATA) + movff EEDATA,temp1 ; Low byte + read_int_eeprom d'3' ; Read byte (stored in EEDATA) + movff EEDATA,temp2 ; high byte + bcf STATUS,C + movlw d'1' + addwf temp1 + movlw d'0' + addwfc temp2 + movff temp1,EEDATA + write_int_eeprom d'2' ; write byte stored in EEDATA + movff temp2,EEDATA + write_int_eeprom d'3' ; write byte stored in EEDATA + + GETCUSTOM15 .28 ; Logbook Offset -> lo, hi + tstfsz lo ; lo=0? + bra change_logbook_offset1 ; No, adjust offset + tstfsz hi ; hi=0? + bra change_logbook_offset1 ; No, adjust offset + bra change_logbook_offset2 ; lo=0 and hi=0 -> skip Offset routine +change_logbook_offset1: + movlw d'1' + addwf lo + movlw d'0' + addwfc hi + movlw d'112' ; CF28 *4 Bytes... + addlw 0x82 + movwf EEADR + movff lo,EEDATA + call write_eeprom ; Lowbyte + movlw d'112' ; CF28 *4 Bytes... + addlw 0x83 + movwf EEADR + movff hi,EEDATA + call write_eeprom ; Highbyte + +change_logbook_offset2: + bcf simulatormode_active ; if we were in simulator mode + call clear_LEDusb + +end_dive_common: + btfsc restore_deco_data ; Restore decodata? + call simulator_restore_tissue_data ; Yes! + + call deco_main_gradient_array + movlb b'00000001' ; select ram bank 1 + + clrf surface_interval+0 + clrf surface_interval+1 ; Clear surface interval timer + + goto surfloop ; and return to surfaceloop + +timeout_divemode: + btfss realdive ; Dive longer then one minute + return + + btfsc FLAG_apnoe_mode ; In Apnoe mode? + bra timeout_divemode2 ; Yes, use CF30 [min] for timeout + + btfsc simulatormode_active ; In Simulator mode? + bra timeout_divemode3 ; Yes, use fixed 5 seconds timeout + + bcf divemode + incf timeout_counter,F + GETCUSTOM8 d'2' ; diveloop_timeout + addlw d'2' ; adds two seconds in case timout=zero! + btfsc STATUS,C ; > 255? + movlw d'255' ; Set to 255... + decf WREG,F ; Limit to 254 + cpfsgt timeout_counter + bsf divemode + return + +timeout_divemode2: + incf timeout_counter,F ; seconds... + movlw d'60' + cpfseq timeout_counter ; timeout_counter=60? + return ; No. + + clrf timeout_counter + bcf divemode + incf apnoe_timeout_counter,F + GETCUSTOM8 d'30' ; apnoe timeout [min] + cpfseq apnoe_timeout_counter + bsf divemode + return + +timeout_divemode3: + bcf divemode + incf timeout_counter,F + movlw d'5' ; Fixed timeout of 5 seconds + cpfsgt timeout_counter + bsf divemode + return + +update_divemode1: ; update any second + call set_dive_modes ; tests if depth>threshold + + btfsc divemode + call set_max_depth ; update max. depth if required + + btfsc divemode + call set_min_temp ; store min. temp if required + + bcf temp_changed ; Display temperature? + movf temperature+0,W + cpfseq last_temperature+0 + bsf temp_changed ; Yes + movf temperature+1,W + cpfseq last_temperature+1 + bsf temp_changed ; Yes + btfsc temp_changed + call PLED_temp_divemode ; Displays temperature + + bcf pres_changed ; Display new depth? + movf amb_pressure+0,W + cpfseq last_pressure+0 + bsf pres_changed ; Yes + movf amb_pressure+1,W + cpfseq last_pressure+1 + bsf pres_changed ; Yes + + btfsc simulatormode_active ; always update depth when in simulator mode + bsf pres_changed + + btfsc pres_changed + call PLED_depth ; Displays new depth + return + +update_divemode60: ; update any minute + call get_battery_voltage ; gets battery voltage + call set_powersafe ; red LED blinking if battery is low + call PLED_max_pressure ; No, use normal max. depth + call check_temp_extrema ; check for new temperature extremas + bcf oneminupdate + return + +set_max_depth: + movff max_pressure+0,sub_a+0 + movff max_pressure+1,sub_a+1 + movff rel_pressure+0,sub_b+0 + movff rel_pressure+1,sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + ; max_pressure<rel_pressure -> neg_flag=1 + ; rel_pressure<=max_pressure -> neg_flag=0 + btfss neg_flag + return + ;max_pressure<rel_pressure + movff rel_pressure+0,max_pressure+0 + movff rel_pressure+1,max_pressure+1 + call PLED_max_pressure ; No, use normal max. depth + return + +set_min_temp: + movff mintemp+0,sub_a+0 + movff mintemp+1,sub_a+1 + movff temperature+0,sub_b+0 + movff temperature+1,sub_b+1 + call sub16 ; sub_c = sub_a - sub_b + ; mintemp<T -> neg_flag=1 + ; T<=mintemp -> neg_flag=0 + btfsc neg_flag + return + ;mintemp>=T + movff temperature+0,mintemp+0 + movff temperature+1,mintemp+1 + return + +set_dive_modes: + bcf divemode2 ; Stop time + + GETCUSTOM8 .0 ; loads dive_threshold in WREG + movwf sub_a+0 ; dive_treshold is in cm + clrf sub_a+1 + + movff rel_pressure+0,sub_b+0 + movff rel_pressure+1,sub_b+1 + + call sub16 ; sub_c = sub_a - sub_b + + btfss neg_flag + bra set_dive_modes2 ; too shallow (rel_pressure<dive_threshold) + + btfsc realdive ; Dive longer than one minute? + clrf timeout_counter + + bsf divemode + bsf divemode2 ; displayed divetime is running + return + +set_dive_modes2: + btfss realdive ; dive longer then one minute? + bcf divemode ; no -> this was no real dive + return + +set_powersafe: + btfsc low_battery_state ; battery warning alread active? + bra set_powersafe2 ; Yes, but is it still required? + ; battery voltage in mV (value*256+Lowbyte=actual treshold) + movlw d'12' ; 3,328V + cpfsgt batt_voltage+1 + bra set_powersafe1 + return + +set_powersafe1: + movlw d'7' ; Type of Alarm (Battery Low) + movwf AlarmType ; Copy to Alarm Register + bsf event_occured ; Set Event Flag + bsf low_battery_state ; set flag for battery warning + return ; return + +set_powersafe2: + movlw d'13' ; 3,584V + cpfsgt batt_voltage+1 + bra set_powersafe1 ; Still to low + bcf low_battery_state ; clear flag for battery warning mode + return + +calc_average_depth: + ; 1. Add new 2xdepth to the Sum of depths registers + movff rel_pressure+0,b0_lo + movff rel_pressure+1,b0_hi + + movf b0_lo,w + addwf average_depth_hold+0,F + movf b0_hi,w + addwfc average_depth_hold+1,F + movlw d'0' + addwfc average_depth_hold+2,F + addwfc average_depth_hold+3,F ; Will work up to 9999mBar*60*60*24=863913600mBar + + movf b0_lo,w + addwf average_depth_hold+0,F + movf b0_hi,w + addwfc average_depth_hold+1,F + movlw d'0' + addwfc average_depth_hold+2,F + addwfc average_depth_hold+3,F ; Will work up to 9999mBar*60*60*24=863913600mBar + + ; 2. Compute Average Depth on base of average_divesecs:2 + + movff average_divesecs+0,xB+0 + movff average_divesecs+1,xB+1 ; Copy + movff average_depth_hold+0,xC+0 + movff average_depth_hold+1,xC+1 + movff average_depth_hold+2,xC+2 + movff average_depth_hold+3,xC+3 + + call div32x16 ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder + movff xC+0,avr_rel_pressure+0 + movff xC+1,avr_rel_pressure+1 + return + + +diveloop_boot: + ostc_debug 'Q' ; Sends debug-information to screen if debugmode active + clrf max_pressure+0 ; clear some variables + clrf max_pressure+1 + + clrf avr_rel_pressure+0 + clrf avr_rel_pressure+1 + + call PLED_brightness_low + read_int_eeprom d'90' ; Brightness offset? (Dim>0, Normal = 0) + movlw d'0' + cpfsgt EEDATA + call PLED_brightness_full + + clrf average_depth_hold+0 + clrf average_depth_hold+1 + clrf average_depth_hold+2 + clrf average_depth_hold+3 ; Clear average depth register + movlw d'1' + movwf average_divesecs+0 + clrf average_divesecs+1 + + movlw d'1' + movwf apnoe_max_pressure+0 + clrf apnoe_max_pressure+1 + clrf apnoe_surface_mins + clrf apnoe_surface_secs + clrf apnoe_mins + clrf apnoe_secs + clrf divemins+0 + clrf divemins+1 + clrf divesecs + clrf samplesecs + clrf apnoe_timeout_counter ; timeout in minutes + clrf timeout_counter ; takes care of the timeout + clrf timeout_counter2 ; Here: counts to six, then store deco data and temperature + clrf AlarmType ; Clear all alarms + bcf event_occured ; clear flag + bcf depth_greater_100m ; clear flag + setf last_diluent ; to be displayed after first calculation (range: 0 to 100 [%]) + clrf char_last_pointer + bcf dekostop_active + call get_free_EEPROM_location ; get last position in external EEPROM, may be up to 2 secs! + + movff last_surfpressure_30min+1,int_I_pres_surface+1 ; HIGH copy surfacepressure to deco routine + movff last_surfpressure_30min+0,int_I_pres_surface+0 ; LOW copy surfacepressure to deco routine + movff temperature+0,mintemp+0 ; Reset Min-Temp registers + movff temperature+1,mintemp+1 ; Reset Min-Temp registers + + clrf wait_temp ; Used to clear Bankx registers + movff wait_temp,char_O_GF_low_pointer + movff wait_temp,char_O_actual_pointer + lfsr FSR0,0x250 + movlw 0x20 + movwf wait_temp +clear_deco_lists: ; Clear Deco list + clrf POSTINC0 + decfsz wait_temp,F + bra clear_deco_lists + lfsr FSR0,0x270 + movlw 0x20 + movwf wait_temp +set_no_forced_stops: ; Init Deco list + movlw 0x01 + movwf POSTINC0 + decfsz wait_temp,F + bra set_no_forced_stops + lfsr FSR0,0x290 ; clear int_O_calc_tissue_call_counter (DEBUG) + clrf POSTINC0 + clrf POSTINC0 + +; Load GF values into RAM + GETCUSTOM8 d'32' ; GF low + movff EEDATA,char_I_GF_Lo_percentage + GETCUSTOM8 d'33' ; GF high + movff EEDATA,char_I_GF_Hi_percentage + +; Start with active Stopwatch? + bsf stopwatch_active + GETCUSTOM8 d'41' ; =1: Start with active Stopwatch + movwf lo + movlw d'1' + cpfseq lo ; CF41=1? + bcf stopwatch_active ; No! + +; Init profile recording parameters + GETCUSTOM8 d'20' ; sample rate + movwf samplesecs_value ; to avoid EEPROM access in the ISR + GETCUSTOM8 d'21' + movwf divisor_temperature ; load divisors for profile storage + GETCUSTOM8 d'22' + movwf divisor_deco + GETCUSTOM8 d'23' + movwf divisor_tank + GETCUSTOM8 d'24' + movwf divisor_ppo2 + GETCUSTOM8 d'25' + movwf divisor_deco_debug + GETCUSTOM8 d'26' + movwf divisor_nuy2 + + btfss FLAG_apnoe_mode ; In Apnoe mode? + bra divemode1 +; Overwrite some parameters in Apnoe mode.... + movlw d'1' + movwf samplesecs_value ; to avoid EEPROM access in the ISR + +divemode1: + read_int_eeprom d'36' ; Read mix 1 ppO2 + btfsc FLAG_const_ppO2_mode + movff EEDATA,char_I_const_ppO2 ; Set ppO2 setpoint if in ppO2 mode + + call clear_LEDnofly ; Clear flags + bcf low_battery_state ; clear flag for battery warning mode + bcf header_stored + bcf premenu + bcf realdive + bsf update_divetime ; set flag + btfss simulatormode_active ; do not disable in simulator mode! + call disable_rs232 ; Disable RS232 unless in external O2 Sensor mode + + read_int_eeprom d'33' ; Read byte (stored in EEDATA) + movff EEDATA,active_gas ; Read start gas (1-5) + +; Read Start Gas and configure char_I_He_ratio, char_I_O2_ratio and char_I_N2_ratio + decf active_gas,W ; Gas 0-4 + mullw d'4' + movf PRODL,W + addlw d'7' ; = address for He ratio + movwf EEADR + call read_eeprom ; Read He ratio + movff EEDATA,char_I_He_ratio ; And copy into hold register + decf active_gas,W ; Gas 0-4 + mullw d'4' + movf PRODL,W + addlw d'6' ; = address for O2 ratio + movwf EEADR + call read_eeprom ; Read O2 ratio + movff EEDATA, char_I_O2_ratio ; O2 ratio + movff char_I_He_ratio, wait_temp ; copy into bank1 register + bsf STATUS,C ; Borrow bit + movlw d'100' ; 100% + subfwb wait_temp,W ; minus He + bsf STATUS,C ; Borrow bit + subfwb EEDATA,F ; minus O2 + movff EEDATA, char_I_N2_ratio ; = N2! + +; New in 1.09 - DecoGas can be configured to achieve exact decompression proposal + ; required variables + ; These values are set when the OSTC is in decompression mode - will be done in routine "check_decogas" + ; char_I_deco_gas_change; ; next gas change in meter + ; char_I_deco_N2_ratio; ; next gas N2 + ; char_I_deco_He_ratio; ; next gas He + clrf lo + movff lo, char_I_deco_gas_change ; clear + movff lo, char_I_deco_N2_ratio ; clear + movff lo, char_I_deco_He_ratio ; clear + bcf multi_gf_display ; Do not display the multi-gf table screen + return \ No newline at end of file