Mercurial > public > hwos_code
changeset 628:cd58f7fc86db
3.05 stable work
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Docu/Changenote-3-02-x.txt Thu Sep 19 12:01:29 2019 +0200 @@ -0,0 +1,186 @@ +Change Note 3.03.4 +================== + +- More compact code for TR firmware and compass. + +- Slightly more compact code for deco engine. + +- Improvement of code for CNS calculation. + +- Added a hysteresis to the dive start / dive end depth threshold. + +- Bugfix in none-helium compile variant. + + +Change Note 3.03.3 +================== + +- Added an option "extended stops" (named "Gas Change/...before 1.Stop" in Deco Setup + -> Deco Parameters -> more). If set to YES, a gas switch will be planned immediately + on the change depth of the gas, even if a stop on that depth is not required by deco + constraints. When set to NO, the gas switch will be planned to be done on the next + regular deco stop. + With extended stops enabled and a setting of "Gas Change (time):+0'" the switch will + be planned with no actual halt at the change depth (i.e. "switch on the fly"). With + change time set to > 0', a dedicated stop will be placed at the change depth for the + given number of minutes. This gas change stop may not be needed by deco constraints, + but it will influence the following deco stop depths and times as it introduces some + added time at depth. + + +Change Note 3.03.2 +================== + +- Complete rework of the alternative dive mode screen layout. + +- Various code improvements. + + + +Change Note 3.03.1 +================== + +- Various code improvements. + +- Included RX firmware update into tech version. + +- Modularization of the code to allow to compile in or not various features. + + +Change Note 3.02.1 +================== + +- Reworked code for ascent and deco stops calculation. Does produce different results + compared to the code used in 3.00.3! With this implementation of an GF-controlled + deco schedule it becomes visible when deco stops disappear due to a high GF slope + (difference between GF low and GF high) combined with a moderate depth of the first + deco stop. + +- When switching between GF and aGF, the depth of the first stop (determined by GF low) + will be recalculated now. + +- Improved calculation of the supersaturation. + +- New tissue graphics option (compile option as of now): shows absolute tissue pressures + (N2 + He added) and saturation per tissue. In the saturation bargraphs, the green line + marks GF low position, the yellow line GF high and the red one 100%. + +- Numerous improvements around dive loop and deco engine start-up. + +- speed_fastest now available again on new OSTC Sport, will adjust to 32 MHz. + +Memory status: 2.252 bytes free with single language (English), RX-functions & screendump + + +Change Note 3.00.3c +=================== + +- GF low can not be set higher than GF high any more as such a setting would produce + an illogical deco schedule. + +- In case the compass is not calibrated, the heading is now displayed as "---°" + instead of ".00°". + + +Change Note 3.00.3b +=================== + +- In the surface tissue graphics, tissues whose supersaturation exceed 100% are shown + in red color now. + +- If any tissue is beyond 100%, no desaturation and no-fly times will be shown anymore. + +- After use of the dive simulator and the deco calculator the interim tissue desaturation + is catched up now. + +- Internal: prohibit selection of fastest speed on OSTC Sport hardware (uses flag for + screen type 2 while there is no dedicated flag for Sport hardware itself). + +Memory status: 2.627 bytes free with single language (English), RX-functions, screendump + and deco engine performance measurement compiled in + +Change Note 3.00.3 +================== + +- Added support for display type 2. + +- Added Deco Engine scheduling performance measurement (accessible via debug output). + +- Open/Next Items: + + + Catch up with tissue desaturation after a simulator run. + + + Widen threshold for DECO ZONE cue to avoid too frequent appearing / disappearing. + + + Detect OSTC Sport hardware and suppress speed_fastest on this hardware. + + + Display dim-up in dive mode could be initiated later when more content is on the screen. + Alternatively use hard switch-on instead of dimming up. + + + The temperature value should be LP-filtered (averaged) to avoid too frequent toggling + when on the edge of +/- 1 degree. + + +Memory status: 2.952 bytes free with single language (English), RX-functions and screendump. + + +Change Note 3.00.2 +================== + +- The Deco Engine has been reworked to now run for up to 700 ms each second (configurable, + 800 ms may be feasible also), split into two compute chunks per second. This increases + reactivity to buttons presses and compass display, while boosting deco calculation turn- + around times significantly. + +Memory status: 3.760 bytes free with single language (English), RX-functions and screendump. + + +Change Note 3.00.1 +================== + +- The simulator now uses the current ambient pressure as surface pressure instead of a fixed + 1.000 hPa as done before. So in mountain diving, when being at the dive site the simulator + will show the same NDL times and deco schedules as will be shown in a real dive. + +- When exiting the surface menu, the return to the normal surface screen has been sped up + and the display of the power-up logo screen is skipped now also. + +- When submerged, the unit will now proceed from surface mode display to dive mode display + without intermediate display of the power-up logos. + +- A cue is given when it is time to go up to th next deco stop by highlighting the next stop + data until ascent is done. + +- When being shallower than the indicated stop depth, i.e. because the deco needs to be + accelerated, the reduced ambient pressure is figured in into the deco calculations such + that the displayed stop time, TTS and gas needs do immediately reflect the reduced depth. + +- When set to imperial units, all depth will be shown in feet now not only in dive mode but + also throughout the whole surface menus. + +- When in a leap year, the 29th of February is now correctly handled when adjusting time and + date on exactly that day. + +- Bugfix: with the option 'always show ppO2' set, in CCR and pSCR mode a "Dil:x.xx" ppO2 + message was sometimes shown twice, once as an info and additionally as an attention or + warning. This has been fixed now: in case of an active attention or warning the secondary + info message gets suppressed. + +- Bugfix: the Simulator +5 min function had a punch-through effect on the real world last + dive time (displayed surface interval). + +- Tissue desaturation is now also computed while in surface and menu modes. + + +Some more internal improvements: + +- Handling of data transfer into and out of the interrupt service routine has been reworked. + +- Memory placement of key variables has been reworked to reduce the number of bank switches. + +- In case option check reveals no errors, an unnecessary write-back to the EEPROM is suppressed + to speed-up restart and reduce wear. + +- Large portion of the code have been inspected / reviewed. + +- Further improvements in code quality, formatting and commenting (done while code review).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Docu/Changenote-3-0x-y.txt Thu Sep 19 12:01:29 2019 +0200 @@ -0,0 +1,278 @@ + +Change Note 3.04.3 +================== + +- Fixed bug in bottom segment gas needs calculation. + +- In the Tech version, max. ppO2 limits can now be adjusted up to 2.0 bar. + Caution: know what you are doing! Recommended max settings are 1.4 bar for + work gases and 1.6 bar for deco gases. + +- CCR mode diluent ppO2 versus setpoint check can be disabled now. + +- Fine tuning of the better gas cue behavior. + +- Improved smoothing of compass display. + +- Attention and warning thresholds for gas density put into the options + table (adjustment via external software only, no mapping in OSTC menu + as of now). + +- Fixed bug in surface mode firmware version output (relevant to Sport only). + + +Change Note 3.04.2 +================== + +- Fine tuning of the deco calculations for extended stops and normal mode. + + +Change Note 3.03.6 - .8 +======================= + +- Various internal code improvements. + + +Change Note 3.03.5 +================== + +- Renamed OC gas type 'normal' to 'work' (gas for the working phase of the + dive). Along with this, it received a down-arrow symbol to depict it as + a gas for use at depth, similar to the '=' symbol that was introduced some + time ago to visually depict deco gases (imagine the horizontal lines as + deco stops). + + Set up gases as follows: + + Single gas dive: + set gas to use as 'first' and all other gases to 'disabled'. + + Gas-change, extended no-stop dive: + set gas to start with to 'first', all other gases to be used later in the dive + to 'work' and the unused gases to 'disabled'. + + Deco-dive with one gas for descent & bottom phase, and deco gases: + set bottom gas to 'first', deco gases to 'deco' and the unused to 'disabled'. + + Deco-dive with a deco gas used as travel gas on ascent, bottom, and deco gases: + configure the deco gas twice: once as travel gas and once as deco dive. Set the + same change depths for both instances and put the travel gas before the deco + gas in the gas list (i.e: gas 1: travel, gas 2: work (bottom) gas, gases 3-5: + deco gases). Set the travel gas to 'first', the bottom gas to 'work', and the + deco gases to 'deco'. Take care to adjust the pressure available on the deco gas + which is used for travel gas, too, to the amount of gas that is planned to remain + after having drawn the travel portion from it! + +- When ppO2 is above normal threshold, but still inside the deco max threshold, and + the dive has not yet progressed to doing the deco stops, the ppO2 warning has been + degraded to an attention, i.e. associated messages appear in yellow now instead of + red as before. + +- In the simulator, the +5 minutes function can now be triggered in succession without + needing to reopen the options menu each time. + +- The French language package has been upgraded. + +- Setting the change depth of the first gas to zero caused some unintended behavior. + This is captured now. Anyhow, since firmware 3.2 it is required to set proper change + depths for gases and diluents, including the ones set as 'first'! + +- The deco calculator now automatically picks the best gas suitable for the set bottom + depth. If no suitable gas is found (i.e. configured), calculation will be aborted with + an error message. By this change it is possible to calculate dives that use a travel + gas (set as 'first') and a bottom gas (set as 'work'), as the deco calculator will now + pick the proper bottom gas for calculating the bottom segment. + Note: the deco calculator does not calculate the descent phase but actually spends all + of the set bottom time at bottom depth. While this puts the deco calculation results + on the safe side, beware that the needs on the travel gas will not show up in the gas + needs calculation results. + +- OSTC TR: The timeouts for attentions and warnings in connection with discontinued + reception of transmitter data have been relaxed a bit: + - For up to 2 minutes without updating the last value received will be retained. + - After 2 minutes without reception of any updates the pressure value will be marked + as outdated. + - After 4 minutes without reception of any updates a transmitter will be declared lost. + +- OSTC TR: pressure logging has been implemented. Logged pressure data can be retrieved + by downloading the logbook data using external logbook software. + +- Descent speed in the simulator has been increased from 19 to 24 meters per minute. + This speed is not configurable, nor the simulator's ascent speed of 9 meters/min! + +- In dive mode, the battery voltage will be shown when reaching 30%, and a warning will + be issued when the percentage reaches 25% with 1.5 Volt batteries or 15% with LiIon + batteries. + + +Change Note 3.03.4 +================== + +- More compact code for TR firmware and compass. + +- Slightly more compact code for deco engine. + +- Improvement of code for CNS calculation. + +- Added a hysteresis to the dive start / dive end depth threshold. + +- Bugfix in non-helium compile variant. + + +Change Note 3.03.3 +================== + +- Added an option "extended stops" (named "Gas Change/...before 1.Stop" in Deco Setup + -> Deco Parameters -> more). If set to YES, a gas switch will be planned immediately + on the change depth of the gas, even if a stop on that depth is not required by deco + constraints. When set to NO, the gas switch will be planned to be done on the next + regular deco stop. + With extended stops enabled and a setting of "Gas Change (time):+0'" the switch will + be planned with no actual halt at the change depth (i.e. "switch on the fly"). With + change time set to > 0', a dedicated stop will be placed at the change depth for the + given number of minutes. This gas change stop may not be needed by deco constraints, + but it will influence the following deco stop depths and times as it introduces some + added time at depth. + + +Change Note 3.03.2 +================== + +- Complete rework of the alternative dive mode screen layout. + +- Various code improvements. + + + +Change Note 3.03.1 +================== + +- Various code improvements. + +- Included RX firmware update into tech version. + +- Modularization of the code to allow to compile in or not various features. + + +Change Note 3.02.1 +================== + +- Reworked code for ascent and deco stops calculation. Does produce different results + compared to the code used in 3.00.3! With this implementation of an GF-controlled + deco schedule it becomes visible when deco stops disappear due to a high GF slope + (difference between GF low and GF high) combined with a moderate depth of the first + deco stop. + +- When switching between GF and aGF, the depth of the first stop (determined by GF low) + will be recalculated now. + +- Improved calculation of the supersaturation. + +- New tissue graphics option (compile option as of now): shows absolute tissue pressures + (N2 + He added) and saturation per tissue. In the saturation bargraphs, the green line + marks GF low position, the yellow line GF high and the red one 100%. + +- Numerous improvements around dive loop and deco engine start-up. + +- speed_fastest now available again on new OSTC Sport, will adjust to 32 MHz. + +Memory status: 2.252 bytes free with single language (English), RX-functions & screendump + + +Change Note 3.00.3c +=================== + +- GF low can not be set higher than GF high any more as such a setting would produce + an illogical deco schedule. + +- In case the compass is not calibrated, the heading is now displayed as "---°" + instead of ".00°". + + +Change Note 3.00.3b +=================== + +- In the surface tissue graphics, tissues whose supersaturation exceed 100% are shown + in red color now. + +- If any tissue is beyond 100%, no desaturation and no-fly times will be shown anymore. + +- After use of the dive simulator and the deco calculator the interim tissue desaturation + is catched up now. + +- Internal: prohibit selection of fastest speed on OSTC Sport hardware (uses flag for + screen type 2 while there is no dedicated flag for Sport hardware itself). + +Memory status: 2.627 bytes free with single language (English), RX-functions, screendump + and deco engine performance measurement compiled in + +Change Note 3.00.3 +================== + +- Added support for display type 2. + +- Added Deco Engine scheduling performance measurement (accessible via debug output). + +Memory status: 2.952 bytes free with single language (English), RX-functions and screendump. + + +Change Note 3.00.2 +================== + +- The Deco Engine has been reworked to now run for up to 700 ms each second (configurable, + 800 ms may be feasible also), split into two compute chunks per second. This increases + reactivity to buttons presses and compass display, while boosting deco calculation turn- + around times significantly. + +Memory status: 3.760 bytes free with single language (English), RX-functions and screendump. + + +Change Note 3.00.1 +================== + +- The simulator now uses the current ambient pressure as surface pressure instead of a fixed + 1.000 hPa as done before. So in mountain diving, when being at the dive site the simulator + will show the same NDL times and deco schedules as will be shown in a real dive. + +- When exiting the surface menu, the return to the normal surface screen has been sped up + and the display of the power-up logo screen is skipped now also. + +- When submerged, the unit will now proceed from surface mode display to dive mode display + without intermediate display of the power-up logos. + +- A cue is given when it is time to go up to th next deco stop by highlighting the next stop + data until ascent is done. + +- When being shallower than the indicated stop depth, i.e. because the deco needs to be + accelerated, the reduced ambient pressure is figured in into the deco calculations such + that the displayed stop time, TTS and gas needs do immediately reflect the reduced depth. + +- When set to imperial units, all depth will be shown in feet now not only in dive mode but + also throughout the whole surface menus. + +- When in a leap year, the 29th of February is now correctly handled when adjusting time and + date on exactly that day. + +- Bugfix: with the option 'always show ppO2' set, in CCR and pSCR mode a "Dil:x.xx" ppO2 + message was sometimes shown twice, once as an info and additionally as an attention or + warning. This has been fixed now: in case of an active attention or warning the secondary + info message gets suppressed. + +- Bugfix: the Simulator +5 min function had a punch-through effect on the real world last + dive time (displayed surface interval). + +- Tissue desaturation is now also computed while in surface and menu modes. + + +Some more internal improvements: + +- Handling of data transfer into and out of the interrupt service routine has been reworked. + +- Memory placement of key variables has been reworked to reduce the number of bank switches. + +- In case option check reveals no errors, an unnecessary write-back to the EEPROM is suppressed + to speed-up restart and reduce wear. + +- Large portion of the code have been inspected / reviewed. + +- Further improvements in code quality, formatting and commenting (done while code review).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Docu/Performance-Measurement.txt Thu Sep 19 12:01:29 2019 +0200 @@ -0,0 +1,40 @@ + +Performance Measurement +----------------------- + +When compiled in, the dive mode screen shows 5 performance data values: + +AAAA.BBB.CC.DD.EE + +AAAA: Relative runtime of the last deco engine invocation, in ms, + signed value: positive numbers: longer than target + negative numbers: unused time budget + +BBB: longest runtime found, in ms + +CC: Calculation phase in which the longest runtime occurred, see table below + +DD: Number of deco engine invocations required to complete the last normal plan + +EE: as above, but for alternative plan + + +Calculation Phases +------------------------------------------------------------------------------------------------------ + +PHASE_00_DONE 00 calculation cycle finished +PHASE_10_DIVE_INIT 10 once-per-dive initialization of the deco engine +PHASE_11_CYCLIC_INIT 11 once-every-cycle initialization of the deco engine +PHASE_20_EXTENDED_BOTTOM_TIME 20 calculate extended bottom time +PHASE_30_NDL_TIME 30 calculate NDL time +PHASE_40_CAVE_ASCENT 40 calculate cave mode return/ascent +PHASE_50_INITIAL_ASCENT 50 calculate initial ascent +PHASE_60_DECO_STOPS 60 calculate deco stops +PHASE_70_RESULTS 70 results - initialization +PHASE_71_RESULTS_STOPS_TABLE 71 results - publish stops table +PHASE_72_RESULTS_NDL 72 results - publish data / within NDL +PHASE_73_RESULTS_DECO 73 results - publish data / in deco +PHASE_80_GAS_NEEDS_SWITCHES 80 calculate gas needs - find gas switches in NDL bailout mode +PHASE_81_GAS_NEEDS_ASCENT 81 calculate gas needs - needs of bottom segment and ascent +PHASE_82_GAS_NEEDS_PRESSURES 82 calculate gas needs - conversion from volumes to pressures +PHASE_90_FINISH 90 finish calculation cycle \ No newline at end of file
--- a/src/Fonts/aa_font36.inc Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1741 +0,0 @@ -;========================================================================== -; Font data exported ven. nov. 16 2012 by FontIO.cpp 110 2011-06-07 11:26:40Z gascuel $ -;========================================================================== -aa_font36_height EQU .32 -aa_font36_width EQU .20 -aa_font36_nbbits EQU .3 -; -aa_font36_bits: -; Space - DB 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -; ! mark - DB 0xFF, 0xF8, 0x41, 0x86, 0x40, 0x02, 0x28, 0x45 - DB 0x60, 0x81, 0x02, 0x20, 0x85, 0x40, 0x11, 0x40 - DB 0x80, 0x40, 0x03, 0x60, 0x84, 0x40, 0x11, 0x40 - DB 0x80, 0x40, 0x03, 0x60, 0x84, 0x40, 0x22, 0x49 - DB 0x65, 0x81, 0x20, 0x01, 0x40, 0x9C, 0x61, 0xFF - DB 0xE4 -; " dquote - DB 0x8A, 0x60, 0x9E, 0x20, 0x00, 0x60, 0x9B, 0x60 - DB 0x01, 0x94, 0x60, 0x21, 0x60, 0x82, 0x60, 0x01 - DB 0x40, 0x93, 0x60, 0x03, 0x40, 0x60, 0x40, 0x01 - DB 0x20, 0x94, 0x40, 0x08, 0x60, 0x94, 0x60, 0x07 - DB 0x40, 0x96, 0x40, 0x04, 0x20, 0x60, 0x98, 0x60 - DB 0x42, 0x60, 0xA2, 0x61, 0x9D, 0x20, 0x00, 0x60 - DB 0x9B, 0x40, 0x00, 0x20, 0x94, 0x40, 0x01, 0x40 - DB 0x82, 0x40, 0x01, 0x40, 0x93, 0x60, 0x03, 0x20 - DB 0x40, 0x20, 0x01, 0x20, 0x94, 0x40, 0x07, 0x20 - DB 0x95, 0x60, 0x06, 0x20, 0x97, 0x40, 0x03, 0x20 - DB 0x40, 0x9A, 0x62, 0xD8 -; # sharp - DB 0x91, 0x60, 0x01, 0x93, 0x60, 0x01, 0x85, 0x60 - DB 0x01, 0x93, 0x60, 0x01, 0x85, 0x60, 0x01, 0x93 - DB 0x60, 0x01, 0x85, 0x60, 0x01, 0x83, 0x61, 0x40 - DB 0x8C, 0x60, 0x01, 0x82, 0x62, 0x40, 0x01, 0x21 - DB 0x04, 0x89, 0x61, 0x41, 0x01, 0x20, 0x0E, 0x86 - DB 0x60, 0x10, 0x22, 0x42, 0x60, 0x86, 0x60, 0x07 - DB 0x21, 0x42, 0x60, 0x40, 0x01, 0x8D, 0x60, 0x20 - DB 0x42, 0x60, 0x40, 0x01, 0x85, 0x60, 0x01, 0x93 - DB 0x60, 0x01, 0x85, 0x60, 0x01, 0x93, 0x60, 0x01 - DB 0x85, 0x60, 0x01, 0x93, 0x60, 0x01, 0x85, 0x60 - DB 0x01, 0x42, 0x21, 0x01, 0x8C, 0x40, 0x01, 0x41 - DB 0x21, 0x0B, 0x86, 0x60, 0x40, 0x21, 0x11, 0x21 - DB 0x40, 0x86, 0x60, 0x0A, 0x22, 0x40, 0x01, 0x61 - DB 0x8B, 0x60, 0x01, 0x21, 0x41, 0x01, 0x60, 0x84 - DB 0x60, 0x01, 0x93, 0x60, 0x01, 0x85, 0x60, 0x01 - DB 0x93, 0x60, 0x01, 0x85, 0x60, 0x01, 0x93, 0x60 - DB 0x01, 0x85, 0x60, 0x21, 0x93, 0x60, 0x21, 0x93 -; $ dolar - DB 0xA8, 0x62, 0x99, 0x60, 0x40, 0x03, 0x20, 0x60 - DB 0x89, 0x41, 0x20, 0x40, 0x88, 0x60, 0x07, 0x40 - DB 0x88, 0x40, 0x01, 0x20, 0x87, 0x60, 0x09, 0x60 - DB 0x88, 0x02, 0x87, 0x40, 0x01, 0x20, 0x60, 0x81 - DB 0x40, 0x02, 0x20, 0x88, 0x20, 0x01, 0x60, 0x86 - DB 0x01, 0x20, 0x84, 0x40, 0x02, 0x40, 0x87, 0x40 - DB 0x01, 0x60, 0x85, 0x60, 0x01, 0x40, 0x85, 0x20 - DB 0x01, 0x20, 0x87, 0x40, 0x01, 0x40, 0x60, 0x41 - DB 0x82, 0x40, 0x01, 0x40, 0x63, 0x41, 0x20, 0x02 - DB 0x23, 0x0A, 0x21, 0x1F, 0x0F, 0x21, 0x44, 0x20 - DB 0x01, 0x40, 0x60, 0x81, 0x42, 0x20, 0x01, 0x63 - DB 0x83, 0x40, 0x02, 0x86, 0x20, 0x01, 0x86, 0x40 - DB 0x01, 0x60, 0x86, 0x60, 0x02, 0x40, 0x84, 0x60 - DB 0x01, 0x20, 0x86, 0x60, 0x01, 0x60, 0x87, 0x40 - DB 0x02, 0x40, 0x60, 0x81, 0x40, 0x02, 0x60, 0x86 - DB 0x60, 0x01, 0x40, 0x87, 0x60, 0x09, 0x20, 0x88 - DB 0x41, 0x60, 0x88, 0x40, 0x07, 0x20, 0x96, 0x60 - DB 0x20, 0x04, 0x40, 0x99, 0x60, 0x41, 0x60, 0xC8 -; % percent - DB 0x83, 0x40, 0x20, 0x02, 0x20, 0x40, 0x8E, 0x40 - DB 0x60, 0x86, 0x20, 0x06, 0x40, 0x8B, 0x60, 0x20 - DB 0x00, 0x20, 0x85, 0x20, 0x01, 0x23, 0x02, 0x60 - DB 0x89, 0x40, 0x03, 0x60, 0x83, 0x60, 0x01, 0x60 - DB 0x84, 0x20, 0x00, 0x40, 0x87, 0x60, 0x20, 0x02 - DB 0x20, 0x60, 0x84, 0x40, 0x00, 0x40, 0x85, 0x60 - DB 0x00, 0x20, 0x86, 0x40, 0x03, 0x40, 0x86, 0x40 - DB 0x00, 0x40, 0x85, 0x60, 0x00, 0x20, 0x84, 0x60 - DB 0x20, 0x02, 0x20, 0x60, 0x87, 0x60, 0x01, 0x60 - DB 0x83, 0x60, 0x20, 0x00, 0x40, 0x83, 0x40, 0x03 - DB 0x40, 0x8A, 0x02, 0x23, 0x02, 0x82, 0x60, 0x20 - DB 0x02, 0x20, 0x60, 0x8B, 0x40, 0x07, 0x60, 0x81 - DB 0x60, 0x03, 0x40, 0x8E, 0x60, 0x40, 0x20, 0x01 - DB 0x20, 0x40, 0x82, 0x20, 0x02, 0x20, 0x60, 0x82 - DB 0x62, 0x91, 0x60, 0x03, 0x40, 0x81, 0x60, 0x20 - DB 0x04, 0x40, 0x8E, 0x20, 0x02, 0x20, 0x60, 0x81 - DB 0x60, 0x07, 0x40, 0x8B, 0x60, 0x03, 0x40, 0x83 - DB 0x01, 0x20, 0x40, 0x61, 0x40, 0x20, 0x01, 0x60 - DB 0x89, 0x20, 0x02, 0x20, 0x60, 0x83, 0x60, 0x00 - DB 0x20, 0x85, 0x20, 0x00, 0x40, 0x87, 0x60, 0x03 - DB 0x40, 0x85, 0x40, 0x00, 0x40, 0x85, 0x20, 0x00 - DB 0x40, 0x86, 0x20, 0x02, 0x20, 0x60, 0x86, 0x40 - DB 0x00, 0x40, 0x85, 0x20, 0x00, 0x60, 0x84, 0x60 - DB 0x03, 0x40, 0x88, 0x60, 0x01, 0x40, 0x82, 0x60 - DB 0x20, 0x01, 0x85, 0x02, 0x20, 0x60, 0x8A, 0x08 - DB 0x40, 0x85, 0x60, 0x00, 0x40, 0x8C, 0x60, 0x06 - DB 0x40, 0x87, 0x60, 0x8F, 0x41, 0x21, 0x40, 0x60 - DB 0x85 -; & and - DB 0x92, 0x60, 0x42, 0x60, 0x8D, 0x61, 0x88, 0x60 - DB 0x20, 0x05, 0x40, 0x88, 0x60, 0x20, 0x03, 0x40 - DB 0x85, 0x40, 0x08, 0x20, 0x86, 0x60, 0x07, 0x40 - DB 0x82, 0x40, 0x03, 0x22, 0x03, 0x40, 0x85, 0x20 - DB 0x08, 0x40, 0x80, 0x40, 0x02, 0x40, 0x60, 0x82 - DB 0x60, 0x20, 0x01, 0x20, 0x84, 0x60, 0x01, 0x20 - DB 0x60, 0x80, 0x60, 0x40, 0x03, 0x20, 0x02, 0x60 - DB 0x86, 0x02, 0x60, 0x83, 0x40, 0x01, 0x84, 0x60 - DB 0x20, 0x04, 0x60, 0x87, 0x40, 0x01, 0x60, 0x83 - DB 0x20, 0x00, 0x20, 0x86, 0x20, 0x02, 0x40, 0x88 - DB 0x40, 0x01, 0x60, 0x83, 0x20, 0x00, 0x20, 0x85 - DB 0x60, 0x04, 0x60, 0x87, 0x40, 0x01, 0x84, 0x40 - DB 0x01, 0x60, 0x83, 0x60, 0x06, 0x60, 0x86, 0x01 - DB 0x20, 0x84, 0x40, 0x01, 0x20, 0x40, 0x60, 0x40 - DB 0x20, 0x02, 0x40, 0x60, 0x03, 0x60, 0x84, 0x40 - DB 0x01, 0x40, 0x85, 0x08, 0x40, 0x81, 0x60, 0x02 - DB 0x20, 0x83, 0x40, 0x01, 0x20, 0x86, 0x40, 0x06 - DB 0x40, 0x83, 0x60, 0x03, 0x61, 0x20, 0x02, 0x60 - DB 0x87, 0x60, 0x20, 0x01, 0x20, 0x40, 0x60, 0x85 - DB 0x40, 0x07, 0x40, 0x95, 0x60, 0x20, 0x04, 0x20 - DB 0x60, 0x92, 0x40, 0x21, 0x08, 0x40, 0x60, 0x91 - DB 0x20, 0x0D, 0x20, 0x8F, 0x20, 0x02, 0x20, 0x41 - DB 0x60, 0x80, 0x40, 0x05, 0x8F, 0x62, 0x87, 0x40 - DB 0x20, 0x02, 0x9D, 0x61, 0x83 -; ' quote - DB 0xEB, 0x00, 0x20, 0x60, 0x9B, 0x40, 0x01, 0x94 - DB 0x61, 0x85, 0x20, 0x00, 0x40, 0x93, 0x40, 0x01 - DB 0x20, 0x83, 0x40, 0x01, 0x60, 0x92, 0x60, 0x04 - DB 0x41, 0x20, 0x01, 0x20, 0x93, 0x40, 0x09, 0x60 - DB 0x93, 0x60, 0x08, 0x60, 0x95, 0x40, 0x05, 0x20 - DB 0x60, 0x97, 0x60, 0x40, 0x21, 0x40, 0x60, 0xFF - DB 0xFF, 0x96 -; ( lparent - DB 0xED, 0x63, 0x96, 0x60, 0x40, 0x20, 0x07, 0x20 - DB 0x40, 0x60, 0x8F, 0x40, 0x20, 0x0E, 0x40, 0x60 - DB 0x8A, 0x40, 0x13, 0x40, 0x87, 0x60, 0x20, 0x04 - DB 0x20, 0x40, 0x61, 0x83, 0x61, 0x40, 0x20, 0x05 - DB 0x60, 0x84, 0x40, 0x03, 0x20, 0x40, 0x8C, 0x60 - DB 0x40, 0x04, 0x40, 0x82, 0x20, 0x02, 0x20, 0x40 - DB 0x91, 0x40, 0x03, 0x20, 0x80, 0x03, 0x40, 0x95 - DB 0x20, 0x02, 0x20, 0x01, 0x20, 0x60, 0x97, 0x40 - DB 0x03, 0x20, 0x9A, 0x60, 0x01, 0x40, 0x9C, 0x60 - DB 0x00, 0x9E, 0x60, 0xFF, 0x9F -; ) rparent - DB 0xDF, 0x60, 0x9E, 0x00, 0x60, 0x9B, 0x60, 0x20 - DB 0x01, 0x60, 0x99, 0x60, 0x04, 0x40, 0x97, 0x40 - DB 0x02, 0x20, 0x02, 0x20, 0x60, 0x93, 0x60, 0x20 - DB 0x02, 0x20, 0x80, 0x20, 0x03, 0x40, 0x60, 0x8F - DB 0x60, 0x40, 0x03, 0x40, 0x82, 0x40, 0x04, 0x20 - DB 0x40, 0x8B, 0x60, 0x20, 0x04, 0x60, 0x84, 0x60 - DB 0x20, 0x05, 0x20, 0x41, 0x63, 0x41, 0x20, 0x05 - DB 0x20, 0x60, 0x87, 0x40, 0x20, 0x11, 0x20, 0x60 - DB 0x8B, 0x40, 0x20, 0x0D, 0x40, 0x60, 0x90, 0x60 - DB 0x40, 0x21, 0x03, 0x21, 0x40, 0x60, 0xFF, 0xC9 -; * star - DB 0xAA, 0x40, 0x84, 0x40, 0x60, 0x96, 0x20, 0x00 - DB 0x40, 0x83, 0x01, 0x40, 0x95, 0x20, 0x00, 0x20 - DB 0x82, 0x40, 0x01, 0x60, 0x96, 0x01, 0x40, 0x81 - DB 0x20, 0x00, 0x40, 0x97, 0x60, 0x00, 0x20, 0x80 - DB 0x40, 0x00, 0x20, 0x99, 0x20, 0x00, 0x40, 0x20 - DB 0x00, 0x60, 0x94, 0x62, 0x82, 0x02, 0x40, 0x81 - DB 0x63, 0x8E, 0x60, 0x0E, 0x20, 0x8E, 0x60, 0x03 - DB 0x21, 0x02, 0x22, 0x02, 0x20, 0x94, 0x60, 0x00 - DB 0x20, 0x00, 0x20, 0x9A, 0x20, 0x00, 0x60, 0x20 - DB 0x00, 0x60, 0x98, 0x40, 0x00, 0x20, 0x80, 0x60 - DB 0x01, 0x97, 0x60, 0x01, 0x60, 0x81, 0x20, 0x00 - DB 0x40, 0x96, 0x20, 0x00, 0x20, 0x82, 0x40, 0x01 - DB 0x60, 0x95, 0x20, 0x00, 0x40, 0x83, 0x20, 0x00 - DB 0x60, 0x96, 0x60, 0x84, 0x60, 0xED -; + plus - DB 0x90, 0x20, 0x01, 0x9C, 0x20, 0x01, 0x9C, 0x20 - DB 0x01, 0x9C, 0x20, 0x01, 0x9C, 0x20, 0x01, 0x9C - DB 0x20, 0x01, 0x9C, 0x20, 0x01, 0x94, 0x40, 0x26 - DB 0x02, 0x27, 0x8C, 0x40, 0x11, 0x8C, 0x40, 0x11 - DB 0x8C, 0x67, 0x20, 0x01, 0x67, 0x94, 0x20, 0x01 - DB 0x9C, 0x20, 0x01, 0x9C, 0x20, 0x01, 0x9C, 0x20 - DB 0x01, 0x9C, 0x20, 0x01, 0x9C, 0x20, 0x01, 0x9C - DB 0x40, 0x21, 0xCB -; , comma - DB 0xFC, 0x40, 0x00, 0x40, 0x9C, 0x20, 0x00, 0x40 - DB 0x94, 0x60, 0x85, 0x40, 0x01, 0x60, 0x92, 0x60 - DB 0x02, 0x40, 0x82, 0x60, 0x01, 0x20, 0x93, 0x20 - DB 0x03, 0x20, 0x41, 0x02, 0x60, 0x93, 0x09, 0x40 - DB 0x94, 0x20, 0x07, 0x20, 0x95, 0x60, 0x06, 0x40 - DB 0x98, 0x41, 0x20, 0x41, 0x60, 0xFF, 0xFF, 0x84 -; - minus - DB 0xF0, 0x40, 0x21, 0x60, 0x9B, 0x20, 0x01, 0x60 - DB 0x9B, 0x20, 0x01, 0x60, 0x9B, 0x20, 0x01, 0x60 - DB 0x9B, 0x20, 0x01, 0x60, 0x9B, 0x20, 0x01, 0x60 - DB 0x9B, 0x20, 0x01, 0x60, 0x9B, 0x20, 0x01, 0x60 - DB 0x9B, 0x20, 0x01, 0x60, 0x9B, 0x20, 0x01, 0x60 - DB 0x9B, 0x20, 0x01, 0x60, 0x9B, 0x42, 0x60, 0xFF - DB 0xAA -; . dot - DB 0xFF, 0xB4, 0x41, 0x60, 0x9A, 0x60, 0x03, 0x40 - DB 0x99, 0x20, 0x04, 0x99, 0x05, 0x60, 0x98, 0x20 - DB 0x04, 0x99, 0x60, 0x03, 0x40, 0x9A, 0x60, 0x21 - DB 0x40, 0xFF, 0xFF, 0x87 -; / slash - DB 0xD9, 0x60, 0x40, 0x9B, 0x40, 0x20, 0x01, 0x60 - DB 0x97, 0x60, 0x40, 0x04, 0x40, 0x94, 0x60, 0x40 - DB 0x20, 0x04, 0x20, 0x40, 0x60, 0x92, 0x60, 0x20 - DB 0x05, 0x40, 0x60, 0x92, 0x60, 0x40, 0x20, 0x04 - DB 0x20, 0x40, 0x93, 0x40, 0x20, 0x05, 0x40, 0x60 - DB 0x92, 0x60, 0x40, 0x05, 0x20, 0x40, 0x93, 0x40 - DB 0x20, 0x05, 0x40, 0x60, 0x92, 0x60, 0x40, 0x05 - DB 0x20, 0x40, 0x95, 0x20, 0x04, 0x40, 0x60, 0x97 - DB 0x40, 0x01, 0x20, 0x40, 0x9A, 0x60, 0x40, 0x60 - DB 0xFF, 0xB9 -; 0 0 - DB 0xAB, 0x61, 0x44, 0x61, 0x93, 0x40, 0x20, 0x0A - DB 0x20, 0x40, 0x8E, 0x60, 0x10, 0x40, 0x8B, 0x40 - DB 0x12, 0x40, 0x89, 0x40, 0x03, 0x20, 0x40, 0x60 - DB 0x85, 0x61, 0x40, 0x20, 0x03, 0x60, 0x88, 0x02 - DB 0x20, 0x60, 0x8C, 0x60, 0x20, 0x01, 0x20, 0x87 - DB 0x40, 0x01, 0x20, 0x8F, 0x60, 0x02, 0x87, 0x40 - DB 0x01, 0x60, 0x90, 0x40, 0x01, 0x60, 0x86, 0x20 - DB 0x01, 0x91, 0x40, 0x01, 0x60, 0x86, 0x20, 0x01 - DB 0x91, 0x40, 0x01, 0x60, 0x86, 0x40, 0x01, 0x60 - DB 0x90, 0x02, 0x87, 0x40, 0x01, 0x20, 0x8F, 0x20 - DB 0x01, 0x40, 0x88, 0x03, 0x40, 0x8B, 0x40, 0x20 - DB 0x02, 0x60, 0x88, 0x40, 0x04, 0x21, 0x45, 0x21 - DB 0x04, 0x40, 0x8A, 0x40, 0x11, 0x40, 0x8C, 0x60 - DB 0x20, 0x0D, 0x40, 0x90, 0x60, 0x41, 0x21, 0x03 - DB 0x21, 0x40, 0x60, 0xC9 -; 1 1 - DB 0xC6, 0x60, 0x90, 0x62, 0x89, 0x60, 0x01, 0x20 - DB 0x8E, 0x02, 0x89, 0x40, 0x01, 0x40, 0x8E, 0x02 - DB 0x89, 0x02, 0x60, 0x8E, 0x02, 0x88, 0x60, 0x01 - DB 0x20, 0x8F, 0x02, 0x88, 0x20, 0x01, 0x40, 0x8F - DB 0x02, 0x88, 0x02, 0x90, 0x02, 0x87, 0x40, 0x16 - DB 0x87, 0x40, 0x16, 0x87, 0x40, 0x16, 0x87, 0x74 - DB 0x02, 0x9C, 0x02, 0x9C, 0x02, 0x9C, 0x02, 0x9C - DB 0x02, 0x9C, 0x22, 0xC3 -; 2 2 - DB 0xC5, 0x20, 0x40, 0x60, 0x8E, 0x60, 0x02, 0x88 - DB 0x40, 0x01, 0x20, 0x8D, 0x60, 0x03, 0x88, 0x02 - DB 0x60, 0x8C, 0x60, 0x04, 0x87, 0x60, 0x01, 0x20 - DB 0x8C, 0x60, 0x05, 0x87, 0x40, 0x01, 0x40, 0x8B - DB 0x60, 0x02, 0x20, 0x02, 0x87, 0x20, 0x01, 0x60 - DB 0x8A, 0x60, 0x02, 0x20, 0x80, 0x02, 0x87, 0x20 - DB 0x01, 0x60, 0x89, 0x60, 0x02, 0x20, 0x80, 0x60 - DB 0x02, 0x87, 0x20, 0x01, 0x60, 0x88, 0x60, 0x02 - DB 0x20, 0x81, 0x60, 0x02, 0x87, 0x40, 0x01, 0x40 - DB 0x87, 0x60, 0x02, 0x20, 0x82, 0x60, 0x02, 0x87 - DB 0x40, 0x02, 0x60, 0x85, 0x40, 0x03, 0x60, 0x82 - DB 0x60, 0x02, 0x88, 0x03, 0x40, 0x60, 0x81, 0x60 - DB 0x20, 0x02, 0x20, 0x60, 0x83, 0x60, 0x02, 0x88 - DB 0x40, 0x0A, 0x20, 0x85, 0x60, 0x02, 0x89, 0x20 - DB 0x08, 0x40, 0x86, 0x60, 0x02, 0x8A, 0x40, 0x05 - DB 0x20, 0x60, 0x87, 0x60, 0x02, 0x8C, 0x60, 0x42 - DB 0x60, 0x89, 0x60, 0x02, 0x9C, 0x62, 0xC3 -; 3 3 - DB 0xD8, 0x60, 0x41, 0x88, 0x20, 0x00, 0x20, 0x60 - DB 0x85, 0x62, 0x86, 0x01, 0x20, 0x88, 0x01, 0x20 - DB 0x85, 0x60, 0x01, 0x60, 0x86, 0x20, 0x01, 0x87 - DB 0x60, 0x01, 0x40, 0x85, 0x60, 0x01, 0x60, 0x86 - DB 0x40, 0x01, 0x60, 0x86, 0x40, 0x01, 0x60, 0x85 - DB 0x60, 0x01, 0x60, 0x86, 0x40, 0x01, 0x60, 0x86 - DB 0x40, 0x01, 0x86, 0x40, 0x01, 0x60, 0x86, 0x40 - DB 0x01, 0x60, 0x86, 0x20, 0x01, 0x86, 0x40, 0x01 - DB 0x60, 0x86, 0x40, 0x01, 0x60, 0x86, 0x20, 0x01 - DB 0x86, 0x20, 0x01, 0x40, 0x86, 0x20, 0x01, 0x87 - DB 0x20, 0x01, 0x60, 0x85, 0x02, 0x40, 0x86, 0x20 - DB 0x00, 0x20, 0x87, 0x40, 0x01, 0x40, 0x84, 0x40 - DB 0x03, 0x85, 0x60, 0x01, 0x40, 0x87, 0x60, 0x02 - DB 0x40, 0x82, 0x40, 0x01, 0x20, 0x01, 0x40, 0x84 - DB 0x20, 0x01, 0x60, 0x88, 0x20, 0x02, 0x22, 0x01 - DB 0x20, 0x60, 0x02, 0x20, 0x61, 0x40, 0x02, 0x20 - DB 0x89, 0x60, 0x07, 0x60, 0x80, 0x20, 0x08, 0x60 - DB 0x8A, 0x60, 0x20, 0x03, 0x20, 0x60, 0x81, 0x60 - DB 0x07, 0x40, 0x8D, 0x60, 0x41, 0x60, 0x85, 0x40 - DB 0x03, 0x20, 0x60, 0x9A, 0x61, 0xC9 -; 4 4 - DB 0x92, 0x40, 0x20, 0x40, 0x60, 0x99, 0x60, 0x20 - DB 0x02, 0x40, 0x98, 0x40, 0x04, 0x40, 0x96, 0x60 - DB 0x20, 0x05, 0x40, 0x95, 0x40, 0x03, 0x41, 0x01 - DB 0x40, 0x93, 0x60, 0x20, 0x02, 0x20, 0x60, 0x80 - DB 0x40, 0x01, 0x40, 0x92, 0x40, 0x03, 0x40, 0x82 - DB 0x40, 0x01, 0x40, 0x90, 0x60, 0x20, 0x02, 0x20 - DB 0x60, 0x83, 0x40, 0x01, 0x40, 0x8F, 0x40, 0x03 - DB 0x40, 0x85, 0x40, 0x01, 0x40, 0x8D, 0x60, 0x20 - DB 0x02, 0x20, 0x60, 0x86, 0x40, 0x01, 0x40, 0x8C - DB 0x60, 0x03, 0x40, 0x88, 0x40, 0x01, 0x40, 0x8C - DB 0x40, 0x02, 0x40, 0x69, 0x40, 0x01, 0x40, 0x64 - DB 0x87, 0x40, 0x16, 0x87, 0x40, 0x16, 0x87, 0x40 - DB 0x16, 0x96, 0x40, 0x01, 0x40, 0x9B, 0x40, 0x01 - DB 0x40, 0x9B, 0x40, 0x01, 0x40, 0x9B, 0x40, 0x01 - DB 0x40, 0x9B, 0x63, 0x88 -; 5 5 - DB 0xD8, 0x62, 0x87, 0x40, 0x2A, 0x40, 0x87, 0x02 - DB 0x87, 0x40, 0x0A, 0x40, 0x87, 0x20, 0x01, 0x87 - DB 0x40, 0x0A, 0x60, 0x87, 0x40, 0x01, 0x60, 0x86 - DB 0x40, 0x01, 0x20, 0x64, 0x40, 0x01, 0x60, 0x87 - DB 0x40, 0x01, 0x60, 0x86, 0x40, 0x01, 0x20, 0x84 - DB 0x60, 0x01, 0x60, 0x87, 0x40, 0x01, 0x60, 0x86 - DB 0x40, 0x01, 0x20, 0x84, 0x60, 0x01, 0x60, 0x87 - DB 0x40, 0x01, 0x60, 0x86, 0x40, 0x01, 0x20, 0x84 - DB 0x60, 0x01, 0x40, 0x87, 0x40, 0x01, 0x87, 0x40 - DB 0x01, 0x20, 0x84, 0x60, 0x01, 0x40, 0x87, 0x20 - DB 0x01, 0x87, 0x40, 0x01, 0x20, 0x85, 0x02, 0x86 - DB 0x40, 0x01, 0x20, 0x87, 0x40, 0x01, 0x20, 0x85 - DB 0x20, 0x01, 0x40, 0x84, 0x60, 0x02, 0x60, 0x87 - DB 0x40, 0x01, 0x20, 0x85, 0x60, 0x02, 0x20, 0x40 - DB 0x61, 0x40, 0x02, 0x20, 0x88, 0x40, 0x01, 0x20 - DB 0x86, 0x20, 0x09, 0x60, 0x88, 0x40, 0x01, 0x20 - DB 0x87, 0x20, 0x07, 0x60, 0x89, 0x63, 0x88, 0x40 - DB 0x04, 0x40, 0x9A, 0x62, 0xC9 -; 6 6 - DB 0xAD, 0x61, 0x43, 0x61, 0x94, 0x40, 0x20, 0x08 - DB 0x20, 0x40, 0x90, 0x40, 0x0E, 0x60, 0x8D, 0x20 - DB 0x04, 0x21, 0x09, 0x40, 0x8B, 0x20, 0x02, 0x20 - DB 0x40, 0x60, 0x80, 0x40, 0x01, 0x40, 0x60, 0x80 - DB 0x60, 0x40, 0x20, 0x02, 0x60, 0x89, 0x20, 0x02 - DB 0x40, 0x82, 0x40, 0x01, 0x60, 0x85, 0x20, 0x01 - DB 0x40, 0x88, 0x60, 0x02, 0x60, 0x83, 0x01, 0x40 - DB 0x87, 0x02, 0x88, 0x20, 0x01, 0x40, 0x83, 0x40 - DB 0x01, 0x88, 0x40, 0x01, 0x60, 0x86, 0x60, 0x01 - DB 0x20, 0x84, 0x40, 0x00, 0x20, 0x88, 0x60, 0x01 - DB 0x60, 0x86, 0x40, 0x01, 0x40, 0x84, 0x20, 0x00 - DB 0x20, 0x88, 0x60, 0x01, 0x60, 0x86, 0x40, 0x01 - DB 0x60, 0x84, 0x20, 0x00, 0x20, 0x88, 0x40, 0x01 - DB 0x87, 0x20, 0x01, 0x85, 0x40, 0x01, 0x60, 0x87 - DB 0x20, 0x00, 0x20, 0x87, 0x20, 0x01, 0x85, 0x40 - DB 0x01, 0x20, 0x86, 0x40, 0x01, 0x40, 0x87, 0x20 - DB 0x01, 0x85, 0x60, 0x02, 0x20, 0x60, 0x83, 0x40 - DB 0x02, 0x60, 0x87, 0x20, 0x01, 0x86, 0x40, 0x03 - DB 0x22, 0x03, 0x40, 0x88, 0x62, 0x87, 0x20, 0x08 - DB 0x40, 0x95, 0x40, 0x05, 0x20, 0x60, 0x98, 0x60 - DB 0x42, 0x60, 0xA8 -; 7 7 - DB 0x83, 0x40, 0x21, 0x40, 0x9B, 0x40, 0x01, 0x20 - DB 0x9B, 0x40, 0x01, 0x20, 0x9B, 0x40, 0x01, 0x20 - DB 0x92, 0x60, 0x87, 0x40, 0x01, 0x20, 0x90, 0x40 - DB 0x20, 0x00, 0x87, 0x40, 0x01, 0x20, 0x8D, 0x60 - DB 0x40, 0x03, 0x87, 0x40, 0x01, 0x20, 0x8B, 0x60 - DB 0x40, 0x05, 0x87, 0x40, 0x01, 0x20, 0x89, 0x60 - DB 0x20, 0x06, 0x20, 0x87, 0x40, 0x01, 0x20, 0x87 - DB 0x60, 0x20, 0x05, 0x20, 0x40, 0x60, 0x88, 0x40 - DB 0x01, 0x20, 0x85, 0x60, 0x20, 0x05, 0x20, 0x60 - DB 0x8B, 0x40, 0x01, 0x20, 0x83, 0x60, 0x20, 0x05 - DB 0x40, 0x60, 0x8D, 0x40, 0x01, 0x20, 0x81, 0x60 - DB 0x40, 0x05, 0x40, 0x90, 0x40, 0x01, 0x40, 0x80 - DB 0x40, 0x05, 0x40, 0x92, 0x40, 0x01, 0x20, 0x05 - DB 0x40, 0x94, 0x40, 0x06, 0x40, 0x96, 0x40, 0x04 - DB 0x40, 0x98, 0x40, 0x02, 0x40, 0x9A, 0x63, 0xD7 -; 8 8 - DB 0x93, 0x60, 0x42, 0x60, 0x8D, 0x60, 0x40, 0x01 - DB 0x20, 0x40, 0x60, 0x84, 0x20, 0x04, 0x40, 0x8B - DB 0x40, 0x06, 0x60, 0x82, 0x20, 0x06, 0x40, 0x89 - DB 0x60, 0x08, 0x60, 0x80, 0x20, 0x02, 0x21, 0x03 - DB 0x60, 0x88, 0x20, 0x01, 0x20, 0x61, 0x40, 0x02 - DB 0x20, 0x60, 0x01, 0x20, 0x60, 0x82, 0x20, 0x01 - DB 0x40, 0x87, 0x60, 0x01, 0x20, 0x83, 0x40, 0x02 - DB 0x20, 0x01, 0x85, 0x02, 0x87, 0x40, 0x01, 0x60 - DB 0x84, 0x20, 0x03, 0x40, 0x85, 0x40, 0x01, 0x87 - DB 0x40, 0x00, 0x20, 0x85, 0x60, 0x02, 0x20, 0x86 - DB 0x40, 0x01, 0x60, 0x86, 0x20, 0x00, 0x20, 0x86 - DB 0x20, 0x01, 0x40, 0x86, 0x60, 0x01, 0x60, 0x86 - DB 0x20, 0x00, 0x20, 0x86, 0x20, 0x01, 0x20, 0x86 - DB 0x60, 0x01, 0x60, 0x86, 0x40, 0x01, 0x85, 0x60 - DB 0x03, 0x60, 0x85, 0x40, 0x01, 0x87, 0x40, 0x01 - DB 0x40, 0x84, 0x20, 0x03, 0x20, 0x85, 0x20, 0x00 - DB 0x20, 0x87, 0x60, 0x02, 0x60, 0x82, 0x40, 0x01 - DB 0x40, 0x02, 0x40, 0x83, 0x40, 0x01, 0x40, 0x88 - DB 0x20, 0x02, 0x21, 0x02, 0x20, 0x80, 0x40, 0x02 - DB 0x40, 0x61, 0x40, 0x02, 0x60, 0x88, 0x60, 0x07 - DB 0x60, 0x80, 0x60, 0x08, 0x40, 0x8A, 0x60, 0x20 - DB 0x03, 0x20, 0x60, 0x82, 0x60, 0x06, 0x20, 0x8D - DB 0x60, 0x41, 0x60, 0x85, 0x60, 0x40, 0x20, 0x01 - DB 0x20, 0x40, 0xE6 -; 9 9 - DB 0x89, 0x60, 0x42, 0x60, 0x97, 0x60, 0x40, 0x05 - DB 0x20, 0x60, 0x87, 0x62, 0x89, 0x60, 0x09, 0x40 - DB 0x86, 0x20, 0x01, 0x88, 0x60, 0x03, 0x22, 0x04 - DB 0x60, 0x85, 0x40, 0x01, 0x60, 0x87, 0x20, 0x01 - DB 0x20, 0x60, 0x83, 0x40, 0x02, 0x20, 0x85, 0x40 - DB 0x01, 0x60, 0x86, 0x60, 0x01, 0x20, 0x86, 0x60 - DB 0x02, 0x60, 0x84, 0x40, 0x01, 0x60, 0x86, 0x40 - DB 0x01, 0x60, 0x87, 0x40, 0x01, 0x40, 0x84, 0x40 - DB 0x01, 0x60, 0x86, 0x40, 0x00, 0x20, 0x88, 0x60 - DB 0x01, 0x40, 0x84, 0x20, 0x01, 0x87, 0x20, 0x00 - DB 0x20, 0x88, 0x60, 0x01, 0x40, 0x84, 0x01, 0x20 - DB 0x87, 0x20, 0x00, 0x20, 0x88, 0x40, 0x01, 0x60 - DB 0x83, 0x40, 0x01, 0x40, 0x87, 0x40, 0x01, 0x60 - DB 0x87, 0x40, 0x01, 0x83, 0x60, 0x02, 0x60, 0x87 - DB 0x60, 0x01, 0x20, 0x86, 0x60, 0x01, 0x40, 0x82 - DB 0x60, 0x02, 0x40, 0x89, 0x20, 0x01, 0x20, 0x60 - DB 0x83, 0x40, 0x01, 0x20, 0x81, 0x40, 0x20, 0x02 - DB 0x20, 0x8A, 0x60, 0x04, 0x21, 0x03, 0x21, 0x04 - DB 0x20, 0x8C, 0x40, 0x0F, 0x40, 0x8E, 0x60, 0x20 - DB 0x0A, 0x20, 0x40, 0x60, 0x91, 0x60, 0x41, 0x23 - DB 0x41, 0x61, 0xEB -; : colon - DB 0xFF, 0xC7, 0x40, 0x00, 0x20, 0x40, 0x86, 0x60 - DB 0x20, 0x00, 0x40, 0x8F, 0x40, 0x03, 0x60, 0x84 - DB 0x60, 0x03, 0x40, 0x8E, 0x04, 0x40, 0x84, 0x40 - DB 0x04, 0x8E, 0x20, 0x03, 0x40, 0x84, 0x40, 0x03 - DB 0x20, 0x8E, 0x60, 0x02, 0x20, 0x86, 0x20, 0x02 - DB 0x60, 0x8F, 0x60, 0x41, 0x88, 0x41, 0x60, 0xFF - DB 0xFF, 0x88 -; ; semicolon - DB 0xFD, 0x20, 0x40, 0x9C, 0x60, 0x01, 0x9C, 0x20 - DB 0x00, 0x20, 0x87, 0x40, 0x00, 0x20, 0x40, 0x87 - DB 0x60, 0x21, 0x60, 0x83, 0x40, 0x01, 0x40, 0x86 - DB 0x40, 0x03, 0x60, 0x85, 0x60, 0x03, 0x40, 0x81 - DB 0x40, 0x01, 0x20, 0x87, 0x04, 0x40, 0x85, 0x40 - DB 0x09, 0x60, 0x87, 0x20, 0x03, 0x40, 0x85, 0x40 - DB 0x08, 0x40, 0x88, 0x60, 0x02, 0x20, 0x86, 0x60 - DB 0x07, 0x40, 0x8A, 0x60, 0x41, 0x89, 0x40, 0x20 - DB 0x01, 0x20, 0x40, 0x60, 0xFF, 0xFF, 0x83 -; < less - DB 0x91, 0x61, 0x9D, 0x00, 0x20, 0x9C, 0x20, 0x01 - DB 0x20, 0x9A, 0x40, 0x03, 0x40, 0x98, 0x40, 0x05 - DB 0x60, 0x96, 0x60, 0x02, 0x41, 0x02, 0x96, 0x20 - DB 0x01, 0x40, 0x81, 0x20, 0x01, 0x20, 0x94, 0x20 - DB 0x01, 0x20, 0x83, 0x02, 0x40, 0x92, 0x40, 0x02 - DB 0x60, 0x83, 0x60, 0x02, 0x60, 0x90, 0x60, 0x02 - DB 0x40, 0x85, 0x40, 0x02, 0x60, 0x8E, 0x60, 0x02 - DB 0x40, 0x87, 0x20, 0x01, 0x20, 0x8E, 0x20, 0x01 - DB 0x20, 0x88, 0x60, 0x02, 0x40, 0x8C, 0x40, 0x02 - DB 0x60, 0x89, 0x40, 0x02, 0x40, 0x8A, 0x60, 0x02 - DB 0x60, 0x8B, 0x20, 0x02, 0x8B, 0x40, 0x00, 0x40 - DB 0x8D, 0x20, 0x00, 0x40, 0x8C, 0x40, 0x8E, 0x61 - DB 0xFF, 0x83 -; = equal - DB 0x8D, 0x62, 0x83, 0x61, 0x96, 0x40, 0x01, 0x82 - DB 0x60, 0x01, 0x60, 0x95, 0x40, 0x01, 0x82, 0x60 - DB 0x01, 0x60, 0x95, 0x40, 0x01, 0x82, 0x60, 0x01 - DB 0x60, 0x95, 0x40, 0x01, 0x82, 0x60, 0x01, 0x60 - DB 0x95, 0x40, 0x01, 0x82, 0x60, 0x01, 0x60, 0x95 - DB 0x40, 0x01, 0x82, 0x60, 0x01, 0x60, 0x95, 0x40 - DB 0x01, 0x82, 0x60, 0x01, 0x60, 0x95, 0x40, 0x01 - DB 0x82, 0x60, 0x01, 0x60, 0x95, 0x40, 0x01, 0x82 - DB 0x60, 0x01, 0x60, 0x95, 0x40, 0x01, 0x82, 0x60 - DB 0x01, 0x60, 0x95, 0x40, 0x01, 0x82, 0x60, 0x01 - DB 0x60, 0x95, 0x40, 0x01, 0x82, 0x60, 0x01, 0x60 - DB 0x95, 0x40, 0x01, 0x82, 0x60, 0x01, 0x60, 0x95 - DB 0x40, 0x01, 0x82, 0x60, 0x01, 0x60, 0x95, 0x40 - DB 0x01, 0x82, 0x60, 0x01, 0x60, 0x95, 0x40, 0x21 - DB 0x82, 0x60, 0x21, 0x60, 0xE7 -; > greater - DB 0xA9, 0x40, 0x60, 0x8D, 0x60, 0x40, 0x8C, 0x20 - DB 0x00, 0x20, 0x8C, 0x60, 0x01, 0x40, 0x8A, 0x60 - DB 0x02, 0x40, 0x8B, 0x20, 0x01, 0x20, 0x8B, 0x40 - DB 0x02, 0x60, 0x89, 0x40, 0x02, 0x60, 0x8C, 0x40 - DB 0x02, 0x60, 0x87, 0x60, 0x02, 0x40, 0x8E, 0x20 - DB 0x01, 0x20, 0x86, 0x60, 0x02, 0x40, 0x8F, 0x60 - DB 0x02, 0x40, 0x85, 0x20, 0x01, 0x20, 0x91, 0x40 - DB 0x02, 0x60, 0x83, 0x40, 0x02, 0x93, 0x40, 0x02 - DB 0x82, 0x60, 0x02, 0x60, 0x94, 0x20, 0x01, 0x20 - DB 0x80, 0x60, 0x02, 0x40, 0x95, 0x60, 0x02, 0x40 - DB 0x20, 0x01, 0x20, 0x97, 0x60, 0x04, 0x20, 0x99 - DB 0x40, 0x03, 0x60, 0x9A, 0x20, 0x01, 0x60, 0x9C - DB 0x00, 0x40, 0x9D, 0x60, 0xEC -; ? question - DB 0xE1, 0x60, 0x41, 0x60, 0x9B, 0x20, 0x01, 0x60 - DB 0x9B, 0x20, 0x01, 0x60, 0x8A, 0x43, 0x60, 0x81 - DB 0x60, 0x20, 0x40, 0x60, 0x85, 0x40, 0x01, 0x40 - DB 0x88, 0x60, 0x04, 0x40, 0x80, 0x60, 0x02, 0x20 - DB 0x85, 0x40, 0x01, 0x40, 0x87, 0x40, 0x05, 0x40 - DB 0x80, 0x40, 0x03, 0x60, 0x84, 0x60, 0x01, 0x20 - DB 0x86, 0x60, 0x03, 0x22, 0x40, 0x80, 0x60, 0x03 - DB 0x86, 0x02, 0x60, 0x84, 0x60, 0x02, 0x20, 0x60 - DB 0x85, 0x40, 0x00, 0x20, 0x40, 0x86, 0x40, 0x01 - DB 0x20, 0x83, 0x60, 0x20, 0x01, 0x20, 0x92, 0x60 - DB 0x02, 0x20, 0x40, 0x60, 0x40, 0x02, 0x20, 0x94 - DB 0x20, 0x08, 0x60, 0x95, 0x20, 0x06, 0x60, 0x97 - DB 0x40, 0x03, 0x40, 0x9B, 0x61, 0xFF, 0x95 -; @ arobas - DB 0x89, 0x60, 0x40, 0x20, 0x06, 0x20, 0x40, 0x60 - DB 0x90, 0x60, 0x40, 0x0C, 0x20, 0x60, 0x8D, 0x40 - DB 0x04, 0x20, 0x44, 0x20, 0x04, 0x40, 0x8B, 0x40 - DB 0x02, 0x20, 0x60, 0x88, 0x40, 0x20, 0x02, 0x60 - DB 0x89, 0x40, 0x01, 0x20, 0x60, 0x8C, 0x40, 0x02 - DB 0x88, 0x60, 0x01, 0x20, 0x83, 0x60, 0x40, 0x20 - DB 0x02, 0x20, 0x40, 0x60, 0x82, 0x40, 0x01, 0x40 - DB 0x87, 0x40, 0x01, 0x83, 0x20, 0x08, 0x60, 0x82 - DB 0x20, 0x00, 0x20, 0x87, 0x01, 0x40, 0x82, 0x20 - DB 0x01, 0x20, 0x43, 0x20, 0x01, 0x20, 0x82, 0x40 - DB 0x01, 0x86, 0x60, 0x01, 0x82, 0x60, 0x01, 0x60 - DB 0x85, 0x40, 0x00, 0x20, 0x82, 0x60, 0x01, 0x60 - DB 0x85, 0x40, 0x00, 0x20, 0x82, 0x40, 0x00, 0x40 - DB 0x85, 0x60, 0x20, 0x00, 0x60, 0x82, 0x60, 0x01 - DB 0x60, 0x85, 0x40, 0x00, 0x20, 0x82, 0x40, 0x00 - DB 0x40, 0x82, 0x60, 0x41, 0x01, 0x40, 0x83, 0x60 - DB 0x01, 0x60, 0x85, 0x40, 0x00, 0x20, 0x82, 0x40 - DB 0x08, 0x20, 0x60, 0x83, 0x60, 0x01, 0x86, 0x60 - DB 0x01, 0x60, 0x81, 0x60, 0x0A, 0x60, 0x82, 0x40 - DB 0x01, 0x87, 0x01, 0x40, 0x82, 0x42, 0x64, 0x40 - DB 0x01, 0x40, 0x82, 0x40, 0x20, 0x40, 0x87, 0x40 - DB 0x01, 0x40, 0x8A, 0x40, 0x00, 0x20, 0x8E, 0x02 - DB 0x40, 0x89, 0x20, 0x00, 0x40, 0x8E, 0x60, 0x03 - DB 0x41, 0x63, 0x41, 0x02, 0x60, 0x8F, 0x60, 0x20 - DB 0x0B, 0x40, 0x92, 0x40, 0x20, 0x07, 0x40, 0x60 - DB 0x96, 0x60, 0x42, 0x61, 0x8E -; A A - DB 0x97, 0x60, 0x40, 0x01, 0x98, 0x60, 0x40, 0x04 - DB 0x95, 0x60, 0x40, 0x20, 0x06, 0x92, 0x60, 0x40 - DB 0x20, 0x06, 0x20, 0x40, 0x90, 0x60, 0x40, 0x20 - DB 0x06, 0x20, 0x40, 0x91, 0x40, 0x20, 0x06, 0x20 - DB 0x01, 0x60, 0x8F, 0x40, 0x20, 0x06, 0x20, 0x60 - DB 0x80, 0x60, 0x01, 0x60, 0x8C, 0x40, 0x20, 0x06 - DB 0x20, 0x40, 0x83, 0x60, 0x01, 0x60, 0x8B, 0x60 - DB 0x05, 0x20, 0x40, 0x86, 0x60, 0x01, 0x60, 0x8B - DB 0x60, 0x02, 0x20, 0x40, 0x60, 0x88, 0x60, 0x01 - DB 0x60, 0x8B, 0x60, 0x04, 0x40, 0x60, 0x87, 0x60 - DB 0x01, 0x60, 0x8B, 0x60, 0x07, 0x40, 0x60, 0x84 - DB 0x60, 0x01, 0x60, 0x8C, 0x60, 0x40, 0x20, 0x06 - DB 0x20, 0x40, 0x60, 0x81, 0x60, 0x01, 0x60, 0x8F - DB 0x60, 0x40, 0x20, 0x06, 0x20, 0x41, 0x01, 0x60 - DB 0x92, 0x60, 0x40, 0x20, 0x08, 0x40, 0x95, 0x60 - DB 0x40, 0x07, 0x20, 0x40, 0x60, 0x95, 0x60, 0x40 - DB 0x08, 0x40, 0x96, 0x60, 0x40, 0x06, 0x99, 0x40 - DB 0x20, 0x03, 0x9C, 0x40, 0x20, 0x00, 0x83 -; B B - DB 0xC2, 0x60, 0x37, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x01, 0x47, 0x20, 0x00, 0x20 - DB 0x47, 0x02, 0x86, 0x60, 0x01, 0x60, 0x86, 0x20 - DB 0x00, 0x20, 0x87, 0x20, 0x01, 0x86, 0x60, 0x01 - DB 0x60, 0x86, 0x20, 0x00, 0x20, 0x87, 0x20, 0x01 - DB 0x86, 0x60, 0x01, 0x60, 0x86, 0x20, 0x00, 0x20 - DB 0x87, 0x20, 0x01, 0x86, 0x60, 0x01, 0x60, 0x86 - DB 0x20, 0x00, 0x20, 0x87, 0x20, 0x01, 0x86, 0x60 - DB 0x01, 0x60, 0x86, 0x01, 0x20, 0x87, 0x20, 0x00 - DB 0x20, 0x86, 0x60, 0x01, 0x40, 0x85, 0x60, 0x02 - DB 0x60, 0x85, 0x60, 0x01, 0x20, 0x87, 0x01, 0x20 - DB 0x85, 0x20, 0x02, 0x40, 0x85, 0x40, 0x01, 0x40 - DB 0x87, 0x20, 0x01, 0x40, 0x83, 0x20, 0x01, 0x20 - DB 0x01, 0x60, 0x83, 0x60, 0x02, 0x60, 0x87, 0x60 - DB 0x03, 0x21, 0x02, 0x41, 0x02, 0x40, 0x61, 0x40 - DB 0x02, 0x40, 0x89, 0x20, 0x06, 0x20, 0x81, 0x08 - DB 0x20, 0x8B, 0x20, 0x04, 0x40, 0x82, 0x60, 0x06 - DB 0x20, 0x60, 0x8C, 0x60, 0x42, 0x60, 0x84, 0x60 - DB 0x40, 0x20, 0x01, 0x20, 0x40, 0xC7 -; C C - DB 0xAA, 0x60, 0x41, 0x23, 0x41, 0x60, 0x93, 0x40 - DB 0x20, 0x0A, 0x20, 0x60, 0x8E, 0x60, 0x0F, 0x20 - DB 0x8C, 0x40, 0x06, 0x23, 0x06, 0x20, 0x8A, 0x40 - DB 0x03, 0x20, 0x40, 0x87, 0x40, 0x20, 0x03, 0x40 - DB 0x89, 0x03, 0x60, 0x8B, 0x60, 0x03, 0x60, 0x87 - DB 0x40, 0x02, 0x60, 0x8D, 0x60, 0x02, 0x40, 0x87 - DB 0x02, 0x40, 0x8F, 0x40, 0x01, 0x20, 0x86, 0x60 - DB 0x01, 0x20, 0x90, 0x60, 0x02, 0x86, 0x60, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x86, 0x60, 0x01, 0x20 - DB 0x91, 0x01, 0x20, 0x87, 0x02, 0x90, 0x40, 0x01 - DB 0x40, 0x87, 0x40, 0x20, 0x40, 0x60, 0x8F, 0x40 - DB 0x01, 0x60, 0xC3 -; D D - DB 0xA3, 0x17, 0x86, 0x60, 0x17, 0x60, 0x85, 0x60 - DB 0x17, 0x60, 0x85, 0x60, 0x01, 0x40, 0x71, 0x20 - DB 0x01, 0x60, 0x85, 0x60, 0x01, 0x40, 0x91, 0x40 - DB 0x01, 0x60, 0x85, 0x60, 0x01, 0x40, 0x91, 0x40 - DB 0x01, 0x60, 0x85, 0x60, 0x01, 0x40, 0x91, 0x40 - DB 0x01, 0x60, 0x85, 0x60, 0x01, 0x40, 0x91, 0x40 - DB 0x01, 0x60, 0x85, 0x60, 0x01, 0x40, 0x91, 0x20 - DB 0x01, 0x87, 0x01, 0x20, 0x91, 0x01, 0x20, 0x87 - DB 0x20, 0x01, 0x60, 0x8F, 0x40, 0x01, 0x40, 0x87 - DB 0x40, 0x01, 0x20, 0x8F, 0x02, 0x60, 0x87, 0x60 - DB 0x02, 0x40, 0x8D, 0x20, 0x01, 0x20, 0x89, 0x20 - DB 0x02, 0x20, 0x60, 0x89, 0x40, 0x20, 0x02, 0x60 - DB 0x89, 0x60, 0x04, 0x20, 0x41, 0x63, 0x41, 0x20 - DB 0x03, 0x40, 0x8B, 0x60, 0x10, 0x40, 0x8D, 0x60 - DB 0x20, 0x0C, 0x20, 0x60, 0x90, 0x60, 0x40, 0x20 - DB 0x06, 0x20, 0x40, 0x60, 0x96, 0x64, 0x8D -; E E - DB 0xE2, 0x60, 0x37, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x01, 0x20, 0x46, 0x20, 0x00 - DB 0x20, 0x47, 0x20, 0x01, 0x86, 0x60, 0x01, 0x40 - DB 0x86, 0x20, 0x00, 0x20, 0x87, 0x20, 0x01, 0x86 - DB 0x60, 0x01, 0x40, 0x86, 0x20, 0x00, 0x20, 0x87 - DB 0x20, 0x01, 0x86, 0x60, 0x01, 0x40, 0x86, 0x20 - DB 0x00, 0x20, 0x87, 0x20, 0x01, 0x86, 0x60, 0x01 - DB 0x40, 0x86, 0x20, 0x00, 0x20, 0x87, 0x20, 0x01 - DB 0x86, 0x60, 0x01, 0x40, 0x86, 0x20, 0x00, 0x20 - DB 0x87, 0x20, 0x01, 0x86, 0x60, 0x01, 0x40, 0x86 - DB 0x20, 0x00, 0x20, 0x87, 0x20, 0x01, 0x86, 0x60 - DB 0x01, 0x40, 0x86, 0x20, 0x00, 0x20, 0x87, 0x20 - DB 0x01, 0x86, 0x60, 0x01, 0x40, 0x86, 0x20, 0x00 - DB 0x20, 0x87, 0x20, 0x01, 0x86, 0x60, 0x01, 0x40 - DB 0x86, 0x20, 0x00, 0x20, 0x87, 0x20, 0x01, 0x86 - DB 0x60, 0x41, 0x60, 0x86, 0x62, 0x87, 0x42, 0xE3 -; F F - DB 0xE2, 0x60, 0x37, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x01, 0x20, 0x46, 0x20, 0x01 - DB 0x4A, 0x86, 0x60, 0x01, 0x40, 0x86, 0x40, 0x01 - DB 0x91, 0x60, 0x01, 0x40, 0x86, 0x40, 0x01, 0x91 - DB 0x60, 0x01, 0x40, 0x86, 0x40, 0x01, 0x91, 0x60 - DB 0x01, 0x40, 0x86, 0x40, 0x01, 0x91, 0x60, 0x01 - DB 0x40, 0x86, 0x40, 0x01, 0x91, 0x60, 0x01, 0x40 - DB 0x86, 0x40, 0x01, 0x91, 0x60, 0x01, 0x40, 0x86 - DB 0x40, 0x01, 0x91, 0x60, 0x01, 0x40, 0x86, 0x40 - DB 0x01, 0x91, 0x60, 0x01, 0x40, 0x86, 0x40, 0x01 - DB 0x91, 0x60, 0x41, 0x60, 0xF8 -; G G - DB 0x88, 0x60, 0x20, 0x0A, 0x40, 0x60, 0x8F, 0x20 - DB 0x0E, 0x40, 0x8C, 0x60, 0x06, 0x23, 0x06, 0x40 - DB 0x8B, 0x03, 0x20, 0x40, 0x60, 0x85, 0x60, 0x40 - DB 0x20, 0x03, 0x60, 0x89, 0x20, 0x02, 0x40, 0x8B - DB 0x40, 0x03, 0x88, 0x60, 0x02, 0x60, 0x8D, 0x40 - DB 0x02, 0x40, 0x87, 0x20, 0x01, 0x40, 0x8F, 0x20 - DB 0x01, 0x20, 0x87, 0x02, 0x90, 0x60, 0x02, 0x86 - DB 0x60, 0x01, 0x40, 0x91, 0x02, 0x60, 0x85, 0x40 - DB 0x01, 0x40, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40 - DB 0x01, 0x60, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40 - DB 0x01, 0x60, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40 - DB 0x01, 0x60, 0x91, 0x20, 0x01, 0x60, 0x85, 0x40 - DB 0x01, 0x40, 0x91, 0x02, 0x86, 0x60, 0x01, 0x40 - DB 0x87, 0x60, 0x48, 0x01, 0x20, 0x87, 0x02, 0x87 - DB 0x40, 0x0A, 0x40, 0x87, 0x20, 0x01, 0x60, 0x86 - DB 0x40, 0x0A, 0x60, 0x87, 0x62, 0x87, 0x40, 0x2A - DB 0xC4 -; H H - DB 0x82, 0x60, 0x37, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x49, 0x01, 0x20, 0x4A, 0x91 - DB 0x01, 0x20, 0x9C, 0x01, 0x20, 0x9C, 0x01, 0x20 - DB 0x9C, 0x01, 0x20, 0x9C, 0x01, 0x20, 0x9C, 0x01 - DB 0x20, 0x9C, 0x01, 0x20, 0x9C, 0x01, 0x20, 0x9C - DB 0x01, 0x20, 0x9C, 0x01, 0x20, 0x91, 0x60, 0x17 - DB 0x86, 0x60, 0x17, 0x86, 0x60, 0x17, 0x87, 0x77 - DB 0xC3 -; I I - DB 0xA2, 0x60, 0x41, 0x60, 0x91, 0x42, 0x86, 0x60 - DB 0x01, 0x40, 0x91, 0x20, 0x01, 0x86, 0x60, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x86, 0x60, 0x01, 0x40 - DB 0x91, 0x20, 0x01, 0x86, 0x60, 0x01, 0x40, 0x91 - DB 0x20, 0x01, 0x86, 0x60, 0x01, 0x40, 0x91, 0x20 - DB 0x01, 0x86, 0x60, 0x01, 0x32, 0x02, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x17, 0x86, 0x60, 0x01, 0x20 - DB 0x51, 0x20, 0x01, 0x86, 0x60, 0x01, 0x40, 0x91 - DB 0x20, 0x01, 0x86, 0x60, 0x01, 0x40, 0x91, 0x20 - DB 0x01, 0x86, 0x60, 0x01, 0x40, 0x91, 0x20, 0x01 - DB 0x86, 0x60, 0x01, 0x40, 0x91, 0x20, 0x01, 0x86 - DB 0x60, 0x01, 0x40, 0x91, 0x20, 0x01, 0x87, 0x62 - DB 0x91, 0x62, 0xE3 -; J J - DB 0xC2, 0x60, 0x41, 0x60, 0x91, 0x22, 0x86, 0x60 - DB 0x01, 0x40, 0x91, 0x20, 0x01, 0x86, 0x60, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x60, 0x85, 0x60, 0x01 - DB 0x40, 0x91, 0x40, 0x01, 0x60, 0x85, 0x60, 0x01 - DB 0x40, 0x91, 0x40, 0x01, 0x60, 0x85, 0x60, 0x01 - DB 0x40, 0x91, 0x40, 0x01, 0x60, 0x85, 0x60, 0x01 - DB 0x40, 0x91, 0x20, 0x01, 0x86, 0x60, 0x01, 0x40 - DB 0x90, 0x60, 0x01, 0x20, 0x86, 0x60, 0x01, 0x40 - DB 0x8F, 0x60, 0x02, 0x40, 0x86, 0x60, 0x01, 0x20 - DB 0x4E, 0x20, 0x03, 0x87, 0x60, 0x15, 0x60, 0x87 - DB 0x60, 0x13, 0x20, 0x60, 0x88, 0x60, 0x31, 0x40 - DB 0x60, 0xFF, 0xA7 -; K K - DB 0xA2, 0x60, 0x37, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x4A, 0x00, 0x20, 0x4A, 0x90 - DB 0x60, 0x02, 0x40, 0x99, 0x40, 0x04, 0x20, 0x97 - DB 0x20, 0x07, 0x60, 0x93, 0x60, 0x20, 0x02, 0x20 - DB 0x60, 0x20, 0x03, 0x40, 0x91, 0x40, 0x03, 0x40 - DB 0x82, 0x40, 0x03, 0x20, 0x60, 0x8E, 0x40, 0x03 - DB 0x60, 0x84, 0x60, 0x04, 0x60, 0x8B, 0x60, 0x20 - DB 0x02, 0x20, 0x60, 0x86, 0x60, 0x20, 0x03, 0x40 - DB 0x89, 0x40, 0x03, 0x20, 0x8A, 0x40, 0x03, 0x20 - DB 0x60, 0x86, 0x60, 0x03, 0x40, 0x8C, 0x40, 0x04 - DB 0x86, 0x60, 0x02, 0x40, 0x8E, 0x60, 0x03, 0x86 - DB 0x60, 0x00, 0x20, 0x60, 0x91, 0x20, 0x01, 0x86 - DB 0x60, 0x20, 0x94, 0x40, 0x00, 0x9E, 0x40, 0xC3 -; L L - DB 0xC2, 0x60, 0x57, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x34, 0x02, 0x9C, 0x20, 0x01 - DB 0x9C, 0x20, 0x01, 0x9C, 0x20, 0x01, 0x9C, 0x20 - DB 0x01, 0x9C, 0x20, 0x01, 0x9C, 0x20, 0x01, 0x9C - DB 0x20, 0x01, 0x9C, 0x20, 0x01, 0x9C, 0x20, 0x01 - DB 0x9C, 0x20, 0x01, 0x9C, 0x40, 0x21, 0xE3 -; M M - DB 0x83, 0x60, 0x44, 0x23, 0x0D, 0x86, 0x60, 0x17 - DB 0x86, 0x60, 0x04, 0x25, 0x44, 0x64, 0x89, 0x60 - DB 0x02, 0x20, 0x40, 0x60, 0x98, 0x60, 0x20, 0x05 - DB 0x40, 0x60, 0x97, 0x60, 0x40, 0x20, 0x05, 0x40 - DB 0x60, 0x97, 0x60, 0x40, 0x20, 0x04, 0x20, 0x40 - DB 0x60, 0x97, 0x60, 0x40, 0x05, 0x20, 0x99, 0x60 - DB 0x20, 0x03, 0x97, 0x60, 0x40, 0x04, 0x20, 0x94 - DB 0x60, 0x40, 0x20, 0x04, 0x40, 0x60, 0x93, 0x40 - DB 0x20, 0x04, 0x20, 0x40, 0x93, 0x60, 0x40, 0x04 - DB 0x20, 0x40, 0x60, 0x94, 0x60, 0x03, 0x20, 0x40 - DB 0x60, 0x97, 0x60, 0x02, 0x20, 0x44, 0x63, 0x91 - DB 0x60, 0x10, 0x23, 0x42, 0x86, 0x60, 0x17, 0x8B - DB 0x62, 0x43, 0x23, 0x08, 0x9A, 0x62, 0x41, 0xA3 -; N N - DB 0x82, 0x60, 0x57, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x17, 0x86, 0x60, 0x03, 0x20, 0x40, 0x60, 0x50 - DB 0x86, 0x60, 0x05, 0x40, 0x60, 0x98, 0x40, 0x05 - DB 0x40, 0x60, 0x97, 0x60, 0x40, 0x05, 0x40, 0x60 - DB 0x97, 0x60, 0x40, 0x05, 0x40, 0x60, 0x97, 0x60 - DB 0x40, 0x05, 0x40, 0x60, 0x97, 0x60, 0x40, 0x05 - DB 0x40, 0x60, 0x97, 0x60, 0x40, 0x05, 0x40, 0x60 - DB 0x97, 0x60, 0x40, 0x05, 0x40, 0x60, 0x97, 0x60 - DB 0x40, 0x05, 0x40, 0x60, 0x97, 0x60, 0x40, 0x05 - DB 0x86, 0x60, 0x2F, 0x42, 0x04, 0x86, 0x60, 0x17 - DB 0x86, 0x60, 0x17, 0x87, 0x77, 0xC3 -; O O - DB 0x87, 0x60, 0x20, 0x0C, 0x40, 0x60, 0x8D, 0x40 - DB 0x10, 0x40, 0x8B, 0x20, 0x04, 0x20, 0x44, 0x21 - DB 0x05, 0x40, 0x89, 0x20, 0x02, 0x20, 0x40, 0x89 - DB 0x40, 0x20, 0x03, 0x60, 0x87, 0x60, 0x02, 0x40 - DB 0x8D, 0x40, 0x02, 0x40, 0x87, 0x20, 0x01, 0x40 - DB 0x8F, 0x40, 0x01, 0x20, 0x86, 0x60, 0x02, 0x91 - DB 0x02, 0x60, 0x85, 0x40, 0x01, 0x40, 0x91, 0x20 - DB 0x01, 0x60, 0x85, 0x40, 0x01, 0x40, 0x91, 0x20 - DB 0x01, 0x60, 0x85, 0x40, 0x01, 0x40, 0x91, 0x20 - DB 0x01, 0x60, 0x85, 0x40, 0x01, 0x40, 0x91, 0x02 - DB 0x86, 0x60, 0x02, 0x90, 0x40, 0x01, 0x20, 0x87 - DB 0x02, 0x20, 0x8E, 0x40, 0x02, 0x40, 0x87, 0x40 - DB 0x02, 0x20, 0x60, 0x8B, 0x40, 0x02, 0x20, 0x89 - DB 0x20, 0x03, 0x20, 0x40, 0x61, 0x83, 0x60, 0x41 - DB 0x04, 0x60, 0x89, 0x60, 0x20, 0x11, 0x60, 0x8C - DB 0x40, 0x0E, 0x40, 0x8F, 0x60, 0x40, 0x20, 0x08 - DB 0x20, 0x40, 0x60, 0x93, 0x61, 0x44, 0x60, 0xAC -; P P - DB 0xC2, 0x60, 0x57, 0x86, 0x40, 0x17, 0x86, 0x40 - DB 0x17, 0x86, 0x40, 0x01, 0x29, 0x02, 0x28, 0x86 - DB 0x40, 0x01, 0x60, 0x88, 0x20, 0x01, 0x8F, 0x40 - DB 0x01, 0x60, 0x88, 0x20, 0x01, 0x8F, 0x40, 0x01 - DB 0x60, 0x88, 0x20, 0x01, 0x8F, 0x40, 0x01, 0x60 - DB 0x88, 0x20, 0x01, 0x8F, 0x40, 0x01, 0x40, 0x88 - DB 0x01, 0x20, 0x8F, 0x60, 0x01, 0x40, 0x87, 0x60 - DB 0x01, 0x40, 0x90, 0x02, 0x87, 0x20, 0x01, 0x60 - DB 0x90, 0x20, 0x01, 0x20, 0x85, 0x40, 0x01, 0x20 - DB 0x91, 0x60, 0x02, 0x20, 0x40, 0x61, 0x40, 0x20 - DB 0x02, 0x60, 0x92, 0x40, 0x09, 0x40, 0x94, 0x40 - DB 0x07, 0x40, 0x96, 0x60, 0x40, 0x20, 0x01, 0x20 - DB 0x40, 0xD1 -; Q Q - DB 0x89, 0x60, 0x41, 0x20, 0x03, 0x21, 0x41, 0x91 - DB 0x60, 0x20, 0x0C, 0x40, 0x60, 0x8D, 0x40, 0x10 - DB 0x40, 0x8B, 0x20, 0x04, 0x20, 0x44, 0x21, 0x05 - DB 0x40, 0x89, 0x20, 0x02, 0x20, 0x40, 0x89, 0x40 - DB 0x20, 0x03, 0x60, 0x87, 0x60, 0x02, 0x40, 0x8D - DB 0x40, 0x02, 0x40, 0x87, 0x20, 0x01, 0x40, 0x8F - DB 0x40, 0x01, 0x20, 0x86, 0x60, 0x02, 0x91, 0x02 - DB 0x60, 0x85, 0x40, 0x01, 0x40, 0x91, 0x20, 0x01 - DB 0x60, 0x85, 0x40, 0x01, 0x40, 0x90, 0x03, 0x60 - DB 0x85, 0x40, 0x01, 0x40, 0x8F, 0x40, 0x04, 0x85 - DB 0x40, 0x01, 0x40, 0x90, 0x05, 0x40, 0x83, 0x60 - DB 0x02, 0x90, 0x40, 0x05, 0x40, 0x83, 0x02, 0x20 - DB 0x8E, 0x40, 0x02, 0x40, 0x03, 0x83, 0x40, 0x02 - DB 0x20, 0x60, 0x8B, 0x40, 0x02, 0x20, 0x81, 0x02 - DB 0x84, 0x20, 0x03, 0x20, 0x40, 0x61, 0x83, 0x60 - DB 0x41, 0x04, 0x60, 0x81, 0x41, 0x00, 0x84, 0x60 - DB 0x20, 0x11, 0x60, 0x84, 0x60, 0x86, 0x40, 0x0E - DB 0x40, 0x8F, 0x60, 0x40, 0x20, 0x08, 0x20, 0x40 - DB 0x60, 0x93, 0x61, 0x44, 0x60, 0x8C -; R R - DB 0xC2, 0x60, 0x17, 0x86, 0x40, 0x17, 0x86, 0x40 - DB 0x17, 0x86, 0x40, 0x01, 0x40, 0x66, 0x40, 0x01 - DB 0x40, 0x69, 0x86, 0x40, 0x01, 0x60, 0x86, 0x60 - DB 0x01, 0x20, 0x60, 0x8F, 0x40, 0x01, 0x60, 0x86 - DB 0x60, 0x03, 0x60, 0x8E, 0x40, 0x01, 0x60, 0x86 - DB 0x60, 0x04, 0x40, 0x8D, 0x40, 0x01, 0x60, 0x86 - DB 0x40, 0x05, 0x40, 0x8C, 0x40, 0x01, 0x40, 0x86 - DB 0x40, 0x00, 0x20, 0x60, 0x03, 0x20, 0x60, 0x8A - DB 0x60, 0x01, 0x20, 0x85, 0x60, 0x01, 0x40, 0x81 - DB 0x20, 0x03, 0x60, 0x8A, 0x02, 0x40, 0x84, 0x20 - DB 0x01, 0x60, 0x82, 0x40, 0x03, 0x40, 0x89, 0x40 - DB 0x02, 0x40, 0x61, 0x40, 0x20, 0x01, 0x20, 0x84 - DB 0x40, 0x03, 0x40, 0x88, 0x60, 0x09, 0x60, 0x85 - DB 0x60, 0x03, 0x20, 0x88, 0x60, 0x07, 0x60, 0x88 - DB 0x20, 0x02, 0x89, 0x60, 0x40, 0x20, 0x01, 0x20 - DB 0x40, 0x8B, 0x40, 0x01, 0x9D, 0x40, 0x00, 0x9E - DB 0x60, 0xA3 -; S S - DB 0xC7, 0x60, 0x41, 0x60, 0x8B, 0x60, 0x40, 0x20 - DB 0x40, 0x89, 0x60, 0x20, 0x04, 0x40, 0x89, 0x60 - DB 0x01, 0x20, 0x88, 0x40, 0x07, 0x40, 0x89, 0x02 - DB 0x87, 0x60, 0x03, 0x21, 0x03, 0x40, 0x88, 0x20 - DB 0x01, 0x87, 0x40, 0x01, 0x20, 0x82, 0x60, 0x03 - DB 0x88, 0x40, 0x01, 0x60, 0x86, 0x02, 0x84, 0x40 - DB 0x02, 0x40, 0x87, 0x40, 0x01, 0x60, 0x85, 0x60 - DB 0x01, 0x40, 0x85, 0x20, 0x01, 0x20, 0x87, 0x40 - DB 0x01, 0x60, 0x85, 0x40, 0x01, 0x60, 0x85, 0x40 - DB 0x02, 0x40, 0x86, 0x40, 0x01, 0x60, 0x85, 0x40 - DB 0x01, 0x60, 0x86, 0x02, 0x20, 0x86, 0x20, 0x01 - DB 0x86, 0x40, 0x01, 0x60, 0x86, 0x40, 0x02, 0x60 - DB 0x85, 0x01, 0x20, 0x86, 0x40, 0x01, 0x60, 0x86 - DB 0x60, 0x02, 0x20, 0x84, 0x40, 0x01, 0x40, 0x86 - DB 0x40, 0x01, 0x40, 0x87, 0x40, 0x02, 0x20, 0x60 - DB 0x81, 0x40, 0x02, 0x60, 0x86, 0x60, 0x01, 0x40 - DB 0x87, 0x60, 0x09, 0x40, 0x87, 0x60, 0x01, 0x40 - DB 0x88, 0x60, 0x07, 0x20, 0x96, 0x60, 0x20, 0x04 - DB 0x40, 0x99, 0x60, 0x41, 0x60, 0xC8 -; T T - DB 0xA2, 0x60, 0x01, 0x40, 0x9B, 0x60, 0x01, 0x40 - DB 0x9B, 0x60, 0x01, 0x40, 0x9B, 0x60, 0x01, 0x40 - DB 0x9B, 0x60, 0x01, 0x40, 0x9B, 0x60, 0x01, 0x40 - DB 0x9B, 0x60, 0x01, 0x40, 0x9B, 0x60, 0x01, 0x35 - DB 0x86, 0x60, 0x17, 0x86, 0x60, 0x17, 0x86, 0x60 - DB 0x01, 0x20, 0x54, 0x86, 0x60, 0x01, 0x40, 0x9B - DB 0x60, 0x01, 0x40, 0x9B, 0x60, 0x01, 0x40, 0x9B - DB 0x60, 0x01, 0x40, 0x9B, 0x60, 0x01, 0x40, 0x9B - DB 0x60, 0x01, 0x40, 0x9B, 0x60, 0x21, 0x40, 0xB8 -; U U - DB 0xA2, 0x60, 0x10, 0x21, 0x40, 0x60, 0x89, 0x60 - DB 0x14, 0x40, 0x88, 0x60, 0x15, 0x40, 0x88, 0x70 - DB 0x41, 0x03, 0x60, 0x9A, 0x60, 0x20, 0x01, 0x40 - DB 0x9B, 0x60, 0x02, 0x9C, 0x20, 0x01, 0x60, 0x9B - DB 0x40, 0x01, 0x60, 0x9B, 0x40, 0x01, 0x60, 0x9B - DB 0x40, 0x01, 0x60, 0x9B, 0x20, 0x01, 0x9C, 0x01 - DB 0x20, 0x9B, 0x40, 0x01, 0x40, 0x99, 0x60, 0x20 - DB 0x02, 0x60, 0x86, 0x60, 0x30, 0x04, 0x40, 0x87 - DB 0x60, 0x14, 0x40, 0x88, 0x60, 0x12, 0x40, 0x60 - DB 0x89, 0x60, 0x50, 0x60, 0xA9 -; V V - DB 0x82, 0x60, 0x00, 0x20, 0x40, 0x60, 0x9A, 0x60 - DB 0x03, 0x20, 0x40, 0x60, 0x97, 0x60, 0x06, 0x20 - DB 0x40, 0x60, 0x95, 0x40, 0x20, 0x07, 0x20, 0x40 - DB 0x60, 0x95, 0x40, 0x20, 0x07, 0x20, 0x40, 0x60 - DB 0x95, 0x41, 0x07, 0x20, 0x40, 0x60, 0x95, 0x60 - DB 0x40, 0x07, 0x20, 0x40, 0x60, 0x95, 0x60, 0x40 - DB 0x20, 0x06, 0x20, 0x40, 0x96, 0x60, 0x40, 0x20 - DB 0x05, 0x99, 0x60, 0x40, 0x20, 0x02, 0x98, 0x60 - DB 0x40, 0x20, 0x03, 0x95, 0x60, 0x40, 0x06, 0x20 - DB 0x92, 0x60, 0x40, 0x06, 0x20, 0x40, 0x60, 0x90 - DB 0x40, 0x20, 0x06, 0x20, 0x40, 0x60, 0x90, 0x40 - DB 0x20, 0x07, 0x40, 0x60, 0x90, 0x40, 0x20, 0x07 - DB 0x40, 0x60, 0x90, 0x60, 0x20, 0x07, 0x40, 0x60 - DB 0x93, 0x60, 0x05, 0x20, 0x40, 0x96, 0x60, 0x02 - DB 0x20, 0x40, 0x99, 0x60, 0x20, 0x40, 0x99 -; W W - DB 0x82, 0x60, 0x0B, 0x22, 0x43, 0x63, 0x87, 0x60 - DB 0x17, 0x87, 0x61, 0x44, 0x23, 0x0C, 0x97, 0x62 - DB 0x40, 0x03, 0x97, 0x60, 0x40, 0x20, 0x04, 0x94 - DB 0x60, 0x40, 0x20, 0x04, 0x20, 0x40, 0x92, 0x60 - DB 0x40, 0x20, 0x04, 0x20, 0x40, 0x93, 0x40, 0x20 - DB 0x04, 0x20, 0x40, 0x96, 0x03, 0x20, 0x60, 0x99 - DB 0x05, 0x40, 0x60, 0x97, 0x60, 0x40, 0x20, 0x05 - DB 0x40, 0x60, 0x97, 0x60, 0x40, 0x20, 0x04, 0x20 - DB 0x40, 0x60, 0x97, 0x60, 0x40, 0x05, 0x20, 0x40 - DB 0x98, 0x60, 0x40, 0x04, 0x93, 0x63, 0x43, 0x20 - DB 0x02, 0x86, 0x60, 0x42, 0x23, 0x10, 0x86, 0x60 - DB 0x15, 0x21, 0x86, 0x60, 0x07, 0x23, 0x42, 0x63 - DB 0x8B, 0x60, 0x40, 0x63, 0xB6 -; X X - DB 0x82, 0x60, 0x00, 0x20, 0x60, 0x90, 0x60, 0x20 - DB 0x01, 0x86, 0x60, 0x02, 0x40, 0x8E, 0x40, 0x03 - DB 0x86, 0x60, 0x03, 0x20, 0x60, 0x8A, 0x60, 0x20 - DB 0x03, 0x20, 0x87, 0x40, 0x04, 0x40, 0x88, 0x40 - DB 0x04, 0x40, 0x89, 0x60, 0x20, 0x03, 0x20, 0x60 - DB 0x84, 0x60, 0x20, 0x03, 0x20, 0x60, 0x8C, 0x60 - DB 0x20, 0x03, 0x20, 0x60, 0x80, 0x60, 0x20, 0x03 - DB 0x20, 0x60, 0x90, 0x40, 0x04, 0x40, 0x04, 0x40 - DB 0x93, 0x60, 0x20, 0x06, 0x40, 0x97, 0x40, 0x04 - DB 0x40, 0x97, 0x40, 0x06, 0x40, 0x94, 0x60, 0x20 - DB 0x08, 0x20, 0x60, 0x91, 0x40, 0x03, 0x20, 0x60 - DB 0x80, 0x40, 0x04, 0x20, 0x60, 0x8D, 0x40, 0x04 - DB 0x40, 0x83, 0x60, 0x20, 0x04, 0x40, 0x8A, 0x60 - DB 0x20, 0x03, 0x20, 0x60, 0x86, 0x60, 0x04, 0x20 - DB 0x60, 0x87, 0x60, 0x04, 0x40, 0x8A, 0x40, 0x04 - DB 0x40, 0x86, 0x60, 0x02, 0x40, 0x8D, 0x60, 0x20 - DB 0x03, 0x86, 0x60, 0x00, 0x20, 0x60, 0x90, 0x40 - DB 0x02, 0x86, 0x60, 0x40, 0x93, 0x60, 0x20, 0x00 - DB 0x9E, 0x40, 0xA3 -; Y Y - DB 0x82, 0x60, 0x02, 0x40, 0x9A, 0x60, 0x04, 0x40 - DB 0x99, 0x40, 0x04, 0x20, 0x60, 0x99, 0x40, 0x04 - DB 0x20, 0x60, 0x99, 0x40, 0x04, 0x40, 0x60, 0x98 - DB 0x60, 0x20, 0x04, 0x40, 0x99, 0x60, 0x20, 0x04 - DB 0x40, 0x99, 0x60, 0x20, 0x0C, 0x92, 0x60, 0x0B - DB 0x91, 0x40, 0x20, 0x0B, 0x8F, 0x40, 0x04, 0x20 - DB 0x68, 0x8D, 0x60, 0x20, 0x03, 0x20, 0x60, 0x95 - DB 0x60, 0x20, 0x04, 0x40, 0x96, 0x40, 0x04, 0x40 - DB 0x96, 0x40, 0x04, 0x20, 0x60, 0x95, 0x60, 0x20 - DB 0x03, 0x20, 0x60, 0x97, 0x60, 0x03, 0x40, 0x99 - DB 0x60, 0x01, 0x40, 0x9B, 0x60, 0x20, 0x60, 0xB9 -; Z Z - DB 0x83, 0x62, 0x91, 0x42, 0x86, 0x60, 0x01, 0x20 - DB 0x8F, 0x60, 0x20, 0x02, 0x86, 0x60, 0x01, 0x20 - DB 0x8E, 0x40, 0x04, 0x86, 0x60, 0x01, 0x20, 0x8C - DB 0x60, 0x20, 0x05, 0x86, 0x60, 0x01, 0x20, 0x8B - DB 0x40, 0x03, 0x20, 0x02, 0x86, 0x60, 0x01, 0x20 - DB 0x89, 0x60, 0x20, 0x03, 0x40, 0x80, 0x02, 0x86 - DB 0x60, 0x01, 0x20, 0x88, 0x40, 0x03, 0x20, 0x60 - DB 0x81, 0x02, 0x86, 0x60, 0x01, 0x20, 0x86, 0x60 - DB 0x20, 0x03, 0x40, 0x83, 0x02, 0x86, 0x60, 0x01 - DB 0x20, 0x85, 0x40, 0x03, 0x20, 0x60, 0x84, 0x02 - DB 0x86, 0x60, 0x01, 0x20, 0x83, 0x60, 0x20, 0x03 - DB 0x40, 0x86, 0x02, 0x86, 0x60, 0x01, 0x20, 0x82 - DB 0x40, 0x03, 0x20, 0x60, 0x87, 0x02, 0x86, 0x60 - DB 0x01, 0x20, 0x80, 0x60, 0x20, 0x03, 0x40, 0x89 - DB 0x02, 0x86, 0x60, 0x01, 0x20, 0x40, 0x03, 0x20 - DB 0x60, 0x8A, 0x02, 0x86, 0x60, 0x06, 0x40, 0x8C - DB 0x02, 0x86, 0x60, 0x04, 0x20, 0x60, 0x8D, 0x02 - DB 0x86, 0x60, 0x03, 0x40, 0x8F, 0x02, 0x86, 0x60 - DB 0x01, 0x20, 0x60, 0x90, 0x02, 0x9C, 0x62, 0xC3 -; [ lsqbracket - DB 0xFF, 0x5F, 0x20, 0x1D, 0x40, 0x20, 0x1D, 0x40 - DB 0x20, 0x00, 0x20, 0x59, 0x01, 0x40, 0x20, 0x00 - DB 0x20, 0x98, 0x40, 0x01, 0x40, 0x20, 0x00, 0x20 - DB 0x98, 0x40, 0x01, 0x40, 0x20, 0x00, 0x20, 0x98 - DB 0x40, 0x01, 0x40, 0x20, 0x00, 0x20, 0x98, 0x40 - DB 0x01, 0x40, 0x20, 0x00, 0x20, 0x98, 0x40, 0x01 - DB 0x41, 0x20, 0x40, 0x98, 0x43, 0xFF, 0xBF -; \ backslash - DB 0xC2, 0x41, 0x60, 0x9C, 0x20, 0x01, 0x20, 0x40 - DB 0x9A, 0x05, 0x40, 0x60, 0x98, 0x40, 0x20, 0x04 - DB 0x20, 0x60, 0x98, 0x60, 0x20, 0x04, 0x20, 0x40 - DB 0x98, 0x60, 0x40, 0x05, 0x40, 0x60, 0x98, 0x40 - DB 0x20, 0x04, 0x20, 0x60, 0x98, 0x60, 0x20, 0x04 - DB 0x20, 0x40, 0x98, 0x60, 0x40, 0x05, 0x40, 0x60 - DB 0x98, 0x40, 0x20, 0x04, 0x20, 0x60, 0x98, 0x60 - DB 0x20, 0x04, 0x20, 0x40, 0x98, 0x60, 0x40, 0x03 - DB 0x20, 0x9B, 0x40, 0x20, 0x00, 0x40, 0x9D, 0x60 - DB 0xFF, 0x83 -; ] rsqbracket - DB 0xDF, 0x42, 0x98, 0x43, 0x20, 0x00, 0x20, 0x98 - DB 0x40, 0x01, 0x40, 0x20, 0x00, 0x20, 0x98, 0x40 - DB 0x01, 0x40, 0x20, 0x00, 0x20, 0x98, 0x40, 0x01 - DB 0x40, 0x20, 0x00, 0x20, 0x98, 0x40, 0x01, 0x40 - DB 0x20, 0x00, 0x20, 0x98, 0x40, 0x01, 0x40, 0x20 - DB 0x00, 0x20, 0x78, 0x40, 0x01, 0x40, 0x20, 0x1D - DB 0x40, 0x20, 0x1D, 0x41, 0x3D, 0x40, 0xFF, 0xDF -; ^ caret - DB 0xAC, 0x60, 0x40, 0x9C, 0x40, 0x01, 0x60, 0x99 - DB 0x40, 0x03, 0x40, 0x97, 0x60, 0x20, 0x02, 0x20 - DB 0x60, 0x96, 0x60, 0x20, 0x02, 0x20, 0x60, 0x97 - DB 0x40, 0x02, 0x20, 0x40, 0x97, 0x60, 0x03, 0x40 - DB 0x99, 0x60, 0x01, 0x40, 0x9B, 0x60, 0x02, 0x40 - DB 0x9B, 0x40, 0x03, 0x40, 0x9A, 0x60, 0x20, 0x02 - DB 0x20, 0x60, 0x9A, 0x60, 0x20, 0x02, 0x20, 0x60 - DB 0x9A, 0x40, 0x03, 0x40, 0x9A, 0x60, 0x20, 0x02 - DB 0x40, 0x9B, 0x60, 0x20, 0x00, 0x9E, 0x60, 0xF0 -; _ underline - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 -; ` backquote - DB 0xFF, 0x81, 0x60, 0x20, 0x9C, 0x40, 0x01, 0x40 - DB 0x9B, 0x60, 0x01, 0x20, 0x9C, 0x40, 0x01, 0x40 - DB 0x9C, 0x01, 0x20, 0x9C, 0x40, 0x01, 0x40, 0x9C - DB 0x20, 0x00, 0x20, 0x9C, 0x60, 0x00, 0x20, 0x9D - DB 0x60, 0xFF, 0xF9 -; a a - DB 0xB6, 0x61, 0x91, 0x60, 0x87, 0x60, 0x20, 0x03 - DB 0x40, 0x8E, 0x60, 0x01, 0x40, 0x84, 0x60, 0x06 - DB 0x60, 0x8D, 0x40, 0x01, 0x85, 0x20, 0x01, 0x21 - DB 0x02, 0x20, 0x8D, 0x20, 0x00, 0x20, 0x84, 0x60 - DB 0x01, 0x40, 0x82, 0x20, 0x01, 0x60, 0x8C, 0x01 - DB 0x40, 0x84, 0x40, 0x00, 0x20, 0x83, 0x40, 0x01 - DB 0x60, 0x8B, 0x60, 0x01, 0x60, 0x84, 0x01, 0x60 - DB 0x83, 0x60, 0x01, 0x60, 0x8B, 0x60, 0x01, 0x60 - DB 0x83, 0x60, 0x01, 0x84, 0x60, 0x01, 0x8C, 0x60 - DB 0x01, 0x60, 0x83, 0x60, 0x01, 0x84, 0x40, 0x00 - DB 0x20, 0x8C, 0x60, 0x01, 0x40, 0x83, 0x40, 0x00 - DB 0x20, 0x84, 0x01, 0x40, 0x8D, 0x01, 0x20, 0x83 - DB 0x40, 0x00, 0x20, 0x83, 0x20, 0x00, 0x20, 0x8E - DB 0x20, 0x01, 0x40, 0x82, 0x40, 0x00, 0x20, 0x81 - DB 0x40, 0x20, 0x00, 0x20, 0x8F, 0x40, 0x03, 0x22 - DB 0x01, 0x20, 0x02, 0x20, 0x42, 0x8E, 0x20, 0x0F - DB 0x8E, 0x60, 0x20, 0x0E, 0x90, 0x60, 0x4D, 0xE3 -; b b - DB 0xC0, 0x60, 0x58, 0x60, 0x84, 0x60, 0x18, 0x20 - DB 0x84, 0x60, 0x19, 0x84, 0x60, 0x29, 0x40, 0x20 - DB 0x03, 0x26, 0x02, 0x8F, 0x20, 0x01, 0x40, 0x60 - DB 0x87, 0x40, 0x01, 0x60, 0x8D, 0x20, 0x00, 0x20 - DB 0x60, 0x89, 0x60, 0x01, 0x60, 0x8C, 0x40, 0x00 - DB 0x20, 0x8B, 0x60, 0x01, 0x60, 0x8C, 0x01, 0x40 - DB 0x8B, 0x60, 0x01, 0x60, 0x8B, 0x60, 0x01, 0x60 - DB 0x8B, 0x40, 0x01, 0x8C, 0x60, 0x01, 0x60, 0x8B - DB 0x20, 0x00, 0x20, 0x8C, 0x60, 0x01, 0x20, 0x8A - DB 0x40, 0x01, 0x40, 0x8D, 0x02, 0x40, 0x88, 0x40 - DB 0x02, 0x60, 0x8D, 0x40, 0x02, 0x20, 0x40, 0x60 - DB 0x82, 0x60, 0x40, 0x20, 0x02, 0x40, 0x8F, 0x20 - DB 0x0C, 0x40, 0x90, 0x60, 0x20, 0x0A, 0x40, 0x93 - DB 0x40, 0x20, 0x05, 0x20, 0x40, 0x98, 0x63, 0xAB -; c c - DB 0xCE, 0x60, 0x40, 0x20, 0x02, 0x20, 0x41, 0x94 - DB 0x60, 0x20, 0x08, 0x20, 0x60, 0x91, 0x40, 0x0C - DB 0x60, 0x8F, 0x40, 0x03, 0x20, 0x40, 0x62, 0x40 - DB 0x04, 0x8F, 0x02, 0x20, 0x60, 0x86, 0x40, 0x02 - DB 0x40, 0x8D, 0x40, 0x01, 0x20, 0x89, 0x20, 0x01 - DB 0x20, 0x8D, 0x20, 0x01, 0x60, 0x8A, 0x02, 0x8D - DB 0x01, 0x20, 0x8B, 0x20, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x20, 0x8B, 0x20, 0x01, 0x8D, 0x01, 0x20 - DB 0x8B, 0x20, 0x00, 0x20, 0x8D, 0x20, 0x01, 0x60 - DB 0x89, 0x60, 0x01, 0x20, 0x8D, 0x40, 0x20, 0x40 - DB 0x60, 0x89, 0x60, 0x20, 0x00, 0x40, 0xE3 -; d d - DB 0xAF, 0x60, 0x40, 0x22, 0x41, 0x60, 0x95, 0x40 - DB 0x08, 0x20, 0x60, 0x91, 0x60, 0x20, 0x0B, 0x40 - DB 0x8F, 0x60, 0x03, 0x21, 0x42, 0x21, 0x03, 0x60 - DB 0x8E, 0x20, 0x01, 0x20, 0x60, 0x86, 0x40, 0x02 - DB 0x20, 0x8D, 0x40, 0x01, 0x20, 0x89, 0x60, 0x02 - DB 0x8D, 0x20, 0x01, 0x8B, 0x40, 0x01, 0x60, 0x8C - DB 0x01, 0x40, 0x8B, 0x60, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x60, 0x8B, 0x60, 0x01, 0x8C, 0x60, 0x01 - DB 0x60, 0x8B, 0x40, 0x00, 0x20, 0x8C, 0x60, 0x01 - DB 0x60, 0x8A, 0x60, 0x01, 0x40, 0x8C, 0x60, 0x01 - DB 0x40, 0x89, 0x40, 0x01, 0x40, 0x8E, 0x01, 0x40 - DB 0x86, 0x60, 0x40, 0x20, 0x01, 0x40, 0x86, 0x60 - DB 0x15, 0x23, 0x84, 0x60, 0x19, 0x84, 0x60, 0x19 - DB 0x85, 0x79, 0xC3 -; e e - DB 0xAF, 0x60, 0x43, 0x61, 0x96, 0x40, 0x20, 0x06 - DB 0x20, 0x60, 0x92, 0x60, 0x20, 0x0A, 0x40, 0x90 - DB 0x60, 0x06, 0x21, 0x04, 0x40, 0x8F, 0x02, 0x20 - DB 0x60, 0x80, 0x01, 0x60, 0x81, 0x60, 0x20, 0x02 - DB 0x60, 0x8D, 0x40, 0x01, 0x40, 0x82, 0x01, 0x60 - DB 0x83, 0x20, 0x01, 0x40, 0x8D, 0x01, 0x20, 0x83 - DB 0x01, 0x60, 0x84, 0x01, 0x20, 0x8C, 0x60, 0x01 - DB 0x40, 0x83, 0x01, 0x60, 0x84, 0x40, 0x01, 0x8C - DB 0x60, 0x01, 0x60, 0x83, 0x01, 0x60, 0x84, 0x60 - DB 0x01, 0x60, 0x8B, 0x60, 0x01, 0x60, 0x83, 0x01 - DB 0x60, 0x84, 0x60, 0x01, 0x60, 0x8B, 0x60, 0x01 - DB 0x40, 0x83, 0x01, 0x60, 0x84, 0x60, 0x01, 0x60 - DB 0x8C, 0x20, 0x01, 0x60, 0x82, 0x01, 0x60, 0x84 - DB 0x40, 0x01, 0x8D, 0x40, 0x02, 0x60, 0x81, 0x01 - DB 0x60, 0x84, 0x40, 0x01, 0x8E, 0x20, 0x03, 0x20 - DB 0x01, 0x60, 0x84, 0x20, 0x00, 0x20, 0x8F, 0x20 - DB 0x05, 0x60, 0x84, 0x01, 0x40, 0x90, 0x40, 0x04 - DB 0x60, 0x83, 0x60, 0x21, 0x60, 0x92, 0x60, 0x42 - DB 0x60, 0xCB -; f f - DB 0xAA, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x60 - DB 0x97, 0x63, 0x40, 0x01, 0x40, 0x6C, 0x87, 0x60 - DB 0x20, 0x15, 0x86, 0x40, 0x17, 0x85, 0x60, 0x18 - DB 0x85, 0x20, 0x01, 0x20, 0x60, 0x83, 0x60, 0x01 - DB 0x60, 0x91, 0x60, 0x01, 0x20, 0x85, 0x60, 0x01 - DB 0x60, 0x91, 0x40, 0x01, 0x60, 0x85, 0x60, 0x01 - DB 0x60, 0x91, 0x40, 0x01, 0x86, 0x60, 0x01, 0x60 - DB 0x91, 0x40, 0x01, 0x86, 0x60, 0x01, 0x60, 0x91 - DB 0x40, 0x01, 0x86, 0x60, 0x01, 0x60, 0x91, 0x60 - DB 0x01, 0x60, 0x85, 0x60, 0x01, 0x60, 0x91, 0x60 - DB 0x01, 0x40, 0x85, 0x60, 0x21, 0x60, 0x92, 0x61 - DB 0x9B -; g g - DB 0x8C, 0x60, 0x41, 0x21, 0x40, 0x60, 0x88, 0x40 - DB 0x01, 0x8B, 0x40, 0x06, 0x40, 0x80, 0x60, 0x20 - DB 0x01, 0x40, 0x80, 0x20, 0x02, 0x8A, 0x40, 0x08 - DB 0x40, 0x20, 0x03, 0x20, 0x03, 0x89, 0x60, 0x02 - DB 0x20, 0x42, 0x0A, 0x20, 0x60, 0x8A, 0x20, 0x01 - DB 0x40, 0x84, 0x20, 0x02, 0x41, 0x02, 0x20, 0x8B - DB 0x60, 0x01, 0x20, 0x86, 0x01, 0x40, 0x81, 0x20 - DB 0x01, 0x60, 0x8B, 0x40, 0x01, 0x60, 0x86, 0x20 - DB 0x00, 0x20, 0x81, 0x40, 0x01, 0x60, 0x8B, 0x40 - DB 0x01, 0x87, 0x40, 0x00, 0x20, 0x81, 0x40, 0x01 - DB 0x60, 0x8B, 0x40, 0x01, 0x87, 0x40, 0x00, 0x20 - DB 0x81, 0x40, 0x01, 0x60, 0x8B, 0x40, 0x01, 0x60 - DB 0x86, 0x20, 0x00, 0x40, 0x81, 0x40, 0x01, 0x60 - DB 0x8B, 0x60, 0x01, 0x40, 0x85, 0x60, 0x01, 0x40 - DB 0x81, 0x40, 0x01, 0x60, 0x8C, 0x02, 0x40, 0x83 - DB 0x60, 0x20, 0x01, 0x60, 0x81, 0x40, 0x01, 0x60 - DB 0x8C, 0x03, 0x20, 0x42, 0x02, 0x40, 0x82, 0x40 - DB 0x01, 0x40, 0x8C, 0x09, 0x20, 0x83, 0x60, 0x02 - DB 0x40, 0x8B, 0x01, 0x21, 0x04, 0x40, 0x85, 0x20 - DB 0x04, 0x89, 0x01, 0x40, 0x80, 0x60, 0x41, 0x60 - DB 0x87, 0x60, 0x04, 0x89, 0x01, 0x40, 0x8D, 0x60 - DB 0x20, 0x02, 0x89, 0x41, 0x60, 0x8F, 0x62, 0xBF -; h h - DB 0xA0, 0x60, 0x59, 0x84, 0x60, 0x19, 0x84, 0x60 - DB 0x19, 0x84, 0x60, 0x29, 0x40, 0x20, 0x03, 0x29 - DB 0x8E, 0x60, 0x20, 0x01, 0x40, 0x60, 0x98, 0x60 - DB 0x01, 0x20, 0x60, 0x9A, 0x20, 0x01, 0x9B, 0x60 - DB 0x01, 0x40, 0x9B, 0x40, 0x01, 0x60, 0x9B, 0x40 - DB 0x01, 0x60, 0x9B, 0x40, 0x01, 0x20, 0x9B, 0x60 - DB 0x02, 0x20, 0x40, 0x6C, 0x8D, 0x20, 0x10, 0x8D - DB 0x60, 0x10, 0x8F, 0x40, 0x20, 0x0D, 0xFF, 0x83 -; i i - DB 0xA9, 0x62, 0x8B, 0x40, 0x21, 0x8D, 0x01, 0x40 - DB 0x8B, 0x40, 0x01, 0x8D, 0x01, 0x40, 0x8B, 0x40 - DB 0x01, 0x8D, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x8D - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x87, 0x60, 0x84 - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x85, 0x60, 0x02 - DB 0x40, 0x82, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x85 - DB 0x20, 0x03, 0x82, 0x11, 0x85, 0x04, 0x60, 0x81 - DB 0x11, 0x85, 0x20, 0x03, 0x82, 0x11, 0x86, 0x20 - DB 0x00, 0x20, 0x60, 0x82, 0x6E, 0x40, 0x01, 0x9C - DB 0x40, 0x01, 0x9C, 0x40, 0x01, 0x9C, 0x40, 0x01 - DB 0x9C, 0x40, 0x01, 0x9C, 0x40, 0x01, 0x9C, 0x62 - DB 0xC3 -; j j - DB 0xA9, 0x41, 0x60, 0x9C, 0x01, 0x40, 0x9C, 0x01 - DB 0x40, 0x9C, 0x01, 0x40, 0x9C, 0x01, 0x40, 0x9C - DB 0x01, 0x40, 0x9C, 0x01, 0x40, 0x9C, 0x01, 0x40 - DB 0x95, 0x60, 0x40, 0x60, 0x83, 0x01, 0x40, 0x94 - DB 0x60, 0x02, 0x40, 0x82, 0x01, 0x40, 0x71, 0x40 - DB 0x81, 0x20, 0x03, 0x60, 0x81, 0x15, 0x81, 0x04 - DB 0x60, 0x81, 0x15, 0x81, 0x40, 0x02, 0x20, 0x82 - DB 0x14, 0x20, 0x82, 0x40, 0x20, 0x40, 0xFF, 0xB9 -; k k - DB 0xA0, 0x60, 0x59, 0x84, 0x60, 0x19, 0x84, 0x60 - DB 0x19, 0x84, 0x60, 0x2F, 0x00, 0x28, 0x94, 0x20 - DB 0x00, 0x40, 0x9B, 0x20, 0x02, 0x40, 0x99, 0x20 - DB 0x04, 0x20, 0x97, 0x20, 0x02, 0x20, 0x02, 0x20 - DB 0x60, 0x94, 0x20, 0x02, 0x60, 0x80, 0x40, 0x03 - DB 0x60, 0x91, 0x60, 0x03, 0x60, 0x82, 0x40, 0x03 - DB 0x40, 0x8F, 0x60, 0x03, 0x60, 0x84, 0x40, 0x03 - DB 0x40, 0x8E, 0x03, 0x60, 0x86, 0x60, 0x03, 0x40 - DB 0x8D, 0x02, 0x60, 0x88, 0x60, 0x03, 0x8D, 0x01 - DB 0x60, 0x8A, 0x60, 0x20, 0x01, 0x8D, 0x00, 0x60 - DB 0x8D, 0x20, 0x00, 0x8D, 0x60, 0x8F, 0x20, 0xE3 -; l l - DB 0xA0, 0x60, 0x01, 0x60, 0x93, 0x40, 0x01, 0x84 - DB 0x60, 0x01, 0x60, 0x93, 0x40, 0x01, 0x84, 0x60 - DB 0x01, 0x60, 0x93, 0x40, 0x01, 0x84, 0x60, 0x01 - DB 0x60, 0x93, 0x40, 0x01, 0x84, 0x60, 0x01, 0x60 - DB 0x93, 0x40, 0x01, 0x84, 0x60, 0x01, 0x60, 0x93 - DB 0x40, 0x01, 0x84, 0x60, 0x01, 0x54, 0x20, 0x01 - DB 0x84, 0x60, 0x19, 0x84, 0x60, 0x19, 0x84, 0x60 - DB 0x37, 0x01, 0x9C, 0x40, 0x01, 0x9C, 0x40, 0x01 - DB 0x9C, 0x40, 0x01, 0x9C, 0x40, 0x01, 0x9C, 0x40 - DB 0x01, 0x9C, 0x40, 0x01, 0x9C, 0x62, 0xC3 -; m m - DB 0x89, 0x11, 0x8D, 0x11, 0x8D, 0x61, 0x40, 0x20 - DB 0x01, 0x20, 0x4A, 0x8E, 0x40, 0x01, 0x40, 0x9A - DB 0x40, 0x00, 0x20, 0x9C, 0x01, 0x60, 0x9B, 0x60 - DB 0x01, 0x40, 0x9B, 0x60, 0x02, 0x20, 0x4D, 0x8D - DB 0x40, 0x10, 0x8E, 0x40, 0x21, 0x0D, 0x8F, 0x40 - DB 0x01, 0x20, 0x41, 0x69, 0x8D, 0x60, 0x01, 0x20 - DB 0x60, 0x9A, 0x20, 0x00, 0x20, 0x9B, 0x60, 0x01 - DB 0x60, 0x9B, 0x60, 0x01, 0x20, 0x60, 0x9B, 0x11 - DB 0x8D, 0x60, 0x10, 0x8F, 0x41, 0x2D, 0xC3 -; n n - DB 0xA9, 0x51, 0x8D, 0x11, 0x8D, 0x11, 0x8D, 0x42 - DB 0x20, 0x02, 0x2A, 0x8E, 0x60, 0x20, 0x01, 0x40 - DB 0x60, 0x99, 0x20, 0x00, 0x20, 0x60, 0x9A, 0x40 - DB 0x01, 0x9C, 0x01, 0x40, 0x9B, 0x60, 0x01, 0x60 - DB 0x9B, 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x20 - DB 0x9C, 0x02, 0x20, 0x40, 0x6C, 0x8D, 0x40, 0x10 - DB 0x8E, 0x20, 0x0F, 0x8F, 0x40, 0x20, 0x0D, 0xFF - DB 0x83 -; o o - DB 0x8E, 0x60, 0x41, 0x22, 0x41, 0x95, 0x60, 0x40 - DB 0x08, 0x40, 0x92, 0x60, 0x0B, 0x20, 0x60, 0x8F - DB 0x60, 0x03, 0x20, 0x43, 0x20, 0x03, 0x20, 0x8F - DB 0x02, 0x20, 0x60, 0x85, 0x60, 0x20, 0x02, 0x40 - DB 0x8D, 0x40, 0x01, 0x20, 0x89, 0x40, 0x01, 0x20 - DB 0x8D, 0x20, 0x01, 0x60, 0x8A, 0x02, 0x8D, 0x01 - DB 0x20, 0x8B, 0x40, 0x01, 0x60, 0x8B, 0x60, 0x01 - DB 0x40, 0x8B, 0x40, 0x01, 0x60, 0x8B, 0x60, 0x01 - DB 0x40, 0x8B, 0x40, 0x01, 0x60, 0x8B, 0x60, 0x01 - DB 0x20, 0x8B, 0x20, 0x01, 0x8D, 0x02, 0x60, 0x89 - DB 0x60, 0x01, 0x20, 0x8D, 0x20, 0x01, 0x20, 0x88 - DB 0x60, 0x02, 0x40, 0x8D, 0x60, 0x02, 0x20, 0x40 - DB 0x84, 0x60, 0x40, 0x02, 0x20, 0x8F, 0x40, 0x04 - DB 0x23, 0x03, 0x20, 0x91, 0x40, 0x0A, 0x20, 0x93 - DB 0x60, 0x20, 0x06, 0x20, 0x40, 0x96, 0x61, 0x42 - DB 0x61, 0xC9 -; p p - DB 0xC9, 0x55, 0x89, 0x15, 0x89, 0x15, 0x89, 0x42 - DB 0x20, 0x03, 0x26, 0x02, 0x23, 0x8A, 0x60, 0x20 - DB 0x01, 0x40, 0x60, 0x87, 0x40, 0x01, 0x8E, 0x20 - DB 0x00, 0x20, 0x60, 0x89, 0x40, 0x01, 0x60, 0x8C - DB 0x40, 0x00, 0x20, 0x8B, 0x60, 0x01, 0x60, 0x8C - DB 0x01, 0x40, 0x8B, 0x60, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x60, 0x8B, 0x40, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x60, 0x8B, 0x20, 0x01, 0x8C, 0x60, 0x01 - DB 0x20, 0x8A, 0x60, 0x01, 0x40, 0x8D, 0x02, 0x40 - DB 0x88, 0x60, 0x02, 0x60, 0x8D, 0x40, 0x02, 0x20 - DB 0x40, 0x60, 0x82, 0x60, 0x40, 0x20, 0x02, 0x40 - DB 0x8F, 0x20, 0x0C, 0x20, 0x90, 0x60, 0x20, 0x0A - DB 0x40, 0x93, 0x40, 0x20, 0x05, 0x20, 0x40, 0x60 - DB 0x97, 0x63, 0xAB -; q q - DB 0xAF, 0x60, 0x40, 0x23, 0x40, 0x60, 0x95, 0x40 - DB 0x08, 0x20, 0x60, 0x91, 0x60, 0x20, 0x0B, 0x40 - DB 0x8F, 0x60, 0x03, 0x21, 0x42, 0x21, 0x03, 0x60 - DB 0x8E, 0x20, 0x01, 0x20, 0x60, 0x86, 0x40, 0x02 - DB 0x20, 0x8D, 0x60, 0x01, 0x20, 0x89, 0x60, 0x02 - DB 0x8D, 0x20, 0x01, 0x8B, 0x40, 0x01, 0x60, 0x8C - DB 0x01, 0x40, 0x8B, 0x60, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x60, 0x8B, 0x60, 0x01, 0x8C, 0x60, 0x01 - DB 0x60, 0x8B, 0x40, 0x00, 0x20, 0x8C, 0x60, 0x01 - DB 0x60, 0x8A, 0x60, 0x01, 0x40, 0x8C, 0x60, 0x01 - DB 0x60, 0x89, 0x40, 0x01, 0x40, 0x8E, 0x01, 0x40 - DB 0x86, 0x60, 0x40, 0x20, 0x01, 0x40, 0x8F, 0x0D - DB 0x21, 0x05, 0x89, 0x15, 0x89, 0x20, 0x14, 0x89 - DB 0x75, 0xBF -; r r - DB 0xA9, 0x21, 0x40, 0x8B, 0x40, 0x21, 0x8D, 0x01 - DB 0x40, 0x8B, 0x40, 0x01, 0x8D, 0x01, 0x40, 0x8B - DB 0x40, 0x01, 0x8D, 0x01, 0x40, 0x8B, 0x40, 0x01 - DB 0x8D, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x8D, 0x01 - DB 0x20, 0x4B, 0x20, 0x01, 0x8D, 0x11, 0x8D, 0x11 - DB 0x8D, 0x43, 0x20, 0x02, 0x22, 0x43, 0x20, 0x01 - DB 0x8F, 0x40, 0x02, 0x40, 0x60, 0x86, 0x40, 0x01 - DB 0x8E, 0x40, 0x01, 0x20, 0x89, 0x40, 0x01, 0x8D - DB 0x40, 0x01, 0x40, 0x8A, 0x40, 0x01, 0x8D, 0x02 - DB 0x8B, 0x40, 0x01, 0x8C, 0x60, 0x01, 0x40, 0x8B - DB 0x40, 0x21, 0x8C, 0x40, 0x01, 0x40, 0x9B, 0x40 - DB 0x01, 0x40, 0x9B, 0x40, 0x01, 0x20, 0x9B, 0x60 - DB 0x00, 0x20, 0x40, 0xB2 -; s s - DB 0xCD, 0x61, 0x88, 0x61, 0x40, 0x8F, 0x40, 0x03 - DB 0x40, 0x85, 0x60, 0x01, 0x20, 0x8E, 0x20, 0x05 - DB 0x40, 0x85, 0x20, 0x01, 0x8D, 0x40, 0x07, 0x60 - DB 0x84, 0x40, 0x01, 0x60, 0x8C, 0x20, 0x01, 0x40 - DB 0x60, 0x40, 0x02, 0x40, 0x84, 0x60, 0x01, 0x40 - DB 0x8B, 0x60, 0x01, 0x40, 0x82, 0x40, 0x01, 0x20 - DB 0x85, 0x01, 0x40, 0x8B, 0x60, 0x01, 0x60, 0x82 - DB 0x60, 0x02, 0x85, 0x01, 0x40, 0x8B, 0x40, 0x01 - DB 0x84, 0x20, 0x01, 0x60, 0x84, 0x01, 0x40, 0x8B - DB 0x40, 0x01, 0x84, 0x40, 0x01, 0x40, 0x83, 0x60 - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x84, 0x40, 0x01 - DB 0x20, 0x83, 0x40, 0x01, 0x60, 0x8B, 0x40, 0x01 - DB 0x60, 0x84, 0x02, 0x40, 0x82, 0x20, 0x01, 0x8C - DB 0x60, 0x01, 0x60, 0x84, 0x20, 0x02, 0x41, 0x20 - DB 0x01, 0x40, 0x8C, 0x60, 0x01, 0x40, 0x84, 0x60 - DB 0x07, 0x60, 0x8D, 0x20, 0x41, 0x85, 0x40, 0x05 - DB 0x40, 0x98, 0x40, 0x20, 0x01, 0x20, 0x60, 0xE5 -; t t - DB 0x89, 0x41, 0x60, 0x9C, 0x01, 0x40, 0x9C, 0x01 - DB 0x40, 0x9C, 0x01, 0x40, 0x9C, 0x01, 0x40, 0x9C - DB 0x01, 0x40, 0x96, 0x40, 0x24, 0x01, 0x2B, 0x40 - DB 0x8A, 0x15, 0x40, 0x87, 0x60, 0x16, 0x60, 0x86 - DB 0x60, 0x45, 0x01, 0x20, 0x49, 0x20, 0x02, 0x20 - DB 0x8D, 0x01, 0x40, 0x8A, 0x40, 0x02, 0x8D, 0x01 - DB 0x40, 0x8B, 0x20, 0x01, 0x60, 0x8C, 0x01, 0x40 - DB 0x8B, 0x40, 0x01, 0x60, 0x8C, 0x01, 0x40, 0x8B - DB 0x40, 0x01, 0x60, 0x8C, 0x01, 0x40, 0x8B, 0x40 - DB 0x01, 0x60, 0x8C, 0x01, 0x40, 0x8B, 0x40, 0x01 - DB 0x8D, 0x01, 0x40, 0x8B, 0x20, 0x00, 0x20, 0x8D - DB 0x62, 0x8B, 0x60, 0x41, 0xC3 -; u u - DB 0xC9, 0x4D, 0x60, 0x90, 0x0F, 0x40, 0x8E, 0x10 - DB 0x60, 0x8D, 0x2D, 0x02, 0x20, 0x9B, 0x60, 0x02 - DB 0x60, 0x9B, 0x40, 0x01, 0x60, 0x9B, 0x60, 0x01 - DB 0x60, 0x9B, 0x60, 0x01, 0x9C, 0x20, 0x00, 0x20 - DB 0x9B, 0x40, 0x01, 0x60, 0x99, 0x60, 0x20, 0x01 - DB 0x40, 0x8E, 0x69, 0x40, 0x20, 0x01, 0x20, 0x60 - DB 0x8F, 0x11, 0x8D, 0x11, 0x8D, 0x11, 0xE3 -; v v - DB 0xA9, 0x00, 0x40, 0x60, 0x9C, 0x02, 0x20, 0x40 - DB 0x9A, 0x05, 0x40, 0x60, 0x97, 0x40, 0x06, 0x20 - DB 0x40, 0x97, 0x40, 0x20, 0x06, 0x40, 0x60, 0x96 - DB 0x60, 0x40, 0x20, 0x05, 0x20, 0x40, 0x97, 0x60 - DB 0x40, 0x06, 0x20, 0x60, 0x97, 0x40, 0x20, 0x05 - DB 0x99, 0x60, 0x40, 0x20, 0x02, 0x98, 0x60, 0x40 - DB 0x20, 0x03, 0x96, 0x40, 0x20, 0x05, 0x20, 0x93 - DB 0x60, 0x40, 0x06, 0x40, 0x60, 0x91, 0x60, 0x40 - DB 0x20, 0x05, 0x20, 0x40, 0x92, 0x40, 0x20, 0x06 - DB 0x40, 0x60, 0x93, 0x06, 0x20, 0x40, 0x96, 0x04 - DB 0x40, 0x60, 0x98, 0x01, 0x20, 0x60, 0x9B, 0x40 - DB 0x60, 0xB3 -; w w - DB 0x89, 0x08, 0x20, 0x41, 0x61, 0x91, 0x0E, 0x21 - DB 0x40, 0x8E, 0x61, 0x41, 0x21, 0x0A, 0x95, 0x61 - DB 0x41, 0x21, 0x03, 0x98, 0x60, 0x40, 0x20, 0x03 - DB 0x96, 0x40, 0x20, 0x04, 0x20, 0x40, 0x93, 0x40 - DB 0x20, 0x04, 0x20, 0x40, 0x60, 0x93, 0x40, 0x05 - DB 0x40, 0x60, 0x96, 0x40, 0x03, 0x60, 0x99, 0x40 - DB 0x04, 0x20, 0x40, 0x98, 0x40, 0x20, 0x05, 0x40 - DB 0x60, 0x97, 0x60, 0x40, 0x05, 0x20, 0x40, 0x60 - DB 0x97, 0x40, 0x20, 0x05, 0x99, 0x60, 0x40, 0x03 - DB 0x93, 0x61, 0x41, 0x21, 0x05, 0x8D, 0x41, 0x21 - DB 0x0D, 0x8D, 0x0B, 0x20, 0x41, 0x61, 0x8E, 0x04 - DB 0x21, 0x41, 0x60, 0x95, 0x20, 0x40, 0x61, 0xB1 -; x x - DB 0x89, 0x20, 0x8E, 0x60, 0x00, 0x8D, 0x00, 0x20 - DB 0x60, 0x8B, 0x40, 0x01, 0x8D, 0x02, 0x40, 0x89 - DB 0x40, 0x02, 0x8D, 0x03, 0x40, 0x87, 0x20, 0x02 - DB 0x20, 0x8D, 0x60, 0x03, 0x20, 0x84, 0x60, 0x03 - DB 0x40, 0x8F, 0x60, 0x20, 0x03, 0x60, 0x81, 0x40 - DB 0x03, 0x40, 0x92, 0x40, 0x03, 0x41, 0x02, 0x20 - DB 0x60, 0x94, 0x60, 0x06, 0x40, 0x97, 0x60, 0x20 - DB 0x03, 0x40, 0x99, 0x20, 0x03, 0x20, 0x60, 0x96 - DB 0x60, 0x20, 0x06, 0x40, 0x94, 0x40, 0x03, 0x41 - DB 0x03, 0x40, 0x92, 0x40, 0x02, 0x20, 0x60, 0x81 - DB 0x60, 0x03, 0x20, 0x60, 0x8E, 0x60, 0x20, 0x02 - DB 0x20, 0x84, 0x60, 0x20, 0x03, 0x60, 0x8D, 0x03 - DB 0x40, 0x87, 0x20, 0x03, 0x8D, 0x02, 0x60, 0x89 - DB 0x40, 0x02, 0x8D, 0x00, 0x20, 0x8C, 0x60, 0x01 - DB 0x8D, 0x40, 0x8E, 0x60, 0x20, 0xC3 -; y y - DB 0x89, 0x20, 0x40, 0x9D, 0x02, 0x40, 0x60, 0x9A - DB 0x04, 0x20, 0x40, 0x98, 0x20, 0x06, 0x40, 0x60 - DB 0x96, 0x60, 0x40, 0x06, 0x20, 0x40, 0x97, 0x40 - DB 0x20, 0x06, 0x40, 0x60, 0x85, 0x60, 0x8F, 0x60 - DB 0x40, 0x20, 0x05, 0x20, 0x40, 0x81, 0x40, 0x20 - DB 0x00, 0x92, 0x60, 0x40, 0x0A, 0x95, 0x41, 0x07 - DB 0x94, 0x60, 0x40, 0x20, 0x04, 0x20, 0x40, 0x93 - DB 0x40, 0x20, 0x05, 0x40, 0x60, 0x92, 0x60, 0x40 - DB 0x05, 0x20, 0x40, 0x92, 0x60, 0x40, 0x20, 0x05 - DB 0x20, 0x60, 0x92, 0x40, 0x20, 0x05, 0x20, 0x40 - DB 0x60, 0x93, 0x06, 0x20, 0x60, 0x96, 0x03, 0x20 - DB 0x40, 0x60, 0x98, 0x01, 0x20, 0x60, 0x9B, 0x40 - DB 0x60, 0xD3 -; z z - DB 0xA9, 0x62, 0x8B, 0x60, 0x41, 0x8D, 0x01, 0x20 - DB 0x8A, 0x40, 0x02, 0x8D, 0x01, 0x20, 0x89, 0x20 - DB 0x03, 0x8D, 0x01, 0x20, 0x87, 0x60, 0x20, 0x04 - DB 0x8D, 0x01, 0x20, 0x86, 0x40, 0x06, 0x8D, 0x01 - DB 0x20, 0x85, 0x40, 0x03, 0x40, 0x20, 0x01, 0x8D - DB 0x01, 0x20, 0x84, 0x20, 0x02, 0x20, 0x60, 0x80 - DB 0x02, 0x8D, 0x01, 0x20, 0x82, 0x60, 0x20, 0x02 - DB 0x20, 0x82, 0x02, 0x8D, 0x01, 0x20, 0x81, 0x40 - DB 0x03, 0x40, 0x83, 0x02, 0x8D, 0x01, 0x20, 0x80 - DB 0x40, 0x03, 0x60, 0x84, 0x02, 0x8D, 0x01, 0x21 - DB 0x02, 0x20, 0x60, 0x85, 0x02, 0x8D, 0x05, 0x20 - DB 0x87, 0x02, 0x8D, 0x04, 0x40, 0x88, 0x02, 0x8D - DB 0x03, 0x60, 0x89, 0x02, 0x8D, 0x01, 0x20, 0x60 - DB 0x8A, 0x02, 0x9C, 0x62, 0xE3 -; { lbrace - DB 0xAC, 0x40, 0x20, 0x40, 0x9C, 0x40, 0x00, 0x20 - DB 0x9C, 0x20, 0x01, 0x9C, 0x20, 0x01, 0x60, 0x9A - DB 0x60, 0x00, 0x20, 0x00, 0x20, 0x93, 0x65, 0x40 - DB 0x01, 0x40, 0x01, 0x20, 0x68, 0x86, 0x60, 0x20 - DB 0x09, 0x60, 0x20, 0x0B, 0x40, 0x83, 0x40, 0x0A - DB 0x40, 0x80, 0x60, 0x0C, 0x20, 0x81, 0x60, 0x03 - DB 0x25, 0x40, 0x60, 0x82, 0x60, 0x40, 0x28, 0x02 - DB 0x40, 0x80, 0x40, 0x01, 0x40, 0x96, 0x60, 0x02 - DB 0x80, 0x20, 0x00, 0x20, 0x98, 0x60, 0x01, 0x60 - DB 0x01, 0x40, 0x99, 0x01, 0x40, 0x01, 0x60, 0x99 - DB 0x20, 0x00, 0x40, 0x01, 0x60, 0x99, 0x20, 0x00 - DB 0x40, 0x61, 0x9A, 0x62, 0xFF -; | bar - DB 0xFF, 0xFF, 0x1F, 0x1F, 0x5F, 0xFF, 0xFF, 0x9F -; } rbrace - DB 0xBF, 0x41, 0x60, 0x99, 0x41, 0x60, 0x01, 0x60 - DB 0x99, 0x20, 0x00, 0x40, 0x01, 0x60, 0x99, 0x20 - DB 0x00, 0x40, 0x01, 0x40, 0x99, 0x01, 0x40, 0x20 - DB 0x00, 0x20, 0x98, 0x40, 0x01, 0x60, 0x40, 0x01 - DB 0x20, 0x60, 0x94, 0x60, 0x40, 0x02, 0x81, 0x09 - DB 0x20, 0x40, 0x82, 0x60, 0x20, 0x0B, 0x40, 0x81 - DB 0x60, 0x0A, 0x40, 0x80, 0x40, 0x0C, 0x40, 0x83 - DB 0x60, 0x40, 0x20, 0x08, 0x60, 0x0B, 0x20, 0x40 - DB 0x8D, 0x60, 0x20, 0x00, 0x20, 0x01, 0x40, 0x99 - DB 0x60, 0x02, 0x40, 0x9B, 0x20, 0x01, 0x9C, 0x20 - DB 0x00, 0x20, 0x9C, 0x40, 0x00, 0x20, 0x9C, 0x60 - DB 0x41, 0xEF -; ~ tilde - DB 0x8A, 0x60, 0x9B, 0x60, 0x20, 0x01, 0x60, 0x99 - DB 0x40, 0x03, 0x60, 0x99, 0x02, 0x40, 0x60, 0x99 - DB 0x40, 0x01, 0x60, 0x9B, 0x40, 0x01, 0x9C, 0x40 - DB 0x01, 0x60, 0x9C, 0x02, 0x60, 0x9B, 0x40, 0x02 - DB 0x40, 0x9B, 0x40, 0x02, 0x60, 0x9B, 0x60, 0x01 - DB 0x20, 0x9C, 0x40, 0x01, 0x9C, 0x40, 0x01, 0x9B - DB 0x60, 0x01, 0x20, 0x99, 0x40, 0x20, 0x02, 0x60 - DB 0x99, 0x20, 0x02, 0x40, 0x9A, 0x40, 0x20, 0x40 - DB 0x60, 0xF4 -; 7F - DB 0xC4, 0x40, 0x20, 0x01, 0x20, 0x40, 0x60, 0x97 - DB 0x20, 0x06, 0x40, 0x95, 0x20, 0x08, 0x60, 0x93 - DB 0x40, 0x01, 0x20, 0x60, 0x81, 0x60, 0x20, 0x01 - DB 0x20, 0x93, 0x20, 0x00, 0x20, 0x85, 0x20, 0x01 - DB 0x60, 0x91, 0x60, 0x01, 0x40, 0x85, 0x60, 0x01 - DB 0x40, 0x91, 0x60, 0x01, 0x60, 0x86, 0x01, 0x40 - DB 0x91, 0x60, 0x01, 0x60, 0x86, 0x01, 0x40, 0x91 - DB 0x60, 0x01, 0x40, 0x85, 0x40, 0x01, 0x60, 0x92 - DB 0x20, 0x01, 0x60, 0x83, 0x60, 0x01, 0x20, 0x93 - DB 0x40, 0x02, 0x20, 0x41, 0x20, 0x02, 0x60, 0x94 - DB 0x40, 0x07, 0x40, 0x96, 0x40, 0x05, 0x40, 0x99 - DB 0x60, 0x41, 0x60, 0xFF, 0x95 -; 80 - DB 0xAE, 0x60, 0x41, 0x22, 0x41, 0x95, 0x60, 0x40 - DB 0x08, 0x40, 0x8A, 0x60, 0x86, 0x60, 0x0B, 0x20 - DB 0x60, 0x86, 0x60, 0x01, 0x20, 0x84, 0x60, 0x03 - DB 0x20, 0x43, 0x20, 0x03, 0x20, 0x86, 0x20, 0x02 - DB 0x40, 0x83, 0x02, 0x20, 0x60, 0x85, 0x60, 0x20 - DB 0x02, 0x40, 0x85, 0x40, 0x02, 0x40, 0x82, 0x40 - DB 0x01, 0x20, 0x89, 0x40, 0x01, 0x20, 0x86, 0x20 - DB 0x00, 0x40, 0x83, 0x20, 0x01, 0x60, 0x8A, 0x02 - DB 0x8D, 0x01, 0x20, 0x8B, 0x40, 0x01, 0x60, 0x8B - DB 0x60, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x60, 0x8B - DB 0x60, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x60, 0x85 - DB 0x60, 0x40, 0x60, 0x82, 0x60, 0x01, 0x20, 0x8B - DB 0x20, 0x01, 0x85, 0x60, 0x02, 0x60, 0x82, 0x02 - DB 0x60, 0x89, 0x60, 0x01, 0x20, 0x85, 0x20, 0x02 - DB 0x40, 0x82, 0x20, 0x01, 0x20, 0x88, 0x60, 0x02 - DB 0x40, 0x85, 0x40, 0x02, 0x60, 0x82, 0x60, 0x02 - DB 0x20, 0x40, 0x84, 0x60, 0x40, 0x02, 0x20, 0x87 - DB 0x40, 0x20, 0x60, 0x84, 0x40, 0x04, 0x23, 0x03 - DB 0x20, 0x91, 0x40, 0x0A, 0x20, 0x93, 0x60, 0x20 - DB 0x06, 0x20, 0x40, 0x96, 0x61, 0x42, 0x61, 0xA9 -; 81 - DB 0xB6, 0x61, 0x91, 0x60, 0x87, 0x60, 0x20, 0x03 - DB 0x40, 0x88, 0x60, 0x84, 0x60, 0x01, 0x40, 0x84 - DB 0x60, 0x06, 0x60, 0x85, 0x60, 0x01, 0x20, 0x83 - DB 0x40, 0x01, 0x85, 0x20, 0x01, 0x21, 0x02, 0x20 - DB 0x85, 0x20, 0x02, 0x40, 0x82, 0x20, 0x00, 0x20 - DB 0x84, 0x60, 0x01, 0x40, 0x82, 0x20, 0x01, 0x60 - DB 0x84, 0x40, 0x02, 0x40, 0x82, 0x01, 0x40, 0x84 - DB 0x40, 0x00, 0x20, 0x83, 0x40, 0x01, 0x60, 0x85 - DB 0x20, 0x00, 0x40, 0x82, 0x60, 0x01, 0x60, 0x84 - DB 0x01, 0x60, 0x83, 0x60, 0x01, 0x60, 0x8B, 0x60 - DB 0x01, 0x60, 0x83, 0x60, 0x01, 0x84, 0x60, 0x01 - DB 0x8C, 0x60, 0x01, 0x60, 0x83, 0x60, 0x01, 0x84 - DB 0x40, 0x00, 0x20, 0x8C, 0x60, 0x01, 0x40, 0x83 - DB 0x40, 0x00, 0x20, 0x84, 0x01, 0x40, 0x86, 0x60 - DB 0x40, 0x60, 0x83, 0x01, 0x20, 0x83, 0x40, 0x00 - DB 0x20, 0x83, 0x20, 0x00, 0x20, 0x86, 0x60, 0x02 - DB 0x60, 0x82, 0x20, 0x01, 0x40, 0x82, 0x40, 0x00 - DB 0x20, 0x81, 0x40, 0x20, 0x00, 0x20, 0x87, 0x20 - DB 0x02, 0x40, 0x82, 0x40, 0x03, 0x22, 0x01, 0x20 - DB 0x02, 0x20, 0x42, 0x85, 0x40, 0x02, 0x60, 0x83 - DB 0x20, 0x0F, 0x86, 0x40, 0x20, 0x60, 0x84, 0x60 - DB 0x20, 0x0E, 0x90, 0x60, 0x4D, 0xE3 -; 82 - DB 0xC9, 0x4D, 0x60, 0x8A, 0x60, 0x84, 0x0F, 0x40 - DB 0x86, 0x60, 0x01, 0x20, 0x83, 0x10, 0x60, 0x85 - DB 0x20, 0x02, 0x40, 0x82, 0x2D, 0x02, 0x20, 0x85 - DB 0x40, 0x02, 0x40, 0x90, 0x60, 0x02, 0x60, 0x85 - DB 0x20, 0x00, 0x40, 0x92, 0x40, 0x01, 0x60, 0x9B - DB 0x60, 0x01, 0x60, 0x9B, 0x60, 0x01, 0x9C, 0x20 - DB 0x00, 0x20, 0x86, 0x60, 0x40, 0x60, 0x91, 0x40 - DB 0x01, 0x60, 0x85, 0x60, 0x02, 0x60, 0x8E, 0x60 - DB 0x20, 0x01, 0x40, 0x86, 0x20, 0x02, 0x40, 0x82 - DB 0x69, 0x40, 0x20, 0x01, 0x20, 0x60, 0x87, 0x40 - DB 0x02, 0x60, 0x82, 0x11, 0x86, 0x40, 0x20, 0x60 - DB 0x83, 0x11, 0x8D, 0x11, 0xE3 -; 83 - DB 0xC4, 0x60, 0x40, 0x20, 0x13, 0x87, 0x40, 0x16 - DB 0x86, 0x20, 0x17, 0x85, 0x40, 0x02, 0x20, 0x40 - DB 0x73, 0x85, 0x20, 0x01, 0x60, 0x9A, 0x60, 0x01 - DB 0x40, 0x9B, 0x40, 0x01, 0x60, 0x86, 0x40, 0x21 - DB 0x40, 0x60, 0x87, 0x20, 0x01, 0x84, 0x40, 0x01 - DB 0x86, 0x20, 0x04, 0x40, 0x86, 0x40, 0x01, 0x60 - DB 0x83, 0x40, 0x01, 0x85, 0x20, 0x06, 0x40, 0x85 - DB 0x60, 0x01, 0x60, 0x83, 0x40, 0x01, 0x60, 0x83 - DB 0x40, 0x01, 0x20, 0x41, 0x03, 0x60, 0x84, 0x60 - DB 0x01, 0x60, 0x83, 0x60, 0x01, 0x20, 0x82, 0x40 - DB 0x01, 0x20, 0x82, 0x60, 0x02, 0x20, 0x84, 0x60 - DB 0x01, 0x60, 0x84, 0x20, 0x02, 0x21, 0x02, 0x84 - DB 0x60, 0x02, 0x60, 0x83, 0x40, 0x01, 0x85, 0x60 - DB 0x06, 0x60, 0x85, 0x20, 0x02, 0x60, 0x81, 0x60 - DB 0x01, 0x20, 0x86, 0x40, 0x04, 0x40, 0x86, 0x60 - DB 0x03, 0x21, 0x02, 0x40, 0x87, 0x60, 0x42, 0x89 - DB 0x40, 0x06, 0x20, 0x97, 0x40, 0x04, 0x40, 0x9A - DB 0x42, 0x60, 0xA6 -; 84 - DB 0xAF, 0x60, 0x43, 0x61, 0x96, 0x40, 0x20, 0x06 - DB 0x20, 0x60, 0x92, 0x60, 0x20, 0x0A, 0x40, 0x90 - DB 0x60, 0x06, 0x21, 0x04, 0x40, 0x8F, 0x02, 0x20 - DB 0x60, 0x80, 0x01, 0x60, 0x81, 0x60, 0x20, 0x02 - DB 0x60, 0x8D, 0x40, 0x01, 0x40, 0x82, 0x01, 0x60 - DB 0x83, 0x20, 0x01, 0x40, 0x88, 0x20, 0x60, 0x82 - DB 0x01, 0x20, 0x83, 0x01, 0x60, 0x84, 0x01, 0x20 - DB 0x87, 0x40, 0x01, 0x81, 0x60, 0x01, 0x40, 0x83 - DB 0x01, 0x60, 0x84, 0x40, 0x01, 0x87, 0x01, 0x40 - DB 0x81, 0x60, 0x01, 0x60, 0x83, 0x01, 0x60, 0x84 - DB 0x60, 0x01, 0x60, 0x85, 0x40, 0x01, 0x60, 0x81 - DB 0x60, 0x01, 0x60, 0x83, 0x01, 0x60, 0x84, 0x60 - DB 0x01, 0x60, 0x85, 0x01, 0x40, 0x82, 0x60, 0x01 - DB 0x40, 0x83, 0x01, 0x60, 0x84, 0x60, 0x01, 0x60 - DB 0x84, 0x40, 0x01, 0x60, 0x83, 0x20, 0x01, 0x60 - DB 0x82, 0x01, 0x60, 0x84, 0x40, 0x01, 0x84, 0x60 - DB 0x01, 0x20, 0x84, 0x40, 0x02, 0x60, 0x81, 0x01 - DB 0x60, 0x84, 0x40, 0x01, 0x84, 0x60, 0x20, 0x00 - DB 0x60, 0x85, 0x20, 0x03, 0x20, 0x01, 0x60, 0x84 - DB 0x20, 0x00, 0x20, 0x86, 0x60, 0x87, 0x20, 0x05 - DB 0x60, 0x84, 0x01, 0x40, 0x90, 0x40, 0x04, 0x60 - DB 0x83, 0x60, 0x21, 0x60, 0x92, 0x60, 0x42, 0x60 - DB 0xCB -; 85 - DB 0xAF, 0x60, 0x43, 0x61, 0x96, 0x40, 0x20, 0x06 - DB 0x20, 0x60, 0x92, 0x60, 0x20, 0x0A, 0x40, 0x87 - DB 0x60, 0x20, 0x86, 0x60, 0x06, 0x21, 0x04, 0x40 - DB 0x85, 0x40, 0x01, 0x40, 0x85, 0x02, 0x20, 0x60 - DB 0x80, 0x01, 0x60, 0x81, 0x60, 0x20, 0x02, 0x60 - DB 0x84, 0x60, 0x01, 0x20, 0x84, 0x40, 0x01, 0x40 - DB 0x82, 0x01, 0x60, 0x83, 0x20, 0x01, 0x40, 0x85 - DB 0x40, 0x01, 0x40, 0x83, 0x01, 0x20, 0x83, 0x01 - DB 0x60, 0x84, 0x01, 0x20, 0x86, 0x01, 0x20, 0x82 - DB 0x60, 0x01, 0x40, 0x83, 0x01, 0x60, 0x84, 0x40 - DB 0x01, 0x86, 0x40, 0x01, 0x40, 0x81, 0x60, 0x01 - DB 0x60, 0x83, 0x01, 0x60, 0x84, 0x60, 0x01, 0x60 - DB 0x86, 0x20, 0x00, 0x20, 0x81, 0x60, 0x01, 0x60 - DB 0x83, 0x01, 0x60, 0x84, 0x60, 0x01, 0x60, 0x86 - DB 0x60, 0x00, 0x20, 0x81, 0x60, 0x01, 0x40, 0x83 - DB 0x01, 0x60, 0x84, 0x60, 0x01, 0x60, 0x87, 0x60 - DB 0x83, 0x20, 0x01, 0x60, 0x82, 0x01, 0x60, 0x84 - DB 0x40, 0x01, 0x8D, 0x40, 0x02, 0x60, 0x81, 0x01 - DB 0x60, 0x84, 0x40, 0x01, 0x8E, 0x20, 0x03, 0x20 - DB 0x01, 0x60, 0x84, 0x20, 0x00, 0x20, 0x8F, 0x20 - DB 0x05, 0x60, 0x84, 0x01, 0x40, 0x90, 0x40, 0x04 - DB 0x60, 0x83, 0x60, 0x21, 0x60, 0x92, 0x60, 0x42 - DB 0x60, 0xCB -; 86 - DB 0xAF, 0x60, 0x43, 0x61, 0x96, 0x40, 0x20, 0x06 - DB 0x20, 0x60, 0x92, 0x60, 0x20, 0x0A, 0x40, 0x8A - DB 0x40, 0x84, 0x60, 0x06, 0x21, 0x04, 0x40, 0x88 - DB 0x40, 0x01, 0x83, 0x02, 0x20, 0x60, 0x80, 0x01 - DB 0x60, 0x81, 0x60, 0x20, 0x02, 0x60, 0x87, 0x01 - DB 0x40, 0x82, 0x40, 0x01, 0x40, 0x82, 0x01, 0x60 - DB 0x83, 0x20, 0x01, 0x40, 0x86, 0x40, 0x01, 0x83 - DB 0x01, 0x20, 0x83, 0x01, 0x60, 0x84, 0x01, 0x20 - DB 0x85, 0x60, 0x01, 0x40, 0x82, 0x60, 0x01, 0x40 - DB 0x83, 0x01, 0x60, 0x84, 0x40, 0x01, 0x85, 0x20 - DB 0x00, 0x20, 0x83, 0x60, 0x01, 0x60, 0x83, 0x01 - DB 0x60, 0x84, 0x60, 0x01, 0x60, 0x84, 0x40, 0x01 - DB 0x60, 0x82, 0x60, 0x01, 0x60, 0x83, 0x01, 0x60 - DB 0x84, 0x60, 0x01, 0x60, 0x85, 0x01, 0x20, 0x82 - DB 0x60, 0x01, 0x40, 0x83, 0x01, 0x60, 0x84, 0x60 - DB 0x01, 0x60, 0x85, 0x40, 0x01, 0x60, 0x82, 0x20 - DB 0x01, 0x60, 0x82, 0x01, 0x60, 0x84, 0x40, 0x01 - DB 0x87, 0x20, 0x00, 0x20, 0x82, 0x40, 0x02, 0x60 - DB 0x81, 0x01, 0x60, 0x84, 0x40, 0x01, 0x87, 0x60 - DB 0x00, 0x20, 0x83, 0x20, 0x03, 0x20, 0x01, 0x60 - DB 0x84, 0x20, 0x00, 0x20, 0x88, 0x60, 0x85, 0x20 - DB 0x05, 0x60, 0x84, 0x01, 0x40, 0x90, 0x40, 0x04 - DB 0x60, 0x83, 0x60, 0x21, 0x60, 0x92, 0x60, 0x42 - DB 0x60, 0xCB -; 87 - DB 0xAE, 0x60, 0x40, 0x20, 0x02, 0x20, 0x41, 0x94 - DB 0x60, 0x20, 0x08, 0x20, 0x60, 0x91, 0x40, 0x0C - DB 0x60, 0x8F, 0x40, 0x03, 0x20, 0x40, 0x62, 0x40 - DB 0x04, 0x8F, 0x02, 0x20, 0x60, 0x86, 0x40, 0x02 - DB 0x40, 0x8D, 0x40, 0x01, 0x20, 0x89, 0x20, 0x01 - DB 0x20, 0x8D, 0x20, 0x01, 0x60, 0x8A, 0x20, 0x00 - DB 0x20, 0x80, 0x60, 0x00, 0x60, 0x89, 0x01, 0x20 - DB 0x89, 0x61, 0x02, 0x40, 0x01, 0x40, 0x88, 0x60 - DB 0x01, 0x40, 0x89, 0x60, 0x40, 0x04, 0x20, 0x89 - DB 0x60, 0x01, 0x40, 0x89, 0x60, 0x40, 0x04, 0x60 - DB 0x89, 0x60, 0x01, 0x40, 0x89, 0x61, 0x40, 0x01 - DB 0x40, 0x8B, 0x60, 0x01, 0x20, 0x8B, 0x20, 0x01 - DB 0x8D, 0x01, 0x20, 0x8B, 0x20, 0x00, 0x20, 0x8D - DB 0x20, 0x01, 0x60, 0x89, 0x60, 0x01, 0x20, 0x8D - DB 0x40, 0x20, 0x40, 0x60, 0x89, 0x60, 0x20, 0x00 - DB 0x40, 0xFF, 0x83 -; 88 - DB 0x96, 0x61, 0x91, 0x60, 0x87, 0x60, 0x20, 0x03 - DB 0x40, 0x8E, 0x60, 0x01, 0x40, 0x84, 0x60, 0x06 - DB 0x60, 0x85, 0x60, 0x20, 0x85, 0x40, 0x01, 0x85 - DB 0x20, 0x01, 0x21, 0x02, 0x20, 0x84, 0x40, 0x01 - DB 0x40, 0x84, 0x20, 0x00, 0x20, 0x84, 0x60, 0x01 - DB 0x40, 0x82, 0x20, 0x01, 0x60, 0x83, 0x60, 0x01 - DB 0x20, 0x84, 0x01, 0x40, 0x84, 0x40, 0x00, 0x20 - DB 0x83, 0x40, 0x01, 0x60, 0x84, 0x40, 0x01, 0x40 - DB 0x82, 0x60, 0x01, 0x60, 0x84, 0x01, 0x60, 0x83 - DB 0x60, 0x01, 0x60, 0x85, 0x01, 0x20, 0x82, 0x60 - DB 0x01, 0x60, 0x83, 0x60, 0x01, 0x84, 0x60, 0x01 - DB 0x86, 0x40, 0x01, 0x40, 0x81, 0x60, 0x01, 0x60 - DB 0x83, 0x60, 0x01, 0x84, 0x40, 0x00, 0x20, 0x87 - DB 0x20, 0x00, 0x20, 0x81, 0x60, 0x01, 0x40, 0x83 - DB 0x40, 0x00, 0x20, 0x84, 0x01, 0x40, 0x87, 0x60 - DB 0x00, 0x20, 0x82, 0x01, 0x20, 0x83, 0x40, 0x00 - DB 0x20, 0x83, 0x20, 0x00, 0x20, 0x89, 0x60, 0x83 - DB 0x20, 0x01, 0x40, 0x82, 0x40, 0x00, 0x20, 0x81 - DB 0x40, 0x20, 0x00, 0x20, 0x8F, 0x40, 0x03, 0x22 - DB 0x01, 0x20, 0x02, 0x20, 0x42, 0x8E, 0x20, 0x0F - DB 0x8E, 0x60, 0x20, 0x0E, 0x90, 0x60, 0x4D, 0xFF - DB 0x83 -; 89 - DB 0x96, 0x61, 0x91, 0x60, 0x87, 0x60, 0x20, 0x03 - DB 0x40, 0x8E, 0x60, 0x01, 0x40, 0x84, 0x60, 0x06 - DB 0x60, 0x8D, 0x40, 0x01, 0x85, 0x20, 0x01, 0x21 - DB 0x02, 0x20, 0x8D, 0x20, 0x00, 0x20, 0x84, 0x60 - DB 0x01, 0x40, 0x82, 0x20, 0x01, 0x60, 0x8C, 0x01 - DB 0x40, 0x84, 0x40, 0x00, 0x20, 0x83, 0x40, 0x01 - DB 0x60, 0x87, 0x20, 0x60, 0x81, 0x60, 0x01, 0x60 - DB 0x84, 0x01, 0x60, 0x83, 0x60, 0x01, 0x60, 0x86 - DB 0x40, 0x01, 0x81, 0x60, 0x01, 0x60, 0x83, 0x60 - DB 0x01, 0x84, 0x60, 0x01, 0x87, 0x01, 0x40, 0x81 - DB 0x60, 0x01, 0x60, 0x83, 0x60, 0x01, 0x84, 0x40 - DB 0x00, 0x20, 0x86, 0x40, 0x01, 0x60, 0x81, 0x60 - DB 0x01, 0x40, 0x83, 0x40, 0x00, 0x20, 0x84, 0x01 - DB 0x40, 0x86, 0x01, 0x40, 0x83, 0x01, 0x20, 0x83 - DB 0x40, 0x00, 0x20, 0x83, 0x20, 0x00, 0x20, 0x86 - DB 0x40, 0x01, 0x60, 0x83, 0x20, 0x01, 0x40, 0x82 - DB 0x40, 0x00, 0x20, 0x81, 0x40, 0x20, 0x00, 0x20 - DB 0x86, 0x60, 0x01, 0x20, 0x84, 0x40, 0x03, 0x22 - DB 0x01, 0x20, 0x02, 0x20, 0x42, 0x84, 0x60, 0x20 - DB 0x00, 0x60, 0x85, 0x20, 0x0F, 0x86, 0x60, 0x86 - DB 0x60, 0x20, 0x0E, 0x90, 0x60, 0x4D, 0xFF, 0x83 -; 8A - DB 0xA9, 0x62, 0x8B, 0x40, 0x21, 0x8D, 0x01, 0x40 - DB 0x8B, 0x40, 0x01, 0x8D, 0x01, 0x40, 0x8B, 0x40 - DB 0x01, 0x8D, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x8D - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x88, 0x20, 0x60 - DB 0x82, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x87, 0x40 - DB 0x01, 0x82, 0x01, 0x40, 0x8B, 0x40, 0x01, 0x87 - DB 0x01, 0x40, 0x82, 0x11, 0x86, 0x40, 0x01, 0x60 - DB 0x82, 0x11, 0x86, 0x01, 0x40, 0x83, 0x11, 0x85 - DB 0x40, 0x01, 0x60, 0x83, 0x6E, 0x40, 0x01, 0x84 - DB 0x60, 0x01, 0x20, 0x93, 0x40, 0x01, 0x84, 0x60 - DB 0x20, 0x00, 0x60, 0x93, 0x40, 0x01, 0x86, 0x60 - DB 0x94, 0x40, 0x01, 0x9C, 0x40, 0x01, 0x9C, 0x40 - DB 0x01, 0x9C, 0x62, 0xC3 -; 8B - DB 0x8E, 0x60, 0x41, 0x22, 0x41, 0x95, 0x60, 0x40 - DB 0x08, 0x40, 0x92, 0x60, 0x0B, 0x20, 0x60, 0x8F - DB 0x60, 0x03, 0x20, 0x43, 0x20, 0x03, 0x20, 0x8F - DB 0x02, 0x20, 0x60, 0x85, 0x60, 0x20, 0x02, 0x40 - DB 0x8D, 0x40, 0x01, 0x20, 0x89, 0x40, 0x01, 0x20 - DB 0x88, 0x20, 0x60, 0x82, 0x20, 0x01, 0x60, 0x8A - DB 0x02, 0x87, 0x40, 0x01, 0x82, 0x01, 0x20, 0x8B - DB 0x40, 0x01, 0x60, 0x86, 0x01, 0x40, 0x81, 0x60 - DB 0x01, 0x40, 0x8B, 0x40, 0x01, 0x60, 0x85, 0x40 - DB 0x01, 0x60, 0x81, 0x60, 0x01, 0x40, 0x8B, 0x40 - DB 0x01, 0x60, 0x85, 0x01, 0x40, 0x82, 0x60, 0x01 - DB 0x20, 0x8B, 0x20, 0x01, 0x85, 0x40, 0x01, 0x60 - DB 0x83, 0x02, 0x60, 0x89, 0x60, 0x01, 0x20, 0x84 - DB 0x60, 0x01, 0x20, 0x84, 0x20, 0x01, 0x20, 0x88 - DB 0x60, 0x02, 0x40, 0x84, 0x60, 0x20, 0x00, 0x60 - DB 0x84, 0x60, 0x02, 0x20, 0x40, 0x84, 0x60, 0x40 - DB 0x02, 0x20, 0x87, 0x60, 0x86, 0x40, 0x04, 0x23 - DB 0x03, 0x20, 0x91, 0x40, 0x0A, 0x20, 0x93, 0x60 - DB 0x20, 0x06, 0x20, 0x40, 0x96, 0x61, 0x42, 0x61 - DB 0xC9 -; 8C - DB 0xA9, 0x4D, 0x60, 0x90, 0x0F, 0x40, 0x8E, 0x10 - DB 0x60, 0x8D, 0x2D, 0x02, 0x20, 0x9B, 0x60, 0x02 - DB 0x60, 0x87, 0x20, 0x60, 0x91, 0x40, 0x01, 0x60 - DB 0x86, 0x40, 0x01, 0x91, 0x60, 0x01, 0x60, 0x86 - DB 0x01, 0x40, 0x91, 0x60, 0x01, 0x86, 0x40, 0x01 - DB 0x60, 0x91, 0x20, 0x00, 0x20, 0x86, 0x01, 0x40 - DB 0x91, 0x40, 0x01, 0x60, 0x85, 0x40, 0x01, 0x60 - DB 0x8F, 0x60, 0x20, 0x01, 0x40, 0x85, 0x60, 0x01 - DB 0x20, 0x84, 0x69, 0x40, 0x20, 0x01, 0x20, 0x60 - DB 0x86, 0x60, 0x20, 0x00, 0x60, 0x84, 0x11, 0x86 - DB 0x60, 0x85, 0x11, 0x8D, 0x11, 0xFF, 0x83 -; 8D - DB 0xA9, 0x51, 0x8D, 0x11, 0x86, 0x60, 0x21, 0x83 - DB 0x11, 0x86, 0x02, 0x60, 0x82, 0x42, 0x20, 0x02 - DB 0x2A, 0x85, 0x40, 0x01, 0x60, 0x84, 0x60, 0x20 - DB 0x01, 0x40, 0x60, 0x90, 0x20, 0x00, 0x20, 0x85 - DB 0x20, 0x00, 0x20, 0x60, 0x92, 0x40, 0x00, 0x20 - DB 0x84, 0x40, 0x01, 0x94, 0x60, 0x01, 0x40, 0x83 - DB 0x01, 0x40, 0x95, 0x40, 0x01, 0x60, 0x81, 0x60 - DB 0x01, 0x60, 0x96, 0x01, 0x40, 0x81, 0x60, 0x01 - DB 0x60, 0x96, 0x01, 0x40, 0x81, 0x60, 0x01, 0x20 - DB 0x95, 0x40, 0x01, 0x60, 0x82, 0x02, 0x20, 0x40 - DB 0x6C, 0x85, 0x40, 0x01, 0x40, 0x83, 0x40, 0x10 - DB 0x86, 0x20, 0x40, 0x85, 0x20, 0x0F, 0x8F, 0x40 - DB 0x20, 0x0D, 0xFF, 0x83 -; 8E - DB 0xFF, 0xC6, 0x61, 0x9C, 0x20, 0x01, 0x40, 0x81 - DB 0x63, 0x4A, 0x23, 0x40, 0x84, 0x40, 0x03, 0x60 - DB 0x80, 0x20, 0x11, 0x40, 0x84, 0x40, 0x03, 0x60 - DB 0x80, 0x20, 0x11, 0x40, 0x85, 0x20, 0x01, 0x40 - DB 0x81, 0x64, 0x49, 0x23, 0x40, 0x86, 0x61, 0xFF - DB 0xFF, 0x96 -; 8F - DB 0xD6, 0x60, 0x41, 0x60, 0x99, 0x60, 0x04, 0x20 - DB 0x60, 0x96, 0x40, 0x07, 0x60, 0x94, 0x40, 0x08 - DB 0x20, 0x93, 0x40, 0x02, 0x20, 0x60, 0x80, 0x60 - DB 0x20, 0x02, 0x40, 0x87, 0x61, 0x87, 0x60, 0x02 - DB 0x40, 0x84, 0x20, 0x01, 0x20, 0x86, 0x20, 0x01 - DB 0x40, 0x81, 0x60, 0x81, 0x60, 0x40, 0x02, 0x20 - DB 0x85, 0x60, 0x02, 0x85, 0x40, 0x03, 0x60, 0x80 - DB 0x20, 0x05, 0x20, 0x87, 0x20, 0x01, 0x60, 0x84 - DB 0x40, 0x03, 0x60, 0x80, 0x20, 0x04, 0x20, 0x88 - DB 0x40, 0x01, 0x40, 0x85, 0x02, 0x20, 0x81, 0x20 - DB 0x03, 0x40, 0x89, 0x40, 0x01, 0x40, 0x86, 0x41 - DB 0x83, 0x62, 0x8B, 0x60, 0x01, 0x20, 0x9B, 0x60 - DB 0x01, 0x20, 0x9C, 0x61, 0xFF, 0xA0 -; 90 - DB 0xFF, 0xD9, 0x40, 0x20, 0x00, 0x9A, 0x60, 0x20 - DB 0x01, 0x20, 0x8C, 0x40, 0x8B, 0x40, 0x01, 0x20 - DB 0x00, 0x60, 0x8B, 0x60, 0x00, 0x40, 0x88, 0x60 - DB 0x01, 0x21, 0x00, 0x60, 0x8B, 0x60, 0x01, 0x20 - DB 0x86, 0x60, 0x40, 0x00, 0x40, 0x21, 0x00, 0x20 - DB 0x8C, 0x00, 0x20, 0x60, 0x00, 0x84, 0x60, 0x40 - DB 0x01, 0x40, 0x22, 0x00, 0x60, 0x8B, 0x60, 0x00 - DB 0x61, 0x00, 0x40, 0x81, 0x60, 0x40, 0x01, 0x20 - DB 0x40, 0x22, 0x00, 0x40, 0x8C, 0x20, 0x00, 0x61 - DB 0x00, 0x20, 0x60, 0x20, 0x01, 0x20, 0x41, 0x22 - DB 0x00, 0x20, 0x8C, 0x60, 0x00, 0x40, 0x61, 0x40 - DB 0x02, 0x20, 0x42, 0x23, 0x00, 0x60, 0x8C, 0x40 - DB 0x00, 0x63, 0x45, 0x23, 0x00, 0x20, 0x8D, 0x00 - DB 0x20, 0x64, 0x43, 0x24, 0x00, 0x60, 0x8C, 0x60 - DB 0x00, 0x40, 0x64, 0x42, 0x24, 0x00, 0x20, 0x8D - DB 0x60, 0x00, 0x66, 0x40, 0x25, 0x00, 0x60, 0x8D - DB 0x20, 0x00, 0x65, 0x41, 0x26, 0x89 -; 91 - DB 0x84, 0x20, 0x00, 0x64, 0x43, 0x23, 0x00, 0x40 - DB 0x8E, 0x00, 0x40, 0x64, 0x44, 0x22, 0x00, 0x60 - DB 0x8E, 0x00, 0x64, 0x46, 0x21, 0x00, 0x40, 0x8E - DB 0x00, 0x63, 0x48, 0x21, 0x01, 0x60, 0x8C, 0x00 - DB 0x62, 0x4B, 0x21, 0x00, 0x20, 0x40, 0x8A, 0x00 - DB 0x61, 0x4D, 0x20, 0x01, 0x40, 0x8A, 0x00, 0x60 - DB 0x4C, 0x20, 0x01, 0x40, 0x60, 0x8B, 0x00, 0x4A - DB 0x20, 0x02, 0x20, 0x60, 0x8D, 0x02, 0x25, 0x03 - DB 0x20, 0x40, 0x60, 0x8F, 0x60, 0x40, 0x20, 0x05 - DB 0x20, 0x41, 0x60, 0xFF, 0xFF, 0xCD -; 92 - DB 0xAC, 0x04, 0x9A, 0x04, 0x9A, 0x04, 0x9A, 0x04 - DB 0x9A, 0x04, 0x9A, 0x04, 0x92, 0x20, 0x12, 0x20 - DB 0x8B, 0x20, 0x10, 0x20, 0x8D, 0x20, 0x0E, 0x20 - DB 0x8F, 0x20, 0x0C, 0x20, 0x91, 0x20, 0x0A, 0x20 - DB 0x93, 0x20, 0x08, 0x20, 0x95, 0x20, 0x06, 0x20 - DB 0x97, 0x20, 0x04, 0x20, 0x99, 0x20, 0x02, 0x20 - DB 0x9B, 0x20, 0x00, 0x20, 0x9D, 0x20, 0xCF -; 93 - DB 0xCC, 0x01, 0x40, 0x9C, 0x01, 0x40, 0x9C, 0x01 - DB 0x40, 0x87, 0x41, 0x92, 0x01, 0x40, 0x87, 0x40 - DB 0x00, 0x40, 0x91, 0x01, 0x40, 0x88, 0x20, 0x00 - DB 0x40, 0x90, 0x01, 0x41, 0x87, 0x60, 0x01, 0x40 - DB 0x8F, 0x01, 0x4A, 0x20, 0x01, 0x40, 0x8E, 0x11 - DB 0x60, 0x8C, 0x40, 0x0F, 0x40, 0x9A, 0x20, 0x00 - DB 0x20, 0x60, 0x9A, 0x40, 0x00, 0x20, 0x9B, 0x60 - DB 0x00, 0x20, 0x9C, 0x40, 0x00, 0x60, 0xFF, 0xA4 -; 94 - DB 0xEC, 0x40, 0x01, 0x94, 0x41, 0x85, 0x40, 0x01 - DB 0x93, 0x60, 0x00, 0x40, 0x85, 0x40, 0x01, 0x92 - DB 0x60, 0x01, 0x60, 0x85, 0x40, 0x01, 0x91, 0x60 - DB 0x01, 0x40, 0x85, 0x41, 0x01, 0x90, 0x40, 0x02 - DB 0x48, 0x01, 0x8F, 0x0F, 0x8F, 0x40, 0x20, 0x0C - DB 0x40, 0x91, 0x40, 0x01, 0x60, 0x9C, 0x40, 0x00 - DB 0x20, 0x9D, 0x20, 0x00, 0x40, 0x9D, 0x00, 0x20 - DB 0xFF, 0xB8 -; 95 - DB 0x8D, 0x40, 0x9D, 0x40, 0x00, 0x60, 0x9B, 0x60 - DB 0x01, 0x20, 0x9B, 0x20, 0x02, 0x20, 0x98, 0x60 - DB 0x20, 0x04, 0x20, 0x60, 0x95, 0x40, 0x01, 0x21 - DB 0x00, 0x21, 0x01, 0x40, 0x94, 0x20, 0x00, 0x40 - DB 0x80, 0x20, 0x00, 0x20, 0x80, 0x40, 0x00, 0x20 - DB 0x94, 0x61, 0x81, 0x20, 0x00, 0x20, 0x81, 0x61 - DB 0x98, 0x20, 0x00, 0x20, 0x9C, 0x20, 0x00, 0x20 - DB 0x9C, 0x20, 0x00, 0x20, 0x9C, 0x20, 0x00, 0x20 - DB 0x98, 0x41, 0x81, 0x20, 0x00, 0x20, 0x81, 0x41 - DB 0x94, 0x20, 0x00, 0x20, 0x60, 0x20, 0x00, 0x20 - DB 0x60, 0x20, 0x00, 0x20, 0x94, 0x60, 0x20, 0x01 - DB 0x20, 0x00, 0x20, 0x01, 0x20, 0x60, 0x96, 0x40 - DB 0x04, 0x40, 0x99, 0x40, 0x02, 0x40, 0x9B, 0x20 - DB 0x00, 0x20, 0x9C, 0x40, 0x00, 0x60, 0x9D, 0x60 - DB 0x90 -; 96 - DB 0xC6, 0x60, 0x20, 0x60, 0x8C, 0x20, 0x40, 0x8D - DB 0x20, 0x01, 0x40, 0x81, 0x40, 0x20, 0x01, 0x20 - DB 0x40, 0x60, 0x80, 0x60, 0x20, 0x01, 0x60, 0x8B - DB 0x60, 0x20, 0x02, 0x40, 0x20, 0x06, 0x20, 0x03 - DB 0x40, 0x8D, 0x20, 0x0D, 0x20, 0x60, 0x8F, 0x40 - DB 0x02, 0x20, 0x60, 0x81, 0x60, 0x40, 0x02, 0x20 - DB 0x92, 0x01, 0x20, 0x85, 0x60, 0x01, 0x40, 0x91 - DB 0x60, 0x01, 0x60, 0x86, 0x20, 0x00, 0x40, 0x91 - DB 0x40, 0x01, 0x87, 0x20, 0x00, 0x20, 0x91, 0x40 - DB 0x01, 0x87, 0x20, 0x00, 0x40, 0x91, 0x60, 0x01 - DB 0x40, 0x85, 0x60, 0x01, 0x60, 0x92, 0x02, 0x60 - DB 0x83, 0x40, 0x02, 0x92, 0x20, 0x03, 0x22, 0x05 - DB 0x60, 0x8E, 0x60, 0x0F, 0x40, 0x8C, 0x60, 0x03 - DB 0x60, 0x40, 0x20, 0x03, 0x20, 0x60, 0x80, 0x20 - DB 0x02, 0x40, 0x8C, 0x20, 0x00, 0x20, 0x60, 0x83 - DB 0x61, 0x84, 0x40, 0x00, 0x20, 0x8E, 0x40, 0x8D - DB 0x40, 0x60, 0xC6 -; TOTAL COMPRESSED SIZE = 12529
--- a/src/Fonts/aa_font36_idx.inc Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -;========================================================================== -; Font index exported ven. nov. 16 2012 by FontIO.cpp 110 2011-06-07 11:26:40Z gascuel $ -;========================================================================== -aa_font36_chars EQU .119 -aa_font36_firstChar EQU ' ' -aa_font36_lastChar EQU '' -; -aa_font36_idx: - DW aa_font36_bits + 0x0000 ; Space - DW aa_font36_bits + 0x0005 ; ! mark - DW aa_font36_bits + 0x002E ; " dquote - DW aa_font36_bits + 0x0082 ; # sharp - DW aa_font36_bits + 0x010A ; $ dolar - DW aa_font36_bits + 0x019A ; % percent - DW aa_font36_bits + 0x0273 ; & and - DW aa_font36_bits + 0x0330 ; ' quote - DW aa_font36_bits + 0x0362 ; ( lparent - DW aa_font36_bits + 0x03AF ; ) rparent - DW aa_font36_bits + 0x03FF ; * star - DW aa_font36_bits + 0x046D ; + plus - DW aa_font36_bits + 0x04A8 ; , comma - DW aa_font36_bits + 0x04D8 ; - minus - DW aa_font36_bits + 0x0509 ; . dot - DW aa_font36_bits + 0x0525 ; / slash - DW aa_font36_bits + 0x056F ; 0 0 - DW aa_font36_bits + 0x05E3 ; 1 1 - DW aa_font36_bits + 0x061F ; 2 2 - DW aa_font36_bits + 0x06A6 ; 3 3 - DW aa_font36_bits + 0x0744 ; 4 4 - DW aa_font36_bits + 0x07B8 ; 5 5 - DW aa_font36_bits + 0x0845 ; 6 6 - DW aa_font36_bits + 0x08E8 ; 7 7 - DW aa_font36_bits + 0x0960 ; 8 8 - DW aa_font36_bits + 0x0A1B ; 9 9 - DW aa_font36_bits + 0x0ABE ; : colon - DW aa_font36_bits + 0x0AF0 ; ; semicolon - DW aa_font36_bits + 0x0B37 ; < less - DW aa_font36_bits + 0x0B99 ; = equal - DW aa_font36_bits + 0x0C0E ; > greater - DW aa_font36_bits + 0x0C73 ; ? question - DW aa_font36_bits + 0x0CDA ; @ arobas - DW aa_font36_bits + 0x0DA7 ; A A - DW aa_font36_bits + 0x0E36 ; B B - DW aa_font36_bits + 0x0ECC ; C C - DW aa_font36_bits + 0x0F47 ; D D - DW aa_font36_bits + 0x0FC6 ; E E - DW aa_font36_bits + 0x1046 ; F F - DW aa_font36_bits + 0x109B ; G G - DW aa_font36_bits + 0x111C ; H H - DW aa_font36_bits + 0x1155 ; I I - DW aa_font36_bits + 0x11B8 ; J J - DW aa_font36_bits + 0x1213 ; K K - DW aa_font36_bits + 0x127B ; L L - DW aa_font36_bits + 0x12AA ; M M - DW aa_font36_bits + 0x1312 ; N N - DW aa_font36_bits + 0x1368 ; O O - DW aa_font36_bits + 0x13F0 ; P P - DW aa_font36_bits + 0x1452 ; Q Q - DW aa_font36_bits + 0x14E8 ; R R - DW aa_font36_bits + 0x156A ; S S - DW aa_font36_bits + 0x1600 ; T T - DW aa_font36_bits + 0x1648 ; U U - DW aa_font36_bits + 0x1695 ; V V - DW aa_font36_bits + 0x170C ; W W - DW aa_font36_bits + 0x1771 ; X X - DW aa_font36_bits + 0x1804 ; Y Y - DW aa_font36_bits + 0x185C ; Z Z - DW aa_font36_bits + 0x18F4 ; [ lsqbracket - DW aa_font36_bits + 0x192B ; \ backslash - DW aa_font36_bits + 0x1975 ; ] rsqbracket - DW aa_font36_bits + 0x19AD ; ^ caret - DW aa_font36_bits + 0x19F5 ; _ underline - DW aa_font36_bits + 0x1A45 ; ` backquote - DW aa_font36_bits + 0x1A68 ; a a - DW aa_font36_bits + 0x1AF0 ; b b - DW aa_font36_bits + 0x1B60 ; c c - DW aa_font36_bits + 0x1BCF ; d d - DW aa_font36_bits + 0x1C3A ; e e - DW aa_font36_bits + 0x1CCC ; f f - DW aa_font36_bits + 0x1D35 ; g g - DW aa_font36_bits + 0x1DE5 ; h h - DW aa_font36_bits + 0x1E25 ; i i - DW aa_font36_bits + 0x1E7E ; j j - DW aa_font36_bits + 0x1EBE ; k k - DW aa_font36_bits + 0x1F16 ; l l - DW aa_font36_bits + 0x1F65 ; m m - DW aa_font36_bits + 0x1FAC ; n n - DW aa_font36_bits + 0x1FE5 ; o o - DW aa_font36_bits + 0x205F ; p p - DW aa_font36_bits + 0x20CA ; q q - DW aa_font36_bits + 0x2134 ; r r - DW aa_font36_bits + 0x2198 ; s s - DW aa_font36_bits + 0x2220 ; t t - DW aa_font36_bits + 0x227D ; u u - DW aa_font36_bits + 0x22B4 ; v v - DW aa_font36_bits + 0x230E ; w w - DW aa_font36_bits + 0x236E ; x x - DW aa_font36_bits + 0x23E4 ; y y - DW aa_font36_bits + 0x2446 ; z z - DW aa_font36_bits + 0x24B3 ; { lbrace - DW aa_font36_bits + 0x2510 ; | bar - DW aa_font36_bits + 0x2518 ; } rbrace - DW aa_font36_bits + 0x2572 ; ~ tilde - DW aa_font36_bits + 0x25B4 ; 7F - DW aa_font36_bits + 0x2611 ; 80 - DW aa_font36_bits + 0x26B1 ; 81 - DW aa_font36_bits + 0x275F ; 82 - DW aa_font36_bits + 0x27BC ; 83 - DW aa_font36_bits + 0x2847 ; 84 - DW aa_font36_bits + 0x28F8 ; 85 - DW aa_font36_bits + 0x29AA ; 86 - DW aa_font36_bits + 0x2A64 ; 87 - DW aa_font36_bits + 0x2ADF ; 88 - DW aa_font36_bits + 0x2B88 ; 89 - DW aa_font36_bits + 0x2C30 ; 8A - DW aa_font36_bits + 0x2C94 ; 8B - DW aa_font36_bits + 0x2D2D ; 8C - DW aa_font36_bits + 0x2D84 ; 8D - DW aa_font36_bits + 0x2DE8 ; 8E - DW aa_font36_bits + 0x2E12 ; 8F - DW aa_font36_bits + 0x2E78 ; 90 - DW aa_font36_bits + 0x2EFE ; 91 - DW aa_font36_bits + 0x2F4C ; 92 - DW aa_font36_bits + 0x2F83 ; 93 - DW aa_font36_bits + 0x2FC3 ; 94 - DW aa_font36_bits + 0x2FFD ; 95 - DW aa_font36_bits + 0x306E ; 96 - DW aa_font36_bits + 0x30F1 ; END OF INDEX
--- a/src/Icons/dive_warning.inc Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,239 +0,0 @@ -; \file D:/Microchip/OSTC/Frog/src/Frog/Icons/dive_warning.inc -; Generated 2012-01-15T23:08:46 -; -dive_warning_version equ .112 -dive_warning_width equ .45 -dive_warning_height equ .39 -; -dive_warning_block: - db .22, .39 - db .128, 0 -; - dw 0x0000 ; rgb=(0,0,0) - dw 0x1881 ; rgb=(25,16,8) - dw 0x3901 ; rgb=(58,33,8) - dw 0x1040 ; rgb=(16,8,0) - dw 0x2081 ; rgb=(33,16,8) - dw 0x9b01 ; rgb=(156,99,8) - dw 0xf4a1 ; rgb=(247,148,8) - dw 0xfce1 ; rgb=(255,156,8) - dw 0xd3c0 ; rgb=(214,123,4) - dw 0x82a1 ; rgb=(132,86,8) - dw 0xece1 ; rgb=(239,156,8) - dw 0xfd61 ; rgb=(255,173,8) - dw 0xfd21 ; rgb=(255,165,8) - dw 0xa2c1 ; rgb=(165,90,8) - dw 0x59c1 ; rgb=(90,58,8) - dw 0xfda0 ; rgb=(255,181,0) - dw 0xfd20 ; rgb=(255,165,0) - dw 0xfce0 ; rgb=(255,156,0) - dw 0x4980 ; rgb=(74,49,0) - dw 0xbbc1 ; rgb=(189,123,8) - dw 0xfd60 ; rgb=(255,173,0) - dw 0xdc20 ; rgb=(222,132,0) - dw 0x0840 ; rgb=(8,8,0) - dw 0x1880 ; rgb=(25,16,0) - dw 0xab81 ; rgb=(169,115,8) - dw 0xdce1 ; rgb=(222,156,8) - dw 0x51c1 ; rgb=(82,58,8) - dw 0xfde0 ; rgb=(255,189,0) - dw 0x3100 ; rgb=(49,33,0) - dw 0x1080 ; rgb=(16,16,0) - dw 0x9b41 ; rgb=(156,107,8) - dw 0x6281 ; rgb=(103,82,8) - dw 0xed21 ; rgb=(236,165,8) - dw 0xfe20 ; rgb=(255,197,0) - dw 0x9b81 ; rgb=(156,115,8) - dw 0xfde1 ; rgb=(255,189,8) - dw 0x9341 ; rgb=(148,107,8) - dw 0xf5e1 ; rgb=(247,189,8) - dw 0xfe21 ; rgb=(255,197,8) - dw 0x5201 ; rgb=(86,66,8) - dw 0xfe61 ; rgb=(255,206,8) - dw 0xfda1 ; rgb=(255,181,8) - dw 0x4141 ; rgb=(66,41,8) - dw 0xd4e1 ; rgb=(214,156,8) - dw 0xf5a1 ; rgb=(247,181,8) - dw 0x28c0 ; rgb=(41,25,0) - dw 0xfca1 ; rgb=(255,148,8) - dw 0xfca0 ; rgb=(255,148,0) - dw 0xfc60 ; rgb=(255,140,0) - dw 0xfc61 ; rgb=(255,140,8) - dw 0x1840 ; rgb=(25,8,0) - dw 0xfea1 ; rgb=(255,214,8) - dw 0xf421 ; rgb=(247,132,8) - dw 0xf464 ; rgb=(247,140,33) - dw 0xf423 ; rgb=(247,132,25) - dw 0xfbc0 ; rgb=(255,123,0) - dw 0x8301 ; rgb=(132,99,8) - dw 0xfe60 ; rgb=(255,206,0) - dw 0xf521 ; rgb=(247,165,8) - dw 0xfce6 ; rgb=(251,156,49) - dw 0xfdac ; rgb=(255,181,102) - dw 0xfdae ; rgb=(255,181,115) - dw 0xfd27 ; rgb=(251,165,62) - dw 0xf461 ; rgb=(247,140,8) - dw 0xf673 ; rgb=(247,206,156) - dw 0xffbe ; rgb=(255,247,247) - dw 0xff3b ; rgb=(252,230,222) - dw 0xe4aa ; rgb=(230,148,82) - dw 0xf420 ; rgb=(247,132,0) - dw 0xe420 ; rgb=(230,132,0) - dw 0xf5a0 ; rgb=(247,181,0) - dw 0xffff ; rgb=(255,255,255) - dw 0xfe72 ; rgb=(255,206,148) - dw 0xf651 ; rgb=(247,202,136) - dw 0xf77d ; rgb=(247,239,239) - dw 0xf4a5 ; rgb=(247,148,41) - dw 0xe421 ; rgb=(230,132,8) - dw 0x9461 ; rgb=(148,140,8) - dw 0xfea0 ; rgb=(255,214,0) - dw 0xf4a0 ; rgb=(247,148,0) - dw 0xf737 ; rgb=(247,230,189) - dw 0xfd6a ; rgb=(251,173,86) - dw 0x5a81 ; rgb=(90,82,8) - dw 0xfee1 ; rgb=(255,222,8) - dw 0xfd62 ; rgb=(255,173,16) - dw 0xfe73 ; rgb=(255,206,156) - dw 0xfeb6 ; rgb=(255,214,181) - dw 0xfeb5 ; rgb=(255,214,173) - dw 0xffbd ; rgb=(255,247,239) - dw 0x6301 ; rgb=(103,99,8) - dw 0xfee0 ; rgb=(255,222,0) - dw 0xf4e1 ; rgb=(247,156,8) - dw 0xf672 ; rgb=(247,206,148) - dw 0xff39 ; rgb=(255,230,206) - dw 0xdc21 ; rgb=(222,132,8) - dw 0xdde1 ; rgb=(222,189,8) - dw 0xf4e0 ; rgb=(247,156,0) - dw 0xf4c2 ; rgb=(247,152,21) - dw 0xdc61 ; rgb=(222,140,8) - dw 0x7341 ; rgb=(115,107,8) - dw 0xee41 ; rgb=(239,203,8) - dw 0x1900 ; rgb=(25,33,0) - dw 0xaca1 ; rgb=(173,148,8) - dw 0x2940 ; rgb=(41,41,0) - dw 0xbd21 ; rgb=(189,165,8) - dw 0x0040 ; rgb=(0,8,0) - dw 0xede0 ; rgb=(235,189,4) - dw 0x2941 ; rgb=(41,41,8) - dw 0xb4e1 ; rgb=(181,156,8) - dw 0x3981 ; rgb=(58,49,8) - dw 0xcd41 ; rgb=(200,168,8) - dw 0x0880 ; rgb=(8,16,0) - dw 0x7b81 ; rgb=(123,115,8) - dw 0xf661 ; rgb=(247,206,8) - dw 0x7b41 ; rgb=(123,107,8) - dw 0x2100 ; rgb=(33,33,0) - dw 0x8b81 ; rgb=(140,115,8) - dw 0xf621 ; rgb=(247,197,8) - dw 0x3181 ; rgb=(49,49,8) - dw 0x5241 ; rgb=(82,74,8) - dw 0xdd41 ; rgb=(218,169,8) - dw 0xd421 ; rgb=(214,132,8) - dw 0x0800 ; rgb=(8,0,0) - dw 0xb341 ; rgb=(181,107,8) - dw 0x7b01 ; rgb=(123,99,8) - dw 0xf561 ; rgb=(247,173,8) - dw 0xcc21 ; rgb=(206,132,8) - dw 0x20c1 ; rgb=(33,25,8) -; - db 0xc8, 0x00, 0x01, 0x02, 0x03, 0xa1, 0x00, 0x04 - db 0x05, 0x06, 0x07, 0x08, 0x04, 0x9e, 0x00, 0x01 - db 0x09, 0x0a, 0x0b, 0x82, 0x0c, 0x0d, 0x9d, 0x00 - db 0x0e, 0x0a, 0x0f, 0x81, 0x10, 0x07, 0x81, 0x11 - db 0x08, 0x9b, 0x00, 0x12, 0x13, 0x81, 0x14, 0x81 - db 0x10, 0x81, 0x0c, 0x81, 0x11, 0x15, 0x16, 0x98 - db 0x00, 0x17, 0x18, 0x14, 0x0f, 0x14, 0x83, 0x10 - db 0x82, 0x11, 0x15, 0x03, 0x96, 0x00, 0x17, 0x09 - db 0x19, 0x0f, 0x81, 0x14, 0x84, 0x10, 0x82, 0x11 - db 0x15, 0x03, 0x95, 0x00, 0x1a, 0x19, 0x1b, 0x0f - db 0x82, 0x14, 0x84, 0x10, 0x82, 0x11, 0x15, 0x03 - db 0x93, 0x00, 0x1c, 0x18, 0x81, 0x1b, 0x81, 0x0f - db 0x82, 0x14, 0x83, 0x10, 0x83, 0x11, 0x15, 0x03 - db 0x91, 0x00, 0x1d, 0x1e, 0x0f, 0x1b, 0x83, 0x0f - db 0x83, 0x14, 0x82, 0x10, 0x83, 0x11, 0x15, 0x03 - db 0x8f, 0x00, 0x03, 0x1f, 0x20, 0x1b, 0x85, 0x0f - db 0x83, 0x14, 0x82, 0x10, 0x83, 0x11, 0x15, 0x03 - db 0x8e, 0x00, 0x1a, 0x19, 0x21, 0x1b, 0x85, 0x0f - db 0x82, 0x14, 0x0b, 0x14, 0x82, 0x10, 0x83, 0x11 - db 0x15, 0x03, 0x8c, 0x00, 0x1c, 0x22, 0x23, 0x21 - db 0x1b, 0x86, 0x0f, 0x81, 0x14, 0x81, 0x0b, 0x14 - db 0x82, 0x10, 0x83, 0x11, 0x15, 0x03, 0x8a, 0x00 - db 0x17, 0x24, 0x25, 0x26, 0x81, 0x23, 0x85, 0x0f - db 0x82, 0x14, 0x82, 0x0b, 0x14, 0x82, 0x10, 0x83 - db 0x11, 0x15, 0x03, 0x88, 0x00, 0x03, 0x27, 0x19 - db 0x28, 0x81, 0x23, 0x29, 0x84, 0x0f, 0x84, 0x14 - db 0x84, 0x0b, 0x81, 0x0c, 0x81, 0x07, 0x81, 0x11 - db 0x15, 0x03, 0x87, 0x00, 0x2a, 0x2b, 0x26, 0x25 - db 0x2c, 0x81, 0x23, 0x83, 0x29, 0x0f, 0x86, 0x14 - db 0x0b, 0x14, 0x81, 0x0b, 0x0c, 0x82, 0x07, 0x81 - db 0x11, 0x15, 0x03, 0x85, 0x00, 0x2d, 0x22, 0x81 - db 0x23, 0x81, 0x20, 0x86, 0x29, 0x0b, 0x83, 0x14 - db 0x83, 0x10, 0x0c, 0x0b, 0x0c, 0x07, 0x82, 0x2e - db 0x07, 0x11, 0x15, 0x03, 0x83, 0x00, 0x16, 0x24 - db 0x81, 0x26, 0x29, 0x84, 0x10, 0x81, 0x0b, 0x10 - db 0x81, 0x0c, 0x84, 0x10, 0x11, 0x83, 0x10, 0x14 - db 0x0c, 0x2f, 0x81, 0x30, 0x31, 0x2f, 0x11, 0x15 - db 0x32, 0x82, 0x00, 0x1a, 0x2b, 0x33, 0x28, 0x29 - db 0x10, 0x92, 0x2f, 0x11, 0x10, 0x11, 0x34, 0x35 - db 0x36, 0x37, 0x30, 0x11, 0x15, 0x32, 0x81, 0x00 - db 0x38, 0x81, 0x39, 0x28, 0x1b, 0x3a, 0x2f, 0x3b - db 0x3c, 0x8e, 0x3d, 0x3c, 0x3e, 0x11, 0x10, 0x3f - db 0x40, 0x41, 0x42, 0x43, 0x44, 0x11, 0x45, 0x17 - db 0x00, 0x27, 0x33, 0x39, 0x26, 0x28, 0x46, 0x0c - db 0x2f, 0x3d, 0x42, 0x8f, 0x47, 0x48, 0x81, 0x2f - db 0x49, 0x82, 0x47, 0x4a, 0x4b, 0x2f, 0x4c, 0x17 - db 0x00, 0x4d, 0x4e, 0x21, 0x81, 0x26, 0x1b, 0x0b - db 0x2f, 0x3d, 0x42, 0x8f, 0x47, 0x48, 0x2e, 0x4f - db 0x50, 0x83, 0x47, 0x51, 0x2f, 0x4c, 0x17, 0x00 - db 0x52, 0x53, 0x39, 0x81, 0x21, 0x1b, 0x54, 0x11 - db 0x51, 0x55, 0x8e, 0x56, 0x57, 0x3c, 0x2e, 0x4f - db 0x49, 0x82, 0x47, 0x58, 0x3b, 0x2f, 0x4c, 0x17 - db 0x81, 0x00, 0x59, 0x5a, 0x39, 0x21, 0x1b, 0x0b - db 0x10, 0x81, 0x2f, 0x90, 0x30, 0x2f, 0x10, 0x5b - db 0x5c, 0x58, 0x5d, 0x3e, 0x2f, 0x07, 0x5e, 0x17 - db 0x82, 0x00, 0x52, 0x5f, 0x4e, 0x21, 0x0f, 0x14 - db 0x82, 0x10, 0x8f, 0x11, 0x10, 0x0b, 0x10, 0x60 - db 0x81, 0x61, 0x2f, 0x07, 0x0c, 0x62, 0x32, 0x83 - db 0x00, 0x16, 0x63, 0x64, 0x28, 0x29, 0x0f, 0x82 - db 0x14, 0x82, 0x0b, 0x81, 0x14, 0x0b, 0x81, 0x0f - db 0x84, 0x14, 0x81, 0x0b, 0x81, 0x14, 0x0b, 0x0c - db 0x10, 0x83, 0x0c, 0x62, 0x03, 0x85, 0x00, 0x65 - db 0x66, 0x21, 0x0f, 0x82, 0x14, 0x84, 0x0b, 0x0c - db 0x0b, 0x29, 0x0f, 0x81, 0x14, 0x81, 0x10, 0x0c - db 0x82, 0x14, 0x82, 0x0b, 0x83, 0x0c, 0x62, 0x03 - db 0x87, 0x00, 0x67, 0x68, 0x39, 0x1b, 0x81, 0x14 - db 0x0b, 0x14, 0x81, 0x0b, 0x0c, 0x14, 0x82, 0x0f - db 0x14, 0x82, 0x10, 0x82, 0x14, 0x83, 0x0b, 0x82 - db 0x0c, 0x62, 0x03, 0x88, 0x00, 0x69, 0x1f, 0x6a - db 0x28, 0x23, 0x29, 0x82, 0x0b, 0x0c, 0x0f, 0x1b - db 0x83, 0x0f, 0x84, 0x14, 0x82, 0x0b, 0x83, 0x0c - db 0x5e, 0x03, 0x8a, 0x00, 0x1d, 0x59, 0x64, 0x28 - db 0x29, 0x0f, 0x81, 0x14, 0x0f, 0x81, 0x1b, 0x84 - db 0x0f, 0x83, 0x14, 0x81, 0x0b, 0x81, 0x0c, 0x81 - db 0x10, 0x62, 0x03, 0x8c, 0x00, 0x6b, 0x6c, 0x28 - db 0x21, 0x0f, 0x82, 0x1b, 0x81, 0x23, 0x83, 0x0f - db 0x85, 0x14, 0x82, 0x10, 0x0c, 0x62, 0x03, 0x8e - db 0x00, 0x6d, 0x6e, 0x39, 0x81, 0x1b, 0x83, 0x23 - db 0x83, 0x0f, 0x83, 0x14, 0x83, 0x10, 0x0c, 0x62 - db 0x03, 0x90, 0x00, 0x63, 0x6a, 0x39, 0x83, 0x23 - db 0x83, 0x0f, 0x83, 0x14, 0x82, 0x10, 0x81, 0x0c - db 0x62, 0x03, 0x91, 0x00, 0x6f, 0x70, 0x71, 0x28 - db 0x81, 0x23, 0x29, 0x0f, 0x81, 0x29, 0x0f, 0x83 - db 0x14, 0x83, 0x0c, 0x62, 0x03, 0x93, 0x00, 0x6b - db 0x6c, 0x28, 0x26, 0x83, 0x29, 0x0f, 0x83, 0x14 - db 0x0b, 0x82, 0x0c, 0x62, 0x03, 0x95, 0x00, 0x6d - db 0x6e, 0x33, 0x23, 0x81, 0x29, 0x81, 0x0f, 0x81 - db 0x14, 0x81, 0x0b, 0x82, 0x0c, 0x62, 0x03, 0x96 - db 0x00, 0x16, 0x72, 0x64, 0x26, 0x82, 0x29, 0x0b - db 0x14, 0x81, 0x0b, 0x82, 0x0c, 0x62, 0x03, 0x98 - db 0x00, 0x73, 0x74, 0x75, 0x23, 0x29, 0x81, 0x0b - db 0x81, 0x14, 0x82, 0x0c, 0x62, 0x03, 0x9a, 0x00 - db 0x76, 0x6e, 0x26, 0x29, 0x0b, 0x81, 0x14, 0x82 - db 0x0c, 0x62, 0x03, 0x9b, 0x00, 0x16, 0x77, 0x78 - db 0x26, 0x81, 0x0b, 0x82, 0x10, 0x79, 0x7a, 0x9d - db 0x00, 0x16, 0x72, 0x23, 0x29, 0x14, 0x10, 0x14 - db 0x7b, 0xa0, 0x00, 0x73, 0x7c, 0x78, 0x7d, 0x7e - db 0x2d, 0xa2, 0x00, 0x16, 0x7f, 0x16, 0xa8, 0x00 -
--- a/src/Icons/warning.inc Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -; \file C:/hw/ostc3/src/OSTC3/Icons/warning.inc -; Generated 2012-08-25T08:45:08 -; -warning_version equ .112 -warning_width equ .25 -warning_height equ .22 -; -warning_block: - db .12, .22 - db .59, 0 -; - dw 0x0000 ; rgb=(0,0,0) - dw 0x2081 ; rgb=(33,16,8) - dw 0xf4a1 ; rgb=(247,148,8) - dw 0xd3c0 ; rgb=(214,123,4) - dw 0x59c1 ; rgb=(90,58,8) - dw 0xfda0 ; rgb=(255,181,0) - dw 0xfd20 ; rgb=(255,165,0) - dw 0xfce1 ; rgb=(255,156,8) - dw 0xfce0 ; rgb=(255,156,0) - dw 0x1880 ; rgb=(25,16,0) - dw 0xfd60 ; rgb=(255,173,0) - dw 0x1040 ; rgb=(16,8,0) - dw 0x51c1 ; rgb=(82,58,8) - dw 0xdce1 ; rgb=(222,156,8) - dw 0x3100 ; rgb=(49,33,0) - dw 0xfde0 ; rgb=(255,189,0) - dw 0xed21 ; rgb=(236,165,8) - dw 0xfde1 ; rgb=(255,189,8) - dw 0xfe20 ; rgb=(255,197,0) - dw 0xfd61 ; rgb=(255,173,8) - dw 0xfda1 ; rgb=(255,181,8) - dw 0xfd21 ; rgb=(255,165,8) - dw 0x28c0 ; rgb=(41,25,0) - dw 0xfca1 ; rgb=(255,148,8) - dw 0x0840 ; rgb=(8,8,0) - dw 0xfe21 ; rgb=(255,197,8) - dw 0xfca0 ; rgb=(255,148,0) - dw 0xfc60 ; rgb=(255,140,0) - dw 0xfc61 ; rgb=(255,140,8) - dw 0x1840 ; rgb=(25,8,0) - dw 0x8301 ; rgb=(132,99,8) - dw 0xfe60 ; rgb=(255,206,0) - dw 0xfce6 ; rgb=(251,156,49) - dw 0xfdae ; rgb=(255,181,115) - dw 0xfd27 ; rgb=(251,165,62) - dw 0xf673 ; rgb=(247,206,156) - dw 0xffbe ; rgb=(255,247,247) - dw 0xe4aa ; rgb=(230,148,82) - dw 0xfea0 ; rgb=(255,214,0) - dw 0xffff ; rgb=(255,255,255) - dw 0xfe72 ; rgb=(255,206,148) - dw 0xf4a0 ; rgb=(247,148,0) - dw 0x6301 ; rgb=(103,99,8) - dw 0xf672 ; rgb=(247,206,148) - dw 0xffbd ; rgb=(255,247,239) - dw 0xee41 ; rgb=(239,203,8) - dw 0x1900 ; rgb=(25,33,0) - dw 0x0040 ; rgb=(0,8,0) - dw 0xede0 ; rgb=(235,189,4) - dw 0x2941 ; rgb=(41,41,8) - dw 0xfe61 ; rgb=(255,206,8) - dw 0x3981 ; rgb=(58,49,8) - dw 0xcd41 ; rgb=(200,168,8) - dw 0x2100 ; rgb=(33,33,0) - dw 0xf621 ; rgb=(247,197,8) - dw 0x5241 ; rgb=(82,74,8) - dw 0x0800 ; rgb=(8,0,0) - dw 0xdd41 ; rgb=(218,169,8) - dw 0xcc21 ; rgb=(206,132,8) -; - db 0xa7, 0x00, 0x01, 0x02, 0x03, 0x90, 0x00, 0x04 - db 0x05, 0x06, 0x07, 0x08, 0x8e, 0x00, 0x09, 0x81 - db 0x0a, 0x81, 0x06, 0x81, 0x08, 0x0b, 0x8b, 0x00 - db 0x0c, 0x0d, 0x05, 0x0a, 0x82, 0x06, 0x81, 0x08 - db 0x0b, 0x8a, 0x00, 0x0e, 0x81, 0x0f, 0x05, 0x0a - db 0x82, 0x06, 0x81, 0x08, 0x0b, 0x88, 0x00, 0x0b - db 0x10, 0x83, 0x05, 0x81, 0x0a, 0x81, 0x06, 0x81 - db 0x08, 0x0b, 0x86, 0x00, 0x0e, 0x11, 0x12, 0x83 - db 0x05, 0x0a, 0x13, 0x0a, 0x81, 0x06, 0x81, 0x08 - db 0x0b, 0x84, 0x00, 0x0b, 0x0d, 0x11, 0x14, 0x82 - db 0x05, 0x82, 0x0a, 0x81, 0x13, 0x81, 0x15, 0x07 - db 0x08, 0x0b, 0x82, 0x00, 0x16, 0x81, 0x11, 0x10 - db 0x83, 0x14, 0x82, 0x0a, 0x81, 0x06, 0x13, 0x07 - db 0x81, 0x17, 0x08, 0x0b, 0x81, 0x00, 0x18, 0x19 - db 0x14, 0x82, 0x06, 0x13, 0x06, 0x15, 0x84, 0x06 - db 0x0a, 0x1a, 0x1b, 0x1c, 0x08, 0x1d, 0x00, 0x1e - db 0x1f, 0x0f, 0x1a, 0x20, 0x88, 0x21, 0x22, 0x06 - db 0x23, 0x24, 0x25, 0x08, 0x09, 0x00, 0x26, 0x19 - db 0x0f, 0x1a, 0x21, 0x88, 0x27, 0x28, 0x29, 0x82 - db 0x27, 0x1a, 0x09, 0x00, 0x2a, 0x1f, 0x0f, 0x06 - db 0x1a, 0x89, 0x1b, 0x06, 0x2b, 0x2c, 0x22, 0x07 - db 0x09, 0x81, 0x00, 0x18, 0x2d, 0x14, 0x05, 0x0a - db 0x81, 0x13, 0x0a, 0x13, 0x05, 0x82, 0x0a, 0x13 - db 0x0a, 0x15, 0x06, 0x81, 0x15, 0x0b, 0x82, 0x00 - db 0x2e, 0x12, 0x05, 0x0a, 0x82, 0x13, 0x15, 0x14 - db 0x81, 0x0a, 0x06, 0x81, 0x0a, 0x81, 0x13, 0x81 - db 0x15, 0x0b, 0x84, 0x00, 0x2f, 0x30, 0x11, 0x81 - db 0x13, 0x15, 0x0f, 0x81, 0x05, 0x82, 0x0a, 0x81 - db 0x13, 0x81, 0x15, 0x0b, 0x86, 0x00, 0x31, 0x32 - db 0x12, 0x81, 0x0f, 0x11, 0x81, 0x05, 0x83, 0x0a - db 0x06, 0x15, 0x0b, 0x89, 0x00, 0x30, 0x82, 0x11 - db 0x81, 0x05, 0x81, 0x0a, 0x81, 0x06, 0x15, 0x0b - db 0x8a, 0x00, 0x31, 0x32, 0x19, 0x81, 0x14, 0x82 - db 0x0a, 0x81, 0x15, 0x0b, 0x8b, 0x00, 0x33, 0x34 - db 0x11, 0x14, 0x05, 0x0a, 0x13, 0x81, 0x15, 0x0b - db 0x8d, 0x00, 0x35, 0x36, 0x14, 0x13, 0x0a, 0x81 - db 0x15, 0x0b, 0x8f, 0x00, 0x37, 0x19, 0x13, 0x81 - db 0x06, 0x38, 0x91, 0x00, 0x35, 0x39, 0x3a, 0x96 - db 0x00
--- a/src/Tests/compass_test.cpp Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -/// compass_test.cpp -/// Unit test for compass calibration. -/// Copyright (c) 2012-2015, JD Gascuel, HeinrichsWeikamp, all right reserved. -////////////////////////////////////////////////////////////////////////////// -// HISTORY -// 2015-05-23 jDG: Rewrite compass testing, to allow reducing code size. - -extern "C" { -# include "compass.h" -} - -#include <gtest/gtest.h> - -#include <math.h> -#include <iostream> - -////////////////////////////////////////////////////////////////////////////// - -inline float uniform() { - return (rand() & 0xFFFF) / 65536.0f; -} -inline float sqr(float x) { - return x*x; -} - -static float radius = 0.21f; -static float cx = 0, cy = 0, cz = 0; - -////////////////////////////////////////////////////////////////////////////// - -static void check_calib() -{ - compass_reset_calibration(); - - //---- Generates random points on a sphere ------------------------------- - // of radius,center (cx, cy, cz): - for(int i=0; i<100; ++i) - { - float theta = uniform()*360.0f; - float phi = uniform()*180.0f - 90.0f; - - float x = cx + radius * cosf(phi)*cosf(theta); - float y = cy + radius * cosf(phi)*sinf(theta); - float z = cz + radius * sinf(phi); - - compass_DX_f = short(32768 * x); - compass_DY_f = short(32768 * y); - compass_DZ_f = short(32768 * z); - compass_add_calibration(); - } - - compass_solve_calibration(); - float r2 = sqr(compass_CX_f/32768.0f - cx) - + sqr(compass_CY_f/32768.0f - cy) - + sqr(compass_CZ_f/32768.0f - cz); - - // Calibration error less than 2 bits: - EXPECT_NEAR(0, sqrtf(r2), 4.0f/32768.0f) - << "Center at (" << compass_CX_f/32768.0f << ", " - << compass_CY_f/32768.0f << ", " - << compass_CZ_f/32768.0f << ")." - << " Error = " << sqrtf(r2); -} - -////////////////////////////////////////////////////////////////////////////// - -TEST(compass, calibration_centered) -{ - compass_CX_f = compass_CY_f = compass_CZ_f = 0; - - // Half-unit, centered, sphere: - radius = 0.5f; - - // Try 10 recalibration passes: - for(int p=0; p<10; ++p) - check_calib(); -} - -////////////////////////////////////////////////////////////////////////////// - -TEST(compass, calibration_near_centered) -{ - // Put magnetic center elsewhere, but keep position+radius < 1.0, to - // avoid Q15 overflow... - radius = 0.21f; - cx = 0.019f, cy = -0.026f, cz = 0.004f; - - // Try 10 recalibration passes: - for(int p=0; p<10; ++p) - check_calib(); -} - -////////////////////////////////////////////////////////////////////////////// - -TEST(compass, calibration_far_centered) -{ - // Put magnetic center elsewhere, but keep position+radius < 1.0, to - // avoid Q15 overflow... - radius = 0.21f; - cx = -0.79f, cy = 0.79f, cz = 0.79f; - - // Try 10 recalibration passes: - for(int p=0; p<10; ++p) - check_calib(); -} - -////////////////////////////////////////////////////////////////////////////// - -TEST(compass, calibration_small_centered_signal) -{ - // use a very very small magnetic signal, centered: - radius = 0.001f; - cx = 0.000f, cy = 0.000f, cz = 0.000f; - - // Try 10 recalibration passes: - for(int p=0; p<10; ++p) - check_calib(); -} - -////////////////////////////////////////////////////////////////////////////// - -TEST(compass, calibration_small_off_centered_signal) -{ - // Have a rather small sphere radius (20%), off-centered buy 80% - radius = 0.200f; - cx = 0.800f, cy = -0.800f, cz = 0.800f; - - // Try 10 recalibration passes: - for(int p=0; p<10; ++p) - check_calib(); -}
--- a/src/Tests/compass_trigo_test.cpp Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -/// compass_trigo_test.cpp -/// Unit test for compass various operations. -/// Copyright (c) 2012-2015, JD Gascuel, HeinrichsWeikamp, all right reserved. -////////////////////////////////////////////////////////////////////////////// -// HISTORY -// 2015-05-23 jDG: Rewrite compass testing, to allow reducing code size. - -extern "C" { -# include "compass.h" -} - -#include <gtest/gtest.h> - -////////////////////////////////////////////////////////////////////////////// -// Fake assembleur fixed point multiplies. -extern "C" Int16 compass_umul(void); -extern "C" Int16 compass_imul(void); -extern "C" Int16 compass_a, compass_b; - -// The (filtered) components of the magnetometer sensor: -Int16 compass_DX_f; -Int16 compass_DY_f; -Int16 compass_DZ_f; - -// Found soft-iron calibration values, deduced from already filtered values. -Int16 compass_CX_f; -Int16 compass_CY_f; -Int16 compass_CZ_f; - -// The (filtered) components of the accelerometer sensor: -Int16 accel_DX_f; -Int16 accel_DY_f; -Int16 accel_DZ_f; - -// The compass result value. -Int16 compass_heading; -Int16 compass_roll; -Int16 compass_pitch; - -Int16 compass_a, compass_b; -Int16 compass_umul() -{ - unsigned int a = compass_a; - unsigned int b = compass_b; - a *= b; - a >>= 15; - return (Int16)a; -} - -Int16 compass_imul() -{ - int a = compass_a; - int b = compass_b; - a *= b; - a >>= 15; - return (Int16)a; -} - -////////////////////////////////////////////////////////////////////////////// - -TEST(ops, multiply) { - // Check basic sign handling: - EXPECT_EQ(umul( 8000, 4000), (Int16)0x03D0); // 8000/2**15 * 4000/2**15 = 0x3D0 - EXPECT_EQ(imul(-8000, 4000), (Int16)0xFC2F); // -976 = 0xFC2F - EXPECT_EQ(imul( 8000, -4000), (Int16)0xFC2F); // -976 = 0xFC2F - EXPECT_EQ(imul(-8000, -4000), (Int16)0x03D0); // +976 = 0x3D0 -} - -TEST(ops, divide) { - // Check basic divides: - EXPECT_EQ(udiv(32000, 32001), (Int16)32766); // 0.99997 ~ 32766 - EXPECT_EQ(udiv( 4000, 8000), (Int16)16384); - EXPECT_EQ(udiv( 2000, 8000), (Int16) 8192); - EXPECT_EQ(udiv( 1000, 8000), (Int16) 4096); - EXPECT_EQ(udiv( 500, 8000), (Int16) 2048); -} - -TEST(trigo, atan) { - // Check angles returned by the SINGLE QUADRANT atan() function: - EXPECT_EQ(utan(100, 100), (Int16)4501); // +1 - EXPECT_EQ(utan( 90, 100), (Int16)4195); // -4 - EXPECT_EQ(utan( 80, 100), (Int16)3864); // -2 - EXPECT_EQ(utan( 70, 100), (Int16)3500); // +1 - EXPECT_EQ(utan( 60, 100), (Int16)3099); // +3 - EXPECT_EQ(utan( 50, 100), (Int16)2658); // +1 - EXPECT_EQ(utan( 40, 100), (Int16)2179); // -1 - EXPECT_EQ(utan( 30, 100), (Int16)1667); // -3 - EXPECT_EQ(utan( 20, 100), (Int16)1127); // -4 - EXPECT_EQ(utan( 10, 100), (Int16) 569); // -2 - EXPECT_EQ(utan( 0, 100), (Int16) 0); -} - -TEST(trigo, cosx2h2) { - // Check ONE-OCTANT pseudo-cosinus function - // Note: cosxh(x**2, x**2+y**2) is computing cos(atan(y/x)) - EXPECT_EQ(cosxh(12769, 13169), (Int16)32268); // 113, 20 --> 10.0369° --> 32267 +1 - EXPECT_EQ(cosxh(10000, 12500), (Int16)29310); // 100, 50 --> 26.5650° --> 29309 +1 - EXPECT_EQ(cosxh(10000, 20000), (Int16)23171); // 100, 100 --> 45.0000° --> 23170 +1 - EXPECT_EQ(cosxh( 2500, 12500), (Int16)14658); // 50, 100 --> 63.4349° --> 14654 +4 - EXPECT_EQ(cosxh( 400, 13169), (Int16) 5718); // 20, 113 --> 79.9631° --> 5711 +7 -} - -TEST(trigo, sinCos) { - Int16 sin, cos; - - //---- Check sincos() FIRST QUADRANT --------------------------------- - sincos( 20, 113, &sin, &cos); // 80° - EXPECT_EQ(sin, (Int16)32269); // +2 - EXPECT_EQ(cos, (Int16) 5727); // +16 - - sincos( 50, 100, &sin, &cos); // 63° - EXPECT_EQ(sin, (Int16)29311); // +2 - EXPECT_EQ(cos, (Int16)14660); // +6 - - sincos(100, 100, &sin, &cos); // 45° - EXPECT_EQ(sin, (Int16)23173); // +3 - EXPECT_EQ(cos, (Int16)23173); // +3 - - sincos(100, 50, &sin, &cos); // 27° - EXPECT_EQ(sin, (Int16)14660); // +6 - EXPECT_EQ(cos, (Int16)29311); // +2 - - sincos(113, 20, &sin, &cos); // 10° - EXPECT_EQ(sin, (Int16) 5727); // +16 - EXPECT_EQ(cos, (Int16)32269); // +2 - - //---- Check sincos() OTHER QUADRANTS -------------------------------- - sincos(-20, 113, &sin, &cos); // 90+80° - EXPECT_EQ(sin, (Int16) 32269); // +2 - EXPECT_EQ(cos, (Int16) -5727); // +16 - - sincos(-20,-113, &sin, &cos); // 180+80° - EXPECT_EQ(sin, (Int16)-32269); // +2 - EXPECT_EQ(cos, (Int16) -5727); // +16 - - sincos( 20,-113, &sin, &cos); // 270+80° - EXPECT_EQ(sin, (Int16)-32269); // +2 - EXPECT_EQ(cos, (Int16) 5727); // +16 -}
--- a/src/Tests/deco_volume_test.cpp Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,291 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -/// deco_volume_test.cpp -/// Unit test for gas consumption c code. -/// Copyright (c) 2015, JD Gascuel, HeinrichsWeikamp, all right reserved. -////////////////////////////////////////////////////////////////////////////// -// HISTORY -// 2015-05-27 jDG: Creation for gas volum re-introduction in hwOS 1.82 - -extern "C" { -# include "p2_deco.c" -} - -#include <gtest/gtest.h> -#include <iostream> - -////////////////////////////////////////////////////////////////////////////// -/// \brief Defines a default OC gas list -static void setup_gas() -{ - char_I_first_gas = 1; - -#define DEFINE_GAS(gas, o2, he, depth, role) \ - char_I_deco_N2_ratio [gas-1] = 100 - o2 - he; \ - char_I_deco_He_ratio [gas-1] = he; \ - char_I_deco_gas_change[gas-1] = depth; - - DEFINE_GAS(1, 21, 0, 0, 1); // Gas#1 : Air FIRST - DEFINE_GAS(2, 18, 30, 0, 2); // Gas#2 : Tx18/30 TRAVEL - DEFINE_GAS(3, 80, 0, 9, 3); // Gas#3 : Nx80 @ 9m DECO - DEFINE_GAS(4, 21, 0, 0, 0); // Gas#2 : air @ 10m DISABLED - DEFINE_GAS(5, 21, 0, 0, 0); // Gas#2 : air @ 40m DISABLED -} - -////////////////////////////////////////////////////////////////////////////// -/// \brief Define a default deco plan. -static void setup_plan(const char* stops, - const char* gas) -{ - int depth = 3 * (stops ? strlen(stops) : 0); - - if( ! depth ) - std::cout << " no deco" << std::endl; - - int s = 0; - while( depth > 0 && s < NUM_STOPS ) { - std::cout << " " << std::setw(2) << int(stops[s]) << "' @ " << depth << "m" << std::endl; - - char_O_deco_time [s] = stops[s]; - char_O_deco_depth[s] = depth; - char_O_deco_gas [s] = gas ? gas[s] : 1; // Gas#1 by default - ++s; - depth -= 3; - } - // Done - for(; s<NUM_STOPS; ++s) { - char_O_deco_time [s] = 0; - char_O_deco_depth[s] = 0; - char_O_deco_gas [s] = 0; - } -} - -static void setup_dive(int bottom, int depth, - const char* stops = 0, const char* gas = 0) -{ - setup_gas(); - setup_plan(stops, gas); - - char_I_bottom_depth = depth; - char_I_bottom_time = bottom; -} - -////////////////////////////////////////////////////////////////////////////// -/// \brief Gas consumption at a fixed depth -static float fixed(int rmv, int time, int depth) { - return rmv * time * (1 + 0.1f*depth); -} - -TEST(gas_volume, fixed) -{ - EXPECT_EQ(20*30*1, fixed(20,30, 0)); // 30' @ 0m - EXPECT_EQ(20*30*5, fixed(20,30,40)); // 30' @ 40m -} - -////////////////////////////////////////////////////////////////////////////// -/// \brief Gas consumption during an ascent at 10m/min. -static float ascent(int rmv, int oldDepth, int newDepth) -{ - return rmv - * abs(oldDepth-newDepth)*0.1f // Ascent time - * (1 + 0.05f*(oldDepth + newDepth)); // Avg pressure. -} - -TEST(gas_volume, ascent) -{ - EXPECT_EQ(0, ascent(20, 30, 30)); // 30m -> 30m : no time, no conso - EXPECT_EQ(20*4*(1+2), ascent(20, 40, 0)); // 40m -> 0m : 4min, avg 20m - EXPECT_EQ(20*4*(1+2), ascent(20, 0, 40)); // 0m -> 40m : 4min, avg 20m -} - -static void check_volumes(float G1, const char* L1, - float G2, const char* L2, - float G3, const char* L3, - float G4, const char* L4, - float G5, const char* L5) -{ - std::cout << " " << std::setw(6) << G1 << " = " << L1 << std::endl; - std::cout << " " << std::setw(6) << G2 << " = " << L2 << std::endl; - std::cout << " " << std::setw(6) << G3 << " = " << L3 << std::endl; - std::cout << " " << std::setw(6) << G4 << " = " << L4 << std::endl; - std::cout << " " << std::setw(6) << G5 << " = " << L5 << std::endl; - - EXPECT_NEAR(G1, int_O_gas_volumes[0], 1) << L1; - EXPECT_NEAR(G2, int_O_gas_volumes[1], 1) << L2; - EXPECT_NEAR(G3, int_O_gas_volumes[2], 1) << L3; - EXPECT_NEAR(G4, int_O_gas_volumes[3], 1) << L4; - EXPECT_NEAR(G5, int_O_gas_volumes[4], 1) << L5; -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, OC, 30%/85% -TEST(gas_volume, OC_13min30m) -{ - char_I_const_ppO2 = 0; // OC - setup_dive(13, 30); // 13' @ 30m --> no deco - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(fixed(20,13,30) + ascent(20,30,0), "Gas1: 1190 L", - 0, "", - 0, "", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, OC, 30%/85% -TEST(gas_volume, OC_15min30m) -{ - char_I_const_ppO2 = 0; // OC - char stops[] = {1, 0}; - char gas[] = {3, 0}; - setup_dive(15, 30, stops, gas); // 15' @ 30m --> 1min at 3m - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(fixed(20,15,30) + ascent(20,30,3), "Gas1: 1343 L", - 0, "", - fixed(20, 1, 3) + ascent(20, 3,0), "Gas3: 33", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, OC, 30%/85% -TEST(gas_volume, OC_29min30m) -{ - char_I_const_ppO2 = 0; // OC - char stops[] = {1, 1, 2, 4, 0}; - char gas[] = {1, 3, 3, 3, 0}; - setup_dive(29, 30, stops, gas); // 29' @ 30m --> 1' 1' 2' 4' - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(fixed(20,29,30) + ascent(20,30,12) + - fixed(20, 1,12) + ascent(20,12, 9), "Gas1: 2488 L", - 0, "", - fixed(20, 1, 9) + ascent(20, 9, 6) + - fixed(20, 2, 6) + ascent(20, 6, 3) + - fixed(20, 4, 3) + ascent(20, 3, 0), "Gas3: 232 L", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, OC, 30%/85% -TEST(gas_volume, OC_15min60m) -{ - char_I_const_ppO2 = 0; // OC - char stops[] = {2, 1, 2, 4, 3, 4, 9, 0}; - char gas[] = {1, 1, 1, 1, 3, 3, 3, 0}; - setup_dive(15, 60, stops, gas); // 15' @ 60m --> DTR 32' - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(fixed(20,15,60) + ascent(20,60,21) + - fixed(20, 2,21) + ascent(20,21,18) + - fixed(20, 1,18) + ascent(20,18,15) + - fixed(20, 2,15) + ascent(20,15,12) + - fixed(20, 4,12) + ascent(20,12, 9), "Gas1: 3010 L", - 0, "", - fixed(20, 3, 9) + ascent(20, 9, 6) + - fixed(20, 4, 6) + ascent(20, 6, 3) + - fixed(20, 9, 3) + ascent(20, 3, 0), "Gas3: 502 L", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, CCR, 30%/85% -TEST(gas_volume, CCR_23min30m) -{ - char_I_const_ppO2 = 140;// SP 1.4 bar - setup_dive(23, 30); // 23' @ 30m --> no deco / no BAIL deco - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(/*NO BTM CONSO*/ ascent(20,30,0), "Gas1: 150 L", - 0, "", - 0, "", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, CCR, 30%/85% -TEST(gas_volume, CCR_25min30m) -{ - char_I_const_ppO2 = 140;// SP 1.4 bar - char stops[] = {1, 0}; - char gas[] = {3, 0}; - setup_dive(25, 30, stops, gas); // 25' @ 30m --> no deco / BAIL 1' @ 3m - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(/*NO BTM CONSO*/ ascent(20,30,3), "Gas1: 143 L", - 0, "", - fixed(20, 1, 3) + ascent(20, 3,0), "Gas3: 33 L", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, CCR, 30%/85% -TEST(gas_volume, CCR_45min30m) -{ - char_I_const_ppO2 = 140; // SP 1.4 bar - char stops[] = {1, 2, 5, 0}; - char gas[] = {3, 3, 3, 0}; - setup_dive(45, 30, stops, gas); // 45' @ 30m - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(/*NO BTM CONSO*/ ascent(20,30, 9), "Gas1: 124 L", - 0, "", - fixed(20, 1, 9) + ascent(20, 9, 6) + - fixed(20, 2, 6) + ascent(20, 6, 3) + - fixed(20, 5, 3) + ascent(20, 3, 0), "Gas3: 258 L", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, CCR, 30%/85% -TEST(gas_volume, CCR_19min51m) -{ - char_I_const_ppO2 = 140; // SP 1.4 bar - char stops[] = {1, 2, 2, 4, 3, 4, 9, 0}; - char gas[] = {1, 1, 1, 1, 3, 3, 3, 0}; - setup_dive(19, 51, stops, gas); // 19' @ 51m --> 20' CCR / 31' BAIL - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(/*NO BTM CONSO*/ ascent(20,51,21) + - fixed(20, 1,21) + ascent(20,21,18) + - fixed(20, 2,18) + ascent(20,18,15) + - fixed(20, 2,15) + ascent(20,15,12) + - fixed(20, 4,12) + ascent(20,12, 9), "Gas1: 786 L", - 0, "", - fixed(20, 3, 9) + ascent(20, 9, 6) + - fixed(20, 4, 6) + ascent(20, 6, 3) + - fixed(20, 9, 3) + ascent(20, 3, 0), "Gas3: 502 L", - 0, "", - 0, ""); -} - -////////////////////////////////////////////////////////////////////////////// -// v1.82 ZH-L16+GF, CCR, 30%/85% -TEST(gas_volume, CCR_15min60m) -{ - char_I_const_ppO2 = 140; // SP 1.4 bar - char stops[] = {2, 1, 1, 3, 5, 4, 8, 0}; // BAILOUT mode - char gas[] = {3, 3, 3, 3, 3, 5, 5, 0}; - setup_dive(15, 60, stops, gas); // 15' @ 60m --> DTR 32' - - DEFINE_GAS(3, 32, 0, 40, 3); // Gas#3 : Nx32 @ 40m DECO - DEFINE_GAS(5, 90, 0, 6, 3); // Gas#5 : Nx90 @ 6m DECO - - ASSERT_NO_THROW( deco_gas_volumes() ); - check_volumes(/*NO BTM CONSO*/ ascent(20,60,21), "Gas1: 394 L", - 0, "", - fixed(20, 2,21) + ascent(20,21,18) + - fixed(20, 1,18) + ascent(20,18,15) + - fixed(20, 1,15) + ascent(20,15,12) + - fixed(20, 3,12) + ascent(20,12, 9) + - fixed(20, 5, 9) + ascent(20, 9, 6), "Gas3: 623 L", - 0, "", - fixed(20, 4, 6) + ascent(20, 6, 3) + - fixed(20, 8, 3) + ascent(20, 3, 0), "Gas5: 352 L"); -}
--- a/src/Tests/unit_test.cpp Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -/// main_test.cpp -/// Launch all defined GoogleTest unit tests defined. -/// Copyright (c) 2012-2015, JD Gascuel, HeinrichsWeikamp, all right reserved. -////////////////////////////////////////////////////////////////////////////// -// HISTORY -// 2015-05-23 jDG: Rewrite compass testing, to allow reducing code size. - -#include <gtest/gtest.h> - -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -
--- a/src/Tests/unit_test.pro Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -#----------------------------------------------------------------------------- -# -# Project created by QtCreator 2013-03-29T10:58:23 -# -#----------------------------------------------------------------------------- - -TEMPLATE = app -TARGET = unit_test - -CONFIG *= qt -CONFIG -= app_bundle - -QT *= core -QT -= gui - -DEFINES *= UNIX - -#----------------------------------------------------------------------------- -# Need the GoogleTest 1.6.0 library here: -GTEST=$$PWD/../../../gtest-1.6.0 -!exists($$GTEST/include): GTEST=$$PWD/../../../../Dependencies/gtest-1.6.0 -!exists($$GTEST/include): error(Requires GoogleTest 1.6.0) -INCLUDEPATH *= $$GTEST/include $$GTEST/gtest-1.6.0 -SOURCES *= $$GTEST/gtest-1.6.0/src/gtest-all.cc - -win32: DEFINES *= _VARIADIC_MAX=10 - -#----------------------------------------------------------------------------- -# Avoid unwanted warnings - -unix { - QMAKE_CXXFLAGS_WARN_ON *= -Wno-unknown-pragmas -} - -win32 { - QMAKE_CXXFLAGS *= -wd4244 -wd4068 -wd4305 -} - -#----------------------------------------------------------------------------- -SOURCES += \ - $$PWD/../compass.c \ - $$PWD/../compass_calib.c \ - compass_trigo_test.cpp \ - compass_test.cpp \ - deco_volume_test.cpp \ - unit_test.cpp - -INCLUDEPATH *= $$PWD/.. -HEADERS += \ - $$PWD/../shared_definitions.h \ - $$PWD/../p2_definitions.h \ - $$PWD/../p2_deco.c \ - $$PWD/../compass.h
--- a/src/aa_fonts.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/aa_fonts.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File aa_fonts.asm combined next generation V3.01.1 +; File aa_fonts.asm combined next generation V3.03.5 ; ; Font-data for the anti-aliased word processor ; @@ -173,8 +173,6 @@ endif ;---- HUGE font description and data ---------------------------------------- - IFDEF _huge_font - global aa_font92_block aa_font92_block: DB ' ', 0x2F @@ -192,7 +190,5 @@ error SMALL font should be encoded with 3bits anti-aliasing... endif - ENDIF - ;============================================================================= END \ No newline at end of file
--- a/src/aa_wordprocessor.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/aa_wordprocessor.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File aa_wordprocessor.asm combined next generation V3.03.1 +; File aa_wordprocessor.asm combined next generation V3.03.7 ; ; Anti-aliased word processor ; @@ -47,10 +47,7 @@ extern aa_font34_block extern aa_font48_block extern aa_font90_block - - IFDEF _huge_font extern aa_font92_block - ENDIF extern convert_for_display2 @@ -121,10 +118,8 @@ ; 4: LARGE font ------------------------------------------------------ aa_char_4: - IFDEF _huge_font decfsz WREG ; requested large font? bra aa_char_5 ; NO - ENDIF movlw LOW aa_font90_block movwf TBLPTRL movlw HIGH aa_font90_block @@ -133,7 +128,6 @@ movwf TBLPTRU bra aa_char_99 - IFDEF _huge_font ; 5: XTRA LARGE font ------------------------------------------------- aa_char_5: movlw LOW aa_font92_block @@ -142,7 +136,7 @@ movwf TBLPTRH movlw UPPER aa_font92_block movwf TBLPTRU - ENDIF + ; Execute font block ------------------------------------------------- aa_char_99: @@ -155,7 +149,7 @@ aa_char_30: tblrd*+ ; read FROM char movf TABLAT,W ; get it, and set Z,N - bz aa_char_32 ; branch if end of translation table reached + bz aa_char_32 ; break at end of translations tblrd*+ ; read TO char cpfseq PRODL ; FROM == current char ? @@ -426,6 +420,8 @@ btfsc screen_type2 ; display 2 ? bra aa_decode_3_display2 ; YES + btfsc screen_type3 ; display 3 ? + bra aa_decode_3_display3 ; YES movff PRODH,PORTA ; move high byte to PORTA movff PRODL,PORTH ; move low byte to PORTH @@ -448,6 +444,17 @@ bsf tft_nwr ; tick decf aa_bitlen,F bnz aa_decode_3_display2 + bra aa_decode_3_done + +aa_decode_3_display3: + movff PRODH,PORTH ; move high byte to PORTH (DISPLAY is big endian) + bcf tft_nwr + bsf tft_nwr ; tick + movff PRODL,PORTH ; move low byte to PORTH + bcf tft_nwr + bsf tft_nwr ; tick + decf aa_bitlen,F + bnz aa_decode_3_display3 aa_decode_3_done: ;---- BYTE-CODE LOOP ------------------------------------------------- @@ -464,7 +471,7 @@ ;------------------------------------------------------------------------------ ; Setup pointers for a char: ; Inputs : buffer : string to print (NULL TERMINATED) -; Output : TFT commands on port D + clocks +; Output : TFT commands on PORTH (Upper) and PORTA (lower) + clocks ; global aa_wordprocessor ; callable from C-code aa_wordprocessor:
--- a/src/adc_lightsensor.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/adc_lightsensor.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File adc_lightsensor.asm combined next generation V3.03.2 +; File adc_lightsensor.asm combined next generation V3.03.5 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -219,7 +219,7 @@ global get_ambient_level ; called from ISR only, in context bank isr_backup -get_ambient_level: ; starts ADC and waits until finished +get_ambient_level: btfsc sleepmode ; in sleep mode? return ; YES - done btfsc adc_is_running ; NO - ADC in use? @@ -486,6 +486,7 @@ banksel HW_variants ; switch to bank where OSTC model variant is stored btfsc analog_switches ; does the OSTC have analog switches? bra get_analog_switches_1 ; YES +get_analog_switches0: banksel common ; NO - back to bank common bcf analog_sw1_pressed ; - clear flag for analog switch 1 bcf analog_sw2_pressed ; - clear flag for analog switch 2 @@ -495,10 +496,13 @@ banksel common ; back to bank common btfsc adc_is_running ; ADC in use? return ; YES - abort - ;bra get_analog_switches_2 ; NO - read switches + btfsc cc_active ; NO - charging? + bra get_analog_switches0 ; YES - abort (And clear both flags) + ;bra get_analog_switches_2 ; NO - read switches get_analog_switches_2: - movlw b'00001001' ; left justified + bsf adc_is_running + movlw b'00001010' ; left justified movwf ADCON2 ; movlw b'00000000' ; Vref+ = Vdd clrf ADCON1 @@ -610,9 +614,9 @@ bsf analog_sw1_pressed ; set right button as pressed get_analog_switches_4: - movlw b'10001101' ; restore to right justified + movlw b'10001010' ; restore to right justified movwf ADCON2 - + bcf adc_is_running banksel common ; back to bank common btfsc analog_sw1_pressed ; right button pressed? return ; YES - done
--- a/src/changelog.txt Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,510 +0,0 @@ -[2.96] -- Beta Version - - - -[2.27] -- Beta Version - -BUGFIX: Display of negative (C) water temperatures -NEW: Display dezimal for temperatures between 10 and 0C - -[2.25] -- Stable Version - -BUGFIX: "lost gas" showed current set of gases (Diluents in CC, OC in Bailout) for both "lost gas" menus -NEW: Show Compass calibration results in Compass menu -BUGFIX: Simulator in CC mode -BUGFIX: Changing the dive mode and starting the simulator (without leaving the menu first) caused false calculations in the simulator -BUGFIX: PSCR Mode "OC Gases" showed Diluents, not OC gases -BUGFIX: CCR Mode ("First Diluent") was chosen based on OC "First Gas" number - -[2.23] -- Beta Version - -CHANGE: CCR Calibration gas range limited to O2% 21-25 and 95-100 to save button presses -NEW: Show a warning for each sensor if the sensor is end-of-life after calibration (Less then 8mV in Air at sea level) -CHANGE: Minor optimizations - -[2.20] -- Beta Version - -BUGFIX: Lost Diluent now possible in CCR and PSCR mode -NEW: ppO2 blinks in sensor mode when min/max boundaries are hit -CHANGE: Show actual GF (Not relative) in custom views in dive mode -BUGFIX: Do not check ppO2 for disabled gases -CHANGE: Apply safety margin parameters to both models (GF and non-GF) -BUGFIX: Impossible fixed-ppO2 (e.g. 1,6bar in 3m) used for tissue calculations -BUGFIX: Menu tree cleaned up (Exited to CCR menu from simulator settings) -BUGFIX: Do not show GF in divemode for non-GF deco mode -BUGFIX: Skip MOD Test for CCR in Sensor modes (OSTC cR and OSTC3 only) -CHANGE: Swap positions of ppO2(O2) and ppO2(Dil) in customview 10 on screen: "left = lean" and "right = rich" -BUGFIX: A wrong configured gas was suggested as "Better gas" on the configured depth even if this resulted in a ppO2 high or low condition -BUGFIX: O2 as diluent in CCR caused wrong calculations (Deco, EAD, END) in less then 6m depth -BUGFIX: Ignore "Toggle GF" Menu entry (in divemode) when using the non-GF deco mode -BUGFIX: Minor dive mode layout fixes in CCR Mode -CHANGE: Minor German language fixes -NEW: Warning for Diluent beeing out of safe ppO2 range in CCR modes -NEW: New Customview 9 in OSTC cR or OSTC3 shows mV readings after Sensor calibration - -[2.18] -- Beta Version - -NEW: Third and fourth logbook page per dive showing Gaslist and Setpoints in standard font size -BUGFIX: several minor graphic issues in logbook fixed -BUGFIX: Rare button issues in OSTC Plus hardware -BUGFIX: Compass sensitivity for newer models -BUGFIX: PSCR mode showed bailout gaslist instead of diluent gaslist -BUGFIX: PSCR mode "Better Gas" showed bailout gases instead of diluents -NEW: More customviews in surface mode for PSCR mode -NEW: Last Dive customviews in surface mode with divetime, depth and interval -BUGFIX: Reset to MOD in Diluent Menu did reset Setpoint change depth -NEW: Two ppO2 max settings. One for travel/bottom and one for deco gases - -[2.15] -- Stable Version - -NEW: Deep Sleep mode for OSTC Plus and OSTC 2 (2017) (Entered automatically) -NEW: Logbook detail page in larger font (And nicer layout) -CHANGE: Sleep mode current slightly reduced for all hwOS devices -NEW: Logbook now records battery information -NEW: Markers in internal logbook drawn as small "m" next to the profile - -[2.14] -- BETA Version - -NEW: PSCR mode (Passive semi-closed rebreather) - -[2.13] -- Stable Version - -BUGFIX: Layout fixes in Gauge mode (German and French language only) - -[2.12] -- Stable Version - -CHANGE: Indicate "Bailout" for bailout deco plan in internal deco planer -CHANGE: Easier to understand "New Battery" menu (OSTC model dependent) -BUGFIX: Minor layout corrections in imperial units dive screen -NEW: New Customview 11 in dive mode shows ppO2, EAD/END and CNS -CHANGE: Customview 4 shows Clock, Battery Information and Tissue Information -CHANGE: Show warnings either in Customview (If active) _or_ next to warning sign -NEW: Show battery type in information menu (T0:1.5V AA, T1:3.6V AA, T2:3.6V/0.8A LiIon, T3:Internal 18650, T4:Internal 16650) -NEW: Show battery type in surface mode next to battery voltage - -[2.10] -- Stable Version - -NEW: Adjustable timeout for Divemode -CHANGE: Firmware now split in two variants (EN/DE) and (FR/IT) -NEW: New battery option for AA 3,7V rechargable (For OSTC 3) -NEW: Show Uptime (Time since last firmware boot) in information menu -NEW: Store more battery info into logbook memory -BUGFIX: Minor text alignment fixes - -[2.09] -- Stable Version - -BUGFIX: Compatibility with "hwOS Config" fixed -NEW: New hardware descriptor command 0x60 added (For PC programs) - -[2.08] -- Stable Version - -CHANGE: Logbook marker temporally disabled in internal logbook -BUGFIX: Characters with descenders were not drawn correctly in rare cases -NEW: Support for different compass chip (Internal hardware change) -CHANGE: Language fixes - -[2.07] -- Stable Version - -Release version for new OSTC2 (Minor internal hardware changes) - -[2.06] -CHANGE: Remove ppO2 [Dil] from OC dive mode screen - -[2.05] -NEW: Support for new logbook memory chip (minor hardware change) -BUGFIX: Button sensitivity was not reset after update in some cases - -[2.04] -- Beta Version - -NEW: New Customview shows ppO2(O2) and ppO2(Diluent) during CCR mode - -[2.03] -- Stable Version - -BUGFIX: Fix missing ccr setup menu (From 2.02) - -[2.02] -- Stable Version - -BUGFIX: Fix rare issue after battery change (OSTC3 did not start properly) - -[2.01] -- Stable Version - -BUGFIX: Divetime >99mins was not displayed (Only OSTC2 with serial > 10500) -BUGFIX: Minor layout fixes in divemode (Dynamic gaslist and stopwatch) -BUGFIX: Minor language updates - -[2.00] -- Stable Version - -NEW: Logbook marker can be set in dive mode menu (OC only) -NEW: Logbook shows markers with small orange boxes in the profile -NEW: "Lost Gas" feature allows disabling gases during the dive - -[1.94] -- Beta Version - -CHANGE: Show velocity from 5m/min or more (Ascend or descent) -BUGFIX: Make sure SP1 is always selected on start in Auto-SP mode -CHANGE: New segmented speed graph in divemode -NEW: Safety Stop can be configured (Start-, End- and reset-depth + length of stop) via PC - -[1.93] -- Stable Version - -BUGFIX: minor text allignment in CCR mode -CHANGE: fix timing issues during Bluetooth download (Bluetooth models only) - -[1.92] -- Stable Version - -CHANGE: Logbook now shows end-of-dive date and time for dives made with firmware <1.92 indicated by an icon in the logbook -CHANGE: Logbook shows start-of-dive date and time for dives made with firmware >=1.92 -BUGFIX: Text alignment in logbook -NEW: Show actual dive count in logbook list view (If <1000) -BUGFIX: Minor language and text aligment fixes - -[1.91] -- Stable Version - -BUGFIX: German texts in ppo2 menu were too long for screen resulting in resulting in text display issues - -[1.90] - -- Stable Version - -CHANGE: Do not show ppO2 in warning area if already shown in custom view -BUGFIX: Logbook list view for more then 100 stored dives -BUGFIX: BLE timings for MAC issues -BUGFIX: Battery consumption calculation in sleep mode (3,6V battery only) -NEW: Bearing can be set in surface mode -BUGFIX: +5min for stopwatch during simulation did not work -CHANGE: minor language updates - -[1.88] - -- Stable Version - -BUGFIX: Start with Sensor use from sleep (cR only) -CHANGE: Apply button settings when button menu is closed -NEW: Reset button settings on a magnet reset (cR and OSTC 2) - - -[1.87] - -- Stable Version - -NEW: Additional temperature calibration via PC interface -NEW: Hardware support (Screen) - -[1.86] - -- Stable Version - - - -[1.85] - -- Beta Version - -BUGFIX: Rotate button sensitivity with screen (OSTC 2 and cR) -CHANGE: GF and aGF high range increased to 45-110% -NEW: New option to download "Compact Headers". Improved BLE support (OSTC 2 and OSTC 3+) -NEW: Quit Simulator automatically when starting a real dive -BUGFIX: Auto-Brightness clipped to lowest settings in bright sunlight on some devices -CHANGE: Auto SP now available on OSTC 2 - -[1.82] - -- Beta Version - -CHANGE: change button sensitivity range and default (OSTC2 and cR) -NEW: MOD Warning (Can be disabled) -NEW: Depth dependent ascend speed (Can be disabled) -NEW: Graphical speed indicator (Can be disabled) -NEW: Option to always show the ppO2, shows ppO2 for Diluent in CC mode -NEW: Mode Auto SP: Automatically switches the SP during descent (CC Mode) -NEW: Deco planer computes gas consumption for all gases and can compute bailout plans for CC modes - -[1.81] - -- Stable Version - -BUGFIX: Fix download issue for dives made with 1.80 firmware - -[1.80] - -- Stable Version - -CHANGE: Automatically abort connection fail after 2mins (Bluetooth only) -BUGFIX: Fast Gas change near the ppO2 limit could cause switching to a non-available Gas #0 -CHANGE: Code now called hwOS officially -BUGFIX: There was a 1:4096 chance that a portion of a dive was not stored correctly resulting in download issues - -[1.78] - -- Stable Version - -BUGFIX: Increase timing tolerance for S8 HUD (cR only) -CHANGE: increase min input voltage from 1,2mV to 1,9mV (cR only) -CHANGE: adjust menu for different hardware versions (OSTC 2) - -[1.77] - -- Stable Version - -BUGFIX: Charge done indicator (cR and 2 Hardware) -BUGFIX: Analog sensors were ignored in 1.76 - -[1.76] - -- Stable Version - -CHANGE: aGF pair has same range then normal GF pair -BUGFIX: Always update CCR sensor data in Sensor-Menu -NEW: Graphical compass display in dive mode -NEW: Bearing option in divemode -CHANGE: New warning icon - -[1.75] - -- Stable Version - -BUGFIX: Show average depth with one dezimal digit only -NEW: Show start gas in OC mode permanently -NEW: Show OSTC2-like active gas boxes in surface mode - -[1.74] - -- Stable Version - -BUGFIX: Show dives with >999mins divetime correctly -NEW: Support for optical hwHUD without the LED module (OSTC3 only) - -[1.72] - -- Stable Version - -BUGFIX: Store new dives after power-loss during divemode correctly -NEW: Make button sensitivity configurable (cR hardware) - -[1.70] - -- Stable Version - -NEW: Show plan parameters in decoplan result page -NEW: On-board simulator can increase divetime in 5min steps -BUGFIX: Layout fixes - -[1.62] - -- Beta Version - -CHANGE: (Slightly) reduce current consumption in Eco and sleep mode -NEW: Allow auto-return from setpoint fallback - -[1.61] - -- Beta Version - -BUGFIX: O2 > 99% was not configurable from the PC -BUGFIX: Quit Apnea mode on the surface manually -BUGFIX: Check min and max values after PC configuration properly -CHANGE: Longer timeout (4 min) for calibration menu and Surface mode (CCR Modes) -NEW: Show Bailout Gas List in Surface mode (CCR Modes) -CHANGE: Faster update rate for sensor display in surface mode - -[1.60] - -- Stable Version - -BUGFIX: END/EAD updated when adjusting current gas during the dive - -[1.54] - -- Beta Version - -BUGFIX: Future TTS in sensor mode (CCR Mode) -CHANGE: Clarify Travel Gases with "---" as change depth -CHANGE: Enable "Change Depth" Menu only for deco gases -CHANGE: Draw a frame around the dive mode menu -BUGFIX: Average depth computation - -[1.53] - -- Beta Version - -BUGFIX: Flip compass with flipped screen, too -BUGFIX: Surface interval was paused during simulator -BUGFIX: False max. temp in Logbook, false Bailout and Gas 6 flags in logbook -CHANGE: Improve internal logbook usability -CHANGE: Compass readout smoothed - -[1.52] - -- Beta Version - -NEW: Safe tissue data, date and time during firmware update -CHANGE: Postion of min. and (NEW:) max. temperature in logbook -BUGFIX: Fast diluent (w/o dive mode menu) change did not work correctly - -[1.51] - -- Beta Version - -BUGFIX: Clear Setpoint-Fallback warning when in bailout -NEW: 180 display rotation option -NEW: Show ppO2 for change depth during gas setup -CHANGE: Re-arranged Settings Menu -BUGFIX: PC configuration issues fixed - -[1.50] - -Stable release - -[1.46] - -- Beta Version - -NEW: Setpoint-Fallback option for external O2 sensor failure - -[1.45] - -- Beta Version - -CHANGE: Minor German language update -BUGFIX: Clock setting (Bug from 1.44beta) - -[1.44] - -- Beta Version - -NEW: Update warnings every second -NEW: Show "Stop" in front of Safety Stop -BUGFIX: Start dive mode simulator in correct depth -BUGFIX: Surface interval was not displayed correctly in some cases -NEW: Store tissue load, date and time, surface interval, desat. time and nofly time every hour and reload them after battery change -NEW: Show clock in Apnea mode, minor layout changes in Apnea mode -NEW: Simplify gas change (Two button presses only) - -[1.41] - -- Beta Version - -NEW: Ceiling display (GF_hi based) in divemode -NEW: Support for C3 hardware -CHANGE: Show heading with leading zeros -BUGFIX: Do not show "GF info" for non-GF modes -BUGFIX: Minor display allignment changes - -[1.40] - -CHANGE: Minor language updates -NEW: Show a Safety Stop if enabled (Menu "Deco Parameters") -BUGFIX: dive profile recording issue in OC mode -BUGFIX: OSTC settings via USB issues -BUGFIX: CNS in deco planner - -[1.30] - -NEW: Show event "Bailout" in internal logbook -CHANGE: Always compute bailout plan based on all active gases -CHANGE: Re-select last diluent when returning from bailout to OC -BUGFIX: Show "*" always in front of the initial Setpoint 1 - -[1.26] - -BUGFIX: compass calibration does now timeout automatically after 60s -BUGFIX: decoplan re-calculation in bailout case - -[1.25] - -BUGFIX: No average depth for end-of-dive portion (<1m) -BUGFIX: Show "CC Diluents" in logbook instead of OC Gas List -NEW: automatic compass gain makes calibration quicker -CHANGE: Battery percent setpoints adjusted to worst case current consumption - -[1.24] - -CHANGE: Minor french translation -CHANGE: No warning sign for selected aGF -CHANGE: Show battery warning sign for less then 10% battery capacity only -CHANGE: Color schemes improved - -[1.23] - -BUGFIX: Reset Logbook did not reset Logbook TOC properly - -[1.22] - -BUGFIX: Potential bug to freeze the OSTC3 after battery change or update - -[1.21] - -CHANGE: French Translations, again -BUGFIX: Fix cursor in "New Battery" menu -NEW: Show serial number and firmware version in main menu -CHANGE: "Reset all" returns to surface mode -CHANGE: Single press surfacemode menu - -[1.20] - -Stable release - -[1.12] - -BUGFIX: Maintain last selected customview in surface mode -BUGFIX: Set Day for months <31 days -CHANGE: Some French Translations -CHANGE: Default Future TTS=0 (Disabled) -NEW: Expand "gas change window" up to 1m below programmed - change depth (If ppO2 within user-set max. threshold) -BUGFIX: Intermittent USB connection on MAC - -[1.11] - -NEW: allow logbook erase from reset menu -NEW: show battery voltage in info menu - -[1.10] - -Stable release - -[1.04] - -NEW: 1.6 hardware support -CHANGE: Backlight level in eco mode -BUGFIX: Display Desat.-Time >100 hours - -[1.03] - -NEW: user-selectable color schemes -BUGFIX: div. language corrections -NEW: Dynamic Gaslist in OC mode (Divemode, Customview 7) -CHANGE: Change "O2" warning to "ppO2" -NEW: "End-of-Dive" countdown when surfaced - -[1.02] - -CHANGE: Time and Date in normal (Not tiny) font -BUGFIX: Minor french language fix - -[1.01] - -BUGFIX: deco gas init in OC planner - -[1.00] - -BUGFIX: Percent display with 1,5V batteries - -[0.99] - -BUGFIX: alternating brightness at very low ambient light -CHANGE: GF high lowest setting 60% -BUGFIX: NOAA tables for CNS are in ATA, not bar -CHANGE: change apnea timeout, do no longer store apnea dives in logbook -BUGFIX: Simulator in CC mode -BUGFIX: Apnea total divetime -BUGFIX: Battery percent value with 3,6V battery -NEW: Surface customview with important deco settings - -[0.98] - -New: Add cardinal (and ordinal) directions for the compass - -[0.97] - -NEW: compass gain option to work with more magnetic battery types -BUGFIX: fix imperial units in logbook - -[0.96] - -NEW: calm compass reading for minor heading changes -NEW: reduce eco low brightness threshold (for cave diving) - -[0.95] - -BUGFIX: Show "MOD:" instead of "EAD:" in gas setup - -[0.94] - -CHANGE: Show Max. Depth with 0.1m precision - -[0.91] - -BUGFIX: Battery percents in cold water - -[0.93] - -BUGFIX: Custom text <60 chars -BUGFIX: Logbook PC protocol -Italian language updates -BUGFIX: Timeout in decoplanner result page -
--- a/src/color_processor.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/color_processor.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File File color_processor.asm combined next generation V3.03.2 +; File File color_processor.asm combined next generation V3.03.7 ; ; Decompress and draw an image ; @@ -154,6 +154,9 @@ btfsc screen_type2 ; display type 2 ? bra color_image_display2 ; YES + btfsc screen_type3 ; display type 3 ? + bra color_image_display3 ; YES + movff PRODH,PORTA ; NO - move color high byte to PORTA movff PRODL,PORTH ; - move color low byte to PORTH @@ -183,6 +186,20 @@ bra color_image_pixel2_loop ; loop if not zero decfsz pixel_count+1 ; decrement pixel counter, high byte bra color_image_pixel2_loop ; loop if not zero + bra color_image_pixel_com ; all pixels transmitted + +color_image_display3: + movff PRODH,PORTH ; move color high byte to PORTH + bcf tft_nwr ; toggle write signal + bsf tft_nwr ; ... + movff PRODL,PORTH ; move color high byte to PORTH + bcf tft_nwr ; toggle write signal + bsf tft_nwr ; ... + decfsz pixel_count+0 ; decrement pixel counter, low byte + bra color_image_display3 ; loop if not zero + decfsz pixel_count+1 ; decrement pixel counter, high byte + bra color_image_display3 ; loop if not zero +; bra color_image_pixel_com ; all pixels transmitted color_image_pixel_com: bsf INTCON,GIE ; re-enable global interrupts
--- a/src/comm.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/comm.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File comm.asm combined next generation V3.03.3 +; File comm.asm combined next generation V3.04.3 ; ; RS232 via USB ; @@ -91,7 +91,13 @@ call TFT_standard_color ; set standard color WIN_TOP .10 ; positioning of USB/BLE logo, row WIN_LEFT .1 ; positioning of USB/BLE logo, column - TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_block ; show USB/BLE logo, respective logo is stored in bootloader section dependent on OSTC type + btfsc battery_gauge_available ; "+" bootloader ? + bra comm_mode_common_3 ; NO + TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_2 ; YES - show USB/BLE logo 2 + bra comm_mode_common_4 +comm_mode_common_3: + TFT_WRITE_PROM_IMAGE_BY_ADDR usb_ble_logo_1 ; NO - show USB/BLE logo 1 +comm_mode_common_4: WIN_SMALL comm_status1_column,comm_status1_row ; positioning of status message STRCPY_TEXT_PRINT tUsbStarting ; print status message "starting..." WIN_TINY .40,.240-.16 ; set output position to bottom line @@ -127,6 +133,8 @@ bra comm_mode2c ; NO bra comm_download_mode ; YES - received start byte for download mode comm_mode2c: + btfsc ble_available ; BLE available? + bra comm_mode4a ; YES - skip USB check check (required for very old OSTC sport) btfss vusb_in ; USB plugged in? bra comm_service_exit_nousb_delay; NO - disconnected, exit comm mode comm_mode4a: @@ -170,7 +178,8 @@ WAITMS d'200' ; wait 200 ms btfsc vusb_in ; USB plugged in? bra comm_mode4a ; YES - (still) connected, return -comm_service_exit_nousb: ; NO - disconnected +comm_service_exit_nousb: + bcf LEDr ; switch off red LED WIN_SMALL comm_status3_column, comm_status3_row STRCPY_TEXT_PRINT tUsbClosed ; print port closed message bra comm_service_exit_common ; exit to restart @@ -410,18 +419,21 @@ dcfsnz comm_timeout_timer,F ; decrement timeout, reached zero? bra comm_service_exit ; YES - exit comm_download_mode2: - rcall comm_get_byte ; No - check for a byte + rcall comm_get_byte ; NO - check for a byte btfsc comm_service_enabled ; com service mode enabled? btg LEDr ; YES - blink in service mode + btfsc ble_available ; BLE available? + bra comm_download_mode3 ; YES - skip USB check (required for very old OSTC sport) btfss vusb_in ; USB plugged in? bra comm_service_exit_nousb ; NO - disconnected -> exit - btfsc switch_right ; YES - shall abort? - bra comm_service_exit ; YES - btfsc trigger_full_second ; NO - did 1 second elapsed meanwhile? - bra comm_download_mode1 ; YES - check for timeout - btfsc rs232_rx_timeout ; NO - got a byte? - bra comm_download_mode2 ; NO - loop waiting for command byte - ; YES - command received +comm_download_mode3: + btfsc switch_right ; shall abort? + bra comm_service_exit ; YES + btfsc trigger_full_second ; NO - did 1 second elapsed meanwhile? + bra comm_download_mode1 ; YES - check for timeout + btfsc rs232_rx_timeout ; NO - got a byte? + bra comm_download_mode2 ; NO - loop waiting for command byte + ; Command received bcf LEDr movlw 0xFF cpfseq RCREG1 @@ -1176,9 +1188,15 @@ dcfsnz WREG movff opt_tissue_graphics, TXREG1 ; RCREG1=0x89 dcfsnz WREG - movff opt_layout, TXREG1 ; RCREG1=0x90 + movff opt_layout, TXREG1 ; RCREG1=0x8A + dcfsnz WREG + movff opt_extended_stops, TXREG1 ; RCREG1=0x8B dcfsnz WREG - movff opt_extended_stops, TXREG1 ; RCREG1=0x91 + movff char_I_gas_density_att, TXREG1 ; RCREG1=0x8C + dcfsnz WREG + movff char_I_gas_density_warn, TXREG1 ; RCREG1=0x8D + dcfsnz WREG + movff char_I_dil_ppO2_check, TXREG1 ; RCREG1=0x8E comm_read_abort: comm_read_done: @@ -1505,9 +1523,15 @@ dcfsnz WREG movff RCREG1, opt_tissue_graphics ; RCREG1=0x89 dcfsnz WREG - movff RCREG1, opt_layout ; RCREG1=0x90 + movff RCREG1, opt_layout ; RCREG1=0x8A + dcfsnz WREG + movff RCREG1, opt_extended_stops ; RCREG1=0x8B dcfsnz WREG - movff RCREG1, opt_extended_stops ; RCREG1=0x91 + movff RCREG1, char_I_gas_density_att ; RCREG1=0x8C + dcfsnz WREG + movff RCREG1, char_I_gas_density_warn ; RCREG1=0x8D + dcfsnz WREG + movff RCREG1, char_I_dil_ppO2_check ; RCREG1=0x8E comm_write_abort:
--- a/src/compass.c Sun Jun 30 23:22:32 2019 +0200 +++ b/src/compass.c Thu Sep 19 12:01:29 2019 +0200 @@ -247,7 +247,7 @@ //---- Calculate sine and cosine of roll angle Phi ----------------------- sincos(accel_DZ_f, accel_DY_f, &sin, &cos); - + //---- rotate by roll angle (-Phi) --------------------------------------- iBfy = imul(iBpy, cos) - imul(iBpz, sin); iBpz = imul(iBpy, sin) + imul(iBpz, cos); @@ -255,7 +255,7 @@ //---- calculate sin and cosine of pitch angle Theta --------------------- sincos(Gz, -accel_DX_f, &sin, &cos); // NOTE: changed sin sign - + /* correct cosine if pitch not in range -90 to 90 degrees */ if( cos < 0 ) cos = -cos;
--- a/src/compass_calib.c Sun Jun 30 23:22:32 2019 +0200 +++ b/src/compass_calib.c Thu Sep 19 12:01:29 2019 +0200 @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////////////// // 2015-05-22 [jDG] Make a smaller calibration code (15.6 --> 6.7 KB). -// 2019-05-14 [rl] make it even smaller again by another 2.000 byte +// 2019-05-14 [rl] make smaller again #include "configuration.inc" #include "compass.h" @@ -39,7 +39,7 @@ static unsigned short int compass_N; -static float Su, Sv, Sw; // first order moments +static float Su, Sv, Sw; // first order moments static float Suu, Svv, Sww, Suv, Suw, Svw; // second order moments static float Saa; // Suu + Svv + Sww static float Saau; // Suuu + Svvu + Swwu third order moment @@ -49,19 +49,11 @@ static float yu, yv, yw; // temp solution vector static float uc, vc, wc; // temp sphere's center -static float yh, uh, S0, S1, S2, S3; // transfer vars for compass_solve_helper() -static float discriminant, delta; // transfer vars for calc_discriminant() - +static float yh,uh,S0,S1,S2,S3; // transfer vars for compass_solve_helper() ////////////////////////////////////////////////////////////////////////////// -#ifndef UNIX -# pragma code compass_calib -#endif - -////////////////////////////////////////////////////////////////////////////// - -void compass_reset_calibration() // 202 byte +void compass_reset_calibration() { RESET_C_STACK; @@ -70,50 +62,36 @@ Suu = Svv = Sww = 0.0; Suv = Suw = Svw = 0.0; Saau = Saav = Saaw = 0.0; - compass_CX_f = compass_CY_f = compass_CZ_f = 0; // int16 + compass_CX_f = compass_CY_f = compass_CZ_f = 0; } ////////////////////////////////////////////////////////////////////////////// -void compass_add_calibration() // 1488 byte +void compass_add_calibration() { - overlay float SQR_yu, SQR_yv, SQR_yw; // squared values; - RESET_C_STACK; - // get filtered/calibrated magnetic direction // 276 byte + // get filtered/calibrated magnetic direction yu = (compass_DX_f - compass_CX_f) / 32768.0f; yv = (compass_DY_f - compass_CY_f) / 32768.0f; yw = (compass_DZ_f - compass_CZ_f) / 32768.0f; - // compute squared values // 156 byte - SQR_yu = yu*yu; - SQR_yv = yv*yv; - SQR_yw = yw*yw; - - // increment count + // add to all moments compass_N++; - // add to all moments // 156 byte Su += yu; Sv += yv; Sw += yw; - // // 156 byte - Suu += SQR_yu; - Svv += SQR_yv; - Sww += SQR_yw; - - // // 312 byte + Suu += yu*yu; Suv += yu*yv; Suw += yu*yw; + Svv += yv*yv; Svw += yv*yw; + Sww += yw*yw; - // // 104 byte - Saa = SQR_yu + SQR_yv + SQR_yw; + Saa = yu*yu + yv*yv + yw*yw; - - // // 312 byte Saau += yu * Saa; Saav += yv * Saa; Saaw += yw * Saa; @@ -121,12 +99,13 @@ ////////////////////////////////////////////////////////////////////////////// -static void calc_discriminant(PARAMETER char column) +static float compass_discriminent(PARAMETER char column) { // basic symmetric matrix - overlay float a = Suu, d = Suv, g = Suw; - overlay float b = Suv, e = Svv, h = Svw; - overlay float c = Suw, f = Svw, i = Sww; + OVERLAY float a = Suu, d = Suv, g = Suw; + OVERLAY float b = Suv, e = Svv, h = Svw; + OVERLAY float c = Suw, f = Svw, i = Sww; + OVERLAY float result; // substitute a column, if asked to if( column==1 ) { a = yu; b = yv; c = yw; } @@ -135,17 +114,16 @@ // do the math in a couple of single terms to reduce // the amount of required ".tmpdata" memory - discriminant = a * (e * i - f * h); - discriminant -= b * (d * i - f * g); - discriminant += c * (d * h - e * g); + result = a * (e * i - f * h); + result -= b * (d * i - f * g); + result += c * (d * h - e * g); - // apply delta if column = 1/2/3 - if( column ) discriminant *= delta; + return result; } ////////////////////////////////////////////////////////////////////////////// -static void compass_solve_helper(void) // 338 byte +static void compass_solve_helper(void) { // computes: // @@ -163,23 +141,24 @@ yh -= (Su*uh + 2*S1) * uc; yh -= (Sv*uh + 2*S2) * vc; yh -= (Sw*uh + 2*S3) * wc; + + return; } ////////////////////////////////////////////////////////////////////////////// -void compass_solve_calibration() // 1738 byte +void compass_solve_calibration() { - overlay float inv_compass_N; + OVERLAY float delta; RESET_C_STACK; - // compute center of measured magnetic directions // 200 byte - inv_compass_N = 1 / compass_N; - uc = Su * inv_compass_N; - vc = Sv * inv_compass_N; - wc = Sw * inv_compass_N; + //---- Compute center of measured magnetic directions -------------------- + uc = Su/compass_N; + vc = Sv/compass_N; + wc = Sw/compass_N; - // normalize partial sums + //---- Normalize partial sums -------------------------------------------- // // We measured the (u, v, w) values, and need the centered (x, y, z) ones // around the sphere center's (uc, vc, wc) as: @@ -222,16 +201,19 @@ Saa = Suu + Svv + Sww; // compute yu = Saau - Saa*uc - compass_dotc(Su*uc + 2*Suu, Sv*uc + 2*Suv, Sw*uc + 2*Suw); - // - uh = uc; S0 = Saau; S1 = Suu; S2 = Suv; S3 = Suw; compass_solve_helper(); yu = yh; + uh = uc; S0 = Saau; S1 = Suu; S2 = Suv; S3 = Suw; + compass_solve_helper(); + yu = yh; // compute yv = Saav - Saa*vc - compass_dotc(Su*vc + 2*Suv, Sv*vc + 2*Svv, Sw*vc + 2*Svw); - // - uh = vc; S0 = Saav; S1 = Suv; S2 = Svv; S3 = Svw; compass_solve_helper(); yv = yh; + uh = vc; S0 = Saav; S1 = Suv; S2 = Svv; S3 = Svw; + compass_solve_helper(); + yv = yh; // compute yw = Saaw - Saa*wc - compass_dotc(Su*wc + 2*Suw, Sv*wc + 2*Svw, Sw*wc + 2*Sww); - // - uh = wc; S0 = Saaw; S1 = Suw; S2 = Svw; S3 = Sww; compass_solve_helper(); yw = yh; + uh = wc; S0 = Saaw; S1 = Suw; S2 = Svw; S3 = Sww; + compass_solve_helper(); + yw = yh; //---- Solve the system -------------------------------------------------- @@ -241,15 +223,14 @@ // // Note this is symmetric, with a positive diagonal, hence discriminant is always not null - //compute delta value - calc_discriminant(0); delta = 0.5f / discriminant; + delta = 0.5f / compass_discriminent(0); - // compute new center, with offset values - calc_discriminant(1); uc += discriminant; - calc_discriminant(2); vc += discriminant; - calc_discriminant(3); wc += discriminant; + // computed new center, with offset values: + uc += compass_discriminent(1) * delta; + vc += compass_discriminent(2) * delta; + wc += compass_discriminent(3) * delta; - // add correction due to already applied calibration + // add correction due to already applied calibration: compass_CX_f += (short)(32768 * uc); compass_CY_f += (short)(32768 * vc); compass_CZ_f += (short)(32768 * wc);
--- a/src/compass_ops.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/compass_ops.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File compass_ops.asm combined next generation V3.03.2 +; File compass_ops.asm combined next generation V3.03.5 ; ; Compass Operations ; @@ -170,7 +170,7 @@ movf PRODH,W ; and add16 addwfc compass_r+0,F movlw 0 - addwfc compass_r+1,F + addwfc compass_r+1,F movf compass_a+0,W ; block al*bh mulwf compass_b+1 @@ -209,23 +209,23 @@ subwfb compass_r+1,F compass_mul_4: - bcf compass_r+1,6 ; copy bit 7 to 6, so keep it after 2x + bcf compass_r+1,6 ; copy bit 7 to 6, so keep it after 2x btfsc compass_r+1,7 bsf compass_r+1,6 bra compass_mul_2 +;----------------------------------------------------------------------------- global compass_calibration_loop -compass_calibration_loop: ; compass calibration - bsf block_sensor_interrupt ; disable sensor interrupts - call I2C_sleep_accelerometer ; stop accelerometer - call I2C_sleep_compass ; stop compass +compass_calibration_loop: ; compass calibration + bsf block_sensor_interrupt ; disable sensor interrupts + call I2C_sleep_compass ; stop compass call TFT_ClearScreen ; Mask WIN_COLOR color_greenish WIN_SMALL .16,.0 STRCPY_TEXT_PRINT tCompassMenu - btfss switch_right2 ; wait until button is released + btfss switch_right2 ; wait until button is released bra $-2 call TFT_standard_color @@ -234,41 +234,44 @@ WAITMS d'255' WAITMS d'255' - call request_speed_fastest ; request CPU speed change to fastest speed + call request_speed_fastest ; request CPU speed change to fastest speed - movlw .7 ; initialize gain + movlw .7 ; initialize gain movff WREG,opt_compass_gain - movlw .60 ; initialize timeout to 60 seconds - movwf isr_timeout_reload ; copy WREG to isr_timeout_reload - bsf reset_timeout ; request ISR to reset the timeout - bcf trigger_timeout ; clear any pending timeout trigger -compass_calibration_gainset: ; reduce the gain, set bank here! - banksel opt_compass_gain ; select bank options table - decf opt_compass_gain,F ; reduce by one - btfsc STATUS,N ; < 0 ? - clrf opt_compass_gain ; YES - keep at zero - banksel common ; bank to bank common + movlw .60 ; initialize timeout to 60 seconds + movwf isr_timeout_reload ; copy WREG to isr_timeout_reload + bsf reset_timeout ; request ISR to reset the timeout + bcf trigger_timeout ; clear any pending timeout trigger +compass_calibration_gainset: ; reduce the gain, set bank here! + banksel opt_compass_gain ; select bank options table + decf opt_compass_gain,F ; reduce by one + btfsc STATUS,N ; < 0 ? + clrf opt_compass_gain ; YES - keep at zero + btfsc STATUS,N ; < 0 ? + bra compass_calibration_loop1 ; YES - skip gain stuff (Would hang here in case of compass failure) + banksel common ; bank to bank common - call I2C_init_accelerometer call I2C_init_compass -; btfsc compass_type ; compass1 ? -; bra compass_calibration_loop1 ; YES - skip gain stuff + btfsc compass_type3 ; compass type 3 ? + bra compass_calibration_loop1 ; YES - skip gain stuff + btfsc compass_type2 ; compass type 2 ? + bra compass_calibration_loop1 ; YES - skip gain stuff - rcall TFT_compass_show_gain ; show the current compass gain + rcall TFT_compass_show_gain ; show the current compass gain WAITMS d'250' - WAITMS d'250' ; wait for first reading... + WAITMS d'250' ; wait for first reading... - movlw .60 ; calibration shall run for 60 seconds - call reset_timeout_time ; set timeout + movlw .60 ; calibration shall run for 60 seconds + call reset_timeout_time ; set timeout - call I2C_RX_compass ; read compass - call I2C_RX_accelerometer ; read accelerometer + call I2C_RX_compass ; read compass + call I2C_RX_accelerometer ; read accelerometer ; Test all axes for +4096 (Hi byte=16) - banksel compass_DX ; select bank common2 + banksel compass_DX ; select bank common2 movlw .16 cpfseq compass_DX+1 bra $+4 @@ -291,28 +294,28 @@ cpfseq compass_DZ+1 bra $+4 bra compass_calibration_gainset - banksel common ; back to bank common -compass_calibration_loop1: ; done with gain - rcall compass_filter_init ; set DX_f values - call compass_reset_calibration ; reset CX_f values (C-code) - banksel common ; back to bank common +compass_calibration_loop1: ; done with gain + banksel common ; bank to bank common + rcall compass_filter_init ; set DX_f values + call compass_reset_calibration ; reset CX_f values (C-code) + banksel common ; back to bank common compass_calibration_loop2: - call I2C_RX_compass ; read compass - call I2C_RX_accelerometer ; test accelerometer - rcall compass_filter ; filter compass raw data + call I2C_RX_compass ; read compass + call I2C_RX_accelerometer ; test accelerometer + rcall compass_filter ; filter compass raw data ; Twice - call I2C_RX_compass ; read compass - call I2C_RX_accelerometer ; test accelerometer - rcall compass_filter ; filter compass raw data + call I2C_RX_compass ; read compass + call I2C_RX_accelerometer ; test accelerometer + rcall compass_filter ; filter compass raw data -; btfsc compass_type ; compass1? -; bra compass_calibration_loop3 ; YES - skip gain stuff +; btfsc compass_type1 ; compass1? +; bra compass_calibration_loop3 ; YES - skip gain stuff ; Test all axes for +4096 (Hi byte=16) - banksel compass_DX ; select bank common2 + banksel compass_DX ; select bank common2 movlw .16 cpfseq compass_DX+1 bra $+4 @@ -335,115 +338,114 @@ cpfseq compass_DZ+1 bra $+4 bra compass_calibration_gainset - banksel common ; back to bank common + banksel common ; back to bank common ; ; ; Three -; call I2C_RX_compass ; read compass -; call I2C_RX_accelerometer ; test accelerometer -; call compass_filter ; filter compass raw data +; call I2C_RX_compass ; read compass +; call I2C_RX_accelerometer ; test accelerometer +; call compass_filter ; filter compass raw data ; ; ; Four times to get cleaner values -; call I2C_RX_compass ; read compass -; call I2C_RX_accelerometer ; test accelerometer -; call compass_filter ; filter compass raw data +; call I2C_RX_compass ; read compass +; call I2C_RX_accelerometer ; test accelerometer +; call compass_filter ; filter compass raw data compass_calibration_loop3: ; and register only one value out of four: - call compass_add_calibration ; check and store new max/min values (C-code) - banksel common ; back to bank common + call compass_add_calibration ; check and store new max/min values (C-code) + banksel common ; back to bank common - rcall TFT_compass_fast ; show values - btfsc trigger_timeout ; timeout (calibration done)? - bra compass_calibration_exit ; YES - exit - btfss trigger_full_second ; NO - new second begun? - bra compass_calibration_loop2 ; NO - loop - bcf trigger_full_second ; YES - clear flag - rcall TFT_show_timeout_testmode ; - show remaining time - bra compass_calibration_loop2 ; - loop + rcall TFT_compass_fast ; show values + btfsc trigger_timeout ; timeout (calibration done)? + bra compass_calibration_exit ; YES - done + btfss trigger_full_second ; NO - new second begun? + bra compass_calibration_loop2 ; NO - loop + bcf trigger_full_second ; YES - clear flag + rcall TFT_show_timeout_testmode ; - show remaining time + bra compass_calibration_loop2 ; - loop compass_calibration_exit: - bcf block_sensor_interrupt ; re-enable sensor interrupts + bcf block_sensor_interrupt ; re-enable sensor interrupts - call compass_solve_calibration ; calculate calibration factors (C-code) - banksel common ; back to bank common + call compass_solve_calibration ; calculate calibration factors (C-code) + banksel common ; back to bank common + + call request_speed_normal ; request CPU speed change to normal speed - call request_speed_normal ; request CPU speed change to normal speed - - call option_save_all ; save all settings into EEPROM + call option_save_all ; save all settings into EEPROM movlw .6 - movff WREG,customview_surfmode ; set to compass view... - goto surfloop ; ...and exit + movff WREG,customview_surfmode ; set to compass view... + goto surfloop ; ...and exit +;----------------------------------------------------------------------------- global TFT_compass_fast TFT_compass_fast: - WIN_TINY .20,.50 - STRCPY "X:" + WIN_TINY .0,.50 + STRCPY "Cx:" MOVII compass_DX,mpr - call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required + output_16 + STRCAT " Cy:" + MOVII compass_DY,mpr + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required + output_16 + STRCAT " Cz:" + MOVII compass_DZ,mpr + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required output_16 - STRCAT " Y:" - MOVII compass_DY,mpr - call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required + STRCAT_PRINT " " + + WIN_TINY .0,.104 + STRCPY "Ax:" + MOVII accel_DX,mpr + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required output_16 - STRCAT " Z:" - MOVII compass_DZ,mpr - call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required + STRCAT " Ay:" + MOVII accel_DY,mpr + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required + output_16 + STRCAT " Az:" + MOVII accel_DZ,mpr + call TFT_convert_signed_16bit ; convert lo:hi into signed-short and add '-' to POSTINC2 if required output_16 STRCAT_PRINT " " return TFT_show_timeout_testmode: - WIN_TINY .20,.68 + WIN_TINY .0,.68 STRCPY "T:" movff isr_timeout_timer,lo bsf leftbind - output_8 ; display remaining time + output_8 ; display remaining time bcf leftbind STRCAT_PRINT "s " return -TFT_compass_show_gain: ; show the current compass gain -; movff opt_compass_gain,lo ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) +TFT_compass_show_gain: ; show the current compass gain +; movff opt_compass_gain,lo ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) ; tstfsz lo -; return ; do not show unless gain=0 - WIN_TINY .20,.86 +; return ; do not show unless gain=0 + WIN_TINY .0,.86 STRCPY_TEXT tCompassGain - movff opt_compass_gain,lo ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) + movff opt_compass_gain,lo ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) bsf leftbind output_8 bcf leftbind STRCAT_PRINT "" return - -TFT_surface_compass_bearing: - WIN_SMALL surf_compass_bear_column,surf_compass_bear_row - MOVII compass_bearing,mpr - PUTC "(" - bsf leftbind - output_16dp .2 ; result is "0.000" - bcf leftbind - ; rearrange figures to "000" - movff buffer+3,buffer+1 - movff buffer+4,buffer+2 - movff buffer+5,buffer+3 - lfsr FSR2,buffer+4 - STRCAT " " - rcall tft_compass_cardinal ; add cardinal and ordinal to POSTINC2 - STRCAT_PRINT ")" - return - +;----------------------------------------------------------------------------- global TFT_surface_compass_mask TFT_surface_compass_mask: WIN_SMALL surf_compass_mask_column,surf_compass_mask_row call TFT_standard_color - STRCPY_TEXT_PRINT tHeading ; Heading: + STRCPY_TEXT_PRINT tHeading ; print "Heading:" return - global TFT_dive_compass_mask ; draws the white box around the heading tape + global TFT_dive_compass_mask ; draws the white box around the heading tape TFT_dive_compass_mask: WIN_FRAME_STD dm_custom_compass_graph_row, dm_custom_compass_graph_row+dm_custom_compass_graph_height, .0, .159 return @@ -454,43 +456,28 @@ rcall compass_heading_common WIN_STD surf_compass_head_column,surf_compass_head_row call TFT_standard_color -TFT_surface_compass_heading_com: ; show "000 N" - MOVII compass_heading_new,mpr - btfss mpr+1,7 ; compass calibrated? - bra TFT_surface_compass_heading_com0 ; YES - STRCAT_PRINT "---" ; NO - print "---" - return ; - done -TFT_surface_compass_heading_com0: - ; Shown and actual identical? - movff compass_heading_shown+0,WREG ; get heading shown, low byte - cpfseq mpr+0 ; compare with current heading, equal? - bra TFT_surface_compass_heading_com1 ; NO - not equal - movff compass_heading_shown+1,WREG ; get heading shown, high byte - cpfseq mpr+1 ; compare with current heading, equal? - bra TFT_surface_compass_heading_com1 ; NO - not equal - bra TFT_surface_compass_heading_com3 ; YES - skip smoothing +TFT_surface_compass_heading_com: ; show "000 N" + movff compass_heading_new+1,WREG ; get upper byte of actual heading + btfsc WREG,7 ; compass calibrated? + bra TFT_compass_uncalibrated ; NO + MOVII compass_heading_shown,mpr ; get heading to be shown + rcall TFT_compass_helper ; show heading and its cardinal + btfsc divemode ; in dive mode? + return ; YES - done for dive mode + ; in surface mode - shall show bearing? + btfss compass_bearing_set ; is a bearing set? + return ; NO - done + btfsc compass_menu ; is the "set bearing" selection shown? + return ; YES - done + ; show bearing + WIN_SMALL surf_compass_bear_column,surf_compass_bear_row + call TFT_attention_color + MOVII compass_bearing,mpr ; get bearing + ;bra TFT_compass_helper ; show number and cardinal and return -TFT_surface_compass_heading_com1: - MOVII mpr,sub_a - MOVII compass_heading_shown,sub_b - call subU16 - btfsc neg_flag - bra TFT_surface_compass_heading_com2 ; shown > actual - ; shown < actual - banksel compass_heading_shown ; select bank common2 - INCI compass_heading_shown ; compass_heading_shown++ - banksel common ; back to bank common - bra TFT_surface_compass_heading_com3 - -TFT_surface_compass_heading_com2: - banksel compass_heading_shown ; select bank common2 - DECI compass_heading_shown ; compass_heading_shown-- - banksel common ; back to bank common - -TFT_surface_compass_heading_com3: - MOVII compass_heading_shown,mpr +TFT_compass_helper: bsf leftbind - output_16dp .2 ; result is "0.000" + output_16dp .2 ; result is "0.000" in buffer bcf leftbind ; rearrange figures to "000" movff buffer+2,buffer+0 @@ -498,101 +485,97 @@ movff buffer+4,buffer+2 lfsr FSR2,buffer+3 STRCAT " " - rcall tft_compass_cardinal ; add cardinal and ordinal to POSTINC2 - clrf WREG - movff WREG,buffer+.7 ; limit to 7 chars - STRCAT_PRINT "" - btfsc divemode ; in dive mode? - return ; YES - done for dive mode - ; show bearing on the surface? - btfss compass_bearing_set ; is a bearing set? - return ; NO - return - btfsc compass_menu ; is the "set bearing" selection shown? - return ; YES - return - bra TFT_surface_compass_bearing ; NO - show bearing and return + rcall tft_compass_cardinal ; add cardinal to POSTINC2 + STRCAT_PRINT "" ; finalize output + return ; done + +TFT_compass_uncalibrated: + STRCAT_PRINT "---" ; print "---" + return ; done global TFT_dive_compass_heading TFT_dive_compass_heading: - WIN_FONT FT_SMALL ; set font size TODO - needed ??? rcall compass_heading_common + WIN_FONT FT_SMALL ; set font size + ; ; ### for development only, hard-coding the bearing ### ; ; 244 : SW - W -; MOVLI .244,xA ; xA used as temp -; MOVII xA,compass_bearing ; compass_bearing is stored in bank isr_backup +; MOVLI .244,xA ; xA used as temp +; MOVII xA,compass_bearing ; compass_bearing is stored in bank isr_backup MOVII compass_heading_shown,xA ; 160 viewing angle: add +360 offset if xA <= 292 for non-negative scale MOVLI .292,sub_a MOVII xA, sub_b - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; xA > 292 ? - bra TFT_dive_compass_heading_1 ; YES - ADDLI .360,xA ; NO - add offset + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; xA > 292 ? + bra TFT_dive_compass_heading_1 ; YES + ADDLI .360,xA ; NO - add offset TFT_dive_compass_heading_1: - SUBLI .80,xA ; subtract 80 (left pixel offset from the center) - MOVII xA,xRD ; save result to xRD - ADDLI .160,xA ; add 160 (display with in pixels) - MOVII xA,xRDr ; save result to xRDr + SUBLI .80,xA ; subtract 80 (left pixel offset from the center) + MOVII xA,xRD ; save result to xRD + ADDLI .160,xA ; add 160 (display with in pixels) + MOVII xA,xRDr ; save result to xRDr - btfss compass_bearing_set ; is a bearing set? - bra TFT_dive_compass_ruler ; NO - skip next calculations - MOVII xRDr,sub_a ; YES - calculate xRD180 = xRDr - 180 + btfss compass_bearing_set ; is a bearing set? + bra TFT_dive_compass_ruler ; NO - skip next calculations + MOVII xRDr,sub_a ; YES - calculate xRD180 = xRDr - 180 MOVLI .180,sub_b - call subU16 ; sub_c = sub_a - sub_b + call subU16 ; sub_c = sub_a - sub_b MOVII sub_c,xRD180 TFT_dive_compass_bearing_1: ; calculate bearing position and visibility (ahead or behind) - bcf compass_bearing_vis ; default is not-visible - bcf compass_bearing_ahd ; default is behind + bcf compass_bearing_vis ; default is not-visible + bcf compass_bearing_ahd ; default is behind MOVII compass_bearing,xA - ADDLI .360,xA ; calculate the bearing virtual display offset - MOVII xA,divA ; save it for reuse for upper/lower turns and ahead/behind checks + ADDLI .360,xA ; calculate the bearing virtual display offset + MOVII xA,divA ; save it for reuse for upper/lower turns and ahead/behind checks ; check if bearing is ahead - MOVII divA,sub_a ; load the bearing offset into sub_a - MOVII xRD, sub_b ; load the display offset back to sub_b + MOVII divA,sub_a ; load the bearing offset into sub_a + MOVII xRD, sub_b ; load the display offset back to sub_b rcall TFT_dive_compass_bearing_ap - btfsc compass_bearing_vis ; bearing visible? - bra TFT_dive_compass_bearing_dir ; YES + btfsc compass_bearing_vis ; bearing visible? + bra TFT_dive_compass_bearing_dir; YES - ; check if it's ahead with an upper turn - MOVII divA,sub_a ; load the bearing offset into sub_a - MOVII xRD, sub_b ; load the display offset back to sub_b + ; check if it is ahead with an upper turn + MOVII divA,sub_a ; load the bearing offset into sub_a + MOVII xRD, sub_b ; load the display offset back to sub_b ADDLI .360,sub_b rcall TFT_dive_compass_bearing_ap - btfsc compass_bearing_vis ; bearing visible? - bra TFT_dive_compass_bearing_dir ; YES + btfsc compass_bearing_vis ; bearing visible? + bra TFT_dive_compass_bearing_dir; YES - ; check if it's ahead with a lower turn - MOVII divA,sub_a ; load the bearing offset into sub_a + ; check if it is ahead with a lower turn + MOVII divA,sub_a ; load the bearing offset into sub_a ADDLI .360,sub_a - MOVII xRD, sub_b ; load the display offset back to sub_b + MOVII xRD, sub_b ; load the display offset back to sub_b rcall TFT_dive_compass_bearing_ap - btfsc compass_bearing_vis ; bearing visible? - bra TFT_dive_compass_bearing_dir ; YES + btfsc compass_bearing_vis ; bearing visible? + bra TFT_dive_compass_bearing_dir; YES ; marker is not ahead of us, check if it is behind of us ; use the (160 - (xRD180 - xCM)) formula to see if it's on the display - MOVII xRD180,sub_a ; load the display offset back to sub_a - MOVII divA, sub_b ; load the marker's offset into sub_b + MOVII xRD180,sub_a ; load the display offset back to sub_a + MOVII divA, sub_b ; load the marker's offset into sub_b rcall TFT_dive_compass_bearing_bp - btfsc compass_bearing_vis ; bearing behind of us? - bra TFT_dive_compass_bearing_dir ; YES + btfsc compass_bearing_vis ; bearing behind of us? + bra TFT_dive_compass_bearing_dir; YES - ; check if it's behind with the upper turn + ; check if it is behind with the upper turn MOVII xRD180,sub_a MOVII divA, sub_b ADDLI .360, sub_b rcall TFT_dive_compass_bearing_bp - btfsc compass_bearing_vis ; bearing behind of us? - bra TFT_dive_compass_bearing_dir ; YES + btfsc compass_bearing_vis ; bearing behind of us? + bra TFT_dive_compass_bearing_dir; YES - ; check if it's behind with the lower turn + ; check if it is behind with the lower turn MOVII xRD180,sub_a ADDLI .360, sub_a - MOVII divA, sub_b ; load the marker's offset into sub_b + MOVII divA, sub_b ; load the marker's offset into sub_b rcall TFT_dive_compass_bearing_bp bra TFT_dive_compass_bearing_dir @@ -600,45 +583,45 @@ ; xCM received in sub_a ; xRD received in sub_b ; 1/a. check if it's viewable from the left side - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; xRD > divA ? - return ; NO - done - MOVII sub_c,xC ; YES - store the RO=RP-RD for drawing + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; xRD > divA ? + return ; NO - done + MOVII sub_c,xC ; YES - store the RO=RP-RD for drawing ; 1/b. check if it's viewable from the right side - ADDLI .2,sub_a ; avoid thin mess on the side of the display - ADDLI .158,sub_b ; load the display offset right side into sub_b - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; xRDr > xA(+2) ? - return ; NO - done - ; YES - print the bearing lines on the screen + ADDLI .2,sub_a ; avoid thin mess on the side of the display + ADDLI .158,sub_b ; load the display offset right side into sub_b + call subU16 ; sub_c = sub_a - sub_b + btfss neg_flag ; xRDr > xA(+2) ? + return ; NO - done + ; YES - print the bearing lines on the screen movff xC+0,xCM - bsf compass_bearing_vis ; set visible - bsf compass_bearing_ahd ; set ahead - return ; done + bsf compass_bearing_vis ; set visible + bsf compass_bearing_ahd ; set ahead + return ; done TFT_dive_compass_bearing_bp: ; use the (160 - (xRD180 - xCM)) formula to see if it's on the display ; the marker's offset received in sub_b ; the xRD180 display offset received in sub_a ; xRD180 - xCM - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; CM > xRD180 ? - return ; NO - not on screen, done - ; YES - check 160 - (X) - MOVLI .158, sub_a ; 158 to avoid thin mess on the side of the display + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; CM > xRD180 ? + return ; NO - not on screen, done + ; YES - check 160 - (X) + MOVLI .158, sub_a ; 158 to avoid thin mess on the side of the display MOVII sub_c,sub_b - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; X > 160 ? - return ; NO - not on screen, done + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; X > 160 ? + return ; NO - not on screen, done ; check if not overflow - this sounds like a double check... - tstfsz sub_c+1 ; high byte = 0 ? - return ; NO - sub_c must be > 160 then, done - movlw d'158' - cpfslt sub_c+0 ; low byte < 158 ? - return ; NO - done - movff sub_c+0,xCM ; YES to both - print the bearing lines on the screen - bsf compass_bearing_vis - return ; done + tstfsz sub_c+1 ; high byte = 0 ? + return ; NO - sub_c must be > 160 then, done + movlw d'158' ; YES - load a 158 + cpfslt sub_c+0 ; - low byte < 158 ? + return ; NO - done + movff sub_c+0,xCM ; YES - print the bearing lines on the screen + bsf compass_bearing_vis ; - flag to show bearing lines + return ; - done TFT_dive_compass_bearing_dir: ; check if bearing to heading, and calculate the direction @@ -652,7 +635,7 @@ cpfseq xA+0 bra TFT_dive_compass_bearing_lr bsf compass_bearing_eq - bra TFT_dive_compass_ruler ; bearing points to heading, no signs are required, go to the ruler + bra TFT_dive_compass_ruler ; bearing points to heading, no signs are required, go to the ruler TFT_dive_compass_bearing_lr: ; get the bearing virtual display offset @@ -660,29 +643,29 @@ ; xA = xA > 292 ? xA : xA+360 MOVLI .292,sub_a MOVII xA, sub_b - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; xA > 292 ? - bra TFT_dive_compass_bearing_lr_1 ; YES - ADDLI .360,xA ; NO - add 360 + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; xA > 292 ? + bra TFT_dive_compass_bearing_lr_1; YES + ADDLI .360,xA ; NO - add 360 TFT_dive_compass_bearing_lr_1: ; 1. calculate whether bearing is to left or to right - bsf compass_bearing_lft ; to the left by default + bsf compass_bearing_lft ; to the left by default ; xC: save center value to compare the direction to front value MOVII xA,xC ; xB: we need the left side for comparison... left = -180 MOVII xA, sub_a MOVLI .180,sub_b - call subU16 ; sub_c = sub_a - sub_b - MOVII sub_c,xB ; xB has the left side of the 180 distance center + call subU16 ; sub_c = sub_a - sub_b + MOVII sub_c,xB ; xB has the left side of the 180 distance center ; xA = xRD > (xC+100) ? RD-280 : xRD+80 MOVII xC, sub_a ADDLI .100,sub_a MOVII xRD, sub_b - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; xRD > xC + 100 ? - bra TFT_dive_compass_bearing_lr_2 ; YES - xA = xRD - 280 - ; NO - xA = xRD + 80 + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; xRD > xC + 100 ? + bra TFT_dive_compass_bearing_lr_2; YES - xA = xRD - 280 + ; NO - xA = xRD + 80 MOVII xRD,xA ADDLI .80,xA bra TFT_dive_compass_bearing_lr_c @@ -690,7 +673,7 @@ TFT_dive_compass_bearing_lr_2: MOVII xRD,sub_a MOVLI .280,sub_b - call subU16 ; sub_c = sub_a - sub_b + call subU16 ; sub_c = sub_a - sub_b MOVII sub_c,xA ;bra TFT_dive_compass_bearing_lr_c @@ -698,37 +681,37 @@ ; xB < xA < xC => right, otherwise left (default) MOVII xA,sub_b MOVII xB,sub_a - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; xA > xB ? - bra TFT_dive_compass_ruler ; NO - xB >= xA, keep default left + call subU16 ; sub_c = sub_a - sub_b + btfss neg_flag ; xA > xB ? + bra TFT_dive_compass_ruler ; NO - xB >= xA, keep default left MOVII xA,sub_a MOVII xC,sub_b - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; xC > xA ? - bra TFT_dive_compass_ruler ; NO - xA >= xC, keep default left + call subU16 ; sub_c = sub_a - sub_b + btfss neg_flag ; xC > xA ? + bra TFT_dive_compass_ruler ; NO - xA >= xC, keep default left bcf compass_bearing_lft TFT_dive_compass_ruler: ; calculate mod15 for the ticks MOVII xRD,xA MOVLI .15,xB - call div16x16 ; xA/xB=xC with xA+0 as remainder + call div16x16 ; xA/xB=xC with xA+0 as remainder ; check the remainder movlw d'0' - cpfsgt xA+0 ; mod15 > 0 ? - bra TFT_dive_compass_ruler_1 ; NO - RM = 0 - ; YES - RM = 15 - RDmod15 + cpfsgt xA+0 ; mod15 > 0 ? + bra TFT_dive_compass_ruler_1 ; NO - RM = 0 + ; YES - RM = 15 - RDmod15 movlw d'15' subfwb xA+0,F TFT_dive_compass_ruler_1: - movff xA+0,lo ; xA+0 holds the RM, store it to 'lo' - clrf hi ; initialize DD to zero, store it to 'hi' + movff xA+0,lo ; xA+0 holds the RM, store it to 'lo' + clrf hi ; initialize DD to zero, store it to 'hi' TFT_dive_compass_ruler_loop: ; 1. check if we run out of the display - movlw d'159' ; looks like 159 works because TFT_box limits the display + movlw d'159' ; looks like 159 works because TFT_box limits the display cpfslt lo,1 - bra TFT_dive_compass_ruler_lend ; xRM >= W + bra TFT_dive_compass_ruler_lend ; xRM >= W ; 2. Clear the tick area from DD to RM - in segments to avoid blinking ; don't do a clear if we are at 0 (zero) otherwise it will blink ; because of the width underflow @@ -739,25 +722,25 @@ TFT_dive_compass_ruler_loop_zz: ; 3. Draw the markers @ RM ; we receive RM in lo and DD in hi - movlw dm_custom_compass_tick_top_top - movwf win_top - movlw dm_custom_compass_tick_height - movwf win_height movlw d'2' - movwf win_bargraph + movwf win_bargraph ; set with of ticks movwf win_width+0 clrf win_width+1 - movff lo,win_leftx2 ; 0..159 - call TFT_standard_color - call TFT_box - movlw dm_custom_compass_tick_bot_top - movwf win_top + movff lo,win_leftx2 ; 0..159 + movlw dm_custom_compass_tick_top_top + movwf win_top ; set position for upper ticks movlw dm_custom_compass_tick_height - movwf win_height - call TFT_standard_color ; color in WREG is trashed, must be set again! - call TFT_box - ; 4. If D<82 and RM>79: means we put something over the center line - ; redraw the center line + movwf win_height ; set hight of ticks + call TFT_standard_color ; set color + call TFT_box ; draw tick + movlw dm_custom_compass_tick_bot_top + movwf win_top ; set position for lower ticks + movlw dm_custom_compass_tick_height + movwf win_height ; set hight of ticks + call TFT_standard_color ; color in WREG is trashed, must be set again! + call TFT_box ; draw tick + ; 4. If D < 82 and RM > 79: means we put something over the center line, + ; so redraw the center line movlw d'82' cpfslt hi,1 bra TFT_dive_compass_ruler_loop_zz2 @@ -765,8 +748,7 @@ cpfsgt lo,1 bra TFT_dive_compass_ruler_loop_zz2 ; enough to print center line as bearing marker is not in the ticker area - movlw color_yellow - WIN_BOX_COLOR dm_custom_compass_tick_top_top, dm_custom_compass_tick_bot_bot,.80,.81 ; center line in yellow + rcall TFT_dive_compass_c ; draw center line in yellow TFT_dive_compass_ruler_loop_zz2: ; 5. set D = RM + 2 : position after the 2px tick movff lo,hi @@ -778,137 +760,137 @@ ; 7. loop bra TFT_dive_compass_ruler_loop -TFT_dive_compass_ruler_lend: ; loop end - ; 8. clear the rest of the tick area if D<160 +TFT_dive_compass_ruler_lend: ; loop end + ; 8. clear the rest of the tick area if D < 160 movlw d'160' cpfslt hi - bra TFT_dive_compass_ruler_lend2 ; D >= W + bra TFT_dive_compass_labels ; D >= W ; 9. position left to end of display to clear the remaining area movlw d'159' movwf lo ; 10. clear it rcall TFT_dive_compass_clr_ruler -TFT_dive_compass_ruler_lend2: +TFT_dive_compass_labels: ; done with the compass ruler, put the labels on the screen - clrf hi ; hi stores the display position - movff hi,xHI ; bank-safe clear of xHI - clrf lo ; lo stores the last item's display position - movff lo,xLO ; bank-safe clear of xLO - MOVLI .219,sub_a ; position of the cardinal - MOVII xRD, sub_b ; get the RD back to sub_b - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_1 ; NO - STRCPY_TEXT_PRINT tSW ; YES - print it + clrf hi ; hi stores the display position + movff hi,xHI ; bank-safe clear of xHI + clrf lo ; lo stores the last item's display position + movff lo,xLO ; bank-safe clear of xLO + MOVLI .219,sub_a ; position of the cardinal + MOVII xRD, sub_b ; get the RD back to sub_b + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_1 ; NO + STRCPY_TEXT_PRINT tSW ; YES - print it dcr_1: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .267,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_2 ; NO - STRCPY_TEXT_PRINT tW ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .267,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_2 ; NO + STRCPY_TEXT_PRINT tW ; YES - print it dcr_2: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .309,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_3 ; NO - STRCPY_TEXT_PRINT tNW ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .309,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_3 ; NO + STRCPY_TEXT_PRINT tNW ; YES - print it dcr_3: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .358,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_4 ; NO - STRCPY_TEXT_PRINT tN ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .358,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_4 ; NO + STRCPY_TEXT_PRINT tN ; YES - print it dcr_4: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .399,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_5 ; NO - STRCPY_TEXT_PRINT tNE ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .399,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_5 ; NO + STRCPY_TEXT_PRINT tNE ; YES - print it dcr_5: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .448,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_6 ; NO - STRCPY_TEXT_PRINT tE ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .448,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_6 ; NO + STRCPY_TEXT_PRINT tE ; YES - print it dcr_6: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .489,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_7 ; NO - STRCPY_TEXT_PRINT tSE ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .489,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_7 ; NO + STRCPY_TEXT_PRINT tSE ; YES - print it dcr_7: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .538,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ;shall show cardinal? - bra dcr_8 ; NO - STRCPY_TEXT_PRINT tS ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .538,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_8 ; NO + STRCPY_TEXT_PRINT tS ; YES - print it dcr_8: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .579,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_9 ; NO - STRCPY_TEXT_PRINT tSW ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .579,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_9 ; NO + STRCPY_TEXT_PRINT tSW ; YES - print it dcr_9: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .627,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_10 ; NO - STRCPY_TEXT_PRINT tW ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .627,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_10 ; NO + STRCPY_TEXT_PRINT tW ; YES - print it dcr_10: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .669,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show cardinal? - bra dcr_11 ; NO - STRCPY_TEXT_PRINT tNW ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .669,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show cardinal? + bra dcr_11 ; NO + STRCPY_TEXT_PRINT tNW ; YES - print it dcr_11: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker - MOVLI .718,sub_a ; position of the cardinal - rcall TFT_dive_compass_label_proc ; check if the cardinal should be on screen - btfss compass_show_cardinal ; shall show? - bra dcr_12 ; NO - STRCPY_TEXT_PRINT tN ; YES - print it + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + MOVLI .718,sub_a ; position of the cardinal + rcall TFT_dive_compass_label_proc ; check if the cardinal shall be on screen + btfss compass_show_cardinal ; shall show? + bra dcr_12 ; NO + STRCPY_TEXT_PRINT tN ; YES - print it dcr_12: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker TFT_dive_compass_label_end: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker ; restore lo and hi for the final cleanup - movff xLO,lo ; xLO and xHI are stored in bank isr_backup + movff xLO,lo ; xLO and xHI are stored in bank isr_backup movff xHI,hi - ; clear the rest of the SQ area if there are more space + ; clear the rest of the SQ area if there is more space movlw d'159' cpfslt hi - bra TFT_dive_compass_label_end2 ; D >= 160, no more space + bra TFT_dive_compass_label_end2 ; D >= 160, no more space ; position left to end of display to clear the remaining area movlw d'158' movwf lo ; clear it rcall TFT_dive_compass_clr_label TFT_dive_compass_label_end2: - rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker + rcall TFT_dive_compass_c_mk ; check if cardinal is on the center line or the marker ; do we have bearing set? - btfsc compass_bearing_set ; bearing set? - bra TFT_dive_compass_dir_text ; YES - print the direction (<< or >>) - rcall TFT_dive_compass_dir_lclr ; NO - clear the area (e.g. we had but removed) + btfsc compass_bearing_set ; bearing set? + bra TFT_dive_compass_dir_text ; YES - print the direction (<< or >>) + rcall TFT_dive_compass_dir_lclr ; NO - clear the area (e.g. we had but removed) rcall TFT_dive_compass_dir_rclr bra TFT_dive_compass_text TFT_dive_compass_dir_text: ; bearing set, but does it point to heading? btfss compass_bearing_eq - bra TFT_dive_compass_dir_text_2 ; bearing != heading - go and print the direction - rcall TFT_dive_compass_dir_lclr ; bearing == heading - no need for direction markers + bra TFT_dive_compass_dir_text_2 ; bearing != heading - go and print the direction + rcall TFT_dive_compass_dir_lclr ; bearing == heading - no need for direction markers rcall TFT_dive_compass_dir_rclr bra TFT_dive_compass_text @@ -916,17 +898,17 @@ movlw color_green call TFT_set_color btfsc compass_bearing_lft - bra TFT_dive_compass_dir_ldir ; bearing_lft=1, print the left marker + bra TFT_dive_compass_dir_ldir ; bearing_lft=1, print the left marker ;TFT_dive_compass_text_rdir: WIN_SMALL dm_custom_compass_rdir_column, dm_custom_compass_head_row-.2 STRCPY_PRINT ">>" - rcall TFT_dive_compass_dir_lclr ; do not forget to clear the left + rcall TFT_dive_compass_dir_lclr ; do not forget to clear the left bra TFT_dive_compass_text TFT_dive_compass_dir_ldir: WIN_SMALL dm_custom_compass_ldir_column, dm_custom_compass_head_row-.2 STRCPY_PRINT "<<" - rcall TFT_dive_compass_dir_rclr ; do not forget to clear the right + rcall TFT_dive_compass_dir_rclr ; do not forget to clear the right ;bra TFT_dive_compass_text TFT_dive_compass_text: @@ -936,7 +918,7 @@ ; Text output call TFT_standard_color WIN_SMALL dm_custom_compass_head_column, dm_custom_compass_head_row - rcall TFT_surface_compass_heading_com ; show "000 N" + rcall TFT_surface_compass_heading_com ; show "xxx N" return TFT_dive_compass_dir_lclr: @@ -951,28 +933,28 @@ TFT_dive_compass_label_proc: movlw d'14' - movwf up ; cardinal width in px + movwf up ; cardinal width in px bcf compass_show_cardinal ; 1/a. check if it's viewable ? sub_a(RP) >= sub_b(RD) ? ; set the carry flag if sub_b(xRD) is equal to or greater than sub_a(xRP): MOVII xRD,sub_b - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag ; >= 0 ? - return ; NO + call subU16 ; sub_c = sub_a - sub_b + btfsc neg_flag ; >= 0 ? + return ; NO ; store the RO=RP-RD for drawing MOVII sub_c,xC ; 1/b. check if it's viewable ? sub_a(RP)+up(width) < sub_b(RD)+160 ; if already above, no need to process the rest of the labels - movff up,WREG ; take care about the width + movff up,WREG ; take care about the width addwf sub_a+0,1 btfsc STATUS, C incf sub_a+1 MOVII xRDr,sub_b - call subU16 ; sub_c = sub_a - sub_b - btfss neg_flag ; < 0 ? - bra TFT_dive_compass_label_end ; NO + call subU16 ; sub_c = sub_a - sub_b + btfss neg_flag ; < 0 ? + bra TFT_dive_compass_label_end ; NO ; 2. restore RO=RP-RD from 1/a. movff xC+0,lo @@ -1005,17 +987,17 @@ ; Common task to draw center line and marker ; until a proper implementation make it simple: rcall TFT_dive_compass_mk +TFT_dive_compass_c: movlw color_yellow WIN_BOX_COLOR dm_custom_compass_tick_top_top, dm_custom_compass_tick_bot_bot,.80,.81 ; center line in yellow return TFT_dive_compass_mk: ; draw the bearing on the screen if visible and if we just put something over it - btfss compass_bearing_set - return ; bearing_set=0 nothing to display - - btfss compass_bearing_vis - return ; bearing set but not visible + btfss compass_bearing_set ; bearing set? + return ; NO - done + btfss compass_bearing_vis ; YES - bearing visible? + return ; NO - bearing set but not visible, done ; save lo/hi from trashing MOVII mpr,xA @@ -1030,7 +1012,7 @@ ;TFT_dive_compass_mk_front: clrf lo movff xCM,lo - bsf compass_show_cardinal ; set=green marker + bsf compass_show_cardinal ; set=green marker rcall TFT_dive_compass_mk_print bcf compass_show_cardinal bra TFT_dive_compass_mk_end @@ -1038,7 +1020,7 @@ TFT_dive_compass_mk_rear: clrf lo movff xCM,lo - bcf compass_show_cardinal ; set=red marker + bcf compass_show_cardinal ; set=red marker rcall TFT_dive_compass_mk_print TFT_dive_compass_mk_end: @@ -1048,7 +1030,7 @@ TFT_dive_compass_mk_print: movlw d'1' cpfsgt lo - bra TFT_dive_compass_mk_print_2 ; lo <= 1, skip the first line + bra TFT_dive_compass_mk_print_2 ; lo <= 1, skip the first line movlw d'2' subwf lo,0 ; movff WREG,win_leftx2 @@ -1207,49 +1189,106 @@ STRCAT_TEXT tNW return +;----------------------------------------------------------------------------- compass_heading_common: btfss compass_enabled ; compass enabled? - bra compass_heading_common3 ; NO + bra compass_heading_common_zero ; NO + ; Get an averaged new heading movlw compass_averaging ; number of averaging cycles movwf up ; initialize loop counter -compass_heading_common1: +compass_heading_common_1: call I2C_RX_compass ; test compass call I2C_RX_accelerometer ; test accelerometer call compass_filter ; filter raw compass + accelerometer readings decfsz up,F ; decrement loop counter, done? - bra compass_heading_common1 ; NO - loop + bra compass_heading_common_1 ; NO - loop - call compass ; do compass corrections (C-code) + call compass ; do compass correction (C-code) banksel common ; back to bank common - MOVII compass_heading_old,sub_a ; transfer old heading to sub16 input - MOVII compass_heading_new,sub_b ; transfer new heading to sub16 input + ; Check for calibration and change + MOVII compass_heading_shown,sub_a ; transfer shown heading to sub_a + MOVII compass_heading_new, sub_b ; transfer new heading to sub_b btfsc sub_b+1,7 ; valid compass calibration? - bra compass_heading_common3 ; NO + bra compass_heading_common_zero ; NO + + movf sub_a+0,W ; get shown heading, low byte + cpfseq sub_b+0 ; compare with new heading, low byte, equal? + bra compass_heading_common_2 ; NO - not equal + movf sub_a+1,W ; get shown heading, high byte + cpfseq sub_b+1 ; compare with new heading, high byte, equal? + bra compass_heading_common_2 ; NO - not equal + return ; YES - done - call sub16 ; calculate compass_heading_old - compass_heading_new - btfss neg_flag ; result < 0 ? - bra compass_heading_common2 ; NO - test for threshold - MOVII compass_heading_new,sub_a ; YES - subtract the other way round - MOVII compass_heading_old,sub_b ; - ... - call sub16 ; - calculate compass_heading_new - compass_heading_old +compass_heading_common_2: + ; turn both headings such that compass_heading_new points to 0 + call subU16 ; sub_c = compass_heading_shown - compass_heading_new + btfss neg_flag ; was compass_heading_new in 1st halve? + bra compass_heading_common_3 ; YES - check where compass_heading_shown is now + MOVLI .360, sub_a ; NO - overturned, need to turn back to match 360 + MOVII sub_c,sub_b ; - move overturned compass_heading_new to sub_b + call subU16 ; - sub_c = angle between overturned compass_heading_shown and 360 +compass_heading_common_3: + ; check if turned compass_heading_shown is in 1st or 2nd halve + MOVII sub_c,sub_a ; sub_a = turned compass_heading_shown + MOVLI .180, sub_b ; sub_b = begin of 2nd halve + call cmpU16 ; check (turned compass_heading_shown) - 180 + btfss neg_flag ; result negative? + bra compass_heading_common_5 ; NO - in 2nd halve, increment towards compass_heading_new + ;bra compass_heading_common_4 ; YES - in 1st halve, decrement towards compass_heading_new -compass_heading_common2: - MOVII compass_heading_new,compass_heading_old ; copy new to old - movlw compass_fast_treshold ; get threshold for fast - cpfsgt sub_c+0 ; heading difference > compass_fast_treshold ? - return ; NO - done - MOVII compass_heading_new,compass_heading_shown ; YES - copy heading - return ; - done +compass_heading_common_4: + ; decrement compass_heading_shown towards compass_heading_new + rcall compass_heading_stepsize_2 ; calculate step size and put it into sub_b + MOVII compass_heading_shown,sub_a ; transfer unturned shown heading to sub_a + call subU16 ; decrement heading: sub_c = compass_heading_shown - step size + btfss neg_flag ; did an under-run occur? + bra compass_heading_common_6 ; NO - store result + MOVLI .360, sub_a ; YES - wrap around 360 + MOVII sub_c,sub_b ; - transfer decrement result to sub_b + call subU16 ; - wrap decrement result around + bra compass_heading_common_6 ; - store wrapped result + -compass_heading_common3: - clrf mpr+0 ; NO - create encoding of 0 - clrf mpr+1 ; - ... - MOVII mpr,compass_heading_shown ; - copy to compass_heading_shown - return ; - done +compass_heading_common_5: + ; increment compass_heading_shown towards compass_heading_new + rcall compass_heading_stepsize_1 ; calculate step size and put it into sub_b + MOVII compass_heading_shown,sub_a ; transfer unturned shown heading to sub_a + call addU16 ; increment heading: sub_c = compass_heading_shown + step size + MOVII sub_c,sub_a ; transfer increment result to sub_a + MOVLI .360, sub_b ; load wrap-around threshold + call subU16 ; calculate if over-run occurred + btfss neg_flag ; did an over-run occur? + bra compass_heading_common_6 ; YES - store already wrapped-around result + MOVII sub_a,sub_c ; NO - retrieve former straight increment result + bra compass_heading_common_6 ; - store wrapped result + +compass_heading_common_zero: + CLRI sub_c ; set heading to 0 + ;bra compass_heading_common_6 ; store heading + +compass_heading_common_6: + MOVII sub_c,compass_heading_shown ; store new shown heading + return ; done + +compass_heading_stepsize_1: + ; turn heading difference (180...359) into a step size + MOVLI .360, sub_a ; load 360 + MOVII sub_c,sub_b ; load difference + call subU16 ; sub_c = 360 - difference (i.e. 1...180 now) +compass_heading_stepsize_2: + ; turn heading difference (1...180) into a step size + bcf STATUS,C ; clear carry + rrcf sub_c+0 ; heading difference /= 2 + bcf STATUS,C ; clear carry + rrcf sub_c+0 ; heading difference /= 2, total /= 4 now + incf sub_c+0,f ; final += 1 to have one increment / decrement at least + MOVII sub_c,sub_b ; transfer result to sub_b + return + ENDIF ; _compass
--- a/src/configuration.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/configuration.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,7 +1,7 @@ #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ; ============================================================================ ; -; File configuration.inc combined next generation V3.03.4 +; File configuration.inc combined next generation V3.04.3 ; ; OSTC hwOS Configuration ; @@ -24,8 +24,8 @@ #endif #define softwareversion_x 0x03 -#define softwareversion_y 0x03 -#define softwareversion_beta 0x01 +#define softwareversion_y 0x05 +#define softwareversion_beta 0x00 #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -43,12 +43,12 @@ #endif #define firmware_creation_year 0x13 -#define firmware_creation_month 0x04 -#define firmware_creation_day 0x0d +#define firmware_creation_month 0x08 +#define firmware_creation_day 0x0a -#define firmware_expire_year 0x13 -#define firmware_expire_month 0x08 -#define firmware_expire_day 0x1e +#define firmware_expire_year 0x14 +#define firmware_expire_month 0x0a +#define firmware_expire_day 0x1f #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -56,14 +56,12 @@ ; global Version Selection ; ------------------------ ; -; _hwos_tech_2_TR compile hwOS in Tech version for OSTC 2, Plus and TR (with RX functions) -; _hwos_tech_3_cR compile hwOS in Tech version for OSTC 3 and cR (with external sensors) -; _hwos_tech compile hwOS in Tech version for all models (does not fit yet) -; _hwos_sport compile hwos in Sport version -; +; _hwos_tech_2_TR compile Tech version for OSTC 2, Plus and TR (1 language only ) memory: 122.054 used, 884 free +; _hwos_tech_3_cR compile Tech version for OSTC 3 and cR (2 languages possible) memory: 118.148 used, 4.790 free (with 1 language only) +; _hwos_sport compile Sport version for all models (2 languages possible) memory: 115.764 used, 7.174 free (with 1 language only) #endif -#define _hwos_tech_2_TR +#define _hwos_tech_3_cR #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -74,12 +72,12 @@ ; _language_1 first or single language, ; set to 'en', 'de', 'fr', or 'it', defaults to 'en' ; -; _language_2 second language, coding as above or 'none' mem: approx. 3854 byte in Sport version +; _language_2 second language, coding as above or 'none' mem: approx. 4.0 kbyte in Sport, 4.228 kbyte in Tech ; #endif -#define _language_1 de -#define _language_2 none +#define _language_1 en +#define _language_2 de #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -87,18 +85,21 @@ ; Features Selection ; ------------------ ; -; _screendump screen dump function mem: 334 byte, default: Sport: included, Tech: included -; _compass compass function mem: 12.488 byte, default: Sport: included, Tech: included -; _rx_functions RX functions (OSTC TR) mem: 7.942 byte, default: Sport: included, Tech: included -; _huge_font huge font mem: 3.651 byte, default: Sport: included, Tech: NOT included -; _helium Helium (Trimix) gases and diluents mem: 2.172 byte, default: Sport: NOT included, Tech: included -; _ccr_pscr loop modes CCR and pSCR mem: 4.308 byte, default: Sport: NOT included, Tech: included -; _external_sensor external sensor for CCR & pSCR 1) mem: 3.640 byte, default: Sport: NOT included, Tech: included -; _cave_mode cave mode way-out calculation mem: byte, default: Sport: NOT included, Tech: included ## FEATURE IS UNDER CONSTRUCTION YET ## -; _min_depth_option resettable min. and max. depth mem: byte, default: Sport: NOT included, Tech: NOT included -; _ostc_logo use of a bitmap-based OSTC logo mem: 1.748 byte, default: Sport: NOT included, Tech: NOT included +; _screendump screen dump function mem: 338 byte +; _compass compass function mem: 10.488 byte +; _rx_functions RX functions (OSTC TR) mem: 4.886 byte +; _rx_update updates RX firmware 1) mem: 2.472 byte +; _helium Helium (Trimix) gases and diluents mem: 2.182 byte +; _ccr_pscr loop modes CCR and pSCR mem: 4.110 byte +; _external_sensor external sensor for CCR & pSCR 2) mem: 3.452 byte +; _gauge_mode gauge mode mem: 30 byte when _not_ included +; _high_ppO2_max raised ppO2 max limit (2.0 bar) mem: 0 byte +; _cave_mode cave mode way-out calculation mem: byte ## under construction yet ## +; _min_depth_option resettable min. and max. depth mem: 394 byte ## special user group only ## +; _gas_contingency continue deco on other gases mem: 452 byte ## special user group only ## ; -; 1) needs to be excluded in case _ccr_pscr is excluded, too. +; 1) needs _rx_functions to be included, too / can not be included without _rx_functions +; 2) needs _ccr_pscr to be included, too / can not be included without _ccr_pscr ; ; NOTES: - Exclude options by prepending NOT_INCLUDED to the label. ; - Not all options will fit concurrently if two languages are slected. @@ -111,50 +112,36 @@ #define _screendump #define _compass -#define _huge_font #define _rx_functions +#define _rx_update #define _helium #define _ccr_pscr +#define _gauge_mode +#define _high_ppO2_max #define NOT_INCLUDED_external_sensor #define NOT_INCLUDED_cave_mode #define NOT_INCLUDED_min_depth_option -#define NOT_INCLUDED_ostc_logo #endif #ifdef _hwos_tech_3_cR -#define _screendump +#define NOT_INCLUDED_screendump #define _compass -#define _huge_font #define _helium #define _ccr_pscr #define _external_sensor +#define _gauge_mode +#define _high_ppO2_max +#define _gas_contingency #define NOT_INCLUDED_rx_functions +#define NOT_INCLUDED_rx_update #define NOT_INCLUDED_cave_mode #define NOT_INCLUDED_min_depth_option -#define NOT_INCLUDED_ostc_logo - -#endif - - -#ifdef _hwos_tech - -#define _screendump -#define _compass -#define _huge_font -#define _rx_functions -#define _helium -#define _ccr_pscr -#define _external_sensor - -#define NOT_INCLUDED_cave_mode -#define NOT_INCLUDED_min_depth_option -#define NOT_INCLUDED_ostc_logo #endif @@ -163,15 +150,16 @@ #define _screendump #define _compass -#define _huge_font #define _rx_functions +#define _rx_update #define NOT_INCLUDED_helium #define NOT_INCLUDED_ccr_pscr #define NOT_INCLUDED_external_sensor +#define NOT_INCLUDED_gauge_mode +#define NOT_INCLUDED_high_ppO2_max #define NOT_INCLUDED_cave_mode #define NOT_INCLUDED_min_depth_option -#define NOT_INCLUDED_ostc_logo #endif @@ -192,3 +180,63 @@ #define NOT_INCLUDED_DEBUG #define NOT_INCLUDED_debug_output #define NOT_INCLUDED_profiling + + + + + +#ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +; +; Software Configuration +; +#endif + +#ifdef _screendump +#define SW_CONF_1 0x01 +#else +#define SW_CONF_1 0x00 +#endif + +#ifdef _compass +#define SW_CONF_2 0x02 +#else +#define SW_CONF_2 0x00 +#endif + +#ifdef _rx_functions +#define SW_CONF_3 0x04 +#else +#define SW_CONF_3 0x00 +#endif + +#ifdef _rx_update +#define SW_CONF_4 0x08 +#else +#define SW_CONF_4 0x00 +#endif + +#ifdef _helium +#define SW_CONF_5 0x10 +#else +#define SW_CONF_5 0x00 +#endif + +#ifdef _ccr_pscr +#define SW_CONF_6 0x20 +#else +#define SW_CONF_6 0x00 +#endif + +#ifdef _external_sensor +#define SW_CONF_7 0x40 +#else +#define SW_CONF_7 0x00 +#endif + +#ifdef _cave_mode +#define SW_CONF_8 0x80 +#else +#define SW_CONF_8 0x00 +#endif + +#define SW_CONF SW_CONF_1 + SW_CONF_2 + SW_CONF_3 + SW_CONF_4 + SW_CONF_5 + SW_CONF_6 + SW_CONF_7 + SW_CONF_8
--- a/src/convert.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/convert.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File convert.asm combined next generation V3.0.1 +; File convert.asm combined next generation V3.04.2 ; ; Converts register values to string ; @@ -17,6 +17,26 @@ ;============================================================================= + global output99DD_call +output99DD_call: + tstfsz lo ; value = 0 ? + bra output99_call ; NO - do normal output + movlw " " ; YES - print a space + movwf POSTINC2 ; - ... + bra output99dd_cont ; - continue with the double dots + + + global output99dd_call +output99dd_call: + tstfsz lo ; value = 0 ? + bra output99_call ; NO - do normal output +output99dd_cont: + movlw "." ; YES - print double dots + movwf POSTINC2 ; - ... + movwf POSTINC2 ; - ... + return ; - done + + global output99_call output99_call: clrf ignore_digits
--- a/src/convert.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/convert.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File convert.inc combined next generation V3.0.1 +; File convert.inc combined next generation V3.04.2 ; ; Converts register values to string ; @@ -43,10 +43,20 @@ endm extern output99x_call -output_99x macro ; displays only last two figures from a 8 bit value with leading zero (00-99) +output_99x macro ; displays only last two digits from a 8 bit value with leading zero (00-99) call output99x_call endm + extern output99dd_call +output_99dd macro ; displays only last two digits from a 8 bit value, prints double-dots if zero - small fonts + call output99dd_call + endm + + extern output99DD_call +output_99DD macro ; displays only last two digits from a 8 bit value, prints double-dots if zero - big fonts + call output99DD_call + endm + extern outputHEX_call output_hex macro ; displays 8 bit integer in hex, input via WREG call outputHEX_call
--- a/src/customview.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/customview.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File customview.asm combined next generation V3.03.2 +; File customview.asm combined next generation V3.03.5 ; ; Custom Views in Surface and Dive Mode ; @@ -100,9 +100,6 @@ IFDEF _compass movlw .6 ; index of surface custom view compass cpfseq active_customview ; will compass be shown in custom view? - call I2C_sleep_accelerometer ; NO - stop accelerometer - movlw .6 ; index of surface custom view compass - cpfseq active_customview ; will compass be shown in custom view? call I2C_sleep_compass ; NO - stop compass ENDIF @@ -234,7 +231,6 @@ surf_customview_init_view6: ; view 6: compass IFDEF _compass - call I2C_init_accelerometer ; start accelerometer call I2C_init_compass ; start compass call TFT_surface_compass_mask ; show compass mask bra customview_toggle_exit ; done @@ -422,7 +418,7 @@ menuview_view9: btfsc FLAG_apnoe_mode ; in apnoe mode? bra menuview_toggle ; YES - goto next option - STRCPY_PRINT "Layout" ; NO - print "Layout" + STRCPY_TEXT_PRINT tDiveLayout ; NO - print "Layout" bra menuview_exit ; - done ;----------------------------------------------------------------------------- @@ -434,9 +430,6 @@ movlw index_compass_dm ; index of custom view compass cpfseq active_customview ; will compass be shown in custom view? - call I2C_sleep_accelerometer ; NO - stop accelerometer - movlw index_compass_dm ; index of custom view compass - cpfseq active_customview ; will compass be shown in custom view? call I2C_sleep_compass ; NO - stop compass movlw index_cv_dm_max ; highest index in use in dive mode custom view @@ -542,7 +535,6 @@ init_TFT_dive_compass: ; compass IFDEF _compass - call I2C_init_accelerometer ; start accelerometer call I2C_init_compass ; start compass call TFT_dive_compass_mask ; show compass mask bra customview_toggle_exit ; done
--- a/src/divemode.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/divemode.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File divemode.asm combined next generation V3.03.4 +; File divemode.asm combined next generation V3.04.3 ; ; Dive Mode ; @@ -180,6 +180,12 @@ TSTOSC opt_layout ; alternative layout enabled? bsf alt_layout_active ; YES - start with alternative layout + IFDEF _gas_contingency + ; disable gas contingency mode (may be left over activated by deco calculator) + clrf WREG + movff WREG,char_I_gas_contingency + ENDIF + ; boot tasks for all modes call diveloop_boot @@ -365,7 +371,7 @@ diveloop_loop_6: ; deco mode tasks every 1/1 second INCI divesecs_avg_trip ; increment the resettable dive time - INCI divesecs_avg_total ; increment the total dive dive time + INCI divesecs_avg_total ; increment the total dive time btfsc FLAG_gauge_mode ; in gauge mode? bra diveloop_loop_7 ; YES - skip deco calculations @@ -396,6 +402,7 @@ diveloop_loop_9: ; deco mode tasks every 1/1 second + rcall check_deco_states ; check and lock if in deco and in the deco stops region rcall TFT_output_3 ; do display updates diveloop_loop_10: @@ -529,25 +536,25 @@ ;-------------------------------------------------------------------------------------------------------- -divemode_apnoe_tasks: ; 1 sec. apnoe tasks - bsf FLAG_TFT_apnoe_divetime ; show apnoe dive times (current/last dive and total) - btfsc apnoe_at_surface ; at the surface? - bra divemode_apnoe_tasks_surf ; YES - at the surface - ;bra divemode_apnoe_tasks_dive ; NO - in dive phase - -divemode_apnoe_tasks_dive: ; apnoe mode, submerged - btfss apnoe_new_dive ; new dive begun? - return ; NO - done - bcf apnoe_new_dive ; YES - clear flag - bsf FLAG_TFT_clear_apnoe_surface; - clear apnoe mode surface data from screen - return ; - done - -divemode_apnoe_tasks_surf: ; apnoe mode, at the surface - bsf FLAG_TFT_apnoe_surface_time ; show apnoe mode surface time +divemode_apnoe_tasks: ; 1 sec. apnoe tasks + bsf FLAG_TFT_apnoe_divetime ; show apnoe dive times (current/last dive and total) + btfsc apnoe_at_surface ; at the surface? + bra divemode_apnoe_tasks_surf ; YES - at the surface + ;bra divemode_apnoe_tasks_dive ; NO - in dive phase + +divemode_apnoe_tasks_dive: ; apnoe mode, submerged + btfss apnoe_new_dive ; new dive begun? + return ; NO - done + bcf apnoe_new_dive ; YES - clear flag + bsf FLAG_TFT_clear_apnoe_surface ; - clear apnoe mode surface data from screen + return ; - done + +divemode_apnoe_tasks_surf: ; apnoe mode, at the surface + bsf FLAG_TFT_apnoe_surface_time ; show apnoe mode surface time ; TODO: these outputs would need to be done only once after surfacing... - bsf FLAG_TFT_depth_maximum_apnoe; show max. depth of last dive - bsf FLAG_TFT_depth_maximum ; show max. depth of all dives - ;bra apnoe_calc_maxdepth ; calculate overall max. depth and return + bsf FLAG_TFT_depth_maximum_apnoe ; show max. depth of last dive + bsf FLAG_TFT_depth_maximum ; show max. depth of all dives + ;bra apnoe_calc_maxdepth ; calculate overall max. depth and return global apnoe_calc_maxdepth @@ -1092,8 +1099,9 @@ ; calculate velocity in m/min MOVII sub_c,xA ; copy pressure differential to xA MOVLI .39,xB ; put scale coefficient into xB (use 77 when called every second) - call mult16x16 ; compute differential pressure in mbar*39 + call mult16x16 ; compute differential pressure in mbar * scale coefficient MOVII xC,divA ; copy result to divA + ADDLI .64,divA ; add some round-up TODO: too sensitive with this? movlw .7 ; divide by 2^7 call div16 ; divA = divA / 2^WREG, yields velocity in m/min @@ -1113,6 +1121,22 @@ ;============================================================================= +check_deco_states: + btfsc deco_region ; been within the deco stops region before? + return ; YES - been in deco then before too, done + movff char_O_deco_info,WREG ; NO - get deco info vector + btfss WREG,deco_stops ; do we have a deco obligation right now? + return ; NO - done + bsf deco_locked ; YES - memorize dive was in deco + movff char_O_deco_depth+0,WREG ; - get depth of first stop in meters into WREG + addlw deco_region_distance+.1 ; - add deco region start distance + 1 meter for the negative test to work + subwf depth_meter,W ; - compute current depth - (first stop depth + deco distance) + btfss STATUS,C ; - result negative? + bsf deco_region ; YES - memorize to have entered the deco stops region + return ; - done + +;============================================================================= + safety_stop_control: TSTOSS opt_enable_safetystop ; safety stop enabled? (=1: show safety stop) return ; NO - done @@ -1286,17 +1310,17 @@ update_backtrack: btfsc dive_turned ; dive turned? return ; YES - done - movwf lo ; NO - store minutes to add in lo - lfsr FSR1,char_I_backtrack_depth ; - load FSR1 with base address of backtrack storage - movff char_I_backtrack_time,FSR1L ; - adjust FSR1 to last index -update_backtrack_loop: - btfsc FLAG_backtrack_full ; - backtracking storage full? + btfsc FLAG_backtrack_full ; NO - backtracking storage full? return ; YES - done - movff depth_meter,PREINC1 ; NO - increment index and write current depth to backtrack storage - incfsz FSR1L,W ; - increment index once more into WREG, did a wrap-around occur (backtrack storage full)? - bra update_backtrack_loop_1 ; NO - continue loop - bsf FLAG_backtrack_full ; YES - flag backtracking storage is full - return ; - done + movwf lo ; NO - store minutes to add in lo + lfsr FSR1,char_I_backtrack_depth ; - load FSR1 with base address of backtrack storage + movff char_I_backtrack_time,FSR1L ; - adjust FSR1 to last index +update_backtrack_loop: + movff depth_meter,PREINC1 ; increment index and write current depth to backtrack storage + incfsz FSR1L,W ; increment index once more and dump to WREG, did a wrap-around occur (backtrack storage full)? + bra update_backtrack_loop_1 ; NO - continue loop + bsf FLAG_backtrack_full ; YES - flag backtracking storage is full + return ; - done update_backtrack_loop_1: decfsz lo,F ; decrement loop counter, did it became zero? bra update_backtrack_loop ; NO - loop @@ -1365,8 +1389,10 @@ set_powersafe: - movlw color_code_battery_low+.1 ; get battery low level threshold [%] - cpfslt batt_percent ; current battery level > low level threshold ? + movlw battery_warn_level_36+1 ; get threshold for 3.6 Volt battery warning, incremented by 1 + btfss battery_is_36v ; actually a 3.6 Volt battery detected? + movlw battery_warn_level_15+1 ; NO - replace with 1.5 Volt battery warning, incremented by 1 + cpfslt batt_percent ; current battery level > warning threshold ? return ; YES - ok, done movlw d'7' ; NO - set type of alarm = battery low movwf alarm_type ; - copy to alarm register @@ -1614,8 +1640,8 @@ movlw NUM_GAS+1 ; - get highest index+1 cpfseq lo ; - all gases checked? bra get_first_gas_to_WREG2 ; NO - not yet - movlw .1 ; YES - return gas 1 - movff WREG,opt_gas_type+0 ; - set to type First + movlw .1 ; YES - default to gas 1 + movff WREG,opt_gas_type+0 ; - force it to be of type First return ; - done get_first_gas_to_WREG3: movf lo,W ; copy index of gas found to be the First to WREG @@ -1639,8 +1665,8 @@ movlw NUM_GAS+1 ; - get highest index+1 cpfseq lo ; - dils checked? bra get_first_dil_to_WREG2 ; NO - not yet - movlw .1 ; YES - return dil 1 - movff WREG,opt_dil_type+0 ; - set to type First + movlw .1 ; YES - default to dil 1 + movff WREG,opt_dil_type+0 ; - force it to be of type First return ; - done get_first_dil_to_WREG3: movf lo,W ; copy index of dil found to be the First to WREG @@ -1651,6 +1677,7 @@ ;============================================================================= + global deco_setup_oc_gases deco_setup_oc_gases: ; with currently breathed gas in WREG (1-5 or 6) movff char_O_deco_status,lo ; working copy of char_O_deco_status in bank common deco_setup_oc_gases_pre: ; entry point with lo preloaded @@ -1667,8 +1694,8 @@ ; opt_gas_change res NUM_GAS | char_I_deco_gas_change res NUM_GAS ; opt_dil_change res NUM_GAS | ; - lfsr FSR2,char_I_deco_O2_ratio ; load FSR2 with base address of char_I_deco_O2_ratio. - ; FSR2 will step through all char_I_deco_... vars. + lfsr FSR2,char_I_deco_O2_ratio ; load FSR2 with base address of char_I_deco_O2_ratio + ; FSR2 will step through all char_I_deco_... vars lfsr FSR1,opt_gas_O2_ratio ; load FSR1 with base address of opt_gas_O2_ratio rcall deco_setup_copy ; copy all OC O2 ratios lfsr FSR1,opt_gas_He_ratio ; load FSR1 with base address of opt_gas_He_ratio @@ -1687,6 +1714,7 @@ IFDEF _ccr_pscr + global deco_setup_cc_diluents deco_setup_cc_diluents: ; with currently breathed diluent in WREG (1-5 or 6) movff char_O_deco_status,lo ; working copy of char_O_deco_status in bank common deco_setup_cc_diluents_pre: ; entry point with lo preloaded @@ -1736,6 +1764,7 @@ return ; YES - done + global setup_gas_registers setup_gas_registers: ; with currently breathed gas in WREG (1-5 or 6) movwf active_gas ; set as current gas movlw .6 @@ -1752,13 +1781,13 @@ setup_gas_registers_15: lfsr FSR1,opt_gas_O2_ratio ; load base address of gas data decf active_gas,W ; set index to O2 ratio of current gas (1-5 -> 0-4) - movff PLUSW1,char_I_O2_ratio ; copy gas 1-5 O2 ratio to deco engine + movff PLUSW1,char_I_O2_ratio ; copy O2 ratio to deco engine addlw .10 ; advance index from O2 ratio to He ratio IFDEF _helium - movff PLUSW1,char_I_He_ratio ; copy gas 1-5 He ratio to deco engine + movff PLUSW1,char_I_He_ratio ; copy He ratio to deco engine ENDIF addlw .10 ; advance index from He ratio to gas type - movff PLUSW1,char_I_current_gas_type ; copy gas 1-5 type (0=Disabled, 1=First, 2=Travel, 3=Deco) + movff PLUSW1,char_I_current_gas_type ; copy gas type (0=Disabled, 1=First, 2=Travel, 3=Deco) setup_gas_registers_com: movff char_O_main_status,lo ; working copy of char_O_main_status in bank common bcf lo,DECO_MODE_PSCR_FLAG ; clear the pSCR-mode flag (may not be set, but never mind) @@ -1771,6 +1800,7 @@ IFDEF _ccr_pscr + global setup_dil_registers setup_dil_registers: ; with currently breathed gas in WREG (1-5 or 6) btfsc bailout_mode ; check if in bailout condition | --------------- FOR SAFETY ONLY -------------- bra setup_gas_registers ; revert to setting up OC gases in bailout condition | This branch should never happen to be taken... @@ -1789,10 +1819,10 @@ setup_dil_registers_15: lfsr FSR1,opt_dil_O2_ratio ; load base address of diluent data decf active_dil,W ; set index to O2 ratio of current diluent (1-5 -> 0-4) - movff PLUSW1,char_I_O2_ratio ; copy diluent 1-5 O2 ratio to deco engine + movff PLUSW1,char_I_O2_ratio ; copy O2 ratio to deco engine addlw .10 ; advance index from O2 ratio to He ratio IFDEF _helium - movff PLUSW1,char_I_He_ratio ; copy diluent 1-5 He ratio to deco engine + movff PLUSW1,char_I_He_ratio ; copy He ratio to deco engine ENDIF addlw .10 ; advance index from He ratio to diluent type movff PLUSW1,char_I_current_gas_type ; copy diluent type (0=Disabled, 1=First, 2=Normal) @@ -1874,6 +1904,11 @@ goto menuview_toggle_reset ; terminate pre-menu and return divemode_option6: + ; check for pending +5 request + movff char_I_sim_advance_time,WREG; get mailbox content + tstfsz WREG ; mailbox clear (=0) ? + return ; NO - still having a pending +5' request, refuse new request + ; advance tissues pressures and deco obligation by 5 minutes movlw .5 ; + 5 minutes movff WREG,char_I_sim_advance_time; copy to mailbox @@ -1928,7 +1963,8 @@ call update_backtrack ; add backtrack data for 5 minutes ENDIF - goto menuview_toggle_reset ; terminate the pre-menu and return +; goto menuview_toggle_reset ; terminate the pre-menu and return + return ; just return, leaving option avail for repeated selection IFDEF _compass divemode_option7: @@ -1979,6 +2015,7 @@ ; in OC mode : - checks only gases for best gas ; - sets better_gas_available on OC gases ; + global check_gas_best check_gas_best: btfsc FLAG_gauge_mode ; in gauge mode? return ; YES - done @@ -1993,7 +2030,7 @@ ; compute max. allowed default ppO2 movff char_O_deco_info,lo ; bank-safe copy of deco info vector - btfss lo,deco_flag ; is the ppO2 deco limit enabled? + btfss lo,deco_mode ; is the ppO2 deco limit enabled? bra check_gas_best_1 ; NO - compute default ppO2 max MOVII ppO2_max_deco,ppO2_max_default ; YES - copy default ppO2 max from deco max. bra check_gas_best_2 ; - continue with common part @@ -2079,7 +2116,7 @@ check_gas_best_gas: ; set minimum ppO2 required - movff char_I_ppO2_min,WREG ; min ppO2 for OC and Bailout + movff char_I_ppO2_min,WREG ; min ppO2 for OC and bailout mullw .100 ; min ppO2 * 100, result in 0.1 mbar MOVII PROD,ppO2_min ; store in ppO2_min ; preset results to nothing found @@ -2161,13 +2198,16 @@ addlw .10 ; add offset of 10 bytes to index change depth in opt_gas_change/opt_dil_change movff PLUSW1,check_gas_depth ; copy change depth of current gas/dil to check_gas_depth MOVII ppO2_max_default,sub_b ; select default ppO2 max for first / travel / normal gas + ; check if the gas is the current gas + movf check_gas_num,W ; get the number of the gas to be checked (1-5) + cpfseq lo ; is this the currently used gas? + bra check_gas_best_common0 ; NO - do the disabled & deco gas checks + bra check_gas_best_common3 ; YES - a gas in use overrides disabled and deco status +check_gas_best_common0: ; check if gas is available (i.e. not disabled) tstfsz check_gas_type ; type = disabled (0) ? bra check_gas_best_common1 ; NO - continue checks - movf check_gas_num,W ; YES - get the number of the gas to be checked (1-5) - cpfseq lo ; - is this the currently used gas? - return ; NO - skip disabled gases which are not the current gas - bra check_gas_best_common3 ; YES - a gas in use overrides it's disabled status, therefore treat it as available + return ; YES - skip disabled gases check_gas_best_common1: ; skip deco gases (type=3) if there are no stops, but include them when in bailout mode movlw .3 ; coding for deco gas @@ -2175,22 +2215,18 @@ bra check_gas_best_common3 ; NO - first or travel/normal then, ok to use btfsc bailout_mode ; YES - in bailout? bra check_gas_best_common2 ; YES - ok to use (using deco gases is always allowed when in bailout) - - TSTOSC opt_extended_stops ; NO - extended stops activated? - bra check_gas_best_common1a ; YES - (1) - movff char_O_deco_info,WREG ; NO - get deco info vector - btfss WREG,deco_flag ; - in deco mode (deco_flag set), i.e. use of deco gases allowed? - return ; NO - skip deco gas while not in deco mode - bra check_gas_best_common2 ; YES - ok to use + TSTOSS opt_extended_stops ; NO - extended stops enables? + bra check_gas_best_common1b ; NO + ;bra check_gas_best_common1a ; YES check_gas_best_common1a: - movff char_O_deco_depth+0,WREG ; (1) - get depth of the first stop - tstfsz WREG ; - is there any stop? - bra check_gas_best_common2 ; YES - ok to use a deco gas - movf check_gas_num,W ; NO - get the number of the gas to be checked (1-5) - cpfseq lo ; - is this the currently used gas? - return ; NO - skip this deco gas - ;bra check_gas_best_common2 ; YES - keep this deco gas as continued allowed - + movff char_O_deco_info,WREG ; get deco info vector + btfss WREG,deco_mode ; are we in deco mode? + return ; NO - skip deco gas while not in deco mode + bra check_gas_best_common2 ; YES - deco gases allowed +check_gas_best_common1b: + btfss deco_region ; are we in the deco region? + return ; NO - skip deco gas while not in the deco region + ;bra check_gas_best_common2 ; YES - deco gases allowed check_gas_best_common2: MOVII ppO2_max_deco,sub_b ; replace by ppO2 max for a deco gas check_gas_best_common3: @@ -2206,10 +2242,11 @@ bra check_gas_best_common5 ; YES - check if the new one is better than the one we have so far bra check_gas_best_common6 ; NO - no need to do the above mentioned check check_gas_best_common5: - ; check if the change depth of the checked gas is < (shallower) than the change depth of the best gas found so far + ; check if the change depth of the checked gas is <= (shallower or equal) the change depth of the best gas found so far movf best_gas_depth,W ; load change depth of best gas so far into WREG - cpfslt check_gas_depth ; change depth of checked gas < (shallower than) change depth of best gas so far? - return ; NO - this gas is not better than the best already found + cpfsgt check_gas_depth ; change depth of checked gas > (deeper than) change depth of best gas so far? + bra check_gas_best_common6 ; NO - this gas is better or equal, continue + return ; YES - this gas is not better than the best already found check_gas_best_common6: ; check if the gas fits into the ppO2 limits movff check_gas_O2_ratio,xB+0 ; xB = O2 ratio, xA is still loaded with (absolute pressure / 10) @@ -2350,7 +2387,7 @@ ; set-up registers rcall get_first_gas_to_WREG ; get first gas (1-5) into WREG rcall setup_gas_registers ; set-up of gas parameters of currently breathed gas (with WREG = gas 1-5) - rcall deco_setup_oc_gases ; set-up of gas list for deco calculations (with WREG = gas 1-5) + rcall deco_setup_oc_gases ; set-up of gas list for deco calculations (with WREG = gas 1-5) return ;============================================================================= @@ -2368,7 +2405,7 @@ ; set-up registers rcall get_first_dil_to_WREG ; get first diluent (1-5) into WREG rcall setup_dil_registers ; set-up of diluent parameters for currently breathed diluent (with WREG = current diluent 1-5) - rcall deco_setup_cc_diluents ; set-up of diluent list for deco calculations (with WREG = current diluent 1-5) + rcall deco_setup_cc_diluents ; set-up of diluent list for deco calculations (with WREG = current diluent 1-5) ; done return @@ -2432,7 +2469,6 @@ call restart_set_modes_and_flags ; stop accelerometer and compass - call I2C_sleep_accelerometer call I2C_sleep_compass ; do an early initialization of all deco engine output variables to @@ -2479,12 +2515,9 @@ bcf lo,DECO_START_ALT ; clear flag for doing an alternative plan, bsf lo,DECO_INITIALIZE ; set flag for initializing the deco engine bcf lo,DECO_ASCENT_FLAG ; disable delayed ascent calculation + bcf lo,DECO_CALCULATOR_MODE ; deco engine not run from the deco calculator movff lo,char_O_deco_status ; bank-safe copy back to deco engine - ; configure distance between actual depth and depth used for deco calculation - movlw deco_distance - movff WREG,char_I_deco_distance - ; disable "fast forward" function movlw .0 movff WREG,char_I_sim_advance_time @@ -2750,22 +2783,22 @@ global check_warn_battery check_warn_battery: - movff batt_percent,lo ; get battery % movlw battery_show_level+1 ; get threshold for showing battery level, incremented by 1 - cpfslt lo ; battery percentage ok? + cpfslt batt_percent ; battery percentage ok? return ; YES - no display, no warning ; Display Battery, but warn? - movff batt_percent,lo ; get battery % - movlw color_code_battery_low+1 ; get threshold for battery warning, incremented by 1 - cpfsgt lo ; battery percent below warning threshold? + movlw battery_warn_level_36+1 ; get threshold for 3.6 Volt battery warning, incremented by 1 + btfss battery_is_36v ; actually a 3.6 Volt battery detected? + movlw battery_warn_level_15+1 ; NO - replace with 1.5 Volt battery warning, incremented by 1 + cpfsgt batt_percent ; battery percent below warning threshold? bsf message_warning ; YES - set warning flag movlw index_clock_batt_surfpress ; index of custom view clock, battery and surface pressure cpfseq active_customview ; battery shown in custom view? bra check_warn_battery2 ; NO - show warning return ; YES - do not show twice (in custom view and in message area) check_warn_battery2: - incf message_counter,F ; increase counter - goto TFT_msg_batt_percent_divemode ; show percent (and return) + incf message_counter,F ; increase counter + goto TFT_msg_batt_percent_divemode ; show percent (and return) check_divetimeout: @@ -2818,7 +2851,7 @@ check_ppo2_display_a: bsf message_attention ; show attention sign check_ppo2_display: - movlw index_ppo2_ead_end_cns ; index of custom view ppO2, EAD/END and CNS) + movlw index_ppo2_ead_end_cns ; index of custom view ppO2, EAD/END and CNS (without He) or gas density (with He) cpfseq active_customview ; ppO2 shown? bra check_ppO2_b ; NO return ; YES - do not show twice (in custom view and in warning area) @@ -2863,10 +2896,12 @@ bsf message_warning ; show warning sign check_cns_violation_2: bsf message_attention ; show attention sign - movlw index_ppo2_ead_end_cns ; index of custom view ppO2, EAD/END and CNS + IFNDEF _helium + movlw index_ppo2_ead_end_cns ; index of custom view ppO2, EAD/END and CNS (without He) or gas density (with He) cpfseq active_customview ; CNS shown? bra check_cns_violation_3 ; NO return ; YES - do not show twice (in custom view and in warning area) + ENDIF check_cns_violation_3: movlw index_CNS ; index of custom view with CNS values cpfseq active_customview ; CNS shown? @@ -2935,8 +2970,12 @@ movff char_O_deco_info,WREG ; NO - get the deco info vector btfss WREG,deco_zone ; check if the deco zone flag is set return ; NO - done, return - incf message_counter,F ; YES - increase counter - goto TFT_info_deco ; - show deco info + btfsc use_aGF ; YES - using alternative GF factors? + return ; YES - suppress deco zone info + btfsc alt_layout_active ; NO - in alternative layout? + return ; YES - suppress deco zone info + incf message_counter,F ; NO - increase counter + goto TFT_info_deco ; - show deco info check_depth_limit: @@ -3046,7 +3085,7 @@ rcall check_tr_functions_helper7 ; check for transmitter 2 pressure warning rcall check_tr_functions_helper8 ; check for transmitter 2 pressure attention check_tr_functions_show_xmtr: - btfss show_transmitter_attention ; shall show transmitter message? + btfss show_transmitter_attention ; shall show transmitter attention message? bra check_tr_functions_show_warn ; NO - continue with pressure warning bsf message_attention ; YES - set flag for attention incf message_counter,F ; - increase counter @@ -3070,7 +3109,7 @@ bcf transmitter1_lost ; NO - clear flag for old lost attention return ; - done check_tr_functions_helper1a: - bsf show_transmitter_attention ; show transmitter attention +; bsf show_transmitter_attention ; show transmitter attention btfsc transmitter1_lost ; is it a new message? return ; NO - do not show the pressure readings custom view again bsf transmitter1_lost ; YES - memorize it's an old message now @@ -3118,7 +3157,7 @@ bcf transmitter2_lost ; NO - clear flag for old lost attention return ; - done check_tr_functions_helper5a: - bsf show_transmitter_attention ; show transmitter attention +; bsf show_transmitter_attention ; show transmitter attention btfsc transmitter2_lost ; is it a new message? return ; NO - do not show the pressure readings custom view again bsf transmitter2_lost ; YES - memorize it's an old message now
--- a/src/divemode.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/divemode.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File divemode.inc combined next generation V3.03.2 +; File divemode.inc combined next generation V3.03.5 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -11,6 +11,14 @@ extern set_dive_modes extern diveloop extern apnoe_calc_maxdepth + extern check_gas_best + extern setup_gas_registers + extern deco_setup_oc_gases + + IFDEF _ccr_pscr + extern setup_dil_registers + extern deco_setup_cc_diluents + ENDIF IFDEF _external_sensor extern calc_deko_divemode_sensor
--- a/src/eeprom_rs232.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/eeprom_rs232.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File eeprom_rs232.asm combined next generation V3.03.1 +; File eeprom_rs232.asm combined next generation V3.04.3 ; ; Internal EEPROM, RS232 ; @@ -90,12 +90,12 @@ movlw 0xAA movwf EECON2 bsf EECON1,WR - bsf INTCON,GIE ; ...but the flag for the ISR routines were still set, so they will interrupt now! write_eep2: btfsc EECON1,WR bra write_eep2 ; wait about 4ms... bcf EECON1,WREN + bsf INTCON,GIE ; ...but the flag for the ISR routines were still set, so they will interrupt now! return ;============================================================================= @@ -108,10 +108,10 @@ clrf TXSTA2 clrf RCSTA2 banksel common ; back to bank common - bcf ir_power ; IR off - bcf mcp_power ; power-down instrumentation amp - bsf s8_npower ; power-down S8 digital interface - bcf s8_digital_avail ; digital S8 interface not available + bcf ir_power ; IR off + bcf mcp_power ; power-down instrumentation amp + bsf s8_npower ; power-down S8 digital interface + bcf s8_digital_avail ; digital S8 interface not available return @@ -138,16 +138,16 @@ return enable_s8: - ; Check for Digital/Analog - bsf s8_npower ; power-down S8 HUD - WAITMS d'1' ; very short delay - bsf mcp_power ; power-up instrumentation amp - btfss mcp_power - bra $-6 - banksel TXSTA2 ; select bank for IO register access + banksel TXSTA2 ; select bank for IO register access clrf TXSTA2 clrf RCSTA2 banksel common ; back to bank common + ; Check for Digital/Analog + bsf s8_npower ; power-down S8 HUD + WAITMS d'2' ; very short delay + bsf mcp_power ; power-up instrumentation amp + btfss mcp_power + bra $-4 ; It may be digital, check for voltage when isolator is powered bcf s8_npower ; power S8 HUD @@ -190,6 +190,7 @@ btfss speed_is_normal ; speed = normal? bra enable_rs232_1 ; NO - wait for ISR to adjust speed bcf PORTE,0 ; start comm + bsf PORTJ,2 ; /Reset (for very old OSTC sport) ;initialize serial port1 (TRISC6/7) movlw b'00100100' ; BRGH=1, SYNC=0 movwf TXSTA1 @@ -204,6 +205,7 @@ clrf TXSTA1 ; UART disable bcf PORTC,6 ; TX hard to GND bsf PORTE,0 ; stop comm + bcf PORTJ,2 ; /Reset (for very old OSTC sport) return
--- a/src/external_flash.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/external_flash.asm Thu Sep 19 12:01:29 2019 +0200 @@ -325,7 +325,7 @@ clrf ext_flash_address+1 clrf ext_flash_address+2 - setf ext_flash_rw ; 256 * 12 kB = 3145728 bytes + clrf ext_flash_rw ; 256 * 12 kB = 3145728 bytes ext_flash_erase_logbook_loop: rcall ext_flash_erase4kB ; 4kB rcall ext_flash_add_4kB ; increase ext_flash_address:3 by 4kB
--- a/src/gaslist.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/gaslist.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File gaslist.asm combined next generation V3.03.2 +; File gaslist.asm combined next generation V3.03.5 ; ; Managing OSTC gas list ; @@ -427,18 +427,21 @@ gaslist_strcat_gas_type: lfsr FSR1,opt_gas_type ; load base address of gas types movf gaslist_gas,W ; load index to WREG (0-4 for gases, 5-9 for diluents) - decf PLUSW1,W ; read gas/dil type into WREG and... - ; ...decrement by 1 (-1 for disabled, 0 for first, 1 for travel/normal, 2 for deco) - bnz gaslist_strcat_gas_type_1 ; type = first? NO - continue with checking for deco gas + decf PLUSW1,W ; get and decrement gas type (-1 for disabled, 0 for first, 1 for work/normal, 2 for deco) + bnz gaslist_strcat_gas_type_1 ; type = first? NO - continue with checking for work and deco gas PUTC "*" ; YES - print "*" for first return ; - done gaslist_strcat_gas_type_1: - decf WREG,W ; decrement gas type (-2 for disabled, -1 for first, 0 for travel/normal, 1 for deco) - decf WREG,W ; decrement gas type (-3 for disabled, -2 for first, -1 for travel/normal, 0 for deco) - bnz gaslist_strcat_gas_type_2 ; type = deco? NO - neither first nor deco + decf WREG,W ; decrement gas type (-2 for disabled, -1 for first, 0 for work/normal, 1 for deco) + bnz gaslist_strcat_gas_type_2 ; type = work? NO - continue with checking for deco gas + PUTC "\xb8" ; YES - print down-arrow for a work gas + return ; - done +gaslist_strcat_gas_type_2: + decf WREG,W ; decrement gas type (-3 for disabled, -2 for first, -1 for work/normal, 0 for deco) + bnz gaslist_strcat_gas_type_3 ; type = deco? NO - neither first nor deco PUTC "=" ; YES - print "=" for a deco gas return ; - done -gaslist_strcat_gas_type_2: +gaslist_strcat_gas_type_3: PUTC " " ; neither first nor deco, print a space return @@ -825,28 +828,31 @@ ;---------------------------------------------------------------------------- -; Compute MOD from char_I_ppO2_max_work/char_I_ppO2_max_deco and current O2 ratio +; Compute MOD from O2 ratio and char_I_ppO2_max_work / char_I_ppO2_max_deco +; Compute MOD from O2 ratio and char_I_ppO2_max_deco ; ; Input: gaslist_gas = current gas index. ; opt_gas_O2_ratio[gaslist_gas] = current O2 ratio ; Output: WREG = MOD [m] ; gaslist_calc_mod: + lfsr FSR1,opt_gas_type ; load base address of opt_gas_type movf gaslist_gas,W ; load index (0...9) + movff PLUSW1,xA+0 ; read gas/dil type into xA+0 (used as temp here) + movff char_I_ppO2_max_work,xB+1 ; get max ppO2 for deco into xB+1 (used as temp here) + movlw .3 ; type code for deco gases + cpfslt xA+0 ; is it a deco gas? +gaslist_calc_mod_deco: + movff char_I_ppO2_max_deco,xB+1 ; YES - overwrite/get ppO2 max with/for work lfsr FSR1,opt_gas_O2_ratio ; load base address of opt_gas_O2_ratio + movf gaslist_gas,W ; load index (0...9) movff PLUSW1,xB+0 ; read O2 ratio into xB+0 - lfsr FSR1,opt_gas_type ; load base address of opt_gas_type - movff PLUSW1,xA+0 ; read gas/dil type into xA+0 (used as temp here) - movff char_I_ppO2_max_deco,xB+1 ; get max ppO2 for deco into xB+1 (used as temp here) - movlw .3 ; type code for deco gases - cpfseq xA+0 ; is it a deco gas? - movff char_I_ppO2_max_work,xB+1 ; NO - overwrite ppO2 max with working phase max - movf xB+1,W ; copy resulting ppO2 max into WREG + movf xB+1,W ; copy ppO2 max into WREG clrf xB+1 ; clear xB+1 for div16x16 operation mullw .10 ; multiply ppO2 max value with 10 MOVII PROD,xA ; copy result to xA call div16x16 ; xC = xA / xB with xA as remainder - movf xC+0,W ; copy low byte of the result to WREG + movf xC+0,W ; copy low byte of the result to WREG addlw -.10 ; subtract 10 cbar return ; return with final result [in meters] in WREG @@ -925,16 +931,24 @@ ; global gaslist_reset_mod_title gaslist_reset_mod_title: - STRCAT_TEXT tDepthReset - rcall gaslist_calc_mod ; compute MOD into WREG - movwf lo ; copy result to lo + STRCAT_TEXT tDepthReset ; print "Reset to MOD:" + PUTC " " ; add a space char lfsr FSR1,opt_gas_change ; load base address of opt_gas_change movf gaslist_gas,W ; load index (0-9) - movf PLUSW1,W ; read change depth into WREG + movff PLUSW1,hi ; read change depth into hi + rcall gaslist_calc_mod ; compute MOD for ppO2 max work/deco dependent on gas type into WREG + movwf lo ; copy (true) MOD to lo + movf hi,W ; copy change depth to WREG cpfslt lo ; change depth > MOD ? - bra gaslist_strcat_depth ; NO - return - call TFT_warning_color ; YES - use red color - bra gaslist_strcat_depth ; - return + bra gaslist_strcat_depth ; NO - print MOD from value in lo + call TFT_attention_color ; YES - use attention color + rcall gaslist_calc_mod_deco ; - compute MOD for ppO2 max deco into WREG + movwf up ; - copy result to up + movf hi,W ; - copy change depth to WREG again + cpfslt up ; - change depth > MOD deco ? + bra gaslist_strcat_depth ; NO - print MOD from value in lo, keeping attention color + call TFT_warning_color ; YES - switch to warning color + bra gaslist_strcat_depth ; - print MOD from value in lo ; set change depth of gas in gaslist_gas (0-9) to its MOD
--- a/src/ghostwriter.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/ghostwriter.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File ghostwriter.asm combined next generation V3.03.1 +; File ghostwriter.asm combined next generation V3.03.7 ; ; Ghostwriter (Log profile recorder) ; @@ -59,8 +59,12 @@ movlw div_cns movwf divisor_cns - movlw div_tank - movwf divisor_tank + IFDEF _rx_functions + clrf WREG ; default to no tank data logging + btfsc tr_functions_activated ; TR functions activated? + movlw div_tank ; YES - get divisor for tank data + movwf divisor_tank ; initialize divisor + ENDIF IFDEF _external_sensor movlw div_ppo2_sensors @@ -136,10 +140,12 @@ movlw infolength_cns ; YES - get length of extra data addwf ProfileFlagByte,F ; - add to ProfileFlagByte check_extended6: + IFDEF _rx_functions decfsz divisor_tank,W ; check divisor if it will become 0, dump decremented value to WREG bra check_extended7 ; NO - skip movlw infolength_tank ; YES - get length of extra data addwf ProfileFlagByte,F ; - add to ProfileFlagByte + ENDIF check_extended7: ; Second, check global event flag @@ -201,7 +207,7 @@ btfss event_occured ; check global event flag (again) bra store_dive_data4 ; no event -; Store the EventByte(s) + additional bytes now + ; Store the EventByte(s) + additional bytes now movf event_byte1,W rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash movf event_byte2,W ; write second event byte... @@ -219,18 +225,20 @@ ENDIF rcall ghostwrite_byte_profile ; - store it bcf event_gas_change_gas6 ; - clear event flag + store_dive_data3b: btfss event_gas_change ; did a gas change occur? bra store_dive_data3c ; NO IFDEF _ccr_pscr - movf active_dil,W ; YES - store active diluent (default, may be overwritten soon) + movf active_dil,W ; YES - get active diluent by default btfsc FLAG_oc_mode ; - in OC mode? - movf active_gas,W ; YES - get active gas + movf active_gas,W ; YES - replace by active gas btfsc bailout_mode ; - in bailout? ENDIF - movf active_gas,W ; YES - get active OC = bailout gas + movf active_gas,W ; YES - get active OC (bailout) gas rcall ghostwrite_byte_profile ; - store it bcf event_gas_change ; - clear event flag + store_dive_data3c: IFDEF _ccr_pscr btfss event_SP_change ; did a setpoint change occur? @@ -239,6 +247,7 @@ rcall ghostwrite_byte_profile ; - store it bcf event_SP_change ; - clear event flag ENDIF + store_dive_data3d: IFDEF _ccr_pscr btfss event_bailout ; did a gas change due to bailout occur? @@ -249,72 +258,84 @@ movff char_I_He_ratio,WREG ; - get He ratio of bailout gas ELSE clrf WREG ; - He ratio is zero - ENDIF + ENDIF ; helium rcall ghostwrite_byte_profile ; - store it bcf event_bailout ; - clear event flag ENDIF ; _ccr_pscr + store_dive_data4: -; Store extended information + ; Store extended information + decfsz divisor_temperature,F ; time to store a temperature sample ? - bra store_extended1 ; NO - skip + bra store_dive_data4a ; NO - skip rcall store_dive_temperature ; YES - store data -store_extended1: +store_dive_data4a: + btfsc divisor_temperature,7 ; did the timer under-run? + clrf divisor_temperature ; YES - reset timer + decfsz divisor_deco,F ; time to store the current deco data? - bra store_extended2 ; NO - skip + bra store_dive_data4b ; NO - skip rcall store_dive_decodata ; YES - store data -store_extended2: +store_dive_data4b: + btfsc divisor_deco,7 ; did the timer under-run? + clrf divisor_deco ; YES - reset timer + decfsz divisor_supersat,F ; time to store the current supersaturation ? - bra store_extended3 ; NO - skip + bra store_dive_data4c ; NO - skip rcall store_dive_supersat ; YES - store data -store_extended3: +store_dive_data4c: + btfsc divisor_supersat,7 ; did the timer under-run? + clrf divisor_supersat ; YES - reset timer + IFDEF _external_sensor decfsz divisor_ppo2_sensors,F ; decrement divisor, did it became 0 ? - bra store_extended4 ; NO - skip + bra store_dive_data4d ; NO - skip rcall store_dive_ppO2_sensors ; YES - store data - ENDIF -store_extended4: - decfsz divisor_decoplan,F ; decrement divisor, did it became 0 ? - bra store_extended5 ; NO - skip - rcall store_dive_decoplan ; YES - store data -store_extended5: - decfsz divisor_cns,F ; decrement divisor, did it became 0 ? - bra store_extended6 ; NO - skip - rcall store_dive_cns ; YES - store data -store_extended6: - decfsz divisor_tank,F ; decrement divisor, did it became 0 ? - bra store_extended7 ; NO - skip - rcall store_dive_tank ; YES - store data -store_extended7: - -; 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 - clrf divisor_deco - - btfsc divisor_supersat,7 - clrf divisor_supersat - - IFDEF _external_sensor - btfsc divisor_ppo2_sensors,7 - clrf divisor_ppo2_sensors +store_dive_data4d: + btfsc divisor_ppo2_sensors,7 ; did the timer under-run? + clrf divisor_ppo2_sensors ; YES - reset timer ENDIF - btfsc divisor_decoplan,7 - clrf divisor_decoplan + decfsz divisor_decoplan,F ; decrement divisor, did it became 0 ? + bra store_dive_data4e ; NO - skip + rcall store_dive_decoplan ; YES - store data +store_dive_data4e: + btfsc divisor_decoplan,7 ; did the timer under-run? + clrf divisor_decoplan ; YES - reset timer - btfsc divisor_cns,7 - clrf divisor_cns + decfsz divisor_cns,F ; decrement divisor, did it became 0 ? + bra store_dive_data4f ; NO - skip + rcall store_dive_cns ; YES - store data +store_dive_data4f: + btfsc divisor_cns,7 ; did the timer under-run? + clrf divisor_cns ; YES - reset timer - btfsc divisor_tank,7 - clrf divisor_tank + IFDEF _rx_functions + decfsz divisor_tank,F ; decrement divisor, did it became 0 ? + bra store_dive_data4g ; NO - skip + rcall store_dive_tank ; YES - store data +store_dive_data4g: + btfsc divisor_tank,7 ; did the timer under-run? + clrf divisor_tank ; YES - reset timer + ENDIF store_dive_data5: bcf event_occured ; clear the global event flag clrf event_byte1 ; reset event byte 1 clrf event_byte2 ; reset event byte 2 - return ; done (sample with all informations written to external flash) + return ; done (sample with all information written to external flash) + + + IFDEF _rx_functions +store_dive_tank: + movff int_O_tank_pressure+0,WREG ; get tank pressure, low byte + rcall ghostwrite_byte_profile ; store it + movff int_O_tank_pressure+1,WREG ; get tank pressure, high byte + rcall ghostwrite_byte_profile ; store it + movlw div_tank ; get sampling rate + movwf divisor_tank ; reload timer + return + ENDIF store_dive_cns: movff int_O_CNS_current+0,WREG ; get current CNS, low byte @@ -323,14 +344,8 @@ bcf WREG,int_warning_flag ; clear warning flag bcf WREG,int_attention_flag ; clear attention flag rcall ghostwrite_byte_profile ; store it - movlw div_cns - movwf divisor_cns ; reload divisor from CF - return - -store_dive_tank: - ; OSTC TR tank pressure logging - movlw div_tank - movwf divisor_tank ; reload divisor from CF + movlw div_cns ; get sampling rate + movwf divisor_cns ; reload timer return store_dive_decoplan: @@ -343,14 +358,12 @@ rcall ghostwrite_byte_profile ; store it decfsz lo,F ; decrement loop counter, became zero? bra store_dive_decoplan_loop ; NO - loop - movlw div_decoplan ; YES - get divisor for deco plan recording + movlw div_decoplan ; YES - get sampling rate movwf divisor_decoplan ; - reload timer return ; - done -;============================================================================= IFDEF _external_sensor - store_dive_ppO2_sensors: movff sensor1_ppO2,WREG ; get sensor 1 ppO2 (in 0.01 bar steps) rcall ghostwrite_byte_profile ; store it @@ -376,18 +389,16 @@ movf hi,W ; in 0.1 mV steps, high byte rcall ghostwrite_byte_profile ; store it - movlw div_ppo2_sensors + movlw div_ppo2_sensors ; get sampling rate movwf divisor_ppo2_sensors ; reload timer return - ENDIF -;============================================================================= store_dive_supersat: movff int_O_lead_supersat+0,WREG ; get leading tissue's supersaturation (value is limited to 255, only lower byte is used for the value) rcall ghostwrite_byte_profile ; store it - movlw div_gf + movlw div_gf ; get sampling rate movwf divisor_supersat ; reload timer return @@ -409,7 +420,7 @@ movff char_O_deco_time,WREG ; get time of the first stop in minutes rcall ghostwrite_byte_profile ; store it store_dive_decodata_common: - movlw div_deco + movlw div_deco ; get sampling rate movwf divisor_deco ; reload timer return @@ -419,7 +430,7 @@ rcall ghostwrite_byte_profile ; store it movf hi,W ; get high byte rcall ghostwrite_byte_profile ; store it - movlw div_temperature + movlw div_temperature ; get sampling rate movwf divisor_temperature ; reload timer return @@ -830,7 +841,7 @@ rcall ghostwrite_byte_header ; store data ; store deco distance - movff char_I_deco_distance,WREG ; get assumed distance to shown stop + clrf WREG ; assumed deco distance - disposed, hard-coded to zero rcall ghostwrite_byte_header ; store data IFDEF _external_sensor @@ -990,10 +1001,10 @@ movlw 0xFA rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - ; Keep room for dive length ext_flash_dive_counter:3 (Stored at the end of the dive) + ; Keep room for dive length ext_flash_dive_counter:3 (stored at the end of the dive) ; Writing 0xFF three times here is mandatory ; - 0xFF can be overwritten after the dive - ; - ghostwrite_byte_profile takes care of 4kB Page switching + ; - ghostwrite_byte_profile takes care of 4kB page switching ; - fixes an issue when we are at exactly 0xXXX000 here... movlw 0xFF @@ -1003,65 +1014,72 @@ movlw 0xFF call write_byte_ext_flash_plus_nocnt ; WREG -> profile in ext. flash (No ext_flash_dive_counter:3 increase) - movf sampling_rate,W ; get sampling rate - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + ; store sizes and sampling rates of recording datasets - movlw .7 ; number of divisors + movf sampling_rate,W ; get general sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw .0 ; type - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw infolength_temperature - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw div_temperature ; divisor temperature + movlw .7 ; get number of additional datasets rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw .1 ; Type + movlw .0 ; type: temperature rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw infolength_deco + movlw infolength_temperature ; get size of recording data rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw div_deco ; divisor deco data + movlw div_temperature ; get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw .2 ; type + movlw .1 ; type: +++ + rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movlw infolength_deco ; get size of recording data + rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movlw div_deco ; get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw infolength_gf + + movlw .2 ; type: saturation rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw div_gf ; divisor gf + movlw infolength_gf ; get size of recording data + rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movlw div_gf ; get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw .3 ; type + movlw .3 ; type: ppO2 sensor data rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw infolength_ppo2_sensors + movlw infolength_ppo2_sensors ; get size of recording data rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw div_ppo2_sensors ; divisor ppO2 - btfss FLAG_ccr_mode ; =1: CCR mode (Fixed ppO2 or Sensor) active - movlw .0 ; no ppO2 data in OC mode + movlw .0 ; default to no ppO2 data + btfsc FLAG_ccr_mode ; in CCR mode? + movlw div_ppo2_sensors ; YES - get sampling rate + btfsc FLAG_pscr_mode ; in pSCR mode? + movlw div_ppo2_sensors ; YES - get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw .4 ; type + movlw .4 ; type: deco plan (stop times) rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw infolength_decoplan + movlw infolength_decoplan ; get size of recording data rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw div_decoplan ; divisor debug + movlw div_decoplan ; get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw .5 ; Type + movlw .5 ; type: CNS rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw infolength_cns + movlw infolength_cns ; get size of recording data rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw div_cns ; divisor CNS + movlw div_cns ; get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw .6 ; Type + movlw .6 ; type: tank pressure + rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash + movlw infolength_tank ; get size of recording data rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw infolength_tank - rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash - movlw div_tank ; divisor tank + movlw .0 ; default to no tank pressure data + btfsc tr_functions_activated ; TR functions activated? + movlw div_tank ; YES - get sampling rate rcall ghostwrite_byte_profile ; WREG -> profile in ext. flash return + divemode_store_statistics: ; store/update statistics for this unit call vault_decodata_into_eeprom ; update deco data call do_logoffset_common_read ; read current logbook offset into mpr
--- a/src/hwos.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/hwos.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File hwos.asm combined next generation V3.03.4 +; File hwos.asm combined next generation V3.03.7 ; ; Definition of the hwOS dive computer platform. ; @@ -43,10 +43,10 @@ ;---- Flags - Hardware Descriptors HW_descriptor res 1 ; OSTC - model descriptor (cleared & rebuilt in restart) HW_variants res 1 ; OSTC - model variants (NOT cleared in restart) -HW_variants2 res 1 ; OSTC - model variants (NOT cleared in restart) - + ;---- Flags - Hardware States -HW_flags_state res 1 ; hardware - states +HW_flags_state1 res 1 ; hardware - states 1 +HW_flags_state2 res 1 ; hardware - states 2 ;--- Flags - Operating System OS_flags_persist res 1 ; system - persistent settings (NOT cleared in restart) @@ -100,12 +100,12 @@ ; 32 byte tmp data placed by C compiler ; 20 byte variables placed by math library ; == -; 81 byte used, 15 byte free (96 byte total available) +; 80 byte used, 16 byte free (96 byte total available) global HW_descriptor global HW_variants - global HW_variants2 - global HW_flags_state + global HW_flags_state1 + global HW_flags_state2 global OS_flags_persist global OS_flags_ISR1 global OS_flags_ISR2 @@ -198,7 +198,7 @@ ; movlw b'00000000' ; init port clrf PORTD - movlw b'00100000' ; 1= input, RE0 -> NPOWER_BLE, RE1 -> Power_IR, RE2 -> CS_MCP, RE3 -> LED_blue, RE4 -> power_sw1, RE5 -> leave as input + movlw b'00100000' ; 1= input, RE0 -> not_Power_BLE, RE1 -> Power_IR, RE2 -> CS_MCP, RE3 -> LED_blue, RE4 -> power_sw1, RE5 -> leave as input movwf TRISE movlw b'00010001' ; init port movwf PORTE @@ -208,7 +208,7 @@ ; movlw b'00000000' ; init port clrf PORTF - movlw b'00001110' ; 1= input, <7:6> not implemented, RG0 -> TX3_PIEZO_CFG, RG2 -> RX2, RG3 -> AN17_RSSI, RG4 -> SOSC_OUT, RG5 -> /RESET + movlw b'00001110' ; 1= input, <7:6> not implemented, RG0 -> TX3_PIEZO_CFG, , RG1 -> TX2, RG2 -> RX2, RG3 -> AN17_RSSI, RG4 -> SOSC_OUT, RG5 -> /RESET movwf TRISG movlw b'00000001' ; init port movwf PORTG @@ -315,8 +315,8 @@ movwf SSP1CON1 ; movlw b'00000000' clrf SSP1CON2 - movlw 0x27 - movwf SSP1ADD ; 100kHz @ 16MHz Fosc + movlw 0x9C + movwf SSP1ADD ; 100kHz @ 64MHz Fosc ; PWM Module(s) @@ -325,7 +325,7 @@ movwf CCP1CON movlw b'00000001' movwf PSTR1CON ; pulse steering disabled - movlw d'255' + movlw d'254' movwf PR2 ; period ; 255 is max brightness (300 mW) clrf CCPR1L ; duty cycle
--- a/src/hwos.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/hwos.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File hwos.inc combined next generation V3.03.4 +; File hwos.inc combined next generation V3.04.3 ; ; OSTC Platform Definitions ; @@ -35,7 +35,8 @@ ; Logo Address Vectors #DEFINE hw_logo_block 0x01E000 ; color image data for heinrichsweikamp logo -#DEFINE usb_ble_logo_block 0x01EEDE ; color image data for USB or BLE logo +#DEFINE usb_ble_logo_1 0x01EEDE ; color image data for USB or BLE logo +#DEFINE usb_ble_logo_2 0x01EA04 ; color image data for USB or BLE logo, "+" bootloader ;-----------------------------EEPROM DATA ------------------------------------ @@ -71,7 +72,7 @@ #DEFINE index_decoplan .8 ; deco plan #DEFINE index_ceiling_GF_tissue .9 ; ceiling, current GF and tissues #DEFINE index_CNS .10 ; CNS values -#DEFINE index_ppo2_ead_end_cns .11 ; ppO2, END/EAD and CNS +#DEFINE index_ppo2_ead_end_cns .11 ; ppO2, END/EAD and CNS or gas density #DEFINE index_gf_factors .12 ; GF factors #DEFINE index_clock_batt_surfpress .13 ; clock, battery and surface pressure #DEFINE index_cv_dm_max .13 ; highest index in use in dive mode custom view @@ -112,7 +113,7 @@ ; External O2 cell input Parameters -#DEFINE min_mv .80 ; = 8 mV +#DEFINE min_mv .70 ; = 7 mV #DEFINE max_mv .2500 ; = 250 mV #DEFINE ignore_mv .3500 ; = 350 mV (to suppress ghost readings for long, open cables) @@ -129,7 +130,7 @@ #DEFINE div_ppo2_sensors .2 ; x sampling rate [s] #DEFINE div_decoplan .12 ; x sampling rate [s] #DEFINE div_cns .12 ; x sampling rate [s] -#DEFINE div_tank .0 ; x sampling rate [s] +#DEFINE div_tank .12 ; x sampling rate [s] ; Profile Recording Data - Attention: Information Lengths must be < 16 ! @@ -139,14 +140,15 @@ #DEFINE infolength_ppo2_sensors .9 ; [byte] #DEFINE infolength_decoplan .15 ; [byte] #DEFINE infolength_cns .2 ; [byte] -#DEFINE infolength_tank .0 ; [byte] +#DEFINE infolength_tank .2 ; [byte] ; RX Functions -#DEFINE rx_packet_overdue_timeout .60 ; [seconds] +#DEFINE rx_packet_overdue_timeout .120 ; [seconds] timeout for pressure measurements becomming declared as outdated (max. 255) #DEFINE max_pres_diff_min .5 ; [bar] minimum selectable pressure difference for ind.double mode #DEFINE max_pres_diff_max .50 ; [bar] maximum selectable pressure difference for ind.double mode + IFDEF _ccr_pscr #DEFINE tr_pres_options .15 ; number of options for pressure measurement source / with diluents ELSE @@ -182,7 +184,7 @@ ; other Timeouts #DEFINE simulator_timeout .15 ; [s] #DEFINE apnoe_timeout .15 ; [min] - +#DEFINE deep_sleep_10mins .144 ; [x 10mins] (24h in this example) ; Surface Mode Thresholds and Limits #DEFINE high_altitude_threshold .880 ; [mbar] ambient pressure at which to switch into high altitude mode @@ -196,6 +198,7 @@ #DEFINE dive_threshold_high_alt_start .325 ; [mbar] relative pressure for high altitude start-of-dive (equals depth in cm) #DEFINE dive_threshold_high_alt_end .75 ; [mbar] relative pressure for high altitude end-of-dive (equals depth in cm) #DEFINE ostc_depth_max .120 ; [m] maximum allowed operational depth for OSTC 2, 3, cR, TR, Plus & Sport +#DEFINE deco_region_distance .2 ; [m] distance below first stop for the deco region to begin ; Dive Mode Margins @@ -213,16 +216,18 @@ #DEFINE ppo2_warning_loop_highest .60 ; [cbar] maximum value for minimum ppO2 on loop #DEFINE ppo2_warning_high_lowest .120 ; [cbar] minimum value for maximum ppO2 in none-deco phase +#DEFINE ppo2_warning_deco_lowest .120 ; [cbar] minimum value for maximum ppO2 in deco phase + #DEFINE ppo2_warning_high_default .140 ; [cbar] default value for maximum ppO2 in none-deco phase -#DEFINE ppo2_warning_high_highest .160 ; [cbar] maximum value for maximum ppO2 in none-deco phase - -#DEFINE ppo2_warning_deco_lowest .120 ; [cbar] minimum value for maximum ppO2 in deco phase #DEFINE ppo2_warning_deco_default .160 ; [cbar] default value for maximum ppO2 in deco phase + + IFDEF _high_ppO2_max +#DEFINE ppo2_warning_high_highest .200 ; [cbar] maximum value for maximum ppO2 in none-deco phase +#DEFINE ppo2_warning_deco_highest .200 ; [cbar] maximum value for maximum ppO2 in deco phase + ELSE +#DEFINE ppo2_warning_high_highest .160 ; [cbar] maximum value for maximum ppO2 in none-deco phase #DEFINE ppo2_warning_deco_highest .160 ; [cbar] maximum value for maximum ppO2 in deco phase - - -; Deco-Model Parameters -#DEFINE deco_distance .0 ; [dm] ex .10 + ENDIF ; Color-Code Parameters for the Dive Mode @@ -235,7 +240,7 @@ #DEFINE simulator_startdepth .200 ; [mbar] initial depth (relative pressure) when entering simulator mode #DEFINE simulator_descent_threshold .50 ; [mbar] remaining distance to target pressure when to slow down descent #DEFINE simulator_ascent_threshold .50 ; [mbar] remaining distance to target pressure when to slow down ascent -#DEFINE simulator_descent_rate .4 ; [mbar/0.125 sec] normal sescent speed, 4 equals 19 m/min +#DEFINE simulator_descent_rate .5 ; [mbar/0.125 sec] normal descent speed, 5 equals 24 m/min #DEFINE simulator_ascent_rate .2 ; [mbar/0.125 sec] normal ascent speed, 2 equals 9 m/min @@ -246,7 +251,8 @@ #DEFINE aa_15v_high .1550 ; [mV] Energizer 1.5 V E2 AA - highest possible voltage, value must be lower than value of lithium_36v_low! #DEFINE aa_15v_low .1100 ; [mV] Energizer 1.5 V E2 AA - lowest possible voltage, according to Energizer data sheet EBC-4201R, page 2 #DEFINE battery_show_level .30 ; [%] threshold when to show battery level -#DEFINE color_code_battery_low .30 ; [%] threshold for battery level color coding, also acts as threshold for setting display brightness level to ECO when in dive mode +#DEFINE battery_warn_level_36 .15 ; [%] threshold for 3.6 V battery warning, also acts as threshold for setting display brightness level to ECO when in dive mode +#DEFINE battery_warn_level_15 .25 ; [%] threshold for 1.5 V battery warning, also acts as threshold for setting display brightness level to ECO when in dive modebattery warning level, also acts as threshold for setting display brightness level to ECO when in dive mode ; 3.6 Volt Battery Sensing Data Points at 70 mA Load @@ -255,12 +261,14 @@ #DEFINE lithium_36v_25 .2600 ; [mV] #DEFINE lithium_36v_10 .2500 ; [mV] + ; Capacity for 2.4 Ah Saft LS14500 and 0.8 Ah Panasonic UR14500P ; battery_gauge: 6 is nAs ; devide through 65536 ; a) devide through 364 -> result is in percent of a 2.4 Ah battery ; or b) devide through 121 -> result is in percent of a 0.8 Ah battery + ; internal Battery Gauging #DEFINE capacity_saft_internal .364 #DEFINE capacity_panasonic_internal .121 @@ -303,7 +311,7 @@ ; IR Link Timeout -#DEFINE ir_timeout_value .64 ; in multiples of 62.5 ms +#DEFINE ir_timeout_value .128 ; in multiples of 62.5 ms ; Setpoint Control @@ -352,7 +360,7 @@ #DEFINE DECO_COMPLETED_NORM .0 ; =1: read: calculation of a normal deco plan has completed #DEFINE DECO_COMPLETED_ALT .1 ; =1: read: calculation of an alternative deco plan has completed #DEFINE DECO_INITIALIZE .2 ; =1: write: initialize deco engine (to be done only once at the begin of every dive) -; .3 ; unused +#DEFINE DECO_CALCULATOR_MODE .3 ; =1: deco engone is run from the deco calculator #DEFINE DECO_BAILOUT_FLAG .4 ; =1: allow gas switches before first deco stop (used in bailout plans) #DEFINE DECO_ASCENT_FLAG .5 ; =1: figure in a delayed ascent (fTTS) ; DECO_MODE_LOOP_FLAG .6 ; =1: calculate simulated tissues in loop mode (CCR or pSCR) @@ -367,11 +375,11 @@ #DEFINE outside_warning .4 ; =1: currently outside the ZHL-16 model #DEFINE outside_warning_lock .5 ; =1: was outside the ZHL-16 model during the dive #DEFINE outside_attention .6 ; =1: currently near to the limits of the ZHL-16 model -#DEFINE stoptable_overflow .7 ; =1: more stops needed than can be stored +#DEFINE deco_plan_incomplete .7 ; =1: internal error: deco calculation incomplete ; Bit Flags for Communication with p2_deco.c - char_O_deco_info -#DEFINE deco_flag .0 ; =1: in deco mode, deco ppO2 levels permitted +#DEFINE deco_mode .0 ; =1: in deco mode, deco ppO2 levels permitted #DEFINE ind_double_switch .1 ; =1: switch to other tank advice active ; .2 ; --- unused #DEFINE deco_zone .3 ; =1: fTTS is <= TTS (not updated when in bailout mode) @@ -435,27 +443,35 @@ ; HW_descriptor,7 ; --- reserved ;---- Hardware - OSTC Model Variants (stored in access RAM, NOT cleared in restart) -#DEFINE screen_type HW_variants,0 ; =1: display 1, =0; display 0 -#DEFINE screen_type2 HW_variants,1 ; =1: display 2, =0: display 0 or 1 -#DEFINE compass_type HW_variants,2 ; =1: compass 1, =0: compass 0 -#DEFINE compass_type2 HW_variants,3 ; =1: compass 2, =0: compass 0 or 1 -#DEFINE analog_switches HW_variants,4 ; =1: analog switches available -#DEFINE battery_is_36v HW_variants,5 ; =1: a 3.6 Volt battery is detected -#DEFINE cc_active HW_variants,6 ; =1: constant current charging active (cR hardware only) -#DEFINE cv_active HW_variants,7 ; =1: constant voltage charging active (cR hardware only) - - #DEFINE compass_type3 HW_variants2,0 ; =1: compass 3, =0: compass 0, 1 or 2 +#DEFINE screen_type1 HW_variants,0 ; =1: display type 1, =0; display type 0 +#DEFINE screen_type2 HW_variants,1 ; =1: display type 2, =0: display type 0 or 1 +#DEFINE screen_type3 HW_variants,2 ; =1: display type 3, =0: display type 0 or 1 or 2 +#DEFINE compass_type1 HW_variants,3 ; =1: compass type 1, =0: compass type 0 +#DEFINE compass_type2 HW_variants,4 ; =1: compass type 2, =0: compass type 0 or 1 +#DEFINE compass_type3 HW_variants,5 ; =1: compass type 3, =0: compass type 0 or 1 or 2 +#DEFINE analog_switches HW_variants,6 ; =1: analog switches available +#DEFINE battery_is_36v HW_variants,7 ; =1: a 3.6 Volt battery is detected -;---- Hardware - States (stored in access RAM) -#DEFINE analog_sw1_pressed HW_flags_state,0 ; =1: analog switch 1 pressed -#DEFINE analog_sw2_pressed HW_flags_state,1 ; =1: analog switch 2 pressed -#DEFINE switch_left HW_flags_state,2 ; =1: left button was pressed -#DEFINE switch_right HW_flags_state,3 ; =1: right button was pressed -#DEFINE flip_screen HW_flags_state,4 ; =1: screen is shown 180 turned -#DEFINE adc_is_running HW_flags_state,5 ; =1: the ADC is in use -#DEFINE tft_is_dimming HW_flags_state,6 ; =1: the TFT is dimming, ignore light sensor -#DEFINE compass_enabled HW_flags_state,7 ; =1: the compass and accelerometer chip is active +;---- Hardware - States 1 (stored in access RAM, cleared on restart) +#DEFINE analog_sw1_pressed HW_flags_state1,0 ; =1: analog switch 1 pressed +#DEFINE analog_sw2_pressed HW_flags_state1,1 ; =1: analog switch 2 pressed +#DEFINE switch_left HW_flags_state1,2 ; =1: left button was pressed +#DEFINE switch_right HW_flags_state1,3 ; =1: right button was pressed +#DEFINE flip_screen HW_flags_state1,4 ; =1: screen is shown 180 turned +#DEFINE adc_is_running HW_flags_state1,5 ; =1: the ADC is in use +#DEFINE tft_is_dimming HW_flags_state1,6 ; =1: the TFT is dimming, ignore light sensor +#DEFINE compass_enabled HW_flags_state1,7 ; =1: the compass and accelerometer chip is active + +;---- Hardware - States 2 (stored in access RAM, NOT cleared on restart) +#DEFINE cc_active HW_flags_state2,0 ; =1: constant current charging active (cR hardware only) +#DEFINE cv_active HW_flags_state2,1 ; =1: constant voltage charging active (cR hardware only) +; HW_flags_state2,2 ; --- unused +; HW_flags_state2,3 ; --- unused +; HW_flags_state2,4 ; --- unused +; HW_flags_state2,5 ; --- unused +; HW_flags_state2,6 ; --- unused +; HW_flags_state2,7 ; --- unused ;---- Operating System - persistent Settings (stored in access RAM, NOT cleared in restart) @@ -525,8 +541,8 @@ #DEFINE dive_turned DM_flags_state,2 ; =1: dive is turned #DEFINE cave_mode DM_flags_state,3 ; =1: in cave mode (gas needs by backtracking) #DEFINE depth_limit_exceeded DM_flags_state,4 ; =1: depth limit exceeded -; DM_flags_state,5 ; --- unused -; DM_flags_state,6 ; --- unused +#DEFINE deco_locked DM_flags_state,5 ; =1: in or has been in deco obligation during the dive +#DEFINE deco_region DM_flags_state,6 ; =1: in or has been in the deco stops region during the dive ; DM_flags_state,7 ; --- unused ;---- Dive Mode - O2 Sensors @@ -815,9 +831,9 @@ extern HW_descriptor extern HW_variants - extern HW_variants2 - extern HW_flags_state + extern HW_flags_state1 + extern HW_flags_state2 extern OS_flags_persist extern OS_flags_ISR1 @@ -1203,7 +1219,7 @@ ; ----------------------------------------------------------------------------- ; sleepmode sleepmode.asm (unused) (unused) ; surfmode surfmode.asm* (unused) (unused) -; simulator simulator.asm (unused) (unused) +; simulator divemode.asm divemode.asm simulator.asm ; divemode divemode.asm divemode.asm ghostwriter.asm ; logbook logbook.asm logbook.asm logbook.asm ; @@ -1265,7 +1281,7 @@ ;---- Menu Processor (8 byte) menustack res 8 ; menu stack -;---- Graphical Compass (17 byte) +;---- Graphical Compass (15 byte) xRD res 2 ; virtual compass ruler offset xRDr res 2 ; virtual compass ruler offset - right end xRD180 res 2 ; virtual compass ruler offset for the -180 marker @@ -1273,7 +1289,6 @@ xHI res 1 ; hi backup to prevent trashing xCM res 1 ; compass bearing relative position compass_heading_new res 2 ; corrected heading (in 1) : -180 .. 180 -compass_heading_old res 2 ; old heading (for smoother display) compass_heading_shown res 2 ; displayed heading compass_bearing res 2 ; displayed bearing @@ -1306,13 +1321,13 @@ rx_firmware_cur_minor res 1 ; TR module current firmware, minor ENDIF -;---- SAC Calculation on Pressure Readings 1 & 2 (20 byte) +;---- SAC Calculation on Pressure Readings 1 & 2 (22 byte) IFDEF _rx_functions pres_accu_1st res 4 ; accumulator for pressure drop in 1/160 bar | ATTENTION: do not pres_accu_2nd res 4 ; accumulator for pressure drop in 1/160 bar | change the -time_accu_1st res 1 ; accumulator for reading ages in seconds | position +time_accu_1st res 2 ; accumulator for reading ages in seconds | position gas__last_1st res 1 ; last gas assignment | of these -time_accu_2nd res 1 ; accumulator for reading ages in seconds | variables +time_accu_2nd res 2 ; accumulator for reading ages in seconds | variables gas__last_2nd res 1 ; last gas assignment | relative pres_last_1st res 2 ; last pressure reading pressure in 1/160 bar | to each pres_last_2nd res 2 ; last pressure reading pressure in 1/160 bar | other!
--- a/src/i2c.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/i2c.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File i2c.asm combined next generation V3.03.2 +; File i2c.asm combined next generation V3.03.5 ; ; I2C Interface ; @@ -28,8 +28,8 @@ ; ; Compass3 ; -------- -; LSM303C's Compass read address (8-Bit): 0x3D -; LSM303C's Compass write address (8-Bit): 0x3C +; LSM303C's Compass read address (8-Bit): 0x3D +; LSM303C's Compass write address (8-Bit): 0x3C ; LSM303C's Acceleration read address (8-Bit): 0x3B ; LSM303C's Acceleration write address (8-Bit): 0x3A ; @@ -91,12 +91,14 @@ global I2C_RX_accelerometer I2C_RX_accelerometer: - btfsc compass_type3 ; compass3 - bra I2C_RX_accelerometer_compass3 ; yes + btfsc compass_type3 ; compass3 ? + bra I2C_RX_accelerometer_compass3 ; YES btfsc compass_type2 ; compass2 ? bra I2C_RX_accelerometer_compass2 ; YES - btfsc compass_type ; compass1 ? + btfsc compass_type1 ; compass1 ? bra I2C_RX_accelerometer_compass1 ; YES + ;bra I2C_RX_accelerometer_compass0 ; NO - compass0 then + I2C_RX_accelerometer_compass0: bsf SSP1CON2,SEN ; start condition rcall WaitMSSP @@ -170,7 +172,7 @@ bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP movlw 0x3D ; address -I2C_RX_accelerometer_compass1_xx: ; compass2 and 3 continue here... +I2C_RX_accelerometer_compass1_xx: ; compass 2 and 3 continue here... rcall I2C_TX ; Non-flipped screen: @@ -258,19 +260,19 @@ bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP movlw 0x33 ; address - bra I2C_RX_accelerometer_compass1_xx + bra I2C_RX_accelerometer_compass1_xx I2C_RX_accelerometer_compass3: - bsf SSP1CON2,SEN ; Start condition + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x3A ; address - rcall I2C_TX - movlw 0x28 ; 0x28 (OUT_X_L_A) - rcall I2C_TX - bsf SSP1CON2,RSEN ; Repeated start condition (!) + movlw 0x3A ; address + rcall I2C_TX + movlw 0x28 ; 0x28 (OUT_X_L_A) + rcall I2C_TX + bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP - movlw 0x3B ; address - bra I2C_RX_accelerometer_compass1_xx + movlw 0x3B ; address + bra I2C_RX_accelerometer_compass1_xx I2C_OneByteRX: bsf SSP1CON2,RCEN ; enable receive mode @@ -284,12 +286,14 @@ global I2C_RX_compass I2C_RX_compass: - btfsc compass_type3 ; compass3 - bra I2C_RX_compass3 ; YES - btfsc compass_type2 ; compass2 ? + btfsc compass_type3 ; compass 3 ? + bra I2C_RX_compass3 ; YES + btfsc compass_type2 ; compass 2 ? bra I2C_RX_compass2 ; YES - btfsc compass_type ; compass1 ? + btfsc compass_type1 ; compass 1 ? bra I2C_RX_compass1 ; YES + ;bra I2C_RX_compass0 ; NO - compass 0 then + I2C_RX_compass0: bsf SSP1CON2,SEN ; start condition rcall WaitMSSP @@ -347,7 +351,7 @@ movff SSP1BUF,compass_DZ+0 ; data byte rcall I2C_OneByteRX ; get one byte movff SSP1BUF,compass_DX+1 ; data byte - bsf SSP1CON2, RCEN ; Enable receive mode + bsf SSP1CON2,RCEN ; enable receive mode rcall WaitMSSP movff SSP1BUF,compass_DX+0 ; data byte bsf SSP1CON2,PEN ; stop condition @@ -362,7 +366,7 @@ banksel common return -I2C_RX_compass1: ; new compass +I2C_RX_compass1: ; compass type 1 bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address @@ -414,7 +418,7 @@ bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ; ... and return -I2C_RX_compass2: ; newest compass +I2C_RX_compass2: ; compass type 2 bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address @@ -425,7 +429,7 @@ rcall WaitMSSP movlw 0x3D ; address rcall I2C_TX -I2C_RX_compass2_xx: ; compass 3 enters here +I2C_RX_compass2_xx: ; compass 3 joins in here ; rcall WaitMSSP rcall I2C_OneByteRX ; get one byte movff SSP1BUF,lo ; data byte @@ -462,20 +466,20 @@ ; rcall I2C_TwoBytesRX_div8_2 MOVII mpr,compass_DZ bsf SSP1CON2,PEN ; stop condition - bra WaitMSSP ;(And return) + bra WaitMSSP ; ...and return -I2C_RX_compass3: - bsf SSP1CON2,SEN ; Start condition +I2C_RX_compass3: ; compass type 3 + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x3C ; address - rcall I2C_TX - movlw 0xA8 ; 0x28 with auto-increment (MSB=1) - rcall I2C_TX - bsf SSP1CON2,RSEN ; Repeated start condition (!) + movlw 0x3C ; address + rcall I2C_TX + movlw 0xA8 ; 0x28 with auto-increment (MSB=1) + rcall I2C_TX + bsf SSP1CON2,RSEN ; repeated start condition (!) rcall WaitMSSP - movlw 0x3D ; address - rcall I2C_TX - bra I2C_RX_compass2_xx + movlw 0x3D ; address + rcall I2C_TX + bra I2C_RX_compass2_xx ; join with compass 2 code ENDIF ; _compass @@ -485,37 +489,38 @@ I2C_init_compass: bsf compass_enabled bcf compass_type2 - bcf compass_type3 - - ; probe compass 3 - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3A ; Address byte + Write bit - movwf SSP1BUF ; control byte - rcall WaitMSSP - btfss SSP1CON2,ACKSTAT ; ACK? - bsf compass_type3 ; ACK send. compass2 present - bsf SSP1CON2,PEN ; Stop condition - rcall WaitMSSP - - btfsc compass_type3 - bra I2C_init_compass3 ; Compass3 + bcf compass_type3 - ; check for compass2 + ; probe for compass 3 bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x32 ; address byte + Write bit + movlw 0x3A ; address byte + write bit movwf SSP1BUF ; control byte rcall WaitMSSP btfss SSP1CON2,ACKSTAT ; ACK? - bsf compass_type2 ; YES - ACK send, compass2 present - bsf SSP1CON2,PEN ; NO - stop condition + bsf compass_type3 ; YES - ACK was send, compass 3 present + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP + + btfsc compass_type3 ; compass 3 found? + bra I2C_init_compass3 ; YES - initialize compass 3 + + ; probe for compass 2 + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - btfsc compass_type2 - bra I2C_init_compass2 ; compass2 + movlw 0x32 ; address byte + write bit + movwf SSP1BUF ; control byte + rcall WaitMSSP + btfss SSP1CON2,ACKSTAT ; ACK? + bsf compass_type2 ; YES - ACK send, compass 2 present + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP - ; check for compass0 or compass1... - bsf compass_type ; set flag + btfsc compass_type2 ; compass 2 found? + bra I2C_init_compass2 ; YES - initialize compass 2 + + ; probe for compass 0 or 1 + bsf compass_type1 ; set flag bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address @@ -530,25 +535,26 @@ movlw 0x3D ; address rcall I2C_TX rcall I2C_OneByteRX ; get one byte - movlw 0x49 ; 0x49 = Compass1 + movlw 0x49 ; 0x49 = compass 1 cpfseq SSP1BUF - bcf compass_type ; clear flag + bcf compass_type1 ; clear flag bsf SSP1CON2,PEN ; stop condition rcall WaitMSSP - btfsc compass_type ; compass1 ? - bra I2C_init_compass1 ; YES - ; init compass0 + btfsc compass_type1 ; compass 1 found? + bra I2C_init_compass1 ; YES - initialize compass 1 + ;bra I2C_init_compass0 ; NO - must be compass 0 then + +I2C_init_compass0: + ; magnetic bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address rcall I2C_TX movlw 0x00 rcall I2C_TX -; movlw b'01101001' ; ConfigA: 3 Hz, 8 samples averaged, test mode (positive bias) movlw b'01101000' ; ConfigA: 3 Hz, 8 samples averaged rcall I2C_TX -I2C_init_compass_common: movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) swapf i2c_temp1,F comf i2c_temp1,F @@ -560,8 +566,48 @@ movlw b'00000000' ; continuous mode rcall I2C_TX bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP + + ; accelerometer + rcall I2C_sleep_accelerometer0 ; registers can only be changed in standby mode + + bsf SSP1CON2,SEN ; start condition + rcall WaitMSSP + movlw 0x38 ; address + rcall I2C_TX + movlw 0x0E ; XYZ_DATA_CFG + rcall I2C_TX + movlw b'00000000' ; high pass filter = 0, +/- 2 g range + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP + bsf SSP1CON2,SEN ; start condition + rcall WaitMSSP + movlw 0x38 ; address + rcall I2C_TX + movlw 0x2A ; CTRL_REG1 + rcall I2C_TX +; movlw b'00110000' ; CTRL_REG1: 160 ms data rate, standby mode + movlw b'00110100' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode + rcall I2C_TX + movlw b'00000010' ; CTRL_REG2: high-res in active mode + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP + + bsf SSP1CON2,SEN ; start condition + rcall WaitMSSP + movlw 0x38 ; address + rcall I2C_TX + movlw 0x2A ; CTRL_REG1 + rcall I2C_TX +; movlw b'00110001' ; CTRL_REG1: 160 ms data rate, active mode + movlw b'00110101' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ; ... and return + I2C_init_compass1: bsf SSP1CON2,SEN ; start condition rcall WaitMSSP @@ -581,7 +627,6 @@ rcall I2C_TX movlw b'01100100' ; CTRL5 HIGH res, 6.25 Hz rcall I2C_TX -init_compass1_common: movff opt_compass_gain,i2c_temp1 ; 0-7 (230 LSB/Gauss to 1370 LSB/Gauss) movlw b'01100000' ; CTRL6 Full scale (+/-12 Gauss -> 2730 LSB/Gauss) dcfsnz i2c_temp1,F ; = 1? @@ -602,57 +647,105 @@ movlw b'00000000' ; CTRL7 Continuous Mode rcall I2C_TX bsf SSP1CON2,PEN ; stop condition - bra WaitMSSP ; ... and return + bra WaitMSSP ; (and return), no I2C_init_accelerometer1 needed (inits with magnetic sensor) I2C_init_compass2: + ; magnetic + bsf SSP1CON2,SEN ; Start condition + rcall WaitMSSP + movlw 0x3C ; address + rcall I2C_TX + movlw 0xE0 ; 0x60 with auto-increment (MSB=1) + rcall I2C_TX + movlw b'10000000' ; CFG_REG_A_M (10Hz, Continuous) 0x60 0x00 + rcall I2C_TX + movlw b'00000011' ; CFG_REG_B_M (low-pass filter enabled) 0x61 (set pulse is released every 63 ODR) + rcall I2C_TX + movlw b'00010000' ; CFG_REG_C_M BDU=1 0x62 0x57 + rcall I2C_TX + bsf SSP1CON2,PEN ; Stop condition + rcall WaitMSSP + + ; accelerometer bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x3C ; address + movlw 0x32 ; address + rcall I2C_TX + movlw 0x9F ; 1F with auto-increment (MSB=1) rcall I2C_TX - movlw 0xE0 ; 0x60 with auto-increment (MSB=1) + movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) + rcall I2C_TX + movlw b'00100111' ; CTRL_REG1_A (10Hz, x,y,z = ON) rcall I2C_TX - movlw b'00000000' ; CFG_REG_A_M 0x60 (10 Hz, continuous) + movlw b'00000000' ; CTRL_REG2_A + rcall I2C_TX + movlw b'00000000' ; CTRL_REG3_A rcall I2C_TX - movlw b'00000000' ; CFG_REG_B_M 0x61 (low-pass filter off, set pulse is released every 63 ODR) + movlw b'00001000' ; CTRL_REG4_A (BDU=0, +/-2g, HR=1) rcall I2C_TX - movlw b'00000000' ; CFG_REG_C_M BDU=0 0x62 - rcall I2C_TX +; movlw b'00000000' ; CTRL_REG5_A +; rcall I2C_TX bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ; ... and return + I2C_init_compass3: - bsf SSP1CON2,SEN ; Start condition + ; magnetic + bsf SSP1CON2,SEN ; Start condition rcall WaitMSSP movlw 0x3C ; address - rcall I2C_TX + rcall I2C_TX movlw 0xA0 ; 0x20 with auto-increment (MSB=1) - rcall I2C_TX - movlw b'00010000' ; CTRL_REG1_M (10Hz) 0x20 - rcall I2C_TX + rcall I2C_TX + movlw b'01110000' ; CTRL_REG1_M (10Hz) 0x20 + rcall I2C_TX movlw b'01100000' ; CTRL_REG2_M (Full-scale: +/- 16gauss) 0x21 - rcall I2C_TX + rcall I2C_TX movlw b'01000000' ; CTRL_REG3_M (Continuous) 0x22 + rcall I2C_TX + movlw b'00000000' ; CTRL_REG4_M (Z in Low-power mode) 0x23 + rcall I2C_TX + movlw b'00000000' ; CTRL_REG5_M 0x24 + rcall I2C_TX + movlw b'00000000' ; CTRL_REG5_M 0x24 + rcall I2C_TX + bsf SSP1CON2,PEN ; Stop condition + rcall WaitMSSP + + ;accelerometer + bsf SSP1CON2,SEN ; Start condition + rcall WaitMSSP + movlw 0x3A ; address + rcall I2C_TX + movlw 0x20 rcall I2C_TX - movlw b'00000000' ; CTRL_REG4_M (Z in Low-power mode) 0x23 + movlw b'10010111' ; CTRL_REG1_A (100Hz, x,y,z = ON, BDU=OFF) 0x20 rcall I2C_TX - movlw b'00000000' ; CTRL_REG5_M 0x24 + movlw b'00000000' ; CTRL_REG2_A 0x21 + rcall I2C_TX + movlw b'00000000' ; CTRL_REG3_A 0x22 rcall I2C_TX - movlw b'00000000' ; CTRL_REG5_M 0x24 - rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ;(And return) - + movlw b'11001100' ; CTRL_REG4_A 0x23 + rcall I2C_TX + bsf SSP1CON2,PEN ; Stop condition + bra WaitMSSP ; (And return) + global I2C_sleep_compass I2C_sleep_compass: + btfss compass_enabled ; compass active? + return ; NO - return bcf compass_enabled - btfsc compass_type3 ; compass3? + btfsc compass_type3 ; compass 3 ? bra I2C_sleep_compass3 ; YES - btfsc compass_type2 ; compass2 ? + btfsc compass_type2 ; compass 2 ? bra I2C_sleep_compass2 ; YES - btfsc compass_type ; compass1 ? + btfsc compass_type1 ; compass 1 ? bra I2C_sleep_compass1 ; YES + ;bra I2C_sleep_compass0 ; NO - must be compass 0 then + I2C_sleep_compass0: + ; magnetic bsf SSP1CON2,SEN ; start condition rcall WaitMSSP movlw 0x3C ; address @@ -666,6 +759,19 @@ movlw b'00000010' ; idle mode rcall I2C_TX bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP + +I2C_sleep_accelerometer0: ;(needed) + ; accelerometer + bsf SSP1CON2,SEN ; start condition + rcall WaitMSSP + movlw 0x38 ; address + rcall I2C_TX + movlw 0x2A ; CTRL_REG1 + rcall I2C_TX + movlw b'00000000' ; standby mode + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ; ... and return I2C_sleep_compass1: @@ -688,7 +794,8 @@ movlw b'00000010' ; data for CTRL_REG7: magnetic sensor power-down mode rcall I2C_TX bsf SSP1CON2,PEN ; stop condition - bra WaitMSSP ; and return + bra WaitMSSP ; (And return) - no I2C_sleep_accelerometer1 required (sleeps with magnetic sensor) + I2C_sleep_compass2: ; magnetic @@ -707,21 +814,8 @@ movlw b'00000000' ; INT_CTRL_REG_M 0x63 rcall I2C_TX bsf SSP1CON2,PEN ; stop condition - bra WaitMSSP ; ... and return + rcall WaitMSSP -I2C_sleep_compass3: - ; magnetic - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3C ; address - rcall I2C_TX - movlw 0xA2 ; 0x22 with auto-increment (MSB=1) - movlw b'01000010' ; CTRL_REG3_M (Power-down) 0x22 - rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ;(And return) - -I2C_sleep_accelerometer2: ; accelerometer bsf SSP1CON2,SEN ; start condition rcall WaitMSSP @@ -736,19 +830,30 @@ bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ; ... and return -I2C_sleep_accelerometer3: - ; accelerometer - bsf SSP1CON2,SEN ; Start condition +I2C_sleep_compass3: + ; magnetic + bsf SSP1CON2,SEN ; start condition rcall WaitMSSP - movlw 0x3A ; address - rcall I2C_TX + movlw 0x3C ; address + rcall I2C_TX + movlw 0xA2 ; 0x22 with auto-increment (MSB=1) + rcall I2C_TX + movlw b'01000010' ; CTRL_REG3_M (power-down) 0x22 + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition + rcall WaitMSSP + + ; accelerometer + bsf SSP1CON2,SEN ; start condition + rcall WaitMSSP + movlw 0x3A ; address + rcall I2C_TX movlw 0x20 - rcall I2C_TX - movlw b'00000000' ; CTRL_REG1_A (100Hz, x,y,z = ON) 0x20 - rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) - + rcall I2C_TX + movlw b'00000000' ; CTRL_REG1_A (100Hz, x,y,z = OFF) 0x20 + rcall I2C_TX + bsf SSP1CON2,PEN ; stop condition + bra WaitMSSP ; ... and return WaitMSSP: decfsz i2c_temp1,F ; check for timeout during I2C action @@ -762,16 +867,16 @@ return I2C_WaitforACK: - btfss SSP1CON2,ACKSTAT ; checks for ACK bit from slave - return -I2CFail: - bsf active_reset_ostc_rx ; RESET RX circuitry (Which may be the cause for the hang up) - rcall I2CReset ; I2C Reset - bcf PIR1,SSP1IF - clrf i2c_temp1 - bsf i2c_error_flag ; set error flag - bcf active_reset_ostc_rx ; release RESET from RX circuitry - return + btfss SSP1CON2,ACKSTAT ; ACK received from slave? + return ; YES +I2CFail: ; NO + bsf active_reset_ostc_rx ; - reset RX circuitry (which may be the cause for the hang up) + rcall I2CReset ; - reset I2C + bcf PIR1,SSP1IF ; - + clrf i2c_temp1 ; - + bsf i2c_error_flag ; - set error flag + bcf active_reset_ostc_rx ; - release reset from RX circuitry + return ; - done I2CReset: ; something went wrong (slave holds SDA low?) clrf SSP1CON1 ; wake-up slave and reset entire module @@ -808,120 +913,11 @@ movwf SSP1CON1 movlw b'00000000' movwf SSP1CON2 - movlw 0x27 + movlw 0x9C movwf SSP1ADD return - global I2C_init_accelerometer -I2C_init_accelerometer: - btfsc compass_type3 ; compass3? - bra I2C_init_accelerometer3 ; YES - - btfsc compass_type2 ; compass2 ? - bra I2C_init_accelerometer2 ; YES - - btfsc compass_type ; compass1 ? - return ; YES - ignore - - rcall I2C_sleep_accelerometer ; registers can only be changed in standby mode - - bsf SSP1CON2,SEN ; start condition - rcall WaitMSSP - movlw 0x38 ; address - rcall I2C_TX - movlw 0x0E ; XYZ_DATA_CFG - rcall I2C_TX - movlw b'00000000' ; high pass filter = 0, +/- 2g range - rcall I2C_TX - bsf SSP1CON2,PEN ; stop condition - rcall WaitMSSP - - bsf SSP1CON2,SEN ; start condition - rcall WaitMSSP - movlw 0x38 ; address - rcall I2C_TX - movlw 0x2A ; CTRL_REG1 - rcall I2C_TX -; movlw b'00110000' ; CTRL_REG1: 160 ms data rate, standby mode - movlw b'00110100' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode - rcall I2C_TX - movlw b'00000010' ; CTRL_REG2: high-res in active mode - rcall I2C_TX - bsf SSP1CON2,PEN ; stop condition - rcall WaitMSSP - - bsf SSP1CON2,SEN ; start condition - rcall WaitMSSP - movlw 0x38 ; address - rcall I2C_TX - movlw 0x2A ; CTRL_REG1 - rcall I2C_TX -; movlw b'00110001' ; CTRL_REG1: 160 ms data rate, active mode - movlw b'00110101' ; CTRL_REG1: 160 ms data rate, standby mode, reduced noise mode, active Mode - rcall I2C_TX - bsf SSP1CON2,PEN ; stop condition - bra WaitMSSP ; ... and return - -I2C_init_accelerometer2: - bsf SSP1CON2,SEN ; start condition - rcall WaitMSSP - movlw 0x32 ; address - rcall I2C_TX - movlw 0x9F ; 1F with auto-increment (MSB=1) - rcall I2C_TX - movlw b'00000000' ; TEMP_CFG_REG_A (Temp sensor off) - rcall I2C_TX - movlw b'01010111' ; CTRL_REG1_A (100Hz, x,y,z = ON) - rcall I2C_TX - movlw b'00000000' ; CTRL_REG2_A - rcall I2C_TX -; movlw b'00000000' ; CTRL_REG3_A -; rcall I2C_TX -; movlw b'00000000' ; CTRL_REG4_A (BDU=0, +/-2g, -; rcall I2C_TX -; movlw b'00000000' ; CTRL_REG5_A -; rcall I2C_TX - bsf SSP1CON2,PEN ; stop condition - bra WaitMSSP ; ... and return - -I2C_init_accelerometer3: - bsf SSP1CON2,SEN ; Start condition - rcall WaitMSSP - movlw 0x3A ; address - rcall I2C_TX - movlw 0x20 - rcall I2C_TX - movlw b'00110111' ; CTRL_REG1_A (100Hz, x,y,z = ON) 0x20 - rcall I2C_TX - movlw b'00000000' ; CTRL_REG2_A 0x21 - rcall I2C_TX - movlw b'00000000' ; CTRL_REG3_A 0x22 - rcall I2C_TX - bsf SSP1CON2,PEN ; Stop condition - bra WaitMSSP ; (And return) - - - global I2C_sleep_accelerometer -I2C_sleep_accelerometer: - btfsc compass_type3 ; Compass3 - bra I2C_sleep_accelerometer3 ; YES - btfsc compass_type2 ; Compass2 - bra I2C_sleep_accelerometer2 ; YES - btfsc compass_type ; compass1? - return ; YES - ignore - - bsf SSP1CON2,SEN ; start condition - rcall WaitMSSP - movlw 0x38 ; address - rcall I2C_TX - movlw 0x2A ; CTRL_REG1 - rcall I2C_TX - movlw b'00000000' ; standby mode - rcall I2C_TX - bsf SSP1CON2,PEN ; stop condition - bra WaitMSSP ; ... and return - lt2942_init_again: clrf i2c_temp1 movlw 0x02 ; point to accumulated charge registers @@ -937,6 +933,7 @@ MOVII battery_accumulated_charge,sub_a ; and init again... + global lt2942_init lt2942_init: ; setup control register B clrf i2c_temp1 @@ -949,6 +946,7 @@ bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ; ... and return + global lt2942_get_status lt2942_get_status: ; read status register bcf battery_gauge_available ; clear flag @@ -999,7 +997,7 @@ bsf SSP1CON2,ACKEN ; master acknowledge rcall WaitMSSP movff SSP1BUF,xA+1 ; store raw temperature, high byte - bsf SSP1CON2, RCEN ; enable receive mode + bsf SSP1CON2,RCEN ; enable receive mode rcall WaitMSSP movff SSP1BUF,xA+0 ; store raw temperature, low byte bsf SSP1CON2,PEN ; stop condition @@ -1075,6 +1073,9 @@ MOVII battery_capacity,xB call div16x16 ; xC = xA / xB with xA as remainder movff xC+0,batt_percent + movlw .100 ; max. value is 100 % + cpfslt batt_percent ; batt_percent < 100 % ? + movwf batt_percent ; NO - limit to 100 % return lt2942_set_to_zero_percent: @@ -1090,6 +1091,7 @@ bsf SSP1CON2,PEN ; stop condition bra WaitMSSP ; ... and return + global lt2942_charge_done lt2942_charge_done: ; reset accumulating registers to 0xFFFF clrf i2c_temp1 @@ -1122,7 +1124,7 @@ movwf SSP1BUF ; control byte rcall WaitMSSP rcall I2C_WaitforACK - bsf SSP1CON2, RCEN ; enable receive mode + bsf SSP1CON2,RCEN ; enable receive mode bra WaitMSSP ; ... and return @@ -1256,6 +1258,8 @@ bra WaitMSSP ; ... and return + IFDEF _rx_update + global I2C_update_OSTC_rx I2C_update_OSTC_rx: ; transfer 64 byte to RX co-processor ; setup for write @@ -1338,7 +1342,9 @@ retlw .0 ; NO - data transfered successfully retlw .255 ; YES - error in data transfer occurred - ENDIF + ENDIF ; _rx_update + + ENDIF ; _rx_functions ;=============================================================================
--- a/src/i2c.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/i2c.inc Thu Sep 19 12:01:29 2019 +0200 @@ -9,8 +9,6 @@ ; 2012-10-24 : [mH] Creation extern I2C_RX_accelerometer - extern I2C_init_accelerometer - extern I2C_sleep_accelerometer extern I2C_init_compass extern I2C_sleep_compass @@ -24,6 +22,9 @@ IFDEF _rx_functions extern I2C_probe_OSTC_rx ; set ostc_rx_present bit if present extern I2C_get_tankdata ; get the tank data + ENDIF + + IFDEF _rx_update extern I2C_update_OSTC_rx ; load new firmware into RX processor ENDIF
--- a/src/icons.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/icons.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File icons.asm combined next generation V3.0.1 +; File icons.asm combined next generation V3.04.3 ; ; Tables for all OSTC icons. ; @@ -19,14 +19,6 @@ global dive_warning2_block ; dive mode warning icon #include "../src/Icons/dive_warning2.inc" ; 45x39 pixels -;----------------------------------------------------------------------------- - - IFDEF _ostc_logo - - global ostc_logo_block ; OSTC logo -#include "../src/Icons/ostc_logo.inc" ; 220x61 pixels - - ENDIF ;-----------------------------------------------------------------------------
--- a/src/isr.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/isr.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File isr.asm combined next generation V3.03.4 +; File isr.asm combined next generation V3.03.7 ; ; INTERUPT subroutines ; @@ -40,7 +40,6 @@ ; initialize interrupt code banksel isr_backup ; default bank for all ISR code is bank ISR data rcall isr_registers_backup ; back-up registers - ; serve buttons btfsc PIR1,TMR1IF ; timer 1 interrupt (button hold-down timer)? rcall timer1int ; YES - reset timer @@ -55,6 +54,9 @@ rcall isr_uart2 ; YES - get a byte from the IR/S8 link btfsc PIR2,TMR3IF ; timer 3 interrupt? rcall isr_timer3 ; YES - check bytes received from IR/S8 link for being a valid telegram + ELSE + bcf PIR3,RC2IF ; Clear UART 2 interrupt? + bcf PIR2,TMR3IF ; Clear timer 3 interrupt? ENDIF ; serve pressure and temperature sensor @@ -151,6 +153,7 @@ ; Take a byte received on IR/S8 link and slot it into the RX buffer ; isr_uart2: + bcf PIR3,RC2IF ; Clear UART 2 interrupt flag banksel RCREG2 ; RC*2 is outside access RAM movff RCREG2,isr_lo ; copy received byte to isr_lo bcf RCSTA2,CREN ; clear receiver status @@ -239,10 +242,10 @@ movff ir_s8_buffer+.14,hud_battery_mv+1 btfsc trigger_S8_data_update ; last data already processed? - bra isr_timer3_reload ; NO - skip copying new results + bra isr_timer3_exit ; NO - skip copying new results (And not reload the timeout) bsf trigger_S8_data_update ; YES - set flag for new data available - ; - copy more data + ; - copy more data movff ir_s8_buffer+.4, s8_rawdata_sensor1+0 movff ir_s8_buffer+.5, s8_rawdata_sensor1+1 movff ir_s8_buffer+.6, s8_rawdata_sensor1+2 @@ -331,6 +334,13 @@ clrf sensor1_ppO2 ; ... clrf sensor2_ppO2 ; ... clrf sensor3_ppO2 ; ... + banksel s8_rawdata_sensor1 + CLRI s8_rawdata_sensor1 ; clear all sensor data (raw data) + clrf s8_rawdata_sensor1+2 + CLRI s8_rawdata_sensor2 ; clear all sensor data (raw data) + clrf s8_rawdata_sensor2+2 + CLRI s8_rawdata_sensor3 ; clear all sensor data (raw data) + clrf s8_rawdata_sensor3+2 banksel isr_backup ; back to ISR default bank bsf trigger_S8_data_update ; signal a data update @@ -426,7 +436,7 @@ isr_sensor_state2_3: ; reset state counter and set update flag clrf sensor_state_counter ; reset state counter - bsf trigger_pres_update ; signal a pressure update +; bsf trigger_pres_update ; signal a pressure update btfss reset_max_pressure ; shall clear the max pressure? bra isr_sensor_state2_3a ; NO - continue with checking for pressure change bcf reset_max_pressure ; YES - clear request flag @@ -520,23 +530,25 @@ isr_dimm_tft: ; adjust until max_CCPR1L = CCPR1L + btfsc screen_type3 ; screen type 3 ? + return ; YES - ignore, no dimming function with screen type 3 btfsc tft_is_dimming ; is the display dimming? return ; YES - ignore movf max_CCPR1L,W ; NO - proceed - cpfsgt CCPR1L ; CCPR1L > max_CCPR1L ? - bra isr_dimm_tft2 ; NO - dim up - decf CCPR1L,F ; YES - dim down - return ; - done + cpfsgt CCPR1L ; - CCPR1L > max_CCPR1L ? + bra isr_dimm_tft2 ; NO - dim up + decf CCPR1L,F ; YES - dim down + return ; - done isr_dimm_tft2: - movf max_CCPR1L,W - sublw ambient_light_min_eco + movf max_CCPR1L,W ; + sublw ambient_light_min_eco ; cpfsgt CCPR1L ; CCPR1L > max_CCPR1L - ambient_light_min_eco ? bra isr_dimm_tft3 ; NO - dim up slow - movlw .10 ; YES - dim up faster - addwf CCPR1L,F + movlw .10 ; YES - dim up faster (+10) + addwf CCPR1L,F ; - add to dimming value isr_dimm_tft3: - incf CCPR1L,F ; +1 - return ; done + incf CCPR1L,F ; - dim up (+1) + return ; - done ;=============================================================================
--- a/src/logbook.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/logbook.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File logbook.asm combined next generation V3.03.4 +; File logbook.asm combined next generation V3.03.5 ; ; Logbook ; @@ -101,8 +101,8 @@ ; Logbook Coordinates #DEFINE logbook_list_left .10 ; column of dive# in list -#DEFINE logbook_row_offset .28 ; distance between rows of list (needs to be <= 32) -#DEFINE logbook_row_number .6 ; amount of rows in the list +#DEFINE logbook_row_offset .27 ; distance between rows of list +#DEFINE logbook_row_number .7 ; amount of rows in the list ; Profile display #DEFINE profile_height_pixels .157 ; amount of pixels height for profile display @@ -236,7 +236,7 @@ ;============================================================================= TFT_logbook_cursor: - WIN_BOX_BLACK .0, .240-.16, logbook_list_left-.8, logbook_list_left-.1 ; top, bottom, left, right + WIN_BOX_BLACK .0, .239, logbook_list_left-.8, logbook_list_left-.1 ; top, bottom, left, right WIN_LEFT logbook_list_left-.8 ; set horizontal position WIN_FONT FT_SMALL ; select small font @@ -346,8 +346,9 @@ ; TFT_mask... WIN_LEFT logbook_list_left - WIN_TOP logbook_row_offset*logbook_row_number + WIN_TOP logbook_row_offset*(logbook_row_number+.0) STRCPY_TEXT_PRINT tNextLog ; "Next Page" + WIN_LEFT logbook_list_left WIN_TOP logbook_row_offset*(logbook_row_number+.1) STRCPY_TEXT_PRINT tExit ; "Exit" @@ -360,7 +361,7 @@ bcf logbook_page_not_empty ; obviously the current page is NOT empty - movlw d'7' ; set cursor to position 7... + movlw d'8' ; set cursor to position 7... btfsc keep_cursor_new_page ; ... if we came from the "new page" line movwf menu_pos_cur ; and set menu_pos_cur byte bcf keep_cursor_new_page @@ -1410,7 +1411,9 @@ movf logbook_divenumber,W ; log_compute_divenumber needs the list number call log_compute_divenumber ; compute dive number bsf leftbind - output_16_3 ; show dive number, but only last three digits + movlw .3 ; start with 3rd digit (i.e. suppress the thousands) + movwf ignore_digits + output_16dp .0 ; show dive number bcf leftbind PUTC ' ' ; display_listdive2:
--- a/src/math.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/math.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File math.asm combined next generation V3.03.2 +; File math.asm combined next generation V3.04.3 ; ; Math subroutines ; @@ -54,6 +54,18 @@ return ; YES - done + global addU16 ; ; sub_c:2 = sub_a:2 + sub_b:2 with USIGNED values + ; trashes WREG +addU16: + movf sub_a+0,W ; get 1st summand (low byte) to WREG + addwf sub_b+0,W ; add 2nd summand (low byte) and store result in WREG + movwf sub_c+0 ; copy result (low byte) to sub_c + movf sub_a+1,W ; get 1st summand (high byte) to WREG + addwfc sub_b+1,W ; add 2nd summand (high byte) and store result in WREG + movwf sub_c+1 ; copy result (high byte) to sub_c + return ; done + + global sub16 ; sub_c:2 = sub_a:2 - sub_b:2 with SIGNED values ; sets neg_flag if result is < 0 ; trashes WREG
--- a/src/math.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/math.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File math.inc combined next generation V3.03.2 +; File math.inc combined next generation V3.04.3 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -18,6 +18,9 @@ extern mult16 ; divA:2 = divA:2 * 2^WREG ; trashes WREG + extern addU16 ; sub_c:2 = sub_a:2 + sub_b:2 with USIGNED values + ; trashes WREG + extern sub16 ; sub_c:2 = sub_a:2 - sub_b:2 with SIGNED values ; sets neg_flag if result is < 0 ; trashes WREG @@ -26,7 +29,7 @@ ; sets neg_flag if result is < 0 ; trashes WREG - extern cmpU16 ; sub_a:2 - sub_b:2 with UNSIGNED values + extern cmpU16 ; trashed = sub_a:2 - sub_b:2 with UNSIGNED values ; sets neg_flag if result is < 0, but does not store result itself ; trashes WREG
--- a/src/mcp.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/mcp.asm Thu Sep 19 12:01:29 2019 +0200 @@ -24,7 +24,7 @@ bcf INTCON3,INT3IE ; disable INT3 bcf mcp_power ; request IR receiver off btfsc mcp_power ; off confirmed? - bra $-4 ; NO - loop waiting + bra $-6 ; NO - loop waiting return ; YES - done ENDIF
--- a/src/menu_tree.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/menu_tree.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File menu_tree.asm next combined generation V3.03.3 +; File menu_tree.asm next combined generation V3.04.3 ; ; OSTC Surface Menus ; @@ -116,12 +116,11 @@ bra do_ccr_menu_cR ENDIF - MENU_BEGIN tCCRSetup, .6 ; OSTC3 menu (and currently also the OSTC2 menu) + MENU_BEGIN tCCRSetup, .5 ; OSTC3 menu (and currently also the OSTC2 menu) MENU_OPTION tCCRMode, oCCRMode, 0 MENU_CALL tDiluentSetup, do_diluent_setup MENU_CALL tFixedSetpoints, do_fixed_setpoints - MENU_CALL tPSCRMenu, do_PSCR_menu - MENU_OPTION tCCmaxFracO2, oCCmaxFracO2, 0 + MENU_CALL tMore, do_ccr_menu_more MENU_CALL tBack, do_return_main_menu MENU_END @@ -129,13 +128,12 @@ IFDEF _external_sensor do_ccr_menu_cR: ; cR menu - MENU_BEGIN tCCRSetup, .7 + MENU_BEGIN tCCRSetup, .6 MENU_OPTION tCCRMode, oCCRMode, 0 MENU_CALL tCalibrateMenu, do_calibrate_menu MENU_CALL tDiluentSetup, do_diluent_setup MENU_CALL tFixedSetpoints, do_fixed_setpoints - MENU_CALL tPSCRMenu, do_PSCR_menu - MENU_OPTION tCCmaxFracO2, oCCmaxFracO2, 0 + MENU_CALL tMore, do_ccr_menu_more MENU_CALL tBack, do_return_main_menu MENU_END @@ -211,8 +209,10 @@ MENU_END -do_PSCR_menu: - MENU_BEGIN tPSCRMenu, .3 ; pSCR Menu +do_ccr_menu_more: + MENU_BEGIN tCCRSetup, .5 ; CCR/pSCR more menu + MENU_OPTION tCCmaxFracO2, oCCmaxFracO2, 0 + MENU_OPTION tDilppO2Check, oDilppO2Check, 0 MENU_OPTION tPSCR_O2_drop, oPSCR_drop, 0 MENU_OPTION tPSCR_lungratio, oPSCR_lungratio, 0 MENU_CALL tBack, do_return_ccr_menu @@ -355,7 +355,8 @@ ; Simulator Menus do_return_planner_menu: - call menu_processor_pop ; drop exit line and ... + call menu_processor_double_pop ; drop exit line and back to last line + bra do_planner_common_1 global do_return_demo_planner do_return_demo_planner: @@ -366,7 +367,7 @@ ; ensure correct simulator results after mode changes without prior excursion to surface mode call option_save_all - ; reset dive time/depth to default values + ; reset planning parameters to default values lfsr FSR0,odiveInterval call option_reset lfsr FSR0,obottomTime @@ -376,8 +377,15 @@ lfsr FSR0,oSimAGF call option_reset + IFDEF _gas_contingency + ; switch off gas contingency mode by default + clrf WREG + movff WREG,char_I_gas_contingency + ENDIF + do_planner_common: call restart_set_modes_and_flags ; initialize dive mode settings +do_planner_common_1: movff opt_dive_mode,WREG ; get dive mode: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR dcfsnz WREG,W ; subtract one, became zero? bra do_planner_common_ccr ; YES - use CCR version @@ -404,11 +412,20 @@ MENU_END do_planner_config: + IFDEF _gas_contingency + MENU_BEGIN tPlan, .4 + MENU_OPTION tSelectSetpoint, oSimSetpoint, 0 + MENU_OPTION tuseAGF, oSimAGF, 0 + MENU_OPTION tGasContingency, oGasContingency, 0 + MENU_CALL tBack, do_return_planner_menu + MENU_END + ELSE MENU_BEGIN tPlan, .3 MENU_OPTION tSelectSetpoint, oSimSetpoint, 0 MENU_OPTION tuseAGF, oSimAGF, 0 MENU_CALL tBack, do_return_planner_menu MENU_END + ENDIF ;============================================================================= @@ -513,7 +530,9 @@ ;============================================================================= ; Setup Menu - +do_return_settings_deeper: ; entry point for return from info menu 2 + call menu_processor_pop ; drop one more stack entry + do_return_settings: bcf imprint_time_date ; stop imprinting of current time & date call menu_processor_double_pop ; drop exit line and back to last line @@ -576,10 +595,10 @@ MENU_BEGIN tInfoMenu, .6 MENU_DYNAMIC info_menu_serial, 0 MENU_DYNAMIC info_menu_firmware, 0 + MENU_DYNAMIC info_menu_config, 0 MENU_DYNAMIC info_menu_battery_volts, 0 MENU_DYNAMIC info_menu_uptime, 0 - MENU_DYNAMIC info_menu_total_dives, 0 - MENU_CALL tBack, do_return_settings + MENU_CALL tMore, do_info_menu2 MENU_END IFDEF _rx_functions @@ -588,13 +607,20 @@ MENU_DYNAMIC info_menu_serial, 0 MENU_DYNAMIC info_menu_firmware, 0 MENU_DYNAMIC info_menu_firmware_rx, 0 - MENU_DYNAMIC info_menu_total_dives, 0 + MENU_DYNAMIC info_menu_config, 0 MENU_DYNAMIC info_menu_battery_volts, 0 MENU_DYNAMIC info_menu_uptime, 0 - MENU_CALL tBack, do_return_settings + MENU_CALL tMore, do_info_menu2 MENU_END ENDIF +do_info_menu2: ;same for all hardware versions + MENU_BEGIN tInfoMenu, .2 + MENU_DYNAMIC info_menu_total_dives, 0 + MENU_CALL tBack, do_return_settings_deeper + MENU_END + + IFDEF _rx_functions
--- a/src/option_table.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/option_table.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File option_table.asm combined next generation V3.03.3 +; File option_table.asm combined next generation V3.04.3 ; ; The Option Table ; @@ -119,6 +119,12 @@ extern char_I_ascent_speed, char_I_descent_speed, tMeterMinute extern char_I_gas_change_time extern char_I_max_pres_diff + extern char_I_gas_density_att, char_I_gas_density_warn + extern char_I_dil_ppO2_check + + IFDEF _gas_contingency + extern char_I_gas_contingency + ENDIF ; Option Table - Format: @@ -135,9 +141,6 @@ option_table_begin: ;============================================================================= ; Manage Deco Planer & Dive Parameters - OPTION_UINT8p10 odiveInterval, .0, .240, .0, tMinutes, volatile, opt_surface_interval ; transfer register used for deco calculator and simulator - OPTION_UINT8p2 obottomTime, .2, .60, .10, tMinutes, volatile, char_I_bottom_time ; transfer register used for deco calculator - OPTION_UINT8p3d obottomDepth, .12, .120, .21, tMeters, volatile, char_I_bottom_depth ; transfer register used for deco calculator and simulator OPTION_ENUM8 oDiveMode, .5, .0, tDvOC, .8, opt_dive_mode ; 0=OC, 1=CC, 2=Gauge, 3=Apnea, 4=PSCR OPTION_ENUM8 oDecoMode, .2, .1, tZHL16, .9, char_I_deco_model ; 0 = ZH-L16, 1 = ZH-L16-GF ; .10 ; in use, see below @@ -189,11 +192,11 @@ OPTION_UINT8 oGas4He, .0, gaslist_max_He, .0, tPercent, .47, opt_gas_He_ratio+3 OPTION_UINT8 oGas5O2, gaslist_min_o2, .100, .21, tPercent, .48, opt_gas_O2_ratio+4 ; O2 % of gas 5 OPTION_UINT8 oGas5He, .0, gaslist_max_He, .0, tPercent, .49, opt_gas_He_ratio+4 ; He % of gas 5 - OPTION_UINT8d oGas1Depth, .0, gaslist_max_change_depth, .66, tMeters, .50, opt_gas_change+0 ; change depth of gas 1 - OPTION_UINT8d oGas2Depth, .0, gaslist_max_change_depth, .66, tMeters, .51, opt_gas_change+1 - OPTION_UINT8d oGas3Depth, .0, gaslist_max_change_depth, .66, tMeters, .52, opt_gas_change+2 - OPTION_UINT8d oGas4Depth, .0, gaslist_max_change_depth, .66, tMeters, .53, opt_gas_change+3 - OPTION_UINT8d oGas5Depth, .0, gaslist_max_change_depth, .66, tMeters, .54, opt_gas_change+4 ; change depth of gas 5 + OPTION_UINT8d oGas1Depth, .0, gaslist_max_change_depth, .56, tMeters, .50, opt_gas_change+0 ; change depth of gas 1 + OPTION_UINT8d oGas2Depth, .0, gaslist_max_change_depth, .56, tMeters, .51, opt_gas_change+1 + OPTION_UINT8d oGas3Depth, .0, gaslist_max_change_depth, .56, tMeters, .52, opt_gas_change+2 + OPTION_UINT8d oGas4Depth, .0, gaslist_max_change_depth, .56, tMeters, .53, opt_gas_change+3 + OPTION_UINT8d oGas5Depth, .0, gaslist_max_change_depth, .56, tMeters, .54, opt_gas_change+4 ; change depth of gas 5 OPTION_UINT8 oDil1O2, gaslist_min_o2, .100, .21, tPercent, .55, opt_dil_O2_ratio+0 ; O2 % of diluent 1 OPTION_UINT8 oDil1He, .0, gaslist_max_He, .0, tPercent, .56, opt_dil_He_ratio+0 ; He % of diluent 1 OPTION_UINT8 oDil2O2, gaslist_min_o2, .100, .21, tPercent, .57, opt_dil_O2_ratio+1 @@ -267,11 +270,10 @@ OPTION_UINT8 oCCmaxFracO2, .80, .100, .90, tPercent, .183, char_I_CC_max_frac_O2 ; max. O2 % in Loop OPTION_UINT8 oSimSetpoint, .1, .5, .1, tblank, .184, opt_sim_setpoint_number ; setpoint to use for deco calculation OPTION_ENUM8 oCalcAscGas, calc_gas_options, .0, tNo, .185, opt_calc_asc_gasvolume ; calculate OC gas volume needs for ascent: no, yes, cave - OPTION_BOOL oSimAGF, .0, volatile, opt_sim_use_aGF ; use GF (no) or aGF (yes) for deco calculation OPTION_ENUM8 oAltMode, .4, .0, tAltModeFly, .186, char_I_altitude_wait ; no-fly time calculation for: 0=no-fly, 1=1000m, 2=2000m, 3=3000m OPTION_BOOL oEnable_IBCD, .1, .187, opt_enable_IBCD ; =1: IBCD warning activated OPTION_UINT8 oAscentSpeed, .5, .10, .10, tMeterMinute, .188, char_I_ascent_speed ; [meter/minute] ascent speed - OPTION_UINT8 oGasChangeTime, .0, .3, .1, tMinutes, .189, char_I_gas_change_time ; (extra) time at a stop to change the gas + OPTION_UINT8 oGasChangeTime, .0, .3, .0, tMinutes, .189, char_I_gas_change_time ; (extra) time at a stop to change the gas OPTION_UINT8p5 osatmult, .100, .140, .110, tPercent, .190, opt_sat_multiplier_non_gf ; saturation factor for NON-GF Mode OPTION_UINT8p5 odesatmult, .60, .100, .90, tPercent, .191, opt_desat_multiplier_non_gf ; desaturation factor for NON-GF Mode OPTION_UINT8 oTransID1_0, .0, .255, .0, notext, .192, opt_transmitter_id_1+0 ; ID of transmitter for gas 1 (LOW) @@ -309,16 +311,18 @@ OPTION_ENUM8 oTr2ndPres, tr_pres_options, .0, tTrPresNone, .224, opt_TR_2nd_pres ; TR functions - 2nd pressure assignment OPTION_ENUM8 oTrBailPres, tr_pres_options, .1, tTrPresNone, .225, opt_TR_Bail_pres ; TR functions - bailout pressure assignment OPTION_UINT8p5 oTrMaxDeltaPres, max_pres_diff_min,max_pres_diff_max,.5, tbar, .226, char_I_max_pres_diff ; TR functions - maximum delta pressure in independent double mode - OPTION_BOOL oRealGasFactorUse, .0, .227, opt_ZfactorUse ; =1: figure in compression factor Z when converting gas volume <-> gas pressure [future option, not used yet] - OPTION_UINT8p5 oRealGasFactorTemp, .0, .30, .15, tLogTunitC, .228, opt_ZfactorTemp ; temperature setpoint for compression factor Z [future option, not used yet] + ; .227 ; spare / unused + ; .228 ; spare / unused OPTION_ENUM8 o2ndDepthDisp, .2, .0, tMaxDepth, .229, opt_2ndDepthDisp ; =1: show average depth instead of max depth OPTION_UINT8d oMaxDepth, .5, ostc_depth_max, ostc_depth_max, tMeters, .230, opt_max_depth ; depth at which a warning will be given - OPTION_UINT8 oDescentSpeed, .5, .30, .10, tMeterMinute, .231, char_I_descent_speed ; descent speed for deco calculator [future option, not used yet] - OPTION_BOOL oStoreApnoeDive, .0, .232, opt_store_apnoe_dive ; =1: store dives in apnoe mode into logbook [future option, not used yet] + OPTION_UINT8 oDescentSpeed, .5, .30, .10, tMeterMinute, .231, char_I_descent_speed ; descent speed for deco calculator [future option, not used yet] + OPTION_BOOL oStoreApnoeDive, .0, .232, opt_store_apnoe_dive ; =1: store dives in apnoe mode into logbook OPTION_ENUM8 oTissueGraphics, tissue_graphics_options, .0, tTissuePresSat, .233, opt_tissue_graphics ; =0: show N2 and He pressures, =1: show pressures and saturations - OPTION_ENUM8 oLogOffsetStep, .4, .0, tLogOffStep1, volatile, opt_logoffset_step ; step size when adjusting the log offset OPTION_ENUM8 oLayout, .2, .0, tLayoutNormal, .234, opt_layout ; initial layout of dive mode screen =0: normal, =1: big - OPTION_BOOL oExtendedStops, .1, .235, opt_extended_stops ; =1: allow placement of gas switches below the depth of the 1st stop + OPTION_BOOL oExtendedStops, .1, .235, opt_extended_stops ; =1: place gas switches also below 1st stop depth + OPTION_UINT8 oGasDensityAttention,.40, .80, .60, notext, .236, char_I_gas_density_att ; threshold for gas density attention [0.1 grams/l] + OPTION_UINT8 oGasDensityWarning, .40, .80, .65, notext, .237, char_I_gas_density_warn ; threshold for gas density warning [0.1 grams/l] + OPTION_BOOL oDilppO2Check, .1, .238, char_I_dil_ppO2_check ; =1: check ppO2 of the pure diluent against current setpoint ; +---------------------------+ ; | /|\ | @@ -333,6 +337,20 @@ ;============================================================================= +; volatile options + + OPTION_UINT8p10 odiveInterval, .0, .240, .0, tMinutes, volatile, opt_surface_interval ; additional surface interval for deco calculator + OPTION_UINT8p2 obottomTime, .2, .60, .10, tMinutes, volatile, char_I_bottom_time ; bottom time for deco calculator + OPTION_UINT8p3d obottomDepth, .12, .120, .21, tMeters, volatile, char_I_bottom_depth ; bottom depth for deco calculator and simulator + OPTION_BOOL oSimAGF, .0, volatile, opt_sim_use_aGF ; use GF (no) or aGF (yes) in deco calculator + OPTION_ENUM8 oLogOffsetStep, .4, .0, tLogOffStep1, volatile, opt_logoffset_step ; step size when adjusting the log offset + + IFDEF _gas_contingency + OPTION_BOOL oGasContingency, .0, volatile, char_I_gas_contingency ; =1: switch to alternative gas if best gas is depleted + ENDIF + + +;============================================================================= ; Set Time/Set Date (RAM only) OPTION_UINT8 oClearSeconds, .0, .0, .0, notext, volatile, rtc_latched_secs OPTION_UINT8 oSetMinutes, .0, .59, .0, notext, volatile, rtc_latched_mins
--- a/src/options.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/options.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File options.asm next combined generation V3.03-1 +; File options.asm next combined generation V3.04.3 ; ; Manage all options data. ; @@ -103,6 +103,9 @@ call gaslist_cleanup_list ; check and correct multiple or none First diluent bcf is_diluent_menu ; setup checking gases call gaslist_cleanup_list ; check and correct multiple or none First gas + IFNDEF _gauge_mode + call option_cleanup_gauge ; check and correct Gauge mode + ENDIF IFDEF _ccr_pscr call option_cleanup_oCCRMode ; check and correct CCR / pSCR mode ENDIF @@ -227,6 +230,7 @@ ; global option_save_all ; save options to EEPROM option_save_all: + bcf PIR3,RC2IE ;---- Save option serial into EEPROM to detect reset and new version movlw LOW(eeprom_serial_save) movwf EEADR @@ -253,6 +257,7 @@ movlw HIGH(option_table_end) cpfseq FSR0H bra option_save_all_2 ; not yet done... + bsf PIR3,RC2IE return ; all done option_save_all_2: rcall option_save ; save one option... @@ -480,7 +485,7 @@ bnz option_inc_enum8_3a ; NO - in some other mode IFNDEF _ccr_pscr incf INDF1,f ; YES - no CCR mode compiled in, advance to gauge mode - bra option_inc_enum8_3_exit ; - done + bra option_inc_enum8_3a ; - check if gauge mode is available ENDIF ; _ccr_pscr IFDEF _rx_functions global option_cleanup_oTrMode_CCR ; embedded clean-up entry-point @@ -491,14 +496,22 @@ bra option_inc_enum8_3_reset ; YES - revert mode to 1 (on) ENDIF ; _rx_functions option_inc_enum8_3a: ; any mode other than CCR + IFNDEF _gauge_mode + movf INDF1,W ; get option value: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR + xorlw .2 ; in Gauge mode? + bnz option_inc_enum8_3b ; NO - in some other mode + incf INDF1,f ; YES - no Gauge mode compiled in, advance to Apnea mode + bra option_inc_enum8_3_exit ; - done (Apnea mode is always available) + ENDIF ; _gauge_mode +option_inc_enum8_3b: IFNDEF _ccr_pscr movf INDF1,W ; get option value: 0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR xorlw .4 ; in pSCR mode? - bnz option_inc_enum8_3b ; NO - in some other mode + bnz option_inc_enum8_3c ; NO - in some other mode clrf INDF1 ; YES - no pSCR mode compiled in, advance to 0 "OC" bra option_inc_enum8_3_exit ; - done ENDIF ; _ccr_pscr -option_inc_enum8_3b: +option_inc_enum8_3c: global option_cleanup_oTrMode_no_CCR ; embedded clean-up entry-point option_cleanup_oTrMode_no_CCR: ; entry point from cleanup during restart movff opt_TR_mode,WREG ; get TR mode @@ -509,6 +522,7 @@ movff WREG,opt_TR_mode ; write to option option_inc_enum8_3_exit: return ; done + option_inc_enum8_4: IFDEF _rx_functions ; Now some rather crude hack to advance opt_TR_mode in dependency of opt_dive_mode @@ -539,6 +553,19 @@ return + IFNDEF _gauge_mode +option_cleanup_gauge: + movff opt_dive_mode,WREG ; get dive mode into WREG (0=OC, 1=CCR, 2=Gauge, 3=Apnea, 4=pSCR) + xorlw .2 ; in Gauge mode? + bnz option_cleanup_gauge_1 ; NO - done + banksel opt_dive_mode ; YES - setting not allowed, select options bank + clrf opt_dive_mode ; - reset to OC mode + banksel common ; - back to bank common +option_cleanup_gauge_1: + return ; done + ENDIF + + IFDEF _ccr_pscr global option_cleanup_oCCRMode global option_cleanup_oCCRMode_pSCR @@ -665,16 +692,25 @@ ;---- Draw an enumerated value (set of translated strings) option_draw_enum8: - movf INDF1,W ; get current value - cpfsgt opt_max ; bound value - clrf WREG - addwf WREG ; *= 2 - addwf opt_inc,W ; base text + 2 * value - movwf FSR1L - movlw .0 - addwfc opt_min,W ; propagate carry... + movff INDF1,lo ; memorize current value + movf INDF1,W ; copy current value to WREG + cpfsgt opt_max ; max value (= highest usable value + 1) > current value? + clrf WREG ; NO - to avoid printing rubbish, reset to first value + addwf WREG ; current value *= 2 + addwf opt_inc,W ; base text + 2 * current value + movwf FSR1L ; load FSR0 + movlw .0 ; propagate carry... + addwfc opt_min,W ; ... movwf FSR1H ; ...into FSR1 - goto strcat_text + call strcat_text ; print text + movf opt_default,W ; get default value + cpfseq lo ; compare with memorized current value, equal? + bra option_draw_enum8_1 ; NO - not default, add * + return ; YES - default, done +option_draw_enum8_1: + PUTC "*" ; print "*" + return ; done + ;-----------------------------------------------------------------------------
--- a/src/p2_deco-TESTING.c Sun Jun 30 23:22:32 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3802 +0,0 @@ -// ************************************************************** -// p2_deco.c REFACTORED VERSION V2.95 -// !! SPECIAL TESTING VERSION - DO NOT USE FOR REAL DIVES !! -// Created on: 12.05.2009 =========================================================== -// Author: chsw -> This version shows the alternative (bailout) stops <- -// -> instead of the stop from the normal dive plan. <- -// ************************************************************** - -////////////////////////////////////////////////////////////////////////////// -// OSTC - diving computer code -// Copyright (C) 2011 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/>. -// -////////////////////////////////////////////////////////////////////////////// - -// ***************************** -// ** I N T R O D U C T I O N ** -// ***************************** -// -// OSTC -// -// code: -// p2_deco.c -// part2 of the OSTC code -// -// summary: -// decompression routines -// for the OSTC experimental project -// written by Christian Weikamp -// contributions by Ralph Lembcke -// -// -// history: -// 01/03/08 v100: first release candidate -// 03/13/08 v101: start of programming ppO2 code -// 03/13/25 v101a: backup of interim version with ppO2 calculation -// 03/13/25 v101: open circuit gas change during deco -// 03/13/25 v101: CNS_fraction calculation -// 03/13/26 v101: optimization of tissue calc routines -// 07/xx/08 v102a: debug of bottom time routine -// 09/xx/08 v102d: Gradient Factor Model implementation -// 10/10/08 v104: renamed to build v103 for v118 stable -// 10/14/08 v104: integration of char_I_depth_last_deco for Gradient Model -// 03/31/09 v107: integration of FONT Incon24 -// 05/23/10 v109: 5 gas changes & 1 min timer -// 07/13/10 v110: cns vault added -// 12/25/10 v110: split in three files (deco.c, main.c, definitions.h) -// 2011/01/20: [jDG] Create a common file included in ASM and C code. -// 2011/01/24: [jDG] Make ascenttime an short. No more overflow! -// 2011/01/25: [jDG] Fusion deco array for both models. -// 2011/01/25: [jDG] Use CF(54) to reverse deco order. -// 2011/02/11: [jDG] Reworked gradient-factor implementation. -// 2011/02/15: [jDG] Fixed inconsistencies introduced by gas switch delays. -// 2011/03/21: [jDG] Added gas consumption (CF56 & CF57) evaluation for OCR mode. -// 2011/04/15: [jDG] Store low_depth in 32bits (w/o rounding), for a better stability. -// 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for deco planning. -// 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor. -// 2011/05/02: [jDG] Added "Future TTS" function (CF58). -// 2011/05/17: [jDG] Various cleanups. -// 2011/08/08: [jDG] Computes CNS during deco planning ascent. -// 2011/11/24: [jDG] Slightly faster and better NDL computation. -// 2011/12/17: [mH] Remove of the useless debug stuff -// 2012/02/24: [jDG] Remove missed stop bug. -// 2012/02/25: [jDG] Looking for a more stable LOW grad factor reference. -// 2012/09/10: [mH] Fill char_O_deco_time_for_log for logbook write -// 2012/10/05: [jDG] Better gas_volumes accuracy (average depth, switch between stop). -// 2013/03/05: [jDG] Should vault low_depth too. -// 2013/03/05: [jDG] Wrobell remark: ascent_to_first_stop works better with finer steps (2sec). -// 2013/05/08: [jDG] A. Salm remark: NOAA tables for CNS are in ATA, not bar. -// 2013/12/21: [jDG] Fix CNS calculation in deco plan w/o marked gas switch -// 2014/06/16: [jDG] Fix Helium diluent. Fix volumes with many travel mix. -// 2014/06/29: [mH] Compute int_O_ceiling -// 2015/06/12: [jDG] Fix NDL prediction while desaturating with the Buhlmann model. -// 2017/08/04: [mH] Switch to absolute GF everywhere and apply safety margin parameters to both models (GF and non-GF), fixes from Ralph Lembcke -// 2017/10/31: [rl] enhancements for pSCR mode and introduction of 2nd deco plan computation -// 2017/12/31: [rl] completion of 2nd deco plan computation and various up-fixes -// -// -// Literature: -// Buhlmann, Albert: Tauchmedizin; 4. Auflage [2002]; -// 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 -// Morrison, Stuart; 2000; DIY DECOMPRESSION; http://www.lizardland.co.uk/DIYDeco.html -// Balthasar, Steffen; Dekompressionstheorie I: Neo Haldane Modelle; http://www.txfreak.de/dekompressionstheorie_1.pdf -// Baker, Erik C.; Clearing Up The Confusion About "Deep Stops" -// Baker, Erik C.; Understanding M-values; http://www.txfreak.de/understanding_m-values.pdf -// -// - -// ********************* -// ** I N C L U D E S ** -// ********************* -#include <math.h> - -// *********************************************** -// ** V A R I A B L E S D E F I N I T I O N S ** -// *********************************************** - -#include "p2_definitions.h" -#define TEST_MAIN -#include "shared_definitions.h" - - -// ambient pressure at different mountain heights -#define P_ambient_1000m 0.880 // [bar] based on 990 hPa and 20C at sea level, 15C at altitude -#define P_ambient_2000m 0.782 // [bar] -#define P_ambient_3000m 0.695 // [bar] - -// ambient pressure in aircraft cabin during flying - worst case according to Buhlmann -#define P_ambient_fly 0.600 // [bar], 0.600 bar is the value used by Buhlmann for his flying-after-diving calculations - // 0.735 bar is a typical cabin pressure for nowadays commercial jet aircrafts - // ----- - // 0.135 bar safety margin - -// constants and factors -#define ppWater 0.0627 // water vapor partial pressure in the lungs -#define METER_TO_BAR 0.09985 // conversion factor -#define BAR_TO_METER 10.0150 // conversion factor (1.0/METER_TO_BAR) -#define SURFACE_DESAT_FACTOR 0.7042 // surface desaturation safety factor -#define HYST 1.0E-06 // threshold for tissue graphics on-gassing / off-gassing visualization - -// thresholds -#define GF_warning_threshold 100 // threshold for GF warning -#define GF_prewarning_threshold 70 // threshold for GF attention -#define CNS_warning_threshold 100 // threshold for CNS warning -#define CNS_prewarning_threshold 70 // threshold for CNS attention -#define ppO2_prewarn_threshold 120 // threshold for ppO2 attention (master warnings come through options_table.asm) -#define GAS_NEEDS_ATTENTION_THRESHOLD 0.70 // threshold for gas needs attention - -// deco engine states and modes -#define DECO_STATUS_MASK 0x03 -#define DECO_STATUS_START 0x00 -#define DECO_STATUS_FINISHED 0x00 -#define DECO_STATUS_STOPS 0x01 -#define DECO_STATUS_ASCENT 0x02 -#define DECO_STATUS_INIT 0x03 - -#define DECO_MODE_MASK 0x0C -#define DECO_MODE_LOOP 0x04 -#define DECO_MODE_CCR 0x04 // to be used with == operator in combination with DECO_MODE_MASK only! -#define DECO_MODE_PSCR 0x08 - -#define DECO_PLAN_ALTERNATE 0x10 -#define DECO_CNS_CALCULATE 0x20 -#define DECO_VOLUME_CALCULATE 0x40 -#define DECO_ASCENT_DELAYED 0x80 - -// deco engine warnings -#define DECO_WARNING_IBCD 0x01 -#define DECO_WARNING_IBCD_lock 0x02 -#define DECO_WARNING_MBUBBLES 0x04 -#define DECO_WARNING_MBUBBLES_lock 0x08 -#define DECO_WARNING_OUTSIDE 0x10 -#define DECO_WARNING_OUTSIDE_lock 0x20 -#define DECO_WARNING_STOPTABLE_OVERFLOW 0x40 -#define DECO_FLAG 0x80 - -// flags used with integer numbers -#define INT_FLAG_INVALID 0x0400 -#define INT_FLAG_ZERO 0x0800 -#define INT_FLAG_LOW 0x1000 -#define INT_FLAG_HIGH 0x2000 -#define INT_FLAG_PREWARNING 0x4000 -#define INT_FLAG_WARNING 0x8000 - - - -// ************************* -// ** P R O T O T Y P E S ** -// ************************* - -static void calc_hauptroutine(void); -static void calc_hauptroutine_data_input(void); -static void calc_hauptroutine_update_tissues(void); -static void calc_hauptroutine_calc_deco(void); -static void calc_tissue(void); -static void calc_limit(void); -static void calc_nullzeit(void); -static void calc_ascenttime(void); -static void calc_dive_interval(void); -static void calc_gradient_factor(void); -static void calc_wo_deco_step_1_min(void); -static void calc_desaturation_time(void); - -static void sim_extra_time(void); -static void sim_ascent_to_first_stop(void); -static void sim_limit(PARAMETER float GF_current); - -static void update_startvalues(void); -static void gas_switch_set(void); -static void compute_CNS_for_display(void); - -static void clear_deco_table(void); -static void clear_tissue(void); - -static unsigned char gas_find_better(void); -static unsigned char calc_nextdecodepth(void); -static unsigned char update_deco_table(PARAMETER unsigned char time_increment); - - -//---- Bank 5 parameters ----------------------------------------------------- -#ifndef UNIX -# pragma udata bank5=0x500 -#endif - -// general deco parameters - -static float GF_low; // initialized from deco parameters, constant during all computations -static float GF_high; // initialized from deco parameters, constant during all computations -static float GF_delta; // initialized from deco parameters, constant during all computations -static float locked_GF_step_norm; // GF_delta / low_depth_norm in normal plan -static float locked_GF_step_alt; // GF_delta / low_depth_alt in alternative plan - -static float low_depth_norm; // Depth of deepest stop in normal plan -static float low_depth_alt; // Depth of deepest stop in alternative plan - -static float float_ascent_speed; // ascent speed from options_table (1.0 .. 10.0 m/min) -static float float_saturation_multiplier; // safety factor for on-gassing rates -static float float_desaturation_multiplier; // safety factor for off-gassing rates -static float float_deco_distance; // additional depth below stop depth for tissue, CNS and gas volume calculation - - -// real context: what we are doing now. - -static float calc_lead_tissue_limit; // minimum tolerated ambient pressure by Buhlmann model -static float CNS_fraction; // current CNS (1.00 = 100%) - -static unsigned short deco_tissue_vector; // 32 bit vector to memories all tissues that are in decompression -static unsigned short IBCD_tissue_vector; // 32 bit vector to memories all tissues that experience IBCD - -// simulation context: used to predict ascent. - -static float sim_lead_tissue_limit; // minimum tolerated ambient pressure by Buhlmann model -static float CNS_sim_norm_fraction; // CNS at end of dive in normal plan -static float CNS_sim_alt_fraction; // CNS at end of dive in alternative plan - -static unsigned char temp_depth_limit; // depth of next stop in meters, used in deco calculations -static unsigned char sim_lead_tissue_no; // Leading compartment number -static unsigned char split_N2_He[NUM_COMP]; // used for calculating the desaturation time - - -// stops table - -static unsigned char internal_deco_depth[NUM_STOPS]; // depth of the stop -static unsigned char internal_deco_time[NUM_STOPS]; // duration of the stop -static unsigned char internal_deco_gas[NUM_STOPS]; // gas used at the stop - - -// transfer variables between calc_desaturation_time() and calc_desaturation_time_helper() - -static float desat_factor; // used to cache a pre-computed factor -static float var_ht; // buffer for a half-time factor -static float pres_target; // target pressure for a compartment -static float pres_actual; // current pressure of the compartment -static unsigned short short_time; // time it takes for the compartment to reach the target pressure - -// transfer variables between gas_volumes() and gas_volumes_helper() -static float float_depth; // depth of the stop or half-way point -static float float_time; // duration of the stop or ascent phase -static float volume; // computed volume of gas -static unsigned char usage; // gas usage in l/min - - -// 44 byte free space left in this bank - - -//---- Bank 6 parameters ----------------------------------------------------- -#ifndef UNIX -# pragma udata bank6=0x600 -#endif - -// indexing and sequencing - -static unsigned char ci; // used as index to the Buhlmann tables -static unsigned char twosectimer = 0; // used for timing the tissue updating -static unsigned char tissue_increment; // Selector for real/simulated tissues and time increment - - -// environmental and gas data - -static float pres_respiration; // current depth in absolute pressure -static float pres_surface; // absolute pressure at the surface -static float temp_deco; // simulated current depth in abs.pressure, used for deco calculations - -static float O2_ratio; // real breathed gas oxygen ratio -static float N2_ratio; // real breathed gas nitrogen ratio -static float He_ratio; // real breathed gas helium ratio - -static float calc_O2_ratio; // simulated breathed gas oxygen ratio -static float calc_N2_ratio; // simulated breathed gas nitrogen ratio -static float calc_He_ratio; // simulated breathed gas helium ratio - -static float O2_ppO2; // ppO2 - calculated for pure oxygen at current depth -static float pSCR_ppO2; // ppO2 - calculated for breathed from pSCR loop -static float pure_ppO2; // ppO2 - calculated for breathed in OC mode - -static unsigned char char_actual_ppO2; // ppO2 - assumed to be breathed, as integer 100 = 1.00 bar - -static float breathed_ppO2; // partial pressure of breathed oxygen -static float ppN2; // partial pressure of breathed nitrogen -static float ppHe; // partial pressure of breathed helium - - -// Buhlmann model parameters - -static float var_N2_a; // Buhlmann a, for current N2 tissue -static float var_N2_b; // Buhlmann b, for current N2 tissue -static float var_He_a; // Buhlmann a, for current He tissue -static float var_He_b; // Buhlmann b, for current He tissue -static float var_N2_e; // exposition, for current N2 tissue -static float var_He_e; // exposition, for current He tissue -static float var_N2_ht; // half-time for current N2 tissue -static float var_He_ht; // half-time for current N2 tissue - - -// gas switch history - -static unsigned char sim_gas_first_used; // Number of first used gas, for bottom segment -static unsigned char sim_gas_last_used; // number of last used gas -static unsigned char sim_gas_last_depth; // change depth of last used gas - - -// vault to back-up & restore tissue data - -static float pres_tissue_N2_vault[NUM_COMP]; // stores the nitrogen tissue pressures -static float pres_tissue_He_vault[NUM_COMP]; // stores the helium tissue pressures -static float low_depth_norm_vault; // stores a parameter of the GF model for normal plan -static float low_depth_alt_vault; // stores a parameter of the GF model for alternative plan -static float cns_vault_float; // stores current CNS (float representation) - -static unsigned int cns_vault_int; // stores current CNS (integer representation) -static unsigned char deco_warnings_vault; // stores warnings status - - -// auxiliary variables for local data buffering - -static float N2_equilibrium; // used for N2 tissue graphics scaling -static float temp_tissue; // auxiliary variable to buffer tissue pressures - - -// 7 byte free space left in this bank - - -//---- Bank 7 parameters ----------------------------------------------------- -#ifndef UNIX -# pragma udata bank7=0x700 -#endif - -// Keep order and position of the variables in bank 7 as they are backed-up to & restored from EEPROM - -float pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes -float pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes -float sim_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes -float sim_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes - - -//---- Bank 8 parameters ----------------------------------------------------- -#ifndef UNIX -# pragma udata overlay bank8=0x800 - -static char md_pi_subst[256]; // Overlay C-code data stack here, too. - -# define C_STACK md_pi_subst -#endif - -// Back to bank6 for further tmp data -#ifndef UNIX -# pragma udata bank6 -#endif - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -///////////////////////////// THE LOOKUP TABLES ////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -// -// End of PROM code is 17F00, So push tables on PROM top... -// -#ifndef UNIX -# pragma romdata Buhlmann_tables = 0x1DD00 // Needs to be in UPPER bank. -#endif - -rom const float Buhlmann_ab[4*16] = { -// Data ZH-L16C, from Bhlmann Tauchmedizin 2002, option 1a (4mn) -// a for N2 b for N2 a of He b for He - 1.2599, 0.5050, 1.7424, 0.4245, - 1.0000, 0.6514, 1.3830, 0.5747, - 0.8618, 0.7222, 1.1919, 0.6527, - 0.7562, 0.7825, 1.0458, 0.7223, - 0.6200, 0.8126, 0.9220, 0.7582, - 0.5043, 0.8434, 0.8205, 0.7957, - 0.4410, 0.8693, 0.7305, 0.8279, - 0.4000, 0.8910, 0.6502, 0.8553, - 0.3750, 0.9092, 0.5950, 0.8757, - 0.3500, 0.9222, 0.5545, 0.8903, - 0.3295, 0.9319, 0.5333, 0.8997, - 0.3065, 0.9403, 0.5189, 0.9073, - 0.2835, 0.9477, 0.5181, 0.9122, - 0.2610, 0.9544, 0.5176, 0.9171, - 0.2480, 0.9602, 0.5172, 0.9217, - 0.2327, 0.9653, 0.5119, 0.9267 -}; - -rom const float Buhlmann_ht[2*16] = { -// Compartment half-life, in minute -//--- N2 ---- He ---------------------- - 4.0, 1.51, - 8.0, 3.02, - 12.5, 4.72, - 18.5, 6.99, - 27.0, 10.21, - 38.3, 14.48, - 54.3, 20.53, - 77.0, 29.11, - 109.0, 41.20, - 146.0, 55.19, - 187.0, 70.69, - 239.0, 90.34, - 305.0, 115.29, - 390.0, 147.42, - 498.0, 188.24, - 635.0, 240.03 -}; - -rom const float e2secs[2*16] = { -// result of 1 - 2^(-1/(2sec*HT)) -//---- N2 ------------- He ------------ - 5.75958E-03, 1.51848E-02, - 2.88395E-03, 7.62144E-03, - 1.84669E-03, 4.88315E-03, - 1.24813E-03, 3.29997E-03, - 8.55371E-04, 2.26041E-03, - 6.03079E-04, 1.59437E-03, - 4.25414E-04, 1.12479E-03, - 3.00019E-04, 7.93395E-04, - 2.11949E-04, 5.60641E-04, - 1.58240E-04, 4.18555E-04, - 1.23548E-04, 3.26795E-04, - 9.66686E-05, 2.55722E-04, - 7.57509E-05, 2.00387E-04, - 5.92416E-05, 1.56716E-04, - 4.63943E-05, 1.22734E-04, - 3.63850E-05, 9.62538E-05 -//------------------------------------- -}; - -rom const float e1min[2*16] = { -// Integration constant for 1 minute, -// Ie. 1- 2^(-1/HT) -//----- N2 --------- e 1min He -------- - 1.59104E-01, 3.68109E-01, - 8.29960E-02, 2.05084E-01, - 5.39424E-02, 1.36579E-01, - 3.67742E-02, 9.44046E-02, - 2.53454E-02, 6.56359E-02, - 1.79351E-02, 4.67416E-02, - 1.26840E-02, 3.31991E-02, - 8.96152E-03, 2.35301E-02, - 6.33897E-03, 1.66832E-02, - 4.73633E-03, 1.24808E-02, - 3.69981E-03, 9.75753E-03, - 2.89600E-03, 7.64329E-03, - 2.27003E-03, 5.99417E-03, - 1.77572E-03, 4.69082E-03, - 1.39089E-03, 3.67548E-03, - 1.09097E-03, 2.88359E-03 -//------------------------------------- -}; - -rom const float e10min[2*16] = { -// The 10 min Value in float notation: -// result of 1 - 2^(-10/ht) -//---- N2 -------------- He ----------- - 8.23223E-01, 9.89851E-01, - 5.79552E-01, 8.99258E-01, - 4.25651E-01, 7.69737E-01, - 3.12487E-01, 6.29027E-01, - 2.26416E-01, 4.92821E-01, - 1.65547E-01, 3.80407E-01, - 1.19840E-01, 2.86538E-01, - 8.60863E-02, 2.11886E-01, - 6.16117E-02, 1.54849E-01, - 4.63665E-02, 1.18026E-01, - 3.63881E-02, 9.34005E-02, - 2.85855E-02, 7.38569E-02, - 2.24698E-02, 5.83504E-02, - 1.76160E-02, 4.59303E-02, - 1.38222E-02, 3.61528E-02, - 1.08563E-02, 2.84646E-02 -//------------------------------------- -}; - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////// THE SUBROUTINES /////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -// -// all new in v.102 -// moved from 0x0D000 to 0x0C000 in v.108 -#ifndef UNIX -# pragma code p2_deco = 0x0C000 -#endif - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -/////////////////////// U T I L I T I E S ///////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////////// -// Bump to blue-screen when an assert is wrong -#ifdef __DEBUG -void assert_failed(PARAMETER short int line) -{ -} -#endif - -////////////////////////////////////////////////////////////////////////////// -// When calling C code from ASM context, the data stack pointer and -// frames should be reset. Bank8 is used by stack - -#ifdef CROSS_COMPILE -# define RESET_C_STACK -#else -# ifdef __DEBUG -# define RESET_C_STACK fillDataStack(); - void fillDataStack(void) - { - _asm - LFSR 1,C_STACK - MOVLW 0xCC - loop: MOVWF POSTINC1,0 - TSTFSZ FSR1L,0 - BRA loop - - LFSR 1,C_STACK - LFSR 2,C_STACK - _endasm - } -# else -# define RESET_C_STACK \ - _asm \ - LFSR 1, C_STACK \ - LFSR 2, C_STACK \ - _endasm -# endif -#endif - -////////////////////////////////////////////////////////////////////////////// -// Fast subroutine to read timer 5. -// Note: result is in 1/32 of milliseconds (30,51757813 us/bit to be precise) -static unsigned short tmr5(void) -{ -#ifndef CROSS_COMPILE - _asm - movff 0xf7c,PRODL // TMR5L - movff 0xf7d,PRODH // TMR5H - _endasm // result in PRODH:PRODL. -#else - return 0; -#endif -} - -////////////////////////////////////////////////////////////////////////////// -// read Buhlmann tables A and B for compartment ci -// -static void read_Buhlmann_coefficients(void) -{ -#ifndef CROSS_COMPILE - // Note: we don't use far rom pointer, because the - // 24 bits is too complex, hence we have to set - // the UPPER page ourself... - // --> Set zero if tables are moved to lower pages ! - _asm - movlw 1 - movwf TBLPTRU,0 - _endasm -#endif - - assert( ci < NUM_COMP ); - - // Use an interleaved array (AoS) to access coefficients with a - // single addressing. - { - overlay rom const float* ptr = &Buhlmann_ab[4*ci]; - var_N2_a = *ptr++; - var_N2_b = *ptr++; - var_He_a = *ptr++; - var_He_b = *ptr++; - } -} - -////////////////////////////////////////////////////////////////////////////// -// read Buhlmann tables for compartment ci -// If period == 0 : 2sec interval -// 1 : 1 min interval -// 2 : 10 min interval. -static void read_Buhlmann_times(PARAMETER char period) -{ -#ifndef CROSS_COMPILE - // Note: we don't use far rom pointer, because the - // 24 bits is to complex, hence we have to set - // the UPPER page ourself... - // --> Set zero if tables are moved to lower pages ! - _asm - movlw 1 - movwf TBLPTRU,0 - _endasm -#endif - - assert( ci < NUM_COMP ); - - // Integration intervals. - switch(period) - { - case 0: //---- 2 sec ----------------------------------------------------- - { - overlay rom const float* ptr = &e2secs[2*ci]; - var_N2_e = *ptr++; - var_He_e = *ptr++; - } - break; - - case 1: //---- 1 min ----------------------------------------------------- - { - overlay rom const float* ptr = &e1min[2*ci]; - var_N2_e = *ptr++; - var_He_e = *ptr++; - } - break; - - case 2: //---- 10 min ---------------------------------------------------- - { - overlay rom const float* ptr = &e10min[2*ci]; - var_N2_e = *ptr++; - var_He_e = *ptr++; - } - break; - - default: - assert(0); // Never go there... - } -} - -////////////////////////////////////////////////////////////////////////////// -// read Buhlmann tables for compartment ci -// -static void read_Buhlmann_ht(void) -{ - -#ifndef CROSS_COMPILE - // Note: we don't use far rom pointer, because the - // 24 bits is to complex, hence we have to set - // the UPPER page ourself... - // --> Set zero if tables are moved to lower pages ! - _asm - movlw 1 - movwf TBLPTRU,0 - _endasm -#endif - - assert( ci < NUM_COMP ); - { - overlay rom const float* ptr = &Buhlmann_ht[2*ci]; - var_N2_ht = *ptr++; - var_He_ht = *ptr++; - } - - assert( 4.0 <= var_N2_ht && var_N2_ht <= 635.0 ); - assert( 1.5099 <= var_He_ht && var_He_ht <= 240.03 ); -} - -////////////////////////////////////////////////////////////////////////////// -// calc_nextdecodepth -// -// new in v.102 -// -// INPUT, changing during dive: -// temp_deco : current depth in absolute pressure -// -// INPUT, fixed during dive: -// pres_surface -// GF_delta -// GF_high -// GF_low -// char_I_depth_last_deco -// -// MODIFIED -// locked_GF_step_norm/_alt : used for GF model -// low_depth_norm/_alt : used for GF model -// -// OUTPUT -// temp_depth_limit : depth of next stop in meters (if RETURN == true ) -// depth we can ascent to without stop (if RETURN == false) -// -// RETURN TRUE if a stop is needed. -// -static unsigned char calc_nextdecodepth(void) -{ - overlay unsigned char need_stop; - - // compute current depth in meters - overlay float depth = (temp_deco - pres_surface) * BAR_TO_METER; - - // compute depth in meters after 1 minute of ascent at float_ascent_speed (5..10 m/min) - overlay float min_depth = (depth > float_ascent_speed) ? (depth - float_ascent_speed) : 0.0; - - - // allow for 200mbar of weather dependent surface pressure change - assert( depth >= -0.2 ); - - - //---- check if a stop is needed for deco reasons ---------------------------- - - // switch on deco model - if( char_I_deco_model != 0 ) - { - //---- ZH-L16 + GRADIENT FACTOR Model ------------------------------------ - - overlay float locked_GF_step; - overlay float low_depth; - overlay float pres_gradient; - - overlay unsigned char first_stop = 0; - - - // calculate minimum depth we can ascent to in absolute pressure - sim_limit( GF_low ); - - // ...and convert the depth into relative pressure - pres_gradient = sim_lead_tissue_limit - pres_surface; - - // check if we can surface directly - if( pres_gradient <= 0.0 ) - { - min_depth = 0.0; // set minimum depth to 0 meters = surface - goto no_deco_stop; // done. - } - - // convert minimum depth we can ascent to from relative pressure to depth in meters - pres_gradient *= BAR_TO_METER; - - // recall low_depth dependent on current plan - low_depth = (char_O_deco_status & DECO_PLAN_ALTERNATE) ? low_depth_alt : low_depth_norm; - - // Store the deepest point needing a deco stop as the LOW reference for GF. - // NOTE: following stops will be validated using this LOW-HIGH GF scale, - // so if we want to keep coherency, we should not validate this stop - // yet, but apply the search to it, as for all the following stops afterward. - if( pres_gradient > low_depth ) - { - // update GF parameters - low_depth = pres_gradient; - locked_GF_step = GF_delta / low_depth; - - // store updated GF parameters dependent on current plan - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) - { - low_depth_alt = low_depth; - locked_GF_step_alt = locked_GF_step; - } - else - { - low_depth_norm = low_depth; - locked_GF_step_norm = locked_GF_step; - } - } - else - { - // recall locked_GF_step dependent on current plan - locked_GF_step = (char_O_deco_status & DECO_PLAN_ALTERNATE) ? locked_GF_step_alt : locked_GF_step_norm; - } - - // invalidate this stop if we can ascent for 1 minute without going above minimum required deco depth - if( pres_gradient < min_depth ) goto no_deco_stop; - - - // if program execution passes here, we need a deco stop - - // Round to multiple of 3 meters - first_stop = 3 * (unsigned char)(0.9995 + pres_gradient * 0.333333); - - // check a constraint - assert( first_stop < 128 ); - - // apply correction for the shallowest stop, use char_I_depth_last_deco (3..6 m) instead - if( first_stop == 3 ) first_stop = char_I_depth_last_deco; - - // We have a stop candidate. - // But maybe ascending to the next stop will diminish the constraint, - // because the GF might decrease more than the pressure gradient... - while(first_stop > 0) - { - // Next depth - overlay unsigned char next_stop; - - // invalidate this stop if we can ascent one more minute without going above minimum required deco depth - if( first_stop <= (unsigned char)min_depth ) goto no_deco_stop; - - // compute depth of next stop - if ( first_stop <= char_I_depth_last_deco ) next_stop = 0; - else if ( first_stop == 6 ) next_stop = char_I_depth_last_deco; - else next_stop = first_stop - 3; - - // compute total pressure at the new stop candidate - pres_gradient = next_stop * METER_TO_BAR + pres_surface; - - // compute limit for the new stop candidate - if( (low_depth == 0.0) || (next_stop > low_depth) ) sim_limit( GF_low ); - else sim_limit( GF_high - next_stop * locked_GF_step ); - - // check if ascent to the next stop candidate is possible - if( sim_lead_tissue_limit >= pres_gradient ) goto deco_stop_found; // no - ascent to next_stop forbidden - - // else, validate that stop and loop... - first_stop = next_stop; - } - -no_deco_stop: - need_stop = 0; // set flag for stop needed to 'no' - temp_depth_limit = (unsigned char)min_depth; // report depth we can ascent to without stop - goto done; - -deco_stop_found: - need_stop = 1; // set flag for stop needed to 'yes' - temp_depth_limit = (unsigned char)first_stop; // stop depth, in meters - -done: - ; - } - else - { - //---- ZH-L16 model ------------------------------------------------- - - overlay float pres_gradient; - - - // calculate minimum depth we can ascent to in absolute pressure - sim_limit(1.0); - - // ...and convert the depth into relative pressure - pres_gradient = sim_lead_tissue_limit - pres_surface; - - // check if we can surface directly - if (pres_gradient >= 0) - { - // no - set flag for stop needed to 'yes' - need_stop = 1; - - // convert stop depth in relative pressure to stop index - pres_gradient *= BAR_TO_METER / 3; - - // convert stop index to depth in meters, rounded to multiple of 3 meters - temp_depth_limit = 3 * (short) (pres_gradient + 0.99); - - // correct last stop to 4m/5m/6m - if( temp_depth_limit == 3 ) temp_depth_limit = char_I_depth_last_deco; - } - else - { - // yes - set flag for stop needed to 'no' - need_stop = 0; - - // set depth we can ascent to as 0 = surface - temp_depth_limit = 0; - } - } - - - // After the first deco stop, gas changes are only done at deco stops now! - - // check if a stop is found and there is a better gas to switch to - if( need_stop && gas_find_better() ) - { - // set the new calculation ratios for N2, He and O2 - gas_switch_set(); - - // prime the deco stop with the gas change time - update_deco_table(char_I_gas_change_time); - } - - return need_stop; -} - -////////////////////////////////////////////////////////////////////////////// -// copy_deco_table -// -// Buffer the stops, once computed, so we can continue to display them -// while computing the next set. -// -static void copy_deco_table(void) -{ - // Copy depth of the first (deepest) stop, because when reversing - // order, it will be hard to find... - char_O_first_deco_depth = internal_deco_depth[0]; - char_O_first_deco_time = internal_deco_time [0]; - - { - overlay unsigned char x, y; - - for(x=0; x<NUM_STOPS; x++) - { - char_O_deco_depth[x] = internal_deco_depth[x]; - char_O_deco_time [x] = internal_deco_time [x]; - char_O_deco_gas [x] = internal_deco_gas [x]; - } - - //Now fill the char_O_deco_time_for_log array - //---- First: search the first non-null depth - for(x=(NUM_STOPS-1); x != 0; --x) - if( internal_deco_depth[x] != 0 ) break; - - //---- Second: copy to output table (in reverse order) - for(y=0; y<NUM_STOPS; y++, --x) - { - char_O_deco_time_for_log[y] = internal_deco_time [x]; - - // Stop only once the last transfer is done. - if( x == 0 ) break; - } - - //---- Third: fill table end with null - for(y++; y<NUM_STOPS; y++) - { - char_O_deco_time_for_log[y] = 0; - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// temp_tissue_safety -// -// outsourced in v.102 -// -// Apply safety factors for both ZH-L16 models. -// -static void temp_tissue_safety(void) -{ - assert( 0.0 < float_desaturation_multiplier && float_desaturation_multiplier <= 1.0 ); - assert( 1.0 <= float_saturation_multiplier && float_saturation_multiplier <= 2.0 ); - - if( temp_tissue < 0.0 ) temp_tissue *= float_desaturation_multiplier; - else temp_tissue *= float_saturation_multiplier; -} - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -// ** THE JUMP-IN CODE ** -// ** for the asm code ** -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////////// -// Called every second during diving. -// updates tissues every second invocation. -// -// Every few seconds (or slower when TTS > 16): -// - updates deco table (char_O_deco_time/depth) with new values. -// - updates ascent time, -// - sets status to zero (so we can check there is new results). -// -void deco_calc_hauptroutine(void) -{ - RESET_C_STACK - calc_hauptroutine(); -} - -////////////////////////////////////////////////////////////////////////////// -// Reset decompression model: -// + Set all tissues to equilibrium with Air at ambient pressure. -// + Reset last stop to 0m -// + Reset all model output. -void deco_clear_tissue(void) -{ - RESET_C_STACK - clear_tissue(); -} - -////////////////////////////////////////////////////////////////////////////// - -void deco_calc_wo_deco_step_1_min(void) -{ - RESET_C_STACK - calc_wo_deco_step_1_min(); - } - -////////////////////////////////////////////////////////////////////////////// - -void deco_calc_desaturation_time(void) -{ - RESET_C_STACK - calc_desaturation_time(); -} - -////////////////////////////////////////////////////////////////////////////// - -void deco_calc_dive_interval(void) -{ - RESET_C_STACK - calc_dive_interval(); -} - -////////////////////////////////////////////////////////////////////////////// -// Find current gas in the list (if any) and get its change depth -// -// Input: char_I_current_gas : 1..6 -// -// Output: sim_gas_last_used : 1..6 or 0 if it is the gas set as FIRST -// sim_gas_last_depth : change depth in meters or 0 if it is the gas set as FIRST -// -static void gas_find_current(void) -{ - assert( 0 <= char_I_current_gas && char_I_current_gas <= NUM_GAS ); - - if( char_I_current_gas <= NUM_GAS ) // Gas1..Gas5 - { - sim_gas_last_used = sim_gas_first_used = char_I_current_gas; - - // If current gas is a deco gas get it's change depth. - // Set change depth to 0 if the current gas is the first gas or - // a travel/normal gas, i.e. if it can be breathed at "any" depth. - if( char_I_deco_gas_change[sim_gas_last_used-1] ) sim_gas_last_depth = char_I_deco_gas_change[sim_gas_last_used-1]; - else sim_gas_last_depth = 0; - } - else - { - sim_gas_last_used = sim_gas_first_used = 0; // Gas 6 (the manually set one) has number 0 here - sim_gas_last_depth = 0; // handle it as a travel/normal gas - } -} - - -////////////////////////////////////////////////////////////////////////////// -// Find the deco gas with the shallowest change depth beyond current depth -// -// INPUT temp_depth_limit : current depth in meters -// char_I_deco_gas_change[] : change depths of the deco gases -// sim_gas_last_depth : change depth of the currently used gas, 0 if on the gas set as FIRST -// -// OUTPUT sim_gas_last_depth : switch depth - only if return value is true -// sim_gas_last_used : index of the gas (1..5) - only if return value is true -// -// RETURNS TRUE if a better gas is available -// -static unsigned char gas_find_better(void) -{ - overlay unsigned char switch_depth = 255; - overlay unsigned char switch_gas = 0; - overlay unsigned char j; - - - // no automatic gas changes in CCR mode and - as of now - in pSCR mode - if( char_O_deco_status & DECO_MODE_LOOP ) return 0; - - // Loop over all deco gases to find the shallowest one below or at current depth. - for(j=0; j<NUM_GAS; ++j) - { - // Is this the gas we are already breathing? - // If yes, skip this gas. - if( j+1 == sim_gas_last_used ) continue; - - // Is the change depth of the gas shallower than the current depth? - // If yes, skip this gas as it is not to be used yet. - // Remark: this check will also skip all disabled gases and the gas set - // as 'first' because these have their change depth set to 0. - if( temp_depth_limit > char_I_deco_gas_change[j] ) continue; - - // Is the change depth of the gas deeper than the change depth of the - // gas we are currently one? - // If yes, skip this gas as it is not better than the current one. - // Remark: if there is more than one gas with the same change depth, - // the last one from the list will be taken. - if( sim_gas_last_depth && (char_I_deco_gas_change[j] > sim_gas_last_depth) ) continue; - - // Is the change depth of the gas shallower or equal to the change depth - // of the best gas found so far, or is it the first better gas found? - // If yes, we have a better gas - if( char_I_deco_gas_change[j] <= switch_depth ) - { - switch_gas = j+1; // remember this gas (1..5) - switch_depth = char_I_deco_gas_change[j]; // remember its change depth - } - } // continue looping through all gases to eventually find an even better gas - - // has a better gas been found? - if( switch_gas ) - { - // yes - sim_gas_last_used = switch_gas; // report the index of the better - sim_gas_last_depth = switch_depth; // report its change depth - - assert( sim_gas_last_depth < switch_depth ); - - return 1; // signal a better gas was found - } - else - { - return 0; // signal no better gas was found - } -} - -////////////////////////////////////////////////////////////////////////////// -// Set calc_N2/He/O2_ratios by sim_gas_last_used -// -// Input: sim_gas_last_used : index of gas to use -// N2_ratio, He_ratio : if gas 0 = the manually set gas is in use -// -// Output: calc_N2_ratio, calc_He_ratio, calc_O2ratio -// -static void gas_switch_set(void) -{ - assert( 0 <= sim_gas_last_used <= NUM_GAS ); - - if( sim_gas_last_used == 0 ) // Gas6 = manually set gas. - { - calc_O2_ratio = O2_ratio; - calc_He_ratio = He_ratio; - } - else - { - calc_O2_ratio = char_I_deco_O2_ratio[sim_gas_last_used-1] * 0.01; - calc_He_ratio = char_I_deco_He_ratio[sim_gas_last_used-1] * 0.01; - } - - calc_N2_ratio = 1.0 - calc_O2_ratio - calc_He_ratio; - - assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); - assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 1.00 ); - assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); -} - -////////////////////////////////////////////////////////////////////////////// -// Compute ppN2 and ppHe -// -// Input: calc_N2_ratio, calc_He_ratio : simulated gas mix. -// temp_deco : simulated respiration pressure -// float_deco_distance : safety factor -// ppWater : water-vapor pressure inside respiratory tract -// -// Output: ppN2, ppHe. -// -static void sim_alveolar_presures(void) -{ - overlay float deco_diluent = temp_deco; - - // read ppO2 reported from sensors or by setpoint // TODO: can be deleted - // char_actual_ppO2 = char_I_const_ppO2; - - - // Take deco offset into account, but not at surface. - // Note: this should be done on ambient pressure, hence before - // computing the diluent partial pressure... - if( deco_diluent > pres_surface ) deco_diluent += float_deco_distance; - - if( char_O_deco_status & DECO_MODE_LOOP ) - { - //---- Loop mode : adjust ppN2 and ppHe for change in ppO2 due to setpoint (CCR) or drop (pSCR)------- - - // get current setpoint (CCR) or sensor value (CCR, for pSCR see text below) as default - overlay float const_ppO2 = char_I_const_ppO2 * 0.01; - - if( char_O_deco_status & DECO_MODE_PSCR ) - { - //---- PSCR mode : compute loop gas ---------------------------------------- - // - // As the ppO2 in the loop changes with water depth, we can not use the current - // sensor value as with CCR mode, but need to compute the ppO2 for the given depth. - // Then we continue with the CCR mode code which calculates the increases of ppN2 - // and ppH2 due to the reduction of the ppO2 in the loop. Essentially, diving a - // PSCR is like diving a CCR with a setpoint lower than the ambient pressure x the - // O2 fraction of the diluent would yield... - // - - // deco_diluent is 0.0 ... in bar - // calc_O2_ratio is 0.0 ... 1 as factor - // char_I_PSCR_drop is 0 ... 15 as % - // char_I_PSCR_lungratio is 5 ... 20 as % - // const_ppO2 is 0.0 ... in bar - - const_ppO2 = (deco_diluent * calc_O2_ratio) - (1 - calc_O2_ratio) * 0.01 * char_I_PSCR_drop * char_I_PSCR_lungratio; - - // capture failure condition - if( const_ppO2 < 0.0 ) const_ppO2 = 0.0; - } - else - { - - //---- CCR mode ------------------------------------------------------------ - - // Limit the setpoint to the maximum physically possible ppO2. This prevents for - // example calculating with a setpoint of 1.3 bar in only 2 meters of depth. - // Additionally, if limiting occurs, the ppO2 can be further reduced to account - // for residual inert gases by the user-adjustable setting char_I_cc_max_frac_o2. - - if( const_ppO2 > deco_diluent ) // no ppWater subtracted here to give some margin for - { // sensors delivering data a little bit over target - - const_ppO2 = 0.01 * char_I_cc_max_frac_o2 * (deco_diluent - ppWater); - } - } - - if ( const_ppO2 == 0.0 ) char_actual_ppO2 = 0; - else if ( const_ppO2 > 2.545 ) char_actual_ppO2 = 255; - else char_actual_ppO2 = (unsigned char)(const_ppO2*100 + 0.5); - - // Note: ppO2 and ratios are known outside the lungs, so there is no ppWater in the equations below: - deco_diluent -= const_ppO2; - deco_diluent /= calc_N2_ratio + calc_He_ratio; - - // capture all failure conditions, including div/0 in case diluent is pure O2 - if( (deco_diluent < 0.0) || (calc_O2_ratio > 99.5) ) - { - deco_diluent = 0.0; - - char_actual_ppO2 = (unsigned char)(temp_deco*100 + 0.5); // without float_deco_distance here as this situation - // is likely to occur only at 6 meters or shallower - } - } - else - { - //---- OC mode: char_actual_ppO2 will be needed for CNS calculation later -------------------------------- - - overlay float ppO2 = pres_respiration * calc_O2_ratio; - - if ( ppO2 > 2.545 ) char_actual_ppO2 = 255; - else char_actual_ppO2 = (unsigned char)(ppO2*100 + 0.5); - } - - - if( deco_diluent > ppWater ) - { - ppN2 = calc_N2_ratio * (deco_diluent - ppWater); - ppHe = calc_He_ratio * (deco_diluent - ppWater); - } - else - { - ppN2 = 0.0; - ppHe = 0.0; - } - - assert( 0.0 <= ppN2 && ppN2 < 14.0 ); - assert( 0.0 <= ppHe && ppHe < 14.0 ); -} - -////////////////////////////////////////////////////////////////////////////// -// clear_tissue -// -// optimized in v.101 (var_N2_a) -// -// preload tissues with standard pressure for the given ambient pressure. -// Note: fixed N2_ratio for standard air. -// -static void clear_tissue(void) -{ - pres_respiration = 0.001 * int_I_pres_respiration; - N2_equilibrium = 0.7902 * (pres_respiration - ppWater); - - for(ci=0; ci<NUM_COMP; ci++) - { - // cycle through the 16 Buhlmann N2 tissues - pres_tissue_N2[ci] = N2_equilibrium; // initialize data for "real" tissue - char_O_tissue_N2_saturation[ci] = 11; // initialize data for tissue graphics - - - // cycle through the 16 Buhlmann He tissues - pres_tissue_He[ci] = 0.0; // initialize data for "real" tissue - char_O_tissue_He_saturation[ci] = 0; // initialize data for tissue graphics - } - - clear_CNS_fraction(); - - clear_deco_table(); - - char_O_main_status = 0; - char_O_deco_status = 0; - char_O_nullzeit = 0; - char_O_gtissue_no = 0; - char_O_deco_warnings = 0; - - int_O_ascenttime = 0; - int_O_gradient_factor = 0; - - calc_lead_tissue_limit = 0.0; -} - -////////////////////////////////////////////////////////////////////////////// -// calc_hauptroutine -// -// this is the major code in dive mode calculates: -// the tissues, -// the bottom time, -// and simulates the ascend with all deco stops. -// -// -static void calc_hauptroutine(void) -{ - unsigned int int_ppO2_min; - unsigned int int_ppO2_max; - - - //--- set-up part -------------------------------------------------------------------------------- - - // twosectimer: - // calc_hauptroutine is now invoked every second to speed up the deco planning. - // Because the tissue and CNS calculations are based on a 2 seconds period, the - // the following toggle-timer will be used by the respective routines to skip - // every 2nd invocation. - twosectimer = (twosectimer) ? 0 : 1; // toggle the toggle-timer - - - // set up normal tissue updating or "fast forward" updating for simulator sim+5' function - // and deco calculator bottom time calculation - if( char_I_sim_advance_time > 0 ) - { - // configure char_I_sim_advance_time minutes of tissue updating - tissue_increment = char_I_sim_advance_time // given number of minutes, limited to 127 - | 128; // set flag for updating the "real" tissues & CNS - - char_I_sim_advance_time = 0; // clear "mailbox" - } - else - { - // configure 2 seconds of tissue updating - tissue_increment = 0 // encoding for 2 seconds update - | 128; // set flag for updating the "real" tissues & CNS - } - - //---- calculate the real tissue's data ----------------------------------------------------------------- - - calc_hauptroutine_data_input(); // acquire current environment data - - calc_hauptroutine_update_tissues(); // update tissue pressures, also sets char_actual_ppO2 - - calc_CNS_fraction(); // calculate CNS% for the real tissues - - compute_CNS_for_display(); // compute integer copy of CNS value for display purpose - - calc_gradient_factor(); // compute current GF - - - //---- compute ppO2 warnings ------------------------------------------------------------------------------ - - // compute conditional min/max values - int_ppO2_min = (char_O_main_status & DECO_MODE_LOOP) ? (unsigned int)char_I_ppO2_min_loop : (unsigned int)char_I_ppO2_min; - int_ppO2_max = (char_O_deco_warnings & DECO_FLAG ) ? (unsigned int)char_I_ppO2_max_deco : (unsigned int)char_I_ppO2_max; - - // check for safe range of pure oxygen - if ( int_O_O2_ppO2 >= int_ppO2_max ) int_O_O2_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; - - // check for safe range of breathed gas - if ( int_O_breathed_ppO2 <= int_ppO2_min ) int_O_breathed_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; - else if ( int_O_breathed_ppO2 >= int_ppO2_max ) int_O_breathed_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; - else if ( int_O_breathed_ppO2 >= ppO2_prewarn_threshold ) int_O_breathed_ppO2 |= INT_FLAG_PREWARNING; - - // check for safe range of pure diluent - if ( int_O_pure_ppO2 <= (unsigned int)char_I_ppO2_min ) int_O_pure_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; - else if ( int_O_pure_ppO2 >= int_ppO2_max ) int_O_pure_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; - - // check for safe range of calculated pSCR loop gas - if ( int_O_pSCR_ppO2 <= int_ppO2_min ) int_O_pSCR_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; - else if ( int_O_pSCR_ppO2 >= int_ppO2_max ) int_O_pSCR_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; - - - //---- toggle between calculation for NDL (bottom time), deco stops and more deco stops (continue) ------ - - switch( char_O_deco_status & DECO_STATUS_MASK ) - { - overlay unsigned char i; - - case DECO_STATUS_INIT: //---- At surface: start a new dive --------------------- - - clear_deco_table(); - copy_deco_table(); - - char_I_ascent_speed = 10; // DEBUG - remove before flight! - char_I_gas_change_time = 1; // DEBUG - remove before flight! - - float_ascent_speed = 1.00 * char_I_ascent_speed; - float_desaturation_multiplier = 0.01 * char_I_desaturation_multiplier; - float_saturation_multiplier = 0.01 * char_I_saturation_multiplier; - float_deco_distance = 0.01 * char_I_deco_distance; - - int_O_ascenttime = 0; // Reset ascent time in normal plan - int_O_alternate_ascenttime = 0; // Reset ascent time in alternative plan - char_O_nullzeit = 0; // Reset no decompression limit (NDL) in normal plan - char_O_alternate_nullzeit = 0; // Reset no decompression limit (NDL) in alternative plan - char_O_deco_warnings = 0; // Reset all deco warning flags - deco_tissue_vector = 0; // Reset tissue deco vector - IBCD_tissue_vector = 0; // Reset tissue IBCD vector - - int_O_desaturation_time = 65535; // tag desaturation time as invalid (it will not be computed during a dive) - - - for(i=0; i<NUM_GAS; ++i) - { - int_O_gas_volumes[i] = 0; - int_O_tank_pres_need[i] = 0 + INT_FLAG_ZERO; // 0 bar + flag for 0 bar - } - - for(i=0; i<NUM_COMP; ++i) - { - split_N2_He[i] = 90; // used for calculation of no-fly time - } - - - // init CNS counters - CNS_sim_norm_fraction = CNS_sim_alt_fraction = CNS_fraction; // the floats - int_O_normal_CNS_fraction = int_O_alternate_CNS_fraction = int_O_CNS_fraction; // the integers - - - // Values that should be reset just once for the full real dive. - // This is used to record the lowest stop for the whole dive, - // including ACCROSS all simulated ascents. - low_depth_norm = low_depth_alt = 0.0; - locked_GF_step_norm = locked_GF_step_alt = 0.0; - - - // continue in state DECO_STATUS_START to calculate the bottom-part of the dive and the NDL - char_O_deco_status &= ~DECO_STATUS_MASK; - - // code execution continues in state DECO_STATUS_START - - - case DECO_STATUS_START: //---- bottom time ------------------------------------- - default: - - // reread the GF settings in case there was a switch between GF/aGF - GF_low = char_I_GF_Low_percentage * 0.01; - GF_high = char_I_GF_High_percentage * 0.01; - GF_delta = GF_high - GF_low; - - // Lookup current gas and store it also as the first gas used. This gas will be used for the bottom - // segment of the dive and for the period of delayed ascent when calculating fTTS or bailout. - gas_find_current(); - - // setup the calculation ratio's for N2, He and O2 - gas_switch_set(); - - // clear the internal(!) stops table - clear_deco_table(); - - // initialize the simulated tissues with the current state of the real tissues - update_startvalues(); - - // calculate the effect of extended bottom time due to delayed ascent / fTTS on current gas - if( char_O_deco_status & DECO_ASCENT_DELAYED ) sim_extra_time(); - - // calculate if we are within no decompression limit (NDL) - calc_nullzeit(); - - // check which plan we are on - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) - { - // alternate dive plan - if( char_O_alternate_nullzeit > 0 ) // Some NDL time left in alternate plan? - { - copy_deco_table(); // DEBUG to be removed again - - // clear tank pressure needs - if( char_O_deco_status & DECO_VOLUME_CALCULATE ) - for(i=0; i<NUM_GAS; ++i) int_O_tank_pres_need[i] = 0 + INT_FLAG_ZERO; // 0 bar + flag for 0 bar - - // calculate the CNS% at the end of the dive if requested: - // as we are in no stop, CNS at end of dive is more or less the same CNS we have now - if( char_O_deco_status & DECO_CNS_CALCULATE ) int_O_alternate_CNS_fraction = int_O_CNS_fraction; - - // clear fTTS ascent time - int_O_alternate_ascenttime = 0; - - char_O_deco_status &= ~DECO_STATUS_MASK; // YES: computation of alternate plan completed - } - else - { - char_O_deco_status &= ~DECO_STATUS_MASK; // NO: clear status bits and set status bits - char_O_deco_status |= DECO_STATUS_ASCENT; // for calculation of ascent on next invocation - } - } - else - { - // normal dive plan - if( char_O_nullzeit > 0 ) // Some NDL time left in normal plan? - { - //copy_deco_table(); DEBUG original - comment in again // copy (erased) internal to external stops table - - // commented out - char_O_deco_last_stop not used for anything - // char_O_deco_last_stop = 0; // set last stop to 0 (for OSTC menu animation) - - // clear tank pressure needs - if( char_O_deco_status & DECO_VOLUME_CALCULATE ) - for(i=0; i<NUM_GAS; ++i) int_O_tank_pres_need[i] = 0 + INT_FLAG_ZERO; // 0 bar + flag for 0 bar - - // calculate the CNS% at the end of the dive if requested: - // as we are in no stop, CNS at end of dive is more or less the same CNS we have now - if( char_O_deco_status & DECO_CNS_CALCULATE ) int_O_normal_CNS_fraction = int_O_CNS_fraction; - - char_O_deco_status &= ~DECO_STATUS_MASK; // computation of normal plan completed - } - else - { - char_O_deco_status &= ~DECO_STATUS_MASK; // clear status bits and set status bits - char_O_deco_status |= DECO_STATUS_ASCENT; // for calculation of ascent on next invocation - } - } - - break; - - - case DECO_STATUS_ASCENT: //---- Simulate ascent to first stop ------------------- - - // initialize depth (in abs.pressure) for ascent and deco simulation, start from current real depth - temp_deco = pres_respiration; - - // calculate ascent to first stop - sim_ascent_to_first_stop(); - - // calculate all further stops next time - char_O_deco_status &= ~DECO_STATUS_MASK; // clear status bits and set status bits - char_O_deco_status |= DECO_STATUS_STOPS; // for calculation of stops on next invocation - - break; - - - case DECO_STATUS_STOPS: //---- Simulate stops ---------------------------------- - - calc_hauptroutine_calc_deco(); - - // If simulation is finished, do some more computations if requested - // and restore the GF low reference so that the next ascent simulation - // is done from the current depth: - if( !(char_O_deco_status & DECO_STATUS_MASK) ) - { - // Calculate ascent time, result in int_O_ascenttime or int_O_alternate_ascenttime - calc_ascenttime(); - - // the current depth is needed by calc_CNS_planning() and gas_volumes() - char_I_bottom_depth = (unsigned char)((pres_respiration - pres_surface)*BAR_TO_METER); - - // if requested, calculate the CNS% at the end of the dive (including the deco stops) - if( char_O_deco_status & DECO_CNS_CALCULATE ) calc_CNS_planning(); - - // if requested, calculate the required gas volumes and tank pressures at the end of the dive. - if( char_O_deco_status & DECO_VOLUME_CALCULATE ) gas_volumes(); - - // some more aftermath dependent on the current plan - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) - { - //---- alternative plan ---------------------------------------------------- - -copy_deco_table(); // DEBUG to be removed again - - // was CNS at end of dive calculated? - if( char_O_deco_status & DECO_CNS_CALCULATE ) - { - // yes - compute CNS value to display - if ( CNS_sim_alt_fraction < 0.01 ) int_O_alternate_CNS_fraction = 0; - else if ( CNS_sim_alt_fraction > 9.985 ) int_O_alternate_CNS_fraction = 999 + INT_FLAG_WARNING; - else - { - // convert float to integer - int_O_alternate_CNS_fraction = (unsigned short)(100 * CNS_sim_alt_fraction + 0.5); - - // set warning flag if CNS is >= 100% - if( int_O_alternate_CNS_fraction >= 100 ) - int_O_alternate_CNS_fraction |= INT_FLAG_WARNING; - - // set invalid flag if there is an overflow in the stops table - if( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) - int_O_alternate_CNS_fraction |= INT_FLAG_INVALID; - } - } - else - { - // no - invalidate value (value = 0, invalid flag set) - int_O_alternate_CNS_fraction = INT_FLAG_INVALID; - } - } - else - { - //---- normal plan --------------------------------------------------------- - - // publish the stops table -// copy_deco_table(); // DEBUG original - - // was CNS at end of dive calculated? - if( char_O_deco_status & DECO_CNS_CALCULATE ) - { - // yes - compute CNS value to display - if ( CNS_sim_norm_fraction < 0.01 ) int_O_normal_CNS_fraction = 0; - else if ( CNS_sim_norm_fraction >= 9.985 ) int_O_normal_CNS_fraction = 999 + INT_FLAG_WARNING; - else - { - // convert float to integer - int_O_normal_CNS_fraction = (unsigned short)(100 * CNS_sim_norm_fraction + 0.5); - - // set warning flag if CNS is >= 100% - if( int_O_normal_CNS_fraction >= 100 ) - int_O_normal_CNS_fraction |= INT_FLAG_WARNING; - - // set invalid flag if there is an overflow in the stops table - if( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) - int_O_normal_CNS_fraction |= INT_FLAG_INVALID; - } - } - else - { - // no - invalidate value (value = 0, invalid flag set) - int_O_normal_CNS_fraction = INT_FLAG_INVALID; - } - - } // aftermath - } // if - - break; - - } // switch -} - -////////////////////////////////////////////////////////////////////////////// -// calc_hauptroutine_data_input -// -// Reset all C-code dive parameters from their ASM-code values. -// Detect gas change condition. -// -void calc_hauptroutine_data_input(void) -{ - // get the current pressures - pres_respiration = 0.001 * int_I_pres_respiration; - pres_surface = 0.001 * int_I_pres_surface; - - // get the currently breathed gas mixture - O2_ratio = 0.01 * char_I_O2_ratio; - He_ratio = 0.01 * char_I_He_ratio; - - // N2 ratios are computed within p2_deco.c from the O2 and He ratios - N2_ratio = 1.0 - O2_ratio - He_ratio; - - // N2 tissue pressure at surface equilibrium, used for tissue graphics scaling - N2_equilibrium = 0.7902 * (pres_surface - ppWater); -} - -////////////////////////////////////////////////////////////////////////////// -// -// -void calc_hauptroutine_update_tissues(void) -{ - overlay float pres_diluent = pres_respiration; - - - assert( 0.00 <= N2_ratio && N2_ratio <= 1.00 ); - assert( 0.00 <= He_ratio && He_ratio <= 1.00 ); - assert( (N2_ratio + He_ratio) <= 1.00 ); - assert( 0.800 < pres_respiration && pres_respiration < 14.0 ); - - - //---- OC, CCR and Bailout Mode Gas Calculations ------------------------------------------------------------ - - // calculate ppO2 of pure oxygen - O2_ppO2 = (pres_respiration - ppWater); - - // capture failure condition in case pres_respiration is < ppWater (should never happen...) - if( O2_ppO2 < 0.0 ) O2_ppO2 = 0.0; - - // calculate ppO2 of the pure gas (diluent) - pure_ppO2 = O2_ppO2 * O2_ratio; - - - //---- PSCR Mode Gas Calculation----------------------------------------------------------- - - // With flags set for PSCR we compute the ppO2 in the loop from the diluent's O2 - // ratio and the PSCR parameters. This figure will be used in the pSCR custom view. - // If sensors are used (char_I_const_ppO2 > 0), we will override the calculated ppO2 - // with the sensor data. Then we continue with the CCR mode code which calculates - // the increase of ppN2 and ppH2 due to the reduction of the ppO2 in the loop. - // Essentially, diving a pSCR is like diving a CCR with a setpoint set lower than - // the ambient pressure multiplied with the O2 fraction of the diluent... - - // calculate pSCR ppO2 - // - // pres_respiration is 0.0 ... in bar - // O2_ratio is 0.0 ... 1.0 as factor - // char_I_PSCR_drop is 0 ... 15 as % - // char_I_PSCR_lungratio is 5 ... 20 as % - // pSCRppO2 is 0.0 ... in bar - - pSCR_ppO2 = (pres_respiration * O2_ratio) - (1 - O2_ratio) * 0.01 * char_I_PSCR_drop * char_I_PSCR_lungratio; - - // capture failure condition if case pSCR_ppO2 becomes negative - if( pSCR_ppO2 < 0.0 ) pSCR_ppO2 = 0.0; - - - //---- Loop modes : adjust ppN2 and ppHe for change in ppO2 due to setpoint (CCR) or drop (pSCR) ------------ - if ( char_O_main_status & DECO_MODE_LOOP ) - { - overlay float const_ppO2; - - // get the current sensor reading (CCR / pSCR if fitted) or the fixed setpoint (CCR) / a zero (pSCR) - const_ppO2 = 0.01 * char_I_const_ppO2; - - // Limit the setpoint to the maximum physically possible ppO2. This prevents for - // example calculating with a setpoint of 1.3 bar in only 2 meters of depth. - // Additionally, if limiting occurs, the ppO2 can be further reduced to account - // for residual inert gases by the user-adjustable setting char_I_cc_max_frac_o2. - - if( const_ppO2 > pres_respiration ) // no ppWater subtracted here to give some margin for - { // sensors delivering data a little bit over target - - const_ppO2 = 0.01 * char_I_cc_max_frac_o2 * (pres_respiration - ppWater); - } - - // check which kind of loop we are on - if( char_O_main_status & DECO_MODE_PSCR ) - { - //---- pSCR Mode -------------------------------------------------------------------------- - - // check if a sensor is fitted - if( char_I_const_ppO2 ) breathed_ppO2 = const_ppO2; // yes - derive ppO2s from (char_I_)const_ppO2 - else breathed_ppO2 = pSCR_ppO2; // no - derive ppO2s from calculated ppO2 - } - else - { - //---- CCR Mode --------------------------------------------------------------------------- - - // derive breathed ppO2 from (char_I_)const_ppO2, which holds sensor reading or fixed setpoint - breathed_ppO2 = const_ppO2; - } - - // adjust diluent pressure (ppN2 + ppHe) for change in ppO2 due to setpoint (CCR) or drop (pSCR) - pres_diluent -= const_ppO2; - pres_diluent /= N2_ratio + He_ratio; - - // capture all failure conditions, including div/0 in case diluent is pure O2 - if( (pres_diluent < 0.0) || (char_I_O2_ratio == 100) ) - { - pres_diluent = 0.0; - breathed_ppO2 = pure_ppO2; - } - - } - else - { //---- OC mode ----------------------------------------------------------------------------------------- - - // breathed ppO2 is ppO2 of pure gas - breathed_ppO2 = pure_ppO2; - } - - - // derive char_actual_ppO2 in [cbar], used for calculating CNS% - if ( breathed_ppO2 < 0.01 ) char_actual_ppO2 = 0; - else if ( breathed_ppO2 >= 2.545 ) char_actual_ppO2 = 255; - else char_actual_ppO2 = (unsigned char)(100 * breathed_ppO2 + 0.5); - - - //---- export ppO2 values in [cbar] for warning generation and display purpose ------------------------------ - - // pure oxygen ppO2 - if ( O2_ppO2 < 0.01 ) int_O_O2_ppO2 = 0; - else if ( O2_ppO2 >= 9.995 ) int_O_O2_ppO2 = 999; - else int_O_O2_ppO2 = (unsigned int)(100 * O2_ppO2 + 0.5); - - // pure gas ppO2 - if ( pure_ppO2 < 0.01 ) int_O_pure_ppO2 = 0; - else if ( pure_ppO2 >= 9.995 ) int_O_pure_ppO2 = 999; - else int_O_pure_ppO2 = (unsigned int)(100 * pure_ppO2 + 0.5); - - // calculated pSCR ppO2 - if ( pSCR_ppO2 < 0.01 ) int_O_pSCR_ppO2 = 0; - else if ( pSCR_ppO2 >= 9.995 ) int_O_pSCR_ppO2 = 999; - else int_O_pSCR_ppO2 = (unsigned int)(100 * pSCR_ppO2 + 0.5); - - // breathed ppO2 - if ( breathed_ppO2 < 0.01 ) int_O_breathed_ppO2 = 0; - else if ( breathed_ppO2 >= 9.995 ) int_O_breathed_ppO2 = 999; - else int_O_breathed_ppO2 = (unsigned int)(100 * breathed_ppO2 + 0.5); - - - //---- calculate ppN2, ppHe and EAD, END ------------------------------------------------------------------- - - if( pres_diluent > ppWater ) - { - overlay float EAD, END; - - ppN2 = N2_ratio * (pres_diluent - ppWater); - ppHe = He_ratio * (pres_diluent - ppWater); - - // EAD : Equivalent Air Depth. Equivalent depth for the same N2 level with plain air. - // ppN2 = 79% * (P_EAD - ppWater) - // EAD = (P_EAD - Psurface) * 10 - // ie: EAD = (ppN2 / 0.7902 + ppWater -Psurface) * 10 - - EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * BAR_TO_METER; - - if( (EAD < 0.0) || (EAD > 245.5) ) EAD = 0.0; - - char_O_EAD = (unsigned char)(EAD + 0.5); - - - // END : Equivalent Narcotic Depth. - // Here we count O2 as narcotic too. Hence everything but helium (has a narcosis - // factor of 0.23 btw). Hence the formula becomes: - // END * BarPerMeter * (1.0 - 0.0) - ppWater + Psurface == Pambient - ppHe - ppWater - // ie: END = (Pambient - ppHe - Psurface) * BAR_TO_METER - // - // Source cited: - // The Physiology and Medicine of Diving by Peter Bennett and David Elliott, - // 4th edition, 1993, W.B.Saunders Company Ltd, London. - - END = (pres_respiration - ppHe - pres_surface) * BAR_TO_METER; - - if( (END < 0.0) || (END > 245.5) ) END = 0.0; - - char_O_END = (unsigned char)(END + 0.5); - } - else - { - ppN2 = ppHe = 0.0; - - char_O_EAD = char_O_END = 0; - } - - - //---- calculate decompression status ---------------------------------------------------------------------- - - // Calculate tissues - calc_tissue(); - - // Calculate limit for surface, ie. GF_high. - calc_limit(); - - - // Fill int_O_ceiling (in mbar) if ceiling is below the surface - if( (calc_lead_tissue_limit - pres_surface) > 0 ) - { - -// compatibility version - int_O_ceiling = (short)((calc_lead_tissue_limit - pres_surface) * 1000); - -// new version -// // Round up to next 10 cm so that the ceiling disappears on the display only when the ceiling -// // limit is really zero. This will coincident then with TTS switching back to NDL time. -// int_O_ceiling = (short)((calc_lead_tissue_limit-pres_surface)*1000+9); - - - // limit int_O_ceiling to 16000 mbar (150 m) - if( int_O_ceiling > 16000) int_O_ceiling = 16000; - } - else - { - int_O_ceiling = 0; - } - - int_O_gtissue_press = (short)((pres_tissue_N2[char_O_gtissue_no] + pres_tissue_He[char_O_gtissue_no]) * 1000); -} - - -////////////////////////////////////////////////////////////////////////////// -// Compute stops. -// -// Note: because this can be very long, break on 16 iterations, and set state -// to DECO_STATUS_FINISHED when finished, or to DECO_STATUS_STOPS when -// needing to continue. -// Note: because each iteration might be very long too (~ 66 ms in 1.84beta), -// break the loop when elapsed time exceeds 512 milliseconds. -// -void calc_hauptroutine_calc_deco(void) -{ - overlay unsigned char loop; - - for(loop = 0; loop < 16; ++loop) - { - // limit loops to 512ms, using timer 5 - if( tmr5() & (512*32) ) break; - - // calc_nextdecodepth() - // - // INPUT temp_deco : current depth in absolute pressure - // OUTPUT temp_depth_limit : depth of next stop in meters - // RETURN true if a stop is needed - // - // The function manages gas changes by itself, including priming - // the deco stop with the configured gas change time. - // - if( calc_nextdecodepth() ) - { - if( temp_depth_limit == 0 ) goto Surface; // this check should not bee needed as in - // this case the RETURN value will be false - - //---- stop required at temp_depth_limit ------------------------------------- - - // convert stop depth in meters to absolute pressure - temp_deco = temp_depth_limit * METER_TO_BAR + pres_surface; - - // add one minute to the current stop, or add a new stop, - // or abort deco calculation if the deco table is full. - if( !update_deco_table(1) ) goto Surface; - } - else - { - //---- no stop required -------------------------------------- - - // ascend by float_ascent_speed for 1 minute - temp_deco -= float_ascent_speed * METER_TO_BAR; - - // finish deco calculation if surface is reached - if( temp_deco <= pres_surface ) - { -Surface: - // set deco engine status to done (DECO_STATUS_FINISHED) - char_O_deco_status &= ~DECO_STATUS_MASK; - - // commented out - char_O_deco_last_stop not used for anything - // surface reached (to animate menu) - // if( !(char_O_deco_status & DECO_PLAN_ALTERNATE)) char_O_deco_last_stop = 0; - - return; - } - } - - - //---- as one minute as passed now, update the tissues ---------------------- - - // program 1 minute interval on simulated tissues (Flagbit 7 = 0) - tissue_increment = 1; - - // compute current ppN2 and ppHe - sim_alveolar_presures(); - - // update the tissues - calc_tissue(); - } - - // commented out - char_O_deco_last_stop not used for anything - // surface not reached, need more stops... store reached depth for menu animation. - // if( !(char_O_deco_status & DECO_PLAN_ALTERNATE) ) char_O_deco_last_stop = temp_depth_limit; -} - - -////////////////////////////////////////////////////////////////////////////// -// Simulate ascent to first deco stop. -// -// -// Modified: temp_deco : current depth in ascent and deco simulation, in bar absolute pressure -// -void sim_ascent_to_first_stop(void) -{ - overlay unsigned char fast = 1; // 1 = 1 minute steps, 0 = 2 seconds steps - overlay unsigned char gaschange = 0; // 1 = do a gas change, 0 = no better gas available - - - //---- Loop until first deco stop or surface is reached ---------- - for(;;) - { - // depth in absolute pressure we came from - overlay float old_deco = temp_deco; - - // try ascending 1 full minute (fast) or 2 seconds (!fast) - if ( fast ) temp_deco -= float_ascent_speed * METER_TO_BAR; // 1 min at float_ascent_speed ( 5 .. 10 m/min) - else temp_deco -= (float_ascent_speed/30.0) * METER_TO_BAR; // 2 sec at float_ascent_speed (17 .. 33 cm/min) - - // but don't go over surface - if( temp_deco < pres_surface ) temp_deco = pres_surface; - - // compute sim_lead_tissue_limit - if ( char_I_deco_model != 0 ) sim_limit(GF_low); - else sim_limit(1.0); - - // did we overshoot the first deco stop? - if( temp_deco < sim_lead_tissue_limit ) - { - // YES - back to last depth below first stop - temp_deco = old_deco; - - // switch to 2 seconds ascent if not yet in, else done - if( fast ) - { - fast = 0; // retry with 2 seconds ascent steps - continue; - } - else - { - break; // done... - } - } - - // If code execution passes along here, we did not overshoot the first stop. - - // did we reach the surface? if yes, done! - if( temp_deco == pres_surface ) break; - - // depth in meters where we are now (no round-up) - temp_depth_limit = (unsigned char)((temp_deco - pres_surface) * BAR_TO_METER); - - // Check if there is a better gas to switch to, but only in alternative plan mode. - // If yes, introduce a stop for the gas change. - if( (char_O_deco_status & DECO_PLAN_ALTERNATE) && gas_find_better() ) - { - // depth in meters we came from - overlay unsigned char old_depth_limit = (unsigned char)((old_deco - pres_surface) * BAR_TO_METER); - - // adjust temp_depth_limit to the gas change depth, but not deeper than the depth we came from - temp_depth_limit = (sim_gas_last_depth < old_depth_limit) ? sim_gas_last_depth : old_depth_limit; - - // create a stop for the gas change - update_deco_table(char_I_gas_change_time); - - // set the new calculation values for N2, He and O2 - gas_switch_set(); - - // signal to create a stop for the gas change and update the tissues - gaschange = char_I_gas_change_time; - - // Adjust the depth for the tissue update to the stop depth. In case of fast mode, this - // imposes that the ascent from the 'old_deco' depth to this stop took 1 minute although - // we might have only ascended one or two meters... - temp_deco = temp_depth_limit * METER_TO_BAR + pres_surface; - } - - // Did one minute pass by and/or do we have a gas change? - // Remark: The 2 seconds ascent iterations towards the first deco stop in !fast speed may take - // up to 28 seconds in total - for this rough half of a minute no tissue updates will be computed. - // Well, it could be done by setting tissue_increment = 0 in !fast condition and making calls to - // sim_alveolar_presures() and calc_tissue() - see code commented out. - if( fast || gaschange ) - { - // program interval on simulated tissues (flag bit 7 = 0) - tissue_increment = fast + gaschange; - - // clear gas change signal - gaschange = 0; - // } - // else - // { - // // program 2 seconds interval on simulated tissues (flag bit 7 = 0) - // tissue_increment = 0; - // } - // { - // compute ppN2/ppHe for current depth from temp_deco - sim_alveolar_presures(); - - // update the tissues - calc_tissue(); - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// Simulate extra time at the current depth. -// -// This routine is used for the futureTTS / delayed ascent feature. -// -void sim_extra_time(void) -{ - overlay unsigned char backup = tissue_increment; // back-up tissue_increment - - tissue_increment = char_I_extra_time; // program interval on simulated tissues (Flagbit 7 = 0) - - calc_tissue(); // update the tissues - - tissue_increment = backup; // restore tissue_increment -} - -////////////////////////////////////////////////////////////////////////////// -// calc_tissue -// -// optimized in v.101 -// -// INPUT: ppN2, ppHe, tissue_increment -// MODIFIED: pres_tissue_N2[], pres_tissue_He[] -// OUTPUT: char_O_tissue_N2_saturation[], char_O_tissue_He_saturation[] -// -static void calc_tissue() -{ - overlay float temp_tissue_N2; - overlay float temp_tissue_He; - overlay unsigned char period; - overlay unsigned char i; - - - assert( 0.00 <= ppN2 && ppN2 < 11.2 ); // 80% N2 at 130m - assert( 0.00 <= ppHe && ppHe < 12.6 ); // 90% He at 130m - - - for (ci=0;ci<NUM_COMP;ci++) // iterate through all compartments - { - i = tissue_increment & 127; // extract number of minutes to do (if i > 0) - // or if one 2 second period is to do (if i = 0) - - if( i == 0 ) // check if we shall do one 2-seconds period - { - read_Buhlmann_times(0); // YES, program coefficients for a 2 seconds period - period = 1; // set period length (in cycles) - i = 1; // and one cycle to do - } - else if( i > 9 ) // check if we can start with 10 minutes periods - { - read_Buhlmann_times(2); // YES, program coefficients for 10 minutes periods - period = 10; // set period length (in cycles) to ten - } - else // we shall do 1 to 9 minutes - { - read_Buhlmann_times(1); // program coefficients for 1 minute periods - period = 1; // set period length (in cycles) to one - } - - do - { - //---- N2 ------------------------------------------------------------------------------- - - temp_tissue = (tissue_increment & 128) ? pres_tissue_N2[ci] : sim_pres_tissue_N2[ci]; - - temp_tissue = (ppN2 - temp_tissue) * var_N2_e; - - temp_tissue_safety(); - - if( tissue_increment & 128 ) - { - // The temp variable takes on purpose just the tissue increment from the last loop's iteration. - temp_tissue_N2 = temp_tissue; - - // Update the real tissues if either we are on the 2 seconds interval, - // or if we shall advance the tissues on a one or several minutes basis. - if( twosectimer || (tissue_increment & 127) ) pres_tissue_N2[ci] += temp_tissue; - } - else - { - // Updates of the sim-tissues always comes on a 1 minutes basis, - // so we do not need to check of the 2 seconds interval. - sim_pres_tissue_N2[ci] += temp_tissue; - } - - - //---- He ------------------------------------------------------------------------------- - - temp_tissue = (tissue_increment & 128) ? pres_tissue_He[ci] : sim_pres_tissue_He[ci]; - - temp_tissue = (ppHe - temp_tissue) * var_He_e; - - temp_tissue_safety(); - - if( tissue_increment & 128 ) - { - // The temp variable takes on purpose just the tissue increment from the last loop's iteration. - temp_tissue_He = temp_tissue; - - // Update the real tissues if either we are on the 2 seconds interval, - // or if we shall advance the tissues on a one or several minutes basis. - if( twosectimer || (tissue_increment & 127) ) pres_tissue_He[ci] += temp_tissue; - - } - else - { - // Updates of the sim-tissues always comes on a 1 minutes basis, - // so we do not need to check of the 2 seconds interval. - sim_pres_tissue_He[ci] += temp_tissue; - } - - - // decrement loop counter - i -= period; - - // check if we need to switch from 10 minute periods to 1 minute periods - if( (i > 0) && (period = 10) && (i < 10) ) - { - read_Buhlmann_times(1); // program coefficients for 1 minute periods - period = 1; // set period length (in cycles) to one - } - } - while( i ); - - - // have the computations been done for the "real" tissues? - if( (tissue_increment & 128) && (twosectimer || (tissue_increment & 127)) ) - { - // net tissue balance - temp_tissue = temp_tissue_N2 + temp_tissue_He; - - // check tissue on-/off-gassing and IBCD with applying a threshold of +/-HYST - // - if ( temp_tissue < -HYST ) // Check if the tissue is off-gassing - { - deco_tissue_vector |= (1 << ci); // tag tissue as being in decompression - IBCD_tissue_vector &= ~(1 << ci); // tag tissue as not experiencing mentionable IBCD - } - else if ( temp_tissue > +HYST ) // check if the tissue in on-gassing - { - deco_tissue_vector &= ~(1 << ci); // tag tissue as not being in decompression - - if( ((temp_tissue_N2 > 0.0) && (temp_tissue_He < 0.0)) // check for counter diffusion - || ((temp_tissue_N2 < 0.0) && (temp_tissue_He > 0.0)) ) - { - IBCD_tissue_vector |= (1 << ci); // tag tissue as experiencing mentionable IBCD - } - } - - - // keep the saturating / desaturating flags from last invocation - char_O_tissue_N2_saturation[ci] &= 128; - char_O_tissue_He_saturation[ci] &= 128; - - // flip the flags applying a hysteresis of HYST (actual value: see #define of HYST) - if( temp_tissue_N2 > +HYST ) char_O_tissue_N2_saturation[ci] = 128; // set flag for tissue pressure is increasing - else if( temp_tissue_N2 < -HYST ) char_O_tissue_N2_saturation[ci] = 0; // clear flag (-> tissue pressure is decreasing) - - if( temp_tissue_He > +HYST ) char_O_tissue_He_saturation[ci] = 128; // set flag for tissue pressure is increasing - else if( temp_tissue_He < -HYST ) char_O_tissue_He_saturation[ci] = 0; // clear flag (-> tissue pressure is decreasing) - - - // For N2 tissue display purpose: - // Scale tissue press so that saturation in 70m on AIR gives a value of approx. 80. - // The surface steady-state tissue loading of [0.7902 * (pres_respiration - ppWater)] bar - // gives then a 10. If N2 is completely washed out of the tissue, result will be 0. - // This scaling is adapted to the capabilities of the tissue graphics in the custom views. - temp_tissue = (pres_tissue_N2[ci] / N2_equilibrium) * 10; - - // limit to 127 to leave space for sat/desat flag - if (temp_tissue > 127) temp_tissue = 127; - - // export as integer - char_O_tissue_N2_saturation[ci] += (unsigned char)temp_tissue; - - - // For H2 tissue display purpose: - // Scale tissue press so that saturation in 120m on TMX 10/70 gives a value of approx. 70. - // With no He in a tissue, result will be 0. - // This scaling is adapted to the capabilities of the tissue graphics in the custom views. - temp_tissue = pres_tissue_He[ci] * 7.7; - - // limit to 127 to leave space for sat/desat flag - if (temp_tissue > 127) temp_tissue = 127; - - // export as integer - char_O_tissue_He_saturation[ci] += (unsigned char)temp_tissue; - } - - }// for -} - -////////////////////////////////////////////////////////////////////////////// -// calc_limit -// -// New in v.111 : separated from calc_tissue(), and depends on GF value. -// -static void calc_limit(void) -{ - char_O_gtissue_no = 0; - calc_lead_tissue_limit = 0.0; - - // clear IBCD, microbubbles and outside warning flags (locked warnings will be preserved) - char_O_deco_warnings &= ~(DECO_WARNING_IBCD + DECO_WARNING_MBUBBLES + DECO_WARNING_OUTSIDE); - - - for(ci=0; ci<NUM_COMP; ci++) - { - overlay float N2 = pres_tissue_N2[ci]; - overlay float He = pres_tissue_He[ci]; - overlay float pres_tissue = N2 + He; - overlay float pres_min; - overlay float gf; - overlay float threshold; - - read_Buhlmann_coefficients(); - var_N2_a = (var_N2_a * N2 + var_He_a * He) / pres_tissue; - var_N2_b = (var_N2_b * N2 + var_He_b * He) / pres_tissue; - - // calculate minimum ambient pressure that the tissue can withstand according to straight Buhlmann - pres_min = (pres_tissue - var_N2_a) * var_N2_b; - - // calculate current gf value (1.0 = 100%) of this tissue - gf = (pres_tissue - pres_respiration) / (pres_tissue - pres_min); - if( gf < 0.0 ) gf = 0.0; - - // calculate a threshold value for use below - // ToDo: finalize the definition of the threshold - threshold = 0.02 * ci + 0.9; - - // check if this tissue is likely to develop microbubbles - // and/or if this tissue is outside the Buhlmann model - if( ci <= 5 ) - { - if( gf >= threshold ) - { - char_O_deco_warnings |= (DECO_WARNING_MBUBBLES + DECO_WARNING_MBUBBLES_lock); - - if( gf >= 1.0 ) - { - char_O_deco_warnings |= (DECO_WARNING_OUTSIDE + DECO_WARNING_OUTSIDE_lock); - } - } - } - else - { - if( gf >= 1.0 ) - { - char_O_deco_warnings |= (DECO_WARNING_MBUBBLES + DECO_WARNING_MBUBBLES_lock); - - if( gf >= threshold ) - { - char_O_deco_warnings |= (DECO_WARNING_OUTSIDE + DECO_WARNING_OUTSIDE_lock); - } - } - } - - - // Apply the Eric Baker's varying gradient factor correction if the GF-Model is selected. - // Note: the correction factor depends both on GF and b, - // Actual values are in the 1.5 .. 1.0 range (for a GF=30%), - // so that can change who is the leading gas... - // Note: Also depends of the GF. So the calculus is different for GF_low, current GF, or GF_high... - // *BUT* calc_tissue() is used to compute bottom time, hence what would happen at surface, - // hence at GF_high. - if( char_I_deco_model != 0 ) pres_min = ( pres_tissue - var_N2_a * ( GF_high) ) * var_N2_b - / ( GF_high + var_N2_b * (1.0 - GF_high) ); - - // check if this tissue requires a higher ambient pressure than was found to be needed up to now - if( pres_min > calc_lead_tissue_limit ) - { - char_O_gtissue_no = ci; - calc_lead_tissue_limit = pres_min; - } - } - - // check IBCD condition - if( !IBCD_tissue_vector ) - { - char_O_deco_warnings &= ~DECO_WARNING_IBCD; // no IBCD in any tissue, clear flag - } - else if( (IBCD_tissue_vector & (1 << char_O_gtissue_no)) - && ((pres_tissue_N2[char_O_gtissue_no] + pres_tissue_He[char_O_gtissue_no]) > pres_respiration) ) - { - // leading tissue is in IBCD condition and in super-saturation, set flags. - char_O_deco_warnings |= (DECO_WARNING_IBCD + DECO_WARNING_IBCD_lock); - } - - // check if is any tissue off-gassing - if (deco_tissue_vector) char_O_deco_warnings |= DECO_FLAG; // yes, set deco flag - else char_O_deco_warnings &= ~DECO_FLAG; // no, clear deco flag - - - assert( char_O_gtissue_no < NUM_COMP ); - assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0); -} - -////////////////////////////////////////////////////////////////////////////// -// calc_nullzeit -// -// calculates the remaining bottom time -// -// NOTE: Erik Baker's closed formula works for Nitroxes. Trimix adds a second -// exponential term to the M-value equation, making it impossible to -// invert... So we have to make a fast-simu until we find a better way. -// -// Input: pres_respiration -// Output: char_O_nullzeit / char_O_alternate_nullzeit -// -static void calc_nullzeit(void) -{ - overlay unsigned char nullzeit = 240; - - - //---- Compute ppN2 and ppHe --------------------------------------------- - temp_deco = pres_respiration; - sim_alveolar_presures(); - - for(ci=0; ci<NUM_COMP; ci++) - { - //---- Read A/B values and loading factor for N2 and He -------------- - - overlay float tN2 = sim_pres_tissue_N2[ci]; - overlay float tHe = sim_pres_tissue_He[ci]; - - overlay float t = tN2 + tHe; - overlay unsigned char ndl; - overlay unsigned char period = 10; - - read_Buhlmann_coefficients(); - read_Buhlmann_times(2); // Starts with a 10min period. - - //---- Simulate for that tissue -------------------------------------- - // NOTE: No need to simulate for longer than the already found NDL. - for(ndl=0; ndl<nullzeit;) - { - //---- Compute updated mix M-value at surface - overlay float a = (var_N2_a * tN2 + var_He_a * tHe) / t; - overlay float b = (var_N2_b * tN2 + var_He_b * tHe) / t; - overlay float M0 = (a + pres_surface/b); - - //---- Add 10min/1min to N2/He tissues - overlay float dTN2 = (ppN2 - tN2) * var_N2_e; - overlay float dTHe = (ppHe - tHe) * var_He_e; - - //---- Apply safety margin for both models - // NDL can be computed while ascending... SO we have - // to check if we are saturating or desaturating. - if( dTN2 > 0.0 ) dTN2 *= float_saturation_multiplier; - else dTN2 *= float_desaturation_multiplier; - - if( dTHe > 0.0 ) dTHe *= float_saturation_multiplier; - else dTHe *= float_saturation_multiplier; - - // adopt M0 value when using the GF extension - if (char_I_deco_model != 0 ) M0 = GF_high * (M0 - pres_surface) + pres_surface; - - //---- Simulate off-gassing while going to surface - // TODO ! - // dTN2 -= exp( ... ascent time ... ppN2...) - // dTHe -= exp( ... ascent time ... ppHe...) - - //---- Ok now, and still ok to surface after 1 or 10 minutes ? - if( (t <= M0) && (t + dTN2 + dTHe <= M0) ) - { - tN2 += dTN2; // YES: apply gas loadings, - tHe += dTHe; - t = tN2 + tHe; - - ndl += period; // increment NDL, - - continue; // and loop. - } - - //---- Should we retry with smaller steps ? - if( period == 10 ) - { - read_Buhlmann_times(1); // 1min coefs. - period = 1; - - continue; - } - - //---- ELSE make a linear approx for the last minute - // Useful to have a meaningful rounding of NDL. - // But ONLY if positive (negative casted to unsigned is bad). - if( M0 > t ) ndl += (unsigned char)(0.5f + (M0-t)/(dTN2+dTHe)); - - break; - } - - // Keep the shortest NDL found - if ( ndl < nullzeit ) nullzeit = ndl; - } - - if( char_O_deco_status & DECO_PLAN_ALTERNATE) char_O_alternate_nullzeit = nullzeit; - else char_O_nullzeit = nullzeit; -} - -////////////////////////////////////////////////////////////////////////////// -// calc_ascenttime -// -// Sum up ascent from bottom to surface at float_ascent_speed, -// but 1 minute per meter for the final ascent, and all stops. -// -// Result in int_O_ascenttime, -// or int_O_alternate_ascenttime if doing the alternative plan. -// -static void calc_ascenttime(void) -{ - overlay unsigned char x; - overlay unsigned short sum; - - // preset final ascent - overlay float final = (float)char_I_depth_last_deco; - - // calculate depth - overlay float ascent = (pres_respiration - pres_surface) * BAR_TO_METER; - - // check if we are already in final ascent - if (ascent <= final) - { - // yes - all ascent is final ascent - final = ascent; - ascent = 0.0; - } - else - { - // no - subtract final ascent part from overall ascent - ascent -= final; - - // compute time for ascent part without final ascent - ascent /= float_ascent_speed; - } - - // add 1 minute for each meter of final ascent - ascent += final; - - // convert to integer - sum = (unsigned short)(ascent + 0.5); - - // add all stop times - for(x=0; x<NUM_STOPS && internal_deco_depth[x]; x++) - sum += (unsigned short)internal_deco_time[x]; - - // limit result to display max. - if( sum > 999) sum = 999; - - // tag result as invalid if there is an overflow in the stops table - if( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) sum |= INT_FLAG_INVALID; - - // route result to output variable - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) int_O_alternate_ascenttime = sum; - else int_O_ascenttime = sum; -} - -////////////////////////////////////////////////////////////////////////////// -// update_startvalues -// -// updated in v.102 -// -void update_startvalues(void) -{ - overlay unsigned char x; - - // Start ascent simulation with current tissue partial pressures. - for(x=0; x<NUM_COMP; x++) - { - sim_pres_tissue_N2[x] = pres_tissue_N2[x]; - sim_pres_tissue_He[x] = pres_tissue_He[x]; - } - - // No leading tissue (yet) for this ascent simulation. - sim_lead_tissue_limit = 0.0; - sim_lead_tissue_no = 1; -} - -////////////////////////////////////////////////////////////////////////////// -// sim_limit() -// -// New in v.111 -// -// Function separated from calc_tissue() to allow recomputing limit on -// different depth, because it depends on current gradient factor. -// -static void sim_limit(PARAMETER float GF_current) -{ - assert( 0.0 < GF_current && GF_current <= 1.0 ); - - sim_lead_tissue_limit = 0.0; - sim_lead_tissue_no = 0; // If no one is critic, keep first tissue. - - for(ci=0; ci<NUM_COMP; ci++) - { - overlay float N2 = sim_pres_tissue_N2[ci]; - overlay float He = sim_pres_tissue_He[ci]; - overlay float p = N2 + He; - - read_Buhlmann_coefficients(); - var_N2_a = (var_N2_a * N2 + var_He_a * He) / p; - var_N2_b = (var_N2_b * N2 + var_He_b * He) / p; - - // Apply the Eric Baker's varying gradient factor correction. - // Note: the correction factor depends both on GF and b, - // Actual values are in the 1.5 .. 1.0 range (for a GF=30%), - // so that can change who is the leading gas... - // Note: Also depends of the GF_current... - if( char_I_deco_model != 0 ) p = ( p - (var_N2_a * GF_current) ) - / ( 1.0 - GF_current + (GF_current / var_N2_b ) ); - - else p = (p - var_N2_a) * var_N2_b; - - - if( p > sim_lead_tissue_limit ) - { - sim_lead_tissue_no = ci; - sim_lead_tissue_limit = p; - } - } // for ci - - assert( sim_lead_tissue_no < NUM_COMP ); - assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0 ); -} - -////////////////////////////////////////////////////////////////////////////// -// clear_deco_table -// -// -static void clear_deco_table(void) -{ - overlay unsigned char x; - - for(x=0; x<NUM_STOPS; ++x) - { - internal_deco_time [x] = 0; - internal_deco_depth[x] = 0; - } - - // clear stop table overflow warning - char_O_deco_warnings &= ~DECO_WARNING_STOPTABLE_OVERFLOW; -} - -////////////////////////////////////////////////////////////////////////////// -// update_deco_table -// -// Add time to a stop at temp_depth_limit -// -// It is possible to create stops with a duration of 0 minutes, e.g. to -// note a gas change "on the fly" while ascending. Therefore the criteria -// to have reached the end of the list needs always to be depth == 0. -// -// Input: temp_depth_limit : stop's depth, in meters. -// sim_gas_last_used : gas used at stop, as index 1..5 -// PARAMETER time_increment : number of minutes to add to the stop -// -// Updated: internal_deco_depth[] : depth (in meters) of each stop -// internal_deco_time [] : time (in minutes) of each stop -// internal_deco_gas [] : gas used (index 1-5) at each stop -// -static unsigned char update_deco_table(PARAMETER unsigned char time_increment) -{ - overlay unsigned char x; - - assert( temp_depth_limit > 0 ); // No stop at surface... - - // loop through internal deco table - for(x=0; x<NUM_STOPS; ++x) - { - // Make sure deco-stops are recorded in order: - assert( !internal_deco_depth[x] || temp_depth_limit <= internal_deco_depth[x] ); - - // Is there already a stop entry for our current depth? - if( internal_deco_depth[x] == temp_depth_limit ) - { - // Yes - increment stop time if possible - // Stop time entries are limited to 99 minutes because of display constraints. - // Else a limit of 254 would account because of constrains in calc_CNS_planning(). - if( internal_deco_time[x] < (99 - time_increment) ) - { - internal_deco_time[x] += time_increment; // increment stop time - return 1; // return with status 'success' - } - } - - // If program flow passes here, there is either no stop entry for the current depth yet, or - // the existing entry is saturated with 99 minutes. So we are looking for the next unused - // table entry. - if( internal_deco_depth[x] == 0 ) - { - internal_deco_time[x] = time_increment; // initialize entry with first stop's time, - internal_deco_depth[x] = temp_depth_limit; // ... depth, and - internal_deco_gas[x] = sim_gas_last_used; // ... gas - return 1; // return with status 'success' - } - } - - // If program flow passes here, all deco table entries are used up. - - // set overflow warning - char_O_deco_warnings |= DECO_WARNING_STOPTABLE_OVERFLOW; - - - // return with status 'failed'. - return 0; -} - -////////////////////////////////////////////////////////////////////////////// -// calc_gradient_factor -// -// optimized in v.101 (var_N2_a) -// new code in v.102 -// -static void calc_gradient_factor(void) -{ - overlay float gf; - overlay float N2 = pres_tissue_N2[char_O_gtissue_no]; - overlay float He = pres_tissue_He[char_O_gtissue_no]; - - assert( char_O_gtissue_no < NUM_COMP ); - assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); - - // tissue > respiration (currently off-gassing) - // GF = 0.00 when respiration == tissue, ie. dissolved gases are at equilibrium. - // GF = 1.00 when respiration == limit. - temp_tissue = N2 + He; - if( temp_tissue <= pres_respiration ) - { - gf = 0.0; - int_O_gradient_factor = 0; - } - else - { - overlay float limit = calc_lead_tissue_limit; - // NOTE: in GF model, calc_lead_tissue_limit include already the - // correction due to gradient factor. To compute the actual - // current GF, we need to (re-)compute the raw ambient-pressure - // limit from the Buhlmann model. - if( char_I_deco_model != 0 ) - { - ci = char_O_gtissue_no; - - read_Buhlmann_coefficients(); - - var_N2_a = (var_N2_a * N2 + var_He_a * He) / temp_tissue; - var_N2_b = (var_N2_b * N2 + var_He_b * He) / temp_tissue; - - limit = (temp_tissue - var_N2_a) * var_N2_b; - } - - gf = (temp_tissue - pres_respiration) / (temp_tissue - limit); - - // limit to 255 because of constraints in ghostwriter code - if ( gf <= 0.0 ) int_O_gradient_factor = 0; - else if( gf > 2.545 ) int_O_gradient_factor = 255 + INT_FLAG_WARNING; - else - { - int_O_gradient_factor = (unsigned int)(100 * gf + 0.5); - - if ( int_O_gradient_factor >= GF_warning_threshold ) int_O_gradient_factor |= INT_FLAG_WARNING; - else if ( int_O_gradient_factor >= GF_prewarning_threshold ) int_O_gradient_factor |= INT_FLAG_PREWARNING; - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// calc_desaturation_time -// -// FIXED N2_ratio -// unchanged in v.101 -// Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier -// Outputs: int_O_desaturation_time, int_O_nofly_time -// -// Helper function -// -void calc_desaturation_time_helper(void) -{ - if( pres_actual > pres_target ) // check if actual pressure is higher then target pressure - { // YES - compute remaining time - overlay float pres_ratio; - - pres_ratio = pres_actual / pres_target; - - // Compute desaturation time with result rounded up to multiples of 10 minutes. - // Main purpose is to avoid confusion, because the times do not clock down in one minute steps any more - // but get constantly re-computed according to current ambient pressure and may therefor make steps of - // several minutes forwards and backwards as ambient pressure rises and falls. - short_time = (unsigned short)( (var_ht * log(pres_ratio) / desat_factor) + 0.9 ); - } - else - { // NO - desaturation state reached, no remaining time - short_time = 0; - } -} - -///////////////////////////////////////////////////////////////////////////// -// Main function -// -void calc_desaturation_time(void) -{ - assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); - assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); - - - N2_ratio = 0.7902; // fraction of N2 in respired air - pres_surface = 0.001 * int_I_pres_surface; // surface pressure in bar - N2_equilibrium = N2_ratio * (pres_surface - ppWater); // partial pressure of N2 in respired air - desat_factor = 0.06931 * char_I_desaturation_multiplier * SURFACE_DESAT_FACTOR; // pre-computed term for later use: - // 10 [Min] * 0.01 [%] * 0.6931 [ln(2)] * ... - int_O_desaturation_time = 0; - int_O_nofly_time = 0; - - - for(ci=NUM_COMP; ci>0;) - { - overlay float pres_tissue_max; - overlay float P_ambient_altitude; - overlay signed char search_direction; - overlay unsigned short nofly_N2 = 0; - overlay unsigned short nofly_He = 0; - overlay unsigned short nofly_last = ~0; - - - ci -= 1; - - read_Buhlmann_ht(); - read_Buhlmann_coefficients(); - - // get selected target altitude - switch( char_I_altitude_wait ) - { - case 1: P_ambient_altitude = P_ambient_1000m; break; - case 2: P_ambient_altitude = P_ambient_2000m; break; - case 3: P_ambient_altitude = P_ambient_3000m; break; - default: P_ambient_altitude = P_ambient_fly; break; - } - - // Target pressure for the tissue is the Buhlmann limit. We use the Buhlmann - // coefficients for N2 also for He because it is easier to calculate and the - // N2 coefficients are more conservative than those for He, so we are on the - // safe side, too. - pres_tissue_max = (P_ambient_altitude/var_N2_b + var_N2_a); - - // Adjust target pressure in case the GF model is in use by GF-high - if( char_I_deco_model != 0 ) - { - pres_tissue_max = ((pres_tissue_max - P_ambient_altitude) * char_I_GF_High_percentage * 0.01) + P_ambient_altitude; - } - - - // - // Desaturation time - // - - // N2: actual amount of tissue pressure above equilibrium. - pres_actual = pres_tissue_N2[ci] - N2_equilibrium; - - // N2: half-time of the current tissue - var_ht = var_N2_ht; - - // Calculate desaturation time for N2 in tissue. - // Desaturated state is defined as residual tissue pressure <= 1.05 x ppN2 respired - - pres_target = 0.05 * N2_equilibrium; - - calc_desaturation_time_helper(); - - if( short_time > int_O_desaturation_time) int_O_desaturation_time = short_time; - - - // He: actual amount of tissue pressure above equilibrium. - pres_actual = pres_tissue_He[ci]; // equilibrium for He is 0 bar - - // He: half-time of the current tissue - var_ht = var_He_ht; - - // Calculate desaturation time for He in the tissue. - // Desaturated state is defined as residual tissue pressure <= 0.05 x ppN2 respired - - pres_target = 0.05 * N2_equilibrium; - - calc_desaturation_time_helper(); - - if( short_time > int_O_desaturation_time) int_O_desaturation_time = short_time; - - - // - // no-fly time - // - - // initialize search direction - search_direction = 0; - - for(;;) - { - // N2: actual amount of tissue pressure above equilibrium. - pres_actual = pres_tissue_N2[ci] - N2_equilibrium; - - // N2: half-time of the current tissue - var_ht = var_N2_ht; - - // Calculate no-fly time for N2 in the tissue. - // Flying is permitted when the N2 pressure fits into the assigned fraction above equilibrium. - - pres_target = (split_N2_He[ci] * 0.01) * (pres_tissue_max - N2_equilibrium); - - if( pres_target < 0.0 ) // check if desaturation to fly target is possible - { - int_O_nofly_time = 288; // NO - set no-fly time to 288 * 10 min = 48 h - break; // done for this compartment - } - else - { - calc_desaturation_time_helper(); - nofly_N2 = short_time; - } - - // He: actual amount of tissue pressure above equilibrium - equilibrium for He is 0 bar. - pres_actual = pres_tissue_He[ci]; - - // He: half-time of the current tissue - var_ht = var_He_ht; - - // Calculate no-fly time for He in the tissue. - // Flying is permitted when the He pressure fits into the assigned fraction. - - pres_target = ((100 - split_N2_He[ci]) * 0.01) * (pres_tissue_max - N2_equilibrium); - - calc_desaturation_time_helper(); - nofly_He = short_time; - - - // Because the sum of N2 and He tissue pressures needs to fit into the Buhlmann limit for - // no-fly time calculation, each gas gets assigned a fraction of the available total pressure - // limit. The optimum split between the two gases can not be computed by a single formular, - // because this would require the inversion of a function with two exponential terms, which is - // not possible. We do not want to do a computational complex simulation here like it is done - // in the deco calculation code (although we tackle the same base problem here), so we just let - // the computer try out which split will balance the no-fly times induced by the N2 and the He - // at best. - - // first of all, skip any optimization in case the current compartment is not the leading one - if( (nofly_N2 <= int_O_nofly_time) && (nofly_He <= int_O_nofly_time) ) break; - - // check if the N2 requires more waiting time than the He - if( nofly_N2 >= nofly_He ) - { - // check if the search direction has changed, which means we are beyond the - // optimum now, or if we are at the upper stop limit of split_N2_He - if( (search_direction < 0) || (split_N2_He[ci] == 99) ) - { - // Either the just completed iteration was more close to the optimum or the one before - // was, so we take the best (i.e. shortest) time of both as the final no-fly time. - int_O_nofly_time = (nofly_N2 < nofly_last) ? nofly_N2 : nofly_last; - break; - } - - // store the no-fly time found in this iteration - nofly_last = nofly_N2; - - // increase the N2 fraction of the split and set search direction towards more N2 - split_N2_He[ci] += 1; - search_direction = +1; - } - else - { - // check if the search direction has changed, which means we are beyond the - // optimum now, or if we are at the lower stop limit of split_N2_He - if( (search_direction > 0) || (split_N2_He[ci] == 1) ) - { - // Either the just completed iteration was more close to the optimum or the one before - // was, so we take the best (i.e. shortest) time of both as the final no-fly time. - int_O_nofly_time = (nofly_He < nofly_last) ? nofly_He : nofly_last; - break; - } - - // store the no-fly time found in this iteration - nofly_last = nofly_He; - - // decrease the N2 fraction of the split and set search direction towards less N2 - split_N2_He[ci] -= 1; - search_direction = -1; - } - - } // for(;;) - - } // for(compartments) - - - // Rescale int_O_desaturation_time and int_O_nofly_time to full minutes for display purpose - int_O_desaturation_time *= 10; - int_O_nofly_time *= 10; - - // Limit int_O_desaturation_time and int_O_nofly_time to 5999 = 99 hours + 59 minutes - // because of display space constraints and rounding done above. - if( int_O_desaturation_time > 5999 ) int_O_desaturation_time = 5999; - if( int_O_nofly_time > 5999 ) int_O_nofly_time = 5999; - - - // Clear the microbubbles warning when the current gradient factor is < GF_warning_threshold. - // As the locked warning will stay set, this will cause the warning be be displayed in attention - // color instead of warning color. - if( int_O_gradient_factor < GF_warning_threshold ) char_O_deco_warnings &= ~DECO_WARNING_MBUBBLES; - - // clear some warnings when the desaturation time has become zero - if( int_O_desaturation_time == 0 ) char_O_deco_warnings &= ~( DECO_WARNING_IBCD + DECO_WARNING_IBCD_lock - + DECO_WARNING_MBUBBLES + DECO_WARNING_MBUBBLES_lock - + DECO_WARNING_OUTSIDE + DECO_WARNING_OUTSIDE_lock ); - -} - -////////////////////////////////////////////////////////////////////////////// -// calc_wo_deco_step_1_min -// -// optimized in v.101 (...saturation_multiplier) -// desaturation slowed down to 70,42% -// -// Input: int_I_pres_surface [mbar] -// -static void calc_wo_deco_step_1_min(void) -{ - assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); - assert( 100 <= char_I_saturation_multiplier && char_I_saturation_multiplier < 200 ); - assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); - - // setup input data for deco routines - pres_respiration = pres_surface = int_I_pres_surface * 0.001; - - N2_ratio = 0.7902; // according to Buhlmann - N2_equilibrium = N2_ratio * (pres_surface - ppWater); // used for N2 tissue graphics scaling - ppN2 = N2_ratio * (pres_respiration - ppWater); - ppHe = 0.0; - - float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01 * SURFACE_DESAT_FACTOR; - float_saturation_multiplier = char_I_saturation_multiplier * 0.01; - - - // program what to do: 128 = Flag for "real" tissues, 1 = 1 minute - tissue_increment = 128 + 1; - - // update the pressure in the tissues N2/He in accordance with the new ambient pressure - calc_tissue(); - - // clock down CNS by a 1 minute step - CNS_fraction *= 0.992327946; - - // compute integer copy of CNS value - compute_CNS_for_display(); - - // reset deco engine start condition (probably not needed to be done here...) - char_O_deco_status &= ~DECO_STATUS_MASK; // clear bits - char_O_deco_status |= DECO_STATUS_INIT; // set bits - - // reset some more data that are not applicable in surface mode - char_O_nullzeit = 0; - int_O_ascenttime = 0; - int_O_alternate_ascenttime = 0; - clear_deco_table(); - - // calculate gradient factor - calc_gradient_factor(); -} - -////////////////////////////////////////////////////////////////////////////// -// calc_dive_interval -// -// Prepare tissue for delay before the next dive simulation. -// -// Inputs: char_I_dive_interval == delay before dive (in 1 Minute steps). -// Modified: CNS_fraction, int_O_CNS_fraction -// pres_tissue_N2/He[] -// -// Should be protected by deco_push_tissues_to_vault(), -// deco_pull_tissues_from_vault() -// -// desaturation slowed down to 70,42%. -// -static void calc_dive_interval(void) -{ - overlay unsigned char t; - - //---- Initialize simulation parameters ---------------------------------- - pres_respiration = pres_surface = int_I_pres_surface * 0.001; - - N2_ratio = 0.7902; // according to buehlmann - N2_equilibrium = N2_ratio * (pres_surface - ppWater); // used for N2 tissue graphics scaling - ppN2 = N2_ratio * (pres_respiration - ppWater); - ppHe = 0.0; - - float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01 * SURFACE_DESAT_FACTOR; - float_saturation_multiplier = char_I_saturation_multiplier * 0.01; - - //---- Perform simulation ------------------------------------------------ - - // Calculate tissues: - // Because tissue_increment is limited to 127 minutes, we have to do two passes - // in case char_I_dive_interval is bigger than 127. - // Ops: char_I_dive_interval must be limited to 254! - - t = char_I_dive_interval; - - if ( t == 255 ) t = 254; - - if ( t > 127 ) // extra pass needed? - { - tissue_increment = 127 // dive interval length in minutes - | 128; // Flag to update the "real" tissues - - calc_tissue(); // update tissues - - t -= 127; // calculate remaining dive interval length - } - - tissue_increment = t // dive interval length in minutes to do - | 128; // Flag to update the "real" tissues - calc_tissue(); // update tissues - - - // Calculate CNS: - // To speed up things and because on most invocations of this code char_I_dive_interval - // is a multiple of 10 minutes, we loop the loop-counter down using two speeds. - - t = char_I_dive_interval; - - while ( t ) - { - if( t > 9 ) - { - CNS_fraction *= 0.925874712; // Half-time = 90min -> 10 min: (1/2)^(1/9) - t -= 10; // fast speed looping - } - else - { - CNS_fraction *= 0.992327946; // Half-time = 90min -> 1 min: (1/2)^(1/90) - t -= 1; // slow speed looping - } - } - - // compute integer copy of CNS value - compute_CNS_for_display(); -} - -////////////////////////////////////////////////////////////////////////////// -// clear_CNS_fraction -// -// new in v.101 -// -void clear_CNS_fraction(void) -{ - CNS_fraction = CNS_sim_norm_fraction = CNS_sim_alt_fraction = 0; - int_O_CNS_fraction = int_O_normal_CNS_fraction = int_O_alternate_CNS_fraction = 0; -} - -////////////////////////////////////////////////////////////////////////////// -// calc_CNS_fraction -// -// Input: char_actual_ppO2 : current ppO2 [decibars] -// tissue_increment : time increment and tissue selector -// CNS_fraction : current CNS% as float before period -// -// Output: CNS_fraction, int_O_CNS_fraction - for the real tissues -// CNS_sim_norm_fraction, int_O_normal_CNS_fraction - in simulation mode, normal plan -// CNS_sim_alt_fraction, int_O_alternate_CNS_fraction - in simulation mode, alternative plan -// -void calc_CNS_fraction(void) -{ - overlay float time_factor = 1.0; // default is 2sec - overlay float CNS_fraction_temp = 0.0; - - assert( char_actual_ppO2 > 15 ); - - // All deco code is now invoked every second. But as the CNS update is based on - // 2 seconds periods, we skip every 2nd seconds-based invocation of this function. - // 128 = 128 (flag for "real" CNS) + 0 (2 seconds period) - // To distribute computational load, the CNS% is calculated in "the other second" - // than the tissues. - if( (tissue_increment == 128) && (twosectimer) ) return; - - // adjust time factor if minute-based stepping is commanded, mask out flag bit - if( tissue_increment & 127 ) time_factor = 30.0 * (float)(tissue_increment & 127); - - - //------------------------------------------------------------------------ - // Don't increase CNS below 0.5 bar, but keep it steady. - if (char_actual_ppO2 < 50) - ; // no changes - //------------------------------------------------------------------------ - // Below (and including) 1.60 bar - else if (char_actual_ppO2 < 61) - CNS_fraction_temp = time_factor/(-533.07 * char_actual_ppO2 + 54000.0); - else if (char_actual_ppO2 < 71) - CNS_fraction_temp = time_factor/(-444.22 * char_actual_ppO2 + 48600.0); - else if (char_actual_ppO2 < 81) - CNS_fraction_temp = time_factor/(-355.38 * char_actual_ppO2 + 42300.0); - else if (char_actual_ppO2 < 91) - CNS_fraction_temp = time_factor/(-266.53 * char_actual_ppO2 + 35100.0); - else if (char_actual_ppO2 < 111) - CNS_fraction_temp = time_factor/(-177.69 * char_actual_ppO2 + 27000.0); - else if (char_actual_ppO2 < 152) - CNS_fraction_temp = time_factor/( -88.84 * char_actual_ppO2 + 17100.0); - else if (char_actual_ppO2 < 167) - CNS_fraction_temp = time_factor/(-222.11 * char_actual_ppO2 + 37350.0); - //------------------------------------------------------------------------ - // Arieli et all.(2002): Modeling pulmonary and CNS O2 toxicity: - // J Appl Physiol 92: 248--256, 2002, doi:10.1152/japplphysiol.00434.2001 - // Formula (A1) based on value for 1.55 and c=20 - // example calculation: Sqrt((1.7/1.55)^20)*0.000404 - else if (char_actual_ppO2 < 172) - CNS_fraction_temp = time_factor*0.00102; - else if (char_actual_ppO2 < 177) - CNS_fraction_temp = time_factor*0.00136; - else if (char_actual_ppO2 < 182) - CNS_fraction_temp = time_factor*0.00180; - else if (char_actual_ppO2 < 187) - CNS_fraction_temp = time_factor*0.00237; - else if (char_actual_ppO2 < 192) - CNS_fraction_temp = time_factor*0.00310; - else if (char_actual_ppO2 < 198) - CNS_fraction_temp = time_factor*0.00401; - else if (char_actual_ppO2 < 203) - CNS_fraction_temp = time_factor*0.00517; - else if (char_actual_ppO2 < 233) - CNS_fraction_temp = time_factor*0.0209; - else - CNS_fraction_temp = time_factor*0.0482; // value for 2.5 bar, used for 2.33 bar and above - - - // Check from where we were called: - // flag (bit 7) is set -> we were called from calc_hauptroutine() - // flag (bit 7) not set -> we were called from the deco planning routines - if ( tissue_increment & 128 ) CNS_fraction += CNS_fraction_temp; // real tissues - else if ( char_O_deco_status & DECO_PLAN_ALTERNATE ) CNS_sim_alt_fraction += CNS_fraction_temp; // alternative plan - else CNS_sim_norm_fraction += CNS_fraction_temp; // normal plan - -} - -////////////////////////////////////////////////////////////////////////////// -// calc_CNS_planning -// -// Compute CNS during predicted ascent. -// -// Note: Needs a call to deco_push_tissues_to_vault(), -// deco_pull_tissues_from_vault() to avoid trashing everything... -// -// Input: CNS_fraction, internal_deco_time[], internal_deco_depth[], internal_deco_gas[] -// Output: CNS_fraction, int_O_normal_CNS_fraction / int_O_alternate_CNS_fraction -// -void calc_CNS_planning(void) -{ - // start with CNS% we already have - if( char_O_deco_status & DECO_PLAN_ALTERNATE ) CNS_sim_alt_fraction = CNS_fraction; - else CNS_sim_norm_fraction = CNS_fraction; - - - //---- CCR mode : do the full TTS at once --------------------------------- - - if( ((char_O_deco_status & DECO_MODE_MASK) == DECO_MODE_CCR) ) - { - overlay unsigned short t; // needs 16 bits here ! - - // get current ppO2 from sensors or setpoint - char_actual_ppO2 = char_I_const_ppO2; - - // calculate CNS% for the period of additional staying at bottom depth (fTTS / delayed ascent) - if( char_O_deco_status & DECO_ASCENT_DELAYED) - { - tissue_increment = char_I_extra_time; // must be limited to 127, is limited by range of char_I_extra_time - calc_CNS_fraction(); - } - - // get the ascent time dependent on the current plan - t = (char_O_deco_status & DECO_PLAN_ALTERNATE) ? int_O_alternate_ascenttime : int_O_ascenttime; - - // start simulating CNS% in chunks of 127 minutes - tissue_increment = 127; - - while( t > 127 ) - { - t -= 127; // tissue_increment is limited to 127 minutes because of flag in bit 7 - calc_CNS_fraction(); // calculate CNS in chunks of full 127 minutes - } - - tissue_increment = (char)t; // get the remaining minutes <= 127 - calc_CNS_fraction(); // calculate CNS for the remaining minutes - } - else //---- OC mode and pSCR without sensors: have to follow all gas switches... ----- - { - overlay float float_actual_ppO2; - overlay float abs_pres; - - overlay unsigned char stop_depth; - overlay unsigned char last_gas; - overlay unsigned char i; // stop table index - - - // retrieve bottom gas 0 (manual gas) or 1-5 (configured gases) - last_gas = sim_gas_last_used = sim_gas_first_used; - - // get the calc_N2/He/O2_ratios of the bottom gas - gas_switch_set(); - - // calculate absolute pressure - abs_pres = pres_surface + char_I_bottom_depth * METER_TO_BAR; - - // switch on deco mode pSCR / OC - if( char_O_deco_status & DECO_MODE_PSCR ) - { - //---- pSCR calculated -------------------------------------------- - - // abs_pres is 0.0 ... in bar - // calc_O2_ratio is 0.0 ... 1.0 as factor - // char_I_PSCR_drop is 0 ... 15 as % - // char_I_PSCR_lungratio is 5 ... 20 as % - // float_actual_ppO2 is 0.0 ... in cbar (!) - - float_actual_ppO2 = (100 * abs_pres * calc_O2_ratio) - - (1.0 - calc_O2_ratio) * char_I_PSCR_drop * char_I_PSCR_lungratio; - } - else - { - //---- OC --------------------------------------------------------- - - float_actual_ppO2 = abs_pres * calc_O2_ratio * 100; // in cbar (!) - } - - // caution: float_actual_ppO2 is in cbar here! - if ( float_actual_ppO2 < 0.0 ) char_actual_ppO2 = 0; - else if ( float_actual_ppO2 > 254.5 ) char_actual_ppO2 = 255; - else char_actual_ppO2 = (unsigned char)(float_actual_ppO2 + 0.5); - - - // simulate extended bottom time (fTTS) / delay before ascent (bailout) if configured - if( char_O_deco_status & DECO_ASCENT_DELAYED ) - { - tissue_increment = char_I_extra_time; // must be limited to 127, is limited by range of char_I_extra_time - calc_CNS_fraction(); - } - - - // For simplicity reason (non-linearity of the relation between ppO2 and CNS increments), the - // whole ascent is calculated with bottom ppO2. This errs, but it does so to the safe side. - - // calculate ascent time (integer division and generous round-up) - tissue_increment = char_I_bottom_depth / char_I_ascent_speed + 1; - - // commented out - not needed when char_I_ascent_speed is limited to a - // minimum of 2.something, it is indeed limited to 5. - // limit tissue_increment to 127 minutes - // if( tissue_increment > 127 ) tissue_increment = 127; - - // simulate the CNS increase - calc_CNS_fraction(); - - - //---- Stops --------------------------------------------------------- - - for(i=0; i<NUM_STOPS; ++i) - { - // get the depth of the stop - stop_depth = internal_deco_depth[i]; - - // did we reach the last entry (depth = 0)? if yes, done - if (stop_depth == 0) break; - - // get the duration of the stop and the gas breathed - tissue_increment = internal_deco_time[i]; - sim_gas_last_used = internal_deco_gas[i]; - - // do we have a gas switch? - if( sim_gas_last_used != last_gas ) - { - // yes - get new calc ratios - gas_switch_set(); - - // remember new gas as last gas - last_gas = sim_gas_last_used; - } - - // calculate absolute pressure at stop depth - abs_pres = pres_surface + stop_depth * METER_TO_BAR; - - // pSCR mode - if( char_O_deco_status & DECO_MODE_PSCR ) - { - // abs_pres is 0.0 ... in bar - // calc_O2_ratio is 0.0 ... 1.0 as factor - // char_I_PSCR_drop is 0 ... 15 as % - // char_I_PSCR_lungratio is 5 ... 20 as % - // float_actual_ppO2 is 0.0 ... in cbar (!) - - float_actual_ppO2 = (100 * abs_pres * calc_O2_ratio) - - (1.0 - calc_O2_ratio) * char_I_PSCR_drop * char_I_PSCR_lungratio; - } - else // OC mode - { - float_actual_ppO2 = abs_pres * calc_O2_ratio * 100; // in cbar (!) - } - - // caution: float_actual_ppO2 is in cbar here! - if ( float_actual_ppO2 < 0.0 ) char_actual_ppO2 = 0; - else if ( float_actual_ppO2 > 254.5 ) char_actual_ppO2 = 255; - else char_actual_ppO2 = (unsigned char)(float_actual_ppO2 + 0.5); - - - // ** Currently, stop times per stop entry are limited to 99 minutes in update_deco_table(), - // ** so the following code block is not needed at times. - // - // // tissue_increment is limited to 127 when fed to deco_calc_CNS_fraction(), - // // so if the stop is longer than 127 minutes (but not longer than 254 minutes!) - // // we need to calculate the CNS in two chunks. - // if( tissue_increment > 127) - // { - // tissue_increment -= 127; // subtract full 127 minutes and do the "remaining" minutes first - // calc_CNS_fraction(); - // tissue_increment = 127; // catch up with the previously subtracted full 127 minutes - // } - - // calculate CNS% for the stop - calc_CNS_fraction(); - } - } -} - -////////////////////////////////////////////////////////////////////////////// -// deco_calc_CNS_decrease_15min -// -// new in v.101 -// -// calculates the half time of 90 minutes in 6 steps of 15 min -// (Used in sleep mode, for low battery mode). -// -// Output: int_O_CNS_fraction -// Uses and Updates: CNS_fraction -// -void deco_calc_CNS_decrease_15min(void) -{ - RESET_C_STACK - - // clock down CNS - CNS_fraction = 0.890899 * CNS_fraction; - - // compute integer copy of CNS value - compute_CNS_for_display(); -} - - -////////////////////////////////////////////////////////////////////////////// -// gas_volumes -// -// calculates volumes and required tank fill pressures for each gas. -// -// Input: char_I_bottom_depth depth of the bottom segment -// char_I_bottom_time duration of the bottom segment -// char_I_extra_time extra bottom time for fTTS / delayed ascent -// float_ascent_speed ascent speed, in meters/minute -// sim_gas_first_used the bottom gas (1-5 for configured gases, 0 for the manual gas) -// internal_deco_depth[] depth of the stops -// internal_deco_time[] duration of the stops -// internal_deco_gas[] gas breathed at the stops -// char_I_bottom_usage gas consumption during bottom part and initial ascent, in liters/minute -// char_I_deco_usage gas consumption during stops and following ascents, in liters/minute -// char_I_tank_size[] size of the tanks for gas 1-5, in liters -// char_I_tank_pres_fill[] fill pressure of the tanks -// -// Output: int_O_gas_volumes[] amount of gas needed, in liters -// int_O_tank_pres_need[] in bar, + flags for fast evaluation by dive mode warnings: -// 2^15: pres_need >= pres_fill -// 2^14: pres_need >= press_fill * GAS_NEEDS_ATTENTION_THRESHOLD -// 2^11: pres_need == 0 -// 2^10: pres_need invalid -// -void gas_volumes_helper(void) -{ - // Calculate the gas volume needed at a given depth, time and usage (SAC rate). - // We use 1.0 for the surface pressure to have stable results when used through - // the deco calculator (simulation mode). - volume = (float_depth * METER_TO_BAR + 1.0) * float_time * usage; - - return; -} - -void gas_volumes(void) -{ - overlay float volumes[NUM_GAS]; - - overlay unsigned char stop_gas; - overlay unsigned char stop_gas_last; - overlay unsigned char stop_time; - overlay unsigned char stop_depth; - overlay unsigned char stop_depth_last; - overlay unsigned char i; - - - //---- initialization ---------------------------------------------------- - - // null the volume accumulators - for(i=0; i<NUM_GAS; ++i) volumes[i] = 0.0; - - // quit for CCR and pSCR mode - if( char_O_deco_status & DECO_MODE_LOOP ) goto done; - - - //---- bottom demand ----------------------------------------------------- - - // sim_gas_first_used : gas used during bottom segment (0, 1-5) - // char_I_bottom_depth: depth of the bottom segment - - assert(0 <= sim_gas_first_used && sim_gas_first_used <= NUM_GAS); - - // get the gas used during bottom segment - stop_gas_last = stop_gas = sim_gas_first_used; - - // set the usage (SAC rate) to bottom usage rate for bottom part and initial ascent - usage = char_I_bottom_usage; - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( stop_gas ) - { - // set the bottom depth - float_depth = (float)char_I_bottom_depth; - - // calculate either bottom segment or fTTS / delayed ascent - if( char_O_deco_status & DECO_ASCENT_DELAYED ) - { - // duration of delayed ascent - float_time = (float)char_I_extra_time; - } - else - { - // duration of bottom segment - float_time = (float)char_I_bottom_time; - } - - // calculate gas demand - gas_volumes_helper(); - - // take result - volumes[stop_gas-1] = volume; - } - - - // initialize stop index with first stop - i = 0; - - - //---- initial ascent demand --------------------------------------------- - - // stop_gas : gas from bottom segment - // char_I_bottom_depth : depth of the bottom segment - // internal_deco_depth[i=0]: depth of the first stop, may be 0 if no stop exists - - // get the data of the first stop - stop_depth = internal_deco_depth[i]; - stop_time = internal_deco_time[i]; - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( stop_gas ) - { - // compute distance between bottom and first stop - float_depth = (float)char_I_bottom_depth - (float)stop_depth; - - // initial ascent exists only if ascent distance is > 0 - if( float_depth > 0.0 ) - { - // compute ascent time - float_time = float_depth / float_ascent_speed; - - // compute average depth between bottom and first stop - float_depth = (float)char_I_bottom_depth - float_depth * 0.5; - - // calculate gas demand - gas_volumes_helper(); - - // add result - volumes[stop_gas-1] += volume; - } - } - - // switch the usage (SAC rate) to deco usage rate - // for stops, intermediate and final ascent - usage = char_I_deco_usage; - - // is there a (first) stop? if yes, goto stops processing - if( stop_depth ) goto stops; - - // add demand of a 3 minutes safety stop at 5 meters, at least for contingency... - float_time = 3.0; - float_depth = 5.0; - - // calculate gas demand - gas_volumes_helper(); - - // add result - volumes[stop_gas-1] += volume; - - // proceed to volume conversion and pressure calculations - goto done; - - - //---- intermediate ascent demand --------------------------------------- -inter_ascents: - - // store last stop depth and gas - stop_depth_last = stop_depth; - stop_gas_last = stop_gas; - - // check if we are at the end of the stops table - if( i < NUM_STOPS-1 ) - { - // there are more entries - get the next stop data - i++; - - // get the next stop depth - stop_depth = internal_deco_depth[i]; - - // check if there is indeed another stop, - // if not (depth = 0) treat as end of table - if( stop_depth == 0 ) goto end_of_table; - - // get the next stop duration - stop_time = internal_deco_time[i]; - } - else - { -end_of_table: - - // End of the stops table reached or no more stops: Split the remaining - // ascent into an intermediate ascent and a final ascent by creating a - // dummy stop at the usual last deco stop depth. Stop gas doesn't change. - stop_time = 0; - stop_depth = char_I_depth_last_deco; - } - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( stop_gas_last ) - { - // compute distance between the two stops: - // last stop will always be deeper than current stop - float_depth = (float)(stop_depth_last - stop_depth); - - // compute ascent time - float_time = float_depth / float_ascent_speed; - - // compute average depth between the two stops - float_depth = (float)stop_depth_last - float_depth * 0.5; - - // calculate gas demand - gas_volumes_helper(); - - // add result - volumes[stop_gas_last-1] += volume; - } - - - //---- next stop demand ------------------------------------------------- -stops: - - // convert depth of the stop - float_depth = (float)stop_depth; - - // get the next gas - stop_gas = internal_deco_gas[i]; - - // do we we have a gas change? - if( stop_gas_last && (stop_gas != stop_gas_last) ) - { - // yes - spend an additional char_I_gas_change_time on the old gas - float_time = (float)char_I_gas_change_time; - - // calculate gas demand - gas_volumes_helper(); - - // add result - volumes[stop_gas_last-1] += volume; - } - - // calculate and add demand on new gas for the full stop duration - if( stop_gas ) - { - // get the duration of the stop - float_time = (float)stop_time; - - // calculate gas demand - gas_volumes_helper(); - - // add result to last gas - volumes[stop_gas-1] += volume; - } - - // continue with the next intermediate ascent if this was not the last stop - if( stop_depth > char_I_depth_last_deco ) goto inter_ascents; - - - //---- final ascent demand ----------------------------------------------- -final_ascent: - - // float_depth: depth of last stop - // stop_gas : gas from last stop (0 or 1-5) - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( stop_gas ) - { - // set ascent time according to an ascent speed of 1 meter per minute - float_time = float_depth; - - // set half-way depth - float_depth *= 0.5; - - // calculate gas demand - gas_volumes_helper(); - - // add result - volumes[stop_gas-1] += volume; - } - - - //---- convert results for the assembler interface ----------------------------- -done: - - for(i=0; i<NUM_GAS; ++i) - { - if( volumes[i] >= 65534.5 ) - { - int_O_gas_volumes[i] = 65535; - int_O_tank_pres_need[i] = 999 + INT_FLAG_WARNING; // 999 bar + warning flag for > pres_fill - } - else - { - overlay unsigned short tank_pres_fill = 10.0 * (unsigned short)char_I_tank_pres_fill[i]; - - // No distinct rounding done here because volumes are not accurate to the single liter anyhow - - // convert gas volumes to integers - int_O_gas_volumes[i] = (unsigned short)volumes[i]; - - // compute how much pressure in the tank will be needed [in bar] (integer-division) - int_O_tank_pres_need[i] = (unsigned short)(int_O_gas_volumes[i] / char_I_tank_size[i]); - - // limit to 999 bar because of display constraints - if( int_O_tank_pres_need[i] > 999 ) int_O_tank_pres_need[i] = 999; - - // set flags for fast evaluation by divemode check for warnings - if ( int_O_tank_pres_need[i] == 0 ) - { - // set flag for 0 bar - int_O_tank_pres_need[i] |= INT_FLAG_ZERO; - } - else if( int_O_tank_pres_need[i] >= tank_pres_fill ) - { - // set warning flag - int_O_tank_pres_need[i] |= INT_FLAG_WARNING; - - } - else if( int_O_tank_pres_need[i] >= tank_pres_fill * GAS_NEEDS_ATTENTION_THRESHOLD ) - { - // set pre-warning flag - int_O_tank_pres_need[i] |= INT_FLAG_PREWARNING; - } - - // set invalid flag if there is an overflow in the stops table - if( char_O_deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) - int_O_tank_pres_need[i] |= INT_FLAG_INVALID; - - } // if( volumes[i] ) - } // for -} - -////////////////////////////////////////////////////////////////////////////// - -void compute_CNS_for_display(void) -{ - if ( CNS_fraction < 0.01 ) int_O_CNS_fraction = 0; - else if ( CNS_fraction >= 9.985 ) int_O_CNS_fraction = 999 + INT_FLAG_WARNING; - else - { - // convert float to integer - int_O_CNS_fraction = (unsigned short)(100 * CNS_fraction + 0.5); - - // compute warnings - if ( int_O_CNS_fraction >= CNS_warning_threshold ) - { - // reset pre-warning and set main warning flag - int_O_CNS_fraction &= ~INT_FLAG_PREWARNING; - int_O_CNS_fraction |= INT_FLAG_WARNING; - } - else if ( int_O_CNS_fraction >= CNS_prewarning_threshold ) - { - // reset main warning but set pre-warning flag - int_O_CNS_fraction &= ~INT_FLAG_WARNING; - int_O_CNS_fraction |= INT_FLAG_PREWARNING; - } - else - { - // clear both warnings - int_O_CNS_fraction &= ~(INT_FLAG_WARNING + INT_FLAG_PREWARNING); - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -void deco_push_tissues_to_vault(void) -{ - overlay unsigned char x; - - RESET_C_STACK - - low_depth_norm_vault = low_depth_norm; - low_depth_alt_vault = low_depth_alt; - cns_vault_float = CNS_fraction; - cns_vault_int = int_O_CNS_fraction; - deco_warnings_vault = char_O_deco_warnings; - - for (x=0;x<NUM_COMP;x++) - { - pres_tissue_N2_vault[x] = pres_tissue_N2[x]; - pres_tissue_He_vault[x] = pres_tissue_He[x]; - } -} - -void deco_pull_tissues_from_vault(void) -{ - overlay unsigned char x; - - RESET_C_STACK - - low_depth_norm = low_depth_norm_vault; - low_depth_alt = low_depth_alt_vault; - CNS_fraction = cns_vault_float; - int_O_CNS_fraction = cns_vault_int; - char_O_deco_warnings = deco_warnings_vault; - - locked_GF_step_norm = GF_delta / low_depth_norm; - locked_GF_step_alt = GF_delta / low_depth_alt; - - for (x=0; x<NUM_COMP; x++) - { - pres_tissue_N2[x] = pres_tissue_N2_vault[x]; - pres_tissue_He[x] = pres_tissue_He_vault[x]; - } -} - -////////////////////////////////////////////////////////////////////////////// -// -#ifndef CROSS_COMPILE -void main() {} -#endif
--- a/src/p2_deco.c Sun Jun 30 23:22:32 2019 +0200 +++ b/src/p2_deco.c Thu Sep 19 12:01:29 2019 +0200 @@ -1,5 +1,5 @@ // *************************************************************************** -// p2_deco.c combined next generation V3.03.4 +// p2_deco.c combined next generation V3.04.3 // // Created on: 12.05.2009 // Author: heinrichs weikamp, contributions by Ralph Lembcke and others @@ -104,8 +104,12 @@ // deco engine scheduling #define INVOKES_PER_SECOND 2 // number of invocations of the deco engine per second (use powers of 2 only: 1, 2, 4, ...) + +#ifdef _hwos_sport +#define BUDGET_PER_SECOND 320 // [ms] total time budget per second for the deco engine, each invocation will preempt after BUDGET_PER_SECOND / INVOKES_PER_SECOND +#else #define BUDGET_PER_SECOND 640 // [ms] total time budget per second for the deco engine, each invocation will preempt after BUDGET_PER_SECOND / INVOKES_PER_SECOND - +#endif // ambient pressure at different mountain heights #define P_ambient_1000m 0.880 // [bar] based on 990 hPa and 20C at sea level, 15C at altitude @@ -126,14 +130,16 @@ #define HYST 1.0E-06 // threshold for tissue graphics on-gassing / off-gassing visualization // thresholds -#define CNS_WARNING_THRESHOLD 100 // threshold for CNS warning -#define CNS_ATTENTION_THRESHOLD 70 // threshold for CNS attention -#define ppO2_GAP_TO_SETPOINT 10 // gap between setpoint and max. ppO2 of the pure diluent [cbar] -#define GAS_NEEDS_ATTENTION_THRESHOLD 0.70 // threshold for gas needs attention [1.00 = 100%] +#define CNS_LIMIT_WARNING 100 // threshold for CNS warning +#define CNS_LIMIT_ATTENTION 70 // threshold for CNS attention #define PRESSURE_LIMIT_WARNING 200 // threshold for pressure reading warning : 20.0 bar #define PRESSURE_LIMIT_ATTENTION 500 // threshold for pressure reading attention: 50.0 bar +#define GAS_NEEDS_LIMIT_ATTENTION 0.70 // threshold for gas needs attention [1.00 = 100%] #define O2_CONSUMPTION_LIMIT_ATTENTION 20 // threshold for O2 "SAC" attention: 2.0 l/min +#define ppO2_GAP_TO_SETPOINT 10 // gap between setpoint and max. ppO2 of the pure diluent [cbar] #define ppO2_MARGIN_ON_MAX 3 // [cbar] margin on ppO2 max to compensate for surface pressures > 1.000 mbar +#define STOP_CHAINING_LIMIT 5 // max. number of chained stop table entries before deco calculation is aborted + // deco engine states and modes - (char_O_)main_status: controls current tissue and deco status calculation (as-is situation) #define CALC_VOLUME 0x01 // =1: calculate gas needs @@ -162,7 +168,7 @@ #define INITIALIZE 0x04 // input: initialize deco engine #define INITIALIZE_START_NORM 0x05 // input: initialize deco engine and start calculation of a normal deco plan #define INITIALIZE_START_ALT 0x06 // input: initialize deco engine and start calculation of an alternative deco plan -// 0x08 // unused - reserved for further deco engine commands +#define DECO_CALCULATOR_MODE 0x08 // input: deco engine is run from deco calculator #define BAILOUT_MODE 0x10 // =1: allow gas switches before first deco stop #define DELAYED_ASCENT 0x20 // =1: figure in a delayed ascent (fTTS) @@ -181,10 +187,10 @@ #define DECO_WARNING_OUTSIDE 0x10 // tissue pressures outside the Buhlmann model now #define DECO_WARNING_OUTSIDE_lock 0x20 // tissue pressures outside the model sometime during the dive #define DECO_ATTENTION_OUTSIDE 0x40 // tissue pressures are very close to the Buhlmann limit -#define DECO_WARNING_STOPTABLE_OVERFLOW 0x80 // internal error: no more space in the deco stops table +#define DECO_WARNING_INCOMPLETE 0x80 // internal error: deco calculation incomplete // deco engine status (char_O_)deco_info -#define DECO_FLAG 0x01 // =1: deco ppO2 levels are permitted +#define DECO_MODE 0x01 // =1: deco ppO2 levels are permitted #define IND_DOUBLE_SWITCH_FLAG 0x02 // =1: switch to other tank advice active // 0x04 // --- unused #define DECO_ZONE 0x08 // =1: fTTS < TTS (not updated when in bailout mode) @@ -202,31 +208,20 @@ // deco engine control - next_planning_phase #define PHASE_00_DONE 0x00 // calculation cycle finished #define PHASE_10_DIVE_INIT 0x10 // once-per-dive initialization of the deco engine -#define PHASE_11_CYCLIC_INIT 0x11 // once-every-cycle initialization of the deco engine -#define PHASE_20_EXTENDED_BOTTOM_TIME 0x20 // calculate extended bottom time -#define PHASE_30_NDL_TIME 0x30 // calculate NDL time -#define PHASE_40_CAVE_ASCENT 0x40 // calculate cave mode return/ascent -#define PHASE_60_DECO_ASCENT 0x60 // calculate open water deco ascent -#define PHASE_70_RESULTS 0x70 // results - initialization -#define PHASE_71_RESULTS_STOPS_TABLE 0x71 // results - publish stops table -#define PHASE_72_RESULTS_NDL 0x72 // results - publish data / within NDL -#define PHASE_73_RESULTS_DECO 0x73 // results - publish data / in deco -#define PHASE_80_GAS_NEEDS_SWITCHES 0x80 // calculate gas needs - find gas switches in NDL bailout mode -#define PHASE_81_GAS_NEEDS_ASCENT 0x81 // calculate gas needs - needs of bottom segment and ascent -#define PHASE_82_GAS_NEEDS_PRESSURES 0x82 // calculate gas needs - conversion from volumes to pressures +#define PHASE_20_CYCLIC_INIT 0x20 // once-every-cycle initialization of the deco engine +#define PHASE_30_EXTENDED_BOTTOM_TIME 0x30 // calculate extended bottom time +#define PHASE_40_BOTTOM_GAS_NEED 0x40 // calculate gas needs for bottom segment +#define PHASE_50_NDL_TIME 0x50 // calculate NDL time +#define PHASE_60_CAVE_RETURN 0x60 // calculate cave mode return +#define PHASE_70_OPEN_WATER_ASCENT 0x70 // calculate open water ascent +#define PHASE_80_RESULTS 0x80 // results - initialization +#define PHASE_81_RESULTS_STOPS_TABLE 0x81 // results - publish stops table +#define PHASE_82_RESULTS_NDL 0x82 // results - publish data / within NDL +#define PHASE_83_RESULTS_DECO 0x83 // results - publish data / in deco +#define PHASE_84_GAS_NEEDS_PRESSURES 0x84 // results - convert gas needs from volumes to pressures #define PHASE_90_FINISH 0x90 // finish calculation cycle -// gas needs calculation - gas_needs_next_phase -#define GAS_NEEDS_INIT 0x00 // initialization -#define GAS_NEEDS_BOTTOM_SEGMENT 0x10 // demand during bottom segment -#define GAS_NEEDS_INITIAL_ASCENT 0x20 // demand of initial ascent -#define GAS_NEEDS_STOP 0x30 // demand on a stop -#define GAS_NEEDS_INTERMEDIATE_ASCENT 0x40 // demand on ascent between two stops -#define GAS_NEEDS_FINAL_ASCENT 0x50 // demand during final ascent -#define GAS_NEEDS_DONE 0x60 // calculation finished - - // flags used with integer numbers #define INT_FLAG_INVALID 0x0400 // =1: value not valid #define INT_FLAG_NOT_COMPUTED_YET 0x0800 // =1: value not computed yet @@ -265,7 +260,7 @@ // Functions combined for real Tissues & Deco Calculations static void calc_alveolar_pressures(void); // Computes the partial pressures from the gas ratios and many more parameters, // needs either calc_hauptroutine_data_input() be called beforehand or - // gas_find_current()/gas_find_better() and gas_set_ratios(). + // gas_take_current() or gas_find_best()/gas_take_best() and gas_set_ratios(). static void calc_tissues(void); // Updates the tissues dependent on the partial pressures of N2 and He. static void calc_CNS(void); // Updates the CNS value dependent on the partial pressure of the O2. static void calc_limit(PARAMETER float GF_current); @@ -278,17 +273,15 @@ // Functions dedicated to Deco Calculations static void clear_deco_table(void); // Clears the deco stops table, invoked at the start of each calculation cycle. -static void gas_find_current(void); // Sets the first gas used for deco calculation, invoked at start of cycle, too. -static unsigned char gas_find_better(void); // Checks for, and eventually switches to, a better gas. +static void gas_take_current(void); // Sets the first gas used for deco calculation, invoked at start of cycle, too. +static unsigned char gas_find_best(void); // Searches for the best gas available. +static void gas_take_best(void); // Switches to the best gas that has been found found before by gas_find_best(). static void gas_set_ratios(void); // Sets the gas ratios for use in deco calculation (simulated tissues), - // needs to be called after each gas change (gas_find_current/_better). + // needs to be called after each gas change (gas_take_current/_better). static void calc_NDL_time_tissue(void); // Calculates the remaining NDL time for a given tissue. -static void find_NDL_gas_changes(void); // Finds the gas changes in an OC bailout ascent that is within NDL. static unsigned char find_next_stop(void); // Finds the next stop when in a deco ascent. static unsigned char update_deco_table(PARAMETER unsigned char time_increment); // Enters a new stop or extends an existing stop in the deco stops table. -static void calc_ascenttime(void); // Calculates the ascent time from current depth and deco stop times. -static void calc_gas_needs_ascent(void); // Calculates required gas volumes and pressures from the data in stops table. static void calc_due_by_depth_time_sac(void); // Calculates gas volume required for a given depth, time and usage (SAC rate). static void convert_gas_needs_to_press(void); // Converts gas volumes into pressures and sets respective flags. @@ -312,9 +305,10 @@ static void adopt_Buhlmann_coefficients(void); // Computes average a and b coefficient by the N2/He tissue ratio. static void push_tissues_to_vault(void); // Stores the state of the real tissues during simulator runs. static void pull_tissues_from_vault(void); // Restores the state of the real tissues after a simulator run. -static void calc_N2_equilibrium(void); // Calculate partial pressure of N2 in respired air at surface pressure -static void get_saturation_factors(void); // Get, safeguard and convert the saturation and desaturation factors -static void apply_saturation_factors(void); // Applies saturation and desaturation factors +static void calc_sim_pres_respiration(void); // Calculate sim_pres_respiration from char_depth_sim. +static void calc_N2_equilibrium(void); // Calculate partial pressure of N2 in respired air at surface pressure. +static void get_saturation_factors(void); // Get, safeguard and convert the saturation and desaturation factors. +static void apply_saturation_factors(void); // Applies saturation and desaturation factors. // ********************************************************************************************************************************* @@ -332,11 +326,11 @@ static float pres_surface; // absolute pressure at the surface -static float float_depth_real; // current real depth in meters, float -static unsigned char char_depth_real; // current real depth in meters, integer -static unsigned char char_depth_sim; // current simulated depth in meters, integer -static unsigned char char_depth_last; // last simulated depth in meters, integer -static unsigned char char_depth_bottom; // bottom depth in meters, integer +static float float_depth_real; // current real depth in meters, float +static unsigned char char_depth_real; // current real depth in meters, integer +static unsigned char char_depth_sim_start; // start value of simulated depth in meters, integer +static unsigned char char_depth_sim; // current value of simulated depth in meters, integer +static unsigned char char_depth_last; // last value of simulated depth in meters, integer static float real_pres_respiration; // current real depth in absolute pressure static float real_O2_ratio; // real breathed gas oxygen ratio @@ -368,7 +362,7 @@ static float GF_slope_alt; // (GF_high - GF_low) / GF_low_depth_alt in alternative plan static float float_ascent_speed; // ascent speed from options_table (5.0 .. 10.0 m/min) -static float float_deco_distance; // additional depth below stop depth for tissue, CNS and gas volume calculation +static float float_deco_distance; // additional depth below stop depth - not used any more static float float_saturation_multiplier; // safety factor for on-gassing rates static float float_desaturation_multiplier; // safety factor for off-gassing rates @@ -395,6 +389,7 @@ static unsigned char NDL_tissue_lead; // tissue with the shortest NDL time found in current cycle static unsigned char NDL_tissue; // tissue for which the NDL is calculated right now + // Result Values from Calculation Functions (9 byte) static float ceiling; // minimum tolerated relative pressure (i.e. without surface pressure) @@ -411,45 +406,28 @@ static unsigned short int_time; // time it takes for the compartment to reach the target pressure -// Gas in Use and Gas Needs (30 byte) - +// Gas in Use and Gas Needs (26 byte) + +static unsigned char sim_gas_last_num; // number of the last used gas static unsigned char sim_gas_current_num; // number of the currently used gas static unsigned char sim_gas_current_depth; // change depth of the currently used gas -static unsigned char gas_needs_stop_time; // duration of the stop in minutes -static unsigned char gas_needs_stop_gas; // gas used now (1-5 or 0) -static unsigned char gas_needs_stop_gas_last; // gas used before (1-5 or 0) -static unsigned char gas_needs_stop_depth; // depth of the stop in meters -static unsigned char gas_needs_stop_depth_last; // depth of the last stop in meters -static unsigned char gas_needs_stop_index; // index to the stop table +static unsigned char sim_gas_best_num; // number of the better gas +static unsigned char sim_gas_best_depth; // change depth of the better gas + static unsigned char gas_needs_gas_index; // index to the gas and tank data arrays -static unsigned char gas_needs_next_phase; // next phase within the ascent gas needs calculation - -static float gas_volume_need[NUM_GAS]; // gas volumes required for return/ascent in liters - - -// Transfer Variables between calc_gas_needs_ascent() and calc_due_by_depth_time_sac() (13 byte) - -static float gas_needs_float_depth; // depth of the stop or half-way point -static float gas_needs_float_time; // duration of the stop or ascent phase -static unsigned char gas_needs_stop_usage; // gas usage in l/min +static float gas_volume_need[NUM_GAS]; // gas volumes required for return/ascent in liters +static float gas_volume_avail[NUM_GAS]; // gas volumes available for return/ascent in liters + + +// Transfer Variables for calc_due_by_depth_time_sac() (7 byte) + +static unsigned char gas_needs_depth; // depth of the stop or half-way point +static unsigned char gas_needs_time; // duration of the stop or ascent phase +static unsigned char gas_needs_usage_rate; // gas usage in l/min static float gas_needs_volume_due; // computed due of gas volume required -// CNS Coefficients (10 byte) - -static float var_cns_a; // two coefficients approximation, gain -static float var_cns_b; // two coefficients approximation, offset -static unsigned short var_cns_c; // one coefficient approximation, value - - -// Transfer values for convert_float_int and convert_float_to_char() (7 byte) - -static float float_value; // input value, float -static unsigned short int_value; // output value, 16 bit -static unsigned char char_value; // output value, 8 bit - - // Auxiliary Variables for Data Buffering (28 byte) static float N2_equilibrium; // used for N2 tissue graphics scaling @@ -461,14 +439,7 @@ static float old_pres_respiration; // auxiliary variable to buffer sim_pres_respiration -// Performance Profiling (4 byte) - -static unsigned short profiling_runtime; // performance measurement: runtime of current invocation -static unsigned char profiling_runs; // performance measurement: invocations per deco calculation cycle -static unsigned char profiling_phase; // performance measurement: current calculation phase - - -// 255 byte used, 1 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) +// 244 byte used, 12 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) //---- Bank 6 parameters ----------------------------------------------------- @@ -482,7 +453,7 @@ static volatile unsigned char tmr5_overflow; // timer 5 overflow flag MUST be at address 0x602 -// Modes, Sequencing and Indexing (11 byte) +// Modes, Sequencing and Indexing (12 byte) static unsigned char main_status; // shadow register for char_O_main_status static unsigned char deco_status; // shadow register for char_O_deco_status @@ -495,6 +466,8 @@ static unsigned char cns_i; // index to the CNS tables (ppO2 range index) static unsigned char i; // general purpose loop counter and index static unsigned char fast; // selects 1 minute or 2 second ascent steps +static unsigned char stop_index; // current stop table position +static unsigned char chained_stops; // counter for chained stop entries // Result Values from Calculation Functions (28 byte) @@ -526,6 +499,13 @@ static float var_He_ht; // half-time, for current He tissue +// CNS Coefficients (10 byte) + +static float var_cns_a; // two coefficients approximation, gain +static float var_cns_b; // two coefficients approximation, offset +static unsigned short var_cns_c; // one coefficient approximation, value + + // Vault to back-up & restore Tissue related Data (134 byte) static float vault_pres_tissue_N2[NUM_COMP]; // stores the nitrogen tissue pressures @@ -535,10 +515,24 @@ static unsigned char vault_deco_info; // stores info status +// Transfer values for convert_float_int and convert_float_to_char() (7 byte) + +static float float_value; // input value, float +static unsigned short int_value; // output value, 16 bit +static unsigned char char_value; // output value, 8 bit + + +// Performance Profiling (4 byte) + +static unsigned short profiling_runtime; // performance measurement: runtime of current invocation +static unsigned char profiling_runs; // performance measurement: invocations per deco calculation cycle +static unsigned char profiling_phase; // performance measurement: current calculation phase + + // 7 byte occupied by compiler-placed vars -// 223 byte used, 33 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) +// 245 byte used, 11 byte left in this bank (4 bytes per float, 2 bytes per short, 1 byte per char) @@ -601,7 +595,7 @@ #endif rom const float CNS_ab[2*11] = { -// CNS increment per 2sec = 1 / (a*ppO2 + b) with ppO2 in [cbar] +// CNS increment per 2 sec = 1 / (a*ppO2 + b) with ppO2 in [cbar] // a b for ppO2 cbar range -533.07, 54000, // 51 - 60 (index 0) -444.22, 48600, // 61 - 70 (index 1) @@ -616,8 +610,8 @@ -222.11, 37350 // 151 - 160 (index 10) }; -rom const unsigned short CNS_c[1*20] = { -// CNS increment per 2sec = c / 100000.0 +rom const unsigned short CNS_c[1*18] = { +// CNS increment per 2 sec = c / 100000.0 // c in [1/100000] for ppO2 cbar range 75, // 161 - 165 (index 0) 102, // 166 - 170 (index 1) @@ -636,9 +630,7 @@ 4820, // 231 - 235 (index 14) 4820, // 236 - 240 (index 15) 4820, // 241 - 245 (index 16) - 4820, // 246 - 250 (index 17) - 4820, // 251 - 255 (index 18) - 0 // not used, just to fill up the memory block + 4820 // 246 - 250 (index 17) }; @@ -668,7 +660,7 @@ }; rom const float Buhlmann_ht[2*16] = { -// Compartment half-life, in minute +// Compartment half-life, in minutes //--- N2 ---- He ---------------------- 4.0, 1.51, 8.0, 3.02, @@ -689,7 +681,8 @@ }; rom const float e2secs[2*16] = { -// result of 1 - 2^(-1/(2sec*HT)) +// Integration constant for 2 seconds, +// result of 1 - 2^(-1/(2sec/60sec * HT)) //---- N2 ------------- He ------------ 5.75958E-03, 1.51848E-02, 2.88395E-03, 7.62144E-03, @@ -712,7 +705,7 @@ rom const float e1min[2*16] = { // Integration constant for 1 minute, -// Ie. 1- 2^(-1/HT) +// result of 1 - 2^(-1/HT) //----- N2 --------- e 1min He -------- 1.59104E-01, 3.68109E-01, 8.29960E-02, 2.05084E-01, @@ -734,8 +727,8 @@ }; rom const float e10min[2*16] = { -// The 10 min Value in float notation: -// result of 1 - 2^(-10/ht) +// Integration constant for 10 minutes, +// result of 1 - 2^(-10/ht) //---- N2 -------------- He ----------- 8.23223E-01, 9.89851E-01, 5.79552E-01, 8.99258E-01, @@ -764,7 +757,7 @@ // ********************************************************************************************************************************* -// moved from 0x0D000 to 0x0C000 in v.108 +// p2deco code moved from 0x0D000 to 0x0C000 in v.108 #ifndef UNIX # pragma code p2_deco = 0x0C000 #endif @@ -780,8 +773,8 @@ ////////////////////////////////////////////////////////////////////////////// -// When calling C code from ASM context, the data stack pointer and -// frames should be reset. Bank 8 is used by stack. +// When calling C code from ASM context, the C data stack pointer need to be +// reset. The C stack is located in bank 8. #ifdef CROSS_COMPILE # define RESET_C_STACK @@ -914,7 +907,7 @@ // Note: We don't use far ROM pointer, because handling // 24 bit is too complex, hence we have to set the // UPPER page ourself... - // -> Set to zero if tables are moved to lower pages! + // -> set to zero if tables are moved to lower pages! _asm movlw 1 movwf TBLPTRU,0 @@ -1047,6 +1040,20 @@ ////////////////////////////////////////////////////////////////////////////// +// Calculate sim_pres_respiration from char_depth_sim +// +// Input: char_depth_sim simulated depth in meters +// pres_surface surface pressure +// +// Output: sim_pres_respiration simulated depth in absolute pressure +// +static void calc_sim_pres_respiration(void) +{ + sim_pres_respiration = (float)char_depth_sim * METER_TO_BAR + pres_surface; +} + + +////////////////////////////////////////////////////////////////////////////// // Calculate partial pressure of N2 in respired air at surface pressure // // Input: pres_surface surface pressure @@ -1138,13 +1145,13 @@ // // called from: divemode.asm // -// Called every second during diving, -// updates tissues on every second invocation. +// Called two times per second during diving, updates the +// tissues every second (i.e. on every second invocation). // -// Every few seconds (or slower when TTS > 16): +// On each computation cycle: // - Updates deco table (char_O_deco_time/depth) with new values, // - updates ascent time, and -// - sets status to zero (so we can check there is new results). +// - sets status to zero (so we can check a cycle has finished). // void deco_calc_hauptroutine(void) { @@ -1166,6 +1173,7 @@ init_output_vars(); } + ////////////////////////////////////////////////////////////////////////////// // deco_clear_tissue // @@ -1173,7 +1181,7 @@ // menu_tree.asm // simulator.asm // -// Sets all tissues to equilibrium with Air at ambient pressure, +// Sets all tissues to equilibrium with air at ambient pressure, // resets all CNS values, any warnings and resets all model output. // void deco_clear_tissue(void) @@ -1188,9 +1196,9 @@ // // called from: simulator.asm // -// Updates tissues and CNS value for char_I_dive_interval minutes on air -// at ambient pressure and calculates resulting GF factor and ceiling for -// a GF-high of 100% (ceiling and GF factor not used by simulator.asm) +// Updates tissues and CNS value for char_I_dive_interval minutes on air at +// ambient pressure and calculates resulting saturation and ceiling for a +// GF-high of 100% (ceiling and saturation not used by simulator.asm) // void deco_calc_dive_interval(void) { @@ -1209,8 +1217,7 @@ // ghostwriter.asm // // Updates tissues and CNS value for 1 minute on air at ambient pressure and -// calculates resulting GF factor and ceiling for a GF-high of 100% (ceiling -// is not used by *.asm files). +// calculates resulting saturation and ceiling for a GF-high of 100%. // void deco_calc_dive_interval_1min(void) { @@ -1225,8 +1232,7 @@ // called from: sleepmode.asm // // Updates tissues and CNS value for 10 minutes on air at ambient pressure and -// calculates resulting GF factor and ceiling for a GF-high of 100% (ceiling -// is not used by sleepmode.asm). +// calculates resulting saturation and ceiling for a GF-high of 100%. // void deco_calc_dive_interval_10min(void) { @@ -1289,15 +1295,13 @@ ////////////////////////////////////////////////////////////////////////////// -// find_next_stop +// Calculate the next deco stop // // INPUT, fixed during dive: // pres_surface : surface pressure (as absolute pressure) // char_I_depth_last_deco : depth of the last deco stop // -// INPUT, changing during dive: -// float_depth_real : current real depth in meters (float) -// char_depth_real : current real depth in meters (integer) +// INPUT, may change during dive: // GF_high : GF high factor // GF_low : GF low factor // @@ -1319,48 +1323,31 @@ { overlay unsigned char depth_1min; overlay unsigned char depth_limit; - overlay unsigned char first_stop; + overlay unsigned char stop_depth; + overlay unsigned char next_stop; overlay unsigned char need_stop; - // ----------------------------------------------------------------------- - // we start with the assumption that a stop is not required - // ----------------------------------------------------------------------- - - need_stop = 0; - - // remember the depth we came from + // memorize the depth we came from char_depth_last = char_depth_sim; - // calculate the limit for the current depth - if( char_I_deco_model == 0 ) calc_limit(1.0); // straight Buhlmann - else if( char_depth_sim >= GF_low_depth ) calc_limit(GF_low); // with GF, below low depth reference - else calc_limit(GF_high - GF_slope * (float)char_depth_sim); // with GF, above low depth reference - - // check if we can surface directly - if( ceiling <= 0.0 ) - { - // YES - ascent to surface is allowed - char_depth_sim = 0; - - // - done - goto done; - } - - // ----------------------------------------------------------------------- - // a stop is required, but maybe not yet within the running minute - // ----------------------------------------------------------------------- - - // convert the depth we can ascent to from relative pressure to meters, - // rounded up (i.e. made deeper) to next full meter. - depth_limit = (unsigned char)(ceiling * BAR_TO_METER + 0.99); - - // calculate the stop depth, i.e. round up to the next multiple of 3 meters - // using integer arithmetics - first_stop = 3 * ( (depth_limit + 2) / 3 ); + // calculate the ceiling (minimum relative pressure) for the current depth + if( char_I_deco_model == 0 ) calc_limit(1.0); // deco or not - straight Buhlmann + else if( NDL_time ) calc_limit(GF_high); // not in deco + else if( char_depth_sim >= GF_low_depth ) calc_limit(GF_low); // in deco with GF, below or at low depth reference + else calc_limit(GF_high - GF_slope * (float)char_depth_sim); // in deco with GF, above low depth reference + + // convert the ceiling from relative pressure to meters, + // rounded up (i.e. made deeper) to next full meter, + // limiting at surface. + depth_limit = (ceiling > 0.0) ? (unsigned char)(ceiling * BAR_TO_METER + 0.99) : 0; + + // calculate the stop depth, i.e. round up (make deeper) to + // the next multiple of 3 meters using integer arithmetics + stop_depth = 3 * ( (depth_limit + 2) / 3 ); // apply correction for the shallowest stop - if( first_stop == 3 ) first_stop = char_I_depth_last_deco; + if( stop_depth == 3 ) stop_depth = char_I_depth_last_deco; // compute depth in meters that will be reached in 1 minute of ascent // at a speed of char_I_ascent_speed (5..10 m/min) @@ -1373,36 +1360,53 @@ depth_1min = 0; } - // is the stop shallower than the depth that can be reached within 1 minute? - if( depth_1min > first_stop ) + // is the stop depth shallower than the depth that can be reached within 1 minute, + // or are we allowed to surface AND can we reach the surface within 1 minute? + if( ( ( stop_depth < depth_1min ) ) + || ( ( stop_depth == 0 ) && ( depth_1min == 0 ) ) + ) { // YES - report the depth that will be reached within 1 minute of ascent char_depth_sim = depth_1min; + // - no stop needed + need_stop = 0; + // - done goto done; } // ----------------------------------------------------------------------- - // we need to make a stop now + // we need to make a stop now, or need to stay at the current stop depth // ----------------------------------------------------------------------- // set stop data need_stop = 1; - char_depth_sim = first_stop; + char_depth_sim = stop_depth; + + // Apply correction in case the stop is to be placed deeper than a + // previously recorded stop for a gas change. This may happen because + // the deco stops are placed at the next deeper multiple of 3 meters + // instead of the real stop's depth. Correction is to relocate the + // deco stop to the depth of the last gas change. The resulting combined + // stop's duration will be the sum of the configured gas change time plus + // the duration of the deco stop itself. + if( 0 < internal_deco_depth[stop_index] ) + if( char_depth_sim > internal_deco_depth[stop_index] ) + char_depth_sim = internal_deco_depth[stop_index]; // done so far if using straight Buhlmann if( char_I_deco_model == 0 ) goto done; // ----------------------------------------------------------------------- - // we need to make a stop now and we are using the GF extension + // we need to make or hold a stop and we are using the GF extension // ----------------------------------------------------------------------- - // is the depth limit deeper than the GF low depth reference used up to now? - if( depth_limit > GF_low_depth ) + // is the stop depth deeper than the GF low depth reference used up to now? + if( stop_depth > GF_low_depth ) { // YES - update the reference - GF_low_depth = depth_limit; + GF_low_depth = stop_depth; GF_slope = (GF_high - GF_low) / (float)GF_low_depth; // store for use in next cycles @@ -1418,13 +1422,6 @@ } } - // keep the stop as it is when it is the first stop - // (i.e. there are no stops in the stops table yet) - if( internal_deco_depth[0] == 0 ) goto done; - - // keep the stop as it is when extended stops are activated - if( main_status & EXTENDED_STOPS ) goto done; - // We have a (first) stop. But with a steep GF slope, the stop(s) after this // first stop may be allowed to ascent to, too. This is because the gradient // factor that will be used at the next depth(s) will allow more tissue super- @@ -1432,35 +1429,39 @@ // ascent to. So we have to probe the next stops that are within the reach of // 1 minute of ascent as well. - // no need to probe for a stop that is beyond 1 minute of ascent - while( first_stop >= (depth_1min + 3) ) + // probe all stop depths that are in reach of 1 minute of ascent + next_stop = stop_depth; + + while(next_stop > 0) { - overlay unsigned char next_stop; - - // compute the depth of the next stop - if ( first_stop <= char_I_depth_last_deco ) next_stop = 0; - else if ( first_stop == 6 ) next_stop = char_I_depth_last_deco; - else next_stop = first_stop - 3; - - // compute the depth limit at the next stop depth - calc_limit(GF_high - GF_slope * (float)next_stop); - - // check if ascent to the next stop is allowed - if( next_stop < (unsigned char)(ceiling * BAR_TO_METER + 0.99) ) + // compute the depth of the next stop ... + if ( next_stop <= char_I_depth_last_deco ) next_stop = 0; + else if ( next_stop == 6 ) next_stop = char_I_depth_last_deco; + else next_stop -= 3; + + // would the next stop be beyond the 1 minute limit? + if( next_stop < depth_1min ) { - // NO - the next stop would be too shallow - break; + // YES - signal that probing is done + next_stop = 0; } else { - // YES - the next stop is allowed - char_depth_sim = next_stop; - - // - ascent to next stop - first_stop = next_stop; - - // - loop to probe the stop following next - continue; + // NO - compute the ceiling at the next stop depth + calc_limit(GF_high - GF_slope * (float)next_stop); + + // - limit ceiling to positive values, i.e. the surface + if( ceiling < 0.0 ) ceiling = 0.0; + + // - check if this stop depth would be allowed + if( next_stop >= (unsigned char)(ceiling * BAR_TO_METER + 0.99) ) + { + // YES - this stop depth is allowed + char_depth_sim = next_stop; + + // - no stop needed if stop depth actually is the surface + if( next_stop == 0 ) need_stop = 0; + } } } @@ -1472,68 +1473,21 @@ done: // calculate absolute pressure at the depth found - sim_pres_respiration = char_depth_sim * METER_TO_BAR + pres_surface; + calc_sim_pres_respiration(); return need_stop; } ////////////////////////////////////////////////////////////////////////////// -// publish_deco_table -// -// Input: internal_deco_depth[] depth in internal stops table -// internal_deco_time[] times ... -// internal_deco_gas[] gases ... -// -// Output: char_O_deco_depth[] depth in the external stops table -// char_O_deco_time[] times ... -// char_O_deco_gas[] gases ... -// char_O_deco_time_for_log times in reverse order -// -static void publish_deco_table(void) -{ - overlay unsigned char x = 0; - overlay unsigned char y; - - - // copy all entries from internal to external stops table - for( y = 0; y < NUM_STOPS; y++ ) - { - // remember index of last entry with a non-null depth - if( internal_deco_depth[y] > 0 ) x = y; - - // copy depth, time and gas - char_O_deco_depth[y] = internal_deco_depth[y]; - char_O_deco_time [y] = internal_deco_time [y]; - char_O_deco_gas [y] = internal_deco_gas [y]; - } - - - // copy times of shallowest stops to logging table - for( y = 0; y < NUM_STOPS_LOG; y++, --x ) - { - char_O_deco_time_for_log[y] = internal_deco_time [x]; - - // stop when all entries are copied - if( x == 0 ) break; - } - - // fill the remainder of the logging table with null - // if it is not completely filled already - for( y++; y < NUM_STOPS_LOG; y++ ) - char_O_deco_time_for_log[y] = 0; -} - - -////////////////////////////////////////////////////////////////////////////// -// Find current gas in the list (if any) and get its change depth +// Find current gas in the list and get its change depth // // Input: char_I_current_gas_num number of current gas (1..5 or 6) // // Output: sim_gas_current_num 1..6 or 0 for the manually configured gas/dil // sim_gas_current_depth change depth (MOD) of the gas/dil in meters // -static void gas_find_current(void) +static void gas_take_current(void) { assert( 1 <= char_I_current_gas_num && char_I_current_gas_num <= 6 ); @@ -1541,6 +1495,9 @@ { sim_gas_current_num = char_I_current_gas_num; sim_gas_current_depth = char_I_deco_gas_change[sim_gas_current_num-1]; + + // capture case of non-configured change depth + if( sim_gas_current_depth == 0 ) sim_gas_current_depth = 255; } else { @@ -1551,34 +1508,27 @@ ////////////////////////////////////////////////////////////////////////////// -// Find the deco gas with the shallowest change depth below or at the current depth +// Find the gas with the shallowest change depth below or at the current depth // // Input: char_depth_sim simulated depth in meters // sim_gas_current_num number of the currently used gas/dil -// sim_gas_current_depth change depth of the currently used gas/dil // char_I_deco_gas_type[] types of the gases/dils // char_I_deco_gas_change[] change depths of the gases/dils // -// Modified: sim_gas_current_num index of the gas (1..5) - only if return value is true -// sim_gas_current_depth switch depth - only if return value is true +// Modified: sim_gas_best_num index of the gas (1..5) - only if return value is true +// sim_gas_best_depth switch depth - only if return value is true // // Return value is TRUE if a better gas is available // -static unsigned char gas_find_better(void) +static unsigned char gas_find_best(void) { overlay unsigned char switch_depth = 255; overlay unsigned char switch_gas = 0; overlay unsigned char j; - // // no automatic gas changes in CCR mode - // if( (deco_status & MODE_MASK) == MODE_CCR ) return 0; - - // loop over all deco gases to find the shallowest one below or at current depth + // loop over all gases to find the shallowest one below or at current depth for( j = 0; j < NUM_GAS; ++j ) { - // Is this gas not the one we are already breathing? - if( j+1 != sim_gas_current_num ) - // Is this gas available? if( char_I_deco_gas_type[j] > 0 ) @@ -1586,42 +1536,58 @@ // at least equal to the current depth? if( char_I_deco_gas_change[j] >= char_depth_sim ) - // Is the change depth of this gas shallower than the - // change depth of the gas we are currently on? - if( char_I_deco_gas_change[j] < sim_gas_current_depth ) - - // Is the change depth of this gas shallower than the change - // depth of the best gas found so far, or is it the first - // better gas found? - if( char_I_deco_gas_change[j] < switch_depth ) + // Is the change depth of this gas shallower than or + // at least equal to the change depth of the best gas + // found so far, or is it the first better gas found? + if( char_I_deco_gas_change[j] <= switch_depth ) + +#ifdef _gas_contingency + // Is there still enough of this gas or doesn't it matter? + if( ( gas_volume_need[j] < gas_volume_avail[j] ) || ( !char_I_gas_contingency ) ) +#endif // If there is a yes to all these questions, we have a better gas! { - switch_gas = j+1; // remember this gas (1..5) - switch_depth = char_I_deco_gas_change[j]; // remember its change depth + // memorize this gas (1..5) and its change depth + switch_gas = j+1; + switch_depth = char_I_deco_gas_change[j]; } - } // continue looping through all gases to eventually find an even better gas - // has a better gas been found? + // has a best gas been found? if( switch_gas ) { - // YES - set the better gas as the new gas - sim_gas_current_num = switch_gas; - - // set its change depth as the last used change depth - sim_gas_current_depth = switch_depth; - - assert( sim_gas_current_depth < switch_depth ); - - // signal a better gas was found - return 1; + // YES - export the best gas and its change depth + sim_gas_best_num = switch_gas; + sim_gas_best_depth = switch_depth; + + // is the best gas different from the current gas? + if( sim_gas_best_num != sim_gas_current_num ) + { + // YES - signal advice for a gas change + return 1; + } } - else - { - // NO - signal no better gas was found - return 0; - } + + // no best gas found or current gas is the best gas + return 0; +} + + +////////////////////////////////////////////////////////////////////////////// +// Switch to the best gas +// +// Input: sim_gas_best_num index of the best gas (1..5) +// sim_gas_best_depth switch depth of the best gas +// +// Modified: sim_gas_current_num index of the new gas (1..5) +// sim_gas_current_depth switch depth of the new gas +// +static void gas_take_best(void) +{ + // set new gas + sim_gas_current_num = sim_gas_best_num; + sim_gas_current_depth = sim_gas_best_depth; } @@ -1699,7 +1665,7 @@ // sim_/real_pSCR_drop : (simulated) pSCR O2 drop // pres_surface : surface pressure [bar] // char_I_const_ppO2 : ppO2 reported from sensors or setpoint [cbar] -// float_deco_distance : safety factor, additional depth below stop depth [bar] +// float_deco_distance : safety factor, additional depth below stop depth [bar] - not used any more // ppWater : water-vapor pressure inside respiratory tract [bar] // // Output: ppN2 : respired N2 partial pressure @@ -1759,6 +1725,8 @@ // correct sim_pres_respiration if shallower than calculated stop depth calc_pres_respiration = ( real_pres_respiration < sim_pres_respiration ) ? real_pres_respiration : sim_pres_respiration; + // +++ pressure surcharge if outside deco stops area yet ??? + status = deco_status; calc_O2_ratio = sim_O2_ratio; calc_N2_ratio = sim_N2_ratio; @@ -1866,8 +1834,8 @@ //---- calculate ppN2 and ppHe --------------------------------------------------------------------- - // add deco safety distance when working on simulated tissues - if( !(tissue_increment & TISSUE_SELECTOR) ) calc_pres_respiration += float_deco_distance; + // add deco safety distance when working on simulated tissues - not used any more + // if( !(tissue_increment & TISSUE_SELECTOR) ) calc_pres_respiration += float_deco_distance; // compute ppN2 and ppHe, capture potential failure conditions first: if( calc_pres_respiration > ppWater ) @@ -1891,12 +1859,29 @@ ppN2 = 0.0; ppHe = 0.0; } + +#ifdef _helium + // calculating real tissues? + if( tissue_increment & TISSUE_SELECTOR ) + { + overlay unsigned char temp; + + // compute gas density of current mix in multiples of 0.01 grams per liter + int_O_gas_density = (unsigned int)( 17.9 * ppHe + 125.1 * ppN2 + 142.8 * ppO2 ); + + // convert gas density into a 8 bit integer + temp = (unsigned char)( (int_O_gas_density + 9) / 10 ); + + // limit to display max and set warning or attention flag + if( temp > 99 ) int_O_gas_density = 999 | INT_FLAG_WARNING; + else if( temp > char_I_gas_density_warn ) int_O_gas_density |= INT_FLAG_WARNING; + else if( temp > char_I_gas_density_att ) int_O_gas_density |= INT_FLAG_ATTENTION; + } +#endif } ////////////////////////////////////////////////////////////////////////////// -// init_output_vars -// // Initializes all output variables to their default values // static void init_output_vars(void) @@ -1939,14 +1924,19 @@ int_O_SAC_measured = 0 + INT_FLAG_NOT_AVAIL; // SAC rate int_O_pressure_need[0] = 0 + INT_FLAG_NOT_AVAIL; // pressure need to reading 1 int_O_pressure_need[1] = 0 + INT_FLAG_NOT_AVAIL; // pressure need to reading 2 + int_O_tank_pressure = 0; // tank pressure for logging #endif +#ifdef _helium + int_O_gas_density = 0; +#endif + + // also clear any time++ request + char_I_sim_advance_time = 0; } ////////////////////////////////////////////////////////////////////////////// -// clear_tissue -// // Reset all tissues to surface pressure equilibrium state // // Input: int_I_pres_surface current surface pressure in hPa (mbar) @@ -2007,7 +1997,7 @@ ////////////////////////////////////////////////////////////////////////////// -// calc_hauptroutine +// Deco engine main code // // This is the major code in dive mode, it calculates the tissue pressures, // the bottom time, and it calculates the ascend with all deco stops, etc. @@ -2021,7 +2011,6 @@ // // char_I_deco_model selector for GF extension // char_I_ascent_speed ascent speed -// char_I_deco_distance safety distance between stop depth and calculated depth // char_I_saturation_multiplier safety factor for tissue saturation // char_I_desaturation_multiplier safety factor for tissue desaturation // @@ -2056,9 +2045,9 @@ static void calc_hauptroutine(void) { overlay unsigned short int_ppO2_min; - overlay unsigned short int_ppO2_max; + overlay unsigned short int_ppO2_max_warn; + overlay unsigned short int_ppO2_max_att; overlay unsigned short int_ppO2_max_dil; - overlay unsigned short int_ppO2_max_max; overlay float EAD; overlay float END; @@ -2112,7 +2101,7 @@ char_O_deco_status &= ~COMMAND_MASK; // set the calculation phase to start with to doing the cyclic initialization - next_planning_phase = PHASE_11_CYCLIC_INIT; + next_planning_phase = PHASE_20_CYCLIC_INIT; // continue in CALCULATING @@ -2155,7 +2144,7 @@ // acquire current environmental data calc_hauptroutine_data_input(); - // calculate ppO2, ppN2 and ppHe + // calculate ppO2, ppN2 and ppHe for real tissues calc_alveolar_pressures(); // add decent calculation here and include trigger in above if-statement @@ -2239,52 +2228,56 @@ #endif - //---- Set/Reset Deco Mode -------------------------------------------------------------------- + //---- Set/Clear Deco Mode ------------------------------------------------------------------ + + // Clear the deco mode flag if: + // deco mode is set + // AND we are deeper than 7 meters below the deepest deco stop + // (7 meters chosen as to be 2 stop depth intervals plus 1 additional meter below) + if ( ( deco_info & DECO_MODE ) > 0 ) + if ( ( char_depth_real ) > char_O_deco_depth[0] + 7 ) + deco_info &= ~DECO_MODE; // Set the deco mode flag if: // deco mode is not set // AND breathing an OC deco gas (gas type 3) // OR breathing a gas or diluent that officially is disabled (type 0) - // OR there is a deco stop and we are less deep than 1 meter below the deepest deco stop - if ( ( deco_info & DECO_FLAG ) == 0 ) - if ( ( char_I_current_gas_type == 3 ) - || ( char_I_current_gas_type == 0 ) - || ( ( char_O_deco_depth[0] > 0 ) && ( char_depth_real <= char_O_deco_depth[0] + 1 ) ) + // OR there is a deco stop + if ( ( deco_info & DECO_MODE ) == 0 ) + if ( ( char_I_current_gas_type == 3 ) + || ( char_I_current_gas_type == 0 ) + || ( char_O_deco_depth[0] > 0 ) ) - deco_info |= DECO_FLAG; - - // Clear the deco mode flag if: - // deco mode is set - // AND deeper than 7 meters below deepest deco stop (7 meters = 2 stop depth intervals plus 1 meter below stop) - if ( ( deco_info & DECO_FLAG ) > 0 ) - if ( ( char_depth_real > char_O_deco_depth[0] + 7 ) - ) - deco_info &= ~DECO_FLAG; + deco_info |= DECO_MODE; //---- Compute ppO2 Warnings ------------------------------------------------------------------ - // compute conditional min values + // compute conditional min value #ifdef _ccr_pscr int_ppO2_min = ( main_status & MODE_LOOP ) ? (unsigned short)char_I_ppO2_min_loop : (unsigned short)char_I_ppO2_min; #else int_ppO2_min = (unsigned short)char_I_ppO2_min; #endif - // compute conditional max values - int_ppO2_max = ( deco_info & DECO_FLAG ) ? (unsigned short)char_I_ppO2_max_deco : (unsigned short)char_I_ppO2_max_work; - - // add some margin on ppO2 max to compensate for surface pressures > 1.000 mbar - int_ppO2_max += ppO2_MARGIN_ON_MAX; - - // get biggest of char_I_ppO2_max_work / char_I_ppO2_max_deco - int_ppO2_max_max = ( char_I_ppO2_max_deco > char_I_ppO2_max_work ) ? char_I_ppO2_max_deco : char_I_ppO2_max_work; + // determine the absolute max value (should be the deco one, but who knows...) + int_ppO2_max_warn = ( char_I_ppO2_max_work > char_I_ppO2_max_deco) ? char_I_ppO2_max_work : char_I_ppO2_max_deco; + + // add some margin to compensate for surface pressures > 1.000 mbar + int_ppO2_max_warn += ppO2_MARGIN_ON_MAX; + + // determine the normal max value + int_ppO2_max_att = ( deco_info & DECO_MODE ) ? (unsigned short)char_I_ppO2_max_deco : (unsigned short)char_I_ppO2_max_work; + + // add some margin to compensate for surface pressures > 1.000 mbar + int_ppO2_max_att += ppO2_MARGIN_ON_MAX; #ifdef _ccr_pscr - // default value for the upper diluent ppO2 warning threshold is the normal upper warning threshold - int_ppO2_max_dil = int_ppO2_max; - - // when in CCR mode, the upper diluent warning threshold gets adjust according to the current setpoint + // default value for the upper diluent ppO2 warning threshold is the upper warning threshold + int_ppO2_max_dil = int_ppO2_max_warn; + + // when enabled and in CCR mode, the upper diluent warning threshold gets adjust according to the current setpoint + if( char_I_dil_ppO2_check ) if( (main_status & MODE_MASK) == MODE_CCR ) { overlay unsigned short max_dil; @@ -2293,8 +2286,8 @@ // (the condition protects from negative numbers which would cause a wrap-around in unsigned integers) max_dil = (char_I_const_ppO2 > ppO2_GAP_TO_SETPOINT) ? (unsigned short)(char_I_const_ppO2 - ppO2_GAP_TO_SETPOINT) : 0; - // ...but never above int_ppO2_max. - if( max_dil < int_ppO2_max ) int_ppO2_max_dil = max_dil; + // ...but never above int_ppO2_max_warn + if( max_dil < int_ppO2_max_warn ) int_ppO2_max_dil = max_dil; // We do not need to guard int_ppO2_max_dil against becoming lower than char_I_ppO2_min because the check // against char_I_ppO2_min is done first and will then raise a low warning and inhibit further checks. @@ -2302,24 +2295,24 @@ #endif // check for safe range of breathed gas - if ( int_O_breathed_ppO2 <= int_ppO2_min ) int_O_breathed_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; - else if ( int_O_breathed_ppO2 >= int_ppO2_max_max ) int_O_breathed_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; - else if ( deco_info & DECO_FLAG ) ; // no attention generated in deco mode - else if ( main_status & MODE_LOOP ) ; // no attention generated in loop modes - else if ( int_O_breathed_ppO2 >= (unsigned short)char_I_ppO2_max_work ) int_O_breathed_ppO2 |= INT_FLAG_ATTENTION; + if ( int_O_breathed_ppO2 <= int_ppO2_min ) int_O_breathed_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; + else if ( int_O_breathed_ppO2 >= int_ppO2_max_warn ) int_O_breathed_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; + else if ( deco_info & DECO_MODE ) ; // no attention generated in deco mode + else if ( main_status & MODE_LOOP ) ; // no attention generated in loop modes + else if ( int_O_breathed_ppO2 >= int_ppO2_max_att ) int_O_breathed_ppO2 |= INT_FLAG_ATTENTION; #ifdef _ccr_pscr // check for safe range of pure oxygen - if ( int_O_O2_ppO2 >= int_ppO2_max ) int_O_O2_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; + if ( int_O_O2_ppO2 >= int_ppO2_max_warn ) int_O_O2_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; // check for safe range of pure diluent - if ( int_O_pure_ppO2 <= (unsigned short)char_I_ppO2_min ) int_O_pure_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; - else if ( int_O_pure_ppO2 >= int_ppO2_max ) int_O_pure_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; - else if ( int_O_pure_ppO2 >= int_ppO2_max_dil ) int_O_pure_ppO2 |= INT_FLAG_ATTENTION; + if ( int_O_pure_ppO2 <= (unsigned short)char_I_ppO2_min ) int_O_pure_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; + else if ( int_O_pure_ppO2 >= int_ppO2_max_warn ) int_O_pure_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; + else if ( int_O_pure_ppO2 >= int_ppO2_max_dil ) int_O_pure_ppO2 |= INT_FLAG_ATTENTION; // check for safe range of calculated pSCR loop gas - if ( int_O_pSCR_ppO2 <= int_ppO2_min ) int_O_pSCR_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; - else if ( int_O_pSCR_ppO2 >= int_ppO2_max ) int_O_pSCR_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; + if ( int_O_pSCR_ppO2 <= int_ppO2_min ) int_O_pSCR_ppO2 |= INT_FLAG_WARNING + INT_FLAG_LOW; + else if ( int_O_pSCR_ppO2 >= int_ppO2_max_warn ) int_O_pSCR_ppO2 |= INT_FLAG_WARNING + INT_FLAG_HIGH; #endif } // tasks every second / on the first section of the second @@ -2373,14 +2366,13 @@ init_output_vars(); // safeguard input parameters that are constant during the course of the dive - if( char_I_deco_distance > 20 ) char_I_deco_distance = 20; if( char_I_ascent_speed < 5 ) char_I_ascent_speed = 5; if( char_I_ascent_speed > 10 ) char_I_ascent_speed = 10; // convert input parameters to float numbers - float_deco_distance = 0.01 * char_I_deco_distance; float_ascent_speed = 1.00 * char_I_ascent_speed; + // initialize values that will be recalculated later on periodically deco_warnings = 0; // reset all deco warnings deco_info = 0; // reset all deco infos @@ -2389,9 +2381,26 @@ NDL_tissue_start_alt = 0; // initialize the tissue to start with when calculating alternative NDL time // enforce initialization of GF data on first cyclic initialization - GF_high_last = 0; - GF_low_last = 0; - + GF_high_last = 255; + GF_low_last = 255; + +#ifdef _gas_contingency + // shall check for gas pan out? + if( char_I_gas_contingency ) + { + overlay float reduction = 0.5 * (float)char_I_SAC_deco * (1.0 + (float)char_I_depth_last_deco / 10.0); + + // YES - calculate volumes available for each gas + for( i = 0; i < NUM_GAS; i++ ) + { + // total available volume = tank size * fill press, char_I_gas_avail_pres is in multiples of 10 bar + gas_volume_avail[i] = (float)char_I_gas_avail_size[i] * (float)char_I_gas_avail_pres[i] * 10.0; + + // reduce total available volumes by due for 1/2 minute on last stop + gas_volume_avail[i] -= reduction; + } + } +#endif #ifdef _cave_mode char_I_backtrack_time = 0; //clear backtracking time (index to char_I_backtrack_depth) @@ -2407,16 +2416,16 @@ // the next calculation phase will do the cyclic initialization of the deco engine if a // normal or alternative plan shall be calculated, else the calculation cycle is done. - if( deco_status & PLAN_MASK ) next_planning_phase = PHASE_11_CYCLIC_INIT; + if( deco_status & PLAN_MASK ) next_planning_phase = PHASE_20_CYCLIC_INIT; else next_planning_phase = PHASE_00_DONE; break; // - //---- once-per-cycle Initialization of the Deco Engine------------------------------------ + //---- once-per-cycle Initialization of the Deco Engine ----------------------------------- // - case PHASE_11_CYCLIC_INIT: + case PHASE_20_CYCLIC_INIT: // target the simulated tissues (flag bit 7 = 0) tissue_increment = 0; @@ -2435,15 +2444,16 @@ if( char_I_deco_model != 0 ) { // update GF parameters (GFs may have been switched between GF and aGF) - if( (char_I_GF_High_percentage != GF_high_last) || (char_I_GF_Low_percentage != GF_low_last) ) + if( (char_I_GF_Low_percentage != GF_low_last) || (char_I_GF_High_percentage != GF_high_last) ) { // store new values in integer format + GF_low_last = char_I_GF_Low_percentage; GF_high_last = char_I_GF_High_percentage; - GF_low_last = char_I_GF_Low_percentage; - - // store new values in float format - GF_high = 0.01 * char_I_GF_High_percentage; - GF_low = 0.01 * char_I_GF_Low_percentage; + + // safeguard and store new values in float format + GF_low = ( GF_low_last > 10 ) ? 0.01 * GF_low_last : 0.10 ; + GF_high = ( GF_high_last > GF_low_last ) ? 0.01 * GF_high_last : GF_low; + // reset low depth references and slopes GF_low_depth_norm = 0; @@ -2468,26 +2478,21 @@ // initialize the simulated CNS value with the current CNS value of the real tissues CNS_fraction_sim = CNS_fraction_real; - // initialize the simulated depth with the current depth (in absolute pressure) + // initialize the simulated depth with the current depth, + // memorize current depth as start depth of the simulation sim_pres_respiration = real_pres_respiration; - - // compute the depth in meters where we are now - float_depth_real = (sim_pres_respiration - pres_surface) * BAR_TO_METER; - - // convert to integer and round up to next full meter - char_depth_real = (unsigned char)(float_depth_real + 0.99); - - // initialize depth for deco ascent calculation - char_depth_sim = char_depth_real; + char_depth_sim = char_depth_real; + char_depth_sim_start = char_depth_real; // Lookup the gas that is currently breathed with the real tissues and set it as // the gas to be used with the simulated tissues, too. This gas will be used until - // gas_find_better() is invoked and finds a better gas to switch to. - gas_find_current(); - - // Setup the calculation ratio's for N2, He and O2 (sim_N2/He/_O2_ratio). These ratios - // can be kept until a gas switch is done. Thus, if a call to gas_find_better() has - // found a better gas and initiated a switch, gas_set_ratios() needs to be called again. + // gas_find_best()/gas_take_best() is invoked and switches to a better gas. + gas_take_current(); + + // Setup the calculation ratio's for N2, He and O2 (sim_N2/He/_O2_ratio). + // These ratios can be kept until a gas switch is done. Thus, if a call to + // gas_find_best() has found a better gas and this gas is taken by a call + // to gas_take_best(), gas_set_ratios() needs to be called again. gas_set_ratios(); // compute ppO2, ppN2 and ppHe for current depth from sim_pres_respiration @@ -2496,6 +2501,9 @@ // initialize the no decompression limit (NDL) time to 240 minutes NDL_time = 240; + // initialize the total ascent time to 0 minutes + ascent_time = 0; + // retrieve the tissue that had the shortest NDL time during last calculation NDL_tissue_start = ( deco_status & CALC_NORM ) ? NDL_tissue_start_norm : NDL_tissue_start_alt; @@ -2507,22 +2515,40 @@ // start with 1 minute ascent steps when calculating the initial ascent fast = 1; - // initialization for calc_gas_needs_ascent() - gas_needs_next_phase = GAS_NEEDS_INIT; - // initialization for convert_gas_needs_to_press() gas_needs_gas_index = 0; + // shall calculate gas needs? + if( main_status & CALC_VOLUME ) + { + // set the usage rate (SAC rate), starting with working part of the dive + gas_needs_usage_rate = char_I_SAC_work; + + // clear the gas volume needs for gases 1-5 + for( i = 0; i < NUM_GAS; ++i ) gas_volume_need[i] = 0.0; + +#ifdef _rx_functions + // only for OSTC TR model with TR functions enabled + if( main_status & TR_FUNCTIONS ) + { + // invalidate pressure needs to pressure readings + int_O_pressure_need[0] = 0 + INT_FLAG_NOT_AVAIL; + int_O_pressure_need[1] = 0 + INT_FLAG_NOT_AVAIL; + } +#endif + } #ifdef _profiling profiling_runs = 0; #endif // The next calculation phase will - // - calculate the bottom segment if extended bottom time is configured (fTTS), + // - calculate the extended bottom segment if extended bottom time is configured (fTTS), + // - calculate the bottom segment gas need if gas needs calculation is configured, // - proceed with calculating the NDL time else. - if ( deco_status & DELAYED_ASCENT ) next_planning_phase = PHASE_20_EXTENDED_BOTTOM_TIME; - else next_planning_phase = PHASE_30_NDL_TIME; + if ( deco_status & DELAYED_ASCENT ) next_planning_phase = PHASE_30_EXTENDED_BOTTOM_TIME; + else if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_40_BOTTOM_GAS_NEED; + else next_planning_phase = PHASE_50_NDL_TIME; break; @@ -2530,22 +2556,51 @@ // //---- extended Bottom Time --------------------------------------------------------------- // - case PHASE_20_EXTENDED_BOTTOM_TIME: + case PHASE_30_EXTENDED_BOTTOM_TIME: // program interval on simulated tissues (flag bit 7 = 0) tissue_increment = char_I_extra_time; - // calculate ppO2, ppN2 and ppHe - calc_alveolar_pressures(); - - // update the tissues + // update the simulated tissues for tissue_increment (char_I_extra_time) minutes at depth, + // calc_alveolar_pressures() has already been called in cyclic initialization calc_tissues(); - // update the CNS value + // update the CNS value for tissue_increment (char_I_extra_time) minutes at depth calc_CNS(); + // the next calculation phase will + // - calculate the extended bottom segment gas needs if gas needs calculation is configured, + // - proceed with calculating the NDL time else. + if ( main_status & CALC_VOLUME ) next_planning_phase = PHASE_40_BOTTOM_GAS_NEED; + else next_planning_phase = PHASE_50_NDL_TIME; + + break; + + + // + //---- Bottom Segment Gas Need ------------------------------------------------------------ + // + case PHASE_40_BOTTOM_GAS_NEED: + + // on gas 1-5 ? + if( sim_gas_current_num ) + { + // YES - set the bottom depth + gas_needs_depth = char_depth_sim_start; + + // take either the whole bottom time or just the fTTS/bailout extra time + gas_needs_time = ( main_status & CALCULATE_BOTTOM ) ? char_I_bottom_time : char_I_extra_time; + + // calculate gas demand + calc_due_by_depth_time_sac(); + + // take the result + gas_volume_need[sim_gas_current_num-1] = gas_needs_volume_due; + } + + // the next calculation phase will calculate the NDL time - next_planning_phase = PHASE_30_NDL_TIME; + next_planning_phase = PHASE_50_NDL_TIME; break; @@ -2553,7 +2608,7 @@ // //---- NDL Time --------------------------------------------------------------------------- // - case PHASE_30_NDL_TIME: + case PHASE_50_NDL_TIME: // Calculate the remaining no decompression limit (NDL) time for the tissue NDL_tissue. // NDL_time will be updated if the NDL time found is shorter than the current NDL_time. @@ -2580,14 +2635,13 @@ // done with calculating NDL time, set next calculation phase: // - calculate return and ascent in cave mode if configured, else - // - proceed with gathering the results if within NDL time, or - // - proceed with the initial ascent if beyond NDL time. + // - proceed with no-stop ascent if within NDL time, or + // - proceed with deco ascent if beyond NDL time. #ifdef _cave_mode - if ( main_status & CAVE_MODE ) next_planning_phase = PHASE_40_CAVE_ASCENT; + if ( main_status & CAVE_MODE ) next_planning_phase = PHASE_60_CAVE_RETURN; else #endif - if ( NDL_time ) next_planning_phase = PHASE_70_RESULTS; - else next_planning_phase = PHASE_60_DECO_ASCENT; + next_planning_phase = PHASE_70_OPEN_WATER_ASCENT; } break; @@ -2595,93 +2649,244 @@ #ifdef _cave_mode // - //---- Cave Mode Return/Ascent ------------------------------------------------------------ + //---- Cave Mode Return ------------------------------------------------------------------- // - case PHASE_40_CAVE_ASCENT: + case PHASE_60_CAVE_RETURN: // TODO // the next calculation phase will gather all results - next_planning_phase = PHASE_70_RESULTS; + next_planning_phase = PHASE_80_RESULTS; break; #endif // - //---- Open Water Ascent with Deco Stops -------------------------------------------------- + //---- Open Water Ascent ------------------------------------------------------------------ // - case PHASE_60_DECO_ASCENT: + case PHASE_70_OPEN_WATER_ASCENT: // program 1 minute interval on simulated tissues tissue_increment = 1; - // ascent to the next stop depth or the depth that is reachable within one minute of ascent - // and decide if a stop is required (return value = 1/true) or not (return value = 0/false) + // memorize current gas in case there will be a gas change + sim_gas_last_num = sim_gas_current_num; + + // find_next_stop(): + // stays at the current stop depth, ascents to the next stop depth, or + // ascents to the depth that is reachable within one minute of ascent + // without needing to stop. + // + // return value : 1/true if a stop is required, else 0/false + // char_depth_sim : current depth (depth achieved) + // char_depth_last : last depth (depth we came from) + // if( find_next_stop() ) { + overlay unsigned char silent_stop = 0; + overlay unsigned char gas_change = 0; + //---- stop required -------------------- // check if there is a better gas to switch to - if( gas_find_better() ) + if( gas_find_best() ) { + // YES - memorize it + gas_change = 1; + + // take the gas + gas_take_best(); + // set the new calculation ratios for N2, He and O2 gas_set_ratios(); - // doing extended stops? - if( main_status & EXTENDED_STOPS ) + // add the gas change time to the stop time + tissue_increment += char_I_gas_change_time; + + // extended stops option enabled and + // gas change depth deeper than the current depth ? + if( main_status & EXTENDED_STOPS ) + if( sim_gas_current_depth > char_depth_sim ) { - // YES - set char_depth_sim to the gas change depth - char_depth_sim = sim_gas_current_depth; - - // - adjust absolute pressure down to the change depth - sim_pres_respiration = char_depth_sim * METER_TO_BAR + pres_surface; + // YES - make a "silent" stop at the gas change depth + // to figure in the gas change + silent_stop = 1; + + // locate the stop at the shallower one of the + // gas change depth or the depth we came from + char_depth_sim = (sim_gas_current_depth < char_depth_last) ? + sim_gas_current_depth : char_depth_last; + + // calculate sim_pres_respiration for + // the adjusted value of char_depth_sim + calc_sim_pres_respiration(); + + // as we didn't travel the full distance, + // account for the gas change time only + tissue_increment = char_I_gas_change_time; + + // if run from the deco calculator, + // put the gas change into the stops table or + // abort deco calculation if the table is full + if( deco_status & DECO_CALCULATOR_MODE ) + if( !update_deco_table(tissue_increment) ) + next_planning_phase = PHASE_80_RESULTS; } - - // prime the deco stop with the gas change time - update_deco_table(char_I_gas_change_time); - } - - // add one minute to an existing stop or add a new stop at char_depth_sim, - // or abort stops calculation if the deco table is full - if( !update_deco_table(1) ) next_planning_phase = PHASE_70_RESULTS; + } // better gas + + + // if the stop is not a silent one, + // add the stop to an existing stop or add a new stop, + // or abort deco calculation if the deco table is full + if( !silent_stop ) + if( !update_deco_table(tissue_increment) ) + next_planning_phase = PHASE_80_RESULTS; + + + // shall calculate gas needs? + if( main_status & CALC_VOLUME ) + { + // encountered a stop, so switch to deco usage rate (SAC deco) + gas_needs_usage_rate = char_I_SAC_deco; + + // set the depth for gas need calculation to the shallower one + // of the start depth (current real depth) and the stop depth + // (assumed depth to be) as we may be shallower than we should be + gas_needs_depth = ( char_depth_sim_start < char_depth_sim ) ? + char_depth_sim_start : char_depth_sim; + + // did a gas change occur and last gas is 1-5 and a gas change time set? + if( gas_change && sim_gas_last_num && char_I_gas_change_time ) + { + // YES - set time it takes for switching the gas + gas_needs_time = char_I_gas_change_time; + + // calculate gas demand + calc_due_by_depth_time_sac(); + + // add the demand to the overall demand on the last gas + gas_volume_need[sim_gas_last_num-1] += gas_needs_volume_due; + } + + // current gas is 1-5 ? + if( sim_gas_current_num ) + { + // YES - time is 1 minute plus the gas change time (if set) + gas_needs_time = tissue_increment; + + // calculate gas demand + calc_due_by_depth_time_sac(); + + // add the demand to the overall demand on the current gas + gas_volume_need[sim_gas_current_num-1] += gas_needs_volume_due; + } + } // gas need } else { //---- no stop required ----------------- - // check if there is a better gas to switch to, but only: + // switch to a better gas, but only: // - // if extended stops are activated, - // OR if in bailout mode. + // if extended stops are activated OR if in bailout OR if within NDL + // AND if the actual depth is below (deeper) or at the change depth of the + // better gas (switch depth has not been passed yet) + // AND if the depth of the last stop is above (shallower) or at the change + // depth of the better gas (do not switch on final ascent) // - // Attention: do not use a && formula over both 'if' terms, the extended stops / bailout - // condition must be checked before a call to gas_find_better() is made! + // Attention: do not use a && formula over all 'if' terms, the + // conditions need to be evaluated in the given order! // - if( (main_status & EXTENDED_STOPS) || (deco_status & BAILOUT_MODE) ) - if( gas_find_better() ) + if( (main_status & EXTENDED_STOPS) || (deco_status & BAILOUT_MODE) || NDL_time ) + if( gas_find_best() ) + if( char_depth_real >= sim_gas_best_depth ) + if( char_I_depth_last_deco <= sim_gas_best_depth ) { + // YES - take the gas + gas_take_best(); + // set the new calculation values for N2, He and O2 gas_set_ratios(); - // stop duration is the gas change time, a change time of 0 minutes - // will set a tissue calculation interval of 2 seconds - tissue_increment += char_I_gas_change_time; - - // set char_depth_sim to the gas change depth, but not deeper than - // the depth we came from. - // (char_depth_last holds the depth from before the ascent step) - char_depth_sim = (sim_gas_current_depth < char_depth_last) ? sim_gas_current_depth : char_depth_last; - - // adjust sim_pres_respiration to the adjusted value of char_depth_sim - sim_pres_respiration = char_depth_sim * METER_TO_BAR + pres_surface; - - // create a stop for the gas change in the stops table - update_deco_table(char_I_gas_change_time); - } - } - - //---- one minute has passed by now, update the tissues ---------------- + // set char_depth_sim to the gas change depth + char_depth_sim = sim_gas_current_depth; + + // calculate sim_pres_respiration for + // the adjusted value of char_depth_sim + calc_sim_pres_respiration(); + + // as we didn't travel the full distance, + // account for the gas change time only + tissue_increment = char_I_gas_change_time; + + // if in deco and + // if run from the deco calculator: + // create a stop for the gas change in the stops table, + // abort deco calculation if the deco table is full + if( !NDL_time ) + if( deco_status & DECO_CALCULATOR_MODE ) + if( !update_deco_table(tissue_increment) ) + next_planning_phase = PHASE_80_RESULTS; + + // shall calculate gas needs and gas change time is set? + if( main_status & CALC_VOLUME ) + if( char_I_gas_change_time ) + { + // YES - set depth to current depth + gas_needs_depth = char_depth_sim; + + // set time it takes for switching the gas + gas_needs_time = tissue_increment; + + // calculate gas demand + calc_due_by_depth_time_sac(); + + // add gas demand to the overall demand on the new gas + gas_volume_need[sim_gas_current_num-1] += gas_needs_volume_due; + + // was the last gas one of the gases 1-5 ? + if( sim_gas_last_num ) + { + // YES - add the same demand to the overall demand on the last gas + gas_volume_need[sim_gas_last_num-1] += gas_needs_volume_due; + } + } // gas switching needs + } // gas switch + + // shall calculate gas needs and + // last (or still current) gas is 1-5 ? + if( main_status & CALC_VOLUME ) + if( sim_gas_last_num ) + { + // YES - compute distance traveled + gas_needs_depth = char_depth_last - char_depth_sim; + + // at least some positive distance traveled? + if( gas_needs_depth > 1 ) + { + // YES - set depth to average depth along the distance + gas_needs_depth += 1; + gas_needs_depth /= 2; + gas_needs_depth += char_depth_sim; + + // ascent time is 1 minute + gas_needs_time = 1; + + // calculate gas demand + calc_due_by_depth_time_sac(); + + // add to overall demand + gas_volume_need[sim_gas_last_num-1] += gas_needs_volume_due; + } + } // gas travel needs + + } // stop / no stop + + // --- one or more minutes have passed by now --- + + // update the ascent time + ascent_time += tissue_increment; // compute current ppO2, ppN2 and ppHe calc_alveolar_pressures(); @@ -2693,7 +2898,7 @@ calc_CNS(); // finish stops calculation if the surface is reached - if( char_depth_sim == 0 ) next_planning_phase = PHASE_70_RESULTS; + if( char_depth_sim == 0 ) next_planning_phase = PHASE_80_RESULTS; break; @@ -2701,20 +2906,29 @@ /// //--- Results - Initialization ------------------------------------------------------------ // - case PHASE_70_RESULTS: - - // The current depth is needed by calc_ascenttime(), find_NDL_gas_changes() and - // calc_gas_needs_ascent(). As we don't want it to be calculated multiple times, - // it is done here on stockpile. - char_depth_bottom = (unsigned char)((real_pres_respiration - pres_surface) * BAR_TO_METER + 0.5); + case PHASE_80_RESULTS: + + // convert the CNS value to integer + convert_sim_CNS_for_display(); + + if( deco_status & CALC_NORM ) + { + // export the integer CNS value + int_O_CNS_norm = int_sim_CNS_fraction; + } + else + { + // export the integer CNS value + int_O_CNS_alt = int_sim_CNS_fraction; + } // The next calculation phase will // - publish the stops table if in normal plan mode, // - proceed with remaining results dependent on if within NDL, or // - in deco - if ( deco_status & CALC_NORM ) next_planning_phase = PHASE_71_RESULTS_STOPS_TABLE; - else if ( NDL_time ) next_planning_phase = PHASE_72_RESULTS_NDL; - else next_planning_phase = PHASE_73_RESULTS_DECO; + if ( deco_status & CALC_NORM ) next_planning_phase = PHASE_81_RESULTS_STOPS_TABLE; + else if ( NDL_time ) next_planning_phase = PHASE_82_RESULTS_NDL; + else next_planning_phase = PHASE_83_RESULTS_DECO; break; @@ -2722,7 +2936,7 @@ /// //--- Publish Stops Table ----------------------------------------------------------------- // - case PHASE_71_RESULTS_STOPS_TABLE: + case PHASE_81_RESULTS_STOPS_TABLE: // publish the stops table to the display functions publish_deco_table(); @@ -2743,14 +2957,14 @@ } // update deco info vector - if( char_O_deco_depth[0] ) deco_info |= DECO_STOPS; // set flag for deco stops found + if( char_O_deco_depth[0] ) deco_info |= DECO_STOPS; // set flag for deco stops found else deco_info &= ~DECO_STOPS; // clear flag for deco stops found // The next calculation phase will publish the main results dependent on being // - within NDL, // - in deco. - if ( NDL_time ) next_planning_phase = PHASE_72_RESULTS_NDL; - else next_planning_phase = PHASE_73_RESULTS_DECO; + if ( NDL_time ) next_planning_phase = PHASE_82_RESULTS_NDL; + else next_planning_phase = PHASE_83_RESULTS_DECO; break; @@ -2758,7 +2972,7 @@ /// //--- Results - within NDL ---------------------------------------------------------------- // - case PHASE_72_RESULTS_NDL: + case PHASE_82_RESULTS_NDL: // results to publish depend on normal or alternative plan if( deco_status & CALC_NORM ) @@ -2768,9 +2982,6 @@ // clear the normal ascent time int_O_TTS_norm = 0; - - // as we are in no stop, CNS at end of dive is more or less the same CNS as we have right now - int_O_CNS_norm = int_O_CNS_current; } else { @@ -2779,18 +2990,13 @@ // clear the alternative ascent time int_O_TTS_alt = 0; - - // as we are in no stop, CNS at end of dive is more or less the same CNS as we have right now - int_O_CNS_alt = int_O_CNS_current; } // The next calculation phase will // - finish the calculation cycle if no gas needs calculation configured, else - // - find gas switches when in bailout mode (we are in NDL), or - // - calculate the gas needs along the ascent + // - calculate the gas needs pressures if ( !(main_status & CALC_VOLUME ) ) next_planning_phase = PHASE_90_FINISH; - else if ( (deco_status & BAILOUT_MODE) ) next_planning_phase = PHASE_80_GAS_NEEDS_SWITCHES; - else next_planning_phase = PHASE_81_GAS_NEEDS_ASCENT; + else next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES; break; @@ -2798,13 +3004,13 @@ /// //--- Results - in Deco ------------------------------------------------------------------- // - case PHASE_73_RESULTS_DECO: - - // calculate the ascent time - calc_ascenttime(); - - // convert the CNS value to integer - convert_sim_CNS_for_display(); + case PHASE_83_RESULTS_DECO: + + // limit ascent time to display max. + if( ascent_time > 999) ascent_time = 999; + + // tag ascent time as invalid if there is an overflow in the stops table + if( deco_warnings & DECO_WARNING_INCOMPLETE ) ascent_time |= INT_FLAG_INVALID; // results to publish depend on normal or alternative plan if( deco_status & CALC_NORM ) @@ -2814,9 +3020,6 @@ // export the ascent time int_O_TTS_norm = ascent_time; - - // export the integer CNS value - int_O_CNS_norm = int_sim_CNS_fraction; } else { @@ -2825,54 +3028,21 @@ // export the ascent time int_O_TTS_alt = ascent_time; - - // export the integer CNS value - int_O_CNS_alt = int_sim_CNS_fraction; } // The next calculation phase will // - finish the calculation cycle if no gas needs calculation configured, else // - calculate the gas needs along the ascent if ( !(main_status & CALC_VOLUME ) ) next_planning_phase = PHASE_90_FINISH; - else next_planning_phase = PHASE_81_GAS_NEEDS_ASCENT; + else next_planning_phase = PHASE_84_GAS_NEEDS_PRESSURES; break; // - //--- Gas Needs - Switches ---------------------------------------------------------------- - // - case PHASE_80_GAS_NEEDS_SWITCHES: - - // When in bailout mode and within NDL, find the gas switches along the ascent and put - // them into the stops table. The stops table can be "polluted" by now because the table - // has already been published in "clean" state before. - find_NDL_gas_changes(); - - // the next calculation phase will calculate the gas needs along the ascent - next_planning_phase = PHASE_81_GAS_NEEDS_ASCENT; - - break; - - + //--- Results - convert Gas Needs Volumes to Pressures ------------------------------------ // - //--- Gas Needs - calculate Ascent Needs using Data from Stop Table ----------------------- - // - case PHASE_81_GAS_NEEDS_ASCENT: - - // calculate the gas needs along the ascent - calc_gas_needs_ascent(); - - // if calculation has finished, advance to next calculation phase - if( gas_needs_next_phase == GAS_NEEDS_DONE ) next_planning_phase = PHASE_82_GAS_NEEDS_PRESSURES; - - break; - - - // - //--- Gas Needs - convert Volumes to Pressures -------------------------------------------- - // - case PHASE_82_GAS_NEEDS_PRESSURES: + case PHASE_84_GAS_NEEDS_PRESSURES: // convert required volume of the gas pointed to by gas_needs_gas_index // into the respective pressure and set the flags @@ -2897,8 +3067,8 @@ // thus BAILOUT_MODE must not be set while doing the alternative plan. if( (deco_status & CALC_ALT) && !(deco_status & BAILOUT_MODE) ) { - if ( int_O_TTS_alt <= int_O_TTS_norm ) deco_info |= DECO_ZONE; - else deco_info &= ~DECO_ZONE; + if( int_O_TTS_alt < int_O_TTS_norm ) deco_info |= DECO_ZONE; + if( int_O_TTS_alt > int_O_TTS_norm ) deco_info &= ~DECO_ZONE; } // export updated deco infos and warnings @@ -2992,6 +3162,14 @@ if( char_I_extra_time > 127 ) char_I_extra_time = 127; if( char_I_gas_change_time > 99 ) char_I_gas_change_time = 99; + + // compute the depth in meters where we are now + float_depth_real = (real_pres_respiration - pres_surface) * BAR_TO_METER; + + // convert to integer and round up to next full meter + char_depth_real = (unsigned char)(float_depth_real + 0.99); + + // calculate partial pressure of N2 in respired air at surface pressure calc_N2_equilibrium(); @@ -3033,50 +3211,6 @@ ////////////////////////////////////////////////////////////////////////////// -// Find gas changes on an NDL ascent -// -// This function is used for finding the gas changes in an OC bailout ascent -// that is within NDL. -// -// Input: char_depth_bottom depth at which the ascent starts, in meters -// -// Output: gas change stops put into stops table -// -// Destroyed: char_depth_sim -// sim_gas_current_num number of current gas -// sim_gas_current_depth change depth of current gas -// -void find_NDL_gas_changes(void) -{ - overlay unsigned char old_depth_limit; - - // set gas to start with - gas_find_current(); - - // loop in ascending until reaching a depth of 3 meters, no gas switches considered thereafter - for( char_depth_sim = char_depth_bottom; char_depth_sim >= 3; ) - { - // memorize the depth we came from - old_depth_limit = char_depth_sim; - - // ascent - initially in steps of 10 m, then slowing down to 1 m steps to not miss a O2 gas - if ( char_depth_sim > 10 ) char_depth_sim -= 10; - else char_depth_sim -= 1; - - // check if there is a better gas to switch to - if( gas_find_better() ) - { - // adjust char_depth_sim to the gas change depth, but not deeper than the depth we came from - char_depth_sim = (sim_gas_current_depth < old_depth_limit) ? sim_gas_current_depth : old_depth_limit; - - // create a stop for the gas change in the stops table - update_deco_table(char_I_gas_change_time); - } - } // for() -} - - -////////////////////////////////////////////////////////////////////////////// // calc_tissues // // INPUT: ppN2 partial pressure of inspired N2 @@ -3684,60 +3818,6 @@ ////////////////////////////////////////////////////////////////////////////// -// calc_ascenttime -// -// Sum up ascent from bottom to surface at char_I_ascent_speed, slowing down -// to 1 minute per meter for the final ascent when in deco, and all stop times. -// -// Input: char_I_depth_last_deco -// char_I_ascent_speed -// char_depth_bottom -// internal_deco_depth[] -// internal_deco_time[] -// -// Output: ascent_time -// -static void calc_ascenttime(void) -{ - // check if there are stops - if( internal_deco_depth[0] ) - { - // YES - stops / in deco - - // check if already at last stop depth or shallower - if( char_depth_bottom <= char_I_depth_last_deco) - { - // YES - final ascent part only - ascent_time = char_depth_bottom; - } - else - { - // NO - ascent part from bottom to last stop - ascent_time = (char_depth_bottom - char_I_depth_last_deco) / char_I_ascent_speed + 1; - - // - ascent part from last stop to surface at 1 meter per minute - ascent_time += char_I_depth_last_deco; - } - - // add all stop times - for( i=0; i < NUM_STOPS && internal_deco_depth[i]; i++ ) - ascent_time += internal_deco_time[i]; - - // limit result to display max. - if( ascent_time > 999) ascent_time = 999; - - // tag result as invalid if there is an overflow in the stops table - if( deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) ascent_time |= INT_FLAG_INVALID; - } - else - { - // NO - no stops / within NDL - ascent_time = char_depth_bottom / char_I_ascent_speed + 1; - } -} - - -////////////////////////////////////////////////////////////////////////////// // clear_deco_table // // Modified: internal_deco_time[] stop durations @@ -3753,8 +3833,12 @@ internal_deco_gas[i] = 0; } + // reset stop table index and chained stops counter + stop_index = 0; + chained_stops = 0; + // clear stop table overflow warning - deco_warnings &= ~DECO_WARNING_STOPTABLE_OVERFLOW; + deco_warnings &= ~DECO_WARNING_INCOMPLETE; } @@ -3777,53 +3861,112 @@ // static unsigned char update_deco_table(PARAMETER unsigned char time_increment) { - overlay unsigned char x; - assert( char_depth_sim > 0 ); // no stop at surface - // loop through internal deco table - for( x = 0; x < NUM_STOPS; ++x ) + + // is there already a stop entry matching with the current depth and gas? + if( internal_deco_depth[stop_index] == char_depth_sim ) + if( internal_deco_gas [stop_index] == sim_gas_current_num ) { - // In case the first deco stop is to be placed deeper than previously recorded - // stops for gas changes during the initial ascent (this may happen because the - // deco stops are placed at the next deeper multiple of 3 meters instead of the - // real stop's depth), relocate the deco stop to the depth of the last gas change. - // The resulting combined stop's duration will be the sum of the configured gas - // change time plus the duration of the deco stop itself. - if( internal_deco_depth[x] && (char_depth_sim > internal_deco_depth[x]) ) - char_depth_sim = internal_deco_depth[x]; - - // Is there already a stop entry for our current depth? - if( internal_deco_depth[x] == char_depth_sim ) + // YES - increment stop time if possible, stop time entries are + // limited to 99 minutes because of display constraints + if( internal_deco_time[stop_index] < (100 - time_increment) ) { - // Yes - increment stop time if possible - // Stop time entries are limited to 99 minutes because of display constraints. - if( internal_deco_time[x] < (100 - time_increment) ) + // YES - time increment fits into current stop entry, + // increment stop time and return with status 'success' + internal_deco_time[stop_index] += time_increment; + return 1; + } + else + { + // NO - A chained stop entry will be created further down in the + // code to continue the stop, but we will limit the number + // of chained stop table entries in order to abort an ever- + // running deco calculation. Too many chained entries? + if( ++chained_stops >= STOP_CHAINING_LIMIT ) { - internal_deco_time[x] += time_increment; // increment stop time - return 1; // return with status 'success' + // YES - set overflow warning and return with status 'failed' + deco_warnings |= DECO_WARNING_INCOMPLETE; + return 0; } } - - // If program flow passes here, there is either no stop entry for the current depth yet, or - // the existing entry is saturated with 99 minutes. So we are looking for the next unused - // table entry. - if( internal_deco_depth[x] == 0 ) + } + + // the current stop entry does not match the current depth and gas, + // or hasn't enough room left for the time increment + + // is the current stop entry in use? + if( internal_deco_depth[stop_index] > 0 ) + { + // YES - current entry is in use, need to move on + // to next entry position if possible + + // have all entry positions been used up? + if( stop_index < (NUM_STOPS - 1) ) { - internal_deco_time[x] = time_increment; // initialize entry with first stop's time, - internal_deco_depth[x] = char_depth_sim; // ... depth, and - internal_deco_gas[x] = sim_gas_current_num; // ... gas - return 1; // return with status 'success' + // NO - move on to next entry position + stop_index += 1; + } + else + { + // YES - set overflow warning and return with status 'failed' + deco_warnings |= DECO_WARNING_INCOMPLETE; + return 0; } } - // If program flow passes here, all deco table entries are used up. - - // set overflow warning - deco_warnings |= DECO_WARNING_STOPTABLE_OVERFLOW; - - // return with status 'failed'. - return 0; + // initial use of a new (or the very first) stop entry, + // store all stop data and return with status 'success' + internal_deco_time [stop_index] = time_increment; + internal_deco_depth[stop_index] = char_depth_sim; + internal_deco_gas [stop_index] = sim_gas_current_num; + return 1; +} + + +////////////////////////////////////////////////////////////////////////////// +// publish_deco_table +// +// Input: internal_deco_depth[] depth in internal stops table +// internal_deco_time[] times ... +// internal_deco_gas[] gases ... +// +// Output: char_O_deco_depth[] depth in the external stops table +// char_O_deco_time[] times ... +// char_O_deco_gas[] gases ... +// char_O_deco_time_for_log times in reverse order +// +static void publish_deco_table(void) +{ + overlay unsigned char x = stop_index; + overlay unsigned char y; + + + // copy depth, time and gas from internal to external stops table + for( y = 0; y < NUM_STOPS; y++ ) + { + char_O_deco_depth[y] = internal_deco_depth[y]; + char_O_deco_time [y] = internal_deco_time [y]; + char_O_deco_gas [y] = internal_deco_gas [y]; + } + + // copy times of shallowest stops to logging table + for(y = 0; y < NUM_STOPS_LOG; x-- ) + { + // copy all stops that have a non-null stop time + if( internal_deco_time[x] ) + char_O_deco_time_for_log[y++] = internal_deco_time[x]; + + // abort if all stops are copied + if( x == 0) break; + } + + // fill the remainder of the logging table with null + // if it is not completely filled already + while( y < NUM_STOPS_LOG ) + { + char_O_deco_time_for_log[y++] = 0; + } } @@ -4301,6 +4444,9 @@ // calculate index for increment look-up cns_i = (char_ppO2 - 161) / 5; // integer division + // indexes > 17 use increment of index 17 + if( cns_i > 17 ) cns_i = 17; + // read coefficient (increment) read_CNS_c_coefficient(); @@ -4344,329 +4490,15 @@ // rate. It uses a fixed surface pressure of 1.0 bar to deliver stable results // when used through the deco calculator. // -// Input: gas_needs_float_depth depth in meters -// gas_needs_float_time time in minutes -// gas_needs_stop_usage gas usage in liters per minute at surface pressure +// Input: gas_needs_depth depth in meters +// gas_needs_time time in minutes +// gas_needs_usage_rate gas usage in liters per minute at surface pressure // -// Output: gas_needs_volume_due required gas volume in liters +// Output: gas_needs_volume_due required gas volume in liters // static void calc_due_by_depth_time_sac(void) { - gas_needs_volume_due = (gas_needs_float_depth * METER_TO_BAR + 1.0) * gas_needs_float_time * gas_needs_stop_usage; -} - - -////////////////////////////////////////////////////////////////////////////// -// calc_gas_needs_ascent -// -// calculates the gas needs along the ascent -// -// Input: char_depth_bottom depth of the bottom segment -// char_I_bottom_time duration of the bottom segment -// char_I_extra_time extra bottom time for fTTS / delayed ascent -// float_ascent_speed ascent speed, in meters/minute -// internal_deco_depth[] depth of the stops -// internal_deco_time[] duration of the stops -// internal_deco_gas[] gas breathed at the stops -// NDL_time remaining NDL time, used to adjust speed of final ascent -// char_I_SAC_work gas consumption during bottom part and initial ascent, in liters/minute -// char_I_SAC_deco gas consumption during stops and following ascents, in liters/minute -// char_I_gas_avail_size[] size of the tanks for gas 1-5, in liters -// char_I_gas_avail_pres[] fill pressure of the tanks -// -// Output: gas_volume_need[] amount of gas needed, in liters -// -static void calc_gas_needs_ascent(void) -{ - switch (gas_needs_next_phase) - { - //--------------------------------------------------------------------- - - case GAS_NEEDS_INIT: - - // set index to the first stop table entry - gas_needs_stop_index = 0; - - // clear the gas volume needs - for( i = 0; i < NUM_GAS; ++i ) gas_volume_need[i] = 0.0; - -#ifdef _rx_functions - // only for OSTC TR model with TR functions enabled - if( main_status & TR_FUNCTIONS ) - { - // invalidate pressure needs to pressure readings - int_O_pressure_need[0] = 0 + INT_FLAG_NOT_AVAIL; - int_O_pressure_need[1] = 0 + INT_FLAG_NOT_AVAIL; - } -#endif - - // terminate if in loop mode (CCR, pSCR) as there are no gas needs to calculate, - // else continue with the gas needs of the bottom segment - if ( deco_status & MODE_LOOP ) gas_needs_next_phase = GAS_NEEDS_DONE; - else gas_needs_next_phase = GAS_NEEDS_BOTTOM_SEGMENT; - - break; - - //--------------------------------------------------------------------- - - case GAS_NEEDS_BOTTOM_SEGMENT: - - // sim_gas_current_num gas used during bottom segment (0, 1-5) - // char_depth_bottom depth of the bottom segment - - // get the gas used during bottom segment - gas_find_current(); - - // initialize variables - gas_needs_stop_gas_last = gas_needs_stop_gas = sim_gas_current_num; - - // set the usage (SAC rate) to bottom usage rate for bottom part and initial ascent - gas_needs_stop_usage = char_I_SAC_work; - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( gas_needs_stop_gas ) - { - // set the bottom depth - gas_needs_float_depth = (float)char_depth_bottom; - - // calculate either whole bottom time or just the fTTS/bailout extra time - gas_needs_float_time = ( main_status & CALCULATE_BOTTOM ) ? (float)char_I_bottom_time : (float)char_I_extra_time; - - // calculate gas demand - calc_due_by_depth_time_sac(); - - // take result - gas_volume_need[gas_needs_stop_gas-1] = gas_needs_volume_due; - } - - // continue with initial ascent demand - gas_needs_next_phase = GAS_NEEDS_INITIAL_ASCENT; - - break; - - - //--------------------------------------------------------------------- - - case GAS_NEEDS_INITIAL_ASCENT: - - // gas_needs_stop_gas : gas from bottom segment - // char_depth_bottom : depth of the bottom segment - // internal_deco_depth[0]: depth of the first stop, may be 0 if no stop exists - - // get the data of the first stop - gas_needs_stop_depth = internal_deco_depth[0]; - gas_needs_stop_time = internal_deco_time[0]; - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( gas_needs_stop_gas ) - { - // compute distance between bottom and first stop - gas_needs_float_depth = (float)char_depth_bottom - (float)gas_needs_stop_depth; - - // initial ascent exists only if ascent distance is > 0 - if( gas_needs_float_depth > 0.0 ) - { - // compute ascent time - gas_needs_float_time = gas_needs_float_depth / float_ascent_speed; - - // compute average depth between bottom and first stop - gas_needs_float_depth = (float)char_depth_bottom - gas_needs_float_depth * 0.5; - - // calculate gas demand - calc_due_by_depth_time_sac(); - - // add to overall demand - gas_volume_need[gas_needs_stop_gas-1] += gas_needs_volume_due; - } - } - - // switch the usage (SAC rate) to deco usage rate - // for stops, intermediate and final ascent - gas_needs_stop_usage = char_I_SAC_deco; - - // is there a (first) stop? - if( gas_needs_stop_depth ) - { - // YES - continue with stop demand - gas_needs_next_phase = GAS_NEEDS_STOP; - - break; - } - else - { - // NO - add demand of a 3 minutes safety stop at 5 meters, at least for contingency... - gas_needs_float_time = 3.0; - gas_needs_float_depth = 5.0; - - // calculate gas demand - calc_due_by_depth_time_sac(); - - // add to overall demand - gas_volume_need[gas_needs_stop_gas-1] += gas_needs_volume_due; - - // calculation finished - gas_needs_next_phase = GAS_NEEDS_DONE; - - break; - } - - - //--------------------------------------------------------------------- - - case GAS_NEEDS_STOP: - - // correct stop depth if shallower than calculated stop depth and convert to float - gas_needs_float_depth = ( char_depth_bottom < gas_needs_stop_depth ) ? (float)char_depth_bottom : (float)gas_needs_stop_depth; - - // get the gas on this stop - gas_needs_stop_gas = internal_deco_gas[gas_needs_stop_index]; - - // do we have a gas change? - if( gas_needs_stop_gas_last && (gas_needs_stop_gas != gas_needs_stop_gas_last) ) - { - // YES - spend an additional char_I_gas_change_time on the old gas - gas_needs_float_time = (float)char_I_gas_change_time; - - // calculate gas demand - calc_due_by_depth_time_sac(); - - // add to overall demand - gas_volume_need[gas_needs_stop_gas_last-1] += gas_needs_volume_due; - } - - // calculate demand of (new) gas for the full stop duration - if( gas_needs_stop_gas ) - { - // get the duration of the stop - gas_needs_float_time = (float)gas_needs_stop_time; - - // calculate gas demand - calc_due_by_depth_time_sac(); - - // add to overall demand - gas_volume_need[gas_needs_stop_gas-1] += gas_needs_volume_due; - } - - // Continue with the demand of the intermediate ascent to the next stop. - // If there is no further stop, it will divert by itself to final ascent. - gas_needs_next_phase = GAS_NEEDS_INTERMEDIATE_ASCENT; - - break; - - - //--------------------------------------------------------------------- - - case GAS_NEEDS_INTERMEDIATE_ASCENT: - - // store last stop depth and last gas - gas_needs_stop_depth_last = gas_needs_stop_depth; - gas_needs_stop_gas_last = gas_needs_stop_gas; - - // check if end of stop table is reached - if( gas_needs_stop_index < NUM_STOPS-1 ) - { - // NO - check if there is another stop entry - if( internal_deco_depth[gas_needs_stop_index+1] == 0 ) - { - // NO - continue with final ascent demand - gas_needs_next_phase = GAS_NEEDS_FINAL_ASCENT; - - break; - } - else - { - // YES - goto next stop entry - gas_needs_stop_index++; - - // get the depth of the next stop entry - gas_needs_stop_depth = internal_deco_depth[gas_needs_stop_index]; - - // get the duration of the next stop - gas_needs_stop_time = internal_deco_time[gas_needs_stop_index]; - } - } - else - { - // YES - end of stop table reached - // We are stranded at some stop depth and do not know how many more - // stops there may be in front of us and how long they may be. So as - // as last resort to calculate at least something, we assume that the - // rest of the ascent will be done in deco final ascent pace, i.e. at - // 1 meter per minute. Because of the stop table overflow, the result - // will be flagged as being invalid later on. - // - gas_needs_next_phase = GAS_NEEDS_FINAL_ASCENT; - - break; - } - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( gas_needs_stop_gas_last ) - { - // compute distance between the two stops - gas_needs_float_depth = (float)(gas_needs_stop_depth_last - gas_needs_stop_depth); - - // compute ascent time - gas_needs_float_time = gas_needs_float_depth / float_ascent_speed; - - // compute average depth between the two stops - gas_needs_float_depth = (float)gas_needs_stop_depth_last - gas_needs_float_depth * 0.5; - - // calculate gas demand - calc_due_by_depth_time_sac(); - - // add to overall demand - gas_volume_need[gas_needs_stop_gas_last-1] += gas_needs_volume_due; - } - - // continue with calculation stop demand - gas_needs_next_phase = GAS_NEEDS_STOP; - - break; - - - //--------------------------------------------------------------------- - - case GAS_NEEDS_FINAL_ASCENT: - - // gas_needs_float_depth: still holds depth of the last stop - // gas_needs_stop_gas : still holds gas from last stop (0 or 1-5) - - // volumes are only calculated for gases 1-5, but not the manually configured one - if( gas_needs_stop_gas ) - { - // set ascent time dependent on deco status - if( NDL_time ) - { - // within NDL - ascent with float_ascent_speed - // - // Remark: When calculating a bailout ascent, there may be stops - // for gas changes although the dive is still within NDL - // and final ascent thus does not need to be slowed down. - gas_needs_float_time = gas_needs_float_depth / float_ascent_speed; - } - else - { - // in deco - reduce ascent speed to 1 meter per minute - gas_needs_float_time = gas_needs_float_depth; - } - - // set half-way depth - gas_needs_float_depth *= 0.5; - - // calculate gas demand - calc_due_by_depth_time_sac(); - - // add to overall demand - gas_volume_need[gas_needs_stop_gas-1] += gas_needs_volume_due; - } - - // calculation finished - gas_needs_next_phase = GAS_NEEDS_DONE; - - break; - - } // switch + gas_needs_volume_due = ((float)gas_needs_depth * METER_TO_BAR + pres_surface) * gas_needs_time * gas_needs_usage_rate; } @@ -4739,7 +4571,7 @@ pres_respiration_sac = real_pres_respiration; // set threshold for SAC rate attention - max_sac_rate = (deco_info & DECO_FLAG) ? char_I_SAC_deco : char_I_SAC_work; + max_sac_rate = (deco_info & DECO_MODE) ? char_I_SAC_deco : char_I_SAC_work; // char_I_SAC_deco / char_I_SAC_work are in l/min, max_sac_rate is in 0.1 l/min max_sac_rate *= 10; @@ -4823,6 +4655,19 @@ } + // select which pressure reading to log + if( char_I_SAC_mode == 1 ) int_O_tank_pressure = int_IO_pressure_value[0]; + else if( char_I_SAC_mode == 2 ) int_O_tank_pressure = int_IO_pressure_value[1]; + else int_O_tank_pressure = 0; + + // strip flags + int_O_tank_pressure &= 0x0FFF; + + // TODO: decide if log shall be in 0.1 bar of full bar only + // scale to full bar only + int_O_tank_pressure /= 10; + + // calculate SAC - modes 1 & 2 if( (char_I_SAC_mode == 1) || (char_I_SAC_mode == 2) ) { @@ -4925,7 +4770,7 @@ // set warning and attention thresholds int_pres_warn = 10.0 * (unsigned short)char_I_gas_avail_pres[i]; - int_pres_attn = GAS_NEEDS_ATTENTION_THRESHOLD * int_pres_warn; + int_pres_attn = GAS_NEEDS_LIMIT_ATTENTION * int_pres_warn; // convert ascent gas volume need from float to integer [in liter] int_O_gas_need_vol[i] = (unsigned short)gas_volume_need[i]; @@ -4943,7 +4788,7 @@ } // set invalid flag if there is an overflow in the stops table - if( deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) int_O_gas_need_pres[i] |= INT_FLAG_INVALID; + if( deco_warnings & DECO_WARNING_INCOMPLETE ) int_O_gas_need_pres[i] |= INT_FLAG_INVALID; #ifdef _rx_functions // only for OSTC TR model with TR functions enabled @@ -4965,7 +4810,7 @@ int_pres_need = (int_pres_need > 400) ? 4000 | INT_FLAG_OUT_OF_RANGE : 10 * int_pres_need; // tag as not available if there is an overflow in the stops table - if( deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) int_pres_need |= INT_FLAG_NOT_AVAIL; + if( deco_warnings & DECO_WARNING_INCOMPLETE ) int_pres_need |= INT_FLAG_NOT_AVAIL; // copy to reading data (in both readings the same gas could be configured) if( char_I_pressure_gas[0] == j ) int_O_pressure_need[0] = int_pres_need; @@ -4989,8 +4834,8 @@ float_value = CNS_fraction_real; convert_float_to_int(); int_O_CNS_current = int_value; // set warning & attention flags - if ( int_O_CNS_current >= CNS_WARNING_THRESHOLD ) int_O_CNS_current |= INT_FLAG_WARNING; - else if ( int_O_CNS_current >= CNS_ATTENTION_THRESHOLD ) int_O_CNS_current |= INT_FLAG_ATTENTION; + if ( int_O_CNS_current >= CNS_LIMIT_WARNING ) int_O_CNS_current |= INT_FLAG_WARNING; + else if ( int_O_CNS_current >= CNS_LIMIT_ATTENTION ) int_O_CNS_current |= INT_FLAG_ATTENTION; } @@ -5009,11 +4854,11 @@ float_value = CNS_fraction_sim; convert_float_to_int(); int_sim_CNS_fraction = int_value; // set warning & attention flags - if ( int_sim_CNS_fraction >= CNS_WARNING_THRESHOLD ) int_sim_CNS_fraction |= INT_FLAG_WARNING; - else if ( int_sim_CNS_fraction >= CNS_ATTENTION_THRESHOLD ) int_sim_CNS_fraction |= INT_FLAG_ATTENTION; + if ( int_sim_CNS_fraction >= CNS_LIMIT_WARNING ) int_sim_CNS_fraction |= INT_FLAG_WARNING; + else if ( int_sim_CNS_fraction >= CNS_LIMIT_ATTENTION ) int_sim_CNS_fraction |= INT_FLAG_ATTENTION; // set invalid flag if there is an overflow in the stops table - if ( deco_warnings & DECO_WARNING_STOPTABLE_OVERFLOW ) int_sim_CNS_fraction |= INT_FLAG_INVALID; + if ( deco_warnings & DECO_WARNING_INCOMPLETE ) int_sim_CNS_fraction |= INT_FLAG_INVALID; } @@ -5060,7 +4905,7 @@ // // Input: ceiling minimum depth permitted in float // -// Output: int_O_ceiling minimum depth permitted in mbar +// Output: int_O_ceiling minimum depth permitted in mbar (cm) // // Modified: deco_info deco engine information vector // @@ -5070,9 +4915,11 @@ // Round up to next 10 cm so that the ceiling disappears only // when the ceiling limit is really zero. This will coincident // with TTS switching back to NDL time. + // The +1.5 term figures in the conversion factor of 10.015 m/bar + // which is used inside the deco engine but not outside of it. if ( ceiling <= 0.0 ) int_O_ceiling = 0; else if ( ceiling > 16.0 ) int_O_ceiling = 16000; - else int_O_ceiling = (unsigned short)(ceiling * 1000 + 9); + else int_O_ceiling = (unsigned short)(ceiling * (1000+1.5) + 9); // set/reset ceiling flag if ( int_O_ceiling ) deco_info |= DECO_CEILING;
--- a/src/ports.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/ports.inc Thu Sep 19 12:01:29 2019 +0200 @@ -15,8 +15,8 @@ ; TRIS=b'00000000' ; PORTB -#DEFINE switch_left1 PORTB,1 ; switch -#DEFINE switch_right2 PORTB,0 ; switch +#DEFINE switch_left1 PORTB,1 ; switch +#DEFINE switch_right2 PORTB,0 ; switch #DEFINE mcp_power PORTB,2 ; RX power supply #DEFINE s8_npower PORTB,3 ; power supply for S8 bulkhead (inverted) #DEFINE LEDg PORTB,4 ; LED green / active_reset_ostc_rx (<- do no longer use this LED unless for debugging)
--- a/src/rx_firmware-1-38.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/rx_firmware-1-38.inc Thu Sep 19 12:01:29 2019 +0200 @@ -20,9 +20,9 @@ DB 0xA1,0xB2,0xB7,0xD8,0xF2,0xB2,0xF2,0x92,0x61,0xC0,0xF4,0xFF DB 0x60,0xC0,0xF3,0xFF,0x11,0x00,0x0F,0x01,0x4F,0x6B,0x50,0x6B DB 0x01,0x01,0x7B,0x90,0x5E,0xCF,0x3D,0xF1,0x5E,0xCF,0x40,0xF1 - DB 0xD8,0x90,0x40,0x33,0x3F,0x51,0x40,0x27,0x02,0x8D,0xA0,0x0E + DB 0xD8,0x90,0x40,0x33,0x3F,0x51,0x40,0x27,0x02,0x8D,0xAA,0x0E DB 0x7D,0xB0,0x06,0x51,0x40,0x61,0x02,0x9D,0xD8,0x90,0x3D,0x31 - DB 0x3F,0x6F,0x02,0xAD,0x82,0x94,0x02,0xBD,0x82,0x84,0x40,0xC1 + DB 0x3F,0x6F,0x02,0xAD,0x82,0x94,0x02,0xBD,0x82,0x84,0x06,0xC1 DB 0x73,0xFF,0x0F,0x01,0x51,0xB5,0x12,0x00,0x01,0x01,0x02,0xAD DB 0x06,0xD0,0x41,0x2B,0x40,0x51,0x45,0x27,0x00,0x0E,0x46,0x23 DB 0x12,0x00,0x42,0x2B,0x2B,0x0E,0x41,0x61,0x12,0xD0,0x0A,0x0E @@ -37,7 +37,7 @@ DB 0x0C,0x6B,0x0F,0x6B,0x08,0x0E,0x0D,0x6F,0x10,0x0E,0x10,0x6F DB 0x05,0x0E,0x11,0x6F,0x41,0x6B,0x42,0x6B,0x47,0xC1,0x19,0xF1 DB 0x48,0xC1,0x1A,0xF1,0x06,0xC1,0x1B,0xF1,0x1C,0x6B,0xB4,0xEC - DB 0x07,0xF0,0x05,0x0E,0x15,0x27,0x15,0xC1,0x06,0xF1,0x12,0x00 + DB 0x07,0xF0,0x03,0x0E,0x15,0x27,0x15,0xC1,0x06,0xF1,0x12,0x00 DB 0x0F,0x01,0xFB,0x0E,0x52,0x6F,0x05,0x0E,0x51,0x6F,0x01,0x01 DB 0x7E,0x90,0x05,0x0E,0x10,0x65,0x06,0xD0,0x0D,0x0E,0x10,0x61 DB 0x03,0xD0,0x80,0x7C,0x02,0xBD,0x0F,0x2B,0x10,0x2F,0x12,0x00 @@ -70,7 +70,7 @@ DB 0x00,0xF0,0x00,0x0E,0x0F,0xD8,0x01,0x0E,0x0D,0xD8,0x02,0x0E DB 0x0B,0xD8,0x03,0x0E,0x09,0xD8,0x04,0x0E,0x07,0xD8,0x05,0x0E DB 0x05,0xD8,0x06,0x0E,0x03,0xD8,0x01,0x01,0x02,0x89,0x12,0x00 - DB 0x60,0x6F,0x50,0x0F,0xE3,0xCF,0x61,0xF3,0x3C,0x0E,0x61,0x63 + DB 0x60,0x6F,0x50,0x0F,0xE3,0xCF,0x61,0xF3,0xF0,0x0E,0x61,0x63 DB 0x12,0x00,0x60,0x51,0xE3,0x6A,0x10,0x0E,0x60,0x25,0xE3,0x6A DB 0x20,0x0E,0x60,0x25,0xE3,0x6A,0x30,0x0E,0x60,0x25,0xE3,0x6A DB 0x40,0x0E,0x60,0x25,0xE3,0x6A,0x50,0x0E,0x60,0x25,0xE3,0x6A @@ -145,7 +145,7 @@ DB 0x12,0xEE,0x40,0xF0,0xE6,0x50,0x15,0xD8,0x02,0xBB,0x11,0xD0 DB 0xC5,0xBC,0xE4,0xD7,0x03,0x2F,0xF8,0xD7,0xE1,0xD7,0x23,0x91 DB 0x01,0x0E,0x0B,0xD8,0x02,0xBB,0x07,0xD0,0xC5,0xBC,0xDA,0xD7 - DB 0x26,0x0E,0x05,0xD8,0x02,0xBB,0x01,0xD0,0xD5,0xD7,0x23,0x6B + DB 0x27,0x0E,0x05,0xD8,0x02,0xBB,0x01,0xD0,0xD5,0xD7,0x23,0x6B DB 0xD3,0xD7,0xC9,0x6E,0xC6,0x88,0x04,0xD0,0xC6,0x88,0x02,0xD8 DB 0xC9,0x50,0x12,0x00,0x27,0x6B,0x9E,0xB6,0x0B,0xD0,0x9E,0xB6 DB 0x09,0xD0,0x9E,0xB6,0x07,0xD0,0x9E,0xB6,0x05,0xD0,0x27,0x2F @@ -183,4 +183,4 @@ ; upper bound = 0x1800 ; lower bound = 0x0000 ; length = 0x1800 (6 kbyte) -; code size = 4063 byte +; code size = ? byte
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rx_firmware-1-39.inc Thu Sep 19 12:01:29 2019 +0200 @@ -0,0 +1,186 @@ +;============================================================================= +; +; File rx_firmware.inc combined next generation V3.03.5 +; +; Firmware for the RX Co-Processor +; +; Copyright (c) 2019, HeinrichsWeikamp, all rights reserved. +;============================================================================= + + +; version of the RX firmware below +#define rx_firmware_major .1 +#define rx_firmware_minor .39 + +; http://srecord.sourceforge.net/ + DB 0x27,0xEF,0x06,0xF0,0x00,0x00,0x00,0x00,0x03,0xD0,0x00,0x00 + DB 0x00,0x00,0x00,0x00,0x01,0x01,0xF3,0xCF,0x60,0xF0,0xF4,0xCF + DB 0x61,0xF0,0x7E,0xB0,0x87,0xD8,0xF0,0xB2,0xC8,0xD8,0x7B,0xB0 + DB 0x0E,0xD8,0x01,0x01,0x9E,0xB0,0xBF,0xD8,0x9E,0xB2,0xB0,0xD8 + DB 0xA1,0xB2,0xB7,0xD8,0xF2,0xB2,0xF2,0x92,0x61,0xC0,0xF4,0xFF + DB 0x60,0xC0,0xF3,0xFF,0x11,0x00,0x0F,0x01,0x4F,0x6B,0x50,0x6B + DB 0x01,0x01,0x7B,0x90,0x5E,0xCF,0x3D,0xF1,0x5E,0xCF,0x40,0xF1 + DB 0xD8,0x90,0x40,0x33,0x3F,0x51,0x40,0x27,0x02,0x8D,0xA0,0x0E + DB 0x7D,0xB0,0x06,0x51,0x40,0x61,0x02,0x9D,0xD8,0x90,0x3D,0x31 + DB 0x3F,0x6F,0x02,0xAD,0x82,0x94,0x02,0xBD,0x82,0x84,0x40,0xC1 + DB 0x73,0xFF,0x0F,0x01,0x51,0xB5,0x12,0x00,0x01,0x01,0x02,0xAD + DB 0x06,0xD0,0x41,0x2B,0x40,0x51,0x45,0x27,0x00,0x0E,0x46,0x23 + DB 0x12,0x00,0x42,0x2B,0x2B,0x0E,0x41,0x61,0x12,0xD0,0x0A,0x0E + DB 0x42,0x61,0x03,0xD0,0x05,0x0E,0x41,0x61,0x05,0xD0,0x41,0x6B + DB 0x42,0x6B,0x45,0x6B,0x46,0x6B,0x12,0x00,0x42,0x51,0x41,0x27 + DB 0x2B,0x0E,0x41,0x61,0x02,0xD0,0x42,0x6B,0x12,0x00,0x41,0xC1 + DB 0x06,0xF1,0x70,0x0E,0x4E,0x6F,0x17,0x0E,0x4F,0x6F,0x45,0xC1 + DB 0x4C,0xF1,0x46,0xC1,0x4D,0xF1,0xDB,0xEC,0x07,0xF0,0x49,0xB1 + DB 0xE6,0xD7,0x45,0xC1,0x47,0xF1,0x46,0xC1,0x48,0xF1,0x45,0x6B + DB 0x46,0x6B,0x0F,0x01,0x53,0x6B,0xAF,0x0E,0x52,0x6F,0x26,0x0E + DB 0x51,0x6F,0x01,0x01,0x7E,0x90,0x02,0xEE,0x00,0xF0,0x7D,0x80 + DB 0x0C,0x6B,0x0F,0x6B,0x08,0x0E,0x0D,0x6F,0x10,0x0E,0x10,0x6F + DB 0x05,0x0E,0x11,0x6F,0x41,0x6B,0x42,0x6B,0x47,0xC1,0x19,0xF1 + DB 0x48,0xC1,0x1A,0xF1,0x06,0xC1,0x1B,0xF1,0x1C,0x6B,0xB4,0xEC + DB 0x07,0xF0,0x05,0x0E,0x15,0x27,0x15,0xC1,0x06,0xF1,0x12,0x00 + DB 0x0F,0x01,0xFB,0x0E,0x52,0x6F,0x05,0x0E,0x51,0x6F,0x01,0x01 + DB 0x7E,0x90,0x05,0x0E,0x10,0x65,0x06,0xD0,0x0D,0x0E,0x10,0x61 + DB 0x03,0xD0,0x80,0x7C,0x02,0xBD,0x0F,0x2B,0x10,0x2F,0x12,0x00 + DB 0x10,0x0E,0x10,0x6F,0x02,0x0E,0xD8,0x80,0x0F,0x65,0xD8,0x90 + DB 0x0E,0x37,0x0C,0x67,0x07,0xD0,0x0E,0xB1,0x05,0xD0,0x0F,0x01 + DB 0x51,0x95,0x01,0x01,0x7D,0x90,0x12,0x00,0x0F,0x6B,0x0C,0x2B + DB 0x0D,0x2F,0x12,0x00,0x08,0x0E,0x0D,0x6F,0x0E,0xC1,0xEE,0xFF + DB 0x11,0x2F,0x12,0x00,0x0F,0x01,0x51,0x95,0x01,0x01,0x7D,0x90 + DB 0x02,0x85,0x12,0x00,0x9E,0x92,0x01,0x01,0x2B,0x2B,0x3E,0x0E + DB 0x2B,0x65,0x12,0x00,0x2B,0x6B,0x02,0x87,0x12,0x00,0x01,0x01 + DB 0xA0,0x92,0xA1,0x92,0x12,0x00,0x01,0x01,0x9E,0x90,0x9D,0x90 + DB 0x12,0x00,0x01,0x01,0xF0,0x92,0x12,0x00,0x12,0xEE,0x10,0xF0 + DB 0x00,0xC3,0xE6,0xFF,0x10,0xC3,0xE6,0xFF,0x20,0xC3,0xE6,0xFF + DB 0x30,0xC3,0xE6,0xFF,0x40,0xC3,0xE6,0xFF,0x50,0xC3,0xE6,0xFF + DB 0x01,0xC3,0xE6,0xFF,0x11,0xC3,0xE6,0xFF,0x21,0xC3,0xE6,0xFF + DB 0x31,0xC3,0xE6,0xFF,0x41,0xC3,0xE6,0xFF,0x51,0xC3,0xE6,0xFF + DB 0x02,0xC3,0xE6,0xFF,0x12,0xC3,0xE6,0xFF,0x22,0xC3,0xE6,0xFF + DB 0x32,0xC3,0xE6,0xFF,0x42,0xC3,0xE6,0xFF,0x52,0xC3,0xE6,0xFF + DB 0x03,0xC3,0xE6,0xFF,0x13,0xC3,0xE6,0xFF,0x23,0xC3,0xE6,0xFF + DB 0x33,0xC3,0xE6,0xFF,0x43,0xC3,0xE6,0xFF,0x53,0xC3,0xE6,0xFF + DB 0x04,0xC3,0xE6,0xFF,0x14,0xC3,0xE6,0xFF,0x24,0xC3,0xE6,0xFF + DB 0x34,0xC3,0xE6,0xFF,0x44,0xC3,0xE6,0xFF,0x54,0xC3,0xE6,0xFF + DB 0x05,0xC3,0xE6,0xFF,0x15,0xC3,0xE6,0xFF,0x25,0xC3,0xE6,0xFF + DB 0x35,0xC3,0xE6,0xFF,0x45,0xC3,0xE6,0xFF,0x55,0xC3,0xE6,0xFF + DB 0x06,0xC3,0xE6,0xFF,0x16,0xC3,0xE6,0xFF,0x26,0xC3,0xE6,0xFF + DB 0x36,0xC3,0xE6,0xFF,0x46,0xC3,0xE6,0xFF,0x56,0xC3,0xE6,0xFF + DB 0x02,0x99,0x12,0x00,0x03,0x01,0x50,0x67,0x50,0x2B,0x51,0x67 + DB 0x51,0x2B,0x52,0x67,0x52,0x2B,0x53,0x67,0x53,0x2B,0x54,0x67 + DB 0x54,0x2B,0x55,0x67,0x55,0x2B,0x56,0x67,0x56,0x2B,0x13,0xEE + DB 0x00,0xF0,0x00,0x0E,0x0F,0xD8,0x01,0x0E,0x0D,0xD8,0x02,0x0E + DB 0x0B,0xD8,0x03,0x0E,0x09,0xD8,0x04,0x0E,0x07,0xD8,0x05,0x0E + DB 0x05,0xD8,0x06,0x0E,0x03,0xD8,0x01,0x01,0x02,0x89,0x12,0x00 + DB 0x60,0x6F,0x50,0x0F,0xE3,0xCF,0x61,0xF3,0xF0,0x0E,0x61,0x63 + DB 0x12,0x00,0x60,0x51,0xE3,0x6A,0x10,0x0E,0x60,0x25,0xE3,0x6A + DB 0x20,0x0E,0x60,0x25,0xE3,0x6A,0x30,0x0E,0x60,0x25,0xE3,0x6A + DB 0x40,0x0E,0x60,0x25,0xE3,0x6A,0x50,0x0E,0x60,0x25,0xE3,0x6A + DB 0x12,0x00,0x01,0x01,0x00,0xC2,0x2D,0xF1,0x01,0xC2,0x2E,0xF1 + DB 0x02,0xC2,0x2F,0xF1,0x03,0xC2,0x30,0xF1,0x04,0xC2,0x31,0xF1 + DB 0x02,0x95,0x32,0x6B,0x33,0x6B,0x34,0x6B,0x35,0x6B,0x36,0x6B + DB 0x37,0x6B,0x2D,0xBF,0x33,0x8B,0x2D,0xBD,0x33,0x89,0x2D,0xBB + DB 0x33,0x87,0x2D,0xB9,0x33,0x85,0x2D,0xB7,0x33,0x83,0x2D,0xB5 + DB 0x33,0x81,0x2D,0xB3,0x34,0x8F,0x2D,0xB1,0x34,0x8D,0x2E,0xBF + DB 0x34,0x8B,0x2E,0xBD,0x34,0x89,0x2E,0xBB,0x34,0x87,0x2E,0xB9 + DB 0x34,0x85,0x2E,0xB7,0x34,0x83,0x2E,0xB5,0x34,0x81,0x33,0xC1 + DB 0x38,0xF1,0x38,0x9B,0x38,0x67,0x01,0xD0,0x00,0xD0,0x04,0x0E + DB 0x38,0x6F,0x11,0xEE,0x2D,0xF0,0x50,0x6B,0xE6,0x50,0x50,0x1B + DB 0x08,0x0E,0x51,0x6F,0xD8,0x90,0x50,0x37,0x85,0x0E,0xD8,0xB0 + DB 0x50,0x1B,0x51,0x2F,0xF9,0xD7,0x38,0x2F,0xF3,0xD7,0x31,0x51 + DB 0x50,0x63,0x12,0x00,0x2E,0xB3,0x35,0x87,0x2E,0xB1,0x35,0x85 + DB 0x2F,0xBF,0x35,0x83,0x2F,0xBD,0x35,0x81,0x2F,0xBB,0x36,0x8F + DB 0x2F,0xB9,0x36,0x8D,0x2F,0xB7,0x36,0x8B,0x2F,0xB5,0x36,0x89 + DB 0x2F,0xB3,0x36,0x87,0x2F,0xB1,0x36,0x85,0x30,0xBF,0x36,0x83 + DB 0x30,0xBD,0x36,0x81,0x00,0x0E,0x36,0x63,0x05,0xD0,0x0C,0x0E + DB 0x35,0x63,0x02,0xD0,0x36,0x6B,0x35,0x6B,0xE4,0x0E,0x21,0x6F + DB 0x0C,0x0E,0x22,0x6F,0x36,0xC1,0x1F,0xF1,0x35,0xC1,0x20,0xF1 + DB 0xA5,0xEC,0x07,0xF0,0x02,0xB1,0x01,0xD0,0x12,0x00,0x30,0xBB + DB 0x37,0x8B,0x30,0xB9,0x37,0x89,0x30,0xB7,0x37,0x87,0x30,0xB5 + DB 0x37,0x85,0x30,0xB3,0x37,0x83,0x30,0xB1,0x37,0x81,0x38,0x6B + DB 0x13,0xEE,0x00,0xF0,0x23,0xEE,0x10,0xF0,0x33,0x51,0xE6,0x62 + DB 0x1E,0xD0,0x34,0x51,0xDE,0x62,0x1C,0xD0,0x13,0xEE,0x00,0xF0 + DB 0x38,0x51,0x33,0xC1,0xE3,0xFF,0x13,0xEE,0x10,0xF0,0x34,0xC1 + DB 0xE3,0xFF,0x13,0xEE,0x20,0xF0,0x35,0xC1,0xE3,0xFF,0x13,0xEE + DB 0x30,0xF0,0x36,0xC1,0xE3,0xFF,0x13,0xEE,0x40,0xF0,0x37,0xC1 + DB 0xE3,0xFF,0x13,0xEE,0x50,0xF0,0xE3,0x6A,0xE3,0x2A,0x02,0x89 + DB 0x12,0x00,0xDE,0x50,0x38,0x2B,0x06,0x0E,0x38,0x63,0xDA,0xD7 + DB 0x38,0x6B,0x13,0xEE,0x50,0xF0,0xE6,0x66,0x01,0xD0,0xDA,0xD7 + DB 0x38,0x2B,0x06,0x0E,0x38,0x63,0xF9,0xD7,0x12,0x00,0x11,0xD9 + DB 0x66,0xD8,0x27,0x6B,0x80,0x88,0x80,0xA8,0xFD,0xD7,0x02,0x9B + DB 0x2B,0x6B,0x12,0xEE,0x00,0xF0,0xE6,0x6A,0x0F,0x0E,0xE2,0x62 + DB 0xFC,0xD7,0x01,0x01,0x9E,0xB6,0x8F,0xD8,0x02,0xBB,0xED,0xD7 + DB 0x02,0xB9,0xA0,0xDE,0x02,0xB5,0x31,0xDF,0x02,0xB7,0x04,0xD8 + DB 0x23,0xB7,0x23,0x97,0x04,0x00,0xF2,0xD7,0x02,0x97,0x29,0x4B + DB 0x2A,0x2B,0xEC,0xDE,0x81,0xB0,0x06,0xD8,0x81,0xA0,0x3B,0x6B + DB 0x28,0x2F,0x12,0x00,0x06,0xD8,0x12,0x00,0x01,0x01,0x3B,0x2B + DB 0x1E,0x0E,0x3B,0x63,0x12,0x00,0x3B,0x6B,0x00,0x0E,0xF2,0x6E + DB 0x00,0x0E,0xF0,0x6E,0x00,0x0E,0x9D,0x6E,0x80,0x0E,0xF1,0x6E + DB 0xCD,0x6A,0xB1,0x6A,0x0F,0x01,0x00,0x0E,0x42,0x6F,0x00,0x0E + DB 0x41,0x6F,0x01,0x01,0x00,0x00,0x00,0x00,0x80,0x98,0x80,0xB8 + DB 0xFD,0xD7,0x2A,0x6B,0x29,0x6B,0x9E,0x96,0x03,0x00,0x00,0x00 + DB 0x81,0xB0,0xFB,0xD7,0x00,0x00,0x80,0x88,0x80,0xA8,0xFD,0xD7 + DB 0x00,0x0E,0xCD,0x6E,0x82,0x0E,0xB1,0x6E,0x13,0xEE,0x00,0xF0 + DB 0xE6,0x6A,0x04,0x0E,0xE2,0x62,0xFC,0xD7,0x0F,0x01,0x00,0x0E + DB 0x42,0x6F,0xE0,0x0E,0x41,0x6F,0x01,0x01,0xC0,0x0E,0xF2,0x6E + DB 0x00,0x0E,0xF1,0x6E,0x10,0x0E,0xF0,0x6E,0x02,0x0E,0x9D,0x6E + DB 0x12,0x00,0xF2,0x9E,0x23,0x97,0x06,0x69,0x04,0x6B,0x06,0x2F + DB 0x02,0xD0,0x9B,0x6A,0x1C,0xD0,0xB2,0x6A,0xB1,0x80,0x03,0x6B + DB 0xA1,0x92,0xB3,0x68,0xFC,0x0E,0xB2,0x6E,0x03,0x2B,0xA1,0xA2 + DB 0xFD,0xD7,0x03,0x51,0x7A,0x08,0xD8,0xA0,0x01,0xD0,0x07,0xD0 + DB 0xFF,0x08,0x01,0x08,0xD8,0xB0,0x09,0xD0,0x04,0x07,0x0D,0xD8 + DB 0xE6,0xD7,0x01,0x08,0xD8,0xB0,0x03,0xD0,0x04,0x2B,0x07,0xD8 + DB 0xE0,0xD7,0x04,0xC1,0x3C,0xF1,0x82,0x0E,0xB1,0x6E,0xF2,0x8E + DB 0x12,0x00,0x04,0xC1,0x05,0xF1,0x05,0x9F,0x05,0x9D,0x05,0xC1 + DB 0x9B,0xFF,0x14,0x0E,0x05,0x6F,0x04,0x00,0xFF,0xEC,0x02,0xF0 + DB 0x05,0x2F,0xFB,0xD7,0x12,0x00,0x9E,0x96,0x0F,0x0E,0x28,0x6F + DB 0xC9,0xCF,0x24,0xF1,0xC7,0xB4,0x1B,0xD0,0xC7,0xAA,0x16,0xD0 + DB 0x23,0x6B,0x1B,0x0E,0x24,0x63,0x02,0xD0,0x23,0x81,0x10,0xD0 + DB 0x1E,0x0E,0x24,0x63,0x02,0xD0,0x23,0x83,0x0B,0xD0,0x2E,0x0E + DB 0x24,0x63,0x02,0xD0,0x23,0x85,0x06,0xD0,0x3E,0x0E,0x24,0x63 + DB 0x02,0xD0,0x23,0x87,0x01,0xD0,0x00,0xD0,0x9E,0x96,0xC6,0x88 + DB 0x12,0x00,0x23,0xB1,0x26,0xD0,0x23,0xB3,0x08,0xD0,0x23,0xB5 + DB 0x14,0xD0,0xFF,0x0E,0x2E,0xD8,0x00,0xD0,0x9E,0x96,0xC6,0x88 + DB 0x12,0x00,0x23,0x93,0x30,0x0E,0x03,0x6F,0x12,0xEE,0x10,0xF0 + DB 0xE6,0x50,0x23,0xD8,0x02,0xBB,0x1F,0xD0,0xC5,0xBC,0xF2,0xD7 + DB 0x03,0x2F,0xF8,0xD7,0xEF,0xD7,0x23,0x95,0x30,0x0E,0x03,0x6F + DB 0x12,0xEE,0x40,0xF0,0xE6,0x50,0x15,0xD8,0x02,0xBB,0x11,0xD0 + DB 0xC5,0xBC,0xE4,0xD7,0x03,0x2F,0xF8,0xD7,0xE1,0xD7,0x23,0x91 + DB 0x01,0x0E,0x0B,0xD8,0x02,0xBB,0x07,0xD0,0xC5,0xBC,0xDA,0xD7 + DB 0x27,0x0E,0x05,0xD8,0x02,0xBB,0x01,0xD0,0xD5,0xD7,0x23,0x6B + DB 0xD3,0xD7,0xC9,0x6E,0xC6,0x88,0x04,0xD0,0xC6,0x88,0x02,0xD8 + DB 0xC9,0x50,0x12,0x00,0x27,0x6B,0x9E,0xB6,0x0B,0xD0,0x9E,0xB6 + DB 0x09,0xD0,0x9E,0xB6,0x07,0xD0,0x9E,0xB6,0x05,0xD0,0x27,0x2F + DB 0x01,0xD0,0x04,0xD0,0x9E,0xA6,0xFE,0xD7,0x9E,0x96,0x12,0x00 + DB 0x02,0x8B,0x9E,0x96,0x12,0x00,0x0F,0x01,0x72,0x0E,0xD3,0x6E + DB 0xD2,0x6A,0x9B,0x6A,0xD1,0x80,0x0C,0x0E,0x92,0x6E,0x05,0x0E + DB 0x93,0x6E,0x59,0x0E,0x94,0x6E,0x0F,0x01,0x04,0x0E,0x38,0x6F + DB 0x39,0x6B,0x3A,0x6B,0x0F,0x01,0x3F,0x6B,0x9B,0x0E,0x3E,0x6F + DB 0x0E,0x0E,0x3D,0x6F,0x0F,0x01,0x04,0x0E,0x61,0x6E,0x0F,0x01 + DB 0x80,0x6A,0x81,0x6A,0x82,0x6A,0xD5,0x6A,0xCD,0x6A,0xCC,0x6A + DB 0x7F,0x0E,0xBA,0x6E,0x82,0x0E,0xB1,0x6E,0xB4,0x6A,0x0F,0x01 + DB 0x51,0x6B,0x0F,0x01,0x01,0x0E,0x4E,0x6F,0x4D,0x6B,0x0F,0x01 + DB 0x04,0x0E,0x4A,0x6F,0x0F,0x01,0x42,0x6B,0xE0,0x0E,0x41,0x6F + DB 0x16,0x0E,0x40,0x6F,0x01,0x01,0xC2,0x6A,0xAC,0x6A,0xAB,0x6A + DB 0xB8,0x6A,0xAF,0x6A,0xB0,0x6A,0x24,0x0E,0x72,0x6E,0x80,0x0E + DB 0x71,0x6E,0x08,0x0E,0x70,0x6E,0x22,0x0E,0x75,0x6E,0x76,0x6A + DB 0x50,0x0E,0xC8,0x6E,0xC7,0x6A,0x26,0x0E,0xC6,0x6E,0x08,0x0E + DB 0xC5,0x6E,0xCB,0x6A,0xCA,0x68,0xC6,0x88,0x23,0x6B,0x26,0x6B + DB 0x9E,0x96,0x0F,0x01,0x92,0x0E,0x49,0x6F,0x0F,0x01,0x07,0x0E + DB 0x5D,0x6F,0x0F,0x01,0x01,0x0E,0x5A,0x6F,0x0F,0x01,0x5C,0x6B + DB 0x0F,0x01,0x5B,0x6B,0x0F,0x01,0xC0,0x0E,0xF2,0x6E,0xF1,0x6A + DB 0xF0,0x6A,0x02,0x0E,0x9D,0x6E,0xA0,0x6A,0xA3,0x6A,0x01,0x0E + DB 0x7A,0x6E,0x01,0x01,0x12,0x00,0x02,0x91,0x21,0x51,0x1F,0x5D + DB 0x1D,0x6F,0x22,0x51,0x20,0x59,0x1E,0x6F,0xD8,0xB0,0x12,0x00 + DB 0x02,0x81,0x1E,0x1F,0x1D,0x6D,0xD8,0xB0,0x1E,0x2B,0x12,0x00 + DB 0x15,0x6B,0x16,0x6B,0x1B,0x51,0x1C,0x11,0xD8,0xB4,0xFF,0x0C + DB 0x01,0x0E,0x14,0x6F,0x1C,0xBF,0x05,0xD0,0x14,0x2B,0xD8,0x90 + DB 0x1B,0x37,0x1C,0x37,0xF9,0xD7,0xD8,0x90,0x15,0x37,0x16,0x37 + DB 0x1B,0x51,0x19,0x5F,0x1C,0x51,0xD8,0xA0,0x1C,0x29,0x1A,0x5F + DB 0xD8,0xB0,0x05,0xD0,0x1B,0x51,0x19,0x27,0x1C,0x51,0x1A,0x23 + DB 0x01,0xD0,0x15,0x81,0x14,0x07,0xD8,0xB4,0x12,0x00,0xD8,0x90 + DB 0x1C,0x33,0x1B,0x33,0xE8,0xD7,0x49,0x91,0x4E,0x51,0x4C,0x5D + DB 0x4A,0x6F,0x4F,0x51,0x4D,0x59,0x4B,0x6F,0xD8,0xB0,0x12,0x00 + DB 0x49,0x81,0x4B,0x1F,0x4A,0x6D,0xD8,0xB0,0x4B,0x2B,0x12,0x00 + ; upper bound = 0x1800 +; lower bound = 0x0000 +; length = 0x1800 (6 kbyte) +; code size = ? byte
--- a/src/rx_firmware.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/rx_firmware.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File rx_firmware.asm combined next generation V3.03.4 +; File rx_firmware.asm combined next generation V3.03.5 ; ; Firmware for the RX Co-Processor ; @@ -15,14 +15,15 @@ ;----------------------------------------------------------------------------- - IFDEF _rx_functions + IFDEF _rx_update global rx_firmware_storage rx_firmware_storage: ;#include "rx_firmware-1-33.inc" ;#include "rx_firmware-1-37.inc" -#include "rx_firmware-1-38.inc" +;#include "rx_firmware-1-38.inc" +#include "rx_firmware-1-39.inc" global rx_firmware_new_major @@ -33,6 +34,6 @@ retlw rx_firmware_minor ; defined in firmware include file - ENDIF ; _rx_functions + ENDIF ; _rx_update END
--- a/src/rx_ops.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/rx_ops.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File rx_ops.asm combined next generation V3.03.1 +; File rx_ops.asm combined next generation V3.03.7 ; ; RX (Tank Pressure Transmitter) Routines. ; @@ -19,9 +19,12 @@ extern get_first_gas_to_WREG + extern I2C_probe_OSTC_rx + + IFDEF _rx_update extern I2C_update_OSTC_rx - extern I2C_probe_OSTC_rx extern rx_firmware_storage + ENDIF IFDEF _ccr_pscr extern get_first_dil_to_WREG @@ -271,9 +274,9 @@ ; ; pres_accu_1st res 4 ; accumulator for pressure drop in 1/(160 * 2^16) bar ; pres_accu_2nd res 4 ; accumulator for pressure drop in 1/(160 * 2^16) bar -; time_accu_1st res 1 ; accumulator for reading periods in seconds +; time_accu_1st res 2 ; accumulator for reading periods in seconds ; gas__last_1st res 1 ; last gas assignment -; time_accu_2nd res 1 ; accumulator for reading periods in seconds +; time_accu_2nd res 2 ; accumulator for reading periods in seconds ; gas__last_2nd res 1 ; last gas assignment ; pres_last_1st res 2 ; last pressure reading pressure in 1/160 bar ; pres_last_2nd res 2 ; last pressure reading pressure in 1/160 bar @@ -287,9 +290,9 @@ ; relative positioning of 16 bit ASM variables #DEFINE offset_FSR1_time_accu .0 ; offset 0 == base address of 1st/2nd -#DEFINE offset_FSR1_gas__last .1 ; offset 1 to base address of 1st/2nd -#DEFINE offset_FSR1_pres_last .4 ; offset 4 ... -#DEFINE offset_FSR1_time_last .8 ; offset 8 ... +#DEFINE offset_FSR1_gas__last .2 ; offset 1 to base address of 1st/2nd +#DEFINE offset_FSR1_pres_last .6 ; offset 6 ... +#DEFINE offset_FSR1_time_last .10 ; offset 10 ... ; relative positioning of shared integer variables #DEFINE offset_FSR2_press_curr .0 ; offset 0 == base address of 1st/2nd @@ -298,9 +301,9 @@ calc_pres_drop_1st: ; set up base addresses - lfsr FSR0,pres_accu_1st-1 ; load base address - 1 of pressure accumulator - lfsr FSR1,time_accu_1st ; load base address of other ASM variables - lfsr FSR2,int_IO_pressure_value+0; load base address of the shared variables + lfsr FSR0,pres_accu_1st ; load base address of pressure accumulator + lfsr FSR1,time_accu_1st ; load base address of other ASM variables + lfsr FSR2,int_IO_pressure_value+0; load base address of the shared variables ; get the currently assigned gas into lo movff char_I_pressure_gas+0,lo @@ -324,11 +327,11 @@ movff char_I_pressure_age+1,hi calc_pres_drop_common: - ; load the pressure accumulator into xC - FSR0 has been initialized to base address -1 - movff PREINC0,xC+0 ; copy pressure accumulator to xC, lowest byte - movff PREINC0,xC+1 ; copy pressure accumulator to xC, second byte - movff PREINC0,xC+2 ; copy pressure accumulator to xC, third byte - movff PREINC0,xC+3 ; copy pressure accumulator to xC, highest byte + ; load the pressure accumulator into xC - after copying, FSR0 stays on highest byte + movff POSTINC0,xC+0 ; copy pressure accumulator to xC, lowest byte + movff POSTINC0,xC+1 ; copy pressure accumulator to xC, second byte + movff POSTINC0,xC+2 ; copy pressure accumulator to xC, third byte + movff INDF0, xC+3 ; copy pressure accumulator to xC, highest byte ; check if the assigned gas has changed movlw offset_FSR1_gas__last ; load index of last assigned gas @@ -342,9 +345,9 @@ bra calc_pres_drop_reset ; YES - reset everything calc_pres_drop_common_1: - ; load the time accumulator into xB - movff INDF1,xB+0 ; load time accumulator, low byte (had been stored) - clrf xB+1 ; clear time accumulator, high byte (will be reset to 0 each round) + ; load the time accumulator into xB - after copying, FSR1 will have been restored to initial address + movff POSTINC1,xB+0 ; load time accumulator, low byte + movff POSTDEC1,xB+1 ; load time accumulator, high byte ; get the current pressure value into divA - after copying, FSR2 will have been restored to initial address movff POSTINC2,divA+0 ; copy current pressure value to divA, low byte @@ -412,6 +415,8 @@ addwf xB+0,F ; add to time_accu (xB), low byte movf hi,W ; copy time_curr (mpr) to WREG, high byte addwfc xB+1,F ; add to time_accu (xB), high_byte + btfsc STATUS,C ; did the accumulator over-run ? + bra calc_pres_drop_restart ; YES - reset both accumulators and set average pressure drop to not available ; subtract the last pressure time from time accumulator: time_accu (xB) -= time_last (sub_b) movf sub_b+0,W ; copy time_last (sub_b) to WREG, low byte @@ -421,15 +426,11 @@ btfss STATUS,C ; did the accumulator under-run (result negative) because of a wrap-around of the current time? bra calc_pres_drop_restart ; YES - reset both accumulators and set average pressure drop to not available - ; check if the time accumulator (xB) is or has become too large - ; this will happen if the last valid pressure reading is older than (256 - time_accu target) seconds - tstfsz xB+1 ; is the time accumulator < 256 [seconds], i.e. high byte = 0 ? - bra calc_pres_drop_restart ; NO - reset both accumulators and set average pressure drop to not available - calc_pres_drop_common_2: ; check if the time accumulator is or has become zero to avoid a div/0 ; as long as no valid pressure value is available, the time accumulator will stay at 0 and the pressure drop calculation kept in reset - movf xB+0,W ; copy time accumulator low byte to WREG, does it set the zero flag? + movf xB+0,W ; copy time accumulator low byte to WREG + iorwf xB+1,W ; inclusive-or time accumulator high byte into WREG, is result = zero ? bz calc_pres_drop_restart ; YES - reset both accumulators and set average pressure drop to not available ; duplicate pressure and time accumulators to other variables because xC and xB will get destroyed in div32x16 operation @@ -444,9 +445,12 @@ call div32x16 ; xC = xC / xB, xC is average pressure drop in 1/(160 * 2^16) bar/sec ; is the time accumulator above target level? (only the low byte needs to be evaluated)? - incf ul,W ; load the target threshold, +1 (incf) transforms cpfslt from < to <= operation - cpfslt divA+0 ; is the time accumulator > target threshold ? - rcall calc_pres_drop_reduce_accus ; YES - do an accumulator reduction + tstfsz divA+1 ; is the time accumulator > 255 seconds? + bra calc_pres_drop_common_2a ; YES - do an accumulator reduction + incf ul,W ; NO - load the target threshold, +1 (incf) transforms cpfslt from < to <= operation + cpfslt divA+0 ; - is the time accumulator > target threshold ? +calc_pres_drop_common_2a: + rcall calc_pres_drop_reduce_accus ; YES - do an accumulator reduction ; do an additional half-rate (every 2nd second) accumulator reduction btfsc timebase_1sec ; are we on an even second? @@ -456,10 +460,11 @@ movff mpr+3,POSTDEC0 ; store pressure accumulator, highest byte movff mpr+2,POSTDEC0 ; store pressure accumulator, third byte movff mpr+1,POSTDEC0 ; store pressure accumulator, second byte - movff mpr+0,POSTDEC0 ; store pressure accumulator, lowest byte + movff mpr+0,INDF0 ; store pressure accumulator, lowest byte - ; store the time accumulator - movff divA+0,INDF1 ; store time accumulator (only the low byte will be stored) + ; store the time accumulator - after copying, FSR1 will have been restored to initial address + movff divA+0,POSTINC1 ; store time accumulator, low byte + movff divA+1,POSTDEC1 ; store time accumulator, high byte ; check if the average pressure drop for transfer to p2deco needs to be limited tstfsz xC+3 ; check if the highest byte is all zero @@ -485,11 +490,15 @@ bsf divA+1,int_not_avail_flag ; YES - set pressure drop to not available, too ; set the average pressure drop as outdated if time_accu (divA) < (target threshold / 2) - rrncf ul,W ; load time accumulator target value / 2 into WREG - decf WREG,W ; subtract 1 to transform cpfsgt from > to >= operation + movlw offset_FSR1_time_accu+1 ; address high byte of time accumulator + tstfsz PLUSW1 ; time accumulator > 255 ? + bra calc_pres_drop_common_3a ; YES - can not be outdated then + rrncf ul,W ; NO - load time accumulator target value / 2 into WREG + decf WREG,W ; subtract 1 to transform cpfsgt from > into >= operation cpfsgt INDF1 ; time accumulator < (target threshold / 2) ? bsf divA+1,int_outdated_flag ; YES - set outdated flag +calc_pres_drop_common_3a: ; write average pressure drop to p2deco interface movlw offset_FSR2_press_drop+0 ; load index of average pressure drop, low byte movff divA+0,PLUSW2 ; store average pressure drop, low byte @@ -545,8 +554,9 @@ clrf POSTDEC0 ; clear pressure accumulator, second byte clrf POSTDEC0 ; clear pressure accumulator, lowest byte - ; clear time accumulator - clrf INDF1 ; clear time accumulator + ; clear time accumulator - after clearing, FSR1 will have been restored to initial address + clrf POSTINC1 ; clear time accumulator, low byte + clrf POSTDEC1 ; clear time accumulator, high byte ; clear pressure drop and set it to not available movlw offset_FSR2_press_drop+0 ; load index of average pressure drop, low byte @@ -605,6 +615,9 @@ ;----------------------------------------------------------------------------- ; Update TR module ; + + IFDEF _rx_update + global update_tr_module update_tr_module: movlw LOW rx_firmware_storage ; setup program memory read for embedded TR firmware @@ -657,6 +670,7 @@ call I2C_probe_OSTC_rx ; - give it a 2nd try return ; - finally done (whatever result on 2nd tray) + ENDIF ; _rx_update ;=============================================================================
--- a/src/rx_ops.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/rx_ops.inc Thu Sep 19 12:01:29 2019 +0200 @@ -11,5 +11,8 @@ extern get_pres_by_transmitter_id extern get_transmitter_id_by_slot extern configure_sac_calculation + ENDIF + + IFDEF _rx_update extern update_tr_module ENDIF
--- a/src/shared_definitions.h Sun Jun 30 23:22:32 2019 +0200 +++ b/src/shared_definitions.h Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ #ifdef xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ; -; shared_definitions.h combined next generation V3.03.1 +; shared_definitions.h combined next generation V3.04.3 ; ; Declare variables used both in C and ASM code ; @@ -89,7 +89,7 @@ #ifdef __18CXX //---- BANK 3 DATA ------------------------------------------------------- // Gather all Data C-Code --> ASM-Code - // Memory usage: 240 Byte used, 16 Byte free + // Memory usage: 247 Byte used, 9 Byte free # pragma udata overlay bank3=0x300 #else ; in ASM, put the same bank, in overlay mode, at the same address @@ -158,7 +158,6 @@ VAR_UCHAR (char_I_GF_High_percentage); // GF model high value VAR_UCHAR (char_I_GF_Low_percentage); // GF model low value -VAR_UCHAR (char_I_deco_distance); // assumed extra depth below required depth for CNS and gas volumes calculations VAR_UCHAR (char_I_depth_last_deco); // depth of the last deco stop in meters VAR_UCHAR (char_I_deco_model); // deco model selection: 0 = ZH-L16, 1 = ZH-L16-GF (with gradient factors) @@ -210,7 +209,7 @@ TAB_UCHAR (char_I_pressure_age, 2); // pressure reading, age of data TAB_UCHAR (char_I_pressure_stat,2); // pressure reading, transmitter status data -VAR_UCHAR (char_I_backtrack_time); // index (in minutes) of backtrack entries in char_I_backtrack_depth +TAB_UCHAR (char_O_deco_time_for_log, NUM_STOPS_LOG); // times of the shallowest NUM_STOPS_LOG deco stops VAR_UINT (int_O_profiling_overrun); // current scheduling overrun in ms VAR_UINT (int_O_profiling_overrun_max); // maximum scheduling overrun in ms @@ -218,7 +217,16 @@ VAR_UCHAR (char_O_profiling_runs_norm); // runs per cycle for normal plan VAR_UCHAR (char_O_profiling_runs_alt); // runs per cycle for alternative plan -TAB_UCHAR (char_O_deco_time_for_log, NUM_STOPS_LOG); // times of the shallowest NUM_STOPS_LOG deco stops +VAR_UINT (int_O_tank_pressure); // tank pressure for logging in [bar] +VAR_UINT (int_O_gas_density); // gas density of currently breathed mix in multiples of 0.01 grams per liter + +VAR_UCHAR (char_I_backtrack_time); // index (in minutes) of backtrack entries in char_I_backtrack_depth +VAR_UCHAR (char_I_gas_contingency); // =1: switch to alternative gas if best gas is depleted + +VAR_UCHAR (char_I_gas_density_att); // threshold for gas density attention [0.1 grams/l] +VAR_UCHAR (char_I_gas_density_warn); // threshold for gas density warning [0.1 grams/l] + +VAR_UCHAR (char_I_dil_ppO2_check); // =1: check ppO2 of the pure diluent against current setpoint #ifdef __18CXX
--- a/src/simulator.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/simulator.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File simulator.asm combined next generation V3.03.3 +; File simulator.asm combined next generation V3.04.3 ; ; Deco Calculator ; @@ -41,7 +41,7 @@ ;---- Private local Variables ------------------------------------------------- - CBLOCK local1 ; max size is 16 Byte !!! + CBLOCK local3 ; max size is 16 Byte !!! decoplan_index ; within each page decoplan_gindex ; global index decoplan_last ; depth of last stop @@ -50,6 +50,7 @@ decoplan_warnings ; deco engine warnings gas_index ; counter for looping through the gases output_row ; used for positioning of the results output + real_CNS ; real CNS value from before simulated dive ENDC ; used: 8 byte, remaining: 8 byte @@ -87,7 +88,10 @@ call deco_push_tissues_to_vault ; back-up the state of the real tissues (C-code) banksel common ; back to bank common + MOVII int_O_CNS_current,real_CNS ; memorize real CNS value from before simulated dive + rcall deco_calculate ; calculate deco plan + btfss decoplan_abort ; was the deco plan calculation aborted? rcall deco_results ; NO - show results @@ -127,21 +131,10 @@ btfsc update_surface_pressure ; is there a pending surface pressure update? bra $-2 ; YES - loop waiting for the ISR to kick in - ; set mode and gases - call dive_boot_oc_bail ; basic setup for all modes, also clears bailout_mode - - IFDEF _ccr_pscr - btfsc FLAG_oc_mode ; in OC mode? - call dive_boot_oc ; YES - set up OC mode - btfss FLAG_oc_mode ; in OC mode? - call dive_boot_cc ; NO - set up CCR/pSCR mode - ELSE - call dive_boot_oc ; set up OC mode - ENDIF - ; set absolute pressure at selected depth movff char_I_bottom_depth,WREG ; get selected depth in meters - mullw .100 ; multiply with 100 to get relative pressure in mbar + movwf depth_meter ; set depth for check_gas_best code + mullw .100 ; multiply depth with 100 to get relative pressure in mbar movff int_I_pres_surface+0,WREG ; low byte - get surface pressure to WREG addwf PRODL,W ; - add relative pressure movff WREG,int_I_pres_respiration+0 ; - store as absolute pressure at depth @@ -149,9 +142,55 @@ addwfc PRODH,W ; - add relative pressure movff WREG,int_I_pres_respiration+1 ; - store as absolute pressure at depth + ; compute absolute pressure / 10, will be used by check_gas_best + MOVII int_I_pres_respiration,xA ; get absolute pressure at depth + MOVLI .10,xB ; divide by 10 + call div16x16 ; xC = xA / xB = absolute pressure / 10 + MOVII xC,pressure_abs_10 ; store result for later use + + ; set up gas / diluent to be used on bottom segment + clrf WREG ; reset the deco info vector / deco flag so that ... + movff WREG,char_O_deco_info ; ... check_gas_best will not pick any deco gases + IFDEF _ccr_pscr + clrf active_dil ; invalidate active diluent + ENDIF + clrf active_gas ; invalidate active gas + call check_gas_best ; determine best diluent and/or gas + + IFDEF _ccr_pscr + btfsc FLAG_oc_mode ; in OC mode? + bra deco_calculate_0_oc ; YES - set up OC mode + ;bra deco_calculate_0_loop ; NO - set up CCR/pSCR mode + +deco_calculate_0_loop: + movf best_dil_number,W ; get best diluent into WREG + bz deco_calculate_0_error ; any usable diluent found? if NO do error handling + call setup_dil_registers ; set-up of diluent parameters for currently breathed diluent + call deco_setup_cc_diluents ; set-up of diluent list for deco calculations + bra deco_calculate_0_com ; continue with common part + ENDIF + +deco_calculate_0_oc: + movf best_gas_number,W ; get best gas into WREG + bz deco_calculate_0_error ; any usable gas found? if NO do error handling + call setup_gas_registers ; set-up of gas parameters of currently breathed gas + call deco_setup_oc_gases ; set-up of gas list for deco calculations + bra deco_calculate_0_com ; continue with common part + +deco_calculate_0_error: + call request_speed_normal ; request switch back to normal speed + WIN_COLOR color_red ; select color for error message + TEXT_SMALL .0, .80, tNoBottomGas1 ; print error message, line 1 + TEXT_SMALL .0, .105, tNoBottomGas2 ; print error message, line 2 + bsf decoplan_abort ; set abort flag + call wait_1s ; wait up to a full second + call wait_1s ; wait a full second + call wait_1s ; wait another full second + bcf switch_left ; clear potential button event + return ; return to deco calculator main function + +deco_calculate_0_com: ; set deco stop settings - movlw deco_distance ; get deco distance safety factor - movff WREG,char_I_deco_distance ; write deco distance safety factor to deco engine movff opt_last_stop,char_I_depth_last_deco ; write last stop depth to deco engine ; set GF factors @@ -198,6 +237,7 @@ bcf lo,DECO_START_NORM ; clear flag for normal plan mode bcf lo,DECO_START_ALT ; clear flag for alternative plan mode bsf lo,DECO_INITIALIZE ; set flag for once-per-dive initialization + bsf lo,DECO_CALCULATOR_MODE ; signal that the deco engine is run from the deco calculator bcf lo,DECO_BAILOUT_FLAG ; no gas switches before first deco stop bcf lo,DECO_ASCENT_FLAG ; no delayed ascent movff lo,char_O_deco_status ; bank-safe copy to deco engine control @@ -213,7 +253,7 @@ WIN_COLOR color_white ; select color for title and progress outputs TEXT_SMALL .0, .40, tCalculating ; print "Calculating..." - ; calculated the surface interval + ; calculate the surface interval TSTOSS opt_surface_interval ; surface interval > 0 ? bra deco_calculate_bottom ; NO - continue with bottom segment TEXT_SMALL .20,.75, tCalcSurfInter ; YES - print what we are doing @@ -227,7 +267,7 @@ ; char_I_sim_advance_time is cleared by deco engine after execution movff char_I_bottom_time,char_I_sim_advance_time - TEXT_SMALL .20,.100, tCalcBotSeg ; print what we are doing + TEXT_SMALL .20,.100,tCalcBotSeg ; print what we are doing ; invoke the deco engine once to condition the real tissues ; to their pressure state at the end of the bottom segment @@ -239,7 +279,7 @@ btfss bailout_mode ; shall calculate a bailout plan? bra deco_calculate_ascent ; NO - skip next - call dive_boot_oc ; YES - switch to OC mode and gases + call dive_boot_oc ; YES - switch to OC mode, configure OC gases and switch to gas set as 'First' movff char_O_main_status,hi ; - bank-safe copy from deco engine control (main status) bcf hi,DECO_BOTTOM_FLAG ; - exclude bottom segment from gas needs, i.e. calculate ascent needs only movff hi,char_O_main_status ; - bank-safe copy back to deco engine control @@ -260,10 +300,10 @@ deco_calculate_loop: btfsc switch_left ; was the left button pressed? bra deco_calculate_abort ; YES - set abort flag, do some clean-up and return - call deco_calc_hauptroutine ; NO - invoke the deco engine so that it can do the deco calculation (C-code) + call deco_calc_hauptroutine ; NO - invoke the deco engine so that it can do the deco calculation (C-code) banksel common ; - back to bank common movff char_O_depth_sim,lo ; - get the depth reached (in meters) - WIN_SMALL .70,.150 ; - set output position + WIN_SMALL .75,.150 ; - set output position output_8 ; - print depth reached (in meters) STRCAT " m" ; - print unit (meters) btg decoplan_toggleflag ; - toggle the toggle flag @@ -327,7 +367,7 @@ WIN_LEFT .135 lfsr FSR2,buffer movff hi,lo - output_99 ; stop entries are 99 min max. + output_99dd ; stop entries are 99 minutes at max., prints double dots if duration is zero STRCAT_PRINT "'" ; draw the bar graph used for deco stops (lo = minutes) @@ -337,9 +377,6 @@ movlw .118 movwf win_leftx2 ; column left (0-159) MOVLI .16,win_width ; column max width -; movlw .16 ; limit length to max. column width - not needed, done by TFT_box -; cpfslt lo -; movwf lo incf lo,W ; add 1 for a minimum visible active bargraph area movwf win_bargraph ; set width of the active bargraph area call TFT_box ; draw bargraph @@ -349,22 +386,6 @@ decf win_top,F ; restore win_top return -;----------------------------------------------------------------------------- -; Clear unused area below last stop -; Inputs: win_top : last used area -; -deco_plan_show_clear_bottom: - movf win_top,W ; get back from bank0 - sublw .239 ; bottom row in planning - movwf win_height - - WIN_LEFT .85 ; full dive menu width - MOVLI .75,win_width ; .159-.85+.1 - - clrf win_color1 ; fill with black - clrf win_color2 - - goto TFT_box ; and return ;----------------------------------------------------------------------------- ; Display the deco plan (simulator) @@ -383,9 +404,9 @@ deco_results_page_1: TEXT_SMALL .80,.1, tDivePlan deco_results_page_2: - movff char_O_deco_depth,WREG ; get depth of the first deco stop - iorwf WREG ; is there at least one deco stop? - bnz deco_plan_show_1 ; YES + movff char_O_deco_info,WREG ; get the deco info vector + btfsc WREG,deco_stops ; are there deco stops? + bra deco_plan_show_1 ; YES ;---- no deco -------------------------------------------------------- call TFT_standard_color @@ -393,11 +414,14 @@ ; output of remaining NDL time WIN_SMALL .80, .50 ; same line as bottom time + PUTC "+" movff char_O_NDL_norm,lo ; get NDL time in normal plan + bsf leftbind output_8 + bcf leftbind PUTC "'" PUTC " " - STRCAT_TEXT_PRINT tNDLleft ; "left" + STRCAT_TEXT_PRINT tNDLleft ; "NDL" bsf decoplan_last_stop_shown return @@ -450,16 +474,13 @@ movf PLUSW0,W ; char_O_deco_depth[decoplan_gindex] bz deco_plan_show_99 ; end of list - ; display the message "more..." - rcall deco_plan_show_clear_bottom ; clear from next line - call TFT_standard_color - TEXT_SMALL .88, .220, tMore + WIN_SMALL .135,.212 + STRCAT_PRINT ">>>" return deco_plan_show_99: bsf decoplan_last_stop_shown ; nothing more in table to display - rcall deco_plan_show_clear_bottom ; clear from next line call TFT_standard_color return @@ -470,27 +491,33 @@ call TFT_ClearScreen call TFT_standard_color - ; display plan parameters + ; print interval WIN_SMALL .0,.25 STRCPY "Int. :" - movff char_I_dive_interval,lo + movff opt_surface_interval,lo output_8 STRCAT_PRINT "'" + + ; print bottom time WIN_SMALL .0,.50 STRCPY_TEXT tBtTm_short movff char_I_bottom_time,lo output_8 STRCAT_PRINT "'" + + ; print bottom depth WIN_SMALL .0,.75 STRCPY_TEXT tDepth PUTC ":" movff char_I_bottom_depth,lo output_8 STRCAT_PRINT "m" - WIN_SMALL .0,.105 ; set position for warnings or sat/dsat factors + + ; print warnings or sat/dsat factors + WIN_SMALL .0,.105 ; check for stop table overflow - btfss decoplan_warnings,stoptable_overflow ; check if we have a overflow warning + btfss decoplan_warnings,deco_plan_incomplete ; check if deco plan is incomplete bra deco_results_0a ; NO - skip ; display overflow warning @@ -587,13 +614,13 @@ ; display CNS result WIN_TOP .205 STRCPY_TEXT tCNS2 ; "CNS:" - MOVII int_O_CNS_current,mpr ; get current CNS + MOVII real_CNS,mpr ; recall real CNS from before simulated dive call TFT_color_code_cns ; color-code CNS output bsf leftbind output_16_3 ; limit to 999 and display only (0-999) bcf leftbind STRCAT "%\x92" ; "->" - MOVII int_O_CNS_norm,mpr ; get CNS at end of dive in normal plan + MOVII int_O_CNS_norm,mpr ; get CNS at end of simulated dive in normal plan call TFT_color_code_cns ; color-code CNS output bsf leftbind output_16_3 ; limit to 999 and display only (0-999) @@ -606,7 +633,7 @@ clrf decoplan_page ; start from first page bcf decoplan_pressures_shown ; when showing the gas needs, start with volumes (liter) deco_results_1a: - WIN_BOX_BLACK .0, .239, .80, .159 ; clear the complete stop result column (top, bottom, left, right) + WIN_BOX_BLACK .0, .239, .80, .159 ; clear the complete right part of the result column (top, bottom, left, right) rcall deco_results_page ; show a results page incf decoplan_page,F ; increment results page number call reset_timeout_surfmode ; reset timeout @@ -635,7 +662,9 @@ btfss WREG,DECO_MODE_LOOP_FLAG ; - check if calculation was made for loop mode (CCR/pSCR) bra deco_results_gas_volumes ; NO - normal OC mode or bailout mode, show gas needs bsf bailout_mode ; YES - do a 2nd deco-plan in bailout mode - rcall deco_calculate_redo ; - redo deco calculation + call deco_pull_tissues_from_vault ; - restore the status of the real tissues (C-code) + banksel common ; - back to bank common + rcall deco_calculate_redo ; - redo complete deco calculation btfss decoplan_abort ; - was the calculation aborted? bra deco_results ; NO - redo display of deco stops return ; YES - return to deco calculator main function @@ -646,7 +675,7 @@ lfsr FSR0,int_O_gas_need_vol ; load base address of gas needs in volume deco_results_gas_common: - WIN_BOX_BLACK .0, .239, .80, .159 ; clear the complete stop result column (top, bottom, left, right) + WIN_BOX_BLACK .0, .239, .80, .159 ; clear the complete right part of the result column (top, bottom, left, right) movlw .25 ; output row is 25 (fixed offset set here) + n*25 (line increment, see below) movwf output_row ; set fixed vertical offset for output row WIN_LEFT .80 ; set column
--- a/src/sleepmode.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/sleepmode.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File sleepmode.asm combined next generation V3.03.1 +; File sleepmode.asm combined next generation V3.03.6 ; ; Sleep Mode ; @@ -23,6 +23,7 @@ #include "i2c.inc" #include "mcp.inc" #include "wait.inc" +#include "tft_outputs.inc" extern vault_decodata_into_eeprom @@ -35,7 +36,8 @@ accel_reference ; acceleration reference value for detecting movement / terminating deep sleep sm_timer_10sec ; timer for 10 seconds tasks (pressure check) sm_timer_10min ; timer for 10 minutes tasks (tissue updating) - sm_timer_15min ; timer for 15 minutes tasks (entering deep sleep) + ;sm_timer_15min ; timer for 15 minutes tasks (entering deep sleep) + sm_10min_counter ; count #of 10 minutes loop_counter ; loop counter, used in init_avg_switches routine sm_flags ; local flags ENDC ; used: 6 byte, remaining: 10 byte @@ -45,7 +47,7 @@ #DEFINE deep_sleep sm_flags,0 ; =1: in deep sleep mode, =0: normal sleep #DEFINE desat_on_10_mins sm_flags,1 ; =1: calculate desaturation every 10 minutes, =0: every minute -; sm_flags,2 ; unused +#DEFINE charge_in_sleep sm_flags,2 ; =1: show charging screen ; sm_flags,3 ; unused ; sm_flags,4 ; unused ; sm_flags,5 ; unused @@ -78,10 +80,7 @@ ENDIF clrf ADCON0 ; power-down ADC module - call TFT_Display_FadeOut ; power-down backlight - call TFT_DisplayOff ; power-down display call disable_rs232 ; power-down USB - call I2C_sleep_accelerometer ; power-down accelerometer call I2C_sleep_compass ; power-down compass call vault_decodata_into_eeprom ; store deco data @@ -90,9 +89,12 @@ clrf sm_timer_10sec ; clear 10 seconds timer clrf sm_timer_10min ; clear 10 minutes timer - clrf sm_timer_15min ; clear 15 minutes timer + clrf sm_10min_counter ; clear 10mins counter clrf sm_flags ; clear all local flags + call TFT_Display_FadeOut ; power-down backlight + call TFT_DisplayOff ; power-down display + sleeploop_loop: btfsc trigger_full_second ; one second in sleep? rcall one_sec_sleep ; YES - check switches, pressure sensor, etc. @@ -118,6 +120,9 @@ rcall deepsleep_get_accel ; read accelerometer into WREG movwf accel_reference ; store as reference value + tstfsz accel_reference ; = 0 ? + bra deepsleep_loop ; NO - continue + bra deepsleep_loop_exit ; YES - no deep sleep (fail-safe) deepsleep_loop: btfsc trigger_full_second ; one second in deep sleep? @@ -134,6 +139,9 @@ btfsc deep_sleep ; shall leave deep sleep mode? bra deepsleep_loop ; NO - loop in deep sleep loop +deepsleep_loop_exit: + bcf deep_sleep ; clear flag (again) + clrf sm_10min_counter ; clear 10mins counter call power_up_switches ; turn on the analog switches rcall init_avg_switches ; initialize the averaging system @@ -175,6 +183,32 @@ one_sec_sleep_1: call get_battery_voltage ; check for charger + ; Test if charging + btfss cc_active ; charging? + bra one_sec_sleep_1a ; NO + btfsc charge_in_sleep ; YES - already showing charge screen? + bra one_sec_sleep_1b ; YES - only update data + + bsf charge_in_sleep + bcf deep_sleep ; wake-up from deepsleep + call TFT_boot ; initialize TFT (includes clear screen) + movlw .32 + movff WREG,max_CCPR1L ; bank safe + call TFT_Display_FadeIn ; dim up the display +one_sec_sleep_1b: + call TFT_batt_surfmode ; show battery type, voltage and color-coded percentage + bra one_sec_sleep_2 ; continue + +one_sec_sleep_1a: + btfss charge_in_sleep ; was showing charge screen? + bra one_sec_sleep_2 ; NO + + ; yes, power-down screen + call TFT_Display_FadeOut ; power-down backlight + call TFT_DisplayOff ; power-down display + bcf charge_in_sleep + + one_sec_sleep_2: incf sm_timer_10sec,F ; increment 10 seconds timer movlw .10 ; load a 10 into WREG @@ -212,20 +246,6 @@ cpfslt sm_timer_10min ; timer < 10 yet? rcall ten_min_sleep ; NO - do the every 10 minutes tasks - ; the 15 minutes timer only ticks on OSTC with analog switches - btfss analog_switches ; OSTC with analog switches? - bra one_min_sleep_1 ; NO - no analog switches, no deep sleep required - - ; the 15 minutes timer also ticks only when not in deep sleep - btfsc deep_sleep ; in deep sleep mode? - bra one_min_sleep_1 ; YES - already in deep sleep - - ; tick the 15 minutes timer - incf sm_timer_15min,F ; increment 15 minutes timer - movlw .15 ; load a 15 into WREG - cpfslt sm_timer_15min ; timer < 15 yet? - rcall fifteen_min_sleep ; NO - do the every 15 minute tasks - one_min_sleep_1: ; continue tasks every minute btfsc desat_on_10_mins ; shall do desaturation calculation on 10 minute intervals? @@ -241,6 +261,21 @@ call sample_surface_pressure ; sample surface pressure and update ISR and deco engine + btfss analog_switches ; OSTC with analog switches? + bra ten_min_sleep_0 ; NO - no analog switches, no deep sleep required + + ; check if we need to enter deep sleep + incf sm_10min_counter,F ; count + movlw deep_sleep_10mins ; threshold + cpfseq sm_10min_counter ; threshold reached? + bra ten_min_sleep_0 ; NO - threshold not reached yet + + decf sm_10min_counter,F ; -1 to re-trigger every 10mins (in case of charging) + + btfss cc_active ; charging? + bsf deep_sleep ; NO - activate deep-sleep mode + +ten_min_sleep_0: btfss desat_on_10_mins ; shall do desaturation calculation on 10 minute intervals? bra ten_min_sleep_1 ; NO - continue checking if schedule can be switched to 10 minutes call deco_calc_dive_interval_10min ; YES - calculate 10 minutes at surface conditions (C-code) @@ -255,19 +290,12 @@ return ; done -fifteen_min_sleep: - ; tasks every 15 minutes in sleep mode - clrf sm_timer_15min ; reset timer to 0 - bsf deep_sleep ; enable deep-sleep mode - return - - one_hour_sleep: ; tasks every hour in sleep mode mode bcf trigger_full_hour ; clear one hour flag call update_battery_registers ; update battery registers into EEPROM call vault_decodata_into_eeprom ; update tissue pressures into EEPROM - return + return ; done init_avg_switches: @@ -310,18 +338,18 @@ btfsc STATUS,N ; result negative? negf WREG ; YES - negate it movwf lo ; save as change of acceleration in Z-axis - movlw .50 ; load threshold (mg) + movlw .100 ; load threshold (mg) cpfslt lo ; change of acceleration > threshold ? bcf deep_sleep ; YES - terminate deep sleep mode return ; done deepsleep_get_accel: - call I2C_init_compass ; start compass, required for compass1 - call I2C_init_accelerometer ; start accelerometer, required for compass2 + call I2C_init_compass ; start compass + rcall sleepmode_sleep ; wait a little bit call I2C_RX_accelerometer ; read accelerometer - call I2C_sleep_compass ; shut down compass, required for compass1 - call I2C_sleep_accelerometer ; shut down accelerometer, required for compass2 + call I2C_RX_accelerometer ; read accelerometer + call I2C_sleep_compass ; shut down compass movff accel_DZ+0,WREG ; transfer result to WREG return ; done @@ -354,6 +382,11 @@ sleepmode_sleep: movff BSR,BSR_backup ; backup BSR + + banksel common + btfsc charge_in_sleep ; already showing charge screen? + bra sleepmode_sleepwalk ; YES - skip the actual sleep (But wait) + banksel T7GCON ; switch bank, T7* is outside access RAM clrf T7GCON ; reset timer7 gate control register movlw b'10001101' ; 1:1 prescaler -> 2 seconds @ 32768 Hz, not synced @@ -363,7 +396,13 @@ clrf T7GCON ; reset timer7 gate control register movlw b'10001001' ; 1:1 prescaler -> 2 seconds @ 32768 Hz, synced movwf T7CON +sleepmode_sleep_1: movff BSR_backup,BSR ; restore BSR return + +sleepmode_sleepwalk: + WAITMS d'65' + bra sleepmode_sleep_1 + END \ No newline at end of file
--- a/src/start.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/start.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File start.asm combined next generation V3.03.2 +; File start.asm combined next generation V3.04.3 ; ; Startup subroutines ; @@ -50,6 +50,9 @@ IFDEF _rx_functions extern option_cleanup_oTrMode_CCR extern option_cleanup_oTrMode_no_CCR + ENDIF + + IFDEF _rx_update extern rx_firmware_new_major extern rx_firmware_new_minor ENDIF @@ -108,12 +111,16 @@ ; get screen type (2) from bootloader info bsf screen_type2 + bsf screen_type3 movlw 0x80 movwf TBLPTRL ; only low byte adjustment needed, high and upper are still at 0x01F7xx TBLRD*+ ; read configuration byte movlw 0x83 ; coding for screen type 2 cpfseq TABLAT ; equal? - bcf screen_type2 ; NO - not screen type 2 + bcf screen_type2 ; NO - not screen type 2 + movlw 0x84 ; coding for screen type 3 + cpfseq TABLAT ; equal? + bcf screen_type3 ; NO - not screen type 3 ; get button polarity from configuration data (EEPROM) movlw LOW .897 @@ -132,14 +139,18 @@ bsf LEDr ; turn on red LED ; first pass, will not have valid temperature yet - bcf trigger_pres_update ; make sure ISR pressure update confirmation is not older than from now on - btfss trigger_pres_update ; has the ISR confirmed a pressure update? - bra $-2 ; NO - not yet, loop waiting for the ISR to kick in + call wait_1s + call wait_1s +; bcf trigger_pres_update ; make sure ISR pressure update confirmation is not older than from now on +; btfss trigger_pres_update ; has the ISR confirmed a pressure update? +; bra $-2 ; NO - not yet, loop waiting for the ISR to kick in ; second pass - complete sensor initialization - bcf trigger_pres_update ; make sure ISR pressure update confirmation is not older than from now on - btfss trigger_pres_update ; has the ISR confirmed a pressure update? - bra $-2 ; NO - not yet, loop waiting for the ISR to kick in + call wait_1s + call wait_1s +; bcf trigger_pres_update ; make sure ISR pressure update confirmation is not older than from now on +; btfss trigger_pres_update ; has the ISR confirmed a pressure update? +; bra $-2 ; NO - not yet, loop waiting for the ISR to kick in ; sensor calibration completed, first valid pressure value is available bcf LEDr ; turn off red LED again @@ -285,7 +296,8 @@ ; clear flag groups clrf HW_descriptor ; hardware - OSTC model descriptor - clrf HW_flags_state ; hardware - status + clrf HW_flags_state1 ; hardware - states + ; ; do not clear HW_flags_state2 ! clrf DM_flags_sensor ; hardware - O2 sensors clrf OS_flags_ISR1 ; operating system - ISR control 1 @@ -331,12 +343,14 @@ bsf lightsen_power ; power-up ambient light sensor again restart2: + IFNDEF _hwos_sport btfsc vusb_in ; USB power detected? bra restart3 ; YES bcf PORTE,0 ; start comm WAITMS d'5' ; wait 5 ms btfss vusb_in ; USB power detected? bra restart3 ; NO + ENDIF bsf ble_available ; YES - BLE available restart3: @@ -379,6 +393,8 @@ btfss ostc_rx_present ; RX module detected? bra restart5 ; NO + IFDEF _rx_update + ; check if TR module firmware is up to date movff rx_firmware_cur_major,hi ; copy current firmware on RX module to bank common, major movff rx_firmware_cur_minor,lo ; copy current firmware on RX module to bank common, minor @@ -403,7 +419,6 @@ STRCAT "TR Update " ; prepare result message ; update firmware in RX module - call I2C_sleep_accelerometer ; stop accelerometer call I2C_sleep_compass ; stop compass call update_tr_module ; update TR module @@ -424,6 +439,8 @@ call wait_1s ; wait (another full) 1 second call wait_1s ; wait (another full) 1 second + ENDIF ; _rx_update + restart4e: btfss ostc_rx_present ; TR module up & running? bra restart5 ; NO @@ -490,8 +507,8 @@ IFDEF _external_sensor call disable_ir_s8 ; switch off IR/S8 digital interface by default + WAITMS d'100' ; Some delay to power down S8-HUD properly ENDIF - ; setup sampling rate movlw .2 ; default to 2 seconds movwf sampling_rate ; write setting
--- a/src/strings.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/strings.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File strings.asm combined next generation V3.03.1 +; File strings.asm combined next generation V3.03.5 ; ; Implementation code various string functions. ; @@ -213,12 +213,11 @@ movlw 4 bra start_common - IFDEF _huge_font global start_huge_block start_huge_block: movlw 5 ;bra start_block_common - ENDIF + start_common: movff WREG,win_font ; needs a bank-safe move here !
--- a/src/strings.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/strings.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File strings.asm combined next generation V3.03.2 +; File strings.asm combined next generation V3.03.5 ; ; Implementation code various string functions ; @@ -144,13 +144,11 @@ DB x, y endm - IFDEF _huge_font extern start_huge_block WIN_HUGE macro x, y call start_huge_block DB x, y endm - ENDIF ;============================================================================= ; Shortcuts for compact display programmings
--- a/src/surfmode.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/surfmode.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File surfmode.asm next combined generation V3.03.2 +; File surfmode.asm next combined generation V3.04.3 ; ; Surface Mode ; @@ -71,7 +71,7 @@ clrf STKPTR ; clear return addresses stack ; clrf CCP1CON ; stop PWM ; bcf PORTC,2 ; pull PWM output to GND - clrf CCPR1L ; backlight off +; clrf CCPR1L ; backlight off call TFT_boot ; initialize TFT (includes clear screen) btfsc restart_fast ; shall make a fast restart? @@ -82,19 +82,12 @@ WIN_LEFT .10 TFT_WRITE_PROM_IMAGE_BY_ADDR hw_logo_block - IFDEF _ostc_logo - ; show graphical OSTC logo - WIN_TOP .100 - WIN_LEFT .34 - TFT_WRITE_PROM_IMAGE_BY_LABEL ostc_logo_block - ELSE ; show textual OSTC logo WIN_COLOR color_white WIN_STD .30,.90 ; column, row STRCPY_PRINT "Open Source" ; show OSTC banner text, line 1 WIN_STD .20,.130 ; column, row STRCPY_PRINT "Tauch-Computer" ; show OSTC banner text, line 2 - ENDIF WIN_COLOR color_white WIN_SMALL .35,.180 @@ -117,7 +110,6 @@ bsf trigger_temp_changed ; set flag to have temperature written to display on first round of surface loop call I2C_sleep_compass ; shut down compass - call I2C_sleep_accelerometer ; shut down accelerometer clrf ext_flash_address+0 clrf ext_flash_address+1 @@ -142,6 +134,9 @@ btfsc restart_fast ; shall make a fast restart? bra surfloop_2 ; YES + call deco_calc_desaturation_time ; calculate desaturation and no-fly/no-altitude time (C-code) + banksel common ; back to bank common + call wait_1s ; wait <= 1 second call wait_1s ; wait 1 second call wait_1s ; wait 1 second @@ -167,12 +162,7 @@ ;---- Logo in upper right corner ----------------------------------------- - IFDEF _ostc_logo - ; show graphical OSTC logo - WIN_TOP .0 - WIN_LEFT .70 - TFT_WRITE_PROM_IMAGE_BY_LABEL ostc_logo_block - ELSE + ; show textual OSTC logo WIN_COLOR color_white ; set text color to white WIN_STD .100,.2 ; set output position @@ -188,7 +178,6 @@ ENDIF WIN_TINY .100,.32 ; set output position call TFT_show_firmware ; show firmware version - ENDIF ; _ostc_logo ;---- fill screen -------------------------------------------------------- @@ -342,7 +331,7 @@ btfsc compass_menu ; YES - "set course" selection already shown? bra test_switches_surfmode3b ; YES - remove it call TFT_surf_set_bearing ; NO - show it - return + return ; - done ENDIF test_switches_surfmode3a: bcf compass_bearing_set ; clear course on entering menu @@ -351,7 +340,7 @@ IFDEF _compass test_switches_surfmode3b: - WIN_BOX_BLACK .158,.190, .15, .99 ; clear "Course" label (top, bottom, left, right) + WIN_BOX_BLACK .158,.190, .15, .99 ; clear "Course" label (top, bottom, left, right) bcf compass_menu ; clear flag for "set course" selection return ENDIF
--- a/src/text_english.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/text_english.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_english.asm next combined generation V3.03.3 +; File text_english.asm next combined generation V3.04.3 ; ; English texts reference file. ; @@ -95,13 +95,13 @@ TCODE tGaslistCC, "CC Diluents" TCODE tGasEdit, "Edit Gas" TCODE tType, "Type: " - TCODE tGasDisabled, "Disabled" ; Disabled - TCODE tGasFirst, "First" ; First - TCODE tGasTravel, "Travel" ; Travel - TCODE tGasDeco, "Deco" ; Deco - TCODE tDilDisabled, "Disabled" ; Disabled - TCODE tDilFirst, "First" ; First - TCODE tDilNorm, "Normal" ; Normal + TCODE tGasDisabled, "Disabled" ; | Enum 0: Disabled + TCODE tGasFirst, "First" ; | 1: First + TCODE tGasTravel, "Work" ; | 2: Work (Travel, Bottom) + TCODE tGasDeco, "Deco" ; | 3: Deco + TCODE tDilDisabled, "Disabled" ; | Enum 0: Disabled + TCODE tDilFirst, "First" ; | 1: First + TCODE tDilNorm, "Normal" ; | 2: Normal TCODE tAir, "Air " ; Enum: values must follow (5 chars) TCODE tO2, "O2 " ; tAir + 5 TCODE tO2Plus, "O2 +" @@ -125,7 +125,7 @@ TCODE tppO2Dil, "ppO2(Dil)" ; ppO2(Dil) TCODE tppO2Mix, "ppO2(Mix)" ; ppO2(Mix) TCODE tCCRMode, "Mode:" ; Mode: - TCODE tCCRModeFixedSP, "Fixed SP/Calc." ; 0 fixed for CCR / calculated for pSCR | ENUM group + TCODE tCCRModeFixedSP, "Fixed SP" ; 0 fixed for CCR / calculated for pSCR | ENUM group TCODE tCCRModeSensor, "Sensor" ; 1 Sensor | TCODE tCCRModeAutoSP, "Auto SP" ; 2 Auto SP | ELSE @@ -179,16 +179,18 @@ TCODE tDkMode, "Decotype: ZH-L16" TCODE tZHL16, " " ; 0 - keep order, enum! TCODE tZHL16GF, "+GF" ; 1 - TCODE tPPO2Max, "Max :" - TCODE tPPO2DECO, "Max Deco:" - TCODE tPPO2MIN, "Min :" + TCODE tPPO2Max, "Max Work:" ; max ppO2 during working phase + TCODE tPPO2DECO, "Max Deco:" ; max ppO2 during deco phase IFDEF _ccr_pscr - TCODE tPPO2MINCC, "Min Loop:" + TCODE tPPO2MIN, "Min OC :" ; min ppO2 in OC mode + TCODE tPPO2MINCC, "Min Loop:" ; min ppO2 in loop mode + ELSE + TCODE tPPO2MIN, "Min :" ; min ppO2 in OC mode ENDIF TCODE tLastDecostop, "Last Deco : " ; last deco stop depth TCODE tAscentSpeed, "Ascent Speed : " ; Ascent Speed TCODE tGasChangeTime, "Gas Change :+" ; additional Gas Change Time - TCODE tExtendedStops, "before 1.Stop: " ; gas switches before 1st stop + TCODE tExtendedStops, "extended Stop: " ; extended stops TCODE tTimeoutDive, "Dive Timeout : " ; Dive Timeout TCODE tStoreApnoeDive, "Store Apnoe : " ; Store Apnoe Dives TCODE tDecoparameters, "Deco Parameters" @@ -210,15 +212,19 @@ TCODE tSetDecoUse, "Deco Gas: " ; Deco Gas: (space) TCODE tCalcAscGas, "Calc.Gas (B/O):" ; Calculate Gas (Bail Out) needs? TCODE tSetup_Tank, "Setup Tank" ; Setup Tank - TCODE tTankSize, "Tank Size" ; Tank Sizes + TCODE tTankSize, "Tank Size" ; Tank Size TCODE tTankUsablePress, "Turn Pres/Asc.Need" ; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars) TCODE tLiter, " l" ; Liter as l TCODE tLiterLong, "Liter" ; Liter as Liter TCODE t2ndDecoPlanMenu, "2nd Deco Plan" ; 2nd Deco Plan IFDEF _ccr_pscr - TCODE tCCmaxFracO2, "Loop %O2 max.:" - TCODE tCopyDilToOC, "Copy Dil.-> OC" ; copy diluent settings to OC gas + TCODE tCCmaxFracO2, "Loop %O2 max. : " ; max O2 percent (absolute) in the loop + TCODE tDilppO2Check, "Check Dil ppO2: " ; check ppO2 of the diluent against the setpoint + TCODE tPSCR_O2_drop, "pSCR O2 Drop: " ; pSCR O2 drop + TCODE tPSCR_lungratio, " Lung Ratio: " ; pSCR lung ratio + TCODE tCopyDilToOC, "Copy Dil.-> OC" ; copy diluent settings to OC gas + TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) ENDIF IFDEF _rx_functions @@ -261,11 +267,11 @@ TCODE tMODwarning, "Depth Warnings:" ; depth Warnings ; TCODE tIBCDwarning, "IBCD Warning :" ; IBCD Warning TCODE tLayout, "Layout :" ; Layout - TCODE t2ndDepth, "2nd Depth:" ; 2nd depth display content (10 chars max) + TCODE t2ndDepth, "2nd Depth:" ; 2nd depth display content (11 chars max) TCODE tTissueGraphics, "Graphics :" ; tissue graphics TCODE tLayoutNormal, "normal" ; normal - TCODE tLayoutBig, "big" ; big + TCODE tLayoutBig, "large" ; large ; VSI display settings @@ -287,7 +293,7 @@ TCODE tImperial, "ft/F" ; 1 ; 111 111 111 111 111 ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 - TCODE tDefName, " Read the Manual, know& understandthe inherentLimitations!" + TCODE tDefName, "HW OSTC" ;" Read the Manual, know& understandthe inherentLimitations!" TCODE tButtonleft, "Left button:" ; Left button TCODE tButtonright, "Right button:" ; Right button TCODE tAltMode, "Waiting Time:" @@ -331,20 +337,28 @@ TCODE tDivePlan, "Dive Plan" ; Dive Plan (max. 10 chars) TCODE tNoDeco, "No Deco" ; No Deco TCODE tMore, "more" ; more - TCODE tSelectSetpoint, "Setpoint : " - TCODE tuseAGF, "use aGF : " + TCODE tSelectSetpoint, "Setpoint : " ; Setpoint + TCODE tuseAGF, "use aGF : " ; use alternative Grdient Factors + IFDEF _gas_contingency + TCODE tGasContingency, "Gas Cont.: " ; Gas Contingency + ENDIF + +; Decoplanner progress indication + TCODE tNoBottomGas1, " No usable Gas for" ; no usable Gas for Bottom Depth found (line 1, max. 22 chars) + TCODE tNoBottomGas2, " Bottom Depth found!" ; no usable Gas for Bottom Depth found (line 2, max. 22 chars) TCODE tCalculating, "Calculating..." ; Calculating... TCODE tCalcSurfInter, "Surface Interval" ; Surface Interval TCODE tCalcBotSeg, "Bottom Segment" ; Bottom Segment TCODE tCalcBailout, "Switch to Bailout" ; Switch to Bailout - TCODE tCalcAscent, "Ascent" ; Ascent - TCODE tNDLleft, "left" ; time left within NDL + TCODE tCalcAscent, "Ascent" ; Ascent (max. 8 chars) + TCODE tNDLleft, "NDL" ; time left within NDL ; Information menu TCODE tFirmware, "Firmware: " ; Firmware: (space) + TCODE tHardware, "Hardware: " ; Hardware: (space) TCODE tSerial, "Serial : " ; Serial : (space) - TCODE tTotalDives, "Total Dives: " ; Total Dives: + TCODE tTotalDives, "Total Dives:" ; Total Dives: (no space, moved to logbook) TCODE tBatteryV, "Battery : " ; Battery : (space) TCODE tUptime, "Uptime : " ; Uptime : (space) @@ -356,6 +370,7 @@ ; Divemode screen TCODE tNDL, "NDL" ; 3 chars max TCODE tTTS, "TTS" ; 3 chars max + TCODE tSlow, " slow " ; slow - max 7 chars TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Select Gas" ; Select Gas @@ -390,7 +405,6 @@ TCODE taGFactors, "aGF Values" ; aGF Values TCODE tGFInfo, "Saturation" ; Saturation TCODE tCeiling, "Ceiling" ; Ceiling - TCODE tDiveSafetyStop, "Stop" ; Stop (four chars, right aligned) TCODE tDiveFallback, "Fallback!" ; Fallback! (max. nine chars) TCODE tDecoInfo, "Deco Zone" ; Deco info TCODE tSensorCheck, "Sensor Check" ; Sensor Check @@ -413,6 +427,7 @@ IFDEF _helium TCODE tHe, "He" ; He TCODE tIBCD, "IBCD N2He" ; IBCD warning + TCODE tGasDensity, "G.Density" ; Gas Density ENDIF IFDEF _rx_functions @@ -440,9 +455,10 @@ ; Divemode menu - TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + TCODE tDiveLayout, "Layout" ; Layout (max. 6 chars) IFDEF _compass - TCODE tSetHeading, "Course" ; set bearing (max. 6 chars) + TCODE tSetHeading, "Course" ; Course (max. 6 chars) ENDIF @@ -520,15 +536,6 @@ TCODE tColorSetName3, "Blue" ; Blue -; pSCR Menu and Settings - IFDEF _ccr_pscr - TCODE tPSCRMenu, "pSCR Setup" ; pSCR Menu - TCODE tPSCR_O2_drop, "O2 Drop " ; O2 drop - TCODE tPSCR_lungratio, "Lung Ratio " ; lung ratio - TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) - ENDIF - - ; Language selection IF _language_2!=none TCODE tLanguage, "Language: " ; used in menu_tree
--- a/src/text_french.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/text_french.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,8 +1,8 @@ ;============================================================================= ; -; File text_french.asm next combined generation V3.03.3 +; File text_french.sm next combined generation V3.04.3 ; -; French texts translation file. +; French texts translation file. ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= @@ -30,7 +30,7 @@ ; Divemode Menu TCODE tDivemenu_Gaslist, "Liste Gaz" ; Gas List (OC) TCODE tDivemenu_ResetAvg, "RaZChrono" ; Reset Avg - TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg, Set Marker (and Turn Dive) ## pending translation + TCODE tDivemenu_Avg_Mkr, "Moyen/Mark" ; Reset Avg, Set Marker (and Turn Dive) TCODE tDivemenu_ToggleGF, "Bascul.GF" ; Toggle GF TCODE tDivemenu_Marker, "Repre" ; Set Marker TCODE tDivemenu_LostGas, "Gaz Perdu" ; Lost Gas @@ -60,7 +60,7 @@ TCODE tSetDate, "Rglage Date" ; Set Date TCODE tSetTimeDate, "Date & Heure" ; Set Time & Date TCODE tDispSets, "Prfr. Rglages" ; Display Settings - TCODE tExit, "Retour" ; Exit + TCODE tExit, "Sortie" ; Exit TCODE tResetMenu, "Menu RaZ" ; Reset Menu TCODE tDiveModeMenu, "Menu Dco" ; Deco Mode TCODE tInfoMenu, "Informations" ; Information @@ -69,15 +69,15 @@ TCODE tDiluentSetup, "Liste Diluant" ; Diluent Setup ENDIF TCODE tFixedSetpoints, "Setpoints Fixes" ; Fixed Setpoints - TCODE tBack, "retour" ; back + TCODE tBack, "Retour" ; back IFDEF _rx_functions - TCODE tTrSettings, "Pressure Display" ; Pressure Display ## pending translation + TCODE tTrSettings, "Affich.Pression" ; Pressure Display TCODE tTrMode, "Mode: " ; Mode TCODE tTr1stPres, "1.Pres.: " ; 1st Pressure TCODE tTr2ndPres, "2.Pres.: " ; 2nd Pressure TCODE tTrBailPres, "1.B/O : " ; Bailout Pressure - TCODE tTrMaxDeltaP, "max deltaP: " ; independent double max diffenerce ## pending translation + TCODE tTrMaxDeltaP, "max deltaP: " ; independent double max diffenerce ENDIF IFDEF _ccr_pscr @@ -97,7 +97,7 @@ TCODE tType, "Type: " TCODE tGasDisabled, "Dsactiv" ; Disabled TCODE tGasFirst, "Premier" ; First - TCODE tGasTravel, "Travel" ; Travel + TCODE tGasTravel, "Travail" ; Work (Travel, Bottom) TCODE tGasDeco, "Dco" ; Deco TCODE tDilDisabled, "Dsactiv" ; Disabled TCODE tDilFirst, "Premier" ; First @@ -180,18 +180,20 @@ TCODE tDkMode, "Modle: ZH-L16" TCODE tZHL16, " " TCODE tZHL16GF, "+GF" - TCODE tPPO2Max, "PpO2 Max :" - TCODE tPPO2DECO, "PpO2 Dco:" - TCODE tPPO2MIN, "PpO2 Min :" + TCODE tPPO2Max, "Max Travail:" + TCODE tPPO2DECO, "Max Dco :" IFDEF _ccr_pscr - TCODE tPPO2MINCC, "Min Loop :" + TCODE tPPO2MIN, "Min OC :" + TCODE tPPO2MINCC, "Min Loop :" + ELSE + TCODE tPPO2MIN, "Min :" ENDIF TCODE tLastDecostop, "Dern.Palier : " - TCODE tAscentSpeed, "Ascent Speed : " ; Ascent Speed ## pending translation - TCODE tGasChangeTime, "Gas Change :+" ; additional Gas Change Time ## pending translation - TCODE tExtendedStops, "before 1.Stop: " ; gas switches before 1st stop ## pending translation - TCODE tTimeoutDive, "Fin Plonge : " ; Dive Timeout - TCODE tStoreApnoeDive, "Store Apnoe : " ; Store Apnoe Dives ## pending translation + TCODE tAscentSpeed, "Vitesse Rem. : " ; Ascent Speed + TCODE tGasChangeTime, "Tps Change Gaz :+" ; additional Gas Change Time + TCODE tExtendedStops, "Paliers + Longs: " ; extended stops + TCODE tTimeoutDive, "Fin Plonge : " ; Dive Timeout + TCODE tStoreApnoeDive, "Carnet Apne : " ; Store Apnoe Dives TCODE tDecoparameters, "Paramtres Dco" TCODE tGF_low, "GF Bas :" TCODE tGF_high, "GF Haut:" @@ -203,7 +205,7 @@ TCODE taGF_low, "aGF Bas :" ; aGF Low TCODE taGF_high, "aGF Haut:" ; aGF High TCODE taGF_enable, "aGF Possible:" ; aGF Selectable - TCODE tDiveaGF_active, "using aGF" ; using aGF ## pending translation + TCODE tDiveaGF_active, "aGF Actif" ; using aGF TCODE tppO2settings, "Menu PpO2" ; ppO2 Settings (max. 18 chars) TCODE tsafetystopmenu, "Palier Scurit:" ; Safety Stop: (max. 16 chars) TCODE tGasUsage, "Usage Gaz" ; Gas Usage @@ -212,38 +214,42 @@ TCODE tCalcAscGas, "Calc.Gaz (B/O):" ; Calculate Gas (Bail Out) needs? TCODE tSetup_Tank, "Config. Blocs" ; Setup Tank TCODE tTankSize, "Volume Bloc" ; Tank Sizes - TCODE tTankUsablePress, "Pression Ascent" ; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars) ## pending translation + TCODE tTankUsablePress, "Besoin Press. Rem." ; Tank Pressure Budget for Ascent (turn pressure) (max 19 chars) TCODE tLiter, " l" ; Liter as l - TCODE tLiterLong, "Liter" ; Liter as Liter - TCODE t2ndDecoPlanMenu, "Suite Menu Dco" ; 2nd Deco Plan + TCODE tLiterLong, "Litre" ; Liter as Liter + TCODE t2ndDecoPlanMenu, "2me Plan Dco" ; 2nd Deco Plan IFDEF _ccr_pscr - TCODE tCCmaxFracO2, "Loop %O2 max.:" ; - TCODE tCopyDilToOC, "Copy Dil.-> OC" ; copy diluent settings to OC gas ## pending translation + TCODE tCCmaxFracO2, "Loop %O2 max. : " ; max O2 percent (absolute) in the loop + TCODE tDilppO2Check, "Check Dil ppO2: " ; check ppO2 of the diluent against the setpoint + TCODE tPSCR_O2_drop, "pSCR O2 Drop: " ; pSCR O2 drop + TCODE tPSCR_lungratio, " Lung Ratio: " ; pSCR lung ratio + TCODE tCopyDilToOC, "Copie Diluant -> OC" ; copy diluent settings to OC gas + TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) ENDIF IFDEF _rx_functions - TCODE tTankPairing, "Config. Transmitter" ; select Transmitter ## pending translation - TCODE tTrModeOff, "off" ; off ## pending translation - TCODE tTrModeOn, "on" ; on ## pending translation - TCODE tTrModeIndDouble, "indep.Double" ; independent double ## pending translation + TCODE tTankPairing, "Appair.Transmetteur" ; select Transmitter + TCODE tTrModeOff, "off" ; off + TCODE tTrModeOn, "on" ; on + TCODE tTrModeIndDouble, "P.Bloc Diff." ; independent double TCODE tTrModeCCR, "CCR Dil+O2" ; CCR diluent and O2 - TCODE tTrPresNone, "none" ; none (big enum group follows) ## pending translation - TCODE tTrPresGas1, "Gas 1" ; Gas 1 - TCODE tTrPresGas2, "Gas 2" ; Gas 2 - TCODE tTrPresGas3, "Gas 3" ; Gas 3 - TCODE tTrPresGas4, "Gas 4" ; Gas 4 - TCODE tTrPresGas5, "Gas 5" ; Gas 5 + TCODE tTrPresNone, "no Press." ; none (big enum group follows) + TCODE tTrPresGas1, "Gaz 1" ; Gas 1 + TCODE tTrPresGas2, "Gaz 2" ; Gas 2 + TCODE tTrPresGas3, "Gaz 3" ; Gas 3 + TCODE tTrPresGas4, "Gaz 4" ; Gas 4 + TCODE tTrPresGas5, "Gaz 5" ; Gas 5 IFDEF _ccr_pscr TCODE tTrPresDil1, "Dil 1" ; Dil 1 TCODE tTrPresDil2, "Dil 2" ; Dil 2 TCODE tTrPresDil3, "Dil 3" ; Dil 3 TCODE tTrPresDil4, "Dil 4" ; Dil 4 TCODE tTrPresDil5, "Dil 5" ; Dil 5 - TCODE tTrPresFirstGas, "First Gas" ; first Gas ## pending translation - TCODE tTrPresActiveGas, "active Gas" ; active Gas ## pending translation - TCODE tTrPresFirstDil, "First Dil" ; first Dil ## pending translation - TCODE tTrPresActiveDil, "active Dil" ; active Dil ## pending translation + TCODE tTrPresFirstGas, "gaz prem." ; first Gas + TCODE tTrPresActiveGas, "gaz actif" ; active Gas + TCODE tTrPresFirstDil, "dil prem." ; first Dil + TCODE tTrPresActiveDil, "dil actif" ; active Dil ENDIF ELSE TCODE tTrModeOff, "" ; dummy target for entry in option table @@ -259,14 +265,14 @@ TCODE tDvSalinity, "Salinit: " ; Salinity TCODE tShowppO2, "Afficher PpO2:" ; Always show ppO2: TCODE tFlip, "Pivoter l'cran:" ; Rotate Screen - TCODE tMODwarning, "Alerte Prof.:" ; depth Warnings + TCODE tMODwarning, "Alerte Prof. :" ; depth Warnings ; TCODE tIBCDwarning, "Alerte CDI :" ; IBCD Warning - TCODE tLayout, "Layout :" ; Layout ## pending translation - TCODE t2ndDepth, "2.Prof.:" ; 2nd depth display content (10 chars max) - TCODE tTissueGraphics, "Dessin :" ; tissue graphics + TCODE tLayout, "Affichage :" ; Layout + TCODE t2ndDepth, "Choix Prof:" ; 2nd depth display content (11 chars max) + TCODE tTissueGraphics, "Dessin :" ; tissue graphics - TCODE tLayoutNormal, "normal" ; normal ## pending translation - TCODE tLayoutBig, "big" ; big ## pending translation + TCODE tLayoutNormal, "normal" ; normal + TCODE tLayoutBig, "large" ; large ; VSI display Settings @@ -288,7 +294,7 @@ TCODE tImperial, "ft/F" ; 111 111 111 111 111 ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 - TCODE tDefName, " Read the Manual, know& understandthe inherentLimitations!" ## pending translation + TCODE tDefName, "HW OSTC" ;"Lire la doc.Connaitre etComprendre les limites de l'OSTC ! " TCODE tButtonleft, "Bouton gauche:" ; Left button TCODE tButtonright, "Bouton droit :" ; Right button TCODE tAltMode, "Temps Attente:" ; Waiting Time @@ -332,20 +338,28 @@ TCODE tDivePlan, "Runtime" ; Dive Plan (max. 10 chars) TCODE tNoDeco, "Pas de Dco" ; No Deco TCODE tMore, "Suite" ; More - TCODE tSelectSetpoint, "Setpoint :" - TCODE tuseAGF, "aGF Permis:" ; use aGF + TCODE tSelectSetpoint, "Setpoint : " + TCODE tuseAGF, "aGF Permis: " ; use aGF + IFDEF _gas_contingency + TCODE tGasContingency, "Gas Cont. : " ; Gas Contingency ## translation pending + ENDIF + +; Decoplanner progress indication + TCODE tNoBottomGas1, "Pas de Gaz Utilisable" ; no usable Gas for Bottom Depth found (line 1, max. 22 chars) + TCODE tNoBottomGas2, "a la Profondeur Maxi!" ; no usable Gas for Bottom Depth found (line 2, max. 22 chars) TCODE tCalculating, "Calcul en cours" ; Calculating - TCODE tCalcSurfInter, "Surface Interval" ; Surface Interval ## pending translation - TCODE tCalcBotSeg, "Bottom Segment" ; Bottom Segment ## pending translation - TCODE tCalcBailout, "Switch to Bailout" ; Switch to Bailout ## pending translation - TCODE tCalcAscent, "Ascent" ; Ascent ## pending translation - TCODE tNDLleft, "left" ; time left within NDL ## pending translation + TCODE tCalcSurfInter, "Intervalle Surface" ; Surface Interval + TCODE tCalcBotSeg, "Calcul P. Max" ; Bottom Segment + TCODE tCalcBailout, "Mode Bailout" ; Switch to Bailout + TCODE tCalcAscent, "Remonte" ; Ascent (max. 8 chars) + TCODE tNDLleft, "NDL" ; time left within NDL ; Information menu TCODE tFirmware, "Logiciel: " ; Firmware: (space) + TCODE tHardware, "Hardware: " ; Hardware: (space) TCODE tSerial, "N. Srie: " ; Serial : (space) - TCODE tTotalDives, "Nbre Plonges:" ; Total Dives: (space) + TCODE tTotalDives, "Nbre Plonges:" ; Total Dives: TCODE tBatteryV, "Batterie: " ; Battery: TCODE tUptime, "Mise a Jour:" ; Uptime: @@ -357,6 +371,7 @@ ; Divemode screen TCODE tNDL, "NDL" ; 3 chars max TCODE tTTS, "DTR" ; 3 chars max + TCODE tSlow, "lente " ; slow - max 7 chars TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Activer Gaz" ; Select Gas @@ -367,7 +382,7 @@ TCODE tDepth, "Prof." ; Depth (max 5 chars) TCODE tMaxDepth, "Prof.Max." ; Max.Depth - max 9 chars! TCODE tAvgDepth, "Prof.Moy." ; average Depth - max 9 chars! - TCODE tTissuePresSat, "Pres+Sat" ; 0 pressure and saturation | ENUM group ## pending translation + TCODE tTissuePresSat, "Press+Sat" ; 0 pressure and saturation | ENUM group IFDEF _helium TCODE tTissueN2He, "N2+He" ; 1 N2 + He pressure | ENDIF @@ -378,8 +393,8 @@ TCODE tApnoeTotal, "Totale" ; Total (six chars, right aligned) TCODE tApnoeMax, "Dern.Plonge" ; Last Descend TCODE tApnoeSurface, "Tps.Surface" ; Surface Time - TCODE tTime, "Time" ; Time ## pending translation - TCODE tSurface, "Surface" ; Surface (max 12 chars) ## pending translation + TCODE tTime, "Heure" ; Time + TCODE tSurface, "Surface" ; Surface (max 12 chars) TCODE tDiveDecoplan, "Runtime" ; Decoplan ; TCODE tDiveClock, "Heure" ; Clock TCODE tDiveEAD_END, "EAD/END" ; EAD/END @@ -389,61 +404,62 @@ TCODE tDiveBailout, "Bailout" ; Bailout (max. 7 chars) TCODE tGFactors, "Valeurs GF" ; GF Values TCODE taGFactors, "Valeurs aGF" ; aGF Values - TCODE tGFInfo, "Saturation" ; Saturation ## pending translation + TCODE tGFInfo, "Saturation" ; Saturation TCODE tCeiling, "Plafond" ; Ceiling - TCODE tDiveSafetyStop, "Stop" ; Stop (four chars, right aligned) TCODE tDiveFallback, "Fallback!" ; Fallback! (max. nine chars) TCODE tDecoInfo, "Zone Dco" ; Deco info - TCODE tSensorCheck, "Ctrl Cell. " ; Sensor Check + TCODE tSensorCheck, " Ctrl Cell." ; Sensor Check TCODE tdil, "Dil:" ; Diluent ppO2 Warning TCODE tmix, "Mix:" ; Pre-Mix ppO2 Warning - TCODE tGasNeedsWarn, "Gas Needs" ; - TCODE tGasNeedsAscent, "Besoins Gaz Ascent" ; ## pending translation + TCODE tGasNeedsWarn, "Gaz Needs" ; + TCODE tGasNeedsAscent, "Besoin Gaz Remonte" ; Gas Needs for Ascent TCODE tCNSsurf, "SNC Surf." ; CNS Surf. TCODE tCNSfTTS, "SNC fDTR" ; CNS fTTS TCODE tCNSBO, "SNC B/O" ; CNS B/O TCODE tCNSnow, "SNC actuel" ; CNS now TCODE tCNSeod, "SNC final" ; CNS fin - TCODE tnoBOgas, "-B/O-Gaz-" ; + TCODE tnoBOgas, "-B/O-Gaz-" ; no bailout gas TCODE tMicroBubbles, "M.Bulles " ; TCODE tCNS, "SNC: " ; - TCODE tgaschange, "Change?" ; better gas found ## pending translation - TCODE tNeed, "Need " ; gas need (5 chars) ## pending translation + TCODE tgaschange, "Changer?" ; better gas found + TCODE tNeed, "Need " ; gas need (5 chars) TCODE tBattery, "Batterie" ; Battery IFDEF _helium TCODE tHe, "He" ; He TCODE tIBCD, "CDI N2He" ; IBCD warning + TCODE tGasDensity, "G.Density" ; Gas Density ## pending translation ENDIF IFDEF _rx_functions - TCODE tTransmitter, "P.Transm." ; pressure transmitter ## pending translation + TCODE tTransmitter, "P.Transm." ; pressure transmitter TCODE tPressure, "Pres Bloc" ; tank pressure TCODE tSAC, "SAC" ; SAC, must be 3 chars! - TCODE tswap, "Swap Tank" ; swap tank (max. 9 chars) ## pending translation + TCODE tswap, "Bloc Ech." ; swap tank (max. 9 chars) ENDIF IFDEF _ccr_pscr IFDEF _external_sensor - TCODE tDiveHudMask1, "cell. 1" - TCODE tDiveHudMask2, "cell. 2" - TCODE tDiveHudMask3, "cell. 3" + TCODE tDiveHudMask1, "Cell. 1" + TCODE tDiveHudMask2, "Cell. 2" + TCODE tDiveHudMask3, "Cell. 3" TCODE tSensorDisagree, "Sensors<>" ; Sensors disagree Warning; Sensors disagree Warning ENDIF ENDIF IFDEF _cave_mode TCODE tGasNeedsCaveMode, "Besoins Gaz Cave Mode" ; title for gas needs custom view - TCODE tDiveTurned, "Dv.turned" ; dive is turned (max. 9 char) ## pending translation + TCODE tDiveTurned, "Ret.Plong" ; dive is turned (max. 9 char) TCODE tCaveMode, "Cave Mode" ; cave mode activated (max. 9 char) TCODE tCaveModeShutdown, "X-Cave-X" ; cave mode shut down (max. 9 char) ENDIF ; Divemode menu - TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + TCODE tDiveLayout, "Affich" ; Layout (max. 6 chars) IFDEF _compass - TCODE tSetHeading, "Cap" ; Bearing (max. 6 chars) + TCODE tSetHeading, "Cap" ; Course (max. 6 chars) ENDIF @@ -474,7 +490,7 @@ TCODE tReboot, "Redmarrage" ; Reboot TCODE tResetMenu2, "Confirmer?" ; Are You Sure? TCODE tAbort, "Quitter" ; Abort - TCODE tResetSettings, "RaZ Settings" ; Reset Settings ## pending translation + TCODE tResetSettings, "RaZ Paramtres" ; Reset Settings TCODE tResetDeco, "RaZ Dco" ; Reset Deco TCODE tResetBattery, "RaZ Batterie" ; Reset Battery TCODE tResetLogbook, "RaZ Carnet" ; Reset Logbook @@ -490,9 +506,9 @@ ; Logbook Offset Menu - TCODE tLogOffset, "N 1re plonge" ; Logbook offset (Max. 15 Chars!) - TCODE tLogOffsetValue, "Offset : " ; Offset ## pending translation - TCODE tLogOffStepSize, "Step Size: " ; Step Size ## pending translation + TCODE tLogOffset, "N 1re Plonge" ; Logbook offset (Max. 15 Chars!) + TCODE tLogOffsetValue, "N1re Plong:" ; Offset + TCODE tLogOffStepSize, "Incrment :" ; Step Size TCODE tLogOffsetplus, "+" ; increment TCODE tLogOffsetminus, "-" ; decrement TCODE tLogOffStep1, " 1" ; adjustment step size 1 | ENUM group @@ -521,15 +537,6 @@ TCODE tColorSetName3, "Bleu" ; Blue -; PSCR Menu and Settings - IFDEF _ccr_pscr - TCODE tPSCRMenu, "Menu pSCR" ; PSCR Menu - TCODE tPSCR_O2_drop, "O2 Drop " ; O2 drop - TCODE tPSCR_lungratio, "Lung Ratio " ; lung ratio - TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) - ENDIF - - ; Language selection IF _language_2!=none TCODE tLanguage, "Langue: " ; used in menu_tree
--- a/src/text_german.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/text_german.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_german.asm next combined generation V3.03.3 +; File text_german.asm next combined generation V3.04.3 ; ; German texts translation file. ; @@ -77,7 +77,7 @@ TCODE tTr1stPres, "1.Druck: " ; 1st Pressure TCODE tTr2ndPres, "2.Druck: " ; 2nd Pressure TCODE tTrBailPres, "1.B/O : " ; Bailout Pressure - TCODE tTrMaxDeltaP, "max Diff.: " ; independent double max diffenerce + TCODE tTrMaxDeltaP, "max Diff.: " ; independent double max difference ENDIF IFDEF _ccr_pscr @@ -97,7 +97,7 @@ TCODE tType, "Type: " TCODE tGasDisabled, "Deaktiviert" ; Disabled TCODE tGasFirst, "Start" ; First - TCODE tGasTravel, "Reise" ; Travel + TCODE tGasTravel, "Arbeit" ; Work (Travel, Bottom) TCODE tGasDeco, "Deko" ; Deco TCODE tDilDisabled, "Deaktiviert" ; Disabled TCODE tDilFirst, "Start" ; First @@ -125,7 +125,7 @@ TCODE tppO2Dil, "ppO2(Dil)" ; ppO2(Dil) TCODE tppO2Mix, "ppO2(Mix)" ; ppO2(Mix) TCODE tCCRMode, "Modus:" ; Mode: - TCODE tCCRModeFixedSP, "fixeSP/Berech." ; 0 fixed for CCR / calculated for pSCR | ENUM group + TCODE tCCRModeFixedSP, "fixe SP" ; 0 fixed for CCR / calculated for pSCR | ENUM group TCODE tCCRModeSensor, "Sensor" ; 1 Sensor | TCODE tCCRModeAutoSP, "Auto SP" ; 2 Auto SP | ELSE @@ -179,16 +179,18 @@ TCODE tDkMode, "Decotype: ZH-L16" TCODE tZHL16, " " ; keep order, enum from here... TCODE tZHL16GF, "+GF" ; ...up to here! - TCODE tPPO2Max, "Max. :" - TCODE tPPO2DECO, "Max. Deko:" - TCODE tPPO2MIN, "Min. :" + TCODE tPPO2Max, "Max. Arbeit:" + TCODE tPPO2DECO, "Max. Deko :" IFDEF _ccr_pscr - TCODE tPPO2MINCC, "Min. Loop:" + TCODE tPPO2MIN, "Min. OC :" + TCODE tPPO2MINCC, "Min. Loop :" + ELSE + TCODE tPPO2MIN, "Min. :" ENDIF TCODE tLastDecostop, "Letzt.Stop : " TCODE tAscentSpeed, "Auf.Geschw. : " ; Ascent Speed TCODE tGasChangeTime, "Gaswechsel :+" ; additional Gas Change Time - TCODE tExtendedStops, "vor 1.Stopp : " ; gas switches before 1st stop + TCODE tExtendedStops, "erw. Stopps : " ; extended stops TCODE tTimeoutDive, "TG-Ende nach: " ; Dive Timeout TCODE tStoreApnoeDive, "Log Apnoe : " ; Store Apnoe Dives TCODE tDecoparameters, "Deko Parameter" @@ -206,8 +208,8 @@ TCODE tppO2settings, "ppO2 Parameter" ; ppO2 Settings TCODE tsafetystopmenu, "Sicherheitsstop:" ; Safety Stop: TCODE tGasUsage, "Gasbedarf" ; Gas Usage - TCODE tSetBotUse, "Reise Gas: " ; Bottom Gas: (space) - TCODE tSetDecoUse, "Deko Gas: " ; Deco Gas: (space) + TCODE tSetBotUse, "Arbeits-Gas:" ; Bottom Gas: + TCODE tSetDecoUse, "Deko Gas:" ; Deco Gas: TCODE tCalcAscGas, "Gasmenge(B/O):" ; Calculate Gas (Bail Out) needs? TCODE tSetup_Tank, "Tank Einstellen" ; Setup Tank TCODE tTankSize, "Tank Gre" @@ -217,8 +219,12 @@ TCODE t2ndDecoPlanMenu, "2.Deko Plan" ; 2nd Deco Plan IFDEF _ccr_pscr - TCODE tCCmaxFracO2, "Loop %O2 max.:" + TCODE tCCmaxFracO2, "Loop %O2 max. : " ; max O2 percent (absolute) in the loop + TCODE tDilppO2Check, "Check Dil ppO2: " ; check ppO2 of the diluent against the setpoint + TCODE tPSCR_O2_drop, "pSCR O2 Abfall: " ; pSCR O2 drop + TCODE tPSCR_lungratio, " L.Verhlt.: " ; pSCR lung ratio TCODE tCopyDilToOC, "Kopiere Dil.-> OC" ; copy diluent settings to OC gas + TCODE tBackToLoop, "auf Loop" ; back to loop (10 chars max) ENDIF IFDEF _rx_functions @@ -261,7 +267,7 @@ TCODE tMODwarning, "Tiefe Warnung:" ; depth Warnings ; TCODE tIBCDwarning, "IBCD Warnung:" ; IBCD warning TCODE tLayout, "Layout :" ; Layout - TCODE t2ndDepth, "2.Tiefe:" ; 2nd depth display content (10 chars max) + TCODE t2ndDepth, "2.Tiefe:" ; 2nd depth display content (11 chars max) TCODE tTissueGraphics, "Grafik :" ; tissue graphics TCODE tLayoutNormal, "normal" ; normal @@ -287,7 +293,7 @@ TCODE tImperial, "ft/F" ; 111 111 111 111 111 ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 - TCODE tDefName, " Lese die Anleitung, kenne und verstehe die Grenzen!" + TCODE tDefName, "HW OSTC" ;" Lese die Anleitung, kenne und verstehe die Grenzen!" TCODE tButtonleft, "Taster links :" ; Left button TCODE tButtonright, "Taster rechts:" ; Right button TCODE tAltMode, "Wartezeit:" @@ -331,20 +337,28 @@ TCODE tDivePlan, "Tauchplan" ; Dive Plan (max. 10 chars) TCODE tNoDeco, "Keine Deko" ; No Deco TCODE tMore, "mehr" ; More - TCODE tSelectSetpoint, "Setpoint :" - TCODE tuseAGF, "Benutze aGF:" + TCODE tSelectSetpoint, "Setpoint : " + TCODE tuseAGF, "Benutze aGF: " + IFDEF _gas_contingency + TCODE tGasContingency, "Gas Cont. : " ; Gas Contingency ## translation pending + ENDIF + +; Decoplanner progress indication + TCODE tNoBottomGas1, " kein auf der Tiefe" ; no usable Gas for Bottom Depth found (line 1, max. 22 chars) ## pending translation + TCODE tNoBottomGas2, "nutzbares Gas gefunden"; no usable Gas for Bottom Depth found (line 2, max. 22 chars) ## pending translation TCODE tCalculating, "Berechnung luft..." TCODE tCalcSurfInter, "Oberflchenpause" ; Surface Interval TCODE tCalcBotSeg, "Grundzeit" ; Bottom Segment TCODE tCalcBailout, "Wechsel auf Bailout" ; Switch to Bailout - TCODE tCalcAscent, "Aufstieg" ; Ascent + TCODE tCalcAscent, "Aufstieg" ; Ascent (max. 8 chars) TCODE tNDLleft, "brig" ; time left within NDL ; Information menu TCODE tFirmware, "Firmware: " ; Firmware: (space) + TCODE tHardware, "Hardware: " ; Hardware: (space) TCODE tSerial, "Seriennr: " ; Serial : (space) - TCODE tTotalDives, "Anzahl TG: " ; Total Dives: + TCODE tTotalDives, "Anzahl TG:" ; Total Dives: TCODE tBatteryV, "Batterie: " ; Battery: TCODE tUptime, "Laufzeit: " ; Uptime: @@ -356,6 +370,7 @@ ; Divemode screen TCODE tNDL, " NZ" ; 3 chars max TCODE tTTS, "TTS" ; 3 chars max + TCODE tSlow, "langsam" ; slow - max 7 chars TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Whle Gas" ; Select Gas @@ -390,7 +405,6 @@ TCODE taGFactors, "aGF Werte" ; aGF Values TCODE tGFInfo, "Sttigung" ; Saturation TCODE tCeiling, "Ceiling" ; Ceiling - TCODE tDiveSafetyStop, "Stop" ; Stop (four chars, right aligned) TCODE tDiveFallback, "Fallback!" ; Fallback! (max. nine chars) TCODE tDecoInfo, "Deko Zone" ; Deco info TCODE tSensorCheck, "Sensor Test" ; Sensor Check @@ -413,6 +427,7 @@ IFDEF _helium TCODE tHe, "He" ; He TCODE tIBCD, "IBCD N2He" ; IBCD warning + TCODE tGasDensity, "Gasdichte" ; Gas Density ENDIF IFDEF _rx_functions @@ -440,9 +455,10 @@ ; Divemode menu - TCODE tDivePreMenu, "Men?" ; Menu? (max. 5 chars) + TCODE tDivePreMenu, "Men?" ; Menu? (max. 5 chars) + TCODE tDiveLayout, "Layout" ; Layout (max. 6 chars) IFDEF _compass - TCODE tSetHeading, "Kurs" ; set bearing (max. 6 chars) + TCODE tSetHeading, "Kurs" ; Course (max. 6 chars) ENDIF @@ -520,15 +536,6 @@ TCODE tColorSetName3, "Blau" ; Blue -; pSCR Menu and Settings - IFDEF _ccr_pscr - TCODE tPSCRMenu, "pSCR Men" ; PSCR Menu - TCODE tPSCR_O2_drop, "O2 Abfall " ; O2 drop - TCODE tPSCR_lungratio, "L.Verhlt. " ; lung ratio - TCODE tBackToLoop, "auf Loop" ; back to loop (10 chars max) - ENDIF - - ; Language selection IF _language_2!=none TCODE tLanguage, "Sprache: " ; used in menu_tree
--- a/src/text_italian.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/text_italian.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File text_italian.asm next combined generation V3.03.3 +; File text_italian.asm next combined generation V3.04.3 ; ; Italian texts translation file. ; @@ -30,7 +30,7 @@ ; Divemode Menu TCODE tDivemenu_Gaslist, "Lista Gas" ; Gaslist (OC) TCODE tDivemenu_ResetAvg, "AzzeraMed" ; Reset Avg - TCODE tDivemenu_Avg_Mkr, "Avg/Marker" ; Reset Avg, Set Marker (and Turn Dive) ## pending translation + TCODE tDivemenu_Avg_Mkr, "Med/Segna" ; Reset Avg, Set Marker (and Turn Dive) TCODE tDivemenu_ToggleGF, "Alterna GF" ; Toggle GF TCODE tDivemenu_Marker, "Set Marker" ; Set Marker TCODE tDivemenu_LostGas, "Gas perso" ; Lost Gas @@ -72,12 +72,12 @@ TCODE tBack, "back" ; back IFDEF _rx_functions - TCODE tTrSettings, "Pressure Display" ; Pressure Display ## pending translation + TCODE tTrSettings, "Display Press.ni" ; Pressure Display TCODE tTrMode, "Modo: " ; Mode - TCODE tTr1stPres, "1.Pres.: " ; 1st Pressure - TCODE tTr2ndPres, "2.Pres.: " ; 2nd Pressure - TCODE tTrBailPres, "1.B/O : " ; Bailout Pressure - TCODE tTrMaxDeltaP, "max deltaP: " ; independent double max diffenerce ## pending translation + TCODE tTr1stPres, "1a Pres: " ; 1st Pressure + TCODE tTr2ndPres, "2a Pres: " ; 2nd Pressure + TCODE tTrBailPres, "1a B/O : " ; Bailout Pressure + TCODE tTrMaxDeltaP, "DeltaP Max: " ; independent double max diffenerce ENDIF IFDEF _ccr_pscr @@ -97,7 +97,7 @@ TCODE tType, "Tipo: " TCODE tGasDisabled, "Disabilitato" ; Disabled TCODE tGasFirst, "Primo" ; First - TCODE tGasTravel, "Viaggio" ; Travel + TCODE tGasTravel, "Lavoro" ; Work (Travel, Bottom) ("Viaggio") TCODE tGasDeco, "Deco" ; Deco TCODE tDilDisabled, "Disabilitato" ; Disabled TCODE tDilFirst, "Primo" ; First @@ -112,15 +112,15 @@ ENDIF TCODE tMOD, "MOD :" TCODE tEAD, "EAD:" - TCODE tSetup_GasDepth, "Cambia profondita'" + TCODE tSetup_GasDepth, "Cambia Profondita'" TCODE tDepthPlus, "Profondita' +" TCODE tDepthMinus, "Profondita' -" TCODE tDepthReset, "Reset a MOD:" - TCODE tSetup_GasMix, "Cambia Miscela" + TCODE tSetup_GasMix, "Cambia Gas" IFDEF _ccr_pscr TCODE tSPPlus, "ppO2+" ; pO2+ TCODE tSensorFallback, "Fallback:" ; Fallback: - TCODE tCalculated, "calcolato" ; calculated + TCODE tCalculated, "Calcolato" ; calculated TCODE tppO2O2, "ppO2(O2)" ; ppO2(O2) TCODE tppO2Dil, "ppO2(Dil)" ; ppO2(Dil) TCODE tppO2Mix, "ppO2(Mix)" ; ppO2(Mix) @@ -139,10 +139,10 @@ ; 1 2 ; ; 12345678901234567890 ; max 20 chars TCODE tNewBattTitle, "Nuova Batteria?" - TCODE tNewBattOld, "Mantieni vecchio" + TCODE tNewBattOld, "Mantieni vecchia" TCODE tNewBattNew36, "3,6V monouso (T1)" ; new 3.6V disposable TCODE tNewBattNew15, "1,5V monouso (T0)" ; new 1.5V disposable - TCODE tNewBattAccu, "3,7V ricaricare (T2)" ; new 3.7V rechargeable + TCODE tNewBattAccu, "3,7V ricaricab. (T2)" ; new 3.7V rechargeable TCODE tNew18650, "OSTC 2 o cR (T3)" ; internal battery on 2 (old) / cR TCODE tNew16650, "OSTC 2 o TR (T4)" ; internal battery on 2 (new) / TR TCODE tConfirmChargeable1,"Conferma:" ; safety question, line 1 @@ -165,7 +165,7 @@ TCODE tUsbClosed, "Porta chiusa" TCODE tUsbExit, "Uscita" TCODE tUsbDownloadMode, "Modo Download abil" - TCODE tUsbLlBld, "Livello-basso Bootloader" + TCODE tUsbLlBld, "Bootloader Basso Livello" ; Dive Settings @@ -179,30 +179,32 @@ TCODE tDkMode, "Algorit.: ZH-L16" TCODE tZHL16, " " TCODE tZHL16GF, "+GF" - TCODE tPPO2Max, "ppO2 Max :" - TCODE tPPO2DECO, "ppO2 Deco:" - TCODE tPPO2MIN, "ppO2 Min :" + TCODE tPPO2Max, "Max Attv:" + TCODE tPPO2DECO, "Max Deco:" IFDEF _ccr_pscr - TCODE tPPO2MINCC, "Loop Min :" + TCODE tPPO2MIN, "Min OC :" + TCODE tPPO2MINCC, "Min Loop:" + ELSE + TCODE tPPO2MIN, "Min :" ENDIF - TCODE tLastDecostop, "Ultima Deco : " - TCODE tAscentSpeed, "Ascent Speed : " ; Ascent Speed ## pending translation - TCODE tGasChangeTime, "Gas Change :+" ; additional Gas Change Time ## pending translation - TCODE tExtendedStops, "before 1.Stop : " ; gas switches before 1st stop ## pending translation + TCODE tLastDecostop, "Ultima Tappa : " + TCODE tAscentSpeed, "Velox Risalita : " ; Ascent Speed + TCODE tGasChangeTime, "Cambio Gas :+" ; additional Gas Change Time + TCODE tExtendedStops, "Anticipa Tappa: " ; extended stops TCODE tTimeoutDive, "Timeout Immsni: " ; Dive Timeout - TCODE tStoreApnoeDive, "Store Apnoe : " ; Store Apnoe Dives ## pending translation + TCODE tStoreApnoeDive, "Salva Apnee : " ; Salva Tuffi Apnea TCODE tDecoparameters, "Parametri Deco" TCODE tGF_low, "GF Basso:" TCODE tGF_high, "GF Alto :" TCODE tSaturationMult, "Saturazione : " TCODE tDesaturationMult, "Desaturazione: " TCODE tFTTSMenu, "TTS Futuro:" ; Future TTS - TCODE tLastDecostopSurf, "Ultima Deco:" ; last deco stop surface custom view + TCODE tLastDecostopSurf, "Ultima Tappa:" ; last deco stop surface custom view TCODE tGFMenu, "Menu GF" ; GF Settings TCODE taGF_low, "aGF Basso:" ; aGF low TCODE taGF_high, "aGF Alto :" ; aGF high TCODE taGF_enable, "aGF Selezionabile:" ; aGF Selectable - TCODE tDiveaGF_active, "using aGF" ; using aGF ## pending translation + TCODE tDiveaGF_active, "Usa aGF" ; using aGF TCODE tppO2settings, "Menu ppO2" ; ppO2 Settings (max. 18 chars) TCODE tsafetystopmenu, "Tappa Sicurezza:" ; Safety Stop: (max. 16 chars) TCODE tGasUsage, "Utilizzo Gas" ; Gas Usage @@ -211,23 +213,27 @@ TCODE tCalcAscGas, "Calc.Gas (B/O):" ; Calculate Gas (Bail Out) needs? TCODE tSetup_Tank, "Imposta Bombola" ; Setup Tank TCODE tTankSize, "Capac. Bombola" ; Tank Size - TCODE tTankUsablePress, "Press. Necess. Asc." ; Tank Press Budget for Ascent (turn pressure) ## pending translation + TCODE tTankUsablePress, "Press. X Risalita" ; Tank Press Budget for Ascent (turn pressure) TCODE tLiter, " l" ; Liter as l TCODE tLiterLong, "Litri" ; Liter as Liter TCODE t2ndDecoPlanMenu, "2o Piano Deco" ; 2nd Deco Plan IFDEF _ccr_pscr - TCODE tCCmaxFracO2, "%O2 max Loop:" ; - TCODE tCopyDilToOC, "Copy Dil->OC" ; copy diluent settings to OC gas ## pending translation - IFDEF _ccr_pscr + TCODE tCCmaxFracO2, "%O2 max Loop : " ; max O2 percent (absolute) in the loop + TCODE tDilppO2Check, "Check Dil ppO2: " ; check ppO2 of the diluent against the setpoint + TCODE tPSCR_O2_drop, "pSCR Caduta O2: " ; pSCR O2 drop + TCODE tPSCR_lungratio, " Lung Ratio: " ; pSCR lung ratio + TCODE tCopyDilToOC, "Copia Dil-OC" ; copy diluent settings to OC gas + TCODE tBackToLoop, "Usa Loop" ; back to loop (10 chars max) + ENDIF IFDEF _rx_functions - TCODE tTankPairing, "Cambia Transmitter" ; select Transmitter ## pending translation - TCODE tTrModeOff, "off" ; off ## pending translation - TCODE tTrModeOn, "on" ; on ## pending translation - TCODE tTrModeIndDouble, "indep.Double" ; independent double ## pending translation + TCODE tTankPairing, "Cambia Transmett." ; select Transmitter + TCODE tTrModeOff, "Off" ; off + TCODE tTrModeOn, "On" ; on + TCODE tTrModeIndDouble, "Bibo Separ." ; independent double TCODE tTrModeCCR, "CCR Dil+O2" ; CCR diluent and O2 - TCODE tTrPresNone, "none" ; none (big enum group follows) ## pending translation + TCODE tTrPresNone, "N/A" ; none (big enum group follows) TCODE tTrPresGas1, "Gas 1" ; Gas 1 TCODE tTrPresGas2, "Gas 2" ; Gas 2 TCODE tTrPresGas3, "Gas 3" ; Gas 3 @@ -239,13 +245,13 @@ TCODE tTrPresDil3, "Dil 3" ; Dil 3 TCODE tTrPresDil4, "Dil 4" ; Dil 4 TCODE tTrPresDil5, "Dil 5" ; Dil 5 - TCODE tTrPresFirstGas, "First Gas" ; first Gas ## pending translation - TCODE tTrPresActiveGas, "active Gas" ; active Gas ## pending translation - TCODE tTrPresFirstDil, "First Dil" ; first Dil ## pending translation - TCODE tTrPresActiveDil, "active Dil" ; active Dil ## pending translation + TCODE tTrPresFirstGas, "Primo Gas" ; first Gas + TCODE tTrPresActiveGas, "Gas Attivo" ; active Gas + TCODE tTrPresFirstDil, "Primo Dil" ; first Dil + TCODE tTrPresActiveDil, "Dil Attivo" ; active Dil ENDIF ELSE - TCODE tTrModeOff, "" ; dummy target for entry in option table + TCODE tTrModeOff, "" ; dummy target for entry in option table TCODE tTrPresNone, "" ; dummy target for entry in option table ENDIF ; _rx_functions @@ -260,12 +266,12 @@ TCODE tFlip, "Ruota schermo:" ; Rotate Screen TCODE tMODwarning, "Avvertimento Prof:" ; depth warnings ; TCODE tIBCDwarning, "Avvertimento IBCD:" ; IBCD Warning - TCODE tLayout, "Layout :" ; Layout ## pending translation - TCODE t2ndDepth, "2.Prof.:" ; 2nd depth display content (10 chars max) + TCODE tLayout, "Layout :" ; Layout + TCODE t2ndDepth, "2a Prof.:" ; 2nd depth display content (11 chars max) TCODE tTissueGraphics, "Grafica:" ; tissue graphics - TCODE tLayoutNormal, "normal" ; normal ## pending translation - TCODE tLayoutBig, "big" ; big ## pending translation + TCODE tLayoutNormal, "Normale" ; normal + TCODE tLayoutBig, "Max" ; big ("Maxi") ; VSI display Settings @@ -287,7 +293,7 @@ TCODE tImperial, "ft/F" ; 111 111 111 111 111 ; 5 rows by 12 chars each: 123456789012123456789012123456789012123456789012123456789012 - TCODE tDefName, " Read the Manual, know& understandthe inherentLimitations!" ## pending translation + TCODE tDefName, "HW OSTC" ;" Read the Manual, know& understandthe inherentLimitations!" TCODE tButtonleft, "Bottone Sx:" ; Left button TCODE tButtonright, "Bottone Dx:" ; Right button TCODE tAltMode, "Attesa :" ; Waiting Time @@ -333,16 +339,24 @@ TCODE tMore, "Dettagli" ; More TCODE tSelectSetpoint, "Setpoint CCR: " ; TCODE tuseAGF, "usa aGF : " ; use aGF + IFDEF _gas_contingency + TCODE tGasContingency, "Gas Cont. : " ; Gas Contingency ## translation pending + ENDIF + +; Decoplanner progress indication + TCODE tNoBottomGas1, "Nessun Gas utile per" ; no usable Gas for Bottom Depth found (line 1, max. 22 chars) + TCODE tNoBottomGas2, "la quota di fondale!" ; no usable Gas for Bottom Depth found (line 2, max. 22 chars) TCODE tCalculating, "Calcolando..." ; calculating... - TCODE tCalcSurfInter, "Surface Interval" ; Surface Interval ## pending translation - TCODE tCalcBotSeg, "Bottom Segment" ; Bottom Segment ## pending translation - TCODE tCalcBailout, "Switch to Bailout" ; Switch to Bailout ## pending translation - TCODE tCalcAscent, "Ascent" ; Ascent ## pending translation - TCODE tNDLleft, "left" ; time left within NDL ## pending translation + TCODE tCalcSurfInter, "Int. Superficie" ; Surface Interval + TCODE tCalcBotSeg, "Tempo di fondo" ; Bottom Segment + TCODE tCalcBailout, "Cambia a Bailout" ; Switch to Bailout + TCODE tCalcAscent, "Risalita" ; Ascent (max 8 chars) + TCODE tNDLleft, "NDL" ; time left within NDL ("Rimasto") ; Information menu TCODE tFirmware, "Firmware: " ; Firmware: (space) + TCODE tHardware, "Hardware: " ; Hardware: (space) TCODE tSerial, "Seriale : " ; Serial : (space) TCODE tTotalDives, "Tot Immersioni:" ; Total Dives: TCODE tBatteryV, "Batteria: " ; Battery: @@ -356,6 +370,7 @@ ; Divemode screen TCODE tNDL, "NDL" ; 3 chars max TCODE tTTS, "TTS" ; 3 chars max + TCODE tSlow, "piano " ; slow - max 7 chars TCODE tVelMetric, "m/min" TCODE tVelImperial, "ft/m " TCODE tGasSelect, "Selez. Gas" ; Select Gas @@ -366,7 +381,7 @@ TCODE tDepth, "Prof." ; Depth (max 5 chars) TCODE tMaxDepth, "Prof.Max" ; Max. Depth - max 9 chars! TCODE tAvgDepth, "Prof.Med." ; average Depth - max 9 chars! - TCODE tTissuePresSat, "Pres+Sat" ; 0 pressure and saturation | ENUM group ## pending translation + TCODE tTissuePresSat, "Pres+Sat" ; 0 pressure and saturation | ENUM group IFDEF _helium TCODE tTissueN2He, "N2+He" ; 1 N2 + He pressure | ENDIF @@ -377,8 +392,8 @@ TCODE tApnoeTotal, "Totale" ; Total (six chars, right aligned) TCODE tApnoeMax, "Ultima Discesa" ; Last descend TCODE tApnoeSurface, "Tp.Superficie" ; Surface Time - TCODE tTime, "Time" ; Time ## pending translation - TCODE tSurface, "Surface" ; Surface (max 12 chars) ## pending translation + TCODE tTime, "Time" ; Time ("Tempo") + TCODE tSurface, "Superficie" ; Surface (max 12 chars) TCODE tDiveDecoplan, "Piano Deco" ; Decoplan ; TCODE tDiveClock, "Orologio" ; Clock TCODE tDiveEAD_END, "EAD/END" ; EAD/END @@ -388,16 +403,15 @@ TCODE tDiveBailout, "Bailout" ; Bailout (max. 7 chars) TCODE tGFactors, "Valori GF" ; GF Values TCODE taGFactors, "Valori aGF" ; aGF Values - TCODE tGFInfo, "Saturation" ; Saturation ## pending translation + TCODE tGFInfo, "Saturazione" ; Saturation TCODE tCeiling, "Tetto" ; Ceiling - TCODE tDiveSafetyStop, "Stop" ; Stop (four chars, right aligned) TCODE tDiveFallback, "Fallback!" ; Fallback! (max. nine chars) - TCODE tDecoInfo, "Zona Deco" ; Deco info + TCODE tDecoInfo, "Zona Deco" ; Deco info ("Curva Deco") TCODE tSensorCheck, "Testa Sensori" ; Sensor Check TCODE tdil, "Dil:" ; Diluent ppO2 Warning TCODE tmix, "Mix:" ; Pre-Mix ppO2 Warning TCODE tGasNeedsWarn, "Gas Neces" ; - TCODE tGasNeedsAscent, "Gas Necess. Ascent" ; ## pending translation + TCODE tGasNeedsAscent, "Pres.Gas x Risalita" ; TCODE tCNSsurf, "CNS Surf." ; TCODE tCNSfTTS, "CNS fTTS" ; TCODE tCNSBO, "CNS B/O" ; @@ -406,20 +420,21 @@ TCODE tnoBOgas, "-B/O-Gas-" ; TCODE tMicroBubbles, "M.Bolle" ; TCODE tCNS, "CNS: " ; - TCODE tgaschange, "Change?" ; better gas found ## pending translation - TCODE tNeed, "Need " ; gas need (5 chars) ## pending translation + TCODE tgaschange, "Cambio?" ; better gas found + TCODE tNeed, "Neces" ; gas need (5 chars) TCODE tBattery, "Batteria" ; Battery IFDEF _helium TCODE tHe, "He" ; He TCODE tIBCD, "IBCD N2He" ; IBCD warning + TCODE tGasDensity, "G.Density" ; Gas Density ## pending translation ENDIF IFDEF _rx_functions - TCODE tTransmitter, "P.Transm." ; pressure transmitter ## pending translation + TCODE tTransmitter, "Pr.Trasm." ; pressure transmitter TCODE tPressure, "P.Bombola" ; tank pressure - TCODE tSAC, "SAC" ; SAC, must be 3 chars! - TCODE tswap, "Swap Tank" ; swap tank (max. 9 chars ## pending translation + TCODE tSAC, "ICS" ; SAC, must be 3 chars! + TCODE tswap, "CambioGas" ; swap tank (max. 9 chars ENDIF IFDEF _ccr_pscr @@ -432,17 +447,18 @@ ENDIF IFDEF _cave_mode - TCODE tGasNeedsCaveMode, "Gas Necess. Cave Mode" ; title for gas needs custom view - TCODE tDiveTurned, "Dv.turned" ; dive is turned (max. 9 char) ## pending translation + TCODE tGasNeedsCaveMode, "Gas Necess. Mod. Cave" ; title for gas needs custom view + TCODE tDiveTurned, "Dv.turned" ; dive is turned (max. 9 char) TCODE tCaveMode, "Cave Mode" ; cave mode activated (max. 9 char) TCODE tCaveModeShutdown, "X-Cave-X" ; cave mode shut down (max. 9 char) ENDIF ; Divemode menu - TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + TCODE tDivePreMenu, "Menu?" ; Menu? (max. 5 chars) + TCODE tDiveLayout, "Layout" ; Layout (max. 6 chars) IFDEF _compass - TCODE tSetHeading, "Salva" ; Bearing (max. 6 chars) + TCODE tSetHeading, "Salva" ; Course (max. 6 chars) ENDIF @@ -473,7 +489,7 @@ TCODE tReboot, "Riavvio" ; Reboot TCODE tResetMenu2, "Sei sicuro?" ; Are you sure? TCODE tAbort, "Annulla" ; Abort - TCODE tResetSettings, "Azzera Settings" ; Reset all ## pending translation + TCODE tResetSettings, "Azzera Settaggi" ; Reset all TCODE tResetDeco, "Azzera Deco" ; Reset Deco TCODE tResetBattery, "Azzera Batteria" ; Reset Battery TCODE tResetLogbook, "Azzera Logbook" ; Reset Logbook @@ -490,8 +506,8 @@ ; Logbook Offset Menu TCODE tLogOffset, "Devia Logbook" ; Logbook offset - TCODE tLogOffsetValue, "Offset : " ; Offset ## pending translation - TCODE tLogOffStepSize, "Step Size: " ; Step Size ## pending translation + TCODE tLogOffsetValue, "Devio : " ; Offset + TCODE tLogOffStepSize, "Moltiplico:" ; Step Size TCODE tLogOffsetplus, "+" ; increment TCODE tLogOffsetminus, "-" ; decrement TCODE tLogOffStep1, " 1" ; adjustment step size 1 | ENUM group @@ -520,15 +536,6 @@ TCODE tColorSetName3, "Blu" ; Blue - ; pSCR Menu and Settings - IFDEF _ccr_pscr - TCODE tPSCRMenu, "Menu pSCR" ; pSCR Menu - TCODE tPSCR_O2_drop, "O2 Drop " ; O2 drop - TCODE tPSCR_lungratio, "Lung Ratio " ; lung ratio - TCODE tBackToLoop, "goto loop" ; back to loop (10 chars max) - ENDIF - - ; Language selection IF _language_2!=none TCODE tLanguage, "Lingua: " ; used in menu_tree @@ -566,4 +573,4 @@ ENDIF ENDIF ENDIF - ENDIF + ENDIF \ No newline at end of file
--- a/src/tft.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/tft.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File tft.asm combined next generation V3.03.2 +; File tft.asm combined next generation V3.03.7 ; ; low-level Display Outputs ; @@ -73,8 +73,10 @@ global TFT_ClearScreen TFT_ClearScreen: - btfsc screen_type2 ; screen type ? + btfsc screen_type2 ; screen type 2? bra TFT_ClearScreen_display2; YES + btfsc screen_type3 ; screen type 3? + bra TFT_ClearScreen_display3; YES Index_out 0x50 ; window horizontal start address Parameter_out 0x00, 0x00 ; 0-239 @@ -158,9 +160,9 @@ movlw 0x22 ; start writing data to GRAM rcall TFT_CmdWrite + movlw .160 ; 160 x 240 x 6 = 230400 ticks +TFT_ClearScreen_display2_loop0: bsf tft_rs ; data! - - movlw .160 movwf PRODH clrf PORTH TFT_ClearScreen_display2_loop1: @@ -185,10 +187,48 @@ bra TFT_ClearScreen_display2_loop1 return +TFT_ClearScreen_display3: + movlw 0x35 ; vertical start address HIGH:LOW + rcall TFT_CmdWrite + mullw 0 + rcall TFT_DataWrite_PROD + + movlw 0x36 ; vertical end address HIGH:LOW + rcall TFT_CmdWrite + movlw 0x01 + rcall TFT_DataWrite + movlw 0x3F + rcall TFT_DataWrite + + movlw 0x37 ; horizontal address START:END + rcall TFT_CmdWrite + movlw 0x00 + rcall TFT_DataWrite + movlw 0xEF + rcall TFT_DataWrite + + movlw 0x20 ; start address horizontal (.0 - .239) + rcall TFT_CmdWrite + rcall TFT_DataWrite_PROD + + movlw 0x21 ; start address vertical (.0 - .319) + rcall TFT_CmdWrite + rcall TFT_DataWrite_PROD + + movlw 0x22 ; start writing data to GRAM + rcall TFT_CmdWrite + + movlw .107 ; 107 x 240 x 6 = 154080 ticks (153600 would be enough) + bra TFT_ClearScreen_display2_loop0 + + ;============================================================================= global TFT_DisplayOff TFT_DisplayOff: + bcf lightsen_power ; power-down light sensor + btfsc screen_type3 + bra TFT_DisplayOff_display3 ; screen needs special power-down sequence clrf CCP1CON ; stop PWM bcf PORTC,2 ; pull PWM out to GND clrf PORTA @@ -199,7 +239,32 @@ bcf tft_cs bcf tft_nreset bsf tft_power ; inverted... - bcf lightsen_power ; power-down light sensor + return + +TFT_DisplayOff_display3: + movlw 0x05 + rcall TFT_CmdWrite + movlw 0x00 + rcall TFT_DataWrite + movlw 0x00 + rcall TFT_DataWrite + WAITMS d'32' + clrf CCP1CON ; stop PWM + bcf PORTC,2 ; pull PWM out to GND + WAITMS d'32' + movlw 0x10 + rcall TFT_CmdWrite + movlw 0x00 + rcall TFT_DataWrite + movlw 0x01 + rcall TFT_DataWrite + WAITMS d'100' + clrf PORTH + bcf tft_nwr + bcf tft_cs + bcf tft_nreset + WAITMS d'10' + bsf tft_power ; inverted... return ; ----------------------------- @@ -214,20 +279,19 @@ clrf PORTA clrf PORTH + RD_L ; LOW - bcf tft_nwr nop - bcf tft_cs + WR_L + nop + NCS_L ; Not CS nop bcf tft_nreset WAITMS d'1' bcf tft_power ; inverted... WAITMS d'1' - RD_H ; Keep high - WR_H ; - NCS_L ; Not CS - + nop WAITMS d'2' bsf tft_nreset WAITMS d'5' @@ -235,8 +299,12 @@ WAITMS d'5' bsf tft_nreset WAITMS d'150' + WR_H ; release bus bsf lightsen_power ; supply power to light sensor + btfsc screen_type3 ; display type 3 ? + bra TFT_boot_screen3 ; YES + ; Data Transfer Synchronization Parameter_out 0x00, 0x00 Parameter_out 0x00, 0x00 @@ -264,7 +332,7 @@ movwf TBLPTRH movlw 0x01 movwf TBLPTRU - bsf screen_type + bsf screen_type1 bra TFT_boot_com TFT_boot_0: @@ -275,7 +343,7 @@ movwf TBLPTRH movlw UPPER display0_config_table movwf TBLPTRU - bcf screen_type + bcf screen_type1 TFT_boot_com: rcall display0_init_loop @@ -284,7 +352,7 @@ btfsc flip_screen ; 180 rotation ? bra TFT_boot2 ; YES - btfss screen_type ; display1? + btfss screen_type1 ; display1? bra TFT_boot1a ; NO Parameter_out 0x10, 0x00 ; display1 bra TFT_boot3 @@ -292,7 +360,7 @@ Parameter_out 0x50, 0x20 ; display0 bra TFT_boot3 TFT_boot2: - btfss screen_type ; display1? + btfss screen_type1 ; display1? bra TFT_boot2a ; NO Parameter_out 0x10, 0x30 ; display1 bra TFT_boot3 @@ -351,7 +419,6 @@ TFT_boot_screen2: - bsf tft_nwr ; release bus rcall display1_init ; initialization sequence btfss flip_screen ; 180 rotation? @@ -362,6 +429,22 @@ rcall TFT_DataWrite ; Write configuration bra TFT_ClearScreen ; clear screen and return +TFT_boot_screen3: + rcall display1_init ; init sequence + rcall TFT_ClearScreen + setf CCPR1L ; duty cycle, 255 is required for OLED + ; Set brightness + movff opt_brightness,PRODL ; =0: Eco, =1:Medium, =2:Full + incf PRODL,F ; +1 + dcfsnz PRODL,F + rcall TFT_display3_low + dcfsnz PRODL,F + rcall TFT_display3_med + dcfsnz PRODL,F + rcall TFT_display3_high + ; ToDo: Flip.... + return + display1_init: movlw LOW (0x1F8BC ) movwf TBLPTRL @@ -388,16 +471,21 @@ TBLRD*+ ; get configuration movf TABLAT,W rcall TFT_DataWrite ; write configuration + btfss screen_type3 ; screen 3 ? + bra display1_init_loop ; NO - loop + ; Screen 3 gets another byte from the table + TBLRD*+ ; get configuration + movf TABLAT,W + rcall TFT_DataWrite ; write configuration bra display1_init_loop ; loop - ;============================================================================= global TFT_CmdWrite TFT_CmdWrite: RS_L ; command - btfsc screen_type2 - bra TFT_CmdWrite_screen2 +; btfsc screen_type2 +; bra TFT_CmdWrite_screen2 clrf PORTA ; upper bcf INTCON,GIE movwf PORTH ; lower @@ -405,28 +493,28 @@ WR_H ; tick bsf INTCON,GIE return -TFT_CmdWrite_screen2: - movwf PORTH ; lower - WR_L - WR_H ; tick - return; +;TFT_CmdWrite_screen2: +; movwf PORTH ; lower +; WR_L +; WR_H ; tick +; return; global TFT_DataWrite TFT_DataWrite: RS_H ; data - btfsc screen_type2 - bra TFT_DataWrite_screen2 +; btfsc screen_type2 +; bra TFT_DataWrite_screen2 bcf INTCON,GIE movwf PORTH ; lower WR_L WR_H ; tick bsf INTCON,GIE return -TFT_DataWrite_screen2: - movwf PORTH ; lower - WR_L - WR_H ; tick - return +;TFT_DataWrite_screen2: +; movwf PORTH ; lower +; WR_L +; WR_H ; tick +; return ;============================================================================= @@ -443,6 +531,8 @@ movlw CCP1CON_VALUE ; get configuration movwf CCP1CON ; set configuration bsf tft_is_dimming ; TFT is dimming, ignore ambient sensor + btfsc screen_type3 + bra TFT_Display_FadeIn_1 clrf CCPR1L ; backlight off - to be sure movff max_CCPR1L,PRODL TFT_Display_FadeIn_0: @@ -452,6 +542,9 @@ bra TFT_Display_FadeIn_0 bcf tft_is_dimming ; dimming done return +TFT_Display_FadeIn_1: + setf CCPR1L + return ;============================================================================= ; Smooth lighting-off of the display: @@ -461,15 +554,47 @@ TFT_Display_FadeOut: movff max_CCPR1L,PRODL bsf tft_is_dimming ; TFT is dimming, ignore ambient sensor + btfsc screen_type3 + bra TFT_Display_FadeOut_1 TFT_Display_FadeOut_0: movff PRODL,CCPR1L ; duty cycle WAITMS d'1' decfsz PRODL,F bra TFT_Display_FadeOut_0 +TFT_Display_FadeOut_1: clrf CCPR1L return ;============================================================================= + ; OLED brightness control +TFT_display3_high: ; 0x01F8F8 + movlw LOW (0x01F8F8 ) + movwf TBLPTRL + movlw HIGH (0x01F8F8 & 0xFFFF) + movwf TBLPTRH + movlw UPPER (0x01F8F8 ) + movwf TBLPTRU + bra display1_init_loop ; and return + +TFT_display3_med: ; 0x01F91C + movlw LOW (0x01F91C ) + movwf TBLPTRL + movlw HIGH (0x01F91C & 0xFFFF) + movwf TBLPTRH + movlw UPPER (0x01F91C ) + movwf TBLPTRU + bra display1_init_loop ; and return + +TFT_display3_low: ; 0x01F8D4 + movlw LOW (0x01F8D4 ) + movwf TBLPTRL + movlw HIGH (0x01F8D4 & 0xFFFF) + movwf TBLPTRH + movlw UPPER (0x01F8D4 ) + movwf TBLPTRU + bra display1_init_loop ; and return + +;============================================================================= global box_std_block, box_black_block, box_color_block @@ -535,20 +660,23 @@ mullw .2 ; win_leftx2 x 2 -> PRODH:PRODL rcall pixel_write_col320 ; start address vertical (.0 - .319) rcall half_pixel_write ; write this half-one + movf win_leftx2,W ; address of next one mullw .2 ; win_leftx2 x 2 -> PRODH:PRODL INCI PROD ; PROD++ rcall pixel_write_col320 - bra half_pixel_write ; note: Cmd 0x20 is mandatory, because + bra half_pixel_write ; and return... note: cmd 0x20 is mandatory, because ; of the auto-increment going vertical global pixel_write_col320 pixel_write_col320: - btfsc screen_type2 ; display type 2 ? - bra pixel_write_col320_d2 ; YES - btfsc screen_type ; NO - display type 1 ? - bra pixel_write_col320_d1 ; YES - ; NO - display type 0 + btfsc screen_type2 ; display type 2 ? + bra pixel_write_col320_d2 ; YES + btfsc screen_type1 ; display type 1 ? + bra pixel_write_col320_d1 ; YES + btfsc screen_type3 ; display type 3 ? + bra pixel_write_col320_d3 ; YES + ; NO to all - display type 0 btfss flip_screen ; 180 rotation? bra pixel_write_noflip_H ; NO bra pixel_write_flip_H ; YES @@ -592,6 +720,11 @@ movf PRODL,W bra TFT_DataWrite ; ... and return +pixel_write_col320_d3: + movlw 0x21 ; start address vertical (.0 - .319) + rcall TFT_CmdWrite + bra TFT_DataWrite_PROD ; and return... + ;----------------------------------------------------------------------------- ; Writes one half-pixel at position (win_top,win_leftx2). ; Inputs: win_leftx2, win_top, win_color:2 @@ -599,12 +732,15 @@ global half_pixel_write half_pixel_write: - movf win_top,W ; d'0' ... d'239' - ; Variant with Y position in WREG. + movf win_top,W ; d'0' ... d'239' + ; Variant with Y position in WREG half_pixel_write_1: - btfsc screen_type2 ; screen tpe 2 ? - bra half_pixel_write_1_display1 ; YES + btfsc screen_type2 ; display type 2 ? + bra half_pixel_write_1_display2 ; YES + btfsc screen_type3 ; display type 3 ? + bra half_pixel_write_1_display3 ; YES +half_pixel_write_1_display1: btfss flip_screen ; 180 rotation? sublw .239 ; 239-Y --> Y mullw .1 ; copy row to PRODL (PRODH=0) @@ -621,7 +757,7 @@ bsf INTCON,GIE return -half_pixel_write_1_display1: +half_pixel_write_1_display2: mullw 1 ; copy row to PRODL (PRODH=0) ; Row address start movlw 0x02 @@ -662,6 +798,24 @@ WR_H ; tick return +half_pixel_write_1_display3: + mullw 1 ; copy row to PRODL (PRODH=0) + + movlw 0x20 ; horizontal address START:END + rcall TFT_CmdWrite + rcall TFT_DataWrite_PROD + + movlw 0x22 ; start writing data to GRAM + rcall TFT_CmdWrite + RS_H ; data + movff win_color1, PORTH + WR_L + WR_H ; tick + movff win_color2, PORTH + WR_L + WR_H ; tick + return ; done + ;----------------------------------------------------------------------------- ; Writes a vertical line of half-pixel at position (win_top,win_leftx2,win_height). ; Inputs: win_leftx2, win_top, win_height, win_color:2 @@ -722,6 +876,8 @@ RS_H ; data btfsc screen_type2 ; screen type 2 ? bra TFT_DataWrite_PROD_display2 ; YES + btfsc screen_type3 ; screen type 3 ? + bra TFT_DataWrite_PROD_display2 ; YES bcf INTCON,GIE ; NO - movff PRODH,PORTA ; - move high byte to PORTA movff PRODL,PORTH ; - move low byte to PORTH @@ -737,10 +893,12 @@ movff PRODL,PORTH ; move low byte to PORTH WR_L ; tick WR_H ; tack - movff win_color3,PORTH ; move low(est) byte to PORTH - WR_L ; tick - WR_H ; tack - return ; done + btfsc screen_type3 ; screen type 3 ? + return ; YES - done + movff win_color3,PORTH ; NO - move low(est) byte to PORTH + WR_L ; - tick + WR_H ; - tack + return ; - done TFT_DataRead_PROD: @@ -783,18 +941,20 @@ btfsc screen_type2 ; screen type 2 ? bra TFT_box_write_display2 ; YES + btfsc screen_type3 ; screen type 3 ? + bra TFT_box_write_display3 ; YES global TFT_box_write_16bit_win_left TFT_box_write_16bit_win_left: ; with column in PRODL:PRODH - btfsc screen_type ; screen type 1 ? + btfsc screen_type1 ; screen type 1 ? bra TFT_box_write_16bit_win_left_d1 ; YES ; screen type 0 btfsc flip_screen ; 180 rotation? - bra DISP_box_flip_H ; YES + bra TFT_box_flip_H ; YES bra TFT_box_write_16bit_win_left_com ; NO TFT_box_write_16bit_win_left_d1: ; Display1 btfss flip_screen ; 180 rotation? - bra DISP_box_flip_H ; NO + bra TFT_box_flip_H ; NO TFT_box_write_16bit_win_left_com: ; YES for screen type 1, NO for type 0 ;---- Normal horizontal window --------------------------------------- Index_out 0x52 ; window vertical start address @@ -812,10 +972,10 @@ Index_out 0x53 ; window vertical end address rcall TFT_DataWrite_PROD - bra DISP_box_noflip_H + bra TFT_box_noflip_H ;---- Flipped horizontal window -------------------------------------- -DISP_box_flip_H: +TFT_box_flip_H: ; calculate new coordinate movf PRODL,W ; 16 bits 319 - PROD --> PROD sublw LOW .319 ; 319 - WREG --> WREG @@ -841,7 +1001,7 @@ Index_out 0x52 ; window vertical end address rcall TFT_DataWrite_PROD -DISP_box_noflip_H: +TFT_box_noflip_H: btfss flip_screen ; 180 rotation ? bra TFT_box_noflip_V ; NO @@ -943,6 +1103,44 @@ movf PRODL,W bra TFT_DataWrite ; ... and return +TFT_box_write_display3: + ;---- Normal horizontal window --------------------------------------- + ; Output 0x35 left, + ; 0x36 right == left + width - 1. + + Index_out 0x35 ; window vertical start address + rcall TFT_DataWrite_PROD ; output left + Index_out 0x21 ; also the horizontal first pix coordinate + rcall TFT_DataWrite_PROD ; output left + + movf win_width+0,W,ACCESS ; right = left + width - 1 + addwf PRODL,F + movf win_width+1,W,ACCESS + addwfc PRODH,F + decf PRODL,F,A ; decrement result + btfss STATUS,C + decf PRODH,F,A + + Index_out 0x36 ; Write and the right border + rcall TFT_DataWrite_PROD + + ;---- Normal vertical window ----------------------------------------- + ; Output 0x37 (top) (bottom) + movff win_top,PRODH ; top --> PRODH (first byte) + movff win_height,WREG + addwf PRODH,W + decf WREG + movwf PRODL ; top + height - 1 --> PRODL (second byte) + + Index_out 0x37 + rcall TFT_DataWrite_PROD + + movff PRODH,PRODL + clrf PRODH ; start pixel V coord == top. + Index_out 0x20 + bra TFT_DataWrite_PROD ; and return... + + ;============================================================================= ; TFT_frame : draw a frame around current box with current color ; Inputs: win_top, win_leftx2, win_height, win_width, win_color1, win_color2 @@ -997,27 +1195,26 @@ global TFT_box TFT_box: - btfsc screen_type2 ; display type 2 ? - bra TFT_box_display2 ; YES - ;---- Define Window ------------------------------------------------------ bcf STATUS,C rlcf win_width+0,F rlcf win_width+1,F ; x2 rcall TFT_box_write ; setup box - global TFT_box_16bit_win_left -TFT_box_16bit_win_left: bcf STATUS,C rrcf win_width+1,F ; width /= 2 rrcf win_width+0,F ;---- Fill Window -------------------------------------------------------- Index_out 0x22 ; frame memory data write start - clrf PRODH ; column counter RS_H ; data + btfsc screen_type2 ; display type 2 ? + bra TFT_box_display2 ; YES + btfsc screen_type3 ; display type 3 ? + bra TFT_box_display3 ; YES + TFT_box2: ; loop height times movff win_height,PRODL @@ -1027,9 +1224,6 @@ movff win_color2,PORTH ; lower WR_L WR_H ; tick - -; movff win_color1,PORTA ; upper -; movff win_color2,PORTH ; lower WR_L WR_H ; tick bsf INTCON,GIE @@ -1037,16 +1231,15 @@ bra TFT_box3 ; NO - continue incf PRODH,F ; column count ++ - - movf win_bargraph,W ; current column == bargraph ? - cpfseq PRODH + movf win_bargraph,W ; get width of active bargraph part + cpfseq PRODH ; current column == end of active bargraph ? bra TFT_box4 ; NO - just loop - clrf win_color1 ; Yes - switch to black + clrf win_color1 ; YES - switch to black clrf win_color2 ; - ... TFT_box4: - movf win_width+0,W ; compare ? - xorwf PRODH,W - bnz TFT_box2 ; loop not finished + movf win_width+0,W ; get total bargraph width + xorwf PRODH,W ; all columns done? + bnz TFT_box2 ; NO - loop movlw 0x00 ; NOP, to stop window mode rcall TFT_CmdWrite @@ -1056,25 +1249,10 @@ return TFT_box_display2: - ;---- Define Window ------------------------------------------------------ - bcf STATUS,C - rlcf win_width+0,F - rlcf win_width+1,F ; x2 - rcall TFT_box_write ; setup box - - bcf STATUS,C - rrcf win_width+1,F ; width /= 2 - rrcf win_width+0,F - + ; Screen 2 movff win_color1,PRODH movff win_color2,PRODL rcall convert_for_display2 - ;---- Fill Window -------------------------------------------------------- - Index_out 0x22 ; frame memory data write start - - clrf PRODH ; column counter - RS_H ; data - TFT_box2_display2: ; loop height times movff win_height,PRODL TFT_box3_display2: ; loop width times @@ -1113,6 +1291,38 @@ setf win_bargraph ; YES - reset bargraph mode return ; - done +TFT_box_display3: + ; Screen 3 +TFT_box2_display3: ; loop height times + movff win_height,PRODL +TFT_box3_display3: ; loop width times + movff win_color1,PORTH + bcf tft_nwr + bsf tft_nwr ; upper + movff win_color2,PORTH + bcf tft_nwr + bsf tft_nwr ; high + movff win_color1,PORTH + bcf tft_nwr + bsf tft_nwr ; low + movff win_color2,PORTH + bcf tft_nwr + bsf tft_nwr ; upper + decfsz PRODL,F ; row loop finished? + bra TFT_box3_display3 ; NO - loop + incf PRODH,F ; YES - column count ++ + movf win_bargraph,W ; - get bargraph width + cpfseq PRODH ; - current column = bargraph ? + bra TFT_box4_display3 ; NO + clrf win_color1 ; Yes - switch to black + clrf win_color2 ; - ... +TFT_box4_display3: + movf win_width+0,W ; get width + cpfseq PRODH ; width loop finished ? + bra TFT_box2_display3 ; NO - loop + setf win_bargraph ; YES - reset bargraph mode + return + ;============================================================================= ; Convert 8 bit RGB b'RRRGGGBB' into 16 bit RGB b'RRRRRGGGGGGBBBBB' @@ -1264,6 +1474,7 @@ global TFT_dump_screen_check global TFT_dump_screen TFT_dump_screen_check: + return btfss vusb_in ; USB (still) plugged in? bcf screen_dump_avail ; NO - disable screen dump function call rs232_get_byte ; try to read data from RS232
--- a/src/tft.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/tft.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File tft.inc combined next generation V3.03.2 +; File tft.inc combined next generation V3.03.7 ; ; Declaring interfaces to the TFT screen and its Oxxx controler ; @@ -51,7 +51,6 @@ extern TFT_box_write extern TFT_box_write_16bit_win_left ; with column in PRODL:PRODH extern TFT_box - extern TFT_box_16bit_win_left ; with column in PRODL:PRODH extern TFT_DataWrite_PROD extern TFT_set_color ; extern init_pixel_write
--- a/src/tft_outputs.asm Sun Jun 30 23:22:32 2019 +0200 +++ b/src/tft_outputs.asm Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File tft_outputs.asm next combined generation V3.03.4 +; File tft_outputs.asm next combined generation V3.04.3 ; ; high-level Display Outputs ; @@ -40,6 +40,7 @@ ;---- external Texts --------------------------------------------------------- extern tFirmware + extern tHardware extern tSerial extern tTotalDives extern tBatteryV @@ -225,7 +226,7 @@ global TFT_color_code_gaslist -TFT_color_code_gaslist: ; color-code current row in gaslist (%O2 in hi) according to current absolute pressure +TFT_color_code_gaslist: ; color-code a gas (%O2 in hi) according to current absolute pressure ; Check very high ppO2 manually MOVII pressure_abs_10,xA movff hi,xB+0 @@ -247,14 +248,14 @@ bra TFT_warning_color ; YES - set warning color and return ; Check for high ppO2 movff char_O_deco_info,WREG ; bank-safe copy of deco info vector - btfsc WREG,deco_flag ; are we in deco? + btfsc WREG,deco_mode ; are we in deco? bra TFT_color_code_gaslist_deco ; YES - check against ppO2 max deco only ; NO - check against ppO2 max travel/normal and deco ; Check for ppO2 max travel/normal movff char_I_ppO2_max_work,WREG ; ppo2 max during working phase mullw d'100' ; char_I_ppO2_max_work*100 - MOVII PRODL,sub_b - INCI sub_b ; add 1 mbar to avoid warning on equal + ADDLI ppO2_margin_on_max,PROD ; add ppO2 margin on max value to compensate for surface pressures > 1000 hPa + MOVII PRODL,sub_b ; copy result to sub_b call cmpU16 ; compare (sub_a - sub_b) btfss neg_flag ; higher than ppO2 max travel/deco? rcall TFT_attention_color ; YES - set attention color @@ -262,8 +263,8 @@ TFT_color_code_gaslist_deco: movff char_I_ppO2_max_deco,WREG ; ppo2 max for deco mullw d'100' ; char_I_ppO2_max_deco * 100 - MOVII PRODL,sub_b ; copy product to sub_b - INCI sub_b ; add 1 mbar to avoid warning on equal + ADDLI ppO2_margin_on_max,PROD ; add ppO2 margin on max value to compensate for surface pressures > 1000 hPa + MOVII PRODL,sub_b ; copy result to sub_b call cmpU16 ; compare (sub_a - sub_b) btfss neg_flag ; higher than ppO2 max deco? bra TFT_warning_color ; YES - set warning color and return @@ -294,7 +295,7 @@ movff char_O_deco_gas+0,WREG ; get flag for invalid deco data btfsc WREG,char_invalid_flag ; is the invalid flag set? bra TFT_disabled_color ; YES - set to disabled color and return - movff char_O_deco_depth,WREG ; NO - get depth of first stop in meters into WREG + movff char_O_deco_depth+0,WREG ; NO - get depth of first stop in meters into WREG subwf depth_meter,W ; - compute current depth - stop depth btfsc STATUS,C ; - result negative? bra TFT_color_code_stop_1 ; NO - not shallower than stop depth, check for ascent advice @@ -307,15 +308,14 @@ bra TFT_warning_color ; YES - set to warning color and return bra TFT_attention_color ; NO - set to attention color and return TFT_color_code_stop_1: - movff char_O_deco_info,WREG ; get deco info vector - btfss WREG,deco_flag ; in deco mode? - bra TFT_memo_color ; NO - set to memo color and return - movff char_O_deco_depth,WREG ; YES - get depth of first stop in meters into WREG - incf WREG,W ; - compute stop depth + 1 meter - subwf depth_meter,W ; - compute current depth - (stop depth + 1 meter) - btfss STATUS,C ; - result negative? - bra TFT_memo_color ; YES - within 1 meter of stop depth - bsf win_invert ; NO - deeper that 1 meter below stop depth, give ascent advice + movff char_O_deco_depth+0,WREG ; get depth of first stop in meters into WREG + incf WREG,W ; compute stop depth + 1 meter + subwf depth_meter,W ; compute current depth - (first stop depth + 1 meter) + btfss STATUS,C ; result negative? + bra TFT_memo_color ; YES - within 1 meter of stop depth, use memo color + btfss deco_region ; NO - within deco stops region? + bra TFT_memo_color ; NO - use memo color + bsf win_invert ; YES - give ascent advice, ... bra TFT_advice_color ; - ... and return @@ -366,7 +366,7 @@ bcf hi,int_warning_flag ; clear warning flag (it may be set) bcf hi,int_attention_flag ; clear attention flag (it may be set) bra TFT_disabled_color ; set to disabled color and return -TFT_color_code_cns_1 +TFT_color_code_cns_1: btfss hi,int_warning_flag ; is the warning flag set? bra TFT_color_code_cns_2 ; NO bcf hi,int_warning_flag ; YES - clear warning flag @@ -417,7 +417,7 @@ TFT_color_code_ppo2_hud: ; color-code ppO2 values (ppO2 in --:lo [cbar]) by its value movff char_O_deco_info,WREG ; get the deco info vector - btfss WREG,deco_flag ; are we in deco? + btfss WREG,deco_mode ; are we in deco? bra TFT_color_code_ppo2_hud_a ; NO - load normal max value as threshold movff char_I_ppO2_max_deco,WREG ; YES - load deco value as threshold bra TFT_color_code_ppo2_hud_b @@ -447,8 +447,10 @@ ;============================================================================= TFT_color_code_battery: ; color-code the battery display, with battery percent in lo - movlw color_code_battery_low ; get warning threshold - cpfsgt lo ; is battery percent < threshold? + movlw battery_warn_level_36+1 ; get threshold for 3.6 Volt battery warning, incremented by 1 + btfss battery_is_36v ; actually a 3.6 Volt battery detected? + movlw battery_warn_level_15+1 ; NO - replace with 1.5 Volt battery warning, incremented by 1 + cpfsgt batt_percent ; is battery percent < threshold? bra TFT_warning_color ; YES - set to warning color and return bra TFT_memo_color ; NO - set to memo color and return @@ -967,7 +969,17 @@ ; - set position WIN_STD dm_ndl_text_column, dm_ndl_text_row STRCPY_TEXT_PRINT tNDL ; - print "NDL" - bra TFT_standard_color ; - done + btfss deco_region ; - was the dive within deco stops region? + bra TFT_standard_color ; NO - done + btfsc safety_stop_active ; YES - safety stop shown? + bra TFT_standard_color ; YES - done +TFT_show_slow_reminder: + call TFT_attention_color ; NO - set color + ; - set position + WIN_STD dm_safetystop_text_column+.5,dm_safetystop_text_row+.5 + STRCPY_TEXT tSlow ; - print "SLOW" reminder + STRCAT_PRINT 0x94 ; - append an up-arrow + bra TFT_standard_color ; - done global TFT_show_tts @@ -1025,16 +1037,20 @@ btfsc dive_main_menu ; is the dive mode menu shown? return ; YES - abort movff char_O_NDL_norm,lo ; NO - get NDL time in normal plan - btfsc alt_layout_active ; - alternative layout active? - bra TFT_show_ndl_alt ; YES - use alternative layout - ;bra TFT_show_ndl_norm ; NO - use normal layout + btfsc deco_locked ; - was the dive in deco? + bra TFT_show_ndl_norm ; YES - use normal layout + btfsc alt_layout_active ; NO - alternative layout active? + bra TFT_show_ndl_alt ; YES - use alternative layout + ;bra TFT_show_ndl_norm ; NO - use normal layout TFT_show_ndl_norm: ; set position WIN_MEDIUM dm_ndl_value_col_norm,dm_ndl_value_row_norm call TFT_memo_color ; set color output_8 ; display 0...240 +TFT_show_ndl_exit_1: STRCAT_PRINT "'" ; print minutes symbol - bra TFT_standard_color ; done +TFT_show_ndl_exit_2: + goto TFT_standard_color ; done TFT_show_ndl_alt: btfsc safety_stop_active ; is the safety stop active? @@ -1045,15 +1061,14 @@ call TFT_memo_color ; set color output_99 ; display 0...99 STRCAT_PRINT "" ; finalize output - bra TFT_standard_color ; done + bra TFT_show_ndl_exit_2 ; done TFT_show_ndl_alt_safety: WIN_MEDIUM dm_ndl_value_col_norm,dm_ndl_value_row_norm call TFT_memo_color ; set color PUTC " " ; fill first digit position output_99 ; display 0...99 - STRCAT_PRINT "'" ; print minutes symbol - goto TFT_standard_color ; done + bra TFT_show_ndl_exit_1 ; print minutes symbol and done global TFT_divemode_sign_show @@ -1212,13 +1227,7 @@ TFT_display_deco_common: movff char_O_deco_time,lo ; get stop time of the first stop in minutes - tstfsz lo ; stop time = 0 ? - bra TFT_display_deco_1 ; NO - print minutes - STRCAT_PRINT " .." ; YES - special treatment - bra TFT_display_deco_2 ; - continue with common part -TFT_display_deco_1: - output_99 ; print minutes -TFT_display_deco_2: + output_99DD ; print minutes or double dots if null STRCAT_PRINT "'" ; add minutes sign bcf win_invert ; back to non-inverted output TFT_display_exit_1: @@ -1285,7 +1294,7 @@ PUTC " " ; put a space char between depth and time movlw NUM_STOPS ; offset between arrays holding depths and durations movff PLUSW0,lo ; get duration of the current stop - output_99 ; output duration to POSTINC2 + output_99dd ; print duration, prints double dots if duration is zero STRCAT_PRINT "'" ; append symbol for minutes and print to screen bsf ex,1 ; flag that a stop was shown return @@ -1300,7 +1309,9 @@ ; YES - clear safety stop area WIN_BOX_BLACK dm_safetystop_row, dm_safetystop_bot, dm_safetystop_text_column, dm_safetystop_rgt ; top, bottom, left, right bcf safety_stop_active ; - safety stop not shown any more - return ; - done + btfsc deco_region ; - was the dive within deco stops region? + bra TFT_show_slow_reminder ; YES - show "SLOW" reminder + return ; NO - done global TFT_safety_stop_show @@ -1312,10 +1323,10 @@ ; NO - clear area that may be polluted by alternative NDL WIN_BOX_BLACK dm_safetystop_row, dm_tts_value_row, dm_ndl_value_col_alt, dm_safetystop_rgt ; top, bottom, left, right call TFT_divemask_color ; - set color for text + bsf safety_stop_active ; - flag safety stop is shown now ; - set position for text - bsf safety_stop_active ; - flag safety stop is shown now WIN_STD dm_safetystop_text_column, dm_safetystop_text_row - STRCPY_TEXT_PRINT tDiveSafetyStop ; - print "Stop" + STRCPY_PRINT "Stop " ; - print "Stop" with a trailing space to wipe away potential other remains TFT_safety_stop_show_time: call TFT_attention_color ; set color for time ; set position for time @@ -1342,12 +1353,21 @@ IFNDEF _min_depth_option WIN_TINY dm_custom_avr_stop_column1+.2,dm_custom_avr_stop_title_row - TSTOSS opt_2ndDepthDisp ; draw avg depth instead of max depth in main screen? + TSTOSS opt_2ndDepthDisp ; show avg depth instead of max depth in main screen? bra TFT_avr_stopwatch_mask_1 ; NO - draw avg depth in custom view then - STRCPY_TEXT_PRINT tMaxDepth ; YES - draw max depth in custom view then - bra TFT_avr_stopwatch_mask_2 + btfss alt_layout_active ; YES - in alternative layout? + bra TFT_avr_stopwatch_mask_max ; NO - show max depth + ;bra TFT_avr_stopwatch_mask_avg ; YES - show avg depth +TFT_avr_stopwatch_mask_avg: + STRCPY_TEXT_PRINT tDiveTotalAvg ; mask for average depth + bra TFT_avr_stopwatch_mask_2 ; continue TFT_avr_stopwatch_mask_1: - STRCPY_TEXT_PRINT tDiveTotalAvg + btfss alt_layout_active ; YES - in alternative layout? + bra TFT_avr_stopwatch_mask_avg ; NO - show avg depth + ;bra TFT_avr_stopwatch_mask_max ; YES - show max depth +TFT_avr_stopwatch_mask_max: + STRCPY_TEXT_PRINT tMaxDepth ; mask for maximum depth + ;bra TFT_avr_stopwatch_mask_2 ; continue TFT_avr_stopwatch_mask_2: WIN_TINY dm_custom_avr_stop_column2+.3,dm_custom_avr_stop_title_row STRCPY_TEXT_PRINT tDiveStopwatch @@ -1377,13 +1397,23 @@ ; total average depth or max depth WIN_MEDIUM dm_custom_avr_stop_column1,dm_custom_avr_stop_row - TSTOSS opt_2ndDepthDisp ; draw average depth instead of maximum depth in main screen? - bra TFT_avr_stopwatch_01 ; NO - draw average depth in custom view then - MOVII pressure_rel_max_cached,mpr ; YES - draw maximum depth in custom view then - bra TFT_avr_stopwatch_02 -TFT_avr_stopwatch_01: + TSTOSS opt_2ndDepthDisp ; show average depth instead of maximum depth in main screen? + + bra TFT_avr_stopwatch_1 ; NO - draw avg depth in custom view then + btfss alt_layout_active ; YES - in alternative layout? + bra TFT_avr_stopwatch_max ; NO - show max depth + ;bra TFT_avr_stopwatch_avg ; YES - show avg depth +TFT_avr_stopwatch_avg: MOVII pressure_rel_avg_total,mpr ; get total dive average depth into hi:lo -TFT_avr_stopwatch_02: + bra TFT_avr_stopwatch_2 ; continue +TFT_avr_stopwatch_1: + btfss alt_layout_active ; YES - in alternative layout? + bra TFT_avr_stopwatch_avg ; NO - show avg depth + ;bra TFT_avr_stopwatch_max ; YES - show max depth +TFT_avr_stopwatch_max: + MOVII pressure_rel_max_cached,mpr ; get maximum depth into hi:lo + ;bra TFT_avr_stopwatch_2 ; continue +TFT_avr_stopwatch_2: call adjust_depth_with_salinity ; compute salinity setting into hi:lo [mbar] TSTOSS opt_units ; 0=m, 1=ft bra TFT_update_avr_stopwatch1_metric ; 0 - metric @@ -1462,19 +1492,22 @@ ; stopped dive time (will also be used by compass custom view) WIN_MEDIUM dm_custom_avr_stop_column2,dm_custom_avr_stop_row TFT_update_stopwatch: ; jump-in point for stopped dive time in compass custom view - bsf leftbind ; print numbers without leading spaces MOVII divesecs_avg_trip,mpr ; get the resettable dive time (stopwatch) call convert_time ; convert hi:lo in seconds to minutes (up:hi) and seconds (lo) movlw .100 ; display layout will change if minutes become >= 100 cpfslt hi ; minutes < 100 ? bra TFT_update_stopwatch_2 ; NO - display hours:minutes - ;bra TFT_update_stopwatch_1 ; YES - display minutes:seconds + bcf aux_flag ; will print minutes : seconds TFT_update_stopwatch_1: movf hi,W ; exchange lo and hi movff lo,hi ; ... movwf lo ; ... - output_8 ; output minutes or hours - PUTC ':' + bcf leftbind ; include leading spaces + output_99 ; output minutes or hours ( 0 - 99) + movlw ":" ; load standard separator + btfsc aux_flag ; will print hours : minutes ? + movlw "'" ; YES - swap to alternative separator + movwf POSTINC2 ; print separator movff hi,lo ; restore lo output_99x ; output seconds or minutes movlw .5 @@ -1487,6 +1520,7 @@ movff hi,lo ; transfer minutes (low byte) to lo movff up,hi ; transfer minutes (high byte) to hi call convert_time ; convert hi:lo in minutes to hours (up:hi) and minutes (lo) + bsf aux_flag ; will print hours : minutes bra TFT_update_stopwatch_1 @@ -1787,8 +1821,20 @@ SMOVII sensor3_mv,mpr ; in 0.1mV steps STRCAT "3: " rcall TFT_sensor_mV_helper - bcf leftbind + + WIN_SMALL surf_mV_sensor_column,surf_mV_sensor3_row+.24 ; 4th row + btfss s8_digital_avail ; do we have a digital S8 interface? + bra TFT_sensor_mV_optical_analog + STRCAT_PRINT "Digital" + bra TFT_display_exit_3 +TFT_sensor_mV_optical_analog: + btfss ir_power ; do we have a optical digital interface? + bra TFT_sensor_mV_analog + STRCAT_PRINT "Optical" + bra TFT_display_exit_3 +TFT_sensor_mV_analog: ; -> optical + STRCAT_PRINT "Analog" bra TFT_display_exit_3 TFT_sensor_mV_helper: @@ -1861,12 +1907,8 @@ global TFT_time_surfmode TFT_time_surfmode: - IFDEF _ostc_logo - WIN_SMALL surf_clock_column,surf_clock_row - ELSE WIN_SMALL surf_clock_column+.7,surf_clock_row - ENDIF -TFT_clock2: ; called from divemode clock +TFT_clock2: ; called from dive mode clock call TFT_standard_color SMOVSS rtc_year,rtc_latched_year ; ISR-safe 6 byte copy of date and time movff rtc_latched_hour,lo @@ -2213,7 +2255,9 @@ movff opt_ccr_mode,WREG ; get setpoint mode =0: Fixed SP, =1: Sensor, =2: Auto SP sublw .1 ; opt_ccr_mode = 1 (Sensor) ? bnz TFT_active_sp_label_1 ; NO - skip - PUTC "*" ; YES - add "*" + btfsc alt_layout_active ; YES - in alternative layout? + bra TFT_active_sp_label_1 ; YES - no space available for the "*" + PUTC "*" ; NO - add "*" TFT_active_sp_label_1: ENDIF STRCAT_PRINT "" ; finalize output @@ -2802,23 +2846,12 @@ tstfsz WREG ; any indicator or warning active (asked again)? call TFT_set_color ; YES - set color - IFDEF _ostc_logo - WIN_TINY batt_percent_column,batt_percent_row - ELSE WIN_SMALL batt_percent_column+.2,batt_percent_row - ENDIF - output_16_3 ; display only last three digits from a 16 bit value (0-999) STRCAT_PRINT "% " bcf win_invert call TFT_standard_color - - IFDEF _ostc_logo - WIN_TINY batt_voltage_column,batt_voltage_row - ELSE WIN_TINY batt_voltage_column+.15,batt_voltage_row - ENDIF - movff battery_type,lo ; =0: 1.5V, =1: 3.6V Saft, =2: LiIon 3.7V/0.8Ah, =3: LiIon 3.7V/3.1Ah, =4: LiIon 3.7V/2.3Ah PUTC "T" bsf leftbind @@ -3338,7 +3371,7 @@ TFT_cat_beta_4 STRCAT "update!" ; print update cue goto TFT_attention_color ; and return - ENDIF ; _DEBUG + ENDIF ; ELSE / _DEBUG ;----------------------------------------------------------------------------- ; show firmware update message @@ -3385,8 +3418,8 @@ STRCPY "#" call TFT_cat_serial STRCAT " " + STRCAT "v" TFT_show_firmware: - STRCAT "v" call TFT_cat_firmware ; will set win_invert if outdated STRCAT " " call TFT_cat_beta_release @@ -3395,6 +3428,23 @@ goto TFT_standard_color ; ...and return ;----------------------------------------------------------------------------- +; For the Information menu: append total dives + + global info_menu_total_dives +info_menu_total_dives: + lfsr FSR1,tTotalDives + call strcat_text +TFT_cat_total_dives: + read_int_eeprom .2 + movff EEDATA,lo + read_int_eeprom .3 + movff EEDATA,hi + bsf leftbind + output_16 + bcf leftbind + return + +;----------------------------------------------------------------------------- ; append firmware version to current string, including color-coding global TFT_cat_firmware @@ -3402,7 +3452,7 @@ movlw softwareversion_x movwf lo bsf leftbind - output_8 ; print major in 1 digit format + output_8 ; print major in 1 or 2 digit format PUTC '.' movlw softwareversion_y movwf lo @@ -3450,7 +3500,7 @@ ENDIF ;----------------------------------------------------------------------------- -; For the Information menu: append serial number +; For the Information menu: serial number global info_menu_serial global TFT_cat_serial @@ -3472,24 +3522,26 @@ return ;----------------------------------------------------------------------------- -; For the Information menu: append total dives - - global info_menu_total_dives -info_menu_total_dives: - lfsr FSR1,tTotalDives +; For the Information menu: hardware / software configuration + + global info_menu_config +info_menu_config: + lfsr FSR1,tHardware call strcat_text -TFT_cat_total_dives: - read_int_eeprom .2 - movff EEDATA,lo - read_int_eeprom .3 - movff EEDATA,hi - bsf leftbind - output_16 - bcf leftbind + call I2C_init_compass ; start compass + movf HW_descriptor,W ; copy hardware descriptor to WREG + output_hex ; print as hex + PUTC "-" ; print a separator + movf HW_variants,W ; copy hardware variants to WREG + output_hex ; print as hex + PUTC "-" ; print a separator + movlw SW_CONF ; get software configuration + output_hex ; print as hex return + ;----------------------------------------------------------------------------- -; For the Information menu: append battery voltage +; For the Information menu: battery voltage global info_menu_battery_volts info_menu_battery_volts: @@ -3506,7 +3558,7 @@ return ;----------------------------------------------------------------------------- -; For the Information menu: append uptime +; For the Information menu: uptime global info_menu_uptime info_menu_uptime: @@ -3530,6 +3582,7 @@ bcf leftbind return ; done +;----------------------------------------------------------------------------- IFDEF _compass @@ -4423,18 +4476,24 @@ bra TFT_custview_exit2 ; and return... - global TFT_ppo2_ead_end_cns_mask ; mask for ppO2, END/EAD and CNS + global TFT_ppo2_ead_end_cns_mask ; mask for ppO2, END/EAD and CNS / gas density TFT_ppo2_ead_end_cns_mask: - rcall TFT_show_ppo2_mask call TFT_divemask_color - WIN_TINY dm_custom_ead_column, dm_custom_eadend_title_row + WIN_TINY dm_custom_ppo2_column-.2, dm_custom_ppo2_title_row + STRCPY_TEXT_PRINT tppO2 + WIN_TINY dm_custom_ead_column, dm_custom_eadend_title_row STRCPY_TEXT_PRINT tDiveEAD_END - WIN_TINY dm_custom_cns_column, dm_custom_cns_title_row + IFDEF _helium + WIN_TINY dm_custom_cns_column-.5, dm_custom_eadend_title_row + STRCPY_TEXT_PRINT tGasDensity + ELSE + WIN_TINY dm_custom_cns_column, dm_custom_cns_title_row STRCPY_TEXT_PRINT tCNS2 + ENDIF bra TFT_custview_exit2 ; and return... - global TFT_ppo2_ead_end_cns ; data for ppO2, END/EAD and CNS + global TFT_ppo2_ead_end_cns ; data for ppO2, END/EAD and CNS / gas density TFT_ppo2_ead_end_cns: ; Show ppO2 WIN_MEDIUM dm_custom_ppo2_column, dm_custom_ppo2_row @@ -4454,6 +4513,18 @@ STRCPY_TEXT tEND ; END: movff char_O_END,lo rcall TFT_end_ead_common ; print "lo m" (or ft) and limit to 8 chars + IFDEF _helium + ; Show Gas Density + WIN_MEDIUM dm_custom_cns_column-.5, dm_custom_cns_row + MOVII int_O_gas_density,mpr ; get current gas density + call TFT_color_code_cns_1 ; color-code output + bsf leftbind ; print left-aligned + movlw .2 ; suppress first and second digit + movwf ignore_digits ; ... + output_16dp .2 ; print as --x.yy + bcf leftbind ; back to normal alignment + STRCAT_PRINT "" ; finalize output + ELSE ; Show CNS WIN_STD dm_custom_cns_column+.3, dm_custom_cns_row MOVII int_O_CNS_current,mpr ; get current CNS @@ -4462,6 +4533,7 @@ output_16_3 ; displays only 0...999 bcf leftbind STRCAT_PRINT "%" + ENDIF TFT_custview_exit2: goto TFT_standard_color ; and return... @@ -5164,8 +5236,8 @@ btfss hi,int_not_avail_flag ; pressure available? bra TFT_pressures_SAC_helper_1a ; YES - print pressure call TFT_disabled_color ; NO - use disabled color as default - btfsc ex,char_transmitter_lost ; - transmitter lost? - call TFT_attention_color ; YES - use attention color +; btfsc ex,char_transmitter_lost ; - transmitter lost? +; call TFT_attention_color ; YES - use attention color STRCAT_PRINT " ---" ; - print " ---" return TFT_pressures_SAC_helper_1a:
--- a/src/tft_outputs.inc Sun Jun 30 23:22:32 2019 +0200 +++ b/src/tft_outputs.inc Thu Sep 19 12:01:29 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File tft_outputs.inc next combined generation V3.03.2 +; File tft_outputs.inc next combined generation V3.03.8 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -53,6 +53,7 @@ extern TFT_show_time_date_menu_fast extern TFT_show_serial_and_firmware extern TFT_show_firmware + extern info_menu_total_dives ; Dive Mode extern TFT_show_cns @@ -120,8 +121,8 @@ extern TFT_ceiling_GF_tissue ; data for ceiling, current GF and tissues extern TFT_CNS_mask ; mask for CNS values extern TFT_CNS ; data for CNS values - extern TFT_ppo2_ead_end_cns_mask ; mask for ppO2, END/EAD and CNS - extern TFT_ppo2_ead_end_cns ; data for ppO2, END/EAD and CNS + extern TFT_ppo2_ead_end_cns_mask ; mask for ppO2, END/EAD and CNS / gas density + extern TFT_ppo2_ead_end_cns ; data for ppO2, END/EAD and CNS / gas density extern TFT_gf_factors_mask ; mask for GF factors ; extern ; data for GF factors (none) extern TFT_clock_batt_surfpress_mask ; mask for clock, battery and surface pressure